Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Nov 2013 01:20:12 +0000 (10:20 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Nov 2013 01:20:12 +0000 (10:20 +0900)
Pull scheduler changes from Ingo Molnar:
 "The main changes in this cycle are:

   - (much) improved CONFIG_NUMA_BALANCING support from Mel Gorman, Rik
     van Riel, Peter Zijlstra et al.  Yay!

   - optimize preemption counter handling: merge the NEED_RESCHED flag
     into the preempt_count variable, by Peter Zijlstra.

   - wait.h fixes and code reorganization from Peter Zijlstra

   - cfs_bandwidth fixes from Ben Segall

   - SMP load-balancer cleanups from Peter Zijstra

   - idle balancer improvements from Jason Low

   - other fixes and cleanups"

* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (129 commits)
  ftrace, sched: Add TRACE_FLAG_PREEMPT_RESCHED
  stop_machine: Fix race between stop_two_cpus() and stop_cpus()
  sched: Remove unnecessary iteration over sched domains to update nr_busy_cpus
  sched: Fix asymmetric scheduling for POWER7
  sched: Move completion code from core.c to completion.c
  sched: Move wait code from core.c to wait.c
  sched: Move wait.c into kernel/sched/
  sched/wait: Fix __wait_event_interruptible_lock_irq_timeout()
  sched: Avoid throttle_cfs_rq() racing with period_timer stopping
  sched: Guarantee new group-entities always have weight
  sched: Fix hrtimer_cancel()/rq->lock deadlock
  sched: Fix cfs_bandwidth misuse of hrtimer_expires_remaining
  sched: Fix race on toggling cfs_bandwidth_used
  sched: Remove extra put_online_cpus() inside sched_setaffinity()
  sched/rt: Fix task_tick_rt() comment
  sched/wait: Fix build breakage
  sched/wait: Introduce prepare_to_wait_event()
  sched/wait: Add ___wait_cond_timeout() to wait_event*_timeout() too
  sched: Remove get_online_cpus() usage
  sched: Fix race in migrate_swap_stop()
  ...

2594 files changed:
Documentation/ABI/testing/configfs-usb-gadget-mass-storage [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-iio
Documentation/ABI/testing/sysfs-class-mic.txt [new file with mode: 0644]
Documentation/ABI/testing/sysfs-driver-sunxi-sid [new file with mode: 0644]
Documentation/DocBook/device-drivers.tmpl
Documentation/DocBook/filesystems.tmpl
Documentation/DocBook/genericirq.tmpl
Documentation/RCU/checklist.txt
Documentation/RCU/stallwarn.txt
Documentation/arm/Marvell/README
Documentation/arm/sunxi/README
Documentation/arm64/booting.txt
Documentation/arm64/memory.txt
Documentation/devicetree/bindings/arm/arm-boards
Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
Documentation/devicetree/bindings/arm/atmel-adc.txt
Documentation/devicetree/bindings/arm/cci.txt
Documentation/devicetree/bindings/arm/omap/omap.txt
Documentation/devicetree/bindings/arm/vic.txt
Documentation/devicetree/bindings/clock/imx6q-clock.txt
Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
Documentation/devicetree/bindings/clock/sunxi.txt
Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt [deleted file]
Documentation/devicetree/bindings/clock/sunxi/sun5i-a10s-gates.txt [deleted file]
Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt [deleted file]
Documentation/devicetree/bindings/clock/sunxi/sun6i-a31-gates.txt [deleted file]
Documentation/devicetree/bindings/clock/sunxi/sun7i-a20-gates.txt [deleted file]
Documentation/devicetree/bindings/crypto/omap-aes.txt [new file with mode: 0644]
Documentation/devicetree/bindings/crypto/omap-sham.txt [new file with mode: 0644]
Documentation/devicetree/bindings/hwrng/omap_rng.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/light/cm36651.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt
Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt [deleted file]
Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt [deleted file]
Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt [new file with mode: 0644]
Documentation/devicetree/bindings/misc/ti,dac7512.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
Documentation/devicetree/bindings/pci/mvebu-pci.txt
Documentation/devicetree/bindings/phy/phy-bindings.txt [new file with mode: 0644]
Documentation/devicetree/bindings/phy/samsung-phy.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
Documentation/devicetree/bindings/usb/msm-hsusb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/omap-usb.txt
Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt
Documentation/devicetree/bindings/usb/usb-phy.txt
Documentation/devicetree/bindings/usb/ux500-usb.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/video/exynos_dp.txt
Documentation/devicetree/bindings/video/exynos_hdmi.txt
Documentation/devicetree/bindings/video/exynos_mixer.txt
Documentation/extcon/porting-android-switch-class
Documentation/filesystems/caching/netfs-api.txt
Documentation/kernel-parameters.txt
Documentation/kernel-per-CPU-kthreads.txt
Documentation/mic/mic_overview.txt [new file with mode: 0644]
Documentation/mic/mpssd/.gitignore [new file with mode: 0644]
Documentation/mic/mpssd/Makefile [new file with mode: 0644]
Documentation/mic/mpssd/micctrl [new file with mode: 0755]
Documentation/mic/mpssd/mpss [new file with mode: 0755]
Documentation/mic/mpssd/mpssd.c [new file with mode: 0644]
Documentation/mic/mpssd/mpssd.h [new file with mode: 0644]
Documentation/mic/mpssd/sysfs.c [new file with mode: 0644]
Documentation/networking/dccp.txt
Documentation/networking/e100.txt
Documentation/networking/ieee802154.txt
Documentation/networking/l2tp.txt
Documentation/networking/netdev-FAQ.txt
Documentation/networking/netlink_mmap.txt
Documentation/networking/operstates.txt
Documentation/networking/rxrpc.txt
Documentation/networking/stmmac.txt
Documentation/networking/vortex.txt
Documentation/networking/x25-iface.txt
Documentation/phy.txt [new file with mode: 0644]
Documentation/pps/pps.txt
Documentation/s390/s390dbf.txt
Documentation/serial/driver
Documentation/sysrq.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/arc/Kconfig
arch/arc/configs/fpga_defconfig
arch/arc/include/asm/cache.h
arch/arc/include/asm/irq.h
arch/arc/include/asm/irqflags.h
arch/arc/include/asm/mmu.h
arch/arc/include/asm/mmu_context.h
arch/arc/include/asm/setup.h
arch/arc/include/asm/smp.h
arch/arc/include/asm/tlbflush.h
arch/arc/include/asm/unaligned.h
arch/arc/kernel/ctx_sw.c
arch/arc/kernel/ctx_sw_asm.S
arch/arc/kernel/entry.S
arch/arc/kernel/head.S
arch/arc/kernel/irq.c
arch/arc/kernel/kgdb.c
arch/arc/kernel/kprobes.c
arch/arc/kernel/reset.c
arch/arc/kernel/setup.c
arch/arc/kernel/smp.c
arch/arc/kernel/stacktrace.c
arch/arc/kernel/time.c
arch/arc/kernel/traps.c
arch/arc/mm/cache_arc700.c
arch/arc/mm/fault.c
arch/arc/mm/tlb.c
arch/arc/mm/tlbex.S
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head-shark.S [deleted file]
arch/arm/boot/compressed/ofw-shark.c [deleted file]
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-base0033.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-bone-common.dtsi
arch/arm/boot/dts/am335x-bone.dts
arch/arm/boot/dts/am335x-boneblack.dts
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-igep0033.dtsi [new file with mode: 0644]
arch/arm/boot/dts/am335x-nano.dts [new file with mode: 0644]
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/armada-370-netgear-rn104.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-370.dtsi
arch/arm/boot/dts/armada-xp-matrix.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-xp-mv78230.dtsi
arch/arm/boot/dts/armada-xp-mv78260.dtsi
arch/arm/boot/dts/armada-xp-mv78460.dtsi
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/at91sam9g20ek_common.dtsi
arch/arm/boot/dts/at91sam9g25.dtsi
arch/arm/boot/dts/at91sam9g35.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9n12ek.dts
arch/arm/boot/dts/at91sam9x25.dtsi
arch/arm/boot/dts/at91sam9x35.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/at91sam9x5_macb0.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91sam9x5_macb1.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91sam9x5_usart3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/atlas6.dtsi
arch/arm/boot/dts/bcm11351-brt.dts
arch/arm/boot/dts/bcm11351.dtsi
arch/arm/boot/dts/bcm28155-ap.dts
arch/arm/boot/dts/dove-cm-a510.dts
arch/arm/boot/dts/dove-cubox.dts
arch/arm/boot/dts/dove-d2plug.dts
arch/arm/boot/dts/dove-d3plug.dts [new file with mode: 0644]
arch/arm/boot/dts/dove-dove-db.dts
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/dra7-evm.dts [new file with mode: 0644]
arch/arm/boot/dts/dra7.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ecx-common.dtsi
arch/arm/boot/dts/emev2-kzm9d-reference.dts [deleted file]
arch/arm/boot/dts/emev2-kzm9d.dts
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210-origen.dts
arch/arm/boot/dts/exynos4210-trats.dts
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4412-origen.dts
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-pinctrl.dtsi
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5420-smdk5420.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5440-sd5v1.dts
arch/arm/boot/dts/exynos5440-ssdk5440.dts
arch/arm/boot/dts/exynos5440.dtsi
arch/arm/boot/dts/imx23-evk.dts
arch/arm/boot/dts/imx23-olinuxino.dts
arch/arm/boot/dts/imx23-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx23-stmp378x_devb.dts
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx27-apf27dev.dts
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx28-apf28.dts
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-cfa10055.dts
arch/arm/boot/dts/imx28-cfa10056.dts
arch/arm/boot/dts/imx28-cfa10057.dts
arch/arm/boot/dts/imx28-cfa10058.dts
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx28-m28cu3.dts [new file with mode: 0644]
arch/arm/boot/dts/imx28-m28evk.dts
arch/arm/boot/dts/imx28-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx28-sps1.dts
arch/arm/boot/dts/imx28-tx28.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx51-apf51dev.dts
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-qsb.dts
arch/arm/boot/dts/imx6q-pinfunc.h
arch/arm/boot/dts/imx6q-sabrelite.dts
arch/arm/boot/dts/imx6q-udoo.dts [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.dtsi
arch/arm/boot/dts/integrator.dtsi
arch/arm/boot/dts/integratorap.dts
arch/arm/boot/dts/integratorcp.dts
arch/arm/boot/dts/keystone-clocks.dtsi [new file with mode: 0644]
arch/arm/boot/dts/keystone.dts
arch/arm/boot/dts/kirkwood-db-88f6281.dts
arch/arm/boot/dts/kirkwood-db-88f6282.dts
arch/arm/boot/dts/kirkwood-db.dtsi
arch/arm/boot/dts/kirkwood-dnskw.dtsi
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-km_kirkwood.dts
arch/arm/boot/dts/kirkwood-mplcec4.dts
arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
arch/arm/boot/dts/kirkwood-nsa310-common.dtsi
arch/arm/boot/dts/kirkwood-nsa310.dts
arch/arm/boot/dts/kirkwood-openblocks_a6.dts
arch/arm/boot/dts/kirkwood-openblocks_a7.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
arch/arm/boot/dts/kirkwood-topkick.dts
arch/arm/boot/dts/kirkwood-ts219-6282.dts
arch/arm/boot/dts/kirkwood.dtsi
arch/arm/boot/dts/msm8660-surf.dts [deleted file]
arch/arm/boot/dts/msm8960-cdp.dts [deleted file]
arch/arm/boot/dts/mxs-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap-zoom-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap2420-h4.dts
arch/arm/boot/dts/omap3-beagle-xm.dts
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-devkit8000.dts
arch/arm/boot/dts/omap3-evm-37xx.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-evm-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-evm.dts
arch/arm/boot/dts/omap3-gta04.dts [new file with mode: 0644]
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-n9.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-n900.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-n950-n9.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-n950.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo.dtsi
arch/arm/boot/dts/omap3-zoom3.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap3430-sdp.dts
arch/arm/boot/dts/omap36xx.dtsi
arch/arm/boot/dts/omap4-panda-common.dtsi
arch/arm/boot/dts/omap4-panda-es.dts
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap5-uevm.dts
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/prima2.dtsi
arch/arm/boot/dts/qcom-msm8660-surf.dts [new file with mode: 0644]
arch/arm/boot/dts/qcom-msm8960-cdp.dts [new file with mode: 0644]
arch/arm/boot/dts/r7s72100-genmai.dts [new file with mode: 0644]
arch/arm/boot/dts/r7s72100.dtsi [new file with mode: 0644]
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.dtsi
arch/arm/boot/dts/r8a7778-bockw-reference.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen-reference.dts
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-koelsch.dts [new file with mode: 0644]
arch/arm/boot/dts/r8a7791.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3066a-bqcurie2.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3066a.dtsi
arch/arm/boot/dts/rk3188-clocks.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3188-radxarock.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3188.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3xxx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/s3c6400.dtsi [new file with mode: 0644]
arch/arm/boot/dts/s3c6410-mini6410.dts [new file with mode: 0644]
arch/arm/boot/dts/s3c6410-smdk6410.dts [new file with mode: 0644]
arch/arm/boot/dts/s3c6410.dtsi [new file with mode: 0644]
arch/arm/boot/dts/s3c64xx-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/s3c64xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d31.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d31ek.dts
arch/arm/boot/dts/sama5d33.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d33ek.dts
arch/arm/boot/dts/sama5d34.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d34ek.dts
arch/arm/boot/dts/sama5d35.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d35ek.dts
arch/arm/boot/dts/sama5d3_can.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3_emac.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3_gmac.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3_lcd.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3_mci2.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3_tcb1.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3_uart.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d3xcm.dtsi
arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria5.dtsi [new file with mode: 0644]
arch/arm/boot/dts/socfpga_arria5_socdk.dts [new file with mode: 0644]
arch/arm/boot/dts/socfpga_cyclone5.dts [deleted file]
arch/arm/boot/dts/socfpga_cyclone5.dtsi [new file with mode: 0644]
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts [new file with mode: 0644]
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts [new file with mode: 0644]
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href-stuib.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-href-tvk1281618.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-href.dtsi
arch/arm/boot/dts/ste-hrefprev60-stuib.dts [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefprev60-tvk.dts [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefprev60.dts [deleted file]
arch/arm/boot/dts/ste-hrefprev60.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefv60plus-stuib.dts [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefv60plus-tvk.dts [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefv60plus.dts [deleted file]
arch/arm/boot/dts/ste-hrefv60plus.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/ste-stuib.dtsi [deleted file]
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i-a10s.dtsi
arch/arm/boot/dts/sun5i-a13.dtsi
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
arch/arm/boot/dts/sun7i-a20-cubietruck.dts [new file with mode: 0644]
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/tegra114-dalmore.dts
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124-venice2.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra124.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra30-cardhu.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/twl4030.dtsi
arch/arm/boot/dts/twl6030_omap4.dtsi [new file with mode: 0644]
arch/arm/boot/dts/vf610-cosmic.dts [new file with mode: 0644]
arch/arm/boot/dts/vf610-twr.dts
arch/arm/boot/dts/vf610.dtsi
arch/arm/common/Makefile
arch/arm/common/via82c505.c [deleted file]
arch/arm/configs/bcm_defconfig
arch/arm/configs/bockw_defconfig
arch/arm/configs/ep93xx_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/integrator_defconfig
arch/arm/configs/keystone_defconfig
arch/arm/configs/koelsch_defconfig [new file with mode: 0644]
arch/arm/configs/lager_defconfig
arch/arm/configs/marzen_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mxs_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/shark_defconfig [deleted file]
arch/arm/configs/sunxi_defconfig [new file with mode: 0644]
arch/arm/configs/tegra_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/configs/vexpress_defconfig
arch/arm/include/asm/mach/pci.h
arch/arm/include/asm/sched_clock.h [deleted file]
arch/arm/include/debug/vf.S [new file with mode: 0644]
arch/arm/kernel/psci_smp.c
arch/arm/kernel/time.c
arch/arm/lib/Makefile
arch/arm/lib/io-shark.c [deleted file]
arch/arm/mach-at91/at91sam9n12.c
arch/arm/mach-at91/board-cam60.c
arch/arm/mach-at91/board-dt-rm9200.c
arch/arm/mach-at91/board-dt-sam9.c
arch/arm/mach-at91/include/mach/at91_adc.h
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/board_bcm281xx.c
arch/arm/mach-bcm2835/bcm2835.c
arch/arm/mach-clps711x/common.c
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-omapl138-hawk.c
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/davinci.h
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/devices.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/include/mach/da8xx.h
arch/arm/mach-davinci/include/mach/gpio-davinci.h [deleted file]
arch/arm/mach-davinci/include/mach/gpio.h [deleted file]
arch/arm/mach-davinci/time.c
arch/arm/mach-dove/board-dt.c
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/common.c
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/include/mach/regs-pmu.h
arch/arm/mach-exynos/mach-exynos4-dt.c
arch/arm/mach-exynos/mach-exynos5-dt.c
arch/arm/mach-gemini/time.c
arch/arm/mach-highbank/Kconfig
arch/arm/mach-highbank/Makefile
arch/arm/mach-highbank/core.h
arch/arm/mach-highbank/highbank.c
arch/arm/mach-highbank/hotplug.c [deleted file]
arch/arm/mach-highbank/platsmp.c [deleted file]
arch/arm/mach-highbank/pm.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/anatop.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/common.h
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/epit.c
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/hotplug.c
arch/arm/mach-imx/imx51-dt.c
arch/arm/mach-imx/mach-armadillo5x0.c
arch/arm/mach-imx/mach-imx53.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-imx6sl.c
arch/arm/mach-imx/mach-mx31_3ds.c
arch/arm/mach-imx/mach-pcm037.c
arch/arm/mach-imx/mach-vf610.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/mach-imx/mx31lilly-db.c
arch/arm/mach-imx/mxc.h
arch/arm/mach-imx/pm-imx6q.c
arch/arm/mach-imx/src.c
arch/arm/mach-imx/system.c
arch/arm/mach-imx/time.c
arch/arm/mach-integrator/cm.h [new file with mode: 0644]
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/include/mach/cm.h [deleted file]
arch/arm/mach-integrator/include/mach/irqs.h [deleted file]
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-integrator/leds.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-keystone/Kconfig
arch/arm/mach-keystone/Makefile
arch/arm/mach-keystone/pm_domain.c [new file with mode: 0644]
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-kirkwood/include/mach/bridge-regs.h
arch/arm/mach-kirkwood/pm.c [new file with mode: 0644]
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/board-dt-8660.c [deleted file]
arch/arm/mach-msm/board-dt-8960.c [deleted file]
arch/arm/mach-msm/board-dt.c [new file with mode: 0644]
arch/arm/mach-msm/include/mach/irqs-8960.h [deleted file]
arch/arm/mach-msm/include/mach/irqs-8x60.h [deleted file]
arch/arm/mach-msm/include/mach/irqs.h
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-nomadik/cpu-8815.c
arch/arm/mach-nspire/nspire.c
arch/arm/mach-omap1/common.h
arch/arm/mach-omap1/fpga.c
arch/arm/mach-omap1/gpio15xx.c
arch/arm/mach-omap1/gpio16xx.c
arch/arm/mach-omap1/gpio7xx.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap1/time.c
arch/arm/mach-omap1/timer32k.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-3630sdp.c [deleted file]
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-igep0020.c [deleted file]
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c [deleted file]
arch/arm/mach-omap2/board-rm680.c [deleted file]
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/board-zoom-debugboard.c [deleted file]
arch/arm/mach-omap2/board-zoom-display.c [deleted file]
arch/arm/mach-omap2/board-zoom-peripherals.c [deleted file]
arch/arm/mach-omap2/board-zoom.c [deleted file]
arch/arm/mach-omap2/board-zoom.h [deleted file]
arch/arm/mach-omap2/cclock3xxx_data.c
arch/arm/mach-omap2/clkt2xxx_apll.c
arch/arm/mach-omap2/clkt2xxx_dpllcore.c
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clockdomain.h
arch/arm/mach-omap2/clockdomains43xx_data.c [new file with mode: 0644]
arch/arm/mach-omap2/cm2xxx.c
arch/arm/mach-omap2/cm2xxx.h
arch/arm/mach-omap2/cm33xx.c
arch/arm/mach-omap2/cm33xx.h
arch/arm/mach-omap2/cm3xxx.c
arch/arm/mach-omap2/cm3xxx.h
arch/arm/mach-omap2/cminst44xx.c
arch/arm/mach-omap2/cminst44xx.h
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/control.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/display.h
arch/arm/mach-omap2/drm.c
arch/arm/mach-omap2/dss-common.c
arch/arm/mach-omap2/dss-common.h
arch/arm/mach-omap2/fb.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/mcbsp.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/omap-secure.c
arch/arm/mach-omap2/omap-secure.h
arch/arm/mach-omap2/omap-smc.S
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h [new file with mode: 0644]
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c [new file with mode: 0644]
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c [new file with mode: 0644]
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_43xx_data.c [new file with mode: 0644]
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_54xx_data.c
arch/arm/mach-omap2/opp.c
arch/arm/mach-omap2/pdata-quirks.c [new file with mode: 0644]
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/powerdomain.h
arch/arm/mach-omap2/powerdomains43xx_data.c [new file with mode: 0644]
arch/arm/mach-omap2/prcm43xx.h [new file with mode: 0644]
arch/arm/mach-omap2/prm3xxx.h
arch/arm/mach-omap2/prm44xx_54xx.h
arch/arm/mach-omap2/prm_common.c
arch/arm/mach-omap2/soc.h
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/twl-common.c
arch/arm/mach-omap2/usb-host.c
arch/arm/mach-omap2/usb.h
arch/arm/mach-prima2/common.c
arch/arm/mach-prima2/common.h
arch/arm/mach-rockchip/Kconfig
arch/arm/mach-rockchip/rockchip.c
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c24xx/clock-s3c2412.c
arch/arm/mach-s3c24xx/common-s3c2443.c
arch/arm/mach-s3c24xx/common.c
arch/arm/mach-s3c24xx/common.h
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm/mach-s3c24xx/mach-smdk2413.c
arch/arm/mach-s3c24xx/mach-smdk2416.c
arch/arm/mach-s3c24xx/mach-smdk2443.c
arch/arm/mach-s3c24xx/mach-vstms.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/clock.c [deleted file]
arch/arm/mach-s3c64xx/common.c
arch/arm/mach-s3c64xx/common.h
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-s3c64xx/include/mach/regs-clock.h
arch/arm/mach-s3c64xx/irq-pm.c
arch/arm/mach-s3c64xx/mach-anw6410.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-ncp.c
arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c [new file with mode: 0644]
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/pm.c
arch/arm/mach-s3c64xx/s3c6400.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s5pv210/include/mach/regs-clock.h
arch/arm/mach-shark/Makefile [deleted file]
arch/arm/mach-shark/Makefile.boot [deleted file]
arch/arm/mach-shark/core.c [deleted file]
arch/arm/mach-shark/dma.c [deleted file]
arch/arm/mach-shark/include/mach/debug-macro.S [deleted file]
arch/arm/mach-shark/include/mach/entry-macro.S [deleted file]
arch/arm/mach-shark/include/mach/framebuffer.h [deleted file]
arch/arm/mach-shark/include/mach/hardware.h [deleted file]
arch/arm/mach-shark/include/mach/irqs.h [deleted file]
arch/arm/mach-shark/include/mach/isa-dma.h [deleted file]
arch/arm/mach-shark/include/mach/memory.h [deleted file]
arch/arm/mach-shark/include/mach/timex.h [deleted file]
arch/arm/mach-shark/include/mach/uncompress.h [deleted file]
arch/arm/mach-shark/irq.c [deleted file]
arch/arm/mach-shark/leds.c [deleted file]
arch/arm/mach-shark/pci.c [deleted file]
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/Makefile.boot
arch/arm/mach-shmobile/board-ape6evm-reference.c
arch/arm/mach-shmobile/board-ape6evm.c
arch/arm/mach-shmobile/board-armadillo800eva.c
arch/arm/mach-shmobile/board-bockw-reference.c
arch/arm/mach-shmobile/board-bockw.c
arch/arm/mach-shmobile/board-genmai.c [new file with mode: 0644]
arch/arm/mach-shmobile/board-koelsch.c [new file with mode: 0644]
arch/arm/mach-shmobile/board-kzm9d-reference.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/mach-shmobile/board-lager-reference.c
arch/arm/mach-shmobile/board-lager.c
arch/arm/mach-shmobile/board-marzen-reference.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-shmobile/clock-r7s72100.c [new file with mode: 0644]
arch/arm/mach-shmobile/clock-r8a73a4.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 [new file with mode: 0644]
arch/arm/mach-shmobile/headsmp.S
arch/arm/mach-shmobile/include/mach/common.h
arch/arm/mach-shmobile/include/mach/r7s72100.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/r8a73a4.h
arch/arm/mach-shmobile/include/mach/r8a7778.h
arch/arm/mach-shmobile/include/mach/r8a7779.h
arch/arm/mach-shmobile/include/mach/r8a7790.h
arch/arm/mach-shmobile/include/mach/r8a7791.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/rcar-gen2.h [new file with mode: 0644]
arch/arm/mach-shmobile/platsmp-apmu.c [new file with mode: 0644]
arch/arm/mach-shmobile/platsmp-scu.c
arch/arm/mach-shmobile/platsmp.c
arch/arm/mach-shmobile/setup-r7s72100.c [new file with mode: 0644]
arch/arm/mach-shmobile/setup-r8a73a4.c
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-r8a7790.c
arch/arm/mach-shmobile/setup-r8a7791.c [new file with mode: 0644]
arch/arm/mach-shmobile/setup-rcar-gen2.c [new file with mode: 0644]
arch/arm/mach-shmobile/smp-emev2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-r8a7790.c [new file with mode: 0644]
arch/arm/mach-shmobile/smp-r8a7791.c [new file with mode: 0644]
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-socfpga/Kconfig
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-spear/Kconfig
arch/arm/mach-sti/board-dt.c
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-sunxi/sunxi.c
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-paz00.c
arch/arm/mach-tegra/board-paz00.h [deleted file]
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/common.c [deleted file]
arch/arm/mach-tegra/cpuidle.c
arch/arm/mach-tegra/flowctrl.c
arch/arm/mach-tegra/fuse.c
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/gpio-names.h [deleted file]
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-tegra/iomap.h
arch/arm/mach-tegra/irammap.h
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/pmc.c
arch/arm/mach-tegra/pmc.h
arch/arm/mach-tegra/powergate.c
arch/arm/mach-tegra/reset-handler.S
arch/arm/mach-tegra/reset.c
arch/arm/mach-tegra/sleep-tegra20.S
arch/arm/mach-tegra/sleep-tegra30.S
arch/arm/mach-tegra/tegra.c
arch/arm/mach-u300/Kconfig
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/Makefile
arch/arm/mach-ux500/board-mop500-audio.c
arch/arm/mach-ux500/board-mop500-sdi.c
arch/arm/mach-ux500/board-mop500-stuib.c [deleted file]
arch/arm/mach-ux500/board-mop500-u8500uib.c [deleted file]
arch/arm/mach-ux500/board-mop500-uib.c [deleted file]
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-mop500.h
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/devices-common.c [deleted file]
arch/arm/mach-ux500/devices-common.h [deleted file]
arch/arm/mach-ux500/devices-db8500.c
arch/arm/mach-ux500/devices-db8500.h
arch/arm/mach-ux500/devices.h
arch/arm/mach-ux500/setup.h
arch/arm/mach-ux500/timer.c
arch/arm/mach-ux500/usb.c [deleted file]
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-vexpress/v2m.c
arch/arm/mach-vt8500/Kconfig
arch/arm/mach-vt8500/common.h [deleted file]
arch/arm/mach-vt8500/vt8500.c
arch/arm/plat-omap/dma.c
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/init.c
arch/arm/plat-samsung/setup-mipiphy.c [deleted file]
arch/arm64/Kconfig
arch/arm64/Makefile
arch/arm64/configs/defconfig
arch/arm64/include/asm/assembler.h
arch/arm64/include/asm/cmpxchg.h
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/cpu_ops.h [new file with mode: 0644]
arch/arm64/include/asm/elf.h
arch/arm64/include/asm/io.h
arch/arm64/include/asm/irq.h
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/pgtable-2level-hwdef.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/processor.h
arch/arm64/include/asm/psci.h
arch/arm64/include/asm/ptrace.h
arch/arm64/include/asm/smp.h
arch/arm64/include/asm/spinlock.h
arch/arm64/include/asm/spinlock_types.h
arch/arm64/include/asm/syscall.h
arch/arm64/include/asm/virt.h
arch/arm64/include/uapi/asm/byteorder.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/arm64ksyms.c
arch/arm64/kernel/cpu_ops.c [new file with mode: 0644]
arch/arm64/kernel/cputable.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/head.S
arch/arm64/kernel/irq.c
arch/arm64/kernel/kuser32.S
arch/arm64/kernel/module.c
arch/arm64/kernel/perf_event.c
arch/arm64/kernel/process.c
arch/arm64/kernel/psci.c
arch/arm64/kernel/setup.c
arch/arm64/kernel/signal32.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/smp_psci.c [deleted file]
arch/arm64/kernel/smp_spin_table.c
arch/arm64/kernel/sys32.S
arch/arm64/kernel/vdso.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/hyp-init.S
arch/arm64/kvm/hyp.S
arch/arm64/mm/ioremap.c
arch/arm64/mm/proc.S
arch/m68k/include/asm/floppy.h
arch/m68k/include/asm/sun3xflop.h
arch/m68k/include/asm/uaccess.h
arch/m68k/platform/68000/timers.c
arch/m68k/platform/68360/config.c
arch/m68k/platform/coldfire/pit.c
arch/m68k/platform/coldfire/sltimers.c
arch/m68k/platform/coldfire/timers.c
arch/metag/kernel/irq.c
arch/mips/Kbuild.platforms
arch/mips/Kconfig
arch/mips/Kconfig.debug
arch/mips/Makefile
arch/mips/alchemy/devboards/db1235.c
arch/mips/ath79/dev-common.c
arch/mips/bcm47xx/Makefile
arch/mips/bcm47xx/board.c [new file with mode: 0644]
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/prom.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/time.c
arch/mips/boot/compressed/Makefile
arch/mips/boot/compressed/decompress.c
arch/mips/boot/compressed/ld.script
arch/mips/boot/ecoff.h
arch/mips/cavium-octeon/setup.c
arch/mips/cobalt/Makefile
arch/mips/cobalt/console.c [deleted file]
arch/mips/cobalt/setup.c
arch/mips/configs/powertv_defconfig [deleted file]
arch/mips/dec/int-handler.S
arch/mips/dec/ioasic-irq.c
arch/mips/dec/prom/call_o32.S
arch/mips/dec/prom/init.c
arch/mips/dec/prom/memory.c
arch/mips/dec/setup.c
arch/mips/include/asm/addrspace.h
arch/mips/include/asm/atomic.h
arch/mips/include/asm/barrier.h
arch/mips/include/asm/cacheops.h
arch/mips/include/asm/dec/ioasic.h
arch/mips/include/asm/dec/ioasic_addrs.h
arch/mips/include/asm/dec/kn01.h
arch/mips/include/asm/dec/kn02ca.h
arch/mips/include/asm/dec/prom.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h [deleted file]
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
arch/mips/include/asm/mach-dec/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mach-generic/dma-coherence.h
arch/mips/include/asm/mach-ip27/dma-coherence.h
arch/mips/include/asm/mach-ip32/dma-coherence.h
arch/mips/include/asm/mach-jazz/dma-coherence.h
arch/mips/include/asm/mach-loongson/dma-coherence.h
arch/mips/include/asm/mach-powertv/asic.h [deleted file]
arch/mips/include/asm/mach-powertv/asic_reg_map.h [deleted file]
arch/mips/include/asm/mach-powertv/asic_regs.h [deleted file]
arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h [deleted file]
arch/mips/include/asm/mach-powertv/dma-coherence.h [deleted file]
arch/mips/include/asm/mach-powertv/interrupts.h [deleted file]
arch/mips/include/asm/mach-powertv/ioremap.h [deleted file]
arch/mips/include/asm/mach-powertv/irq.h [deleted file]
arch/mips/include/asm/mach-powertv/powertv-clock.h [deleted file]
arch/mips/include/asm/mach-powertv/war.h [deleted file]
arch/mips/include/asm/mips-boards/piix4.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/ptrace.h
arch/mips/include/asm/r4kcache.h
arch/mips/include/asm/setup.h
arch/mips/include/asm/stackframe.h
arch/mips/include/asm/syscall.h [new file with mode: 0644]
arch/mips/include/asm/thread_info.h
arch/mips/include/asm/time.h
arch/mips/include/asm/unistd.h
arch/mips/include/uapi/asm/siginfo.h
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/csrc-powertv.c [deleted file]
arch/mips/kernel/early_printk_8250.c [new file with mode: 0644]
arch/mips/kernel/ftrace.c
arch/mips/kernel/genex.S
arch/mips/kernel/irq_cpu.c
arch/mips/kernel/module.c
arch/mips/kernel/perf_event_mipsxx.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/setup.c
arch/mips/kernel/smp-bmips.c
arch/mips/kernel/smp.c
arch/mips/kernel/traps.c
arch/mips/lantiq/irq.c
arch/mips/lantiq/xway/sysctrl.c
arch/mips/mm/c-r4k.c
arch/mips/mm/dma-default.c
arch/mips/mm/tlb-funcs.S
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/malta-int.c
arch/mips/netlogic/common/smp.c
arch/mips/pci/fixup-malta.c
arch/mips/pci/pci-ar71xx.c
arch/mips/pci/pci-ar724x.c
arch/mips/pci/pci.c
arch/mips/powertv/Kconfig [deleted file]
arch/mips/powertv/Makefile [deleted file]
arch/mips/powertv/Platform [deleted file]
arch/mips/powertv/asic/Makefile [deleted file]
arch/mips/powertv/asic/asic-calliope.c [deleted file]
arch/mips/powertv/asic/asic-cronus.c [deleted file]
arch/mips/powertv/asic/asic-gaia.c [deleted file]
arch/mips/powertv/asic/asic-zeus.c [deleted file]
arch/mips/powertv/asic/asic_devices.c [deleted file]
arch/mips/powertv/asic/asic_int.c [deleted file]
arch/mips/powertv/asic/irq_asic.c [deleted file]
arch/mips/powertv/asic/prealloc-calliope.c [deleted file]
arch/mips/powertv/asic/prealloc-cronus.c [deleted file]
arch/mips/powertv/asic/prealloc-cronuslite.c [deleted file]
arch/mips/powertv/asic/prealloc-gaia.c [deleted file]
arch/mips/powertv/asic/prealloc-zeus.c [deleted file]
arch/mips/powertv/asic/prealloc.h [deleted file]
arch/mips/powertv/init.c [deleted file]
arch/mips/powertv/init.h [deleted file]
arch/mips/powertv/ioremap.c [deleted file]
arch/mips/powertv/memory.c [deleted file]
arch/mips/powertv/pci/Makefile [deleted file]
arch/mips/powertv/pci/fixup-powertv.c [deleted file]
arch/mips/powertv/pci/powertv-pci.h [deleted file]
arch/mips/powertv/powertv-clock.h [deleted file]
arch/mips/powertv/powertv-usb.c [deleted file]
arch/mips/powertv/powertv_setup.c [deleted file]
arch/mips/powertv/reset.c [deleted file]
arch/mips/powertv/reset.h [deleted file]
arch/mips/powertv/time.c [deleted file]
arch/mips/ralink/clk.c
arch/mips/ralink/mt7620.c
arch/mips/ralink/of.c
arch/mips/ralink/rt305x.c
arch/mips/ralink/timer.c
arch/parisc/Kconfig
arch/parisc/Makefile
arch/parisc/configs/generic-32bit_defconfig [new file with mode: 0644]
arch/parisc/configs/generic-64bit_defconfig [new file with mode: 0644]
arch/parisc/include/asm/assembly.h
arch/parisc/include/asm/delay.h
arch/parisc/include/asm/hardirq.h
arch/parisc/include/asm/ptrace.h
arch/parisc/include/asm/thread_info.h
arch/parisc/include/asm/uaccess.h
arch/parisc/install.sh
arch/parisc/kernel/Makefile
arch/parisc/kernel/audit.c [new file with mode: 0644]
arch/parisc/kernel/compat_audit.c [new file with mode: 0644]
arch/parisc/kernel/irq.c
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/setup.c
arch/parisc/kernel/smp.c
arch/parisc/kernel/syscall.S
arch/parisc/lib/Makefile
arch/parisc/lib/delay.c [new file with mode: 0644]
arch/parisc/lib/lusercopy.S
arch/parisc/math-emu/float.h
arch/parisc/mm/fault.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/uprobes.h
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/vio.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/appldata/appldata_base.c
arch/s390/configs/default_defconfig [new file with mode: 0644]
arch/s390/configs/gcov_defconfig [new file with mode: 0644]
arch/s390/configs/performance_defconfig [new file with mode: 0644]
arch/s390/configs/zfcpdump_defconfig [new file with mode: 0644]
arch/s390/crypto/aes_s390.c
arch/s390/defconfig
arch/s390/include/asm/atomic.h
arch/s390/include/asm/bitops.h
arch/s390/include/asm/compat.h
arch/s390/include/asm/ctl_reg.h
arch/s390/include/asm/debug.h
arch/s390/include/asm/dis.h [new file with mode: 0644]
arch/s390/include/asm/fcx.h
arch/s390/include/asm/ipl.h
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/page.h
arch/s390/include/asm/pci_debug.h
arch/s390/include/asm/pci_insn.h
arch/s390/include/asm/percpu.h
arch/s390/include/asm/processor.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/smp.h
arch/s390/include/asm/switch_to.h
arch/s390/include/asm/timex.h
arch/s390/include/asm/uaccess.h
arch/s390/include/uapi/asm/ptrace.h
arch/s390/include/uapi/asm/sigcontext.h
arch/s390/kernel/Makefile
arch/s390/kernel/bitmap.c [deleted file]
arch/s390/kernel/cache.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_linux.h
arch/s390/kernel/compat_signal.c
arch/s390/kernel/crash_dump.c
arch/s390/kernel/debug.c
arch/s390/kernel/dis.c
arch/s390/kernel/dumpstack.c
arch/s390/kernel/early.c
arch/s390/kernel/entry.h
arch/s390/kernel/ftrace.c
arch/s390/kernel/head.S
arch/s390/kernel/ipl.c
arch/s390/kernel/irq.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/pgm_check.S
arch/s390/kernel/process.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/runtime_instr.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/smp.c
arch/s390/kernel/vdso.c
arch/s390/kernel/vtime.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/trace.h
arch/s390/lib/Makefile
arch/s390/lib/find.c [new file with mode: 0644]
arch/s390/lib/uaccess_mvcos.c
arch/s390/lib/uaccess_pt.c
arch/s390/lib/uaccess_std.c [deleted file]
arch/s390/math-emu/math.c
arch/s390/mm/cmm.c
arch/s390/mm/fault.c
arch/s390/mm/gup.c
arch/s390/mm/mmap.c
arch/s390/mm/pageattr.c
arch/s390/mm/pgtable.c
arch/s390/net/bpf_jit_comp.c
arch/s390/pci/pci.c
arch/s390/pci/pci_clp.c
arch/s390/pci/pci_dma.c
arch/s390/pci/pci_event.c
arch/sh/kernel/irq.c
arch/sparc/kernel/irq_64.c
arch/x86/Kconfig
arch/x86/include/asm/uprobes.h
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_intel_lbr.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/i8259.c
arch/x86/kernel/irq_32.c
arch/x86/kernel/irq_64.c
arch/x86/kernel/nmi.c
arch/x86/lib/usercopy.c
arch/x86/mm/fault.c
arch/x86/oprofile/backtrace.c
drivers/Kconfig
drivers/Makefile
drivers/base/bus.c
drivers/base/class.c
drivers/base/core.c
drivers/base/devres.c
drivers/base/firmware_class.c
drivers/base/platform.c
drivers/bcma/main.c
drivers/block/Kconfig
drivers/bus/arm-cci.c
drivers/char/hpet.c
drivers/char/misc.c
drivers/char/nwbutton.c
drivers/char/rtc.c
drivers/char/snsc.c
drivers/char/snsc_event.c
drivers/char/tlclk.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/clk/clk-bcm2835.c
drivers/clk/clk-highbank.c
drivers/clk/clk-nomadik.c
drivers/clk/clk-prima2.c
drivers/clk/clk-vt8500.c
drivers/clk/mvebu/armada-370.c
drivers/clk/mxs/clk-imx23.c
drivers/clk/mxs/clk-imx28.c
drivers/clk/samsung/Makefile
drivers/clk/socfpga/clk.c
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/ux500/Makefile
drivers/clk/ux500/u8500_of_clk.c [new file with mode: 0644]
drivers/clk/ux500/u8540_clk.c
drivers/clk/versatile/clk-icst.c
drivers/cpufreq/integrator-cpufreq.c
drivers/cpuidle/Kconfig.arm
drivers/cpuidle/cpuidle-calxeda.c
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/s3c24xx-dma.c [new file with mode: 0644]
drivers/extcon/extcon-adc-jack.c
drivers/extcon/extcon-arizona.c
drivers/extcon/extcon-class.c
drivers/extcon/extcon-gpio.c
drivers/extcon/extcon-max77693.c
drivers/extcon/extcon-max8997.c
drivers/extcon/extcon-palmas.c
drivers/gpio/gpio-davinci.c
drivers/gpio/gpio-samsung.c
drivers/gpio/gpio-tnetv107x.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/i915/intel_crt.c
drivers/hid/hid-sensor-hub.c
drivers/hsi/hsi.c
drivers/hv/channel.c
drivers/hv/channel_mgmt.c
drivers/hv/connection.c
drivers/hv/hv.c
drivers/hv/hv_util.c
drivers/hv/hyperv_vmbus.h
drivers/hv/vmbus_drv.c
drivers/ide/Kconfig
drivers/ide/ide-sysfs.c
drivers/ide/ide.c
drivers/iio/accel/bma180.c
drivers/iio/accel/hid-sensor-accel-3d.c
drivers/iio/accel/kxsd9.c
drivers/iio/accel/st_accel_buffer.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/ad7266.c
drivers/iio/adc/ad7298.c
drivers/iio/adc/ad7476.c
drivers/iio/adc/ad7791.c
drivers/iio/adc/ad7887.c
drivers/iio/adc/ad7923.c
drivers/iio/adc/ad_sigma_delta.c
drivers/iio/adc/at91_adc.c
drivers/iio/adc/max1363.c
drivers/iio/adc/mcp3422.c [new file with mode: 0644]
drivers/iio/adc/nau7802.c
drivers/iio/adc/ti-adc081c.c
drivers/iio/adc/ti_am335x_adc.c
drivers/iio/adc/twl6030-gpadc.c
drivers/iio/buffer_cb.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/common/st_sensors/st_sensors_buffer.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/Kconfig
drivers/iio/dac/ad5064.c
drivers/iio/dac/ad5360.c
drivers/iio/dac/ad5380.c
drivers/iio/dac/ad5421.c
drivers/iio/dac/ad5446.c
drivers/iio/dac/ad5449.c
drivers/iio/dac/ad5504.c
drivers/iio/dac/ad5624r_spi.c
drivers/iio/dac/ad5686.c
drivers/iio/dac/ad5755.c
drivers/iio/dac/ad5764.c
drivers/iio/dac/ad5791.c
drivers/iio/dac/ad7303.c
drivers/iio/dac/max517.c
drivers/iio/dac/mcp4725.c
drivers/iio/frequency/adf4350.c
drivers/iio/gyro/adis16080.c
drivers/iio/gyro/adis16130.c
drivers/iio/gyro/adis16260.c
drivers/iio/gyro/adxrs450.c
drivers/iio/gyro/hid-sensor-gyro-3d.c
drivers/iio/gyro/itg3200_buffer.c
drivers/iio/gyro/st_gyro_buffer.c
drivers/iio/gyro/st_gyro_core.c
drivers/iio/iio_core.h
drivers/iio/imu/adis16400_buffer.c
drivers/iio/imu/adis_buffer.c
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-event.c
drivers/iio/industrialio-triggered-buffer.c
drivers/iio/kfifo_buf.c
drivers/iio/light/Kconfig
drivers/iio/light/Makefile
drivers/iio/light/adjd_s311.c
drivers/iio/light/apds9300.c
drivers/iio/light/cm36651.c [new file with mode: 0644]
drivers/iio/light/gp2ap020a00f.c [new file with mode: 0644]
drivers/iio/light/hid-sensor-als.c
drivers/iio/light/tcs3472.c [new file with mode: 0644]
drivers/iio/light/tsl2563.c
drivers/iio/light/tsl4531.c [new file with mode: 0644]
drivers/iio/light/vcnl4000.c
drivers/iio/magnetometer/Kconfig
drivers/iio/magnetometer/Makefile
drivers/iio/magnetometer/ak8975.c
drivers/iio/magnetometer/hid-sensor-magn-3d.c
drivers/iio/magnetometer/mag3110.c [new file with mode: 0644]
drivers/iio/magnetometer/st_magn_buffer.c
drivers/iio/magnetometer/st_magn_core.c
drivers/iio/pressure/Kconfig
drivers/iio/pressure/st_pressure.h
drivers/iio/pressure/st_pressure_buffer.c
drivers/iio/pressure/st_pressure_core.c
drivers/iio/pressure/st_pressure_i2c.c
drivers/iio/pressure/st_pressure_spi.c
drivers/iio/temperature/tmp006.c
drivers/iio/trigger/iio-trig-sysfs.c
drivers/input/gameport/gameport.c
drivers/input/serio/Kconfig
drivers/input/serio/serio.c
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/ipack/ipack.c
drivers/irqchip/irq-armada-370-xp.c
drivers/irqchip/irq-bcm2835.c
drivers/irqchip/irq-vic.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/md.h
drivers/media/platform/Kconfig
drivers/media/platform/exynos4-is/Kconfig
drivers/media/platform/exynos4-is/mipi-csis.c
drivers/memstick/core/memstick.c
drivers/message/i2o/core.h
drivers/message/i2o/device.c
drivers/message/i2o/driver.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/dbx500-prcmu-regs.h
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/arm-charlcd.c
drivers/misc/atmel_pwm.c
drivers/misc/bh1780gli.c
drivers/misc/bmp085.c
drivers/misc/cb710/core.c
drivers/misc/eeprom/Kconfig
drivers/misc/eeprom/Makefile
drivers/misc/eeprom/at24.c
drivers/misc/eeprom/at25.c
drivers/misc/eeprom/eeprom_93xx46.c
drivers/misc/eeprom/sunxi_sid.c [new file with mode: 0644]
drivers/misc/ibmasm/module.c
drivers/misc/lkdtm.c
drivers/misc/mei/amthif.c
drivers/misc/mei/bus.c
drivers/misc/mei/client.c
drivers/misc/mei/client.h
drivers/misc/mei/hbm.c
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/init.c
drivers/misc/mei/interrupt.c
drivers/misc/mei/main.c
drivers/misc/mei/mei_dev.h
drivers/misc/mei/nfc.c
drivers/misc/mei/pci-me.c
drivers/misc/mei/wd.c
drivers/misc/mic/Kconfig [new file with mode: 0644]
drivers/misc/mic/Makefile [new file with mode: 0644]
drivers/misc/mic/card/Makefile [new file with mode: 0644]
drivers/misc/mic/card/mic_debugfs.c [new file with mode: 0644]
drivers/misc/mic/card/mic_device.c [new file with mode: 0644]
drivers/misc/mic/card/mic_device.h [new file with mode: 0644]
drivers/misc/mic/card/mic_virtio.c [new file with mode: 0644]
drivers/misc/mic/card/mic_virtio.h [new file with mode: 0644]
drivers/misc/mic/card/mic_x100.c [new file with mode: 0644]
drivers/misc/mic/card/mic_x100.h [new file with mode: 0644]
drivers/misc/mic/common/mic_dev.h [new file with mode: 0644]
drivers/misc/mic/host/Makefile [new file with mode: 0644]
drivers/misc/mic/host/mic_boot.c [new file with mode: 0644]
drivers/misc/mic/host/mic_debugfs.c [new file with mode: 0644]
drivers/misc/mic/host/mic_device.h [new file with mode: 0644]
drivers/misc/mic/host/mic_fops.c [new file with mode: 0644]
drivers/misc/mic/host/mic_fops.h [new file with mode: 0644]
drivers/misc/mic/host/mic_intr.c [new file with mode: 0644]
drivers/misc/mic/host/mic_intr.h [new file with mode: 0644]
drivers/misc/mic/host/mic_main.c [new file with mode: 0644]
drivers/misc/mic/host/mic_smpt.c [new file with mode: 0644]
drivers/misc/mic/host/mic_smpt.h [new file with mode: 0644]
drivers/misc/mic/host/mic_sysfs.c [new file with mode: 0644]
drivers/misc/mic/host/mic_virtio.c [new file with mode: 0644]
drivers/misc/mic/host/mic_virtio.h [new file with mode: 0644]
drivers/misc/mic/host/mic_x100.c [new file with mode: 0644]
drivers/misc/mic/host/mic_x100.h [new file with mode: 0644]
drivers/misc/phantom.c
drivers/misc/pti.c
drivers/misc/ti_dac7512.c
drivers/misc/tifm_7xx1.c
drivers/misc/tifm_core.c
drivers/misc/vmw_vmci/vmci_guest.c
drivers/misc/vmw_vmci/vmci_host.c
drivers/misc/vmw_vmci/vmci_queue_pair.c
drivers/mmc/core/bus.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/host/mvsdio.c
drivers/mtd/nand/atmel_nand.c
drivers/net/bonding/bond_sysfs.c
drivers/net/can/c_can/c_can.c
drivers/net/can/usb/kvaser_usb.c
drivers/net/ethernet/amd/declance.c
drivers/net/ethernet/broadcom/bgmac.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
drivers/net/ethernet/chelsio/cxgb3/sge.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/ibm/emac/mal.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/netconsole.c
drivers/net/phy/mdio_bus.c
drivers/net/usb/ax88179_178a.c
drivers/net/virtio_net.c
drivers/net/wan/sbni.c
drivers/net/xen-netback/common.h
drivers/net/xen-netback/interface.c
drivers/net/xen-netback/netback.c
drivers/pci/host/Kconfig
drivers/pci/host/pci-mvebu.c
drivers/pci/hotplug/s390_pci_hpc.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.h
drivers/pcmcia/at91_cf.c
drivers/pcmcia/ds.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/yenta_socket.c
drivers/phy/Kconfig [new file with mode: 0644]
drivers/phy/Makefile [new file with mode: 0644]
drivers/phy/phy-core.c [new file with mode: 0644]
drivers/phy/phy-exynos-dp-video.c [new file with mode: 0644]
drivers/phy/phy-exynos-mipi-video.c [new file with mode: 0644]
drivers/phy/phy-omap-usb2.c [new file with mode: 0644]
drivers/phy/phy-twl4030-usb.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-single.c
drivers/pnp/base.h
drivers/pnp/driver.c
drivers/pnp/interface.c
drivers/rapidio/rio-driver.c
drivers/rapidio/rio-sysfs.c
drivers/rapidio/rio.h
drivers/rtc/rtc-hid-sensor-time.c
drivers/s390/block/dasd.c
drivers/s390/block/scm_blk.c
drivers/s390/block/scm_blk.h
drivers/s390/char/monwriter.c
drivers/s390/char/raw3270.c
drivers/s390/char/zcore.c
drivers/s390/cio/airq.c
drivers/s390/cio/eadm_sch.c
drivers/s390/cio/eadm_sch.h
drivers/s390/cio/qdio_debug.h
drivers/s390/cio/qdio_main.c
drivers/s390/crypto/zcrypt_debug.h
drivers/s390/net/claw.h
drivers/s390/net/ctcm_dbug.c
drivers/s390/net/lcs.h
drivers/s390/net/netiucv.c
drivers/s390/net/qeth_core_main.c
drivers/s390/scsi/zfcp_dbf.h
drivers/scsi/fcoe/fcoe_sysfs.c
drivers/ssb/main.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/Kconfig
drivers/staging/android/alarm-dev.c
drivers/staging/android/ashmem.c
drivers/staging/android/binder.c
drivers/staging/android/timed_output.h
drivers/staging/bcm/Adapter.h
drivers/staging/bcm/Bcmchar.c
drivers/staging/bcm/Bcmnet.c
drivers/staging/bcm/CmHost.c
drivers/staging/bcm/CmHost.h
drivers/staging/bcm/DDRInit.c
drivers/staging/bcm/HandleControlPacket.c
drivers/staging/bcm/IPv6Protocol.c
drivers/staging/bcm/InterfaceDld.c
drivers/staging/bcm/InterfaceIdleMode.c
drivers/staging/bcm/InterfaceInit.c
drivers/staging/bcm/InterfaceIsr.c
drivers/staging/bcm/InterfaceMisc.c
drivers/staging/bcm/InterfaceRx.c
drivers/staging/bcm/InterfaceRx.h
drivers/staging/bcm/InterfaceTx.c
drivers/staging/bcm/LeakyBucket.c
drivers/staging/bcm/Misc.c
drivers/staging/bcm/PHSModule.c
drivers/staging/bcm/PHSModule.h
drivers/staging/bcm/Prototypes.h
drivers/staging/bcm/Qos.c
drivers/staging/bcm/Transmit.c
drivers/staging/bcm/Typedefs.h
drivers/staging/bcm/led_control.c
drivers/staging/bcm/nvm.c
drivers/staging/bcm/vendorspecificextn.c
drivers/staging/bcm/vendorspecificextn.h
drivers/staging/btmtk_usb/btmtk_usb.c
drivers/staging/ced1401/ced_ioc.c
drivers/staging/comedi/Kconfig
drivers/staging/comedi/comedi_buf.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/comedidev.h
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/8253.h
drivers/staging/comedi/drivers/8255.c
drivers/staging/comedi/drivers/addi-data/addi_common.c
drivers/staging/comedi/drivers/addi-data/addi_common.h
drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
drivers/staging/comedi/drivers/addi_apci_1516.c
drivers/staging/comedi/drivers/addi_apci_16xx.c
drivers/staging/comedi/drivers/addi_apci_2032.c
drivers/staging/comedi/drivers/addi_apci_2200.c
drivers/staging/comedi/drivers/addi_apci_3120.c
drivers/staging/comedi/drivers/addi_apci_3501.c
drivers/staging/comedi/drivers/addi_apci_3xxx.c
drivers/staging/comedi/drivers/adl_pci6208.c
drivers/staging/comedi/drivers/adl_pci7x3x.c
drivers/staging/comedi/drivers/adl_pci9111.c
drivers/staging/comedi/drivers/adl_pci9118.c
drivers/staging/comedi/drivers/adq12b.c
drivers/staging/comedi/drivers/adv_pci1710.c
drivers/staging/comedi/drivers/adv_pci1723.c
drivers/staging/comedi/drivers/adv_pci_dio.c
drivers/staging/comedi/drivers/aio_iiro_16.c
drivers/staging/comedi/drivers/amplc_dio200_common.c
drivers/staging/comedi/drivers/amplc_pc263.c
drivers/staging/comedi/drivers/amplc_pci224.c
drivers/staging/comedi/drivers/amplc_pci230.c
drivers/staging/comedi/drivers/amplc_pci263.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/comedi/drivers/cb_pcidas.c
drivers/staging/comedi/drivers/cb_pcidas64.c
drivers/staging/comedi/drivers/comedi_fc.h
drivers/staging/comedi/drivers/comedi_parport.c
drivers/staging/comedi/drivers/contec_pci_dio.c
drivers/staging/comedi/drivers/das08.c
drivers/staging/comedi/drivers/das08.h
drivers/staging/comedi/drivers/das16.c
drivers/staging/comedi/drivers/das16m1.c
drivers/staging/comedi/drivers/das1800.c
drivers/staging/comedi/drivers/das800.c
drivers/staging/comedi/drivers/dmm32at.c
drivers/staging/comedi/drivers/dt2801.c
drivers/staging/comedi/drivers/dt2811.c
drivers/staging/comedi/drivers/dt2817.c
drivers/staging/comedi/drivers/dt282x.c
drivers/staging/comedi/drivers/dt3000.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/dyna_pci10xx.c
drivers/staging/comedi/drivers/fl512.c
drivers/staging/comedi/drivers/icp_multi.c
drivers/staging/comedi/drivers/ii_pci20kc.c
drivers/staging/comedi/drivers/me4000.c
drivers/staging/comedi/drivers/me_daq.c
drivers/staging/comedi/drivers/multiq3.c
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_660x.c
drivers/staging/comedi/drivers/ni_670x.c
drivers/staging/comedi/drivers/ni_at_a2150.c
drivers/staging/comedi/drivers/ni_at_ao.c
drivers/staging/comedi/drivers/ni_atmio16d.c
drivers/staging/comedi/drivers/ni_daq_700.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/comedi/drivers/ni_stc.h
drivers/staging/comedi/drivers/pcl711.c
drivers/staging/comedi/drivers/pcl726.c
drivers/staging/comedi/drivers/pcl730.c
drivers/staging/comedi/drivers/pcl812.c
drivers/staging/comedi/drivers/pcl816.c
drivers/staging/comedi/drivers/pcl818.c
drivers/staging/comedi/drivers/pcmad.c
drivers/staging/comedi/drivers/pcmmio.c
drivers/staging/comedi/drivers/pcmuio.c
drivers/staging/comedi/drivers/quatech_daqp_cs.c
drivers/staging/comedi/drivers/rtd520.c
drivers/staging/comedi/drivers/rti800.c
drivers/staging/comedi/drivers/s526.c
drivers/staging/comedi/drivers/s626.c
drivers/staging/comedi/drivers/s626.h
drivers/staging/comedi/drivers/skel.c
drivers/staging/comedi/drivers/ssv_dnp.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/comedi/drivers/vmk80xx.c
drivers/staging/cptm1217/clearpad_tm1217.c
drivers/staging/crystalhd/crystalhd_hw.c
drivers/staging/crystalhd/crystalhd_lnx.c
drivers/staging/cxt1e1/comet.c
drivers/staging/cxt1e1/comet.h
drivers/staging/cxt1e1/hwprobe.c
drivers/staging/cxt1e1/linux.c
drivers/staging/cxt1e1/musycc.c
drivers/staging/cxt1e1/pmcc4_drv.c
drivers/staging/cxt1e1/sbecom_inline_linux.h
drivers/staging/cxt1e1/sbecrc.c
drivers/staging/cxt1e1/sbeid.c
drivers/staging/cxt1e1/sbeproc.c
drivers/staging/cxt1e1/sbew_ioc.h
drivers/staging/dgap/Makefile
drivers/staging/dgap/dgap_downld.h
drivers/staging/dgap/dgap_driver.c
drivers/staging/dgap/dgap_driver.h
drivers/staging/dgap/dgap_fep5.c
drivers/staging/dgap/dgap_fep5.h
drivers/staging/dgap/dgap_kcompat.h
drivers/staging/dgap/dgap_parse.c
drivers/staging/dgap/dgap_sysfs.c
drivers/staging/dgap/dgap_tty.c
drivers/staging/dgap/digi.h
drivers/staging/dgap/downld.c
drivers/staging/dgnc/dgnc_cls.c
drivers/staging/dgnc/dgnc_driver.c
drivers/staging/dgnc/dgnc_driver.h
drivers/staging/dgnc/dgnc_kcompat.h
drivers/staging/dgnc/dgnc_mgmt.c
drivers/staging/dgnc/dgnc_neo.c
drivers/staging/dgnc/dgnc_neo.h
drivers/staging/dgnc/dgnc_sysfs.c
drivers/staging/dgnc/dgnc_sysfs.h
drivers/staging/dgnc/dgnc_tty.c
drivers/staging/dgnc/dgnc_tty.h
drivers/staging/dgnc/digi.h
drivers/staging/dgrp/dgrp_sysfs.c
drivers/staging/dwc2/TODO [new file with mode: 0644]
drivers/staging/dwc2/core.c
drivers/staging/dwc2/core.h
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/pci.c
drivers/staging/dwc2/platform.c
drivers/staging/et131x/Module.symvers [new file with mode: 0644]
drivers/staging/et131x/README
drivers/staging/et131x/et131x.c
drivers/staging/ft1000/ft1000-pcmcia/boot.h
drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
drivers/staging/ft1000/ft1000-usb/ft1000_download.c
drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
drivers/staging/fwserial/fwserial.c
drivers/staging/gdm724x/gdm_lte.c
drivers/staging/gdm724x/gdm_mux.c
drivers/staging/gdm724x/gdm_tty.c
drivers/staging/gdm724x/gdm_usb.c
drivers/staging/iio/Documentation/iio_utils.h
drivers/staging/iio/TODO
drivers/staging/iio/accel/adis16220_core.c
drivers/staging/iio/accel/lis3l02dq_core.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/accel/sca3000_core.c
drivers/staging/iio/accel/sca3000_ring.c
drivers/staging/iio/adc/Kconfig
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/adc/ad7280a.c
drivers/staging/iio/adc/ad7291.c
drivers/staging/iio/adc/ad7606_core.c
drivers/staging/iio/adc/ad7606_ring.c
drivers/staging/iio/adc/ad7780.c
drivers/staging/iio/adc/ad7816.c
drivers/staging/iio/adc/ad799x.h
drivers/staging/iio/adc/ad799x_core.c
drivers/staging/iio/adc/ad799x_ring.c
drivers/staging/iio/adc/lpc32xx_adc.c
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/iio/adc/spear_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/cdc/ad7150.c
drivers/staging/iio/cdc/ad7746.c
drivers/staging/iio/frequency/ad5930.c
drivers/staging/iio/frequency/ad9832.c
drivers/staging/iio/frequency/ad9834.c
drivers/staging/iio/frequency/ad9850.c
drivers/staging/iio/frequency/ad9852.c
drivers/staging/iio/frequency/ad9910.c
drivers/staging/iio/frequency/ad9951.c
drivers/staging/iio/iio_simple_dummy.c
drivers/staging/iio/iio_simple_dummy.h
drivers/staging/iio/iio_simple_dummy_buffer.c
drivers/staging/iio/iio_simple_dummy_events.c
drivers/staging/iio/impedance-analyzer/ad5933.c
drivers/staging/iio/light/isl29018.c
drivers/staging/iio/light/tsl2583.c
drivers/staging/iio/light/tsl2x7x_core.c
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/iio/meter/ade7753.c
drivers/staging/iio/meter/ade7754.c
drivers/staging/iio/meter/ade7758_core.c
drivers/staging/iio/meter/ade7758_ring.c
drivers/staging/iio/meter/ade7759.c
drivers/staging/iio/meter/ade7854-i2c.c
drivers/staging/iio/meter/ade7854-spi.c
drivers/staging/iio/meter/ade7854.c
drivers/staging/iio/resolver/ad2s1200.c
drivers/staging/iio/resolver/ad2s1210.c
drivers/staging/iio/resolver/ad2s90.c
drivers/staging/iio/trigger/iio-trig-bfin-timer.c
drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
drivers/staging/imx-drm/Makefile
drivers/staging/imx-drm/TODO
drivers/staging/imx-drm/imx-drm-core.c
drivers/staging/imx-drm/imx-drm.h
drivers/staging/imx-drm/imx-ldb.c
drivers/staging/imx-drm/imx-tve.c
drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
drivers/staging/imx-drm/ipu-v3/ipu-common.c
drivers/staging/imx-drm/ipu-v3/ipu-dc.c
drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c
drivers/staging/imx-drm/ipu-v3/ipu-dp.c
drivers/staging/imx-drm/ipuv3-crtc.c
drivers/staging/imx-drm/ipuv3-plane.c [new file with mode: 0644]
drivers/staging/imx-drm/ipuv3-plane.h [new file with mode: 0644]
drivers/staging/keucr/usb.c
drivers/staging/line6/driver.c
drivers/staging/line6/midi.c
drivers/staging/line6/playback.c
drivers/staging/line6/toneport.c
drivers/staging/lustre/include/linux/libcfs/bitmap.h
drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
drivers/staging/lustre/include/linux/lnet/lib-lnet.h
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
drivers/staging/lustre/lnet/lnet/acceptor.c
drivers/staging/lustre/lnet/lnet/config.c
drivers/staging/lustre/lnet/lnet/lib-move.c
drivers/staging/lustre/lnet/lnet/lo.c
drivers/staging/lustre/lnet/lnet/module.c
drivers/staging/lustre/lnet/lnet/router_proc.c
drivers/staging/lustre/lnet/selftest/brw_test.c
drivers/staging/lustre/lnet/selftest/conrpc.c
drivers/staging/lustre/lnet/selftest/console.c
drivers/staging/lustre/lnet/selftest/timer.c
drivers/staging/lustre/lustre/Kconfig
drivers/staging/lustre/lustre/fid/fid_request.c
drivers/staging/lustre/lustre/fld/fld_cache.c
drivers/staging/lustre/lustre/fld/fld_request.c
drivers/staging/lustre/lustre/include/cl_object.h
drivers/staging/lustre/lustre/include/lclient.h
drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
drivers/staging/lustre/lustre/include/lu_object.h
drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
drivers/staging/lustre/lustre/include/lustre_dlm.h
drivers/staging/lustre/lustre/include/lustre_export.h
drivers/staging/lustre/lustre/include/lustre_fid.h
drivers/staging/lustre/lustre/include/lustre_lite.h
drivers/staging/lustre/lustre/include/lustre_net.h
drivers/staging/lustre/lustre/include/obd.h
drivers/staging/lustre/lustre/include/obd_support.h
drivers/staging/lustre/lustre/lclient/lcommon_cl.c
drivers/staging/lustre/lustre/ldlm/interval_tree.c
drivers/staging/lustre/lustre/ldlm/ldlm_extent.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/hash.c
drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c
drivers/staging/lustre/lustre/libcfs/prng.c
drivers/staging/lustre/lustre/libcfs/tracefile.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_close.c
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/llite/lloop.c
drivers/staging/lustre/lustre/llite/lproc_llite.c
drivers/staging/lustre/lustre/llite/rw.c
drivers/staging/lustre/lustre/llite/rw26.c
drivers/staging/lustre/lustre/llite/statahead.c
drivers/staging/lustre/lustre/llite/vvp_dev.c
drivers/staging/lustre/lustre/lov/lov_cl_internal.h
drivers/staging/lustre/lustre/lov/lov_dev.c
drivers/staging/lustre/lustre/lov/lov_internal.h
drivers/staging/lustre/lustre/lov/lov_io.c
drivers/staging/lustre/lustre/lov/lov_lock.c
drivers/staging/lustre/lustre/lov/lov_obd.c
drivers/staging/lustre/lustre/lov/lov_object.c
drivers/staging/lustre/lustre/lov/lov_pack.c
drivers/staging/lustre/lustre/lov/lov_pool.c
drivers/staging/lustre/lustre/lov/lov_request.c
drivers/staging/lustre/lustre/lvfs/fsfilt.c
drivers/staging/lustre/lustre/lvfs/lvfs_lib.c
drivers/staging/lustre/lustre/lvfs/lvfs_linux.c
drivers/staging/lustre/lustre/obdclass/cl_io.c
drivers/staging/lustre/lustre/obdclass/cl_object.c
drivers/staging/lustre/lustre/obdclass/class_obd.c
drivers/staging/lustre/lustre/obdclass/genops.c
drivers/staging/lustre/lustre/obdclass/llog_test.c
drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
drivers/staging/lustre/lustre/obdclass/lu_object.c
drivers/staging/lustre/lustre/obdclass/obd_config.c
drivers/staging/lustre/lustre/obdclass/uuid.c
drivers/staging/lustre/lustre/obdecho/echo_client.c
drivers/staging/lustre/lustre/osc/lproc_osc.c
drivers/staging/lustre/lustre/osc/osc_io.c
drivers/staging/lustre/lustre/osc/osc_lock.c
drivers/staging/lustre/lustre/osc/osc_page.c
drivers/staging/lustre/lustre/osc/osc_quota.c
drivers/staging/lustre/lustre/osc/osc_request.c
drivers/staging/lustre/lustre/ptlrpc/client.c
drivers/staging/lustre/lustre/ptlrpc/connection.c
drivers/staging/lustre/lustre/ptlrpc/import.c
drivers/staging/lustre/lustre/ptlrpc/layout.c
drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
drivers/staging/lustre/lustre/ptlrpc/service.c
drivers/staging/media/go7007/go7007-usb.c
drivers/staging/media/lirc/lirc_bt829.c
drivers/staging/media/lirc/lirc_imon.c
drivers/staging/mt29f_spinand/Kconfig [new file with mode: 0644]
drivers/staging/mt29f_spinand/Makefile [new file with mode: 0644]
drivers/staging/mt29f_spinand/TODO [new file with mode: 0644]
drivers/staging/mt29f_spinand/mt29f_spinand.c [new file with mode: 0644]
drivers/staging/mt29f_spinand/mt29f_spinand.h [new file with mode: 0644]
drivers/staging/netlogic/xlr_net.c
drivers/staging/netlogic/xlr_net.h
drivers/staging/nvec/Kconfig
drivers/staging/nvec/nvec.c
drivers/staging/octeon-usb/Makefile
drivers/staging/octeon-usb/cvmx-usb.c [deleted file]
drivers/staging/octeon-usb/cvmx-usb.h [deleted file]
drivers/staging/octeon-usb/cvmx-usbcx-defs.h [deleted file]
drivers/staging/octeon-usb/cvmx-usbnx-defs.h [deleted file]
drivers/staging/octeon-usb/octeon-hcd.c
drivers/staging/octeon-usb/octeon-hcd.h [new file with mode: 0644]
drivers/staging/octeon/ethernet-rx.c
drivers/staging/octeon/ethernet-spi.c
drivers/staging/octeon/ethernet-tx.c
drivers/staging/octeon/ethernet.c
drivers/staging/olpc_dcon/Kconfig
drivers/staging/olpc_dcon/olpc_dcon.c
drivers/staging/quickstart/quickstart.c
drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8187se/r8180_dm.c
drivers/staging/rtl8187se/r8180_rtl8225z2.c
drivers/staging/rtl8187se/r8180_wx.c
drivers/staging/rtl8187se/r8185b_init.c
drivers/staging/rtl8188eu/Makefile
drivers/staging/rtl8188eu/TODO
drivers/staging/rtl8188eu/core/rtw_ap.c
drivers/staging/rtl8188eu/core/rtw_br_ext.c
drivers/staging/rtl8188eu/core/rtw_cmd.c
drivers/staging/rtl8188eu/core/rtw_efuse.c
drivers/staging/rtl8188eu/core/rtw_ieee80211.c
drivers/staging/rtl8188eu/core/rtw_mlme.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
drivers/staging/rtl8188eu/core/rtw_p2p.c
drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
drivers/staging/rtl8188eu/core/rtw_recv.c
drivers/staging/rtl8188eu/core/rtw_security.c
drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
drivers/staging/rtl8188eu/core/rtw_wlan_util.c
drivers/staging/rtl8188eu/core/rtw_xmit.c
drivers/staging/rtl8188eu/hal/Hal8188EFWImg_CE.c [deleted file]
drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c
drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
drivers/staging/rtl8188eu/hal/usb_halinit.c
drivers/staging/rtl8188eu/hal/usb_ops_linux.c
drivers/staging/rtl8188eu/include/Hal8188EFWImg_CE.h [deleted file]
drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h
drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h
drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h
drivers/staging/rtl8188eu/include/ieee80211.h
drivers/staging/rtl8188eu/include/odm.h
drivers/staging/rtl8188eu/include/odm_HWConfig.h
drivers/staging/rtl8188eu/include/odm_debug.h
drivers/staging/rtl8188eu/include/odm_precomp.h
drivers/staging/rtl8188eu/include/rtw_cmd.h
drivers/staging/rtl8188eu/include/rtw_led.h
drivers/staging/rtl8188eu/include/rtw_mlme.h
drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h
drivers/staging/rtl8188eu/include/rtw_recv.h
drivers/staging/rtl8188eu/include/rtw_rf.h
drivers/staging/rtl8188eu/include/sta_info.h
drivers/staging/rtl8188eu/include/wifi.h
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8188eu/os_dep/os_intfs.c
drivers/staging/rtl8188eu/os_dep/osdep_service.c
drivers/staging/rtl8188eu/os_dep/recv_linux.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/rtl8192e/dot11d.c
drivers/staging/rtl8192e/dot11d.h
drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c
drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
drivers/staging/rtl8192e/rtl819x_TSProc.c
drivers/staging/rtl8192e/rtllib_rx.c
drivers/staging/rtl8192e/rtllib_softmac.c
drivers/staging/rtl8192e/rtllib_tx.c
drivers/staging/rtl8192e/rtllib_wx.c
drivers/staging/rtl8192u/dot11d.h [deleted file]
drivers/staging/rtl8192u/ieee80211/dot11d.h
drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
drivers/staging/rtl8192u/ieee80211_crypt.h [deleted file]
drivers/staging/rtl8192u/r8180_pm.c [deleted file]
drivers/staging/rtl8192u/r8180_pm.h [deleted file]
drivers/staging/rtl8192u/r8190_rtl8256.h
drivers/staging/rtl8192u/r8192U.h
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rtl8192u/r8192U_dm.c
drivers/staging/rtl8192u/r8192U_wx.c
drivers/staging/rtl8192u/r819xU_HTType.h
drivers/staging/rtl8192u/r819xU_cmdpkt.c
drivers/staging/rtl8192u/r819xU_cmdpkt.h
drivers/staging/rtl8192u/r819xU_firmware.c
drivers/staging/rtl8192u/r819xU_phy.c
drivers/staging/rtl8192u/r819xU_phy.h
drivers/staging/rtl8712/os_intfs.c
drivers/staging/rtl8712/rtl8712_cmd.c
drivers/staging/rtl8712/rtl8712_efuse.c
drivers/staging/rtl8712/rtl8712_recv.c
drivers/staging/rtl8712/rtl871x_cmd.c
drivers/staging/rtl8712/rtl871x_ioctl_linux.c
drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
drivers/staging/rtl8712/rtl871x_mlme.c
drivers/staging/rtl8712/rtl871x_mp.c
drivers/staging/rtl8712/rtl871x_security.c
drivers/staging/rtl8712/rtl871x_sta_mgt.c
drivers/staging/rtl8712/usb_intf.c
drivers/staging/rtl8712/xmit_linux.c
drivers/staging/rts5139/rts51x_scsi.c
drivers/staging/sb105x/sb_mp_register.h
drivers/staging/sb105x/sb_pci_mp.c
drivers/staging/sbe-2t3e3/cpld.c
drivers/staging/sep/sep_crypto.c
drivers/staging/sep/sep_main.c
drivers/staging/silicom/bp_mod.h
drivers/staging/silicom/bpctl_mod.c
drivers/staging/slicoss/slicoss.c
drivers/staging/sm7xxfb/sm7xxfb.c
drivers/staging/speakup/Kconfig
drivers/staging/speakup/kobjects.c
drivers/staging/speakup/main.c
drivers/staging/speakup/speakup_acntpc.c
drivers/staging/speakup/speakup_apollo.c
drivers/staging/speakup/speakup_audptr.c
drivers/staging/speakup/varhandlers.c
drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
drivers/staging/tidspbridge/rmgr/dspdrv.c
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/stub_main.c
drivers/staging/usbip/userspace/configure.ac
drivers/staging/usbip/userspace/doc/usbip.8
drivers/staging/usbip/userspace/doc/usbipd.8
drivers/staging/usbip/userspace/src/usbip_network.c
drivers/staging/usbip/userspace/src/usbip_network.h
drivers/staging/usbip/userspace/src/usbipd.c
drivers/staging/usbip/vhci_hcd.c
drivers/staging/vt6655/80211mgr.c
drivers/staging/vt6655/aes_ccmp.c
drivers/staging/vt6655/baseband.c
drivers/staging/vt6655/bssdb.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/michael.h
drivers/staging/vt6655/rf.c
drivers/staging/vt6655/tkip.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/wpactl.c
drivers/staging/vt6655/wroute.c
drivers/staging/vt6655/wroute.h
drivers/staging/vt6656/aes_ccmp.c
drivers/staging/vt6656/bssdb.c
drivers/staging/vt6656/bssdb.h
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/dpc.h
drivers/staging/vt6656/firmware.c
drivers/staging/vt6656/hostap.c
drivers/staging/vt6656/iwctl.c
drivers/staging/vt6656/key.c
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/power.c
drivers/staging/vt6656/rxtx.c
drivers/staging/vt6656/rxtx.h
drivers/staging/vt6656/usbpipe.c
drivers/staging/vt6656/wcmd.c
drivers/staging/vt6656/wcmd.h
drivers/staging/vt6656/wctl.c
drivers/staging/vt6656/wmgr.c
drivers/staging/vt6656/wmgr.h
drivers/staging/vt6656/wpactl.c
drivers/staging/winbond/core.h
drivers/staging/winbond/mds.c
drivers/staging/winbond/mto.c
drivers/staging/winbond/mto.h
drivers/staging/winbond/phy_calibration.c
drivers/staging/winbond/reg.c
drivers/staging/winbond/wb35tx.c
drivers/staging/winbond/wbusb.c
drivers/staging/wlags49_h2/hcf.h
drivers/staging/wlags49_h2/sta_h2.c
drivers/staging/wlan-ng/cfg80211.c
drivers/staging/wlan-ng/hfa384x_usb.c
drivers/staging/wlan-ng/p80211netdev.h
drivers/staging/wlan-ng/p80211wep.c
drivers/staging/xgifb/XGI_main_26.c
drivers/staging/xgifb/vb_setmode.c
drivers/staging/xgifb/vb_table.h
drivers/staging/xillybus/Kconfig
drivers/staging/xillybus/xillybus_core.c
drivers/staging/xillybus/xillybus_of.c
drivers/staging/xillybus/xillybus_pcie.c
drivers/staging/zram/zram_drv.c
drivers/staging/zsmalloc/Kconfig
drivers/tty/bfin_jtag_comm.c
drivers/tty/hvc/hvc_dcc.c
drivers/tty/hvc/hvc_iucv.c
drivers/tty/hvc/hvc_vio.c
drivers/tty/n_tty.c
drivers/tty/nozomi.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/8250/8250_em.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/Kconfig
drivers/tty/serial/amba-pl010.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/arc_uart.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/bfin_sport_uart.c
drivers/tty/serial/bfin_uart.c
drivers/tty/serial/clps711x.c
drivers/tty/serial/ifx6x60.c
drivers/tty/serial/imx.c
drivers/tty/serial/ip22zilog.c
drivers/tty/serial/max310x.c
drivers/tty/serial/mfd.c
drivers/tty/serial/mpc52xx_uart.c
drivers/tty/serial/mpsc.c
drivers/tty/serial/mrst_max3110.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/sa1100.c
drivers/tty/serial/samsung.c
drivers/tty/serial/samsung.h
drivers/tty/serial/sccnxp.c
drivers/tty/serial/serial-tegra.c
drivers/tty/serial/serial_txx9.c
drivers/tty/serial/sirfsoc_uart.c
drivers/tty/serial/sirfsoc_uart.h
drivers/tty/serial/sunsab.c
drivers/tty/serial/sunsu.c
drivers/tty/serial/sunzilog.c
drivers/tty/serial/ucc_uart.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/sysrq.c
drivers/tty/tty_port.c
drivers/tty/vt/vt.c
drivers/uio/uio.c
drivers/uio/uio_aec.c
drivers/uio/uio_cif.c
drivers/uio/uio_mf624.c
drivers/uio/uio_netx.c
drivers/uio/uio_pdrv_genirq.c
drivers/uio/uio_sercos3.c
drivers/usb/atm/usbatm.h
drivers/usb/chipidea/bits.h
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/chipidea/core.c
drivers/usb/chipidea/host.c
drivers/usb/chipidea/udc.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/file.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/core/sysfs.c
drivers/usb/core/urb.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/ep0.c
drivers/usb/early/ehci-dbgp.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/acm_ms.c
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/configfs.h [new file with mode: 0644]
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/f_mass_storage.h [new file with mode: 0644]
drivers/usb/gadget/g_ffs.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/mass_storage.c
drivers/usb/gadget/multi.c
drivers/usb/gadget/mv_u3d_core.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/pch_udc.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/storage_common.c
drivers/usb/gadget/storage_common.h [new file with mode: 0644]
drivers/usb/gadget/tcm_usb_gadget.c
drivers/usb/gadget/udc-core.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-atmel.c
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-exynos.c [new file with mode: 0644]
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-grlib.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-msm.c
drivers/usb/host/ehci-mv.c
drivers/usb/host/ehci-octeon.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-pmcmsp.c
drivers/usb/host/ehci-ppc-of.c
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-s5p.c [deleted file]
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-sead3.c
drivers/usb/host/ehci-sh.c
drivers/usb/host/ehci-sysfs.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ehci-tilegx.c
drivers/usb/host/ehci-w90x900.c
drivers/usb/host/ehci-xilinx-of.c
drivers/usb/host/ehci.h
drivers/usb/host/fotg210-hcd.c
drivers/usb/host/fusbh200-hcd.c
drivers/usb/host/hwa-hc.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-ep93xx.c [deleted file]
drivers/usb/host/ohci-exynos.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-nxp.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-omap3.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-platform.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/ohci-sm501.c
drivers/usb/host/ohci-spear.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/pci-quirks.h
drivers/usb/host/sl811-hcd.c
drivers/usb/host/uhci-debug.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/uhci-pci.c
drivers/usb/host/uhci-platform.c
drivers/usb/host/whci/hcd.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/usbtest.c
drivers/usb/musb/Kconfig
drivers/usb/musb/am35x.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/da8xx.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_am335x.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_cppi41.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_virthub.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/musb/ux500.c
drivers/usb/phy/Kconfig
drivers/usb/phy/Makefile
drivers/usb/phy/phy-am335x-control.c
drivers/usb/phy/phy-am335x.c
drivers/usb/phy/phy-fsl-usb.c
drivers/usb/phy/phy-fsl-usb.h
drivers/usb/phy/phy-fsm-usb.c
drivers/usb/phy/phy-fsm-usb.h
drivers/usb/phy/phy-generic.c
drivers/usb/phy/phy-generic.h
drivers/usb/phy/phy-omap-control.c
drivers/usb/phy/phy-omap-usb2.c [deleted file]
drivers/usb/phy/phy-omap-usb3.c
drivers/usb/phy/phy-rcar-gen2-usb.c [new file with mode: 0644]
drivers/usb/phy/phy-samsung-usb2.c
drivers/usb/phy/phy-samsung-usb3.c
drivers/usb/phy/phy-tegra-usb.c
drivers/usb/phy/phy-twl4030-usb.c [deleted file]
drivers/usb/phy/phy-twl6030-usb.c
drivers/usb/phy/phy-ulpi-viewport.c
drivers/usb/phy/phy.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/generic.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/wusbcore/cbaf.c
drivers/usb/wusbcore/devconnect.c
drivers/usb/wusbcore/wa-hc.c
drivers/usb/wusbcore/wa-hc.h
drivers/usb/wusbcore/wa-rpipe.c
drivers/usb/wusbcore/wa-xfer.c
drivers/uwb/lc-dev.c
drivers/uwb/umc-bus.c
drivers/video/backlight/atmel-pwm-bl.c
drivers/video/console/sticore.c
drivers/video/cyber2000fb.c
drivers/video/exynos/Kconfig
drivers/video/exynos/exynos_dp_core.c
drivers/video/exynos/exynos_dp_core.h
drivers/video/exynos/exynos_dp_reg.c
drivers/video/exynos/exynos_mipi_dsi.c
drivers/video/sticore.h
drivers/video/stifb.c
drivers/virtio/virtio.c
drivers/w1/masters/ds1wm.c
drivers/w1/masters/omap_hdq.c
drivers/w1/masters/w1-gpio.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe.h
drivers/xen/xenbus/xenbus_probe_backend.c
drivers/xen/xenbus/xenbus_probe_frontend.c
fs/9p/cache.c
fs/afs/cell.c
fs/afs/inode.c
fs/afs/vlocation.c
fs/afs/volume.c
fs/cachefiles/interface.c
fs/ceph/cache.c
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/fscache.c
fs/cifs/ioctl.c
fs/cifs/misc.c
fs/cifs/smb1ops.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smb2proto.h
fs/cifs/smb2transport.c
fs/cifs/transport.c
fs/dcache.c
fs/fscache/cookie.c
fs/fscache/fsdef.c
fs/fscache/netfs.c
fs/fscache/object.c
fs/fscache/page.c
fs/gfs2/aops.c
fs/gfs2/bmap.c
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/main.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/quota.h
fs/gfs2/rgrp.c
fs/gfs2/rgrp.h
fs/gfs2/super.c
fs/gfs2/sys.c
fs/gfs2/util.c
fs/gfs2/util.h
fs/gfs2/xattr.c
fs/nfs/Kconfig
fs/nfs/callback.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/fscache.c
fs/nfs/fscache.h
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4namespace.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4super.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
fs/nfs/unlink.c
fs/sysfs/Makefile
fs/sysfs/bin.c [deleted file]
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/group.c
fs/sysfs/inode.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/dt-bindings/mfd/dbx500-prcmu.h [new file with mode: 0644]
include/dt-bindings/pinctrl/am43xx.h [new file with mode: 0644]
include/dt-bindings/pinctrl/dra.h [new file with mode: 0644]
include/linux/atmel_serial.h
include/linux/clk/mxs.h
include/linux/clk/sunxi.h [deleted file]
include/linux/debugfs.h
include/linux/device.h
include/linux/extcon.h
include/linux/extcon/extcon-adc-jack.h
include/linux/extcon/extcon-gpio.h
include/linux/fs.h
include/linux/fscache-cache.h
include/linux/fscache.h
include/linux/hid-sensor-hub.h
include/linux/hyperv.h
include/linux/i2c/twl.h
include/linux/ide.h
include/linux/iio/buffer.h
include/linux/iio/common/st_sensors.h
include/linux/iio/consumer.h
include/linux/iio/events.h
include/linux/iio/iio.h
include/linux/iio/sysfs.h
include/linux/iio/types.h
include/linux/interrupt.h
include/linux/ipc_namespace.h
include/linux/irqchip/bcm2835.h [deleted file]
include/linux/kobj_completion.h [new file with mode: 0644]
include/linux/kobject.h
include/linux/lockref.h
include/linux/mfd/dbx500-prcmu.h
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
include/linux/mfd/ti_am335x_tscadc.h
include/linux/netdevice.h
include/linux/netpoll.h
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/perf_event.h
include/linux/phy/phy.h [new file with mode: 0644]
include/linux/platform_data/clk-nomadik.h [deleted file]
include/linux/platform_data/clk-ux500.h
include/linux/platform_data/dma-s3c24xx.h [new file with mode: 0644]
include/linux/platform_data/gpio-davinci.h [new file with mode: 0644]
include/linux/platform_data/mipi-csis.h
include/linux/platform_data/pinctrl-single.h [new file with mode: 0644]
include/linux/platform_data/usb-ehci-s5p.h [deleted file]
include/linux/platform_data/usb-ohci-exynos.h [deleted file]
include/linux/platform_data/usb-rcar-gen2-phy.h [new file with mode: 0644]
include/linux/platform_device.h
include/linux/printk.h
include/linux/rculist.h
include/linux/rcupdate.h
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/serial_core.h
include/linux/sunrpc/clnt.h
include/linux/sunrpc/sched.h
include/linux/sunrpc/xprt.h
include/linux/sysfs.h
include/linux/sysrq.h
include/linux/tegra-powergate.h
include/linux/tty.h
include/linux/uprobes.h
include/linux/usb.h
include/linux/usb/hcd.h
include/linux/usb/intel_mid_otg.h [deleted file]
include/linux/usb/musb.h
include/linux/usb/omap_control_usb.h
include/linux/usb/serial.h
include/linux/usb/usb_phy_gen_xceiv.h
include/linux/usb/wusb-wa.h
include/net/ip6_fib.h
include/trace/events/rcu.h
include/uapi/linux/Kbuild
include/uapi/linux/mic_common.h [new file with mode: 0644]
include/uapi/linux/mic_ioctl.h [new file with mode: 0644]
include/uapi/linux/nfs_mount.h
include/uapi/linux/perf_event.h
include/video/exynos_dp.h [deleted file]
include/video/exynos_mipi_dsim.h
init/Kconfig
ipc/ipc_sysctl.c
kernel/Makefile
kernel/events/core.c
kernel/events/internal.h
kernel/events/ring_buffer.c
kernel/events/uprobes.c
kernel/fork.c
kernel/irq/manage.c
kernel/lockdep.c
kernel/rcu.h [deleted file]
kernel/rcu/Makefile [new file with mode: 0644]
kernel/rcu/rcu.h [new file with mode: 0644]
kernel/rcu/srcu.c [new file with mode: 0644]
kernel/rcu/tiny.c [new file with mode: 0644]
kernel/rcu/tiny_plugin.h [new file with mode: 0644]
kernel/rcu/torture.c [new file with mode: 0644]
kernel/rcu/tree.c [new file with mode: 0644]
kernel/rcu/tree.h [new file with mode: 0644]
kernel/rcu/tree_plugin.h [new file with mode: 0644]
kernel/rcu/tree_trace.c [new file with mode: 0644]
kernel/rcu/update.c [new file with mode: 0644]
kernel/rcupdate.c [deleted file]
kernel/rcutiny.c [deleted file]
kernel/rcutiny_plugin.h [deleted file]
kernel/rcutorture.c [deleted file]
kernel/rcutree.c [deleted file]
kernel/rcutree.h [deleted file]
kernel/rcutree_plugin.h [deleted file]
kernel/rcutree_trace.c [deleted file]
kernel/softirq.c
kernel/srcu.c [deleted file]
kernel/sysctl.c
kernel/trace/trace_event_perf.c
lib/Kconfig.debug
lib/kobject.c
lib/lockref.c
lib/scatterlist.c
mm/memcontrol.c
net/bridge/br_device.c
net/bridge/br_input.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/bridge/netfilter/ebt_ulog.c
net/core/flow_dissector.c
net/core/net-sysfs.c
net/core/netpoll.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/tcp_input.c
net/ipv4/tcp_offload.c
net/ipv4/xfrm4_policy.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/route.c
net/ipv6/xfrm6_policy.c
net/netfilter/x_tables.c
net/netfilter/xt_NFQUEUE.c
net/openvswitch/dp_notify.c
net/openvswitch/vport-netdev.c
net/openvswitch/vport-netdev.h
net/sched/sch_fq.c
net/sctp/ipv6.c
net/sctp/sm_sideeffect.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/clnt.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c
net/x25/Kconfig
net/xfrm/xfrm_ipcomp.c
scripts/kallsyms.c
scripts/link-vmlinux.sh
scripts/package/Makefile
sound/core/pcm.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/wm_hubs.c
sound/soc/samsung/Kconfig
sound/soc/samsung/s3c-i2s-v2.c
sound/soc/soc-dapm.c
tools/hv/hv_kvp_daemon.c
tools/hv/hv_vss_daemon.c
tools/lib/traceevent/Makefile
tools/lib/traceevent/event-parse.c
tools/lib/traceevent/event-parse.h
tools/perf/.gitignore
tools/perf/Documentation/Makefile
tools/perf/Documentation/perf-buildid-cache.txt
tools/perf/Documentation/perf-kvm.txt
tools/perf/Documentation/perf-lock.txt
tools/perf/Documentation/perf-record.txt
tools/perf/Documentation/perf-report.txt
tools/perf/Documentation/perf-stat.txt
tools/perf/Documentation/perf-timechart.txt
tools/perf/Documentation/perf-top.txt
tools/perf/Documentation/perf-trace.txt
tools/perf/Makefile
tools/perf/Makefile.perf [new file with mode: 0644]
tools/perf/arch/x86/include/perf_regs.h
tools/perf/arch/x86/util/unwind.c
tools/perf/bash_completion
tools/perf/bench/mem-memcpy-arch.h
tools/perf/bench/mem-memcpy.c
tools/perf/bench/mem-memset-arch.h
tools/perf/bench/mem-memset.c
tools/perf/bench/numa.c
tools/perf/bench/sched-pipe.c
tools/perf/builtin-annotate.c
tools/perf/builtin-bench.c
tools/perf/builtin-buildid-cache.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-diff.c
tools/perf/builtin-evlist.c
tools/perf/builtin-inject.c
tools/perf/builtin-kmem.c
tools/perf/builtin-kvm.c
tools/perf/builtin-list.c
tools/perf/builtin-lock.c
tools/perf/builtin-mem.c
tools/perf/builtin-probe.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.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/config/Makefile
tools/perf/config/feature-checks/Makefile [new file with mode: 0644]
tools/perf/config/feature-checks/test-all.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-backtrace.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-bionic.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-cplus-demangle.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-dwarf.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-fortify-source.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-glibc.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-gtk2-infobar.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-gtk2.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-hello.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libaudit.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libbfd.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libelf-getphdrnum.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libelf-mmap.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libelf.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libnuma.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libperl.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libpython-version.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libpython.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libslang.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-libunwind.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-on-exit.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-stackprotector-all.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-stackprotector.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-timerfd.c [new file with mode: 0644]
tools/perf/config/feature-checks/test-volatile-register-var.c [new file with mode: 0644]
tools/perf/config/feature-tests.mak [deleted file]
tools/perf/config/utilities.mak
tools/perf/perf.c
tools/perf/perf.h
tools/perf/scripts/python/Perf-Trace-Util/Context.c
tools/perf/tests/attr/README
tools/perf/tests/attr/test-record-graph-default
tools/perf/tests/attr/test-record-graph-dwarf
tools/perf/tests/attr/test-record-graph-fp
tools/perf/tests/code-reading.c
tools/perf/tests/dso-data.c
tools/perf/tests/hists_link.c
tools/perf/tests/parse-events.c
tools/perf/tests/perf-record.c
tools/perf/tests/rdpmc.c
tools/perf/tests/sample-parsing.c
tools/perf/tests/task-exit.c
tools/perf/ui/browser.h
tools/perf/ui/browsers/annotate.c
tools/perf/ui/browsers/hists.c
tools/perf/ui/browsers/map.c
tools/perf/ui/browsers/map.h
tools/perf/ui/browsers/scripts.c
tools/perf/ui/gtk/annotate.c
tools/perf/ui/gtk/browser.c
tools/perf/ui/gtk/gtk.h
tools/perf/ui/gtk/progress.c
tools/perf/ui/gtk/setup.c
tools/perf/ui/gtk/util.c
tools/perf/ui/hist.c
tools/perf/ui/progress.c
tools/perf/ui/progress.h
tools/perf/ui/setup.c
tools/perf/ui/stdio/hist.c
tools/perf/ui/tui/progress.c
tools/perf/ui/tui/setup.c
tools/perf/ui/tui/tui.h [new file with mode: 0644]
tools/perf/ui/ui.h
tools/perf/util/PERF-VERSION-GEN
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/build-id.c
tools/perf/util/build-id.h
tools/perf/util/cache.h
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/color.c
tools/perf/util/color.h
tools/perf/util/comm.c [new file with mode: 0644]
tools/perf/util/comm.h [new file with mode: 0644]
tools/perf/util/cpumap.c
tools/perf/util/data.c [new file with mode: 0644]
tools/perf/util/data.h [new file with mode: 0644]
tools/perf/util/dso.c
tools/perf/util/dso.h
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/fs.c [new file with mode: 0644]
tools/perf/util/fs.h [new file with mode: 0644]
tools/perf/util/generate-cmdlist.sh
tools/perf/util/header.c
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/include/dwarf-regs.h
tools/perf/util/include/linux/compiler.h
tools/perf/util/include/linux/magic.h
tools/perf/util/intlist.c
tools/perf/util/intlist.h
tools/perf/util/machine.c
tools/perf/util/machine.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/parse-events.c
tools/perf/util/parse-events.l
tools/perf/util/parse-options.c
tools/perf/util/parse-options.h
tools/perf/util/path.c
tools/perf/util/perf_regs.h
tools/perf/util/pmu.c
tools/perf/util/pmu.h
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/pstack.h
tools/perf/util/python-ext-sources
tools/perf/util/python.c
tools/perf/util/rblist.c
tools/perf/util/rblist.h
tools/perf/util/record.c
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/srcline.c [new file with mode: 0644]
tools/perf/util/strfilter.c
tools/perf/util/strfilter.h
tools/perf/util/symbol-elf.c
tools/perf/util/symbol-minimal.c
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/sysfs.c [deleted file]
tools/perf/util/sysfs.h [deleted file]
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/perf/util/top.h
tools/perf/util/trace-event-parse.c
tools/perf/util/trace-event.h
tools/perf/util/unwind.h
tools/perf/util/util.c
tools/perf/util/util.h
tools/scripts/Makefile.include

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-mass-storage b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
new file mode 100644 (file)
index 0000000..ad72a37
--- /dev/null
@@ -0,0 +1,31 @@
+What:          /config/usb-gadget/gadget/functions/mass_storage.name
+Date:          Oct 2013
+KenelVersion:  3.13
+Description:
+               The attributes:
+
+               stall           - Set to permit function to halt bulk endpoints.
+                               Disabled on some USB devices known not to work
+                               correctly. You should set it to true.
+               num_buffers     - Number of pipeline buffers. Valid numbers
+                               are 2..4. Available only if
+                               CONFIG_USB_GADGET_DEBUG_FILES is set.
+
+What:          /config/usb-gadget/gadget/functions/mass_storage.name/lun.name
+Date:          Oct 2013
+KenelVersion:  3.13
+Description:
+               The attributes:
+
+               file            - The path to the backing file for the LUN.
+                               Required if LUN is not marked as removable.
+               ro              - Flag specifying access to the LUN shall be
+                               read-only. This is implied if CD-ROM emulation
+                               is enabled as well as when it was impossible
+                               to open "filename" in R/W mode.
+               removable       - Flag specifying that LUN shall be indicated as
+                               being removable.
+               cdrom           - Flag specifying that LUN shall be reported as
+                               being a CD-ROM.
+               nofua           - Flag specifying that FUA flag
+                               in SCSI WRITE(10,12)
index 39c8de0e53d00924630c789e27c9e6c10af5e960..b20e829d350f7fa207760fd4c43c6f9b7db7cb60 100644 (file)
@@ -79,7 +79,7 @@ Description:
                correspond to externally available input one of the named
                versions may be used. The number must always be specified and
                unique to allow association with event codes. Units after
-               application of scale and offset are microvolts.
+               application of scale and offset are millivolts.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw
 KernelVersion: 2.6.35
@@ -90,7 +90,7 @@ Description:
                physically equivalent inputs when non differential readings are
                separately available. In differential only parts, then all that
                is required is a consistent labeling.  Units after application
-               of scale and offset are microvolts.
+               of scale and offset are millivolts.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw
 KernelVersion: 3.2
@@ -537,6 +537,62 @@ Description:
                value is in raw device units or in processed units (as _raw
                and _input do on sysfs direct channel read attributes).
 
+What:          /sys/.../events/in_accel_x_thresh_rising_hysteresis
+What:          /sys/.../events/in_accel_x_thresh_falling_hysteresis
+What:          /sys/.../events/in_accel_x_thresh_either_hysteresis
+What:          /sys/.../events/in_accel_y_thresh_rising_hysteresis
+What:          /sys/.../events/in_accel_y_thresh_falling_hysteresis
+What:          /sys/.../events/in_accel_y_thresh_either_hysteresis
+What:          /sys/.../events/in_accel_z_thresh_rising_hysteresis
+What:          /sys/.../events/in_accel_z_thresh_falling_hysteresis
+What:          /sys/.../events/in_accel_z_thresh_either_hysteresis
+What:          /sys/.../events/in_anglvel_x_thresh_rising_hysteresis
+What:          /sys/.../events/in_anglvel_x_thresh_falling_hysteresis
+What:          /sys/.../events/in_anglvel_x_thresh_either_hysteresis
+What:          /sys/.../events/in_anglvel_y_thresh_rising_hysteresis
+What:          /sys/.../events/in_anglvel_y_thresh_falling_hysteresis
+What:          /sys/.../events/in_anglvel_y_thresh_either_hysteresis
+What:          /sys/.../events/in_anglvel_z_thresh_rising_hysteresis
+What:          /sys/.../events/in_anglvel_z_thresh_falling_hysteresis
+What:          /sys/.../events/in_anglvel_z_thresh_either_hysteresis
+What:          /sys/.../events/in_magn_x_thresh_rising_hysteresis
+What:          /sys/.../events/in_magn_x_thresh_falling_hysteresis
+What:          /sys/.../events/in_magn_x_thresh_either_hysteresis
+What:          /sys/.../events/in_magn_y_thresh_rising_hysteresis
+What:          /sys/.../events/in_magn_y_thresh_falling_hysteresis
+What:          /sys/.../events/in_magn_y_thresh_either_hysteresis
+What:          /sys/.../events/in_magn_z_thresh_rising_hysteresis
+What:          /sys/.../events/in_magn_z_thresh_falling_hysteresis
+What:          /sys/.../events/in_magn_z_thresh_either_hysteresis
+What:          /sys/.../events/in_voltageY_thresh_rising_hysteresis
+What:          /sys/.../events/in_voltageY_thresh_falling_hysteresis
+What:          /sys/.../events/in_voltageY_thresh_either_hysteresis
+What:          /sys/.../events/in_tempY_thresh_rising_hysteresis
+What:          /sys/.../events/in_tempY_thresh_falling_hysteresis
+What:          /sys/.../events/in_tempY_thresh_either_hysteresis
+What:          /sys/.../events/in_illuminance0_thresh_falling_hysteresis
+what:          /sys/.../events/in_illuminance0_thresh_rising_hysteresis
+what:          /sys/.../events/in_illuminance0_thresh_either_hysteresis
+what:          /sys/.../events/in_proximity0_thresh_falling_hysteresis
+what:          /sys/.../events/in_proximity0_thresh_rising_hysteresis
+what:          /sys/.../events/in_proximity0_thresh_either_hysteresis
+KernelVersion: 3.13
+Contact:       linux-iio@vger.kernel.org
+Description:
+               Specifies the hysteresis of threshold that the device is comparing
+               against for the events enabled by
+               <type>Y[_name]_thresh[_(rising|falling)]_hysteresis.
+               If separate attributes exist for the two directions, but
+               direction is not specified for this attribute, then a single
+               hysteresis value applies to both directions.
+               For falling events the hysteresis is added to the _value attribute for
+               this event to get the upper threshold for when the event goes back to
+               normal, for rising events the hysteresis is subtracted from the _value
+               attribute. E.g. if in_voltage0_raw_thresh_rising_value is set to 1200
+               and in_voltage0_raw_thresh_rising_hysteresis is set to 50. The event
+               will get activated once in_voltage0_raw goes above 1200 and will become
+               deactived again once the value falls below 1150.
+
 What:          /sys/.../events/in_accel_x_raw_roc_rising_value
 What:          /sys/.../events/in_accel_x_raw_roc_falling_value
 What:          /sys/.../events/in_accel_y_raw_roc_rising_value
@@ -811,3 +867,14 @@ Description:
                Writing '1' stores the current device configuration into
                on-chip EEPROM. After power-up or chip reset the device will
                automatically load the saved configuration.
+
+What:          /sys/.../iio:deviceX/in_intensity_red_integration_time
+What:          /sys/.../iio:deviceX/in_intensity_green_integration_time
+What:          /sys/.../iio:deviceX/in_intensity_blue_integration_time
+What:          /sys/.../iio:deviceX/in_intensity_clear_integration_time
+What:          /sys/.../iio:deviceX/in_illuminance_integration_time
+KernelVersion: 3.12
+Contact:       linux-iio@vger.kernel.org
+Description:
+               This attribute is used to get/set the integration time in
+               seconds.
diff --git a/Documentation/ABI/testing/sysfs-class-mic.txt b/Documentation/ABI/testing/sysfs-class-mic.txt
new file mode 100644 (file)
index 0000000..13f48af
--- /dev/null
@@ -0,0 +1,157 @@
+What:          /sys/class/mic/
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               The mic class directory belongs to Intel MIC devices and
+               provides information per MIC device. An Intel MIC device is a
+               PCIe form factor add-in Coprocessor card based on the Intel Many
+               Integrated Core (MIC) architecture that runs a Linux OS.
+
+What:          /sys/class/mic/mic(x)
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               The directories /sys/class/mic/mic0, /sys/class/mic/mic1 etc.,
+               represent MIC devices (0,1,..etc). Each directory has
+               information specific to that MIC device.
+
+What:          /sys/class/mic/mic(x)/family
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               Provides information about the Coprocessor family for an Intel
+               MIC device. For example - "x100"
+
+What:          /sys/class/mic/mic(x)/stepping
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               Provides information about the silicon stepping for an Intel
+               MIC device. For example - "A0" or "B0"
+
+What:          /sys/class/mic/mic(x)/state
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               When read, this entry provides the current state of an Intel
+               MIC device in the context of the card OS. Possible values that
+               will be read are:
+               "offline" - The MIC device is ready to boot the card OS. On
+               reading this entry after an OSPM resume, a "boot" has to be
+               written to this entry if the card was previously shutdown
+               during OSPM suspend.
+               "online" - The MIC device has initiated booting a card OS.
+               "shutting_down" - The card OS is shutting down.
+               "reset_failed" - The MIC device has failed to reset.
+               "suspending" - The MIC device is currently being prepared for
+               suspend. On reading this entry, a "suspend" has to be written
+               to the state sysfs entry to ensure the card is shutdown during
+               OSPM suspend.
+               "suspended" - The MIC device has been suspended.
+
+               When written, this sysfs entry triggers different state change
+               operations depending upon the current state of the card OS.
+               Acceptable values are:
+               "boot" - Boot the card OS image specified by the combination
+                        of firmware, ramdisk, cmdline and bootmode
+                       sysfs entries.
+               "reset" - Initiates device reset.
+               "shutdown" - Initiates card OS shutdown.
+               "suspend" - Initiates card OS shutdown and also marks the card
+               as suspended.
+
+What:          /sys/class/mic/mic(x)/shutdown_status
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               An Intel MIC device runs a Linux OS during its operation. This
+               OS can shutdown because of various reasons. When read, this
+               entry provides the status on why the card OS was shutdown.
+               Possible values are:
+               "nop" -  shutdown status is not applicable, when the card OS is
+                       "online"
+               "crashed" - Shutdown because of a HW or SW crash.
+               "halted" - Shutdown because of a halt command.
+               "poweroff" - Shutdown because of a poweroff command.
+               "restart" - Shutdown because of a restart command.
+
+What:          /sys/class/mic/mic(x)/cmdline
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               An Intel MIC device runs a Linux OS during its operation. Before
+               booting this card OS, it is possible to pass kernel command line
+               options to configure various features in it, similar to
+               self-bootable machines. When read, this entry provides
+               information about the current kernel command line options set to
+               boot the card OS. This entry can be written to change the
+               existing kernel command line options. Typically, the user would
+               want to read the current command line options, append new ones
+               or modify existing ones and then write the whole kernel command
+               line back to this entry.
+
+What:          /sys/class/mic/mic(x)/firmware
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               When read, this sysfs entry provides the path name under
+               /lib/firmware/ where the firmware image to be booted on the
+               card can be found. The entry can be written to change the
+               firmware image location under /lib/firmware/.
+
+What:          /sys/class/mic/mic(x)/ramdisk
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               When read, this sysfs entry provides the path name under
+               /lib/firmware/ where the ramdisk image to be used during card
+               OS boot can be found. The entry can be written to change
+               the ramdisk image location under /lib/firmware/.
+
+What:          /sys/class/mic/mic(x)/bootmode
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               When read, this sysfs entry provides the current bootmode for
+               the card. This sysfs entry can be written with the following
+               valid strings:
+               a) linux - Boot a Linux image.
+               b) elf - Boot an elf image for flash updates.
+
+What:          /sys/class/mic/mic(x)/log_buf_addr
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               An Intel MIC device runs a Linux OS during its operation. For
+               debugging purpose and early kernel boot messages, the user can
+               access the card OS log buffer via debugfs. When read, this entry
+               provides the kernel virtual address of the buffer where the card
+               OS log buffer can be read. This entry is written by the host
+               configuration daemon to set the log buffer address. The correct
+               log buffer address to be written can be found in the System.map
+               file of the card OS.
+
+What:          /sys/class/mic/mic(x)/log_buf_len
+Date:          October 2013
+KernelVersion: 3.13
+Contact:       Sudeep Dutt <sudeep.dutt@intel.com>
+Description:
+               An Intel MIC device runs a Linux OS during its operation. For
+               debugging purpose and early kernel boot messages, the user can
+               access the card OS log buffer via debugfs. When read, this entry
+               provides the kernel virtual address where the card OS log buffer
+               length can be read. This entry is written by host configuration
+               daemon to set the log buffer length address. The correct log
+               buffer length address to be written can be found in the
+               System.map file of the card OS.
diff --git a/Documentation/ABI/testing/sysfs-driver-sunxi-sid b/Documentation/ABI/testing/sysfs-driver-sunxi-sid
new file mode 100644 (file)
index 0000000..ffb9536
--- /dev/null
@@ -0,0 +1,22 @@
+What:          /sys/devices/*/<our-device>/eeprom
+Date:          August 2013
+Contact:       Oliver Schinagl <oliver@schinagl.nl>
+Description:   read-only access to the SID (Security-ID) on current
+               A-series SoC's from Allwinner. Currently supports A10, A10s, A13
+               and A20 CPU's. The earlier A1x series of SoCs exports 16 bytes,
+               whereas the newer A20 SoC exposes 512 bytes split into sections.
+               Besides the 16 bytes of SID, there's also an SJTAG area,
+               HDMI-HDCP key and some custom keys. Below a quick overview, for
+               details see the user manual:
+               0x000  128 bit root-key (sun[457]i)
+               0x010  128 bit boot-key (sun7i)
+               0x020   64 bit security-jtag-key (sun7i)
+               0x028   16 bit key configuration (sun7i)
+               0x02b   16 bit custom-vendor-key (sun7i)
+               0x02c  320 bit low general key (sun7i)
+               0x040   32 bit read-control access (sun7i)
+               0x064  224 bit low general key (sun7i)
+               0x080 2304 bit HDCP-key (sun7i)
+               0x1a0  768 bit high general key (sun7i)
+Users:         any user space application which wants to read the SID on
+               Allwinner's A-series of CPU's.
index fe397f90a34f50153f5936cfa13635ed7bc85b7b..6c9d9d37c83a30e24cce3ed25abf484e1bbd18f1 100644 (file)
@@ -87,7 +87,10 @@ X!Iinclude/linux/kobject.h
 !Ekernel/printk/printk.c
 !Ekernel/panic.c
 !Ekernel/sys.c
-!Ekernel/rcupdate.c
+!Ekernel/rcu/srcu.c
+!Ekernel/rcu/tree.c
+!Ekernel/rcu/tree_plugin.h
+!Ekernel/rcu/update.c
      </sect1>
 
      <sect1><title>Device Resource Management</title>
index 25b58efd955dd2bebf2d716aea851fe283f792c1..4f676838da06a61aed3e26243185a0a7fa2f0311 100644 (file)
@@ -91,7 +91,6 @@
      <title>The Filesystem for Exporting Kernel Objects</title>
 !Efs/sysfs/file.c
 !Efs/sysfs/symlink.c
-!Efs/sysfs/bin.c
   </chapter>
 
   <chapter id="debugfs">
index d16d21b7a3b7aec2884c2183005c337b3d075002..46347f6033539e4b6a207cb5640c335158b6dd3c 100644 (file)
@@ -87,7 +87,7 @@
   <chapter id="rationale">
     <title>Rationale</title>
        <para>
-       The original implementation of interrupt handling in Linux is using
+       The original implementation of interrupt handling in Linux uses
        the __do_IRQ() super-handler, which is able to deal with every
        type of interrupt logic.
        </para>
        </itemizedlist>
        </para>
        <para>
-       This split implementation of highlevel IRQ handlers allows us to
+       This split implementation of high-level IRQ handlers allows us to
        optimize the flow of the interrupt handling for each specific
-       interrupt type. This reduces complexity in that particular codepath
+       interrupt type. This reduces complexity in that particular code path
        and allows the optimized handling of a given type.
        </para>
        <para>
        The original general IRQ implementation used hw_interrupt_type
        structures and their ->ack(), ->end() [etc.] callbacks to
        differentiate the flow control in the super-handler. This leads to
-       a mix of flow logic and lowlevel hardware logic, and it also leads
-       to unnecessary code duplication: for example in i386, there is a
-       ioapic_level_irq and a ioapic_edge_irq irq-type which share many
-       of the lowlevel details but have different flow handling.
+       a mix of flow logic and low-level hardware logic, and it also leads
+       to unnecessary code duplication: for example in i386, there is an
+       ioapic_level_irq and an ioapic_edge_irq IRQ-type which share many
+       of the low-level details but have different flow handling.
        </para>
        <para>
        A more natural abstraction is the clean separation of the
        <para>
        Analysing a couple of architecture's IRQ subsystem implementations
        reveals that most of them can use a generic set of 'irq flow'
-       methods and only need to add the chip level specific code.
+       methods and only need to add the chip-level specific code.
        The separation is also valuable for (sub)architectures
-       which need specific quirks in the irq flow itself but not in the
-       chip-details - and thus provides a more transparent IRQ subsystem
+       which need specific quirks in the IRQ flow itself but not in the
+       chip details - and thus provides a more transparent IRQ subsystem
        design.
        </para>
        <para>
-       Each interrupt descriptor is assigned its own highlevel flow
+       Each interrupt descriptor is assigned its own high-level flow
        handler, which is normally one of the generic
-       implementations. (This highlevel flow handler implementation also
+       implementations. (This high-level flow handler implementation also
        makes it simple to provide demultiplexing handlers which can be
        found in embedded platforms on various architectures.)
        </para>
        <para>
        The separation makes the generic interrupt handling layer more
        flexible and extensible. For example, an (sub)architecture can
-       use a generic irq-flow implementation for 'level type' interrupts
+       use a generic IRQ-flow implementation for 'level type' interrupts
        and add a (sub)architecture specific 'edge type' implementation.
        </para>
        <para>
     <para>
        There are three main levels of abstraction in the interrupt code:
        <orderedlist>
-         <listitem><para>Highlevel driver API</para></listitem>
-         <listitem><para>Highlevel IRQ flow handlers</para></listitem>
-         <listitem><para>Chiplevel hardware encapsulation</para></listitem>
+         <listitem><para>High-level driver API</para></listitem>
+         <listitem><para>High-level IRQ flow handlers</para></listitem>
+         <listitem><para>Chip-level hardware encapsulation</para></listitem>
        </orderedlist>
     </para>
     <sect1 id="Interrupt_control_flow">
        which are assigned to this interrupt.
        </para>
        <para>
-       Whenever an interrupt triggers, the lowlevel arch code calls into
-       the generic interrupt code by calling desc->handle_irq().
-       This highlevel IRQ handling function only uses desc->irq_data.chip
+       Whenever an interrupt triggers, the low-level architecture code calls
+       into the generic interrupt code by calling desc->handle_irq().
+       This high-level IRQ handling function only uses desc->irq_data.chip
        primitives referenced by the assigned chip descriptor structure.
        </para>
     </sect1>
     <sect1 id="Highlevel_Driver_API">
-       <title>Highlevel Driver API</title>
+       <title>High-level Driver API</title>
        <para>
-         The highlevel Driver API consists of following functions:
+         The high-level Driver API consists of following functions:
          <itemizedlist>
          <listitem><para>request_irq()</para></listitem>
          <listitem><para>free_irq()</para></listitem>
        </para>
     </sect1>
     <sect1 id="Highlevel_IRQ_flow_handlers">
-       <title>Highlevel IRQ flow handlers</title>
+       <title>High-level IRQ flow handlers</title>
        <para>
          The generic layer provides a set of pre-defined irq-flow methods:
          <itemizedlist>
          <listitem><para>handle_edge_eoi_irq</para></listitem>
          <listitem><para>handle_bad_irq</para></listitem>
          </itemizedlist>
-         The interrupt flow handlers (either predefined or architecture
+         The interrupt flow handlers (either pre-defined or architecture
          specific) are assigned to specific interrupts by the architecture
          either during bootup or during device initialization.
        </para>
@@ -297,7 +297,7 @@ desc->irq_data.chip->irq_unmask();
                <para>
                handle_fasteoi_irq provides a generic implementation
                for interrupts, which only need an EOI at the end of
-               the handler
+               the handler.
                </para>
                <para>
                The following control flow is implemented (simplified excerpt):
@@ -394,7 +394,7 @@ if (desc->irq_data.chip->irq_eoi)
        The generic functions are intended for 'clean' architectures and chips,
        which have no platform-specific IRQ handling quirks. If an architecture
        needs to implement quirks on the 'flow' level then it can do so by
-       overriding the highlevel irq-flow handler.
+       overriding the high-level irq-flow handler.
        </para>
        </sect2>
        <sect2 id="Delayed_interrupt_disable">
@@ -419,9 +419,9 @@ if (desc->irq_data.chip->irq_eoi)
        </sect2>
     </sect1>
     <sect1 id="Chiplevel_hardware_encapsulation">
-       <title>Chiplevel hardware encapsulation</title>
+       <title>Chip-level hardware encapsulation</title>
        <para>
-       The chip level hardware descriptor structure irq_chip
+       The chip-level hardware descriptor structure irq_chip
        contains all the direct chip relevant functions, which
        can be utilized by the irq flow implementations.
          <itemizedlist>
@@ -429,14 +429,14 @@ if (desc->irq_data.chip->irq_eoi)
          <listitem><para>irq_mask_ack() - Optional, recommended for performance</para></listitem>
          <listitem><para>irq_mask()</para></listitem>
          <listitem><para>irq_unmask()</para></listitem>
-         <listitem><para>irq_eoi() - Optional, required for eoi flow handlers</para></listitem>
+         <listitem><para>irq_eoi() - Optional, required for EOI flow handlers</para></listitem>
          <listitem><para>irq_retrigger() - Optional</para></listitem>
          <listitem><para>irq_set_type() - Optional</para></listitem>
          <listitem><para>irq_set_wake() - Optional</para></listitem>
          </itemizedlist>
        These primitives are strictly intended to mean what they say: ack means
        ACK, masking means masking of an IRQ line, etc. It is up to the flow
-       handler(s) to use these basic units of lowlevel functionality.
+       handler(s) to use these basic units of low-level functionality.
        </para>
     </sect1>
   </chapter>
@@ -445,7 +445,7 @@ if (desc->irq_data.chip->irq_eoi)
      <title>__do_IRQ entry point</title>
      <para>
        The original implementation __do_IRQ() was an alternative entry
-       point for all types of interrupts. It not longer exists.
+       point for all types of interrupts. It no longer exists.
      </para>
      <para>
        This handler turned out to be not suitable for all
@@ -468,11 +468,11 @@ if (desc->irq_data.chip->irq_eoi)
   <chapter id="genericchip">
      <title>Generic interrupt chip</title>
      <para>
-       To avoid copies of identical implementations of irq chips the
+       To avoid copies of identical implementations of IRQ chips the
        core provides a configurable generic interrupt chip
        implementation. Developers should check carefuly whether the
        generic chip fits their needs before implementing the same
-       functionality slightly different themself.
+       functionality slightly differently themselves.
      </para>
 !Ekernel/irq/generic-chip.c
   </chapter>
index 7703ec73a9bbb225a45258c4cde11c8cc9dd236f..91266193b8f49e840709db77d75f8357428b2806 100644 (file)
@@ -202,8 +202,8 @@ over a rather long period of time, but improvements are always welcome!
        updater uses call_rcu_sched() or synchronize_sched(), then
        the corresponding readers must disable preemption, possibly
        by calling rcu_read_lock_sched() and rcu_read_unlock_sched().
-       If the updater uses synchronize_srcu() or call_srcu(),
-       the the corresponding readers must use srcu_read_lock() and
+       If the updater uses synchronize_srcu() or call_srcu(), then
+       the corresponding readers must use srcu_read_lock() and
        srcu_read_unlock(), and with the same srcu_struct.  The rules for
        the expedited primitives are the same as for their non-expedited
        counterparts.  Mixing things up will result in confusion and
index 8e9359de1d28b2e845d25425be72451b3f6be4f7..6f3a0057548ec0b3c13d02fe5d82ea7b0bf2ece4 100644 (file)
@@ -12,12 +12,12 @@ CONFIG_RCU_CPU_STALL_TIMEOUT
        This kernel configuration parameter defines the period of time
        that RCU will wait from the beginning of a grace period until it
        issues an RCU CPU stall warning.  This time period is normally
-       sixty seconds.
+       21 seconds.
 
        This configuration parameter may be changed at runtime via the
        /sys/module/rcutree/parameters/rcu_cpu_stall_timeout, however
        this parameter is checked only at the beginning of a cycle.
-       So if you are 30 seconds into a 70-second stall, setting this
+       So if you are 10 seconds into a 40-second stall, setting this
        sysfs parameter to (say) five will shorten the timeout for the
        -next- stall, or the following warning for the current stall
        (assuming the stall lasts long enough).  It will not affect the
@@ -32,7 +32,7 @@ CONFIG_RCU_CPU_STALL_VERBOSE
        also dump the stacks of any tasks that are blocking the current
        RCU-preempt grace period.
 
-RCU_CPU_STALL_INFO
+CONFIG_RCU_CPU_STALL_INFO
 
        This kernel configuration parameter causes the stall warning to
        print out additional per-CPU diagnostic information, including
@@ -43,7 +43,8 @@ RCU_STALL_DELAY_DELTA
        Although the lockdep facility is extremely useful, it does add
        some overhead.  Therefore, under CONFIG_PROVE_RCU, the
        RCU_STALL_DELAY_DELTA macro allows five extra seconds before
-       giving an RCU CPU stall warning message.
+       giving an RCU CPU stall warning message.  (This is a cpp
+       macro, not a kernel configuration parameter.)
 
 RCU_STALL_RAT_DELAY
 
@@ -52,7 +53,8 @@ RCU_STALL_RAT_DELAY
        However, if the offending CPU does not detect its own stall in
        the number of jiffies specified by RCU_STALL_RAT_DELAY, then
        some other CPU will complain.  This delay is normally set to
-       two jiffies.
+       two jiffies.  (This is a cpp macro, not a kernel configuration
+       parameter.)
 
 When a CPU detects that it is stalling, it will print a message similar
 to the following:
@@ -86,7 +88,12 @@ printing, there will be a spurious stall-warning message:
 
 INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
 
-This is rare, but does happen from time to time in real life.
+This is rare, but does happen from time to time in real life.  It is also
+possible for a zero-jiffy stall to be flagged in this case, depending
+on how the stall warning and the grace-period initialization happen to
+interact.  Please note that it is not possible to entirely eliminate this
+sort of false positive without resorting to things like stop_machine(),
+which is overkill for this sort of problem.
 
 If the CONFIG_RCU_CPU_STALL_INFO kernel configuration parameter is set,
 more information is printed with the stall-warning message, for example:
@@ -216,4 +223,5 @@ that portion of the stack which remains the same from trace to trace.
 If you can reliably trigger the stall, ftrace can be quite helpful.
 
 RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE
-and with RCU's event tracing.
+and with RCU's event tracing.  For information on RCU's event tracing,
+see include/trace/events/rcu.h.
index 8f08a86e03b7a36d9ece83f1e2e2957ecfe49d8d..da0151db996419f0b685f35b0f461d38ffaec924 100644 (file)
@@ -88,6 +88,7 @@ EBU Armada family
         MV78230
         MV78260
         MV78460
+    NOTE: not to be confused with the non-SMP 78xx0 SoCs
 
   Product Brief: http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
   No public datasheet available.
index e3f93fb9224e9495b3683264d334619b259869ce..7945238453edb58444f09938bc251150a2e4a0aa 100644 (file)
@@ -10,6 +10,10 @@ SunXi family
   Linux kernel mach directory: arch/arm/mach-sunxi
 
   Flavors:
+    * ARM926 based SoCs
+      - Allwinner F20 (sun3i)
+        + Not Supported
+
     * ARM Cortex-A8 based SoCs
       - Allwinner A10 (sun4i)
         + Datasheet
@@ -25,4 +29,24 @@ SunXi family
         + Datasheet
          http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
         + User Manual
-         http://dl.linux-sunxi.org/A13/A13%20User%20Manual%20-%20v1.2%20%282013-08-08%29.pdf
+          http://dl.linux-sunxi.org/A13/A13%20User%20Manual%20-%20v1.2%20%282013-01-08%29.pdf
+
+    * Dual ARM Cortex-A7 based SoCs
+      - Allwinner A20 (sun7i)
+        + User Manual
+          http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf
+
+      - Allwinner A23
+        + Not Supported
+
+    * Quad ARM Cortex-A7 based SoCs
+      - Allwinner A31 (sun6i)
+        + Datasheet
+          http://dl.linux-sunxi.org/A31/A31%20Datasheet%20-%20v1.00%20(2012-12-24).pdf
+
+      - Allwinner A31s (sun6i)
+        + Not Supported
+
+    * Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs
+      - Allwinner A80
+        + Not Supported
\ No newline at end of file
index 98df4a03807e7c4ab02c7a27f4c46272f3bd12df..a9691cc48fe3943bb42fc40797c524cd0843690e 100644 (file)
@@ -115,9 +115,10 @@ Before jumping into the kernel, the following conditions must be met:
   External caches (if present) must be configured and disabled.
 
 - Architected timers
-  CNTFRQ must be programmed with the timer frequency.
-  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
-  set where available.
+  CNTFRQ must be programmed with the timer frequency and CNTVOFF must
+  be programmed with a consistent value on all CPUs.  If entering the
+  kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0) set where
+  available.
 
 - Coherency
   All CPUs to be booted by the kernel must be part of the same coherency
@@ -130,30 +131,46 @@ Before jumping into the kernel, the following conditions must be met:
   the kernel image will be entered must be initialised by software at a
   higher exception level to prevent execution in an UNKNOWN state.
 
+The requirements described above for CPU mode, caches, MMUs, architected
+timers, coherency and system registers apply to all CPUs.  All CPUs must
+enter the kernel in the same exception level.
+
 The boot loader is expected to enter the kernel on each CPU in the
 following manner:
 
 - The primary CPU must jump directly to the first instruction of the
   kernel image.  The device tree blob passed by this CPU must contain
-  for each CPU node:
-
-    1. An 'enable-method' property. Currently, the only supported value
-       for this field is the string "spin-table".
-
-    2. A 'cpu-release-addr' property identifying a 64-bit,
-       zero-initialised memory location.
+  an 'enable-method' property for each cpu node.  The supported
+  enable-methods are described below.
 
   It is expected that the bootloader will generate these device tree
   properties and insert them into the blob prior to kernel entry.
 
-- Any secondary CPUs must spin outside of the kernel in a reserved area
-  of memory (communicated to the kernel by a /memreserve/ region in the
+- CPUs with a "spin-table" enable-method must have a 'cpu-release-addr'
+  property in their cpu node.  This property identifies a
+  naturally-aligned 64-bit zero-initalised memory location.
+
+  These CPUs should spin outside of the kernel in a reserved area of
+  memory (communicated to the kernel by a /memreserve/ region in the
   device tree) polling their cpu-release-addr location, which must be
   contained in the reserved region.  A wfe instruction may be inserted
   to reduce the overhead of the busy-loop and a sev will be issued by
   the primary CPU.  When a read of the location pointed to by the
-  cpu-release-addr returns a non-zero value, the CPU must jump directly
-  to this value.
+  cpu-release-addr returns a non-zero value, the CPU must jump to this
+  value.  The value will be written as a single 64-bit little-endian
+  value, so CPUs must convert the read value to their native endianness
+  before jumping to it.
+
+- CPUs with a "psci" enable method should remain outside of
+  the kernel (i.e. outside of the regions of memory described to the
+  kernel in the memory node, or in a reserved area of memory described
+  to the kernel by a /memreserve/ region in the device tree).  The
+  kernel will issue CPU_ON calls as described in ARM document number ARM
+  DEN 0022A ("Power State Coordination Interface System Software on ARM
+  processors") to bring CPUs into the kernel.
+
+  The device tree should contain a 'psci' node, as described in
+  Documentation/devicetree/bindings/arm/psci.txt.
 
 - Secondary CPU general-purpose register settings
   x0 = 0 (reserved for future use)
index 78a377124ef04ec1f25fa4f47a5d065f449fe221..5e054bfe4dde8e30e178c073d19c8c2b520a7e0f 100644 (file)
@@ -21,7 +21,7 @@ The swapper_pgd_dir address is written to TTBR1 and never written to
 TTBR0.
 
 
-AArch64 Linux memory layout:
+AArch64 Linux memory layout with 4KB pages:
 
 Start                  End                     Size            Use
 -----------------------------------------------------------------------
@@ -39,13 +39,38 @@ ffffffbffbc00000    ffffffbffbdfffff           2MB          earlyprintk device
 
 ffffffbffbe00000       ffffffbffbe0ffff          64KB          PCI I/O space
 
-ffffffbbffff0000       ffffffbcffffffff          ~2MB          [guard]
+ffffffbffbe10000       ffffffbcffffffff          ~2MB          [guard]
 
 ffffffbffc000000       ffffffbfffffffff          64MB          modules
 
 ffffffc000000000       ffffffffffffffff         256GB          kernel logical memory map
 
 
+AArch64 Linux memory layout with 64KB pages:
+
+Start                  End                     Size            Use
+-----------------------------------------------------------------------
+0000000000000000       000003ffffffffff           4TB          user
+
+fffffc0000000000       fffffdfbfffeffff          ~2TB          vmalloc
+
+fffffdfbffff0000       fffffdfbffffffff          64KB          [guard page]
+
+fffffdfc00000000       fffffdfdffffffff           8GB          vmemmap
+
+fffffdfe00000000       fffffdfffbbfffff          ~8GB          [guard, future vmmemap]
+
+fffffdfffbc00000       fffffdfffbdfffff           2MB          earlyprintk device
+
+fffffdfffbe00000       fffffdfffbe0ffff          64KB          PCI I/O space
+
+fffffdfffbe10000       fffffdfffbffffff          ~2MB          [guard]
+
+fffffdfffc000000       fffffdffffffffff          64MB          modules
+
+fffffe0000000000       ffffffffffffffff           2TB          kernel logical memory map
+
+
 Translation table lookup with 4KB pages:
 
 +--------+--------+--------+--------+--------+--------+--------+--------+
index db5858e32d3f86f88c9776e80b98eddb27435131..5fac246a9530168fc42b378d7b37da9e694dbb91 100644 (file)
@@ -9,9 +9,53 @@ Required properties (in root node):
 
 FPGA type interrupt controllers, see the versatile-fpga-irq binding doc.
 
-In the root node the Integrator/CP must have a /cpcon node pointing
-to the CP control registers, and the Integrator/AP must have a
-/syscon node pointing to the Integrator/AP system controller.
+Required nodes:
+
+- core-module: the root node to the Integrator platforms must have
+  a core-module with regs and the compatible string
+  "arm,core-module-integrator"
+
+  Required properties for the core module:
+  - regs: the location and size of the core module registers, one
+    range of 0x200 bytes.
+
+- syscon: the root node of the Integrator platforms must have a
+  system controller node pointong to the control registers,
+  with the compatible string
+  "arm,integrator-ap-syscon"
+  "arm,integrator-cp-syscon"
+  respectively.
+
+  Required properties for the system controller:
+  - regs: the location and size of the system controller registers,
+    one range of 0x100 bytes.
+
+  Required properties for the AP system controller:
+  - interrupts: the AP syscon node must include the logical module
+    interrupts, stated in order of module instance <module 0>,
+    <module 1>, <module 2> ... for the CP system controller this
+    is not required not of any use.
+
+/dts-v1/;
+/include/ "integrator.dtsi"
+
+/ {
+       model = "ARM Integrator/AP";
+       compatible = "arm,integrator-ap";
+
+       core-module@10000000 {
+               compatible = "arm,core-module-integrator";
+               reg = <0x10000000 0x200>;
+       };
+
+       syscon {
+               compatible = "arm,integrator-ap-syscon";
+               reg = <0x11000000 0x100>;
+               interrupt-parent = <&pic>;
+               /* These are the logic module IRQs */
+               interrupts = <9>, <10>, <11>, <12>;
+       };
+};
 
 
 ARM Versatile Application and Platform Baseboards
index 61df564c0d238613e55b3057192528db54151e8b..d74091a8a3bfd243490d83faedd452ec9a2c426c 100644 (file)
@@ -4,6 +4,8 @@ Marvell Armada 370 and Armada XP Interrupt Controller
 Required properties:
 - compatible: Should be "marvell,mpic"
 - interrupt-controller: Identifies the node as an interrupt controller.
+- msi-controller: Identifies the node as an PCI Message Signaled
+  Interrupt controller.
 - #interrupt-cells: The number of cells to define the interrupts. Should be 1.
   The cell is the IRQ number
 
@@ -24,6 +26,7 @@ Example:
               #address-cells = <1>;
               #size-cells = <1>;
               interrupt-controller;
+              msi-controller;
               reg = <0xd0020a00 0x1d0>,
                     <0xd0021070 0x58>;
         };
index 723c205cb10d840e13a75be509ff0a06c37721bc..d1061469f63d9efec6a7265892bdbd6d9459d021 100644 (file)
@@ -7,7 +7,6 @@ Required properties:
   - interrupts: Should contain the IRQ line for the ADC
   - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
     device
-  - atmel,adc-num-channels: Number of channels available in the ADC
   - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
     defined in the datasheet
   - atmel,adc-vref: Reference voltage in millivolts for the conversions
@@ -24,6 +23,13 @@ Optional properties:
                       resolution will be used.
   - atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
   - atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
+  - atmel,adc-ts-wires: Number of touch screen wires. Should be 4 or 5. If this
+                        value is set, then adc driver will enable touch screen
+                        support.
+    NOTE: when adc touch screen enabled, the adc hardware trigger will be
+          disabled. Since touch screen will occupied the trigger register.
+  - atmel,adc-ts-pressure-threshold: a pressure threshold for touchscreen. It
+                                     make touch detect more precision.
  
 Optional trigger Nodes:
   - Required properties:
index 92d36e2aa87791c75af70f23da1da3169c94f96c..f28d82bbbc56b3f3dff7716ede2f200f315d8e70 100644 (file)
@@ -36,14 +36,18 @@ specific to ARM.
 
        - reg
                Usage: required
-               Value type: <prop-encoded-array>
+               Value type: Integer cells. A register entry, expressed as a pair
+                           of cells, containing base and size.
                Definition: A standard property. Specifies base physical
                            address of CCI control registers common to all
                            interfaces.
 
        - ranges:
                Usage: required
-               Value type: <prop-encoded-array>
+               Value type: Integer cells. An array of range entries, expressed
+                           as a tuple of cells, containing child address,
+                           parent address and the size of the region in the
+                           child address space.
                Definition: A standard property. Follow rules in the ePAPR for
                            hierarchical bus addressing. CCI interfaces
                            addresses refer to the parent node addressing
@@ -74,11 +78,49 @@ specific to ARM.
 
                - reg:
                        Usage: required
-                       Value type: <prop-encoded-array>
+                       Value type: Integer cells. A register entry, expressed
+                                   as a pair of cells, containing base and
+                                   size.
                        Definition: the base address and size of the
                                    corresponding interface programming
                                    registers.
 
+       - CCI PMU node
+
+               Parent node must be CCI interconnect node.
+
+               A CCI pmu node must contain the following properties:
+
+               - compatible
+                       Usage: required
+                       Value type: <string>
+                       Definition: must be "arm,cci-400-pmu"
+
+               - reg:
+                       Usage: required
+                       Value type: Integer cells. A register entry, expressed
+                                   as a pair of cells, containing base and
+                                   size.
+                       Definition: the base address and size of the
+                                   corresponding interface programming
+                                   registers.
+
+               - interrupts:
+                       Usage: required
+                       Value type: Integer cells. Array of interrupt specifier
+                                   entries, as defined in
+                                   ../interrupt-controller/interrupts.txt.
+                       Definition: list of counter overflow interrupts, one per
+                                   counter. The interrupts must be specified
+                                   starting with the cycle counter overflow
+                                   interrupt, followed by counter0 overflow
+                                   interrupt, counter1 overflow interrupt,...
+                                   ,counterN overflow interrupt.
+
+                                   The CCI PMU has an interrupt signal for each
+                                   counter. The number of interrupts must be
+                                   equal to the number of counters.
+
 * CCI interconnect bus masters
 
        Description: masters in the device tree connected to a CCI port
@@ -144,7 +186,7 @@ Example:
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <0x0 0x2c090000 0 0x1000>;
-               ranges = <0x0 0x0 0x2c090000 0x6000>;
+               ranges = <0x0 0x0 0x2c090000 0x10000>;
 
                cci_control0: slave-if@1000 {
                        compatible = "arm,cci-400-ctrl-if";
@@ -163,6 +205,16 @@ Example:
                        interface-type = "ace";
                        reg = <0x5000 0x1000>;
                };
+
+               pmu@9000 {
+                        compatible = "arm,cci-400-pmu";
+                        reg = <0x9000 0x5000>;
+                        interrupts = <0 101 4>,
+                                     <0 102 4>,
+                                     <0 103 4>,
+                                     <0 104 4>,
+                                     <0 105 4>;
+               };
        };
 
 This CCI node corresponds to a CCI component whose control registers sits
index 91b7049affa1ea5f5e0da13b52db79212c94ca52..808c1543b0f87f374c5d93517d8389a3b3479be9 100644 (file)
@@ -21,7 +21,8 @@ Required properties:
 Optional properties:
 - ti,no_idle_on_suspend: When present, it prevents the PM to idle the module
   during suspend.
-
+- ti,no-reset-on-init: When present, the module should not be reset at init
+- ti,no-idle-on-init: When present, the module should not be idled at init
 
 Example:
 
index 266716b2343723525278d34db2f1c4c05ae2826b..dd527216c5fbddfce790fe9bf4a2342f56e025f1 100644 (file)
@@ -18,6 +18,15 @@ Required properties:
 Optional properties:
 
 - interrupts : Interrupt source for parent controllers if the VIC is nested.
+- valid-mask : A one cell big bit mask of valid interrupt sources. Each bit
+  represents single interrupt source, starting from source 0 at LSb and ending
+  at source 31 at MSb. A bit that is set means that the source is wired and
+  clear means otherwise. If unspecified, defaults to all valid.
+- valid-wakeup-mask : A one cell big bit mask of interrupt sources that can be
+  configured as wake up source for the system. Order of bits is the same as for
+  valid-mask property. A set bit means that this interrupt source can be
+  configured as a wake up source for the system. If unspecied, defaults to all
+  interrupt sources configurable as wake up sources.
 
 Example:
 
@@ -26,4 +35,7 @@ Example:
                interrupt-controller;
                #interrupt-cells = <1>;
                reg = <0x60000 0x1000>;
+
+               valid-mask = <0xffffff7f>;
+               valid-wakeup-mask = <0x0000ff7f>;
        };
index 5a90a724b52069c793b65c8d20899cc304818abd..6aab72bf67ea96280796eda3251e4a9e634f0a92 100644 (file)
@@ -215,6 +215,11 @@ clocks and IDs.
        cko2                    200
        cko                     201
        vdoa                    202
+       pll4_audio_div          203
+       lvds1_sel               204
+       lvds2_sel               205
+       lvds1_gate              206
+       lvds2_gate              207
 
 Examples:
 
diff --git a/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
new file mode 100644 (file)
index 0000000..c62391f
--- /dev/null
@@ -0,0 +1,19 @@
+* Core Divider Clock bindings for Marvell MVEBU SoCs
+
+The following is a list of provided IDs and clock names on Armada 370/XP:
+ 0 = nand (NAND clock)
+
+Required properties:
+- compatible : must be "marvell,armada-370-corediv-clock"
+- reg : must be the register address of Core Divider control register
+- #clock-cells : from common clock binding; shall be set to 1
+- clocks : must be set to the parent's phandle
+
+Example:
+
+corediv_clk: corediv-clocks@18740 {
+       compatible = "marvell,armada-370-corediv-clock";
+       reg = <0x18740 0xc>;
+       #clock-cells = <1>;
+       clocks = <&pll>;
+};
index cffc93d97f54800cb91d47cf50d666abe16e8758..fc2910fa7e45fdbbe41a0ccdd947e736ca2e0e75 100644 (file)
@@ -1,10 +1,10 @@
-* Gated Clock bindings for Marvell Orion SoCs
+* Gated Clock bindings for Marvell EBU SoCs
 
-Marvell Dove and Kirkwood allow some peripheral clocks to be gated to save
-some power. The clock consumer should specify the desired clock by having
-the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
-the corresponding clock gating control bit in HW to ease manual clock lookup
-in datasheet.
+Marvell Armada 370/XP, Dove and Kirkwood allow some peripheral clocks to be
+gated to save some power. The clock consumer should specify the desired clock
+by having the clock ID in its "clocks" phandle cell. The clock ID is directly
+mapped to the corresponding clock gating control bit in HW to ease manual clock
+lookup in datasheet.
 
 The following is a list of provided IDs for Armada 370:
 ID     Clock   Peripheral
@@ -94,6 +94,8 @@ ID    Clock   Peripheral
 
 Required properties:
 - compatible : shall be one of the following:
+       "marvell,armada-370-gating-clock" - for Armada 370 SoC clock gating
+       "marvell,armada-xp-gating-clock" - for Armada XP SoC clock gating
        "marvell,dove-gating-clock" - for Dove SoC clock gating
        "marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating
 - reg : shall be the register address of the Clock Gating Control register
index 00a5c26454eb773f4be1496b54d676f09bfcc0f1..91a748fed13d0c540084781ee8cd68491d4f5bfd 100644 (file)
@@ -45,8 +45,8 @@ Additionally, "allwinner,*-gates-clk" clocks require:
 
 Clock consumers should specify the desired clocks they use with a
 "clocks" phandle cell. Consumers that are using a gated clock should
-provide an additional ID in their clock property. The values of this
-ID are documented in sunxi/<soc>-gates.txt.
+provide an additional ID in their clock property. This ID is the
+offset of the bit controlling this particular gate in the register.
 
 For example:
 
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt
deleted file mode 100644 (file)
index 6a03475..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-Gate clock outputs
-------------------
-
-  * AXI gates ("allwinner,sun4i-axi-gates-clk")
-
-    DRAM                                       0
-
-  * AHB gates ("allwinner,sun4i-ahb-gates-clk")
-
-    USB0                                       0
-    EHCI0                                      1
-    OHCI0                                      2*
-    EHCI1                                      3
-    OHCI1                                      4*
-    SS                                         5
-    DMA                                                6
-    BIST                                       7
-    MMC0                                       8
-    MMC1                                       9
-    MMC2                                       10
-    MMC3                                       11
-    MS                                         12**
-    NAND                                       13
-    SDRAM                                      14
-
-    ACE                                                16
-    EMAC                                       17
-    TS                                         18
-
-    SPI0                                       20
-    SPI1                                       21
-    SPI2                                       22
-    SPI3                                       23
-    PATA                                       24
-    SATA                                       25**
-    GPS                                                26*
-
-    VE                                         32
-    TVD                                                33
-    TVE0                                       34
-    TVE1                                       35
-    LCD0                                       36
-    LCD1                                       37
-
-    CSI0                                       40
-    CSI1                                       41
-
-    HDMI                                       43
-    DE_BE0                                     44
-    DE_BE1                                     45
-    DE_FE1                                     46
-    DE_FE1                                     47
-
-    MP                                         50
-
-    MALI400                                    52
-
-  * APB0 gates ("allwinner,sun4i-apb0-gates-clk")
-
-    CODEC                                      0
-    SPDIF                                      1*
-    AC97                                       2
-    IIS                                                3
-
-    PIO                                                5
-    IR0                                                6
-    IR1                                                7
-
-    KEYPAD                                     10
-
-  * APB1 gates ("allwinner,sun4i-apb1-gates-clk")
-
-    I2C0                                       0
-    I2C1                                       1
-    I2C2                                       2
-
-    CAN                                                4
-    SCR                                                5
-    PS20                                       6
-    PS21                                       7
-
-    UART0                                      16
-    UART1                                      17
-    UART2                                      18
-    UART3                                      19
-    UART4                                      20
-    UART5                                      21
-    UART6                                      22
-    UART7                                      23
-
-Notation:
- [*]:  The datasheet didn't mention these, but they are present on AW code
- [**]: The datasheet had this marked as "NC" but they are used on AW code
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun5i-a10s-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun5i-a10s-gates.txt
deleted file mode 100644 (file)
index d24279f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-Gate clock outputs
-------------------
-
-  * AXI gates ("allwinner,sun4i-axi-gates-clk")
-
-    DRAM                                       0
-
-  * AHB gates ("allwinner,sun5i-a10s-ahb-gates-clk")
-
-    USB0                                       0
-    EHCI0                                      1
-    OHCI0                                      2
-
-    SS                                         5
-    DMA                                                6
-    BIST                                       7
-    MMC0                                       8
-    MMC1                                       9
-    MMC2                                       10
-
-    NAND                                       13
-    SDRAM                                      14
-
-    EMAC                                       17
-    TS                                         18
-
-    SPI0                                       20
-    SPI1                                       21
-    SPI2                                       22
-
-    GPS                                                26
-
-    HSTIMER                                    28
-
-    VE                                         32
-
-    TVE                                                34
-
-    LCD                                                36
-
-    CSI                                                40
-
-    HDMI                                       43
-    DE_BE                                      44
-
-    DE_FE                                      46
-
-    IEP                                                51
-    MALI400                                    52
-
-  * APB0 gates ("allwinner,sun5i-a10s-apb0-gates-clk")
-
-    CODEC                                      0
-
-    IIS                                                3
-
-    PIO                                                5
-    IR                                         6
-
-    KEYPAD                                     10
-
-  * APB1 gates ("allwinner,sun5i-a10s-apb1-gates-clk")
-
-    I2C0                                       0
-    I2C1                                       1
-    I2C2                                       2
-
-    UART0                                      16
-    UART1                                      17
-    UART2                                      18
-    UART3                                      19
-
-Notation:
- [*]:  The datasheet didn't mention these, but they are present on AW code
- [**]: The datasheet had this marked as "NC" but they are used on AW code
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt
deleted file mode 100644 (file)
index 006b6df..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-Gate clock outputs
-------------------
-
-  * AXI gates ("allwinner,sun4i-axi-gates-clk")
-
-    DRAM                                       0
-
-  * AHB gates ("allwinner,sun5i-a13-ahb-gates-clk")
-
-    USBOTG                                     0
-    EHCI                                       1
-    OHCI                                       2
-
-    SS                                         5
-    DMA                                                6
-    BIST                                       7
-    MMC0                                       8
-    MMC1                                       9
-    MMC2                                       10
-
-    NAND                                       13
-    SDRAM                                      14
-
-    SPI0                                       20
-    SPI1                                       21
-    SPI2                                       22
-
-    STIMER                                     28
-
-    VE                                         32
-
-    LCD                                                36
-
-    CSI                                                40
-
-    DE_BE                                      44
-
-    DE_FE                                      46
-
-    IEP                                                51
-    MALI400                                    52
-
-  * APB0 gates ("allwinner,sun5i-a13-apb0-gates-clk")
-
-    CODEC                                      0
-
-    PIO                                                5
-    IR                                         6
-
-  * APB1 gates ("allwinner,sun5i-a13-apb1-gates-clk")
-
-    I2C0                                       0
-    I2C1                                       1
-    I2C2                                       2
-
-    UART1                                      17
-
-    UART3                                      19
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun6i-a31-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun6i-a31-gates.txt
deleted file mode 100644 (file)
index fe44932..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-Gate clock outputs
-------------------
-
-  * AHB1 gates ("allwinner,sun6i-a31-ahb1-gates-clk")
-
-    MIPI DSI                                   1
-
-    SS                                         5
-    DMA                                                6
-
-    MMC0                                       8
-    MMC1                                       9
-    MMC2                                       10
-    MMC3                                       11
-
-    NAND1                                      12
-    NAND0                                      13
-    SDRAM                                      14
-
-    GMAC                                       17
-    TS                                         18
-    HSTIMER                                    19
-    SPI0                                       20
-    SPI1                                       21
-    SPI2                                       22
-    SPI3                                       23
-    USB_OTG                                    24
-
-    EHCI0                                      26
-    EHCI1                                      27
-
-    OHCI0                                      29
-    OHCI1                                      30
-    OHCI2                                      31
-    VE                                         32
-
-    LCD0                                       36
-    LCD1                                       37
-
-    CSI                                                40
-
-    HDMI                                       43
-    DE_BE0                                     44
-    DE_BE1                                     45
-    DE_FE1                                     46
-    DE_FE1                                     47
-
-    MP                                         50
-
-    GPU                                                52
-
-    DEU0                                       55
-    DEU1                                       56
-    DRC0                                       57
-    DRC1                                       58
-
-  * APB1 gates ("allwinner,sun6i-a31-apb1-gates-clk")
-
-    CODEC                                      0
-
-    DIGITAL MIC                                        4
-    PIO                                                5
-
-    DAUDIO0                                    12
-    DAUDIO1                                    13
-
-  * APB2 gates ("allwinner,sun6i-a31-apb2-gates-clk")
-
-    I2C0                                       0
-    I2C1                                       1
-    I2C2                                       2
-    I2C3                                       3
-
-    UART0                                      16
-    UART1                                      17
-    UART2                                      18
-    UART3                                      19
-    UART4                                      20
-    UART5                                      21
-
-Notation:
- [*]:  The datasheet didn't mention these, but they are present on AW code
- [**]: The datasheet had this marked as "NC" but they are used on AW code
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun7i-a20-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun7i-a20-gates.txt
deleted file mode 100644 (file)
index 357f4fd..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-Gate clock outputs
-------------------
-
-  * AXI gates ("allwinner,sun4i-axi-gates-clk")
-
-    DRAM                                       0
-
-  * AHB gates ("allwinner,sun7i-a20-ahb-gates-clk")
-
-    USB0                                       0
-    EHCI0                                      1
-    OHCI0                                      2
-    EHCI1                                      3
-    OHCI1                                      4
-    SS                                         5
-    DMA                                                6
-    BIST                                       7
-    MMC0                                       8
-    MMC1                                       9
-    MMC2                                       10
-    MMC3                                       11
-    MS                                         12
-    NAND                                       13
-    SDRAM                                      14
-
-    ACE                                                16
-    EMAC                                       17
-    TS                                         18
-
-    SPI0                                       20
-    SPI1                                       21
-    SPI2                                       22
-    SPI3                                       23
-
-    SATA                                       25
-
-    HSTIMER                                    28
-
-    VE                                         32
-    TVD                                                33
-    TVE0                                       34
-    TVE1                                       35
-    LCD0                                       36
-    LCD1                                       37
-
-    CSI0                                       40
-    CSI1                                       41
-
-    HDMI1                                      42
-    HDMI0                                      43
-    DE_BE0                                     44
-    DE_BE1                                     45
-    DE_FE1                                     46
-    DE_FE1                                     47
-
-    GMAC                                       49
-    MP                                         50
-
-    MALI400                                    52
-
-  * APB0 gates ("allwinner,sun7i-a20-apb0-gates-clk")
-
-    CODEC                                      0
-    SPDIF                                      1
-    AC97                                       2
-    IIS0                                       3
-    IIS1                                       4
-    PIO                                                5
-    IR0                                                6
-    IR1                                                7
-    IIS2                                       8
-
-    KEYPAD                                     10
-
-  * APB1 gates ("allwinner,sun7i-a20-apb1-gates-clk")
-
-    I2C0                                       0
-    I2C1                                       1
-    I2C2                                       2
-    I2C3                                       3
-    CAN                                                4
-    SCR                                                5
-    PS20                                       6
-    PS21                                       7
-
-    I2C4                                       15
-    UART0                                      16
-    UART1                                      17
-    UART2                                      18
-    UART3                                      19
-    UART4                                      20
-    UART5                                      21
-    UART6                                      22
-    UART7                                      23
-
-Notation:
- [*]:  The datasheet didn't mention these, but they are present on AW code
- [**]: The datasheet had this marked as "NC" but they are used on AW code
diff --git a/Documentation/devicetree/bindings/crypto/omap-aes.txt b/Documentation/devicetree/bindings/crypto/omap-aes.txt
new file mode 100644 (file)
index 0000000..fd97176
--- /dev/null
@@ -0,0 +1,31 @@
+OMAP SoC AES crypto Module
+
+Required properties:
+
+- compatible : Should contain entries for this and backward compatible
+  AES versions:
+  - "ti,omap2-aes" for OMAP2.
+  - "ti,omap3-aes" for OMAP3.
+  - "ti,omap4-aes" for OMAP4 and AM33XX.
+  Note that the OMAP2 and 3 versions are compatible (OMAP3 supports
+  more algorithms) but they are incompatible with OMAP4.
+- ti,hwmods: Name of the hwmod associated with the AES module
+- reg : Offset and length of the register set for the module
+- interrupts : the interrupt-specifier for the AES module.
+
+Optional properties:
+- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
+       Documentation/devicetree/bindings/dma/dma.txt
+- dma-names: DMA request names should include "tx" and "rx" if present.
+
+Example:
+       /* AM335x */
+       aes: aes@53500000 {
+               compatible = "ti,omap4-aes";
+               ti,hwmods = "aes";
+               reg = <0x53500000 0xa0>;
+               interrupts = <102>;
+               dmas = <&edma 6>,
+                      <&edma 5>;
+               dma-names = "tx", "rx";
+       };
diff --git a/Documentation/devicetree/bindings/crypto/omap-sham.txt b/Documentation/devicetree/bindings/crypto/omap-sham.txt
new file mode 100644 (file)
index 0000000..f839acd
--- /dev/null
@@ -0,0 +1,28 @@
+OMAP SoC SHA crypto Module
+
+Required properties:
+
+- compatible : Should contain entries for this and backward compatible
+  SHAM versions:
+  - "ti,omap2-sham" for OMAP2 & OMAP3.
+  - "ti,omap4-sham" for OMAP4 and AM33XX.
+  Note that these two versions are incompatible.
+- ti,hwmods: Name of the hwmod associated with the SHAM module
+- reg : Offset and length of the register set for the module
+- interrupts : the interrupt-specifier for the SHAM module.
+
+Optional properties:
+- dmas: DMA specifiers for the rx dma. See the DMA client binding,
+       Documentation/devicetree/bindings/dma/dma.txt
+- dma-names: DMA request name. Should be "rx" if a dma is present.
+
+Example:
+       /* AM335x */
+       sham: sham@53100000 {
+               compatible = "ti,omap4-sham";
+               ti,hwmods = "sham";
+               reg = <0x53100000 0x200>;
+               interrupts = <109>;
+               dmas = <&edma 36>;
+               dma-names = "rx";
+       };
diff --git a/Documentation/devicetree/bindings/hwrng/omap_rng.txt b/Documentation/devicetree/bindings/hwrng/omap_rng.txt
new file mode 100644 (file)
index 0000000..6a62acd
--- /dev/null
@@ -0,0 +1,22 @@
+OMAP SoC HWRNG Module
+
+Required properties:
+
+- compatible : Should contain entries for this and backward compatible
+  RNG versions:
+  - "ti,omap2-rng" for OMAP2.
+  - "ti,omap4-rng" for OMAP4, OMAP5 and AM33XX.
+  Note that these two versions are incompatible.
+- ti,hwmods: Name of the hwmod associated with the RNG module
+- reg : Offset and length of the register set for the module
+- interrupts : the interrupt number for the RNG module.
+               Only used for "ti,omap4-rng".
+
+Example:
+/* AM335x */
+rng: rng@48310000 {
+       compatible = "ti,omap4-rng";
+       ti,hwmods = "rng";
+       reg = <0x48310000 0x2000>;
+       interrupts = <111>;
+};
diff --git a/Documentation/devicetree/bindings/iio/light/cm36651.txt b/Documentation/devicetree/bindings/iio/light/cm36651.txt
new file mode 100644 (file)
index 0000000..c03e19d
--- /dev/null
@@ -0,0 +1,26 @@
+* Capella CM36651 I2C Proximity and Color Light sensor
+
+Required properties:
+- compatible: must be "capella,cm36651"
+- reg: the I2C address of the device
+- interrupts: interrupt-specifier for the sole interrupt
+             generated by the device
+- vled-supply: regulator for the IR LED. IR_LED is a part
+             of the cm36651 for proximity detection.
+             As covered in ../../regulator/regulator.txt
+
+Example:
+
+       i2c_cm36651: i2c-gpio {
+               /* ... */
+
+               cm36651@18 {
+                       compatible = "capella,cm36651";
+                       reg = <0x18>;
+                       interrupt-parent = <&gpx0>;
+                       interrupts = <2 0>;
+                       vled-supply = <&ps_als_reg>;
+               };
+
+               /* ... */
+       };
diff --git a/Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt b/Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt
new file mode 100644 (file)
index 0000000..9231c82
--- /dev/null
@@ -0,0 +1,21 @@
+* Sharp GP2AP020A00F I2C Proximity/ALS sensor
+
+The proximity detector sensor requires power supply
+for its built-in led. It is also defined by this binding.
+
+Required properties:
+
+  - compatible : should be "sharp,gp2ap020a00f"
+  - reg : the I2C slave address of the light sensor
+  - interrupts : interrupt specifier for the sole interrupt generated
+                by the device
+  - vled-supply : VLED power supply, as covered in ../regulator/regulator.txt
+
+Example:
+
+gp2ap020a00f@39 {
+       compatible = "sharp,gp2ap020a00f";
+       reg = <0x39>;
+       interrupts = <2 0>;
+       vled-supply = <...>;
+};
index 57edb30dbbca72f47b06b777267995389e136eb5..3d3b2b91e3330665d365ccae672c844379832711 100644 (file)
@@ -8,9 +8,6 @@ Required properties:
 - #interrupt-cells : Specifies the number of cells needed to encode an
   interrupt source. The value shall be 1.
 
-For the valid interrupt sources for your SoC, see the documentation in
-sunxi/<soc>.txt
-
 Example:
 
 intc: interrupt-controller {
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt b/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt
deleted file mode 100644 (file)
index 76b98c8..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-Allwinner A10 (sun4i) interrupt sources
----------------------------------------
-
-The interrupt sources available for the Allwinner A10 SoC are the
-following one:
-
-0: ENMI
-1: UART0
-2: UART1
-3: UART2
-4: UART3
-5: IR0
-6: IR1
-7: I2C0
-8: I2C1
-9: I2C2
-10: SPI0
-11: SPI1
-12: SPI2
-13: SPDIF
-14: AC97
-15: TS
-16: I2S
-17: UART4
-18: UART5
-19: UART6
-20: UART7
-21: KEYPAD
-22: TIMER0
-23: TIMER1
-24: TIMER2
-25: TIMER3
-26: CAN
-27: DMA
-28: PIO
-29: TOUCH_PANEL
-30: AUDIO_CODEC
-31: LRADC
-32: MMC0
-33: MMC1
-34: MMC2
-35: MMC3
-36: MEMSTICK
-37: NAND
-38: USB0
-39: USB1
-40: USB2
-41: SCR
-42: CSI0
-43: CSI1
-44: LCDCTRL0
-45: LCDCTRL1
-46: MP
-47: DEFEBE0
-48: DEFEBE1
-49: PMU
-50: SPI3
-51: TZASC
-52: PATA
-53: VE
-54: SS
-55: EMAC
-56: SATA
-57: GPS
-58: HDMI
-59: TVE
-60: ACE
-61: TVD
-62: PS2_0
-63: PS2_1
-64: USB3
-65: USB4
-66: PLE_PFM
-67: TIMER4
-68: TIMER5
-69: GPU_GP
-70: GPU_GPMMU
-71: GPU_PP0
-72: GPU_PPMMU0
-73: GPU_PMU
-74: GPU_RSV0
-75: GPU_RSV1
-76: GPU_RSV2
-77: GPU_RSV3
-78: GPU_RSV4
-79: GPU_RSV5
-80: GPU_RSV6
-82: SYNC_TIMER0
-83: SYNC_TIMER1
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt b/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt
deleted file mode 100644 (file)
index 2ec3b5c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-Allwinner A13 (sun5i) interrupt sources
----------------------------------------
-
-The interrupt sources available for the Allwinner A13 SoC are the
-following one:
-
-0: ENMI
-2: UART1
-4: UART3
-5: IR
-7: I2C0
-8: I2C1
-9: I2C2
-10: SPI0
-11: SPI1
-12: SPI2
-22: TIMER0
-23: TIMER1
-24: TIMER2
-25: TIMER3
-27: DMA
-28: PIO
-29: TOUCH_PANEL
-30: AUDIO_CODEC
-31: LRADC
-32: MMC0
-33: MMC1
-34: MMC2
-37: NAND
-38: USB OTG
-39: USB EHCI
-40: USB OHCI
-42: CSI
-44: LCDCTRL
-47: DEFEBE
-49: PMU
-53: VE
-54: SS
-66: PLE_PFM
-67: TIMER4
-68: TIMER5
-69: GPU_GP
-70: GPU_GPMMU
-71: GPU_PP0
-72: GPU_PPMMU0
-73: GPU_PMU
-74: GPU_RSV0
-75: GPU_RSV1
-76: GPU_RSV2
-77: GPU_RSV3
-78: GPU_RSV4
-79: GPU_RSV5
-80: GPU_RSV6
-82: SYNC_TIMER0
-83: SYNC_TIMER1
diff --git a/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt
new file mode 100644 (file)
index 0000000..68ba372
--- /dev/null
@@ -0,0 +1,17 @@
+Allwinner sunxi-sid
+
+Required properties:
+- compatible: "allwinner,sun4i-sid" or "allwinner,sun7i-a20-sid".
+- reg: Should contain registers location and length
+
+Example for sun4i:
+       sid@01c23800 {
+               compatible = "allwinner,sun4i-sid";
+               reg = <0x01c23800 0x10>
+       };
+
+Example for sun7i:
+       sid@01c23800 {
+               compatible = "allwinner,sun7i-a20-sid";
+               reg = <0x01c23800 0x200>
+       };
diff --git a/Documentation/devicetree/bindings/misc/ti,dac7512.txt b/Documentation/devicetree/bindings/misc/ti,dac7512.txt
new file mode 100644 (file)
index 0000000..1db4593
--- /dev/null
@@ -0,0 +1,20 @@
+TI DAC7512 DEVICETREE BINDINGS
+
+Required properties:
+
+       - "compatible"          Must be set to "ti,dac7512"
+
+Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
+apply. In particular, "reg" and "spi-max-frequency" properties must be given.
+
+
+Example:
+
+       spi_master {
+               dac7512: dac7512@0 {
+                       compatible = "ti,dac7512";
+                       reg = <0>; /* CS0 */
+                       spi-max-frequency = <1000000>;
+               };
+       };
+
index ed271fc255b23c5d3595f1a1725687cb74d077be..8c8908ab84bab3a570b422a93f15a7f8367adaa8 100644 (file)
@@ -20,8 +20,29 @@ ti,dual-volt: boolean, supports dual voltage cards
 ti,non-removable: non-removable slot (like eMMC)
 ti,needs-special-reset: Requires a special softreset sequence
 ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed
+dmas: List of DMA specifiers with the controller specific format
+as described in the generic DMA client binding. A tx and rx
+specifier is required.
+dma-names: List of DMA request names. These strings correspond
+1:1 with the DMA specifiers listed in dmas. The string naming is
+to be "rx" and "tx" for RX and TX DMA requests, respectively.
+
+Examples:
+
+[hwmod populated DMA resources]
+
+       mmc1: mmc@0x4809c000 {
+               compatible = "ti,omap4-hsmmc";
+               reg = <0x4809c000 0x400>;
+               ti,hwmods = "mmc1";
+               ti,dual-volt;
+               bus-width = <4>;
+               vmmc-supply = <&vmmc>; /* phandle to regulator node */
+               ti,non-removable;
+       };
+
+[generic DMA request binding]
 
-Example:
        mmc1: mmc@0x4809c000 {
                compatible = "ti,omap4-hsmmc";
                reg = <0x4809c000 0x400>;
@@ -30,4 +51,7 @@ Example:
                bus-width = <4>;
                vmmc-supply = <&vmmc>; /* phandle to regulator node */
                ti,non-removable;
+               dmas = <&edma 24
+                       &edma 25>;
+               dma-names = "tx", "rx";
        };
index 9556e2fedf6deb77a1b49579521b7744f7318d1e..08c716b2c6b6c411a13a04055ec267ce3ac5e4f2 100644 (file)
@@ -5,6 +5,7 @@ Mandatory properties:
 - compatible: one of the following values:
     marvell,armada-370-pcie
     marvell,armada-xp-pcie
+    marvell,dove-pcie
     marvell,kirkwood-pcie
 - #address-cells, set to <3>
 - #size-cells, set to <2>
@@ -14,6 +15,8 @@ Mandatory properties:
 - ranges: ranges describing the MMIO registers to control the PCIe
   interfaces, and ranges describing the MBus windows needed to access
   the memory and I/O regions of each PCIe interface.
+- msi-parent: Link to the hardware entity that serves as the Message
+  Signaled Interrupt controller for this PCI controller.
 
 The ranges describing the MMIO registers have the following layout:
 
@@ -74,6 +77,8 @@ and the following optional properties:
 - marvell,pcie-lane: the physical PCIe lane number, for ports having
   multiple lanes. If this property is not found, we assume that the
   value is 0.
+- reset-gpios: optional gpio to PERST#
+- reset-delay-us: delay in us to wait after reset de-assertion
 
 Example:
 
@@ -86,6 +91,7 @@ pcie-controller {
        #size-cells = <2>;
 
        bus-range = <0x00 0xff>;
+       msi-parent = <&mpic>;
 
        ranges =
               <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000   /* Port 0.0 registers */
@@ -135,6 +141,10 @@ pcie-controller {
                interrupt-map = <0 0 0 0 &mpic 58>;
                marvell,pcie-port = <0>;
                marvell,pcie-lane = <0>;
+               /* low-active PERST# reset on GPIO 25 */
+               reset-gpios = <&gpio0 25 1>;
+               /* wait 20ms for device settle after reset deassertion */
+               reset-delay-us = <20000>;
                clocks = <&gateclk 5>;
                status = "disabled";
        };
diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt
new file mode 100644 (file)
index 0000000..8ae844f
--- /dev/null
@@ -0,0 +1,66 @@
+This document explains only the device tree data binding. For general
+information about PHY subsystem refer to Documentation/phy.txt
+
+PHY device node
+===============
+
+Required Properties:
+#phy-cells:    Number of cells in a PHY specifier;  The meaning of all those
+               cells is defined by the binding for the phy node. The PHY
+               provider can use the values in cells to find the appropriate
+               PHY.
+
+For example:
+
+phys: phy {
+    compatible = "xxx";
+    reg = <...>;
+    .
+    .
+    #phy-cells = <1>;
+    .
+    .
+};
+
+That node describes an IP block (PHY provider) that implements 2 different PHYs.
+In order to differentiate between these 2 PHYs, an additonal specifier should be
+given while trying to get a reference to it.
+
+PHY user node
+=============
+
+Required Properties:
+phys : the phandle for the PHY device (used by the PHY subsystem)
+phy-names : the names of the PHY corresponding to the PHYs present in the
+           *phys* phandle
+
+Example 1:
+usb1: usb_otg_ss@xxx {
+    compatible = "xxx";
+    reg = <xxx>;
+    .
+    .
+    phys = <&usb2_phy>, <&usb3_phy>;
+    phy-names = "usb2phy", "usb3phy";
+    .
+    .
+};
+
+This node represents a controller that uses two PHYs, one for usb2 and one for
+usb3.
+
+Example 2:
+usb2: usb_otg_ss@xxx {
+    compatible = "xxx";
+    reg = <xxx>;
+    .
+    .
+    phys = <&phys 1>;
+    phy-names = "usbphy";
+    .
+    .
+};
+
+This node represents a controller that uses one of the PHYs of the PHY provider
+device defined previously. Note that the phy handle has an additional specifier
+"1" to differentiate between the two PHYs.
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
new file mode 100644 (file)
index 0000000..c0fccaa
--- /dev/null
@@ -0,0 +1,22 @@
+Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
+-------------------------------------------------
+
+Required properties:
+- compatible : should be "samsung,s5pv210-mipi-video-phy";
+- reg : offset and length of the MIPI DPHY register set;
+- #phy-cells : from the generic phy bindings, must be 1;
+
+For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
+the PHY specifier identifies the PHY and its meaning is as follows:
+  0 - MIPI CSIS 0,
+  1 - MIPI DSIM 0,
+  2 - MIPI CSIS 1,
+  3 - MIPI DSIM 1.
+
+Samsung EXYNOS SoC series Display Port PHY
+-------------------------------------------------
+
+Required properties:
+- compatible : should be "samsung,exynos5250-dp-video-phy";
+- reg : offset and length of the Display Port PHY register set;
+- #phy-cells : from the generic PHY bindings, must be 0;
index 3077370c89af75c22b60fd59f83ea1dc841eea37..1e70a8aff2600ec72eba7e5f707da425aa19fc4e 100644 (file)
@@ -59,16 +59,16 @@ Required subnode-properties:
 
 Optional subnode-properties:
 - fsl,drive-strength: Integer.
-    0: mA
-    1: mA
-    2: 12 mA
-    3: 16 mA
+    0: MXS_DRIVE_4mA
+    1: MXS_DRIVE_8mA
+    2: MXS_DRIVE_12mA
+    3: MXS_DRIVE_16mA
 - fsl,voltage: Integer.
-    0: 1.8 V
-    1: 3.3 V
+    0: MXS_VOLTAGE_LOW  - 1.8 V
+    1: MXS_VOLTAGE_HIGH - 3.3 V
 - fsl,pull-up: Integer.
-    0: Disable the internal pull-up
-    1: Enable the internal pull-up
+    0: MXS_PULL_DISABLE - Disable the internal pull-up
+    1: MXS_PULL_ENABLE  - Enable the internal pull-up
 
 Note that when enabling the pull-up, the internal pad keeper gets disabled.
 Also, some pins doesn't have a pull up, in that case, setting the fsl,pull-up
@@ -85,23 +85,32 @@ pinctrl@80018000 {
        mmc0_8bit_pins_a: mmc0-8bit@0 {
                reg = <0>;
                fsl,pinmux-ids = <
-                       0x2000 0x2010 0x2020 0x2030
-                       0x2040 0x2050 0x2060 0x2070
-                       0x2080 0x2090 0x20a0>;
-               fsl,drive-strength = <1>;
-               fsl,voltage = <1>;
-               fsl,pull-up = <1>;
+                       MX28_PAD_SSP0_DATA0__SSP0_D0
+                       MX28_PAD_SSP0_DATA1__SSP0_D1
+                       MX28_PAD_SSP0_DATA2__SSP0_D2
+                       MX28_PAD_SSP0_DATA3__SSP0_D3
+                       MX28_PAD_SSP0_DATA4__SSP0_D4
+                       MX28_PAD_SSP0_DATA5__SSP0_D5
+                       MX28_PAD_SSP0_DATA6__SSP0_D6
+                       MX28_PAD_SSP0_DATA7__SSP0_D7
+                       MX28_PAD_SSP0_CMD__SSP0_CMD
+                       MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+                       MX28_PAD_SSP0_SCK__SSP0_SCK
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_ENABLE>;
        };
 
        mmc_cd_cfg: mmc-cd-cfg {
-               fsl,pinmux-ids = <0x2090>;
-               fsl,pull-up = <0>;
+               fsl,pinmux-ids = <MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
        };
 
        mmc_sck_cfg: mmc-sck-cfg {
-               fsl,pinmux-ids = <0x20a0>;
-               fsl,drive-strength = <2>;
-               fsl,pull-up = <0>;
+               fsl,pinmux-ids = <MX28_PAD_SSP0_SCK__SSP0_SCK>;
+               fsl,drive-strength = <MXS_DRIVE_12mA>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
        };
 };
 
@@ -112,811 +121,7 @@ adjusting the configuration for pins card-detection and clock from what group
 node mmc0-8bit defines.  Only the configuration properties to be adjusted need
 to be listed in the config nodes.
 
-Valid values for i.MX28 pinmux-id:
-
-pinmux                                         id
-------                                         --
-MX28_PAD_GPMI_D00__GPMI_D0                     0x0000
-MX28_PAD_GPMI_D01__GPMI_D1                     0x0010
-MX28_PAD_GPMI_D02__GPMI_D2                     0x0020
-MX28_PAD_GPMI_D03__GPMI_D3                     0x0030
-MX28_PAD_GPMI_D04__GPMI_D4                     0x0040
-MX28_PAD_GPMI_D05__GPMI_D5                     0x0050
-MX28_PAD_GPMI_D06__GPMI_D6                     0x0060
-MX28_PAD_GPMI_D07__GPMI_D7                     0x0070
-MX28_PAD_GPMI_CE0N__GPMI_CE0N                  0x0100
-MX28_PAD_GPMI_CE1N__GPMI_CE1N                  0x0110
-MX28_PAD_GPMI_CE2N__GPMI_CE2N                  0x0120
-MX28_PAD_GPMI_CE3N__GPMI_CE3N                  0x0130
-MX28_PAD_GPMI_RDY0__GPMI_READY0                        0x0140
-MX28_PAD_GPMI_RDY1__GPMI_READY1                        0x0150
-MX28_PAD_GPMI_RDY2__GPMI_READY2                        0x0160
-MX28_PAD_GPMI_RDY3__GPMI_READY3                        0x0170
-MX28_PAD_GPMI_RDN__GPMI_RDN                    0x0180
-MX28_PAD_GPMI_WRN__GPMI_WRN                    0x0190
-MX28_PAD_GPMI_ALE__GPMI_ALE                    0x01a0
-MX28_PAD_GPMI_CLE__GPMI_CLE                    0x01b0
-MX28_PAD_GPMI_RESETN__GPMI_RESETN              0x01c0
-MX28_PAD_LCD_D00__LCD_D0                       0x1000
-MX28_PAD_LCD_D01__LCD_D1                       0x1010
-MX28_PAD_LCD_D02__LCD_D2                       0x1020
-MX28_PAD_LCD_D03__LCD_D3                       0x1030
-MX28_PAD_LCD_D04__LCD_D4                       0x1040
-MX28_PAD_LCD_D05__LCD_D5                       0x1050
-MX28_PAD_LCD_D06__LCD_D6                       0x1060
-MX28_PAD_LCD_D07__LCD_D7                       0x1070
-MX28_PAD_LCD_D08__LCD_D8                       0x1080
-MX28_PAD_LCD_D09__LCD_D9                       0x1090
-MX28_PAD_LCD_D10__LCD_D10                      0x10a0
-MX28_PAD_LCD_D11__LCD_D11                      0x10b0
-MX28_PAD_LCD_D12__LCD_D12                      0x10c0
-MX28_PAD_LCD_D13__LCD_D13                      0x10d0
-MX28_PAD_LCD_D14__LCD_D14                      0x10e0
-MX28_PAD_LCD_D15__LCD_D15                      0x10f0
-MX28_PAD_LCD_D16__LCD_D16                      0x1100
-MX28_PAD_LCD_D17__LCD_D17                      0x1110
-MX28_PAD_LCD_D18__LCD_D18                      0x1120
-MX28_PAD_LCD_D19__LCD_D19                      0x1130
-MX28_PAD_LCD_D20__LCD_D20                      0x1140
-MX28_PAD_LCD_D21__LCD_D21                      0x1150
-MX28_PAD_LCD_D22__LCD_D22                      0x1160
-MX28_PAD_LCD_D23__LCD_D23                      0x1170
-MX28_PAD_LCD_RD_E__LCD_RD_E                    0x1180
-MX28_PAD_LCD_WR_RWN__LCD_WR_RWN                        0x1190
-MX28_PAD_LCD_RS__LCD_RS                                0x11a0
-MX28_PAD_LCD_CS__LCD_CS                                0x11b0
-MX28_PAD_LCD_VSYNC__LCD_VSYNC                  0x11c0
-MX28_PAD_LCD_HSYNC__LCD_HSYNC                  0x11d0
-MX28_PAD_LCD_DOTCLK__LCD_DOTCLK                        0x11e0
-MX28_PAD_LCD_ENABLE__LCD_ENABLE                        0x11f0
-MX28_PAD_SSP0_DATA0__SSP0_D0                   0x2000
-MX28_PAD_SSP0_DATA1__SSP0_D1                   0x2010
-MX28_PAD_SSP0_DATA2__SSP0_D2                   0x2020
-MX28_PAD_SSP0_DATA3__SSP0_D3                   0x2030
-MX28_PAD_SSP0_DATA4__SSP0_D4                   0x2040
-MX28_PAD_SSP0_DATA5__SSP0_D5                   0x2050
-MX28_PAD_SSP0_DATA6__SSP0_D6                   0x2060
-MX28_PAD_SSP0_DATA7__SSP0_D7                   0x2070
-MX28_PAD_SSP0_CMD__SSP0_CMD                    0x2080
-MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT         0x2090
-MX28_PAD_SSP0_SCK__SSP0_SCK                    0x20a0
-MX28_PAD_SSP1_SCK__SSP1_SCK                    0x20c0
-MX28_PAD_SSP1_CMD__SSP1_CMD                    0x20d0
-MX28_PAD_SSP1_DATA0__SSP1_D0                   0x20e0
-MX28_PAD_SSP1_DATA3__SSP1_D3                   0x20f0
-MX28_PAD_SSP2_SCK__SSP2_SCK                    0x2100
-MX28_PAD_SSP2_MOSI__SSP2_CMD                   0x2110
-MX28_PAD_SSP2_MISO__SSP2_D0                    0x2120
-MX28_PAD_SSP2_SS0__SSP2_D3                     0x2130
-MX28_PAD_SSP2_SS1__SSP2_D4                     0x2140
-MX28_PAD_SSP2_SS2__SSP2_D5                     0x2150
-MX28_PAD_SSP3_SCK__SSP3_SCK                    0x2180
-MX28_PAD_SSP3_MOSI__SSP3_CMD                   0x2190
-MX28_PAD_SSP3_MISO__SSP3_D0                    0x21a0
-MX28_PAD_SSP3_SS0__SSP3_D3                     0x21b0
-MX28_PAD_AUART0_RX__AUART0_RX                  0x3000
-MX28_PAD_AUART0_TX__AUART0_TX                  0x3010
-MX28_PAD_AUART0_CTS__AUART0_CTS                        0x3020
-MX28_PAD_AUART0_RTS__AUART0_RTS                        0x3030
-MX28_PAD_AUART1_RX__AUART1_RX                  0x3040
-MX28_PAD_AUART1_TX__AUART1_TX                  0x3050
-MX28_PAD_AUART1_CTS__AUART1_CTS                        0x3060
-MX28_PAD_AUART1_RTS__AUART1_RTS                        0x3070
-MX28_PAD_AUART2_RX__AUART2_RX                  0x3080
-MX28_PAD_AUART2_TX__AUART2_TX                  0x3090
-MX28_PAD_AUART2_CTS__AUART2_CTS                        0x30a0
-MX28_PAD_AUART2_RTS__AUART2_RTS                        0x30b0
-MX28_PAD_AUART3_RX__AUART3_RX                  0x30c0
-MX28_PAD_AUART3_TX__AUART3_TX                  0x30d0
-MX28_PAD_AUART3_CTS__AUART3_CTS                        0x30e0
-MX28_PAD_AUART3_RTS__AUART3_RTS                        0x30f0
-MX28_PAD_PWM0__PWM_0                           0x3100
-MX28_PAD_PWM1__PWM_1                           0x3110
-MX28_PAD_PWM2__PWM_2                           0x3120
-MX28_PAD_SAIF0_MCLK__SAIF0_MCLK                        0x3140
-MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK              0x3150
-MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK            0x3160
-MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0            0x3170
-MX28_PAD_I2C0_SCL__I2C0_SCL                    0x3180
-MX28_PAD_I2C0_SDA__I2C0_SDA                    0x3190
-MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0            0x31a0
-MX28_PAD_SPDIF__SPDIF_TX                       0x31b0
-MX28_PAD_PWM3__PWM_3                           0x31c0
-MX28_PAD_PWM4__PWM_4                           0x31d0
-MX28_PAD_LCD_RESET__LCD_RESET                  0x31e0
-MX28_PAD_ENET0_MDC__ENET0_MDC                  0x4000
-MX28_PAD_ENET0_MDIO__ENET0_MDIO                        0x4010
-MX28_PAD_ENET0_RX_EN__ENET0_RX_EN              0x4020
-MX28_PAD_ENET0_RXD0__ENET0_RXD0                        0x4030
-MX28_PAD_ENET0_RXD1__ENET0_RXD1                        0x4040
-MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK            0x4050
-MX28_PAD_ENET0_TX_EN__ENET0_TX_EN              0x4060
-MX28_PAD_ENET0_TXD0__ENET0_TXD0                        0x4070
-MX28_PAD_ENET0_TXD1__ENET0_TXD1                        0x4080
-MX28_PAD_ENET0_RXD2__ENET0_RXD2                        0x4090
-MX28_PAD_ENET0_RXD3__ENET0_RXD3                        0x40a0
-MX28_PAD_ENET0_TXD2__ENET0_TXD2                        0x40b0
-MX28_PAD_ENET0_TXD3__ENET0_TXD3                        0x40c0
-MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK            0x40d0
-MX28_PAD_ENET0_COL__ENET0_COL                  0x40e0
-MX28_PAD_ENET0_CRS__ENET0_CRS                  0x40f0
-MX28_PAD_ENET_CLK__CLKCTRL_ENET                        0x4100
-MX28_PAD_JTAG_RTCK__JTAG_RTCK                  0x4140
-MX28_PAD_EMI_D00__EMI_DATA0                    0x5000
-MX28_PAD_EMI_D01__EMI_DATA1                    0x5010
-MX28_PAD_EMI_D02__EMI_DATA2                    0x5020
-MX28_PAD_EMI_D03__EMI_DATA3                    0x5030
-MX28_PAD_EMI_D04__EMI_DATA4                    0x5040
-MX28_PAD_EMI_D05__EMI_DATA5                    0x5050
-MX28_PAD_EMI_D06__EMI_DATA6                    0x5060
-MX28_PAD_EMI_D07__EMI_DATA7                    0x5070
-MX28_PAD_EMI_D08__EMI_DATA8                    0x5080
-MX28_PAD_EMI_D09__EMI_DATA9                    0x5090
-MX28_PAD_EMI_D10__EMI_DATA10                   0x50a0
-MX28_PAD_EMI_D11__EMI_DATA11                   0x50b0
-MX28_PAD_EMI_D12__EMI_DATA12                   0x50c0
-MX28_PAD_EMI_D13__EMI_DATA13                   0x50d0
-MX28_PAD_EMI_D14__EMI_DATA14                   0x50e0
-MX28_PAD_EMI_D15__EMI_DATA15                   0x50f0
-MX28_PAD_EMI_ODT0__EMI_ODT0                    0x5100
-MX28_PAD_EMI_DQM0__EMI_DQM0                    0x5110
-MX28_PAD_EMI_ODT1__EMI_ODT1                    0x5120
-MX28_PAD_EMI_DQM1__EMI_DQM1                    0x5130
-MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK        0x5140
-MX28_PAD_EMI_CLK__EMI_CLK                      0x5150
-MX28_PAD_EMI_DQS0__EMI_DQS0                    0x5160
-MX28_PAD_EMI_DQS1__EMI_DQS1                    0x5170
-MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN            0x51a0
-MX28_PAD_EMI_A00__EMI_ADDR0                    0x6000
-MX28_PAD_EMI_A01__EMI_ADDR1                    0x6010
-MX28_PAD_EMI_A02__EMI_ADDR2                    0x6020
-MX28_PAD_EMI_A03__EMI_ADDR3                    0x6030
-MX28_PAD_EMI_A04__EMI_ADDR4                    0x6040
-MX28_PAD_EMI_A05__EMI_ADDR5                    0x6050
-MX28_PAD_EMI_A06__EMI_ADDR6                    0x6060
-MX28_PAD_EMI_A07__EMI_ADDR7                    0x6070
-MX28_PAD_EMI_A08__EMI_ADDR8                    0x6080
-MX28_PAD_EMI_A09__EMI_ADDR9                    0x6090
-MX28_PAD_EMI_A10__EMI_ADDR10                   0x60a0
-MX28_PAD_EMI_A11__EMI_ADDR11                   0x60b0
-MX28_PAD_EMI_A12__EMI_ADDR12                   0x60c0
-MX28_PAD_EMI_A13__EMI_ADDR13                   0x60d0
-MX28_PAD_EMI_A14__EMI_ADDR14                   0x60e0
-MX28_PAD_EMI_BA0__EMI_BA0                      0x6100
-MX28_PAD_EMI_BA1__EMI_BA1                      0x6110
-MX28_PAD_EMI_BA2__EMI_BA2                      0x6120
-MX28_PAD_EMI_CASN__EMI_CASN                    0x6130
-MX28_PAD_EMI_RASN__EMI_RASN                    0x6140
-MX28_PAD_EMI_WEN__EMI_WEN                      0x6150
-MX28_PAD_EMI_CE0N__EMI_CE0N                    0x6160
-MX28_PAD_EMI_CE1N__EMI_CE1N                    0x6170
-MX28_PAD_EMI_CKE__EMI_CKE                      0x6180
-MX28_PAD_GPMI_D00__SSP1_D0                     0x0001
-MX28_PAD_GPMI_D01__SSP1_D1                     0x0011
-MX28_PAD_GPMI_D02__SSP1_D2                     0x0021
-MX28_PAD_GPMI_D03__SSP1_D3                     0x0031
-MX28_PAD_GPMI_D04__SSP1_D4                     0x0041
-MX28_PAD_GPMI_D05__SSP1_D5                     0x0051
-MX28_PAD_GPMI_D06__SSP1_D6                     0x0061
-MX28_PAD_GPMI_D07__SSP1_D7                     0x0071
-MX28_PAD_GPMI_CE0N__SSP3_D0                    0x0101
-MX28_PAD_GPMI_CE1N__SSP3_D3                    0x0111
-MX28_PAD_GPMI_CE2N__CAN1_TX                    0x0121
-MX28_PAD_GPMI_CE3N__CAN1_RX                    0x0131
-MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT           0x0141
-MX28_PAD_GPMI_RDY1__SSP1_CMD                   0x0151
-MX28_PAD_GPMI_RDY2__CAN0_TX                    0x0161
-MX28_PAD_GPMI_RDY3__CAN0_RX                    0x0171
-MX28_PAD_GPMI_RDN__SSP3_SCK                    0x0181
-MX28_PAD_GPMI_WRN__SSP1_SCK                    0x0191
-MX28_PAD_GPMI_ALE__SSP3_D1                     0x01a1
-MX28_PAD_GPMI_CLE__SSP3_D2                     0x01b1
-MX28_PAD_GPMI_RESETN__SSP3_CMD                 0x01c1
-MX28_PAD_LCD_D03__ETM_DA8                      0x1031
-MX28_PAD_LCD_D04__ETM_DA9                      0x1041
-MX28_PAD_LCD_D08__ETM_DA3                      0x1081
-MX28_PAD_LCD_D09__ETM_DA4                      0x1091
-MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT                0x1141
-MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN         0x1151
-MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT                0x1161
-MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN         0x1171
-MX28_PAD_LCD_RD_E__LCD_VSYNC                   0x1181
-MX28_PAD_LCD_WR_RWN__LCD_HSYNC                 0x1191
-MX28_PAD_LCD_RS__LCD_DOTCLK                    0x11a1
-MX28_PAD_LCD_CS__LCD_ENABLE                    0x11b1
-MX28_PAD_LCD_VSYNC__SAIF1_SDATA0               0x11c1
-MX28_PAD_LCD_HSYNC__SAIF1_SDATA1               0x11d1
-MX28_PAD_LCD_DOTCLK__SAIF1_MCLK                        0x11e1
-MX28_PAD_SSP0_DATA4__SSP2_D0                   0x2041
-MX28_PAD_SSP0_DATA5__SSP2_D3                   0x2051
-MX28_PAD_SSP0_DATA6__SSP2_CMD                  0x2061
-MX28_PAD_SSP0_DATA7__SSP2_SCK                  0x2071
-MX28_PAD_SSP1_SCK__SSP2_D1                     0x20c1
-MX28_PAD_SSP1_CMD__SSP2_D2                     0x20d1
-MX28_PAD_SSP1_DATA0__SSP2_D6                   0x20e1
-MX28_PAD_SSP1_DATA3__SSP2_D7                   0x20f1
-MX28_PAD_SSP2_SCK__AUART2_RX                   0x2101
-MX28_PAD_SSP2_MOSI__AUART2_TX                  0x2111
-MX28_PAD_SSP2_MISO__AUART3_RX                  0x2121
-MX28_PAD_SSP2_SS0__AUART3_TX                   0x2131
-MX28_PAD_SSP2_SS1__SSP2_D1                     0x2141
-MX28_PAD_SSP2_SS2__SSP2_D2                     0x2151
-MX28_PAD_SSP3_SCK__AUART4_TX                   0x2181
-MX28_PAD_SSP3_MOSI__AUART4_RX                  0x2191
-MX28_PAD_SSP3_MISO__AUART4_RTS                 0x21a1
-MX28_PAD_SSP3_SS0__AUART4_CTS                  0x21b1
-MX28_PAD_AUART0_RX__I2C0_SCL                   0x3001
-MX28_PAD_AUART0_TX__I2C0_SDA                   0x3011
-MX28_PAD_AUART0_CTS__AUART4_RX                 0x3021
-MX28_PAD_AUART0_RTS__AUART4_TX                 0x3031
-MX28_PAD_AUART1_RX__SSP2_CARD_DETECT           0x3041
-MX28_PAD_AUART1_TX__SSP3_CARD_DETECT           0x3051
-MX28_PAD_AUART1_CTS__USB0_OVERCURRENT          0x3061
-MX28_PAD_AUART1_RTS__USB0_ID                   0x3071
-MX28_PAD_AUART2_RX__SSP3_D1                    0x3081
-MX28_PAD_AUART2_TX__SSP3_D2                    0x3091
-MX28_PAD_AUART2_CTS__I2C1_SCL                  0x30a1
-MX28_PAD_AUART2_RTS__I2C1_SDA                  0x30b1
-MX28_PAD_AUART3_RX__CAN0_TX                    0x30c1
-MX28_PAD_AUART3_TX__CAN0_RX                    0x30d1
-MX28_PAD_AUART3_CTS__CAN1_TX                   0x30e1
-MX28_PAD_AUART3_RTS__CAN1_RX                   0x30f1
-MX28_PAD_PWM0__I2C1_SCL                                0x3101
-MX28_PAD_PWM1__I2C1_SDA                                0x3111
-MX28_PAD_PWM2__USB0_ID                         0x3121
-MX28_PAD_SAIF0_MCLK__PWM_3                     0x3141
-MX28_PAD_SAIF0_LRCLK__PWM_4                    0x3151
-MX28_PAD_SAIF0_BITCLK__PWM_5                   0x3161
-MX28_PAD_SAIF0_SDATA0__PWM_6                   0x3171
-MX28_PAD_I2C0_SCL__TIMROT_ROTARYA              0x3181
-MX28_PAD_I2C0_SDA__TIMROT_ROTARYB              0x3191
-MX28_PAD_SAIF1_SDATA0__PWM_7                   0x31a1
-MX28_PAD_LCD_RESET__LCD_VSYNC                  0x31e1
-MX28_PAD_ENET0_MDC__GPMI_CE4N                  0x4001
-MX28_PAD_ENET0_MDIO__GPMI_CE5N                 0x4011
-MX28_PAD_ENET0_RX_EN__GPMI_CE6N                        0x4021
-MX28_PAD_ENET0_RXD0__GPMI_CE7N                 0x4031
-MX28_PAD_ENET0_RXD1__GPMI_READY4               0x4041
-MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER           0x4051
-MX28_PAD_ENET0_TX_EN__GPMI_READY5              0x4061
-MX28_PAD_ENET0_TXD0__GPMI_READY6               0x4071
-MX28_PAD_ENET0_TXD1__GPMI_READY7               0x4081
-MX28_PAD_ENET0_RXD2__ENET1_RXD0                        0x4091
-MX28_PAD_ENET0_RXD3__ENET1_RXD1                        0x40a1
-MX28_PAD_ENET0_TXD2__ENET1_TXD0                        0x40b1
-MX28_PAD_ENET0_TXD3__ENET1_TXD1                        0x40c1
-MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER             0x40d1
-MX28_PAD_ENET0_COL__ENET1_TX_EN                        0x40e1
-MX28_PAD_ENET0_CRS__ENET1_RX_EN                        0x40f1
-MX28_PAD_GPMI_CE2N__ENET0_RX_ER                        0x0122
-MX28_PAD_GPMI_CE3N__SAIF1_MCLK                 0x0132
-MX28_PAD_GPMI_RDY0__USB0_ID                    0x0142
-MX28_PAD_GPMI_RDY2__ENET0_TX_ER                        0x0162
-MX28_PAD_GPMI_RDY3__HSADC_TRIGGER              0x0172
-MX28_PAD_GPMI_ALE__SSP3_D4                     0x01a2
-MX28_PAD_GPMI_CLE__SSP3_D5                     0x01b2
-MX28_PAD_LCD_D00__ETM_DA0                      0x1002
-MX28_PAD_LCD_D01__ETM_DA1                      0x1012
-MX28_PAD_LCD_D02__ETM_DA2                      0x1022
-MX28_PAD_LCD_D03__ETM_DA3                      0x1032
-MX28_PAD_LCD_D04__ETM_DA4                      0x1042
-MX28_PAD_LCD_D05__ETM_DA5                      0x1052
-MX28_PAD_LCD_D06__ETM_DA6                      0x1062
-MX28_PAD_LCD_D07__ETM_DA7                      0x1072
-MX28_PAD_LCD_D08__ETM_DA8                      0x1082
-MX28_PAD_LCD_D09__ETM_DA9                      0x1092
-MX28_PAD_LCD_D10__ETM_DA10                     0x10a2
-MX28_PAD_LCD_D11__ETM_DA11                     0x10b2
-MX28_PAD_LCD_D12__ETM_DA12                     0x10c2
-MX28_PAD_LCD_D13__ETM_DA13                     0x10d2
-MX28_PAD_LCD_D14__ETM_DA14                     0x10e2
-MX28_PAD_LCD_D15__ETM_DA15                     0x10f2
-MX28_PAD_LCD_D16__ETM_DA7                      0x1102
-MX28_PAD_LCD_D17__ETM_DA6                      0x1112
-MX28_PAD_LCD_D18__ETM_DA5                      0x1122
-MX28_PAD_LCD_D19__ETM_DA4                      0x1132
-MX28_PAD_LCD_D20__ETM_DA3                      0x1142
-MX28_PAD_LCD_D21__ETM_DA2                      0x1152
-MX28_PAD_LCD_D22__ETM_DA1                      0x1162
-MX28_PAD_LCD_D23__ETM_DA0                      0x1172
-MX28_PAD_LCD_RD_E__ETM_TCTL                    0x1182
-MX28_PAD_LCD_WR_RWN__ETM_TCLK                  0x1192
-MX28_PAD_LCD_HSYNC__ETM_TCTL                   0x11d2
-MX28_PAD_LCD_DOTCLK__ETM_TCLK                  0x11e2
-MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT       0x20c2
-MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN                0x20d2
-MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT     0x20e2
-MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN      0x20f2
-MX28_PAD_SSP2_SCK__SAIF0_SDATA1                        0x2102
-MX28_PAD_SSP2_MOSI__SAIF0_SDATA2               0x2112
-MX28_PAD_SSP2_MISO__SAIF1_SDATA1               0x2122
-MX28_PAD_SSP2_SS0__SAIF1_SDATA2                        0x2132
-MX28_PAD_SSP2_SS1__USB1_OVERCURRENT            0x2142
-MX28_PAD_SSP2_SS2__USB0_OVERCURRENT            0x2152
-MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT       0x2182
-MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN       0x2192
-MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT      0x21a2
-MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN                0x21b2
-MX28_PAD_AUART0_RX__DUART_CTS                  0x3002
-MX28_PAD_AUART0_TX__DUART_RTS                  0x3012
-MX28_PAD_AUART0_CTS__DUART_RX                  0x3022
-MX28_PAD_AUART0_RTS__DUART_TX                  0x3032
-MX28_PAD_AUART1_RX__PWM_0                      0x3042
-MX28_PAD_AUART1_TX__PWM_1                      0x3052
-MX28_PAD_AUART1_CTS__TIMROT_ROTARYA            0x3062
-MX28_PAD_AUART1_RTS__TIMROT_ROTARYB            0x3072
-MX28_PAD_AUART2_RX__SSP3_D4                    0x3082
-MX28_PAD_AUART2_TX__SSP3_D5                    0x3092
-MX28_PAD_AUART2_CTS__SAIF1_BITCLK              0x30a2
-MX28_PAD_AUART2_RTS__SAIF1_LRCLK               0x30b2
-MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT      0x30c2
-MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN       0x30d2
-MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT     0x30e2
-MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN      0x30f2
-MX28_PAD_PWM0__DUART_RX                                0x3102
-MX28_PAD_PWM1__DUART_TX                                0x3112
-MX28_PAD_PWM2__USB1_OVERCURRENT                        0x3122
-MX28_PAD_SAIF0_MCLK__AUART4_CTS                        0x3142
-MX28_PAD_SAIF0_LRCLK__AUART4_RTS               0x3152
-MX28_PAD_SAIF0_BITCLK__AUART4_RX               0x3162
-MX28_PAD_SAIF0_SDATA0__AUART4_TX               0x3172
-MX28_PAD_I2C0_SCL__DUART_RX                    0x3182
-MX28_PAD_I2C0_SDA__DUART_TX                    0x3192
-MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1            0x31a2
-MX28_PAD_SPDIF__ENET1_RX_ER                    0x31b2
-MX28_PAD_ENET0_MDC__SAIF0_SDATA1               0x4002
-MX28_PAD_ENET0_MDIO__SAIF0_SDATA2              0x4012
-MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1             0x4022
-MX28_PAD_ENET0_RXD0__SAIF1_SDATA2              0x4032
-MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT   0x4052
-MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT     0x4092
-MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN      0x40a2
-MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT     0x40b2
-MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN      0x40c2
-MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN    0x40d2
-MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT      0x40e2
-MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN       0x40f2
-MX28_PAD_GPMI_D00__GPIO_0_0                    0x0003
-MX28_PAD_GPMI_D01__GPIO_0_1                    0x0013
-MX28_PAD_GPMI_D02__GPIO_0_2                    0x0023
-MX28_PAD_GPMI_D03__GPIO_0_3                    0x0033
-MX28_PAD_GPMI_D04__GPIO_0_4                    0x0043
-MX28_PAD_GPMI_D05__GPIO_0_5                    0x0053
-MX28_PAD_GPMI_D06__GPIO_0_6                    0x0063
-MX28_PAD_GPMI_D07__GPIO_0_7                    0x0073
-MX28_PAD_GPMI_CE0N__GPIO_0_16                  0x0103
-MX28_PAD_GPMI_CE1N__GPIO_0_17                  0x0113
-MX28_PAD_GPMI_CE2N__GPIO_0_18                  0x0123
-MX28_PAD_GPMI_CE3N__GPIO_0_19                  0x0133
-MX28_PAD_GPMI_RDY0__GPIO_0_20                  0x0143
-MX28_PAD_GPMI_RDY1__GPIO_0_21                  0x0153
-MX28_PAD_GPMI_RDY2__GPIO_0_22                  0x0163
-MX28_PAD_GPMI_RDY3__GPIO_0_23                  0x0173
-MX28_PAD_GPMI_RDN__GPIO_0_24                   0x0183
-MX28_PAD_GPMI_WRN__GPIO_0_25                   0x0193
-MX28_PAD_GPMI_ALE__GPIO_0_26                   0x01a3
-MX28_PAD_GPMI_CLE__GPIO_0_27                   0x01b3
-MX28_PAD_GPMI_RESETN__GPIO_0_28                        0x01c3
-MX28_PAD_LCD_D00__GPIO_1_0                     0x1003
-MX28_PAD_LCD_D01__GPIO_1_1                     0x1013
-MX28_PAD_LCD_D02__GPIO_1_2                     0x1023
-MX28_PAD_LCD_D03__GPIO_1_3                     0x1033
-MX28_PAD_LCD_D04__GPIO_1_4                     0x1043
-MX28_PAD_LCD_D05__GPIO_1_5                     0x1053
-MX28_PAD_LCD_D06__GPIO_1_6                     0x1063
-MX28_PAD_LCD_D07__GPIO_1_7                     0x1073
-MX28_PAD_LCD_D08__GPIO_1_8                     0x1083
-MX28_PAD_LCD_D09__GPIO_1_9                     0x1093
-MX28_PAD_LCD_D10__GPIO_1_10                    0x10a3
-MX28_PAD_LCD_D11__GPIO_1_11                    0x10b3
-MX28_PAD_LCD_D12__GPIO_1_12                    0x10c3
-MX28_PAD_LCD_D13__GPIO_1_13                    0x10d3
-MX28_PAD_LCD_D14__GPIO_1_14                    0x10e3
-MX28_PAD_LCD_D15__GPIO_1_15                    0x10f3
-MX28_PAD_LCD_D16__GPIO_1_16                    0x1103
-MX28_PAD_LCD_D17__GPIO_1_17                    0x1113
-MX28_PAD_LCD_D18__GPIO_1_18                    0x1123
-MX28_PAD_LCD_D19__GPIO_1_19                    0x1133
-MX28_PAD_LCD_D20__GPIO_1_20                    0x1143
-MX28_PAD_LCD_D21__GPIO_1_21                    0x1153
-MX28_PAD_LCD_D22__GPIO_1_22                    0x1163
-MX28_PAD_LCD_D23__GPIO_1_23                    0x1173
-MX28_PAD_LCD_RD_E__GPIO_1_24                   0x1183
-MX28_PAD_LCD_WR_RWN__GPIO_1_25                 0x1193
-MX28_PAD_LCD_RS__GPIO_1_26                     0x11a3
-MX28_PAD_LCD_CS__GPIO_1_27                     0x11b3
-MX28_PAD_LCD_VSYNC__GPIO_1_28                  0x11c3
-MX28_PAD_LCD_HSYNC__GPIO_1_29                  0x11d3
-MX28_PAD_LCD_DOTCLK__GPIO_1_30                 0x11e3
-MX28_PAD_LCD_ENABLE__GPIO_1_31                 0x11f3
-MX28_PAD_SSP0_DATA0__GPIO_2_0                  0x2003
-MX28_PAD_SSP0_DATA1__GPIO_2_1                  0x2013
-MX28_PAD_SSP0_DATA2__GPIO_2_2                  0x2023
-MX28_PAD_SSP0_DATA3__GPIO_2_3                  0x2033
-MX28_PAD_SSP0_DATA4__GPIO_2_4                  0x2043
-MX28_PAD_SSP0_DATA5__GPIO_2_5                  0x2053
-MX28_PAD_SSP0_DATA6__GPIO_2_6                  0x2063
-MX28_PAD_SSP0_DATA7__GPIO_2_7                  0x2073
-MX28_PAD_SSP0_CMD__GPIO_2_8                    0x2083
-MX28_PAD_SSP0_DETECT__GPIO_2_9                 0x2093
-MX28_PAD_SSP0_SCK__GPIO_2_10                   0x20a3
-MX28_PAD_SSP1_SCK__GPIO_2_12                   0x20c3
-MX28_PAD_SSP1_CMD__GPIO_2_13                   0x20d3
-MX28_PAD_SSP1_DATA0__GPIO_2_14                 0x20e3
-MX28_PAD_SSP1_DATA3__GPIO_2_15                 0x20f3
-MX28_PAD_SSP2_SCK__GPIO_2_16                   0x2103
-MX28_PAD_SSP2_MOSI__GPIO_2_17                  0x2113
-MX28_PAD_SSP2_MISO__GPIO_2_18                  0x2123
-MX28_PAD_SSP2_SS0__GPIO_2_19                   0x2133
-MX28_PAD_SSP2_SS1__GPIO_2_20                   0x2143
-MX28_PAD_SSP2_SS2__GPIO_2_21                   0x2153
-MX28_PAD_SSP3_SCK__GPIO_2_24                   0x2183
-MX28_PAD_SSP3_MOSI__GPIO_2_25                  0x2193
-MX28_PAD_SSP3_MISO__GPIO_2_26                  0x21a3
-MX28_PAD_SSP3_SS0__GPIO_2_27                   0x21b3
-MX28_PAD_AUART0_RX__GPIO_3_0                   0x3003
-MX28_PAD_AUART0_TX__GPIO_3_1                   0x3013
-MX28_PAD_AUART0_CTS__GPIO_3_2                  0x3023
-MX28_PAD_AUART0_RTS__GPIO_3_3                  0x3033
-MX28_PAD_AUART1_RX__GPIO_3_4                   0x3043
-MX28_PAD_AUART1_TX__GPIO_3_5                   0x3053
-MX28_PAD_AUART1_CTS__GPIO_3_6                  0x3063
-MX28_PAD_AUART1_RTS__GPIO_3_7                  0x3073
-MX28_PAD_AUART2_RX__GPIO_3_8                   0x3083
-MX28_PAD_AUART2_TX__GPIO_3_9                   0x3093
-MX28_PAD_AUART2_CTS__GPIO_3_10                 0x30a3
-MX28_PAD_AUART2_RTS__GPIO_3_11                 0x30b3
-MX28_PAD_AUART3_RX__GPIO_3_12                  0x30c3
-MX28_PAD_AUART3_TX__GPIO_3_13                  0x30d3
-MX28_PAD_AUART3_CTS__GPIO_3_14                 0x30e3
-MX28_PAD_AUART3_RTS__GPIO_3_15                 0x30f3
-MX28_PAD_PWM0__GPIO_3_16                       0x3103
-MX28_PAD_PWM1__GPIO_3_17                       0x3113
-MX28_PAD_PWM2__GPIO_3_18                       0x3123
-MX28_PAD_SAIF0_MCLK__GPIO_3_20                 0x3143
-MX28_PAD_SAIF0_LRCLK__GPIO_3_21                        0x3153
-MX28_PAD_SAIF0_BITCLK__GPIO_3_22               0x3163
-MX28_PAD_SAIF0_SDATA0__GPIO_3_23               0x3173
-MX28_PAD_I2C0_SCL__GPIO_3_24                   0x3183
-MX28_PAD_I2C0_SDA__GPIO_3_25                   0x3193
-MX28_PAD_SAIF1_SDATA0__GPIO_3_26               0x31a3
-MX28_PAD_SPDIF__GPIO_3_27                      0x31b3
-MX28_PAD_PWM3__GPIO_3_28                       0x31c3
-MX28_PAD_PWM4__GPIO_3_29                       0x31d3
-MX28_PAD_LCD_RESET__GPIO_3_30                  0x31e3
-MX28_PAD_ENET0_MDC__GPIO_4_0                   0x4003
-MX28_PAD_ENET0_MDIO__GPIO_4_1                  0x4013
-MX28_PAD_ENET0_RX_EN__GPIO_4_2                 0x4023
-MX28_PAD_ENET0_RXD0__GPIO_4_3                  0x4033
-MX28_PAD_ENET0_RXD1__GPIO_4_4                  0x4043
-MX28_PAD_ENET0_TX_CLK__GPIO_4_5                        0x4053
-MX28_PAD_ENET0_TX_EN__GPIO_4_6                 0x4063
-MX28_PAD_ENET0_TXD0__GPIO_4_7                  0x4073
-MX28_PAD_ENET0_TXD1__GPIO_4_8                  0x4083
-MX28_PAD_ENET0_RXD2__GPIO_4_9                  0x4093
-MX28_PAD_ENET0_RXD3__GPIO_4_10                 0x40a3
-MX28_PAD_ENET0_TXD2__GPIO_4_11                 0x40b3
-MX28_PAD_ENET0_TXD3__GPIO_4_12                 0x40c3
-MX28_PAD_ENET0_RX_CLK__GPIO_4_13               0x40d3
-MX28_PAD_ENET0_COL__GPIO_4_14                  0x40e3
-MX28_PAD_ENET0_CRS__GPIO_4_15                  0x40f3
-MX28_PAD_ENET_CLK__GPIO_4_16                   0x4103
-MX28_PAD_JTAG_RTCK__GPIO_4_20                  0x4143
-
-Valid values for i.MX23 pinmux-id:
-
-pinmux                                         id
-------                                         --
-MX23_PAD_GPMI_D00__GPMI_D00                    0x0000
-MX23_PAD_GPMI_D01__GPMI_D01                    0x0010
-MX23_PAD_GPMI_D02__GPMI_D02                    0x0020
-MX23_PAD_GPMI_D03__GPMI_D03                    0x0030
-MX23_PAD_GPMI_D04__GPMI_D04                    0x0040
-MX23_PAD_GPMI_D05__GPMI_D05                    0x0050
-MX23_PAD_GPMI_D06__GPMI_D06                    0x0060
-MX23_PAD_GPMI_D07__GPMI_D07                    0x0070
-MX23_PAD_GPMI_D08__GPMI_D08                    0x0080
-MX23_PAD_GPMI_D09__GPMI_D09                    0x0090
-MX23_PAD_GPMI_D10__GPMI_D10                    0x00a0
-MX23_PAD_GPMI_D11__GPMI_D11                    0x00b0
-MX23_PAD_GPMI_D12__GPMI_D12                    0x00c0
-MX23_PAD_GPMI_D13__GPMI_D13                    0x00d0
-MX23_PAD_GPMI_D14__GPMI_D14                    0x00e0
-MX23_PAD_GPMI_D15__GPMI_D15                    0x00f0
-MX23_PAD_GPMI_CLE__GPMI_CLE                    0x0100
-MX23_PAD_GPMI_ALE__GPMI_ALE                    0x0110
-MX23_PAD_GPMI_CE2N__GPMI_CE2N                  0x0120
-MX23_PAD_GPMI_RDY0__GPMI_RDY0                  0x0130
-MX23_PAD_GPMI_RDY1__GPMI_RDY1                  0x0140
-MX23_PAD_GPMI_RDY2__GPMI_RDY2                  0x0150
-MX23_PAD_GPMI_RDY3__GPMI_RDY3                  0x0160
-MX23_PAD_GPMI_WPN__GPMI_WPN                    0x0170
-MX23_PAD_GPMI_WRN__GPMI_WRN                    0x0180
-MX23_PAD_GPMI_RDN__GPMI_RDN                    0x0190
-MX23_PAD_AUART1_CTS__AUART1_CTS                        0x01a0
-MX23_PAD_AUART1_RTS__AUART1_RTS                        0x01b0
-MX23_PAD_AUART1_RX__AUART1_RX                  0x01c0
-MX23_PAD_AUART1_TX__AUART1_TX                  0x01d0
-MX23_PAD_I2C_SCL__I2C_SCL                      0x01e0
-MX23_PAD_I2C_SDA__I2C_SDA                      0x01f0
-MX23_PAD_LCD_D00__LCD_D00                      0x1000
-MX23_PAD_LCD_D01__LCD_D01                      0x1010
-MX23_PAD_LCD_D02__LCD_D02                      0x1020
-MX23_PAD_LCD_D03__LCD_D03                      0x1030
-MX23_PAD_LCD_D04__LCD_D04                      0x1040
-MX23_PAD_LCD_D05__LCD_D05                      0x1050
-MX23_PAD_LCD_D06__LCD_D06                      0x1060
-MX23_PAD_LCD_D07__LCD_D07                      0x1070
-MX23_PAD_LCD_D08__LCD_D08                      0x1080
-MX23_PAD_LCD_D09__LCD_D09                      0x1090
-MX23_PAD_LCD_D10__LCD_D10                      0x10a0
-MX23_PAD_LCD_D11__LCD_D11                      0x10b0
-MX23_PAD_LCD_D12__LCD_D12                      0x10c0
-MX23_PAD_LCD_D13__LCD_D13                      0x10d0
-MX23_PAD_LCD_D14__LCD_D14                      0x10e0
-MX23_PAD_LCD_D15__LCD_D15                      0x10f0
-MX23_PAD_LCD_D16__LCD_D16                      0x1100
-MX23_PAD_LCD_D17__LCD_D17                      0x1110
-MX23_PAD_LCD_RESET__LCD_RESET                  0x1120
-MX23_PAD_LCD_RS__LCD_RS                                0x1130
-MX23_PAD_LCD_WR__LCD_WR                                0x1140
-MX23_PAD_LCD_CS__LCD_CS                                0x1150
-MX23_PAD_LCD_DOTCK__LCD_DOTCK                  0x1160
-MX23_PAD_LCD_ENABLE__LCD_ENABLE                        0x1170
-MX23_PAD_LCD_HSYNC__LCD_HSYNC                  0x1180
-MX23_PAD_LCD_VSYNC__LCD_VSYNC                  0x1190
-MX23_PAD_PWM0__PWM0                            0x11a0
-MX23_PAD_PWM1__PWM1                            0x11b0
-MX23_PAD_PWM2__PWM2                            0x11c0
-MX23_PAD_PWM3__PWM3                            0x11d0
-MX23_PAD_PWM4__PWM4                            0x11e0
-MX23_PAD_SSP1_CMD__SSP1_CMD                    0x2000
-MX23_PAD_SSP1_DETECT__SSP1_DETECT              0x2010
-MX23_PAD_SSP1_DATA0__SSP1_DATA0                        0x2020
-MX23_PAD_SSP1_DATA1__SSP1_DATA1                        0x2030
-MX23_PAD_SSP1_DATA2__SSP1_DATA2                        0x2040
-MX23_PAD_SSP1_DATA3__SSP1_DATA3                        0x2050
-MX23_PAD_SSP1_SCK__SSP1_SCK                    0x2060
-MX23_PAD_ROTARYA__ROTARYA                      0x2070
-MX23_PAD_ROTARYB__ROTARYB                      0x2080
-MX23_PAD_EMI_A00__EMI_A00                      0x2090
-MX23_PAD_EMI_A01__EMI_A01                      0x20a0
-MX23_PAD_EMI_A02__EMI_A02                      0x20b0
-MX23_PAD_EMI_A03__EMI_A03                      0x20c0
-MX23_PAD_EMI_A04__EMI_A04                      0x20d0
-MX23_PAD_EMI_A05__EMI_A05                      0x20e0
-MX23_PAD_EMI_A06__EMI_A06                      0x20f0
-MX23_PAD_EMI_A07__EMI_A07                      0x2100
-MX23_PAD_EMI_A08__EMI_A08                      0x2110
-MX23_PAD_EMI_A09__EMI_A09                      0x2120
-MX23_PAD_EMI_A10__EMI_A10                      0x2130
-MX23_PAD_EMI_A11__EMI_A11                      0x2140
-MX23_PAD_EMI_A12__EMI_A12                      0x2150
-MX23_PAD_EMI_BA0__EMI_BA0                      0x2160
-MX23_PAD_EMI_BA1__EMI_BA1                      0x2170
-MX23_PAD_EMI_CASN__EMI_CASN                    0x2180
-MX23_PAD_EMI_CE0N__EMI_CE0N                    0x2190
-MX23_PAD_EMI_CE1N__EMI_CE1N                    0x21a0
-MX23_PAD_GPMI_CE1N__GPMI_CE1N                  0x21b0
-MX23_PAD_GPMI_CE0N__GPMI_CE0N                  0x21c0
-MX23_PAD_EMI_CKE__EMI_CKE                      0x21d0
-MX23_PAD_EMI_RASN__EMI_RASN                    0x21e0
-MX23_PAD_EMI_WEN__EMI_WEN                      0x21f0
-MX23_PAD_EMI_D00__EMI_D00                      0x3000
-MX23_PAD_EMI_D01__EMI_D01                      0x3010
-MX23_PAD_EMI_D02__EMI_D02                      0x3020
-MX23_PAD_EMI_D03__EMI_D03                      0x3030
-MX23_PAD_EMI_D04__EMI_D04                      0x3040
-MX23_PAD_EMI_D05__EMI_D05                      0x3050
-MX23_PAD_EMI_D06__EMI_D06                      0x3060
-MX23_PAD_EMI_D07__EMI_D07                      0x3070
-MX23_PAD_EMI_D08__EMI_D08                      0x3080
-MX23_PAD_EMI_D09__EMI_D09                      0x3090
-MX23_PAD_EMI_D10__EMI_D10                      0x30a0
-MX23_PAD_EMI_D11__EMI_D11                      0x30b0
-MX23_PAD_EMI_D12__EMI_D12                      0x30c0
-MX23_PAD_EMI_D13__EMI_D13                      0x30d0
-MX23_PAD_EMI_D14__EMI_D14                      0x30e0
-MX23_PAD_EMI_D15__EMI_D15                      0x30f0
-MX23_PAD_EMI_DQM0__EMI_DQM0                    0x3100
-MX23_PAD_EMI_DQM1__EMI_DQM1                    0x3110
-MX23_PAD_EMI_DQS0__EMI_DQS0                    0x3120
-MX23_PAD_EMI_DQS1__EMI_DQS1                    0x3130
-MX23_PAD_EMI_CLK__EMI_CLK                      0x3140
-MX23_PAD_EMI_CLKN__EMI_CLKN                    0x3150
-MX23_PAD_GPMI_D00__LCD_D8                      0x0001
-MX23_PAD_GPMI_D01__LCD_D9                      0x0011
-MX23_PAD_GPMI_D02__LCD_D10                     0x0021
-MX23_PAD_GPMI_D03__LCD_D11                     0x0031
-MX23_PAD_GPMI_D04__LCD_D12                     0x0041
-MX23_PAD_GPMI_D05__LCD_D13                     0x0051
-MX23_PAD_GPMI_D06__LCD_D14                     0x0061
-MX23_PAD_GPMI_D07__LCD_D15                     0x0071
-MX23_PAD_GPMI_D08__LCD_D18                     0x0081
-MX23_PAD_GPMI_D09__LCD_D19                     0x0091
-MX23_PAD_GPMI_D10__LCD_D20                     0x00a1
-MX23_PAD_GPMI_D11__LCD_D21                     0x00b1
-MX23_PAD_GPMI_D12__LCD_D22                     0x00c1
-MX23_PAD_GPMI_D13__LCD_D23                     0x00d1
-MX23_PAD_GPMI_D14__AUART2_RX                   0x00e1
-MX23_PAD_GPMI_D15__AUART2_TX                   0x00f1
-MX23_PAD_GPMI_CLE__LCD_D16                     0x0101
-MX23_PAD_GPMI_ALE__LCD_D17                     0x0111
-MX23_PAD_GPMI_CE2N__ATA_A2                     0x0121
-MX23_PAD_AUART1_RTS__IR_CLK                    0x01b1
-MX23_PAD_AUART1_RX__IR_RX                      0x01c1
-MX23_PAD_AUART1_TX__IR_TX                      0x01d1
-MX23_PAD_I2C_SCL__GPMI_RDY2                    0x01e1
-MX23_PAD_I2C_SDA__GPMI_CE2N                    0x01f1
-MX23_PAD_LCD_D00__ETM_DA8                      0x1001
-MX23_PAD_LCD_D01__ETM_DA9                      0x1011
-MX23_PAD_LCD_D02__ETM_DA10                     0x1021
-MX23_PAD_LCD_D03__ETM_DA11                     0x1031
-MX23_PAD_LCD_D04__ETM_DA12                     0x1041
-MX23_PAD_LCD_D05__ETM_DA13                     0x1051
-MX23_PAD_LCD_D06__ETM_DA14                     0x1061
-MX23_PAD_LCD_D07__ETM_DA15                     0x1071
-MX23_PAD_LCD_D08__ETM_DA0                      0x1081
-MX23_PAD_LCD_D09__ETM_DA1                      0x1091
-MX23_PAD_LCD_D10__ETM_DA2                      0x10a1
-MX23_PAD_LCD_D11__ETM_DA3                      0x10b1
-MX23_PAD_LCD_D12__ETM_DA4                      0x10c1
-MX23_PAD_LCD_D13__ETM_DA5                      0x10d1
-MX23_PAD_LCD_D14__ETM_DA6                      0x10e1
-MX23_PAD_LCD_D15__ETM_DA7                      0x10f1
-MX23_PAD_LCD_RESET__ETM_TCTL                   0x1121
-MX23_PAD_LCD_RS__ETM_TCLK                      0x1131
-MX23_PAD_LCD_DOTCK__GPMI_RDY3                  0x1161
-MX23_PAD_LCD_ENABLE__I2C_SCL                   0x1171
-MX23_PAD_LCD_HSYNC__I2C_SDA                    0x1181
-MX23_PAD_LCD_VSYNC__LCD_BUSY                   0x1191
-MX23_PAD_PWM0__ROTARYA                         0x11a1
-MX23_PAD_PWM1__ROTARYB                         0x11b1
-MX23_PAD_PWM2__GPMI_RDY3                       0x11c1
-MX23_PAD_PWM3__ETM_TCTL                                0x11d1
-MX23_PAD_PWM4__ETM_TCLK                                0x11e1
-MX23_PAD_SSP1_DETECT__GPMI_CE3N                        0x2011
-MX23_PAD_SSP1_DATA1__I2C_SCL                   0x2031
-MX23_PAD_SSP1_DATA2__I2C_SDA                   0x2041
-MX23_PAD_ROTARYA__AUART2_RTS                   0x2071
-MX23_PAD_ROTARYB__AUART2_CTS                   0x2081
-MX23_PAD_GPMI_D00__SSP2_DATA0                  0x0002
-MX23_PAD_GPMI_D01__SSP2_DATA1                  0x0012
-MX23_PAD_GPMI_D02__SSP2_DATA2                  0x0022
-MX23_PAD_GPMI_D03__SSP2_DATA3                  0x0032
-MX23_PAD_GPMI_D04__SSP2_DATA4                  0x0042
-MX23_PAD_GPMI_D05__SSP2_DATA5                  0x0052
-MX23_PAD_GPMI_D06__SSP2_DATA6                  0x0062
-MX23_PAD_GPMI_D07__SSP2_DATA7                  0x0072
-MX23_PAD_GPMI_D08__SSP1_DATA4                  0x0082
-MX23_PAD_GPMI_D09__SSP1_DATA5                  0x0092
-MX23_PAD_GPMI_D10__SSP1_DATA6                  0x00a2
-MX23_PAD_GPMI_D11__SSP1_DATA7                  0x00b2
-MX23_PAD_GPMI_D15__GPMI_CE3N                   0x00f2
-MX23_PAD_GPMI_RDY0__SSP2_DETECT                        0x0132
-MX23_PAD_GPMI_RDY1__SSP2_CMD                   0x0142
-MX23_PAD_GPMI_WRN__SSP2_SCK                    0x0182
-MX23_PAD_AUART1_CTS__SSP1_DATA4                        0x01a2
-MX23_PAD_AUART1_RTS__SSP1_DATA5                        0x01b2
-MX23_PAD_AUART1_RX__SSP1_DATA6                 0x01c2
-MX23_PAD_AUART1_TX__SSP1_DATA7                 0x01d2
-MX23_PAD_I2C_SCL__AUART1_TX                    0x01e2
-MX23_PAD_I2C_SDA__AUART1_RX                    0x01f2
-MX23_PAD_LCD_D08__SAIF2_SDATA0                 0x1082
-MX23_PAD_LCD_D09__SAIF1_SDATA0                 0x1092
-MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK             0x10a2
-MX23_PAD_LCD_D11__SAIF_LRCLK                   0x10b2
-MX23_PAD_LCD_D12__SAIF2_SDATA1                 0x10c2
-MX23_PAD_LCD_D13__SAIF2_SDATA2                 0x10d2
-MX23_PAD_LCD_D14__SAIF1_SDATA2                 0x10e2
-MX23_PAD_LCD_D15__SAIF1_SDATA1                 0x10f2
-MX23_PAD_LCD_D16__SAIF_ALT_BITCLK              0x1102
-MX23_PAD_LCD_RESET__GPMI_CE3N                  0x1122
-MX23_PAD_PWM0__DUART_RX                                0x11a2
-MX23_PAD_PWM1__DUART_TX                                0x11b2
-MX23_PAD_PWM3__AUART1_CTS                      0x11d2
-MX23_PAD_PWM4__AUART1_RTS                      0x11e2
-MX23_PAD_SSP1_CMD__JTAG_TDO                    0x2002
-MX23_PAD_SSP1_DETECT__USB_OTG_ID               0x2012
-MX23_PAD_SSP1_DATA0__JTAG_TDI                  0x2022
-MX23_PAD_SSP1_DATA1__JTAG_TCLK                 0x2032
-MX23_PAD_SSP1_DATA2__JTAG_RTCK                 0x2042
-MX23_PAD_SSP1_DATA3__JTAG_TMS                  0x2052
-MX23_PAD_SSP1_SCK__JTAG_TRST                   0x2062
-MX23_PAD_ROTARYA__SPDIF                                0x2072
-MX23_PAD_ROTARYB__GPMI_CE3N                    0x2082
-MX23_PAD_GPMI_D00__GPIO_0_0                    0x0003
-MX23_PAD_GPMI_D01__GPIO_0_1                    0x0013
-MX23_PAD_GPMI_D02__GPIO_0_2                    0x0023
-MX23_PAD_GPMI_D03__GPIO_0_3                    0x0033
-MX23_PAD_GPMI_D04__GPIO_0_4                    0x0043
-MX23_PAD_GPMI_D05__GPIO_0_5                    0x0053
-MX23_PAD_GPMI_D06__GPIO_0_6                    0x0063
-MX23_PAD_GPMI_D07__GPIO_0_7                    0x0073
-MX23_PAD_GPMI_D08__GPIO_0_8                    0x0083
-MX23_PAD_GPMI_D09__GPIO_0_9                    0x0093
-MX23_PAD_GPMI_D10__GPIO_0_10                   0x00a3
-MX23_PAD_GPMI_D11__GPIO_0_11                   0x00b3
-MX23_PAD_GPMI_D12__GPIO_0_12                   0x00c3
-MX23_PAD_GPMI_D13__GPIO_0_13                   0x00d3
-MX23_PAD_GPMI_D14__GPIO_0_14                   0x00e3
-MX23_PAD_GPMI_D15__GPIO_0_15                   0x00f3
-MX23_PAD_GPMI_CLE__GPIO_0_16                   0x0103
-MX23_PAD_GPMI_ALE__GPIO_0_17                   0x0113
-MX23_PAD_GPMI_CE2N__GPIO_0_18                  0x0123
-MX23_PAD_GPMI_RDY0__GPIO_0_19                  0x0133
-MX23_PAD_GPMI_RDY1__GPIO_0_20                  0x0143
-MX23_PAD_GPMI_RDY2__GPIO_0_21                  0x0153
-MX23_PAD_GPMI_RDY3__GPIO_0_22                  0x0163
-MX23_PAD_GPMI_WPN__GPIO_0_23                   0x0173
-MX23_PAD_GPMI_WRN__GPIO_0_24                   0x0183
-MX23_PAD_GPMI_RDN__GPIO_0_25                   0x0193
-MX23_PAD_AUART1_CTS__GPIO_0_26                 0x01a3
-MX23_PAD_AUART1_RTS__GPIO_0_27                 0x01b3
-MX23_PAD_AUART1_RX__GPIO_0_28                  0x01c3
-MX23_PAD_AUART1_TX__GPIO_0_29                  0x01d3
-MX23_PAD_I2C_SCL__GPIO_0_30                    0x01e3
-MX23_PAD_I2C_SDA__GPIO_0_31                    0x01f3
-MX23_PAD_LCD_D00__GPIO_1_0                     0x1003
-MX23_PAD_LCD_D01__GPIO_1_1                     0x1013
-MX23_PAD_LCD_D02__GPIO_1_2                     0x1023
-MX23_PAD_LCD_D03__GPIO_1_3                     0x1033
-MX23_PAD_LCD_D04__GPIO_1_4                     0x1043
-MX23_PAD_LCD_D05__GPIO_1_5                     0x1053
-MX23_PAD_LCD_D06__GPIO_1_6                     0x1063
-MX23_PAD_LCD_D07__GPIO_1_7                     0x1073
-MX23_PAD_LCD_D08__GPIO_1_8                     0x1083
-MX23_PAD_LCD_D09__GPIO_1_9                     0x1093
-MX23_PAD_LCD_D10__GPIO_1_10                    0x10a3
-MX23_PAD_LCD_D11__GPIO_1_11                    0x10b3
-MX23_PAD_LCD_D12__GPIO_1_12                    0x10c3
-MX23_PAD_LCD_D13__GPIO_1_13                    0x10d3
-MX23_PAD_LCD_D14__GPIO_1_14                    0x10e3
-MX23_PAD_LCD_D15__GPIO_1_15                    0x10f3
-MX23_PAD_LCD_D16__GPIO_1_16                    0x1103
-MX23_PAD_LCD_D17__GPIO_1_17                    0x1113
-MX23_PAD_LCD_RESET__GPIO_1_18                  0x1123
-MX23_PAD_LCD_RS__GPIO_1_19                     0x1133
-MX23_PAD_LCD_WR__GPIO_1_20                     0x1143
-MX23_PAD_LCD_CS__GPIO_1_21                     0x1153
-MX23_PAD_LCD_DOTCK__GPIO_1_22                  0x1163
-MX23_PAD_LCD_ENABLE__GPIO_1_23                 0x1173
-MX23_PAD_LCD_HSYNC__GPIO_1_24                  0x1183
-MX23_PAD_LCD_VSYNC__GPIO_1_25                  0x1193
-MX23_PAD_PWM0__GPIO_1_26                       0x11a3
-MX23_PAD_PWM1__GPIO_1_27                       0x11b3
-MX23_PAD_PWM2__GPIO_1_28                       0x11c3
-MX23_PAD_PWM3__GPIO_1_29                       0x11d3
-MX23_PAD_PWM4__GPIO_1_30                       0x11e3
-MX23_PAD_SSP1_CMD__GPIO_2_0                    0x2003
-MX23_PAD_SSP1_DETECT__GPIO_2_1                 0x2013
-MX23_PAD_SSP1_DATA0__GPIO_2_2                  0x2023
-MX23_PAD_SSP1_DATA1__GPIO_2_3                  0x2033
-MX23_PAD_SSP1_DATA2__GPIO_2_4                  0x2043
-MX23_PAD_SSP1_DATA3__GPIO_2_5                  0x2053
-MX23_PAD_SSP1_SCK__GPIO_2_6                    0x2063
-MX23_PAD_ROTARYA__GPIO_2_7                     0x2073
-MX23_PAD_ROTARYB__GPIO_2_8                     0x2083
-MX23_PAD_EMI_A00__GPIO_2_9                     0x2093
-MX23_PAD_EMI_A01__GPIO_2_10                    0x20a3
-MX23_PAD_EMI_A02__GPIO_2_11                    0x20b3
-MX23_PAD_EMI_A03__GPIO_2_12                    0x20c3
-MX23_PAD_EMI_A04__GPIO_2_13                    0x20d3
-MX23_PAD_EMI_A05__GPIO_2_14                    0x20e3
-MX23_PAD_EMI_A06__GPIO_2_15                    0x20f3
-MX23_PAD_EMI_A07__GPIO_2_16                    0x2103
-MX23_PAD_EMI_A08__GPIO_2_17                    0x2113
-MX23_PAD_EMI_A09__GPIO_2_18                    0x2123
-MX23_PAD_EMI_A10__GPIO_2_19                    0x2133
-MX23_PAD_EMI_A11__GPIO_2_20                    0x2143
-MX23_PAD_EMI_A12__GPIO_2_21                    0x2153
-MX23_PAD_EMI_BA0__GPIO_2_22                    0x2163
-MX23_PAD_EMI_BA1__GPIO_2_23                    0x2173
-MX23_PAD_EMI_CASN__GPIO_2_24                   0x2183
-MX23_PAD_EMI_CE0N__GPIO_2_25                   0x2193
-MX23_PAD_EMI_CE1N__GPIO_2_26                   0x21a3
-MX23_PAD_GPMI_CE1N__GPIO_2_27                  0x21b3
-MX23_PAD_GPMI_CE0N__GPIO_2_28                  0x21c3
-MX23_PAD_EMI_CKE__GPIO_2_29                    0x21d3
-MX23_PAD_EMI_RASN__GPIO_2_30                   0x21e3
-MX23_PAD_EMI_WEN__GPIO_2_31                    0x21f3
+Valid values for i.MX28/i.MX23 pinmux-id are defined in
+arch/arm/boot/dts/imx28-pinfunc.h and arch/arm/boot/dts/imx23-pinfunc.h.
+The definitions for the padconfig properties can be found in
+arch/arm/boot/dts/mxs-pinfunc.h.
index 5a02e30dd262dfabfca818339c4da04dc2eae9d2..7069a0b84e3a43d46f0a3e698975ad208ab45e17 100644 (file)
@@ -72,6 +72,13 @@ Optional properties:
                /* pin base, nr pins & gpio function */
                pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>;
 
+- interrupt-controller : standard interrupt controller binding if using
+  interrupts for wake-up events for example. In this case pinctrl-single
+  is set up as a chained interrupt controller and the wake-up interrupts
+  can be requested by the drivers using request_irq().
+
+- #interrupt-cells : standard interrupt binding if using interrupts
+
 This driver assumes that there is only one register for each pin (unless the
 pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as
 specified in the pinctrl-bindings.txt document in this directory.
@@ -121,6 +128,8 @@ pmx_core: pinmux@4a100040 {
        reg = <0x4a100040 0x0196>;
        #address-cells = <1>;
        #size-cells = <0>;
+       #interrupt-cells = <1>;
+       interrupt-controller;
        pinctrl-single,register-width = <16>;
        pinctrl-single,function-mask = <0xffff>;
 };
@@ -131,6 +140,8 @@ pmx_wkup: pinmux@4a31e040 {
        reg = <0x4a31e040 0x0038>;
        #address-cells = <1>;
        #size-cells = <0>;
+       #interrupt-cells = <1>;
+       interrupt-controller;
        pinctrl-single,register-width = <16>;
        pinctrl-single,function-mask = <0xffff>;
 };
index 46882058b59b54a12e457a72c1ed81ae62c90651..ee05dc3906941a10c5f20546e59b09e77bdf9c7b 100644 (file)
@@ -1,7 +1,8 @@
 * Freescale i.MX28 LRADC device driver
 
 Required properties:
-- compatible: Should be "fsl,imx28-lradc"
+- compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc"
+              for i.MX28 SoC
 - reg: Address and length of the register set for the device
 - interrupts: Should contain the LRADC interrupts
 
@@ -9,13 +10,38 @@ Optional properties:
 - fsl,lradc-touchscreen-wires: Number of wires used to connect the touchscreen
                                to LRADC. Valid value is either 4 or 5. If this
                                property is not present, then the touchscreen is
-                               disabled.
+                               disabled. 5 wires is valid for i.MX28 SoC only.
+- fsl,ave-ctrl: number of samples per direction to calculate an average value.
+                Allowed value is 1 ... 31, default is 4
+- fsl,ave-delay: delay between consecutive samples. Allowed value is
+                 1 ... 2047. It is used if 'fsl,ave-ctrl' > 1, counts at
+                 2 kHz and its default is 2 (= 1 ms)
+- fsl,settling: delay between plate switch to next sample. Allowed value is
+                1 ... 2047. It counts at 2 kHz and its default is
+                10 (= 5 ms)
 
-Examples:
+Example for i.MX23 SoC:
+
+       lradc@80050000 {
+               compatible = "fsl,imx23-lradc";
+               reg = <0x80050000 0x2000>;
+               interrupts = <36 37 38 39 40 41 42 43 44>;
+               status = "okay";
+               fsl,lradc-touchscreen-wires = <4>;
+               fsl,ave-ctrl = <4>;
+               fsl,ave-delay = <2>;
+               fsl,settling = <10>;
+       };
+
+Example for i.MX28 SoC:
 
        lradc@80050000 {
                compatible = "fsl,imx28-lradc";
                reg = <0x80050000 0x2000>;
-               interrupts = <10 14 15 16 17 18 19
-                               20 21 22 23 24 25>;
+               interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>;
+               status = "okay";
+               fsl,lradc-touchscreen-wires = <5>;
+               fsl,ave-ctrl = <4>;
+               fsl,ave-delay = <2>;
+               fsl,settling = <10>;
        };
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
new file mode 100644 (file)
index 0000000..5ea26c6
--- /dev/null
@@ -0,0 +1,17 @@
+MSM SoC HSUSB controllers
+
+EHCI
+
+Required properties:
+- compatible:  Should contain "qcom,ehci-host"
+- regs:                        offset and length of the register set in the memory map
+- usb-phy:             phandle for the PHY device
+
+Example EHCI controller device node:
+
+       ehci: ehci@f9a55000 {
+               compatible = "qcom,ehci-host";
+               reg = <0xf9a55000 0x400>;
+               usb-phy = <&usb_otg>;
+       };
+
index 9088ab09e20028c99257244975600fa24f44c403..090e5e22bd2b831a1b05885d5d01db228aec9bef 100644 (file)
@@ -3,9 +3,6 @@ OMAP GLUE AND OTHER OMAP SPECIFIC COMPONENTS
 OMAP MUSB GLUE
  - compatible : Should be "ti,omap4-musb" or "ti,omap3-musb"
  - ti,hwmods : must be "usb_otg_hs"
- - ti,has-mailbox : to specify that omap uses an external mailbox
-   (in control module) to communicate with the musb core during device connect
-   and disconnect.
  - multipoint : Should be "1" indicating the musb controller supports
    multipoint. This is a MUSB configuration-specific setting.
  - num-eps : Specifies the number of endpoints. This is also a
@@ -19,6 +16,9 @@ OMAP MUSB GLUE
  - power : Should be "50". This signifies the controller can supply up to
    100mA when operating in host mode.
  - usb-phy : the phandle for the PHY device
+ - phys : the phandle for the PHY device (used by generic PHY framework)
+ - phy-names : the names of the PHY corresponding to the PHYs present in the
+   *phy* phandle.
 
 Optional properties:
  - ctrl-module : phandle of the control module this glue uses to write to
@@ -28,11 +28,12 @@ SOC specific device node entry
 usb_otg_hs: usb_otg_hs@4a0ab000 {
        compatible = "ti,omap4-musb";
        ti,hwmods = "usb_otg_hs";
-       ti,has-mailbox;
        multipoint = <1>;
        num-eps = <16>;
        ram-bits = <12>;
        ctrl-module = <&omap_control_usb>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
 };
 
 Board specific device node entry
@@ -78,22 +79,22 @@ omap_dwc3 {
 OMAP CONTROL USB
 
 Required properties:
- - compatible: Should be "ti,omap-control-usb"
+ - compatible: Should be one of
+ "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4.
+ "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register
+                       e.g. USB2_PHY on OMAP5.
+ "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control
+                       e.g. USB3 PHY and SATA PHY on OMAP5.
+ "ti,control-phy-dra7usb2" - if it has power down register like USB2 PHY on
+                       DRA7 platform.
  - reg : Address and length of the register set for the device. It contains
-   the address of "control_dev_conf" and "otghs_control" or "phy_power_usb"
-   depending upon omap4 or omap5.
- - reg-names: The names of the register addresses corresponding to the registers
-   filled in "reg".
- - ti,type: This is used to differentiate whether the control module has
-   usb mailbox or usb3 phy power. omap4 has usb mailbox in control module to
-   notify events to the musb core and omap5 has usb3 phy power register to
-   power on usb3 phy. Should be "1" if it has mailbox and "2" if it has usb3
-   phy power.
+   the address of "otghs_control" for control-phy-otghs or "power" register
+   for other types.
+ - reg-names: should be "otghs_control" control-phy-otghs and "power" for
+   other types.
 
 omap_control_usb: omap-control-usb@4a002300 {
-       compatible = "ti,omap-control-usb";
-       reg = <0x4a002300 0x4>,
-             <0x4a00233c 0x4>;
-       reg-names = "control_dev_conf", "otghs_control";
-       ti,type = <1>;
+       compatible = "ti,control-phy-otghs";
+       reg = <0x4a00233c 0x4>;
+       reg-names = "otghs_control";
 };
index d7e272671c7e42819c35fc0583d3744aaecd74d9..1bd37faba05b9c3aab70a0ec305107f308ba7665 100644 (file)
@@ -15,7 +15,7 @@ Optional properties:
 
 - vcc-supply: phandle to the regulator that provides RESET to the PHY.
 
-- reset-supply: phandle to the regulator that provides power to the PHY.
+- reset-gpios: Should specify the GPIO for reset.
 
 Example:
 
@@ -25,10 +25,9 @@ Example:
                clocks = <&osc 0>;
                clock-names = "main_clk";
                vcc-supply = <&hsusb1_vcc_regulator>;
-               reset-supply = <&hsusb1_reset_regulator>;
+               reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
        };
 
 hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator
 and expects that clock to be configured to 19.2MHz by the NOP PHY driver.
-hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator
-controls RESET.
+hsusb1_vcc_regulator provides power to the PHY and GPIO 7 controls RESET.
index 61496f5cb095b39c149705e7f80c3fba379c434d..c0245c888982b9be44bad31e76664880e2449e2c 100644 (file)
@@ -5,6 +5,8 @@ OMAP USB2 PHY
 Required properties:
  - compatible: Should be "ti,omap-usb2"
  - reg : Address and length of the register set for the device.
+ - #phy-cells: determine the number of cells that should be given in the
+   phandle while referencing this phy.
 
 Optional properties:
  - ctrl-module : phandle of the control module used by PHY driver to power on
@@ -16,6 +18,7 @@ usb2phy@4a0ad080 {
        compatible = "ti,omap-usb2";
        reg = <0x4a0ad080 0x58>;
        ctrl-module = <&omap_control_usb>;
+       #phy-cells = <0>;
 };
 
 OMAP USB3 PHY
@@ -25,6 +28,8 @@ Required properties:
  - reg : Address and length of the register set for the device.
  - reg-names: The names of the register addresses corresponding to the registers
    filled in "reg".
+ - #phy-cells: determine the number of cells that should be given in the
+   phandle while referencing this phy.
 
 Optional properties:
  - ctrl-module : phandle of the control module used by PHY driver to power on
@@ -39,4 +44,5 @@ usb3phy@4a084400 {
              <0x4a084c00 0x40>;
        reg-names = "phy_rx", "phy_tx", "pll_ctrl";
        ctrl-module = <&omap_control_usb>;
+       #phy-cells = <0>;
 };
index 330d6ec154016caf4bccd0a5bde0d36847412fcb..439a41c79afacd680a6c8309935ab37573cd6326 100644 (file)
@@ -15,7 +15,7 @@ Optional properties:
 Example:
 
 usb_per5@a03e0000 {
-       compatible = "stericsson,db8500-musb", "mentor,musb";
+       compatible = "stericsson,db8500-musb";
        reg = <0xa03e0000 0x10000>;
        interrupts = <0 23 0x4>;
        interrupt-names = "mc";
index 2956800f0240c8b3e48c9427151220ef2fc39fc1..04eab45dd14816280f3acbd63e2f69d08b12e277 100644 (file)
@@ -15,6 +15,7 @@ atmel Atmel Corporation
 avago  Avago Technologies
 bosch  Bosch Sensortec GmbH
 brcm   Broadcom Corporation
+capella        Capella Microsystems, Inc
 cavium Cavium, Inc.
 chrp   Common Hardware Reference Platform
 cirrus Cirrus Logic, Inc.
index 84f10c16cb383497b0fc5a736d4ce03a59668c4c..3289d76a21d0b2d01b81620e0c19fb10af29cf6b 100644 (file)
@@ -6,10 +6,10 @@ We use two nodes:
        -dptx-phy node(defined inside dp-controller node)
 
 For the DP-PHY initialization, we use the dptx-phy node.
-Required properties for dptx-phy:
-       -reg:
+Required properties for dptx-phy: deprecated, use phys and phy-names
+       -reg: deprecated
                Base address of DP PHY register.
-       -samsung,enable-mask:
+       -samsung,enable-mask: deprecated
                The bit-mask used to enable/disable DP PHY.
 
 For the Panel initialization, we read data from dp-controller node.
@@ -27,6 +27,10 @@ Required properties for dp-controller:
                from common clock binding: Shall be "dp".
        -interrupt-parent:
                phandle to Interrupt combiner node.
+       -phys:
+               from general PHY binding: the phandle for the PHY device.
+       -phy-names:
+               from general PHY binding: Should be "dp".
        -samsung,color-space:
                input video data format.
                        COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
@@ -68,11 +72,8 @@ SOC specific portion:
                clocks = <&clock 342>;
                clock-names = "dp";
 
-               dptx-phy {
-                       reg = <0x10040720>;
-                       samsung,enable-mask = <1>;
-               };
-
+               phys = <&dp_phy>;
+               phy-names = "dp";
        };
 
 Board Specific portion:
index 323983be3c30d1684ec155736f0e9e179922fccc..50decf8e1b90a573b11dc864c7b30612a5d5c5a0 100644 (file)
@@ -12,7 +12,19 @@ Required properties:
        a) phandle of the gpio controller node.
        b) pin number within the gpio controller.
        c) optional flags and pull up/down.
-
+- clocks: list of clock IDs from SoC clock driver.
+       a) hdmi: Gate of HDMI IP bus clock.
+       b) sclk_hdmi: Gate of HDMI special clock.
+       c) sclk_pixel: Pixel special clock, one of the two possible inputs of
+               HDMI clock mux.
+       d) sclk_hdmiphy: HDMI PHY clock output, one of two possible inputs of
+               HDMI clock mux.
+       e) mout_hdmi: It is required by the driver to switch between the 2
+               parents i.e. sclk_pixel and sclk_hdmiphy. If hdmiphy is stable
+               after configuration, parent is set to sclk_hdmiphy else
+               sclk_pixel.
+- clock-names: aliases as per driver requirements for above clock IDs:
+       "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
 Example:
 
        hdmi {
index 3334b0a8e343ee078825100c796c6c8b77dcebcc..7bfde9c9d658d780e82452d52d3fa5cfa3e36919 100644 (file)
@@ -10,6 +10,10 @@ Required properties:
 - reg: physical base address of the mixer and length of memory mapped
        region.
 - interrupts: interrupt number to the cpu.
+- clocks: list of clock IDs from SoC clock driver.
+       a) mixer: Gate of Mixer IP bus clock.
+       b) sclk_hdmi: HDMI Special clock, one of the two possible inputs of
+               mixer mux.
 
 Example:
 
index eb0fa5f4fe88f4b6e6b2b381f41561367bd80be8..5377f63179613e6f09721bf878e52e7f04a141a8 100644 (file)
@@ -25,8 +25,10 @@ MyungJoo Ham <myungjoo.ham@samsung.com>
     @print_state: no change but type change (switch_dev->extcon_dev)
 
 - switch_dev_register(sdev, dev)
-       => extcon_dev_register(edev, dev)
-       : no change but type change (sdev->edev)
+       => extcon_dev_register(edev)
+       : type change (sdev->edev)
+       : remove second param('dev'). if edev has parent device, should store
+         'dev' to 'edev.dev.parent' before registering extcon device
 - switch_dev_unregister(sdev)
        => extcon_dev_unregister(edev)
        : no change but type change (sdev->edev)
index 11a0a40ce445fa5c2f6fb0276dd63907eb55574d..aed6b94160b1cec74face20a05f9c03f03a057f2 100644 (file)
@@ -29,15 +29,16 @@ This document contains the following sections:
         (6) Index registration
         (7) Data file registration
         (8) Miscellaneous object registration
-        (9) Setting the data file size
+        (9) Setting the data file size
        (10) Page alloc/read/write
        (11) Page uncaching
        (12) Index and data file consistency
-       (13) Miscellaneous cookie operations
-       (14) Cookie unregistration
-       (15) Index invalidation
-       (16) Data file invalidation
-       (17) FS-Cache specific page flags.
+       (13) Cookie enablement
+       (14) Miscellaneous cookie operations
+       (15) Cookie unregistration
+       (16) Index invalidation
+       (17) Data file invalidation
+       (18) FS-Cache specific page flags.
 
 
 =============================
@@ -334,7 +335,8 @@ the path to the file:
        struct fscache_cookie *
        fscache_acquire_cookie(struct fscache_cookie *parent,
                               const struct fscache_object_def *def,
-                              void *netfs_data);
+                              void *netfs_data,
+                              bool enable);
 
 This function creates an index entry in the index represented by parent,
 filling in the index entry by calling the operations pointed to by def.
@@ -350,6 +352,10 @@ object needs to be created somewhere down the hierarchy.  Furthermore, an index
 may be created in several different caches independently at different times.
 This is all handled transparently, and the netfs doesn't see any of it.
 
+A cookie will be created in the disabled state if enabled is false.  A cookie
+must be enabled to do anything with it.  A disabled cookie can be enabled by
+calling fscache_enable_cookie() (see below).
+
 For example, with AFS, a cell would be added to the primary index.  This index
 entry would have a dependent inode containing a volume location index for the
 volume mappings within this cell:
@@ -357,7 +363,7 @@ volume mappings within this cell:
        cell->cache =
                fscache_acquire_cookie(afs_cache_netfs.primary_index,
                                       &afs_cell_cache_index_def,
-                                      cell);
+                                      cell, true);
 
 Then when a volume location was accessed, it would be entered into the cell's
 index and an inode would be allocated that acts as a volume type and hash chain
@@ -366,7 +372,7 @@ combination:
        vlocation->cache =
                fscache_acquire_cookie(cell->cache,
                                       &afs_vlocation_cache_index_def,
-                                      vlocation);
+                                      vlocation, true);
 
 And then a particular flavour of volume (R/O for example) could be added to
 that index, creating another index for vnodes (AFS inode equivalents):
@@ -374,7 +380,7 @@ that index, creating another index for vnodes (AFS inode equivalents):
        volume->cache =
                fscache_acquire_cookie(vlocation->cache,
                                       &afs_volume_cache_index_def,
-                                      volume);
+                                      volume, true);
 
 
 ======================
@@ -388,7 +394,7 @@ the object definition should be something other than index type.
        vnode->cache =
                fscache_acquire_cookie(volume->cache,
                                       &afs_vnode_cache_object_def,
-                                      vnode);
+                                      vnode, true);
 
 
 =================================
@@ -404,7 +410,7 @@ it would be some other type of object such as a data file.
        xattr->cache =
                fscache_acquire_cookie(vnode->cache,
                                       &afs_xattr_cache_object_def,
-                                      xattr);
+                                      xattr, true);
 
 Miscellaneous objects might be used to store extended attributes or directory
 entries for example.
@@ -733,6 +739,47 @@ Note that partial updates may happen automatically at other times, such as when
 data blocks are added to a data file object.
 
 
+=================
+COOKIE ENABLEMENT
+=================
+
+Cookies exist in one of two states: enabled and disabled.  If a cookie is
+disabled, it ignores all attempts to acquire child cookies; check, update or
+invalidate its state; allocate, read or write backing pages - though it is
+still possible to uncache pages and relinquish the cookie.
+
+The initial enablement state is set by fscache_acquire_cookie(), but the cookie
+can be enabled or disabled later.  To disable a cookie, call:
+    
+       void fscache_disable_cookie(struct fscache_cookie *cookie,
+                                   bool invalidate);
+    
+If the cookie is not already disabled, this locks the cookie against other
+enable and disable ops, marks the cookie as being disabled, discards or
+invalidates any backing objects and waits for cessation of activity on any
+associated object before unlocking the cookie.
+
+All possible failures are handled internally.  The caller should consider
+calling fscache_uncache_all_inode_pages() afterwards to make sure all page
+markings are cleared up.
+    
+Cookies can be enabled or reenabled with:
+    
+       void fscache_enable_cookie(struct fscache_cookie *cookie,
+                                  bool (*can_enable)(void *data),
+                                  void *data)
+    
+If the cookie is not already enabled, this locks the cookie against other
+enable and disable ops, invokes can_enable() and, if the cookie is not an index
+cookie, will begin the procedure of acquiring backing objects.
+
+The optional can_enable() function is passed the data argument and returns a
+ruling as to whether or not enablement should actually be permitted to begin.
+
+All possible failures are handled internally.  The cookie will only be marked
+as enabled if provisional backing objects are allocated.
+
+
 ===============================
 MISCELLANEOUS COOKIE OPERATIONS
 ===============================
@@ -778,7 +825,7 @@ COOKIE UNREGISTRATION
 To get rid of a cookie, this function should be called.
 
        void fscache_relinquish_cookie(struct fscache_cookie *cookie,
-                                      int retire);
+                                      bool retire);
 
 If retire is non-zero, then the object will be marked for recycling, and all
 copies of it will be removed from all active caches in which it is present.
index fcbb736d55feb439c1152be71355d5ab79f8edd2..203f4a9d9efe9ae1b2384c6d040cfd3d6f93a603 100644 (file)
@@ -2599,7 +2599,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        ramdisk_size=   [RAM] Sizes of RAM disks in kilobytes
                        See Documentation/blockdev/ramdisk.txt.
 
-       rcu_nocbs=      [KNL,BOOT]
+       rcu_nocbs=      [KNL]
                        In kernels built with CONFIG_RCU_NOCB_CPU=y, set
                        the specified list of CPUs to be no-callback CPUs.
                        Invocation of these CPUs' RCU callbacks will
@@ -2612,7 +2612,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        real-time workloads.  It can also improve energy
                        efficiency for asymmetric multiprocessors.
 
-       rcu_nocb_poll   [KNL,BOOT]
+       rcu_nocb_poll   [KNL]
                        Rather than requiring that offloaded CPUs
                        (specified by rcu_nocbs= above) explicitly
                        awaken the corresponding "rcuoN" kthreads,
@@ -2623,126 +2623,145 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        energy efficiency by requiring that the kthreads
                        periodically wake up to do the polling.
 
-       rcutree.blimit= [KNL,BOOT]
+       rcutree.blimit= [KNL]
                        Set maximum number of finished RCU callbacks to process
                        in one batch.
 
-       rcutree.fanout_leaf=    [KNL,BOOT]
+       rcutree.rcu_fanout_leaf= [KNL]
                        Increase the number of CPUs assigned to each
                        leaf rcu_node structure.  Useful for very large
                        systems.
 
-       rcutree.jiffies_till_first_fqs= [KNL,BOOT]
+       rcutree.jiffies_till_first_fqs= [KNL]
                        Set delay from grace-period initialization to
                        first attempt to force quiescent states.
                        Units are jiffies, minimum value is zero,
                        and maximum value is HZ.
 
-       rcutree.jiffies_till_next_fqs= [KNL,BOOT]
+       rcutree.jiffies_till_next_fqs= [KNL]
                        Set delay between subsequent attempts to force
                        quiescent states.  Units are jiffies, minimum
                        value is one, and maximum value is HZ.
 
-       rcutree.qhimark=        [KNL,BOOT]
+       rcutree.qhimark= [KNL]
                        Set threshold of queued
                        RCU callbacks over which batch limiting is disabled.
 
-       rcutree.qlowmark=       [KNL,BOOT]
+       rcutree.qlowmark= [KNL]
                        Set threshold of queued RCU callbacks below which
                        batch limiting is re-enabled.
 
-       rcutree.rcu_cpu_stall_suppress= [KNL,BOOT]
-                       Suppress RCU CPU stall warning messages.
-
-       rcutree.rcu_cpu_stall_timeout= [KNL,BOOT]
-                       Set timeout for RCU CPU stall warning messages.
-
-       rcutree.rcu_idle_gp_delay=      [KNL,BOOT]
+       rcutree.rcu_idle_gp_delay= [KNL]
                        Set wakeup interval for idle CPUs that have
                        RCU callbacks (RCU_FAST_NO_HZ=y).
 
-       rcutree.rcu_idle_lazy_gp_delay= [KNL,BOOT]
+       rcutree.rcu_idle_lazy_gp_delay= [KNL]
                        Set wakeup interval for idle CPUs that have
                        only "lazy" RCU callbacks (RCU_FAST_NO_HZ=y).
                        Lazy RCU callbacks are those which RCU can
                        prove do nothing more than free memory.
 
-       rcutorture.fqs_duration= [KNL,BOOT]
+       rcutorture.fqs_duration= [KNL]
                        Set duration of force_quiescent_state bursts.
 
-       rcutorture.fqs_holdoff= [KNL,BOOT]
+       rcutorture.fqs_holdoff= [KNL]
                        Set holdoff time within force_quiescent_state bursts.
 
-       rcutorture.fqs_stutter= [KNL,BOOT]
+       rcutorture.fqs_stutter= [KNL]
                        Set wait time between force_quiescent_state bursts.
 
-       rcutorture.irqreader= [KNL,BOOT]
-                       Test RCU readers from irq handlers.
+       rcutorture.gp_exp= [KNL]
+                       Use expedited update-side primitives.
+
+       rcutorture.gp_normal= [KNL]
+                       Use normal (non-expedited) update-side primitives.
+                       If both gp_exp and gp_normal are set, do both.
+                       If neither gp_exp nor gp_normal are set, still
+                       do both.
 
-       rcutorture.n_barrier_cbs= [KNL,BOOT]
+       rcutorture.n_barrier_cbs= [KNL]
                        Set callbacks/threads for rcu_barrier() testing.
 
-       rcutorture.nfakewriters= [KNL,BOOT]
+       rcutorture.nfakewriters= [KNL]
                        Set number of concurrent RCU writers.  These just
                        stress RCU, they don't participate in the actual
                        test, hence the "fake".
 
-       rcutorture.nreaders= [KNL,BOOT]
+       rcutorture.nreaders= [KNL]
                        Set number of RCU readers.
 
-       rcutorture.onoff_holdoff= [KNL,BOOT]
+       rcutorture.object_debug= [KNL]
+                       Enable debug-object double-call_rcu() testing.
+
+       rcutorture.onoff_holdoff= [KNL]
                        Set time (s) after boot for CPU-hotplug testing.
 
-       rcutorture.onoff_interval= [KNL,BOOT]
+       rcutorture.onoff_interval= [KNL]
                        Set time (s) between CPU-hotplug operations, or
                        zero to disable CPU-hotplug testing.
 
-       rcutorture.shuffle_interval= [KNL,BOOT]
+       rcutorture.rcutorture_runnable= [BOOT]
+                       Start rcutorture running at boot time.
+
+       rcutorture.shuffle_interval= [KNL]
                        Set task-shuffle interval (s).  Shuffling tasks
                        allows some CPUs to go into dyntick-idle mode
                        during the rcutorture test.
 
-       rcutorture.shutdown_secs= [KNL,BOOT]
+       rcutorture.shutdown_secs= [KNL]
                        Set time (s) after boot system shutdown.  This
                        is useful for hands-off automated testing.
 
-       rcutorture.stall_cpu= [KNL,BOOT]
+       rcutorture.stall_cpu= [KNL]
                        Duration of CPU stall (s) to test RCU CPU stall
                        warnings, zero to disable.
 
-       rcutorture.stall_cpu_holdoff= [KNL,BOOT]
+       rcutorture.stall_cpu_holdoff= [KNL]
                        Time to wait (s) after boot before inducing stall.
 
-       rcutorture.stat_interval= [KNL,BOOT]
+       rcutorture.stat_interval= [KNL]
                        Time (s) between statistics printk()s.
 
-       rcutorture.stutter= [KNL,BOOT]
+       rcutorture.stutter= [KNL]
                        Time (s) to stutter testing, for example, specifying
                        five seconds causes the test to run for five seconds,
                        wait for five seconds, and so on.  This tests RCU's
                        ability to transition abruptly to and from idle.
 
-       rcutorture.test_boost= [KNL,BOOT]
+       rcutorture.test_boost= [KNL]
                        Test RCU priority boosting?  0=no, 1=maybe, 2=yes.
                        "Maybe" means test if the RCU implementation
                        under test support RCU priority boosting.
 
-       rcutorture.test_boost_duration= [KNL,BOOT]
+       rcutorture.test_boost_duration= [KNL]
                        Duration (s) of each individual boost test.
 
-       rcutorture.test_boost_interval= [KNL,BOOT]
+       rcutorture.test_boost_interval= [KNL]
                        Interval (s) between each boost test.
 
-       rcutorture.test_no_idle_hz= [KNL,BOOT]
+       rcutorture.test_no_idle_hz= [KNL]
                        Test RCU's dyntick-idle handling.  See also the
                        rcutorture.shuffle_interval parameter.
 
-       rcutorture.torture_type= [KNL,BOOT]
+       rcutorture.torture_type= [KNL]
                        Specify the RCU implementation to test.
 
-       rcutorture.verbose= [KNL,BOOT]
+       rcutorture.verbose= [KNL]
                        Enable additional printk() statements.
 
+       rcupdate.rcu_expedited= [KNL]
+                       Use expedited grace-period primitives, for
+                       example, synchronize_rcu_expedited() instead
+                       of synchronize_rcu().  This reduces latency,
+                       but can increase CPU utilization, degrade
+                       real-time latency, and degrade energy efficiency.
+
+       rcupdate.rcu_cpu_stall_suppress= [KNL]
+                       Suppress RCU CPU stall warning messages.
+
+       rcupdate.rcu_cpu_stall_timeout= [KNL]
+                       Set timeout for RCU CPU stall warning messages.
+
        rdinit=         [KNL]
                        Format: <full_path>
                        Run specified binary instead of /init from the ramdisk,
index 32351bfabf2038617c35326f4545ac9f33b02073..827104fb9364cf60df2359e45c3336f61d4568c5 100644 (file)
@@ -181,12 +181,17 @@ To reduce its OS jitter, do any of the following:
                make sure that this is safe on your particular system.
        d.      It is not possible to entirely get rid of OS jitter
                from vmstat_update() on CONFIG_SMP=y systems, but you
-               can decrease its frequency by writing a large value to
-               /proc/sys/vm/stat_interval.  The default value is HZ,
-               for an interval of one second.  Of course, larger values
-               will make your virtual-memory statistics update more
-               slowly.  Of course, you can also run your workload at
-               a real-time priority, thus preempting vmstat_update().
+               can decrease its frequency by writing a large value
+               to /proc/sys/vm/stat_interval.  The default value is
+               HZ, for an interval of one second.  Of course, larger
+               values will make your virtual-memory statistics update
+               more slowly.  Of course, you can also run your workload
+               at a real-time priority, thus preempting vmstat_update(),
+               but if your workload is CPU-bound, this is a bad idea.
+               However, there is an RFC patch from Christoph Lameter
+               (based on an earlier one from Gilad Ben-Yossef) that
+               reduces or even eliminates vmstat overhead for some
+               workloads at https://lkml.org/lkml/2013/9/4/379.
        e.      If running on high-end powerpc servers, build with
                CONFIG_PPC_RTAS_DAEMON=n.  This prevents the RTAS
                daemon from running on each CPU every second or so.
diff --git a/Documentation/mic/mic_overview.txt b/Documentation/mic/mic_overview.txt
new file mode 100644 (file)
index 0000000..b419292
--- /dev/null
@@ -0,0 +1,51 @@
+An Intel MIC X100 device is a PCIe form factor add-in coprocessor
+card based on the Intel Many Integrated Core (MIC) architecture
+that runs a Linux OS. It is a PCIe endpoint in a platform and therefore
+implements the three required standard address spaces i.e. configuration,
+memory and I/O. The host OS loads a device driver as is typical for
+PCIe devices. The card itself runs a bootstrap after reset that
+transfers control to the card OS downloaded from the host driver. The
+host driver supports OSPM suspend and resume operations. It shuts down
+the card during suspend and reboots the card OS during resume.
+The card OS as shipped by Intel is a Linux kernel with modifications
+for the X100 devices.
+
+Since it is a PCIe card, it does not have the ability to host hardware
+devices for networking, storage and console. We provide these devices
+on X100 coprocessors thus enabling a self-bootable equivalent environment
+for applications. A key benefit of our solution is that it leverages
+the standard virtio framework for network, disk and console devices,
+though in our case the virtio framework is used across a PCIe bus.
+
+Here is a block diagram of the various components described above. The
+virtio backends are situated on the host rather than the card given better
+single threaded performance for the host compared to MIC, the ability of
+the host to initiate DMA's to/from the card using the MIC DMA engine and
+the fact that the virtio block storage backend can only be on the host.
+
+                              |
+       +----------+           |             +----------+
+       | Card OS  |           |             | Host OS  |
+       +----------+           |             +----------+
+                              |
++-------+ +--------+ +------+ | +---------+  +--------+ +--------+
+| Virtio| |Virtio  | |Virtio| | |Virtio   |  |Virtio  | |Virtio  |
+| Net   | |Console | |Block | | |Net      |  |Console | |Block   |
+| Driver| |Driver  | |Driver| | |backend  |  |backend | |backend |
++-------+ +--------+ +------+ | +---------+  +--------+ +--------+
+    |         |         |     |      |            |         |
+    |         |         |     |User  |            |         |
+    |         |         |     |------|------------|---------|-------
+    +-------------------+     |Kernel +--------------------------+
+              |               |       | Virtio over PCIe IOCTLs  |
+              |               |       +--------------------------+
+      +--------------+        |                   |
+      |Intel MIC     |        |            +---------------+
+      |Card Driver   |        |            |Intel MIC      |
+      +--------------+        |            |Host Driver    |
+              |               |            +---------------+
+              |               |                   |
+     +-------------------------------------------------------------+
+     |                                                             |
+     |                    PCIe Bus                                 |
+     +-------------------------------------------------------------+
diff --git a/Documentation/mic/mpssd/.gitignore b/Documentation/mic/mpssd/.gitignore
new file mode 100644 (file)
index 0000000..8b7c72f
--- /dev/null
@@ -0,0 +1 @@
+mpssd
diff --git a/Documentation/mic/mpssd/Makefile b/Documentation/mic/mpssd/Makefile
new file mode 100644 (file)
index 0000000..eb860a7
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Makefile - Intel MIC User Space Tools.
+# Copyright(c) 2013, Intel Corporation.
+#
+ifdef DEBUG
+CFLAGS += $(USERWARNFLAGS) -I. -g -Wall -DDEBUG=$(DEBUG)
+else
+CFLAGS += $(USERWARNFLAGS) -I. -g -Wall
+endif
+
+mpssd: mpssd.o sysfs.o
+       $(CC) $(CFLAGS) -o $@ $^ -lpthread
+
+install:
+       install mpssd /usr/sbin/mpssd
+       install micctrl /usr/sbin/micctrl
+
+clean:
+       rm -f mpssd *.o
diff --git a/Documentation/mic/mpssd/micctrl b/Documentation/mic/mpssd/micctrl
new file mode 100755 (executable)
index 0000000..8f2629b
--- /dev/null
@@ -0,0 +1,173 @@
+#!/bin/bash
+# Intel MIC Platform Software Stack (MPSS)
+#
+# Copyright(c) 2013 Intel Corporation.
+#
+# 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.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Intel MIC User Space Tools.
+#
+# micctrl - Controls MIC boot/start/stop.
+#
+# chkconfig: 2345 95 05
+# description: start MPSS stack processing.
+#
+### BEGIN INIT INFO
+# Provides: micctrl
+### END INIT INFO
+
+# Source function library.
+. /etc/init.d/functions
+
+sysfs="/sys/class/mic"
+
+_status()
+{
+       f=$sysfs/$1
+       echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
+}
+
+status()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _status $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _status `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_reset()
+{
+       f=$sysfs/$1
+       echo reset > $f/state
+}
+
+reset()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _reset $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _reset `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_boot()
+{
+       f=$sysfs/$1
+       echo "linux" > $f/bootmode
+       echo "mic/uos.img" > $f/firmware
+       echo "mic/$1.image" > $f/ramdisk
+       echo "boot" > $f/state
+}
+
+boot()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _boot $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _boot `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_shutdown()
+{
+       f=$sysfs/$1
+       echo shutdown > $f/state
+}
+
+shutdown()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _shutdown $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _shutdown `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_wait()
+{
+       f=$sysfs/$1
+       while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
+       do
+               sleep 1
+               echo -e "Waiting for $1 to go offline"
+       done
+}
+
+wait()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _wait $1
+               return $?
+       fi
+       # Wait for the cards to go offline
+       for f in $sysfs/*
+       do
+               _wait `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+if [ ! -d "$sysfs" ]; then
+       echo -e $"Module unloaded "
+       exit 3
+fi
+
+case $1 in
+       -s)
+               status $2
+               ;;
+       -r)
+               reset $2
+               ;;
+       -b)
+               boot $2
+               ;;
+       -S)
+               shutdown $2
+               ;;
+       -w)
+               wait $2
+               ;;
+       *)
+               echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
+               exit 2
+esac
+
+exit $?
diff --git a/Documentation/mic/mpssd/mpss b/Documentation/mic/mpssd/mpss
new file mode 100755 (executable)
index 0000000..3136c68
--- /dev/null
@@ -0,0 +1,202 @@
+#!/bin/bash
+# Intel MIC Platform Software Stack (MPSS)
+#
+# Copyright(c) 2013 Intel Corporation.
+#
+# 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.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Intel MIC User Space Tools.
+#
+# mpss Start mpssd.
+#
+# chkconfig: 2345 95 05
+# description: start MPSS stack processing.
+#
+### BEGIN INIT INFO
+# Provides: mpss
+# Required-Start:
+# Required-Stop:
+# Short-Description: MPSS stack control
+# Description: MPSS stack control
+### END INIT INFO
+
+# Source function library.
+. /etc/init.d/functions
+
+exec=/usr/sbin/mpssd
+sysfs="/sys/class/mic"
+
+start()
+{
+       [ -x $exec ] || exit 5
+
+       if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
+               echo -e $"MPSSD already running! "
+               success
+               echo
+               return 0
+       fi
+
+       echo -e $"Starting MPSS Stack"
+       echo -e $"Loading MIC_HOST Module"
+
+       # Ensure the driver is loaded
+       if [ ! -d "$sysfs" ]; then
+               modprobe mic_host
+               RETVAL=$?
+               if [ $RETVAL -ne 0 ]; then
+                       failure
+                       echo
+                       return $RETVAL
+               fi
+       fi
+
+       # Start the daemon
+       echo -n $"Starting MPSSD "
+       $exec
+       RETVAL=$?
+       if [ $RETVAL -ne 0 ]; then
+               failure
+               echo
+               return $RETVAL
+       fi
+       success
+       echo
+
+       sleep 5
+
+       # Boot the cards
+       micctrl -b
+
+       # Wait till ping works
+       for f in $sysfs/*
+       do
+               count=100
+               ipaddr=`cat $f/cmdline`
+               ipaddr=${ipaddr#*address,}
+               ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
+               while [ $count -ge 0 ]
+               do
+                       echo -e "Pinging "`basename $f`" "
+                       ping -c 1 $ipaddr &> /dev/null
+                       RETVAL=$?
+                       if [ $RETVAL -eq 0 ]; then
+                               success
+                               break
+                       fi
+                       sleep 1
+                       count=`expr $count - 1`
+               done
+               [ $RETVAL -ne 0 ] && failure || success
+               echo
+       done
+       return $RETVAL
+}
+
+stop()
+{
+       echo -e $"Shutting down MPSS Stack: "
+
+       # Bail out if module is unloaded
+       if [ ! -d "$sysfs" ]; then
+               echo -n $"Module unloaded "
+               success
+               echo
+               return 0
+       fi
+
+       # Shut down the cards.
+       micctrl -S
+
+       # Wait for the cards to go offline
+       for f in $sysfs/*
+       do
+               while [ "`cat $f/state`" != "offline" ]
+               do
+                       sleep 1
+                       echo -e "Waiting for "`basename $f`" to go offline"
+               done
+       done
+
+       # Display the status of the cards
+       micctrl -s
+
+       # Kill MPSSD now
+       echo -n $"Killing MPSSD"
+       killall -9 mpssd 2>/dev/null
+       RETVAL=$?
+       [ $RETVAL -ne 0 ] && failure || success
+       echo
+       return $RETVAL
+}
+
+restart()
+{
+       stop
+       sleep 5
+       start
+}
+
+status()
+{
+       micctrl -s
+       if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
+               echo "mpssd is running"
+       else
+               echo "mpssd is stopped"
+       fi
+       return 0
+}
+
+unload()
+{
+       if [ ! -d "$sysfs" ]; then
+               echo -n $"No MIC_HOST Module: "
+               success
+               echo
+               return
+       fi
+
+       stop
+
+       sleep 5
+       echo -n $"Removing MIC_HOST Module: "
+       modprobe -r mic_host
+       RETVAL=$?
+       [ $RETVAL -ne 0 ] && failure || success
+       echo
+       return $RETVAL
+}
+
+case $1 in
+       start)
+               start
+               ;;
+       stop)
+               stop
+               ;;
+       restart)
+               restart
+               ;;
+       status)
+               status
+               ;;
+       unload)
+               unload
+               ;;
+       *)
+               echo $"Usage: $0 {start|stop|restart|status|unload}"
+               exit 2
+esac
+
+exit $?
diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c
new file mode 100644 (file)
index 0000000..0c980ad
--- /dev/null
@@ -0,0 +1,1721 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC User Space Tools.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <poll.h>
+#include <features.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <linux/virtio_ring.h>
+#include <linux/virtio_net.h>
+#include <linux/virtio_console.h>
+#include <linux/virtio_blk.h>
+#include <linux/version.h>
+#include "mpssd.h"
+#include <linux/mic_ioctl.h>
+#include <linux/mic_common.h>
+
+static void init_mic(struct mic_info *mic);
+
+static FILE *logfp;
+static struct mic_info mic_list;
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define min_t(type, x, y) ({                           \
+               type __min1 = (x);                      \
+               type __min2 = (y);                      \
+               __min1 < __min2 ? __min1 : __min2; })
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_DOWN(addr, size)  ((addr)&(~((size)-1)))
+#define _ALIGN_UP(addr, size)    _ALIGN_DOWN(addr + size - 1, size)
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)        _ALIGN(addr, PAGE_SIZE)
+
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+#define GSO_ENABLED            1
+#define MAX_GSO_SIZE           (64 * 1024)
+#define ETH_H_LEN              14
+#define MAX_NET_PKT_SIZE       (_ALIGN_UP(MAX_GSO_SIZE + ETH_H_LEN, 64))
+#define MIC_DEVICE_PAGE_END    0x1000
+
+#ifndef VIRTIO_NET_HDR_F_DATA_VALID
+#define VIRTIO_NET_HDR_F_DATA_VALID    2       /* Csum is valid */
+#endif
+
+static struct {
+       struct mic_device_desc dd;
+       struct mic_vqconfig vqconfig[2];
+       __u32 host_features, guest_acknowledgements;
+       struct virtio_console_config cons_config;
+} virtcons_dev_page = {
+       .dd = {
+               .type = VIRTIO_ID_CONSOLE,
+               .num_vq = ARRAY_SIZE(virtcons_dev_page.vqconfig),
+               .feature_len = sizeof(virtcons_dev_page.host_features),
+               .config_len = sizeof(virtcons_dev_page.cons_config),
+       },
+       .vqconfig[0] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+       .vqconfig[1] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+};
+
+static struct {
+       struct mic_device_desc dd;
+       struct mic_vqconfig vqconfig[2];
+       __u32 host_features, guest_acknowledgements;
+       struct virtio_net_config net_config;
+} virtnet_dev_page = {
+       .dd = {
+               .type = VIRTIO_ID_NET,
+               .num_vq = ARRAY_SIZE(virtnet_dev_page.vqconfig),
+               .feature_len = sizeof(virtnet_dev_page.host_features),
+               .config_len = sizeof(virtnet_dev_page.net_config),
+       },
+       .vqconfig[0] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+       .vqconfig[1] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+#if GSO_ENABLED
+               .host_features = htole32(
+               1 << VIRTIO_NET_F_CSUM |
+               1 << VIRTIO_NET_F_GSO |
+               1 << VIRTIO_NET_F_GUEST_TSO4 |
+               1 << VIRTIO_NET_F_GUEST_TSO6 |
+               1 << VIRTIO_NET_F_GUEST_ECN |
+               1 << VIRTIO_NET_F_GUEST_UFO),
+#else
+               .host_features = 0,
+#endif
+};
+
+static const char *mic_config_dir = "/etc/sysconfig/mic";
+static const char *virtblk_backend = "VIRTBLK_BACKEND";
+static struct {
+       struct mic_device_desc dd;
+       struct mic_vqconfig vqconfig[1];
+       __u32 host_features, guest_acknowledgements;
+       struct virtio_blk_config blk_config;
+} virtblk_dev_page = {
+       .dd = {
+               .type = VIRTIO_ID_BLOCK,
+               .num_vq = ARRAY_SIZE(virtblk_dev_page.vqconfig),
+               .feature_len = sizeof(virtblk_dev_page.host_features),
+               .config_len = sizeof(virtblk_dev_page.blk_config),
+       },
+       .vqconfig[0] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+       .host_features =
+               htole32(1<<VIRTIO_BLK_F_SEG_MAX),
+       .blk_config = {
+               .seg_max = htole32(MIC_VRING_ENTRIES - 2),
+               .capacity = htole64(0),
+        }
+};
+
+static char *myname;
+
+static int
+tap_configure(struct mic_info *mic, char *dev)
+{
+       pid_t pid;
+       char *ifargv[7];
+       char ipaddr[IFNAMSIZ];
+       int ret = 0;
+
+       pid = fork();
+       if (pid == 0) {
+               ifargv[0] = "ip";
+               ifargv[1] = "link";
+               ifargv[2] = "set";
+               ifargv[3] = dev;
+               ifargv[4] = "up";
+               ifargv[5] = NULL;
+               mpsslog("Configuring %s\n", dev);
+               ret = execvp("ip", ifargv);
+               if (ret < 0) {
+                       mpsslog("%s execvp failed errno %s\n",
+                               mic->name, strerror(errno));
+                       return ret;
+               }
+       }
+       if (pid < 0) {
+               mpsslog("%s fork failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+
+       ret = waitpid(pid, NULL, 0);
+       if (ret < 0) {
+               mpsslog("%s waitpid failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+
+       snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id);
+
+       pid = fork();
+       if (pid == 0) {
+               ifargv[0] = "ip";
+               ifargv[1] = "addr";
+               ifargv[2] = "add";
+               ifargv[3] = ipaddr;
+               ifargv[4] = "dev";
+               ifargv[5] = dev;
+               ifargv[6] = NULL;
+               mpsslog("Configuring %s ipaddr %s\n", dev, ipaddr);
+               ret = execvp("ip", ifargv);
+               if (ret < 0) {
+                       mpsslog("%s execvp failed errno %s\n",
+                               mic->name, strerror(errno));
+                       return ret;
+               }
+       }
+       if (pid < 0) {
+               mpsslog("%s fork failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+
+       ret = waitpid(pid, NULL, 0);
+       if (ret < 0) {
+               mpsslog("%s waitpid failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+       mpsslog("MIC name %s %s %d DONE!\n",
+               mic->name, __func__, __LINE__);
+       return 0;
+}
+
+static int tun_alloc(struct mic_info *mic, char *dev)
+{
+       struct ifreq ifr;
+       int fd, err;
+#if GSO_ENABLED
+       unsigned offload;
+#endif
+       fd = open("/dev/net/tun", O_RDWR);
+       if (fd < 0) {
+               mpsslog("Could not open /dev/net/tun %s\n", strerror(errno));
+               goto done;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+
+       ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+       if (*dev)
+               strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+
+       err = ioctl(fd, TUNSETIFF, (void *)&ifr);
+       if (err < 0) {
+               mpsslog("%s %s %d TUNSETIFF failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               close(fd);
+               return err;
+       }
+#if GSO_ENABLED
+       offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
+               TUN_F_TSO_ECN | TUN_F_UFO;
+
+       err = ioctl(fd, TUNSETOFFLOAD, offload);
+       if (err < 0) {
+               mpsslog("%s %s %d TUNSETOFFLOAD failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               close(fd);
+               return err;
+       }
+#endif
+       strcpy(dev, ifr.ifr_name);
+       mpsslog("Created TAP %s\n", dev);
+done:
+       return fd;
+}
+
+#define NET_FD_VIRTIO_NET 0
+#define NET_FD_TUN 1
+#define MAX_NET_FD 2
+
+static void set_dp(struct mic_info *mic, int type, void *dp)
+{
+       switch (type) {
+       case VIRTIO_ID_CONSOLE:
+               mic->mic_console.console_dp = dp;
+               return;
+       case VIRTIO_ID_NET:
+               mic->mic_net.net_dp = dp;
+               return;
+       case VIRTIO_ID_BLOCK:
+               mic->mic_virtblk.block_dp = dp;
+               return;
+       }
+       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+       assert(0);
+}
+
+static void *get_dp(struct mic_info *mic, int type)
+{
+       switch (type) {
+       case VIRTIO_ID_CONSOLE:
+               return mic->mic_console.console_dp;
+       case VIRTIO_ID_NET:
+               return mic->mic_net.net_dp;
+       case VIRTIO_ID_BLOCK:
+               return mic->mic_virtblk.block_dp;
+       }
+       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+       assert(0);
+       return NULL;
+}
+
+static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
+{
+       struct mic_device_desc *d;
+       int i;
+       void *dp = get_dp(mic, type);
+
+       for (i = mic_aligned_size(struct mic_bootparam); i < PAGE_SIZE;
+               i += mic_total_desc_size(d)) {
+               d = dp + i;
+
+               /* End of list */
+               if (d->type == 0)
+                       break;
+
+               if (d->type == -1)
+                       continue;
+
+               mpsslog("%s %s d-> type %d d %p\n",
+                       mic->name, __func__, d->type, d);
+
+               if (d->type == (__u8)type)
+                       return d;
+       }
+       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+       assert(0);
+       return NULL;
+}
+
+/* See comments in vhost.c for explanation of next_desc() */
+static unsigned next_desc(struct vring_desc *desc)
+{
+       unsigned int next;
+
+       if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT))
+               return -1U;
+       next = le16toh(desc->next);
+       return next;
+}
+
+/* Sum up all the IOVEC length */
+static ssize_t
+sum_iovec_len(struct mic_copy_desc *copy)
+{
+       ssize_t sum = 0;
+       int i;
+
+       for (i = 0; i < copy->iovcnt; i++)
+               sum += copy->iov[i].iov_len;
+       return sum;
+}
+
+static inline void verify_out_len(struct mic_info *mic,
+       struct mic_copy_desc *copy)
+{
+       if (copy->out_len != sum_iovec_len(copy)) {
+               mpsslog("%s %s %d BUG copy->out_len 0x%x len 0x%zx\n",
+                       mic->name, __func__, __LINE__,
+                       copy->out_len, sum_iovec_len(copy));
+               assert(copy->out_len == sum_iovec_len(copy));
+       }
+}
+
+/* Display an iovec */
+static void
+disp_iovec(struct mic_info *mic, struct mic_copy_desc *copy,
+          const char *s, int line)
+{
+       int i;
+
+       for (i = 0; i < copy->iovcnt; i++)
+               mpsslog("%s %s %d copy->iov[%d] addr %p len 0x%zx\n",
+                       mic->name, s, line, i,
+                       copy->iov[i].iov_base, copy->iov[i].iov_len);
+}
+
+static inline __u16 read_avail_idx(struct mic_vring *vr)
+{
+       return ACCESS_ONCE(vr->info->avail_idx);
+}
+
+static inline void txrx_prepare(int type, bool tx, struct mic_vring *vr,
+                               struct mic_copy_desc *copy, ssize_t len)
+{
+       copy->vr_idx = tx ? 0 : 1;
+       copy->update_used = true;
+       if (type == VIRTIO_ID_NET)
+               copy->iov[1].iov_len = len - sizeof(struct virtio_net_hdr);
+       else
+               copy->iov[0].iov_len = len;
+}
+
+/* Central API which triggers the copies */
+static int
+mic_virtio_copy(struct mic_info *mic, int fd,
+               struct mic_vring *vr, struct mic_copy_desc *copy)
+{
+       int ret;
+
+       ret = ioctl(fd, MIC_VIRTIO_COPY_DESC, copy);
+       if (ret) {
+               mpsslog("%s %s %d errno %s ret %d\n",
+                       mic->name, __func__, __LINE__,
+                       strerror(errno), ret);
+       }
+       return ret;
+}
+
+/*
+ * This initialization routine requires at least one
+ * vring i.e. vr0. vr1 is optional.
+ */
+static void *
+init_vr(struct mic_info *mic, int fd, int type,
+       struct mic_vring *vr0, struct mic_vring *vr1, int num_vq)
+{
+       int vr_size;
+       char *va;
+
+       vr_size = PAGE_ALIGN(vring_size(MIC_VRING_ENTRIES,
+               MIC_VIRTIO_RING_ALIGN) + sizeof(struct _mic_vring_info));
+       va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
+               PROT_READ, MAP_SHARED, fd, 0);
+       if (MAP_FAILED == va) {
+               mpsslog("%s %s %d mmap failed errno %s\n",
+                       mic->name, __func__, __LINE__,
+                       strerror(errno));
+               goto done;
+       }
+       set_dp(mic, type, va);
+       vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
+       vr0->info = vr0->va +
+               vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
+       vring_init(&vr0->vr,
+                  MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
+       mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
+               __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);
+       if (vr1) {
+               vr1->va = (struct mic_vring *)
+                       &va[MIC_DEVICE_PAGE_END + vr_size];
+               vr1->info = vr1->va + vring_size(MIC_VRING_ENTRIES,
+                       MIC_VIRTIO_RING_ALIGN);
+               vring_init(&vr1->vr,
+                          MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
+               mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
+                       __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);
+       }
+done:
+       return va;
+}
+
+static void
+wait_for_card_driver(struct mic_info *mic, int fd, int type)
+{
+       struct pollfd pollfd;
+       int err;
+       struct mic_device_desc *desc = get_device_desc(mic, type);
+
+       pollfd.fd = fd;
+       mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
+               mic->name, __func__, type, desc->status);
+       while (1) {
+               pollfd.events = POLLIN;
+               pollfd.revents = 0;
+               err = poll(&pollfd, 1, -1);
+               if (err < 0) {
+                       mpsslog("%s %s poll failed %s\n",
+                               mic->name, __func__, strerror(errno));
+                       continue;
+               }
+
+               if (pollfd.revents) {
+                       mpsslog("%s %s Waiting... desc-> type %d status 0x%x\n",
+                               mic->name, __func__, type, desc->status);
+                       if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
+                               mpsslog("%s %s poll.revents %d\n",
+                                       mic->name, __func__, pollfd.revents);
+                               mpsslog("%s %s desc-> type %d status 0x%x\n",
+                                       mic->name, __func__, type,
+                                       desc->status);
+                               break;
+                       }
+               }
+       }
+}
+
+/* Spin till we have some descriptors */
+static void
+spin_for_descriptors(struct mic_info *mic, struct mic_vring *vr)
+{
+       __u16 avail_idx = read_avail_idx(vr);
+
+       while (avail_idx == le16toh(ACCESS_ONCE(vr->vr.avail->idx))) {
+#ifdef DEBUG
+               mpsslog("%s %s waiting for desc avail %d info_avail %d\n",
+                       mic->name, __func__,
+                       le16toh(vr->vr.avail->idx), vr->info->avail_idx);
+#endif
+               sched_yield();
+       }
+}
+
+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);
+       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]) } },
+               { { .iov_base = vnet_hdr[1], .iov_len = sizeof(vnet_hdr[1]) },
+                 { .iov_base = vnet_buf[1], .iov_len = sizeof(vnet_buf[1]) } },
+       };
+       struct iovec *iov0 = vnet_iov[0], *iov1 = vnet_iov[1];
+       struct mic_info *mic = (struct mic_info *)arg;
+       char if_name[IFNAMSIZ];
+       struct pollfd net_poll[MAX_NET_FD];
+       struct mic_vring tx_vr, rx_vr;
+       struct mic_copy_desc copy;
+       struct mic_device_desc *desc;
+       int err;
+
+       snprintf(if_name, IFNAMSIZ, "mic%d", mic->id);
+       mic->mic_net.tap_fd = tun_alloc(mic, if_name);
+       if (mic->mic_net.tap_fd < 0)
+               goto done;
+
+       if (tap_configure(mic, if_name))
+               goto done;
+       mpsslog("MIC name %s id %d\n", mic->name, mic->id);
+
+       net_poll[NET_FD_VIRTIO_NET].fd = mic->mic_net.virtio_net_fd;
+       net_poll[NET_FD_VIRTIO_NET].events = POLLIN;
+       net_poll[NET_FD_TUN].fd = mic->mic_net.tap_fd;
+       net_poll[NET_FD_TUN].events = POLLIN;
+
+       if (MAP_FAILED == init_vr(mic, mic->mic_net.virtio_net_fd,
+                                 VIRTIO_ID_NET, &tx_vr, &rx_vr,
+               virtnet_dev_page.dd.num_vq)) {
+               mpsslog("%s init_vr failed %s\n",
+                       mic->name, strerror(errno));
+               goto done;
+       }
+
+       copy.iovcnt = 2;
+       desc = get_device_desc(mic, VIRTIO_ID_NET);
+
+       while (1) {
+               ssize_t len;
+
+               net_poll[NET_FD_VIRTIO_NET].revents = 0;
+               net_poll[NET_FD_TUN].revents = 0;
+
+               /* Start polling for data from tap and virtio net */
+               err = poll(net_poll, 2, -1);
+               if (err < 0) {
+                       mpsslog("%s poll failed %s\n",
+                               __func__, strerror(errno));
+                       continue;
+               }
+               if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK))
+                       wait_for_card_driver(mic, mic->mic_net.virtio_net_fd,
+                                            VIRTIO_ID_NET);
+               /*
+                * Check if there is data to be read from TUN and write to
+                * virtio net fd if there is.
+                */
+               if (net_poll[NET_FD_TUN].revents & POLLIN) {
+                       copy.iov = iov0;
+                       len = readv(net_poll[NET_FD_TUN].fd,
+                               copy.iov, copy.iovcnt);
+                       if (len > 0) {
+                               struct virtio_net_hdr *hdr
+                                       = (struct virtio_net_hdr *)vnet_hdr[0];
+
+                               /* Disable checksums on the card since we are on
+                                  a reliable PCIe link */
+                               hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
+#ifdef DEBUG
+                               mpsslog("%s %s %d hdr->flags 0x%x ", mic->name,
+                                       __func__, __LINE__, hdr->flags);
+                               mpsslog("copy.out_len %d hdr->gso_type 0x%x\n",
+                                       copy.out_len, hdr->gso_type);
+#endif
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read from tap 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       len);
+#endif
+                               spin_for_descriptors(mic, &tx_vr);
+                               txrx_prepare(VIRTIO_ID_NET, 1, &tx_vr, &copy,
+                                            len);
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_net.virtio_net_fd, &tx_vr,
+                                       &copy);
+                               if (err < 0) {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                               }
+                               if (!err)
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d wrote to net 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       sum_iovec_len(&copy));
+#endif
+                               /* Reinitialize IOV for next run */
+                               iov0[1].iov_len = MAX_NET_PKT_SIZE;
+                       } else if (len < 0) {
+                               disp_iovec(mic, &copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read failed %s ", mic->name,
+                                       __func__, __LINE__, strerror(errno));
+                               mpsslog("cnt %d sum %zd\n",
+                                       copy.iovcnt, sum_iovec_len(&copy));
+                       }
+               }
+
+               /*
+                * Check if there is data to be read from virtio net and
+                * write to TUN if there is.
+                */
+               if (net_poll[NET_FD_VIRTIO_NET].revents & POLLIN) {
+                       while (rx_vr.info->avail_idx !=
+                               le16toh(rx_vr.vr.avail->idx)) {
+                               copy.iov = iov1;
+                               txrx_prepare(VIRTIO_ID_NET, 0, &rx_vr, &copy,
+                                            MAX_NET_PKT_SIZE
+                                       + sizeof(struct virtio_net_hdr));
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_net.virtio_net_fd, &rx_vr,
+                                       &copy);
+                               if (!err) {
+#ifdef DEBUG
+                                       struct virtio_net_hdr *hdr
+                                               = (struct virtio_net_hdr *)
+                                                       vnet_hdr[1];
+
+                                       mpsslog("%s %s %d hdr->flags 0x%x, ",
+                                               mic->name, __func__, __LINE__,
+                                               hdr->flags);
+                                       mpsslog("out_len %d gso_type 0x%x\n",
+                                               copy.out_len,
+                                               hdr->gso_type);
+#endif
+                                       /* Set the correct output iov_len */
+                                       iov1[1].iov_len = copy.out_len -
+                                               sizeof(struct virtio_net_hdr);
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                                       disp_iovec(mic, copy, __func__,
+                                                  __LINE__);
+                                       mpsslog("%s %s %d ",
+                                               mic->name, __func__, __LINE__);
+                                       mpsslog("read from net 0x%lx\n",
+                                               sum_iovec_len(copy));
+#endif
+                                       len = writev(net_poll[NET_FD_TUN].fd,
+                                               copy.iov, copy.iovcnt);
+                                       if (len != sum_iovec_len(&copy)) {
+                                               mpsslog("Tun write failed %s ",
+                                                       strerror(errno));
+                                               mpsslog("len 0x%zx ", len);
+                                               mpsslog("read_len 0x%zx\n",
+                                                       sum_iovec_len(&copy));
+                                       } else {
+#ifdef DEBUG
+                                               disp_iovec(mic, &copy, __func__,
+                                                          __LINE__);
+                                               mpsslog("%s %s %d ",
+                                                       mic->name, __func__,
+                                                       __LINE__);
+                                               mpsslog("wrote to tap 0x%lx\n",
+                                                       len);
+#endif
+                                       }
+                               } else {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                                       break;
+                               }
+                       }
+               }
+               if (net_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
+                       mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
+       }
+done:
+       pthread_exit(NULL);
+}
+
+/* virtio_console */
+#define VIRTIO_CONSOLE_FD 0
+#define MONITOR_FD (VIRTIO_CONSOLE_FD + 1)
+#define MAX_CONSOLE_FD (MONITOR_FD + 1)  /* must be the last one + 1 */
+#define MAX_BUFFER_SIZE PAGE_SIZE
+
+static void *
+virtio_console(void *arg)
+{
+       static __u8 vcons_buf[2][PAGE_SIZE];
+       struct iovec vcons_iov[2] = {
+               { .iov_base = vcons_buf[0], .iov_len = sizeof(vcons_buf[0]) },
+               { .iov_base = vcons_buf[1], .iov_len = sizeof(vcons_buf[1]) },
+       };
+       struct iovec *iov0 = &vcons_iov[0], *iov1 = &vcons_iov[1];
+       struct mic_info *mic = (struct mic_info *)arg;
+       int err;
+       struct pollfd console_poll[MAX_CONSOLE_FD];
+       int pty_fd;
+       char *pts_name;
+       ssize_t len;
+       struct mic_vring tx_vr, rx_vr;
+       struct mic_copy_desc copy;
+       struct mic_device_desc *desc;
+
+       pty_fd = posix_openpt(O_RDWR);
+       if (pty_fd < 0) {
+               mpsslog("can't open a pseudoterminal master device: %s\n",
+                       strerror(errno));
+               goto _return;
+       }
+       pts_name = ptsname(pty_fd);
+       if (pts_name == NULL) {
+               mpsslog("can't get pts name\n");
+               goto _close_pty;
+       }
+       printf("%s console message goes to %s\n", mic->name, pts_name);
+       mpsslog("%s console message goes to %s\n", mic->name, pts_name);
+       err = grantpt(pty_fd);
+       if (err < 0) {
+               mpsslog("can't grant access: %s %s\n",
+                       pts_name, strerror(errno));
+               goto _close_pty;
+       }
+       err = unlockpt(pty_fd);
+       if (err < 0) {
+               mpsslog("can't unlock a pseudoterminal: %s %s\n",
+                       pts_name, strerror(errno));
+               goto _close_pty;
+       }
+       console_poll[MONITOR_FD].fd = pty_fd;
+       console_poll[MONITOR_FD].events = POLLIN;
+
+       console_poll[VIRTIO_CONSOLE_FD].fd = mic->mic_console.virtio_console_fd;
+       console_poll[VIRTIO_CONSOLE_FD].events = POLLIN;
+
+       if (MAP_FAILED == init_vr(mic, mic->mic_console.virtio_console_fd,
+                                 VIRTIO_ID_CONSOLE, &tx_vr, &rx_vr,
+               virtcons_dev_page.dd.num_vq)) {
+               mpsslog("%s init_vr failed %s\n",
+                       mic->name, strerror(errno));
+               goto _close_pty;
+       }
+
+       copy.iovcnt = 1;
+       desc = get_device_desc(mic, VIRTIO_ID_CONSOLE);
+
+       for (;;) {
+               console_poll[MONITOR_FD].revents = 0;
+               console_poll[VIRTIO_CONSOLE_FD].revents = 0;
+               err = poll(console_poll, MAX_CONSOLE_FD, -1);
+               if (err < 0) {
+                       mpsslog("%s %d: poll failed: %s\n", __func__, __LINE__,
+                               strerror(errno));
+                       continue;
+               }
+               if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK))
+                       wait_for_card_driver(mic,
+                                            mic->mic_console.virtio_console_fd,
+                               VIRTIO_ID_CONSOLE);
+
+               if (console_poll[MONITOR_FD].revents & POLLIN) {
+                       copy.iov = iov0;
+                       len = readv(pty_fd, copy.iov, copy.iovcnt);
+                       if (len > 0) {
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read from tap 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       len);
+#endif
+                               spin_for_descriptors(mic, &tx_vr);
+                               txrx_prepare(VIRTIO_ID_CONSOLE, 1, &tx_vr,
+                                            &copy, len);
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_console.virtio_console_fd,
+                                       &tx_vr, &copy);
+                               if (err < 0) {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                               }
+                               if (!err)
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d wrote to net 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       sum_iovec_len(copy));
+#endif
+                               /* Reinitialize IOV for next run */
+                               iov0->iov_len = PAGE_SIZE;
+                       } else if (len < 0) {
+                               disp_iovec(mic, &copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read failed %s ",
+                                       mic->name, __func__, __LINE__,
+                                       strerror(errno));
+                               mpsslog("cnt %d sum %zd\n",
+                                       copy.iovcnt, sum_iovec_len(&copy));
+                       }
+               }
+
+               if (console_poll[VIRTIO_CONSOLE_FD].revents & POLLIN) {
+                       while (rx_vr.info->avail_idx !=
+                               le16toh(rx_vr.vr.avail->idx)) {
+                               copy.iov = iov1;
+                               txrx_prepare(VIRTIO_ID_CONSOLE, 0, &rx_vr,
+                                            &copy, PAGE_SIZE);
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_console.virtio_console_fd,
+                                       &rx_vr, &copy);
+                               if (!err) {
+                                       /* Set the correct output iov_len */
+                                       iov1->iov_len = copy.out_len;
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                                       disp_iovec(mic, copy, __func__,
+                                                  __LINE__);
+                                       mpsslog("%s %s %d ",
+                                               mic->name, __func__, __LINE__);
+                                       mpsslog("read from net 0x%lx\n",
+                                               sum_iovec_len(copy));
+#endif
+                                       len = writev(pty_fd,
+                                               copy.iov, copy.iovcnt);
+                                       if (len != sum_iovec_len(&copy)) {
+                                               mpsslog("Tun write failed %s ",
+                                                       strerror(errno));
+                                               mpsslog("len 0x%zx ", len);
+                                               mpsslog("read_len 0x%zx\n",
+                                                       sum_iovec_len(&copy));
+                                       } else {
+#ifdef DEBUG
+                                               disp_iovec(mic, copy, __func__,
+                                                          __LINE__);
+                                               mpsslog("%s %s %d ",
+                                                       mic->name, __func__,
+                                                       __LINE__);
+                                               mpsslog("wrote to tap 0x%lx\n",
+                                                       len);
+#endif
+                                       }
+                               } else {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                                       break;
+                               }
+                       }
+               }
+               if (console_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
+                       mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
+       }
+_close_pty:
+       close(pty_fd);
+_return:
+       pthread_exit(NULL);
+}
+
+static void
+add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd)
+{
+       char path[PATH_MAX];
+       int fd, err;
+
+       snprintf(path, PATH_MAX, "/dev/mic%d", mic->id);
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               mpsslog("Could not open %s %s\n", path, strerror(errno));
+               return;
+       }
+
+       err = ioctl(fd, MIC_VIRTIO_ADD_DEVICE, dd);
+       if (err < 0) {
+               mpsslog("Could not add %d %s\n", dd->type, strerror(errno));
+               close(fd);
+               return;
+       }
+       switch (dd->type) {
+       case VIRTIO_ID_NET:
+               mic->mic_net.virtio_net_fd = fd;
+               mpsslog("Added VIRTIO_ID_NET for %s\n", mic->name);
+               break;
+       case VIRTIO_ID_CONSOLE:
+               mic->mic_console.virtio_console_fd = fd;
+               mpsslog("Added VIRTIO_ID_CONSOLE for %s\n", mic->name);
+               break;
+       case VIRTIO_ID_BLOCK:
+               mic->mic_virtblk.virtio_block_fd = fd;
+               mpsslog("Added VIRTIO_ID_BLOCK for %s\n", mic->name);
+               break;
+       }
+}
+
+static bool
+set_backend_file(struct mic_info *mic)
+{
+       FILE *config;
+       char buff[PATH_MAX], *line, *evv, *p;
+
+       snprintf(buff, PATH_MAX, "%s/mpssd%03d.conf", mic_config_dir, mic->id);
+       config = fopen(buff, "r");
+       if (config == NULL)
+               return false;
+       do {  /* look for "virtblk_backend=XXXX" */
+               line = fgets(buff, PATH_MAX, config);
+               if (line == NULL)
+                       break;
+               if (*line == '#')
+                       continue;
+               p = strchr(line, '\n');
+               if (p)
+                       *p = '\0';
+       } while (strncmp(line, virtblk_backend, strlen(virtblk_backend)) != 0);
+       fclose(config);
+       if (line == NULL)
+               return false;
+       evv = strchr(line, '=');
+       if (evv == NULL)
+               return false;
+       mic->mic_virtblk.backend_file = malloc(strlen(evv) + 1);
+       if (mic->mic_virtblk.backend_file == NULL) {
+               mpsslog("%s %d can't allocate memory\n", mic->name, mic->id);
+               return false;
+       }
+       strcpy(mic->mic_virtblk.backend_file, evv + 1);
+       return true;
+}
+
+#define SECTOR_SIZE 512
+static bool
+set_backend_size(struct mic_info *mic)
+{
+       mic->mic_virtblk.backend_size = lseek(mic->mic_virtblk.backend, 0,
+               SEEK_END);
+       if (mic->mic_virtblk.backend_size < 0) {
+               mpsslog("%s: can't seek: %s\n",
+                       mic->name, mic->mic_virtblk.backend_file);
+               return false;
+       }
+       virtblk_dev_page.blk_config.capacity =
+               mic->mic_virtblk.backend_size / SECTOR_SIZE;
+       if ((mic->mic_virtblk.backend_size % SECTOR_SIZE) != 0)
+               virtblk_dev_page.blk_config.capacity++;
+
+       virtblk_dev_page.blk_config.capacity =
+               htole64(virtblk_dev_page.blk_config.capacity);
+
+       return true;
+}
+
+static bool
+open_backend(struct mic_info *mic)
+{
+       if (!set_backend_file(mic))
+               goto _error_exit;
+       mic->mic_virtblk.backend = open(mic->mic_virtblk.backend_file, O_RDWR);
+       if (mic->mic_virtblk.backend < 0) {
+               mpsslog("%s: can't open: %s\n", mic->name,
+                       mic->mic_virtblk.backend_file);
+               goto _error_free;
+       }
+       if (!set_backend_size(mic))
+               goto _error_close;
+       mic->mic_virtblk.backend_addr = mmap(NULL,
+               mic->mic_virtblk.backend_size,
+               PROT_READ|PROT_WRITE, MAP_SHARED,
+               mic->mic_virtblk.backend, 0L);
+       if (mic->mic_virtblk.backend_addr == MAP_FAILED) {
+               mpsslog("%s: can't map: %s %s\n",
+                       mic->name, mic->mic_virtblk.backend_file,
+                       strerror(errno));
+               goto _error_close;
+       }
+       return true;
+
+ _error_close:
+       close(mic->mic_virtblk.backend);
+ _error_free:
+       free(mic->mic_virtblk.backend_file);
+ _error_exit:
+       return false;
+}
+
+static void
+close_backend(struct mic_info *mic)
+{
+       munmap(mic->mic_virtblk.backend_addr, mic->mic_virtblk.backend_size);
+       close(mic->mic_virtblk.backend);
+       free(mic->mic_virtblk.backend_file);
+}
+
+static bool
+start_virtblk(struct mic_info *mic, struct mic_vring *vring)
+{
+       if (((unsigned long)&virtblk_dev_page.blk_config % 8) != 0) {
+               mpsslog("%s: blk_config is not 8 byte aligned.\n",
+                       mic->name);
+               return false;
+       }
+       add_virtio_device(mic, &virtblk_dev_page.dd);
+       if (MAP_FAILED == init_vr(mic, mic->mic_virtblk.virtio_block_fd,
+                                 VIRTIO_ID_BLOCK, vring, NULL,
+                                 virtblk_dev_page.dd.num_vq)) {
+               mpsslog("%s init_vr failed %s\n",
+                       mic->name, strerror(errno));
+               return false;
+       }
+       return true;
+}
+
+static void
+stop_virtblk(struct mic_info *mic)
+{
+       int vr_size, ret;
+
+       vr_size = PAGE_ALIGN(vring_size(MIC_VRING_ENTRIES,
+               MIC_VIRTIO_RING_ALIGN) + sizeof(struct _mic_vring_info));
+       ret = munmap(mic->mic_virtblk.block_dp,
+               MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
+       if (ret < 0)
+               mpsslog("%s munmap errno %d\n", mic->name, errno);
+       close(mic->mic_virtblk.virtio_block_fd);
+}
+
+static __u8
+header_error_check(struct vring_desc *desc)
+{
+       if (le32toh(desc->len) != sizeof(struct virtio_blk_outhdr)) {
+               mpsslog("%s() %d: length is not sizeof(virtio_blk_outhd)\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT)) {
+               mpsslog("%s() %d: alone\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       if (le16toh(desc->flags) & VRING_DESC_F_WRITE) {
+               mpsslog("%s() %d: not read\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       return 0;
+}
+
+static int
+read_header(int fd, struct virtio_blk_outhdr *hdr, __u32 desc_idx)
+{
+       struct iovec iovec;
+       struct mic_copy_desc copy;
+
+       iovec.iov_len = sizeof(*hdr);
+       iovec.iov_base = hdr;
+       copy.iov = &iovec;
+       copy.iovcnt = 1;
+       copy.vr_idx = 0;  /* only one vring on virtio_block */
+       copy.update_used = false;  /* do not update used index */
+       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+}
+
+static int
+transfer_blocks(int fd, struct iovec *iovec, __u32 iovcnt)
+{
+       struct mic_copy_desc copy;
+
+       copy.iov = iovec;
+       copy.iovcnt = iovcnt;
+       copy.vr_idx = 0;  /* only one vring on virtio_block */
+       copy.update_used = false;  /* do not update used index */
+       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+}
+
+static __u8
+status_error_check(struct vring_desc *desc)
+{
+       if (le32toh(desc->len) != sizeof(__u8)) {
+               mpsslog("%s() %d: length is not sizeof(status)\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       return 0;
+}
+
+static int
+write_status(int fd, __u8 *status)
+{
+       struct iovec iovec;
+       struct mic_copy_desc copy;
+
+       iovec.iov_base = status;
+       iovec.iov_len = sizeof(*status);
+       copy.iov = &iovec;
+       copy.iovcnt = 1;
+       copy.vr_idx = 0;  /* only one vring on virtio_block */
+       copy.update_used = true; /* Update used index */
+       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+}
+
+static void *
+virtio_block(void *arg)
+{
+       struct mic_info *mic = (struct mic_info *)arg;
+       int ret;
+       struct pollfd block_poll;
+       struct mic_vring vring;
+       __u16 avail_idx;
+       __u32 desc_idx;
+       struct vring_desc *desc;
+       struct iovec *iovec, *piov;
+       __u8 status;
+       __u32 buffer_desc_idx;
+       struct virtio_blk_outhdr hdr;
+       void *fos;
+
+       for (;;) {  /* forever */
+               if (!open_backend(mic)) { /* No virtblk */
+                       for (mic->mic_virtblk.signaled = 0;
+                               !mic->mic_virtblk.signaled;)
+                               sleep(1);
+                       continue;
+               }
+
+               /* backend file is specified. */
+               if (!start_virtblk(mic, &vring))
+                       goto _close_backend;
+               iovec = malloc(sizeof(*iovec) *
+                       le32toh(virtblk_dev_page.blk_config.seg_max));
+               if (!iovec) {
+                       mpsslog("%s: can't alloc iovec: %s\n",
+                               mic->name, strerror(ENOMEM));
+                       goto _stop_virtblk;
+               }
+
+               block_poll.fd = mic->mic_virtblk.virtio_block_fd;
+               block_poll.events = POLLIN;
+               for (mic->mic_virtblk.signaled = 0;
+                    !mic->mic_virtblk.signaled;) {
+                       block_poll.revents = 0;
+                                       /* timeout in 1 sec to see signaled */
+                       ret = poll(&block_poll, 1, 1000);
+                       if (ret < 0) {
+                               mpsslog("%s %d: poll failed: %s\n",
+                                       __func__, __LINE__,
+                                       strerror(errno));
+                               continue;
+                       }
+
+                       if (!(block_poll.revents & POLLIN)) {
+#ifdef DEBUG
+                               mpsslog("%s %d: block_poll.revents=0x%x\n",
+                                       __func__, __LINE__, block_poll.revents);
+#endif
+                               continue;
+                       }
+
+                       /* POLLIN */
+                       while (vring.info->avail_idx !=
+                               le16toh(vring.vr.avail->idx)) {
+                               /* read header element */
+                               avail_idx =
+                                       vring.info->avail_idx &
+                                       (vring.vr.num - 1);
+                               desc_idx = le16toh(
+                                       vring.vr.avail->ring[avail_idx]);
+                               desc = &vring.vr.desc[desc_idx];
+#ifdef DEBUG
+                               mpsslog("%s() %d: avail_idx=%d ",
+                                       __func__, __LINE__,
+                                       vring.info->avail_idx);
+                               mpsslog("vring.vr.num=%d desc=%p\n",
+                                       vring.vr.num, desc);
+#endif
+                               status = header_error_check(desc);
+                               ret = read_header(
+                                       mic->mic_virtblk.virtio_block_fd,
+                                       &hdr, desc_idx);
+                               if (ret < 0) {
+                                       mpsslog("%s() %d %s: ret=%d %s\n",
+                                               __func__, __LINE__,
+                                               mic->name, ret,
+                                               strerror(errno));
+                                       break;
+                               }
+                               /* buffer element */
+                               piov = iovec;
+                               status = 0;
+                               fos = mic->mic_virtblk.backend_addr +
+                                       (hdr.sector * SECTOR_SIZE);
+                               buffer_desc_idx = next_desc(desc);
+                               desc_idx = buffer_desc_idx;
+                               for (desc = &vring.vr.desc[buffer_desc_idx];
+                                    desc->flags & VRING_DESC_F_NEXT;
+                                    desc_idx = next_desc(desc),
+                                            desc = &vring.vr.desc[desc_idx]) {
+                                       piov->iov_len = desc->len;
+                                       piov->iov_base = fos;
+                                       piov++;
+                                       fos += desc->len;
+                               }
+                               /* Returning NULLs for VIRTIO_BLK_T_GET_ID. */
+                               if (hdr.type & ~(VIRTIO_BLK_T_OUT |
+                                       VIRTIO_BLK_T_GET_ID)) {
+                                       /*
+                                         VIRTIO_BLK_T_IN - does not do
+                                         anything. Probably for documenting.
+                                         VIRTIO_BLK_T_SCSI_CMD - for
+                                         virtio_scsi.
+                                         VIRTIO_BLK_T_FLUSH - turned off in
+                                         config space.
+                                         VIRTIO_BLK_T_BARRIER - defined but not
+                                         used in anywhere.
+                                       */
+                                       mpsslog("%s() %d: type %x ",
+                                               __func__, __LINE__,
+                                               hdr.type);
+                                       mpsslog("is not supported\n");
+                                       status = -ENOTSUP;
+
+                               } else {
+                                       ret = transfer_blocks(
+                                       mic->mic_virtblk.virtio_block_fd,
+                                               iovec,
+                                               piov - iovec);
+                                       if (ret < 0 &&
+                                           status != 0)
+                                               status = ret;
+                               }
+                               /* write status and update used pointer */
+                               if (status != 0)
+                                       status = status_error_check(desc);
+                               ret = write_status(
+                                       mic->mic_virtblk.virtio_block_fd,
+                                       &status);
+#ifdef DEBUG
+                               mpsslog("%s() %d: write status=%d on desc=%p\n",
+                                       __func__, __LINE__,
+                                       status, desc);
+#endif
+                       }
+               }
+               free(iovec);
+_stop_virtblk:
+               stop_virtblk(mic);
+_close_backend:
+               close_backend(mic);
+       }  /* forever */
+
+       pthread_exit(NULL);
+}
+
+static void
+reset(struct mic_info *mic)
+{
+#define RESET_TIMEOUT 120
+       int i = RESET_TIMEOUT;
+       setsysfs(mic->name, "state", "reset");
+       while (i) {
+               char *state;
+               state = readsysfs(mic->name, "state");
+               if (!state)
+                       goto retry;
+               mpsslog("%s: %s %d state %s\n",
+                       mic->name, __func__, __LINE__, state);
+
+               /*
+                * If the shutdown was initiated by OSPM, the state stays
+                * in "suspended" which is also a valid condition for reset.
+                */
+               if ((!strcmp(state, "offline")) ||
+                   (!strcmp(state, "suspended"))) {
+                       free(state);
+                       break;
+               }
+               free(state);
+retry:
+               sleep(1);
+               i--;
+       }
+}
+
+static int
+get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
+{
+       if (!strcmp(shutdown_status, "nop"))
+               return MIC_NOP;
+       if (!strcmp(shutdown_status, "crashed"))
+               return MIC_CRASHED;
+       if (!strcmp(shutdown_status, "halted"))
+               return MIC_HALTED;
+       if (!strcmp(shutdown_status, "poweroff"))
+               return MIC_POWER_OFF;
+       if (!strcmp(shutdown_status, "restart"))
+               return MIC_RESTART;
+       mpsslog("%s: BUG invalid status %s\n", mic->name, shutdown_status);
+       /* Invalid state */
+       assert(0);
+};
+
+static int get_mic_state(struct mic_info *mic, char *state)
+{
+       if (!strcmp(state, "offline"))
+               return MIC_OFFLINE;
+       if (!strcmp(state, "online"))
+               return MIC_ONLINE;
+       if (!strcmp(state, "shutting_down"))
+               return MIC_SHUTTING_DOWN;
+       if (!strcmp(state, "reset_failed"))
+               return MIC_RESET_FAILED;
+       if (!strcmp(state, "suspending"))
+               return MIC_SUSPENDING;
+       if (!strcmp(state, "suspended"))
+               return MIC_SUSPENDED;
+       mpsslog("%s: BUG invalid state %s\n", mic->name, state);
+       /* Invalid state */
+       assert(0);
+};
+
+static void mic_handle_shutdown(struct mic_info *mic)
+{
+#define SHUTDOWN_TIMEOUT 60
+       int i = SHUTDOWN_TIMEOUT, ret, stat = 0;
+       char *shutdown_status;
+       while (i) {
+               shutdown_status = readsysfs(mic->name, "shutdown_status");
+               if (!shutdown_status)
+                       continue;
+               mpsslog("%s: %s %d shutdown_status %s\n",
+                       mic->name, __func__, __LINE__, shutdown_status);
+               switch (get_mic_shutdown_status(mic, shutdown_status)) {
+               case MIC_RESTART:
+                       mic->restart = 1;
+               case MIC_HALTED:
+               case MIC_POWER_OFF:
+               case MIC_CRASHED:
+                       free(shutdown_status);
+                       goto reset;
+               default:
+                       break;
+               }
+               free(shutdown_status);
+               sleep(1);
+               i--;
+       }
+reset:
+       ret = kill(mic->pid, SIGTERM);
+       mpsslog("%s: %s %d kill pid %d ret %d\n",
+               mic->name, __func__, __LINE__,
+               mic->pid, ret);
+       if (!ret) {
+               ret = waitpid(mic->pid, &stat,
+                       WIFSIGNALED(stat));
+               mpsslog("%s: %s %d waitpid ret %d pid %d\n",
+                       mic->name, __func__, __LINE__,
+                       ret, mic->pid);
+       }
+       if (ret == mic->pid)
+               reset(mic);
+}
+
+static void *
+mic_config(void *arg)
+{
+       struct mic_info *mic = (struct mic_info *)arg;
+       char *state = NULL;
+       char pathname[PATH_MAX];
+       int fd, ret;
+       struct pollfd ufds[1];
+       char value[4096];
+
+       snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
+                MICSYSFSDIR, mic->name, "state");
+
+       fd = open(pathname, O_RDONLY);
+       if (fd < 0) {
+               mpsslog("%s: opening file %s failed %s\n",
+                       mic->name, pathname, strerror(errno));
+               goto error;
+       }
+
+       do {
+               ret = read(fd, value, sizeof(value));
+               if (ret < 0) {
+                       mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
+                               mic->name, pathname, strerror(errno));
+                       goto close_error1;
+               }
+retry:
+               state = readsysfs(mic->name, "state");
+               if (!state)
+                       goto retry;
+               mpsslog("%s: %s %d state %s\n",
+                       mic->name, __func__, __LINE__, state);
+               switch (get_mic_state(mic, state)) {
+               case MIC_SHUTTING_DOWN:
+                       mic_handle_shutdown(mic);
+                       goto close_error;
+               case MIC_SUSPENDING:
+                       mic->boot_on_resume = 1;
+                       setsysfs(mic->name, "state", "suspend");
+                       mic_handle_shutdown(mic);
+                       goto close_error;
+               case MIC_OFFLINE:
+                       if (mic->boot_on_resume) {
+                               setsysfs(mic->name, "state", "boot");
+                               mic->boot_on_resume = 0;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               free(state);
+
+               ufds[0].fd = fd;
+               ufds[0].events = POLLERR | POLLPRI;
+               ret = poll(ufds, 1, -1);
+               if (ret < 0) {
+                       mpsslog("%s: poll failed %s\n",
+                               mic->name, strerror(errno));
+                       goto close_error1;
+               }
+       } while (1);
+close_error:
+       free(state);
+close_error1:
+       close(fd);
+error:
+       init_mic(mic);
+       pthread_exit(NULL);
+}
+
+static void
+set_cmdline(struct mic_info *mic)
+{
+       char buffer[PATH_MAX];
+       int len;
+
+       len = snprintf(buffer, PATH_MAX,
+               "clocksource=tsc highres=off nohz=off ");
+       len += snprintf(buffer + len, PATH_MAX,
+               "cpufreq_on;corec6_off;pc3_off;pc6_off ");
+       len += snprintf(buffer + len, PATH_MAX,
+               "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
+               mic->id);
+
+       setsysfs(mic->name, "cmdline", buffer);
+       mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
+       snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id);
+       mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
+}
+
+static void
+set_log_buf_info(struct mic_info *mic)
+{
+       int fd;
+       off_t len;
+       char system_map[] = "/lib/firmware/mic/System.map";
+       char *map, *temp, log_buf[17] = {'\0'};
+
+       fd = open(system_map, O_RDONLY);
+       if (fd < 0) {
+               mpsslog("%s: Opening System.map failed: %d\n",
+                       mic->name, errno);
+               return;
+       }
+       len = lseek(fd, 0, SEEK_END);
+       if (len < 0) {
+               mpsslog("%s: Reading System.map size failed: %d\n",
+                       mic->name, errno);
+               close(fd);
+               return;
+       }
+       map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+       if (map == MAP_FAILED) {
+               mpsslog("%s: mmap of System.map failed: %d\n",
+                       mic->name, errno);
+               close(fd);
+               return;
+       }
+       temp = strstr(map, "__log_buf");
+       if (!temp) {
+               mpsslog("%s: __log_buf not found: %d\n", mic->name, errno);
+               munmap(map, len);
+               close(fd);
+               return;
+       }
+       strncpy(log_buf, temp - 19, 16);
+       setsysfs(mic->name, "log_buf_addr", log_buf);
+       mpsslog("%s: log_buf_addr: %s\n", mic->name, log_buf);
+       temp = strstr(map, "log_buf_len");
+       if (!temp) {
+               mpsslog("%s: log_buf_len not found: %d\n", mic->name, errno);
+               munmap(map, len);
+               close(fd);
+               return;
+       }
+       strncpy(log_buf, temp - 19, 16);
+       setsysfs(mic->name, "log_buf_len", log_buf);
+       mpsslog("%s: log_buf_len: %s\n", mic->name, log_buf);
+       munmap(map, len);
+       close(fd);
+}
+
+static void init_mic(struct mic_info *mic);
+
+static void
+change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
+{
+       struct mic_info *mic;
+
+       for (mic = mic_list.next; mic != NULL; mic = mic->next)
+               mic->mic_virtblk.signaled = 1/* true */;
+}
+
+static void
+init_mic(struct mic_info *mic)
+{
+       struct sigaction ignore = {
+               .sa_flags = 0,
+               .sa_handler = SIG_IGN
+       };
+       struct sigaction act = {
+               .sa_flags = SA_SIGINFO,
+               .sa_sigaction = change_virtblk_backend,
+       };
+       char buffer[PATH_MAX];
+       int err;
+
+       /*
+        * Currently, one virtio block device is supported for each MIC card
+        * at a time. Any user (or test) can send a SIGUSR1 to the MIC daemon.
+        * The signal informs the virtio block backend about a change in the
+        * configuration file which specifies the virtio backend file name on
+        * the host. Virtio block backend then re-reads the configuration file
+        * and switches to the new block device. This signalling mechanism may
+        * not be required once multiple virtio block devices are supported by
+        * the MIC daemon.
+        */
+       sigaction(SIGUSR1, &ignore, NULL);
+
+       mic->pid = fork();
+       switch (mic->pid) {
+       case 0:
+               set_log_buf_info(mic);
+               set_cmdline(mic);
+               add_virtio_device(mic, &virtcons_dev_page.dd);
+               add_virtio_device(mic, &virtnet_dev_page.dd);
+               err = pthread_create(&mic->mic_console.console_thread, NULL,
+                       virtio_console, mic);
+               if (err)
+                       mpsslog("%s virtcons pthread_create failed %s\n",
+                               mic->name, strerror(err));
+               err = pthread_create(&mic->mic_net.net_thread, NULL,
+                       virtio_net, mic);
+               if (err)
+                       mpsslog("%s virtnet pthread_create failed %s\n",
+                               mic->name, strerror(err));
+               err = pthread_create(&mic->mic_virtblk.block_thread, NULL,
+                       virtio_block, mic);
+               if (err)
+                       mpsslog("%s virtblk pthread_create failed %s\n",
+                               mic->name, strerror(err));
+               sigemptyset(&act.sa_mask);
+               err = sigaction(SIGUSR1, &act, NULL);
+               if (err)
+                       mpsslog("%s sigaction SIGUSR1 failed %s\n",
+                               mic->name, strerror(errno));
+               while (1)
+                       sleep(60);
+       case -1:
+               mpsslog("fork failed MIC name %s id %d errno %d\n",
+                       mic->name, mic->id, errno);
+               break;
+       default:
+               if (mic->restart) {
+                       snprintf(buffer, PATH_MAX, "boot");
+                       setsysfs(mic->name, "state", buffer);
+                       mpsslog("%s restarting mic %d\n",
+                               mic->name, mic->restart);
+                       mic->restart = 0;
+               }
+               pthread_create(&mic->config_thread, NULL, mic_config, mic);
+       }
+}
+
+static void
+start_daemon(void)
+{
+       struct mic_info *mic;
+
+       for (mic = mic_list.next; mic != NULL; mic = mic->next)
+               init_mic(mic);
+
+       while (1)
+               sleep(60);
+}
+
+static int
+init_mic_list(void)
+{
+       struct mic_info *mic = &mic_list;
+       struct dirent *file;
+       DIR *dp;
+       int cnt = 0;
+
+       dp = opendir(MICSYSFSDIR);
+       if (!dp)
+               return 0;
+
+       while ((file = readdir(dp)) != NULL) {
+               if (!strncmp(file->d_name, "mic", 3)) {
+                       mic->next = calloc(1, sizeof(struct mic_info));
+                       if (mic->next) {
+                               mic = mic->next;
+                               mic->id = atoi(&file->d_name[3]);
+                               mic->name = malloc(strlen(file->d_name) + 16);
+                               if (mic->name)
+                                       strcpy(mic->name, file->d_name);
+                               mpsslog("MIC name %s id %d\n", mic->name,
+                                       mic->id);
+                               cnt++;
+                       }
+               }
+       }
+
+       closedir(dp);
+       return cnt;
+}
+
+void
+mpsslog(char *format, ...)
+{
+       va_list args;
+       char buffer[4096];
+       char ts[52], *ts1;
+       time_t t;
+
+       if (logfp == NULL)
+               return;
+
+       va_start(args, format);
+       vsprintf(buffer, format, args);
+       va_end(args);
+
+       time(&t);
+       ts1 = ctime_r(&t, ts);
+       ts1[strlen(ts1) - 1] = '\0';
+       fprintf(logfp, "%s: %s", ts1, buffer);
+
+       fflush(logfp);
+}
+
+int
+main(int argc, char *argv[])
+{
+       int cnt;
+       pid_t pid;
+
+       myname = argv[0];
+
+       logfp = fopen(LOGFILE_NAME, "a+");
+       if (!logfp) {
+               fprintf(stderr, "cannot open logfile '%s'\n", LOGFILE_NAME);
+               exit(1);
+       }
+       pid = fork();
+       switch (pid) {
+       case 0:
+               break;
+       case -1:
+               exit(2);
+       default:
+               exit(0);
+       }
+
+       mpsslog("MIC Daemon start\n");
+
+       cnt = init_mic_list();
+       if (cnt == 0) {
+               mpsslog("MIC module not loaded\n");
+               exit(3);
+       }
+       mpsslog("MIC found %d devices\n", cnt);
+
+       start_daemon();
+
+       exit(0);
+}
diff --git a/Documentation/mic/mpssd/mpssd.h b/Documentation/mic/mpssd/mpssd.h
new file mode 100644 (file)
index 0000000..f5f18b1
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC User Space Tools.
+ */
+#ifndef _MPSSD_H_
+#define _MPSSD_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/dir.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <signal.h>
+#include <limits.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <net/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_tun.h>
+#include <linux/virtio_ids.h>
+
+#define MICSYSFSDIR "/sys/class/mic"
+#define LOGFILE_NAME "/var/log/mpssd"
+#define PAGE_SIZE 4096
+
+struct mic_console_info {
+       pthread_t       console_thread;
+       int             virtio_console_fd;
+       void            *console_dp;
+};
+
+struct mic_net_info {
+       pthread_t       net_thread;
+       int             virtio_net_fd;
+       int             tap_fd;
+       void            *net_dp;
+};
+
+struct mic_virtblk_info {
+       pthread_t       block_thread;
+       int             virtio_block_fd;
+       void            *block_dp;
+       volatile sig_atomic_t   signaled;
+       char            *backend_file;
+       int             backend;
+       void            *backend_addr;
+       long            backend_size;
+};
+
+struct mic_info {
+       int             id;
+       char            *name;
+       pthread_t       config_thread;
+       pid_t           pid;
+       struct mic_console_info mic_console;
+       struct mic_net_info     mic_net;
+       struct mic_virtblk_info mic_virtblk;
+       int             restart;
+       int             boot_on_resume;
+       struct mic_info *next;
+};
+
+__attribute__((format(printf, 1, 2)))
+void mpsslog(char *format, ...);
+char *readsysfs(char *dir, char *entry);
+int setsysfs(char *dir, char *entry, char *value);
+#endif
diff --git a/Documentation/mic/mpssd/sysfs.c b/Documentation/mic/mpssd/sysfs.c
new file mode 100644 (file)
index 0000000..8dd3269
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC User Space Tools.
+ */
+
+#include "mpssd.h"
+
+#define PAGE_SIZE 4096
+
+char *
+readsysfs(char *dir, char *entry)
+{
+       char filename[PATH_MAX];
+       char value[PAGE_SIZE];
+       char *string = NULL;
+       int fd;
+       int len;
+
+       if (dir == NULL)
+               snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
+       else
+               snprintf(filename, PATH_MAX,
+                        "%s/%s/%s", MICSYSFSDIR, dir, entry);
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               mpsslog("Failed to open sysfs entry '%s': %s\n",
+                       filename, strerror(errno));
+               return NULL;
+       }
+
+       len = read(fd, value, sizeof(value));
+       if (len < 0) {
+               mpsslog("Failed to read sysfs entry '%s': %s\n",
+                       filename, strerror(errno));
+               goto readsys_ret;
+       }
+       if (len == 0)
+               goto readsys_ret;
+
+       value[len - 1] = '\0';
+
+       string = malloc(strlen(value) + 1);
+       if (string)
+               strcpy(string, value);
+
+readsys_ret:
+       close(fd);
+       return string;
+}
+
+int
+setsysfs(char *dir, char *entry, char *value)
+{
+       char filename[PATH_MAX];
+       char *oldvalue;
+       int fd, ret = 0;
+
+       if (dir == NULL)
+               snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
+       else
+               snprintf(filename, PATH_MAX, "%s/%s/%s",
+                        MICSYSFSDIR, dir, entry);
+
+       oldvalue = readsysfs(dir, entry);
+
+       fd = open(filename, O_RDWR);
+       if (fd < 0) {
+               ret = errno;
+               mpsslog("Failed to open sysfs entry '%s': %s\n",
+                       filename, strerror(errno));
+               goto done;
+       }
+
+       if (!oldvalue || strcmp(value, oldvalue)) {
+               if (write(fd, value, strlen(value)) < 0) {
+                       ret = errno;
+                       mpsslog("Failed to write new sysfs entry '%s': %s\n",
+                               filename, strerror(errno));
+               }
+       }
+       close(fd);
+done:
+       if (oldvalue)
+               free(oldvalue);
+       return ret;
+}
index d718bc2ff1cfc4e1e8d54d3002657dd8400086e3..bf5dbe3ab8c51ed25fea951249af0393105d2329 100644 (file)
@@ -18,8 +18,8 @@ Introduction
 Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
 oriented protocol designed to solve issues present in UDP and TCP, particularly
 for real-time and multimedia (streaming) traffic.
-It divides into a base protocol (RFC 4340) and plugable congestion control
-modules called CCIDs. Like plugable TCP congestion control, at least one CCID
+It divides into a base protocol (RFC 4340) and pluggable congestion control
+modules called CCIDs. Like pluggable TCP congestion control, at least one CCID
 needs to be enabled in order for the protocol to function properly. In the Linux
 implementation, this is the TCP-like CCID2 (RFC 4341). Additional CCIDs, such as
 the TCP-friendly CCID3 (RFC 4342), are optional.
index 13a32124bca074b9722818809969899ff602c407..f862cf3aff3495d96f699cd666af6dbf3d18a453 100644 (file)
@@ -103,7 +103,7 @@ Additional Configurations
   PRO/100 Family of Adapters is e100.
 
   As an example, if you install the e100 driver for two PRO/100 adapters
-  (eth0 and eth1), add the following to a configuraton file in /etc/modprobe.d/
+  (eth0 and eth1), add the following to a configuration file in /etc/modprobe.d/
 
        alias eth0 e100
        alias eth1 e100
index 09eb57329f115d17d65c37eac449d0270859b0f7..22bbc7225f8ed599e8c8b51653c017a6c4845c53 100644 (file)
@@ -4,7 +4,7 @@
 
 Introduction
 ============
-The IEEE 802.15.4 working group focuses on standartization of bottom
+The IEEE 802.15.4 working group focuses on standardization of bottom
 two layers: Medium Access Control (MAC) and Physical (PHY). And there
 are mainly two options available for upper layers:
  - ZigBee - proprietary protocol from ZigBee Alliance
@@ -66,7 +66,7 @@ net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family
 code via plain sk_buffs. On skb reception skb->cb must contain additional
 info as described in the struct ieee802154_mac_cb. During packet transmission
 the skb->cb is used to provide additional data to device's header_ops->create
-function. Be aware, that this data can be overriden later (when socket code
+function. Be aware that this data can be overridden later (when socket code
 submits skb to qdisc), so if you need something from that cb later, you should
 store info in the skb->data on your own.
 
index e63fc1f7bf875ad6908b4a7ff3ade9a72f14557d..c74434de2fa50a5873c9cef9900bc47fd6431839 100644 (file)
@@ -197,7 +197,7 @@ state information because the file format is subject to change. It is
 implemented to provide extra debug information to help diagnose
 problems.) Users should use the netlink API.
 
-/proc/net/pppol2tp is also provided for backwards compaibility with
+/proc/net/pppol2tp is also provided for backwards compatibility with
 the original pppol2tp driver. It lists information about L2TPv2
 tunnels and sessions only. Its use is discouraged.
 
index d9112f01c44a384f4c076b6a0eb27f9adf7fda46..0fe1c6e0dbcd58fccdcc953477da11e2d6598358 100644 (file)
@@ -4,23 +4,23 @@ Information you need to know about netdev
 
 Q: What is netdev?
 
-A: It is a mailing list for all network related linux stuff.  This includes
+A: It is a mailing list for all network-related Linux stuff.  This includes
    anything found under net/  (i.e. core code like IPv6) and drivers/net
-   (i.e. hardware specific drivers) in the linux source tree.
+   (i.e. hardware specific drivers) in the Linux source tree.
 
    Note that some subsystems (e.g. wireless drivers) which have a high volume
    of traffic have their own specific mailing lists.
 
-   The netdev list is managed (like many other linux mailing lists) through
+   The netdev list is managed (like many other Linux mailing lists) through
    VGER ( http://vger.kernel.org/ ) and archives can be found below:
 
        http://marc.info/?l=linux-netdev
        http://www.spinics.net/lists/netdev/
 
-   Aside from subsystems like that mentioned above, all network related linux
-   development (i.e. RFC, review, comments, etc) takes place on netdev.
+   Aside from subsystems like that mentioned above, all network-related Linux
+   development (i.e. RFC, review, comments, etc.) takes place on netdev.
 
-Q: How do the changes posted to netdev make their way into linux?
+Q: How do the changes posted to netdev make their way into Linux?
 
 A: There are always two trees (git repositories) in play.  Both are driven
    by David Miller, the main network maintainer.  There is the "net" tree,
@@ -35,7 +35,7 @@ A: There are always two trees (git repositories) in play.  Both are driven
 Q: How often do changes from these trees make it to the mainline Linus tree?
 
 A: To understand this, you need to know a bit of background information
-   on the cadence of linux development.  Each new release starts off with
+   on the cadence of Linux development.  Each new release starts off with
    a two week "merge window" where the main maintainers feed their new
    stuff to Linus for merging into the mainline tree.  After the two weeks,
    the merge window is closed, and it is called/tagged "-rc1".  No new
@@ -46,7 +46,7 @@ A: To understand this, you need to know a bit of background information
    things are in a state of churn), and a week after the last vX.Y-rcN
    was done, the official "vX.Y" is released.
 
-   Relating that to netdev:  At the beginning of the 2 week merge window,
+   Relating that to netdev:  At the beginning of the 2-week merge window,
    the net-next tree will be closed - no new changes/features.  The
    accumulated new content of the past ~10 weeks will be passed onto
    mainline/Linus via a pull request for vX.Y -- at the same time,
@@ -59,16 +59,16 @@ A: To understand this, you need to know a bit of background information
    IMPORTANT:  Do not send new net-next content to netdev during the
    period during which net-next tree is closed.
 
-   Shortly after the two weeks have passed, (and vX.Y-rc1 is released) the
+   Shortly after the two weeks have passed (and vX.Y-rc1 is released), the
    tree for net-next reopens to collect content for the next (vX.Y+1) release.
 
    If you aren't subscribed to netdev and/or are simply unsure if net-next
    has re-opened yet, simply check the net-next git repository link above for
-   any new networking related commits.
+   any new networking-related commits.
 
    The "net" tree continues to collect fixes for the vX.Y content, and
    is fed back to Linus at regular (~weekly) intervals.  Meaning that the
-   focus for "net" is on stablilization and bugfixes.
+   focus for "net" is on stabilization and bugfixes.
 
    Finally, the vX.Y gets released, and the whole cycle starts over.
 
@@ -217,7 +217,7 @@ A: Attention to detail.  Re-read your own work as if you were the
    to why it happens, and then if necessary, explain why the fix proposed
    is the best way to get things done.   Don't mangle whitespace, and as
    is common, don't mis-indent function arguments that span multiple lines.
-   If it is your 1st patch, mail it to yourself so you can test apply
+   If it is your first patch, mail it to yourself so you can test apply
    it to an unpatched tree to confirm infrastructure didn't mangle it.
 
    Finally, go back and read Documentation/SubmittingPatches to be
index 533378839546f9271022189c96ee9d440b44e9ae..b26122973525f81e691f2ef05e7069647d6b7e19 100644 (file)
@@ -45,7 +45,7 @@ processing.
 
 Conversion of the reception path involves calling poll() on the file
 descriptor, once the socket is readable the frames from the ring are
-processsed in order until no more messages are available, as indicated by
+processed in order until no more messages are available, as indicated by
 a status word in the frame header.
 
 On kernel side, in order to make use of memory mapped I/O on receive, the
@@ -56,7 +56,7 @@ Dumps of kernel databases automatically support memory mapped I/O.
 
 Conversion of the transmit path involves changing message construction to
 use memory from the TX ring instead of (usually) a buffer declared on the
-stack and setting up the frame header approriately. Optionally poll() can
+stack and setting up the frame header appropriately. Optionally poll() can
 be used to wait for free frames in the TX ring.
 
 Structured and definitions for using memory mapped I/O are contained in
@@ -231,7 +231,7 @@ Ring setup:
        if (setsockopt(fd, NETLINK_TX_RING, &req, sizeof(req)) < 0)
                exit(1)
 
-       /* Calculate size of each invididual ring */
+       /* Calculate size of each individual ring */
        ring_size = req.nm_block_nr * req.nm_block_size;
 
        /* Map RX/TX rings. The TX ring is located after the RX ring */
index 97694572338be53d1cfddd03b4112e7ef6a771a8..355c6d8ef8ad7bff92071f45ebfbf085f9115df9 100644 (file)
@@ -89,8 +89,8 @@ packets. The name 'carrier' and the inversion are historical, think of
 it as lower layer.
 
 Note that for certain kind of soft-devices, which are not managing any
-real hardware, there is possible to set this bit from userpsace.
-One should use TVL IFLA_CARRIER to do so.
+real hardware, it is possible to set this bit from userspace.  One
+should use TVL IFLA_CARRIER to do so.
 
 netif_carrier_ok() can be used to query that bit.
 
index 60d05eb77c6429f883d342e95de4546c50e759a2..b89bc82eed4656430ab2d4d4a6454d08ac44624f 100644 (file)
@@ -144,7 +144,7 @@ An overview of the RxRPC protocol:
  (*) Calls use ACK packets to handle reliability.  Data packets are also
      explicitly sequenced per call.
 
- (*) There are two types of positive acknowledgement: hard-ACKs and soft-ACKs.
+ (*) There are two types of positive acknowledgment: hard-ACKs and soft-ACKs.
      A hard-ACK indicates to the far side that all the data received to a point
      has been received and processed; a soft-ACK indicates that the data has
      been received but may yet be discarded and re-requested.  The sender may
index 457b8bbafb08061a3bbe523e0875e84c8289496a..cdd916da838d44317974161311d1f81e2db2c233 100644 (file)
@@ -160,7 +160,7 @@ Where:
  o pmt: core has the embedded power module (optional).
  o force_sf_dma_mode: force DMA to use the Store and Forward mode
                     instead of the Threshold.
- o force_thresh_dma_mode: force DMA to use the Shreshold mode other than
+ o force_thresh_dma_mode: force DMA to use the Threshold mode other than
                     the Store and Forward mode.
  o riwt_off: force to disable the RX watchdog feature and switch to NAPI mode.
  o fix_mac_speed: this callback is used for modifying some syscfg registers
@@ -175,7 +175,7 @@ Where:
             registers.
  o custom_cfg/custom_data: this is a custom configuration that can be passed
                           while initializing the resources.
- o bsp_priv: another private poiter.
+ o bsp_priv: another private pointer.
 
 For MDIO bus The we have:
 
@@ -271,7 +271,7 @@ reset procedure etc).
  o dwmac1000_dma.c:  dma functions for the GMAC chip;
  o dwmac1000.h: specific header file for the GMAC;
  o dwmac100_core: MAC 100 core and dma code;
- o dwmac100_dma.c: dma funtions for the MAC chip;
+ o dwmac100_dma.c: dma functions for the MAC chip;
  o dwmac1000.h: specific header file for the MAC;
  o dwmac_lib.c: generic DMA functions shared among chips;
  o enh_desc.c: functions for handling enhanced descriptors;
@@ -364,4 +364,4 @@ Auto-negotiated Link Parter Ability.
 10) TODO:
  o XGMAC is not supported.
  o Complete the TBI & RTBI support.
- o extened VLAN support for 3.70a SYNP GMAC.
+ o extend VLAN support for 3.70a SYNP GMAC.
index 9a8041dcbb53209a1861edc4032729364a81998d..97282da82b75c150158c84172910f9765d8b7eef 100644 (file)
@@ -68,7 +68,7 @@ Module parameters
 
 There are several parameters which may be provided to the driver when
 its module is loaded.  These are usually placed in /etc/modprobe.d/*.conf
-configuretion files.  Example:
+configuration files.  Example:
 
 options 3c59x debug=3 rx_copybreak=300
 
@@ -178,7 +178,7 @@ max_interrupt_work=N
 
   The driver's interrupt service routine can handle many receive and
   transmit packets in a single invocation.  It does this in a loop. 
-  The value of max_interrupt_work governs how mnay times the interrupt
+  The value of max_interrupt_work governs how many times the interrupt
   service routine will loop.  The default value is 32 loops.  If this
   is exceeded the interrupt service routine gives up and generates a
   warning message "eth0: Too much work in interrupt".
index 78f662ee0622abb312aff56f13b97768c0bff81f..7f213b556e85aaa493aeef6e0b9e36c654c30342 100644 (file)
@@ -105,7 +105,7 @@ reduced by the following measures or a combination thereof:
     later.
     The lapb module interface was modified to support this. Its
     data_indication() method should now transparently pass the
-    netif_rx() return value to the (lapb mopdule) caller.
+    netif_rx() return value to the (lapb module) caller.
 (2) Drivers for kernel versions 2.2.x should always check the global
     variable netdev_dropping when a new frame is received. The driver
     should only call netif_rx() if netdev_dropping is zero. Otherwise
diff --git a/Documentation/phy.txt b/Documentation/phy.txt
new file mode 100644 (file)
index 0000000..0103e4b
--- /dev/null
@@ -0,0 +1,166 @@
+                           PHY SUBSYSTEM
+                 Kishon Vijay Abraham I <kishon@ti.com>
+
+This document explains the Generic PHY Framework along with the APIs provided,
+and how-to-use.
+
+1. Introduction
+
+*PHY* is the abbreviation for physical layer. It is used to connect a device
+to the physical medium e.g., the USB controller has a PHY to provide functions
+such as serialization, de-serialization, encoding, decoding and is responsible
+for obtaining the required data transmission rate. Note that some USB
+controllers have PHY functionality embedded into it and others use an external
+PHY. Other peripherals that use PHY include Wireless LAN, Ethernet,
+SATA etc.
+
+The intention of creating this framework is to bring the PHY drivers spread
+all over the Linux kernel to drivers/phy to increase code re-use and for
+better code maintainability.
+
+This framework will be of use only to devices that use external PHY (PHY
+functionality is not embedded within the controller).
+
+2. Registering/Unregistering the PHY provider
+
+PHY provider refers to an entity that implements one or more PHY instances.
+For the simple case where the PHY provider implements only a single instance of
+the PHY, the framework provides its own implementation of of_xlate in
+of_phy_simple_xlate. If the PHY provider implements multiple instances, it
+should provide its own implementation of of_xlate. of_xlate is used only for
+dt boot case.
+
+#define of_phy_provider_register(dev, xlate)    \
+        __of_phy_provider_register((dev), THIS_MODULE, (xlate))
+
+#define devm_of_phy_provider_register(dev, xlate)       \
+        __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
+
+of_phy_provider_register and devm_of_phy_provider_register macros can be used to
+register the phy_provider and it takes device and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 macros to register the PHY provider.
+
+void devm_of_phy_provider_unregister(struct device *dev,
+       struct phy_provider *phy_provider);
+void of_phy_provider_unregister(struct phy_provider *phy_provider);
+
+devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to
+unregister the PHY.
+
+3. Creating the PHY
+
+The PHY driver should create the PHY in order for other peripheral controllers
+to make use of it. The PHY framework provides 2 APIs to create the PHY.
+
+struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
+        struct phy_init_data *init_data);
+struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
+       struct phy_init_data *init_data);
+
+The PHY drivers can use one of the above 2 APIs to create the PHY by passing
+the device pointer, phy ops and init_data.
+phy_ops is a set of function pointers for performing PHY operations such as
+init, exit, power_on and power_off. *init_data* is mandatory to get a reference
+to the PHY in the case of non-dt boot. See section *Board File Initialization*
+on how init_data should be used.
+
+Inorder to dereference the private data (in phy_ops), the phy provider driver
+can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in
+phy_ops to get back the private data.
+
+4. Getting a reference to the PHY
+
+Before the controller can make use of the PHY, it has to get a reference to
+it. This framework provides the following APIs to get a reference to the PHY.
+
+struct phy *phy_get(struct device *dev, const char *string);
+struct phy *devm_phy_get(struct device *dev, const char *string);
+
+phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot,
+the string arguments should contain the phy name as given in the dt data and
+in the case of non-dt boot, it should contain the label of the PHY.
+The only difference between the two APIs is that devm_phy_get associates the
+device with the PHY using devres on successful PHY get. On driver detach,
+release function is invoked on the the devres data and devres data is freed.
+
+5. Releasing a reference to the PHY
+
+When the controller no longer needs the PHY, it has to release the reference
+to the PHY it has obtained using the APIs mentioned in the above section. The
+PHY framework provides 2 APIs to release a reference to the PHY.
+
+void phy_put(struct phy *phy);
+void devm_phy_put(struct device *dev, struct phy *phy);
+
+Both these APIs are used to release a reference to the PHY and devm_phy_put
+destroys the devres associated with this PHY.
+
+6. Destroying the PHY
+
+When the driver that created the PHY is unloaded, it should destroy the PHY it
+created using one of the following 2 APIs.
+
+void phy_destroy(struct phy *phy);
+void devm_phy_destroy(struct device *dev, struct phy *phy);
+
+Both these APIs destroy the PHY and devm_phy_destroy destroys the devres
+associated with this PHY.
+
+7. PM Runtime
+
+This subsystem is pm runtime enabled. So while creating the PHY,
+pm_runtime_enable of the phy device created by this subsystem is called and
+while destroying the PHY, pm_runtime_disable is called. Note that the phy
+device created by this subsystem will be a child of the device that calls
+phy_create (PHY provider device).
+
+So pm_runtime_get_sync of the phy_device created by this subsystem will invoke
+pm_runtime_get_sync of PHY provider device because of parent-child relationship.
+It should also be noted that phy_power_on and phy_power_off performs
+phy_pm_runtime_get_sync and phy_pm_runtime_put respectively.
+There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync,
+phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and
+phy_pm_runtime_forbid for performing PM operations.
+
+8. Board File Initialization
+
+Certain board file initialization is necessary in order to get a reference
+to the PHY in the case of non-dt boot.
+Say we have a single device that implements 3 PHYs that of USB, SATA and PCIe,
+then in the board file the following initialization should be done.
+
+struct phy_consumer consumers[] = {
+       PHY_CONSUMER("dwc3.0", "usb"),
+       PHY_CONSUMER("pcie.0", "pcie"),
+       PHY_CONSUMER("sata.0", "sata"),
+};
+PHY_CONSUMER takes 2 parameters, first is the device name of the controller
+(PHY consumer) and second is the port name.
+
+struct phy_init_data init_data = {
+       .consumers = consumers,
+       .num_consumers = ARRAY_SIZE(consumers),
+};
+
+static const struct platform_device pipe3_phy_dev = {
+       .name = "pipe3-phy",
+       .id = -1,
+       .dev = {
+               .platform_data = {
+                       .init_data = &init_data,
+               },
+       },
+};
+
+then, while doing phy_create, the PHY driver should pass this init_data
+       phy_create(dev, ops, pdata->init_data);
+
+and the controller driver (phy consumer) should pass the port name along with
+the device to get a reference to the PHY
+       phy_get(dev, "pcie");
+
+9. DeviceTree Binding
+
+The documentation for PHY dt binding can be found @
+Documentation/devicetree/bindings/phy/phy-bindings.txt
index d35dcdd82ff6a6c93b2dae00be717080b9b21cb1..c03b1be5eb1517b7b16cbddd6d2999101020ca53 100644 (file)
@@ -66,6 +66,21 @@ In LinuxPPS the PPS sources are simply char devices usually mapped
 into files /dev/pps0, /dev/pps1, etc..
 
 
+PPS with USB to serial devices
+------------------------------
+
+It is possible to grab the PPS from an USB to serial device. However,
+you should take into account the latencies and jitter introduced by
+the USB stack. Users has reported clock instability around +-1ms when
+synchronized with PPS through USB. This isn't suited for time server
+synchronization.
+
+If your device doesn't report PPS, you can check that the feature is
+supported by its driver. Most of the time, you only need to add a call
+to usb_serial_handle_dcd_change after checking the DCD status (see
+ch341 and pl2303 examples).
+
+
 Coding example
 --------------
 
index fcaf0b4efba21cfe51ed1aa4a6d9303aa614dea5..3da163383c931258641c69ce01f4f3812c97aafd 100644 (file)
@@ -157,6 +157,16 @@ Return Value:  none
 
 Description:   Sets new actual debug level if new_level is valid. 
 
+---------------------------------------------------------------------------
+bool debug_level_enabled (debug_info_t * id, int level);
+
+Parameter:    id:        handle for debug log
+             level:      debug level
+
+Return Value: True if level is less or equal to the current debug level.
+
+Description:  Returns true if debug events for the specified level would be
+             logged. Otherwise returns false.
 ---------------------------------------------------------------------------
 void debug_stop_all(void);
 
index 067c47d4691747757b9b0a36efc37d95e79df1e3..c3a7689a90e69260aa1ca76910db8a1aaa258662 100644 (file)
@@ -264,10 +264,6 @@ hardware.
        Locking: none.
        Interrupts: caller dependent.
 
-  set_wake(port,state)
-       Enable/disable power management wakeup on serial activity.  Not
-       currently implemented.
-
   type(port)
        Return a pointer to a string constant describing the specified
        port, or return NULL, in which case the string 'unknown' is
index 8cb4d7842a5ffa001eb4c0e56bed1198ffdb8d96..0e307c94809a02586d59c13ca8c56985b632cfaf 100644 (file)
@@ -11,27 +11,29 @@ regardless of whatever else it is doing, unless it is completely locked up.
 You need to say "yes" to 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' when
 configuring the kernel. When running a kernel with SysRq compiled in,
 /proc/sys/kernel/sysrq controls the functions allowed to be invoked via
-the SysRq key. By default the file contains 1 which means that every
-possible SysRq request is allowed (in older versions SysRq was disabled
-by default, and you were required to specifically enable it at run-time
-but this is not the case any more). Here is the list of possible values
-in /proc/sys/kernel/sysrq:
+the SysRq key. The default value in this file is set by the
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE config symbol, which itself defaults
+to 1. Here is the list of possible values in /proc/sys/kernel/sysrq:
    0 - disable sysrq completely
    1 - enable all functions of sysrq
   >1 - bitmask of allowed sysrq functions (see below for detailed function
        description):
-          2 - enable control of console logging level
-          4 - enable control of keyboard (SAK, unraw)
-          8 - enable debugging dumps of processes etc.
-         16 - enable sync command
-         32 - enable remount read-only
-         64 - enable signalling of processes (term, kill, oom-kill)
-        128 - allow reboot/poweroff
-        256 - allow nicing of all RT tasks
+          2 =   0x2 - enable control of console logging level
+          4 =   0x4 - enable control of keyboard (SAK, unraw)
+          8 =   0x8 - enable debugging dumps of processes etc.
+         16 =  0x10 - enable sync command
+         32 =  0x20 - enable remount read-only
+         64 =  0x40 - enable signalling of processes (term, kill, oom-kill)
+        128 =  0x80 - allow reboot/poweroff
+        256 = 0x100 - allow nicing of all RT tasks
 
 You can set the value in the file by the following command:
     echo "number" >/proc/sys/kernel/sysrq
 
+The number may be written here either as decimal or as hexadecimal
+with the 0x prefix. CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE must always be
+written in hexadecimal.
+
 Note that the value of /proc/sys/kernel/sysrq influences only the invocation
 via a keyboard. Invocation of any operation via /proc/sysrq-trigger is always
 allowed (by a user with admin privileges).
index dcd69cb34806fce523bd516b28ad1572f28eeadf..5c746dd83f3a8914137af4aedd98c24e217ab6d5 100644 (file)
@@ -763,6 +763,10 @@ W: http://maxim.org.za/at91_26.html
 W:     http://www.linux4sam.org
 S:     Supported
 F:     arch/arm/mach-at91/
+F:     arch/arm/boot/dts/at91*.dts
+F:     arch/arm/boot/dts/at91*.dtsi
+F:     arch/arm/boot/dts/sama*.dts
+F:     arch/arm/boot/dts/sama*.dtsi
 
 ARM/CALXEDA HIGHBANK ARCHITECTURE
 M:     Rob Herring <rob.herring@calxeda.com>
@@ -929,7 +933,7 @@ M:  Javier Martinez Canillas <javier@dowhile0.org>
 L:     linux-omap@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-F:     arch/arm/mach-omap2/board-igep0020.c
+F:     arch/arm/boot/dts/omap3-igep*
 
 ARM/INCOME PXA270 SUPPORT
 M:     Marek Vasut <marek.vasut@gmail.com>
@@ -1157,11 +1161,6 @@ S:       Maintained
 F:     arch/arm/mach-rockchip/
 F:     drivers/*/*rockchip*
 
-ARM/SHARK MACHINE SUPPORT
-M:     Alexander Schulz <alex@shark-linux.de>
-W:     http://www.shark-linux.de/shark.html
-S:     Maintained
-
 ARM/SAMSUNG ARM ARCHITECTURES
 M:     Ben Dooks <ben-linux@fluff.org>
 M:     Kukjin Kim <kgene.kim@samsung.com>
@@ -1169,6 +1168,8 @@ L:        linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 W:     http://www.fluff.org/ben/linux/
 S:     Maintained
+F:     arch/arm/boot/dts/s3c*
+F:     arch/arm/boot/dts/exynos*
 F:     arch/arm/plat-samsung/
 F:     arch/arm/mach-s3c24*/
 F:     arch/arm/mach-s3c64xx/
@@ -3691,6 +3692,14 @@ S:       Maintained
 F:     include/asm-generic/
 F:     include/uapi/asm-generic/
 
+GENERIC PHY FRAMEWORK
+M:     Kishon Vijay Abraham I <kishon@ti.com>
+L:     linux-kernel@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git
+S:     Supported
+F:     drivers/phy/
+F:     include/linux/phy/
+
 GENERIC UIO DRIVER FOR PCI DEVICES
 M:     "Michael S. Tsirkin" <mst@redhat.com>
 L:     kvm@vger.kernel.org
@@ -4232,7 +4241,7 @@ S:        Maintained
 F:     drivers/media/rc/iguanair.c
 
 IIO SUBSYSTEM AND DRIVERS
-M:     Jonathan Cameron <jic23@cam.ac.uk>
+M:     Jonathan Cameron <jic23@kernel.org>
 L:     linux-iio@vger.kernel.org
 S:     Maintained
 F:     drivers/iio/
@@ -4769,6 +4778,13 @@ S:       Maintained
 F:     Documentation/hwmon/k8temp
 F:     drivers/hwmon/k8temp.c
 
+KTAP
+M:     Jovi Zhangwei <jovi.zhangwei@gmail.com>
+W:     http://www.ktap.org
+L:     ktap@freelists.org
+S:     Maintained
+F:     drivers/staging/ktap/
+
 KCONFIG
 M:     Michal Marek <mmarek@suse.cz>
 L:     linux-kbuild@vger.kernel.org
@@ -6109,6 +6125,12 @@ L:       linux-omap@vger.kernel.org
 S:     Maintained
 F:     drivers/gpio/gpio-omap.c
 
+OMAP/NEWFLOW NANOBONE MACHINE SUPPORT
+M:     Mark Jackson <mpfj@newflow.co.uk>
+L:     linux-omap@vger.kernel.org
+S:     Maintained
+F:     arch/arm/boot/dts/am335x-nano.dts
+
 OMFS FILESYSTEM
 M:     Bob Copeland <me@bobcopeland.com>
 L:     linux-karma-devel@lists.sourceforge.net
@@ -6950,7 +6972,7 @@ M:        "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:     Documentation/RCU/torture.txt
-F:     kernel/rcutorture.c
+F:     kernel/rcu/torture.c
 
 RDC R-321X SoC
 M:     Florian Fainelli <florian@openwrt.org>
@@ -6977,8 +6999,9 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:     Documentation/RCU/
 X:     Documentation/RCU/torture.txt
 F:     include/linux/rcu*
-F:     kernel/rcu*
-X:     kernel/rcutorture.c
+X:     include/linux/srcu.h
+F:     kernel/rcu/
+X:     kernel/rcu/torture.c
 
 REAL TIME CLOCK (RTC) SUBSYSTEM
 M:     Alessandro Zummo <a.zummo@towertech.it>
@@ -7667,8 +7690,8 @@ M:        "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 W:     http://www.rdrop.com/users/paulmck/RCU/
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
-F:     include/linux/srcu*
-F:     kernel/srcu*
+F:     include/linux/srcu.h
+F:     kernel/rcu/srcu.c
 
 SMACK SECURITY MODULE
 M:     Casey Schaufler <casey@schaufler-ca.com>
@@ -8003,7 +8026,7 @@ S:        Maintained
 F:     drivers/staging/media/go7007/
 
 STAGING - INDUSTRIAL IO
-M:     Jonathan Cameron <jic23@cam.ac.uk>
+M:     Jonathan Cameron <jic23@kernel.org>
 L:     linux-iio@vger.kernel.org
 S:     Odd Fixes
 F:     drivers/staging/iio/
@@ -8919,61 +8942,14 @@ W:      http://pegasus2.sourceforge.net/
 S:     Maintained
 F:     drivers/net/usb/rtl8150.c
 
-USB SERIAL BELKIN F5U103 DRIVER
-M:     William Greathouse <wgreathouse@smva.com>
-L:     linux-usb@vger.kernel.org
-S:     Maintained
-F:     drivers/usb/serial/belkin_sa.*
-
-USB SERIAL CYPRESS M8 DRIVER
-M:     Lonnie Mendez <dignome@gmail.com>
-L:     linux-usb@vger.kernel.org
-S:     Maintained
-W:     http://geocities.com/i0xox0i
-W:     http://firstlight.net/cvs
-F:     drivers/usb/serial/cypress_m8.*
-
-USB SERIAL CYBERJACK DRIVER
-M:     Matthias Bruestle and Harald Welte <support@reiner-sct.com>
-W:     http://www.reiner-sct.de/support/treiber_cyberjack.php
-S:     Maintained
-F:     drivers/usb/serial/cyberjack.c
-
-USB SERIAL DIGI ACCELEPORT DRIVER
-M:     Peter Berger <pberger@brimson.com>
-M:     Al Borchers <alborchers@steinerpoint.com>
+USB SERIAL SUBSYSTEM
+M:     Johan Hovold <jhovold@gmail.com>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
-F:     drivers/usb/serial/digi_acceleport.c
-
-USB SERIAL DRIVER
-M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-L:     linux-usb@vger.kernel.org
-S:     Supported
 F:     Documentation/usb/usb-serial.txt
-F:     drivers/usb/serial/generic.c
-F:     drivers/usb/serial/usb-serial.c
+F:     drivers/usb/serial/
 F:     include/linux/usb/serial.h
 
-USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
-M:     Gary Brubaker <xavyer@ix.netcom.com>
-L:     linux-usb@vger.kernel.org
-S:     Maintained
-F:     drivers/usb/serial/empeg.c
-
-USB SERIAL KEYSPAN DRIVER
-M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-L:     linux-usb@vger.kernel.org
-S:     Maintained
-F:     drivers/usb/serial/*keyspan*
-
-USB SERIAL WHITEHEAT DRIVER
-M:     Support Department <support@connecttech.com>
-L:     linux-usb@vger.kernel.org
-W:     http://www.connecttech.com
-S:     Supported
-F:     drivers/usb/serial/whiteheat*
-
 USB SMSC75XX ETHERNET DRIVER
 M:     Steve Glendinning <steve.glendinning@shawell.net>
 L:     netdev@vger.kernel.org
index 868c0eb67b081bcedbb9a284c0fdd2ec6f1af8ee..67077ad6edbb26cbe7ea9b54efbc7ad51105548a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 12
 SUBLEVEL = 0
-EXTRAVERSION = -rc7
+EXTRAVERSION =
 NAME = One Giant Leap for Frogkind
 
 # *DOCUMENTATION*
index af2cc6eabcc781c4e8f7ee2067de75844ed5874d..ad95133f8faedd283906798781eeae14b8cc4042 100644 (file)
@@ -390,6 +390,16 @@ config HAVE_UNDERSCORE_SYMBOL_PREFIX
          Some architectures generate an _ in front of C symbols; things like
          module loading and assembly files need to know about this.
 
+config HAVE_IRQ_EXIT_ON_IRQ_STACK
+       bool
+       help
+         Architecture doesn't only execute the irq handler on the irq stack
+         but also irq_exit(). This way we can process softirqs on this irq
+         stack instead of switching to a new one when we call __do_softirq()
+         in the end of an hardirq.
+         This spares a stack switch and improves cache usage on softirq
+         processing.
+
 #
 # ABI hall of shame
 #
index 91dbb2757afd1d352d38faae2924c8861e435631..5ede5460c80692502730d69510a57975b386fe8d 100644 (file)
@@ -35,6 +35,12 @@ config ARC
        select PERF_USE_VMALLOC
        select HAVE_DEBUG_STACKOVERFLOW
 
+config TRACE_IRQFLAGS_SUPPORT
+       def_bool y
+
+config LOCKDEP_SUPPORT
+       def_bool y
+
 config SCHED_OMIT_FRAME_POINTER
        def_bool y
 
@@ -130,17 +136,14 @@ if SMP
 config ARC_HAS_COH_CACHES
        def_bool n
 
-config ARC_HAS_COH_RTSC
-       def_bool n
-
 config ARC_HAS_REENTRANT_IRQ_LV2
        def_bool n
 
 endif
 
 config NR_CPUS
-       int "Maximum number of CPUs (2-32)"
-       range 2 32
+       int "Maximum number of CPUs (2-4096)"
+       range 2 4096
        depends on SMP
        default "2"
 
@@ -326,8 +329,7 @@ config ARC_HAS_RTSC
        bool "Insn: RTSC (64-bit r/o cycle counter)"
        default y
        depends on ARC_CPU_REL_4_10
-       # if SMP, enable RTSC only if counter is coherent across cores
-       depends on !SMP || ARC_HAS_COH_RTSC
+       depends on !SMP
 
 endmenu   # "ARC CPU Configuration"
 
index 4ca50f1f8d05185e9fc83e9290fbc2731010be77..e283aa586934cdb33a2be23955e82bfce5e74394 100644 (file)
@@ -2,6 +2,8 @@ CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -62,4 +64,5 @@ CONFIG_TMPFS=y
 CONFIG_NFS_FS=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_DEBUG_PREEMPT is not set
 CONFIG_XZ_DEC=y
index e4abdaac6f9fead2fc27807602090937d20addae..2fd3162ec4df13db67b8ba62bc4a6d7e9a603763 100644 (file)
 #endif
 
 #define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)
-
-/* For a rare case where customers have differently config I/D */
-#define ARC_ICACHE_LINE_LEN    L1_CACHE_BYTES
-#define ARC_DCACHE_LINE_LEN    L1_CACHE_BYTES
-
-#define ICACHE_LINE_MASK       (~(ARC_ICACHE_LINE_LEN - 1))
-#define DCACHE_LINE_MASK       (~(ARC_DCACHE_LINE_LEN - 1))
+#define CACHE_LINE_MASK                (~(L1_CACHE_BYTES - 1))
 
 /*
  * ARC700 doesn't cache any access in top 256M.
index c0a72105ee0b0946e57a094b24fa5bbb3cb8f425..291a70db68b8b0fa0d262a79d80d7e9be9681c0e 100644 (file)
@@ -18,8 +18,8 @@
 
 #include <asm-generic/irq.h>
 
-extern void __init arc_init_IRQ(void);
-extern int __init get_hw_config_num_irq(void);
+extern void arc_init_IRQ(void);
+extern int get_hw_config_num_irq(void);
 
 void arc_local_timer_setup(unsigned int cpu);
 
index b68b53f458d1bc07f89b5b64c8f9fd9dc84ba323..cb7efc29f16ff076778c254f97d17212c0631e89 100644 (file)
@@ -151,16 +151,38 @@ static inline void arch_unmask_irq(unsigned int irq)
 
 #else
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+.macro TRACE_ASM_IRQ_DISABLE
+       bl      trace_hardirqs_off
+.endm
+
+.macro TRACE_ASM_IRQ_ENABLE
+       bl      trace_hardirqs_on
+.endm
+
+#else
+
+.macro TRACE_ASM_IRQ_DISABLE
+.endm
+
+.macro TRACE_ASM_IRQ_ENABLE
+.endm
+
+#endif
+
 .macro IRQ_DISABLE  scratch
        lr      \scratch, [status32]
        bic     \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK)
        flag    \scratch
+       TRACE_ASM_IRQ_DISABLE
 .endm
 
 .macro IRQ_ENABLE  scratch
        lr      \scratch, [status32]
        or      \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK)
        flag    \scratch
+       TRACE_ASM_IRQ_ENABLE
 .endm
 
 #endif /* __ASSEMBLY__ */
index c2663b32866b5c142dfd5c8642320dd5446fc1ea..8c84ae98c33767937ce52f33c8cab6daddabe278 100644 (file)
@@ -48,7 +48,7 @@
 #ifndef __ASSEMBLY__
 
 typedef struct {
-       unsigned long asid    /* 8 bit MMU PID + Generation cycle */
+       unsigned long asid[NR_CPUS];    /* 8 bit MMU PID + Generation cycle */
 } mm_context_t;
 
 #ifdef CONFIG_ARC_DBG_TLB_PARANOIA
index 43a1b51bb8cc90b404c8225a9b6cdcb40862a0f2..1fd467ef658fe861b34f36247674d8f3e167acad 100644 (file)
  * "Fast Context Switch" i.e. no TLB flush on ctxt-switch
  *
  * Linux assigns each task a unique ASID. A simple round-robin allocation
- * of H/w ASID is done using software tracker @asid_cache.
+ * of H/w ASID is done using software tracker @asid_cpu.
  * When it reaches max 255, the allocation cycle starts afresh by flushing
  * the entire TLB and wrapping ASID back to zero.
  *
  * A new allocation cycle, post rollover, could potentially reassign an ASID
  * to a different task. Thus the rule is to refresh the ASID in a new cycle.
- * The 32 bit @asid_cache (and mm->asid) have 8 bits MMU PID and rest 24 bits
+ * The 32 bit @asid_cpu (and mm->asid) have 8 bits MMU PID and rest 24 bits
  * serve as cycle/generation indicator and natural 32 bit unsigned math
  * automagically increments the generation when lower 8 bits rollover.
  */
 #define MM_CTXT_FIRST_CYCLE    (MM_CTXT_ASID_MASK + 1)
 #define MM_CTXT_NO_ASID                0UL
 
-#define hw_pid(mm)             (mm->context.asid & MM_CTXT_ASID_MASK)
+#define asid_mm(mm, cpu)       mm->context.asid[cpu]
+#define hw_pid(mm, cpu)                (asid_mm(mm, cpu) & MM_CTXT_ASID_MASK)
 
-extern unsigned int asid_cache;
+DECLARE_PER_CPU(unsigned int, asid_cache);
+#define asid_cpu(cpu)          per_cpu(asid_cache, cpu)
 
 /*
  * Get a new ASID if task doesn't have a valid one (unalloc or from prev cycle)
@@ -57,6 +59,7 @@ extern unsigned int asid_cache;
  */
 static inline void get_new_mmu_context(struct mm_struct *mm)
 {
+       const unsigned int cpu = smp_processor_id();
        unsigned long flags;
 
        local_irq_save(flags);
@@ -71,28 +74,28 @@ static inline void get_new_mmu_context(struct mm_struct *mm)
         *       first need to destroy the context, setting it to invalid
         *       value.
         */
-       if (!((mm->context.asid ^ asid_cache) & MM_CTXT_CYCLE_MASK))
+       if (!((asid_mm(mm, cpu) ^ asid_cpu(cpu)) & MM_CTXT_CYCLE_MASK))
                goto set_hw;
 
        /* move to new ASID and handle rollover */
-       if (unlikely(!(++asid_cache & MM_CTXT_ASID_MASK))) {
+       if (unlikely(!(++asid_cpu(cpu) & MM_CTXT_ASID_MASK))) {
 
-               flush_tlb_all();
+               local_flush_tlb_all();
 
                /*
                 * Above checke for rollover of 8 bit ASID in 32 bit container.
                 * If the container itself wrapped around, set it to a non zero
                 * "generation" to distinguish from no context
                 */
-               if (!asid_cache)
-                       asid_cache = MM_CTXT_FIRST_CYCLE;
+               if (!asid_cpu(cpu))
+                       asid_cpu(cpu) = MM_CTXT_FIRST_CYCLE;
        }
 
        /* Assign new ASID to tsk */
-       mm->context.asid = asid_cache;
+       asid_mm(mm, cpu) = asid_cpu(cpu);
 
 set_hw:
-       write_aux_reg(ARC_REG_PID, hw_pid(mm) | MMU_ENABLE);
+       write_aux_reg(ARC_REG_PID, hw_pid(mm, cpu) | MMU_ENABLE);
 
        local_irq_restore(flags);
 }
@@ -104,16 +107,45 @@ set_hw:
 static inline int
 init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
-       mm->context.asid = MM_CTXT_NO_ASID;
+       int i;
+
+       for_each_possible_cpu(i)
+               asid_mm(mm, i) = MM_CTXT_NO_ASID;
+
        return 0;
 }
 
+static inline void destroy_context(struct mm_struct *mm)
+{
+       unsigned long flags;
+
+       /* Needed to elide CONFIG_DEBUG_PREEMPT warning */
+       local_irq_save(flags);
+       asid_mm(mm, smp_processor_id()) = MM_CTXT_NO_ASID;
+       local_irq_restore(flags);
+}
+
 /* Prepare the MMU for task: setup PID reg with allocated ASID
     If task doesn't have an ASID (never alloc or stolen, get a new ASID)
 */
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                             struct task_struct *tsk)
 {
+       const int cpu = smp_processor_id();
+
+       /*
+        * Note that the mm_cpumask is "aggregating" only, we don't clear it
+        * for the switched-out task, unlike some other arches.
+        * It is used to enlist cpus for sending TLB flush IPIs and not sending
+        * it to CPUs where a task once ran-on, could cause stale TLB entry
+        * re-use, specially for a multi-threaded task.
+        * e.g. T1 runs on C1, migrates to C3. T2 running on C2 munmaps.
+        *      For a non-aggregating mm_cpumask, IPI not sent C1, and if T1
+        *      were to re-migrate to C1, it could access the unmapped region
+        *      via any existing stale TLB entries.
+        */
+       cpumask_set_cpu(cpu, mm_cpumask(next));
+
 #ifndef CONFIG_SMP
        /* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
@@ -131,11 +163,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
  */
 #define activate_mm(prev, next)                switch_mm(prev, next, NULL)
 
-static inline void destroy_context(struct mm_struct *mm)
-{
-       mm->context.asid = MM_CTXT_NO_ASID;
-}
-
 /* it seemed that deactivate_mm( ) is a reasonable place to do book-keeping
  * for retiring-mm. However destroy_context( ) still needs to do that because
  * between mm_release( ) = >deactive_mm( ) and
index 229e506814970aa0cbec36c60a8a4b62f9e0cab1..e10f8cef56a8efcaaaf1ff77190ed8125b2d3e1a 100644 (file)
@@ -31,7 +31,7 @@ struct cpuinfo_data {
 extern int root_mountflags, end_mem;
 extern int running_on_hw;
 
-void __init setup_processor(void);
+void setup_processor(void);
 void __init setup_arch_memory(void);
 
 #endif /* __ASMARC_SETUP_H */
index c4fb211dcd25bef135c78ea0683e71d9259a8c20..eefc29f08cdbe4ba0ea3f4b12d8f1234d59c0527 100644 (file)
@@ -30,7 +30,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
  * APIs provided by arch SMP code to rest of arch code
  */
 extern void __init smp_init_cpus(void);
-extern void __init first_lines_of_secondary(void);
+extern void first_lines_of_secondary(void);
 extern const char *arc_platform_smp_cpuinfo(void);
 
 /*
index b2f9bc7f68c8cb13ba73a368a321ffc2ece31c05..71c7b2e4b8745002083e71fd19ae28305d62972e 100644 (file)
@@ -18,11 +18,18 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end);
 void local_flush_tlb_range(struct vm_area_struct *vma,
                           unsigned long start, unsigned long end);
 
-/* XXX: Revisit for SMP */
+#ifndef CONFIG_SMP
 #define flush_tlb_range(vma, s, e)     local_flush_tlb_range(vma, s, e)
 #define flush_tlb_page(vma, page)      local_flush_tlb_page(vma, page)
 #define flush_tlb_kernel_range(s, e)   local_flush_tlb_kernel_range(s, e)
 #define flush_tlb_all()                        local_flush_tlb_all()
 #define flush_tlb_mm(mm)               local_flush_tlb_mm(mm)
-
+#else
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+                                                        unsigned long end);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+#endif /* CONFIG_SMP */
 #endif
index 60702f3751d2bd7077286fbb929f86c676558e1e..3e5f071bc00c7541cebf06ea00855ad53719d359 100644 (file)
@@ -22,7 +22,8 @@ static inline int
 misaligned_fixup(unsigned long address, struct pt_regs *regs,
                 struct callee_regs *cregs)
 {
-       return 0;
+       /* Not fixed */
+       return 1;
 }
 #endif
 
index 34410eb1a308e7d801abbc6ece893db54975f9c7..c14a5bea0c76792ead17b42e1f548e38960cc194 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
 
+#define KSP_WORD_OFF   ((TASK_THREAD + THREAD_KSP) / 4)
+
 struct task_struct *__sched
 __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 {
@@ -45,7 +47,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #endif
 
                /* set ksp of outgoing task in tsk->thread.ksp */
+#if KSP_WORD_OFF <= 255
                "st.as   sp, [%3, %1]    \n\t"
+#else
+               /*
+                * Workaround for NR_CPUS=4k
+                * %1 is bigger than 255 (S9 offset for st.as)
+                */
+               "add2    r24, %3, %1     \n\t"
+               "st      sp, [r24]       \n\t"
+#endif
 
                "sync   \n\t"
 
@@ -97,7 +108,7 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
                /* FP/BLINK restore generated by gcc (standard func epilogue */
 
                : "=r"(tmp)
-               : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev)
+               : "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
                : "blink"
        );
 
index d8972345e4c22ab9bd036827c76974065229cb39..65690e7fcc8cce6b3d1f76e33750f49b788d0b19 100644 (file)
@@ -14,6 +14,8 @@
 #include <asm/asm-offsets.h>
 #include <asm/linkage.h>
 
+#define KSP_WORD_OFF   ((TASK_THREAD + THREAD_KSP) / 4)
+
 ;################### Low Level Context Switch ##########################
 
        .section .sched.text,"ax",@progbits
@@ -28,8 +30,13 @@ __switch_to:
        SAVE_CALLEE_SAVED_KERNEL
 
        /* Save the now KSP in task->thread.ksp */
-       st.as  sp, [r0, (TASK_THREAD + THREAD_KSP)/4]
-
+#if KSP_WORD_OFF  <= 255
+       st.as  sp, [r0, KSP_WORD_OFF]
+#else
+       /* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */
+       add2    r24, r0, KSP_WORD_OFF
+       st      sp, [r24]
+#endif
        /*
        * Return last task in r0 (return reg)
        * On ARC, Return reg = First Arg reg = r0.
index b908dde8a331c26a00a4912309af78cf643fc05b..47d09d07f09371d62804680b18bfec19c5fbbe3d 100644 (file)
@@ -250,6 +250,14 @@ ARC_ENTRY handle_interrupt_level1
        lr  r0, [icause1]
        and r0, r0, 0x1f
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       ; icause1 needs to be read early, before calling tracing, which
+       ; can clobber scratch regs, hence use of stack to stash it
+       push r0
+       TRACE_ASM_IRQ_DISABLE
+       pop  r0
+#endif
+
        bl.d  @arch_do_IRQ
        mov r1, sp
 
@@ -337,9 +345,9 @@ ARC_ENTRY EV_TLBProtV
        ;  vineetg: Mar 6th: Random Seg Fault issue #1
        ;  ecr and efa were not saved in case an Intr sneaks in
        ;  after fake rtie
-       ;
+
        lr  r2, [ecr]
-       lr  r1, [efa]   ; Faulting Data address
+       lr  r0, [efa]   ; Faulting Data address
 
        ; --------(4) Return from CPU Exception Mode ---------
        ;  Fake a rtie, but rtie to next label
@@ -348,6 +356,8 @@ ARC_ENTRY EV_TLBProtV
 
        FAKE_RET_FROM_EXCPN r9
 
+       mov   r1, sp
+
        ;------ (5) Type of Protection Violation? ----------
        ;
        ; ProtV Hardware Exception is triggered for Access Faults of 2 types
@@ -358,16 +368,12 @@ ARC_ENTRY EV_TLBProtV
        bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f
 
        ;========= (6a) Access Violation Processing ========
-       mov r0, sp              ; pt_regs
        bl  do_page_fault
        b   ret_from_exception
 
        ;========== (6b) Non aligned access ============
 4:
-       mov r0, r1
-       mov r1, sp              ; pt_regs
 
-#ifdef  CONFIG_ARC_MISALIGN_ACCESS
        SAVE_CALLEE_SAVED_USER
        mov r2, sp              ; callee_regs
 
@@ -376,9 +382,6 @@ ARC_ENTRY EV_TLBProtV
        ; TBD: optimize - do this only if a callee reg was involved
        ; either a dst of emulated LD/ST or src with address-writeback
        RESTORE_CALLEE_SAVED_USER
-#else
-       bl  do_misaligned_error
-#endif
 
        b   ret_from_exception
 
@@ -575,6 +578,7 @@ resume_user_mode_begin:
        ; --- (Slow Path #2) pending signal  ---
        mov r0, sp      ; pt_regs for arg to do_signal()/do_notify_resume()
 
+       GET_CURR_THR_INFO_FLAGS   r9
        bbit0  r9, TIF_SIGPENDING, .Lchk_notify_resume
 
        ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
@@ -640,6 +644,8 @@ resume_kernel_mode:
 
 restore_regs :
 
+       TRACE_ASM_IRQ_ENABLE
+
        lr      r10, [status32]
 
        ; Restore REG File. In case multiple Events outstanding,
index 0f944f0245134baa37b33b32550a1fc0c528932b..2c878e964a64a0d50d90b72ad633a31f06597f29 100644 (file)
@@ -95,7 +95,7 @@ stext:
 ;----------------------------------------------------------------
 ;     First lines of code run by secondary before jumping to 'C'
 ;----------------------------------------------------------------
-       .section .init.text, "ax",@progbits
+       .section .text, "ax",@progbits
        .type first_lines_of_secondary, @function
        .globl first_lines_of_secondary
 
index 5fc92455da368132960515a7eb81faa72c7717ae..a4b141ee9a6a19c9e6e4001583fc7b6637b3f1f4 100644 (file)
@@ -39,10 +39,14 @@ void arc_init_IRQ(void)
        level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
        level_mask |= IS_ENABLED(CONFIG_ARC_IRQ6_LV2) << 6;
 
-       if (level_mask) {
+       /*
+        * Write to register, even if no LV2 IRQs configured to reset it
+        * in case bootloader had mucked with it
+        */
+       write_aux_reg(AUX_IRQ_LEV, level_mask);
+
+       if (level_mask)
                pr_info("Level-2 interrupts bitset %x\n", level_mask);
-               write_aux_reg(AUX_IRQ_LEV, level_mask);
-       }
 }
 
 /*
@@ -146,7 +150,7 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
        set_irq_regs(old_regs);
 }
 
-int __init get_hw_config_num_irq(void)
+int get_hw_config_num_irq(void)
 {
        uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR);
 
index a7698fb148180bfb17f9c5f0c7cae1f229bf216e..a2ff5c5d1450a7e58a11e2a771e42e93f01ce8e8 100644 (file)
@@ -196,6 +196,18 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
        instruction_pointer(regs) = ip;
 }
 
+static void kgdb_call_nmi_hook(void *ignored)
+{
+       kgdb_nmicallback(raw_smp_processor_id(), NULL);
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+       local_irq_enable();
+       smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+       local_irq_disable();
+}
+
 struct kgdb_arch arch_kgdb_ops = {
        /* breakpoint instruction: TRAP_S 0x3 */
 #ifdef CONFIG_CPU_BIG_ENDIAN
index 72f97822784a4627da66e835002c309b84dc14d9..eb1c2ee5eaf0a4e0b8811092568943ed96be5388 100644 (file)
@@ -87,13 +87,13 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 
 static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
        kcb->kprobe_status = kcb->prev_kprobe.status;
 }
 
 static inline void __kprobes set_current_kprobe(struct kprobe *p)
 {
-       __get_cpu_var(current_kprobe) = p;
+       __this_cpu_write(current_kprobe, p);
 }
 
 static void __kprobes resume_execution(struct kprobe *p, unsigned long addr,
@@ -237,7 +237,7 @@ int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs)
 
                return 1;
        } else if (kprobe_running()) {
-               p = __get_cpu_var(current_kprobe);
+               p = __this_cpu_read(current_kprobe);
                if (p->break_handler && p->break_handler(p, regs)) {
                        setup_singlestep(p, regs);
                        kcb->kprobe_status = KPROBE_HIT_SS;
index e227a2b1c9431fac35485c5d1e988b2a3ef3fd87..2768fa1e39b9e1ee59f6edc2975d66e65bf3a438 100644 (file)
@@ -31,3 +31,4 @@ void machine_power_off(void)
 }
 
 void (*pm_power_off) (void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
index 2c68bc7e6a784132a97d3ad6b04d8535cf546deb..d9e15f16633ebbd52e782e2ca4c6a29a6ca7eb6d 100644 (file)
@@ -37,8 +37,7 @@ struct task_struct *_current_task[NR_CPUS];   /* For stack switching */
 
 struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
 
-
-void read_arc_build_cfg_regs(void)
+static void read_arc_build_cfg_regs(void)
 {
        struct bcr_perip uncached_space;
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -106,7 +105,7 @@ static const struct cpuinfo_data arc_cpu_tbl[] = {
        { {0x00, NULL           } }
 };
 
-char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
+static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
 {
        int n = 0;
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
@@ -171,7 +170,7 @@ static const struct id_to_str mac_mul_nm[] = {
        {0x6, "Dual 16x16 and 32x16"}
 };
 
-char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
+static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
 {
        int n = 0;
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
@@ -234,7 +233,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
        return buf;
 }
 
-void arc_chk_ccms(void)
+static void arc_chk_ccms(void)
 {
 #if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -269,7 +268,7 @@ void arc_chk_ccms(void)
  * hardware has dedicated regs which need to be saved/restored on ctx-sw
  * (Single Precision uses core regs), thus kernel is kind of oblivious to it
  */
-void arc_chk_fpu(void)
+static void arc_chk_fpu(void)
 {
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
 
index bca3052c956dab7edc2c5ccffba613f7a1d5cd39..c2f9ebbc38f61f819a0194fcc08de77ebdb5beb4 100644 (file)
@@ -95,7 +95,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
  *        If it turns out to be elaborate, it's better to code it in assembly
  *
  */
-void __attribute__((weak)) arc_platform_smp_wait_to_boot(int cpu)
+void __weak arc_platform_smp_wait_to_boot(int cpu)
 {
        /*
         * As a hack for debugging - since debugger will single-step over the
@@ -128,6 +128,7 @@ void start_kernel_secondary(void)
        atomic_inc(&mm->mm_users);
        atomic_inc(&mm->mm_count);
        current->active_mm = mm;
+       cpumask_set_cpu(cpu, mm_cpumask(mm));
 
        notify_cpu_starting(cpu);
        set_cpu_online(cpu, true);
@@ -210,7 +211,6 @@ enum ipi_msg_type {
        IPI_NOP = 0,
        IPI_RESCHEDULE = 1,
        IPI_CALL_FUNC,
-       IPI_CALL_FUNC_SINGLE,
        IPI_CPU_STOP
 };
 
@@ -254,7 +254,7 @@ void smp_send_stop(void)
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-       ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+       ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC);
 }
 
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
@@ -286,10 +286,6 @@ static inline void __do_IPI(unsigned long *ops, struct ipi_data *ipi, int cpu)
                        generic_smp_call_function_interrupt();
                        break;
 
-               case IPI_CALL_FUNC_SINGLE:
-                       generic_smp_call_function_single_interrupt();
-                       break;
-
                case IPI_CPU_STOP:
                        ipi_cpu_stop(cpu);
                        break;
index f8b7d880304dcc777db967a0d344515b2e6d2453..9ce47cfe23037fa12f463a350819731422aadd9b 100644 (file)
@@ -237,11 +237,14 @@ unsigned int get_wchan(struct task_struct *tsk)
  */
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
+       /* Assumes @tsk is sleeping so unwinds from __switch_to */
        arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace);
 }
 
 void save_stack_trace(struct stack_trace *trace)
 {
-       arc_unwind_core(current, NULL, __collect_all, trace);
+       /* Pass NULL for task so it unwinds the current call frame */
+       arc_unwind_core(NULL, NULL, __collect_all, trace);
 }
+EXPORT_SYMBOL_GPL(save_stack_trace);
 #endif
index 3fde7de3ea670351ac69e0f441f35f776ebbb7d8..e5f3a837fb35f2b4a37dc162f5b2054a1008ae15 100644 (file)
 
 int arc_counter_setup(void)
 {
-       /* RTSC insn taps into cpu clk, needs no setup */
-
-       /* For SMP, only allowed if cross-core-sync, hence usable as cs */
+       /*
+        * For SMP this needs to be 0. However Kconfig glue doesn't
+        * enable this option for SMP configs
+        */
        return 1;
 }
 
@@ -206,7 +207,7 @@ static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
 
 static irqreturn_t timer_irq_handler(int irq, void *dev_id)
 {
-       struct clock_event_device *clk = &__get_cpu_var(arc_clockevent_device);
+       struct clock_event_device *clk = this_cpu_ptr(&arc_clockevent_device);
 
        arc_timer_event_ack(clk->mode == CLOCK_EVT_MODE_PERIODIC);
        clk->event_handler(clk);
@@ -223,7 +224,7 @@ static struct irqaction arc_timer_irq = {
  * Setup the local event timer for @cpu
  * N.B. weak so that some exotic ARC SoCs can completely override it
  */
-void __attribute__((weak)) arc_local_timer_setup(unsigned int cpu)
+void __weak arc_local_timer_setup(unsigned int cpu)
 {
        struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu);
 
index e21692d2fdabc35a5f1120bb26bec82c828c4d0c..3eadfdabc32295008aa899d74dab4057173ea19e 100644 (file)
@@ -84,19 +84,18 @@ DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR)
 DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
 DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
 
-#ifdef CONFIG_ARC_MISALIGN_ACCESS
 /*
  * Entry Point for Misaligned Data access Exception, for emulating in software
  */
 int do_misaligned_access(unsigned long address, struct pt_regs *regs,
                         struct callee_regs *cregs)
 {
+       /* If emulation not enabled, or failed, kill the task */
        if (misaligned_fixup(address, regs, cregs) != 0)
                return do_misaligned_error(address, regs);
 
        return 0;
 }
-#endif
 
 /*
  * Entry point for miscll errors such as Nested Exceptions
index 5a1259cd948c8ff91475f47b225aae3274e30fbd..6b58c1de757744feac1d0ae54ec1fdd0693fc500 100644 (file)
@@ -182,7 +182,7 @@ void arc_cache_init(void)
 
 #ifdef CONFIG_ARC_HAS_ICACHE
        /* 1. Confirm some of I-cache params which Linux assumes */
-       if (ic->line_len != ARC_ICACHE_LINE_LEN)
+       if (ic->line_len != L1_CACHE_BYTES)
                panic("Cache H/W doesn't match kernel Config");
 
        if (ic->ver != CONFIG_ARC_MMU_VER)
@@ -205,7 +205,7 @@ chk_dc:
                return;
 
 #ifdef CONFIG_ARC_HAS_DCACHE
-       if (dc->line_len != ARC_DCACHE_LINE_LEN)
+       if (dc->line_len != L1_CACHE_BYTES)
                panic("Cache H/W doesn't match kernel Config");
 
        /* check for D-Cache aliasing */
@@ -240,6 +240,67 @@ chk_dc:
 #define OP_INV         0x1
 #define OP_FLUSH       0x2
 #define OP_FLUSH_N_INV 0x3
+#define OP_INV_IC      0x4
+
+/*
+ * Common Helper for Line Operations on {I,D}-Cache
+ */
+static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr,
+                                    unsigned long sz, const int cacheop)
+{
+       unsigned int aux_cmd, aux_tag;
+       int num_lines;
+       const int full_page_op = __builtin_constant_p(sz) && sz == PAGE_SIZE;
+
+       if (cacheop == OP_INV_IC) {
+               aux_cmd = ARC_REG_IC_IVIL;
+               aux_tag = ARC_REG_IC_PTAG;
+       }
+       else {
+               /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
+               aux_cmd = cacheop & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL;
+               aux_tag = ARC_REG_DC_PTAG;
+       }
+
+       /* Ensure we properly floor/ceil the non-line aligned/sized requests
+        * and have @paddr - aligned to cache line and integral @num_lines.
+        * This however can be avoided for page sized since:
+        *  -@paddr will be cache-line aligned already (being page aligned)
+        *  -@sz will be integral multiple of line size (being page sized).
+        */
+       if (!full_page_op) {
+               sz += paddr & ~CACHE_LINE_MASK;
+               paddr &= CACHE_LINE_MASK;
+               vaddr &= CACHE_LINE_MASK;
+       }
+
+       num_lines = DIV_ROUND_UP(sz, L1_CACHE_BYTES);
+
+#if (CONFIG_ARC_MMU_VER <= 2)
+       /* MMUv2 and before: paddr contains stuffed vaddrs bits */
+       paddr |= (vaddr >> PAGE_SHIFT) & 0x1F;
+#else
+       /* if V-P const for loop, PTAG can be written once outside loop */
+       if (full_page_op)
+               write_aux_reg(ARC_REG_DC_PTAG, paddr);
+#endif
+
+       while (num_lines-- > 0) {
+#if (CONFIG_ARC_MMU_VER > 2)
+               /* MMUv3, cache ops require paddr seperately */
+               if (!full_page_op) {
+                       write_aux_reg(aux_tag, paddr);
+                       paddr += L1_CACHE_BYTES;
+               }
+
+               write_aux_reg(aux_cmd, vaddr);
+               vaddr += L1_CACHE_BYTES;
+#else
+               write_aux_reg(aux, paddr);
+               paddr += L1_CACHE_BYTES;
+#endif
+       }
+}
 
 #ifdef CONFIG_ARC_HAS_DCACHE
 
@@ -289,53 +350,6 @@ static inline void __dc_entire_op(const int cacheop)
                write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
 }
 
-/*
- * Per Line Operation on D-Cache
- * Doesn't deal with type-of-op/IRQ-disabling/waiting-for-flush-to-complete
- * It's sole purpose is to help gcc generate ZOL
- * (aliasing VIPT dcache flushing needs both vaddr and paddr)
- */
-static inline void __dc_line_loop(unsigned long paddr, unsigned long vaddr,
-                                 unsigned long sz, const int aux_reg)
-{
-       int num_lines;
-
-       /* Ensure we properly floor/ceil the non-line aligned/sized requests
-        * and have @paddr - aligned to cache line and integral @num_lines.
-        * This however can be avoided for page sized since:
-        *  -@paddr will be cache-line aligned already (being page aligned)
-        *  -@sz will be integral multiple of line size (being page sized).
-        */
-       if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) {
-               sz += paddr & ~DCACHE_LINE_MASK;
-               paddr &= DCACHE_LINE_MASK;
-               vaddr &= DCACHE_LINE_MASK;
-       }
-
-       num_lines = DIV_ROUND_UP(sz, ARC_DCACHE_LINE_LEN);
-
-#if (CONFIG_ARC_MMU_VER <= 2)
-       paddr |= (vaddr >> PAGE_SHIFT) & 0x1F;
-#endif
-
-       while (num_lines-- > 0) {
-#if (CONFIG_ARC_MMU_VER > 2)
-               /*
-                * Just as for I$, in MMU v3, D$ ops also require
-                * "tag" bits in DC_PTAG, "index" bits in FLDL,IVDL ops
-                */
-               write_aux_reg(ARC_REG_DC_PTAG, paddr);
-
-               write_aux_reg(aux_reg, vaddr);
-               vaddr += ARC_DCACHE_LINE_LEN;
-#else
-               /* paddr contains stuffed vaddrs bits */
-               write_aux_reg(aux_reg, paddr);
-#endif
-               paddr += ARC_DCACHE_LINE_LEN;
-       }
-}
-
 /* For kernel mappings cache operation: index is same as paddr */
 #define __dc_line_op_k(p, sz, op)      __dc_line_op(p, p, sz, op)
 
@@ -346,7 +360,6 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
                                unsigned long sz, const int cacheop)
 {
        unsigned long flags, tmp = tmp;
-       int aux;
 
        local_irq_save(flags);
 
@@ -361,12 +374,7 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
                write_aux_reg(ARC_REG_DC_CTRL, tmp | DC_CTRL_INV_MODE_FLUSH);
        }
 
-       if (cacheop & OP_INV)   /* Inv / flush-n-inv use same cmd reg */
-               aux = ARC_REG_DC_IVDL;
-       else
-               aux = ARC_REG_DC_FLDL;
-
-       __dc_line_loop(paddr, vaddr, sz, aux);
+       __cache_line_loop(paddr, vaddr, sz, cacheop);
 
        if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */
                wait_for_flush();
@@ -438,42 +446,9 @@ static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
                                unsigned long sz)
 {
        unsigned long flags;
-       int num_lines;
-
-       /*
-        * Ensure we properly floor/ceil the non-line aligned/sized requests:
-        * However page sized flushes can be compile time optimised.
-        *  -@paddr will be cache-line aligned already (being page aligned)
-        *  -@sz will be integral multiple of line size (being page sized).
-        */
-       if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) {
-               sz += paddr & ~ICACHE_LINE_MASK;
-               paddr &= ICACHE_LINE_MASK;
-               vaddr &= ICACHE_LINE_MASK;
-       }
-
-       num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN);
-
-#if (CONFIG_ARC_MMU_VER <= 2)
-       /* bits 17:13 of vaddr go as bits 4:0 of paddr */
-       paddr |= (vaddr >> PAGE_SHIFT) & 0x1F;
-#endif
 
        local_irq_save(flags);
-       while (num_lines-- > 0) {
-#if (CONFIG_ARC_MMU_VER > 2)
-               /* tag comes from phy addr */
-               write_aux_reg(ARC_REG_IC_PTAG, paddr);
-
-               /* index bits come from vaddr */
-               write_aux_reg(ARC_REG_IC_IVIL, vaddr);
-               vaddr += ARC_ICACHE_LINE_LEN;
-#else
-               /* paddr contains stuffed vaddrs bits */
-               write_aux_reg(ARC_REG_IC_IVIL, paddr);
-#endif
-               paddr += ARC_ICACHE_LINE_LEN;
-       }
+       __cache_line_loop(paddr, vaddr, sz, OP_INV_IC);
        local_irq_restore(flags);
 }
 
index d63f3de0cd5bf60e209bf00be68fb8c628862126..9c69552350c49754ee056ab854a5971b460fe5f8 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/pgalloc.h>
 #include <asm/mmu.h>
 
-static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
+static int handle_vmalloc_fault(unsigned long address)
 {
        /*
         * Synchronize this task's top level page-table
@@ -27,7 +27,7 @@ static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
        pud_t *pud, *pud_k;
        pmd_t *pmd, *pmd_k;
 
-       pgd = pgd_offset_fast(mm, address);
+       pgd = pgd_offset_fast(current->active_mm, address);
        pgd_k = pgd_offset_k(address);
 
        if (!pgd_present(*pgd_k))
@@ -52,7 +52,7 @@ bad_area:
        return 1;
 }
 
-void do_page_fault(struct pt_regs *regs, unsigned long address)
+void do_page_fault(unsigned long address, struct pt_regs *regs)
 {
        struct vm_area_struct *vma = NULL;
        struct task_struct *tsk = current;
@@ -72,7 +72,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address)
         * nothing more.
         */
        if (address >= VMALLOC_START && address <= VMALLOC_END) {
-               ret = handle_vmalloc_fault(mm, address);
+               ret = handle_vmalloc_fault(address);
                if (unlikely(ret))
                        goto bad_area_nosemaphore;
                else
index 71cb26df42555feadce79409c44d097260bd06e7..e1acf0ce56479d63be92629ad7b7c19c2ddd8950 100644 (file)
 
 
 /* A copy of the ASID from the PID reg is kept in asid_cache */
-unsigned int asid_cache = MM_CTXT_FIRST_CYCLE;
+DEFINE_PER_CPU(unsigned int, asid_cache) = MM_CTXT_FIRST_CYCLE;
 
 /*
  * Utility Routine to erase a J-TLB entry
@@ -274,6 +274,7 @@ noinline void local_flush_tlb_mm(struct mm_struct *mm)
 void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                           unsigned long end)
 {
+       const unsigned int cpu = smp_processor_id();
        unsigned long flags;
 
        /* If range @start to @end is more than 32 TLB entries deep,
@@ -297,9 +298,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 
        local_irq_save(flags);
 
-       if (vma->vm_mm->context.asid != MM_CTXT_NO_ASID) {
+       if (asid_mm(vma->vm_mm, cpu) != MM_CTXT_NO_ASID) {
                while (start < end) {
-                       tlb_entry_erase(start | hw_pid(vma->vm_mm));
+                       tlb_entry_erase(start | hw_pid(vma->vm_mm, cpu));
                        start += PAGE_SIZE;
                }
        }
@@ -346,6 +347,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 
 void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
+       const unsigned int cpu = smp_processor_id();
        unsigned long flags;
 
        /* Note that it is critical that interrupts are DISABLED between
@@ -353,14 +355,87 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
         */
        local_irq_save(flags);
 
-       if (vma->vm_mm->context.asid != MM_CTXT_NO_ASID) {
-               tlb_entry_erase((page & PAGE_MASK) | hw_pid(vma->vm_mm));
+       if (asid_mm(vma->vm_mm, cpu) != MM_CTXT_NO_ASID) {
+               tlb_entry_erase((page & PAGE_MASK) | hw_pid(vma->vm_mm, cpu));
                utlb_invalidate();
        }
 
        local_irq_restore(flags);
 }
 
+#ifdef CONFIG_SMP
+
+struct tlb_args {
+       struct vm_area_struct *ta_vma;
+       unsigned long ta_start;
+       unsigned long ta_end;
+};
+
+static inline void ipi_flush_tlb_page(void *arg)
+{
+       struct tlb_args *ta = arg;
+
+       local_flush_tlb_page(ta->ta_vma, ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_range(void *arg)
+{
+       struct tlb_args *ta = arg;
+
+       local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
+}
+
+static inline void ipi_flush_tlb_kernel_range(void *arg)
+{
+       struct tlb_args *ta = (struct tlb_args *)arg;
+
+       local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
+}
+
+void flush_tlb_all(void)
+{
+       on_each_cpu((smp_call_func_t)local_flush_tlb_all, NULL, 1);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+       on_each_cpu_mask(mm_cpumask(mm), (smp_call_func_t)local_flush_tlb_mm,
+                        mm, 1);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+       struct tlb_args ta = {
+               .ta_vma = vma,
+               .ta_start = uaddr
+       };
+
+       on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, &ta, 1);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+                    unsigned long end)
+{
+       struct tlb_args ta = {
+               .ta_vma = vma,
+               .ta_start = start,
+               .ta_end = end
+       };
+
+       on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range, &ta, 1);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+       struct tlb_args ta = {
+               .ta_start = start,
+               .ta_end = end
+       };
+
+       on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
+}
+#endif
+
 /*
  * Routine to create a TLB entry
  */
@@ -400,7 +475,7 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 
        local_irq_save(flags);
 
-       tlb_paranoid_check(vma->vm_mm->context.asid, address);
+       tlb_paranoid_check(asid_mm(vma->vm_mm, smp_processor_id()), address);
 
        address &= PAGE_MASK;
 
@@ -610,9 +685,9 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
                          struct pt_regs *regs)
 {
        int set, way, n;
-       unsigned int pd0[4], pd1[4];    /* assume max 4 ways */
        unsigned long flags, is_valid;
        struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
+       unsigned int pd0[mmu->ways], pd1[mmu->ways];
 
        local_irq_save(flags);
 
@@ -637,7 +712,7 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
                        continue;
 
                /* Scan the set for duplicate ways: needs a nested loop */
-               for (way = 0; way < mmu->ways; way++) {
+               for (way = 0; way < mmu->ways - 1; way++) {
                        if (!pd0[way])
                                continue;
 
index cf7d7d9ad695c2e607ab10a9f0423215f079b1f7..3fcfdb38d242d47512a5aa9a174434d25d6e6450 100644 (file)
@@ -369,8 +369,8 @@ do_slow_path_pf:
        EXCEPTION_PROLOGUE
 
        ; ------- setup args for Linux Page fault Hanlder ---------
-       mov_s r0, sp
-       lr  r1, [efa]
+       mov_s r1, sp
+       lr    r0, [efa]
 
        ; We don't want exceptions to be disabled while the fault is handled.
        ; Now that we have saved the context we return from exception hence
index 1ad6fb6c094db415ec76a72a28356e75bdfd7d17..04163fece49fea0662fcd338814aab1177842732 100644 (file)
@@ -317,6 +317,7 @@ config ARCH_INTEGRATOR
        select NEED_MACH_MEMORY_H
        select PLAT_VERSATILE
        select SPARSE_IRQ
+       select USE_OF
        select VERSATILE_FPGA_IRQ
        help
          Support for ARM's Integrator platform.
@@ -358,7 +359,6 @@ config ARCH_AT91
        bool "Atmel AT91"
        select ARCH_REQUIRE_GPIOLIB
        select CLKDEV_LOOKUP
-       select HAVE_CLK
        select IRQ_DOMAIN
        select NEED_MACH_GPIO_H
        select NEED_MACH_IO_H if PCCARD
@@ -372,7 +372,6 @@ config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
        select ARCH_REQUIRE_GPIOLIB
        select AUTO_ZRELADDR
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select COMMON_CLK
        select CPU_ARM720T
@@ -386,8 +385,9 @@ config ARCH_CLPS711X
 config ARCH_GEMINI
        bool "Cortina Systems Gemini"
        select ARCH_REQUIRE_GPIOLIB
-       select ARCH_USES_GETTIMEOFFSET
+       select CLKSRC_MMIO
        select CPU_FA526
+       select GENERIC_CLOCKEVENTS
        select NEED_MACH_GPIO_H
        help
          Support for the Cortina Systems Gemini family SoCs
@@ -631,7 +631,6 @@ config ARCH_PXA
 config ARCH_MSM
        bool "Qualcomm MSM"
        select ARCH_REQUIRE_GPIOLIB
-       select CLKDEV_LOOKUP
        select CLKSRC_OF if OF
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
@@ -649,7 +648,6 @@ config ARCH_SHMOBILE
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_CLK
        select HAVE_MACH_CLKDEV
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
@@ -706,7 +704,6 @@ config ARCH_S3C24XX
        select CLKSRC_SAMSUNG_PWM
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
-       select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select HAVE_S3C_RTC if RTC_CLASS
@@ -727,21 +724,22 @@ config ARCH_S3C64XX
        select ARM_VIC
        select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
+       select COMMON_CLK
        select CPU_V6
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
-       select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select HAVE_TCM
        select NEED_MACH_GPIO_H
        select NO_IOPORT
        select PLAT_SAMSUNG
+       select PM_GENERIC_DOMAINS
        select S3C_DEV_NAND
        select S3C_GPIO_TRACK
        select SAMSUNG_ATAGS
-       select SAMSUNG_CLKSRC
        select SAMSUNG_GPIOLIB_4BIT
+       select SAMSUNG_WAKEMASK
        select SAMSUNG_WDT_RESET
        select USB_ARCH_HAS_OHCI
        help
@@ -754,7 +752,6 @@ config ARCH_S5P64X0
        select CPU_V6
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
-       select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select HAVE_S3C_RTC if RTC_CLASS
@@ -773,7 +770,6 @@ config ARCH_S5PC100
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
-       select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select HAVE_S3C_RTC if RTC_CLASS
@@ -793,7 +789,6 @@ config ARCH_S5PV210
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
-       select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select HAVE_S3C_RTC if RTC_CLASS
@@ -810,11 +805,9 @@ config ARCH_EXYNOS
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_SPARSEMEM_ENABLE
        select ARM_GIC
-       select CLKDEV_LOOKUP
        select COMMON_CLK
        select CPU_V7
        select GENERIC_CLOCKEVENTS
-       select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select HAVE_S3C_RTC if RTC_CLASS
@@ -824,20 +817,6 @@ config ARCH_EXYNOS
        help
          Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
 
-config ARCH_SHARK
-       bool "Shark"
-       select ARCH_USES_GETTIMEOFFSET
-       select CPU_SA110
-       select ISA
-       select ISA_DMA
-       select NEED_MACH_MEMORY_H
-       select PCI
-       select VIRT_TO_BUS
-       select ZONE_DMA
-       help
-         Support for the StrongARM based Digital DNARD machine, also known
-         as "Shark" (<http://www.shark-linux.de/shark.html>).
-
 config ARCH_DAVINCI
        bool "TI DaVinci"
        select ARCH_HAS_HOLES_MEMORYMODEL
@@ -847,7 +826,6 @@ config ARCH_DAVINCI
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
        select HAVE_IDE
-       select NEED_MACH_GPIO_H
        select TI_PRIV_EDMA
        select USE_OF
        select ZONE_DMA
@@ -865,7 +843,6 @@ config ARCH_OMAP1
        select CLKSRC_MMIO
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select HAVE_CLK
        select HAVE_IDE
        select IRQ_DOMAIN
        select NEED_MACH_IO_H if PCCARD
@@ -1009,9 +986,7 @@ source "arch/arm/mach-sti/Kconfig"
 
 source "arch/arm/mach-s3c24xx/Kconfig"
 
-if ARCH_S3C64XX
 source "arch/arm/mach-s3c64xx/Kconfig"
-endif
 
 source "arch/arm/mach-s5p64x0/Kconfig"
 
@@ -1431,12 +1406,6 @@ config PCI_NANOENGINE
 config PCI_SYSCALL
        def_bool PCI
 
-# Select the host bridge type
-config PCI_HOST_VIA82C505
-       bool
-       depends on PCI && ARCH_SHARK
-       default y
-
 config PCI_HOST_ITE8152
        bool
        depends on PCI && MACH_ARMCORE
index 9762c84b419845f05ee6a7d1f9f95084dde310b5..d597c6b8488ba257fa37319d9afc7dc6362933a7 100644 (file)
@@ -386,6 +386,13 @@ choice
                  when u-boot hands over to the kernel, the system
                  silently crashes, with no serial output at all.
 
+       config DEBUG_VF_UART
+               bool "Vybrid UART"
+               depends on SOC_VF610
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on Vybrid based platforms.
+
        config DEBUG_NOMADIK_UART
                bool "Kernel low-level debugging messages via NOMADIK UART"
                depends on ARCH_NOMADIK
@@ -906,6 +913,7 @@ config DEBUG_LL_INCLUDE
        default "debug/tegra.S" if DEBUG_TEGRA_UART
        default "debug/ux500.S" if DEBUG_UX500_UART
        default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT
+       default "debug/vf.S" if DEBUG_VF_UART
        default "debug/vt8500.S" if DEBUG_VT8500_UART0
        default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
        default "mach/debug-macro.S"
index db50b626be9871f7426ee394a9b189d8d504c8a3..8b667132d7b419bb572549d3f5149c7f9e503860 100644 (file)
@@ -188,7 +188,6 @@ machine-$(CONFIG_ARCH_S5P64X0)              += s5p64x0
 machine-$(CONFIG_ARCH_S5PC100)         += s5pc100
 machine-$(CONFIG_ARCH_S5PV210)         += s5pv210
 machine-$(CONFIG_ARCH_SA1100)          += sa1100
-machine-$(CONFIG_ARCH_SHARK)           += shark
 machine-$(CONFIG_ARCH_SHMOBILE)        += shmobile
 machine-$(CONFIG_ARCH_SHMOBILE_MULTI)  += shmobile
 machine-$(CONFIG_ARCH_SIRF)            += prima2
index 7ac1610252baad07ce50c2a9381da25965952fdc..e7190bb5998e149906a4763e815712953c7421f5 100644 (file)
@@ -44,10 +44,6 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
 OBJS           += ll_char_wr.o font.o
 endif
 
-ifeq ($(CONFIG_ARCH_SHARK),y)
-OBJS           += head-shark.o ofw-shark.o
-endif
-
 ifeq ($(CONFIG_ARCH_SA1100),y)
 OBJS           += head-sa1100.o
 endif
diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S
deleted file mode 100644 (file)
index 92b5689..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* The head-file for the Shark
- * by Alexander Schulz
- *
- * Does the following:
- * - get the memory layout from firmware. This can only be done as long as the mmu
- *   is still on.
- * - switch the mmu off, so we have physical addresses
- * - copy the kernel to 0x08508000. This is done to have a fixed address where the
- *   C-parts (misc.c) are executed. This address must be known at compile-time,
- *   but the load-address of the kernel depends on how much memory is installed.
- * - Jump to this location.
- * - Set r8 with 0, r7 with the architecture ID for head.S
- */
-
-#include <linux/linkage.h>
-
-#include <asm/assembler.h>
-       
-               .section        ".start", "ax"
-
-               .arch armv4
-               b       __beginning
-       
-__ofw_data:    .long   0                               @ the number of memory blocks
-               .space  128                             @ (startaddr,size) ...
-               .space  128                             @ bootargs
-               .align
-
-__beginning:   mov     r4, r0                          @ save the entry to the firmware
-
-               mov     r0, #0xC0                       @ disable irq and fiq
-               mov     r1, r0
-               mrs     r3, cpsr
-               bic     r2, r3, r0
-               eor     r2, r2, r1
-               msr     cpsr_c, r2
-
-               mov     r0, r4                          @ get the Memory layout from firmware
-               adr     r1, __ofw_data
-               add     r2, r1, #4
-               mov     lr, pc
-               b       ofw_init
-               mov     r1, #0
-
-               adr     r2, __mmu_off                   @ calculate physical address
-               sub     r2, r2, #0xf0000000             @ openprom maps us at f000 virt, 0e50 phys
-               adr     r0, __ofw_data
-               ldr     r0, [r0, #4]
-               add     r2, r2, r0
-               add     r2, r2, #0x00500000
-
-               mrc     p15, 0, r3, c1, c0
-               bic     r3, r3, #0xC                    @ Write Buffer and DCache
-               bic     r3, r3, #0x1000                 @ ICache
-               mcr     p15, 0, r3, c1, c0              @ disabled
-
-               mov     r0, #0
-               mcr     p15, 0, r0, c7, c7              @ flush I,D caches on v4
-               mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
-               mcr     p15, 0, r0, c8, c7              @ flush I,D TLBs on v4
-
-               bic     r3, r3, #0x1                    @ MMU
-               mcr     p15, 0, r3, c1, c0              @ disabled
-
-               mov     pc, r2
-
-__copy_target: .long   0x08507FFC
-__copy_end:    .long   0x08607FFC
-               
-               .word   _start
-               .word   __bss_start
-
-               .align
-__temp_stack:  .space 128
-
-__mmu_off:
-               adr     r0, __ofw_data                  @ read the 1. entry of the memory map
-               ldr     r0, [r0, #4]
-               orr     r0, r0, #0x00600000
-               sub     r0, r0, #4
-       
-               ldr     r1, __copy_end
-               ldr     r3, __copy_target
-
-/* r0 = 0x0e600000 (current end of kernelcode)
- * r3 = 0x08508000 (where it should begin)
- * r1 = 0x08608000 (end of copying area, 1MB)
- * The kernel is compressed, so 1 MB should be enough.
- * copy the kernel to the beginning of physical memory
- * We start from the highest address, so we can copy
- * from 0x08500000 to 0x08508000 if we have only 8MB
- */
-
-/* As we get more 2.6-kernels it gets more and more
- * uncomfortable to be bound to kernel images of 1MB only.
- * So we add a loop here, to be able to copy some more.
- * Alexander Schulz 2005-07-17
- */
-
-               mov     r4, #3                          @ How many megabytes to copy
-
-
-__MoveCode:    sub     r4, r4, #1
-       
-__Copy:                ldr     r2, [r0], #-4
-               str     r2, [r1], #-4
-               teq     r1, r3
-               bne     __Copy
-
-               /* The firmware maps us in blocks of 1 MB, the next block is
-                  _below_ the last one. So our decrementing source pointer
-                  ist right here, but the destination pointer must be increased
-                  by 2 MB */
-               add     r1, r1, #0x00200000
-               add     r3, r3, #0x00100000
-
-               teq     r4, #0
-               bne     __MoveCode
-
-
-               /* and jump to it */
-               adr     r2, __go_on                     @ where we want to jump
-               adr     r0, __ofw_data                  @ read the 1. entry of the memory map
-               ldr     r0, [r0, #4]
-               sub     r2, r2, r0                      @ we are mapped add 0e50 now, sub that (-0e00)
-               sub     r2, r2, #0x00500000             @ -0050
-               ldr     r0, __copy_target               @ and add 0850 8000 instead
-               add     r0, r0, #4
-               add     r2, r2, r0
-               mov     pc, r2                          @ and jump there
-
-__go_on:
-               adr     sp, __temp_stack
-               add     sp, sp, #128
-               adr     r0, __ofw_data
-               mov     lr, pc
-               b       create_params
-       
-               mov     r8, #0
-               mov     r7, #15
diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c
deleted file mode 100644 (file)
index 465c54b..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/ofw-shark.c
- *
- * by Alexander Schulz
- *
- * This file is used to get some basic information
- * about the memory layout of the shark we are running
- * on. Memory is usually divided in blocks a 8 MB.
- * And bootargs are copied from OpenFirmware.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <asm/setup.h>
-#include <asm/page.h>
-
-
-asmlinkage void
-create_params (unsigned long *buffer)
-{
-       /* Is there a better address? Also change in mach-shark/core.c */
-       struct tag *tag = (struct tag *) 0x08003000;
-       int j,i,m,k,nr_banks,size;
-       unsigned char *c;
-
-       k = 0;
-
-       /* Head of the taglist */
-       tag->hdr.tag  = ATAG_CORE;
-       tag->hdr.size = tag_size(tag_core);
-       tag->u.core.flags = 1;
-       tag->u.core.pagesize = PAGE_SIZE;
-       tag->u.core.rootdev = 0;
-
-       /* Build up one tagged block for each memory region */
-       size=0;
-       nr_banks=(unsigned int) buffer[0];
-       for (j=0;j<nr_banks;j++){
-               /* search the lowest address and put it into the next entry   */
-               /* not a fast sort algorithm, but there are at most 8 entries */
-               /* and this is used only once anyway                          */
-               m=0xffffffff;
-               for (i=0;i<(unsigned int) buffer[0];i++){
-                       if (buffer[2*i+1]<m) {
-                               m=buffer[2*i+1];
-                               k=i;
-                       }
-               }
-         
-               tag = tag_next(tag);
-               tag->hdr.tag = ATAG_MEM;
-               tag->hdr.size = tag_size(tag_mem32);
-               tag->u.mem.size = buffer[2*k+2];
-               tag->u.mem.start = buffer[2*k+1];
-
-               size += buffer[2*k+2];
-
-               buffer[2*k+1]=0xffffffff;                    /* mark as copied */
-       }
-       
-       /* The command line */
-       tag = tag_next(tag);
-       tag->hdr.tag = ATAG_CMDLINE;
-       
-       c=(unsigned char *)(&buffer[34]);
-       j=0;
-       while (*c) tag->u.cmdline.cmdline[j++]=*c++;
-
-       tag->u.cmdline.cmdline[j]=0;
-       tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
-
-       /* Hardware revision */
-       tag = tag_next(tag);
-       tag->hdr.tag = ATAG_REVISION;
-       tag->hdr.size = tag_size(tag_revision);
-       tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
-
-       /* End of the taglist */
-       tag = tag_next(tag);
-       tag->hdr.tag = 0;
-       tag->hdr.size = 0;
-}
-
-
-typedef int (*ofw_handle_t)(void *);
-
-/* Everything below is called with a wrong MMU setting.
- * This means: no string constants, no initialization of
- * arrays, no global variables! This is ugly but I didn't
- * want to write this in assembler :-)
- */
-
-int
-of_decode_int(const unsigned char *p)
-{
-       unsigned int i = *p++ << 8;
-       i = (i + *p++) << 8;
-       i = (i + *p++) << 8;
-       return (i + *p);
-}
-  
-int
-OF_finddevice(ofw_handle_t openfirmware, char *name)
-{
-       unsigned int args[8];
-       char service[12];
-
-       service[0]='f';
-       service[1]='i';
-       service[2]='n';
-       service[3]='d';
-       service[4]='d';
-       service[5]='e';
-       service[6]='v';
-       service[7]='i';
-       service[8]='c';
-       service[9]='e';
-       service[10]='\0';
-
-       args[0]=(unsigned int)service;
-       args[1]=1;
-       args[2]=1;
-       args[3]=(unsigned int)name;
-
-       if (openfirmware(args) == -1)
-               return -1;
-       return args[4];
-}
-
-int
-OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
-{
-       unsigned int args[8];
-       char service[12];
-
-       service[0]='g';
-       service[1]='e';
-       service[2]='t';
-       service[3]='p';
-       service[4]='r';
-       service[5]='o';
-       service[6]='p';
-       service[7]='l';
-       service[8]='e';
-       service[9]='n';
-       service[10]='\0';
-
-       args[0] = (unsigned int)service;
-       args[1] = 2;
-       args[2] = 1;
-       args[3] = (unsigned int)handle;
-       args[4] = (unsigned int)prop;
-
-       if (openfirmware(args) == -1)
-               return -1;
-       return args[5];
-}
-  
-int
-OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
-{
-       unsigned int args[8];
-       char service[8];
-
-       service[0]='g';
-       service[1]='e';
-       service[2]='t';
-       service[3]='p';
-       service[4]='r';
-       service[5]='o';
-       service[6]='p';
-       service[7]='\0';
-
-       args[0] = (unsigned int)service;
-       args[1] = 4;
-       args[2] = 1;
-       args[3] = (unsigned int)handle;
-       args[4] = (unsigned int)prop;
-       args[5] = (unsigned int)buf;
-       args[6] = buflen;
-
-       if (openfirmware(args) == -1)
-               return -1;
-       return args[7];
-}
-  
-asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
-{
-       int phandle,i,mem_len,buffer[32];
-       char temp[15];
-  
-       temp[0]='/';
-       temp[1]='m';
-       temp[2]='e';
-       temp[3]='m';
-       temp[4]='o';
-       temp[5]='r';
-       temp[6]='y';
-       temp[7]='\0';
-
-       phandle=OF_finddevice(o,temp);
-
-       temp[0]='r';
-       temp[1]='e';
-       temp[2]='g';
-       temp[3]='\0';
-
-       mem_len = OF_getproplen(o,phandle, temp);
-       OF_getprop(o,phandle, temp, buffer, mem_len);
-       *nomr=mem_len >> 3;
-
-       for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
-
-       temp[0]='/';
-       temp[1]='c';
-       temp[2]='h';
-       temp[3]='o';
-       temp[4]='s';
-       temp[5]='e';
-       temp[6]='n';
-       temp[7]='\0';
-
-       phandle=OF_finddevice(o,temp);
-
-       temp[0]='b';
-       temp[1]='o';
-       temp[2]='o';
-       temp[3]='t';
-       temp[4]='a';
-       temp[5]='r';
-       temp[6]='g';
-       temp[7]='s';
-       temp[8]='\0';
-
-       mem_len = OF_getproplen(o,phandle, temp);
-       OF_getprop(o,phandle, temp, buffer, mem_len);
-       if (mem_len > 128) mem_len=128;
-       for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
-       pointer[i+33]=0;
-
-       temp[0]='/';
-       temp[1]='\0';
-       phandle=OF_finddevice(o,temp);
-       temp[0]='b';
-       temp[1]='a';
-       temp[2]='n';
-       temp[3]='n';
-       temp[4]='e';
-       temp[5]='r';
-       temp[6]='-';
-       temp[7]='n';
-       temp[8]='a';
-       temp[9]='m';
-       temp[10]='e';
-       temp[11]='\0';
-       mem_len = OF_getproplen(o,phandle, temp);
-       OF_getprop(o,phandle, temp, buffer, mem_len);
-       * ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
-}
index 802720e3e8fd5c72004c14cce0bc572a0355356a..d57c1a65b24f981fb25c62aa58c73c1fedd84ab8 100644 (file)
@@ -40,17 +40,17 @@ dtb-$(CONFIG_ARCH_AT91)     += sama5d31ek.dtb
 dtb-$(CONFIG_ARCH_AT91)        += sama5d33ek.dtb
 dtb-$(CONFIG_ARCH_AT91)        += sama5d34ek.dtb
 dtb-$(CONFIG_ARCH_AT91)        += sama5d35ek.dtb
-
 dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
-
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
-dtb-$(CONFIG_ARCH_BCM) += bcm11351-brt.dtb \
+dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \
        bcm28155-ap.dtb
+dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
 dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \
        da850-evm.dtb
 dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
        dove-cubox.dtb \
        dove-d2plug.dtb \
+       dove-d3plug.dtb \
        dove-dove-db.dtb
 dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
        exynos4210-smdkv310.dtb \
@@ -96,22 +96,25 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
        kirkwood-ns2mini.dtb \
        kirkwood-nsa310.dtb \
        kirkwood-nsa310a.dtb \
+       kirkwood-openblocks_a6.dtb \
+       kirkwood-openblocks_a7.dtb \
        kirkwood-sheevaplug.dtb \
        kirkwood-sheevaplug-esata.dtb \
        kirkwood-topkick.dtb \
        kirkwood-ts219-6281.dtb \
-       kirkwood-ts219-6282.dtb \
-       kirkwood-openblocks_a6.dtb
+       kirkwood-ts219-6282.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
-dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \
-       msm8960-cdp.dtb
+dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
+       qcom-msm8960-cdp.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
        armada-370-mirabox.dtb \
        armada-370-netgear-rn102.dtb \
+       armada-370-netgear-rn104.dtb \
        armada-370-rd.dtb \
        armada-xp-axpwifiap.dtb \
        armada-xp-db.dtb \
        armada-xp-gp.dtb \
+       armada-xp-matrix.dtb \
        armada-xp-openblocks-ax3-4.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
        imx25-karo-tx25.dtb \
@@ -142,8 +145,10 @@ dtb-$(CONFIG_ARCH_MXC) += \
        imx6q-sabrelite.dtb \
        imx6q-sabresd.dtb \
        imx6q-sbc6x.dtb \
+       imx6q-udoo.dtb \
        imx6q-wandboard.dtb \
        imx6sl-evk.dtb \
+       vf610-cosmic.dtb \
        vf610-twr.dtb
 dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
        imx23-olinuxino.dtb \
@@ -159,6 +164,7 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
        imx28-cfa10057.dtb \
        imx28-cfa10058.dtb \
        imx28-evk.dtb \
+       imx28-m28cu3.dtb \
        imx28-m28evk.dtb \
        imx28-sps1.dtb \
        imx28-tx28.dtb
@@ -172,9 +178,15 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        omap3-devkit8000.dtb \
        omap3-beagle-xm.dtb \
        omap3-evm.dtb \
+       omap3-evm-37xx.dtb \
+       omap3-n900.dtb \
+       omap3-n9.dtb \
+       omap3-n950.dtb \
        omap3-tobi.dtb \
+       omap3-gta04.dtb \
        omap3-igep0020.dtb \
        omap3-igep0030.dtb \
+       omap3-zoom3.dtb \
        omap4-panda.dtb \
        omap4-panda-a4.dtb \
        omap4-panda-es.dtb \
@@ -186,25 +198,33 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        am335x-evmsk.dtb \
        am335x-bone.dtb \
        am335x-boneblack.dtb \
+       am335x-nano.dtb \
+       am335x-base0033.dtb \
        am3517-evm.dtb \
        am3517_mt_ventoux.dtb \
-       am43x-epos-evm.dtb
+       am43x-epos-evm.dtb \
+       dra7-evm.dtb
 dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
 dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
-       ste-hrefprev60.dtb \
-       ste-hrefv60plus.dtb \
+       ste-hrefprev60-stuib.dtb \
+       ste-hrefprev60-tvk.dtb \
+       ste-hrefv60plus-stuib.dtb \
+       ste-hrefv60plus-tvk.dtb \
        ste-ccu8540.dtb \
        ste-ccu9540.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 \
-       emev2-kzm9d-reference.dtb \
+       r7s72100-genmai.dtb \
        r8a7740-armadillo800eva.dtb \
        r8a7778-bockw.dtb \
        r8a7778-bockw-reference.dtb \
        r8a7740-armadillo800eva-reference.dtb \
        r8a7779-marzen.dtb \
        r8a7779-marzen-reference.dtb \
+       r8a7791-koelsch.dtb \
        r8a7790-lager.dtb \
        r8a7790-lager-reference.dtb \
        sh73a0-kzm9g.dtb \
@@ -212,8 +232,10 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
        r8a73a4-ape6evm.dtb \
        r8a73a4-ape6evm-reference.dtb \
        sh7372-mackerel.dtb
-dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d-reference.dtb
-dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \
+dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb
+dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_arria5_socdk.dtb \
+       socfpga_cyclone5_socdk.dtb \
+       socfpga_cyclone5_sockit.dtb \
        socfpga_vt.dtb
 dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
        spear1340-evb.dtb
@@ -235,6 +257,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \
        sun5i-a13-olinuxino.dtb \
        sun6i-a31-colombus.dtb \
        sun7i-a20-cubieboard2.dtb \
+       sun7i-a20-cubietruck.dtb \
        sun7i-a20-olinuxino-micro.dtb
 dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
        tegra20-iris-512.dtb \
@@ -249,7 +272,8 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
        tegra30-beaver.dtb \
        tegra30-cardhu-a02.dtb \
        tegra30-cardhu-a04.dtb \
-       tegra114-dalmore.dtb
+       tegra114-dalmore.dtb \
+       tegra124-venice2.dtb
 dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
        versatile-pb.dtb
 dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb
diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts
new file mode 100644 (file)
index 0000000..b4f95c2
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * am335x-base0033.dts - Device Tree file for IGEP AQUILA EXPANSION
+ *
+ * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "am335x-igep0033.dtsi"
+
+/ {
+       model = "IGEP COM AM335x on AQUILA Expansion";
+       compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
+};
index 2f66deda9f5c171b4394046e14dba7b4814588df..e3f27ec317182b887961c0a58ca49f66407935d8 100644 (file)
                reg = <0x80000000 0x10000000>; /* 256 MB */
        };
 
-       am33xx_pinmux: pinmux@44e10800 {
+       leds {
                pinctrl-names = "default";
-               pinctrl-0 = <&clkout2_pin>;
-
-               user_leds_s0: user_leds_s0 {
-                       pinctrl-single,pins = <
-                               0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
-                               0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a6.gpio1_22 */
-                               0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a7.gpio1_23 */
-                               0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a8.gpio1_24 */
-                       >;
-               };
+               pinctrl-0 = <&user_leds_s0>;
 
-               i2c0_pins: pinmux_i2c0_pins {
-                       pinctrl-single,pins = <
-                               0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                               0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
-                       >;
-               };
+               compatible = "gpio-leds";
 
-               uart0_pins: pinmux_uart0_pins {
-                       pinctrl-single,pins = <
-                               0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                               0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
-                       >;
+               led@2 {
+                       label = "beaglebone:green:heartbeat";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
                };
 
-               clkout2_pin: pinmux_clkout2_pin {
-                       pinctrl-single,pins = <
-                               0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
-                       >;
+               led@3 {
+                       label = "beaglebone:green:mmc0";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc0";
+                       default-state = "off";
                };
 
-               cpsw_default: cpsw_default {
-                       pinctrl-single,pins = <
-                               /* Slave 1 */
-                               0x110 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxerr.mii1_rxerr */
-                               0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */
-                               0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxdv.mii1_rxdv */
-                               0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */
-                               0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */
-                               0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */
-                               0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */
-                               0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_txclk.mii1_txclk */
-                               0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxclk.mii1_rxclk */
-                               0x134 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd3.mii1_rxd3 */
-                               0x138 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd2.mii1_rxd2 */
-                               0x13c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd1.mii1_rxd1 */
-                               0x140 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd0.mii1_rxd0 */
-                       >;
+               led@4 {
+                       label = "beaglebone:green:usr2";
+                       gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "cpu0";
+                       default-state = "off";
                };
 
-               cpsw_sleep: cpsw_sleep {
-                       pinctrl-single,pins = <
-                               /* Slave 1 reset value */
-                               0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       >;
+               led@5 {
+                       label = "beaglebone:green:usr3";
+                       gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc1";
+                       default-state = "off";
                };
+       };
 
-               davinci_mdio_default: davinci_mdio_default {
-                       pinctrl-single,pins = <
-                               /* MDIO */
-                               0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                               0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
-                       >;
-               };
+       vmmcsd_fixed: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
 
-               davinci_mdio_sleep: davinci_mdio_sleep {
-                       pinctrl-single,pins = <
-                               /* MDIO reset value */
-                               0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       >;
-               };
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&clkout2_pin>;
+
+       user_leds_s0: user_leds_s0 {
+               pinctrl-single,pins = <
+                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
+                       0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a6.gpio1_22 */
+                       0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a7.gpio1_23 */
+                       0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a8.gpio1_24 */
+               >;
        };
 
-       ocp {
-               uart0: serial@44e09000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&uart0_pins>;
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
+                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+               >;
+       };
 
-                       status = "okay";
-               };
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+               >;
+       };
 
-               musb: usb@47400000 {
-                       status = "okay";
+       clkout2_pin: pinmux_clkout2_pin {
+               pinctrl-single,pins = <
+                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+               >;
+       };
 
-                       control@44e10000 {
-                               status = "okay";
-                       };
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       0x110 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxerr.mii1_rxerr */
+                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */
+                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxdv.mii1_rxdv */
+                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */
+                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */
+                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */
+                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */
+                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_txclk.mii1_txclk */
+                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxclk.mii1_rxclk */
+                       0x134 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd3.mii1_rxd3 */
+                       0x138 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd2.mii1_rxd2 */
+                       0x13c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd1.mii1_rxd1 */
+                       0x140 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd0.mii1_rxd0 */
+               >;
+       };
 
-                       usb-phy@47401300 {
-                               status = "okay";
-                       };
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
 
-                       usb-phy@47401b00 {
-                               status = "okay";
-                       };
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
+                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+               >;
+       };
 
-                       usb@47401000 {
-                               status = "okay";
-                       };
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
 
-                       usb@47401800 {
-                               status = "okay";
-                               dr_mode = "host";
-                       };
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x160 (PIN_INPUT | MUX_MODE7) /* GPIO0_6 */
+               >;
+       };
 
-                       dma-controller@07402000  {
-                               status = "okay";
-                       };
-               };
+       emmc_pins: pinmux_emmc_pins {
+               pinctrl-single,pins = <
+                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+                       0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+                       0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+                       0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+                       0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+               >;
+       };
+};
 
-               i2c0: i2c@44e0b000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&i2c0_pins>;
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
 
-                       status = "okay";
-                       clock-frequency = <400000>;
+       status = "okay";
+};
 
-                       tps: tps@24 {
-                               reg = <0x24>;
-                       };
+&usb {
+       status = "okay";
 
-               };
+       control@44e10000 {
+               status = "okay";
        };
 
-       leds {
-               pinctrl-names = "default";
-               pinctrl-0 = <&user_leds_s0>;
+       usb-phy@47401300 {
+               status = "okay";
+       };
 
-               compatible = "gpio-leds";
+       usb-phy@47401b00 {
+               status = "okay";
+       };
 
-               led@2 {
-                       label = "beaglebone:green:heartbeat";
-                       gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "heartbeat";
-                       default-state = "off";
-               };
+       usb@47401000 {
+               status = "okay";
+       };
 
-               led@3 {
-                       label = "beaglebone:green:mmc0";
-                       gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "mmc0";
-                       default-state = "off";
-               };
+       usb@47401800 {
+               status = "okay";
+               dr_mode = "host";
+       };
 
-               led@4 {
-                       label = "beaglebone:green:usr2";
-                       gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
-                       default-state = "off";
-               };
+       dma-controller@07402000  {
+               status = "okay";
+       };
+};
 
-               led@5 {
-                       label = "beaglebone:green:usr3";
-                       gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
-                       default-state = "off";
-               };
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       tps: tps@24 {
+               reg = <0x24>;
        };
+
 };
 
 /include/ "tps65217.dtsi"
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
 };
+
+&mmc1 {
+       status = "okay";
+       bus-width = <0x4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+       cd-inverted;
+};
index 7993c489982c86ab2cf03a85b152f9b7db99ad3f..94ee427a6db17663bfbd28912df2a62d17ce6085 100644 (file)
@@ -9,3 +9,21 @@
 
 #include "am33xx.dtsi"
 #include "am335x-bone-common.dtsi"
+
+&ldo3_reg {
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-always-on;
+};
+
+&mmc1 {
+       vmmc-supply = <&ldo3_reg>;
+};
+
+&sham {
+       status = "okay";
+};
+
+&aes {
+       status = "okay";
+};
index 197cadf72d2cd92ed03351e3c2ac590c2401bd50..6b71ad95a5cfd085a12dd390b794a7d37290a468 100644 (file)
        regulator-max-microvolt = <1800000>;
        regulator-always-on;
 };
+
+&mmc1 {
+       vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&mmc2 {
+       vmmc-supply = <&vmmcsd_fixed>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>;
+       bus-width = <8>;
+       status = "okay";
+       ti,vcc-aux-disable-is-sleep;
+};
+
+&am33xx_pinmux {
+       nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
+               pinctrl-single,pins = <
+                       0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+                       0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xa8 0x08       /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xac 0x08       /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xb0 0x08       /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xb4 0x08       /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xb8 0x08       /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xbc 0x08       /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xc0 0x08       /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xc4 0x08       /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xc8 0x08       /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xcc 0x08       /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xd0 0x08       /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xd4 0x08       /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xd8 0x08       /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xdc 0x08       /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+                       0xe0 0x00       /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+                       0xe4 0x00       /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+                       0xe8 0x00       /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+                       0xec 0x00       /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+               >;
+       };
+       nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
+               pinctrl-single,pins = <
+                       0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+               >;
+       };
+};
+
+&lcdc {
+       status = "okay";
+};
+
+/ {
+       hdmi {
+               compatible = "ti,tilcdc,slave";
+               i2c = <&i2c0>;
+               pinctrl-names = "default", "off";
+               pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+               pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+               status = "okay";
+       };
+};
index e8ec8756e4985f2b616a2aa8da28682dbd043246..987429436171f0dd2ac8bb1bd0b64e548fc1e722 100644 (file)
                reg = <0x80000000 0x10000000>; /* 256 MB */
        };
 
-       am33xx_pinmux: pinmux@44e10800 {
-               pinctrl-names = "default";
-               pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>;
-
-               matrix_keypad_s0: matrix_keypad_s0 {
-                       pinctrl-single,pins = <
-                               0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
-                               0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a6.gpio1_22 */
-                               0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a9.gpio1_25 */
-                               0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a10.gpio1_26 */
-                               0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a11.gpio1_27 */
-                       >;
-               };
-
-               volume_keys_s0: volume_keys_s0 {
-                       pinctrl-single,pins = <
-                               0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* spi0_sclk.gpio0_2 */
-                               0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* spi0_d0.gpio0_3 */
-                       >;
-               };
-
-               i2c0_pins: pinmux_i2c0_pins {
-                       pinctrl-single,pins = <
-                               0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                               0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
-                       >;
-               };
-
-               i2c1_pins: pinmux_i2c1_pins {
-                       pinctrl-single,pins = <
-                               0x158 (PIN_INPUT_PULLUP | MUX_MODE2)    /* spi0_d1.i2c1_sda */
-                               0x15c (PIN_INPUT_PULLUP | MUX_MODE2)    /* spi0_cs0.i2c1_scl */
-                       >;
-               };
-
-               uart0_pins: pinmux_uart0_pins {
-                       pinctrl-single,pins = <
-                               0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                               0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
-                       >;
-               };
-
-               clkout2_pin: pinmux_clkout2_pin {
-                       pinctrl-single,pins = <
-                               0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
-                       >;
-               };
-
-               nandflash_pins_s0: nandflash_pins_s0 {
-                       pinctrl-single,pins = <
-                               0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
-                               0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
-                               0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
-                               0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
-                               0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
-                               0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
-                               0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
-                               0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
-                               0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                               0x74 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_wpn.gpio0_30 */
-                               0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
-                               0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                               0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                               0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                               0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
-                       >;
-               };
-
-               ecap0_pins: backlight_pins {
-                       pinctrl-single,pins = <
-                               0x164 0x0       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
-                       >;
-               };
-
-               cpsw_default: cpsw_default {
-                       pinctrl-single,pins = <
-                               /* Slave 1 */
-                               0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
-                               0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
-                               0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
-                               0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
-                               0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
-                               0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
-                               0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rgmii1_rclk */
-                               0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd3.rgmii1_rd3 */
-                               0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd2.rgmii1_rd2 */
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
-                       >;
-               };
-
-               cpsw_sleep: cpsw_sleep {
-                       pinctrl-single,pins = <
-                               /* Slave 1 reset value */
-                               0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       >;
-               };
-
-               davinci_mdio_default: davinci_mdio_default {
-                       pinctrl-single,pins = <
-                               /* MDIO */
-                               0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                               0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
-                       >;
-               };
-
-               davinci_mdio_sleep: davinci_mdio_sleep {
-                       pinctrl-single,pins = <
-                               /* MDIO reset value */
-                               0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       >;
-               };
-       };
-
-       ocp {
-               uart0: serial@44e09000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&uart0_pins>;
-
-                       status = "okay";
-               };
-
-               i2c0: i2c@44e0b000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&i2c0_pins>;
-
-                       status = "okay";
-                       clock-frequency = <400000>;
-
-                       tps: tps@2d {
-                               reg = <0x2d>;
-                       };
-               };
-
-               musb: usb@47400000 {
-                       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";
-                       };
-               };
-
-               i2c1: i2c@4802a000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&i2c1_pins>;
-
-                       status = "okay";
-                       clock-frequency = <100000>;
-
-                       lis331dlh: lis331dlh@18 {
-                               compatible = "st,lis331dlh", "st,lis3lv02d";
-                               reg = <0x18>;
-                               Vdd-supply = <&lis3_reg>;
-                               Vdd_IO-supply = <&lis3_reg>;
-
-                               st,click-single-x;
-                               st,click-single-y;
-                               st,click-single-z;
-                               st,click-thresh-x = <10>;
-                               st,click-thresh-y = <10>;
-                               st,click-thresh-z = <10>;
-                               st,irq1-click;
-                               st,irq2-click;
-                               st,wakeup-x-lo;
-                               st,wakeup-x-hi;
-                               st,wakeup-y-lo;
-                               st,wakeup-y-hi;
-                               st,wakeup-z-lo;
-                               st,wakeup-z-hi;
-                               st,min-limit-x = <120>;
-                               st,min-limit-y = <120>;
-                               st,min-limit-z = <140>;
-                               st,max-limit-x = <550>;
-                               st,max-limit-y = <550>;
-                               st,max-limit-z = <750>;
-                       };
-
-                       tsl2550: tsl2550@39 {
-                               compatible = "taos,tsl2550";
-                               reg = <0x39>;
-                       };
-
-                       tmp275: tmp275@48 {
-                               compatible = "ti,tmp275";
-                               reg = <0x48>;
-                       };
-               };
-
-               elm: elm@48080000 {
-                       status = "okay";
-               };
-
-               epwmss0: epwmss@48300000 {
-                       status = "okay";
-
-                       ecap0: ecap@48300100 {
-                               status = "okay";
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&ecap0_pins>;
-                       };
-               };
-
-               gpmc: gpmc@50000000 {
-                       status = "okay";
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&nandflash_pins_s0>;
-                       ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
-                       nand@0,0 {
-                               reg = <0 0 0>; /* CS0, offset 0 */
-                               nand-bus-width = <8>;
-                               ti,nand-ecc-opt = "bch8";
-                               gpmc,device-nand = "true";
-                               gpmc,device-width = <1>;
-                               gpmc,sync-clk-ps = <0>;
-                               gpmc,cs-on-ns = <0>;
-                               gpmc,cs-rd-off-ns = <44>;
-                               gpmc,cs-wr-off-ns = <44>;
-                               gpmc,adv-on-ns = <6>;
-                               gpmc,adv-rd-off-ns = <34>;
-                               gpmc,adv-wr-off-ns = <44>;
-                               gpmc,we-on-ns = <0>;
-                               gpmc,we-off-ns = <40>;
-                               gpmc,oe-on-ns = <0>;
-                               gpmc,oe-off-ns = <54>;
-                               gpmc,access-ns = <64>;
-                               gpmc,rd-cycle-ns = <82>;
-                               gpmc,wr-cycle-ns = <82>;
-                               gpmc,wait-on-read = "true";
-                               gpmc,wait-on-write = "true";
-                               gpmc,bus-turnaround-ns = <0>;
-                               gpmc,cycle2cycle-delay-ns = <0>;
-                               gpmc,clk-activation-ns = <0>;
-                               gpmc,wait-monitoring-ns = <0>;
-                               gpmc,wr-access-ns = <40>;
-                               gpmc,wr-data-mux-bus-ns = <0>;
-
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               elm_id = <&elm>;
-
-                               /* MTD partition table */
-                               partition@0 {
-                                       label = "SPL1";
-                                       reg = <0x00000000 0x000020000>;
-                               };
-
-                               partition@1 {
-                                       label = "SPL2";
-                                       reg = <0x00020000 0x00020000>;
-                               };
-
-                               partition@2 {
-                                       label = "SPL3";
-                                       reg = <0x00040000 0x00020000>;
-                               };
-
-                               partition@3 {
-                                       label = "SPL4";
-                                       reg = <0x00060000 0x00020000>;
-                               };
-
-                               partition@4 {
-                                       label = "U-boot";
-                                       reg = <0x00080000 0x001e0000>;
-                               };
-
-                               partition@5 {
-                                       label = "environment";
-                                       reg = <0x00260000 0x00020000>;
-                               };
-
-                               partition@6 {
-                                       label = "Kernel";
-                                       reg = <0x00280000 0x00500000>;
-                               };
-
-                               partition@7 {
-                                       label = "File-System";
-                                       reg = <0x00780000 0x0F880000>;
-                               };
-                       };
-               };
-       };
-
        vbat: fixedregulator@0 {
                compatible = "regulator-fixed";
                regulator-name = "vbat";
                brightness-levels = <0 51 53 56 62 75 101 152 255>;
                default-brightness-level = <8>;
        };
+
+       panel {
+               compatible = "ti,tilcdc,panel";
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&lcd_pins_s0>;
+               panel-info {
+                       ac-bias           = <255>;
+                       ac-bias-intrpt    = <0>;
+                       dma-burst-sz      = <16>;
+                       bpp               = <32>;
+                       fdd               = <0x80>;
+                       sync-edge         = <0>;
+                       sync-ctrl         = <1>;
+                       raster-order      = <0>;
+                       fifo-th           = <0>;
+               };
+
+               display-timings {
+                       800x480p62 {
+                               clock-frequency = <30000000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hfront-porch = <39>;
+                               hback-porch = <39>;
+                               hsync-len = <47>;
+                               vback-porch = <29>;
+                               vfront-porch = <13>;
+                               vsync-len = <2>;
+                               hsync-active = <1>;
+                               vsync-active = <1>;
+                       };
+               };
+       };
+
+       sound {
+               compatible = "ti,da830-evm-audio";
+               ti,model = "AM335x-EVM";
+               ti,audio-codec = <&tlv320aic3106>;
+               ti,mcasp-controller = <&mcasp1>;
+               ti,codec-clock-rate = <12000000>;
+               ti,audio-routing =
+                       "Headphone Jack",       "HPLOUT",
+                       "Headphone Jack",       "HPROUT",
+                       "LINE1L",               "Line In",
+                       "LINE1R",               "Line In";
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>;
+
+       matrix_keypad_s0: matrix_keypad_s0 {
+               pinctrl-single,pins = <
+                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
+                       0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a6.gpio1_22 */
+                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a9.gpio1_25 */
+                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a10.gpio1_26 */
+                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a11.gpio1_27 */
+               >;
+       };
+
+       volume_keys_s0: volume_keys_s0 {
+               pinctrl-single,pins = <
+                       0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* spi0_sclk.gpio0_2 */
+                       0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* spi0_d0.gpio0_3 */
+               >;
+       };
+
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
+                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0x158 (PIN_INPUT_PULLUP | MUX_MODE2)    /* spi0_d1.i2c1_sda */
+                       0x15c (PIN_INPUT_PULLUP | MUX_MODE2)    /* spi0_cs0.i2c1_scl */
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       clkout2_pin: pinmux_clkout2_pin {
+               pinctrl-single,pins = <
+                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+               >;
+       };
+
+       nandflash_pins_s0: nandflash_pins_s0 {
+               pinctrl-single,pins = <
+                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
+                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
+                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
+                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
+                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
+                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_wpn.gpio0_30 */
+                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
+                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
+                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
+                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
+                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+               >;
+       };
+
+       ecap0_pins: backlight_pins {
+               pinctrl-single,pins = <
+                       0x164 0x0       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+               >;
+       };
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
+                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+                       0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rgmii1_rclk */
+                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd3.rgmii1_rd3 */
+                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd2.rgmii1_rd2 */
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
+               >;
+       };
+
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
+                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+               >;
+       };
+
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       lcd_pins_s0: lcd_pins_s0 {
+               pinctrl-single,pins = <
+                       0x20 0x01       /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */
+                       0x24 0x01       /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */
+                       0x28 0x01       /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */
+                       0x2c 0x01       /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */
+                       0x30 0x01       /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */
+                       0x34 0x01       /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */
+                       0x38 0x01       /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */
+                       0x3c 0x01       /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */
+                       0xa0 0x00       /* lcd_data0.lcd_data0, OUTPUT | MODE0 */
+                       0xa4 0x00       /* lcd_data1.lcd_data1, OUTPUT | MODE0 */
+                       0xa8 0x00       /* lcd_data2.lcd_data2, OUTPUT | MODE0 */
+                       0xac 0x00       /* lcd_data3.lcd_data3, OUTPUT | MODE0 */
+                       0xb0 0x00       /* lcd_data4.lcd_data4, OUTPUT | MODE0 */
+                       0xb4 0x00       /* lcd_data5.lcd_data5, OUTPUT | MODE0 */
+                       0xb8 0x00       /* lcd_data6.lcd_data6, OUTPUT | MODE0 */
+                       0xbc 0x00       /* lcd_data7.lcd_data7, OUTPUT | MODE0 */
+                       0xc0 0x00       /* lcd_data8.lcd_data8, OUTPUT | MODE0 */
+                       0xc4 0x00       /* lcd_data9.lcd_data9, OUTPUT | MODE0 */
+                       0xc8 0x00       /* lcd_data10.lcd_data10, OUTPUT | MODE0 */
+                       0xcc 0x00       /* lcd_data11.lcd_data11, OUTPUT | MODE0 */
+                       0xd0 0x00       /* lcd_data12.lcd_data12, OUTPUT | MODE0 */
+                       0xd4 0x00       /* lcd_data13.lcd_data13, OUTPUT | MODE0 */
+                       0xd8 0x00       /* lcd_data14.lcd_data14, OUTPUT | MODE0 */
+                       0xdc 0x00       /* lcd_data15.lcd_data15, OUTPUT | MODE0 */
+                       0xe0 0x00       /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */
+                       0xe4 0x00       /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */
+                       0xe8 0x00       /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */
+                       0xec 0x00       /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */
+               >;
+       };
+
+       am335x_evm_audio_pins: am335x_evm_audio_pins {
+               pinctrl-single,pins = <
+                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */
+                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */
+                       0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+               >;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       tps: tps@2d {
+               reg = <0x2d>;
+       };
+};
+
+&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";
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       status = "okay";
+       clock-frequency = <100000>;
+
+       lis331dlh: lis331dlh@18 {
+               compatible = "st,lis331dlh", "st,lis3lv02d";
+               reg = <0x18>;
+               Vdd-supply = <&lis3_reg>;
+               Vdd_IO-supply = <&lis3_reg>;
+
+               st,click-single-x;
+               st,click-single-y;
+               st,click-single-z;
+               st,click-thresh-x = <10>;
+               st,click-thresh-y = <10>;
+               st,click-thresh-z = <10>;
+               st,irq1-click;
+               st,irq2-click;
+               st,wakeup-x-lo;
+               st,wakeup-x-hi;
+               st,wakeup-y-lo;
+               st,wakeup-y-hi;
+               st,wakeup-z-lo;
+               st,wakeup-z-hi;
+               st,min-limit-x = <120>;
+               st,min-limit-y = <120>;
+               st,min-limit-z = <140>;
+               st,max-limit-x = <550>;
+               st,max-limit-y = <550>;
+               st,max-limit-z = <750>;
+       };
+
+       tsl2550: tsl2550@39 {
+               compatible = "taos,tsl2550";
+               reg = <0x39>;
+       };
+
+       tmp275: tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tlv320aic3106: tlv320aic3106@1b {
+               compatible = "ti,tlv320aic3106";
+               reg = <0x1b>;
+               status = "okay";
+
+               /* Regulators */
+               AVDD-supply = <&vaux2_reg>;
+               IOVDD-supply = <&vaux2_reg>;
+               DRVDD-supply = <&vaux2_reg>;
+               DVDD-supply = <&vbat>;
+       };
+};
+
+&lcdc {
+       status = "okay";
+};
+
+&elm {
+       status = "okay";
+};
+
+&epwmss0 {
+       status = "okay";
+
+       ecap0: ecap@48300100 {
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&ecap0_pins>;
+       };
+};
+
+&gpmc {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&nandflash_pins_s0>;
+       ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
+       nand@0,0 {
+               reg = <0 0 0>; /* CS0, offset 0 */
+               nand-bus-width = <8>;
+               ti,nand-ecc-opt = "bch8";
+               gpmc,device-nand = "true";
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,wait-on-read = "true";
+               gpmc,wait-on-write = "true";
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+               elm_id = <&elm>;
+
+               /* MTD partition table */
+               partition@0 {
+                       label = "SPL1";
+                       reg = <0x00000000 0x000020000>;
+               };
+
+               partition@1 {
+                       label = "SPL2";
+                       reg = <0x00020000 0x00020000>;
+               };
+
+               partition@2 {
+                       label = "SPL3";
+                       reg = <0x00040000 0x00020000>;
+               };
+
+               partition@3 {
+                       label = "SPL4";
+                       reg = <0x00060000 0x00020000>;
+               };
+
+               partition@4 {
+                       label = "U-boot";
+                       reg = <0x00080000 0x001e0000>;
+               };
+
+               partition@5 {
+                       label = "environment";
+                       reg = <0x00260000 0x00020000>;
+               };
+
+               partition@6 {
+                       label = "Kernel";
+                       reg = <0x00280000 0x00500000>;
+               };
+
+               partition@7 {
+                       label = "File-System";
+                       reg = <0x00780000 0x0F880000>;
+               };
+       };
 };
 
 #include "tps65910.dtsi"
 
+&mcasp1 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&am335x_evm_audio_pins>;
+
+               status = "okay";
+
+               op-mode = <0>;          /* MCASP_IIS_MODE */
+               tdm-slots = <2>;
+               /* 4 serializers */
+               serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+                       0 0 1 2
+               >;
+               tx-num-evt = <1>;
+               rx-num-evt = <1>;
+};
+
 &tps {
        vcc1-supply = <&vbat>;
        vcc2-supply = <&vbat>;
                };
 
                vmmc_reg: regulator@12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
        };
                ti,adc-channels = <4 5 6 7>;
        };
 };
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&vmmc_reg>;
+       bus-width = <4>;
+};
+
+&sham {
+       status = "okay";
+};
+
+&aes {
+       status = "okay";
+};
index 4f339fa91c5772b7eaaa4c9a306a1d6808387765..03febf85fd2f055373259c19e01c5ad9d8148e65 100644 (file)
                reg = <0x80000000 0x10000000>; /* 256 MB */
        };
 
-       am33xx_pinmux: pinmux@44e10800 {
-               pinctrl-names = "default";
-               pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>;
-
-               user_leds_s0: user_leds_s0 {
-                       pinctrl-single,pins = <
-                               0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad4.gpio1_4 */
-                               0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad5.gpio1_5 */
-                               0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad6.gpio1_6 */
-                               0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad7.gpio1_7 */
-                       >;
-               };
-
-               gpio_keys_s0: gpio_keys_s0 {
-                       pinctrl-single,pins = <
-                               0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_oen_ren.gpio2_3 */
-                               0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_advn_ale.gpio2_2 */
-                               0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_wait0.gpio0_30 */
-                               0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ben0_cle.gpio2_5 */
-                       >;
-               };
-
-               i2c0_pins: pinmux_i2c0_pins {
-                       pinctrl-single,pins = <
-                               0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                               0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
-                       >;
-               };
-
-               uart0_pins: pinmux_uart0_pins {
-                       pinctrl-single,pins = <
-                               0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                               0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)         /* uart0_txd.uart0_txd */
-                       >;
-               };
-
-               clkout2_pin: pinmux_clkout2_pin {
-                       pinctrl-single,pins = <
-                               0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)         /* xdma_event_intr1.clkout2 */
-                       >;
-               };
-
-               ecap2_pins: backlight_pins {
-                       pinctrl-single,pins = <
-                               0x19c 0x4       /* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */
-                       >;
-               };
-
-               cpsw_default: cpsw_default {
-                       pinctrl-single,pins = <
-                               /* Slave 1 */
-                               0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
-                               0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
-                               0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
-                               0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
-                               0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
-                               0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
-                               0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rgmii1_rclk */
-                               0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd3.rgmii1_rd3 */
-                               0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd2.rgmii1_rd2 */
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
-
-                               /* Slave 2 */
-                               0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a0.rgmii2_tctl */
-                               0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a1.rgmii2_rctl */
-                               0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a2.rgmii2_td3 */
-                               0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a3.rgmii2_td2 */
-                               0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a4.rgmii2_td1 */
-                               0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a5.rgmii2_td0 */
-                               0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a6.rgmii2_tclk */
-                               0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a7.rgmii2_rclk */
-                               0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a8.rgmii2_rd3 */
-                               0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a9.rgmii2_rd2 */
-                               0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a10.rgmii2_rd1 */
-                               0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a11.rgmii2_rd0 */
-                       >;
-               };
-
-               cpsw_sleep: cpsw_sleep {
-                       pinctrl-single,pins = <
-                               /* Slave 1 reset value */
-                               0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-
-                               /* Slave 2 reset value*/
-                               0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       >;
-               };
-
-               davinci_mdio_default: davinci_mdio_default {
-                       pinctrl-single,pins = <
-                               /* MDIO */
-                               0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                               0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
-                       >;
-               };
-
-               davinci_mdio_sleep: davinci_mdio_sleep {
-                       pinctrl-single,pins = <
-                               /* MDIO reset value */
-                               0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       >;
-               };
-       };
-
-       ocp {
-               uart0: serial@44e09000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&uart0_pins>;
-
-                       status = "okay";
-               };
-
-               i2c0: i2c@44e0b000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&i2c0_pins>;
-
-                       status = "okay";
-                       clock-frequency = <400000>;
-
-                       tps: tps@2d {
-                               reg = <0x2d>;
-                       };
-
-                       lis331dlh: lis331dlh@18 {
-                               compatible = "st,lis331dlh", "st,lis3lv02d";
-                               reg = <0x18>;
-                               Vdd-supply = <&lis3_reg>;
-                               Vdd_IO-supply = <&lis3_reg>;
-
-                               st,click-single-x;
-                               st,click-single-y;
-                               st,click-single-z;
-                               st,click-thresh-x = <10>;
-                               st,click-thresh-y = <10>;
-                               st,click-thresh-z = <10>;
-                               st,irq1-click;
-                               st,irq2-click;
-                               st,wakeup-x-lo;
-                               st,wakeup-x-hi;
-                               st,wakeup-y-lo;
-                               st,wakeup-y-hi;
-                               st,wakeup-z-lo;
-                               st,wakeup-z-hi;
-                               st,min-limit-x = <120>;
-                               st,min-limit-y = <120>;
-                               st,min-limit-z = <140>;
-                               st,max-limit-x = <550>;
-                               st,max-limit-y = <550>;
-                               st,max-limit-z = <750>;
-                       };
-               };
-
-               musb: usb@47400000 {
-                       status = "okay";
-
-                       control@44e10000 {
-                               status = "okay";
-                       };
-
-                       usb-phy@47401300 {
-                               status = "okay";
-                       };
-
-                       usb@47401000 {
-                               status = "okay";
-                       };
-               };
-
-               epwmss2: epwmss@48304000 {
-                       status = "okay";
-
-                       ecap2: ecap@48304100 {
-                               status = "okay";
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&ecap2_pins>;
-                       };
-               };
-       };
-
        vbat: fixedregulator@0 {
                compatible = "regulator-fixed";
                regulator-name = "vbat";
                brightness-levels = <0 58 61 66 75 90 125 170 255>;
                default-brightness-level = <8>;
        };
+
+       sound {
+               compatible = "ti,da830-evm-audio";
+               ti,model = "AM335x-EVMSK";
+               ti,audio-codec = <&tlv320aic3106>;
+               ti,mcasp-controller = <&mcasp1>;
+               ti,codec-clock-rate = <24576000>;
+               ti,audio-routing =
+                       "Headphone Jack",       "HPLOUT",
+                       "Headphone Jack",       "HPROUT";
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>;
+
+       user_leds_s0: user_leds_s0 {
+               pinctrl-single,pins = <
+                       0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad4.gpio1_4 */
+                       0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad5.gpio1_5 */
+                       0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad6.gpio1_6 */
+                       0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad7.gpio1_7 */
+               >;
+       };
+
+       gpio_keys_s0: gpio_keys_s0 {
+               pinctrl-single,pins = <
+                       0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_oen_ren.gpio2_3 */
+                       0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_advn_ale.gpio2_2 */
+                       0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_wait0.gpio0_30 */
+                       0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ben0_cle.gpio2_5 */
+               >;
+       };
+
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
+                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)         /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       clkout2_pin: pinmux_clkout2_pin {
+               pinctrl-single,pins = <
+                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)         /* xdma_event_intr1.clkout2 */
+               >;
+       };
+
+       ecap2_pins: backlight_pins {
+               pinctrl-single,pins = <
+                       0x19c 0x4       /* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */
+               >;
+       };
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
+                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+                       0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rgmii1_rclk */
+                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd3.rgmii1_rd3 */
+                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd2.rgmii1_rd2 */
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
+
+                       /* Slave 2 */
+                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a0.rgmii2_tctl */
+                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a1.rgmii2_rctl */
+                       0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a2.rgmii2_td3 */
+                       0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a3.rgmii2_td2 */
+                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a4.rgmii2_td1 */
+                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a5.rgmii2_td0 */
+                       0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a6.rgmii2_tclk */
+                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a7.rgmii2_rclk */
+                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a8.rgmii2_rd3 */
+                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a9.rgmii2_rd2 */
+                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a10.rgmii2_rd1 */
+                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a11.rgmii2_rd0 */
+               >;
+       };
+
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+
+                       /* Slave 2 reset value*/
+                       0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
+                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+               >;
+       };
+
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       mcasp1_pins: mcasp1_pins {
+               pinctrl-single,pins = <
+                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+                       0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+               >;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       tps: tps@2d {
+               reg = <0x2d>;
+       };
+
+       lis331dlh: lis331dlh@18 {
+               compatible = "st,lis331dlh", "st,lis3lv02d";
+               reg = <0x18>;
+               Vdd-supply = <&lis3_reg>;
+               Vdd_IO-supply = <&lis3_reg>;
+
+               st,click-single-x;
+               st,click-single-y;
+               st,click-single-z;
+               st,click-thresh-x = <10>;
+               st,click-thresh-y = <10>;
+               st,click-thresh-z = <10>;
+               st,irq1-click;
+               st,irq2-click;
+               st,wakeup-x-lo;
+               st,wakeup-x-hi;
+               st,wakeup-y-lo;
+               st,wakeup-y-hi;
+               st,wakeup-z-lo;
+               st,wakeup-z-hi;
+               st,min-limit-x = <120>;
+               st,min-limit-y = <120>;
+               st,min-limit-z = <140>;
+               st,max-limit-x = <550>;
+               st,max-limit-y = <550>;
+               st,max-limit-z = <750>;
+       };
+
+       tlv320aic3106: tlv320aic3106@1b {
+               compatible = "ti,tlv320aic3106";
+               reg = <0x1b>;
+               status = "okay";
+
+               /* Regulators */
+               AVDD-supply = <&vaux2_reg>;
+               IOVDD-supply = <&vaux2_reg>;
+               DRVDD-supply = <&vaux2_reg>;
+               DVDD-supply = <&vbat>;
+       };
+};
+
+&usb {
+       status = "okay";
+
+       control@44e10000 {
+               status = "okay";
+       };
+
+       usb-phy@47401300 {
+               status = "okay";
+       };
+
+       usb@47401000 {
+               status = "okay";
+       };
+};
+
+&epwmss2 {
+       status = "okay";
+
+       ecap2: ecap@48304100 {
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&ecap2_pins>;
+       };
 };
 
 #include "tps65910.dtsi"
                };
 
                vmmc_reg: regulator@12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
        };
        phy_id = <&davinci_mdio>, <1>;
        phy-mode = "rgmii-txid";
 };
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&vmmc_reg>;
+       bus-width = <4>;
+};
+
+&sham {
+       status = "okay";
+};
+
+&aes {
+       status = "okay";
+};
+
+&gpio0 {
+       ti,no-reset-on-init;
+};
+
+&mcasp1 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&mcasp1_pins>;
+
+               status = "okay";
+
+               op-mode = <0>;          /* MCASP_IIS_MODE */
+               tdm-slots = <2>;
+               /* 4 serializers */
+               serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+                       0 0 1 2
+               >;
+               tx-num-evt = <1>;
+               rx-num-evt = <1>;
+};
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi
new file mode 100644 (file)
index 0000000..6196244
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * am335x-igep0033.dtsi - Device Tree file for IGEP COM AQUILA AM335x
+ *
+ * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vdd1_reg>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&leds_pins>;
+
+               compatible = "gpio-leds";
+
+               led@0 {
+                       label = "com:green:user";
+                       gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+               };
+       };
+
+       vbat: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vbat";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+       };
+
+       vmmc: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&am33xx_pinmux {
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
+                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       nandflash_pins: pinmux_nandflash_pins {
+               pinctrl-single,pins = <
+                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
+                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
+                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
+                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
+                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
+                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_wpn.gpio0_30 */
+                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0 */
+                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
+                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
+                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
+                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       leds_pins: pinmux_leds_pins {
+               pinctrl-single,pins = <
+                       0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a7.gpio1_23 */
+               >;
+       };
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <1>;
+};
+
+&elm {
+       status = "okay";
+};
+
+&gpmc {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&nandflash_pins>;
+
+       ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
+
+       nand@0,0 {
+               reg = <0 0 0>; /* CS0, offset 0 */
+               nand-bus-width = <8>;
+               ti,nand-ecc-opt = "bch8";
+               gpmc,device-nand = "true";
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,wait-on-read = "true";
+               gpmc,wait-on-write = "true";
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+               elm_id = <&elm>;
+
+               /* MTD partition table */
+               partition@0 {
+                       label = "SPL";
+                       reg = <0x00000000 0x000080000>;
+               };
+
+               partition@1 {
+                       label = "U-boot";
+                       reg = <0x00080000 0x001e0000>;
+               };
+
+               partition@2 {
+                       label = "U-Boot Env";
+                       reg = <0x00260000 0x00020000>;
+               };
+
+               partition@3 {
+                       label = "Kernel";
+                       reg = <0x00280000 0x00500000>;
+               };
+
+               partition@4 {
+                       label = "File System";
+                       reg = <0x00780000 0x007880000>;
+               };
+       };
+};
+
+&i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       clock-frequency = <400000>;
+
+       tps: tps@2d {
+               reg = <0x2d>;
+       };
+};
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&vmmc>;
+       bus-width = <4>;
+};
+
+&uart0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+};
+
+#include "tps65910.dtsi"
+
+&tps {
+       vcc1-supply = <&vbat>;
+       vcc2-supply = <&vbat>;
+       vcc3-supply = <&vbat>;
+       vcc4-supply = <&vbat>;
+       vcc5-supply = <&vbat>;
+       vcc6-supply = <&vbat>;
+       vcc7-supply = <&vbat>;
+       vccio-supply = <&vbat>;
+
+       regulators {
+               vrtc_reg: regulator@0 {
+                       regulator-always-on;
+               };
+
+               vio_reg: regulator@1 {
+                       regulator-always-on;
+               };
+
+               vdd1_reg: regulator@2 {
+                       /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <912500>;
+                       regulator-max-microvolt = <1312500>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               vdd2_reg: regulator@3 {
+                       /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <912500>;
+                       regulator-max-microvolt = <1150000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               vdd3_reg: regulator@4 {
+                       regulator-always-on;
+               };
+
+               vdig1_reg: regulator@5 {
+                       regulator-always-on;
+               };
+
+               vdig2_reg: regulator@6 {
+                       regulator-always-on;
+               };
+
+               vpll_reg: regulator@7 {
+                       regulator-always-on;
+               };
+
+               vdac_reg: regulator@8 {
+                       regulator-always-on;
+               };
+
+               vaux1_reg: regulator@9 {
+                       regulator-always-on;
+               };
+
+               vaux2_reg: regulator@10 {
+                       regulator-always-on;
+               };
+
+               vaux33_reg: regulator@11 {
+                       regulator-always-on;
+               };
+
+               vmmc_reg: regulator@12 {
+                       regulator-always-on;
+               };
+       };
+};
+
diff --git a/arch/arm/boot/dts/am335x-nano.dts b/arch/arm/boot/dts/am335x-nano.dts
new file mode 100644 (file)
index 0000000..9907b49
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2013 Newflow Ltd - http://www.newflow.co.uk/
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+       model = "Newflow AM335x NanoBone";
+       compatible = "ti,am33xx";
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&dcdc2_reg>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led@0 {
+                       label = "nanobone:green:usr1";
+                       gpios = <&gpio1 5 0>;
+                       default-state = "off";
+               };
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&misc_pins>;
+
+       misc_pins: misc_pins {
+               pinctrl-single,pins = <
+                       0x15c (PIN_OUTPUT | MUX_MODE7)  /* spi0_cs0.gpio0_5 */
+               >;
+       };
+
+       gpmc_pins: gpmc_pins {
+               pinctrl-single,pins = <
+                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
+                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
+                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
+                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
+                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+                       0x20 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad8.gpmc_ad8 */
+                       0x24 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad9.gpmc_ad9 */
+                       0x28 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad10.gpmc_ad10 */
+                       0x2c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad11.gpmc_ad11 */
+                       0x30 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad12.gpmc_ad12 */
+                       0x34 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad13.gpmc_ad13 */
+                       0x38 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad14.gpmc_ad14 */
+                       0x3c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad15.gpmc_ad15 */
+
+                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
+                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0 */
+                       0x80 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn1.gpmc_csn1 */
+                       0x84 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn2.gpmc_csn2 */
+                       0x88 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn3.gpmc_csn3 */
+
+                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
+                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
+                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
+                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_ben0_cle.gpmc_ben0_cle */
+
+                       0xa4 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data1.gpmc_a1 */
+                       0xa8 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data2.gpmc_a2 */
+                       0xac (PIN_OUTPUT | MUX_MODE1)           /* lcd_data3.gpmc_a3 */
+                       0xb0 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data4.gpmc_a4 */
+                       0xb4 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data5.gpmc_a5 */
+                       0xb8 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data6.gpmc_a6 */
+                       0xbc (PIN_OUTPUT | MUX_MODE1)           /* lcd_data7.gpmc_a7 */
+
+                       0xe0 (PIN_OUTPUT | MUX_MODE1)           /* lcd_vsync.gpmc_a8 */
+                       0xe4 (PIN_OUTPUT | MUX_MODE1)           /* lcd_hsync.gpmc_a9 */
+                       0xe8 (PIN_OUTPUT | MUX_MODE1)           /* lcd_pclk.gpmc_a10 */
+               >;
+       };
+
+       i2c0_pins: i2c0_pins {
+               pinctrl-single,pins = <
+                       0x188 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
+                       0x18c (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       uart0_pins: uart0_pins {
+               pinctrl-single,pins = <
+                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       0x174 (PIN_OUTPUT | MUX_MODE0)          /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       uart1_pins: uart1_pins {
+               pinctrl-single,pins = <
+                       0x178 (PIN_OUTPUT | MUX_MODE7)          /* uart1_ctsn.uart1_ctsn */
+                       0x17c (PIN_OUTPUT | MUX_MODE7)          /* uart1_rtsn.uart1_rtsn */
+                       0x180 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_rxd.uart1_rxd */
+                       0x184 (PIN_OUTPUT | MUX_MODE0)          /* uart1_txd.uart1_txd */
+               >;
+       };
+
+       uart2_pins: uart2_pins {
+               pinctrl-single,pins = <
+                       0xc0 (PIN_INPUT_PULLUP | MUX_MODE7)     /* lcd_data8.gpio2[14] */
+                       0xc4 (PIN_OUTPUT | MUX_MODE7)           /* lcd_data9.gpio2[15] */
+                       0x150 (PIN_INPUT | MUX_MODE1)           /* spi0_sclk.uart2_rxd */
+                       0x154 (PIN_OUTPUT | MUX_MODE1)          /* spi0_d0.uart2_txd */
+               >;
+       };
+
+       uart3_pins: uart3_pins {
+               pinctrl-single,pins = <
+                       0xc8 (PIN_INPUT_PULLUP | MUX_MODE6)     /* lcd_data10.uart3_ctsn */
+                       0xcc (PIN_OUTPUT | MUX_MODE6)           /* lcd_data11.uart3_rtsn */
+                       0x160 (PIN_INPUT | MUX_MODE1)           /* spi0_cs1.uart3_rxd */
+                       0x164 (PIN_OUTPUT | MUX_MODE1)          /* ecap0_in_pwm0_out.uart3_txd */
+               >;
+       };
+
+       uart4_pins: uart4_pins {
+               pinctrl-single,pins = <
+                       0xd0 (PIN_INPUT_PULLUP | MUX_MODE6)     /* lcd_data12.uart4_ctsn */
+                       0xd4 (PIN_OUTPUT | MUX_MODE6)           /* lcd_data13.uart4_rtsn */
+                       0x168 (PIN_INPUT | MUX_MODE1)           /* uart0_ctsn.uart4_rxd */
+                       0x16c (PIN_OUTPUT | MUX_MODE1)          /* uart0_rtsn.uart4_txd */
+               >;
+       };
+
+       uart5_pins: uart5_pins {
+               pinctrl-single,pins = <
+                       0xd8 (PIN_INPUT | MUX_MODE4)            /* lcd_data14.uart5_rxd */
+                       0x144 (PIN_OUTPUT | MUX_MODE3)          /* rmiii1_refclk.uart5_txd */
+               >;
+       };
+
+       mmc1_pins: mmc1_pins {
+               pinctrl-single,pins = <
+                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat0.mmc0_dat0 */
+                       0xf4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat1.mmc0_dat1 */
+                       0xf8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat2.mmc0_dat2 */
+                       0xfc (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat3.mmc0_dat3 */
+                       0x100 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_clk.mmc0_clk */
+                       0x104 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_cmd.mmc0_cmd */
+                       0x1e8 (PIN_INPUT_PULLUP | MUX_MODE7)    /* emu1.gpio3[8] */
+                       0x1a0 (PIN_INPUT_PULLUP | MUX_MODE7)    /* mcasp0_aclkr.gpio3[18] */
+               >;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       status = "okay";
+       rts-gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+       rs485-rts-active-high;
+       rs485-rx-during-tx;
+       rs485-rts-delay = <1 1>;
+       linux,rs485-enabled-at-boot-time;
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+       rts-gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+       rs485-rts-active-high;
+       rs485-rts-delay = <1 1>;
+       linux,rs485-enabled-at-boot-time;
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_pins>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart5_pins>;
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       gpio@20 {
+               compatible = "mcp,mcp23017";
+               reg = <0x20>;
+       };
+
+       tps: tps@24 {
+               reg = <0x24>;
+       };
+
+       eeprom@53 {
+               compatible = "mcp,24c02";
+               reg = <0x53>;
+               pagesize = <8>;
+       };
+
+       rtc@68 {
+               compatible = "dallas,ds1307";
+               reg = <0x68>;
+       };
+};
+
+&elm {
+       status = "okay";
+};
+
+&gpmc {
+       compatible = "ti,am3352-gpmc";
+       ti,hwmods = "gpmc";
+       status = "okay";
+       gpmc,num-waitpins = <2>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpmc_pins>;
+
+       #address-cells = <2>;
+       #size-cells = <1>;
+       ranges = <0 0 0x08000000 0x08000000>;   /* CS0: NOR 128M */
+
+       nor@0,0 {
+               reg = <0 0x00000000 0x08000000>;
+               compatible = "cfi-flash";
+               linux,mtd-name = "spansion,s29gl010p11t";
+               bank-width = <2>;
+
+               gpmc,mux-add-data = <2>;
+
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <160>;
+               gpmc,cs-wr-off-ns = <160>;
+               gpmc,adv-on-ns = <10>;
+               gpmc,adv-rd-off-ns = <30>;
+               gpmc,adv-wr-off-ns = <30>;
+               gpmc,oe-on-ns = <40>;
+               gpmc,oe-off-ns = <160>;
+               gpmc,we-on-ns = <40>;
+               gpmc,we-off-ns = <160>;
+               gpmc,rd-cycle-ns = <160>;
+               gpmc,wr-cycle-ns = <160>;
+               gpmc,access-ns = <150>;
+               gpmc,page-burst-access-ns = <10>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-delay-ns = <20>;
+               gpmc,wr-data-mux-bus-ns = <70>;
+               gpmc,wr-access-ns = <80>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               /*
+               MTD partition table
+               ===================
+               +------------+-->0x00000000-> U-Boot start
+               |            |
+               |            |-->0x000BFFFF-> U-Boot end
+               |            |-->0x000C0000-> ENV1 start
+               |            |
+               |            |-->0x000DFFFF-> ENV1 end
+               |            |-->0x000E0000-> ENV2 start
+               |            |
+               |            |-->0x000FFFFF-> ENV2 end
+               |            |-->0x00100000-> Kernel start
+               |            |
+               |            |-->0x004FFFFF-> Kernel end
+               |            |-->0x00500000-> File system start
+               |            |
+               |            |-->0x014FFFFF-> File system end
+               |            |-->0x01500000-> User data start
+               |            |
+               |            |-->0x03FFFFFF-> User data end
+               |            |-->0x04000000-> Data storage start
+               |            |
+               +------------+-->0x08000000-> NOR end (Free end)
+               */
+               partition@0 {
+                       label = "boot";
+                       reg = <0x00000000 0x000c0000>; /* 768KB */
+               };
+
+               partition@1 {
+                       label = "env1";
+                       reg = <0x000c0000 0x00020000>; /* 128KB */
+               };
+
+               partition@2 {
+                       label = "env2";
+                       reg = <0x000e0000 0x00020000>; /* 128KB */
+               };
+
+               partition@3 {
+                       label = "kernel";
+                       reg = <0x00100000 0x00400000>; /* 4MB */
+               };
+
+               partition@4 {
+                       label = "rootfs";
+                       reg = <0x00500000 0x01000000>; /* 16MB */
+               };
+
+               partition@5 {
+                       label = "user";
+                       reg = <0x01500000 0x02b00000>; /* 43MB */
+               };
+
+               partition@6 {
+                       label = "data";
+                       reg = <0x04000000 0x04000000>; /* 64MB */
+               };
+       };
+};
+
+&mac {
+       dual_emac = <1>;
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <1>;
+       dual_emac_res_vlan = <2>;
+};
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&ldo4_reg>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       bus-width = <4>;
+       cd-gpios = <&gpio3 8 0>;
+       wp-gpios = <&gpio3 18 0>;
+};
+
+#include "tps65217.dtsi"
+
+&tps {
+       regulators {
+               dcdc1_reg: regulator@0 {
+                       /* +1.5V voltage with Â±4% tolerance */
+                       regulator-min-microvolt = <1450000>;
+                       regulator-max-microvolt = <1550000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc2_reg: regulator@1 {
+                       /* VDD_MPU voltage limits 0.95V - 1.1V with Â±4% tolerance */
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <915000>;
+                       regulator-max-microvolt = <1140000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc3_reg: regulator@2 {
+                       /* VDD_CORE voltage limits 0.95V - 1.1V with Â±4% tolerance */
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <915000>;
+                       regulator-max-microvolt = <1140000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo1_reg: regulator@3 {
+                       /* +1.8V voltage with Â±4% tolerance */
+                       regulator-min-microvolt = <1750000>;
+                       regulator-max-microvolt = <1870000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo2_reg: regulator@4 {
+                       /* +3.3V voltage with Â±4% tolerance */
+                       regulator-min-microvolt = <3175000>;
+                       regulator-max-microvolt = <3430000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo3_reg: regulator@5 {
+                       /* +1.8V voltage with Â±4% tolerance */
+                       regulator-min-microvolt = <1750000>;
+                       regulator-max-microvolt = <1870000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo4_reg: regulator@6 {
+                       /* +3.3V voltage with Â±4% tolerance */
+                       regulator-min-microvolt = <3175000>;
+                       regulator-max-microvolt = <3430000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+};
index f9c5da9c7fe1ce7d56557fb4582a0d9a53bbcfde..fcb9c8e42ab79b053f14639886c2d75bd58f2161 100644 (file)
@@ -18,6 +18,9 @@
        interrupt-parent = <&intc>;
 
        aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
                serial0 = &uart0;
                serial1 = &uart1;
                serial2 = &uart2;
@@ -30,6 +33,8 @@
                usb1 = &usb1;
                phy0 = &usb0_phy;
                phy1 = &usb1_phy;
+               ethernet0 = &cpsw_emac0;
+               ethernet1 = &cpsw_emac1;
        };
 
        cpus {
                };
        };
 
+       pmu {
+               compatible = "arm,cortex-a8-pmu";
+               interrupts = <3>;
+       };
+
        /*
         * The soc node represents the soc top level view. It is uses for IPs
         * that are not memory mapped in the MPU view or for the MPU itself.
                        reg = <0x48200000 0x1000>;
                };
 
+               edma: edma@49000000 {
+                       compatible = "ti,edma3";
+                       ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+                       reg =   <0x49000000 0x10000>,
+                               <0x44e10f90 0x10>;
+                       interrupts = <12 13 14>;
+                       #dma-cells = <1>;
+                       dma-channels = <64>;
+                       ti,edma-regions = <4>;
+                       ti,edma-slots = <256>;
+               };
+
                gpio0: gpio@44e07000 {
                        compatible = "ti,omap4-gpio";
                        ti,hwmods = "gpio1";
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                        reg = <0x44e07000 0x1000>;
                        interrupts = <96>;
                };
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                        reg = <0x4804c000 0x1000>;
                        interrupts = <98>;
                };
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                        reg = <0x481ac000 0x1000>;
                        interrupts = <32>;
                };
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                        reg = <0x481ae000 0x1000>;
                        interrupts = <62>;
                };
                        status = "disabled";
                };
 
+               mmc1: mmc@48060000 {
+                       compatible = "ti,omap4-hsmmc";
+                       ti,hwmods = "mmc1";
+                       ti,dual-volt;
+                       ti,needs-special-reset;
+                       ti,needs-special-hs-handling;
+                       dmas = <&edma 24
+                               &edma 25>;
+                       dma-names = "tx", "rx";
+                       interrupts = <64>;
+                       interrupt-parent = <&intc>;
+                       reg = <0x48060000 0x1000>;
+                       status = "disabled";
+               };
+
+               mmc2: mmc@481d8000 {
+                       compatible = "ti,omap4-hsmmc";
+                       ti,hwmods = "mmc2";
+                       ti,needs-special-reset;
+                       dmas = <&edma 2
+                               &edma 3>;
+                       dma-names = "tx", "rx";
+                       interrupts = <28>;
+                       interrupt-parent = <&intc>;
+                       reg = <0x481d8000 0x1000>;
+                       status = "disabled";
+               };
+
+               mmc3: mmc@47810000 {
+                       compatible = "ti,omap4-hsmmc";
+                       ti,hwmods = "mmc3";
+                       ti,needs-special-reset;
+                       interrupts = <29>;
+                       interrupt-parent = <&intc>;
+                       reg = <0x47810000 0x1000>;
+                       status = "disabled";
+               };
+
+               hwspinlock: spinlock@480ca000 {
+                       compatible = "ti,omap4-hwspinlock";
+                       reg = <0x480ca000 0x1000>;
+                       ti,hwmods = "spinlock";
+               };
+
                wdt2: wdt@44e35000 {
                        compatible = "ti,omap3-wdt";
                        ti,hwmods = "wd_timer2";
                        interrupts = <65>;
                        ti,spi-num-cs = <2>;
                        ti,hwmods = "spi0";
+                       dmas = <&edma 16
+                               &edma 17
+                               &edma 18
+                               &edma 19>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
                        status = "disabled";
                };
 
                        interrupts = <125>;
                        ti,spi-num-cs = <2>;
                        ti,hwmods = "spi1";
+                       dmas = <&edma 42
+                               &edma 43
+                               &edma 44
+                               &edma 45>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
                        status = "disabled";
                };
 
                        ti,hwmods = "usb_otg_hs";
                        status = "disabled";
 
-                       ctrl_mod: control@44e10000 {
+                       usb_ctrl_mod: control@44e10000 {
                                compatible = "ti,am335x-usb-ctrl-module";
                                reg = <0x44e10620 0x10
                                        0x44e10648 0x4>;
                                reg = <0x47401300 0x100>;
                                reg-names = "phy";
                                status = "disabled";
-                               ti,ctrl_mod = <&ctrl_mod>;
+                               ti,ctrl_mod = <&usb_ctrl_mod>;
                        };
 
                        usb0: usb@47401000 {
                                reg = <0x47401b00 0x100>;
                                reg-names = "phy";
                                status = "disabled";
-                               ti,ctrl_mod = <&ctrl_mod>;
+                               ti,ctrl_mod = <&usb_ctrl_mod>;
                        };
 
                        usb1: usb@47401800 {
                        reg = <0x44d00000 0x4000        /* M3 UMEM */
                               0x44d80000 0x2000>;      /* M3 DMEM */
                        ti,hwmods = "wkup_m3";
+                       ti,no-reset-on-init;
                };
 
                elm: elm@48080000 {
                        status = "disabled";
                };
 
+               lcdc: lcdc@4830e000 {
+                       compatible = "ti,am33xx-tilcdc";
+                       reg = <0x4830e000 0x1000>;
+                       interrupt-parent = <&intc>;
+                       interrupts = <36>;
+                       ti,hwmods = "lcdc";
+                       status = "disabled";
+               };
+
                tscadc: tscadc@44e0d000 {
                        compatible = "ti,am3359-tscadc";
                        reg = <0x44e0d000 0x1000>;
                gpmc: gpmc@50000000 {
                        compatible = "ti,am3352-gpmc";
                        ti,hwmods = "gpmc";
+                       ti,no-idle-on-init;
                        reg = <0x50000000 0x2000>;
                        interrupts = <100>;
                        gpmc,num-cs = <7>;
                        #size-cells = <1>;
                        status = "disabled";
                };
+
+               sham: sham@53100000 {
+                       compatible = "ti,omap4-sham";
+                       ti,hwmods = "sham";
+                       reg = <0x53100000 0x200>;
+                       interrupts = <109>;
+                       dmas = <&edma 36>;
+                       dma-names = "rx";
+               };
+
+               aes: aes@53500000 {
+                       compatible = "ti,omap4-aes";
+                       ti,hwmods = "aes";
+                       reg = <0x53500000 0xa0>;
+                       interrupts = <103>;
+                       dmas = <&edma 6>,
+                              <&edma 5>;
+                       dma-names = "tx", "rx";
+               };
+
+               mcasp0: mcasp@48038000 {
+                       compatible = "ti,am33xx-mcasp-audio";
+                       ti,hwmods = "mcasp0";
+                       reg = <0x48038000 0x2000>,
+                             <0x46000000 0x400000>;
+                       reg-names = "mpu", "dat";
+                       interrupts = <80>, <81>;
+                       interrupts-names = "tx", "rx";
+                       status = "disabled";
+                       dmas = <&edma 8>,
+                               <&edma 9>;
+                       dma-names = "tx", "rx";
+               };
+
+               mcasp1: mcasp@4803C000 {
+                       compatible = "ti,am33xx-mcasp-audio";
+                       ti,hwmods = "mcasp1";
+                       reg = <0x4803C000 0x2000>,
+                             <0x46400000 0x400000>;
+                       reg-names = "mpu", "dat";
+                       interrupts = <82>, <83>;
+                       interrupts-names = "tx", "rx";
+                       status = "disabled";
+                       dmas = <&edma 10>,
+                               <&edma 11>;
+                       dma-names = "tx", "rx";
+               };
+
+               rng: rng@48310000 {
+                       compatible = "ti,omap4-rng";
+                       ti,hwmods = "rng";
+                       reg = <0x48310000 0x2000>;
+                       interrupts = <111>;
+               };
        };
 };
index ddc1df77ac5261b5f5a6f4bcc84f69eb2c30dc0c..974d103ab3b1e673fe255e28e5c13d8544ad2565 100644 (file)
 
 
        aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
                serial0 = &uart0;
+               ethernet0 = &cpsw_emac0;
+               ethernet1 = &cpsw_emac1;
        };
 
        cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
                cpu@0 {
                        compatible = "arm,cortex-a9";
+                       device_type = "cpu";
+                       reg = <0>;
                };
        };
 
                      <0x48240100 0x0100>;
        };
 
+       l2-cache-controller@48242000 {
+               compatible = "arm,pl310-cache";
+               reg = <0x48242000 0x1000>;
+               cache-unified;
+               cache-level = <2>;
+       };
+
+       am43xx_pinmux: pinmux@44e10800 {
+               compatible = "pinctrl-single";
+               reg = <0x44e10800 0x31c>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0xffffffff>;
+       };
+
        ocp {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
+               ti,hwmods = "l3_main";
+
+               edma: edma@49000000 {
+                       compatible = "ti,edma3";
+                       ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+                       reg =   <0x49000000 0x10000>,
+                               <0x44e10f90 0x10>;
+                       interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       dma-channels = <64>;
+                       ti,edma-regions = <4>;
+                       ti,edma-slots = <256>;
+               };
 
                uart0: serial@44e09000 {
                        compatible = "ti,am4372-uart","ti,omap2-uart";
                        reg = <0x44e09000 0x2000>;
                        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart1";
+               };
+
+               uart1: serial@48022000 {
+                       compatible = "ti,am4372-uart","ti,omap2-uart";
+                       reg = <0x48022000 0x2000>;
+                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart2";
+                       status = "disabled";
+               };
+
+               uart2: serial@48024000 {
+                       compatible = "ti,am4372-uart","ti,omap2-uart";
+                       reg = <0x48024000 0x2000>;
+                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart3";
+                       status = "disabled";
+               };
+
+               uart3: serial@481a6000 {
+                       compatible = "ti,am4372-uart","ti,omap2-uart";
+                       reg = <0x481a6000 0x2000>;
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart4";
+                       status = "disabled";
+               };
+
+               uart4: serial@481a8000 {
+                       compatible = "ti,am4372-uart","ti,omap2-uart";
+                       reg = <0x481a8000 0x2000>;
+                       interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart5";
+                       status = "disabled";
+               };
+
+               uart5: serial@481aa000 {
+                       compatible = "ti,am4372-uart","ti,omap2-uart";
+                       reg = <0x481aa000 0x2000>;
+                       interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart6";
+                       status = "disabled";
+               };
+
+               mailbox: mailbox@480C8000 {
+                       compatible = "ti,omap4-mailbox";
+                       reg = <0x480C8000 0x200>;
+                       interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mailbox";
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <8>;
+                       ti,mbox-names = "wkup_m3";
+                       ti,mbox-data = <0 0 0 0>;
+                       status = "disabled";
                };
 
                timer1: timer@44e31000 {
                        reg = <0x44e31000 0x400>;
                        interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
                        ti,timer-alwon;
+                       ti,hwmods = "timer1";
                };
 
                timer2: timer@48040000  {
                        compatible = "ti,am4372-timer","ti,am335x-timer";
                        reg = <0x48040000  0x400>;
                        interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer2";
+               };
+
+               timer3: timer@48042000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x48042000 0x400>;
+                       interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer3";
+                       status = "disabled";
+               };
+
+               timer4: timer@48044000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x48044000 0x400>;
+                       interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,timer-pwm;
+                       ti,hwmods = "timer4";
+                       status = "disabled";
+               };
+
+               timer5: timer@48046000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x48046000 0x400>;
+                       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,timer-pwm;
+                       ti,hwmods = "timer5";
+                       status = "disabled";
+               };
+
+               timer6: timer@48048000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x48048000 0x400>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,timer-pwm;
+                       ti,hwmods = "timer6";
+                       status = "disabled";
+               };
+
+               timer7: timer@4804a000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x4804a000 0x400>;
+                       interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,timer-pwm;
+                       ti,hwmods = "timer7";
+                       status = "disabled";
+               };
+
+               timer8: timer@481c1000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x481c1000 0x400>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer8";
+                       status = "disabled";
+               };
+
+               timer9: timer@4833d000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x4833d000 0x400>;
+                       interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer9";
+                       status = "disabled";
+               };
+
+               timer10: timer@4833f000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x4833f000 0x400>;
+                       interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer10";
+                       status = "disabled";
+               };
+
+               timer11: timer@48341000 {
+                       compatible = "ti,am4372-timer","ti,am335x-timer";
+                       reg = <0x48341000 0x400>;
+                       interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer11";
+                       status = "disabled";
                };
 
                counter32k: counter@44e86000 {
                        compatible = "ti,am4372-counter32k","ti,omap-counter32k";
                        reg = <0x44e86000 0x40>;
+                       ti,hwmods = "counter_32k";
+               };
+
+               rtc@44e3e000 {
+                       compatible = "ti,am4372-rtc","ti,da830-rtc";
+                       reg = <0x44e3e000 0x1000>;
+                       interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "rtc";
+                       status = "disabled";
+               };
+
+               wdt@44e35000 {
+                       compatible = "ti,am4372-wdt","ti,omap3-wdt";
+                       reg = <0x44e35000 0x1000>;
+                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "wd_timer2";
+               };
+
+               gpio0: gpio@44e07000 {
+                       compatible = "ti,am4372-gpio","ti,omap4-gpio";
+                       reg = <0x44e07000 0x1000>;
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ti,hwmods = "gpio1";
+                       status = "disabled";
+               };
+
+               gpio1: gpio@4804c000 {
+                       compatible = "ti,am4372-gpio","ti,omap4-gpio";
+                       reg = <0x4804c000 0x1000>;
+                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ti,hwmods = "gpio2";
+                       status = "disabled";
+               };
+
+               gpio2: gpio@481ac000 {
+                       compatible = "ti,am4372-gpio","ti,omap4-gpio";
+                       reg = <0x481ac000 0x1000>;
+                       interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ti,hwmods = "gpio3";
+                       status = "disabled";
+               };
+
+               gpio3: gpio@481ae000 {
+                       compatible = "ti,am4372-gpio","ti,omap4-gpio";
+                       reg = <0x481ae000 0x1000>;
+                       interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ti,hwmods = "gpio4";
+                       status = "disabled";
+               };
+
+               gpio4: gpio@48320000 {
+                       compatible = "ti,am4372-gpio","ti,omap4-gpio";
+                       reg = <0x48320000 0x1000>;
+                       interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ti,hwmods = "gpio5";
+                       status = "disabled";
+               };
+
+               gpio5: gpio@48322000 {
+                       compatible = "ti,am4372-gpio","ti,omap4-gpio";
+                       reg = <0x48322000 0x1000>;
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ti,hwmods = "gpio6";
+                       status = "disabled";
+               };
+
+               i2c0: i2c@44e0b000 {
+                       compatible = "ti,am4372-i2c","ti,omap4-i2c";
+                       reg = <0x44e0b000 0x1000>;
+                       interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "i2c1";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@4802a000 {
+                       compatible = "ti,am4372-i2c","ti,omap4-i2c";
+                       reg = <0x4802a000 0x1000>;
+                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "i2c2";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@4819c000 {
+                       compatible = "ti,am4372-i2c","ti,omap4-i2c";
+                       reg = <0x4819c000 0x1000>;
+                       interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "i2c3";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi0: spi@48030000 {
+                       compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+                       reg = <0x48030000 0x400>;
+                       interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "spi0";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               mmc1: mmc@48060000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x48060000 0x1000>;
+                       ti,hwmods = "mmc1";
+                       ti,dual-volt;
+                       ti,needs-special-reset;
+                       dmas = <&edma 24
+                               &edma 25>;
+                       dma-names = "tx", "rx";
+                       interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               mmc2: mmc@481d8000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x481d8000 0x1000>;
+                       ti,hwmods = "mmc2";
+                       ti,needs-special-reset;
+                       dmas = <&edma 2
+                               &edma 3>;
+                       dma-names = "tx", "rx";
+                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               mmc3: mmc@47810000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x47810000 0x1000>;
+                       ti,hwmods = "mmc3";
+                       ti,needs-special-reset;
+                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               spi1: spi@481a0000 {
+                       compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+                       reg = <0x481a0000 0x400>;
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "spi1";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi2: spi@481a2000 {
+                       compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+                       reg = <0x481a2000 0x400>;
+                       interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "spi2";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi3: spi@481a4000 {
+                       compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+                       reg = <0x481a4000 0x400>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "spi3";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi4: spi@48345000 {
+                       compatible = "ti,am4372-mcspi","ti,omap4-mcspi";
+                       reg = <0x48345000 0x400>;
+                       interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "spi4";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               mac: ethernet@4a100000 {
+                       compatible = "ti,am4372-cpsw","ti,cpsw";
+                       reg = <0x4a100000 0x800
+                              0x4a101200 0x100>;
+                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ti,hwmods = "cpgmac0";
+                       status = "disabled";
+                       cpdma_channels = <8>;
+                       ale_entries = <1024>;
+                       bd_ram_size = <0x2000>;
+                       no_bd_ram = <0>;
+                       rx_descs = <64>;
+                       mac_control = <0x20>;
+                       slaves = <2>;
+                       active_slave = <0>;
+                       cpts_clock_mult = <0x80000000>;
+                       cpts_clock_shift = <29>;
+                       ranges;
+
+                       davinci_mdio: mdio@4a101000 {
+                               compatible = "ti,am4372-mdio","ti,davinci_mdio";
+                               reg = <0x4a101000 0x100>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               ti,hwmods = "davinci_mdio";
+                               bus_freq = <1000000>;
+                               status = "disabled";
+                       };
+
+                       cpsw_emac0: slave@4a100200 {
+                               /* Filled in by U-Boot */
+                               mac-address = [ 00 00 00 00 00 00 ];
+                       };
+
+                       cpsw_emac1: slave@4a100300 {
+                               /* Filled in by U-Boot */
+                               mac-address = [ 00 00 00 00 00 00 ];
+                       };
+               };
+
+               epwmss0: epwmss@48300000 {
+                       compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+                       reg = <0x48300000 0x10>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "epwmss0";
+                       status = "disabled";
+
+                       ecap0: ecap@48300100 {
+                               compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+                               reg = <0x48300100 0x80>;
+                               ti,hwmods = "ecap0";
+                               status = "disabled";
+                       };
+
+                       ehrpwm0: ehrpwm@48300200 {
+                               compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               reg = <0x48300200 0x80>;
+                               ti,hwmods = "ehrpwm0";
+                               status = "disabled";
+                       };
+               };
+
+               epwmss1: epwmss@48302000 {
+                       compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+                       reg = <0x48302000 0x10>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "epwmss1";
+                       status = "disabled";
+
+                       ecap1: ecap@48302100 {
+                               compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+                               reg = <0x48302100 0x80>;
+                               ti,hwmods = "ecap1";
+                               status = "disabled";
+                       };
+
+                       ehrpwm1: ehrpwm@48302200 {
+                               compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               reg = <0x48302200 0x80>;
+                               ti,hwmods = "ehrpwm1";
+                               status = "disabled";
+                       };
+               };
+
+               epwmss2: epwmss@48304000 {
+                       compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+                       reg = <0x48304000 0x10>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "epwmss2";
+                       status = "disabled";
+
+                       ecap2: ecap@48304100 {
+                               compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+                               reg = <0x48304100 0x80>;
+                               ti,hwmods = "ecap2";
+                               status = "disabled";
+                       };
+
+                       ehrpwm2: ehrpwm@48304200 {
+                               compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               reg = <0x48304200 0x80>;
+                               ti,hwmods = "ehrpwm2";
+                               status = "disabled";
+                       };
+               };
+
+               epwmss3: epwmss@48306000 {
+                       compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+                       reg = <0x48306000 0x10>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "epwmss3";
+                       status = "disabled";
+
+                       ehrpwm3: ehrpwm@48306200 {
+                               compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               reg = <0x48306200 0x80>;
+                               ti,hwmods = "ehrpwm3";
+                               status = "disabled";
+                       };
+               };
+
+               epwmss4: epwmss@48308000 {
+                       compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+                       reg = <0x48308000 0x10>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "epwmss4";
+                       status = "disabled";
+
+                       ehrpwm4: ehrpwm@48308200 {
+                               compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               reg = <0x48308200 0x80>;
+                               ti,hwmods = "ehrpwm4";
+                               status = "disabled";
+                       };
+               };
+
+               epwmss5: epwmss@4830a000 {
+                       compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
+                       reg = <0x4830a000 0x10>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "epwmss5";
+                       status = "disabled";
+
+                       ehrpwm5: ehrpwm@4830a200 {
+                               compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               reg = <0x4830a200 0x80>;
+                               ti,hwmods = "ehrpwm5";
+                               status = "disabled";
+                       };
+               };
+
+               sham: sham@53100000 {
+                       compatible = "ti,omap5-sham";
+                       ti,hwmods = "sham";
+                       reg = <0x53100000 0x300>;
+                       dmas = <&edma 36>;
+                       dma-names = "rx";
+                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               aes: aes@53501000 {
+                       compatible = "ti,omap4-aes";
+                       ti,hwmods = "aes";
+                       reg = <0x53501000 0xa0>;
+                       interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&edma 6
+                               &edma 5>;
+                       dma-names = "tx", "rx";
+               };
+
+               des: des@53701000 {
+                       compatible = "ti,omap4-des";
+                       ti,hwmods = "des";
+                       reg = <0x53701000 0xa0>;
+                       interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&edma 34
+                               &edma 33>;
+                       dma-names = "tx", "rx";
+               };
+
+               mcasp0: mcasp@48038000 {
+                       compatible = "ti,am33xx-mcasp-audio";
+                       ti,hwmods = "mcasp0";
+                       reg = <0x48038000 0x2000>,
+                             <0x46000000 0x400000>;
+                       reg-names = "mpu", "dat";
+                       interrupts = <80>, <81>;
+                       interrupts-names = "tx", "rx";
+                       status = "disabled";
+                       dmas = <&edma 8>,
+                              <&edma 9>;
+                       dma-names = "tx", "rx";
+               };
+
+               mcasp1: mcasp@4803C000 {
+                       compatible = "ti,am33xx-mcasp-audio";
+                       ti,hwmods = "mcasp1";
+                       reg = <0x4803C000 0x2000>,
+                             <0x46400000 0x400000>;
+                       reg-names = "mpu", "dat";
+                       interrupts = <82>, <83>;
+                       interrupts-names = "tx", "rx";
+                       status = "disabled";
+                       dmas = <&edma 10>,
+                              <&edma 11>;
+                       dma-names = "tx", "rx";
                };
        };
 };
index 74174d48f476718f091f4211b723cbda57c19b3e..fbf9c4c7a94fe7f998346140d32540b6ebf3507f 100644 (file)
 /dts-v1/;
 
 #include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "TI AM43x EPOS EVM";
        compatible = "ti,am43x-epos-evm","ti,am4372","ti,am43";
+
+       vmmcsd_fixed: fixedregulator-sd {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+       };
+
+       am43xx_pinmux: pinmux@44e10800 {
+               cpsw_default: cpsw_default {
+                       pinctrl-single,pins = <
+                               /* Slave 1 */
+                               0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs */
+                               0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxerr.rmii1_rxerr */
+                               0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
+                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxdv.rmii1_rxdv */
+                               0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+                               0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd1.rmii1_rxd1 */
+                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd0.rmii1_rxd0 */
+                               0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* rmii1_refclk.rmii1_refclk */
+                       >;
+               };
+
+               cpsw_sleep: cpsw_sleep {
+                       pinctrl-single,pins = <
+                               /* Slave 1 reset value */
+                               0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       >;
+               };
+
+               davinci_mdio_default: davinci_mdio_default {
+                       pinctrl-single,pins = <
+                               /* MDIO */
+                               0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
+                               0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       >;
+               };
+
+               davinci_mdio_sleep: davinci_mdio_sleep {
+                       pinctrl-single,pins = <
+                               /* MDIO reset value */
+                               0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       >;
+               };
+
+               i2c0_pins: pinmux_i2c0_pins {
+                       pinctrl-single,pins = <
+                               0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
+                               0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                       >;
+               };
+       };
+
+       matrix_keypad: matrix_keypad@0 {
+                       compatible = "gpio-matrix-keypad";
+                       debounce-delay-ms = <5>;
+                       col-scan-delay-us = <2>;
+
+                       row-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH         /* Bank0, pin12 */
+                                    &gpio0 13 GPIO_ACTIVE_HIGH         /* Bank0, pin13 */
+                                    &gpio0 14 GPIO_ACTIVE_HIGH         /* Bank0, pin14 */
+                                    &gpio0 15 GPIO_ACTIVE_HIGH>;       /* Bank0, pin15 */
+
+                       col-gpios = <&gpio3 9 GPIO_ACTIVE_HIGH          /* Bank3, pin9 */
+                                    &gpio3 10 GPIO_ACTIVE_HIGH         /* Bank3, pin10 */
+                                    &gpio2 18 GPIO_ACTIVE_HIGH         /* Bank2, pin18 */
+                                    &gpio2 19 GPIO_ACTIVE_HIGH>;       /* Bank2, pin19 */
+
+                       linux,keymap = <0x00000201      /* P1 */
+                               0x01000204      /* P4 */
+                               0x02000207      /* P7 */
+                               0x0300020a      /* NUMERIC_STAR */
+                               0x00010202      /* P2 */
+                               0x01010205      /* P5 */
+                               0x02010208      /* P8 */
+                               0x03010200      /* P0 */
+                               0x00020203      /* P3 */
+                               0x01020206      /* P6 */
+                               0x02020209      /* P9 */
+                               0x0302020b      /* NUMERIC_POUND */
+                               0x00030067      /* UP */
+                               0x0103006a      /* RIGHT */
+                               0x0203006c      /* DOWN */
+                               0x03030069>;    /* LEFT */
+               };
+};
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&vmmcsd_fixed>;
+       bus-width = <4>;
+};
+
+&mac {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_default>;
+       pinctrl-1 = <&cpsw_sleep>;
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_default>;
+       pinctrl-1 = <&davinci_mdio_sleep>;
+       status = "okay";
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <16>;
+       phy-mode = "rmii";
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <1>;
+       phy-mode = "rmii";
+};
+
+&i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       at24@50 {
+               compatible = "at24,24c256";
+               pagesize = <64>;
+               reg = <0x50>;
+       };
+
+       pixcir_ts@5c {
+               compatible = "pixcir,pixcir_ts";
+               reg = <0x5c>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <17 0>;
+
+               attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+
+               x-size = <1024>;
+               y-size = <768>;
+       };
+};
+
+&gpio0 {
+       status = "okay";
+};
+
+&gpio1 {
+       status = "okay";
+};
+
+&gpio2 {
+       status = "okay";
+};
+
+&gpio3 {
+       status = "okay";
 };
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
new file mode 100644 (file)
index 0000000..b0b32f5
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS 104
+ *
+ * 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 "armada-370.dtsi"
+
+/ {
+       model = "NETGEAR ReadyNAS 104";
+       compatible = "netgear,readynas-104", "marvell,armada370", "marvell,armada-370-xp";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>; /* 512 MB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+                         MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+               pcie-controller {
+                       status = "okay";
+
+                       /* Connected to FL1009 USB 3.0 controller */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+
+                       /* Connected to Marvell 88SE9215 SATA controller */
+                       pcie@2,0 {
+                               /* Port 1, Lane 0 */
+                               status = "okay";
+                       };
+               };
+
+               internal-regs {
+                       serial@12000 {
+                               clock-frequency = <200000000>;
+                               status = "okay";
+                       };
+
+                       pinctrl {
+                               poweroff: poweroff {
+                                       marvell,pins = "mpp60";
+                                       marvell,function = "gpio";
+                               };
+
+                               backup_key_pin: backup-key-pin {
+                                       marvell,pins = "mpp52";
+                                       marvell,function = "gpio";
+                               };
+
+                               power_key_pin: power-key-pin {
+                                       marvell,pins = "mpp62";
+                                       marvell,function = "gpio";
+                               };
+
+                               backup_led_pin: backup-led-pin {
+                                       marvell,pins = "mpp63";
+                                       marvell,function = "gpo";
+                               };
+
+                               power_led_pin: power-led-pin {
+                                       marvell,pins = "mpp64";
+                                       marvell,function = "gpio";
+                               };
+
+                               reset_key_pin: reset-key-pin {
+                                       marvell,pins = "mpp65";
+                                       marvell,function = "gpio";
+                               };
+                       };
+
+                       mdio {
+                               phy0: ethernet-phy@0 {
+                                       reg = <0>;
+                               };
+
+                               phy1: ethernet-phy@1 {
+                                       reg = <1>;
+                               };
+                       };
+
+                       ethernet@70000 {
+                               status = "okay";
+                               phy = <&phy0>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       ethernet@74000 {
+                               status = "okay";
+                               phy = <&phy1>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       usb@50000 {
+                               status = "okay";
+                       };
+
+                       i2c@11000 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               clock-frequency = <100000>;
+                               status = "okay";
+
+                               g762: g762@3e {
+                                       compatible = "gmt,g762";
+                                       reg = <0x3e>;
+                                       clocks = <&g762_clk>; /* input clock */
+                                       fan_gear_mode = <0>;
+                                       fan_startv = <1>;
+                                       pwm_polarity = <0>;
+                               };
+                       };
+               };
+       };
+
+       clocks {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              g762_clk: fixedclk {
+                        compatible = "fixed-clock";
+                        #clock-cells = <0>;
+                        clock-frequency = <8192>;
+              };
+       };
+
+       gpio_leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&backup_led_pin &power_led_pin>;
+               pinctrl-names = "default";
+
+               blue_backup_led {
+                       label = "rn104:blue:backup";
+                       gpios = <&gpio1 31 0>;   /* GPIO 63 Active High */
+                       default-state = "off";
+               };
+
+               blue_power_led {
+                       label = "rn104:blue:pwr";
+                       gpios = <&gpio2 0 1>;    /* GPIO 64 Active Low */
+                       linux,default-trigger = "keep";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&backup_key_pin
+                            &power_key_pin
+                            &reset_key_pin>;
+               pinctrl-names = "default";
+
+               button@1 {
+                       label = "Backup Button";
+                       linux,code = <133>;     /* KEY_COPY */
+                       gpios = <&gpio1 20 1>;
+               };
+
+               button@2 {
+                       label = "Power Button";
+                       linux,code = <116>;     /* KEY_POWER */
+                       gpios = <&gpio1 30 0>;
+               };
+
+               button@3 {
+                       label = "Reset Button";
+                       linux,code = <0x198>;   /* KEY_RESTART */
+                       gpios = <&gpio2 1 1>;
+               };
+       };
+
+       gpio_poweroff {
+               compatible = "gpio-poweroff";
+               pinctrl-0 = <&poweroff>;
+               pinctrl-names = "default";
+               gpios = <&gpio1 28 1>;
+       };
+};
index 1de2dae0fdae6f6353169dc423d75e07d4f65f6f..00d6a798c705b9b04408a8d28af70cd7b7cc6868 100644 (file)
                                #interrupt-cells = <1>;
                                #size-cells = <1>;
                                interrupt-controller;
+                               msi-controller;
                        };
 
                        coherency-fabric@20200 {
                                status = "disabled";
                        };
 
+                       coredivclk: corediv-clock@18740 {
+                               compatible = "marvell,armada-370-corediv-clock";
+                               reg = <0x18740 0xc>;
+                               #clock-cells = <1>;
+                               clocks = <&mainpll>;
+                               clock-output-names = "nand";
+                       };
+
                        timer@20300 {
                                reg = <0x20300 0x30>, <0x21040 0x30>;
                                interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
 
                        i2c0: i2c@11000 {
                                compatible = "marvell,mv64xxx-i2c";
-                               reg = <0x11000 0x20>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                interrupts = <31>;
 
                        i2c1: i2c@11100 {
                                compatible = "marvell,mv64xxx-i2c";
-                               reg = <0x11100 0x20>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                interrupts = <32>;
 
                };
        };
+
+       clocks {
+               /* 2 GHz fixed main PLL */
+               mainpll: mainpll {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <2000000000>;
+               };
+       };
  };
index e134d7a90c9ab9a5d24bfb500ed9206875f8f033..7a4b82e71aaf399eec2dc461656826e2fdad738a 100644 (file)
@@ -44,6 +44,7 @@
                        #address-cells = <3>;
                        #size-cells = <2>;
 
+                       msi-parent = <&mpic>;
                        bus-range = <0x00 0xff>;
 
                        ranges =
                                };
                        };
 
+                       i2c0: i2c@11000 {
+                               reg = <0x11000 0x20>;
+                       };
+
+                       i2c1: i2c@11100 {
+                               reg = <0x11100 0x20>;
+                       };
+
                        usb@50000 {
                                clocks = <&coreclk 0>;
                        };
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
new file mode 100644 (file)
index 0000000..e47c49e
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Device Tree file for Marvell Armada XP Matrix board
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Lior Amsalem <alior@marvell.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.
+ */
+
+/dts-v1/;
+#include "armada-xp-mv78460.dtsi"
+
+/ {
+       model = "Marvell Armada XP Matrix Board";
+       compatible = "marvell,axp-matrix", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0 0x00000000 0 0x80000000>; /* 2 GB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+               internal-regs {
+                       serial@12000 {
+                               clock-frequency = <250000000>;
+                               status = "okay";
+                       };
+                       serial@12100 {
+                               clock-frequency = <250000000>;
+                               status = "okay";
+                       };
+                       serial@12200 {
+                               clock-frequency = <250000000>;
+                               status = "okay";
+                       };
+                       serial@12300 {
+                               clock-frequency = <250000000>;
+                               status = "okay";
+                       };
+
+                       sata@a0000 {
+                               nr-ports = <2>;
+                               status = "okay";
+                       };
+
+                       ethernet@30000 {
+                               status = "okay";
+                               phy-mode = "sgmii";
+                       };
+
+                       pcie-controller {
+                               status = "okay";
+
+                               pcie@1,0 {
+                                       /* Port 0, Lane 0 */
+                                       status = "okay";
+                               };
+                       };
+
+                       usb@50000 {
+                               status = "okay";
+                       };
+               };
+       };
+};
index 0358a33cba489d40c97fda0a1bd7cb5769ade9b8..3f5e6121c730a21ae2079acff268da2be20518ef 100644 (file)
@@ -57,6 +57,7 @@
                        #address-cells = <3>;
                        #size-cells = <2>;
 
+                       msi-parent = <&mpic>;
                        bus-range = <0x00 0xff>;
 
                        ranges =
index 0e82c5062243f2d20f608bbc36d80faf37645abd..3e9fd1353f895d6778972e95518850268ef6eb4e 100644 (file)
@@ -58,6 +58,7 @@
                        #address-cells = <3>;
                        #size-cells = <2>;
 
+                       msi-parent = <&mpic>;
                        bus-range = <0x00 0xff>;
 
                        ranges =
index e82c1b80af171e3915b6e09f95bfb9078d0b0201..31ba6d8fbadf8803f28aca6312c8205c79c23aee 100644 (file)
@@ -74,6 +74,7 @@
                        #address-cells = <3>;
                        #size-cells = <2>;
 
+                       msi-parent = <&mpic>;
                        bus-range = <0x00 0xff>;
 
                        ranges =
index 3058522f5aad2929092f7f7bcc2dd78a9c62c22a..281c6447e87272c0df44f89da6489876b8c9ade8 100644 (file)
                                };
                        };
 
+                       i2c0: i2c@11000 {
+                               compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+                               reg = <0x11000 0x100>;
+                       };
+
+                       i2c1: i2c@11100 {
+                               compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+                               reg = <0x11100 0x100>;
+                       };
+
                        usb@50000 {
                                clocks = <&gateclk 18>;
                        };
index 137354689ad0a6dfdd08d07b348cd8cf08705e42..cb2c010e08e21fd5bd5b871aa3d3e496ffc0005e 100644 (file)
@@ -96,7 +96,6 @@
                        };
 
                        spi0: spi@fffc8000 {
-                               status = "okay";
                                cs-gpios = <0>, <&pioC 11 0>, <0>, <0>;
                                mtd_dataflash@0 {
                                        compatible = "atmel,at45", "atmel,dataflash";
index b4ec6fe53fc798e4469ca772a3ff6d02e86eba32..17b879990914c8643bfc63cb98b634c112f4f454 100644 (file)
@@ -7,6 +7,8 @@
  */
 
 #include "at91sam9x5.dtsi"
+#include "at91sam9x5_usart3.dtsi"
+#include "at91sam9x5_macb0.dtsi"
 
 / {
        model = "Atmel AT91SAM9G25 SoC";
index bebf9f55614b50c27edb1a1dd42fb7b3ae6c54de..e35c2fcf82985fabcbc1150510db2b3eedd58daa 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "at91sam9x5.dtsi"
+#include "at91sam9x5_macb0.dtsi"
 
 / {
        model = "Atmel AT91SAM9G35 SoC";
index 9fb7ffd32af26cd9ab7d959f7e1641b2937e050a..6224f9fe2f2b7205f32a3205ff78d0b31036ad09 100644 (file)
                                compatible = "atmel,at91sam9g45-ssc";
                                reg = <0xf0010000 0x4000>;
                                interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>;
+                               dmas = <&dma 0 AT91_DMA_CFG_PER_ID(21)>,
+                                      <&dma 0 AT91_DMA_CFG_PER_ID(22)>;
+                               dma-names = "tx", "rx";
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
                                status = "disabled";
index 27a9352b9d7a02e047303a2fb72bb47a5ec9f0c8..e9487f6f01660409ee193649d3c1d56c98376cb5 100644 (file)
                                status = "okay";
                        };
 
+                       ssc0: ssc@f0010000 {
+                               status = "okay";
+                       };
+
                        i2c0: i2c@f8010000 {
                                status = "okay";
 
+                               wm8904: codec@1a {
+                                       compatible = "wm8904";
+                                       reg = <0x1a>;
+                               };
+
                                qt1070: keyboard@1b {
                                        compatible = "qt1070";
                                        reg = <0x1b>;
                                                        <AT91_PIOA 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
                                        };
                                };
+
+                               sound {
+                                       pinctrl_pck0_as_audio_mck: pck0_as_audio_mck {
+                                               atmel,pins =
+                                                       <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
                        };
 
                        spi0: spi@f0000000 {
                        gpio-key,wakeup;
                };
        };
+
+       sound {
+               compatible = "atmel,asoc-wm8904";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pck0_as_audio_mck>;
+
+               atmel,model = "wm8904 @ AT91SAM9N12";
+               atmel,audio-routing =
+                       "Headphone Jack", "HPOUTL",
+                       "Headphone Jack", "HPOUTR",
+                       "IN2L", "Line In Jack",
+                       "IN2R", "Line In Jack",
+                       "Mic", "MICBIAS",
+                       "IN1L", "Mic";
+
+               atmel,ssc-controller = <&ssc0>;
+               atmel,audio-codec = <&wm8904>;
+       };
 };
index 49e94aba938ff65f5827e1f56bd17fcde898fd38..c2554219f7a4eb736c2f46f6ce36175311d5d530 100644 (file)
@@ -7,6 +7,9 @@
  */
 
 #include "at91sam9x5.dtsi"
+#include "at91sam9x5_usart3.dtsi"
+#include "at91sam9x5_macb0.dtsi"
+#include "at91sam9x5_macb1.dtsi"
 
 / {
        model = "Atmel AT91SAM9X25 SoC";
                                       0x80000000 0xfffd0000 0xb83fffff  /* pioC */
                                       0x003fffff 0x003f8000 0x00000000  /* pioD */
                                      >;
-
-                               macb1 {
-                                       pinctrl_macb1_rmii: macb1_rmii-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC16 periph B */
-                                                        AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC18 periph B */
-                                                        AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC19 periph B */
-                                                        AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC20 periph B */
-                                                        AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC21 periph B */
-                                                        AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC27 periph B */
-                                                        AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC28 periph B */
-                                                        AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC29 periph B */
-                                                        AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC30 periph B */
-                                                        AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC31 periph B */
-                                       };
-                               };
-                       };
-
-                       macb1: ethernet@f8030000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_macb1_rmii>;
                        };
                };
        };
index 1a3d525a1f5d43b5f49f9183b6ce6a41b359b6ee..8eac66ce0ab7766f76476d836488f7374f1b4a90 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "at91sam9x5.dtsi"
+#include "at91sam9x5_macb0.dtsi"
 
 / {
        model = "Atmel AT91SAM9X35 SoC";
index e74dc15efa9d2f77fa339a16b975f42566ca726e..40267a116c3c44438d7d915e10c9d119a4577540 100644 (file)
                                        };
                                };
 
-                               usart3 {
-                                       pinctrl_usart3: usart3-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP        /* PC22 periph B with pullup */
-                                                        AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC23 periph B */
-                                       };
-
-                                       pinctrl_usart3_rts: usart3_rts-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC24 periph B */
-                                       };
-
-                                       pinctrl_usart3_cts: usart3_cts-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC25 periph B */
-                                       };
-
-                                       pinctrl_usart3_sck: usart3_sck-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC26 periph B */
-                                       };
-                               };
-
                                uart0 {
                                        pinctrl_uart0: uart0-0 {
                                                atmel,pins =
                                        };
                                };
 
-                               macb0 {
-                                       pinctrl_macb0_rmii: macb0_rmii-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB0 periph A */
-                                                        AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB1 periph A */
-                                                        AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB2 periph A */
-                                                        AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB3 periph A */
-                                                        AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB4 periph A */
-                                                        AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB5 periph A */
-                                                        AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB6 periph A */
-                                                        AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB7 periph A */
-                                                        AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A */
-                                                        AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A */
-                                       };
-
-                                       pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB8 periph A */
-                                                        AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB11 periph A */
-                                                        AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB12 periph A */
-                                                        AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB13 periph A */
-                                                        AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB14 periph A */
-                                                        AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB15 periph A */
-                                                        AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB16 periph A */
-                                                        AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB17 periph A */
-                                       };
-                               };
-
                                mmc0 {
                                        pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
                                                atmel,pins =
                                status = "disabled";
                        };
 
-                       macb0: ethernet@f802c000 {
-                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
-                               reg = <0xf802c000 0x100>;
-                               interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_macb0_rmii>;
-                               status = "disabled";
-                       };
-
-                       macb1: ethernet@f8030000 {
-                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
-                               reg = <0xf8030000 0x100>;
-                               interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>;
-                               status = "disabled";
-                       };
-
                        i2c0: i2c@f8010000 {
                                compatible = "atmel,at91sam9x5-i2c";
                                reg = <0xf8010000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9x5_macb0.dtsi b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi
new file mode 100644 (file)
index 0000000..55731ff
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * at91sam9x5_macb0.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 1
+ * Ethernet interface.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff400 {
+                               macb0 {
+                                       pinctrl_macb0_rmii: macb0_rmii-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB0 periph A */
+                                                        AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB1 periph A */
+                                                        AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB2 periph A */
+                                                        AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB3 periph A */
+                                                        AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB4 periph A */
+                                                        AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB5 periph A */
+                                                        AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB6 periph A */
+                                                        AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB7 periph A */
+                                                        AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A */
+                                                        AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A */
+                                       };
+
+                                       pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB8 periph A */
+                                                        AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB11 periph A */
+                                                        AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB12 periph A */
+                                                        AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB13 periph A */
+                                                        AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB14 periph A */
+                                                        AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB15 periph A */
+                                                        AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB16 periph A */
+                                                        AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB17 periph A */
+                                       };
+                               };
+                       };
+
+                       macb0: ethernet@f802c000 {
+                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
+                               reg = <0xf802c000 0x100>;
+                               interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_macb0_rmii>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_macb1.dtsi b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi
new file mode 100644 (file)
index 0000000..77425a6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * at91sam9x5_macb1.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 2
+ * Ethernet interfaces.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff400 {
+                               macb1 {
+                                       pinctrl_macb1_rmii: macb1_rmii-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC16 periph B */
+                                                        AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC18 periph B */
+                                                        AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC19 periph B */
+                                                        AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC20 periph B */
+                                                        AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC21 periph B */
+                                                        AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC27 periph B */
+                                                        AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC28 periph B */
+                                                        AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC29 periph B */
+                                                        AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PC30 periph B */
+                                                        AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC31 periph B */
+                                       };
+                               };
+                       };
+
+                       macb1: ethernet@f8030000 {
+                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
+                               reg = <0xf8030000 0x100>;
+                               interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_macb1_rmii>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5_usart3.dtsi b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi
new file mode 100644 (file)
index 0000000..2347e95
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * at91sam9x5_usart3.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * 4 USART.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff400 {
+                               usart3 {
+                                       pinctrl_usart3: usart3-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP        /* PC22 periph B with pullup */
+                                                        AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;         /* PC23 periph B */
+                                       };
+
+                                       pinctrl_usart3_rts: usart3_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;         /* PC24 periph B */
+                                       };
+
+                                       pinctrl_usart3_cts: usart3_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>;         /* PC25 periph B */
+                                       };
+
+                                       pinctrl_usart3_sck: usart3_sck-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;         /* PC26 periph B */
+                                       };
+                               };
+                       };
+
+                       usart3: serial@f8028000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xf8028000 0x200>;
+                               interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart3>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 6db4f81d4795d2855b83aac5a72cc3c7b8cb6727..a49032c6e1998e4ee57018f63671e1c503d5de77 100644 (file)
                                compatible = "sirf,prima2-rsc";
                                reg = <0x88020000 0x1000>;
                        };
+
+                       cphifbg@88030000 {
+                               compatible = "sirf,prima2-cphifbg";
+                               reg = <0x88030000 0x1000>;
+                       };
                };
 
                mem-iobg {
 
                        memory-controller@90000000 {
                                compatible = "sirf,prima2-memc";
-                               reg = <0x90000000 0x10000>;
+                               reg = <0x90000000 0x2000>;
                                interrupts = <27>;
                                clocks = <&clks 5>;
                        };
+
+                       memc-monitor {
+                               compatible = "sirf,prima2-memcmon";
+                               reg = <0x90002000 0x200>;
+                               interrupts = <4>;
+                               clocks = <&clks 32>;
+                       };
                };
 
                disp-iobg {
                        };
                };
 
+               graphics2d-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xa0000000 0xa0000000 0x8000000>;
+
+                       ble@a0000000 {
+                               compatible = "sirf,atlas6-ble";
+                               reg = <0xa0000000 0x2000>;
+                               interrupts = <5>;
+                               clocks = <&clks 33>;
+                       };
+               };
+
                dsp-iobg {
                        compatible = "simple-bus";
                        #address-cells = <1>;
                                compatible = "sirf,prima2-spi";
                                reg = <0xb0170000 0x10000>;
                                interrupts = <16>;
+                               sirf,spi-num-chipselects = <1>;
+                               sirf,spi-dma-rx-channel = <12>;
+                               sirf,spi-dma-tx-channel = <13>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                clocks = <&clks 20>;
                                status = "disabled";
                        };
index 9d36eb4e3c41e8f2d0e7047acf08809dbd39f835..23cd16d736bf782f0be04f6e8413462ac8e60f86 100644 (file)
@@ -40,6 +40,7 @@
 
        sdio4: sdio@3f1b0000 {
                max-frequency = <48000000>;
+               cd-gpios = <&gpio 14 0>;
                status = "okay";
        };
 
index 05a5aabe3b2ccadbef92c305659ccf4f51fd7580..b0c0610d13958248f48bb55b0891aaf306c50ee8 100644 (file)
                reg-io-width = <4>;
        };
 
+       uart@3e001000 {
+               compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+               status = "disabled";
+               reg = <0x3e001000 0x1000>;
+               clock-frequency = <13000000>;
+               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
+
+       uart@3e002000 {
+               compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+               status = "disabled";
+               reg = <0x3e002000 0x1000>;
+               clock-frequency = <13000000>;
+               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
+
+       uart@3e003000 {
+               compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+               status = "disabled";
+               reg = <0x3e003000 0x1000>;
+               clock-frequency = <13000000>;
+               interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
+
        L2: l2-cache {
                compatible = "brcm,bcm11351-a2-pl310-cache";
                reg = <0x3ff20000 0x1000>;
                clock-frequency = <32768>;
        };
 
+       gpio: gpio@35003000 {
+               compatible = "brcm,bcm11351-gpio", "brcm,kona-gpio";
+               reg = <0x35003000 0x800>;
+               interrupts =
+                      <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               #interrupt-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+       };
+
        sdio1: sdio@3f180000 {
                compatible = "brcm,kona-sdhci";
                reg = <0x3f180000 0x10000>;
-               interrupts = <0x0 77 0x4>;
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        sdio2: sdio@3f190000 {
                compatible = "brcm,kona-sdhci";
                reg = <0x3f190000 0x10000>;
-               interrupts = <0x0 76 0x4>;
+               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        sdio3: sdio@3f1a0000 {
                compatible = "brcm,kona-sdhci";
                reg = <0x3f1a0000 0x10000>;
-               interrupts = <0x0 74 0x4>;
+               interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        sdio4: sdio@3f1b0000 {
                compatible = "brcm,kona-sdhci";
                reg = <0x3f1b0000 0x10000>;
-               interrupts = <0x0 73 0x4>;
+               interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
index 96ae67a2f0d37dc9ec852b9c00eba004aa0757fa..08e47c285227a941d0bf7852c815054bd0d10a82 100644 (file)
@@ -40,6 +40,7 @@
 
        sdio4: sdio@3f1b0000 {
                max-frequency = <48000000>;
+               cd-gpios = <&gpio 14 0>;
                status = "okay";
        };
 };
index 61a8062e56de00f741ce83582257dcb9e1f7b630..50c0d69044979fef24292cfe4c8ef7c57b8b2760 100644 (file)
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "dove.dtsi"
+#include "dove.dtsi"
 
 / {
        model = "Compulab CM-A510";
index 022646ef4b3842278f636ed23b6f8c030a1db623..8349a248eceaf242f8a079e6c565af109ee69708 100644 (file)
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "dove.dtsi"
+#include "dove.dtsi"
 
 / {
        model = "SolidRun CuBox";
                        silabs,pll-master;
                };
 
-               clkout1 {
-                       reg = <1>;
-                       silabs,drive-strength = <8>;
-                       silabs,multisynth-source = <1>;
-                       silabs,clock-source = <0>;
-                       silabs,pll-master;
-               };
-
                clkout2 {
                        reg = <2>;
+                       silabs,drive-strength = <8>;
                        silabs,multisynth-source = <1>;
                        silabs,clock-source = <0>;
+                       silabs,pll-master;
                };
        };
 };
                reg = <0>;
        };
 };
+
+&audio1 {
+       status = "okay";
+       clocks = <&gate_clk 13>, <&si5351 2>;
+       clock-names = "internal", "extclk";
+       pinctrl-0 = <&pmx_audio1_i2s1_spdifo &pmx_audio1_extclk>;
+       pinctrl-names = "default";
+};
index e2222ce94f2f2494380d137f70267f942f231646..c11d3636c8e5635004aa5ae73ceb3ab450882dd2 100644 (file)
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "dove.dtsi"
+#include "dove.dtsi"
 
 / {
        model = "Globalscale D2Plug";
diff --git a/arch/arm/boot/dts/dove-d3plug.dts b/arch/arm/boot/dts/dove-d3plug.dts
new file mode 100644 (file)
index 0000000..f5f59bb
--- /dev/null
@@ -0,0 +1,103 @@
+/dts-v1/;
+
+#include "dove.dtsi"
+
+/ {
+       model = "Globalscale D3Plug";
+       compatible = "globalscale,d3plug", "marvell,dove";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/mmcblk0p2 rw rootwait";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_gpio_0 &pmx_gpio_1 &pmx_gpio_2>;
+               pinctrl-names = "default";
+
+               wlan-act {
+                       label = "wlan-act";
+                       gpios = <&gpio0 0 1>;
+               };
+
+               wlan-ap {
+                       label = "wlan-ap";
+                       gpios = <&gpio0 1 1>;
+               };
+
+               status {
+                       label = "status";
+                       gpios = <&gpio0 2 1>;
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usb_power: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "USB Power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       gpio = <&gpio0 8 0>;
+                       pinctrl-0 = <&pmx_gpio_8>;
+                       pinctrl-names = "default";
+               };
+       };
+};
+
+&uart0 { status = "okay"; };
+&sata0 { status = "okay"; };
+&i2c0 { status = "okay"; };
+
+/* Samsung M8G2F eMMC */
+&sdio0 {
+       status = "okay";
+       non-removable;
+       bus-width = <4>;
+};
+
+/* Marvell SD8787 WLAN/BT */
+&sdio1 {
+       status = "okay";
+       non-removable;
+};
+
+&spi0 {
+       status = "okay";
+
+       /* spi0.0: 2M Flash Macronix MX25L1605D */
+       spi-flash@0 {
+               compatible = "st,m25l1605d";
+               spi-max-frequency = <86000000>;
+               reg = <0>;
+       };
+};
+
+&pcie {
+       status = "okay";
+       /* Fresco Logic USB3.0 xHCI controller */
+       pcie-port@0 {
+               status = "okay";
+               reset-gpios = <&gpio0 26 1>;
+               reset-delay-us = <20000>;
+               pinctrl-0 = <&pmx_camera_gpio>;
+               pinctrl-names = "default";
+       };
+       /* Mini-PCIe slot */
+       pcie-port@1 {
+               status = "okay";
+               reset-gpios = <&gpio0 25 1>;
+       };
+};
index e5a920beab450546a3231941d11c756495b1c516..bb725dca3a1000f7f8de5a9e9cd79bc2d9be38df 100644 (file)
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "dove.dtsi"
+#include "dove.dtsi"
 
 / {
        model = "Marvell DB-MV88AP510-BP Development Board";
index cc279166646fc4cb33751c8de2f1e19de2dd7440..113a8bc7bee73649a33cc3e212336536f47399b3 100644 (file)
@@ -1,8 +1,11 @@
 /include/ "skeleton.dtsi"
 
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
 / {
        compatible = "marvell,dove";
        model = "Marvell Armada 88AP510 SoC";
+       interrupt-parent = <&intc>;
 
        aliases {
                gpio0 = &gpio0;
                marvell,tauros2-cache-features = <0>;
        };
 
-       soc@f1000000 {
-               compatible = "simple-bus";
-               #address-cells = <1>;
+       mbus {
+               compatible = "marvell,dove-mbus", "marvell,mbus", "simple-bus";
+               #address-cells = <2>;
                #size-cells = <1>;
-               interrupt-parent = <&intc>;
-
-               ranges = <0xc8000000 0xc8000000 0x0100000   /* CESA SRAM   1M */
-                         0xe0000000 0xe0000000 0x8000000   /* PCIe0 Mem 128M */
-                         0xe8000000 0xe8000000 0x8000000   /* PCIe1 Mem 128M */
-                         0xf0000000 0xf0000000 0x0100000   /* ScratchPad  1M */
-                         0x00000000 0xf1000000 0x1000000   /* SB/NB regs 16M */
-                         0xf2000000 0xf2000000 0x0100000   /* PCIe0 I/O   1M */
-                         0xf2100000 0xf2100000 0x0100000   /* PCIe0 I/O   1M */
-                         0xf8000000 0xf8000000 0x8000000>; /* BootROM   128M */
-
-               timer: timer@20300 {
-                       compatible = "marvell,orion-timer";
-                       reg = <0x20300 0x20>;
-                       interrupt-parent = <&bridge_intc>;
-                       interrupts = <1>, <2>;
-                       clocks = <&core_clk 0>;
-               };
-
-               intc: main-interrupt-ctrl@20200 {
-                       compatible = "marvell,orion-intc";
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
-                       reg = <0x20200 0x10>, <0x20210 0x10>;
-               };
-
-               bridge_intc: bridge-interrupt-ctrl@20110 {
-                       compatible = "marvell,orion-bridge-intc";
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
-                       reg = <0x20110 0x8>;
-                       interrupts = <0>;
-                       marvell,#interrupts = <5>;
-               };
-
-               core_clk: core-clocks@d0214 {
-                       compatible = "marvell,dove-core-clock";
-                       reg = <0xd0214 0x4>;
-                       #clock-cells = <1>;
-               };
-
-               gate_clk: clock-gating-ctrl@d0038 {
-                       compatible = "marvell,dove-gating-clock";
-                       reg = <0xd0038 0x4>;
-                       clocks = <&core_clk 0>;
-                       #clock-cells = <1>;
-               };
-
-               thermal: thermal-diode@d001c {
-                       compatible = "marvell,dove-thermal";
-                       reg = <0xd001c 0x0c>, <0xd005c 0x08>;
-               };
-
-               uart0: serial@12000 {
-                       compatible = "ns16550a";
-                       reg = <0x12000 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <7>;
-                       clocks = <&core_clk 0>;
-                       status = "disabled";
-               };
-
-               uart1: serial@12100 {
-                       compatible = "ns16550a";
-                       reg = <0x12100 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <8>;
-                       clocks = <&core_clk 0>;
-                       pinctrl-0 = <&pmx_uart1>;
-                       pinctrl-names = "default";
-                       status = "disabled";
-               };
-
-               uart2: serial@12200 {
-                       compatible = "ns16550a";
-                       reg = <0x12000 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <9>;
-                       clocks = <&core_clk 0>;
+               controller = <&mbusc>;
+               pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256M MEM space */
+               pcie-io-aperture  = <0xf2000000 0x00200000>; /*   2M I/O space */
+
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x0100000   /* MBUS regs  1M */
+                         MBUS_ID(0xf0, 0x02) 0 0xf1800000 0x1000000   /* AXI  regs 16M */
+                         MBUS_ID(0x01, 0xfd) 0 0xf8000000 0x8000000   /* BootROM  128M */
+                         MBUS_ID(0x03, 0x01) 0 0xc8000000 0x0100000   /* CESA SRAM  1M */
+                         MBUS_ID(0x0d, 0x00) 0 0xf0000000 0x0100000>; /* PMU  SRAM  1M */
+
+               pcie: pcie-controller {
+                       compatible = "marvell,dove-pcie";
                        status = "disabled";
-               };
-
-               uart3: serial@12300 {
-                       compatible = "ns16550a";
-                       reg = <0x12100 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <10>;
-                       clocks = <&core_clk 0>;
-                       status = "disabled";
-               };
-
-               gpio0: gpio-ctrl@d0400 {
-                       compatible = "marvell,orion-gpio";
-                       #gpio-cells = <2>;
-                       gpio-controller;
-                       reg = <0xd0400 0x20>;
-                       ngpios = <32>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-                       interrupts = <12>, <13>, <14>, <60>;
-               };
-
-               gpio1: gpio-ctrl@d0420 {
-                       compatible = "marvell,orion-gpio";
-                       #gpio-cells = <2>;
-                       gpio-controller;
-                       reg = <0xd0420 0x20>;
-                       ngpios = <32>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-                       interrupts = <61>;
-               };
-
-               gpio2: gpio-ctrl@e8400 {
-                       compatible = "marvell,orion-gpio";
-                       #gpio-cells = <2>;
-                       gpio-controller;
-                       reg = <0xe8400 0x0c>;
-                       ngpios = <8>;
-               };
-
-               pinctrl: pin-ctrl@d0200 {
-                       compatible = "marvell,dove-pinctrl";
-                       reg = <0xd0200 0x10>;
-                       clocks = <&gate_clk 22>;
-
-                       pmx_gpio_0: pmx-gpio-0 {
-                               marvell,pins = "mpp0";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_1: pmx-gpio-1 {
-                               marvell,pins = "mpp1";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_2: pmx-gpio-2 {
-                               marvell,pins = "mpp2";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_3: pmx-gpio-3 {
-                               marvell,pins = "mpp3";
-                               marvell,function = "gpio";
+                       device_type = "pci";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       msi-parent = <&intc>;
+                       bus-range = <0x00 0xff>;
+
+                       ranges = <0x82000000 0x0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x2000
+                                 0x82000000 0x0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x2000
+                                 0x82000000 0x1 0x0 MBUS_ID(0x04, 0xe8) 0 1 0   /* Port 0.0 Mem */
+                                 0x81000000 0x1 0x0 MBUS_ID(0x04, 0xe0) 0 1 0   /* Port 0.0 I/O */
+                                 0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0   /* Port 1.0 Mem */
+                                 0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */
+
+                       pcie-port@0 {
+                               device_type = "pci";
+                               status = "disabled";
+                               assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+                               reg = <0x0800 0 0 0 0>;
+                               clocks = <&gate_clk 4>;
+                               marvell,pcie-port = <0>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+                                         0x81000000 0 0 0x81000000 0x1 0 1 0>;
+
+                               #interrupt-cells = <1>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &intc 16>;
+                       };
+
+                       pcie-port@1 {
+                               device_type = "pci";
+                               status = "disabled";
+                               assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               clocks = <&gate_clk 5>;
+                               marvell,pcie-port = <1>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+                                         0x81000000 0 0 0x81000000 0x2 0 1 0>;
+
+                               #interrupt-cells = <1>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &intc 18>;
                        };
-
-                       pmx_gpio_4: pmx-gpio-4 {
-                               marvell,pins = "mpp4";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_5: pmx-gpio-5 {
-                               marvell,pins = "mpp5";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_6: pmx-gpio-6 {
-                               marvell,pins = "mpp6";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_7: pmx-gpio-7 {
-                               marvell,pins = "mpp7";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_8: pmx-gpio-8 {
-                               marvell,pins = "mpp8";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_9: pmx-gpio-9 {
-                               marvell,pins = "mpp9";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_10: pmx-gpio-10 {
-                               marvell,pins = "mpp10";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_11: pmx-gpio-11 {
-                               marvell,pins = "mpp11";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_12: pmx-gpio-12 {
-                               marvell,pins = "mpp12";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_13: pmx-gpio-13 {
-                               marvell,pins = "mpp13";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_14: pmx-gpio-14 {
-                               marvell,pins = "mpp14";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_15: pmx-gpio-15 {
-                               marvell,pins = "mpp15";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_16: pmx-gpio-16 {
-                               marvell,pins = "mpp16";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_17: pmx-gpio-17 {
-                               marvell,pins = "mpp17";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_18: pmx-gpio-18 {
-                               marvell,pins = "mpp18";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_19: pmx-gpio-19 {
-                               marvell,pins = "mpp19";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_20: pmx-gpio-20 {
-                               marvell,pins = "mpp20";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_gpio_21: pmx-gpio-21 {
-                               marvell,pins = "mpp21";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_camera: pmx-camera {
-                               marvell,pins = "mpp_camera";
-                               marvell,function = "camera";
-                       };
-
-                       pmx_camera_gpio: pmx-camera-gpio {
-                               marvell,pins = "mpp_camera";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_sdio0: pmx-sdio0 {
-                               marvell,pins = "mpp_sdio0";
-                               marvell,function = "sdio0";
-                       };
-
-                       pmx_sdio0_gpio: pmx-sdio0-gpio {
-                               marvell,pins = "mpp_sdio0";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_sdio1: pmx-sdio1 {
-                               marvell,pins = "mpp_sdio1";
-                               marvell,function = "sdio1";
-                       };
-
-                       pmx_sdio1_gpio: pmx-sdio1-gpio {
-                               marvell,pins = "mpp_sdio1";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_audio1_gpio: pmx-audio1-gpio {
-                               marvell,pins = "mpp_audio1";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_spi0: pmx-spi0 {
-                               marvell,pins = "mpp_spi0";
-                               marvell,function = "spi0";
-                       };
-
-                       pmx_spi0_gpio: pmx-spi0-gpio {
-                               marvell,pins = "mpp_spi0";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_uart1: pmx-uart1 {
-                               marvell,pins = "mpp_uart1";
-                               marvell,function = "uart1";
-                       };
-
-                       pmx_uart1_gpio: pmx-uart1-gpio {
-                               marvell,pins = "mpp_uart1";
-                               marvell,function = "gpio";
-                       };
-
-                       pmx_nand: pmx-nand {
-                               marvell,pins = "mpp_nand";
-                               marvell,function = "nand";
-                       };
-
-                       pmx_nand_gpo: pmx-nand-gpo {
-                               marvell,pins = "mpp_nand";
-                               marvell,function = "gpo";
-                       };
-               };
-
-               spi0: spi-ctrl@10600 {
-                       compatible = "marvell,orion-spi";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <0>;
-                       interrupts = <6>;
-                       reg = <0x10600 0x28>;
-                       clocks = <&core_clk 0>;
-                       pinctrl-0 = <&pmx_spi0>;
-                       pinctrl-names = "default";
-                       status = "disabled";
-               };
-
-               spi1: spi-ctrl@14600 {
-                       compatible = "marvell,orion-spi";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <1>;
-                       interrupts = <5>;
-                       reg = <0x14600 0x28>;
-                       clocks = <&core_clk 0>;
-                       status = "disabled";
-               };
-
-               i2c0: i2c-ctrl@11000 {
-                       compatible = "marvell,mv64xxx-i2c";
-                       reg = <0x11000 0x20>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <11>;
-                       clock-frequency = <400000>;
-                       timeout-ms = <1000>;
-                       clocks = <&core_clk 0>;
-                       status = "disabled";
                };
 
-               ehci0: usb-host@50000 {
-                       compatible = "marvell,orion-ehci";
-                       reg = <0x50000 0x1000>;
-                       interrupts = <24>;
-                       clocks = <&gate_clk 0>;
-                       status = "okay";
-               };
-
-               ehci1: usb-host@51000 {
-                       compatible = "marvell,orion-ehci";
-                       reg = <0x51000 0x1000>;
-                       interrupts = <25>;
-                       clocks = <&gate_clk 1>;
-                       status = "okay";
-               };
-
-               sdio0: sdio-host@92000 {
-                       compatible = "marvell,dove-sdhci";
-                       reg = <0x92000 0x100>;
-                       interrupts = <35>, <37>;
-                       clocks = <&gate_clk 8>;
-                       pinctrl-0 = <&pmx_sdio0>;
-                       pinctrl-names = "default";
-                       status = "disabled";
-               };
-
-               sdio1: sdio-host@90000 {
-                       compatible = "marvell,dove-sdhci";
-                       reg = <0x90000 0x100>;
-                       interrupts = <36>, <38>;
-                       clocks = <&gate_clk 9>;
-                       pinctrl-0 = <&pmx_sdio1>;
-                       pinctrl-names = "default";
-                       status = "disabled";
-               };
-
-               sata0: sata-host@a0000 {
-                       compatible = "marvell,orion-sata";
-                       reg = <0xa0000 0x2400>;
-                       interrupts = <62>;
-                       clocks = <&gate_clk 3>;
-                       nr-ports = <1>;
-                       status = "disabled";
-               };
-
-               rtc: real-time-clock@d8500 {
-                       compatible = "marvell,orion-rtc";
-                       reg = <0xd8500 0x20>;
-               };
-
-               crypto: crypto-engine@30000 {
-                       compatible = "marvell,orion-crypto";
-                       reg = <0x30000 0x10000>,
-                             <0xc8000000 0x800>;
-                       reg-names = "regs", "sram";
-                       interrupts = <31>;
-                       clocks = <&gate_clk 15>;
-                       status = "okay";
-               };
-
-               xor0: dma-engine@60800 {
-                       compatible = "marvell,orion-xor";
-                       reg = <0x60800 0x100
-                              0x60a00 0x100>;
-                       clocks = <&gate_clk 23>;
-                       status = "okay";
-
-                       channel0 {
-                               interrupts = <39>;
-                               dmacap,memcpy;
-                               dmacap,xor;
-                       };
-
-                       channel1 {
-                               interrupts = <40>;
-                               dmacap,memset;
-                               dmacap,memcpy;
-                               dmacap,xor;
-                       };
-               };
-
-               xor1: dma-engine@60900 {
-                       compatible = "marvell,orion-xor";
-                       reg = <0x60900 0x100
-                              0x60b00 0x100>;
-                       clocks = <&gate_clk 24>;
-                       status = "okay";
-
-                       channel0 {
-                               interrupts = <42>;
-                               dmacap,memcpy;
-                               dmacap,xor;
-                       };
-
-                       channel1 {
-                               interrupts = <43>;
-                               dmacap,memset;
-                               dmacap,memcpy;
-                               dmacap,xor;
-                       };
-               };
-
-               mdio: mdio-bus@72004 {
-                       compatible = "marvell,orion-mdio";
+               internal-regs {
+                       compatible = "simple-bus";
                        #address-cells = <1>;
-                       #size-cells = <0>;
-                       reg = <0x72004 0x84>;
-                       interrupts = <30>;
-                       clocks = <&gate_clk 2>;
-                       status = "disabled";
-
-                       ethphy: ethernet-phy {
-                               device-type = "ethernet-phy";
-                               /* set phy address in board file */
-                       };
-               };
-
-               eth: ethernet-controller@72000 {
-                       compatible = "marvell,orion-eth";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       reg = <0x72000 0x4000>;
-                       clocks = <&gate_clk 2>;
-                       marvell,tx-checksum-limit = <1600>;
-                       status = "disabled";
-
-                       ethernet-port@0 {
-                               device_type = "network";
-                               compatible = "marvell,orion-eth-port";
-                               reg = <0>;
-                               interrupts = <29>;
-                               /* overwrite MAC address in bootloader */
-                               local-mac-address = [00 00 00 00 00 00];
-                               phy-handle = <&ethphy>;
+                       #size-cells = <1>;
+                       ranges = <0x00000000 MBUS_ID(0xf0, 0x01) 0 0x0100000   /* MBUS regs  1M */
+                                 0x00800000 MBUS_ID(0xf0, 0x02) 0 0x1000000   /* AXI  regs 16M */
+                                 0xffffe000 MBUS_ID(0x03, 0x01) 0 0x0000800   /* CESA SRAM  2k */
+                                 0xfffff000 MBUS_ID(0x0d, 0x00) 0 0x0000800>; /* PMU  SRAM  2k */
+
+                       mbusc: mbus-ctrl@20000 {
+                               compatible = "marvell,mbus-controller";
+                               reg = <0x20000 0x80>, <0x800100 0x8>;
+                       };
+
+                       timer: timer@20300 {
+                               compatible = "marvell,orion-timer";
+                               reg = <0x20300 0x20>;
+                               interrupt-parent = <&bridge_intc>;
+                               interrupts = <1>, <2>;
+                               clocks = <&core_clk 0>;
+                       };
+
+                       intc: main-interrupt-ctrl@20200 {
+                               compatible = "marvell,orion-intc";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x20200 0x10>, <0x20210 0x10>;
+                       };
+
+                       bridge_intc: bridge-interrupt-ctrl@20110 {
+                               compatible = "marvell,orion-bridge-intc";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x20110 0x8>;
+                               interrupts = <0>;
+                               marvell,#interrupts = <5>;
+                       };
+
+                       core_clk: core-clocks@d0214 {
+                               compatible = "marvell,dove-core-clock";
+                               reg = <0xd0214 0x4>;
+                               #clock-cells = <1>;
+                       };
+
+                       gate_clk: clock-gating-ctrl@d0038 {
+                               compatible = "marvell,dove-gating-clock";
+                               reg = <0xd0038 0x4>;
+                               clocks = <&core_clk 0>;
+                               #clock-cells = <1>;
+                       };
+
+                       thermal: thermal-diode@d001c {
+                               compatible = "marvell,dove-thermal";
+                               reg = <0xd001c 0x0c>, <0xd005c 0x08>;
+                       };
+
+                       uart0: serial@12000 {
+                               compatible = "ns16550a";
+                               reg = <0x12000 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <7>;
+                               clocks = <&core_clk 0>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@12100 {
+                               compatible = "ns16550a";
+                               reg = <0x12100 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <8>;
+                               clocks = <&core_clk 0>;
+                               pinctrl-0 = <&pmx_uart1>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       uart2: serial@12200 {
+                               compatible = "ns16550a";
+                               reg = <0x12000 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <9>;
+                               clocks = <&core_clk 0>;
+                               status = "disabled";
+                       };
+
+                       uart3: serial@12300 {
+                               compatible = "ns16550a";
+                               reg = <0x12100 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <10>;
+                               clocks = <&core_clk 0>;
+                               status = "disabled";
+                       };
+
+                       gpio0: gpio-ctrl@d0400 {
+                               compatible = "marvell,orion-gpio";
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               reg = <0xd0400 0x20>;
+                               ngpios = <32>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <12>, <13>, <14>, <60>;
+                       };
+
+                       gpio1: gpio-ctrl@d0420 {
+                               compatible = "marvell,orion-gpio";
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               reg = <0xd0420 0x20>;
+                               ngpios = <32>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <61>;
+                       };
+
+                       gpio2: gpio-ctrl@e8400 {
+                               compatible = "marvell,orion-gpio";
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               reg = <0xe8400 0x0c>;
+                               ngpios = <8>;
+                       };
+
+                       pinctrl: pin-ctrl@d0200 {
+                               compatible = "marvell,dove-pinctrl";
+                               reg = <0xd0200 0x10>;
+                               clocks = <&gate_clk 22>;
+
+                               pmx_gpio_0: pmx-gpio-0 {
+                                       marvell,pins = "mpp0";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_1: pmx-gpio-1 {
+                                       marvell,pins = "mpp1";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_2: pmx-gpio-2 {
+                                       marvell,pins = "mpp2";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_3: pmx-gpio-3 {
+                                       marvell,pins = "mpp3";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_4: pmx-gpio-4 {
+                                       marvell,pins = "mpp4";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_5: pmx-gpio-5 {
+                                       marvell,pins = "mpp5";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_6: pmx-gpio-6 {
+                                       marvell,pins = "mpp6";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_7: pmx-gpio-7 {
+                                       marvell,pins = "mpp7";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_8: pmx-gpio-8 {
+                                       marvell,pins = "mpp8";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_9: pmx-gpio-9 {
+                                       marvell,pins = "mpp9";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_10: pmx-gpio-10 {
+                                       marvell,pins = "mpp10";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_11: pmx-gpio-11 {
+                                       marvell,pins = "mpp11";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_12: pmx-gpio-12 {
+                                       marvell,pins = "mpp12";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_13: pmx-gpio-13 {
+                                       marvell,pins = "mpp13";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_audio1_extclk: pmx-audio1-extclk {
+                                       marvell,pins = "mpp13";
+                                       marvell,function = "audio1";
+                               };
+
+                               pmx_gpio_14: pmx-gpio-14 {
+                                       marvell,pins = "mpp14";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_15: pmx-gpio-15 {
+                                       marvell,pins = "mpp15";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_16: pmx-gpio-16 {
+                                       marvell,pins = "mpp16";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_17: pmx-gpio-17 {
+                                       marvell,pins = "mpp17";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_18: pmx-gpio-18 {
+                                       marvell,pins = "mpp18";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_19: pmx-gpio-19 {
+                                       marvell,pins = "mpp19";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_20: pmx-gpio-20 {
+                                       marvell,pins = "mpp20";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_gpio_21: pmx-gpio-21 {
+                                       marvell,pins = "mpp21";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_camera: pmx-camera {
+                                       marvell,pins = "mpp_camera";
+                                       marvell,function = "camera";
+                               };
+
+                               pmx_camera_gpio: pmx-camera-gpio {
+                                       marvell,pins = "mpp_camera";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_sdio0: pmx-sdio0 {
+                                       marvell,pins = "mpp_sdio0";
+                                       marvell,function = "sdio0";
+                               };
+
+                               pmx_sdio0_gpio: pmx-sdio0-gpio {
+                                       marvell,pins = "mpp_sdio0";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_sdio1: pmx-sdio1 {
+                                       marvell,pins = "mpp_sdio1";
+                                       marvell,function = "sdio1";
+                               };
+
+                               pmx_sdio1_gpio: pmx-sdio1-gpio {
+                                       marvell,pins = "mpp_sdio1";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_audio1_gpio: pmx-audio1-gpio {
+                                       marvell,pins = "mpp_audio1";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_audio1_i2s1_spdifo: pmx-audio1-i2s1-spdifo {
+                                       marvell,pins = "mpp_audio1";
+                                       marvell,function = "i2s1/spdifo";
+                               };
+
+                               pmx_spi0: pmx-spi0 {
+                                       marvell,pins = "mpp_spi0";
+                                       marvell,function = "spi0";
+                               };
+
+                               pmx_spi0_gpio: pmx-spi0-gpio {
+                                       marvell,pins = "mpp_spi0";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_uart1: pmx-uart1 {
+                                       marvell,pins = "mpp_uart1";
+                                       marvell,function = "uart1";
+                               };
+
+                               pmx_uart1_gpio: pmx-uart1-gpio {
+                                       marvell,pins = "mpp_uart1";
+                                       marvell,function = "gpio";
+                               };
+
+                               pmx_nand: pmx-nand {
+                                       marvell,pins = "mpp_nand";
+                                       marvell,function = "nand";
+                               };
+
+                               pmx_nand_gpo: pmx-nand-gpo {
+                                       marvell,pins = "mpp_nand";
+                                       marvell,function = "gpo";
+                               };
+                       };
+
+                       spi0: spi-ctrl@10600 {
+                               compatible = "marvell,orion-spi";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <0>;
+                               interrupts = <6>;
+                               reg = <0x10600 0x28>;
+                               clocks = <&core_clk 0>;
+                               pinctrl-0 = <&pmx_spi0>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       spi1: spi-ctrl@14600 {
+                               compatible = "marvell,orion-spi";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <1>;
+                               interrupts = <5>;
+                               reg = <0x14600 0x28>;
+                               clocks = <&core_clk 0>;
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c-ctrl@11000 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               reg = <0x11000 0x20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <11>;
+                               clock-frequency = <400000>;
+                               timeout-ms = <1000>;
+                               clocks = <&core_clk 0>;
+                               status = "disabled";
+                       };
+
+                       ehci0: usb-host@50000 {
+                               compatible = "marvell,orion-ehci";
+                               reg = <0x50000 0x1000>;
+                               interrupts = <24>;
+                               clocks = <&gate_clk 0>;
+                               status = "okay";
+                       };
+
+                       ehci1: usb-host@51000 {
+                               compatible = "marvell,orion-ehci";
+                               reg = <0x51000 0x1000>;
+                               interrupts = <25>;
+                               clocks = <&gate_clk 1>;
+                               status = "okay";
+                       };
+
+                       sdio0: sdio-host@92000 {
+                               compatible = "marvell,dove-sdhci";
+                               reg = <0x92000 0x100>;
+                               interrupts = <35>, <37>;
+                               clocks = <&gate_clk 8>;
+                               pinctrl-0 = <&pmx_sdio0>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       sdio1: sdio-host@90000 {
+                               compatible = "marvell,dove-sdhci";
+                               reg = <0x90000 0x100>;
+                               interrupts = <36>, <38>;
+                               clocks = <&gate_clk 9>;
+                               pinctrl-0 = <&pmx_sdio1>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       sata0: sata-host@a0000 {
+                               compatible = "marvell,orion-sata";
+                               reg = <0xa0000 0x2400>;
+                               interrupts = <62>;
+                               clocks = <&gate_clk 3>;
+                               nr-ports = <1>;
+                               status = "disabled";
+                       };
+
+                       rtc: real-time-clock@d8500 {
+                               compatible = "marvell,orion-rtc";
+                               reg = <0xd8500 0x20>;
+                       };
+
+                       crypto: crypto-engine@30000 {
+                               compatible = "marvell,orion-crypto";
+                               reg = <0x30000 0x10000>,
+                                     <0xffffe000 0x800>;
+                               reg-names = "regs", "sram";
+                               interrupts = <31>;
+                               clocks = <&gate_clk 15>;
+                               status = "okay";
+                       };
+
+                       xor0: dma-engine@60800 {
+                               compatible = "marvell,orion-xor";
+                               reg = <0x60800 0x100
+                                      0x60a00 0x100>;
+                               clocks = <&gate_clk 23>;
+                               status = "okay";
+
+                               channel0 {
+                                       interrupts = <39>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+
+                               channel1 {
+                                       interrupts = <40>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+                       };
+
+                       xor1: dma-engine@60900 {
+                               compatible = "marvell,orion-xor";
+                               reg = <0x60900 0x100
+                                      0x60b00 0x100>;
+                               clocks = <&gate_clk 24>;
+                               status = "okay";
+
+                               channel0 {
+                                       interrupts = <42>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+
+                               channel1 {
+                                       interrupts = <43>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+                       };
+
+                       mdio: mdio-bus@72004 {
+                               compatible = "marvell,orion-mdio";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x72004 0x84>;
+                               interrupts = <30>;
+                               clocks = <&gate_clk 2>;
+                               status = "disabled";
+
+                               ethphy: ethernet-phy {
+                                       device-type = "ethernet-phy";
+                                       /* set phy address in board file */
+                               };
+                       };
+
+                       eth: ethernet-ctrl@72000 {
+                               compatible = "marvell,orion-eth";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x72000 0x4000>;
+                               clocks = <&gate_clk 2>;
+                               marvell,tx-checksum-limit = <1600>;
+                               status = "disabled";
+
+                               ethernet-port@0 {
+                                       device_type = "network";
+                                       compatible = "marvell,orion-eth-port";
+                                       reg = <0>;
+                                       interrupts = <29>;
+                                       /* overwrite MAC address in bootloader */
+                                       local-mac-address = [00 00 00 00 00 00];
+                                       phy-handle = <&ethphy>;
+                               };
+                       };
+
+                       audio0: audio-controller@b0000 {
+                               compatible = "marvell,dove-audio";
+                               reg = <0xb0000 0x2210>;
+                               interrupts = <19>, <20>;
+                               clocks = <&gate_clk 12>;
+                               clock-names = "internal";
+                               status = "disabled";
+                       };
+
+                       audio1: audio-controller@b4000 {
+                               compatible = "marvell,dove-audio";
+                               reg = <0xb4000 0x2210>;
+                               interrupts = <21>, <22>;
+                               clocks = <&gate_clk 13>;
+                               clock-names = "internal";
+                               status = "disabled";
                        };
                };
        };
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
new file mode 100644 (file)
index 0000000..5babba0
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ */
+/dts-v1/;
+
+#include "dra7.dtsi"
+
+/ {
+       model = "TI DRA7";
+       compatible = "ti,dra7-evm", "ti,dra752", "ti,dra7";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x60000000>; /* 1536 MB */
+       };
+
+       mmc2_3v3: fixedregulator-mmc2 {
+               compatible = "regulator-fixed";
+               regulator-name = "mmc2_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&dra7_pmx_core {
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0x400 (PIN_INPUT | MUX_MODE0) /* i2c1_sda */
+                       0x404 (PIN_INPUT | MUX_MODE0) /* i2c1_scl */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       0x408 (PIN_INPUT | MUX_MODE0) /* i2c2_sda */
+                       0x40c (PIN_INPUT | MUX_MODE0) /* i2c2_scl */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0x410 (PIN_INPUT | MUX_MODE0) /* i2c3_sda */
+                       0x414 (PIN_INPUT | MUX_MODE0) /* i2c3_scl */
+               >;
+       };
+
+       mcspi1_pins: pinmux_mcspi1_pins {
+               pinctrl-single,pins = <
+                       0x3a4 (PIN_INPUT | MUX_MODE0) /* spi2_clk */
+                       0x3a8 (PIN_INPUT | MUX_MODE0) /* spi2_d1 */
+                       0x3ac (PIN_INPUT | MUX_MODE0) /* spi2_d0 */
+                       0x3b0 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */
+                       0x3b4 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs1 */
+                       0x3b8 (PIN_INPUT_SLEW | MUX_MODE6) /* spi2_cs2 */
+                       0x3bc (PIN_INPUT_SLEW | MUX_MODE6) /* spi2_cs3 */
+               >;
+       };
+
+       mcspi2_pins: pinmux_mcspi2_pins {
+               pinctrl-single,pins = <
+                       0x3c0 (PIN_INPUT | MUX_MODE0) /* spi2_sclk */
+                       0x3c4 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+                       0x3c8 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+                       0x3cc (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */
+               >;
+       };
+
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                       0x3e0 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_rxd */
+                       0x3e4 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_txd */
+                       0x3e8 (PIN_INPUT | MUX_MODE3) /* uart1_ctsn */
+                       0x3ec (PIN_INPUT | MUX_MODE3) /* uart1_rtsn */
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       0x3f0 (PIN_INPUT | MUX_MODE0) /* uart2_rxd */
+                       0x3f4 (PIN_INPUT | MUX_MODE0) /* uart2_txd */
+                       0x3f8 (PIN_INPUT | MUX_MODE0) /* uart2_ctsn */
+                       0x3fc (PIN_INPUT | MUX_MODE0) /* uart2_rtsn */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       0x248 (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */
+                       0x24c (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */
+               >;
+       };
+};
+
+&i2c1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+       clock-frequency = <400000>;
+
+       tps659038: tps659038@58 {
+               compatible = "ti,tps659038";
+               reg = <0x58>;
+
+               tps659038_pmic {
+                       compatible = "ti,tps659038-pmic";
+
+                       regulators {
+                               smps123_reg: smps123 {
+                                       /* VDD_MPU */
+                                       regulator-name = "smps123";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps45_reg: smps45 {
+                                       /* VDD_DSPEVE */
+                                       regulator-name = "smps45";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1150000>;
+                                       regulator-boot-on;
+                               };
+
+                               smps6_reg: smps6 {
+                                       /* VDD_GPU - over VDD_SMPS6 */
+                                       regulator-name = "smps6";
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <12500000>;
+                                       regulator-boot-on;
+                               };
+
+                               smps7_reg: smps7 {
+                                       /* CORE_VDD */
+                                       regulator-name = "smps7";
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <1030000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps8_reg: smps8 {
+                                       /* VDD_IVAHD */
+                                       regulator-name = "smps8";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       regulator-boot-on;
+                               };
+
+                               smps9_reg: smps9 {
+                                       /* VDDS1V8 */
+                                       regulator-name = "smps9";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo1_reg: ldo1 {
+                                       /* LDO1_OUT --> SDIO  */
+                                       regulator-name = "ldo1";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-boot-on;
+                               };
+
+                               ldo2_reg: ldo2 {
+                                       /* VDD_RTCIO */
+                                       /* LDO2 -> VDDSHV5, LDO2 also goes to CAN_PHY_3V3 */
+                                       regulator-name = "ldo2";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-boot-on;
+                               };
+
+                               ldo3_reg: ldo3 {
+                                       /* VDDA_1V8_PHY */
+                                       regulator-name = "ldo3";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-boot-on;
+                               };
+
+                               ldo9_reg: ldo9 {
+                                       /* VDD_RTC */
+                                       regulator-name = "ldo9";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                                       regulator-boot-on;
+                               };
+
+                               ldoln_reg: ldoln {
+                                       /* VDDA_1V8_PLL */
+                                       regulator-name = "ldoln";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldousb_reg: ldousb {
+                                       /* VDDA_3V_USB: VDDA_USBHS33 */
+                                       regulator-name = "ldousb";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-boot-on;
+                               };
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+       clock-frequency = <3400000>;
+};
+
+&mcspi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcspi1_pins>;
+};
+
+&mcspi2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcspi2_pins>;
+};
+
+&uart1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&ldo1_reg>;
+       bus-width = <4>;
+};
+
+&mmc2 {
+       status = "okay";
+       vmmc-supply = <&mmc2_3v3>;
+       bus-width = <8>;
+};
+
+&cpu0 {
+       cpu0-supply = <&smps123_reg>;
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
new file mode 100644 (file)
index 0000000..d0df4c4
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ * Based on "omap4.dtsi"
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/dra.h>
+
+#include "skeleton.dtsi"
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       compatible = "ti,dra7xx";
+       interrupt-parent = <&gic>;
+
+       aliases {
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
+               i2c4 = &i2c5;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               serial5 = &uart6;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <0>;
+
+                       operating-points = <
+                               /* kHz    uV */
+                               1000000 1060000
+                               1176000 1160000
+                               >;
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <1>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       gic: interrupt-controller@48211000 {
+               compatible = "arm,cortex-a15-gic";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               reg = <0x48211000 0x1000>,
+                     <0x48212000 0x1000>,
+                     <0x48214000 0x2000>,
+                     <0x48216000 0x2000>;
+               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       /*
+        * The soc node represents the soc top level view. It is uses for IPs
+        * that are not memory mapped in the MPU view or for the MPU itself.
+        */
+       soc {
+               compatible = "ti,omap-infra";
+               mpu {
+                       compatible = "ti,omap5-mpu";
+                       ti,hwmods = "mpu";
+               };
+       };
+
+       /*
+        * XXX: Use a flat representation of the SOC interconnect.
+        * The real OMAP interconnect network is quite complex.
+        * Since that will not bring real advantage to represent that in DT for
+        * the moment, just use a fake OCP bus entry to represent the whole bus
+        * hierarchy.
+        */
+       ocp {
+               compatible = "ti,omap4-l3-noc", "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               ti,hwmods = "l3_main_1", "l3_main_2";
+               reg = <0x44000000 0x2000>,
+                     <0x44800000 0x3000>;
+               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+               counter32k: counter@4ae04000 {
+                       compatible = "ti,omap-counter32k";
+                       reg = <0x4ae04000 0x40>;
+                       ti,hwmods = "counter_32k";
+               };
+
+               dra7_pmx_core: pinmux@4a003400 {
+                       compatible = "pinctrl-single";
+                       reg = <0x4a003400 0x0464>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       pinctrl-single,register-width = <32>;
+                       pinctrl-single,function-mask = <0x3fffffff>;
+               };
+
+               sdma: dma-controller@4a056000 {
+                       compatible = "ti,omap4430-sdma";
+                       reg = <0x4a056000 0x1000>;
+                       interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       #dma-channels = <32>;
+                       #dma-requests = <127>;
+               };
+
+               gpio1: gpio@4ae10000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x4ae10000 0x200>;
+                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio1";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio2: gpio@48055000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x48055000 0x200>;
+                       interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio2";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio3: gpio@48057000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x48057000 0x200>;
+                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio3";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio4: gpio@48059000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x48059000 0x200>;
+                       interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio4";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio5: gpio@4805b000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x4805b000 0x200>;
+                       interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio5";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio6: gpio@4805d000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x4805d000 0x200>;
+                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio6";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio7: gpio@48051000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x48051000 0x200>;
+                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio7";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio8: gpio@48053000 {
+                       compatible = "ti,omap4-gpio";
+                       reg = <0x48053000 0x200>;
+                       interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "gpio8";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               uart1: serial@4806a000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x4806a000 0x100>;
+                       interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart1";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart2: serial@4806c000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x4806c000 0x100>;
+                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart2";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart3: serial@48020000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x48020000 0x100>;
+                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart3";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart4: serial@4806e000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x4806e000 0x100>;
+                       interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart4";
+                       clock-frequency = <48000000>;
+                        status = "disabled";
+               };
+
+               uart5: serial@48066000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x48066000 0x100>;
+                       interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart5";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart6: serial@48068000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x48068000 0x100>;
+                       interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "uart6";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart7: serial@48420000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x48420000 0x100>;
+                       ti,hwmods = "uart7";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart8: serial@48422000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x48422000 0x100>;
+                       ti,hwmods = "uart8";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart9: serial@48424000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x48424000 0x100>;
+                       ti,hwmods = "uart9";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               uart10: serial@4ae2b000 {
+                       compatible = "ti,omap4-uart";
+                       reg = <0x4ae2b000 0x100>;
+                       ti,hwmods = "uart10";
+                       clock-frequency = <48000000>;
+                       status = "disabled";
+               };
+
+               timer1: timer@4ae18000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x4ae18000 0x80>;
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer1";
+                       ti,timer-alwon;
+               };
+
+               timer2: timer@48032000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48032000 0x80>;
+                       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer2";
+               };
+
+               timer3: timer@48034000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48034000 0x80>;
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer3";
+               };
+
+               timer4: timer@48036000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48036000 0x80>;
+                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer4";
+               };
+
+               timer5: timer@48820000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48820000 0x80>;
+                       interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer5";
+                       ti,timer-dsp;
+               };
+
+               timer6: timer@48822000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48822000 0x80>;
+                       interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer6";
+                       ti,timer-dsp;
+                       ti,timer-pwm;
+               };
+
+               timer7: timer@48824000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48824000 0x80>;
+                       interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer7";
+                       ti,timer-dsp;
+               };
+
+               timer8: timer@48826000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48826000 0x80>;
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer8";
+                       ti,timer-dsp;
+                       ti,timer-pwm;
+               };
+
+               timer9: timer@4803e000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x4803e000 0x80>;
+                       interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer9";
+               };
+
+               timer10: timer@48086000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48086000 0x80>;
+                       interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer10";
+               };
+
+               timer11: timer@48088000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48088000 0x80>;
+                       interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "timer11";
+                       ti,timer-pwm;
+               };
+
+               timer13: timer@48828000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x48828000 0x80>;
+                       ti,hwmods = "timer13";
+                       status = "disabled";
+               };
+
+               timer14: timer@4882a000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x4882a000 0x80>;
+                       ti,hwmods = "timer14";
+                       status = "disabled";
+               };
+
+               timer15: timer@4882c000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x4882c000 0x80>;
+                       ti,hwmods = "timer15";
+                       status = "disabled";
+               };
+
+               timer16: timer@4882e000 {
+                       compatible = "ti,omap5430-timer";
+                       reg = <0x4882e000 0x80>;
+                       ti,hwmods = "timer16";
+                       status = "disabled";
+               };
+
+               wdt2: wdt@4ae14000 {
+                       compatible = "ti,omap4-wdt";
+                       reg = <0x4ae14000 0x80>;
+                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "wd_timer2";
+               };
+
+               i2c1: i2c@48070000 {
+                       compatible = "ti,omap4-i2c";
+                       reg = <0x48070000 0x100>;
+                       interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c1";
+                       status = "disabled";
+               };
+
+               i2c2: i2c@48072000 {
+                       compatible = "ti,omap4-i2c";
+                       reg = <0x48072000 0x100>;
+                       interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c2";
+                       status = "disabled";
+               };
+
+               i2c3: i2c@48060000 {
+                       compatible = "ti,omap4-i2c";
+                       reg = <0x48060000 0x100>;
+                       interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c3";
+                       status = "disabled";
+               };
+
+               i2c4: i2c@4807a000 {
+                       compatible = "ti,omap4-i2c";
+                       reg = <0x4807a000 0x100>;
+                       interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c4";
+                       status = "disabled";
+               };
+
+               i2c5: i2c@4807c000 {
+                       compatible = "ti,omap4-i2c";
+                       reg = <0x4807c000 0x100>;
+                       interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c5";
+                       status = "disabled";
+               };
+
+               mmc1: mmc@4809c000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x4809c000 0x400>;
+                       interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmc1";
+                       ti,dual-volt;
+                       ti,needs-special-reset;
+                       dmas = <&sdma 61>, <&sdma 62>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               mmc2: mmc@480b4000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x480b4000 0x400>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmc2";
+                       ti,needs-special-reset;
+                       dmas = <&sdma 47>, <&sdma 48>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               mmc3: mmc@480ad000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x480ad000 0x400>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmc3";
+                       ti,needs-special-reset;
+                       dmas = <&sdma 77>, <&sdma 78>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               mmc4: mmc@480d1000 {
+                       compatible = "ti,omap4-hsmmc";
+                       reg = <0x480d1000 0x400>;
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmc4";
+                       ti,needs-special-reset;
+                       dmas = <&sdma 57>, <&sdma 58>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               mcspi1: spi@48098000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x48098000 0x200>;
+                       interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi1";
+                       ti,spi-num-cs = <4>;
+                       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";
+                       status = "disabled";
+               };
+
+               mcspi2: spi@4809a000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x4809a000 0x200>;
+                       interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi2";
+                       ti,spi-num-cs = <2>;
+                       dmas = <&sdma 43>,
+                              <&sdma 44>,
+                              <&sdma 45>,
+                              <&sdma 46>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
+                       status = "disabled";
+               };
+
+               mcspi3: spi@480b8000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x480b8000 0x200>;
+                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi3";
+                       ti,spi-num-cs = <2>;
+                       dmas = <&sdma 15>, <&sdma 16>;
+                       dma-names = "tx0", "rx0";
+                       status = "disabled";
+               };
+
+               mcspi4: spi@480ba000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x480ba000 0x200>;
+                       interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi4";
+                       ti,spi-num-cs = <1>;
+                       dmas = <&sdma 70>, <&sdma 71>;
+                       dma-names = "tx0", "rx0";
+                       status = "disabled";
+               };
+       };
+};
index e8559b753c9de009595bcc6f4f7dc981b131bbee..bc22557d7a6a977b3cce656c115eb31e1d060398 100644 (file)
                bootargs = "console=ttyAMA0";
        };
 
+       psci {
+               compatible      = "arm,psci";
+               method          = "smc";
+               cpu_suspend     = <0x84000002>;
+               cpu_off         = <0x84000004>;
+               cpu_on          = <0x84000006>;
+       };
+
        soc {
                #address-cells = <1>;
                #size-cells = <1>;
diff --git a/arch/arm/boot/dts/emev2-kzm9d-reference.dts b/arch/arm/boot/dts/emev2-kzm9d-reference.dts
deleted file mode 100644 (file)
index cceefda..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Device Tree Source for the KZM9D board
- *
- * 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/ "emev2.dtsi"
-
-/ {
-       model = "EMEV2 KZM9D Board";
-       compatible = "renesas,kzm9d-reference", "renesas,emev2";
-
-       memory {
-               device_type = "memory";
-               reg = <0x40000000 0x8000000>;
-       };
-
-       chosen {
-               bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp";
-       };
-
-       reg_1p8v: regulator@0 {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-1.8V";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
-       reg_3p3v: regulator@1 {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-3.3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
-       lan9220@20000000 {
-               compatible = "smsc,lan9220", "smsc,lan9115";
-               reg = <0x20000000 0x10000>;
-               phy-mode = "mii";
-               interrupt-parent = <&gpio0>;
-               interrupts = <1 1>;     /* active high */
-               reg-io-width = <4>;
-               smsc,irq-active-high;
-               smsc,irq-push-pull;
-               vddvario-supply = <&reg_1p8v>;
-               vdd33a-supply = <&reg_3p3v>;
-       };
-};
index f92e812fdd9f3f5b00c7fc0f187e3b75eb90e8b4..861aa7d6fc7dbc480c0b9d6b185d6a291d38fcd2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for the KZM9D board
  *
- * Copyright (C) 2012 Renesas Solutions Corp.
+ * 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
        chosen {
                bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp";
        };
+
+       reg_1p8v: regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       reg_3p3v: regulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       lan9220@20000000 {
+               compatible = "smsc,lan9220", "smsc,lan9115";
+               reg = <0x20000000 0x10000>;
+               phy-mode = "mii";
+               interrupt-parent = <&gpio0>;
+               interrupts = <1 1>;     /* active high */
+               reg-io-width = <4>;
+               smsc,irq-active-high;
+               smsc,irq-push-pull;
+               vddvario-supply = <&reg_1p8v>;
+               vdd33a-supply = <&reg_3p3v>;
+       };
 };
index caadc025734210362effb5fe01b5d0d500235e6d..a73eeb5f258fba0b88e55640f6e0df220b7b1cbb 100644 (file)
                reg = <0x10000000 0x100>;
        };
 
+       mipi_phy: video-phy@10020710 {
+               compatible = "samsung,s5pv210-mipi-video-phy";
+               reg = <0x10020710 8>;
+               #phy-cells = <1>;
+       };
+
        pd_mfc: mfc-power-domain@10023C40 {
                compatible = "samsung,exynos4210-pd";
                reg = <0x10023C40 0x20>;
                        clock-names = "csis", "sclk_csis";
                        bus-width = <4>;
                        samsung,power-domain = <&pd_cam>;
+                       phys = <&mipi_phy 0>;
+                       phy-names = "csis";
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        clock-names = "csis", "sclk_csis";
                        bus-width = <2>;
                        samsung,power-domain = <&pd_cam>;
+                       phys = <&mipi_phy 2>;
+                       phy-names = "csis";
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
index 382d8c7e290602058fd9f2609ba2d1646461da7c..1a12fb23767c522be3f6af9311a858d93750846a 100644 (file)
                bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
        };
 
-       mmc_reg: voltage-regulator {
-               compatible = "regulator-fixed";
-               regulator-name = "VMEM_VDD_2.8V";
-               regulator-min-microvolt = <2800000>;
-               regulator-max-microvolt = <2800000>;
-               gpio = <&gpx1 1 0>;
-               enable-active-high;
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mmc_reg: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "VMEM_VDD_2.8V";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+                       gpio = <&gpx1 1 0>;
+                       enable-active-high;
+               };
        };
 
        tmu@100C0000 {
                                };
 
                                buck1_reg: BUCK1 {
-                                       regulator-name = "VDD_ARM_1.2V";
+                                       /*
+                                       * HACK: The real name is VDD_ARM_1.2V,
+                                       * but exynos-cpufreq does not support
+                                       * DT-based regulator lookup yet.
+                                       */
+                                       regulator-name = "vdd_arm";
                                        regulator-min-microvolt = <950000>;
                                        regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
index 1c164f234bcca89892c7a05fa3d8012a86cffd22..63cc571ca30794b04f53239efc5f8393af8f3022 100644 (file)
                                };
 
                                varm_breg: BUCK1 {
-                                    regulator-name = "VARM_1.2V_C210";
+                                    /*
+                                     * HACK: The real name is VARM_1.2V_C210,
+                                     * but exynos-cpufreq does not support
+                                     * DT-based regulator lookup yet.
+                                     */
+                                    regulator-name = "vdd_arm";
                                     regulator-min-microvolt = <900000>;
                                     regulator-max-microvolt = <1350000>;
                                     regulator-always-on;
index 889cdada1ce9c92bce9550474ab04fb34f33fe5f..d2e3f5f5916dad4c325ab4dc3f71ff0ef34d9b39 100644 (file)
                status = "okay";
        };
 };
+
+&mdma1 {
+       reg = <0x12840000 0x1000>;
+};
index 8768b03702e5a14c3ebf742677a03e0b76082a42..d65984c440f6786b245275a09497670271714e90 100644 (file)
                reg = <0x0203F000 0x1000>;
        };
 
-       mmc_reg: voltage-regulator {
-               compatible = "regulator-fixed";
-               regulator-name = "VMEM_VDD_2.8V";
-               regulator-min-microvolt = <2800000>;
-               regulator-max-microvolt = <2800000>;
-               gpio = <&gpx1 1 0>;
-               enable-active-high;
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mmc_reg: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "VMEM_VDD_2.8V";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+                       gpio = <&gpx1 1 0>;
+                       enable-active-high;
+               };
        };
 
        pinctrl@11000000 {
index cee55fa33731195c7230aee40480aef77361b694..684527087aa4cc2bdc8da3c3f801a1626f3d9439 100644 (file)
        };
 
        i2c@12C80000 {
-               status = "disabled";
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <66000>;
+               samsung,i2c-slave-addr = <0x50>;
+
+               hdmiddc@50 {
+                       compatible = "samsung,exynos4210-hdmiddc";
+                       reg = <0x50>;
+               };
        };
 
        i2c@12C90000 {
                status = "disabled";
        };
 
+       i2c@12CE0000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <66000>;
+               samsung,i2c-slave-addr = <0x38>;
+
+               hdmiphy@38 {
+                       compatible = "samsung,exynos4212-hdmiphy";
+                       reg = <0x38>;
+               };
+       };
+
        i2c@121D0000 {
                status = "disabled";
        };
                status = "disabled";
        };
 
+       i2s0: i2s@03830000 {
+               status = "okay";
+       };
+
        spi_0: spi@12d20000 {
                status = "disabled";
        };
                #address-cells = <1>;
                #size-cells = <0>;
 
-               main_dc_reg: fixedregulator@1 {
+               main_dc_reg: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "MAIN_DC";
                };
 
-               mmc_reg: voltage-regulator {
+               mmc_reg: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "VDD_33ON_2.8V";
                        regulator-min-microvolt = <2800000>;
                        regulator-max-microvolt = <2800000>;
                        enable-active-high;
                };
 
-               reg_hdmi_en: fixedregulator@0 {
+               reg_hdmi_en: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "hdmi-en";
                };
        };
index 724a22f9b1c8f732513321becc6c7f6e65f4cb7d..9a49e6804ae15587f13a3bb6c0052e3968e27a19 100644 (file)
                        samsung,pins = "gpa0-2", "gpa0-3";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                i2c2_bus: i2c2-bus {
                        samsung,pins = "gpa0-6", "gpa0-7";
                        samsung,pin-function = <3>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                i2c2_hs_bus: i2c2-hs-bus {
                        samsung,pins = "gpa0-6", "gpa0-7";
                        samsung,pin-function = <4>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                uart2_data: uart2-data {
                        samsung,pins = "gpa1-2", "gpa1-3";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                i2c3_bus: i2c3-bus {
                        samsung,pins = "gpa1-2", "gpa1-3";
                        samsung,pin-function = <3>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                i2c3_hs_bus: i2c3-hs-bus {
                        samsung,pins = "gpa1-2", "gpa1-3";
                        samsung,pin-function = <4>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                uart3_data: uart3-data {
                        samsung,pins = "gpa2-0", "gpa2-1";
                        samsung,pin-function = <3>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                i2c5_bus: i2c5-bus {
                        samsung,pins = "gpa2-2", "gpa2-3";
                        samsung,pin-function = <3>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                spi1_bus: spi1-bus {
                        samsung,pins = "gpb3-0", "gpb3-1";
                        samsung,pin-function = <4>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                i2c1_hs_bus: i2c1-hs-bus {
                        samsung,pins = "gpb3-2", "gpb3-3";
                        samsung,pin-function = <4>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                sd0_clk: sd0-clk {
                        samsung,pins = "gpd0-2", "gpd0-3";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                dp_hpd: dp_hpd {
                        samsung,pins = "gpx0-7";
                        samsung,pin-function = <3>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
        };
 
                                       "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
                        samsung,pin-function = <3>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_i2c2_bus: cam-i2c2-bus {
                        samsung,pins = "gpe0-6", "gpe1-0";
                        samsung,pin-function = <4>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_spi1_bus: cam-spi1-bus {
                        samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
                        samsung,pin-function = <4>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_i2c1_bus: cam-i2c1-bus {
                        samsung,pins = "gpf0-2", "gpf0-3";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_i2c0_bus: cam-i2c0-bus {
                        samsung,pins = "gpf0-0", "gpf0-1";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <3>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_spi0_bus: cam-spi0-bus {
                        samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_bayrgb_bus: cam-bayrgb-bus {
                                       "gpg2-0", "gpg2-1";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                cam_port_a: cam-port-a {
                                       "gph1-4", "gph1-5", "gph1-6", "gph1-7";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
        };
 
                                       "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
 
                c2c_txd: c2c-txd {
                                       "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7";
                        samsung,pin-function = <2>;
                        samsung,pin-pud = <0>;
-                       samaung,pin-drv = <0>;
+                       samsung,pin-drv = <0>;
                };
        };
 
index 2538b329f2cea5367f1517c37673cc77d3e13d3d..f86d56760a45a0f42692f5636376c899f81edbc3 100644 (file)
                status = "okay";
        };
 
-       i2s1: i2s@12D60000 {
-               status = "disabled";
-       };
-
-       i2s2: i2s@12D70000 {
-               status = "disabled";
-       };
-
        sound {
                compatible = "samsung,smdk-wm8994";
 
index bbac42a78ce543c2790a7943697afda1eba2e2aa..9db5047812f3d6c05a36643abbea0e1fb33e8195 100644 (file)
 
        i2s0: i2s@03830000 {
                compatible = "samsung,s5pv210-i2s";
+               status = "disabled";
                reg = <0x03830000 0x100>;
                dmas = <&pdma0 10
                        &pdma0 9
 
        i2s1: i2s@12D60000 {
                compatible = "samsung,s3c6410-i2s";
+               status = "disabled";
                reg = <0x12D60000 0x100>;
                dmas = <&pdma1 12
                        &pdma1 11>;
 
        i2s2: i2s@12D70000 {
                compatible = "samsung,s3c6410-i2s";
+               status = "disabled";
                reg = <0x12D70000 0x100>;
                dmas = <&pdma0 12
                        &pdma0 11>;
                compatible = "samsung,exynos4212-hdmi";
                reg = <0x14530000 0x70000>;
                interrupts = <0 95 0>;
-               clocks = <&clock 333>, <&clock 136>, <&clock 137>,
-                               <&clock 333>, <&clock 333>;
+               clocks = <&clock 344>, <&clock 136>, <&clock 137>,
+                               <&clock 159>, <&clock 1024>;
                clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
-                               "sclk_hdmiphy", "hdmiphy";
+                               "sclk_hdmiphy", "mout_hdmi";
        };
 
        mixer {
                compatible = "samsung,exynos5250-mixer";
                reg = <0x14450000 0x10000>;
                interrupts = <0 94 0>;
+               clocks = <&clock 343>, <&clock 136>;
+               clock-names = "mixer", "sclk_hdmi";
        };
 
        dp_phy: video-phy@10040720 {
index bafba25ba7c29f44adba081b8bea245aa3d4b11a..79524c74c60354344bd9026b67614ce414ffbe31 100644 (file)
                };
        };
 
+       pinctrl@13400000 {
+               hdmi_hpd_irq: hdmi-hpd-irq {
+                       samsung,pins = "gpx3-7";
+                       samsung,pin-function = <0>;
+                       samsung,pin-pud = <1>;
+                       samsung,pin-drv = <0>;
+               };
+       };
+
+       hdmi@14530000 {
+               status = "okay";
+               hpd-gpio = <&gpx3 7 0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hdmi_hpd_irq>;
+       };
+
+       i2c_2: i2c@12C80000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <66000>;
+               status = "okay";
+
+               hdmiddc@50 {
+                       compatible = "samsung,exynos4210-hdmiddc";
+                       reg = <0x50>;
+               };
+       };
 };
index d537cd704e190b89faec41f3d7509d2e2cb50059..09aa06cb3d3af77be582328167c25f8735a09fb2 100644 (file)
                pinctrl2 = &pinctrl_2;
                pinctrl3 = &pinctrl_3;
                pinctrl4 = &pinctrl_4;
+               i2c0 = &i2c_0;
+               i2c1 = &i2c_1;
+               i2c2 = &i2c_2;
+               i2c3 = &i2c_3;
        };
 
        cpus {
                io-channel-ranges;
                status = "disabled";
        };
+
+       i2c_0: i2c@12C60000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C60000 0x100>;
+               interrupts = <0 56 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 261>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c0_bus>;
+               status = "disabled";
+       };
+
+       i2c_1: i2c@12C70000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C70000 0x100>;
+               interrupts = <0 57 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 262>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c1_bus>;
+               status = "disabled";
+       };
+
+       i2c_2: i2c@12C80000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C80000 0x100>;
+               interrupts = <0 58 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 263>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_bus>;
+               status = "disabled";
+       };
+
+       i2c_3: i2c@12C90000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C90000 0x100>;
+               interrupts = <0 59 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 264>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c3_bus>;
+               status = "disabled";
+       };
+
+       hdmi@14530000 {
+               compatible = "samsung,exynos4212-hdmi";
+               reg = <0x14530000 0x70000>;
+               interrupts = <0 95 0>;
+               clocks = <&clock 413>, <&clock 143>, <&clock 768>,
+                       <&clock 158>, <&clock 640>;
+               clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
+                       "sclk_hdmiphy", "mout_hdmi";
+               status = "disabled";
+       };
+
+       mixer@14450000 {
+               compatible = "samsung,exynos5420-mixer";
+               reg = <0x14450000 0x10000>;
+               interrupts = <0 94 0>;
+               clocks = <&clock 431>, <&clock 143>;
+               clock-names = "mixer", "sclk_hdmi";
+       };
 };
index 5b22508050dad3f63c8a1fd8e57d692510a55ea3..777fb1c2c70f322b00b3075472a8a412e5c42509 100644 (file)
@@ -17,7 +17,7 @@
        compatible = "samsung,sd5v1", "samsung,exynos5440";
 
        chosen {
-               bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
+               bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
        };
 
        fixed-rate-clocks {
index ede772741f81c13a2d6e62d3963b7219cb6196c8..d58cb787061af4a85e7d60e90222c659dbc8d412 100644 (file)
@@ -17,7 +17,7 @@
        compatible = "samsung,ssdk5440", "samsung,exynos5440";
 
        chosen {
-               bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
+               bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
        };
 
        spi_0: spi@D0000 {
 
        pcie@290000 {
                reset-gpio = <&pin_ctrl 5 0>;
+               status = "okay";
        };
 
        pcie@2a0000 {
                reset-gpio = <&pin_ctrl 22 0>;
+               status = "okay";
        };
 };
index 5d6cf4965d6eb3c7db9b2b4f8d4724e2824d2b0d..8da107088ce414b3138d9073a07304fb3575bcea 100644 (file)
                interrupt-map-mask = <0 0 0 0>;
                interrupt-map = <0x0 0 &gic 53>;
                num-lanes = <4>;
+               status = "disabled";
        };
 
        pcie@2a0000 {
                interrupt-map-mask = <0 0 0 0>;
                interrupt-map = <0x0 0 &gic 56>;
                num-lanes = <4>;
+               status = "disabled";
        };
 };
index 185c7c01102ad755541e420faa77ee708fdab498..1f026adefd451e594628d1855acf949f9cd7d7cf 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx23.dtsi"
+#include "imx23.dtsi"
 
 / {
        model = "Freescale i.MX23 Evaluation Kit";
                                hog_pins_a: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1123 /* MX23_PAD_LCD_RESET__GPIO_1_18 */
-                                               0x11d3 /* MX23_PAD_PWM3__GPIO_1_29 */
-                                               0x11e3 /* MX23_PAD_PWM4__GPIO_1_30 */
-                                               0x2010 /* MX23_PAD_SSP1_DETECT__SSP1_DETECT */
+                                               MX23_PAD_LCD_RESET__GPIO_1_18
+                                               MX23_PAD_PWM3__GPIO_1_29
+                                               MX23_PAD_PWM4__GPIO_1_30
+                                               MX23_PAD_SSP1_DETECT__SSP1_DETECT
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
index fc766ae12e24526fcbb5e0e79508acd3a0721f51..526bfdbd87f9f84f08747c6c045c059a657d2cbc 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 /dts-v1/;
-/include/ "imx23.dtsi"
+#include "imx23.dtsi"
 
 / {
        model = "i.MX23 Olinuxino Low Cost Board";
                                hog_pins_a: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0113 /* MX23_PAD_GPMI_ALE__GPIO_0_17 */
+                                               MX23_PAD_GPMI_ALE__GPIO_0_17
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                led_pin_gpio2_1: led_gpio2_1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2013 /* MX23_PAD_SSP1_DETECT__GPIO_2_1 */
+                                               MX23_PAD_SSP1_DETECT__GPIO_2_1
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
diff --git a/arch/arm/boot/dts/imx23-pinfunc.h b/arch/arm/boot/dts/imx23-pinfunc.h
new file mode 100644 (file)
index 0000000..5c0f32c
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * Header providing constants for i.MX23 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MX23_PINCTRL_H__
+#define __DT_BINDINGS_MX23_PINCTRL_H__
+
+#include "mxs-pinfunc.h"
+
+#define MX23_PAD_GPMI_D00__GPMI_D00                    0x0000
+#define MX23_PAD_GPMI_D01__GPMI_D01                    0x0010
+#define MX23_PAD_GPMI_D02__GPMI_D02                    0x0020
+#define MX23_PAD_GPMI_D03__GPMI_D03                    0x0030
+#define MX23_PAD_GPMI_D04__GPMI_D04                    0x0040
+#define MX23_PAD_GPMI_D05__GPMI_D05                    0x0050
+#define MX23_PAD_GPMI_D06__GPMI_D06                    0x0060
+#define MX23_PAD_GPMI_D07__GPMI_D07                    0x0070
+#define MX23_PAD_GPMI_D08__GPMI_D08                    0x0080
+#define MX23_PAD_GPMI_D09__GPMI_D09                    0x0090
+#define MX23_PAD_GPMI_D10__GPMI_D10                    0x00a0
+#define MX23_PAD_GPMI_D11__GPMI_D11                    0x00b0
+#define MX23_PAD_GPMI_D12__GPMI_D12                    0x00c0
+#define MX23_PAD_GPMI_D13__GPMI_D13                    0x00d0
+#define MX23_PAD_GPMI_D14__GPMI_D14                    0x00e0
+#define MX23_PAD_GPMI_D15__GPMI_D15                    0x00f0
+#define MX23_PAD_GPMI_CLE__GPMI_CLE                    0x0100
+#define MX23_PAD_GPMI_ALE__GPMI_ALE                    0x0110
+#define MX23_PAD_GPMI_CE2N__GPMI_CE2N                  0x0120
+#define MX23_PAD_GPMI_RDY0__GPMI_RDY0                  0x0130
+#define MX23_PAD_GPMI_RDY1__GPMI_RDY1                  0x0140
+#define MX23_PAD_GPMI_RDY2__GPMI_RDY2                  0x0150
+#define MX23_PAD_GPMI_RDY3__GPMI_RDY3                  0x0160
+#define MX23_PAD_GPMI_WPN__GPMI_WPN                    0x0170
+#define MX23_PAD_GPMI_WRN__GPMI_WRN                    0x0180
+#define MX23_PAD_GPMI_RDN__GPMI_RDN                    0x0190
+#define MX23_PAD_AUART1_CTS__AUART1_CTS                        0x01a0
+#define MX23_PAD_AUART1_RTS__AUART1_RTS                        0x01b0
+#define MX23_PAD_AUART1_RX__AUART1_RX                  0x01c0
+#define MX23_PAD_AUART1_TX__AUART1_TX                  0x01d0
+#define MX23_PAD_I2C_SCL__I2C_SCL                      0x01e0
+#define MX23_PAD_I2C_SDA__I2C_SDA                      0x01f0
+#define MX23_PAD_LCD_D00__LCD_D00                      0x1000
+#define MX23_PAD_LCD_D01__LCD_D01                      0x1010
+#define MX23_PAD_LCD_D02__LCD_D02                      0x1020
+#define MX23_PAD_LCD_D03__LCD_D03                      0x1030
+#define MX23_PAD_LCD_D04__LCD_D04                      0x1040
+#define MX23_PAD_LCD_D05__LCD_D05                      0x1050
+#define MX23_PAD_LCD_D06__LCD_D06                      0x1060
+#define MX23_PAD_LCD_D07__LCD_D07                      0x1070
+#define MX23_PAD_LCD_D08__LCD_D08                      0x1080
+#define MX23_PAD_LCD_D09__LCD_D09                      0x1090
+#define MX23_PAD_LCD_D10__LCD_D10                      0x10a0
+#define MX23_PAD_LCD_D11__LCD_D11                      0x10b0
+#define MX23_PAD_LCD_D12__LCD_D12                      0x10c0
+#define MX23_PAD_LCD_D13__LCD_D13                      0x10d0
+#define MX23_PAD_LCD_D14__LCD_D14                      0x10e0
+#define MX23_PAD_LCD_D15__LCD_D15                      0x10f0
+#define MX23_PAD_LCD_D16__LCD_D16                      0x1100
+#define MX23_PAD_LCD_D17__LCD_D17                      0x1110
+#define MX23_PAD_LCD_RESET__LCD_RESET                  0x1120
+#define MX23_PAD_LCD_RS__LCD_RS                                0x1130
+#define MX23_PAD_LCD_WR__LCD_WR                                0x1140
+#define MX23_PAD_LCD_CS__LCD_CS                                0x1150
+#define MX23_PAD_LCD_DOTCK__LCD_DOTCK                  0x1160
+#define MX23_PAD_LCD_ENABLE__LCD_ENABLE                        0x1170
+#define MX23_PAD_LCD_HSYNC__LCD_HSYNC                  0x1180
+#define MX23_PAD_LCD_VSYNC__LCD_VSYNC                  0x1190
+#define MX23_PAD_PWM0__PWM0                            0x11a0
+#define MX23_PAD_PWM1__PWM1                            0x11b0
+#define MX23_PAD_PWM2__PWM2                            0x11c0
+#define MX23_PAD_PWM3__PWM3                            0x11d0
+#define MX23_PAD_PWM4__PWM4                            0x11e0
+#define MX23_PAD_SSP1_CMD__SSP1_CMD                    0x2000
+#define MX23_PAD_SSP1_DETECT__SSP1_DETECT              0x2010
+#define MX23_PAD_SSP1_DATA0__SSP1_DATA0                        0x2020
+#define MX23_PAD_SSP1_DATA1__SSP1_DATA1                        0x2030
+#define MX23_PAD_SSP1_DATA2__SSP1_DATA2                        0x2040
+#define MX23_PAD_SSP1_DATA3__SSP1_DATA3                        0x2050
+#define MX23_PAD_SSP1_SCK__SSP1_SCK                    0x2060
+#define MX23_PAD_ROTARYA__ROTARYA                      0x2070
+#define MX23_PAD_ROTARYB__ROTARYB                      0x2080
+#define MX23_PAD_EMI_A00__EMI_A00                      0x2090
+#define MX23_PAD_EMI_A01__EMI_A01                      0x20a0
+#define MX23_PAD_EMI_A02__EMI_A02                      0x20b0
+#define MX23_PAD_EMI_A03__EMI_A03                      0x20c0
+#define MX23_PAD_EMI_A04__EMI_A04                      0x20d0
+#define MX23_PAD_EMI_A05__EMI_A05                      0x20e0
+#define MX23_PAD_EMI_A06__EMI_A06                      0x20f0
+#define MX23_PAD_EMI_A07__EMI_A07                      0x2100
+#define MX23_PAD_EMI_A08__EMI_A08                      0x2110
+#define MX23_PAD_EMI_A09__EMI_A09                      0x2120
+#define MX23_PAD_EMI_A10__EMI_A10                      0x2130
+#define MX23_PAD_EMI_A11__EMI_A11                      0x2140
+#define MX23_PAD_EMI_A12__EMI_A12                      0x2150
+#define MX23_PAD_EMI_BA0__EMI_BA0                      0x2160
+#define MX23_PAD_EMI_BA1__EMI_BA1                      0x2170
+#define MX23_PAD_EMI_CASN__EMI_CASN                    0x2180
+#define MX23_PAD_EMI_CE0N__EMI_CE0N                    0x2190
+#define MX23_PAD_EMI_CE1N__EMI_CE1N                    0x21a0
+#define MX23_PAD_GPMI_CE1N__GPMI_CE1N                  0x21b0
+#define MX23_PAD_GPMI_CE0N__GPMI_CE0N                  0x21c0
+#define MX23_PAD_EMI_CKE__EMI_CKE                      0x21d0
+#define MX23_PAD_EMI_RASN__EMI_RASN                    0x21e0
+#define MX23_PAD_EMI_WEN__EMI_WEN                      0x21f0
+#define MX23_PAD_EMI_D00__EMI_D00                      0x3000
+#define MX23_PAD_EMI_D01__EMI_D01                      0x3010
+#define MX23_PAD_EMI_D02__EMI_D02                      0x3020
+#define MX23_PAD_EMI_D03__EMI_D03                      0x3030
+#define MX23_PAD_EMI_D04__EMI_D04                      0x3040
+#define MX23_PAD_EMI_D05__EMI_D05                      0x3050
+#define MX23_PAD_EMI_D06__EMI_D06                      0x3060
+#define MX23_PAD_EMI_D07__EMI_D07                      0x3070
+#define MX23_PAD_EMI_D08__EMI_D08                      0x3080
+#define MX23_PAD_EMI_D09__EMI_D09                      0x3090
+#define MX23_PAD_EMI_D10__EMI_D10                      0x30a0
+#define MX23_PAD_EMI_D11__EMI_D11                      0x30b0
+#define MX23_PAD_EMI_D12__EMI_D12                      0x30c0
+#define MX23_PAD_EMI_D13__EMI_D13                      0x30d0
+#define MX23_PAD_EMI_D14__EMI_D14                      0x30e0
+#define MX23_PAD_EMI_D15__EMI_D15                      0x30f0
+#define MX23_PAD_EMI_DQM0__EMI_DQM0                    0x3100
+#define MX23_PAD_EMI_DQM1__EMI_DQM1                    0x3110
+#define MX23_PAD_EMI_DQS0__EMI_DQS0                    0x3120
+#define MX23_PAD_EMI_DQS1__EMI_DQS1                    0x3130
+#define MX23_PAD_EMI_CLK__EMI_CLK                      0x3140
+#define MX23_PAD_EMI_CLKN__EMI_CLKN                    0x3150
+#define MX23_PAD_GPMI_D00__LCD_D8                      0x0001
+#define MX23_PAD_GPMI_D01__LCD_D9                      0x0011
+#define MX23_PAD_GPMI_D02__LCD_D10                     0x0021
+#define MX23_PAD_GPMI_D03__LCD_D11                     0x0031
+#define MX23_PAD_GPMI_D04__LCD_D12                     0x0041
+#define MX23_PAD_GPMI_D05__LCD_D13                     0x0051
+#define MX23_PAD_GPMI_D06__LCD_D14                     0x0061
+#define MX23_PAD_GPMI_D07__LCD_D15                     0x0071
+#define MX23_PAD_GPMI_D08__LCD_D18                     0x0081
+#define MX23_PAD_GPMI_D09__LCD_D19                     0x0091
+#define MX23_PAD_GPMI_D10__LCD_D20                     0x00a1
+#define MX23_PAD_GPMI_D11__LCD_D21                     0x00b1
+#define MX23_PAD_GPMI_D12__LCD_D22                     0x00c1
+#define MX23_PAD_GPMI_D13__LCD_D23                     0x00d1
+#define MX23_PAD_GPMI_D14__AUART2_RX                   0x00e1
+#define MX23_PAD_GPMI_D15__AUART2_TX                   0x00f1
+#define MX23_PAD_GPMI_CLE__LCD_D16                     0x0101
+#define MX23_PAD_GPMI_ALE__LCD_D17                     0x0111
+#define MX23_PAD_GPMI_CE2N__ATA_A2                     0x0121
+#define MX23_PAD_AUART1_RTS__IR_CLK                    0x01b1
+#define MX23_PAD_AUART1_RX__IR_RX                      0x01c1
+#define MX23_PAD_AUART1_TX__IR_TX                      0x01d1
+#define MX23_PAD_I2C_SCL__GPMI_RDY2                    0x01e1
+#define MX23_PAD_I2C_SDA__GPMI_CE2N                    0x01f1
+#define MX23_PAD_LCD_D00__ETM_DA8                      0x1001
+#define MX23_PAD_LCD_D01__ETM_DA9                      0x1011
+#define MX23_PAD_LCD_D02__ETM_DA10                     0x1021
+#define MX23_PAD_LCD_D03__ETM_DA11                     0x1031
+#define MX23_PAD_LCD_D04__ETM_DA12                     0x1041
+#define MX23_PAD_LCD_D05__ETM_DA13                     0x1051
+#define MX23_PAD_LCD_D06__ETM_DA14                     0x1061
+#define MX23_PAD_LCD_D07__ETM_DA15                     0x1071
+#define MX23_PAD_LCD_D08__ETM_DA0                      0x1081
+#define MX23_PAD_LCD_D09__ETM_DA1                      0x1091
+#define MX23_PAD_LCD_D10__ETM_DA2                      0x10a1
+#define MX23_PAD_LCD_D11__ETM_DA3                      0x10b1
+#define MX23_PAD_LCD_D12__ETM_DA4                      0x10c1
+#define MX23_PAD_LCD_D13__ETM_DA5                      0x10d1
+#define MX23_PAD_LCD_D14__ETM_DA6                      0x10e1
+#define MX23_PAD_LCD_D15__ETM_DA7                      0x10f1
+#define MX23_PAD_LCD_RESET__ETM_TCTL                   0x1121
+#define MX23_PAD_LCD_RS__ETM_TCLK                      0x1131
+#define MX23_PAD_LCD_DOTCK__GPMI_RDY3                  0x1161
+#define MX23_PAD_LCD_ENABLE__I2C_SCL                   0x1171
+#define MX23_PAD_LCD_HSYNC__I2C_SDA                    0x1181
+#define MX23_PAD_LCD_VSYNC__LCD_BUSY                   0x1191
+#define MX23_PAD_PWM0__ROTARYA                         0x11a1
+#define MX23_PAD_PWM1__ROTARYB                         0x11b1
+#define MX23_PAD_PWM2__GPMI_RDY3                       0x11c1
+#define MX23_PAD_PWM3__ETM_TCTL                                0x11d1
+#define MX23_PAD_PWM4__ETM_TCLK                                0x11e1
+#define MX23_PAD_SSP1_DETECT__GPMI_CE3N                        0x2011
+#define MX23_PAD_SSP1_DATA1__I2C_SCL                   0x2031
+#define MX23_PAD_SSP1_DATA2__I2C_SDA                   0x2041
+#define MX23_PAD_ROTARYA__AUART2_RTS                   0x2071
+#define MX23_PAD_ROTARYB__AUART2_CTS                   0x2081
+#define MX23_PAD_GPMI_D00__SSP2_DATA0                  0x0002
+#define MX23_PAD_GPMI_D01__SSP2_DATA1                  0x0012
+#define MX23_PAD_GPMI_D02__SSP2_DATA2                  0x0022
+#define MX23_PAD_GPMI_D03__SSP2_DATA3                  0x0032
+#define MX23_PAD_GPMI_D04__SSP2_DATA4                  0x0042
+#define MX23_PAD_GPMI_D05__SSP2_DATA5                  0x0052
+#define MX23_PAD_GPMI_D06__SSP2_DATA6                  0x0062
+#define MX23_PAD_GPMI_D07__SSP2_DATA7                  0x0072
+#define MX23_PAD_GPMI_D08__SSP1_DATA4                  0x0082
+#define MX23_PAD_GPMI_D09__SSP1_DATA5                  0x0092
+#define MX23_PAD_GPMI_D10__SSP1_DATA6                  0x00a2
+#define MX23_PAD_GPMI_D11__SSP1_DATA7                  0x00b2
+#define MX23_PAD_GPMI_D15__GPMI_CE3N                   0x00f2
+#define MX23_PAD_GPMI_RDY0__SSP2_DETECT                        0x0132
+#define MX23_PAD_GPMI_RDY1__SSP2_CMD                   0x0142
+#define MX23_PAD_GPMI_WRN__SSP2_SCK                    0x0182
+#define MX23_PAD_AUART1_CTS__SSP1_DATA4                        0x01a2
+#define MX23_PAD_AUART1_RTS__SSP1_DATA5                        0x01b2
+#define MX23_PAD_AUART1_RX__SSP1_DATA6                 0x01c2
+#define MX23_PAD_AUART1_TX__SSP1_DATA7                 0x01d2
+#define MX23_PAD_I2C_SCL__AUART1_TX                    0x01e2
+#define MX23_PAD_I2C_SDA__AUART1_RX                    0x01f2
+#define MX23_PAD_LCD_D08__SAIF2_SDATA0                 0x1082
+#define MX23_PAD_LCD_D09__SAIF1_SDATA0                 0x1092
+#define MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK             0x10a2
+#define MX23_PAD_LCD_D11__SAIF_LRCLK                   0x10b2
+#define MX23_PAD_LCD_D12__SAIF2_SDATA1                 0x10c2
+#define MX23_PAD_LCD_D13__SAIF2_SDATA2                 0x10d2
+#define MX23_PAD_LCD_D14__SAIF1_SDATA2                 0x10e2
+#define MX23_PAD_LCD_D15__SAIF1_SDATA1                 0x10f2
+#define MX23_PAD_LCD_D16__SAIF_ALT_BITCLK              0x1102
+#define MX23_PAD_LCD_RESET__GPMI_CE3N                  0x1122
+#define MX23_PAD_PWM0__DUART_RX                                0x11a2
+#define MX23_PAD_PWM1__DUART_TX                                0x11b2
+#define MX23_PAD_PWM3__AUART1_CTS                      0x11d2
+#define MX23_PAD_PWM4__AUART1_RTS                      0x11e2
+#define MX23_PAD_SSP1_CMD__JTAG_TDO                    0x2002
+#define MX23_PAD_SSP1_DETECT__USB_OTG_ID               0x2012
+#define MX23_PAD_SSP1_DATA0__JTAG_TDI                  0x2022
+#define MX23_PAD_SSP1_DATA1__JTAG_TCLK                 0x2032
+#define MX23_PAD_SSP1_DATA2__JTAG_RTCK                 0x2042
+#define MX23_PAD_SSP1_DATA3__JTAG_TMS                  0x2052
+#define MX23_PAD_SSP1_SCK__JTAG_TRST                   0x2062
+#define MX23_PAD_ROTARYA__SPDIF                                0x2072
+#define MX23_PAD_ROTARYB__GPMI_CE3N                    0x2082
+#define MX23_PAD_GPMI_D00__GPIO_0_0                    0x0003
+#define MX23_PAD_GPMI_D01__GPIO_0_1                    0x0013
+#define MX23_PAD_GPMI_D02__GPIO_0_2                    0x0023
+#define MX23_PAD_GPMI_D03__GPIO_0_3                    0x0033
+#define MX23_PAD_GPMI_D04__GPIO_0_4                    0x0043
+#define MX23_PAD_GPMI_D05__GPIO_0_5                    0x0053
+#define MX23_PAD_GPMI_D06__GPIO_0_6                    0x0063
+#define MX23_PAD_GPMI_D07__GPIO_0_7                    0x0073
+#define MX23_PAD_GPMI_D08__GPIO_0_8                    0x0083
+#define MX23_PAD_GPMI_D09__GPIO_0_9                    0x0093
+#define MX23_PAD_GPMI_D10__GPIO_0_10                   0x00a3
+#define MX23_PAD_GPMI_D11__GPIO_0_11                   0x00b3
+#define MX23_PAD_GPMI_D12__GPIO_0_12                   0x00c3
+#define MX23_PAD_GPMI_D13__GPIO_0_13                   0x00d3
+#define MX23_PAD_GPMI_D14__GPIO_0_14                   0x00e3
+#define MX23_PAD_GPMI_D15__GPIO_0_15                   0x00f3
+#define MX23_PAD_GPMI_CLE__GPIO_0_16                   0x0103
+#define MX23_PAD_GPMI_ALE__GPIO_0_17                   0x0113
+#define MX23_PAD_GPMI_CE2N__GPIO_0_18                  0x0123
+#define MX23_PAD_GPMI_RDY0__GPIO_0_19                  0x0133
+#define MX23_PAD_GPMI_RDY1__GPIO_0_20                  0x0143
+#define MX23_PAD_GPMI_RDY2__GPIO_0_21                  0x0153
+#define MX23_PAD_GPMI_RDY3__GPIO_0_22                  0x0163
+#define MX23_PAD_GPMI_WPN__GPIO_0_23                   0x0173
+#define MX23_PAD_GPMI_WRN__GPIO_0_24                   0x0183
+#define MX23_PAD_GPMI_RDN__GPIO_0_25                   0x0193
+#define MX23_PAD_AUART1_CTS__GPIO_0_26                 0x01a3
+#define MX23_PAD_AUART1_RTS__GPIO_0_27                 0x01b3
+#define MX23_PAD_AUART1_RX__GPIO_0_28                  0x01c3
+#define MX23_PAD_AUART1_TX__GPIO_0_29                  0x01d3
+#define MX23_PAD_I2C_SCL__GPIO_0_30                    0x01e3
+#define MX23_PAD_I2C_SDA__GPIO_0_31                    0x01f3
+#define MX23_PAD_LCD_D00__GPIO_1_0                     0x1003
+#define MX23_PAD_LCD_D01__GPIO_1_1                     0x1013
+#define MX23_PAD_LCD_D02__GPIO_1_2                     0x1023
+#define MX23_PAD_LCD_D03__GPIO_1_3                     0x1033
+#define MX23_PAD_LCD_D04__GPIO_1_4                     0x1043
+#define MX23_PAD_LCD_D05__GPIO_1_5                     0x1053
+#define MX23_PAD_LCD_D06__GPIO_1_6                     0x1063
+#define MX23_PAD_LCD_D07__GPIO_1_7                     0x1073
+#define MX23_PAD_LCD_D08__GPIO_1_8                     0x1083
+#define MX23_PAD_LCD_D09__GPIO_1_9                     0x1093
+#define MX23_PAD_LCD_D10__GPIO_1_10                    0x10a3
+#define MX23_PAD_LCD_D11__GPIO_1_11                    0x10b3
+#define MX23_PAD_LCD_D12__GPIO_1_12                    0x10c3
+#define MX23_PAD_LCD_D13__GPIO_1_13                    0x10d3
+#define MX23_PAD_LCD_D14__GPIO_1_14                    0x10e3
+#define MX23_PAD_LCD_D15__GPIO_1_15                    0x10f3
+#define MX23_PAD_LCD_D16__GPIO_1_16                    0x1103
+#define MX23_PAD_LCD_D17__GPIO_1_17                    0x1113
+#define MX23_PAD_LCD_RESET__GPIO_1_18                  0x1123
+#define MX23_PAD_LCD_RS__GPIO_1_19                     0x1133
+#define MX23_PAD_LCD_WR__GPIO_1_20                     0x1143
+#define MX23_PAD_LCD_CS__GPIO_1_21                     0x1153
+#define MX23_PAD_LCD_DOTCK__GPIO_1_22                  0x1163
+#define MX23_PAD_LCD_ENABLE__GPIO_1_23                 0x1173
+#define MX23_PAD_LCD_HSYNC__GPIO_1_24                  0x1183
+#define MX23_PAD_LCD_VSYNC__GPIO_1_25                  0x1193
+#define MX23_PAD_PWM0__GPIO_1_26                       0x11a3
+#define MX23_PAD_PWM1__GPIO_1_27                       0x11b3
+#define MX23_PAD_PWM2__GPIO_1_28                       0x11c3
+#define MX23_PAD_PWM3__GPIO_1_29                       0x11d3
+#define MX23_PAD_PWM4__GPIO_1_30                       0x11e3
+#define MX23_PAD_SSP1_CMD__GPIO_2_0                    0x2003
+#define MX23_PAD_SSP1_DETECT__GPIO_2_1                 0x2013
+#define MX23_PAD_SSP1_DATA0__GPIO_2_2                  0x2023
+#define MX23_PAD_SSP1_DATA1__GPIO_2_3                  0x2033
+#define MX23_PAD_SSP1_DATA2__GPIO_2_4                  0x2043
+#define MX23_PAD_SSP1_DATA3__GPIO_2_5                  0x2053
+#define MX23_PAD_SSP1_SCK__GPIO_2_6                    0x2063
+#define MX23_PAD_ROTARYA__GPIO_2_7                     0x2073
+#define MX23_PAD_ROTARYB__GPIO_2_8                     0x2083
+#define MX23_PAD_EMI_A00__GPIO_2_9                     0x2093
+#define MX23_PAD_EMI_A01__GPIO_2_10                    0x20a3
+#define MX23_PAD_EMI_A02__GPIO_2_11                    0x20b3
+#define MX23_PAD_EMI_A03__GPIO_2_12                    0x20c3
+#define MX23_PAD_EMI_A04__GPIO_2_13                    0x20d3
+#define MX23_PAD_EMI_A05__GPIO_2_14                    0x20e3
+#define MX23_PAD_EMI_A06__GPIO_2_15                    0x20f3
+#define MX23_PAD_EMI_A07__GPIO_2_16                    0x2103
+#define MX23_PAD_EMI_A08__GPIO_2_17                    0x2113
+#define MX23_PAD_EMI_A09__GPIO_2_18                    0x2123
+#define MX23_PAD_EMI_A10__GPIO_2_19                    0x2133
+#define MX23_PAD_EMI_A11__GPIO_2_20                    0x2143
+#define MX23_PAD_EMI_A12__GPIO_2_21                    0x2153
+#define MX23_PAD_EMI_BA0__GPIO_2_22                    0x2163
+#define MX23_PAD_EMI_BA1__GPIO_2_23                    0x2173
+#define MX23_PAD_EMI_CASN__GPIO_2_24                   0x2183
+#define MX23_PAD_EMI_CE0N__GPIO_2_25                   0x2193
+#define MX23_PAD_EMI_CE1N__GPIO_2_26                   0x21a3
+#define MX23_PAD_GPMI_CE1N__GPIO_2_27                  0x21b3
+#define MX23_PAD_GPMI_CE0N__GPIO_2_28                  0x21c3
+#define MX23_PAD_EMI_CKE__GPIO_2_29                    0x21d3
+#define MX23_PAD_EMI_RASN__GPIO_2_30                   0x21e3
+#define MX23_PAD_EMI_WEN__GPIO_2_31                    0x21f3
+
+#endif /* __DT_BINDINGS_MX23_PINCTRL_H__ */
index 85c3864b6a56a92de2a85d52ddb35bcc1ce15c4f..cb64e2b191ea1ae48098c1c79ced4afe6f57b521 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx23.dtsi"
+#include "imx23.dtsi"
 
 / {
        model = "Freescale STMP378x Development Board";
                                hog_pins_a: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x11d3 /* MX23_PAD_PWM3__GPIO_1_29 */
-                                               0x11e3 /* MX23_PAD_PWM4__GPIO_1_30 */
+                                               MX23_PAD_PWM3__GPIO_1_29
+                                               MX23_PAD_PWM4__GPIO_1_30
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
                };
index 28b5ce289662b8c74955ecb38e023a6b773cb7b0..c96ceaef7ddf565b448f5b3ba707ff80824d3cf2 100644 (file)
@@ -9,7 +9,8 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include "imx23-pinfunc.h"
 
 / {
        interrupt-parent = <&icoll>;
                                duart_pins_a: duart@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x11a2 /* MX23_PAD_PWM0__DUART_RX */
-                                               0x11b2 /* MX23_PAD_PWM1__DUART_TX */
+                                               MX23_PAD_PWM0__DUART_RX
+                                               MX23_PAD_PWM1__DUART_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart0_pins_a: auart0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x01c0 /* MX23_PAD_AUART1_RX__AUART1_RX */
-                                               0x01d0 /* MX23_PAD_AUART1_TX__AUART1_TX */
-                                               0x01a0 /* MX23_PAD_AUART1_CTS__AUART1_CTS */
-                                               0x01b0 /* MX23_PAD_AUART1_RTS__AUART1_RTS */
+                                               MX23_PAD_AUART1_RX__AUART1_RX
+                                               MX23_PAD_AUART1_TX__AUART1_TX
+                                               MX23_PAD_AUART1_CTS__AUART1_CTS
+                                               MX23_PAD_AUART1_RTS__AUART1_RTS
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart0_2pins_a: auart0-2pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x01e2 /* MX23_PAD_I2C_SCL__AUART1_TX */
-                                               0x01f2 /* MX23_PAD_I2C_SDA__AUART1_RX */
+                                               MX23_PAD_I2C_SCL__AUART1_TX
+                                               MX23_PAD_I2C_SDA__AUART1_RX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                gpmi_pins_a: gpmi-nand@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0000 /* MX23_PAD_GPMI_D00__GPMI_D00 */
-                                               0x0010 /* MX23_PAD_GPMI_D01__GPMI_D01 */
-                                               0x0020 /* MX23_PAD_GPMI_D02__GPMI_D02 */
-                                               0x0030 /* MX23_PAD_GPMI_D03__GPMI_D03 */
-                                               0x0040 /* MX23_PAD_GPMI_D04__GPMI_D04 */
-                                               0x0050 /* MX23_PAD_GPMI_D05__GPMI_D05 */
-                                               0x0060 /* MX23_PAD_GPMI_D06__GPMI_D06 */
-                                               0x0070 /* MX23_PAD_GPMI_D07__GPMI_D07 */
-                                               0x0100 /* MX23_PAD_GPMI_CLE__GPMI_CLE */
-                                               0x0110 /* MX23_PAD_GPMI_ALE__GPMI_ALE */
-                                               0x0130 /* MX23_PAD_GPMI_RDY0__GPMI_RDY0 */
-                                               0x0140 /* MX23_PAD_GPMI_RDY1__GPMI_RDY1 */
-                                               0x0170 /* MX23_PAD_GPMI_WPN__GPMI_WPN */
-                                               0x0180 /* MX23_PAD_GPMI_WRN__GPMI_WRN */
-                                               0x0190 /* MX23_PAD_GPMI_RDN__GPMI_RDN */
-                                               0x21b0 /* MX23_PAD_GPMI_CE1N__GPMI_CE1N */
-                                               0x21c0 /* MX23_PAD_GPMI_CE0N__GPMI_CE0N */
+                                               MX23_PAD_GPMI_D00__GPMI_D00
+                                               MX23_PAD_GPMI_D01__GPMI_D01
+                                               MX23_PAD_GPMI_D02__GPMI_D02
+                                               MX23_PAD_GPMI_D03__GPMI_D03
+                                               MX23_PAD_GPMI_D04__GPMI_D04
+                                               MX23_PAD_GPMI_D05__GPMI_D05
+                                               MX23_PAD_GPMI_D06__GPMI_D06
+                                               MX23_PAD_GPMI_D07__GPMI_D07
+                                               MX23_PAD_GPMI_CLE__GPMI_CLE
+                                               MX23_PAD_GPMI_ALE__GPMI_ALE
+                                               MX23_PAD_GPMI_RDY0__GPMI_RDY0
+                                               MX23_PAD_GPMI_RDY1__GPMI_RDY1
+                                               MX23_PAD_GPMI_WPN__GPMI_WPN
+                                               MX23_PAD_GPMI_WRN__GPMI_WRN
+                                               MX23_PAD_GPMI_RDN__GPMI_RDN
+                                               MX23_PAD_GPMI_CE1N__GPMI_CE1N
+                                               MX23_PAD_GPMI_CE0N__GPMI_CE0N
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                gpmi_pins_fixup: gpmi-pins-fixup {
                                        fsl,pinmux-ids = <
-                                               0x0170 /* MX23_PAD_GPMI_WPN__GPMI_WPN */
-                                               0x0180 /* MX23_PAD_GPMI_WRN__GPMI_WRN */
-                                               0x0190 /* MX23_PAD_GPMI_RDN__GPMI_RDN */
+                                               MX23_PAD_GPMI_WPN__GPMI_WPN
+                                               MX23_PAD_GPMI_WRN__GPMI_WRN
+                                               MX23_PAD_GPMI_RDN__GPMI_RDN
                                        >;
-                                       fsl,drive-strength = <2>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
                                };
 
                                mmc0_4bit_pins_a: mmc0-4bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2020 /* MX23_PAD_SSP1_DATA0__SSP1_DATA0 */
-                                               0x2030 /* MX23_PAD_SSP1_DATA1__SSP1_DATA1 */
-                                               0x2040 /* MX23_PAD_SSP1_DATA2__SSP1_DATA2 */
-                                               0x2050 /* MX23_PAD_SSP1_DATA3__SSP1_DATA3 */
-                                               0x2000 /* MX23_PAD_SSP1_CMD__SSP1_CMD */
-                                               0x2060 /* MX23_PAD_SSP1_SCK__SSP1_SCK */
+                                               MX23_PAD_SSP1_DATA0__SSP1_DATA0
+                                               MX23_PAD_SSP1_DATA1__SSP1_DATA1
+                                               MX23_PAD_SSP1_DATA2__SSP1_DATA2
+                                               MX23_PAD_SSP1_DATA3__SSP1_DATA3
+                                               MX23_PAD_SSP1_CMD__SSP1_CMD
+                                               MX23_PAD_SSP1_SCK__SSP1_SCK
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mmc0_8bit_pins_a: mmc0-8bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2020 /* MX23_PAD_SSP1_DATA0__SSP1_DATA0 */
-                                               0x2030 /* MX23_PAD_SSP1_DATA1__SSP1_DATA1 */
-                                               0x2040 /* MX23_PAD_SSP1_DATA2__SSP1_DATA2 */
-                                               0x2050 /* MX23_PAD_SSP1_DATA3__SSP1_DATA3 */
-                                               0x0082 /* MX23_PAD_GPMI_D08__SSP1_DATA4 */
-                                               0x0092 /* MX23_PAD_GPMI_D09__SSP1_DATA5 */
-                                               0x00a2 /* MX23_PAD_GPMI_D10__SSP1_DATA6 */
-                                               0x00b2 /* MX23_PAD_GPMI_D11__SSP1_DATA7 */
-                                               0x2000 /* MX23_PAD_SSP1_CMD__SSP1_CMD */
-                                               0x2010 /* MX23_PAD_SSP1_DETECT__SSP1_DETECT */
-                                               0x2060 /* MX23_PAD_SSP1_SCK__SSP1_SCK */
+                                               MX23_PAD_SSP1_DATA0__SSP1_DATA0
+                                               MX23_PAD_SSP1_DATA1__SSP1_DATA1
+                                               MX23_PAD_SSP1_DATA2__SSP1_DATA2
+                                               MX23_PAD_SSP1_DATA3__SSP1_DATA3
+                                               MX23_PAD_GPMI_D08__SSP1_DATA4
+                                               MX23_PAD_GPMI_D09__SSP1_DATA5
+                                               MX23_PAD_GPMI_D10__SSP1_DATA6
+                                               MX23_PAD_GPMI_D11__SSP1_DATA7
+                                               MX23_PAD_SSP1_CMD__SSP1_CMD
+                                               MX23_PAD_SSP1_DETECT__SSP1_DETECT
+                                               MX23_PAD_SSP1_SCK__SSP1_SCK
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mmc0_pins_fixup: mmc0-pins-fixup {
                                        fsl,pinmux-ids = <
-                                               0x2010 /* MX23_PAD_SSP1_DETECT__SSP1_DETECT */
-                                               0x2060 /* MX23_PAD_SSP1_SCK__SSP1_SCK */
+                                               MX23_PAD_SSP1_DETECT__SSP1_DETECT
+                                               MX23_PAD_SSP1_SCK__SSP1_SCK
                                        >;
-                                       fsl,pull-up = <0>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                pwm2_pins_a: pwm2@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x11c0 /* MX23_PAD_PWM2__PWM2 */
+                                               MX23_PAD_PWM2__PWM2
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_24bit_pins_a: lcdif-24bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1000 /* MX23_PAD_LCD_D00__LCD_D0 */
-                                               0x1010 /* MX23_PAD_LCD_D01__LCD_D1 */
-                                               0x1020 /* MX23_PAD_LCD_D02__LCD_D2 */
-                                               0x1030 /* MX23_PAD_LCD_D03__LCD_D3 */
-                                               0x1040 /* MX23_PAD_LCD_D04__LCD_D4 */
-                                               0x1050 /* MX23_PAD_LCD_D05__LCD_D5 */
-                                               0x1060 /* MX23_PAD_LCD_D06__LCD_D6 */
-                                               0x1070 /* MX23_PAD_LCD_D07__LCD_D7 */
-                                               0x1080 /* MX23_PAD_LCD_D08__LCD_D8 */
-                                               0x1090 /* MX23_PAD_LCD_D09__LCD_D9 */
-                                               0x10a0 /* MX23_PAD_LCD_D10__LCD_D10 */
-                                               0x10b0 /* MX23_PAD_LCD_D11__LCD_D11 */
-                                               0x10c0 /* MX23_PAD_LCD_D12__LCD_D12 */
-                                               0x10d0 /* MX23_PAD_LCD_D13__LCD_D13 */
-                                               0x10e0 /* MX23_PAD_LCD_D14__LCD_D14 */
-                                               0x10f0 /* MX23_PAD_LCD_D15__LCD_D15 */
-                                               0x1100 /* MX23_PAD_LCD_D16__LCD_D16 */
-                                               0x1110 /* MX23_PAD_LCD_D17__LCD_D17 */
-                                               0x0081 /* MX23_PAD_GPMI_D08__LCD_D18 */
-                                               0x0091 /* MX23_PAD_GPMI_D09__LCD_D19 */
-                                               0x00a1 /* MX23_PAD_GPMI_D10__LCD_D20 */
-                                               0x00b1 /* MX23_PAD_GPMI_D11__LCD_D21 */
-                                               0x00c1 /* MX23_PAD_GPMI_D12__LCD_D22 */
-                                               0x00d1 /* MX23_PAD_GPMI_D13__LCD_D23 */
-                                               0x1160 /* MX23_PAD_LCD_DOTCK__LCD_DOTCK */
-                                               0x1170 /* MX23_PAD_LCD_ENABLE__LCD_ENABLE */
-                                               0x1180 /* MX23_PAD_LCD_HSYNC__LCD_HSYNC */
-                                               0x1190 /* MX23_PAD_LCD_VSYNC__LCD_VSYNC */
+                                               MX23_PAD_LCD_D00__LCD_D00
+                                               MX23_PAD_LCD_D01__LCD_D01
+                                               MX23_PAD_LCD_D02__LCD_D02
+                                               MX23_PAD_LCD_D03__LCD_D03
+                                               MX23_PAD_LCD_D04__LCD_D04
+                                               MX23_PAD_LCD_D05__LCD_D05
+                                               MX23_PAD_LCD_D06__LCD_D06
+                                               MX23_PAD_LCD_D07__LCD_D07
+                                               MX23_PAD_LCD_D08__LCD_D08
+                                               MX23_PAD_LCD_D09__LCD_D09
+                                               MX23_PAD_LCD_D10__LCD_D10
+                                               MX23_PAD_LCD_D11__LCD_D11
+                                               MX23_PAD_LCD_D12__LCD_D12
+                                               MX23_PAD_LCD_D13__LCD_D13
+                                               MX23_PAD_LCD_D14__LCD_D14
+                                               MX23_PAD_LCD_D15__LCD_D15
+                                               MX23_PAD_LCD_D16__LCD_D16
+                                               MX23_PAD_LCD_D17__LCD_D17
+                                               MX23_PAD_GPMI_D08__LCD_D18
+                                               MX23_PAD_GPMI_D09__LCD_D19
+                                               MX23_PAD_GPMI_D10__LCD_D20
+                                               MX23_PAD_GPMI_D11__LCD_D21
+                                               MX23_PAD_GPMI_D12__LCD_D22
+                                               MX23_PAD_GPMI_D13__LCD_D23
+                                               MX23_PAD_LCD_DOTCK__LCD_DOTCK
+                                               MX23_PAD_LCD_ENABLE__LCD_ENABLE
+                                               MX23_PAD_LCD_HSYNC__LCD_HSYNC
+                                               MX23_PAD_LCD_VSYNC__LCD_VSYNC
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                spi2_pins_a: spi2@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0182 /* MX23_PAD_GPMI_WRN__SSP2_SCK */
-                                               0x0142 /* MX23_PAD_GPMI_RDY1__SSP2_CMD */
-                                               0x0002 /* MX23_PAD_GPMI_D00__SSP2_DATA0 */
-                                               0x0032 /* MX23_PAD_GPMI_D03__SSP2_DATA3 */
+                                               MX23_PAD_GPMI_WRN__SSP2_SCK
+                                               MX23_PAD_GPMI_RDY1__SSP2_CMD
+                                               MX23_PAD_GPMI_D00__SSP2_DATA0
+                                               MX23_PAD_GPMI_D03__SSP2_DATA3
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
                        };
 
                                reg = <0x80050000 0x2000>;
                                interrupts = <36 37 38 39 40 41 42 43 44>;
                                status = "disabled";
+                               clocks = <&clks 26>;
                        };
 
                        spdif@80054000 {
index 2a377ca1881a9a40004a951a1a8310a02d434727..47c8c26012e4d24661124f15ff8396f428136797 100644 (file)
        model = "Armadeus Systems APF27Dev docking/development board";
        compatible = "armadeus,imx27-apf27dev", "armadeus,imx27-apf27", "fsl,imx27";
 
+       display: display {
+               model = "Chimei-LW700AT9003";
+               native-mode = <&timing0>;
+               bits-per-pixel = <16>;  /* non-standard but required */
+               fsl,pcr = <0xfae80083>; /* non-standard but required */
+               display-timings {
+                       timing0: 640x480 {
+                               clock-frequency = <33000033>;
+                               hactive = <800>;
+                               vactive = <640>;
+                               hback-porch = <96>;
+                               hfront-porch = <96>;
+                               vback-porch = <20>;
+                               vfront-porch = <21>;
+                               hsync-len = <64>;
+                               vsync-len = <4>;
+                       };
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
        status = "okay";
 };
 
+&fb {
+       display = <&display>;
+       fsl,dmacr = <0x00020010>;
+       status = "okay";
+};
+
 &i2c1 {
        clock-frequency = <400000>;
        status = "okay";
index b7a1c6d950b984b44efd65c100c05024c80c1b4a..826231eb44466f9187a564b3a587c7b18d686b28 100644 (file)
                        };
 
                        pwm: pwm@10006000 {
+                               #pwm-cells = <2>;
                                compatible = "fsl,imx27-pwm";
                                reg = <0x10006000 0x1000>;
                                interrupts = <23>;
index 7eb075876c4ca0358b661f8fe045052c5cead5ac..7198fe3798c62b52c2c86f5d2f895cc5179571fe 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
 
 / {
        model = "Armadeus Systems APF28 module";
index b602494c152b3a82a89c544adffb761cf2a64820..e2efd8d89c4fb82bca3602274380c7a81a515518 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* APF28Dev is a docking board for the APF28 SOM */
-/include/ "imx28-apf28.dts"
+#include "imx28-apf28.dts"
 
 / {
        model = "Armadeus Systems APF28Dev docking/development board";
                                hog_pins_apf28dev: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1103 /* MX28_PAD_LCD_D16__GPIO_1_16 */
-                                               0x1113 /* MX28_PAD_LCD_D17__GPIO_1_17 */
-                                               0x1123 /* MX28_PAD_LCD_D18__GPIO_1_18 */
-                                               0x1133 /* MX28_PAD_LCD_D19__GPIO_1_19 */
-                                               0x1143 /* MX28_PAD_LCD_D20__GPIO_1_20 */
-                                               0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */
-                                               0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
+                                               MX28_PAD_LCD_D16__GPIO_1_16
+                                               MX28_PAD_LCD_D17__GPIO_1_17
+                                               MX28_PAD_LCD_D18__GPIO_1_18
+                                               MX28_PAD_LCD_D19__GPIO_1_19
+                                               MX28_PAD_LCD_D20__GPIO_1_20
+                                               MX28_PAD_LCD_D21__GPIO_1_21
+                                               MX28_PAD_LCD_D22__GPIO_1_22
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_apf28dev: lcdif-apf28dev@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
index 0e7fed47bd8d2941292ce8b7411036cf46883f44..6f254ca816cbd42b3ff80d61c3bfdb86c6f8438d 100644 (file)
@@ -1,5 +1,5 @@
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
 
 / {
        model = "Bluegiga APX4 Development Kit";
                                hog_pins_a: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0113 /* MX28_PAD_GPMI_CE1N__GPIO_0_17 */
-                                               0x0153 /* MX28_PAD_GPMI_RDY1__GPIO_0_21 */
-                                               0x2123 /* MX28_PAD_SSP2_MISO__GPIO_2_18 */
-                                               0x2131 /* MX28_PAD_SSP2_SS0__GPIO_2_19 */
-                                               0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */
-                                               0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
-                                               0x4143 /* MX28_PAD_JTAG_RTCK__GPIO_4_20 */
+                                               MX28_PAD_GPMI_CE1N__GPIO_0_17
+                                               MX28_PAD_GPMI_RDY1__GPIO_0_21
+                                               MX28_PAD_SSP2_MISO__GPIO_2_18
+                                               MX28_PAD_SSP2_SS0__AUART3_TX /* was: 0x2131 - MX28_PAD_SSP2_SS0__GPIO_2_19 */
+                                               MX28_PAD_PWM3__GPIO_3_28
+                                               MX28_PAD_LCD_RESET__GPIO_3_30
+                                               MX28_PAD_JTAG_RTCK__GPIO_4_20
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_apx4: lcdif-apx4@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                mmc2_4bit_pins_apx4: mmc2-4bit-apx4@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2041 /* MX28_PAD_SSP0_DATA4__SSP2_D0 */
-                                               0x2051 /* MX28_PAD_SSP0_DATA5__SSP2_D3 */
-                                               0x2061 /* MX28_PAD_SSP0_DATA6__SSP2_CMD */
-                                               0x2071 /* MX28_PAD_SSP0_DATA7__SSP2_SCK */
-                                               0x2141 /* MX28_PAD_SSP2_SS1__SSP2_D1 */
-                                               0x2151 /* MX28_PAD_SSP2_SS2__SSP2_D2 */
+                                               MX28_PAD_SSP0_DATA4__SSP2_D0
+                                               MX28_PAD_SSP0_DATA5__SSP2_D3
+                                               MX28_PAD_SSP0_DATA6__SSP2_CMD
+                                               MX28_PAD_SSP0_DATA7__SSP2_SCK
+                                               MX28_PAD_SSP2_SS1__SSP2_D1
+                                               MX28_PAD_SSP2_SS2__SSP2_D2
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mmc2_sck_cfg_apx4: mmc2-sck-cfg-apx4 {
                                        fsl,pinmux-ids = <
-                                               0x2071 /* MX28_PAD_SSP0_DATA7__SSP2_SCK */
+                                               MX28_PAD_SSP0_DATA7__SSP2_SCK
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
index 1ec8c94bbac97f82f48fad9a868b70a66a438030..cabb6171a19d925c214442daa47473a6a2be31a5 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
 
 / {
        model = "Crystalfontz CFA-10036 Board";
                                ssd1306_cfa10036: ssd1306-10036@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2073 /* MX28_PAD_SSP0_D7__GPIO_2_7 */
+                                               MX28_PAD_SSP0_DATA7__GPIO_2_7
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                led_pins_cfa10036: leds-10036@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3043 /* MX28_PAD_AUART1_RX__GPIO_3_4 */
+                                               MX28_PAD_AUART1_RX__GPIO_3_4
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                usb0_otg_cfa10036: otg-10036@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0142 /* MX28_PAD_GPMI_READY0__USB0_ID */
+                                               MX28_PAD_GPMI_RDY0__USB0_ID
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                        };
index 182b99fe35f39b77b0c43cb396593624a043f7ba..f93e9a700e52b39287ff6761cf9c2ffdc21ea617 100644 (file)
@@ -13,7 +13,7 @@
  * The CFA-10049 is an expansion board for the CFA-10036 module, thus we
  * need to include the CFA-10036 DTS.
  */
-/include/ "imx28-cfa10036.dts"
+#include "imx28-cfa10036.dts"
 
 / {
        model = "Crystalfontz CFA-10037 Board";
                                usb_pins_cfa10037: usb-10037@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
+                                               MX28_PAD_GPMI_D07__GPIO_0_7
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                mac0_pins_cfa10037: mac0-10037@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */
+                                               MX28_PAD_SSP2_SS2__GPIO_2_21
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
                };
index 06e4cfaf7dd2678b71ba7d523891c2008e31eff5..7087b4bf6a8f88e5748a70747af337de3524a5c0 100644 (file)
@@ -13,7 +13,7 @@
  * The CFA-10049 is an expansion board for the CFA-10036 module, thus we
  * need to include the CFA-10036 DTS.
  */
-/include/ "imx28-cfa10036.dts"
+#include "imx28-cfa10036.dts"
 
 / {
        model = "Crystalfontz CFA-10049 Board";
                                usb_pins_cfa10049: usb-10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
+                                               MX28_PAD_GPMI_D07__GPIO_0_7
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                i2cmux_pins_cfa10049: i2cmux-10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
-                                               0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */
+                                               MX28_PAD_LCD_D22__GPIO_1_22
+                                               MX28_PAD_LCD_D23__GPIO_1_23
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                mac0_pins_cfa10049: mac0-10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */
+                                               MX28_PAD_SSP2_SS2__GPIO_2_21
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                pca_pins_cfa10049: pca-10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2133 /* MX28_PAD_SSP2_D3__GPIO_2_19 */
+                                               MX28_PAD_SSP2_SS0__GPIO_2_19
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                rotary_pins_cfa10049: rotary-10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3183 /* MX28_PAD_I2C0_SCL__GPIO_3_24 */
-                                               0x3193 /* MX28_PAD_I2C0_SDA__GPIO_3_25 */
+                                               MX28_PAD_I2C0_SCL__GPIO_3_24
+                                               MX28_PAD_I2C0_SDA__GPIO_3_25
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                rotary_btn_pins_cfa10049: rotary-btn-10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31a3 /* MX28_PAD_SAIF_SDATA0__GPIO_3_26 */
+                                               MX28_PAD_SAIF1_SDATA0__GPIO_3_26
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                spi2_pins_cfa10049: spi2-cfa10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */
-                                               0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */
-                                               0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */
-                                               0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+                                               MX28_PAD_SSP2_SCK__GPIO_2_16
+                                               MX28_PAD_SSP2_MOSI__GPIO_2_17
+                                               MX28_PAD_SSP2_MISO__GPIO_2_18
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                spi3_pins_cfa10049: spi3-cfa10049@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0183 /* MX28_PAD_GPMI_RDN__GPIO_0_24 */
-                                               0x01c3 /* MX28_PAD_GPMI_RESETN__GPIO_0_28 */
-                                               0x0113 /* MX28_PAD_GPMI_CE1N__GPIO_0_17 */
-                                               0x01a3 /* MX28_PAD_GPMI_ALE__GPIO_0_26 */
-                                               0x01b3 /* MX28_PAD_GPMI_CLE__GPIO_0_27 */
+                                               MX28_PAD_GPMI_RDN__GPIO_0_24
+                                               MX28_PAD_GPMI_RESETN__GPIO_0_28
+                                               MX28_PAD_GPMI_CE1N__GPIO_0_17
+                                               MX28_PAD_GPMI_ALE__GPIO_0_26
+                                               MX28_PAD_GPMI_CLE__GPIO_0_27
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                lcdif_18bit_pins_cfa10049: lcdif-18bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
-                                               0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
-                                               0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
-                                               0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
-                                               0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
-                                               0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
-                                               0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
-                                               0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
-                                               0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
-                                               0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
-                                               0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
-                                               0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
-                                               0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
-                                               0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
-                                               0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
-                                               0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
-                                               0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
-                                               0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10049: lcdif-evk@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10049_pullup: lcdif-10049-pullup@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
+                                               MX28_PAD_LCD_RESET__GPIO_3_30
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                w1_gpio_pins: w1-gpio@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */
+                                               MX28_PAD_LCD_D21__GPIO_1_21
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>; /* 0 will enable the keeper */
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>; /* 0 will enable the keeper */
                                };
                        };
 
index 171bcbe1ec4b3ed995f7895a5b6a51868460b48c..c3900e7ba3318e3d8f191b49edc35597824ae91d 100644 (file)
@@ -14,7 +14,7 @@
  * The CFA-10055 is an expansion board for the CFA-10036 module and
  * CFA-10037, thus we need to include the CFA-10037 DTS.
  */
-/include/ "imx28-cfa10037.dts"
+#include "imx28-cfa10037.dts"
 
 / {
        model = "Crystalfontz CFA-10055 Board";
                                spi2_pins_cfa10055: spi2-cfa10055@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */
-                                               0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */
-                                               0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */
-                                               0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+                                               MX28_PAD_SSP2_SCK__GPIO_2_16
+                                               MX28_PAD_SSP2_MOSI__GPIO_2_17
+                                               MX28_PAD_SSP2_MISO__GPIO_2_18
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                lcdif_18bit_pins_cfa10055: lcdif-18bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
-                                               0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
-                                               0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
-                                               0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
-                                               0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
-                                               0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
-                                               0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
-                                               0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
-                                               0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
-                                               0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
-                                               0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
-                                               0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
-                                               0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
-                                               0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
-                                               0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
-                                               0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
-                                               0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
-                                               0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10055: lcdif-evk@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10055_pullup: lcdif-10055-pullup@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
+                                               MX28_PAD_LCD_RESET__GPIO_3_30
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
                        };
 
index b45dd0e4ee57931d9cecd7dfe567408c64d65b1b..cef959a97219b8e14bca15b01c96d6e93cf1730a 100644 (file)
@@ -13,7 +13,7 @@
  * The CFA-10055 is an expansion board for the CFA-10036 module and
  * CFA-10037, thus we need to include the CFA-10037 DTS.
  */
-/include/ "imx28-cfa10037.dts"
+#include "imx28-cfa10037.dts"
 
 / {
        model = "Crystalfontz CFA-10056 Board";
                                spi2_pins_cfa10056: spi2-cfa10056@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */
-                                               0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */
-                                               0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */
-                                               0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+                                               MX28_PAD_SSP2_SCK__GPIO_2_16
+                                               MX28_PAD_SSP2_MOSI__GPIO_2_17
+                                               MX28_PAD_SSP2_MISO__GPIO_2_18
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                lcdif_pins_cfa10056: lcdif-10056@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10056_pullup: lcdif-10056-pullup@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
+                                               MX28_PAD_LCD_RESET__GPIO_3_30
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
                        };
 
index 0333c0532f28f3ff5e4e011036214b31393c29df..3c1312885ae0dafc1642e30d27a58cc3cf49d12b 100644 (file)
@@ -14,7 +14,7 @@
  * The CFA-10057 is an expansion board for the CFA-10036 module, thus we
  * need to include the CFA-10036 DTS.
  */
-/include/ "imx28-cfa10036.dts"
+#include "imx28-cfa10036.dts"
 
 / {
        model = "Crystalfontz CFA-10057 Board";
                                usb_pins_cfa10057: usb-10057@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
+                                               MX28_PAD_GPMI_D07__GPIO_0_7
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_18bit_pins_cfa10057: lcdif-18bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
-                                               0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
-                                               0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
-                                               0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
-                                               0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
-                                               0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
-                                               0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
-                                               0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
-                                               0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
-                                               0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
-                                               0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
-                                               0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
-                                               0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
-                                               0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
-                                               0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
-                                               0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
-                                               0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
-                                               0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10057: lcdif-evk@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
index 64c64c55a82a27cbb2221a9ac7f6390a173426e7..2469d34df0ae1499de3236f13e180969dd78eed7 100644 (file)
@@ -14,7 +14,7 @@
  * The CFA-10058 is an expansion board for the CFA-10036 module, thus we
  * need to include the CFA-10036 DTS.
  */
-/include/ "imx28-cfa10036.dts"
+#include "imx28-cfa10036.dts"
 
 / {
        model = "Crystalfontz CFA-10058 Board";
                                usb_pins_cfa10058: usb-10058@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
+                                               MX28_PAD_GPMI_D07__GPIO_0_7
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_cfa10058: lcdif-10058@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
index 15715d921d14417a5f0e1e8fe76047410239aaa9..4267c2b05d600ac8bfb9cf2612a3b72977d7dc0e 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
 
 / {
        model = "Freescale i.MX28 Evaluation Kit";
                                hog_pins_a: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x20d3 /* MX28_PAD_SSP1_CMD__GPIO_2_13 */
-                                               0x20f3 /* MX28_PAD_SSP1_DATA3__GPIO_2_15 */
-                                               0x40d3 /* MX28_PAD_ENET0_RX_CLK__GPIO_4_13 */
-                                               0x20c3 /* MX28_PAD_SSP1_SCK__GPIO_2_12 */
-                                               0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */
-                                               0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
-                                               0x3083 /* MX28_PAD_AUART2_RX__GPIO_3_8 */
-                                               0x3093 /* MX28_PAD_AUART2_TX__GPIO_3_9 */
+                                               MX28_PAD_SSP1_CMD__GPIO_2_13
+                                               MX28_PAD_SSP1_DATA3__GPIO_2_15
+                                               MX28_PAD_ENET0_RX_CLK__GPIO_4_13
+                                               MX28_PAD_SSP1_SCK__GPIO_2_12
+                                               MX28_PAD_PWM3__GPIO_3_28
+                                               MX28_PAD_LCD_RESET__GPIO_3_30
+                                               MX28_PAD_AUART2_RX__GPIO_3_8
+                                               MX28_PAD_AUART2_TX__GPIO_3_9
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                led_pin_gpio3_5: led_gpio3_5@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                gpmi_pins_evk: gpmi-nand-evk@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0110 /* MX28_PAD_GPMI_CE1N__GPMI_CE1N */
-                                               0x0150 /* MX28_PAD_GPMI_RDY1__GPMI_READY1 */
+                                               MX28_PAD_GPMI_CE1N__GPMI_CE1N
+                                               MX28_PAD_GPMI_RDY1__GPMI_READY1
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_evk: lcdif-evk@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
                        };
 
                        lradc@80050000 {
+                               fsl,lradc-touchscreen-wires = <4>;
                                status = "okay";
+                               fsl,lradc-touchscreen-wires = <4>;
+                               fsl,ave-ctrl = <4>;
+                               fsl,ave-delay = <2>;
+                               fsl,settling = <10>;
                        };
 
                        i2c0: i2c@80058000 {
 
        ahb@80080000 {
                usb0: usb@80080000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb0_id_pins_a>;
                        vbus-supply = <&reg_usb0_vbus>;
                        status = "okay";
                };
diff --git a/arch/arm/boot/dts/imx28-m28cu3.dts b/arch/arm/boot/dts/imx28-m28cu3.dts
new file mode 100644 (file)
index 0000000..d3958da
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2013 Marek Vasut <marex@denx.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 = "MSR M28CU3";
+       compatible = "msr,m28cu3", "fsl,imx28";
+
+       memory {
+               reg = <0x40000000 0x08000000>;
+       };
+
+       apb@80000000 {
+               apbh@80000000 {
+                       gpmi-nand@8000c000 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+                               status = "okay";
+
+                               partition@0 {
+                                       label = "gpmi-nfc-0-boot";
+                                       reg = <0x00000000 0x01400000>;
+                                       read-only;
+                               };
+
+                               partition@1 {
+                                       label = "gpmi-nfc-general-use";
+                                       reg = <0x01400000 0x0ec00000>;
+                               };
+                       };
+
+                       ssp0: ssp@80010000 {
+                               compatible = "fsl,imx28-mmc";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&mmc0_4bit_pins_a
+                                            &mmc0_cd_cfg
+                                            &mmc0_sck_cfg>;
+                               bus-width = <4>;
+                               vmmc-supply = <&reg_vddio_sd0>;
+                               status = "okay";
+                       };
+
+                       ssp2: ssp@80014000 {
+                               compatible = "fsl,imx28-mmc";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&mmc2_4bit_pins_a
+                                            &mmc2_cd_cfg
+                                            &mmc2_sck_cfg>;
+                               bus-width = <4>;
+                               vmmc-supply = <&reg_vddio_sd1>;
+                               status = "okay";
+                       };
+
+                       pinctrl@80018000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&hog_pins_a>;
+
+                               hog_pins_a: hog@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP2_SS0__GPIO_2_19
+                                               MX28_PAD_PWM4__GPIO_3_29
+                                               MX28_PAD_AUART2_RX__GPIO_3_8
+                                               MX28_PAD_ENET0_RX_CLK__GPIO_4_13
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               lcdif_pins_m28: lcdif-m28@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_VSYNC__LCD_VSYNC
+                                               MX28_PAD_LCD_HSYNC__LCD_HSYNC
+                                               MX28_PAD_LCD_DOTCLK__LCD_DOTCLK
+                                               MX28_PAD_LCD_RESET__LCD_RESET
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               led_pins_gpio: leds-m28@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP3_MISO__GPIO_2_26
+                                               MX28_PAD_SSP3_SCK__GPIO_2_24
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+                       };
+
+                       ocotp@8002c000 {
+                               status = "okay";
+                       };
+
+                       lcdif@80030000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&lcdif_24bit_pins_a
+                                            &lcdif_pins_m28>;
+                               display = <&display>;
+                               reset-active-high;
+                               status = "okay";
+
+                               display: display0 {
+                                       bits-per-pixel = <32>;
+                                       bus-width = <24>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <6410256>;
+                                                       hactive = <320>;
+                                                       vactive = <240>;
+                                                       hback-porch = <38>;
+                                                       hfront-porch = <20>;
+                                                       vback-porch = <15>;
+                                                       vfront-porch = <5>;
+                                                       hsync-len = <30>;
+                                                       vsync-len = <3>;
+                                                       hsync-active = <0>;
+                                                       vsync-active = <0>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <1>;
+                                               };
+                                       };
+                               };
+                       };
+               };
+
+               apbx@80040000 {
+                       duart: serial@80074000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&duart_pins_b>;
+                               status = "okay";
+                       };
+
+                       usbphy1: usbphy@8007e000 {
+                               status = "okay";
+                       };
+
+                       auart0: serial@8006a000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&auart0_2pins_a>;
+                               status = "okay";
+                       };
+
+                       auart3: serial@80070000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&auart3_2pins_b>;
+                               status = "okay";
+                       };
+
+                       pwm: pwm@80064000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pwm3_pins_a>;
+                               status = "okay";
+                       };
+               };
+       };
+
+       ahb@80080000 {
+               usb1: usb@80090000 {
+                       vbus-supply = <&reg_usb1_vbus>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usbphy1_pins_a>;
+                       disable-over-current;
+                       status = "okay";
+               };
+
+               mac0: ethernet@800f0000 {
+                       phy-mode = "rmii";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mac0_pins_a>;
+                       phy-reset-gpios = <&gpio4 13 0>;
+                       phy-reset-duration = <100>;
+                       status = "okay";
+               };
+
+               mac1: ethernet@800f4000 {
+                       phy-mode = "rmii";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mac1_pins_a>;
+                       status = "okay";
+               };
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 3 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_gpio>;
+
+               user1 {
+                       label = "sd0-led";
+                       gpios = <&gpio2 26 0>;
+                       linux,default-trigger = "mmc0";
+               };
+
+               user2 {
+                       label = "sd1-led";
+                       gpios = <&gpio2 24 0>;
+                       linux,default-trigger = "mmc2";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_vddio_sd0: vddio-sd0 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "vddio-sd0";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 29 0>;
+               };
+
+               reg_vddio_sd1: vddio-sd1 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "vddio-sd1";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio2 19 0>;
+               };
+
+               reg_usb1_vbus: usb1_vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usb1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 8 0>;
+                       enable-active-high;
+               };
+       };
+};
index 0d322a2bebaf5fe31e088d8b98c73f08ed4b9d7d..8e2477fbe1d70963d583973ed4c46a6554c99104 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
 
 / {
        model = "DENX M28EVK";
                                hog_pins_a: hog@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */
-                                               0x30a3 /* MX28_PAD_AUART2_CTS__GPIO_3_10 */
-                                               0x30b3 /* MX28_PAD_AUART2_RTS__GPIO_3_11 */
-                                               0x30c3 /* MX28_PAD_AUART3_RX__GPIO_3_12 */
-                                               0x30d3 /* MX28_PAD_AUART3_TX__GPIO_3_13 */
+                                               MX28_PAD_PWM3__GPIO_3_28
+                                               MX28_PAD_AUART2_CTS__GPIO_3_10
+                                               MX28_PAD_AUART2_RTS__GPIO_3_11
+                                               MX28_PAD_AUART3_RX__GPIO_3_12
+                                               MX28_PAD_AUART3_TX__GPIO_3_13
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_pins_m28: lcdif-m28@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x11e0 /* MX28_PAD_LCD_DOTCLK__LCD_DOTCLK */
-                                               0x11f0 /* MX28_PAD_LCD_ENABLE__LCD_ENABLE */
+                                               MX28_PAD_LCD_DOTCLK__LCD_DOTCLK
+                                               MX28_PAD_LCD_ENABLE__LCD_ENABLE
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
                        };
 
diff --git a/arch/arm/boot/dts/imx28-pinfunc.h b/arch/arm/boot/dts/imx28-pinfunc.h
new file mode 100644 (file)
index 0000000..e11f69b
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MX28_PINCTRL_H__
+#define __DT_BINDINGS_MX28_PINCTRL_H__
+
+#include "mxs-pinfunc.h"
+
+#define MX28_PAD_GPMI_D00__GPMI_D0                     0x0000
+#define MX28_PAD_GPMI_D01__GPMI_D1                     0x0010
+#define MX28_PAD_GPMI_D02__GPMI_D2                     0x0020
+#define MX28_PAD_GPMI_D03__GPMI_D3                     0x0030
+#define MX28_PAD_GPMI_D04__GPMI_D4                     0x0040
+#define MX28_PAD_GPMI_D05__GPMI_D5                     0x0050
+#define MX28_PAD_GPMI_D06__GPMI_D6                     0x0060
+#define MX28_PAD_GPMI_D07__GPMI_D7                     0x0070
+#define MX28_PAD_GPMI_CE0N__GPMI_CE0N                  0x0100
+#define MX28_PAD_GPMI_CE1N__GPMI_CE1N                  0x0110
+#define MX28_PAD_GPMI_CE2N__GPMI_CE2N                  0x0120
+#define MX28_PAD_GPMI_CE3N__GPMI_CE3N                  0x0130
+#define MX28_PAD_GPMI_RDY0__GPMI_READY0                        0x0140
+#define MX28_PAD_GPMI_RDY1__GPMI_READY1                        0x0150
+#define MX28_PAD_GPMI_RDY2__GPMI_READY2                        0x0160
+#define MX28_PAD_GPMI_RDY3__GPMI_READY3                        0x0170
+#define MX28_PAD_GPMI_RDN__GPMI_RDN                    0x0180
+#define MX28_PAD_GPMI_WRN__GPMI_WRN                    0x0190
+#define MX28_PAD_GPMI_ALE__GPMI_ALE                    0x01a0
+#define MX28_PAD_GPMI_CLE__GPMI_CLE                    0x01b0
+#define MX28_PAD_GPMI_RESETN__GPMI_RESETN              0x01c0
+#define MX28_PAD_LCD_D00__LCD_D0                       0x1000
+#define MX28_PAD_LCD_D01__LCD_D1                       0x1010
+#define MX28_PAD_LCD_D02__LCD_D2                       0x1020
+#define MX28_PAD_LCD_D03__LCD_D3                       0x1030
+#define MX28_PAD_LCD_D04__LCD_D4                       0x1040
+#define MX28_PAD_LCD_D05__LCD_D5                       0x1050
+#define MX28_PAD_LCD_D06__LCD_D6                       0x1060
+#define MX28_PAD_LCD_D07__LCD_D7                       0x1070
+#define MX28_PAD_LCD_D08__LCD_D8                       0x1080
+#define MX28_PAD_LCD_D09__LCD_D9                       0x1090
+#define MX28_PAD_LCD_D10__LCD_D10                      0x10a0
+#define MX28_PAD_LCD_D11__LCD_D11                      0x10b0
+#define MX28_PAD_LCD_D12__LCD_D12                      0x10c0
+#define MX28_PAD_LCD_D13__LCD_D13                      0x10d0
+#define MX28_PAD_LCD_D14__LCD_D14                      0x10e0
+#define MX28_PAD_LCD_D15__LCD_D15                      0x10f0
+#define MX28_PAD_LCD_D16__LCD_D16                      0x1100
+#define MX28_PAD_LCD_D17__LCD_D17                      0x1110
+#define MX28_PAD_LCD_D18__LCD_D18                      0x1120
+#define MX28_PAD_LCD_D19__LCD_D19                      0x1130
+#define MX28_PAD_LCD_D20__LCD_D20                      0x1140
+#define MX28_PAD_LCD_D21__LCD_D21                      0x1150
+#define MX28_PAD_LCD_D22__LCD_D22                      0x1160
+#define MX28_PAD_LCD_D23__LCD_D23                      0x1170
+#define MX28_PAD_LCD_RD_E__LCD_RD_E                    0x1180
+#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN                        0x1190
+#define MX28_PAD_LCD_RS__LCD_RS                                0x11a0
+#define MX28_PAD_LCD_CS__LCD_CS                                0x11b0
+#define MX28_PAD_LCD_VSYNC__LCD_VSYNC                  0x11c0
+#define MX28_PAD_LCD_HSYNC__LCD_HSYNC                  0x11d0
+#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK                        0x11e0
+#define MX28_PAD_LCD_ENABLE__LCD_ENABLE                        0x11f0
+#define MX28_PAD_SSP0_DATA0__SSP0_D0                   0x2000
+#define MX28_PAD_SSP0_DATA1__SSP0_D1                   0x2010
+#define MX28_PAD_SSP0_DATA2__SSP0_D2                   0x2020
+#define MX28_PAD_SSP0_DATA3__SSP0_D3                   0x2030
+#define MX28_PAD_SSP0_DATA4__SSP0_D4                   0x2040
+#define MX28_PAD_SSP0_DATA5__SSP0_D5                   0x2050
+#define MX28_PAD_SSP0_DATA6__SSP0_D6                   0x2060
+#define MX28_PAD_SSP0_DATA7__SSP0_D7                   0x2070
+#define MX28_PAD_SSP0_CMD__SSP0_CMD                    0x2080
+#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT         0x2090
+#define MX28_PAD_SSP0_SCK__SSP0_SCK                    0x20a0
+#define MX28_PAD_SSP1_SCK__SSP1_SCK                    0x20c0
+#define MX28_PAD_SSP1_CMD__SSP1_CMD                    0x20d0
+#define MX28_PAD_SSP1_DATA0__SSP1_D0                   0x20e0
+#define MX28_PAD_SSP1_DATA3__SSP1_D3                   0x20f0
+#define MX28_PAD_SSP2_SCK__SSP2_SCK                    0x2100
+#define MX28_PAD_SSP2_MOSI__SSP2_CMD                   0x2110
+#define MX28_PAD_SSP2_MISO__SSP2_D0                    0x2120
+#define MX28_PAD_SSP2_SS0__SSP2_D3                     0x2130
+#define MX28_PAD_SSP2_SS1__SSP2_D4                     0x2140
+#define MX28_PAD_SSP2_SS2__SSP2_D5                     0x2150
+#define MX28_PAD_SSP3_SCK__SSP3_SCK                    0x2180
+#define MX28_PAD_SSP3_MOSI__SSP3_CMD                   0x2190
+#define MX28_PAD_SSP3_MISO__SSP3_D0                    0x21a0
+#define MX28_PAD_SSP3_SS0__SSP3_D3                     0x21b0
+#define MX28_PAD_AUART0_RX__AUART0_RX                  0x3000
+#define MX28_PAD_AUART0_TX__AUART0_TX                  0x3010
+#define MX28_PAD_AUART0_CTS__AUART0_CTS                        0x3020
+#define MX28_PAD_AUART0_RTS__AUART0_RTS                        0x3030
+#define MX28_PAD_AUART1_RX__AUART1_RX                  0x3040
+#define MX28_PAD_AUART1_TX__AUART1_TX                  0x3050
+#define MX28_PAD_AUART1_CTS__AUART1_CTS                        0x3060
+#define MX28_PAD_AUART1_RTS__AUART1_RTS                        0x3070
+#define MX28_PAD_AUART2_RX__AUART2_RX                  0x3080
+#define MX28_PAD_AUART2_TX__AUART2_TX                  0x3090
+#define MX28_PAD_AUART2_CTS__AUART2_CTS                        0x30a0
+#define MX28_PAD_AUART2_RTS__AUART2_RTS                        0x30b0
+#define MX28_PAD_AUART3_RX__AUART3_RX                  0x30c0
+#define MX28_PAD_AUART3_TX__AUART3_TX                  0x30d0
+#define MX28_PAD_AUART3_CTS__AUART3_CTS                        0x30e0
+#define MX28_PAD_AUART3_RTS__AUART3_RTS                        0x30f0
+#define MX28_PAD_PWM0__PWM_0                           0x3100
+#define MX28_PAD_PWM1__PWM_1                           0x3110
+#define MX28_PAD_PWM2__PWM_2                           0x3120
+#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK                        0x3140
+#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK              0x3150
+#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK            0x3160
+#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0            0x3170
+#define MX28_PAD_I2C0_SCL__I2C0_SCL                    0x3180
+#define MX28_PAD_I2C0_SDA__I2C0_SDA                    0x3190
+#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0            0x31a0
+#define MX28_PAD_SPDIF__SPDIF_TX                       0x31b0
+#define MX28_PAD_PWM3__PWM_3                           0x31c0
+#define MX28_PAD_PWM4__PWM_4                           0x31d0
+#define MX28_PAD_LCD_RESET__LCD_RESET                  0x31e0
+#define MX28_PAD_ENET0_MDC__ENET0_MDC                  0x4000
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO                        0x4010
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN              0x4020
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0                        0x4030
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1                        0x4040
+#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK            0x4050
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN              0x4060
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0                        0x4070
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1                        0x4080
+#define MX28_PAD_ENET0_RXD2__ENET0_RXD2                        0x4090
+#define MX28_PAD_ENET0_RXD3__ENET0_RXD3                        0x40a0
+#define MX28_PAD_ENET0_TXD2__ENET0_TXD2                        0x40b0
+#define MX28_PAD_ENET0_TXD3__ENET0_TXD3                        0x40c0
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK            0x40d0
+#define MX28_PAD_ENET0_COL__ENET0_COL                  0x40e0
+#define MX28_PAD_ENET0_CRS__ENET0_CRS                  0x40f0
+#define MX28_PAD_ENET_CLK__CLKCTRL_ENET                        0x4100
+#define MX28_PAD_JTAG_RTCK__JTAG_RTCK                  0x4140
+#define MX28_PAD_EMI_D00__EMI_DATA0                    0x5000
+#define MX28_PAD_EMI_D01__EMI_DATA1                    0x5010
+#define MX28_PAD_EMI_D02__EMI_DATA2                    0x5020
+#define MX28_PAD_EMI_D03__EMI_DATA3                    0x5030
+#define MX28_PAD_EMI_D04__EMI_DATA4                    0x5040
+#define MX28_PAD_EMI_D05__EMI_DATA5                    0x5050
+#define MX28_PAD_EMI_D06__EMI_DATA6                    0x5060
+#define MX28_PAD_EMI_D07__EMI_DATA7                    0x5070
+#define MX28_PAD_EMI_D08__EMI_DATA8                    0x5080
+#define MX28_PAD_EMI_D09__EMI_DATA9                    0x5090
+#define MX28_PAD_EMI_D10__EMI_DATA10                   0x50a0
+#define MX28_PAD_EMI_D11__EMI_DATA11                   0x50b0
+#define MX28_PAD_EMI_D12__EMI_DATA12                   0x50c0
+#define MX28_PAD_EMI_D13__EMI_DATA13                   0x50d0
+#define MX28_PAD_EMI_D14__EMI_DATA14                   0x50e0
+#define MX28_PAD_EMI_D15__EMI_DATA15                   0x50f0
+#define MX28_PAD_EMI_ODT0__EMI_ODT0                    0x5100
+#define MX28_PAD_EMI_DQM0__EMI_DQM0                    0x5110
+#define MX28_PAD_EMI_ODT1__EMI_ODT1                    0x5120
+#define MX28_PAD_EMI_DQM1__EMI_DQM1                    0x5130
+#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK        0x5140
+#define MX28_PAD_EMI_CLK__EMI_CLK                      0x5150
+#define MX28_PAD_EMI_DQS0__EMI_DQS0                    0x5160
+#define MX28_PAD_EMI_DQS1__EMI_DQS1                    0x5170
+#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN            0x51a0
+#define MX28_PAD_EMI_A00__EMI_ADDR0                    0x6000
+#define MX28_PAD_EMI_A01__EMI_ADDR1                    0x6010
+#define MX28_PAD_EMI_A02__EMI_ADDR2                    0x6020
+#define MX28_PAD_EMI_A03__EMI_ADDR3                    0x6030
+#define MX28_PAD_EMI_A04__EMI_ADDR4                    0x6040
+#define MX28_PAD_EMI_A05__EMI_ADDR5                    0x6050
+#define MX28_PAD_EMI_A06__EMI_ADDR6                    0x6060
+#define MX28_PAD_EMI_A07__EMI_ADDR7                    0x6070
+#define MX28_PAD_EMI_A08__EMI_ADDR8                    0x6080
+#define MX28_PAD_EMI_A09__EMI_ADDR9                    0x6090
+#define MX28_PAD_EMI_A10__EMI_ADDR10                   0x60a0
+#define MX28_PAD_EMI_A11__EMI_ADDR11                   0x60b0
+#define MX28_PAD_EMI_A12__EMI_ADDR12                   0x60c0
+#define MX28_PAD_EMI_A13__EMI_ADDR13                   0x60d0
+#define MX28_PAD_EMI_A14__EMI_ADDR14                   0x60e0
+#define MX28_PAD_EMI_BA0__EMI_BA0                      0x6100
+#define MX28_PAD_EMI_BA1__EMI_BA1                      0x6110
+#define MX28_PAD_EMI_BA2__EMI_BA2                      0x6120
+#define MX28_PAD_EMI_CASN__EMI_CASN                    0x6130
+#define MX28_PAD_EMI_RASN__EMI_RASN                    0x6140
+#define MX28_PAD_EMI_WEN__EMI_WEN                      0x6150
+#define MX28_PAD_EMI_CE0N__EMI_CE0N                    0x6160
+#define MX28_PAD_EMI_CE1N__EMI_CE1N                    0x6170
+#define MX28_PAD_EMI_CKE__EMI_CKE                      0x6180
+#define MX28_PAD_GPMI_D00__SSP1_D0                     0x0001
+#define MX28_PAD_GPMI_D01__SSP1_D1                     0x0011
+#define MX28_PAD_GPMI_D02__SSP1_D2                     0x0021
+#define MX28_PAD_GPMI_D03__SSP1_D3                     0x0031
+#define MX28_PAD_GPMI_D04__SSP1_D4                     0x0041
+#define MX28_PAD_GPMI_D05__SSP1_D5                     0x0051
+#define MX28_PAD_GPMI_D06__SSP1_D6                     0x0061
+#define MX28_PAD_GPMI_D07__SSP1_D7                     0x0071
+#define MX28_PAD_GPMI_CE0N__SSP3_D0                    0x0101
+#define MX28_PAD_GPMI_CE1N__SSP3_D3                    0x0111
+#define MX28_PAD_GPMI_CE2N__CAN1_TX                    0x0121
+#define MX28_PAD_GPMI_CE3N__CAN1_RX                    0x0131
+#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT           0x0141
+#define MX28_PAD_GPMI_RDY1__SSP1_CMD                   0x0151
+#define MX28_PAD_GPMI_RDY2__CAN0_TX                    0x0161
+#define MX28_PAD_GPMI_RDY3__CAN0_RX                    0x0171
+#define MX28_PAD_GPMI_RDN__SSP3_SCK                    0x0181
+#define MX28_PAD_GPMI_WRN__SSP1_SCK                    0x0191
+#define MX28_PAD_GPMI_ALE__SSP3_D1                     0x01a1
+#define MX28_PAD_GPMI_CLE__SSP3_D2                     0x01b1
+#define MX28_PAD_GPMI_RESETN__SSP3_CMD                 0x01c1
+#define MX28_PAD_LCD_D03__ETM_DA8                      0x1031
+#define MX28_PAD_LCD_D04__ETM_DA9                      0x1041
+#define MX28_PAD_LCD_D08__ETM_DA3                      0x1081
+#define MX28_PAD_LCD_D09__ETM_DA4                      0x1091
+#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT                0x1141
+#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN         0x1151
+#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT                0x1161
+#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN         0x1171
+#define MX28_PAD_LCD_RD_E__LCD_VSYNC                   0x1181
+#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC                 0x1191
+#define MX28_PAD_LCD_RS__LCD_DOTCLK                    0x11a1
+#define MX28_PAD_LCD_CS__LCD_ENABLE                    0x11b1
+#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0               0x11c1
+#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1               0x11d1
+#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK                        0x11e1
+#define MX28_PAD_SSP0_DATA4__SSP2_D0                   0x2041
+#define MX28_PAD_SSP0_DATA5__SSP2_D3                   0x2051
+#define MX28_PAD_SSP0_DATA6__SSP2_CMD                  0x2061
+#define MX28_PAD_SSP0_DATA7__SSP2_SCK                  0x2071
+#define MX28_PAD_SSP1_SCK__SSP2_D1                     0x20c1
+#define MX28_PAD_SSP1_CMD__SSP2_D2                     0x20d1
+#define MX28_PAD_SSP1_DATA0__SSP2_D6                   0x20e1
+#define MX28_PAD_SSP1_DATA3__SSP2_D7                   0x20f1
+#define MX28_PAD_SSP2_SCK__AUART2_RX                   0x2101
+#define MX28_PAD_SSP2_MOSI__AUART2_TX                  0x2111
+#define MX28_PAD_SSP2_MISO__AUART3_RX                  0x2121
+#define MX28_PAD_SSP2_SS0__AUART3_TX                   0x2131
+#define MX28_PAD_SSP2_SS1__SSP2_D1                     0x2141
+#define MX28_PAD_SSP2_SS2__SSP2_D2                     0x2151
+#define MX28_PAD_SSP3_SCK__AUART4_TX                   0x2181
+#define MX28_PAD_SSP3_MOSI__AUART4_RX                  0x2191
+#define MX28_PAD_SSP3_MISO__AUART4_RTS                 0x21a1
+#define MX28_PAD_SSP3_SS0__AUART4_CTS                  0x21b1
+#define MX28_PAD_AUART0_RX__I2C0_SCL                   0x3001
+#define MX28_PAD_AUART0_TX__I2C0_SDA                   0x3011
+#define MX28_PAD_AUART0_CTS__AUART4_RX                 0x3021
+#define MX28_PAD_AUART0_RTS__AUART4_TX                 0x3031
+#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT           0x3041
+#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT           0x3051
+#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT          0x3061
+#define MX28_PAD_AUART1_RTS__USB0_ID                   0x3071
+#define MX28_PAD_AUART2_RX__SSP3_D1                    0x3081
+#define MX28_PAD_AUART2_TX__SSP3_D2                    0x3091
+#define MX28_PAD_AUART2_CTS__I2C1_SCL                  0x30a1
+#define MX28_PAD_AUART2_RTS__I2C1_SDA                  0x30b1
+#define MX28_PAD_AUART3_RX__CAN0_TX                    0x30c1
+#define MX28_PAD_AUART3_TX__CAN0_RX                    0x30d1
+#define MX28_PAD_AUART3_CTS__CAN1_TX                   0x30e1
+#define MX28_PAD_AUART3_RTS__CAN1_RX                   0x30f1
+#define MX28_PAD_PWM0__I2C1_SCL                                0x3101
+#define MX28_PAD_PWM1__I2C1_SDA                                0x3111
+#define MX28_PAD_PWM2__USB0_ID                         0x3121
+#define MX28_PAD_SAIF0_MCLK__PWM_3                     0x3141
+#define MX28_PAD_SAIF0_LRCLK__PWM_4                    0x3151
+#define MX28_PAD_SAIF0_BITCLK__PWM_5                   0x3161
+#define MX28_PAD_SAIF0_SDATA0__PWM_6                   0x3171
+#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA              0x3181
+#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB              0x3191
+#define MX28_PAD_SAIF1_SDATA0__PWM_7                   0x31a1
+#define MX28_PAD_LCD_RESET__LCD_VSYNC                  0x31e1
+#define MX28_PAD_ENET0_MDC__GPMI_CE4N                  0x4001
+#define MX28_PAD_ENET0_MDIO__GPMI_CE5N                 0x4011
+#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N                        0x4021
+#define MX28_PAD_ENET0_RXD0__GPMI_CE7N                 0x4031
+#define MX28_PAD_ENET0_RXD1__GPMI_READY4               0x4041
+#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER           0x4051
+#define MX28_PAD_ENET0_TX_EN__GPMI_READY5              0x4061
+#define MX28_PAD_ENET0_TXD0__GPMI_READY6               0x4071
+#define MX28_PAD_ENET0_TXD1__GPMI_READY7               0x4081
+#define MX28_PAD_ENET0_RXD2__ENET1_RXD0                        0x4091
+#define MX28_PAD_ENET0_RXD3__ENET1_RXD1                        0x40a1
+#define MX28_PAD_ENET0_TXD2__ENET1_TXD0                        0x40b1
+#define MX28_PAD_ENET0_TXD3__ENET1_TXD1                        0x40c1
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER             0x40d1
+#define MX28_PAD_ENET0_COL__ENET1_TX_EN                        0x40e1
+#define MX28_PAD_ENET0_CRS__ENET1_RX_EN                        0x40f1
+#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER                        0x0122
+#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK                 0x0132
+#define MX28_PAD_GPMI_RDY0__USB0_ID                    0x0142
+#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER                        0x0162
+#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER              0x0172
+#define MX28_PAD_GPMI_ALE__SSP3_D4                     0x01a2
+#define MX28_PAD_GPMI_CLE__SSP3_D5                     0x01b2
+#define MX28_PAD_LCD_D00__ETM_DA0                      0x1002
+#define MX28_PAD_LCD_D01__ETM_DA1                      0x1012
+#define MX28_PAD_LCD_D02__ETM_DA2                      0x1022
+#define MX28_PAD_LCD_D03__ETM_DA3                      0x1032
+#define MX28_PAD_LCD_D04__ETM_DA4                      0x1042
+#define MX28_PAD_LCD_D05__ETM_DA5                      0x1052
+#define MX28_PAD_LCD_D06__ETM_DA6                      0x1062
+#define MX28_PAD_LCD_D07__ETM_DA7                      0x1072
+#define MX28_PAD_LCD_D08__ETM_DA8                      0x1082
+#define MX28_PAD_LCD_D09__ETM_DA9                      0x1092
+#define MX28_PAD_LCD_D10__ETM_DA10                     0x10a2
+#define MX28_PAD_LCD_D11__ETM_DA11                     0x10b2
+#define MX28_PAD_LCD_D12__ETM_DA12                     0x10c2
+#define MX28_PAD_LCD_D13__ETM_DA13                     0x10d2
+#define MX28_PAD_LCD_D14__ETM_DA14                     0x10e2
+#define MX28_PAD_LCD_D15__ETM_DA15                     0x10f2
+#define MX28_PAD_LCD_D16__ETM_DA7                      0x1102
+#define MX28_PAD_LCD_D17__ETM_DA6                      0x1112
+#define MX28_PAD_LCD_D18__ETM_DA5                      0x1122
+#define MX28_PAD_LCD_D19__ETM_DA4                      0x1132
+#define MX28_PAD_LCD_D20__ETM_DA3                      0x1142
+#define MX28_PAD_LCD_D21__ETM_DA2                      0x1152
+#define MX28_PAD_LCD_D22__ETM_DA1                      0x1162
+#define MX28_PAD_LCD_D23__ETM_DA0                      0x1172
+#define MX28_PAD_LCD_RD_E__ETM_TCTL                    0x1182
+#define MX28_PAD_LCD_WR_RWN__ETM_TCLK                  0x1192
+#define MX28_PAD_LCD_HSYNC__ETM_TCTL                   0x11d2
+#define MX28_PAD_LCD_DOTCLK__ETM_TCLK                  0x11e2
+#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT       0x20c2
+#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN                0x20d2
+#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT     0x20e2
+#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN      0x20f2
+#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1                        0x2102
+#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2               0x2112
+#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1               0x2122
+#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2                        0x2132
+#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT            0x2142
+#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT            0x2152
+#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT       0x2182
+#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN       0x2192
+#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT      0x21a2
+#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN                0x21b2
+#define MX28_PAD_AUART0_RX__DUART_CTS                  0x3002
+#define MX28_PAD_AUART0_TX__DUART_RTS                  0x3012
+#define MX28_PAD_AUART0_CTS__DUART_RX                  0x3022
+#define MX28_PAD_AUART0_RTS__DUART_TX                  0x3032
+#define MX28_PAD_AUART1_RX__PWM_0                      0x3042
+#define MX28_PAD_AUART1_TX__PWM_1                      0x3052
+#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA            0x3062
+#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB            0x3072
+#define MX28_PAD_AUART2_RX__SSP3_D4                    0x3082
+#define MX28_PAD_AUART2_TX__SSP3_D5                    0x3092
+#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK              0x30a2
+#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK               0x30b2
+#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT      0x30c2
+#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN       0x30d2
+#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT     0x30e2
+#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN      0x30f2
+#define MX28_PAD_PWM0__DUART_RX                                0x3102
+#define MX28_PAD_PWM1__DUART_TX                                0x3112
+#define MX28_PAD_PWM2__USB1_OVERCURRENT                        0x3122
+#define MX28_PAD_SAIF0_MCLK__AUART4_CTS                        0x3142
+#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS               0x3152
+#define MX28_PAD_SAIF0_BITCLK__AUART4_RX               0x3162
+#define MX28_PAD_SAIF0_SDATA0__AUART4_TX               0x3172
+#define MX28_PAD_I2C0_SCL__DUART_RX                    0x3182
+#define MX28_PAD_I2C0_SDA__DUART_TX                    0x3192
+#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1            0x31a2
+#define MX28_PAD_SPDIF__ENET1_RX_ER                    0x31b2
+#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1               0x4002
+#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2              0x4012
+#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1             0x4022
+#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2              0x4032
+#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT   0x4052
+#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT     0x4092
+#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN      0x40a2
+#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT     0x40b2
+#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN      0x40c2
+#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN    0x40d2
+#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT      0x40e2
+#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN       0x40f2
+#define MX28_PAD_GPMI_D00__GPIO_0_0                    0x0003
+#define MX28_PAD_GPMI_D01__GPIO_0_1                    0x0013
+#define MX28_PAD_GPMI_D02__GPIO_0_2                    0x0023
+#define MX28_PAD_GPMI_D03__GPIO_0_3                    0x0033
+#define MX28_PAD_GPMI_D04__GPIO_0_4                    0x0043
+#define MX28_PAD_GPMI_D05__GPIO_0_5                    0x0053
+#define MX28_PAD_GPMI_D06__GPIO_0_6                    0x0063
+#define MX28_PAD_GPMI_D07__GPIO_0_7                    0x0073
+#define MX28_PAD_GPMI_CE0N__GPIO_0_16                  0x0103
+#define MX28_PAD_GPMI_CE1N__GPIO_0_17                  0x0113
+#define MX28_PAD_GPMI_CE2N__GPIO_0_18                  0x0123
+#define MX28_PAD_GPMI_CE3N__GPIO_0_19                  0x0133
+#define MX28_PAD_GPMI_RDY0__GPIO_0_20                  0x0143
+#define MX28_PAD_GPMI_RDY1__GPIO_0_21                  0x0153
+#define MX28_PAD_GPMI_RDY2__GPIO_0_22                  0x0163
+#define MX28_PAD_GPMI_RDY3__GPIO_0_23                  0x0173
+#define MX28_PAD_GPMI_RDN__GPIO_0_24                   0x0183
+#define MX28_PAD_GPMI_WRN__GPIO_0_25                   0x0193
+#define MX28_PAD_GPMI_ALE__GPIO_0_26                   0x01a3
+#define MX28_PAD_GPMI_CLE__GPIO_0_27                   0x01b3
+#define MX28_PAD_GPMI_RESETN__GPIO_0_28                        0x01c3
+#define MX28_PAD_LCD_D00__GPIO_1_0                     0x1003
+#define MX28_PAD_LCD_D01__GPIO_1_1                     0x1013
+#define MX28_PAD_LCD_D02__GPIO_1_2                     0x1023
+#define MX28_PAD_LCD_D03__GPIO_1_3                     0x1033
+#define MX28_PAD_LCD_D04__GPIO_1_4                     0x1043
+#define MX28_PAD_LCD_D05__GPIO_1_5                     0x1053
+#define MX28_PAD_LCD_D06__GPIO_1_6                     0x1063
+#define MX28_PAD_LCD_D07__GPIO_1_7                     0x1073
+#define MX28_PAD_LCD_D08__GPIO_1_8                     0x1083
+#define MX28_PAD_LCD_D09__GPIO_1_9                     0x1093
+#define MX28_PAD_LCD_D10__GPIO_1_10                    0x10a3
+#define MX28_PAD_LCD_D11__GPIO_1_11                    0x10b3
+#define MX28_PAD_LCD_D12__GPIO_1_12                    0x10c3
+#define MX28_PAD_LCD_D13__GPIO_1_13                    0x10d3
+#define MX28_PAD_LCD_D14__GPIO_1_14                    0x10e3
+#define MX28_PAD_LCD_D15__GPIO_1_15                    0x10f3
+#define MX28_PAD_LCD_D16__GPIO_1_16                    0x1103
+#define MX28_PAD_LCD_D17__GPIO_1_17                    0x1113
+#define MX28_PAD_LCD_D18__GPIO_1_18                    0x1123
+#define MX28_PAD_LCD_D19__GPIO_1_19                    0x1133
+#define MX28_PAD_LCD_D20__GPIO_1_20                    0x1143
+#define MX28_PAD_LCD_D21__GPIO_1_21                    0x1153
+#define MX28_PAD_LCD_D22__GPIO_1_22                    0x1163
+#define MX28_PAD_LCD_D23__GPIO_1_23                    0x1173
+#define MX28_PAD_LCD_RD_E__GPIO_1_24                   0x1183
+#define MX28_PAD_LCD_WR_RWN__GPIO_1_25                 0x1193
+#define MX28_PAD_LCD_RS__GPIO_1_26                     0x11a3
+#define MX28_PAD_LCD_CS__GPIO_1_27                     0x11b3
+#define MX28_PAD_LCD_VSYNC__GPIO_1_28                  0x11c3
+#define MX28_PAD_LCD_HSYNC__GPIO_1_29                  0x11d3
+#define MX28_PAD_LCD_DOTCLK__GPIO_1_30                 0x11e3
+#define MX28_PAD_LCD_ENABLE__GPIO_1_31                 0x11f3
+#define MX28_PAD_SSP0_DATA0__GPIO_2_0                  0x2003
+#define MX28_PAD_SSP0_DATA1__GPIO_2_1                  0x2013
+#define MX28_PAD_SSP0_DATA2__GPIO_2_2                  0x2023
+#define MX28_PAD_SSP0_DATA3__GPIO_2_3                  0x2033
+#define MX28_PAD_SSP0_DATA4__GPIO_2_4                  0x2043
+#define MX28_PAD_SSP0_DATA5__GPIO_2_5                  0x2053
+#define MX28_PAD_SSP0_DATA6__GPIO_2_6                  0x2063
+#define MX28_PAD_SSP0_DATA7__GPIO_2_7                  0x2073
+#define MX28_PAD_SSP0_CMD__GPIO_2_8                    0x2083
+#define MX28_PAD_SSP0_DETECT__GPIO_2_9                 0x2093
+#define MX28_PAD_SSP0_SCK__GPIO_2_10                   0x20a3
+#define MX28_PAD_SSP1_SCK__GPIO_2_12                   0x20c3
+#define MX28_PAD_SSP1_CMD__GPIO_2_13                   0x20d3
+#define MX28_PAD_SSP1_DATA0__GPIO_2_14                 0x20e3
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15                 0x20f3
+#define MX28_PAD_SSP2_SCK__GPIO_2_16                   0x2103
+#define MX28_PAD_SSP2_MOSI__GPIO_2_17                  0x2113
+#define MX28_PAD_SSP2_MISO__GPIO_2_18                  0x2123
+#define MX28_PAD_SSP2_SS0__GPIO_2_19                   0x2133
+#define MX28_PAD_SSP2_SS1__GPIO_2_20                   0x2143
+#define MX28_PAD_SSP2_SS2__GPIO_2_21                   0x2153
+#define MX28_PAD_SSP3_SCK__GPIO_2_24                   0x2183
+#define MX28_PAD_SSP3_MOSI__GPIO_2_25                  0x2193
+#define MX28_PAD_SSP3_MISO__GPIO_2_26                  0x21a3
+#define MX28_PAD_SSP3_SS0__GPIO_2_27                   0x21b3
+#define MX28_PAD_AUART0_RX__GPIO_3_0                   0x3003
+#define MX28_PAD_AUART0_TX__GPIO_3_1                   0x3013
+#define MX28_PAD_AUART0_CTS__GPIO_3_2                  0x3023
+#define MX28_PAD_AUART0_RTS__GPIO_3_3                  0x3033
+#define MX28_PAD_AUART1_RX__GPIO_3_4                   0x3043
+#define MX28_PAD_AUART1_TX__GPIO_3_5                   0x3053
+#define MX28_PAD_AUART1_CTS__GPIO_3_6                  0x3063
+#define MX28_PAD_AUART1_RTS__GPIO_3_7                  0x3073
+#define MX28_PAD_AUART2_RX__GPIO_3_8                   0x3083
+#define MX28_PAD_AUART2_TX__GPIO_3_9                   0x3093
+#define MX28_PAD_AUART2_CTS__GPIO_3_10                 0x30a3
+#define MX28_PAD_AUART2_RTS__GPIO_3_11                 0x30b3
+#define MX28_PAD_AUART3_RX__GPIO_3_12                  0x30c3
+#define MX28_PAD_AUART3_TX__GPIO_3_13                  0x30d3
+#define MX28_PAD_AUART3_CTS__GPIO_3_14                 0x30e3
+#define MX28_PAD_AUART3_RTS__GPIO_3_15                 0x30f3
+#define MX28_PAD_PWM0__GPIO_3_16                       0x3103
+#define MX28_PAD_PWM1__GPIO_3_17                       0x3113
+#define MX28_PAD_PWM2__GPIO_3_18                       0x3123
+#define MX28_PAD_SAIF0_MCLK__GPIO_3_20                 0x3143
+#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21                        0x3153
+#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22               0x3163
+#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23               0x3173
+#define MX28_PAD_I2C0_SCL__GPIO_3_24                   0x3183
+#define MX28_PAD_I2C0_SDA__GPIO_3_25                   0x3193
+#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26               0x31a3
+#define MX28_PAD_SPDIF__GPIO_3_27                      0x31b3
+#define MX28_PAD_PWM3__GPIO_3_28                       0x31c3
+#define MX28_PAD_PWM4__GPIO_3_29                       0x31d3
+#define MX28_PAD_LCD_RESET__GPIO_3_30                  0x31e3
+#define MX28_PAD_ENET0_MDC__GPIO_4_0                   0x4003
+#define MX28_PAD_ENET0_MDIO__GPIO_4_1                  0x4013
+#define MX28_PAD_ENET0_RX_EN__GPIO_4_2                 0x4023
+#define MX28_PAD_ENET0_RXD0__GPIO_4_3                  0x4033
+#define MX28_PAD_ENET0_RXD1__GPIO_4_4                  0x4043
+#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5                        0x4053
+#define MX28_PAD_ENET0_TX_EN__GPIO_4_6                 0x4063
+#define MX28_PAD_ENET0_TXD0__GPIO_4_7                  0x4073
+#define MX28_PAD_ENET0_TXD1__GPIO_4_8                  0x4083
+#define MX28_PAD_ENET0_RXD2__GPIO_4_9                  0x4093
+#define MX28_PAD_ENET0_RXD3__GPIO_4_10                 0x40a3
+#define MX28_PAD_ENET0_TXD2__GPIO_4_11                 0x40b3
+#define MX28_PAD_ENET0_TXD3__GPIO_4_12                 0x40c3
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13               0x40d3
+#define MX28_PAD_ENET0_COL__GPIO_4_14                  0x40e3
+#define MX28_PAD_ENET0_CRS__GPIO_4_15                  0x40f3
+#define MX28_PAD_ENET_CLK__GPIO_4_16                   0x4103
+#define MX28_PAD_JTAG_RTCK__GPIO_4_20                  0x4143
+
+#endif /* __DT_BINDINGS_MX28_PINCTRL_H__ */
index 6c6a5442800ad78adfe13ada4cf44a2cfd3cfbc5..4870f07bf56a86423c6a910a5c86ce6fce1624a4 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
 
 / {
        model = "SchulerControl GmbH, SC SPS 1";
                                hog_pins_a: hog-gpios@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0003 /* MX28_PAD_GPMI_D00__GPIO_0_0 */
-                                               0x0033 /* MX28_PAD_GPMI_D03__GPIO_0_3 */
-                                               0x0063 /* MX28_PAD_GPMI_D06__GPIO_0_6 */
+                                               MX28_PAD_GPMI_D00__GPIO_0_0
+                                               MX28_PAD_GPMI_D03__GPIO_0_3
+                                               MX28_PAD_GPMI_D06__GPIO_0_6
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                        };
index 37be532f00550bf868b3265d1a7d7362b3443a35..be5a0550d58c3312d37f36e04c937d5739c7f181 100644 (file)
+/*
+ * Copyright 2012 Shawn Guo <shawn.guo@linaro.org>
+ * Copyright 2013 Lothar Waßmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
 /dts-v1/;
-/include/ "imx28.dtsi"
+#include "imx28.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "Ka-Ro electronics TX28 module";
        compatible = "karo,tx28", "fsl,imx28";
 
+       aliases {
+               can0 = &can0;
+               can1 = &can1;
+               display = &display;
+               ds1339 = &ds1339;
+               gpio5 = &gpio5;
+               lcdif = &lcdif;
+               lcdif_23bit_pins = &tx28_lcdif_23bit_pins;
+               lcdif_24bit_pins = &lcdif_24bit_pins_a;
+               stk5led = &user_led;
+               usbotg = &usb0;
+       };
+
        memory {
-               reg = <0x40000000 0x08000000>;
-       };
-
-       apb@80000000 {
-               apbh@80000000 {
-                       ssp0: ssp@80010000 {
-                               compatible = "fsl,imx28-mmc";
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&mmc0_4bit_pins_a
-                                            &mmc0_cd_cfg
-                                            &mmc0_sck_cfg>;
-                               bus-width = <4>;
-                               status = "okay";
-                       };
+               reg = <0 0>; /* will be filled in by U-Boot */
+       };
 
-                       pinctrl@80018000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&hog_pins_a>;
-
-                               hog_pins_a: hog@0 {
-                                       reg = <0>;
-                                       fsl,pinmux-ids = <
-                                               0x40a3 /* MX28_PAD_ENET0_RXD3__GPIO_4_10 */
-                                       >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
-                               };
-
-                               mac0_pins_gpio: mac0-gpio-mode@0 {
-                                       reg = <0>;
-                                       fsl,pinmux-ids = <
-                                               0x4003 /* MX28_PAD_ENET0_MDC__GPIO_4_0 */
-                                               0x4013 /* MX28_PAD_ENET0_MDIO__GPIO_4_1 */
-                                               0x4023 /* MX28_PAD_ENET0_RX_EN__GPIO_4_2 */
-                                               0x4033 /* MX28_PAD_ENET0_RXD0__GPIO_4_3 */
-                                               0x4043 /* MX28_PAD_ENET0_RXD1__GPIO_4_4 */
-                                               0x4063 /* MX28_PAD_ENET0_TX_EN__GPIO_4_6 */
-                                               0x4073 /* MX28_PAD_ENET0_TXD0__GPIO_4_7 */
-                                               0x4083 /* MX28_PAD_ENET0_TXD1__GPIO_4_8 */
-                                               0x4103 /* MX28_PAD_ENET_CLK__GPIO_4_16 */
-                                       >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
-                               };
-                       };
+       onewire {
+               compatible = "w1-gpio";
+               gpios = <&gpio2 7 0>;
+               status = "disabled";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_usb0_vbus: usb0_vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usb0_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio0 18 0>;
+                       enable-active-high;
                };
 
-               apbx@80040000 {
-                       i2c0: i2c@80058000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&i2c0_pins_a>;
-                               status = "okay";
+               reg_usb1_vbus: usb1_vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usb1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 27 0>;
+                       enable-active-high;
+               };
 
-                               ds1339: rtc@68 {
-                                       compatible = "mxim,ds1339";
-                                       reg = <0x68>;
-                               };
-                       };
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
 
-                       pwm: pwm@80064000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pwm0_pins_a>;
-                               status = "okay";
-                       };
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
 
-                       duart: serial@80074000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&duart_4pins_a>;
-                               status = "okay";
-                       };
+               reg_can_xcvr: can-xcvr {
+                       compatible = "regulator-fixed";
+                       regulator-name = "CAN XCVR";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio1 0 0>;
+                       enable-active-low;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&tx28_flexcan_xcvr_pins>;
+               };
 
-                       auart1: serial@8006c000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&auart1_pins_a>;
-                               status = "okay";
-                       };
+               reg_lcd: lcd-power {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD POWER";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio1 31 0>;
+                       enable-active-high;
+               };
+
+               reg_lcd_reset: lcd-reset {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 30 0>;
+                       startup-delay-us = <300000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
                };
        };
 
-       ahb@80080000 {
-               mac0: ethernet@800f0000 {
-                       phy-mode = "rmii";
-                       pinctrl-names = "default", "gpio_mode";
-                       pinctrl-0 = <&mac0_pins_a>;
-                       pinctrl-1 = <&mac0_pins_gpio>;
-                       status = "okay";
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               mclk: clock@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <27000000>;
                };
        };
 
+       sound {
+               compatible = "fsl,imx28-tx28-sgtl5000",
+                            "fsl,mxs-audio-sgtl5000";
+               model = "imx28-tx28-sgtl5000";
+               saif-controllers = <&saif0 &saif1>;
+               audio-codec = <&sgtl5000>;
+       };
+
        leds {
                compatible = "gpio-leds";
 
-               user {
+               user_led: user {
                        label = "Heartbeat";
                        gpios = <&gpio4 10 0>;
                        linux,default-trigger = "heartbeat";
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm 0 5000000>;
-               brightness-levels = <0 4 8 16 32 64 128 255>;
-               default-brightness-level = <6>;
+               pwms = <&pwm 0 500000>;
+               /*
+                * a silly way to create a 1:1 relationship between the
+                * PWM value and the actual duty cycle
+                */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 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 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+       };
+
+       matrix_keypad: matrix-keypad@0 {
+               compatible = "gpio-matrix-keypad";
+               col-gpios = <
+                       &gpio5 0 0
+                       &gpio5 1 0
+                       &gpio5 2 0
+                       &gpio5 3 0
+               >;
+               row-gpios = <
+                       &gpio5 4 0
+                       &gpio5 5 0
+                       &gpio5 6 0
+                       &gpio5 7 0
+               >;
+               /* sample keymap */
+               linux,keymap = <
+                       0x00000074 /* row 0, col 0, KEY_POWER */
+                       0x00010052 /* row 0, col 1, KEY_KP0 */
+                       0x0002004f /* row 0, col 2, KEY_KP1 */
+                       0x00030050 /* row 0, col 3, KEY_KP2 */
+                       0x01000051 /* row 1, col 0, KEY_KP3 */
+                       0x0101004b /* row 1, col 1, KEY_KP4 */
+                       0x0102004c /* row 1, col 2, KEY_KP5 */
+                       0x0103004d /* row 1, col 3, KEY_KP6 */
+                       0x02000047 /* row 2, col 0, KEY_KP7 */
+                       0x02010048 /* row 2, col 1, KEY_KP8 */
+                       0x02020049 /* row 2, col 2, KEY_KP9 */
+               >;
+               gpio-activelow;
+               linux,wakeup;
+               debounce-delay-ms = <100>;
+               col-scan-delay-us = <5000>;
+               linux,no-autorepeat;
+       };
+};
+
+/* 2nd TX-Std UART - (A)UART1  */
+&auart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&auart1_pins_a>;
+       status = "okay";
+};
+
+/* 3rd TX-Std UART - (A)UART3  */
+&auart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&auart3_pins_a>;
+       status = "okay";
+};
+
+&can0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&can0_pins_a>;
+       xceiver-supply = <&reg_can_xcvr>;
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&can1_pins_a>;
+       xceiver-supply = <&reg_can_xcvr>;
+       status = "okay";
+};
+
+&digctl {
+       status = "okay";
+};
+
+/* 1st TX-Std UART - (D)UART */
+&duart {
+       pinctrl-names = "default";
+       pinctrl-0 = <&duart_4pins_a>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+       nand-on-flash-bbt;
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       clock-frequency = <400000>;
+       status = "okay";
+
+       sgtl5000: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_2p5v>;
+               VDDIO-supply = <&reg_3p3v>;
+               clocks = <&mclk>;
+       };
+
+       gpio5: pca953x@20 {
+               compatible = "nxp,pca9554";
+               reg = <0x20>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tx28_pca9554_pins>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <28 0>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       polytouch: edt-ft5x06@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tx28_edt_ft5x06_pins>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <5 0>;
+               reset-gpios = <&gpio2 6 1>;
+               wake-gpios = <&gpio4 9 0>;
+       };
+
+       touchscreen: tsc2007@48 {
+               compatible = "ti,tsc2007";
+               reg = <0x48>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tx28_tsc2007_pins>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <20 0>;
+               pendown-gpio = <&gpio3 20 1>;
+               ti,x-plate-ohms = /bits/ 16 <660>;
+       };
+
+       ds1339: rtc@68 {
+               compatible = "mxim,ds1339";
+               reg = <0x68>;
+       };
+};
+
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&lcdif_24bit_pins_a &lcdif_sync_pins_a &tx28_lcdif_ctrl_pins>;
+       lcd-supply = <&reg_lcd>;
+       display = <&display>;
+       status = "okay";
+
+       display: display@0 {
+               bits-per-pixel = <32>;
+               bus-width = <24>;
+               display-timings {
+                       native-mode = <&timing5>;
+                       timing0: timing0 {
+                               panel-name = "VGA";
+                               clock-frequency = <25175000>;
+                               hactive = <640>;
+                               vactive = <480>;
+                               hback-porch = <48>;
+                               hsync-len = <96>;
+                               hfront-porch = <16>;
+                               vback-porch = <33>;
+                               vsync-len = <2>;
+                               vfront-porch = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+
+                       timing1: timing1 {
+                               panel-name = "ETV570";
+                               clock-frequency = <25175000>;
+                               hactive = <640>;
+                               vactive = <480>;
+                               hback-porch = <114>;
+                               hsync-len = <30>;
+                               hfront-porch = <16>;
+                               vback-porch = <32>;
+                               vsync-len = <3>;
+                               vfront-porch = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+
+                       timing2: timing2 {
+                               panel-name = "ET0350";
+                               clock-frequency = <6500000>;
+                               hactive = <320>;
+                               vactive = <240>;
+                               hback-porch = <34>;
+                               hsync-len = <34>;
+                               hfront-porch = <20>;
+                               vback-porch = <15>;
+                               vsync-len = <3>;
+                               vfront-porch = <4>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+
+                       timing3: timing3 {
+                               panel-name = "ET0430";
+                               clock-frequency = <9000000>;
+                               hactive = <480>;
+                               vactive = <272>;
+                               hback-porch = <2>;
+                               hsync-len = <41>;
+                               hfront-porch = <2>;
+                               vback-porch = <2>;
+                               vsync-len = <10>;
+                               vfront-porch = <2>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+
+                       timing4: timing4 {
+                               panel-name = "ET0500", "ET0700";
+                               clock-frequency = <33260000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hback-porch = <88>;
+                               hsync-len = <128>;
+                               hfront-porch = <40>;
+                               vback-porch = <33>;
+                               vsync-len = <2>;
+                               vfront-porch = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+
+                       timing5: timing5 {
+                               panel-name = "ETQ570";
+                               clock-frequency = <6400000>;
+                               hactive = <320>;
+                               vactive = <240>;
+                               hback-porch = <38>;
+                               hsync-len = <30>;
+                               hfront-porch = <30>;
+                               vback-porch = <16>;
+                               vsync-len = <3>;
+                               vfront-porch = <4>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+               };
+       };
+};
+
+&lradc {
+       fsl,lradc-touchscreen-wires = <4>;
+       status = "okay";
+};
+
+&mac0 {
+       phy-mode = "rmii";
+       pinctrl-names = "default", "gpio_mode";
+       pinctrl-0 = <&mac0_pins_a>;
+       pinctrl-1 = <&tx28_mac0_pins_gpio>;
+       status = "okay";
+};
+
+&mac1 {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mac1_pins_a>;
+       /* not enabled by default */
+};
+
+&mxs_rtc {
+       status = "okay";
+};
+
+&ocotp {
+       status = "okay";
+};
+
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins_a>;
+       status = "okay";
+};
+
+&pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hog_pins_a>;
+
+       hog_pins_a: hog@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_ENET0_RXD3__GPIO_4_10 /* module LED */
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_edt_ft5x06_pins: tx28-edt-ft5x06-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_SSP0_DATA6__GPIO_2_6 /* RESET */
+                       MX28_PAD_SSP0_DATA5__GPIO_2_5 /* IRQ */
+                       MX28_PAD_ENET0_RXD2__GPIO_4_9 /* WAKE */
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_flexcan_xcvr_pins: tx28-flexcan-xcvr-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D00__GPIO_1_0
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_lcdif_23bit_pins: tx28-lcdif-23bit {
+               fsl,pinmux-ids = <
+                       /* LCD_D00 may be used as Flexcan Transceiver Enable on STK5-V5 */
+                       MX28_PAD_LCD_D01__LCD_D1
+                       MX28_PAD_LCD_D02__LCD_D2
+                       MX28_PAD_LCD_D03__LCD_D3
+                       MX28_PAD_LCD_D04__LCD_D4
+                       MX28_PAD_LCD_D05__LCD_D5
+                       MX28_PAD_LCD_D06__LCD_D6
+                       MX28_PAD_LCD_D07__LCD_D7
+                       MX28_PAD_LCD_D08__LCD_D8
+                       MX28_PAD_LCD_D09__LCD_D9
+                       MX28_PAD_LCD_D10__LCD_D10
+                       MX28_PAD_LCD_D11__LCD_D11
+                       MX28_PAD_LCD_D12__LCD_D12
+                       MX28_PAD_LCD_D13__LCD_D13
+                       MX28_PAD_LCD_D14__LCD_D14
+                       MX28_PAD_LCD_D15__LCD_D15
+                       MX28_PAD_LCD_D16__LCD_D16
+                       MX28_PAD_LCD_D17__LCD_D17
+                       MX28_PAD_LCD_D18__LCD_D18
+                       MX28_PAD_LCD_D19__LCD_D19
+                       MX28_PAD_LCD_D20__LCD_D20
+                       MX28_PAD_LCD_D21__LCD_D21
+                       MX28_PAD_LCD_D22__LCD_D22
+                       MX28_PAD_LCD_D23__LCD_D23
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_lcdif_ctrl_pins: tx28-lcdif-ctrl {
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_ENABLE__GPIO_1_31 /* Enable */
+                       MX28_PAD_LCD_RESET__GPIO_3_30  /* Reset */
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_mac0_pins_gpio: tx28-mac0-gpio-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_ENET0_MDC__GPIO_4_0
+                       MX28_PAD_ENET0_MDIO__GPIO_4_1
+                       MX28_PAD_ENET0_RX_EN__GPIO_4_2
+                       MX28_PAD_ENET0_RXD0__GPIO_4_3
+                       MX28_PAD_ENET0_RXD1__GPIO_4_4
+                       MX28_PAD_ENET0_TX_EN__GPIO_4_6
+                       MX28_PAD_ENET0_TXD0__GPIO_4_7
+                       MX28_PAD_ENET0_TXD1__GPIO_4_8
+                       MX28_PAD_ENET_CLK__GPIO_4_16
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_pca9554_pins: tx28-pca9554-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_PWM3__GPIO_3_28
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_tsc2007_pins: tx28-tsc2007-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_SAIF0_MCLK__GPIO_3_20 /* TSC2007 IRQ */
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+
+       tx28_usbphy0_pins: tx28-usbphy0-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_GPMI_CE2N__GPIO_0_18 /* USBOTG_VBUSEN */
+                       MX28_PAD_GPMI_CE3N__GPIO_0_19 /* USBOTH_OC */
+               >;
+               fsl,drive-strength = <MXS_DRIVE_12mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       tx28_usbphy1_pins: tx28-usbphy1-pins {
+               fsl,pinmux-ids = <
+                       MX28_PAD_SPDIF__GPIO_3_27 /* USBH_VBUSEN */
+                       MX28_PAD_JTAG_RTCK__GPIO_4_20 /* USBH_OC */
+               >;
+               fsl,drive-strength = <MXS_DRIVE_12mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+};
+
+&saif0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&saif0_pins_b>;
+       fsl,saif-master;
+       status = "okay";
+};
+
+&saif1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&saif1_pins_a>;
+       status = "okay";
+};
+
+&ssp0 {
+       compatible = "fsl,imx28-mmc";
+       pinctrl-names = "default", "special";
+       pinctrl-0 = <&mmc0_4bit_pins_a
+                    &mmc0_cd_cfg
+                    &mmc0_sck_cfg>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&ssp3 {
+       compatible = "fsl,imx28-spi";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi3_pins_a>;
+       clock-frequency = <57600000>;
+       status = "okay";
+
+       spidev0: spi@0 {
+               compatible = "spidev";
+               reg = <0>;
+               spi-max-frequency = <57600000>;
+       };
+
+       spidev1: spi@1 {
+               compatible = "spidev";
+               reg = <1>;
+               spi-max-frequency = <57600000>;
        };
 };
+
+&usb0 {
+       vbus-supply = <&reg_usb0_vbus>;
+       disable-over-current;
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&usb1 {
+       vbus-supply = <&reg_usb1_vbus>;
+       disable-over-current;
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usbphy0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&tx28_usbphy0_pins>;
+       phy_type = "utmi";
+       status = "okay";
+};
+
+&usbphy1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&tx28_usbphy1_pins>;
+       phy_type = "utmi";
+       status = "okay";
+};
index 7363fded95ee9411d21faf35c4a242ccd5aeb592..cda19c8b0a470ecb6900255c8a9eb17b85bdf9dc 100644 (file)
@@ -9,7 +9,8 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include "imx28-pinfunc.h"
 
 / {
        interrupt-parent = <&icoll>;
                                duart_pins_a: duart@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3102 /* MX28_PAD_PWM0__DUART_RX */
-                                               0x3112 /* MX28_PAD_PWM1__DUART_TX */
+                                               MX28_PAD_PWM0__DUART_RX
+                                               MX28_PAD_PWM1__DUART_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                duart_pins_b: duart@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */
-                                               0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */
+                                               MX28_PAD_AUART0_CTS__DUART_RX
+                                               MX28_PAD_AUART0_RTS__DUART_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                duart_4pins_a: duart-4pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */
-                                               0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */
-                                               0x3002 /* MX28_PAD_AUART0_RX__DUART_CTS */
-                                               0x3012 /* MX28_PAD_AUART0_TX__DUART_RTS */
+                                               MX28_PAD_AUART0_CTS__DUART_RX
+                                               MX28_PAD_AUART0_RTS__DUART_TX
+                                               MX28_PAD_AUART0_RX__DUART_CTS
+                                               MX28_PAD_AUART0_TX__DUART_RTS
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                gpmi_pins_a: gpmi-nand@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0000 /* MX28_PAD_GPMI_D00__GPMI_D0 */
-                                               0x0010 /* MX28_PAD_GPMI_D01__GPMI_D1 */
-                                               0x0020 /* MX28_PAD_GPMI_D02__GPMI_D2 */
-                                               0x0030 /* MX28_PAD_GPMI_D03__GPMI_D3 */
-                                               0x0040 /* MX28_PAD_GPMI_D04__GPMI_D4 */
-                                               0x0050 /* MX28_PAD_GPMI_D05__GPMI_D5 */
-                                               0x0060 /* MX28_PAD_GPMI_D06__GPMI_D6 */
-                                               0x0070 /* MX28_PAD_GPMI_D07__GPMI_D7 */
-                                               0x0100 /* MX28_PAD_GPMI_CE0N__GPMI_CE0N */
-                                               0x0140 /* MX28_PAD_GPMI_RDY0__GPMI_READY0 */
-                                               0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */
-                                               0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */
-                                               0x01a0 /* MX28_PAD_GPMI_ALE__GPMI_ALE */
-                                               0x01b0 /* MX28_PAD_GPMI_CLE__GPMI_CLE */
-                                               0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */
+                                               MX28_PAD_GPMI_D00__GPMI_D0
+                                               MX28_PAD_GPMI_D01__GPMI_D1
+                                               MX28_PAD_GPMI_D02__GPMI_D2
+                                               MX28_PAD_GPMI_D03__GPMI_D3
+                                               MX28_PAD_GPMI_D04__GPMI_D4
+                                               MX28_PAD_GPMI_D05__GPMI_D5
+                                               MX28_PAD_GPMI_D06__GPMI_D6
+                                               MX28_PAD_GPMI_D07__GPMI_D7
+                                               MX28_PAD_GPMI_CE0N__GPMI_CE0N
+                                               MX28_PAD_GPMI_RDY0__GPMI_READY0
+                                               MX28_PAD_GPMI_RDN__GPMI_RDN
+                                               MX28_PAD_GPMI_WRN__GPMI_WRN
+                                               MX28_PAD_GPMI_ALE__GPMI_ALE
+                                               MX28_PAD_GPMI_CLE__GPMI_CLE
+                                               MX28_PAD_GPMI_RESETN__GPMI_RESETN
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                gpmi_status_cfg: gpmi-status-cfg {
                                        fsl,pinmux-ids = <
-                                               0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */
-                                               0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */
-                                               0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */
+                                               MX28_PAD_GPMI_RDN__GPMI_RDN
+                                               MX28_PAD_GPMI_WRN__GPMI_WRN
+                                               MX28_PAD_GPMI_RESETN__GPMI_RESETN
                                        >;
-                                       fsl,drive-strength = <2>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
                                };
 
                                auart0_pins_a: auart0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */
-                                               0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */
-                                               0x3020 /* MX28_PAD_AUART0_CTS__AUART0_CTS */
-                                               0x3030 /* MX28_PAD_AUART0_RTS__AUART0_RTS */
+                                               MX28_PAD_AUART0_RX__AUART0_RX
+                                               MX28_PAD_AUART0_TX__AUART0_TX
+                                               MX28_PAD_AUART0_CTS__AUART0_CTS
+                                               MX28_PAD_AUART0_RTS__AUART0_RTS
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart0_2pins_a: auart0-2pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */
-                                               0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */
+                                               MX28_PAD_AUART0_RX__AUART0_RX
+                                               MX28_PAD_AUART0_TX__AUART0_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart1_pins_a: auart1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */
-                                               0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */
-                                               0x3060 /* MX28_PAD_AUART1_CTS__AUART1_CTS */
-                                               0x3070 /* MX28_PAD_AUART1_RTS__AUART1_RTS */
+                                               MX28_PAD_AUART1_RX__AUART1_RX
+                                               MX28_PAD_AUART1_TX__AUART1_TX
+                                               MX28_PAD_AUART1_CTS__AUART1_CTS
+                                               MX28_PAD_AUART1_RTS__AUART1_RTS
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart1_2pins_a: auart1-2pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */
-                                               0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */
+                                               MX28_PAD_AUART1_RX__AUART1_RX
+                                               MX28_PAD_AUART1_TX__AUART1_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart2_2pins_a: auart2-2pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2101 /* MX28_PAD_SSP2_SCK__AUART2_RX */
-                                               0x2111 /* MX28_PAD_SSP2_MOSI__AUART2_TX */
+                                               MX28_PAD_SSP2_SCK__AUART2_RX
+                                               MX28_PAD_SSP2_MOSI__AUART2_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart2_2pins_b: auart2-2pins@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x3080 /* MX28_PAD_AUART2_RX__AUART2_RX */
-                                               0x3090 /* MX28_PAD_AUART2_TX__AUART2_TX */
+                                               MX28_PAD_AUART2_RX__AUART2_RX
+                                               MX28_PAD_AUART2_TX__AUART2_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       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 = <
-                                               0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */
-                                               0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */
-                                               0x30e0 /* MX28_PAD_AUART3_CTS__AUART3_CTS */
-                                               0x30f0 /* MX28_PAD_AUART3_RTS__AUART3_RTS */
+                                               MX28_PAD_AUART3_RX__AUART3_RX
+                                               MX28_PAD_AUART3_TX__AUART3_TX
+                                               MX28_PAD_AUART3_CTS__AUART3_CTS
+                                               MX28_PAD_AUART3_RTS__AUART3_RTS
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart3_2pins_a: auart3-2pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2121 /* MX28_PAD_SSP2_MISO__AUART3_RX */
-                                               0x2131 /* MX28_PAD_SSP2_SS0__AUART3_TX */
+                                               MX28_PAD_SSP2_MISO__AUART3_RX
+                                               MX28_PAD_SSP2_SS0__AUART3_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart3_2pins_b: auart3-2pins@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */
-                                               0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */
+                                               MX28_PAD_AUART3_RX__AUART3_RX
+                                               MX28_PAD_AUART3_TX__AUART3_TX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                auart4_2pins_a: auart4@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2181 /* MX28_PAD_SSP3_SCK__AUART4_TX */
-                                               0x2191 /* MX28_PAD_SSP3_MOSI__AUART4_RX */
+                                               MX28_PAD_SSP3_SCK__AUART4_TX
+                                               MX28_PAD_SSP3_MOSI__AUART4_RX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                mac0_pins_a: mac0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x4000 /* MX28_PAD_ENET0_MDC__ENET0_MDC */
-                                               0x4010 /* MX28_PAD_ENET0_MDIO__ENET0_MDIO */
-                                               0x4020 /* MX28_PAD_ENET0_RX_EN__ENET0_RX_EN */
-                                               0x4030 /* MX28_PAD_ENET0_RXD0__ENET0_RXD0 */
-                                               0x4040 /* MX28_PAD_ENET0_RXD1__ENET0_RXD1 */
-                                               0x4060 /* MX28_PAD_ENET0_TX_EN__ENET0_TX_EN */
-                                               0x4070 /* MX28_PAD_ENET0_TXD0__ENET0_TXD0 */
-                                               0x4080 /* MX28_PAD_ENET0_TXD1__ENET0_TXD1 */
-                                               0x4100 /* MX28_PAD_ENET_CLK__CLKCTRL_ENET */
+                                               MX28_PAD_ENET0_MDC__ENET0_MDC
+                                               MX28_PAD_ENET0_MDIO__ENET0_MDIO
+                                               MX28_PAD_ENET0_RX_EN__ENET0_RX_EN
+                                               MX28_PAD_ENET0_RXD0__ENET0_RXD0
+                                               MX28_PAD_ENET0_RXD1__ENET0_RXD1
+                                               MX28_PAD_ENET0_TX_EN__ENET0_TX_EN
+                                               MX28_PAD_ENET0_TXD0__ENET0_TXD0
+                                               MX28_PAD_ENET0_TXD1__ENET0_TXD1
+                                               MX28_PAD_ENET_CLK__CLKCTRL_ENET
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mac1_pins_a: mac1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x40f1 /* MX28_PAD_ENET0_CRS__ENET1_RX_EN */
-                                               0x4091 /* MX28_PAD_ENET0_RXD2__ENET1_RXD0 */
-                                               0x40a1 /* MX28_PAD_ENET0_RXD3__ENET1_RXD1 */
-                                               0x40e1 /* MX28_PAD_ENET0_COL__ENET1_TX_EN */
-                                               0x40b1 /* MX28_PAD_ENET0_TXD2__ENET1_TXD0 */
-                                               0x40c1 /* MX28_PAD_ENET0_TXD3__ENET1_TXD1 */
+                                               MX28_PAD_ENET0_CRS__ENET1_RX_EN
+                                               MX28_PAD_ENET0_RXD2__ENET1_RXD0
+                                               MX28_PAD_ENET0_RXD3__ENET1_RXD1
+                                               MX28_PAD_ENET0_COL__ENET1_TX_EN
+                                               MX28_PAD_ENET0_TXD2__ENET1_TXD0
+                                               MX28_PAD_ENET0_TXD3__ENET1_TXD1
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mmc0_8bit_pins_a: mmc0-8bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */
-                                               0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */
-                                               0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */
-                                               0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */
-                                               0x2040 /* MX28_PAD_SSP0_DATA4__SSP0_D4 */
-                                               0x2050 /* MX28_PAD_SSP0_DATA5__SSP0_D5 */
-                                               0x2060 /* MX28_PAD_SSP0_DATA6__SSP0_D6 */
-                                               0x2070 /* MX28_PAD_SSP0_DATA7__SSP0_D7 */
-                                               0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */
-                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
-                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                               MX28_PAD_SSP0_DATA0__SSP0_D0
+                                               MX28_PAD_SSP0_DATA1__SSP0_D1
+                                               MX28_PAD_SSP0_DATA2__SSP0_D2
+                                               MX28_PAD_SSP0_DATA3__SSP0_D3
+                                               MX28_PAD_SSP0_DATA4__SSP0_D4
+                                               MX28_PAD_SSP0_DATA5__SSP0_D5
+                                               MX28_PAD_SSP0_DATA6__SSP0_D6
+                                               MX28_PAD_SSP0_DATA7__SSP0_D7
+                                               MX28_PAD_SSP0_CMD__SSP0_CMD
+                                               MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+                                               MX28_PAD_SSP0_SCK__SSP0_SCK
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mmc0_4bit_pins_a: mmc0-4bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */
-                                               0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */
-                                               0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */
-                                               0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */
-                                               0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */
-                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
-                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                               MX28_PAD_SSP0_DATA0__SSP0_D0
+                                               MX28_PAD_SSP0_DATA1__SSP0_D1
+                                               MX28_PAD_SSP0_DATA2__SSP0_D2
+                                               MX28_PAD_SSP0_DATA3__SSP0_D3
+                                               MX28_PAD_SSP0_CMD__SSP0_CMD
+                                               MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+                                               MX28_PAD_SSP0_SCK__SSP0_SCK
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                mmc0_cd_cfg: mmc0-cd-cfg {
                                        fsl,pinmux-ids = <
-                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                               MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
                                        >;
-                                       fsl,pull-up = <0>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                mmc0_sck_cfg: mmc0-sck-cfg {
                                        fsl,pinmux-ids = <
-                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                               MX28_PAD_SSP0_SCK__SSP0_SCK
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc2_4bit_pins_a: mmc2-4bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DATA4__SSP2_D0
+                                               MX28_PAD_SSP1_SCK__SSP2_D1
+                                               MX28_PAD_SSP1_CMD__SSP2_D2
+                                               MX28_PAD_SSP0_DATA5__SSP2_D3
+                                               MX28_PAD_SSP0_DATA6__SSP2_CMD
+                                               MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+                                               MX28_PAD_SSP0_DATA7__SSP2_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
+                               mmc2_cd_cfg: mmc2-cd-cfg {
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+                                       >;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               mmc2_sck_cfg: mmc2-sck-cfg {
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_SSP0_DATA7__SSP2_SCK
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                i2c0_pins_a: i2c0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3180 /* MX28_PAD_I2C0_SCL__I2C0_SCL */
-                                               0x3190 /* MX28_PAD_I2C0_SDA__I2C0_SDA */
+                                               MX28_PAD_I2C0_SCL__I2C0_SCL
+                                               MX28_PAD_I2C0_SDA__I2C0_SDA
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                i2c0_pins_b: i2c0@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x3001 /* MX28_PAD_AUART0_RX__I2C0_SCL */
-                                               0x3011 /* MX28_PAD_AUART0_TX__I2C0_SDA */
+                                               MX28_PAD_AUART0_RX__I2C0_SCL
+                                               MX28_PAD_AUART0_TX__I2C0_SDA
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                i2c1_pins_a: i2c1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3101 /* MX28_PAD_PWM0__I2C1_SCL */
-                                               0x3111 /* MX28_PAD_PWM1__I2C1_SDA */
+                                               MX28_PAD_PWM0__I2C1_SCL
+                                               MX28_PAD_PWM1__I2C1_SDA
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                saif0_pins_a: saif0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3140 /* MX28_PAD_SAIF0_MCLK__SAIF0_MCLK */
-                                               0x3150 /* MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK */
-                                               0x3160 /* MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK */
-                                               0x3170 /* MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 */
+                                               MX28_PAD_SAIF0_MCLK__SAIF0_MCLK
+                                               MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+                                               MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+                                               MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                saif0_pins_b: saif0@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x3150 /* MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK */
-                                               0x3160 /* MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK */
-                                               0x3170 /* MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 */
+                                               MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+                                               MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+                                               MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                saif1_pins_a: saif1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31a0 /* MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 */
+                                               MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                pwm0_pins_a: pwm0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3100 /* MX28_PAD_PWM0__PWM_0 */
+                                               MX28_PAD_PWM0__PWM_0
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                pwm2_pins_a: pwm2@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3120 /* MX28_PAD_PWM2__PWM_2 */
+                                               MX28_PAD_PWM2__PWM_2
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                pwm3_pins_a: pwm3@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31c0 /* MX28_PAD_PWM3__PWM_3 */
+                                               MX28_PAD_PWM3__PWM_3
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                pwm3_pins_b: pwm3@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x3141 /* MX28_PAD_SAIF0_MCLK__PWM3 */
+                                               MX28_PAD_SAIF0_MCLK__PWM_3
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                pwm4_pins_a: pwm4@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x31d0 /* MX28_PAD_PWM4__PWM_4 */
+                                               MX28_PAD_PWM4__PWM_4
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_24bit_pins_a: lcdif-24bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
-                                               0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
-                                               0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
-                                               0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
-                                               0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
-                                               0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
-                                               0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
-                                               0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
-                                               0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
-                                               0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
-                                               0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
-                                               0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
-                                               0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
-                                               0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
-                                               0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
-                                               0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
-                                               0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
-                                               0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
-                                               0x1120 /* MX28_PAD_LCD_D18__LCD_D18 */
-                                               0x1130 /* MX28_PAD_LCD_D19__LCD_D19 */
-                                               0x1140 /* MX28_PAD_LCD_D20__LCD_D20 */
-                                               0x1150 /* MX28_PAD_LCD_D21__LCD_D21 */
-                                               0x1160 /* MX28_PAD_LCD_D22__LCD_D22 */
-                                               0x1170 /* MX28_PAD_LCD_D23__LCD_D23 */
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
+                                               MX28_PAD_LCD_D18__LCD_D18
+                                               MX28_PAD_LCD_D19__LCD_D19
+                                               MX28_PAD_LCD_D20__LCD_D20
+                                               MX28_PAD_LCD_D21__LCD_D21
+                                               MX28_PAD_LCD_D22__LCD_D22
+                                               MX28_PAD_LCD_D23__LCD_D23
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_16bit_pins_a: lcdif-16bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
-                                               0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
-                                               0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
-                                               0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
-                                               0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
-                                               0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
-                                               0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
-                                               0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
-                                               0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
-                                               0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
-                                               0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
-                                               0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
-                                               0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
-                                               0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
-                                               0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
-                                               0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                lcdif_sync_pins_a: lcdif-sync@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
-                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
-                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
-                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
+                                               MX28_PAD_LCD_RS__LCD_DOTCLK
+                                               MX28_PAD_LCD_CS__LCD_ENABLE
+                                               MX28_PAD_LCD_RD_E__LCD_VSYNC
+                                               MX28_PAD_LCD_WR_RWN__LCD_HSYNC
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                can0_pins_a: can0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0161 /* MX28_PAD_GPMI_RDY2__CAN0_TX */
-                                               0x0171 /* MX28_PAD_GPMI_RDY3__CAN0_RX */
+                                               MX28_PAD_GPMI_RDY2__CAN0_TX
+                                               MX28_PAD_GPMI_RDY3__CAN0_RX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                can1_pins_a: can1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x0121 /* MX28_PAD_GPMI_CE2N__CAN1_TX */
-                                               0x0131 /* MX28_PAD_GPMI_CE3N__CAN1_RX */
+                                               MX28_PAD_GPMI_CE2N__CAN1_TX
+                                               MX28_PAD_GPMI_CE3N__CAN1_RX
                                        >;
-                                       fsl,drive-strength = <0>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                spi2_pins_a: spi2@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2100 /* MX28_PAD_SSP2_SCK__SSP2_SCK */
-                                               0x2110 /* MX28_PAD_SSP2_MOSI__SSP2_CMD */
-                                               0x2120 /* MX28_PAD_SSP2_MISO__SSP2_D0 */
-                                               0x2130 /* MX28_PAD_SSP2_SS0__SSP2_D3 */
+                                               MX28_PAD_SSP2_SCK__SSP2_SCK
+                                               MX28_PAD_SSP2_MOSI__SSP2_CMD
+                                               MX28_PAD_SSP2_MISO__SSP2_D0
+                                               MX28_PAD_SSP2_SS0__SSP2_D3
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <1>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
 
                                spi3_pins_a: spi3@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x3082 /* MX28_PAD_AUART2_RX__SSP3_D4 */
-                                               0x3092 /* MX28_PAD_AUART2_TX__SSP3_D5 */
-                                               0x2180 /* MX28_PAD_SSP3_SCK__SSP3_SCK */
-                                               0x2190 /* MX28_PAD_SSP3_MOSI__SSP3_CMD */
-                                               0x21A0 /* MX28_PAD_SSP3_MISO__SSP3_D0 */
-                                               0x21B0 /* MX28_PAD_SSP3_SS0__SSP3_D3 */
+                                               MX28_PAD_AUART2_RX__SSP3_D4
+                                               MX28_PAD_AUART2_TX__SSP3_D5
+                                               MX28_PAD_SSP3_SCK__SSP3_SCK
+                                               MX28_PAD_SSP3_MOSI__SSP3_CMD
+                                               MX28_PAD_SSP3_MISO__SSP3_D0
+                                               MX28_PAD_SSP3_SS0__SSP3_D3
                                        >;
-                                       fsl,drive-strength = <1>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_8mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                usbphy0_pins_a: usbphy0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2152 /* MX28_PAD_SSP2_SS2__USB0_OVERCURRENT */
+                                               MX28_PAD_SSP2_SS2__USB0_OVERCURRENT
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                usbphy0_pins_b: usbphy0@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
-                                               0x3061 /* MX28_PAD_AUART1_CTS__USB0_OVERCURRENT */
+                                               MX28_PAD_AUART1_CTS__USB0_OVERCURRENT
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
                                usbphy1_pins_a: usbphy1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               0x2142 /* MX28_PAD_SSP2_SS1__USB1_OVERCURRENT */
+                                               MX28_PAD_SSP2_SS1__USB1_OVERCURRENT
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               usb0_id_pins_a: usb0id@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RTS__USB0_ID
                                        >;
-                                       fsl,drive-strength = <2>;
-                                       fsl,voltage = <1>;
-                                       fsl,pull-up = <0>;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
                        };
 
                                interrupts = <10 14 15 16 17 18 19
                                                20 21 22 23 24 25>;
                                status = "disabled";
+                               clocks = <&clks 41>;
                        };
 
                        spdif: spdif@80054000 {
index 123fe84e0e8c4b4777f2cb80d017bb75da59a69d..5a7f552786a112dadff76c0d664fc6fb682f7ccf 100644 (file)
        model = "Armadeus Systems APF51Dev docking/development board";
        compatible = "armadeus,imx51-apf51dev", "armadeus,imx51-apf51", "fsl,imx51";
 
+       display@di1 {
+               compatible = "fsl,imx-parallel-display";
+               crtcs = <&ipu 0>;
+               interface-pix-fmt = "bgr666";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+
+               display-timings {
+                       lw700 {
+                               native-mode;
+                               clock-frequency = <33000033>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hback-porch = <96>;
+                               hfront-porch = <96>;
+                               vback-porch = <20>;
+                               vfront-porch = <21>;
+                               hsync-len = <64>;
+                               vsync-len = <4>;
+                               hsync-active = <1>;
+                               vsync-active = <1>;
+                               de-active = <1>;
+                               pixelclk-active = <0>;
+                       };
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
index 1d337d99ecd533e7deea58a46a8a3fb55287a8d8..be1407cf5abd1b1479e55fbfeac48be44dc90d4c 100644 (file)
                interface-pix-fmt = "rgb24";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: dvi {
+                               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>;
+                       };
+               };
        };
 
        display@di1 {
                interface-pix-fmt = "rgb565";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+               status = "disabled";
+               display-timings {
+                       native-mode = <&timing1>;
+                       timing1: claawvga {
+                               clock-frequency = <27000000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hback-porch = <40>;
+                               hfront-porch = <60>;
+                               vback-porch = <10>;
+                               vfront-porch = <10>;
+                               hsync-len = <20>;
+                               vsync-len = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <0>;
+                       };
+               };
        };
 
        gpio-keys {
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1>;
+       pinctrl-0 = <&pinctrl_uart3_1 &pinctrl_uart3_rtscts_1>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1_1 &pinctrl_uart1_rtscts_1>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
index 54cee6517902d647507f3ed40302135fcba1b849..f4dcff3a9969a053d0a7c136015c94526a739cb8 100644 (file)
                interrupt-parent = <&tzic>;
                ranges;
 
+               iram: iram@1ffe0000 {
+                       compatible = "mmio-sram";
+                       reg = <0x1ffe0000 0x20000>;
+               };
+
                ipu: ipu@40000000 {
                        #crtc-cells = <1>;
                        compatible = "fsl,imx51-ipu";
                                clocks = <&clks 107>;
                        };
 
+                       owire: owire@83fa4000 {
+                               compatible = "fsl,imx51-owire", "fsl,imx21-owire";
+                               reg = <0x83fa4000 0x4000>;
+                               interrupts = <88>;
+                               clocks = <&clks 159>;
+                               status = "disabled";
+                       };
+
                        ecspi2: ecspi@83fac000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                        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
                        >;
                        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
                        >;
index e97ddae09d74cd1afea569013c75fcfde5b4b4b0..91a5935a4aacd63879f2f2104f546d6f41bb7e60 100644 (file)
                        label = "Power Button";
                        gpios = <&gpio1 8 0>;
                        linux,code = <116>; /* KEY_POWER */
-                       gpio-key,wakeup;
                };
 
                volume-up {
                        label = "Volume Up";
                        gpios = <&gpio2 14 0>;
                        linux,code = <115>; /* KEY_VOLUMEUP */
+                       gpio-key,wakeup;
                };
 
                volume-down {
                        label = "Volume Down";
                        gpios = <&gpio2 15 0>;
                        linux,code = <114>; /* KEY_VOLUMEDOWN */
+                       gpio-key,wakeup;
                };
        };
 
 &esdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_esdhc1_1>;
-       cd-gpios = <&gpio3 13 0>;
        status = "okay";
 };
 
        pinctrl-0 = <&pinctrl_esdhc3_1>;
        cd-gpios = <&gpio3 11 0>;
        wp-gpios = <&gpio3 12 0>;
+       bus-width = <8>;
        status = "okay";
 };
 
                                MX53_PAD_PATA_DATA15__GPIO2_15    0x80000000
                                MX53_PAD_EIM_DA11__GPIO3_11       0x80000000
                                MX53_PAD_EIM_DA12__GPIO3_12       0x80000000
-                               MX53_PAD_EIM_DA13__GPIO3_13       0x80000000
                                MX53_PAD_PATA_DA_0__GPIO7_6       0x80000000
                                MX53_PAD_PATA_DA_2__GPIO7_8       0x80000000
                                MX53_PAD_GPIO_16__GPIO7_11        0x80000000
 };
 
 &usbotg {
-       status = "okay";
+       dr_mode = "peripheral";
+       status = "okay";
 };
index 9bbe82bdee4112ca0b15de05118b70472b04287c..97ed0816a6e0c749b5bccd2562b2cbe8655ff326 100644 (file)
 #define MX6QDL_PAD_ENET_REF_CLK__ESAI_RX_FS         0x1d4 0x4e8 0x85c 0x2 0x0
 #define MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23         0x1d4 0x4e8 0x000 0x5 0x0
 #define MX6QDL_PAD_ENET_REF_CLK__SPDIF_SR_CLK       0x1d4 0x4e8 0x000 0x6 0x0
-#define MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID           0x1d8 0x4ec 0x000 0x0 0x0
+#define MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID           0x1d8 0x4ec 0x004 0x0 0xff0d0100
 #define MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER           0x1d8 0x4ec 0x000 0x1 0x0
 #define MX6QDL_PAD_ENET_RX_ER__ESAI_RX_HF_CLK       0x1d8 0x4ec 0x864 0x2 0x0
 #define MX6QDL_PAD_ENET_RX_ER__SPDIF_IN             0x1d8 0x4ec 0x914 0x3 0x1
 #define MX6QDL_PAD_GPIO_1__ESAI_RX_CLK              0x224 0x5f4 0x86c 0x0 0x1
 #define MX6QDL_PAD_GPIO_1__WDOG2_B                  0x224 0x5f4 0x000 0x1 0x0
 #define MX6QDL_PAD_GPIO_1__KEY_ROW5                 0x224 0x5f4 0x8f4 0x2 0x0
-#define MX6QDL_PAD_GPIO_1__USB_OTG_ID               0x224 0x5f4 0x000 0x3 0x0
+#define MX6QDL_PAD_GPIO_1__USB_OTG_ID               0x224 0x5f4 0x004 0x3 0xff0d0101
 #define MX6QDL_PAD_GPIO_1__PWM2_OUT                 0x224 0x5f4 0x000 0x4 0x0
 #define MX6QDL_PAD_GPIO_1__GPIO1_IO01               0x224 0x5f4 0x000 0x5 0x0
 #define MX6QDL_PAD_GPIO_1__SD1_CD_B                 0x224 0x5f4 0x000 0x6 0x0
index 3530280f5150e43d826987ab225e4b53930b33aa..f004913f7d80a1f2c0df7b229f7a011b17399818 100644 (file)
        };
 };
 
-&sata {
+&audmux {
        status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux_1>;
 };
 
 &ecspi1 {
        };
 };
 
-&ssi1 {
-       fsl,mode = "i2s-slave";
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet_1>;
+       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>;
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&reg_2p5v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+};
+
 &iomuxc {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
                                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
                        >;
                };
        };
 };
 
-&usbotg {
-       vbus-supply = <&reg_usb_otg_vbus>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
-       disable-over-current;
+&ldb {
+       status = "okay";
+
+       lvds-channel@0 {
+               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>;
+                       };
+               };
+       };
+};
+
+&sata {
+       status = "okay";
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
        status = "okay";
 };
 
+&uart2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_1>;
+};
+
 &usbh1 {
        status = "okay";
 };
 
-&fec {
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
-       phy-mode = "rgmii";
-       phy-reset-gpios = <&gpio3 23 0>;
+       pinctrl-0 = <&pinctrl_usbotg_1>;
+       disable-over-current;
        status = "okay";
 };
 
        vmmc-supply = <&reg_3p3v>;
        status = "okay";
 };
-
-&audmux {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
-};
-
-&uart2 {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
-};
-
-&i2c1 {
-       status = "okay";
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
-
-       codec: sgtl5000@0a {
-               compatible = "fsl,sgtl5000";
-               reg = <0x0a>;
-               clocks = <&clks 201>;
-               VDDA-supply = <&reg_2p5v>;
-               VDDIO-supply = <&reg_3p3v>;
-       };
-};
diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts
new file mode 100644 (file)
index 0000000..6e1ccdc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.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.
+ *
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+       model = "Udoo i.MX6 Quad Board";
+       compatible = "udoo,imx6q-udoo", "fsl,imx6q";
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+};
+
+&sata {
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_1>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       non-removable;
+       status = "okay";
+};
index 1cbbc5160d27d3f9065a61bbe1d7e77eb81d6605..ff6f1e8f2dd9bfa54a6387998421f1ac8877c841 100644 (file)
@@ -54,6 +54,7 @@
                        fsl,pins = <
                                MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
                                MX6QDL_PAD_SD2_DAT2__GPIO1_IO13  0x80000000
+                               MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
                        >;
                };
        };
 };
 
 &usdhc3 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc3_1>;
+       pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
        cd-gpios = <&gpio6 15 0>;
        wp-gpios = <&gpio1 13 0>;
        status = "okay";
index 39eafc222a2ece4f07184b26b1a96e85b23eb871..e75e11b36dffec5ea9e695c01d8f66ac35b83dee 100644 (file)
                mux-int-port = <2>;
                mux-ext-port = <3>;
        };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               status = "okay";
+       };
 };
 
 &audmux {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet_1>;
        phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 25 0>;
        status = "okay";
 };
 
                                MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x80000000
                                MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
                                MX6QDL_PAD_EIM_D22__GPIO3_IO22  0x80000000
+                               MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
                        >;
                };
        };
        };
 };
 
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_1>;
+       status = "okay";
+};
+
 &ssi2 {
        fsl,mode = "i2s-slave";
        status = "okay";
 &usdhc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2_1>;
+       bus-width = <8>;
        cd-gpios = <&gpio2 2 0>;
        wp-gpios = <&gpio2 3 0>;
        status = "okay";
 &usdhc3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc3_1>;
+       bus-width = <8>;
        cd-gpios = <&gpio2 0 0>;
        wp-gpios = <&gpio2 1 0>;
        status = "okay";
index a55113e65bcb0a3d9d6345f7129623384ee881b6..35f54792916795dd85d77624289d94ee3ab97811 100644 (file)
                mux-int-port = <1>;
                mux-ext-port = <3>;
        };
+
+       sound-spdif {
+               compatible = "fsl,imx-audio-spdif";
+               model = "imx-spdif";
+               spdif-controller = <&spdif>;
+               spdif-out;
+       };
 };
 
 &audmux {
@@ -81,6 +88,7 @@
                                MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* WL_REG_ON */
                                MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* WL_HOST_WAKE */
                                MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* WL_WAKE */
+                               MX6QDL_PAD_EIM_D29__GPIO3_IO29   0x80000000
                        >;
                };
        };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet_1>;
        phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio3 29 0>;
+       status = "okay";
+};
+
+&spdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spdif_3>;
        status = "okay";
 };
 
        status = "okay";
 };
 
+&usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg_1>;
+       disable-over-current;
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
 &usdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1_2>;
index ccd55c2fdb67e3a69402021709275108a96a6f75..59154dc15fe4ee441c80fd17d9c9141a16ee5e60 100644 (file)
                        arm,data-latency = <4 2 3>;
                };
 
+               pcie: pcie@0x01000000 {
+                       compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
+                       reg = <0x01ffc000 0x4000>; /* DBI */
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000 /* configuration space */
+                                 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>;
+                       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>;
                                ranges;
 
                                spdif: spdif@02004000 {
+                                       compatible = "fsl,imx35-spdif";
                                        reg = <0x02004000 0x4000>;
                                        interrupts = <0 52 0x04>;
+                                       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>;
+                                       clock-names = "core",  "rxtx0",
+                                                     "rxtx1", "rxtx2",
+                                                     "rxtx3", "rxtx4",
+                                                     "rxtx5", "rxtx6",
+                                                     "rxtx7";
+                                       status = "disabled";
                                };
 
                                ecspi1: ecspi@02008000 {
                                                        MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
                                                >;
                                        };
+
+                                       pinctrl_spdif_3: spdifgrp-3 {
+                                               fsl,pins = <
+                                                       MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
+                                               >;
+                                       };
                                };
 
                                uart1 {
                                                >;
                                        };
 
+                                       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
index 2886a590823dc440a9f0ba8a5d72c8efe31916d4..cc68e19c51631666e8241fbc1d4965a18605ca28 100644 (file)
        memory {
                reg = <0x80000000 0x40000000>;
        };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_usb_otg1_vbus: usb_otg1_vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usb_otg1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio4 0 0>;
+                       enable-active-high;
+               };
+
+               reg_usb_otg2_vbus: usb_otg2_vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usb_otg2_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio4 2 0>;
+                       enable-active-high;
+               };
+       };
+};
+
+&ecspi1 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio4 11 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "st,m25p32";
+               spi-max-frequency = <20000000>;
+               reg = <0>;
+       };
 };
 
 &fec {
@@ -38,6 +76,8 @@
                                MX6SL_PAD_SD2_DAT7__GPIO5_IO00    0x17059
                                MX6SL_PAD_SD2_DAT6__GPIO4_IO29    0x17059
                                MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
+                               MX6SL_PAD_KEY_COL4__GPIO4_IO00  0x80000000
+                               MX6SL_PAD_KEY_COL5__GPIO4_IO02  0x80000000
                        >;
                };
        };
        status = "okay";
 };
 
-&usdhc1 {
+&usbotg1 {
+       vbus-supply = <&reg_usb_otg1_vbus>;
        pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1_1>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbotg2 {
+       vbus-supply = <&reg_usb_otg2_vbus>;
+       dr_mode = "host";
+       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>;
        bus-width = <8>;
        cd-gpios = <&gpio4 7 0>;
        wp-gpios = <&gpio4 6 0>;
 };
 
 &usdhc2 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2_1>;
+       pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
        cd-gpios = <&gpio5 0 0>;
        wp-gpios = <&gpio4 29 0>;
        status = "okay";
 };
 
 &usdhc3 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc3_1>;
+       pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
        cd-gpios = <&gpio3 22 0>;
        status = "okay";
 };
index c46651e4d966769948be53636b6e1653005cda13..28558f1aaf2da8e67cb6b191f2d11e7964518b59 100644 (file)
 
 / {
        aliases {
-               serial0 = &uart1;
-               serial1 = &uart2;
-               serial2 = &uart3;
-               serial3 = &uart4;
-               serial4 = &uart5;
                gpio0 = &gpio1;
                gpio1 = &gpio2;
                gpio2 = &gpio3;
                gpio3 = &gpio4;
                gpio4 = &gpio5;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               spi0 = &ecspi1;
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
        };
 
        cpus {
                        };
 
                        anatop: anatop@020c8000 {
-                               compatible = "fsl,imx6sl-anatop", "syscon", "simple-bus";
+                               compatible = "fsl,imx6sl-anatop",
+                                            "fsl,imx6q-anatop",
+                                            "syscon", "simple-bus";
                                reg = <0x020c8000 0x1000>;
                                interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
 
                                interrupts = <0 89 0x04>;
                        };
 
+                       gpr: iomuxc-gpr@020e0000 {
+                               compatible = "fsl,imx6sl-iomuxc-gpr",
+                                            "fsl,imx6q-iomuxc-gpr", "syscon";
+                               reg = <0x020e0000 0x38>;
+                       };
+
                        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 = <
                                        };
                                };
 
+                               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_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 {
                                                        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 {
                                                        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
+                                               >;
+                                       };
                                };
                        };
 
                                         <&clks IMX6SL_CLK_SDMA>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
-                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6sl.bin";
+                               /* imx6sl reuses imx6q sdma firmware */
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
                        };
 
                        pxp: pxp@020f0000 {
                        usbotg2: usb@02184200 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184200 0x200>;
-                               interrupts = <0 40 0x04>;
+                               interrupts = <0 42 0x04>;
                                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 42 0x04>;
+                               interrupts = <0 40 0x04>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
index 813b91d7bea25f58288e1a5dc783734af0789f2c..0f06f8687b0bb46581be1b75dce84a4f93e303e5 100644 (file)
@@ -5,6 +5,11 @@
 /include/ "skeleton.dtsi"
 
 / {
+       core-module@10000000 {
+               compatible = "arm,core-module-integrator";
+               reg = <0x10000000 0x200>;
+       };
+
        timer@13000000 {
                reg = <0x13000000 0x100>;
                interrupt-parent = <&pic>;
index b6b82eca8d1e8f2ecd2869aa90b4fd58f8da9afa..e6be9315ff0a54033e07daba296399b8f45112ca 100644 (file)
        };
 
        syscon {
-               /* AP system controller registers */
+               compatible = "arm,integrator-ap-syscon";
                reg = <0x11000000 0x100>;
+               interrupt-parent = <&pic>;
+               /* These are the logical module IRQs */
+               interrupts = <9>, <10>, <11>, <12>;
        };
 
        timer0: timer@13000000 {
index 72693a69f8300421f687f404ffa9f95768ea33d3..7deb3a3182b42513d95bfdf34894692425a62c43 100644 (file)
@@ -13,8 +13,8 @@
                bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
        };
 
-       cpcon {
-               /* CP controller registers */
+       syscon {
+               compatible = "arm,integrator-cp-syscon";
                reg = <0xcb000000 0x100>;
        };
 
diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi
new file mode 100644 (file)
index 0000000..d6713b1
--- /dev/null
@@ -0,0 +1,821 @@
+/*
+ * Device Tree Source for Keystone 2 clock tree
+ *
+ * Copyright (C) 2013 Texas Instruments, 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.
+ */
+
+clocks {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges;
+
+       refclkmain: refclkmain {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <122880000>;
+               clock-output-names = "refclk-main";
+       };
+
+       mainpllclk: mainpllclk@2310110 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,main-pll-clock";
+               clocks = <&refclkmain>;
+               reg = <0x02620350 4>, <0x02310110 4>;
+               reg-names = "control", "multiplier";
+               fixed-postdiv = <2>;
+       };
+
+       papllclk: papllclk@2620358 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkmain>;
+               clock-output-names = "pa-pll-clk";
+               reg = <0x02620358 4>;
+               reg-names = "control";
+               fixed-postdiv = <6>;
+       };
+
+       ddr3allclk: ddr3apllclk@2620360 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkmain>;
+               clock-output-names = "ddr-3a-pll-clk";
+               reg = <0x02620360 4>;
+               reg-names = "control";
+               fixed-postdiv = <6>;
+       };
+
+       ddr3bllclk: ddr3bpllclk@2620368 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkmain>;
+               clock-output-names = "ddr-3b-pll-clk";
+               reg = <0x02620368 4>;
+               reg-names = "control";
+               fixed-postdiv = <6>;
+       };
+
+       armpllclk: armpllclk@2620370 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkmain>;
+               clock-output-names = "arm-pll-clk";
+               reg = <0x02620370 4>;
+               reg-names = "control";
+               fixed-postdiv = <6>;
+       };
+
+       mainmuxclk: mainmuxclk@2310108 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-mux-clock";
+               clocks = <&mainpllclk>, <&refclkmain>;
+               reg = <0x02310108 4>;
+               bit-shift = <23>;
+               bit-mask = <1>;
+               clock-output-names = "mainmuxclk";
+       };
+
+       chipclk1: chipclk1 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&mainmuxclk>;
+               clock-div = <1>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk1";
+       };
+
+       chipclk1rstiso: chipclk1rstiso {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&mainmuxclk>;
+               clock-div = <1>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk1rstiso";
+       };
+
+       gemtraceclk: gemtraceclk@2310120 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-divider-clock";
+               clocks = <&mainmuxclk>;
+               reg = <0x02310120 4>;
+               bit-shift = <0>;
+               bit-mask = <8>;
+               clock-output-names = "gemtraceclk";
+       };
+
+       chipstmxptclk: chipstmxptclk {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-divider-clock";
+               clocks = <&mainmuxclk>;
+               reg = <0x02310164 4>;
+               bit-shift = <0>;
+               bit-mask = <8>;
+               clock-output-names = "chipstmxptclk";
+       };
+
+       chipclk12: chipclk12 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1>;
+               clock-div = <2>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk12";
+       };
+
+       chipclk13: chipclk13 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1>;
+               clock-div = <3>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk13";
+       };
+
+       chipclk14: chipclk14 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1>;
+               clock-div = <4>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk14";
+       };
+
+       chipclk16: chipclk16 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1>;
+               clock-div = <6>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk16";
+       };
+
+       chipclk112: chipclk112 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1>;
+               clock-div = <12>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk112";
+       };
+
+       chipclk124: chipclk124 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1>;
+               clock-div = <24>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk114";
+       };
+
+       chipclk1rstiso13: chipclk1rstiso13 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1rstiso>;
+               clock-div = <3>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk1rstiso13";
+       };
+
+       chipclk1rstiso14: chipclk1rstiso14 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1rstiso>;
+               clock-div = <4>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk1rstiso14";
+       };
+
+       chipclk1rstiso16: chipclk1rstiso16 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1rstiso>;
+               clock-div = <6>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk1rstiso16";
+       };
+
+       chipclk1rstiso112: chipclk1rstiso112 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&chipclk1rstiso>;
+               clock-div = <12>;
+               clock-mult = <1>;
+               clock-output-names = "chipclk1rstiso112";
+       };
+
+       clkmodrst0: clkmodrst0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk16>;
+               clock-output-names = "modrst0";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+
+       clkusb: clkusb {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk16>;
+               clock-output-names = "usb";
+               reg = <0x02350008 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkaemifspi: clkaemifspi {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk16>;
+               clock-output-names = "aemif-spi";
+               reg = <0x0235000c 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+
+       clkdebugsstrc: clkdebugsstrc {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "debugss-trc";
+               reg = <0x02350014 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clktetbtrc: clktetbtrc {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tetb-trc";
+               reg = <0x02350018 0xb00>, <0x02350004 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <1>;
+       };
+
+       clkpa: clkpa {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk16>;
+               clock-output-names = "pa";
+               reg = <0x0235001c 0xb00>, <0x02350008 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <2>;
+       };
+
+       clkcpgmac: clkcpgmac {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkpa>;
+               clock-output-names = "cpgmac";
+               reg = <0x02350020 0xb00>, <0x02350008 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <2>;
+       };
+
+       clksa: clksa {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkpa>;
+               clock-output-names = "sa";
+               reg = <0x02350024 0xb00>, <0x02350008 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <2>;
+       };
+
+       clkpcie: clkpcie {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "pcie";
+               reg = <0x02350028 0xb00>, <0x0235000c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <3>;
+       };
+
+       clksrio: clksrio {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1rstiso13>;
+               clock-output-names = "srio";
+               reg = <0x0235002c 0xb00>, <0x02350010 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <4>;
+       };
+
+       clkhyperlink0: clkhyperlink0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "hyperlink-0";
+               reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <5>;
+       };
+
+       clksr: clksr {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1rstiso112>;
+               clock-output-names = "sr";
+               reg = <0x02350034 0xb00>, <0x02350018 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <6>;
+       };
+
+       clkmsmcsram: clkmsmcsram {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "msmcsram";
+               reg = <0x02350038 0xb00>, <0x0235001c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <7>;
+       };
+
+       clkgem0: clkgem0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem0";
+               reg = <0x0235003c 0xb00>, <0x02350020 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <8>;
+       };
+
+       clkgem1: clkgem1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem1";
+               reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <9>;
+       };
+
+       clkgem2: clkgem2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem2";
+               reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <10>;
+       };
+
+       clkgem3: clkgem3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem3";
+               reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <11>;
+       };
+
+       clkgem4: clkgem4 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem4";
+               reg = <0x0235004c 0xb00>, <0x02350030 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <12>;
+       };
+
+       clkgem5: clkgem5 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem5";
+               reg = <0x02350050 0xb00>, <0x02350034 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <13>;
+       };
+
+       clkgem6: clkgem6 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem6";
+               reg = <0x02350054 0xb00>, <0x02350038 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <14>;
+       };
+
+       clkgem7: clkgem7 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem7";
+               reg = <0x02350058 0xb00>, <0x0235003c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <15>;
+       };
+
+       clkddr30: clkddr30 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "ddr3-0";
+               reg = <0x0235005c 0xb00>, <0x02350040 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <16>;
+       };
+
+       clkddr31: clkddr31 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "ddr3-1";
+               reg = <0x02350060 0xb00>, <0x02350040 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <16>;
+       };
+
+       clktac: clktac {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tac";
+               reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <17>;
+       };
+
+       clkrac01: clktac01 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "rac-01";
+               reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <17>;
+       };
+
+       clkrac23: clktac23 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "rac-23";
+               reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <18>;
+       };
+
+       clkfftc0: clkfftc0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-0";
+               reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <19>;
+       };
+
+       clkfftc1: clkfftc1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-1";
+               reg = <0x02350074 0xb00>, <0x023504c0 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <19>;
+       };
+
+       clkfftc2: clkfftc2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-2";
+               reg = <0x02350078 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkfftc3: clkfftc3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-3";
+               reg = <0x0235007c 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkfftc4: clkfftc4 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-4";
+               reg = <0x02350080 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkfftc5: clkfftc5 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-5";
+               reg = <0x02350084 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkaif: clkaif {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "aif";
+               reg = <0x02350088 0xb00>, <0x02350054 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <21>;
+       };
+
+       clktcp3d0: clktcp3d0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-0";
+               reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <22>;
+       };
+
+       clktcp3d1: clktcp3d1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-1";
+               reg = <0x02350090 0xb00>, <0x02350058 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <22>;
+       };
+
+       clktcp3d2: clktcp3d2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-2";
+               reg = <0x02350094 0xb00>, <0x0235005c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <23>;
+       };
+
+       clktcp3d3: clktcp3d3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-3";
+               reg = <0x02350098 0xb00>, <0x0235005c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <23>;
+       };
+
+       clkvcp0: clkvcp0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-0";
+               reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp1: clkvcp1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-1";
+               reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp2: clkvcp2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-2";
+               reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp3: clkvcp3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-3";
+               reg = <0x0235000a8 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp4: clkvcp4 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-4";
+               reg = <0x023500ac 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkvcp5: clkvcp5 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-5";
+               reg = <0x023500b0 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkvcp6: clkvcp6 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-6";
+               reg = <0x023500b4 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkvcp7: clkvcp7 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-7";
+               reg = <0x023500b8 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkbcp: clkbcp {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "bcp";
+               reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <26>;
+       };
+
+       clkdxb: clkdxb {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "dxb";
+               reg = <0x023500c0 0xb00>, <0x0235006c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <27>;
+       };
+
+       clkhyperlink1: clkhyperlink1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "hyperlink-1";
+               reg = <0x023500c4 0xb00>, <0x02350070 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <28>;
+       };
+
+       clkxge: clkxge {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "xge";
+               reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <29>;
+       };
+
+       clkwdtimer0: clkwdtimer0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "timer0";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkwdtimer1: clkwdtimer1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "timer1";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkwdtimer2: clkwdtimer2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "timer2";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkwdtimer3: clkwdtimer3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "timer3";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkuart0: clkuart0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "uart0";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkuart1: clkuart1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "uart1";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkaemif: clkaemif {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkaemifspi>;
+               clock-output-names = "aemif";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkusim: clkusim {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "usim";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clki2c: clki2c {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "i2c";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkspi: clkspi {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkaemifspi>;
+               clock-output-names = "spi";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkgpio: clkgpio {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "gpio";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkkeymgr: clkkeymgr {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "keymgr";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+};
index a68e34bbecb2628d21fcfb018cb9567f722efc3b..100bdf52b8478d61b558750924b845842ad32a83 100644 (file)
                        reg = <0x023100e8 4>;   /* pll reset control reg */
                };
 
+               /include/ "keystone-clocks.dtsi"
+
                uart0: serial@02530c00 {
                        compatible = "ns16550a";
                        current-speed = <115200>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        reg = <0x02530c00 0x100>;
-                       clock-frequency = <133120000>;
+                       clocks  = <&clkuart0>;
                        interrupts = <GIC_SPI 277 IRQ_TYPE_EDGE_RISING>;
                };
 
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        reg = <0x02531000 0x100>;
-                       clock-frequency = <133120000>;
+                       clocks  = <&clkuart1>;
                        interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>;
                };
 
+               i2c0: i2c@2530000 {
+                       compatible = "ti,davinci-i2c";
+                       reg = <0x02530000 0x400>;
+                       clock-frequency = <100000>;
+                       clocks = <&clki2c>;
+                       interrupts = <GIC_SPI 283 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       dtt@50 {
+                               compatible = "at,24c1024";
+                               reg = <0x50>;
+                       };
+               };
+
+               i2c1: i2c@2530400 {
+                       compatible = "ti,davinci-i2c";
+                       reg = <0x02530400 0x400>;
+                       clock-frequency = <100000>;
+                       clocks = <&clki2c>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_EDGE_RISING>;
+               };
+
+               i2c2: i2c@2530800 {
+                       compatible = "ti,davinci-i2c";
+                       reg = <0x02530800 0x400>;
+                       clock-frequency = <100000>;
+                       clocks = <&clki2c>;
+                       interrupts = <GIC_SPI 289 IRQ_TYPE_EDGE_RISING>;
+               };
+
+               spi0: spi@21000400 {
+                       compatible = "ti,dm6441-spi";
+                       reg = <0x21000400 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 292 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkspi>;
+               };
+
+               spi1: spi@21000600 {
+                       compatible = "ti,dm6441-spi";
+                       reg = <0x21000600 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkspi>;
+               };
+
+               spi2: spi@21000800 {
+                       compatible = "ti,dm6441-spi";
+                       reg = <0x21000800 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 300 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkspi>;
+               };
        };
 };
index 72c4b0a0366ffcd656f16456c430b067ff814b5a..c39dd766c75a03caf11e0a79e71d3a25778fd33b 100644 (file)
@@ -19,7 +19,6 @@
        compatible = "marvell,db-88f6281-bp", "marvell,kirkwood-88f6281", "marvell,kirkwood";
 
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
index 36c411d349268e41e05d220f3d56e2d82553506e..701c6b6cdaa2ffd82b49ac2a0fe145e1e9d626a5 100644 (file)
@@ -19,7 +19,6 @@
        compatible = "marvell,db-88f6282-bp", "marvell,kirkwood-88f6282", "marvell,kirkwood";
 
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
index c0e2a587917474a37a515ff7c70e133ee193f0ba..053aa20fb30f88a0e13be1878e9d9d6ba241c4c2 100644 (file)
                        status = "ok";
                };
 
-               nand@3000000 {
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-                       chip-delay = <25>;
-                       status = "okay";
-
-                       partition@0 {
-                               label = "uboot";
-                               reg = <0x0 0x100000>;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x100000 0x400000>;
-                       };
-
-                       partition@500000 {
-                               label = "root";
-                               reg = <0x500000 0x1fb00000>;
-                       };
-               };
-
                sata@80000 {
                        nr-ports = <2>;
                        status = "okay";
        };
 };
 
+&nand {
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+       chip-delay = <25>;
+       status = "okay";
+
+       partition@0 {
+               label = "uboot";
+               reg = <0x0 0x100000>;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x100000 0x400000>;
+       };
+
+       partition@500000 {
+               label = "root";
+               reg = <0x500000 0x1fb00000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index d544f77a4ca465ccc268b90d5edc9c1ca9aee490..aefa375a550d3ac0e7615cd76ba50e83c99ac094 100644 (file)
                        status = "okay";
                        nr-ports = <2>;
                };
-
-               nand@3000000 {
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-                       status = "okay";
-                       chip-delay = <35>;
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x100000>;
-                               read-only;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x0100000 0x500000>;
-                       };
-
-                       partition@600000 {
-                               label = "ramdisk";
-                               reg = <0x0600000 0x500000>;
-                       };
-
-                       partition@b00000 {
-                               label = "image";
-                               reg = <0x0b00000 0x6600000>;
-                       };
-
-                       partition@7100000 {
-                               label = "mini firmware";
-                               reg = <0x7100000 0xa00000>;
-                       };
-
-                       partition@7b00000 {
-                               label = "config";
-                               reg = <0x7b00000 0x500000>;
-                       };
-               };
        };
 
        regulators {
        };
 };
 
+&nand {
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+       status = "okay";
+       chip-delay = <35>;
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x100000>;
+               read-only;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x0100000 0x500000>;
+       };
+
+       partition@600000 {
+               label = "ramdisk";
+               reg = <0x0600000 0x500000>;
+       };
+
+       partition@b00000 {
+               label = "image";
+               reg = <0x0b00000 0x6600000>;
+       };
+
+       partition@7100000 {
+               label = "mini firmware";
+               reg = <0x7100000 0xa00000>;
+       };
+
+       partition@7b00000 {
+               label = "config";
+               reg = <0x7b00000 0x500000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 59a2117c35a7fe2dc68f2b5f7171810dd60532d1..33ff368fbfa5696353353fc5151b4fefd7cc6198 100644 (file)
                serial@12000 {
                        status = "ok";
                };
-
-               nand@3000000 {
-                       status = "okay";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x100000>;
-                               read-only;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x0100000 0x400000>;
-                       };
-
-                       partition@500000 {
-                               label = "data";
-                               reg = <0x0500000 0xfb00000>;
-                       };
-               };
        };
        gpio-leds {
                compatible = "gpio-leds";
        };
 };
 
+&nand {
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x100000>;
+               read-only;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x0100000 0x400000>;
+       };
+
+       partition@500000 {
+               label = "data";
+               reg = <0x0500000 0xfb00000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 6f7c7d7ecf2acf74bcd5a11f2122c30aea72fb3a..a43bebb251102fbbfcde84e58f1955ce52f5de5b 100644 (file)
                        status = "ok";
                };
 
-               nand@3000000 {
-                       chip-delay = <40>;
-                       status = "okay";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x100000>;
-                               read-only;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x0100000 0x400000>;
-                       };
-
-                       partition@500000 {
-                               label = "pogoplug";
-                               reg = <0x0500000 0x2000000>;
-                       };
-
-                       partition@2500000 {
-                               label = "root";
-                               reg = <0x02500000 0xd800000>;
-                       };
-               };
                sata@80000 {
                        status = "okay";
                        nr-ports = <2>;
        };
 };
 
+&nand {
+       chip-delay = <40>;
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x100000>;
+               read-only;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x0100000 0x400000>;
+       };
+
+       partition@500000 {
+               label = "pogoplug";
+               reg = <0x0500000 0x2000000>;
+       };
+
+       partition@2500000 {
+               label = "root";
+               reg = <0x02500000 0xd800000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 6548b9dc685560887f3771156f74987e5842d918..d30a91a5047d6939c2dfdd69989bde39c359f9b7 100644 (file)
                        status = "ok";
                };
 
-               nand@3000000 {
-                       status = "okay";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x00000000 0x00100000>;
-                               read-only;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x00100000 0x00400000>;
-                       };
-
-                       partition@500000 {
-                               label = "data";
-                               reg = <0x00500000 0x1fb00000>;
-                       };
-               };
-
                sata@80000 {
                        status = "okay";
                        nr-ports = <1>;
        };
 };
 
+&nand {
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x00000000 0x00100000>;
+               read-only;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x00100000 0x00400000>;
+       };
+
+       partition@500000 {
+               label = "data";
+               reg = <0x00500000 0x1fb00000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index cb711a3bd9833f3061060783fe38357bbf65cce3..c5fb02f7ebc3e33107ac067d46a6394d6c21b27d 100644 (file)
@@ -5,7 +5,7 @@
 
 / {
        model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
-       compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0",  "marvell,kirkwood-88f6281", "marvell,kirkwood";
+       compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
 
        memory {
                device_type = "memory";
@@ -43,6 +43,7 @@
                                marvell,function = "gpio";
                        };
                };
+
                serial@12000 {
                        status = "okay";
                };
                        status = "okay";
                        nr-ports = <2>;
                };
-
-               nand@3000000 {
-                       status = "okay";
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x100000>;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x0100000 0x600000>;
-                       };
-
-                       partition@700000 {
-                               label = "root";
-                               reg = <0x0700000 0xf900000>;
-                       };
-
-               };
        };
 
        gpio_keys {
@@ -93,6 +72,7 @@
                        gpios = <&gpio0 28 1>;
                };
        };
+
        gpio-leds {
                compatible = "gpio-leds";
                pinctrl-0 = <&pmx_led_os_red &pmx_led_os_green
                        gpios = <&gpio0 27 0>;
                };
        };
+
        gpio_poweroff {
                compatible = "gpio-poweroff";
                pinctrl-0 = <&pmx_power_off>;
                pinctrl-names = "default";
                gpios = <&gpio0 24 0>;
        };
+};
+
+&nand {
+       status = "okay";
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0xe0000>;
+       };
 
+       partition@e0000 {
+               label = "u-boot environment";
+               reg = <0xe0000 0x100000>;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x0100000 0x600000>;
+       };
+
+       partition@700000 {
+               label = "root";
+               reg = <0x0700000 0xf900000>;
+       };
 
 };
 
 
 &eth0 {
        status = "okay";
+
        ethernet0-port@0 {
                phy-handle = <&ethphy0>;
        };
index 0323f017eeedecbc9ea3acc64d632b16b15103cd..4a62b206f680b4c1261a404ce16ce26fb498f6c0 100644 (file)
@@ -19,7 +19,6 @@
        };
 
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
                serial@12000 {
                        status = "ok";
                };
-
-               nand@3000000 {
-                       status = "okay";
-
-                       partition@0 {
-                               label = "uboot";
-                               reg = <0x0000000 0xc0000>;
-                       };
-
-                       partition@a0000 {
-                               label = "env";
-                               reg = <0xa0000 0x20000>;
-                       };
-
-                       partition@100000 {
-                               label = "zImage";
-                               reg = <0x100000 0x300000>;
-                       };
-
-                       partition@540000 {
-                               label = "initrd";
-                               reg = <0x540000 0x300000>;
-                       };
-
-                       partition@980000 {
-                               label = "boot";
-                               reg = <0x980000 0x1f400000>;
-                       };
-               };
        };
 
        gpio-leds {
        };
 };
 
+&nand {
+       status = "okay";
+
+       partition@0 {
+               label = "uboot";
+               reg = <0x0000000 0xc0000>;
+       };
+
+       partition@a0000 {
+               label = "env";
+               reg = <0xa0000 0x20000>;
+       };
+
+       partition@100000 {
+               label = "zImage";
+               reg = <0x100000 0x300000>;
+       };
+
+       partition@540000 {
+               label = "initrd";
+               reg = <0x540000 0x300000>;
+       };
+
+       partition@980000 {
+               label = "boot";
+               reg = <0x980000 0x1f400000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index df8447442b37b406332766ece95f83677ea53819..d15395d671ededf4caf501518bb1e33ffba0cba8 100644 (file)
                        status = "ok";
                };
 
-               nand@3000000 {
-                       status = "okay";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x100000>;
-                               read-only;
-                       };
-
-                       partition@a0000 {
-                               label = "env";
-                               reg = <0xa0000 0x20000>;
-                               read-only;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x100000 0x300000>;
-                       };
-
-                       partition@400000 {
-                               label = "uInitrd";
-                               reg = <0x540000 0x1000000>;
-                       };
-               };
                sata@80000 {
                        status = "okay";
                        nr-ports = <2>;
        };
 };
 
+&nand {
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x100000>;
+               read-only;
+       };
+
+       partition@a0000 {
+               label = "env";
+               reg = <0xa0000 0x20000>;
+               read-only;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x100000 0x300000>;
+       };
+
+       partition@400000 {
+               label = "uInitrd";
+               reg = <0x540000 0x1000000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 6899408482d24c1cf2229add5ba8f63fd07f8645..cd44f37e54b5b7fb81f6c53f966abc9e3e511c8e 100644 (file)
                serial@12000 {
                        status = "ok";
                };
-
-               nand@3000000 {
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-                       status = "ok";
-                       chip-delay = <25>;
-               };
        };
 
        i2c@0 {
        };
 };
 
+&nand {
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+       status = "ok";
+       chip-delay = <25>;
+};
+
 &mdio {
        status = "okay";
 
index ce2b94b513dbe1dc20478e7b8287864a13c1cb89..6c1ec2786e6e2f77c334292bab84b4e24d4cfef6 100644 (file)
@@ -17,7 +17,6 @@
         };
 
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
                         pinctrl-names = "default";
                 };
 
-                nand@3000000 {
-                        pinctrl-0 = <&pmx_nand>;
-                        pinctrl-names = "default";
-                        status = "okay";
-
-                        partition@0 {
-                                label = "uboot";
-                                reg = <0x0000000 0x100000>;
-                        };
-
-                        partition@100000 {
-                                label = "env";
-                                reg = <0x100000 0x80000>;
-                        };
-
-                        partition@180000 {
-                                label = "fdt";
-                                reg = <0x180000 0x80000>;
-                        };
-
-                        partition@200000 {
-                                label = "kernel";
-                                reg = <0x200000 0x400000>;
-                        };
-
-                        partition@600000 {
-                                label = "rootfs";
-                                reg = <0x600000 0x1fa00000>;
-                        };
-                };
-
                rtc@10300 {
                        status = "disabled";
                };
        };
 };
 
+&nand {
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       partition@0 {
+               label = "uboot";
+               reg = <0x0000000 0x100000>;
+       };
+
+       partition@100000 {
+               label = "env";
+               reg = <0x100000 0x80000>;
+       };
+
+       partition@180000 {
+               label = "fdt";
+               reg = <0x180000 0x80000>;
+       };
+
+       partition@200000 {
+               label = "kernel";
+               reg = <0x200000 0x400000>;
+       };
+
+       partition@600000 {
+               label = "rootfs";
+               reg = <0x600000 0x1fa00000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 874857ea9cb8c8a80fc812609a2b3cd368cb40df..e6a102cf424cd646d9e121acd2b821ea46bb81be 100644 (file)
@@ -17,7 +17,6 @@
        };
 
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
                        status = "okay";
                };
 
-               nand@3000000 {
-                       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>;
-                       };
-               };
-
                sata@80000 {
                        status = "okay";
                        nr-ports = <2>;
         };
 };
 
+&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";
 
index 06267a91de38d7aa4bd1dc69f1e61bf39047faec..e3f915defd3da6174ad0e1829cf1be0c15e38f80 100644 (file)
                        nr-ports = <2>;
                };
 
-               nand@3000000 {
-                       status = "okay";
-                       chip-delay = <35>;
-
-                       partition@0 {
-                               label = "uboot";
-                               reg = <0x0000000 0x0100000>;
-                               read-only;
-                       };
-                       partition@100000 {
-                               label = "uboot_env";
-                               reg = <0x0100000 0x0080000>;
-                       };
-                       partition@180000 {
-                               label = "key_store";
-                               reg = <0x0180000 0x0080000>;
-                       };
-                       partition@200000 {
-                               label = "info";
-                               reg = <0x0200000 0x0080000>;
-                       };
-                       partition@280000 {
-                               label = "etc";
-                               reg = <0x0280000 0x0a00000>;
-                       };
-                       partition@c80000 {
-                               label = "kernel_1";
-                               reg = <0x0c80000 0x0a00000>;
-                       };
-                       partition@1680000 {
-                               label = "rootfs1";
-                               reg = <0x1680000 0x2fc0000>;
-                       };
-                       partition@4640000 {
-                               label = "kernel_2";
-                               reg = <0x4640000 0x0a00000>;
-                       };
-                       partition@5040000 {
-                               label = "rootfs2";
-                               reg = <0x5040000 0x2fc0000>;
-                       };
-               };
-
                pcie-controller {
                        status = "okay";
 
                };
        };
 };
+
+&nand {
+       status = "okay";
+       chip-delay = <35>;
+
+       partition@0 {
+               label = "uboot";
+               reg = <0x0000000 0x0100000>;
+               read-only;
+       };
+       partition@100000 {
+               label = "uboot_env";
+               reg = <0x0100000 0x0080000>;
+       };
+       partition@180000 {
+               label = "key_store";
+               reg = <0x0180000 0x0080000>;
+       };
+       partition@200000 {
+               label = "info";
+               reg = <0x0200000 0x0080000>;
+       };
+       partition@280000 {
+               label = "etc";
+               reg = <0x0280000 0x0a00000>;
+       };
+       partition@c80000 {
+               label = "kernel_1";
+               reg = <0x0c80000 0x0a00000>;
+       };
+       partition@1680000 {
+               label = "rootfs1";
+               reg = <0x1680000 0x2fc0000>;
+       };
+       partition@4640000 {
+               label = "kernel_2";
+               reg = <0x4640000 0x0a00000>;
+       };
+       partition@5040000 {
+               label = "rootfs2";
+               reg = <0x5040000 0x2fc0000>;
+       };
+};
index 7aeae0c2c1f498bd31fd6572b278dbe944eab107..b5418bcaeccead3b1313074c5ebf885d5f8f0e49 100644 (file)
@@ -15,7 +15,6 @@
        };
 
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
index 85ccf8d8abb133bf62289ddd6adb0ef218764eae..f0e3d213604c975b760173bc854d624d68e38ccd 100644 (file)
                        pinctrl-names = "default";
                };
 
-               nand@3000000 {
-                       chip-delay = <25>;
-                       status = "okay";
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-
-                       partition@0 {
-                               label = "uboot";
-                               reg = <0x0 0x90000>;
-                       };
-
-                       partition@90000 {
-                               label = "env";
-                               reg = <0x90000 0x44000>;
-                       };
-
-                       partition@d4000 {
-                               label = "test";
-                               reg = <0xd4000 0x24000>;
-                       };
-
-                       partition@f4000 {
-                               label = "conf";
-                               reg = <0xf4000 0x400000>;
-                       };
-
-                       partition@4f4000 {
-                               label = "linux";
-                               reg = <0x4f4000 0x1d20000>;
-                       };
-
-                       partition@2214000 {
-                               label = "user";
-                               reg = <0x2214000 0x1dec000>;
-                       };
-               };
-
                sata@80000 {
                        nr-ports = <1>;
                        status = "okay";
        };
 };
 
+&nand {
+       chip-delay = <25>;
+       status = "okay";
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+
+       partition@0 {
+               label = "uboot";
+               reg = <0x0 0x90000>;
+       };
+
+       partition@90000 {
+               label = "env";
+               reg = <0x90000 0x44000>;
+       };
+
+       partition@d4000 {
+               label = "test";
+               reg = <0xd4000 0x24000>;
+       };
+
+       partition@f4000 {
+               label = "conf";
+               reg = <0xf4000 0x400000>;
+       };
+
+       partition@4f4000 {
+               label = "linux";
+               reg = <0x4f4000 0x1d20000>;
+       };
+
+       partition@2214000 {
+               label = "user";
+               reg = <0x2214000 0x1dec000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts
new file mode 100644 (file)
index 0000000..851fb2a
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Device Tree file for OpenBlocks A7 board
+ *
+ * Copyright (C) 2013 Free Electrons
+ *
+ * Thomas Petazzoni <thomas.petazzoni@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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+       model = "Plat'Home OpenBlocksA7";
+       compatible = "plathome,openblocks-a7", "marvell,kirkwood-88f6283", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000>; /* 1 GB */
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk";
+       };
+
+       ocp@f1000000 {
+               serial@12000 {
+                       status = "ok";
+                       pinctrl-0 = <&pmx_uart0>;
+                       pinctrl-names = "default";
+               };
+
+               serial@12100 {
+                       status = "ok";
+                       pinctrl-0 = <&pmx_uart1>;
+                       pinctrl-names = "default";
+               };
+
+               sata@80000 {
+                       nr-ports = <1>;
+                       status = "okay";
+               };
+
+               i2c@11100 {
+                       status = "okay";
+                       pinctrl-0 = <&pmx_twsi1>;
+                       pinctrl-names = "default";
+
+                       s24c02: s24c02@50 {
+                               compatible = "24c02";
+                               reg = <0x50>;
+                       };
+               };
+
+               pinctrl: pinctrl@10000 {
+                       pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header>;
+                       pinctrl-names = "default";
+
+                       pmx_uart0: pmx-uart0 {
+                               marvell,pins = "mpp10", "mpp11", "mpp15",
+                                       "mpp16";
+                               marvell,function = "uart0";
+                       };
+
+                       pmx_uart1: pmx-uart1 {
+                               marvell,pins = "mpp13", "mpp14", "mpp8",
+                                       "mpp9";
+                               marvell,function = "uart1";
+                       };
+
+                       pmx_sysrst: pmx-sysrst {
+                               marvell,pins = "mpp6";
+                               marvell,function = "sysrst";
+                       };
+
+                       pmx_dip_switches: pmx-dip-switches {
+                               marvell,pins = "mpp44", "mpp45", "mpp46", "mpp47";
+                               marvell,function = "gpio";
+                       };
+
+                       /*
+                        * Accessible on connector J202. The MPP
+                        * listed below are pin 1-7, pin 8 is unused,
+                        * pin 9 is external reset input and pin 10 is
+                        * ground.
+                        */
+                       pmx_gpio_header: pmx-gpio-header {
+                               marvell,pins = "mpp17", "mpp7", "mpp29", "mpp28",
+                                              "mpp35", "mpp34", "mpp40";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_gpio_init: pmx-init {
+                               marvell,pins = "mpp38";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_usb_oc: pmx-usb-oc {
+                               marvell,pins = "mpp39";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_leds: pmx-leds {
+                               marvell,pins = "mpp41", "mpp42", "mpp43";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_ge1: pmx-ge1 {
+                               marvell,pins = "mpp20", "mpp21", "mpp22", "mpp23",
+                                              "mpp24", "mpp25", "mpp26", "mpp27",
+                                              "mpp30", "mpp31", "mpp32", "mpp33";
+                               marvell,function = "ge1";
+                       };
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_leds>;
+               pinctrl-names = "default";
+
+               led-red {
+                       label = "obsa7:red:stat";
+                       gpios = <&gpio1 9 1>;
+               };
+
+               led-green {
+                       label = "obsa7:green:stat";
+                       gpios = <&gpio1 10 1>;
+               };
+
+               led-yellow {
+                       label = "obsa7:yellow:stat";
+                       gpios = <&gpio1 11 1>;
+               };
+        };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&pmx_gpio_init>;
+               pinctrl-names = "default";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               button@1 {
+                       label = "Init Button";
+                       linux,code = <116>;
+                       gpios = <&gpio1 6 0>;
+               };
+       };
+};
+
+&nand {
+       chip-delay = <25>;
+       status = "okay";
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+
+       partition@0 {
+               label = "uboot";
+               reg = <0x0 0x1c0000>;
+       };
+
+       partition@1c0000 {
+               label = "env";
+               reg = <0x1c0000 0x2c0000>;
+       };
+
+       partition@480000 {
+               label = "test";
+               reg = <0x480000 0x160000>;
+       };
+
+       partition@5e0000 {
+               label = "conf";
+               reg = <0x5e0000 0x540000>;
+       };
+
+       partition@b20000 {
+               label = "linux";
+               reg = <0xb20000 0x3d40000>;
+       };
+
+       partition@4860000 {
+               label = "user";
+               reg = <0x4860000 0xb7a0000>;
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               device_type = "ethernet-phy";
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               device_type = "ethernet-phy";
+               reg = <1>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
+
+&eth1 {
+       status = "okay";
+       pinctrl-0 = <&pmx_ge1>;
+       pinctrl-names = "default";
+       ethernet1-port@0 {
+               phy-handle = <&ethphy1>;
+       };
+};
index 5696b630b70bb0c19fb0d4bc38b17342cd5a5228..1173d7fb31b23f9e11565a45592fcb99f17e41bf 100644 (file)
                        pinctrl-names = "default";
                        status = "okay";
                };
-
-               nand@3000000 {
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-                       status = "okay";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x100000>;
-                       };
-
-                       partition@100000 {
-                               label = "uImage";
-                               reg = <0x0100000 0x400000>;
-                       };
-
-                       partition@500000 {
-                               label = "root";
-                               reg = <0x0500000 0x1fb00000>;
-                       };
-               };
        };
 
        regulators {
        };
 };
 
+&nand {
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x100000>;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x0100000 0x400000>;
+       };
+
+       partition@500000 {
+               label = "root";
+               reg = <0x0500000 0x1fb00000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 30842b4ff29394185f61d3cc702ddcd192000043..320da677b9847e94f0aba2bcc634bd90890686a6 100644 (file)
                        pinctrl-names = "default";
                };
 
-               nand@3000000 {
-                       status = "okay";
-                       pinctrl-0 = <&pmx_nand>;
-                       pinctrl-names = "default";
-
-                       partition@0 {
-                               label = "u-boot";
-                               reg = <0x0000000 0x180000>;
-                       };
-
-                       partition@180000 {
-                               label = "u-boot env";
-                               reg = <0x0180000 0x20000>;
-                       };
-
-                       partition@200000 {
-                               label = "uImage";
-                               reg = <0x0200000 0x600000>;
-                       };
-
-                       partition@800000 {
-                               label = "uInitrd";
-                               reg = <0x0800000 0x1000000>;
-                       };
-
-                       partition@1800000 {
-                               label = "rootfs";
-                               reg = <0x1800000 0xe800000>;
-                       };
-               };
-
                sata@80000 {
                        status = "okay";
                        nr-ports = <1>;
        };
 };
 
+&nand {
+       status = "okay";
+       pinctrl-0 = <&pmx_nand>;
+       pinctrl-names = "default";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x180000>;
+       };
+
+       partition@180000 {
+               label = "u-boot env";
+               reg = <0x0180000 0x20000>;
+       };
+
+       partition@200000 {
+               label = "uImage";
+               reg = <0x0200000 0x600000>;
+       };
+
+       partition@800000 {
+               label = "uInitrd";
+               reg = <0x0800000 0x1000000>;
+       };
+
+       partition@1800000 {
+               label = "rootfs";
+               reg = <0x1800000 0xe800000>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 9efcd2dc79d3f74eaffb2b95bc9ff4fb9c7662db..345562f7589182975d27ae5e95b1e4319bc7f843 100644 (file)
@@ -6,7 +6,6 @@
 
 / {
        mbus {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
                pcie-controller {
                        status = "okay";
 
index 1335b2e1bed4c66efe95ee2f679129d3856ccb43..8b73c80f1dad40995be65547ee5caa4a4fbffdaa 100644 (file)
                compatible = "marvell,kirkwood-mbus", "simple-bus";
                #address-cells = <2>;
                #size-cells = <1>;
+               /* If a board file needs to change this ranges it must replace it completely */
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000     /* internal-regs */
+                         MBUS_ID(0x01, 0x2f) 0 0xf4000000 0x10000      /* nand flash */
+                         MBUS_ID(0x03, 0x01) 0 0xf5000000 0x10000      /* crypto sram */
+                         >;
                controller = <&mbusc>;
                pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256 MiB memory space */
                pcie-io-aperture  = <0xf2000000 0x100000>;   /*   1 MiB    I/O space */
+
+               crypto@0301 {
+                       compatible = "marvell,orion-crypto";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x30000 0x10000>,
+                             <MBUS_ID(0x03, 0x01) 0 0x800>;
+                       reg-names = "regs", "sram";
+                       interrupts = <22>;
+                       clocks = <&gate_clk 17>;
+                       status = "okay";
+               };
+
+               nand: nand@012f {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cle = <0>;
+                       ale = <1>;
+                       bank-width = <1>;
+                       compatible = "marvell,orion-nand";
+                       reg = <MBUS_ID(0x01, 0x2f) 0 0x400>;
+                       chip-delay = <25>;
+                       /* set partition map and/or chip-delay in board dts */
+                       clocks = <&gate_clk 7>;
+                       status = "disabled";
+               };
        };
 
        ocp@f1000000 {
                compatible = "simple-bus";
-               ranges = <0x00000000 0xf1000000 0x0100000
-                         0xf4000000 0xf4000000 0x0000400
-                         0xf5000000 0xf5000000 0x0000400>;
+               ranges = <0x00000000 0xf1000000 0x0100000>;
                #address-cells = <1>;
                #size-cells = <1>;
 
                        status = "okay";
                };
 
-               nand@3000000 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       cle = <0>;
-                       ale = <1>;
-                       bank-width = <1>;
-                       compatible = "marvell,orion-nand";
-                       reg = <0xf4000000 0x400>;
-                       chip-delay = <25>;
-                       /* set partition map and/or chip-delay in board dts */
-                       clocks = <&gate_clk 7>;
-                       status = "disabled";
-               };
-
                i2c@11000 {
                        compatible = "marvell,mv64xxx-i2c";
                        reg = <0x11000 0x20>;
                        status = "disabled";
                };
 
-               crypto@30000 {
-                       compatible = "marvell,orion-crypto";
-                       reg = <0x30000 0x10000>,
-                             <0xf5000000 0x800>;
-                       reg-names = "regs", "sram";
-                       interrupts = <22>;
-                       clocks = <&gate_clk 17>;
-                       status = "okay";
-               };
-
                mdio: mdio-bus@72004 {
                        compatible = "marvell,orion-mdio";
                        #address-cells = <1>;
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts
deleted file mode 100644 (file)
index 386d428..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/dts-v1/;
-
-/include/ "skeleton.dtsi"
-
-/ {
-       model = "Qualcomm MSM8660 SURF";
-       compatible = "qcom,msm8660-surf", "qcom,msm8660";
-       interrupt-parent = <&intc>;
-
-       intc: interrupt-controller@2080000 {
-               compatible = "qcom,msm-8660-qgic";
-               interrupt-controller;
-               #interrupt-cells = <3>;
-               reg = < 0x02080000 0x1000 >,
-                     < 0x02081000 0x1000 >;
-       };
-
-       timer@2000000 {
-               compatible = "qcom,scss-timer", "qcom,msm-timer";
-               interrupts = <1 0 0x301>,
-                            <1 1 0x301>,
-                            <1 2 0x301>;
-               reg = <0x02000000 0x100>;
-               clock-frequency = <27000000>,
-                                 <32768>;
-               cpu-offset = <0x40000>;
-       };
-
-       msmgpio: gpio@800000 {
-               compatible = "qcom,msm-gpio";
-               reg = <0x00800000 0x1000>;
-               gpio-controller;
-               #gpio-cells = <2>;
-               ngpio = <173>;
-               interrupts = <0 32 0x4>;
-               interrupt-controller;
-               #interrupt-cells = <2>;
-       };
-
-       serial@19c40000 {
-               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-               reg = <0x19c40000 0x1000>,
-                     <0x19c00000 0x1000>;
-               interrupts = <0 195 0x0>;
-       };
-
-       qcom,ssbi@500000 {
-               compatible = "qcom,ssbi";
-               reg = <0x500000 0x1000>;
-               qcom,controller-type = "pmic-arbiter";
-       };
-};
diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/msm8960-cdp.dts
deleted file mode 100644 (file)
index 93e9f7e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/dts-v1/;
-
-/include/ "skeleton.dtsi"
-
-/ {
-       model = "Qualcomm MSM8960 CDP";
-       compatible = "qcom,msm8960-cdp", "qcom,msm8960";
-       interrupt-parent = <&intc>;
-
-       intc: interrupt-controller@2000000 {
-               compatible = "qcom,msm-qgic2";
-               interrupt-controller;
-               #interrupt-cells = <3>;
-               reg = < 0x02000000 0x1000 >,
-                     < 0x02002000 0x1000 >;
-       };
-
-       timer@200a000 {
-               compatible = "qcom,kpss-timer", "qcom,msm-timer";
-               interrupts = <1 1 0x301>,
-                            <1 2 0x301>,
-                            <1 3 0x301>;
-               reg = <0x0200a000 0x100>;
-               clock-frequency = <27000000>,
-                                 <32768>;
-               cpu-offset = <0x80000>;
-       };
-
-       msmgpio: gpio@800000 {
-               compatible = "qcom,msm-gpio";
-               gpio-controller;
-               #gpio-cells = <2>;
-               ngpio = <150>;
-               interrupts = <0 32 0x4>;
-               interrupt-controller;
-               #interrupt-cells = <2>;
-               reg = <0x800000 0x4000>;
-       };
-
-       serial@16440000 {
-               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-               reg = <0x16440000 0x1000>,
-                     <0x16400000 0x1000>;
-               interrupts = <0 154 0x0>;
-       };
-
-       qcom,ssbi@500000 {
-               compatible = "qcom,ssbi";
-               reg = <0x500000 0x1000>;
-               qcom,controller-type = "pmic-arbiter";
-       };
-};
diff --git a/arch/arm/boot/dts/mxs-pinfunc.h b/arch/arm/boot/dts/mxs-pinfunc.h
new file mode 100644 (file)
index 0000000..c6da987
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MXS_PINCTRL_H__
+#define __DT_BINDINGS_MXS_PINCTRL_H__
+
+/* fsl,drive-strength property */
+#define MXS_DRIVE_4mA          0
+#define MXS_DRIVE_8mA          1
+#define MXS_DRIVE_12mA         2
+#define MXS_DRIVE_16mA         3
+
+/* fsl,voltage property */
+#define MXS_VOLTAGE_LOW                0
+#define MXS_VOLTAGE_HIGH       1
+
+/* fsl,pull-up property */
+#define MXS_PULL_DISABLE       0
+#define MXS_PULL_ENABLE                1
+
+#endif /* __DT_BINDINGS_MXS_PINCTRL_H__ */
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
new file mode 100644 (file)
index 0000000..9c18adf
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Common file for GPMC connected smsc911x on omaps
+ *
+ * Note that the board specifc DTS file needs to specify
+ * ranges, pinctrl, reg, interrupt parent and interrupts.
+ */
+
+/ {
+       vddvario: regulator-vddvario {
+                 compatible = "regulator-fixed";
+                 regulator-name = "vddvario";
+                 regulator-always-on;
+       };
+
+       vdd33a: regulator-vdd33a {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd33a";
+               regulator-always-on;
+       };
+};
+
+&gpmc {
+       ethernet@gpmc {
+               compatible = "smsc,lan9221", "smsc,lan9115";
+               bank-width = <2>;
+               gpmc,mux-add-data;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <186>;
+               gpmc,cs-wr-off-ns = <186>;
+               gpmc,adv-on-ns = <12>;
+               gpmc,adv-rd-off-ns = <48>;
+               gpmc,adv-wr-off-ns = <48>;
+               gpmc,oe-on-ns = <54>;
+               gpmc,oe-off-ns = <168>;
+               gpmc,we-on-ns = <54>;
+               gpmc,we-off-ns = <168>;
+               gpmc,rd-cycle-ns = <186>;
+               gpmc,wr-cycle-ns = <186>;
+               gpmc,access-ns = <114>;
+               gpmc,page-burst-access-ns = <6>;
+               gpmc,bus-turnaround-ns = <12>;
+               gpmc,cycle2cycle-delay-ns = <18>;
+               gpmc,wr-data-mux-bus-ns = <90>;
+               gpmc,wr-access-ns = <186>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-diffcsen;
+               vmmc-supply = <&vddvario>;
+               vmmc_aux-supply = <&vdd33a>;
+               reg-io-width = <4>;
+               smsc,save-mac-address;
+       };
+};
diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi
new file mode 100644 (file)
index 0000000..b0ee342
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Common features on the Zoom debug board
+ */
+
+#include "omap-gpmc-smsc911x.dtsi"
+
+&gpmc {
+       ranges = <3 0 0x10000000 0x00000400>,
+                <7 0 0x2c000000 0x01000000>;
+
+       /*
+        * Four port TL16CP754C serial port on GPMC,
+        * they probably share the same GPIO IRQ
+        * REVISIT: Add timing support from slls644g.pdf
+        */
+       8250@3,0 {
+               compatible = "ns16550a";
+               reg = <3 0 0x100>;
+               bank-width = <2>;
+               reg-shift = <1>;
+               reg-io-width = <1>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <6 IRQ_TYPE_EDGE_RISING>;  /* gpio102 */
+               clock-frequency = <1843200>;
+               current-speed = <115200>;
+       };
+
+       ethernet@gpmc {
+               reg = <7 0 0xff>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <30 IRQ_TYPE_LEVEL_LOW>;   /* gpio158 */
+       };
+};
index 224c08f472f42788d9903f70b67640cad47ddb9b..34cdecb4fddabae4dfc8bb3d2be3671309ac1de0 100644 (file)
                        label = "bootloader";
                        reg = <0 0x20000>;
                };
-               partition@0x20000 {
+               partition@20000 {
                        label = "params";
                        reg = <0x20000 0x20000>;
                };
-               partition@0x40000 {
+               partition@40000 {
                        label = "kernel";
                        reg = <0x40000 0x200000>;
                };
-               partition@0x240000 {
+               partition@240000 {
                        label = "file-system";
                        reg = <0x240000 0x3dc0000>;
                };
index 2816bf61267231fd7ec2dd11f87c6da9ed4b3311..31a632f7effbf239f298ff3619cdacdc5587356e 100644 (file)
                };
 
        };
+
+       /* HS USB Port 2 Power */
+       hsusb2_power: hsusb2_power_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb2_vbus";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&twl_gpio 18 0>;        /* GPIO LEDA */
+               startup-delay-us = <70000>;
+       };
+
+       /* HS USB Host PHY on PORT 2 */
+       hsusb2_phy: hsusb2_phy {
+               compatible = "usb-nop-xceiv";
+               reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */
+               vcc-supply = <&hsusb2_power>;
+       };
 };
 
 &omap3_pmx_wkup {
        };
 };
 
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &hsusbb2_pins
+       >;
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                       0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
+               >;
+       };
+
+       hsusbb2_pins: pinmux_hsusbb2_pins {
+               pinctrl-single,pins = <
+                       0x5c0 (PIN_OUTPUT | MUX_MODE3)          /* etk_d10.hsusb2_clk */
+                       0x5c2 (PIN_OUTPUT | MUX_MODE3)          /* etk_d11.hsusb2_stp */
+                       0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d12.hsusb2_dir */
+                       0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d13.hsusb2_nxt */
+                       0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d14.hsusb2_data0 */
+                       0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d15.hsusb2_data1 */
+                       0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi1_cs3.hsusb2_data2 */
+                       0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_clk.hsusb2_data7 */
+                       0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_simo.hsusb2_data4 */
+                       0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_somi.hsusb2_data5 */
+                       0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_cs0.hsusb2_data6 */
+                       0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_cs1.hsusb2_data3 */
+               >;
+       };
+};
+
 &i2c1 {
        clock-frequency = <2600000>;
 
 &usb_otg_hs {
        interface-type = <0>;
        usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
        mode = <3>;
        power = <50>;
 };
 
-&omap3_pmx_core {
-       uart3_pins: pinmux_uart3_pins {
-               pinctrl-single,pins = <
-                       0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
-               >;
-       };
-};
-
 &uart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart3_pins>;
        pinctrl-names = "default";
        pinctrl-0 = <&gpio1_pins>;
 };
+
+&usbhshost {
+       port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <0 &hsusb2_phy>;
+};
index dfd83103657aa85669499f747428e9449c1854ff..fa532aaacc68943989241b92a6e31743e3e854fe 100644 (file)
                };
        };
 
-       /* HS USB Port 2 RESET */
-       hsusb2_reset: hsusb2_reset_reg {
-               compatible = "regulator-fixed";
-               regulator-name = "hsusb2_reset";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio5 19 0>;   /* gpio_147 */
-               startup-delay-us = <70000>;
-               enable-active-high;
-       };
-
        /* HS USB Port 2 Power */
        hsusb2_power: hsusb2_power_reg {
                compatible = "regulator-fixed";
@@ -68,7 +57,7 @@
        /* HS USB Host PHY on PORT 2 */
        hsusb2_phy: hsusb2_phy {
                compatible = "usb-nop-xceiv";
-               reset-supply = <&hsusb2_reset>;
+               reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>;      /* gpio_147 */
                vcc-supply = <&hsusb2_power>;
        };
 
 
        hsusbb2_pins: pinmux_hsusbb2_pins {
                pinctrl-single,pins = <
-                       0x5c0 (PIN_OUTPUT | MUX_MODE3)          /* usbb2_ulpitll_clk.usbb1_ulpiphy_clk */
-                       0x5c2 (PIN_OUTPUT | MUX_MODE3)          /* usbb2_ulpitll_clk.usbb1_ulpiphy_stp */
-                       0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dir */
-                       0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_nxt */
-                       0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat0 */
-                       0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat1 */
-                       0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat2 */
-                       0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat3 */
-                       0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat4 */
-                       0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat5 */
-                       0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat6 */
-                       0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat7 */
+                       0x5c0 (PIN_OUTPUT | MUX_MODE3)          /* etk_d10.hsusb2_clk */
+                       0x5c2 (PIN_OUTPUT | MUX_MODE3)          /* etk_d11.hsusb2_stp */
+                       0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d12.hsusb2_dir */
+                       0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d13.hsusb2_nxt */
+                       0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d14.hsusb2_data0 */
+                       0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d15.hsusb2_data1 */
+                       0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi1_cs3.hsusb2_data2 */
+                       0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_clk.hsusb2_data7 */
+                       0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_simo.hsusb2_data4 */
+                       0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_somi.hsusb2_data5 */
+                       0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_cs0.hsusb2_data6 */
+                       0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* mcspi2_cs1.hsusb2_data3 */
                >;
        };
 
        pinctrl-names = "default";
        pinctrl-0 = <&gpio1_pins>;
 };
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
index 7ef282795dd4194fb05df05def1a8b918d94a434..4665421bb7bc348fc549c1883a1bf8dbd5602327 100644 (file)
                nand-bus-width = <16>;
 
                gpmc,device-nand;
-               gpmc,sync-clki-ps = <0>;
+               gpmc,sync-clk-ps = <0>;
                gpmc,cs-on-ns = <0>;
                gpmc,cs-rd-off-ns = <44>;
                gpmc,cs-wr-off-ns = <44>;
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
new file mode 100644 (file)
index 0000000..4df68ad
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "omap3-evm-common.dtsi"
+
+
+/ {
+       model = "TI OMAP37XX EVM (TMDSEVM3730)";
+       compatible = "ti,omap3-evm-37xx", "ti,omap36xx";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       wl12xx_vmmc: wl12xx_vmmc {
+               pinctrl-names = "default";
+               pinctrl-0 = <&wl12xx_gpio>;
+       };
+};
+
+&omap3_pmx_core {
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
+                       0x116 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_cmd.sdmmc1_cmd */
+                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0.sdmmc1_dat0 */
+                       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_PULLUP | MUX_MODE0)    /* sdmmc1_dat4.sdmmc1_dat4 */
+                       0x122 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat5.sdmmc1_dat5 */
+                       0x124 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat6.sdmmc1_dat6 */
+                       0x126 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat7.sdmmc1_dat7 */
+               >;
+       };
+
+       /* NOTE: Clocked externally, needs INPUT also for sdmmc2_clk.sdmmc2_clk */
+       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 (WAKEUP_EN | 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 */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                       0x170 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx_irtx.uart3_tx_irtx */
+               >;
+       };
+
+       wl12xx_gpio: pinmux_wl12xx_gpio {
+               pinctrl-single,pins = <
+                       0x150 (PIN_OUTPUT | MUX_MODE4)          /* uart1_cts.gpio_150 */
+                       0x14e (PIN_INPUT | MUX_MODE4)           /* uart1_rts.gpio_149 */
+               >;
+       };
+
+       smsc911x_pins: pinmux_smsc911x_pins {
+               pinctrl-single,pins = <
+                       0x1a2 (PIN_INPUT | MUX_MODE4)           /* mcspi1_cs2.gpio_176 */
+               >;
+       };
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
+&gpmc {
+       ranges = <0 0 0x00000000 0x20000000>,
+                <5 0 0x2c000000 0x01000000>;
+
+       nand@0,0 {
+               linux,mtd-name= "hynix,h8kds0un0mer-4em";
+               reg = <0 0 0>;
+               nand-bus-width = <16>;
+               ti,nand-ecc-opt = "bch8";
+
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       label = "X-Loader";
+                       reg = <0 0x80000>;
+               };
+               partition@0x80000 {
+                       label = "U-Boot";
+                       reg = <0x80000 0x1c0000>;
+               };
+               partition@0x1c0000 {
+                       label = "Environment";
+                       reg = <0x240000 0x40000>;
+               };
+               partition@0x280000 {
+                       label = "Kernel";
+                       reg = <0x280000 0x500000>;
+               };
+               partition@0x780000 {
+                       label = "Filesystem";
+                       reg = <0x780000 0x1f880000>;
+               };
+       };
+
+       ethernet@gpmc {
+               pinctrl-names = "default";
+               pinctrl-0 = <&smsc911x_pins>;
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi
new file mode 100644 (file)
index 0000000..3007e79
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Common support for omap3 EVM boards
+ */
+
+#include "omap-gpmc-smsc911x.dtsi"
+
+/ {
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               ledb {
+                       label = "omap3evm::ledb";
+                       gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
+                       linux,default-trigger = "default-on";
+               };
+       };
+
+       wl12xx_vmmc: wl12xx_vmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1271";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpio = <&gpio5 22 0>;   /* gpio150 */
+               startup-delay-us = <70000>;
+               enable-active-high;
+               vin-supply = <&vmmc2>;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+       };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c2 {
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+
+       /*
+        * TVP5146 Video decoder-in for analog input support.
+        */
+       tvp5146@5c {
+               compatible = "ti,tvp5146m2";
+               reg = <0x5c>;
+       };
+};
+
+&mmc1 {
+       vmmc-supply = <&vmmc1>;
+       vmmc_aux-supply = <&vsim>;
+       bus-width = <8>;
+};
+
+&mmc2 {
+       vmmc-supply = <&wl12xx_vmmc>;
+       non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+};
+
+&twl_gpio {
+       ti,use-leds;
+};
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
+
+&gpmc {
+       ethernet@gpmc {
+               interrupt-parent = <&gpio6>;
+               interrupts = <16 8>;
+               reg = <5 0 0xff>;
+       };
+};
index 7d4329d179c43e24cae9bfaddb4c5b1fbc626535..e10dcd0fa539452f6fcaab8ae295fd60085f18b6 100644 (file)
@@ -8,68 +8,14 @@
 /dts-v1/;
 
 #include "omap34xx.dtsi"
+#include "omap3-evm-common.dtsi"
 
 / {
-       model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)";
+       model = "TI OMAP35XX EVM (TMDSEVM3530)";
        compatible = "ti,omap3-evm", "ti,omap3";
 
-       cpus {
-               cpu@0 {
-                       cpu0-supply = <&vcc>;
-               };
-       };
-
        memory {
                device_type = "memory";
                reg = <0x80000000 0x10000000>; /* 256 MB */
        };
-
-       leds {
-               compatible = "gpio-leds";
-               ledb {
-                       label = "omap3evm::ledb";
-                       gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
-                       linux,default-trigger = "default-on";
-               };
-       };
-};
-
-&i2c1 {
-       clock-frequency = <2600000>;
-
-       twl: twl@48 {
-               reg = <0x48>;
-               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
-               interrupt-parent = <&intc>;
-       };
-};
-
-#include "twl4030.dtsi"
-#include "twl4030_omap3.dtsi"
-
-&i2c2 {
-       clock-frequency = <400000>;
-};
-
-&i2c3 {
-       clock-frequency = <400000>;
-
-       /*
-        * TVP5146 Video decoder-in for analog input support.
-        */
-       tvp5146@5c {
-               compatible = "ti,tvp5146m2";
-               reg = <0x5c>;
-       };
-};
-
-&twl_gpio {
-       ti,use-leds;
-};
-
-&usb_otg_hs {
-       interface-type = <0>;
-       usb-phy = <&usb2_phy>;
-       mode = <3>;
-       power = <50>;
 };
diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts
new file mode 100644 (file)
index 0000000..b9b55c9
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2013 Marek Belisko <marek@goldelico.com>
+ *
+ * Based on omap3-beagle-xm.dts
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+
+/ {
+       model = "OMAP3 GTA04";
+       compatible = "ti,omap3-gta04", "ti,omap3";
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>; /* 512 MB */
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               aux-button {
+                       label = "aux";
+                       linux,code = <169>;
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+                       gpio-key,wakeup;
+               };
+       };
+};
+
+&omap3_pmx_core {
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                       0x152 (PIN_INPUT | MUX_MODE0)           /* uart1_rx.uart1_rx */
+                       0x14c (PIN_OUTPUT |MUX_MODE0)           /* uart1_tx.uart1_tx */
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       0x14a (PIN_INPUT | MUX_MODE0)           /* uart2_rx.uart2_rx */
+                       0x148 (PIN_OUTPUT | MUX_MODE0)          /* uart2_tx.uart2_tx */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       0x16e (PIN_INPUT | MUX_MODE0)           /* uart3_rx.uart3_rx */
+                       0x170 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx.uart3_tx */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x114 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_clk.sdmmc1_clk */
+                       0x116 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_cmd.sdmmc1_cmd */
+                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0.sdmmc1_dat0 */
+                       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 */
+               >;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+       };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c2 {
+       clock-frequency = <400000>;
+
+       /* pressure sensor */
+       bmp085@77 {
+               compatible = "bosch,bmp085";
+               reg = <0x77>;
+       };
+
+       /* leds */
+       tca6507@45 {
+               compatible = "ti,tca6507";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x45>;
+
+               gta04_led0: red_aux@0 {
+                       label = "gta04:red:aux";
+                       reg = <0x0>;
+               };
+
+               gta04_led1: green_aux@1 {
+                       label = "gta04:green:aux";
+                       reg = <0x1>;
+               };
+
+               gta04_led3: red_power@3 {
+                       label = "gta04:red:power";
+                       reg = <0x3>;
+                       linux,default-trigger = "default-on";
+               };
+
+               gta04_led4: green_power@4 {
+                       label = "gta04:green:power";
+                       reg = <0x4>;
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+};
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&vmmc1>;
+       vmmc_aux-supply = <&vsim>;
+       bus-width = <4>;
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
index 2326d11462a57dcb9e43991b359f63ce14da1520..ba1e58b7b7e35ddbdf4825853cf72cef6a951939 100644 (file)
@@ -77,6 +77,8 @@
                        0x1a2 (PIN_INPUT | MUX_MODE4)           /* mcspi1_cs2.gpio_176 */
                >;
        };
+
+       leds_pins: pinmux_leds_pins { };
 };
 
 &i2c1 {
 &twl_gpio {
        ti,use-leds;
 };
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
index e8c48284587cb0b741347b501f036f746eb22423..d5cc792672501012f2a368b4d27b17bbb7669d95 100644 (file)
  */
 
 #include "omap3-igep.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
        model = "IGEPv2";
        compatible = "isee,omap3-igep0020", "ti,omap3";
 
        leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&leds_pins>;
                compatible = "gpio-leds";
+
                boot {
                         label = "omap3:green:boot";
                         gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
                };
        };
 
-       vddvario: regulator-vddvario {
-                 compatible = "regulator-fixed";
-                 regulator-name = "vddvario";
-                 regulator-always-on;
+       /* HS USB Port 1 Power */
+       hsusb1_power: hsusb1_power_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb1_vbus";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&twl_gpio 18 GPIO_ACTIVE_LOW>;  /* GPIO LEDA */
+               startup-delay-us = <70000>;
+       };
+
+       /* HS USB Host PHY on PORT 1 */
+       hsusb1_phy: hsusb1_phy {
+               compatible = "usb-nop-xceiv";
+               reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; /* gpio_24 */
+               vcc-supply = <&hsusb1_power>;
        };
+};
 
-       vdd33a: regulator-vdd33a {
-               compatible = "regulator-fixed";
-               regulator-name = "vdd33a";
-               regulator-always-on;
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               &hsusbb1_pins
+       >;
+
+       hsusbb1_pins: pinmux_hsusbb1_pins {
+               pinctrl-single,pins = <
+                       0x5aa (PIN_OUTPUT | MUX_MODE3)          /* etk_ctl.hsusb1_clk */
+                       0x5a8 (PIN_OUTPUT | MUX_MODE3)          /* etk_clk.hsusb1_stp */
+                       0x5bc (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d8.hsusb1_dir */
+                       0x5be (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d9.hsusb1_nxt */
+                       0x5ac (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d0.hsusb1_data0 */
+                       0x5ae (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d1.hsusb1_data1 */
+                       0x5b0 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d2.hsusb1_data2 */
+                       0x5b2 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d3.hsusb1_data7 */
+                       0x5b4 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d4.hsusb1_data4 */
+                       0x5b6 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d5.hsusb1_data5 */
+                       0x5b8 (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d6.hsusb1_data6 */
+                       0x5ba (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d7.hsusb1_data3 */
+               >;
        };
 };
 
+&leds_pins {
+       pinctrl-single,pins = <
+               0x5c4 (PIN_OUTPUT | MUX_MODE4) /* etk_d12.gpio_26 */
+               0x5c6 (PIN_OUTPUT | MUX_MODE4) /* etk_d13.gpio_27 */
+               0x5c8 (PIN_OUTPUT | MUX_MODE4) /* etk_d14.gpio_28 */
+       >;
+};
+
 &i2c3 {
        clock-frequency = <100000>;
 
                        label = "SPL";
                        reg = <0 0x100000>;
                };
-               partition@0x80000 {
+               partition@80000 {
                        label = "U-Boot";
                        reg = <0x100000 0x180000>;
                };
-               partition@0x1c0000 {
+               partition@1c0000 {
                        label = "Environment";
                        reg = <0x280000 0x100000>;
                };
-               partition@0x280000 {
+               partition@280000 {
                        label = "Kernel";
                        reg = <0x380000 0x300000>;
                };
-               partition@0x780000 {
+               partition@780000 {
                        label = "Filesystem";
                        reg = <0x680000 0x1f980000>;
                };
        };
 
-       ethernet@5,0 {
+       ethernet@gpmc {
                pinctrl-names = "default";
                pinctrl-0 = <&smsc911x_pins>;
-               compatible = "smsc,lan9221", "smsc,lan9115";
                reg = <5 0 0xff>;
-               bank-width = <2>;
-
-               gpmc,mux-add-data;
-               gpmc,cs-on-ns = <0>;
-               gpmc,cs-rd-off-ns = <186>;
-               gpmc,cs-wr-off-ns = <186>;
-               gpmc,adv-on-ns = <12>;
-               gpmc,adv-rd-off-ns = <48>;
-               gpmc,adv-wr-off-ns = <48>;
-               gpmc,oe-on-ns = <54>;
-               gpmc,oe-off-ns = <168>;
-               gpmc,we-on-ns = <54>;
-               gpmc,we-off-ns = <168>;
-               gpmc,rd-cycle-ns = <186>;
-               gpmc,wr-cycle-ns = <186>;
-               gpmc,access-ns = <114>;
-               gpmc,page-burst-access-ns = <6>;
-               gpmc,bus-turnaround-ns = <12>;
-               gpmc,cycle2cycle-delay-ns = <18>;
-               gpmc,wr-data-mux-bus-ns = <90>;
-               gpmc,wr-access-ns = <186>;
-               gpmc,cycle2cycle-samecsen;
-               gpmc,cycle2cycle-diffcsen;
-
                interrupt-parent = <&gpio6>;
-               interrupts = <16 8>;
-               vmmc-supply = <&vddvario>;
-               vmmc_aux-supply = <&vdd33a>;
-               reg-io-width = <4>;
-
-               smsc,save-mac-address;
+               interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
        };
 };
+
+&usbhshost {
+       port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <&hsusb1_phy>;
+};
index 644d05383836f45dfe5612ad760d100fb12e9072..525e6d9b09784c721b4660554a17abdda14273e9 100644 (file)
        compatible = "isee,omap3-igep0030", "ti,omap3";
 
        leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&leds_pins>;
                compatible = "gpio-leds";
+
                boot {
                         label = "omap3:green:boot";
                         gpios = <&twl_gpio 13 GPIO_ACTIVE_LOW>;
        };
 };
 
+&leds_pins {
+       pinctrl-single,pins = <
+               0x5b0 (PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */
+       >;
+};
+
 &gpmc {
        ranges = <0 0 0x00000000 0x20000000>;
 
                        label = "SPL";
                        reg = <0 0x100000>;
                };
-               partition@0x80000 {
+               partition@80000 {
                        label = "U-Boot";
                        reg = <0x100000 0x180000>;
                };
-               partition@0x1c0000 {
+               partition@1c0000 {
                        label = "Environment";
                        reg = <0x280000 0x100000>;
                };
-               partition@0x280000 {
+               partition@280000 {
                        label = "Kernel";
                        reg = <0x380000 0x300000>;
                };
-               partition@0x780000 {
+               partition@780000 {
                        label = "Filesystem";
                        reg = <0x680000 0x1f980000>;
                };
diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts
new file mode 100644 (file)
index 0000000..39828ce
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * omap3-n9.dts - Device Tree file for Nokia N9
+ *
+ * Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "omap3-n950-n9.dtsi"
+
+/ {
+       model = "Nokia N9";
+       compatible = "nokia,omap3-n9", "ti,omap3";
+};
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
new file mode 100644 (file)
index 0000000..c4f20bf
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2013 Pavel Machek <pavel@ucw.cz>
+ * Copyright 2013 Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 (or later) as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+
+/ {
+       model = "Nokia N900";
+       compatible = "nokia,omap3-n900", "ti,omap3";
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               camera_lens_cover {
+                       label = "Camera Lens Cover";
+                       gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* 110 */
+                       linux,input-type = <5>; /* EV_SW */
+                       linux,code = <0x09>; /* SW_CAMERA_LENS_COVER */
+                       gpio-key,wakeup;
+               };
+
+               camera_focus {
+                       label = "Camera Focus";
+                       gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 68 */
+                       linux,code = <0x210>; /* KEY_CAMERA_FOCUS */
+                       gpio-key,wakeup;
+               };
+
+               camera_capture {
+                       label = "Camera Capture";
+                       gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; /* 69 */
+                       linux,code = <0xd4>; /* KEY_CAMERA */
+                       gpio-key,wakeup;
+               };
+
+               lock_button {
+                       label = "Lock Button";
+                       gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* 113 */
+                       linux,code = <0x98>; /* KEY_SCREENLOCK */
+                       gpio-key,wakeup;
+               };
+
+               keypad_slide {
+                       label = "Keypad Slide";
+                       gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; /* 71 */
+                       linux,input-type = <5>; /* EV_SW */
+                       linux,code = <0x0a>; /* SW_KEYPAD_SLIDE */
+                       gpio-key,wakeup;
+               };
+
+               proximity_sensor {
+                       label = "Proximity Sensor";
+                       gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>; /* 89 */
+                       linux,input-type = <5>; /* EV_SW */
+                       linux,code = <0x0b>; /* SW_FRONT_PROXIMITY */
+               };
+       };
+
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       0x14a (PIN_INPUT | MUX_MODE0)           /* uart2_rx */
+                       0x148 (PIN_OUTPUT | MUX_MODE0)          /* uart2_tx */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       0x16e (PIN_INPUT | MUX_MODE0)           /* uart3_rx */
+                       0x170 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0x18a (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl */
+                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       0x18e (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c2_scl */
+                       0x190 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c2_sda */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0x192 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c3_scl */
+                       0x194 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c3_sda */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x114 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_clk */
+                       0x116 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_cmd */
+                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0 */
+                       0x11a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat1 */
+                       0x11c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat2 */
+                       0x11e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat3 */
+               >;
+       };
+
+       display_pins: pinmux_display_pins {
+               pinctrl-single,pins = <
+                       0x0d4 (PIN_OUTPUT | MUX_MODE4)          /* RX51_LCD_RESET_GPIO */
+               >;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       clock-frequency = <2200000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+       };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&vaux1 {
+       regulator-name = "V28";
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+       regulator-always-on; /* due battery cover sensor */
+};
+
+&vaux2 {
+       regulator-name = "VCSI";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+};
+
+&vaux3 {
+       regulator-name = "VMMC2_30";
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <3000000>;
+};
+
+&vaux4 {
+       regulator-name = "VCAM_ANA_28";
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+};
+
+&vmmc1 {
+       regulator-name = "VMMC1";
+       regulator-min-microvolt = <1850000>;
+       regulator-max-microvolt = <3150000>;
+};
+
+&vmmc2 {
+       regulator-name = "V28_A";
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-always-on; /* due VIO leak to AIC34 VDDs */
+};
+
+&vpll1 {
+       regulator-name = "VPLL";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-always-on;
+};
+
+&vpll2 {
+       regulator-name = "VSDI_CSI";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-always-on;
+};
+
+&vsim {
+       regulator-name = "VMMC2_IO_18";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+};
+
+&vio {
+       regulator-name = "VIO";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+
+};
+
+&vintana1 {
+       regulator-name = "VINTANA1";
+       /* fixed to 1500000 */
+       regulator-always-on;
+};
+
+&vintana2 {
+       regulator-name = "VINTANA2";
+       regulator-min-microvolt = <2750000>;
+       regulator-max-microvolt = <2750000>;
+       regulator-always-on;
+};
+
+&vintdig {
+       regulator-name = "VINTDIG";
+       /* fixed to 1500000 */
+       regulator-always-on;
+};
+
+&twl {
+       twl_audio: audio {
+               compatible = "ti,twl4030-audio";
+               ti,enable-vibra = <1>;
+       };
+};
+
+&twl_gpio {
+       ti,pullups      = <0x0>;
+       ti,pulldowns    = <0x03ff3f>; /* BIT(0..5) | BIT(8..17) */
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+
+       clock-frequency = <100000>;
+
+       tlv320aic3x: tlv320aic3x@18 {
+               compatible = "ti,tlv320aic3x";
+               reg = <0x18>;
+               gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */
+               ai3x-gpio-func = <
+                       0 /* AIC3X_GPIO1_FUNC_DISABLED */
+                       5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */
+               >;
+
+               AVDD-supply = <&vmmc2>;
+               DRVDD-supply = <&vmmc2>;
+               IOVDD-supply = <&vio>;
+               DVDD-supply = <&vio>;
+       };
+
+       tlv320aic3x_aux: tlv320aic3x@19 {
+               compatible = "ti,tlv320aic3x";
+               reg = <0x19>;
+               gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */
+
+               AVDD-supply = <&vmmc2>;
+               DRVDD-supply = <&vmmc2>;
+               IOVDD-supply = <&vio>;
+               DVDD-supply = <&vio>;
+       };
+
+       lp5523: lp5523@32 {
+               compatible = "national,lp5523";
+               reg = <0x32>;
+               clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */
+               enable-gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */
+
+               chan0 {
+                       chan-name = "lp5523:kb1";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan1 {
+                       chan-name = "lp5523:kb2";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan2 {
+                       chan-name = "lp5523:kb3";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan3 {
+                       chan-name = "lp5523:kb4";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan4 {
+                       chan-name = "lp5523:b";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan5 {
+                       chan-name = "lp5523:g";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan6 {
+                       chan-name = "lp5523:r";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan7 {
+                       chan-name = "lp5523:kb5";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+
+               chan8 {
+                       chan-name = "lp5523:kb6";
+                       led-cur = /bits/ 8 <50>;
+                       max-cur = /bits/ 8 <100>;
+               };
+       };
+
+       bq27200: bq27200@55 {
+               compatible = "ti,bq27200";
+               reg = <0x55>;
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+
+       clock-frequency = <400000>;
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&vmmc1>;
+       bus-width = <4>;
+       cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&gpmc {
+       ranges = <0 0 0x04000000 0x10000000>; /* 256MB */
+
+       /* gpio-irq for dma: 65 */
+
+       onenand@0,0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0 0 0x10000000>;
+
+               gpmc,sync-read;
+               gpmc,sync-write;
+               gpmc,burst-length = <16>;
+               gpmc,burst-read;
+               gpmc,burst-wrap;
+               gpmc,burst-write;
+               gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
+               gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <87>;
+               gpmc,cs-wr-off-ns = <87>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <10>;
+               gpmc,adv-wr-off-ns = <10>;
+               gpmc,oe-on-ns = <15>;
+               gpmc,oe-off-ns = <87>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <87>;
+               gpmc,rd-cycle-ns = <112>;
+               gpmc,wr-cycle-ns = <112>;
+               gpmc,access-ns = <81>;
+               gpmc,page-burst-access-ns = <15>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,clk-activation-ns = <5>;
+               gpmc,wr-data-mux-bus-ns = <30>;
+               gpmc,wr-access-ns = <81>;
+               gpmc,sync-clk-ps = <15000>;
+
+               /*
+                * MTD partition table corresponding to Nokia's
+                * Maemo 5 (Fremantle) release.
+                */
+               partition@0 {
+                       label = "bootloader";
+                       reg = <0x00000000 0x00020000>;
+                       read-only;
+               };
+               partition@1 {
+                       label = "config";
+                       reg = <0x00020000 0x00060000>;
+               };
+               partition@2 {
+                       label = "log";
+                       reg = <0x00080000 0x00040000>;
+               };
+               partition@3 {
+                       label = "kernel";
+                       reg = <0x000c0000 0x00200000>;
+               };
+               partition@4 {
+                       label = "initfs";
+                       reg = <0x002c0000 0x00200000>;
+               };
+               partition@5 {
+                       label = "rootfs";
+                       reg = <0x004c0000 0x0fb40000>;
+               };
+       };
+};
+
+&mcspi1 {
+       /*
+        * For some reason, touchscreen is necessary for screen to work at
+        * all on real hw. It works well without it on emulator.
+        *
+        * Also... order in the device tree actually matters here.
+        */
+       tsc2005@0 {
+               compatible = "tsc2005";
+               spi-max-frequency = <6000000>;
+               reg = <0>;
+       };
+       mipid@2 {
+               compatible = "acx565akm";
+               spi-max-frequency = <6000000>;
+               reg = <2>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&display_pins>;
+       };
+};
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <2>;
+       power = <50>;
+};
+
+&uart1 {
+       status = "disabled";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
new file mode 100644 (file)
index 0000000..94eb77d
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * omap3-n950-n9.dtsi - Device Tree file for Nokia N950 & N9 (common stuff)
+ *
+ * Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap36xx.dtsi"
+
+/ {
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>; /* 1 GB */
+       };
+
+       vemmc: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "VEMMC";
+               regulator-min-microvolt = <2900000>;
+               regulator-max-microvolt = <2900000>;
+               gpio = <&gpio5 29 0>; /* gpio line 157 */
+               startup-delay-us = <150>;
+               enable-active-high;
+       };
+};
+
+&omap3_pmx_core {
+       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 */
+               >;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2900000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+       };
+};
+
+/include/ "twl4030.dtsi"
+
+&twl {
+       compatible = "ti,twl5031";
+};
+
+&twl_gpio {
+       ti,pullups      = <0x000001>; /* BIT(0) */
+       ti,pulldowns    = <0x008106>; /* BIT(1) | BIT(2) | BIT(8) | BIT(15) */
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+};
+
+&mmc1 {
+       status = "disabled";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&vemmc>;
+       bus-width = <4>;
+       ti,non-removable;
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
+
+&gpmc {
+       ranges = <0 0 0x04000000 0x20000000>;
+
+       onenand@0,0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0 0 0x20000000>;
+
+               gpmc,sync-read;
+               gpmc,sync-write;
+               gpmc,burst-length = <16>;
+               gpmc,burst-read;
+               gpmc,burst-wrap;
+               gpmc,burst-write;
+               gpmc,device-width = <2>;
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <87>;
+               gpmc,cs-wr-off-ns = <87>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <10>;
+               gpmc,adv-wr-off-ns = <10>;
+               gpmc,oe-on-ns = <15>;
+               gpmc,oe-off-ns = <87>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <87>;
+               gpmc,rd-cycle-ns = <112>;
+               gpmc,wr-cycle-ns = <112>;
+               gpmc,access-ns = <81>;
+               gpmc,page-burst-access-ns = <15>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,clk-activation-ns = <5>;
+               gpmc,wr-data-mux-bus-ns = <30>;
+               gpmc,wr-access-ns = <81>;
+               gpmc,sync-clk-ps = <15000>;
+
+               /*
+                * MTD partition table corresponding to Nokia's MeeGo 1.2
+                * Harmattan release.
+                */
+               partition@0 {
+                       label = "bootloader";
+                       reg = <0x00000000 0x00100000>;
+               };
+               partition@1 {
+                       label = "config";
+                       reg = <0x00100000 0x002c0000>;
+               };
+               partition@2 {
+                       label = "kernel";
+                       reg = <0x003c0000 0x01000000>;
+               };
+               partition@3 {
+                       label = "log";
+                       reg = <0x013c0000 0x00200000>;
+               };
+               partition@4 {
+                       label = "var";
+                       reg = <0x015c0000 0x1ca40000>;
+               };
+               partition@5 {
+                       label = "moslo";
+                       reg = <0x1e000000 0x02000000>;
+               };
+               partition@6 {
+                       label = "omap2-onenand";
+                       reg = <0x00000000 0x20000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
new file mode 100644 (file)
index 0000000..b076a52
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * omap3-n950.dts - Device Tree file for Nokia N950
+ *
+ * Written by: Aaro Koskinen <aaro.koskinen@iki.fi>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "omap3-n950-n9.dtsi"
+
+/ {
+       model = "Nokia N950";
+       compatible = "nokia,omap3-n950", "ti,omap3";
+};
index 8f1abec78275635535f9faf4cdd03c60d2daf909..a461d2fd1fb0e81862805ccec939e1c1b3a41244 100644 (file)
@@ -76,6 +76,8 @@
 &usb_otg_hs {
        interface-type = <0>;
        usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
        mode = <3>;
        power = <50>;
 };
diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts
new file mode 100644 (file)
index 0000000..15eb9fe
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+#include "omap-zoom-common.dtsi"
+
+/ {
+       model = "TI Zoom3";
+       compatible = "ti,omap3-zoom3", "ti,omap36xx", "ti,omap3";
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>; /* 512 MB */
+       };
+
+       vddvario: regulator-vddvario {
+                 compatible = "regulator-fixed";
+                 regulator-name = "vddvario";
+                 regulator-always-on;
+       };
+
+       vdd33a: regulator-vdd33a {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd33a";
+               regulator-always-on;
+       };
+
+       wl12xx_vmmc: wl12xx_vmmc {
+               pinctrl-names = "default";
+               pinctrl-0 = <&wl12xx_gpio>;
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1271";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpio = <&gpio4 5 0>;    /* gpio101 */
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+};
+
+&omap3_pmx_core {
+       /* REVISIT: twl gpio0 is mmc0_cd */
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
+                       0x116 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_cmd.sdmmc1_cmd */
+                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0.sdmmc1_dat0 */
+                       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 */
+               >;
+       };
+
+       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 | MUX_MODE0)           /* sdmmc2_dat0.sdmmc2_dat0 */
+                       0x12e (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat1.sdmmc2_dat1 */
+                       0x130 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat2.sdmmc2_dat2 */
+                       0x132 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat3.sdmmc2_dat3 */
+                       0x134 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat4.sdmmc2_dat4 */
+                       0x136 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat5.sdmmc2_dat5 */
+                       0x138 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat6.sdmmc2_dat6 */
+                       0x13a (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat7.sdmmc2_dat7 */
+               >;
+       };
+
+       mmc3_pins: pinmux_mmc3_pins {
+               pinctrl-single,pins = <
+                       0x168 (PIN_INPUT | MUX_MODE4)   /* mcbsp1_clkx.gpio_162 WLAN IRQ */
+                       0x1a0 (PIN_INPUT_PULLUP | MUX_MODE3)    /* mcspi1_cs1.sdmmc3_cmd */
+                       0x5a8 (PIN_INPUT_PULLUP | MUX_MODE2)    /* etk_clk.sdmmc3_clk */
+                       0x5b4 (PIN_INPUT_PULLUP | MUX_MODE2)    /* etk_d4.sdmmc3_dat0 */
+                       0x5b6 (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */
+                       0x5b8 (PIN_INPUT_PULLUP | MUX_MODE2)    /* etk_d6.sdmmc3_dat2 */
+                       0x5b2 (PIN_INPUT_PULLUP | MUX_MODE2)    /* etk_d3.sdmmc3_dat3 */
+               >;
+       };
+
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                        0x150 (PIN_INPUT | MUX_MODE0)          /* uart1_cts.uart1_cts */
+                        0x14e (PIN_OUTPUT | MUX_MODE0)         /* uart1_rts.uart1_rts */
+                        0x152 (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+                        0x14c (PIN_OUTPUT | MUX_MODE0)         /* uart1_tx.uart1_tx */
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                        0x144 (PIN_INPUT_PULLUP | MUX_MODE0)   /* uart2_cts.uart2_cts */
+                        0x146 (PIN_OUTPUT | MUX_MODE0)         /* uart2_rts.uart2_rts */
+                        0x14a (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+                        0x148 (PIN_OUTPUT | MUX_MODE0)         /* uart2_tx.uart2_tx */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                        0x16a (PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */
+                        0x16c (PIN_OUTPUT | MUX_MODE0)         /* uart3_rts_sd.uart3_rts_sd */
+                        0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                        0x170 (PIN_OUTPUT | MUX_MODE0)         /* uart3_tx_irtx.uart3_tx_irtx */
+               >;
+       };
+
+       /* wl12xx GPIO output for WLAN_EN */
+       wl12xx_gpio: pinmux_wl12xx_gpio {
+               pinctrl-single,pins = <
+                       0xea (PIN_OUTPUT| MUX_MODE4)            /* cam_d2.gpio_101 */
+               >;
+       };
+};
+
+&omap3_pmx_wkup {
+       wlan_host_wkup: pinmux_wlan_host_wkup_pins {
+               pinctrl-single,pins = <
+                       0x1a (PIN_INPUT_PULLUP | MUX_MODE4)     /* sys_clkout1.gpio_10 WLAN_HOST_WKUP */
+               >;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+       };
+};
+
+#include "twl4030.dtsi"
+
+&i2c2 {
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+
+       /*
+        * TVP5146 Video decoder-in for analog input support.
+        */
+       tvp5146@5c {
+               compatible = "ti,tvp5146m2";
+               reg = <0x5c>;
+       };
+};
+
+&twl_gpio {
+       ti,use-leds;
+};
+
+&mmc1 {
+       vmmc-supply = <&vmmc1>;
+       vmmc_aux-supply = <&vsim>;
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+};
+/*
+&mmc2 {
+       vmmc-supply = <&vmmc2>;
+       ti,non-removable;
+       bus-width = <8>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+};
+*/
+&mmc3 {
+       vmmc-supply = <&wl12xx_vmmc>;
+       non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc3_pins>;
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
+&uart4 {
+       status = "disabled";
+};
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       mode = <3>;
+       power = <50>;
+};
index b41bd57f43287a048b73bfefe35b262ee139600e..f3a0c26ed0c2bcd6d6df65dcecc3f18329abec18 100644 (file)
@@ -19,6 +19,9 @@
        interrupt-parent = <&intc>;
 
        aliases {
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
@@ -37,6 +40,7 @@
 
        pmu {
                compatible = "arm,cortex-a8-pmu";
+               reg = <0x54000000 0x800000>;
                interrupts = <3>;
                ti,hwmods = "debugss";
        };
@@ -71,6 +75,8 @@
         */
        ocp {
                compatible = "simple-bus";
+               reg = <0x68000000 0x10000>;
+               interrupts = <9 10>;
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
                        reg = <0x48002030 0x05cc>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
                        pinctrl-single,register-width = <16>;
                        pinctrl-single,function-mask = <0xff1f>;
                };
 
-               omap3_pmx_wkup: pinmux@0x48002a00 {
+               omap3_pmx_wkup: pinmux@48002a00 {
                        compatible = "ti,omap3-padconf", "pinctrl-single";
                        reg = <0x48002a00 0x5c>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
                        pinctrl-single,register-width = <16>;
                        pinctrl-single,function-mask = <0xff1f>;
                };
 
                uart1: serial@4806a000 {
                        compatible = "ti,omap3-uart";
+                       reg = <0x4806a000 0x2000>;
+                       interrupts = <72>;
+                       dmas = <&sdma 49 &sdma 50>;
+                       dma-names = "tx", "rx";
                        ti,hwmods = "uart1";
                        clock-frequency = <48000000>;
                };
 
                uart2: serial@4806c000 {
                        compatible = "ti,omap3-uart";
+                       reg = <0x4806c000 0x400>;
+                       interrupts = <73>;
+                       dmas = <&sdma 51 &sdma 52>;
+                       dma-names = "tx", "rx";
                        ti,hwmods = "uart2";
                        clock-frequency = <48000000>;
                };
 
                uart3: serial@49020000 {
                        compatible = "ti,omap3-uart";
+                       reg = <0x49020000 0x400>;
+                       interrupts = <74>;
+                       dmas = <&sdma 53 &sdma 54>;
+                       dma-names = "tx", "rx";
                        ti,hwmods = "uart3";
                        clock-frequency = <48000000>;
                };
 
                i2c1: i2c@48070000 {
                        compatible = "ti,omap3-i2c";
+                       reg = <0x48070000 0x80>;
+                       interrupts = <56>;
+                       dmas = <&sdma 27 &sdma 28>;
+                       dma-names = "tx", "rx";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "i2c1";
 
                i2c2: i2c@48072000 {
                        compatible = "ti,omap3-i2c";
+                       reg = <0x48072000 0x80>;
+                       interrupts = <57>;
+                       dmas = <&sdma 29 &sdma 30>;
+                       dma-names = "tx", "rx";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "i2c2";
 
                i2c3: i2c@48060000 {
                        compatible = "ti,omap3-i2c";
+                       reg = <0x48060000 0x80>;
+                       interrupts = <61>;
+                       dmas = <&sdma 25 &sdma 26>;
+                       dma-names = "tx", "rx";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "i2c3";
 
                mcspi1: spi@48098000 {
                        compatible = "ti,omap2-mcspi";
+                       reg = <0x48098000 0x100>;
+                       interrupts = <65>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "mcspi1";
 
                mcspi2: spi@4809a000 {
                        compatible = "ti,omap2-mcspi";
+                       reg = <0x4809a000 0x100>;
+                       interrupts = <66>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "mcspi2";
 
                mcspi3: spi@480b8000 {
                        compatible = "ti,omap2-mcspi";
+                       reg = <0x480b8000 0x100>;
+                       interrupts = <91>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "mcspi3";
 
                mcspi4: spi@480ba000 {
                        compatible = "ti,omap2-mcspi";
+                       reg = <0x480ba000 0x100>;
+                       interrupts = <48>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "mcspi4";
                        dma-names = "tx0", "rx0";
                };
 
+               hdqw1w: 1w@480b2000 {
+                       compatible = "ti,omap3-1w";
+                       reg = <0x480b2000 0x1000>;
+                       interrupts = <58>;
+                       ti,hwmods = "hdq1w";
+               };
+
                mmc1: mmc@4809c000 {
                        compatible = "ti,omap3-hsmmc";
+                       reg = <0x4809c000 0x200>;
+                       interrupts = <83>;
                        ti,hwmods = "mmc1";
                        ti,dual-volt;
                        dmas = <&sdma 61>, <&sdma 62>;
 
                mmc2: mmc@480b4000 {
                        compatible = "ti,omap3-hsmmc";
+                       reg = <0x480b4000 0x200>;
+                       interrupts = <86>;
                        ti,hwmods = "mmc2";
                        dmas = <&sdma 47>, <&sdma 48>;
                        dma-names = "tx", "rx";
 
                mmc3: mmc@480ad000 {
                        compatible = "ti,omap3-hsmmc";
+                       reg = <0x480ad000 0x200>;
+                       interrupts = <94>;
                        ti,hwmods = "mmc3";
                        dmas = <&sdma 77>, <&sdma 78>;
                        dma-names = "tx", "rx";
 
                wdt2: wdt@48314000 {
                        compatible = "ti,omap3-wdt";
+                       reg = <0x48314000 0x80>;
                        ti,hwmods = "wd_timer2";
                };
 
index e2249bcc3e63fa5a6404d2a2d761a011f15261bf..281914ed015136c57cb65d1039136899726bfd12 100644 (file)
                        label = "bootloader-nor";
                        reg = <0 0x40000>;
                };
-               partition@0x40000 {
+               partition@40000 {
                        label = "params-nor";
                        reg = <0x40000 0x40000>;
                };
-               partition@0x80000 {
+               partition@80000 {
                        label = "kernel-nor";
                        reg = <0x80000 0x200000>;
                };
-               partition@0x280000 {
+               partition@280000 {
                        label = "filesystem-nor";
                        reg = <0x240000 0x7d80000>;
                };
                        label = "xloader-nand";
                        reg = <0 0x80000>;
                };
-               partition@0x80000 {
+               partition@80000 {
                        label = "bootloader-nand";
                        reg = <0x80000 0x140000>;
                };
-               partition@0x1c0000 {
+               partition@1c0000 {
                        label = "params-nand";
                        reg = <0x1c0000 0xc0000>;
                };
-               partition@0x280000 {
+               partition@280000 {
                        label = "kernel-nand";
                        reg = <0x280000 0x500000>;
                };
-               partition@0x780000 {
+               partition@780000 {
                        label = "filesystem-nand";
                        reg = <0x780000 0x7880000>;
                };
                        label = "xloader-onenand";
                        reg = <0 0x80000>;
                };
-               partition@0x80000 {
+               partition@80000 {
                        label = "bootloader-onenand";
                        reg = <0x80000 0x40000>;
                };
-               partition@0xc0000 {
+               partition@c0000 {
                        label = "params-onenand";
                        reg = <0xc0000 0x20000>;
                };
-               partition@0xe0000 {
+               partition@e0000 {
                        label = "kernel-onenand";
                        reg = <0xe0000 0x200000>;
                };
-               partition@0x2e0000 {
+               partition@2e0000 {
                        label = "filesystem-onenand";
                        reg = <0x2e0000 0xfd20000>;
                };
index f8b3765eb9becea27e0f6028b15bf9d56ab8b484..380c22eb468ef705186e9f3f55137e19809ac8d4 100644 (file)
        ocp {
                uart4: serial@49042000 {
                        compatible = "ti,omap3-uart";
+                       reg = <0x49042000 0x400>;
+                       interrupts = <80>;
+                       dmas = <&sdma 81 &sdma 82>;
+                       dma-names = "tx", "rx";
                        ti,hwmods = "uart4";
                        clock-frequency = <48000000>;
                };
index 814ab67c8c299b0b818f669c917d51ebcb8a94c0..298e85020e1b20bec89b8ecc52b38886e4656467 100644 (file)
                        "AFMR", "Line In";
        };
 
-       /*
-        * Temp hack: Need to be replaced with the proper gpio-controlled
-        * reset driver as soon it will be merged.
-        * http://thread.gmane.org/gmane.linux.drivers.devicetree/36830
-        */
-       /* HS USB Port 1 RESET */
-       hsusb1_reset: hsusb1_reset_reg {
-               compatible = "regulator-fixed";
-               regulator-name = "hsusb1_reset";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio2 30 0>;   /* gpio_62 */
-               startup-delay-us = <70000>;
-               enable-active-high;
-       };
-
        /* HS USB Port 1 Power */
        hsusb1_power: hsusb1_power_reg {
                compatible = "regulator-fixed";
@@ -97,7 +81,7 @@
        /* HS USB Host PHY on PORT 1 */
        hsusb1_phy: hsusb1_phy {
                compatible = "usb-nop-xceiv";
-               reset-supply = <&hsusb1_reset>;
+               reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>;   /* gpio_62 */
                vcc-supply = <&hsusb1_power>;
        /**
         * FIXME:
        };
 };
 
-&omap4_pmx_wkup {
-       pinctrl-names = "default";
-       pinctrl-0 = <
-                       &twl6030_wkup_pins
-       >;
-
-       twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
-               pinctrl-single,pins = <
-                       0x14 (PIN_OUTPUT | MUX_MODE2)           /* fref_clk0_out.sys_drm_msecure */
-               >;
-       };
-};
-
 &omap4_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
-                       &twl6030_pins
                        &twl6040_pins
                        &mcpdm_pins
                        &mcbsp1_pins
+                       &dss_dpi_pins
+                       &tfp410_pins
                        &dss_hdmi_pins
                        &tpd12s015_pins
                        &hsusbb1_pins
        >;
 
-       twl6030_pins: pinmux_twl6030_pins {
-               pinctrl-single,pins = <
-                       0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)        /* sys_nirq1.sys_nirq1 */
-               >;
-       };
-
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
                        0xe0 (PIN_OUTPUT | MUX_MODE3)   /* hdq_sio.gpio_127 */
                >;
        };
 
+       dss_dpi_pins: pinmux_dss_dpi_pins {
+               pinctrl-single,pins = <
+                       0x122 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data23 */
+                       0x124 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data22 */
+                       0x126 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data21 */
+                       0x128 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data20 */
+                       0x12a (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data19 */
+                       0x12c (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data18 */
+                       0x12e (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data15 */
+                       0x130 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data14 */
+                       0x132 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data13 */
+                       0x134 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data12 */
+                       0x136 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data11 */
+
+                       0x174 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data10 */
+                       0x176 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data9 */
+                       0x178 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data16 */
+                       0x17a (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data17 */
+                       0x17c (PIN_OUTPUT | MUX_MODE5)  /* dispc2_hsync */
+                       0x17e (PIN_OUTPUT | MUX_MODE5)  /* dispc2_pclk */
+                       0x180 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_vsync */
+                       0x182 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_de */
+                       0x184 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data8 */
+                       0x186 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data7 */
+                       0x188 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data6 */
+                       0x18a (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data5 */
+                       0x18c (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data4 */
+                       0x18e (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data3 */
+
+                       0x190 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data2 */
+                       0x192 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data1 */
+                       0x194 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data0 */
+               >;
+       };
+
+       tfp410_pins: pinmux_tfp410_pins {
+               pinctrl-single,pins = <
+                       0x144 (PIN_OUTPUT | MUX_MODE3)  /* gpio_0 */
+               >;
+       };
+
        dss_hdmi_pins: pinmux_dss_hdmi_pins {
                pinctrl-single,pins = <
                        0x5a (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_cec.hdmi_cec */
 };
 
 #include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
 
 &i2c2 {
        pinctrl-names = "default";
index 56c435468e94a8399f21236b7b553eea15bcc697..816d1c95b592965304fb2aa502da664c9f07ffe4 100644 (file)
@@ -62,3 +62,7 @@
                gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
        };
 };
+
+&gpio1 {
+        ti,no-reset-on-init;
+};
index 4f78380ecdb890c5b72cae0ac8937365540d80bd..5fc3f43c5a81d4c9256b063f31bb32fc544dde38 100644 (file)
        };
 };
 
-&omap4_pmx_wkup {
-       pinctrl-names = "default";
-       pinctrl-0 = <
-                       &twl6030_wkup_pins
-       >;
-
-       twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
-               pinctrl-single,pins = <
-                       0x14 (PIN_OUTPUT | MUX_MODE2)           /* fref_clk0_out.sys_drm_msecure */
-               >;
-       };
-};
-
 &omap4_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
-                       &twl6030_pins
                        &twl6040_pins
                        &mcpdm_pins
                        &dmic_pins
                >;
        };
 
-       twl6030_pins: pinmux_twl6030_pins {
-               pinctrl-single,pins = <
-                       0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)        /* sys_nirq1.sys_nirq1 */
-               >;
-       };
-
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
                        0xe0 (PIN_OUTPUT | MUX_MODE3)           /* hdq_sio.gpio_127 */
 };
 
 #include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
 
 &i2c2 {
        pinctrl-names = "default";
index 22d9f2b593d461eb5bde36a35f24e2eaea40e298..a1e05853afcd583c15da3ad259c8f715992b2d7f 100644 (file)
        interrupt-parent = <&gic>;
 
        aliases {
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
@@ -56,7 +60,7 @@
                cache-level = <2>;
        };
 
-       local-timer@0x48240600 {
+       local-timer@48240600 {
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x48240600 0x20>;
                interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
                        reg = <0x4a100040 0x0196>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
                        pinctrl-single,register-width = <16>;
                        pinctrl-single,function-mask = <0x7fff>;
                };
                        reg = <0x4a31e040 0x0038>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
                        pinctrl-single,register-width = <16>;
                        pinctrl-single,function-mask = <0x7fff>;
                };
                        gpmc,num-cs = <8>;
                        gpmc,num-waitpins = <4>;
                        ti,hwmods = "gpmc";
+                       ti,no-idle-on-init;
                };
 
                uart1: serial@4806a000 {
                        clock-frequency = <48000000>;
                };
 
+               hwspinlock: spinlock@4a0f6000 {
+                       compatible = "ti,omap4-hwspinlock";
+                       reg = <0x4a0f6000 0x1000>;
+                       ti,hwmods = "spinlock";
+               };
+
                i2c1: i2c@48070000 {
                        compatible = "ti,omap4-i2c";
                        reg = <0x48070000 0x100>;
                        reg = <0x4c000000 0x100>;
                        interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
                        ti,hwmods = "emif1";
+                       ti,no-idle-on-init;
                        phy-type = <1>;
                        hw-caps-read-idle-ctrl;
                        hw-caps-ll-interface;
                        reg = <0x4d000000 0x100>;
                        interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
                        ti,hwmods = "emif2";
+                       ti,no-idle-on-init;
                        phy-type = <1>;
                        hw-caps-read-idle-ctrl;
                        hw-caps-ll-interface;
                        usb2_phy: usb2phy@4a0ad080 {
                                compatible = "ti,omap-usb2";
                                reg = <0x4a0ad080 0x58>;
-                               ctrl-module = <&omap_control_usb>;
+                               ctrl-module = <&omap_control_usb2phy>;
+                               #phy-cells = <0>;
                        };
                };
 
                        };
                };
 
-               omap_control_usb: omap-control-usb@4a002300 {
-                       compatible = "ti,omap-control-usb";
-                       reg = <0x4a002300 0x4>,
-                             <0x4a00233c 0x4>;
-                       reg-names = "control_dev_conf", "otghs_control";
-                       ti,type = <1>;
+               omap_control_usb2phy: control-phy@4a002300 {
+                       compatible = "ti,control-phy-usb2";
+                       reg = <0x4a002300 0x4>;
+                       reg-names = "power";
+               };
+
+               omap_control_usbotg: control-phy@4a00233c {
+                       compatible = "ti,control-phy-otghs";
+                       reg = <0x4a00233c 0x4>;
+                       reg-names = "otghs_control";
                };
 
                usb_otg_hs: usb_otg_hs@4a0ab000 {
                        interrupt-names = "mc", "dma";
                        ti,hwmods = "usb_otg_hs";
                        usb-phy = <&usb2_phy>;
+                       phys = <&usb2_phy>;
+                       phy-names = "usb2-phy";
                        multipoint = <1>;
                        num-eps = <16>;
                        ram-bits = <12>;
-                       ti,has-mailbox;
+                       ctrl-module = <&omap_control_usbotg>;
+               };
+
+               aes: aes@4b501000 {
+                       compatible = "ti,omap4-aes";
+                       ti,hwmods = "aes";
+                       reg = <0x4b501000 0xa0>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&sdma 111>, <&sdma 110>;
+                       dma-names = "tx", "rx";
+               };
+
+               des: des@480a5000 {
+                       compatible = "ti,omap4-des";
+                       ti,hwmods = "des";
+                       reg = <0x480a5000 0xa0>;
+                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&sdma 117>, <&sdma 116>;
+                       dma-names = "tx", "rx";
                };
        };
 };
index 65d7b601651c390f78272602c79d6fb3b172ce4f..002fa70180a5bf38eaa66564cedd21f16897d626 100644 (file)
                regulator-max-microvolt = <3000000>;
        };
 
-       /* HS USB Port 2 RESET */
-       hsusb2_reset: hsusb2_reset_reg {
-               compatible = "regulator-fixed";
-               regulator-name = "hsusb2_reset";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>; /* gpio3_80 HUB_NRESET */
-               startup-delay-us = <70000>;
-               enable-active-high;
-       };
-
        /* HS USB Host PHY on PORT 2 */
        hsusb2_phy: hsusb2_phy {
                compatible = "usb-nop-xceiv";
-               reset-supply = <&hsusb2_reset>;
+               reset-gpios = <&gpio3 16 GPIO_ACTIVE_LOW>; /* gpio3_80 HUB_NRESET */
        /**
          * FIXME
          * Put the right clock phandle here when available
                clock-frequency = <19200000>;
        };
 
-       /* HS USB Port 3 RESET */
-       hsusb3_reset: hsusb3_reset_reg {
-               compatible = "regulator-fixed";
-               regulator-name = "hsusb3_reset";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; /* gpio3_79 ETH_NRESET */
-               startup-delay-us = <70000>;
-               enable-active-high;
-       };
-
        /* HS USB Host PHY on PORT 3 */
        hsusb3_phy: hsusb3_phy {
                compatible = "usb-nop-xceiv";
-               reset-supply = <&hsusb3_reset>;
+               reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; /* gpio3_79 ETH_NRESET */
        };
 
        leds {
@@ -84,7 +62,6 @@
        pinctrl-0 = <
                        &twl6040_pins
                        &mcpdm_pins
-                       &dmic_pins
                        &mcbsp1_pins
                        &mcbsp2_pins
                        &usbhost_pins
@@ -93,7 +70,7 @@
 
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
-                       0x18a (PIN_OUTPUT | MUX_MODE6)  /* perslimbus2_clock.gpio5_145 */
+                       0x17e (PIN_OUTPUT | MUX_MODE6)  /* mcspi1_somi.gpio5_141 */
                >;
        };
 
                >;
        };
 
-       dmic_pins: pinmux_dmic_pins {
-               pinctrl-single,pins = <
-                       0x144 (PIN_INPUT | MUX_MODE0)           /* abedmic_din1.abedmic_din1 */
-                       0x146 (PIN_INPUT | MUX_MODE0)           /* abedmic_din2.abedmic_din2 */
-                       0x148 (PIN_INPUT | MUX_MODE0)           /* abedmic_din3.abedmic_din3 */
-                       0x14a (PIN_OUTPUT | MUX_MODE0)          /* abedmic_clk1.abedmic_clk1 */
-               >;
-       };
-
        mcbsp1_pins: pinmux_mcbsp1_pins {
                pinctrl-single,pins = <
                        0x14c (PIN_INPUT | MUX_MODE1)           /* abedmic_clk2.abemcbsp1_fsx */
                        0xbc (PIN_INPUT | MUX_MODE0)            /*  mcspi2_clk */
                        0xbe (PIN_INPUT | MUX_MODE0)            /*  mcspi2_simo */
                        0xc0 (PIN_INPUT_PULLUP | MUX_MODE0)     /*  mcspi2_somi */
-                       0xc2 (PIN_OUTPUT | MUX_MODE0)           /*  mcspi2_cs */
+                       0xc2 (PIN_OUTPUT | MUX_MODE0)           /*  mcspi2_cs0 */
                >;
        };
 
        mcspi3_pins: pinmux_mcspi3_pins {
                pinctrl-single,pins = <
-                       0x78 (PIN_INPUT | MUX_MODE1)            /*  mcspi2_somi */
-                       0x7a (PIN_INPUT | MUX_MODE1)            /*  mcspi2_cs */
-                       0x7c (PIN_INPUT | MUX_MODE1)            /*  mcspi2_simo */
-                       0x7e (PIN_INPUT | MUX_MODE1)            /*  mcspi2_clk */
+                       0x78 (PIN_INPUT | MUX_MODE1)            /*  mcspi3_somi */
+                       0x7a (PIN_INPUT | MUX_MODE1)            /*  mcspi3_cs0 */
+                       0x7c (PIN_INPUT | MUX_MODE1)            /*  mcspi3_simo */
+                       0x7e (PIN_INPUT | MUX_MODE1)            /*  mcspi3_clk */
                >;
        };
 
        mcspi4_pins: pinmux_mcspi4_pins {
                pinctrl-single,pins = <
-                       0x164 (PIN_INPUT | MUX_MODE1)           /*  mcspi2_clk */
-                       0x168 (PIN_INPUT | MUX_MODE1)           /*  mcspi2_simo */
-                       0x16a (PIN_INPUT | MUX_MODE1)           /*  mcspi2_somi */
-                       0x16c (PIN_INPUT | MUX_MODE1)           /*  mcspi2_cs */
+                       0x164 (PIN_INPUT | MUX_MODE1)           /*  mcspi4_clk */
+                       0x168 (PIN_INPUT | MUX_MODE1)           /*  mcspi4_simo */
+                       0x16a (PIN_INPUT | MUX_MODE1)           /*  mcspi4_somi */
+                       0x16c (PIN_INPUT | MUX_MODE1)           /*  mcspi4_cs0 */
                >;
        };
 
                reg = <0x48>;
                interrupt-controller;
                #interrupt-cells = <2>;
+               ti,system-power-controller;
+
+               extcon_usb3: palmas_usb {
+                       compatible = "ti,palmas-usb-vid";
+                       ti,enable-vbus-detection;
+                       ti,enable-id-detection;
+                       ti,wakeup;
+               };
 
                palmas_pmic {
                        compatible = "ti,palmas-pmic";
                                        ti,smps-range = <0x80>;
                                };
 
-                               smps10_reg: smps10 {
+                               smps10_out2_reg: smps10_out2 {
                                        /* VBUS_5V_OTG */
-                                       regulator-name = "smps10";
+                                       regulator-name = "smps10_out2";
                                        regulator-min-microvolt = <5000000>;
                                        regulator-max-microvolt = <5000000>;
                                        regulator-always-on;
                                        regulator-boot-on;
                                };
 
+                               smps10_out1_reg: smps10_out1 {
+                                       /* VBUS_5V_OTG */
+                                       regulator-name = "smps10_out1";
+                                       regulator-min-microvolt = <5000000>;
+                                       regulator-max-microvolt = <5000000>;
+                               };
+
                                ldo1_reg: ldo1 {
                                        /* VDDAPHY_CAM: vdda_csiport */
                                        regulator-name = "ldo1";
        phys = <0 &hsusb2_phy &hsusb3_phy>;
 };
 
+&usb3 {
+       extcon = <&extcon_usb3>;
+       vbus-supply = <&smps10_out1_reg>;
+};
+
 &mcspi1 {
 
 };
         pinctrl-names = "default";
         pinctrl-0 = <&uart5_pins>;
 };
+
+&cpu0 {
+       cpu0-supply = <&smps123_reg>;
+};
index 7cdea1bfea091917455e46cc18af7d6d80a2c0f0..fc3fad563861ba3caf5818de8ea9594c59dd021f 100644 (file)
        interrupt-parent = <&gic>;
 
        aliases {
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
+               i2c4 = &i2c5;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x0>;
+
+                       operating-points = <
+                               /* kHz    uV */
+                               500000  880000
+                               1000000 1060000
+                               1500000 1250000
+                       >;
                };
                cpu@1 {
                        device_type = "cpu";
@@ -52,7 +64,6 @@
                             <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
                             <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
                             <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>;
-               clock-frequency = <6144000>;
        };
 
        gic: interrupt-controller@48211000 {
                        ti,hwmods = "i2c5";
                };
 
+               hwspinlock: spinlock@4a0f6000 {
+                       compatible = "ti,omap4-hwspinlock";
+                       reg = <0x4a0f6000 0x1000>;
+                       ti,hwmods = "spinlock";
+               };
+
                mcspi1: spi@48098000 {
                        compatible = "ti,omap4-mcspi";
                        reg = <0x48098000 0x200>;
                        ti,hwmods = "wd_timer2";
                };
 
-               emif1: emif@0x4c000000 {
+               emif1: emif@4c000000 {
                        compatible      = "ti,emif-4d5";
                        ti,hwmods       = "emif1";
+                       ti,no-idle-on-init;
                        phy-type        = <2>; /* DDR PHY type: Intelli PHY */
                        reg = <0x4c000000 0x400>;
                        interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
                        hw-caps-temp-alert;
                };
 
-               emif2: emif@0x4d000000 {
+               emif2: emif@4d000000 {
                        compatible      = "ti,emif-4d5";
                        ti,hwmods       = "emif2";
+                       ti,no-idle-on-init;
                        phy-type        = <2>; /* DDR PHY type: Intelli PHY */
                        reg = <0x4d000000 0x400>;
                        interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
                        hw-caps-temp-alert;
                };
 
-               omap_control_usb: omap-control-usb@4a002300 {
-                       compatible = "ti,omap-control-usb";
-                       reg = <0x4a002300 0x4>,
-                             <0x4a002370 0x4>;
-                       reg-names = "control_dev_conf", "phy_power_usb";
-                       ti,type = <2>;
+               omap_control_usb2phy: control-phy@4a002300 {
+                       compatible = "ti,control-phy-usb2";
+                       reg = <0x4a002300 0x4>;
+                       reg-names = "power";
+               };
+
+               omap_control_usb3phy: control-phy@4a002370 {
+                       compatible = "ti,control-phy-pipe3";
+                       reg = <0x4a002370 0x4>;
+                       reg-names = "power";
                };
 
-               omap_dwc3@4a020000 {
+               usb3: omap_dwc3@4a020000 {
                        compatible = "ti,dwc3";
                        ti,hwmods = "usb_otg_ss";
                        reg = <0x4a020000 0x10000>;
                                reg = <0x4a030000 0x10000>;
                                interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
                                usb-phy = <&usb2_phy>, <&usb3_phy>;
+                               dr_mode = "peripheral";
                                tx-fifo-resize;
                        };
                };
                        usb2_phy: usb2phy@4a084000 {
                                compatible = "ti,omap-usb2";
                                reg = <0x4a084000 0x7c>;
-                               ctrl-module = <&omap_control_usb>;
+                               ctrl-module = <&omap_control_usb2phy>;
                        };
 
                        usb3_phy: usb3phy@4a084400 {
                                      <0x4a084800 0x64>,
                                      <0x4a084c00 0x40>;
                                reg-names = "phy_rx", "phy_tx", "pll_ctrl";
-                               ctrl-module = <&omap_control_usb>;
+                               ctrl-module = <&omap_control_usb3phy>;
                        };
                };
 
index 27ed9f5144bcb927d777cf4468c1ddaa5c11c837..7cf78afee7b1dfba7aec7137446d043af55d023f 100644 (file)
                                compatible = "sirf,prima2-rsc";
                                reg = <0x88020000 0x1000>;
                        };
+
+                       cphifbg@88030000 {
+                               compatible = "sirf,prima2-cphifbg";
+                               reg = <0x88030000 0x1000>;
+                       };
                };
 
                mem-iobg {
 
                        memory-controller@90000000 {
                                compatible = "sirf,prima2-memc";
-                               reg = <0x90000000 0x10000>;
+                               reg = <0x90000000 0x2000>;
                                interrupts = <27>;
                                clocks = <&clks 5>;
                        };
+
+                       memc-monitor {
+                               compatible = "sirf,prima2-memcmon";
+                               reg = <0x90002000 0x200>;
+                               interrupts = <4>;
+                               clocks = <&clks 32>;
+                       };
                };
 
                disp-iobg {
                                compatible = "sirf,prima2-spi";
                                reg = <0xb00d0000 0x10000>;
                                interrupts = <15>;
+                               sirf,spi-num-chipselects = <1>;
+                               sirf,spi-dma-rx-channel = <25>;
+                               sirf,spi-dma-tx-channel = <20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                clocks = <&clks 19>;
+                               status = "disabled";
                        };
 
                        spi1: spi@b0170000 {
                                compatible = "sirf,prima2-spi";
                                reg = <0xb0170000 0x10000>;
                                interrupts = <16>;
+                               sirf,spi-num-chipselects = <1>;
+                               sirf,spi-dma-rx-channel = <12>;
+                               sirf,spi-dma-tx-channel = <13>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                clocks = <&clks 20>;
+                               status = "disabled";
                        };
 
                        i2c0: i2c@b00e0000 {
                                reg = <0xb00e0000 0x10000>;
                                interrupts = <24>;
                                clocks = <&clks 17>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                        };
 
                        i2c1: i2c@b00f0000 {
                                reg = <0xb00f0000 0x10000>;
                                interrupts = <25>;
                                clocks = <&clks 18>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                        };
 
                        tsc@b0110000 {
diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts
new file mode 100644 (file)
index 0000000..386d428
--- /dev/null
@@ -0,0 +1,52 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+       model = "Qualcomm MSM8660 SURF";
+       compatible = "qcom,msm8660-surf", "qcom,msm8660";
+       interrupt-parent = <&intc>;
+
+       intc: interrupt-controller@2080000 {
+               compatible = "qcom,msm-8660-qgic";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               reg = < 0x02080000 0x1000 >,
+                     < 0x02081000 0x1000 >;
+       };
+
+       timer@2000000 {
+               compatible = "qcom,scss-timer", "qcom,msm-timer";
+               interrupts = <1 0 0x301>,
+                            <1 1 0x301>,
+                            <1 2 0x301>;
+               reg = <0x02000000 0x100>;
+               clock-frequency = <27000000>,
+                                 <32768>;
+               cpu-offset = <0x40000>;
+       };
+
+       msmgpio: gpio@800000 {
+               compatible = "qcom,msm-gpio";
+               reg = <0x00800000 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               ngpio = <173>;
+               interrupts = <0 32 0x4>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       serial@19c40000 {
+               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+               reg = <0x19c40000 0x1000>,
+                     <0x19c00000 0x1000>;
+               interrupts = <0 195 0x0>;
+       };
+
+       qcom,ssbi@500000 {
+               compatible = "qcom,ssbi";
+               reg = <0x500000 0x1000>;
+               qcom,controller-type = "pmic-arbiter";
+       };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
new file mode 100644 (file)
index 0000000..93e9f7e
--- /dev/null
@@ -0,0 +1,52 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+       model = "Qualcomm MSM8960 CDP";
+       compatible = "qcom,msm8960-cdp", "qcom,msm8960";
+       interrupt-parent = <&intc>;
+
+       intc: interrupt-controller@2000000 {
+               compatible = "qcom,msm-qgic2";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               reg = < 0x02000000 0x1000 >,
+                     < 0x02002000 0x1000 >;
+       };
+
+       timer@200a000 {
+               compatible = "qcom,kpss-timer", "qcom,msm-timer";
+               interrupts = <1 1 0x301>,
+                            <1 2 0x301>,
+                            <1 3 0x301>;
+               reg = <0x0200a000 0x100>;
+               clock-frequency = <27000000>,
+                                 <32768>;
+               cpu-offset = <0x80000>;
+       };
+
+       msmgpio: gpio@800000 {
+               compatible = "qcom,msm-gpio";
+               gpio-controller;
+               #gpio-cells = <2>;
+               ngpio = <150>;
+               interrupts = <0 32 0x4>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               reg = <0x800000 0x4000>;
+       };
+
+       serial@16440000 {
+               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+               reg = <0x16440000 0x1000>,
+                     <0x16400000 0x1000>;
+               interrupts = <0 154 0x0>;
+       };
+
+       qcom,ssbi@500000 {
+               compatible = "qcom,ssbi";
+               reg = <0x500000 0x1000>;
+               qcom,controller-type = "pmic-arbiter";
+       };
+};
diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts
new file mode 100644 (file)
index 0000000..1fb20f2
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Device Tree Source for the Genmai board
+ *
+ * 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/ "r7s72100.dtsi"
+
+/ {
+       model = "Genmai";
+       compatible = "renesas,genmai", "renesas,r7s72100";
+
+       chosen {
+               bootargs = "console=ttySC2,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x08000000 0x08000000>;
+       };
+
+       lbsc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
new file mode 100644 (file)
index 0000000..46b82aa
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Device Tree Source for the r7s72100 SoC
+ *
+ * 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.
+ */
+
+/ {
+       compatible = "renesas,r7s72100";
+       interrupt-parent = <&gic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+               };
+       };
+
+       gic: interrupt-controller@e8201000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0xe8201000 0x1000>,
+                       <0xe8202000 0x1000>;
+       };
+};
index f444624eb0974c881e5bac7de144183d366f42b6..9443e93d3cac7f07cfdca4fa24b825424ab310a2 100644 (file)
@@ -10,6 +10,7 @@
 
 /dts-v1/;
 /include/ "r8a73a4.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "APE6EVM";
                reg = <0 0x40000000 0 0x40000000>;
        };
 
+       vcc_mmc0: regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "MMC0 Vcc";
+               regulator-min-microvolt = <2800000>;
+               regulator-max-microvolt = <2800000>;
+               regulator-always-on;
+       };
+
+       vcc_sdhi0: regulator@1 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI0 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&pfc 76 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       /* Common 3.3V rail, used by several devices on APE6EVM */
+       ape6evm_fixed_3v3: regulator@2 {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
        lbsc {
                compatible = "simple-bus";
                #address-cells = <1>;
@@ -33,6 +62,7 @@
 };
 
 &i2c5 {
+       status = "okay";
        vdd_dvfs: max8973@1b {
                compatible = "maxim,max8973";
                reg = <0x1b>;
                renesas,groups = "scifa0_data";
                renesas,function = "scifa0";
        };
+
+       mmc0_pins: mmcif {
+               renesas,groups = "mmc0_data8", "mmc0_ctrl";
+               renesas,function = "mmc0";
+       };
+
+       sdhi0_pins: sdhi0 {
+               renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
+               renesas,function = "sdhi0";
+       };
+
+       sdhi1_pins: sdhi1 {
+               renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+               renesas,function = "sdhi1";
+       };
+};
+
+&mmcif0 {
+       vmmc-supply = <&vcc_mmc0>;
+       bus-width = <8>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins>;
+       status = "okay";
+};
+
+&sdhi0 {
+       vmmc-supply = <&vcc_sdhi0>;
+       bus-width = <4>;
+       toshiba,mmc-wrprotect-disable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhi0_pins>;
+       status = "okay";
+};
+
+&sdhi1 {
+       vmmc-supply = <&ape6evm_fixed_3v3>;
+       bus-width = <4>;
+       broken-cd;
+       toshiba,mmc-wrprotect-disable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhi1_pins>;
+       status = "okay";
 };
index 72f867e657910e268858091d276353f2cc141d6d..91436b58016f1d48fa5cd12c3946377500b9d70a 100644 (file)
@@ -52,6 +52,7 @@
 };
 
 &i2c5 {
+       status = "okay";
        vdd_dvfs: max8973@1b {
                compatible = "maxim,max8973";
                reg = <0x1b>;
index 658fcc537576b309ae06ecb74eaf65b3e3f2856c..287e047592a03d28e009cc0500c27ab6a18e6de1 100644 (file)
                                <0 56 4>, <0 57 4>;
        };
 
+       dmac: dma-multiplexer@0 {
+               compatible = "renesas,shdma-mux";
+               #dma-cells = <1>;
+               dma-channels = <20>;
+               dma-requests = <256>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               dma0: dma-controller@e6700020 {
+                       compatible = "renesas,shdma-r8a73a4";
+                       reg = <0 0xe6700020 0 0x89e0>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 220 4
+                                       0 200 4
+                                       0 201 4
+                                       0 202 4
+                                       0 203 4
+                                       0 204 4
+                                       0 205 4
+                                       0 206 4
+                                       0 207 4
+                                       0 208 4
+                                       0 209 4
+                                       0 210 4
+                                       0 211 4
+                                       0 212 4
+                                       0 213 4
+                                       0 214 4
+                                       0 215 4
+                                       0 216 4
+                                       0 217 4
+                                       0 218 4
+                                       0 219 4>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15",
+                                       "ch16", "ch17", "ch18", "ch19";
+               };
+       };
+
        thermal@e61f0000 {
                compatible = "renesas,rcar-thermal";
                reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>,
                reg = <0 0xe6500000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 174 0x4>;
+               status = "disabled";
        };
 
        i2c1: i2c@e6510000 {
                reg = <0 0xe6510000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 175 0x4>;
+               status = "disabled";
        };
 
        i2c2: i2c@e6520000 {
                reg = <0 0xe6520000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 176 0x4>;
+               status = "disabled";
        };
 
        i2c3: i2c@e6530000 {
                reg = <0 0xe6530000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 177 0x4>;
+               status = "disabled";
        };
 
        i2c4: i2c@e6540000 {
                reg = <0 0xe6540000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 178 0x4>;
+               status = "disabled";
        };
 
        i2c5: i2c@e60b0000 {
                reg = <0 0xe60b0000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 179 0x4>;
+               status = "disabled";
        };
 
        i2c6: i2c@e6550000 {
                reg = <0 0xe6550000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 184 0x4>;
+               status = "disabled";
        };
 
        i2c7: i2c@e6560000 {
                reg = <0 0xe6560000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 185 0x4>;
+               status = "disabled";
        };
 
        i2c8: i2c@e6570000 {
                reg = <0 0xe6570000 0 0x428>;
                interrupt-parent = <&gic>;
                interrupts = <0 173 0x4>;
+               status = "disabled";
        };
 
        mmcif0: mmcif@ee200000 {
index c638e4ab91b8ee95655ab0784803f8a2ffb5ce1c..1c56c5e56950846217471ae98ee00c5bed4922ac 100644 (file)
@@ -11,6 +11,7 @@
 /dts-v1/;
 /include/ "r8a7740.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "armadillo 800 eva reference";
                regulator-boot-on;
        };
 
+       vcc_sdhi0: regulator@1 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI0 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&pfc 75 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi0: regulator@2 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI0 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc_sdhi0>;
+
+               enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>;
+               gpios = <&pfc 17 GPIO_ACTIVE_HIGH>;
+               states = <3300000 0
+                         1800000 1>;
+
+               enable-active-high;
+       };
+
        leds {
                compatible = "gpio-leds";
                led1 {
                        gpios = <&pfc 177 GPIO_ACTIVE_HIGH>;
                };
        };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&tpu 2 33333 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 1 2 4 8 16 32 64 128 255>;
+               default-brightness-level = <9>;
+               pinctrl-0 = <&backlight_pins>;
+               pinctrl-names = "default";
+       };
 };
 
 &i2c0 {
+       status = "okay";
        touchscreen: st1232@55 {
                compatible = "sitronix,st1232";
                reg = <0x55>;
                renesas,groups = "intc_irq10";
                renesas,function = "intc";
        };
+
+       backlight_pins: backlight {
+               renesas,groups = "tpu0_to2_1";
+               renesas,function = "tpu0";
+       };
+
+       mmc0_pins: mmc0 {
+               renesas,groups = "mmc0_data8_1", "mmc0_ctrl_1";
+               renesas,function = "mmc0";
+       };
+
+       sdhi0_pins: sdhi0 {
+               renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp";
+               renesas,function = "sdhi0";
+       };
+};
+
+&tpu {
+       status = "okay";
+};
+
+&mmcif0 {
+       pinctrl-0 = <&mmc0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&reg_3p3v>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi0>;
+       vqmmc-supply = <&vccq_sdhi0>;
+       bus-width = <4>;
+       cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>;
+       status = "okay";
 };
index 44d3d520e01ffd0cce0c48527889d2ddf8e4c230..ae1e230f711ddf243168abc55cfc6cd3e3095cf8 100644 (file)
                              0 202 0x4
                              0 203 0x4
                              0 204 0x4>;
+               status = "disabled";
        };
 
        i2c1: i2c@e6c20000 {
                              0 71 0x4
                              0 72 0x4
                              0 73 0x4>;
+               status = "disabled";
        };
 
        pfc: pfc@e6050000 {
                status = "disabled";
                #pwm-cells = <3>;
        };
+
+       mmcif0: mmcif@e6bd0000 {
+               compatible = "renesas,sh-mmcif";
+               reg = <0xe6bd0000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 56 4
+                               0 57 4>;
+               status = "disabled";
+       };
+
+       sdhi0: sdhi@e6850000 {
+               compatible = "renesas,sdhi-r8a7740";
+               reg = <0xe6850000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 117 4
+                               0 118 4
+                               0 119 4>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi1: sdhi@e6860000 {
+               compatible = "renesas,sdhi-r8a7740";
+               reg = <0xe6860000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 121 4
+                               0 122 4
+                               0 123 4>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
 };
index 9bb903a3230d0d781fa866949fd4d33fc54a3c23..969e386e852c443f0b5bb95440a0e595d491c04e 100644 (file)
        compatible = "renesas,bockw-reference", "renesas,r8a7778";
 
        chosen {
-               bootargs = "console=ttySC0,115200 ignore_loglevel rw";
+               bootargs = "console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw";
        };
 
        memory {
                device_type = "memory";
                reg = <0x60000000 0x10000000>;
        };
+
+       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;
+       };
+
+       ethernet@18300000 {
+               compatible = "smsc,lan9220", "smsc,lan9115";
+               reg = <0x18300000 0x1000>;
+
+               phy-mode = "mii";
+               interrupt-parent = <&irqpin>;
+               interrupts = <0 0>; /* IRQ0: hwirq 0 on irqpin */
+               reg-io-width = <4>;
+               vddvario-supply = <&fixedregulator3v3>;
+               vdd33a-supply = <&fixedregulator3v3>;
+       };
+};
+
+&irqpin {
+       status = "okay";
 };
index 3577aba8258336bab80d44c3065c6e94f6ffe8a7..a6308a399e2d2dbbf4fed33ee943b37f98ed0991 100644 (file)
                      <0xfe430000 0x100>;
        };
 
+       /* irqpin: IRQ0 - IRQ3 */
+       irqpin: irqpin@fe78001c {
+               compatible = "renesas,intc-irqpin";
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               status = "disabled"; /* default off */
+               reg =   <0xfe78001c 4>,
+                       <0xfe780010 4>,
+                       <0xfe780024 4>,
+                       <0xfe780044 4>,
+                       <0xfe780064 4>;
+               interrupt-parent = <&gic>;
+               interrupts =   <0 27 0x4
+                               0 28 0x4
+                               0 29 0x4
+                               0 30 0x4>;
+               sense-bitfield-width = <2>;
+       };
+
        gpio0: gpio@ffc40000 {
                compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
                reg = <0xffc40000 0x2c>;
index 6d55083922521619781af8c877ade660ae5ad057..ab4110aa3c3b5a4ad31f1600959195099f8ace9c 100644 (file)
@@ -42,8 +42,8 @@
                pinctrl-names = "default";
 
                phy-mode = "mii";
-               interrupt-parent = <&gic>;
-               interrupts = <0 28 0x4>;
+               interrupt-parent = <&irqpin0>;
+               interrupts = <1 0>; /* IRQ1: hwirq 1 on irqpin0 */
                reg-io-width = <4>;
                vddvario-supply = <&fixedregulator3v3>;
                vdd33a-supply = <&fixedregulator3v3>;
        };
 };
 
+&irqpin0 {
+       status = "okay";
+};
+
 &pfc {
        pinctrl-0 = <&scif2_pins &scif4_pins &sdhi0_pins>;
        pinctrl-names = "default";
index ebbe507fcbfa118280da96482dfaa109854f18c8..19faeac3fd2e1b74f5d289948dd486f473f931de 100644 (file)
        irqpin0: irqpin@fe780010 {
                compatible = "renesas,intc-irqpin";
                #interrupt-cells = <2>;
+               status = "disabled";
                interrupt-controller;
                reg = <0xfe78001c 4>,
                        <0xfe780010 4>,
                reg = <0xffc70000 0x1000>;
                interrupt-parent = <&gic>;
                interrupts = <0 79 0x4>;
+               status = "disabled";
        };
 
        i2c1: i2c@ffc71000 {
                reg = <0xffc71000 0x1000>;
                interrupt-parent = <&gic>;
                interrupts = <0 82 0x4>;
+               status = "disabled";
        };
 
        i2c2: i2c@ffc72000 {
                reg = <0xffc72000 0x1000>;
                interrupt-parent = <&gic>;
                interrupts = <0 80 0x4>;
+               status = "disabled";
        };
 
        i2c3: i2c@ffc73000 {
                reg = <0xffc73000 0x1000>;
                interrupt-parent = <&gic>;
                interrupts = <0 81 0x4>;
+               status = "disabled";
        };
 
        pfc: pfc@fffc0000 {
index 413b4c29e782d7ded622563b8a458e28d382db19..ee845fad939b895a1bfb907c6597f9f916d926f8 100644 (file)
                        reg = <0>;
                        clock-frequency = <1300000000>;
                };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <1>;
+                       clock-frequency = <1300000000>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <2>;
+                       clock-frequency = <1300000000>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <3>;
+                       clock-frequency = <1300000000>;
+               };
+
+               cpu4: cpu@4 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x100>;
+                       clock-frequency = <780000000>;
+               };
+
+               cpu5: cpu@5 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x101>;
+                       clock-frequency = <780000000>;
+               };
+
+               cpu6: cpu@6 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x102>;
+                       clock-frequency = <780000000>;
+               };
+
+               cpu7: cpu@7 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x103>;
+                       clock-frequency = <780000000>;
+               };
        };
 
        gic: interrupt-controller@f1001000 {
                interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>;
        };
 
+       i2c0: i2c@e6508000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7790";
+               reg = <0 0xe6508000 0 0x40>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 287 0x4>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@e6518000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7790";
+               reg = <0 0xe6518000 0 0x40>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 288 0x4>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@e6530000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7790";
+               reg = <0 0xe6530000 0 0x40>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 286 0x4>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@e6540000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7790";
+               reg = <0 0xe6540000 0 0x40>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 290 0x4>;
+               status = "disabled";
+       };
+
        mmcif0: mmcif@ee200000 {
                compatible = "renesas,sh-mmcif";
                reg = <0 0xee200000 0 0x80>;
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
new file mode 100644 (file)
index 0000000..1ce5250
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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"
+
+/ {
+       model = "Koelsch";
+       compatible = "renesas,koelsch", "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>;
+       };
+};
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
new file mode 100644 (file)
index 0000000..fea5cfe
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Device Tree Source for the r8a7791 SoC
+ *
+ * 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.
+ */
+
+/ {
+       compatible = "renesas,r8a7791";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <0>;
+                       clock-frequency = <1300000000>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <1>;
+                       clock-frequency = <1300000000>;
+               };
+       };
+
+       gic: interrupt-controller@f1001000 {
+               compatible = "arm,cortex-a15-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0 0xf1001000 0 0x1000>,
+                       <0 0xf1002000 0 0x1000>,
+                       <0 0xf1004000 0 0x2000>,
+                       <0 0xf1006000 0 0x2000>;
+               interrupts = <1 9 0xf04>;
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <1 13 0xf08>,
+                               <1 14 0xf08>,
+                               <1 11 0xf08>,
+                               <1 10 0xf08>;
+       };
+
+       irqc0: interrupt-controller@e61c0000 {
+               compatible = "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>;
+       };
+};
diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
new file mode 100644 (file)
index 0000000..035df40
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+/dts-v1/;
+#include "rk3066a.dtsi"
+
+/ {
+       model = "bq Curie 2";
+
+       memory {
+               reg = <0x60000000 0x40000000>;
+       };
+
+       soc {
+               uart0: serial@10124000 {
+                       status = "okay";
+               };
+
+               uart1: serial@10126000 {
+                       status = "okay";
+               };
+
+               uart2: serial@20064000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&uart2_xfer>;
+                       status = "okay";
+               };
+
+               uart3: serial@20068000 {
+                       status = "okay";
+               };
+
+               vcc_sd0: fixed-regulator {
+                       compatible = "regulator-fixed";
+                       regulator-name = "sdmmc-supply";
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+                       gpio = <&gpio3 7 GPIO_ACTIVE_LOW>;
+                       startup-delay-us = <100000>;
+               };
+
+               dwmmc@10214000 { /* sdmmc */
+                       num-slots = <1>;
+                       status = "okay";
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>;
+                       vmmc-supply = <&vcc_sd0>;
+
+                       slot@0 {
+                               reg = <0>;
+                               bus-width = <4>;
+                               disable-wp;
+                       };
+               };
+
+               dwmmc@10218000 { /* wifi */
+                       num-slots = <1>;
+                       status = "okay";
+                       non-removable;
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>;
+
+                       slot@0 {
+                               reg = <0>;
+                               bus-width = <4>;
+                               disable-wp;
+                       };
+               };
+
+               gpio-keys {
+                       compatible = "gpio-keys";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       autorepeat;
+
+                       button@0 {
+                               gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; /* GPIO6_A2 */
+                               linux,code = <116>;
+                               label = "GPIO Key Power";
+                               linux,input-type = <1>;
+                               gpio-key,wakeup = <1>;
+                               debounce-interval = <100>;
+                       };
+                       button@1 {
+                               gpios = <&gpio4 21 GPIO_ACTIVE_LOW>; /* GPIO4_C5 */
+                               linux,code = <104>;
+                               label = "GPIO Key Vol-";
+                               linux,input-type = <1>;
+                               gpio-key,wakeup = <0>;
+                               debounce-interval = <100>;
+                       };
+                       /* VOL+ comes somehow thru the ADC */
+               };
+       };
+};
index 56bfac93d3f614f04d1f122a445090922941270a..be5d2b09a363d15c66c648ab5079c9d1312226ce 100644 (file)
  */
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/pinctrl/rockchip.h>
-#include "skeleton.dtsi"
+#include "rk3xxx.dtsi"
 #include "rk3066a-clocks.dtsi"
 
 / {
        compatible = "rockchip,rk3066a";
-       interrupt-parent = <&gic>;
 
        cpus {
                #address-cells = <1>;
        };
 
        soc {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               compatible = "simple-bus";
-               ranges;
-
-               gic: interrupt-controller@1013d000 {
-                       compatible = "arm,cortex-a9-gic";
-                       interrupt-controller;
-                       #interrupt-cells = <3>;
-                       reg = <0x1013d000 0x1000>,
-                             <0x1013c100 0x0100>;
-               };
-
-               L2: l2-cache-controller@10138000 {
-                       compatible = "arm,pl310-cache";
-                       reg = <0x10138000 0x1000>;
-                       cache-unified;
-                       cache-level = <2>;
-               };
-
-               local-timer@1013c600 {
-                       compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x1013c600 0x20>;
-                       interrupts = <GIC_PPI 13 0x304>;
-                       clocks = <&dummy150m>;
-               };
-
                timer@20038000 {
                        compatible = "snps,dw-apb-timer-osc";
                        reg = <0x20038000 0x100>;
                                uart0_xfer: uart0-xfer {
                                        rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                uart0_cts: uart0-cts {
                                        rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                uart0_rts: uart0-rts {
                                        rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
                        };
 
                                uart1_xfer: uart1-xfer {
                                        rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                uart1_cts: uart1-cts {
                                        rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                uart1_rts: uart1-rts {
                                        rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
                        };
 
                                uart2_xfer: uart2-xfer {
                                        rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
                                /* no rts / cts for uart2 */
                        };
                                uart3_xfer: uart3-xfer {
                                        rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                uart3_cts: uart3-cts {
                                        rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                uart3_rts: uart3-rts {
                                        rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
                        };
 
                        sd0 {
                                sd0_clk: sd0-clk {
                                        rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd0_cmd: sd0-cmd {
                                        rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd0_cd: sd0-cd {
                                        rockchip,pins = <RK_GPIO3 14 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd0_wp: sd0-wp {
                                        rockchip,pins = <RK_GPIO3 15 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd0_bus1: sd0-bus-width1 {
                                        rockchip,pins = <RK_GPIO3 10 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd0_bus4: sd0-bus-width4 {
                                                        <RK_GPIO3 11 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO3 12 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO3 13 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
                        };
 
                        sd1 {
                                sd1_clk: sd1-clk {
                                        rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd1_cmd: sd1-cmd {
                                        rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd1_cd: sd1-cd {
                                        rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd1_wp: sd1-wp {
                                        rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd1_bus1: sd1-bus-width1 {
                                        rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
 
                                sd1_bus4: sd1-bus-width4 {
                                                        <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_default>,
                                                        <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_default>;
-                                       rockchip,config = <&pcfg_pull_default>;
                                };
                        };
                };
-
-               uart0: serial@10124000 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x10124000 0x400>;
-                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-shift = <2>;
-                       reg-io-width = <1>;
-                       clocks = <&clk_gates1 8>;
-                       status = "disabled";
-               };
-
-               uart1: serial@10126000 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x10126000 0x400>;
-                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-shift = <2>;
-                       reg-io-width = <1>;
-                       clocks = <&clk_gates1 10>;
-                       status = "disabled";
-               };
-
-               uart2: serial@20064000 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x20064000 0x400>;
-                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-shift = <2>;
-                       reg-io-width = <1>;
-                       clocks = <&clk_gates1 12>;
-                       status = "disabled";
-               };
-
-               uart3: serial@20068000 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x20068000 0x400>;
-                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-shift = <2>;
-                       reg-io-width = <1>;
-                       clocks = <&clk_gates1 14>;
-                       status = "disabled";
-               };
-
-               dwmmc@10214000 {
-                       compatible = "rockchip,rk2928-dw-mshc";
-                       reg = <0x10214000 0x1000>;
-                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       clocks = <&clk_gates5 10>, <&clk_gates2 11>;
-                       clock-names = "biu", "ciu";
-
-                       status = "disabled";
-               };
-
-               dwmmc@10218000 {
-                       compatible = "rockchip,rk2928-dw-mshc";
-                       reg = <0x10218000 0x1000>;
-                       interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       clocks = <&clk_gates5 11>, <&clk_gates2 13>;
-                       clock-names = "biu", "ciu";
-
-                       status = "disabled";
-               };
        };
 };
diff --git a/arch/arm/boot/dts/rk3188-clocks.dtsi b/arch/arm/boot/dts/rk3188-clocks.dtsi
new file mode 100644 (file)
index 0000000..b1b92dc
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+/ {
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /*
+                * This is a dummy clock, to be used as placeholder on
+                * other mux clocks when a specific parent clock is not
+                * yet implemented. It should be dropped when the driver
+                * is complete.
+                */
+               dummy: dummy {
+                       compatible = "fixed-clock";
+                       clock-frequency = <0>;
+                       #clock-cells = <0>;
+               };
+
+               xin24m: xin24m {
+                       compatible = "fixed-clock";
+                       clock-frequency = <24000000>;
+                       #clock-cells = <0>;
+               };
+
+               dummy48m: dummy48m {
+                       compatible = "fixed-clock";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+
+               dummy150m: dummy150m {
+                       compatible = "fixed-clock";
+                       clock-frequency = <150000000>;
+                       #clock-cells = <0>;
+               };
+
+               clk_gates0: gate-clk@200000d0 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000d0 0x4>;
+                       clocks = <&dummy150m>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_core_periph", "gate_cpu_gpll",
+                               "gate_ddrphy", "gate_aclk_cpu",
+                               "gate_hclk_cpu", "gate_pclk_cpu",
+                               "gate_atclk_cpu", "gate_aclk_core",
+                               "reserved", "gate_i2s0",
+                               "gate_i2s0_frac", "reserved",
+                               "reserved", "gate_spdif",
+                               "gate_spdif_frac", "gate_testclk";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates1: gate-clk@200000d4 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000d4 0x4>;
+                       clocks = <&xin24m>, <&xin24m>,
+                                <&xin24m>, <&dummy>,
+                                <&dummy>, <&xin24m>,
+                                <&xin24m>, <&dummy>,
+                                <&xin24m>, <&dummy>,
+                                <&xin24m>, <&dummy>,
+                                <&xin24m>, <&dummy>,
+                                <&xin24m>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_timer0", "gate_timer1",
+                               "gate_timer3", "gate_jtag",
+                               "gate_aclk_lcdc1_src", "gate_otgphy0",
+                               "gate_otgphy1", "gate_ddr_gpll",
+                               "gate_uart0", "gate_frac_uart0",
+                               "gate_uart1", "gate_frac_uart1",
+                               "gate_uart2", "gate_frac_uart2",
+                               "gate_uart3", "gate_frac_uart3";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates2: gate-clk@200000d8 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000d8 0x4>;
+                       clocks = <&clk_gates2 1>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&clk_gates2 3>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy48m>,
+                                <&dummy>, <&dummy48m>,
+                                <&dummy>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_periph_src", "gate_aclk_periph",
+                               "gate_hclk_periph", "gate_pclk_periph",
+                               "gate_smc", "gate_mac",
+                               "gate_hsadc", "gate_hsadc_frac",
+                               "gate_saradc", "gate_spi0",
+                               "gate_spi1", "gate_mmc0",
+                               "gate_mac_lbtest", "gate_mmc1",
+                               "gate_emmc", "reserved";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates3: gate-clk@200000dc {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000dc 0x4>;
+                       clocks = <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&xin24m>, <&xin24m>,
+                                <&dummy>, <&dummy>,
+                                <&xin24m>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&xin24m>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_aclk_lcdc0_src", "gate_dclk_lcdc0",
+                               "gate_dclk_lcdc1", "gate_pclkin_cif0",
+                               "gate_timer2", "gate_timer4",
+                               "gate_hsicphy", "gate_cif0_out",
+                               "gate_timer5", "gate_aclk_vepu",
+                               "gate_hclk_vepu", "gate_aclk_vdpu",
+                               "gate_hclk_vdpu", "reserved",
+                               "gate_timer6", "gate_aclk_gpu_src";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates4: gate-clk@200000e0 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000e0 0x4>;
+                       clocks = <&clk_gates2 2>, <&clk_gates2 3>,
+                                <&clk_gates2 1>, <&clk_gates2 1>,
+                                <&clk_gates2 1>, <&clk_gates2 2>,
+                                <&clk_gates2 2>, <&clk_gates2 2>,
+                                <&clk_gates0 4>, <&clk_gates0 4>,
+                                <&clk_gates0 3>, <&dummy>,
+                                <&clk_gates0 3>, <&dummy>,
+                                <&dummy>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_hclk_peri_axi_matrix", "gate_pclk_peri_axi_matrix",
+                               "gate_aclk_cpu_peri", "gate_aclk_peri_axi_matrix",
+                               "gate_aclk_pei_niu", "gate_hclk_usb_peri",
+                               "gate_hclk_peri_ahb_arbi", "gate_hclk_emem_peri",
+                               "gate_hclk_cpubus", "gate_hclk_ahb2apb",
+                               "gate_aclk_strc_sys", "reserved",
+                               "gate_aclk_intmem", "reserved",
+                               "gate_hclk_imem1", "gate_hclk_imem0";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates5: gate-clk@200000e4 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000e4 0x4>;
+                       clocks = <&clk_gates0 3>, <&clk_gates2 1>,
+                                <&clk_gates0 5>, <&clk_gates0 5>,
+                                <&clk_gates0 5>, <&clk_gates0 5>,
+                                <&clk_gates0 4>, <&clk_gates0 5>,
+                                <&clk_gates2 1>, <&clk_gates2 2>,
+                                <&clk_gates2 2>, <&clk_gates2 2>,
+                                <&clk_gates2 2>, <&clk_gates4 5>;
+
+                       clock-output-names =
+                               "gate_aclk_dmac1", "gate_aclk_dmac2",
+                               "gate_pclk_efuse", "gate_pclk_tzpc",
+                               "gate_pclk_grf", "gate_pclk_pmu",
+                               "gate_hclk_rom", "gate_pclk_ddrupctl",
+                               "gate_aclk_smc", "gate_hclk_nandc",
+                               "gate_hclk_mmc0", "gate_hclk_mmc1",
+                               "gate_hclk_emmc", "gate_hclk_otg0";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates6: gate-clk@200000e8 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000e8 0x4>;
+                       clocks = <&clk_gates3 0>, <&clk_gates0 4>,
+                                <&clk_gates0 4>, <&clk_gates1 4>,
+                                <&clk_gates0 4>, <&clk_gates3 0>,
+                                <&dummy>, <&dummy>,
+                                <&clk_gates3 0>, <&clk_gates0 4>,
+                                <&clk_gates0 4>, <&clk_gates1 4>,
+                                <&clk_gates0 4>, <&clk_gates3 0>;
+
+                       clock-output-names =
+                               "gate_aclk_lcdc0", "gate_hclk_lcdc0",
+                               "gate_hclk_lcdc1", "gate_aclk_lcdc1",
+                               "gate_hclk_cif0", "gate_aclk_cif0",
+                               "reserved", "reserved",
+                               "gate_aclk_ipp", "gate_hclk_ipp",
+                               "gate_hclk_rga", "gate_aclk_rga",
+                               "gate_hclk_vio_bus", "gate_aclk_vio0";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates7: gate-clk@200000ec {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000ec 0x4>;
+                       clocks = <&clk_gates2 2>, <&clk_gates0 4>,
+                                <&clk_gates0 4>, <&dummy>,
+                                <&dummy>, <&clk_gates2 2>,
+                                <&clk_gates2 2>, <&clk_gates0 5>,
+                                <&dummy>, <&clk_gates0 5>,
+                                <&clk_gates0 5>, <&clk_gates2 3>,
+                                <&clk_gates2 3>, <&clk_gates2 3>,
+                                <&clk_gates2 3>, <&clk_gates2 3>;
+
+                       clock-output-names =
+                               "gate_hclk_emac", "gate_hclk_spdif",
+                               "gate_hclk_i2s0_2ch", "gate_hclk_otg1",
+                               "gate_hclk_hsic", "gate_hclk_hsadc",
+                               "gate_hclk_pidf", "gate_pclk_timer0",
+                               "reserved", "gate_pclk_timer2",
+                               "gate_pclk_pwm01", "gate_pclk_pwm23",
+                               "gate_pclk_spi0", "gate_pclk_spi1",
+                               "gate_pclk_saradc", "gate_pclk_wdt";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates8: gate-clk@200000f0 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000f0 0x4>;
+                       clocks = <&clk_gates0 5>, <&clk_gates0 5>,
+                                <&clk_gates2 3>, <&clk_gates2 3>,
+                                <&clk_gates0 5>, <&clk_gates0 5>,
+                                <&clk_gates2 3>, <&clk_gates2 3>,
+                                <&clk_gates2 3>, <&clk_gates0 5>,
+                                <&clk_gates0 5>, <&clk_gates0 5>,
+                                <&clk_gates2 3>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_pclk_uart0", "gate_pclk_uart1",
+                               "gate_pclk_uart2", "gate_pclk_uart3",
+                               "gate_pclk_i2c0", "gate_pclk_i2c1",
+                               "gate_pclk_i2c2", "gate_pclk_i2c3",
+                               "gate_pclk_i2c4", "gate_pclk_gpio0",
+                               "gate_pclk_gpio1", "gate_pclk_gpio2",
+                               "gate_pclk_gpio3", "gate_aclk_gps";
+
+                       #clock-cells = <1>;
+               };
+
+               clk_gates9: gate-clk@200000f4 {
+                       compatible = "rockchip,rk2928-gate-clk";
+                       reg = <0x200000f4 0x4>;
+                       clocks = <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>,
+                                <&dummy>, <&dummy>;
+
+                       clock-output-names =
+                               "gate_clk_core_dbg", "gate_pclk_dbg",
+                               "gate_clk_trace", "gate_atclk",
+                               "gate_clk_l2c", "gate_aclk_vio1",
+                               "gate_pclk_publ", "gate_aclk_gpu";
+
+                       #clock-cells = <1>;
+               };
+       };
+
+};
diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
new file mode 100644 (file)
index 0000000..3ba1968
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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.
+ */
+
+/dts-v1/;
+#include "rk3188.dtsi"
+
+/ {
+       model = "Radxa Rock";
+
+       memory {
+               reg = <0x60000000 0x80000000>;
+       };
+
+       soc {
+               uart0: serial@10124000 {
+                       status = "okay";
+               };
+
+               uart1: serial@10126000 {
+                       status = "okay";
+               };
+
+               uart2: serial@20064000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&uart2_xfer>;
+                       status = "okay";
+               };
+
+               uart3: serial@20068000 {
+                       status = "okay";
+               };
+
+               gpio-keys {
+                       compatible = "gpio-keys";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       autorepeat;
+
+                       button@0 {
+                               gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+                               linux,code = <116>;
+                               label = "GPIO Key Power";
+                               linux,input-type = <1>;
+                               gpio-key,wakeup = <1>;
+                               debounce-interval = <100>;
+                       };
+               };
+
+               gpio-leds {
+                       compatible = "gpio-leds";
+
+                       green {
+                               gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+                               default-state = "off";
+                       };
+
+                       yellow {
+                               gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+                               default-state = "off";
+                       };
+
+                       sleep {
+                               gpios = <&gpio0 15 0>;
+                               default-state = "off";
+                       };
+               };
+
+       };
+};
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
new file mode 100644 (file)
index 0000000..1a26b03
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3xxx.dtsi"
+#include "rk3188-clocks.dtsi"
+
+/ {
+       compatible = "rockchip,rk3188";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x0>;
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x1>;
+               };
+               cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x2>;
+               };
+               cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x3>;
+               };
+       };
+
+       soc {
+               global-timer@1013c200 {
+                       interrupts = <GIC_PPI 11 0xf04>;
+               };
+
+               local-timer@1013c600 {
+                       interrupts = <GIC_PPI 13 0xf04>;
+               };
+
+               pinctrl@20008000 {
+                       compatible = "rockchip,rk3188-pinctrl";
+                       reg = <0x20008000 0xa0>,
+                             <0x20008164 0x1a0>;
+                       reg-names = "base", "pull";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       gpio0: gpio0@0x2000a000 {
+                               compatible = "rockchip,rk3188-gpio-bank0";
+                               reg = <0x2000a000 0x100>,
+                                     <0x20004064 0x8>;
+                               interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk_gates8 9>;
+
+                               gpio-controller;
+                               #gpio-cells = <2>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio1: gpio1@0x2003c000 {
+                               compatible = "rockchip,gpio-bank";
+                               reg = <0x2003c000 0x100>;
+                               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk_gates8 10>;
+
+                               gpio-controller;
+                               #gpio-cells = <2>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio2@2003e000 {
+                               compatible = "rockchip,gpio-bank";
+                               reg = <0x2003e000 0x100>;
+                               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk_gates8 11>;
+
+                               gpio-controller;
+                               #gpio-cells = <2>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio3@20080000 {
+                               compatible = "rockchip,gpio-bank";
+                               reg = <0x20080000 0x100>;
+                               interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk_gates8 12>;
+
+                               gpio-controller;
+                               #gpio-cells = <2>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       pcfg_pull_up: pcfg_pull_up {
+                               bias-pull-up;
+                       };
+
+                       pcfg_pull_down: pcfg_pull_down {
+                               bias-pull-down;
+                       };
+
+                       pcfg_pull_none: pcfg_pull_none {
+                               bias-disable;
+                       };
+
+                       uart0 {
+                               uart0_xfer: uart0-xfer {
+                                       rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               uart0_cts: uart0-cts {
+                                       rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               uart0_rts: uart0-rts {
+                                       rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+                       };
+
+                       uart1 {
+                               uart1_xfer: uart1-xfer {
+                                       rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               uart1_cts: uart1-cts {
+                                       rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               uart1_rts: uart1-rts {
+                                       rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+                       };
+
+                       uart2 {
+                               uart2_xfer: uart2-xfer {
+                                       rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+                               /* no rts / cts for uart2 */
+                       };
+
+                       uart3 {
+                               uart3_xfer: uart3-xfer {
+                                       rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               uart3_cts: uart3-cts {
+                                       rockchip,pins = <RK_GPIO1 12 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               uart3_rts: uart3-rts {
+                                       rockchip,pins = <RK_GPIO1 13 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+                       };
+
+                       sd0 {
+                               sd0_clk: sd0-clk {
+                                       rockchip,pins = <RK_GPIO3 2 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd0_cmd: sd0-cmd {
+                                       rockchip,pins = <RK_GPIO3 3 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd0_cd: sd0-cd {
+                                       rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd0_wp: sd0-wp {
+                                       rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd0_pwr: sd0-pwr {
+                                       rockchip,pins = <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd0_bus1: sd0-bus-width1 {
+                                       rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd0_bus4: sd0-bus-width4 {
+                                       rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO3 6 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO3 7 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+                       };
+
+                       sd1 {
+                               sd1_clk: sd1-clk {
+                                       rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd1_cmd: sd1-cmd {
+                                       rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd1_cd: sd1-cd {
+                                       rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd1_wp: sd1-wp {
+                                       rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd1_bus1: sd1-bus-width1 {
+                                       rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+
+                               sd1_bus4: sd1-bus-width4 {
+                                       rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_none>,
+                                                       <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_none>;
+                               };
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
new file mode 100644 (file)
index 0000000..0fcbcfd
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+       interrupt-parent = <&gic>;
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges;
+
+               gic: interrupt-controller@1013d000 {
+                       compatible = "arm,cortex-a9-gic";
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       reg = <0x1013d000 0x1000>,
+                             <0x1013c100 0x0100>;
+               };
+
+               L2: l2-cache-controller@10138000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x10138000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               global-timer@1013c200 {
+                       compatible = "arm,cortex-a9-global-timer";
+                       reg = <0x1013c200 0x20>;
+                       interrupts = <GIC_PPI 11 0x304>;
+                       clocks = <&dummy150m>;
+               };
+
+               local-timer@1013c600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x1013c600 0x20>;
+                       interrupts = <GIC_PPI 13 0x304>;
+                       clocks = <&dummy150m>;
+               };
+
+               uart0: serial@10124000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x10124000 0x400>;
+                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <1>;
+                       clocks = <&clk_gates1 8>;
+                       status = "disabled";
+               };
+
+               uart1: serial@10126000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x10126000 0x400>;
+                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <1>;
+                       clocks = <&clk_gates1 10>;
+                       status = "disabled";
+               };
+
+               uart2: serial@20064000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x20064000 0x400>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <1>;
+                       clocks = <&clk_gates1 12>;
+                       status = "disabled";
+               };
+
+               uart3: serial@20068000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x20068000 0x400>;
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <1>;
+                       clocks = <&clk_gates1 14>;
+                       status = "disabled";
+               };
+
+               dwmmc@10214000 {
+                       compatible = "rockchip,rk2928-dw-mshc";
+                       reg = <0x10214000 0x1000>;
+                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       clocks = <&clk_gates5 10>, <&clk_gates2 11>;
+                       clock-names = "biu", "ciu";
+
+                       status = "disabled";
+               };
+
+               dwmmc@10218000 {
+                       compatible = "rockchip,rk2928-dw-mshc";
+                       reg = <0x10218000 0x1000>;
+                       interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       clocks = <&clk_gates5 11>, <&clk_gates2 13>;
+                       clock-names = "biu", "ciu";
+
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/s3c6400.dtsi b/arch/arm/boot/dts/s3c6400.dtsi
new file mode 100644 (file)
index 0000000..a7d1c8e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Samsung's S3C6400 SoC device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C6400 SoC device nodes are listed in this file. S3C6400
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S3C6400 SoC. As device tree coverage for S3C6400 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "s3c64xx.dtsi"
+
+/ {
+       compatible = "samsung,s3c6400";
+};
+
+&vic0 {
+       valid-mask = <0xfffffe1f>;
+       valid-wakeup-mask = <0x00200004>;
+};
+
+&vic1 {
+       valid-mask = <0xffffffff>;
+       valid-wakeup-mask = <0x53020000>;
+};
+
+&soc {
+       clocks: clock-controller@7e00f000 {
+               compatible = "samsung,s3c6400-clock";
+               reg = <0x7e00f000 0x1000>;
+               #clock-cells = <1>;
+       };
+};
diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
new file mode 100644 (file)
index 0000000..57e00f9
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Samsung's S3C6410 based Mini6410 board device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Device tree source file for FriendlyARM Mini6410 board which is based on
+ * Samsung's S3C6410 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "s3c6410.dtsi"
+
+/ {
+       model = "FriendlyARM Mini6410 board based on S3C6410";
+       compatible = "friendlyarm,mini6410", "samsung,s3c6410";
+
+       memory {
+               reg = <0x50000000 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1";
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fin_pll: oscillator@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       clock-frequency = <12000000>;
+                       clock-output-names = "fin_pll";
+                       #clock-cells = <0>;
+               };
+
+               xusbxti: oscillator@1 {
+                       compatible = "fixed-clock";
+                       reg = <1>;
+                       clock-output-names = "xusbxti";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+       };
+
+       srom-cs1@18000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x18000000 0x8000000>;
+               ranges;
+
+               ethernet@18000000 {
+                       compatible = "davicom,dm9000";
+                       reg = <0x18000000 0x2 0x18000004 0x2>;
+                       interrupt-parent = <&gpn>;
+                       interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+                       davicom,no-eeprom;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys>;
+               autorepeat;
+
+               button-k1 {
+                       label = "K1";
+                       gpios = <&gpn 0 GPIO_ACTIVE_LOW>;
+                       linux,code = <2>;
+                       debounce-interval = <20>;
+               };
+
+               button-k2 {
+                       label = "K2";
+                       gpios = <&gpn 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <3>;
+                       debounce-interval = <20>;
+               };
+
+               button-k3 {
+                       label = "K3";
+                       gpios = <&gpn 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <4>;
+                       debounce-interval = <20>;
+               };
+
+               button-k4 {
+                       label = "K4";
+                       gpios = <&gpn 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <5>;
+                       debounce-interval = <20>;
+               };
+
+               button-k5 {
+                       label = "K5";
+                       gpios = <&gpn 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <6>;
+                       debounce-interval = <20>;
+               };
+
+               button-k6 {
+                       label = "K6";
+                       gpios = <&gpn 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <7>;
+                       debounce-interval = <20>;
+               };
+
+               button-k7 {
+                       label = "K7";
+                       gpios = <&gpl 11 GPIO_ACTIVE_LOW>;
+                       linux,code = <8>;
+                       debounce-interval = <20>;
+               };
+
+               button-k8 {
+                       label = "K8";
+                       gpios = <&gpl 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <9>;
+                       debounce-interval = <20>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_leds>;
+
+               led-1 {
+                       label = "LED1";
+                       gpios = <&gpk 4 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led-2 {
+                       label = "LED2";
+                       gpios = <&gpk 5 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "mmc0";
+               };
+
+               led-3 {
+                       label = "LED3";
+                       gpios = <&gpk 6 GPIO_ACTIVE_LOW>;
+               };
+
+               led-4 {
+                       label = "LED4";
+                       gpios = <&gpk 7 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       buzzer {
+               compatible = "pwm-beeper";
+               pwms = <&pwm 0 1000000 0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_out>;
+       };
+};
+
+&sdhci0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_data>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_data>, <&uart1_fctl>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_data>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_data>;
+       status = "okay";
+};
+
+&pwm {
+       status = "okay";
+};
+
+&pinctrl0 {
+       gpio_leds: gpio-leds {
+               samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7";
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       gpio_keys: gpio-keys {
+               samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3",
+                               "gpn-4", "gpn-5", "gpl-11", "gpl-12";
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_bus>;
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c08";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts
new file mode 100644 (file)
index 0000000..ecf35ec
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Samsung S3C6410 based SMDK6410 board device tree source.
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Device tree source file for SAMSUNG SMDK6410 board which is based on
+ * Samsung's S3C6410 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "s3c6410.dtsi"
+
+/ {
+       model = "SAMSUNG SMDK6410 board based on S3C6410";
+       compatible = "samsung,mini6410", "samsung,s3c6410";
+
+       memory {
+               reg = <0x50000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1";
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fin_pll: oscillator@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       clock-frequency = <12000000>;
+                       clock-output-names = "fin_pll";
+                       #clock-cells = <0>;
+               };
+
+               xusbxti: oscillator@1 {
+                       compatible = "fixed-clock";
+                       reg = <1>;
+                       clock-output-names = "xusbxti";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+       };
+
+       srom-cs1@18000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x18000000 0x8000000>;
+               ranges;
+
+               ethernet@18000000 {
+                       compatible = "smsc,lan9115";
+                       reg = <0x18000000 0x10000>;
+                       interrupt-parent = <&gpn>;
+                       interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+                       phy-mode = "mii";
+                       reg-io-width = <4>;
+                       smsc,force-internal-phy;
+               };
+       };
+};
+
+&sdhci0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_data>, <&uart0_fctl>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_data>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_data>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_data>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/s3c6410.dtsi b/arch/arm/boot/dts/s3c6410.dtsi
new file mode 100644 (file)
index 0000000..eb4226b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Samsung's S3C6410 SoC device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C6410 SoC device nodes are listed in this file. S3C6410
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S3C6410 SoC. As device tree coverage for S3C6410 increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "s3c64xx.dtsi"
+
+/ {
+       compatible = "samsung,s3c6410";
+
+       aliases {
+               i2c1 = &i2c1;
+       };
+};
+
+&vic0 {
+       valid-mask = <0xffffff7f>;
+       valid-wakeup-mask = <0x00200004>;
+};
+
+&vic1 {
+       valid-mask = <0xffffffff>;
+       valid-wakeup-mask = <0x53020000>;
+};
+
+&soc {
+       clocks: clock-controller@7e00f000 {
+               compatible = "samsung,s3c6410-clock";
+               reg = <0x7e00f000 0x1000>;
+               #clock-cells = <1>;
+       };
+
+       i2c1: i2c@7f00f000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x7f00f000 0x1000>;
+               interrupt-parent = <&vic0>;
+               interrupts = <5>;
+               clock-names = "i2c";
+               clocks = <&clocks PCLK_IIC1>;
+               status = "disabled";
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
diff --git a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..b1197d8
--- /dev/null
@@ -0,0 +1,687 @@
+/*
+ * Samsung's S3C64xx SoC series common device tree source
+ * - pin control-related definitions
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C64xx SoCs pin banks, pin-mux and pin-config options are
+ * listed as device tree nodes in this file.
+ *
+ * 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.
+ */
+
+#define PIN_PULL_NONE  0
+#define PIN_PULL_DOWN  1
+#define PIN_PULL_UP    2
+
+&pinctrl0 {
+       /*
+        * Pin banks
+        */
+
+       gpa: gpa {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpb: gpb {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpc: gpc {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpd: gpd {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpe: gpe {
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       gpf: gpf {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpg: gpg {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gph: gph {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpi: gpi {
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       gpj: gpj {
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       gpk: gpk {
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       gpl: gpl {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpm: gpm {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpn: gpn {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpo: gpo {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpp: gpp {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpq: gpq {
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       /*
+        * Pin groups
+        */
+
+       uart0_data: uart0-data {
+               samsung,pins = "gpa-0", "gpa-1";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       uart0_fctl: uart0-fctl {
+               samsung,pins = "gpa-2", "gpa-3";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       uart1_data: uart1-data {
+               samsung,pins = "gpa-4", "gpa-5";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       uart1_fctl: uart1-fctl {
+               samsung,pins = "gpa-6", "gpa-7";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       uart2_data: uart2-data {
+               samsung,pins = "gpb-0", "gpb-1";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       uart3_data: uart3-data {
+               samsung,pins = "gpb-2", "gpb-3";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       ext_dma_0: ext-dma-0 {
+               samsung,pins = "gpb-0", "gpb-1";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       ext_dma_1: ext-dma-1 {
+               samsung,pins = "gpb-2", "gpb-3";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       irda_data_0: irda-data-0 {
+               samsung,pins = "gpb-0", "gpb-1";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       irda_data_1: irda-data-1 {
+               samsung,pins = "gpb-2", "gpb-3";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       irda_sdbw: irda-sdbw {
+               samsung,pins = "gpb-4";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2c0_bus: i2c0-bus {
+               samsung,pins = "gpb-5", "gpb-6";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_UP>;
+       };
+
+       i2c1_bus: i2c1-bus {
+               /* S3C6410-only */
+               samsung,pins = "gpb-2", "gpb-3";
+               samsung,pin-function = <6>;
+               samsung,pin-pud = <PIN_PULL_UP>;
+       };
+
+       spi0_bus: spi0-bus {
+               samsung,pins = "gpc-0", "gpc-1", "gpc-2";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_UP>;
+       };
+
+       spi0_cs: spi0-cs {
+               samsung,pins = "gpc-3";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       spi1_bus: spi1-bus {
+               samsung,pins = "gpc-4", "gpc-5", "gpc-6";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_UP>;
+       };
+
+       spi1_cs: spi1-cs {
+               samsung,pins = "gpc-7";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd0_cmd: sd0-cmd {
+               samsung,pins = "gpg-1";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd0_clk: sd0-clk {
+               samsung,pins = "gpg-0";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd0_bus1: sd0-bus1 {
+               samsung,pins = "gpg-2";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd0_bus4: sd0-bus4 {
+               samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd0_cd: sd0-cd {
+               samsung,pins = "gpg-6";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_UP>;
+       };
+
+       sd1_cmd: sd1-cmd {
+               samsung,pins = "gph-1";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd1_clk: sd1-clk {
+               samsung,pins = "gph-0";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd1_bus1: sd1-bus1 {
+               samsung,pins = "gph-2";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd1_bus4: sd1-bus4 {
+               samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd1_bus8: sd1-bus8 {
+               samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5",
+                               "gph-6", "gph-7", "gph-8", "gph-9";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd1_cd: sd1-cd {
+               samsung,pins = "gpg-6";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_UP>;
+       };
+
+       sd2_cmd: sd2-cmd {
+               samsung,pins = "gpc-4";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd2_clk: sd2-clk {
+               samsung,pins = "gpc-5";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd2_bus1: sd2-bus1 {
+               samsung,pins = "gph-6";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       sd2_bus4: sd2-bus4 {
+               samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2s0_bus: i2s0-bus {
+               samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2s0_cdclk: i2s0-cdclk {
+               samsung,pins = "gpd-1";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2s1_bus: i2s1-bus {
+               samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2s1_cdclk: i2s1-cdclk {
+               samsung,pins = "gpe-1";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2s2_bus: i2s2-bus {
+               /* S3C6410-only */
+               samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6",
+                               "gph-8", "gph-9";
+               samsung,pin-function = <5>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       i2s2_cdclk: i2s2-cdclk {
+               /* S3C6410-only */
+               samsung,pins = "gph-7";
+               samsung,pin-function = <5>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pcm0_bus: pcm0-bus {
+               samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pcm0_extclk: pcm0-extclk {
+               samsung,pins = "gpd-1";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pcm1_bus: pcm1-bus {
+               samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pcm1_extclk: pcm1-extclk {
+               samsung,pins = "gpe-1";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       ac97_bus_0: ac97-bus-0 {
+               samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       ac97_bus_1: ac97-bus-1 {
+               samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       cam_port: cam-port {
+               samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4",
+                               "gpf-5", "gpf-6", "gpf-7", "gpf-8",
+                               "gpf-9", "gpf-10", "gpf-11", "gpf-12";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       cam_rst: cam-rst {
+               samsung,pins = "gpf-3";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       cam_field: cam-field {
+               /* S3C6410-only */
+               samsung,pins = "gpb-4";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pwm_extclk: pwm-extclk {
+               samsung,pins = "gpf-13";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pwm0_out: pwm0-out {
+               samsung,pins = "gpf-14";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       pwm1_out: pwm1-out {
+               samsung,pins = "gpf-15";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       clkout0: clkout-0 {
+               samsung,pins = "gpf-14";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col0_0: keypad-col0-0 {
+               samsung,pins = "gph-0";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col1_0: keypad-col1-0 {
+               samsung,pins = "gph-1";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col2_0: keypad-col2-0 {
+               samsung,pins = "gph-2";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col3_0: keypad-col3-0 {
+               samsung,pins = "gph-3";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col4_0: keypad-col4-0 {
+               samsung,pins = "gph-4";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col5_0: keypad-col5-0 {
+               samsung,pins = "gph-5";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col6_0: keypad-col6-0 {
+               samsung,pins = "gph-6";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col7_0: keypad-col7-0 {
+               samsung,pins = "gph-7";
+               samsung,pin-function = <4>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col0_1: keypad-col0-1 {
+               samsung,pins = "gpl-0";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col1_1: keypad-col1-1 {
+               samsung,pins = "gpl-1";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col2_1: keypad-col2-1 {
+               samsung,pins = "gpl-2";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col3_1: keypad-col3-1 {
+               samsung,pins = "gpl-3";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col4_1: keypad-col4-1 {
+               samsung,pins = "gpl-4";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col5_1: keypad-col5-1 {
+               samsung,pins = "gpl-5";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col6_1: keypad-col6-1 {
+               samsung,pins = "gpl-6";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_col7_1: keypad-col7-1 {
+               samsung,pins = "gpl-7";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row0_0: keypad-row0-0 {
+               samsung,pins = "gpk-8";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row1_0: keypad-row1-0 {
+               samsung,pins = "gpk-9";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row2_0: keypad-row2-0 {
+               samsung,pins = "gpk-10";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row3_0: keypad-row3-0 {
+               samsung,pins = "gpk-11";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row4_0: keypad-row4-0 {
+               samsung,pins = "gpk-12";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row5_0: keypad-row5-0 {
+               samsung,pins = "gpk-13";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row6_0: keypad-row6-0 {
+               samsung,pins = "gpk-14";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row7_0: keypad-row7-0 {
+               samsung,pins = "gpk-15";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row0_1: keypad-row0-1 {
+               samsung,pins = "gpn-0";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row1_1: keypad-row1-1 {
+               samsung,pins = "gpn-1";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row2_1: keypad-row2-1 {
+               samsung,pins = "gpn-2";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row3_1: keypad-row3-1 {
+               samsung,pins = "gpn-3";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row4_1: keypad-row4-1 {
+               samsung,pins = "gpn-4";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row5_1: keypad-row5-1 {
+               samsung,pins = "gpn-5";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row6_1: keypad-row6-1 {
+               samsung,pins = "gpn-6";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       keypad_row7_1: keypad-row7-1 {
+               samsung,pins = "gpn-7";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       lcd_ctrl: lcd-ctrl {
+               samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       lcd_data16: lcd-data-width16 {
+               samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6",
+                               "gpi-7", "gpi-10", "gpi-11", "gpi-12",
+                               "gpi-13", "gpi-14", "gpi-15", "gpj-3",
+                               "gpj-4", "gpj-5", "gpj-6", "gpj-7";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       lcd_data18: lcd-data-width18 {
+               samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5",
+                               "gpi-6", "gpi-7", "gpi-10", "gpi-11",
+                               "gpi-12", "gpi-13", "gpi-14", "gpi-15",
+                               "gpj-2", "gpj-3", "gpj-4", "gpj-5",
+                               "gpj-6", "gpj-7";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       lcd_data24: lcd-data-width24 {
+               samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
+                               "gpi-4", "gpi-5", "gpi-6", "gpi-7",
+                               "gpi-8", "gpi-9", "gpi-10", "gpi-11",
+                               "gpi-12", "gpi-13", "gpi-14", "gpi-15",
+                               "gpj-0", "gpj-1", "gpj-2", "gpj-3",
+                               "gpj-4", "gpj-5", "gpj-6", "gpj-7";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+
+       hsi_bus: hsi-bus {
+               samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3",
+                               "gpk-4", "gpk-5", "gpk-6", "gpk-7";
+               samsung,pin-function = <3>;
+               samsung,pin-pud = <PIN_PULL_NONE>;
+       };
+};
diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
new file mode 100644 (file)
index 0000000..4e3be4d
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Samsung's S3C64xx SoC series common device tree source
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung's S3C64xx SoC series device nodes are listed in this file.
+ * Particular SoCs from S3C64xx series can include this file and provide
+ * values for SoCs specfic bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * S3C64xx SoCs. As device tree coverage for S3C64xx increases, additional
+ * nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
+
+/ {
+       aliases {
+               i2c0 = &i2c0;
+               pinctrl0 = &pinctrl0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,arm1176jzf-s", "arm,arm1176";
+                       reg = <0x0>;
+               };
+       };
+
+       soc: soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               vic0: interrupt-controller@71200000 {
+                       compatible = "arm,pl192-vic";
+                       interrupt-controller;
+                       reg = <0x71200000 0x1000>;
+                       #interrupt-cells = <1>;
+               };
+
+               vic1: interrupt-controller@71300000 {
+                       compatible = "arm,pl192-vic";
+                       interrupt-controller;
+                       reg = <0x71300000 0x1000>;
+                       #interrupt-cells = <1>;
+               };
+
+               sdhci0: sdhci@7c200000 {
+                       compatible = "samsung,s3c6410-sdhci";
+                       reg = <0x7c200000 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <24>;
+                       clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+                       clocks = <&clocks HCLK_HSMMC0>, <&clocks HCLK_HSMMC0>,
+                                       <&clocks SCLK_MMC0>;
+                       status = "disabled";
+               };
+
+               sdhci1: sdhci@7c300000 {
+                       compatible = "samsung,s3c6410-sdhci";
+                       reg = <0x7c300000 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <25>;
+                       clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+                       clocks = <&clocks HCLK_HSMMC1>, <&clocks HCLK_HSMMC1>,
+                                       <&clocks SCLK_MMC1>;
+                       status = "disabled";
+               };
+
+               sdhci2: sdhci@7c400000 {
+                       compatible = "samsung,s3c6410-sdhci";
+                       reg = <0x7c400000 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <17>;
+                       clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2";
+                       clocks = <&clocks HCLK_HSMMC2>, <&clocks HCLK_HSMMC2>,
+                                       <&clocks SCLK_MMC2>;
+                       status = "disabled";
+               };
+
+               watchdog: watchdog@7e004000 {
+                       compatible = "samsung,s3c2410-wdt";
+                       reg = <0x7e004000 0x1000>;
+                       interrupt-parent = <&vic0>;
+                       interrupts = <26>;
+                       clock-names = "watchdog";
+                       clocks = <&clocks PCLK_WDT>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@7f004000 {
+                       compatible = "samsung,s3c2440-i2c";
+                       reg = <0x7f004000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <18>;
+                       clock-names = "i2c";
+                       clocks = <&clocks PCLK_IIC0>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               uart0: serial@7f005000 {
+                       compatible = "samsung,s3c6400-uart";
+                       reg = <0x7f005000 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <5>;
+                       clock-names = "uart", "clk_uart_baud2",
+                                       "clk_uart_baud3";
+                       clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+                                       <&clocks SCLK_UART>;
+                       status = "disabled";
+               };
+
+               uart1: serial@7f005400 {
+                       compatible = "samsung,s3c6400-uart";
+                       reg = <0x7f005400 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <6>;
+                       clock-names = "uart", "clk_uart_baud2",
+                                       "clk_uart_baud3";
+                       clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>,
+                                       <&clocks SCLK_UART>;
+                       status = "disabled";
+               };
+
+               uart2: serial@7f005800 {
+                       compatible = "samsung,s3c6400-uart";
+                       reg = <0x7f005800 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <7>;
+                       clock-names = "uart", "clk_uart_baud2",
+                                       "clk_uart_baud3";
+                       clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>,
+                                       <&clocks SCLK_UART>;
+                       status = "disabled";
+               };
+
+               uart3: serial@7f005c00 {
+                       compatible = "samsung,s3c6400-uart";
+                       reg = <0x7f005c00 0x100>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <8>;
+                       clock-names = "uart", "clk_uart_baud2",
+                                       "clk_uart_baud3";
+                       clocks = <&clocks PCLK_UART3>, <&clocks PCLK_UART3>,
+                                       <&clocks SCLK_UART>;
+                       status = "disabled";
+               };
+
+               pwm: pwm@7f006000 {
+                       compatible = "samsung,s3c6400-pwm";
+                       reg = <0x7f006000 0x1000>;
+                       interrupt-parent = <&vic0>;
+                       interrupts = <23>, <24>, <25>, <27>, <28>;
+                       clock-names = "timers";
+                       clocks = <&clocks PCLK_PWM>;
+                       samsung,pwm-outputs = <0>, <1>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
+
+               pinctrl0: pinctrl@7f008000 {
+                       compatible = "samsung,s3c64xx-pinctrl";
+                       reg = <0x7f008000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <21>;
+
+                       pctrl_int_map: pinctrl-interrupt-map {
+                               interrupt-map = <0 &vic0 0>,
+                                               <1 &vic0 1>,
+                                               <2 &vic1 0>,
+                                               <3 &vic1 1>;
+                               #address-cells = <0>;
+                               #size-cells = <0>;
+                               #interrupt-cells = <1>;
+                       };
+
+                       wakeup-interrupt-controller {
+                               compatible = "samsung,s3c64xx-wakeup-eint";
+                               interrupts = <0>, <1>, <2>, <3>;
+                               interrupt-parent = <&pctrl_int_map>;
+                       };
+               };
+       };
+};
+
+#include "s3c64xx-pinctrl.dtsi"
index b7f49615120db6527bc9da1e2165b2133ba0e879..5cdaba4cea8653d8db51616f443a4d8ee2d79ef4 100644 (file)
@@ -31,7 +31,6 @@
                gpio3 = &pioD;
                gpio4 = &pioE;
                tcb0 = &tcb0;
-               tcb1 = &tcb1;
                i2c0 = &i2c0;
                i2c1 = &i2c1;
                i2c2 = &i2c2;
                                status = "disabled";
                        };
 
-                       can0: can@f000c000 {
-                               compatible = "atmel,at91sam9x5-can";
-                               reg = <0xf000c000 0x300>;
-                               interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_can0_rx_tx>;
-                               status = "disabled";
-                       };
-
                        tcb0: timer@f0010000 {
                                compatible = "atmel,at91sam9x5-tcb";
                                reg = <0xf0010000 0x100>;
                                status = "disabled";
                        };
 
-                       macb0: ethernet@f0028000 {
-                               compatible = "cdns,pc302-gem", "cdns,gem";
-                               reg = <0xf0028000 0x100>;
-                               interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>;
-                               status = "disabled";
-                       };
-
                        isi: isi@f0034000 {
                                compatible = "atmel,at91sam9g45-isi";
                                reg = <0xf0034000 0x4000>;
                                #size-cells = <0>;
                        };
 
-                       mmc2: mmc@f8004000 {
-                               compatible = "atmel,hsmci";
-                               reg = <0xf8004000 0x600>;
-                               interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
-                               dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(1)>;
-                               dma-names = "rxtx";
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>;
-                               status = "disabled";
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                       };
-
                        spi1: spi@f8008000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                status = "disabled";
                        };
 
-                       can1: can@f8010000 {
-                               compatible = "atmel,at91sam9x5-can";
-                               reg = <0xf8010000 0x300>;
-                               interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_can1_rx_tx>;
-                       };
-
-                       tcb1: timer@f8014000 {
-                               compatible = "atmel,at91sam9x5-tcb";
-                               reg = <0xf8014000 0x100>;
-                               interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
-                       };
-
                        adc0: adc@f8018000 {
                                compatible = "atmel,at91sam9260-adc";
                                reg = <0xf8018000 0x100>;
                                status = "disabled";
                        };
 
-                       macb1: ethernet@f802c000 {
-                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
-                               reg = <0xf802c000 0x100>;
-                               interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_macb1_rmii>;
-                               status = "disabled";
-                       };
-
                        sha@f8034000 {
                                compatible = "atmel,sam9g46-sha";
                                reg = <0xf8034000 0x100>;
                                        };
                                };
 
-                               can0 {
-                                       pinctrl_can0_rx_tx: can0_rx_tx {
-                                               atmel,pins =
-                                                       <AT91_PIOD 14 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */
-                                                        AT91_PIOD 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */
-                                       };
-                               };
-
-                               can1 {
-                                       pinctrl_can1_rx_tx: can1_rx_tx {
-                                               atmel,pins =
-                                                       <AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB14 periph B RX, conflicts with GCRS */
-                                                        AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB15 periph B TX, conflicts with GCOL */
-                                       };
-                               };
-
                                dbgu {
                                        pinctrl_dbgu: dbgu-0 {
                                                atmel,pins =
                                        };
                                };
 
-                               lcd {
-                                       pinctrl_lcd: lcd-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA24 periph A LCDPWM */
-                                                        AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA26 periph A LCDVSYNC */
-                                                        AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA27 periph A LCDHSYNC */
-                                                        AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA25 periph A LCDDISP */
-                                                        AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA29 periph A LCDDEN */
-                                                        AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA28 periph A LCDPCK */
-                                                        AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA0 periph A LCDD0 pin */
-                                                        AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA1 periph A LCDD1 pin */
-                                                        AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA2 periph A LCDD2 pin */
-                                                        AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA3 periph A LCDD3 pin */
-                                                        AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA4 periph A LCDD4 pin */
-                                                        AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA5 periph A LCDD5 pin */
-                                                        AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA6 periph A LCDD6 pin */
-                                                        AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA7 periph A LCDD7 pin */
-                                                        AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA8 periph A LCDD8 pin */
-                                                        AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA9 periph A LCDD9 pin */
-                                                        AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA10 periph A LCDD10 pin */
-                                                        AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA11 periph A LCDD11 pin */
-                                                        AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA12 periph A LCDD12 pin */
-                                                        AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA13 periph A LCDD13 pin */
-                                                        AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA14 periph A LCDD14 pin */
-                                                        AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA15 periph A LCDD15 pin */
-                                                        AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC14 periph C LCDD16 pin */
-                                                        AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC13 periph C LCDD17 pin */
-                                                        AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC12 periph C LCDD18 pin */
-                                                        AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC11 periph C LCDD19 pin */
-                                                        AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC10 periph C LCDD20 pin */
-                                                        AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC15 periph C LCDD21 pin */
-                                                        AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PE27 periph C LCDD22 pin */
-                                                        AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PE28 periph C LCDD23 pin */
-                                       };
-                               };
-
-                               macb0 {
-                                       pinctrl_macb0_data_rgmii: macb0_data_rgmii {
-                                               atmel,pins =
-                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB0 periph A GTX0, conflicts with PWMH0 */
-                                                        AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB1 periph A GTX1, conflicts with PWML0 */
-                                                        AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB2 periph A GTX2, conflicts with TK1 */
-                                                        AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB3 periph A GTX3, conflicts with TF1 */
-                                                        AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB4 periph A GRX0, conflicts with PWMH1 */
-                                                        AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB5 periph A GRX1, conflicts with PWML1 */
-                                                        AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB6 periph A GRX2, conflicts with TD1 */
-                                                        AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;  /* PB7 periph A GRX3, conflicts with RK1 */
-                                       };
-                                       pinctrl_macb0_data_gmii: macb0_data_gmii {
-                                               atmel,pins =
-                                                       <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB19 periph B GTX4, conflicts with MCI1_CDA */
-                                                        AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB20 periph B GTX5, conflicts with MCI1_DA0 */
-                                                        AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB21 periph B GTX6, conflicts with MCI1_DA1 */
-                                                        AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB22 periph B GTX7, conflicts with MCI1_DA2 */
-                                                        AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB23 periph B GRX4, conflicts with MCI1_DA3 */
-                                                        AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB24 periph B GRX5, conflicts with MCI1_CK */
-                                                        AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB25 periph B GRX6, conflicts with SCK1 */
-                                                        AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB26 periph B GRX7, conflicts with CTS1 */
-                                       };
-                                       pinctrl_macb0_signal_rgmii: macb0_signal_rgmii {
-                                               atmel,pins =
-                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB8 periph A GTXCK, conflicts with PWMH2 */
-                                                        AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A GTXEN, conflicts with PWML2 */
-                                                        AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB11 periph A GRXCK, conflicts with RD1 */
-                                                        AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB13 periph A GRXER, conflicts with PWML3 */
-                                                        AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB16 periph A GMDC */
-                                                        AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB17 periph A GMDIO */
-                                                        AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A G125CK */
-                                       };
-                                       pinctrl_macb0_signal_gmii: macb0_signal_gmii {
-                                               atmel,pins =
-                                                       <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A GTXEN, conflicts with PWML2 */
-                                                        AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB10 periph A GTXER, conflicts with RF1 */
-                                                        AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB11 periph A GRXCK, conflicts with RD1 */
-                                                        AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB12 periph A GRXDV, conflicts with PWMH3 */
-                                                        AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB13 periph A GRXER, conflicts with PWML3 */
-                                                        AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB14 periph A GCRS, conflicts with CANRX1 */
-                                                        AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB15 periph A GCOL, conflicts with CANTX1 */
-                                                        AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB16 periph A GMDC */
-                                                        AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB17 periph A GMDIO */
-                                                        AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB27 periph B G125CKO */
-                                       };
-
-                               };
-
-                               macb1 {
-                                       pinctrl_macb1_rmii: macb1_rmii-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC0 periph A ETX0, conflicts with TIOA3 */
-                                                        AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC1 periph A ETX1, conflicts with TIOB3 */
-                                                        AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC2 periph A ERX0, conflicts with TCLK3 */
-                                                        AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC3 periph A ERX1, conflicts with TIOA4 */
-                                                        AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC4 periph A ETXEN, conflicts with TIOB4 */
-                                                        AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC5 periph A ECRSDV,conflicts with TCLK4 */
-                                                        AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC6 periph A ERXER, conflicts with TIOA5 */
-                                                        AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC7 periph A EREFCK, conflicts with TIOB5 */
-                                                        AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC8 periph A EMDC, conflicts with TCLK5 */
-                                                        AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;  /* PC9 periph A EMDIO  */
-                                       };
-                               };
-
                                mmc0 {
                                        pinctrl_mmc0_clk_cmd_dat0: mmc0_clk_cmd_dat0 {
                                                atmel,pins =
                                        };
                                };
 
-                               mmc2 {
-                                       pinctrl_mmc2_clk_cmd_dat0: mmc2_clk_cmd_dat0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC15 periph A MCI2_CK, conflicts with PCK2 */
-                                                        AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP        /* PC10 periph A MCI2_CDA with pullup */
-                                                        AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;      /* PC11 periph A MCI2_DA0 with pullup */
-                                       };
-                                       pinctrl_mmc2_dat1_3: mmc2_dat1_3 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */
-                                                        AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */
-                                                        AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */
-                                       };
-                               };
-
                                nand0 {
                                        pinctrl_nand0_ale_cle: nand0_ale_cle-0 {
                                                atmel,pins =
                                        };
                                };
 
-                               uart0 {
-                                       pinctrl_uart0: uart0-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC29 periph A, conflicts with PWMFI2, ISI_D8 */
-                                                        AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;      /* PC30 periph A with pullup, conflicts with ISI_PCK */
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1: uart1-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PA30 periph B, conflicts with TWD0, ISI_VSYNC */
-                                                        AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;      /* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */
-                                       };
-                               };
-
                                usart0 {
                                        pinctrl_usart0: usart0-0 {
                                                atmel,pins =
diff --git a/arch/arm/boot/dts/sama5d31.dtsi b/arch/arm/boot/dts/sama5d31.dtsi
new file mode 100644 (file)
index 0000000..7997dc9
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * sama5d31.dtsi - Device Tree Include file for SAMA5D31 SoC
+ *
+ *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_emac.dtsi"
+#include "sama5d3_mci2.dtsi"
+#include "sama5d3_uart.dtsi"
+
+/ {
+       compatible = "atmel,samad31", "atmel,sama5d3", "atmel,sama5";
+};
index 027bac7510b6cc2cfb92ebb488c8d8e24de06749..04eec0dfcf7de7792c0a1b7f6de0a1ece304a871 100644 (file)
@@ -7,12 +7,13 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
+#include "sama5d31.dtsi"
 #include "sama5d3xmb.dtsi"
 #include "sama5d3xdm.dtsi"
 
 / {
        model = "Atmel SAMA5D31-EK";
-       compatible = "atmel,sama5d31ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d31ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
 
        ahb {
                apb {
diff --git a/arch/arm/boot/dts/sama5d33.dtsi b/arch/arm/boot/dts/sama5d33.dtsi
new file mode 100644 (file)
index 0000000..39f8322
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * sama5d33.dtsi - Device Tree Include file for SAMA5D33 SoC
+ *
+ *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_gmac.dtsi"
+
+/ {
+       compatible = "atmel,samad33", "atmel,sama5d3", "atmel,sama5";
+};
index 99bd0c8e047116b4a04cce14c466068268d21cc2..cbd6a3ff154535541d38b412bd9c7834371fbe5d 100644 (file)
@@ -7,12 +7,13 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
+#include "sama5d33.dtsi"
 #include "sama5d3xmb.dtsi"
 #include "sama5d3xdm.dtsi"
 
 / {
        model = "Atmel SAMA5D33-EK";
-       compatible = "atmel,sama5d33ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d33ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5";
 
        ahb {
                apb {
diff --git a/arch/arm/boot/dts/sama5d34.dtsi b/arch/arm/boot/dts/sama5d34.dtsi
new file mode 100644 (file)
index 0000000..89cda2c
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * sama5d34.dtsi - Device Tree Include file for SAMA5D34 SoC
+ *
+ *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_lcd.dtsi"
+#include "sama5d3_gmac.dtsi"
+#include "sama5d3_can.dtsi"
+#include "sama5d3_mci2.dtsi"
+
+/ {
+       compatible = "atmel,samad34", "atmel,sama5d3", "atmel,sama5";
+};
index fb8ee11cf282bdf051e1ecf0193e1622adb7d7d4..878aa164275a0fc7ec5d74e1c8dee143f48afd79 100644 (file)
@@ -7,12 +7,13 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
+#include "sama5d34.dtsi"
 #include "sama5d3xmb.dtsi"
 #include "sama5d3xdm.dtsi"
 
 / {
        model = "Atmel SAMA5D34-EK";
-       compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5";
 
        ahb {
                apb {
diff --git a/arch/arm/boot/dts/sama5d35.dtsi b/arch/arm/boot/dts/sama5d35.dtsi
new file mode 100644 (file)
index 0000000..d20cd71
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * sama5d35.dtsi - Device Tree Include file for SAMA5D35 SoC
+ *
+ *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include "sama5d3.dtsi"
+#include "sama5d3_gmac.dtsi"
+#include "sama5d3_emac.dtsi"
+#include "sama5d3_can.dtsi"
+#include "sama5d3_mci2.dtsi"
+#include "sama5d3_uart.dtsi"
+#include "sama5d3_tcb1.dtsi"
+
+/ {
+       compatible = "atmel,samad35", "atmel,sama5d3", "atmel,sama5";
+};
index 509a53d9cc7baee10258878cd257d8574d6b25e0..9089c7c6cea863e547a26d7c8d2233c138827334 100644 (file)
@@ -7,11 +7,12 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
+#include "sama5d35.dtsi"
 #include "sama5d3xmb.dtsi"
 
 / {
        model = "Atmel SAMA5D35-EK";
-       compatible = "atmel,sama5d35ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d35ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d35", "atmel,sama5d3", "atmel,sama5";
 
        ahb {
                apb {
diff --git a/arch/arm/boot/dts/sama5d3_can.dtsi b/arch/arm/boot/dts/sama5d3_can.dtsi
new file mode 100644 (file)
index 0000000..8ed3260
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * at91sama5d3_can.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * CAN support
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff200 {
+                               can0 {
+                                       pinctrl_can0_rx_tx: can0_rx_tx {
+                                               atmel,pins =
+                                                       <AT91_PIOD 14 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */
+                                                        AT91_PIOD 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */
+                                       };
+                               };
+
+                               can1 {
+                                       pinctrl_can1_rx_tx: can1_rx_tx {
+                                               atmel,pins =
+                                                       <AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB14 periph B RX, conflicts with GCRS */
+                                                        AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB15 periph B TX, conflicts with GCOL */
+                                       };
+                               };
+
+                       };
+
+                       can0: can@f000c000 {
+                               compatible = "atmel,at91sam9x5-can";
+                               reg = <0xf000c000 0x300>;
+                               interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_can0_rx_tx>;
+                               status = "disabled";
+                       };
+
+                       can1: can@f8010000 {
+                               compatible = "atmel,at91sam9x5-can";
+                               reg = <0xf8010000 0x300>;
+                               interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_can1_rx_tx>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/sama5d3_emac.dtsi b/arch/arm/boot/dts/sama5d3_emac.dtsi
new file mode 100644 (file)
index 0000000..4d4f351
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * at91sama5d3_emac.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * Ethernet.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff200 {
+                               macb1 {
+                                       pinctrl_macb1_rmii: macb1_rmii-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC0 periph A ETX0, conflicts with TIOA3 */
+                                                        AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC1 periph A ETX1, conflicts with TIOB3 */
+                                                        AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC2 periph A ERX0, conflicts with TCLK3 */
+                                                        AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC3 periph A ERX1, conflicts with TIOA4 */
+                                                        AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC4 periph A ETXEN, conflicts with TIOB4 */
+                                                        AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC5 periph A ECRSDV,conflicts with TCLK4 */
+                                                        AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC6 periph A ERXER, conflicts with TIOA5 */
+                                                        AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC7 periph A EREFCK, conflicts with TIOB5 */
+                                                        AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PC8 periph A EMDC, conflicts with TCLK5 */
+                                                        AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;  /* PC9 periph A EMDIO  */
+                                       };
+                               };
+                       };
+
+                       macb1: ethernet@f802c000 {
+                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
+                               reg = <0xf802c000 0x100>;
+                               interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_macb1_rmii>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/sama5d3_gmac.dtsi b/arch/arm/boot/dts/sama5d3_gmac.dtsi
new file mode 100644 (file)
index 0000000..0ba8be3
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * at91sama5d3_gmac.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * Gigabit Ethernet.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff200 {
+                               macb0 {
+                                       pinctrl_macb0_data_rgmii: macb0_data_rgmii {
+                                               atmel,pins =
+                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB0 periph A GTX0, conflicts with PWMH0 */
+                                                        AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB1 periph A GTX1, conflicts with PWML0 */
+                                                        AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB2 periph A GTX2, conflicts with TK1 */
+                                                        AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB3 periph A GTX3, conflicts with TF1 */
+                                                        AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB4 periph A GRX0, conflicts with PWMH1 */
+                                                        AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB5 periph A GRX1, conflicts with PWML1 */
+                                                        AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB6 periph A GRX2, conflicts with TD1 */
+                                                        AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;  /* PB7 periph A GRX3, conflicts with RK1 */
+                                       };
+                                       pinctrl_macb0_data_gmii: macb0_data_gmii {
+                                               atmel,pins =
+                                                       <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB19 periph B GTX4, conflicts with MCI1_CDA */
+                                                        AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB20 periph B GTX5, conflicts with MCI1_DA0 */
+                                                        AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB21 periph B GTX6, conflicts with MCI1_DA1 */
+                                                        AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB22 periph B GTX7, conflicts with MCI1_DA2 */
+                                                        AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB23 periph B GRX4, conflicts with MCI1_DA3 */
+                                                        AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB24 periph B GRX5, conflicts with MCI1_CK */
+                                                        AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PB25 periph B GRX6, conflicts with SCK1 */
+                                                        AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB26 periph B GRX7, conflicts with CTS1 */
+                                       };
+                                       pinctrl_macb0_signal_rgmii: macb0_signal_rgmii {
+                                               atmel,pins =
+                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB8 periph A GTXCK, conflicts with PWMH2 */
+                                                        AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A GTXEN, conflicts with PWML2 */
+                                                        AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB11 periph A GRXCK, conflicts with RD1 */
+                                                        AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB13 periph A GRXER, conflicts with PWML3 */
+                                                        AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB16 periph A GMDC */
+                                                        AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB17 periph A GMDIO */
+                                                        AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A G125CK */
+                                       };
+                                       pinctrl_macb0_signal_gmii: macb0_signal_gmii {
+                                               atmel,pins =
+                                                       <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A GTXEN, conflicts with PWML2 */
+                                                        AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB10 periph A GTXER, conflicts with RF1 */
+                                                        AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB11 periph A GRXCK, conflicts with RD1 */
+                                                        AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB12 periph A GRXDV, conflicts with PWMH3 */
+                                                        AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB13 periph A GRXER, conflicts with PWML3 */
+                                                        AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB14 periph A GCRS, conflicts with CANRX1 */
+                                                        AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB15 periph A GCOL, conflicts with CANTX1 */
+                                                        AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB16 periph A GMDC */
+                                                        AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PB17 periph A GMDIO */
+                                                        AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB27 periph B G125CKO */
+                                       };
+
+                               };
+                       };
+
+                       macb0: ethernet@f0028000 {
+                               compatible = "cdns,pc302-gem", "cdns,gem";
+                               reg = <0xf0028000 0x100>;
+                               interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/sama5d3_lcd.dtsi b/arch/arm/boot/dts/sama5d3_lcd.dtsi
new file mode 100644 (file)
index 0000000..01f52a7
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * at91sama5d3_lcd.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * LCD support
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff200 {
+                               lcd {
+                                       pinctrl_lcd: lcd-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA24 periph A LCDPWM */
+                                                        AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA26 periph A LCDVSYNC */
+                                                        AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA27 periph A LCDHSYNC */
+                                                        AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA25 periph A LCDDISP */
+                                                        AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA29 periph A LCDDEN */
+                                                        AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA28 periph A LCDPCK */
+                                                        AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA0 periph A LCDD0 pin */
+                                                        AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA1 periph A LCDD1 pin */
+                                                        AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA2 periph A LCDD2 pin */
+                                                        AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA3 periph A LCDD3 pin */
+                                                        AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA4 periph A LCDD4 pin */
+                                                        AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA5 periph A LCDD5 pin */
+                                                        AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA6 periph A LCDD6 pin */
+                                                        AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA7 periph A LCDD7 pin */
+                                                        AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA8 periph A LCDD8 pin */
+                                                        AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PA9 periph A LCDD9 pin */
+                                                        AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA10 periph A LCDD10 pin */
+                                                        AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA11 periph A LCDD11 pin */
+                                                        AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA12 periph A LCDD12 pin */
+                                                        AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA13 periph A LCDD13 pin */
+                                                        AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA14 periph A LCDD14 pin */
+                                                        AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PA15 periph A LCDD15 pin */
+                                                        AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC14 periph C LCDD16 pin */
+                                                        AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC13 periph C LCDD17 pin */
+                                                        AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC12 periph C LCDD18 pin */
+                                                        AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC11 periph C LCDD19 pin */
+                                                        AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC10 periph C LCDD20 pin */
+                                                        AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PC15 periph C LCDD21 pin */
+                                                        AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE   /* PE27 periph C LCDD22 pin */
+                                                        AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PE28 periph C LCDD23 pin */
+                                       };
+                               };
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi
new file mode 100644 (file)
index 0000000..38e88e3
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * at91sama5d3_mci2.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * 3 MMC ports
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff200 {
+                               mmc2 {
+                                       pinctrl_mmc2_clk_cmd_dat0: mmc2_clk_cmd_dat0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC15 periph A MCI2_CK, conflicts with PCK2 */
+                                                        AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP        /* PC10 periph A MCI2_CDA with pullup */
+                                                        AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;      /* PC11 periph A MCI2_DA0 with pullup */
+                                       };
+                                       pinctrl_mmc2_dat1_3: mmc2_dat1_3 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */
+                                                        AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */
+                                                        AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */
+                                       };
+                               };
+                       };
+
+                       mmc2: mmc@f8004000 {
+                               compatible = "atmel,hsmci";
+                               reg = <0xf8004000 0x600>;
+                               interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+                               dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(1)>;
+                               dma-names = "rxtx";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>;
+                               status = "disabled";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi
new file mode 100644 (file)
index 0000000..5264bb4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * at91sama5d3_tcb1.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * 2 TC blocks.
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       aliases {
+               tcb1 = &tcb1;
+       };
+
+       ahb {
+               apb {
+                       tcb1: timer@f8014000 {
+                               compatible = "atmel,at91sam9x5-tcb";
+                               reg = <0xf8014000 0x100>;
+                               interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi
new file mode 100644 (file)
index 0000000..98fcb2d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * at91sama5d3_uart.dtsi - Device Tree Include file for AT91SAM9x5 SoC with
+ * UART support
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       ahb {
+               apb {
+                       pinctrl@fffff200 {
+                               uart0 {
+                                       pinctrl_uart0: uart0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE   /* PC29 periph A, conflicts with PWMFI2, ISI_D8 */
+                                                        AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;      /* PC30 periph A with pullup, conflicts with ISI_PCK */
+                                       };
+                               };
+
+                               uart1 {
+                                       pinctrl_uart1: uart1-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE   /* PA30 periph B, conflicts with TWD0, ISI_VSYNC */
+                                                        AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;      /* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */
+                                       };
+                               };
+                       };
+
+                       uart0: serial@f0024000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xf0024000 0x200>;
+                               interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_uart0>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@f8028000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xf8028000 0x200>;
+                               interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_uart1>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 31ed9e3bb649ab9a6af644d58a36576bc0d3cabd..726a0f35100c5218fb0b467bef7fa611f953b6de 100644 (file)
@@ -6,7 +6,6 @@
  *
  * Licensed under GPLv2 or later.
  */
-#include "sama5d3.dtsi"
 
 / {
        compatible = "atmel,samad3xcm", "atmel,sama5d3", "atmel,sama5";
index 212230629f271459950547d1af23c143fb67e981..8ee06dd81799da98cbe14ed6c43973e4d4bd513f 100644 (file)
 };
 
 &i2c0 {
+       status = "okay";
        as3711@40 {
                compatible = "ams,as3711";
                reg = <0x40>;
 &i2c3 {
        pinctrl-0 = <&i2c3_pins>;
        pinctrl-names = "default";
+       status = "okay";
 };
 
 &mmcif {
index 3955c7606a6f45a33036bec612ad918806315dee..fcf26889a8a0aacb380d980fb6cccdd36ee36dff 100644 (file)
                              0 168 0x4
                              0 169 0x4
                              0 170 0x4>;
+               status = "disabled";
        };
 
        i2c1: i2c@e6822000 {
                              0 52 0x4
                              0 53 0x4
                              0 54 0x4>;
+               status = "disabled";
        };
 
        i2c2: i2c@e6824000 {
                              0 172 0x4
                              0 173 0x4
                              0 174 0x4>;
+               status = "disabled";
        };
 
        i2c3: i2c@e6826000 {
                              0 184 0x4
                              0 185 0x4
                              0 186 0x4>;
+               status = "disabled";
        };
 
        i2c4: i2c@e6828000 {
                              0 188 0x4
                              0 189 0x4
                              0 190 0x4>;
+               status = "disabled";
        };
 
        mmcif: mmcif@e6bd0000 {
index e273fa993b8c82aa696273be311a145d38d21e5d..6d09b8d42fdd123da5e3b5e4b315983c42f9c6eb 100644 (file)
                                                        reg = <0x58>;
                                                };
 
-                                               cfg_s2f_usr0_clk: cfg_s2f_usr0_clk {
+                                               cfg_h2f_usr0_clk: cfg_h2f_usr0_clk {
                                                        #clock-cells = <0>;
                                                        compatible = "altr,socfpga-perip-clk";
                                                        clocks = <&main_pll>;
                                                        reg = <0x98>;
                                                };
 
-                                               s2f_usr1_clk: s2f_usr1_clk {
+                                               h2f_usr1_clk: h2f_usr1_clk {
                                                        #clock-cells = <0>;
                                                        compatible = "altr,socfpga-perip-clk";
                                                        clocks = <&periph_pll>;
                                                        reg = <0xD0>;
                                                };
 
-                                               s2f_usr2_clk: s2f_usr2_clk {
+                                               h2f_usr2_clk: h2f_usr2_clk {
                                                        #clock-cells = <0>;
                                                        compatible = "altr,socfpga-perip-clk";
                                                        clocks = <&sdram_pll>;
                                                };
                                        };
 
-                               mpu_periph_clk: mpu_periph_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mpuclk>;
-                                       fixed-divider = <4>;
+                                       mpu_periph_clk: mpu_periph_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mpuclk>;
+                                               fixed-divider = <4>;
                                        };
 
-                               mpu_l2_ram_clk: mpu_l2_ram_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mpuclk>;
-                                       fixed-divider = <2>;
+                                       mpu_l2_ram_clk: mpu_l2_ram_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mpuclk>;
+                                               fixed-divider = <2>;
                                        };
 
-                               l4_main_clk: l4_main_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mainclk>;
-                                       clk-gate = <0x60 0>;
+                                       l4_main_clk: l4_main_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mainclk>;
+                                               clk-gate = <0x60 0>;
                                        };
 
-                               l3_main_clk: l3_main_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mainclk>;
+                                       l3_main_clk: l3_main_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mainclk>;
                                        };
 
-                               l3_mp_clk: l3_mp_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mainclk>;
-                                       div-reg = <0x64 0 2>;
-                                       clk-gate = <0x60 1>;
+                                       l3_mp_clk: l3_mp_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mainclk>;
+                                               div-reg = <0x64 0 2>;
+                                               clk-gate = <0x60 1>;
                                        };
 
-                               l3_sp_clk: l3_sp_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mainclk>;
-                                       div-reg = <0x64 2 2>;
-                               };
+                                       l3_sp_clk: l3_sp_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mainclk>;
+                                               div-reg = <0x64 2 2>;
+                                       };
 
-                               l4_mp_clk: l4_mp_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mainclk>, <&per_base_clk>;
-                                       div-reg = <0x64 4 3>;
-                                       clk-gate = <0x60 2>;
+                                       l4_mp_clk: l4_mp_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mainclk>, <&per_base_clk>;
+                                               div-reg = <0x64 4 3>;
+                                               clk-gate = <0x60 2>;
                                        };
 
-                               l4_sp_clk: l4_sp_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&mainclk>, <&per_base_clk>;
-                                       div-reg = <0x64 7 3>;
-                                       clk-gate = <0x60 3>;
+                                       l4_sp_clk: l4_sp_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&mainclk>, <&per_base_clk>;
+                                               div-reg = <0x64 7 3>;
+                                               clk-gate = <0x60 3>;
                                        };
 
-                               dbg_at_clk: dbg_at_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&dbg_base_clk>;
-                                       div-reg = <0x68 0 2>;
-                                       clk-gate = <0x60 4>;
+                                       dbg_at_clk: dbg_at_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&dbg_base_clk>;
+                                               div-reg = <0x68 0 2>;
+                                               clk-gate = <0x60 4>;
                                        };
 
-                               dbg_clk: dbg_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&dbg_base_clk>;
-                                       div-reg = <0x68 2 2>;
-                                       clk-gate = <0x60 5>;
+                                       dbg_clk: dbg_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&dbg_base_clk>;
+                                               div-reg = <0x68 2 2>;
+                                               clk-gate = <0x60 5>;
                                        };
 
-                               dbg_trace_clk: dbg_trace_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&dbg_base_clk>;
-                                       div-reg = <0x6C 0 3>;
-                                       clk-gate = <0x60 6>;
+                                       dbg_trace_clk: dbg_trace_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&dbg_base_clk>;
+                                               div-reg = <0x6C 0 3>;
+                                               clk-gate = <0x60 6>;
                                        };
 
-                               dbg_timer_clk: dbg_timer_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&dbg_base_clk>;
-                                       clk-gate = <0x60 7>;
+                                       dbg_timer_clk: dbg_timer_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&dbg_base_clk>;
+                                               clk-gate = <0x60 7>;
                                        };
 
-                               cfg_clk: cfg_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&cfg_s2f_usr0_clk>;
-                                       clk-gate = <0x60 8>;
+                                       cfg_clk: cfg_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&cfg_h2f_usr0_clk>;
+                                               clk-gate = <0x60 8>;
                                        };
 
-                               s2f_user0_clk: s2f_user0_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&cfg_s2f_usr0_clk>;
-                                       clk-gate = <0x60 9>;
+                                       h2f_user0_clk: h2f_user0_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&cfg_h2f_usr0_clk>;
+                                               clk-gate = <0x60 9>;
                                        };
 
-                               emac_0_clk: emac_0_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&emac0_clk>;
-                                       clk-gate = <0xa0 0>;
+                                       emac_0_clk: emac_0_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&emac0_clk>;
+                                               clk-gate = <0xa0 0>;
                                        };
 
-                               emac_1_clk: emac_1_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&emac1_clk>;
-                                       clk-gate = <0xa0 1>;
+                                       emac_1_clk: emac_1_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&emac1_clk>;
+                                               clk-gate = <0xa0 1>;
                                        };
 
-                               usb_mp_clk: usb_mp_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&per_base_clk>;
-                                       clk-gate = <0xa0 2>;
-                                       div-reg = <0xa4 0 3>;
+                                       usb_mp_clk: usb_mp_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&per_base_clk>;
+                                               clk-gate = <0xa0 2>;
+                                               div-reg = <0xa4 0 3>;
                                        };
 
-                               spi_m_clk: spi_m_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&per_base_clk>;
-                                       clk-gate = <0xa0 3>;
-                                       div-reg = <0xa4 3 3>;
+                                       spi_m_clk: spi_m_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&per_base_clk>;
+                                               clk-gate = <0xa0 3>;
+                                               div-reg = <0xa4 3 3>;
                                        };
 
-                               can0_clk: can0_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&per_base_clk>;
-                                       clk-gate = <0xa0 4>;
-                                       div-reg = <0xa4 6 3>;
+                                       can0_clk: can0_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&per_base_clk>;
+                                               clk-gate = <0xa0 4>;
+                                               div-reg = <0xa4 6 3>;
                                        };
 
-                               can1_clk: can1_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&per_base_clk>;
-                                       clk-gate = <0xa0 5>;
-                                       div-reg = <0xa4 9 3>;
+                                       can1_clk: can1_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&per_base_clk>;
+                                               clk-gate = <0xa0 5>;
+                                               div-reg = <0xa4 9 3>;
                                        };
 
-                               gpio_db_clk: gpio_db_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&per_base_clk>;
-                                       clk-gate = <0xa0 6>;
-                                       div-reg = <0xa8 0 24>;
+                                       gpio_db_clk: gpio_db_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&per_base_clk>;
+                                               clk-gate = <0xa0 6>;
+                                               div-reg = <0xa8 0 24>;
                                        };
 
-                               s2f_user1_clk: s2f_user1_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&s2f_usr1_clk>;
-                                       clk-gate = <0xa0 7>;
+                                       h2f_user1_clk: h2f_user1_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&h2f_usr1_clk>;
+                                               clk-gate = <0xa0 7>;
                                        };
 
-                               sdmmc_clk: sdmmc_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
-                                       clk-gate = <0xa0 8>;
+                                       sdmmc_clk: sdmmc_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+                                               clk-gate = <0xa0 8>;
                                        };
 
-                               nand_x_clk: nand_x_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
-                                       clk-gate = <0xa0 9>;
+                                       nand_x_clk: nand_x_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+                                               clk-gate = <0xa0 9>;
                                        };
 
-                               nand_clk: nand_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
-                                       clk-gate = <0xa0 10>;
-                                       fixed-divider = <4>;
+                                       nand_clk: nand_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+                                               clk-gate = <0xa0 10>;
+                                               fixed-divider = <4>;
                                        };
 
-                               qspi_clk: qspi_clk {
-                                       #clock-cells = <0>;
-                                       compatible = "altr,socfpga-gate-clk";
-                                       clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>;
-                                       clk-gate = <0xa0 11>;
+                                       qspi_clk: qspi_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>;
+                                               clk-gate = <0xa0 11>;
                                        };
                                };
                        };
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0xfffec600 0x100>;
                        interrupts = <1 13 0xf04>;
+                       clocks = <&mpu_periph_clk>;
                };
 
                timer0: timer0@ffc08000 {
                };
 
                rstmgr@ffd05000 {
-                               compatible = "altr,rst-mgr";
-                               reg = <0xffd05000 0x1000>;
-                       };
+                       compatible = "altr,rst-mgr";
+                       reg = <0xffd05000 0x1000>;
+               };
 
                sysmgr@ffd08000 {
                                compatible = "altr,sys-mgr";
diff --git a/arch/arm/boot/dts/socfpga_arria5.dtsi b/arch/arm/boot/dts/socfpga_arria5.dtsi
new file mode 100644 (file)
index 0000000..a85b404
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+/include/ "socfpga.dtsi"
+
+/ {
+       soc {
+               clkmgr@ffd04000 {
+                       clocks {
+                               osc1 {
+                                       clock-frequency = <25000000>;
+                               };
+                       };
+               };
+
+               serial0@ffc02000 {
+                       clock-frequency = <100000000>;
+               };
+
+               serial1@ffc03000 {
+                       clock-frequency = <100000000>;
+               };
+
+               sysmgr@ffd08000 {
+                       cpu1-start-addr = <0xffd080c4>;
+               };
+
+               timer0@ffc08000 {
+                       clock-frequency = <100000000>;
+               };
+
+               timer1@ffc09000 {
+                       clock-frequency = <100000000>;
+               };
+
+               timer2@ffd00000 {
+                       clock-frequency = <25000000>;
+               };
+
+               timer3@ffd01000 {
+                       clock-frequency = <25000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
new file mode 100644 (file)
index 0000000..5beffb2
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 2013 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/include/ "socfpga_arria5.dtsi"
+
+/ {
+       model = "Altera SOCFPGA Arria V SoC Development Kit";
+       compatible = "altr,socfpga-arria5", "altr,socfpga";
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+       };
+
+       memory {
+               name = "memory";
+               device_type = "memory";
+               reg = <0x0 0x40000000>; /* 1GB */
+       };
+
+       aliases {
+               /* this allow the ethaddr uboot environmnet variable contents
+               * to be added to the gmac1 device tree blob.
+               */
+               ethernet0 = &gmac1;
+       };
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts
deleted file mode 100644 (file)
index 973999d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Copyright (C) 2012 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
- */
-
-/dts-v1/;
-/include/ "socfpga.dtsi"
-
-/ {
-       model = "Altera SOCFPGA Cyclone V";
-       compatible = "altr,socfpga-cyclone5", "altr,socfpga";
-
-       chosen {
-               bootargs = "console=ttyS0,57600";
-       };
-
-       memory {
-               name = "memory";
-               device_type = "memory";
-               reg = <0x0 0x40000000>; /* 1GB */
-       };
-
-       aliases {
-               /* this allow the ethaddr uboot environmnet variable contents
-                * to be added to the gmac1 device tree blob.
-                */
-               ethernet0 = &gmac1;
-       };
-
-       soc {
-               clkmgr@ffd04000 {
-                       clocks {
-                               osc1 {
-                                       clock-frequency = <25000000>;
-                               };
-                       };
-               };
-
-               ethernet@ff702000 {
-                       phy-mode = "rgmii";
-                       phy-addr = <0xffffffff>; /* probe for phy addr */
-                       status = "okay";
-               };
-
-               timer0@ffc08000 {
-                       clock-frequency = <100000000>;
-               };
-
-               timer1@ffc09000 {
-                       clock-frequency = <100000000>;
-               };
-
-               timer2@ffd00000 {
-                       clock-frequency = <25000000>;
-               };
-
-               timer3@ffd01000 {
-                       clock-frequency = <25000000>;
-               };
-
-               serial0@ffc02000 {
-                       clock-frequency = <100000000>;
-               };
-
-               serial1@ffc03000 {
-                       clock-frequency = <100000000>;
-               };
-
-               sysmgr@ffd08000 {
-                       cpu1-start-addr = <0xffd080c4>;
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dtsi b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
new file mode 100644 (file)
index 0000000..a8716f6
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (C) 2012 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+/include/ "socfpga.dtsi"
+
+/ {
+       soc {
+               clkmgr@ffd04000 {
+                       clocks {
+                               osc1 {
+                                       clock-frequency = <25000000>;
+                               };
+                       };
+               };
+
+               ethernet@ff702000 {
+                       phy-mode = "rgmii";
+                       phy-addr = <0xffffffff>; /* probe for phy addr */
+                       status = "okay";
+               };
+
+               timer0@ffc08000 {
+                       clock-frequency = <100000000>;
+               };
+
+               timer1@ffc09000 {
+                       clock-frequency = <100000000>;
+               };
+
+               timer2@ffd00000 {
+                       clock-frequency = <25000000>;
+               };
+
+               timer3@ffd01000 {
+                       clock-frequency = <25000000>;
+               };
+
+               serial0@ffc02000 {
+                       clock-frequency = <100000000>;
+               };
+
+               serial1@ffc03000 {
+                       clock-frequency = <100000000>;
+               };
+
+               sysmgr@ffd08000 {
+                       cpu1-start-addr = <0xffd080c4>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
new file mode 100644 (file)
index 0000000..2ee52ab
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 2012 Altera Corporation <www.altera.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/include/ "socfpga_cyclone5.dtsi"
+
+/ {
+       model = "Altera SOCFPGA Cyclone V SoC Development Kit";
+       compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+       };
+
+       memory {
+               name = "memory";
+               device_type = "memory";
+               reg = <0x0 0x40000000>; /* 1GB */
+       };
+
+       aliases {
+               /* this allow the ethaddr uboot environmnet variable contents
+                * to be added to the gmac1 device tree blob.
+                */
+               ethernet0 = &gmac1;
+       };
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
new file mode 100644 (file)
index 0000000..50b99a2
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.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, see <http://www.gnu.org/licenses/>.
+ */
+
+/include/ "socfpga_cyclone5.dtsi"
+
+/ {
+       model = "Terasic SoCkit";
+       compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+       };
+
+       memory {
+               name = "memory";
+               device_type = "memory";
+               reg = <0x0 0x40000000>; /* 1GB */
+       };
+};
+
+&gmac1 {
+       status = "okay";
+};
index 1c1091eedadec293f619d5843f46506e31f14ffb..7da99fe497e13d59215b2bdd1b16a41fcd120c70 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/mfd/dbx500-prcmu.h>
 #include "skeleton.dtsi"
 
 / {
                        interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+
+               clocks {
+                       compatible = "stericsson,u8500-clks";
+
+                       prcmu_clk: prcmu-clock {
+                               #clock-cells = <1>;
+                       };
+
+                       prcc_pclk: prcc-periph-clock {
+                               #clock-cells = <2>;
+                       };
+
+                       prcc_kclk: prcc-kernel-clock {
+                               #clock-cells = <2>;
+                       };
+
+                       rtc_clk: rtc32k-clock {
+                               #clock-cells = <0>;
+                       };
+
+                       smp_twd_clk: smp-twd-clock {
+                               #clock-cells = <0>;
+                       };
+               };
+
+               mtu@a03c6000 {
+                       /* Nomadik System Timer */
+                       compatible = "st,nomadik-mtu";
+                       reg = <0xa03c6000 0x1000>;
+                       interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+
+                       clocks = <&prcmu_clk PRCMU_TIMCLK>, <&prcc_pclk 6 6>;
+                       clock-names = "timclk", "apb_pclk";
+               };
+
                timer@a0410600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0xa0410600 0x20>;
                        interrupts = <1 13 0x304>; /* IRQ level high per-CPU */
+
+                       clocks = <&smp_twd_clk>;
                };
 
                rtc@80154000 {
                        compatible = "arm,rtc-pl031", "arm,primecell";
                        reg = <0x80154000 0x1000>;
                        interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+
+                       clocks = <&rtc_clk>;
+                       clock-names = "apb_pclk";
                };
 
                gpio0: gpio@8012e000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <0>;
+
+                       clocks = <&prcc_pclk 1 9>;
                };
 
                gpio1: gpio@8012e080 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <1>;
+
+                       clocks = <&prcc_pclk 1 9>;
                };
 
                gpio2: gpio@8000e000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <2>;
+
+                       clocks = <&prcc_pclk 3 8>;
                };
 
                gpio3: gpio@8000e080 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <3>;
+
+                       clocks = <&prcc_pclk 3 8>;
                };
 
                gpio4: gpio@8000e100 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <4>;
+
+                       clocks = <&prcc_pclk 3 8>;
                };
 
                gpio5: gpio@8000e180 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <5>;
+
+                       clocks = <&prcc_pclk 3 8>;
                };
 
                gpio6: gpio@8011e000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <6>;
+
+                       clocks = <&prcc_pclk 2 11>;
                };
 
                gpio7: gpio@8011e080 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <7>;
+
+                       clocks = <&prcc_pclk 2 11>;
                };
 
                gpio8: gpio@a03fe000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        gpio-bank = <8>;
+
+                       clocks = <&prcc_pclk 5 1>;
                };
 
                pinctrl {
                };
 
                usb_per5@a03e0000 {
-                       compatible = "stericsson,db8500-musb",
-                               "mentor,musb";
+                       compatible = "stericsson,db8500-musb";
                        reg = <0xa03e0000 0x10000>;
                        interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "mc";
                                    "iep_6_14", "oep_6_14",
                                    "iep_7_15", "oep_7_15",
                                    "iep_8",    "oep_8";
+
+                       clocks = <&prcc_pclk 5 0>;
                };
 
                dma: dma-controller@801C0000 {
 
                        #dma-cells = <3>;
                        memcpy-channels = <56 57 58 59 60>;
+
+                       clocks = <&prcmu_clk PRCMU_DMACLK>;
                };
 
                prcmu: prcmu@80157000 {
                                reg = <0x80157450 0xC>;
                        };
 
+                       cpufreq {
+                               compatible = "stericsson,cpufreq-ux500";
+                               clocks = <&prcmu_clk PRCMU_ARMSS>;
+                               clock-names = "armss";
+                               status = "disabled";
+                       };
+
                        thermal@801573c0 {
                                compatible = "stericsson,db8500-thermal";
                                reg = <0x801573c0 0x40>;
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80004000 0x1000>;
                        interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
-                       arm,primecell-periphid = <0x180024>;
 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        v-i2c-supply = <&db8500_vape_reg>;
 
                        clock-frequency = <400000>;
+                       clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>;
+                       clock-names = "i2cclk", "apb_pclk";
                };
 
                i2c@80122000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80122000 0x1000>;
                        interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
-                       arm,primecell-periphid = <0x180024>;
 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        v-i2c-supply = <&db8500_vape_reg>;
 
                        clock-frequency = <400000>;
+
+                       clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>;
+                       clock-names = "i2cclk", "apb_pclk";
                };
 
                i2c@80128000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80128000 0x1000>;
                        interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
-                       arm,primecell-periphid = <0x180024>;
 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        v-i2c-supply = <&db8500_vape_reg>;
 
                        clock-frequency = <400000>;
+
+                       clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>;
+                       clock-names = "i2cclk", "apb_pclk";
                };
 
                i2c@80110000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80110000 0x1000>;
                        interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>;
-                       arm,primecell-periphid = <0x180024>;
 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        v-i2c-supply = <&db8500_vape_reg>;
 
                        clock-frequency = <400000>;
+
+                       clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>;
+                       clock-names = "i2cclk", "apb_pclk";
                };
 
                i2c@8012a000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x8012a000 0x1000>;
                        interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
-                       arm,primecell-periphid = <0x180024>;
 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        v-i2c-supply = <&db8500_vape_reg>;
 
                        clock-frequency = <400000>;
+
+                       clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>;
+                       clock-names = "i2cclk", "apb_pclk";
                };
 
                ssp@80002000 {
                        interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       status = "disabled";
+                       clocks = <&prcc_kclk 3 1>, <&prcc_pclk 3 1>;
+                       clock-names = "ssp0clk", "apb_pclk";
+                       dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */
+                              <&dma 8 0 0x0>; /* Logical - MemToDev */
+                       dma-names = "rx", "tx";
+               };
+
+               ssp@80003000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x80003000 0x1000>;
+                       interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&prcc_kclk 3 2>, <&prcc_pclk 3 2>;
+                       clock-names = "ssp1clk", "apb_pclk";
+                       dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */
+                              <&dma 9 0 0x0>; /* Logical - MemToDev */
+                       dma-names = "rx", "tx";
+               };
+
+               spi@8011a000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x8011a000 0x1000>;
+                       interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       /* Same clock wired to kernel and pclk */
+                       clocks = <&prcc_pclk 2 8>, <&prcc_pclk 2 8>;
+                       clock-names = "spi0clk", "apb_pclk";
+                       dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */
+                              <&dma 0 0 0x0>; /* Logical - MemToDev */
+                       dma-names = "rx", "tx";
+               };
+
+               spi@80112000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x80112000 0x1000>;
+                       interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       /* Same clock wired to kernel and pclk */
+                       clocks = <&prcc_pclk 2 2>, <&prcc_pclk 2 2>;
+                       clock-names = "spi1clk", "apb_pclk";
+                       dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */
+                              <&dma 35 0 0x0>; /* Logical - MemToDev */
+                       dma-names = "rx", "tx";
+               };
+
+               spi@80111000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x80111000 0x1000>;
+                       interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       /* Same clock wired to kernel and pclk */
+                       clocks = <&prcc_pclk 2 1>, <&prcc_pclk 2 1>;
+                       clock-names = "spi2clk", "apb_pclk";
+                       dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */
+                              <&dma 33 0 0x0>; /* Logical - MemToDev */
+                       dma-names = "rx", "tx";
+               };
+
+               spi@80129000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x80129000 0x1000>;
+                       interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       /* Same clock wired to kernel and pclk */
+                       clocks = <&prcc_pclk 1 7>, <&prcc_pclk 1 7>;
+                       clock-names = "spi3clk", "apb_pclk";
+                       dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */
+                              <&dma 40 0 0x0>; /* Logical - MemToDev */
+                       dma-names = "rx", "tx";
                };
 
                uart@80120000 {
                               <&dma 13 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 1 0>, <&prcc_pclk 1 0>;
+                       clock-names = "uart", "apb_pclk";
+
                        status = "disabled";
                };
 
                               <&dma 12 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 1 1>, <&prcc_pclk 1 1>;
+                       clock-names = "uart", "apb_pclk";
+
                        status = "disabled";
                };
 
                               <&dma 11 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 3 6>, <&prcc_pclk 3 6>;
+                       clock-names = "uart", "apb_pclk";
+
                        status = "disabled";
                };
 
                               <&dma 29 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>;
+                       clock-names = "sdi", "apb_pclk";
+
                        status = "disabled";
                };
 
                               <&dma 32 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>;
+                       clock-names = "sdi", "apb_pclk";
+
                        status = "disabled";
                };
 
                               <&dma 28 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>;
+                       clock-names = "sdi", "apb_pclk";
+
                        status = "disabled";
                };
 
                        compatible = "arm,pl18x", "arm,primecell";
                        reg = <0x80119000 0x1000>;
                        interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
+
+                       clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>;
+                       clock-names = "sdi", "apb_pclk";
+
                        status = "disabled";
                };
 
                               <&dma 42 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
 
+                       clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>;
+                       clock-names = "sdi", "apb_pclk";
+
                        status = "disabled";
                };
 
                        compatible = "arm,pl18x", "arm,primecell";
                        reg = <0x80008000 0x1000>;
                        interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+
+                       clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>;
+                       clock-names = "sdi", "apb_pclk";
+
                        status = "disabled";
                };
 
                        reg = <0x80123000 0x1000>;
                        interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
                        v-ape-supply = <&db8500_vape_reg>;
+
+                       clocks = <&prcc_kclk 1 3>, <&prcc_pclk 1 3>;
+                       clock-names = "msp", "apb_pclk";
+
                        status = "disabled";
                };
 
                        reg = <0x80124000 0x1000>;
                        interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
                        v-ape-supply = <&db8500_vape_reg>;
+
+                       clocks = <&prcc_kclk 1 4>, <&prcc_pclk 1 4>;
+                       clock-names = "msp", "apb_pclk";
+
                        status = "disabled";
                };
 
                        reg = <0x80117000 0x1000>;
                        interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
                        v-ape-supply = <&db8500_vape_reg>;
+
+                       clocks = <&prcc_kclk 2 3>, <&prcc_pclk 2 5>;
+                       clock-names = "msp", "apb_pclk";
+
                        status = "disabled";
                };
 
                        reg = <0x80125000 0x1000>;
                        interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
                        v-ape-supply = <&db8500_vape_reg>;
+
+                       clocks = <&prcc_kclk 1 10>, <&prcc_pclk 1 11>;
+                       clock-names = "msp", "apb_pclk";
+
                        status = "disabled";
                };
 
                cpufreq-cooling {
                        compatible = "stericsson,db8500-cpufreq-cooling";
                        status = "disabled";
-                };
+               };
 
                vmmci: regulator-gpio {
                        compatible = "regulator-gpio";
                        interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
 
                        v-ape-supply = <&db8500_vape_reg>;
+                       clocks = <&prcc_pclk 6 1>;
                };
 
                hash@a03c2000 {
                        reg = <0xa03c2000 0x1000>;
 
                        v-ape-supply = <&db8500_vape_reg>;
+                       clocks = <&prcc_pclk 6 2>;
                };
        };
 };
diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi
new file mode 100644 (file)
index 0000000..76704ec
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       soc {
+               i2c@80004000 {
+                       stmpe1601: stmpe1601@40 {
+                               compatible = "st,stmpe1601";
+                               reg = <0x40>;
+                               interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+                               interrupt-parent = <&gpio6>;
+                               interrupt-controller;
+
+                               wakeup-source;
+                               st,autosleep-timeout = <1024>;
+
+                               stmpe_keypad {
+                                       compatible = "st,stmpe-keypad";
+
+                                       debounce-interval = <64>;
+                                       st,scan-count = <8>;
+                                       st,no-autorepeat;
+
+                                       linux,keymap = <0x205006b
+                                                       0x4010074
+                                                       0x3050072
+                                                       0x1030004
+                                                       0x502006a
+                                                       0x500000a
+                                                       0x5008b
+                                                       0x706001c
+                                                       0x405000b
+                                                       0x6070003
+                                                       0x3040067
+                                                       0x303006c
+                                                       0x60400e7
+                                                       0x602009e
+                                                       0x4020073
+                                                       0x5050002
+                                                       0x4030069
+                                                       0x3020008>;
+                               };
+                       };
+               };
+
+               i2c@80110000 {
+                       bu21013_tp@5c {
+                               compatible = "rohm,bu21013_tp";
+                               reg = <0x5c>;
+                               avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+                               rohm,touch-max-x = <384>;
+                               rohm,touch-max-y = <704>;
+                               rohm,flip-y;
+                       };
+
+                       bu21013_tp@5d {
+                               compatible = "rohm,bu21013_tp";
+                               reg = <0x5d>;
+                               avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+                               rohm,touch-max-x = <384>;
+                               rohm,touch-max-y = <704>;
+                               rohm,flip-y;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi
new file mode 100644 (file)
index 0000000..76d3ef1
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the TVK1281618 UIB
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       soc {
+               /* Add Synaptics touch screen, TC35892 keypad etc here */
+               i2c@80004000 {
+                       tc3589x@44 {
+                               compatible = "tc3589x";
+                               reg = <0x44>;
+                               interrupt-parent = <&gpio6>;
+                               interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+
+                               tc3589x_gpio {
+                                       compatible = "tc3589x-gpio";
+                                       interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                               };
+                       };
+               };
+       };
+};
index 370e03f5e7b2c8bcd416dd871b89c44e5e9ddfb8..aa3f02060fdd43114570eceedbf1ef54dc49a01f 100644 (file)
                        status = "okay";
                };
 
-               i2c@80004000 {
-                       tc3589x@42 {
-                               compatible = "tc3589x";
-                               reg = <0x42>;
-                               interrupt-parent = <&gpio6>;
-                               interrupts = <25 IRQ_TYPE_EDGE_RISING>;
-
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-
-                               tc3589x_gpio: tc3589x_gpio {
-                                       compatible = "tc3589x-gpio";
-                                       interrupts = <0 IRQ_TYPE_EDGE_RISING>;
-
-                                       interrupt-controller;
-                                       #interrupt-cells = <2>;
-                                       gpio-controller;
-                                       #gpio-cells = <2>;
-                               };
-                       };
-               };
-
                i2c@80128000 {
                        lp5521@33 {
                                compatible = "national,lp5521";
@@ -72,6 +50,7 @@
                                chan0 {
                                        led-cur = /bits/ 8 <0x2f>;
                                        max-cur = /bits/ 8 <0x5f>;
+                                       linux,default-trigger = "heartbeat";
                                };
                                chan1 {
                                        led-cur = /bits/ 8 <0x2f>;
                        };
                        bh1780@29 {
                                compatible = "rohm,bh1780gli";
-                               reg = <0x33>;
+                               reg = <0x29>;
                        };
                };
 
                };
 
                prcmu@80157000 {
-                       db8500-prcmu-regulators {
-                               db8500_vape_reg: db8500_vape {
-                                       regulator-name = "db8500-vape";
-                               };
-
-                               db8500_varm_reg: db8500_varm {
-                                       regulator-name = "db8500-varm";
-                               };
-
-                               db8500_vmodem_reg: db8500_vmodem {
-                                       regulator-name = "db8500-vmodem";
-                               };
-
-                               db8500_vpll_reg: db8500_vpll {
-                                       regulator-name = "db8500-vpll";
-                               };
-
-                               db8500_vsmps1_reg: db8500_vsmps1 {
-                                       regulator-name = "db8500-vsmps1";
-                               };
-
-                               db8500_vsmps2_reg: db8500_vsmps2 {
-                                       regulator-name = "db8500-vsmps2";
-                               };
-
-                               db8500_vsmps3_reg: db8500_vsmps3 {
-                                       regulator-name = "db8500-vsmps3";
-                               };
-
-                               db8500_vrf1_reg: db8500_vrf1 {
-                                       regulator-name = "db8500-vrf1";
-                               };
-
-                               db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
-                                       regulator-name = "db8500-sva-mmdsp";
-                               };
-
-                               db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
-                                       regulator-name = "db8500-sva-mmdsp-ret";
-                               };
-
-                               db8500_sva_pipe_reg: db8500_sva_pipe {
-                                       regulator-name = "db8500_sva_pipe";
-                               };
-
-                               db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
-                                       regulator-name = "db8500_sia_mmdsp";
-                               };
-
-                               db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
-                                       regulator-name = "db8500-sia-mmdsp-ret";
-                               };
-
-                               db8500_sia_pipe_reg: db8500_sia_pipe {
-                                       regulator-name = "db8500-sia-pipe";
-                               };
-
-                               db8500_sga_reg: db8500_sga {
-                                       regulator-name = "db8500-sga";
-                               };
-
-                               db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
-                                       regulator-name = "db8500-b2r2-mcde";
-                               };
-
-                               db8500_esram12_reg: db8500_esram12 {
-                                       regulator-name = "db8500-esram12";
-                               };
-
-                               db8500_esram12_ret_reg: db8500_esram12_ret {
-                                       regulator-name = "db8500-esram12-ret";
-                               };
-
-                               db8500_esram34_reg: db8500_esram34 {
-                                       regulator-name = "db8500-esram34";
+                       ab8500 {
+                               ab8500-gpio {
+                                       compatible = "stericsson,ab8500-gpio";
                                };
 
-                               db8500_esram34_ret_reg: db8500_esram34_ret {
-                                       regulator-name = "db8500-esram34-ret";
-                               };
-                       };
-
-                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
diff --git a/arch/arm/boot/dts/ste-hrefprev60-stuib.dts b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts
new file mode 100644 (file)
index 0000000..2b1cb5b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 "ste-hrefprev60.dtsi"
+#include "ste-href-stuib.dtsi"
+
+/ {
+       model = "ST-Ericsson HREF (pre-v60) and ST UIB";
+       compatible = "st-ericsson,mop500", "st-ericsson,u8500";
+
+       soc {
+               /* Reset line for the BU21013 touchscreen */
+               i2c@80110000 {
+                       /* Only one of these will be used */
+                       bu21013_tp@5c {
+                               touch-gpio = <&gpio2 12 0x4>;
+                               reset-gpio = <&tc3589x_gpio 13 0x4>;
+                       };
+                       bu21013_tp@5d {
+                               touch-gpio = <&gpio2 12 0x4>;
+                               reset-gpio = <&tc3589x_gpio 13 0x4>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-hrefprev60-tvk.dts b/arch/arm/boot/dts/ste-hrefprev60-tvk.dts
new file mode 100644 (file)
index 0000000..59523f8
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 "ste-hrefprev60.dtsi"
+#include "ste-href-tvk1281618.dtsi"
+
+/ {
+       model = "ST-Ericsson HREF (pre-v60) and TVK1281618 UIB";
+       compatible = "st-ericsson,mop500", "st-ericsson,u8500";
+};
diff --git a/arch/arm/boot/dts/ste-hrefprev60.dts b/arch/arm/boot/dts/ste-hrefprev60.dts
deleted file mode 100644 (file)
index d8d3b99..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2012 ST-Ericsson AB
- *
- * 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 "ste-dbx5x0.dtsi"
-#include "ste-href.dtsi"
-#include "ste-stuib.dtsi"
-
-/ {
-       model = "ST-Ericsson HREF (pre-v60) platform with Device Tree";
-       compatible = "st-ericsson,mop500", "st-ericsson,u8500";
-
-       gpio_keys {
-               button@1 {
-                       gpios = <&tc3589x_gpio 7 0x4>;
-               };
-       };
-
-       soc {
-               prcmu@80157000 {
-                       ab8500@5 {
-                               ab8500-gpio {
-                                       compatible = "stericsson,ab8500-gpio";
-                               };
-                       };
-               };
-
-               i2c@80004000 {
-                       tps61052@33 {
-                               compatible = "tps61052";
-                               reg = <0x33>;
-                       };
-               };
-
-               i2c@80110000 {
-                       bu21013_tp@5c {
-                               reset-gpio = <&tc3589x_gpio 13 0x4>;
-                       };
-               };
-
-               vmmci: regulator-gpio {
-                       gpios = <&tc3589x_gpio 18 0x4>;
-                       enable-gpio = <&tc3589x_gpio 17 0x4>;
-
-                       status = "okay";
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi
new file mode 100644 (file)
index 0000000..b2cd7bc
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the HREF+ prior to the v60 variant.
+ */
+
+#include "ste-dbx5x0.dtsi"
+#include "ste-href.dtsi"
+
+/ {
+       gpio_keys {
+               button@1 {
+                       gpios = <&tc3589x_gpio 7 0x4>;
+               };
+       };
+
+       soc {
+               i2c@80004000 {
+                       tps61052@33 {
+                               compatible = "tps61052";
+                               reg = <0x33>;
+                       };
+
+                       tc3589x@42 {
+                               compatible = "tc3589x";
+                               reg = <0x42>;
+                               interrupt-parent = <&gpio6>;
+                               interrupts = <25 IRQ_TYPE_EDGE_RISING>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+
+                               tc3589x_gpio: tc3589x_gpio {
+                                       compatible = "tc3589x-gpio";
+                                       interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                               };
+                       };
+               };
+
+               vmmci: regulator-gpio {
+                       gpios = <&tc3589x_gpio 18 0x4>;
+                       enable-gpio = <&tc3589x_gpio 17 0x4>;
+
+                       status = "okay";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
new file mode 100644 (file)
index 0000000..8c6a2de
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the HREF version 60 or later with the ST UIB
+ */
+
+/dts-v1/;
+#include "ste-hrefv60plus.dtsi"
+#include "ste-href-stuib.dtsi"
+
+/ {
+       model = "ST-Ericsson HREF (v60+) and ST UIB";
+       compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
+
+       soc {
+               /* Reset line for the BU21013 touchscreen */
+               i2c@80110000 {
+                       /* Only one of these will be used */
+                       bu21013_tp@5c {
+                               touch-gpio = <&gpio2 20 0x4>;
+                               reset-gpio = <&gpio4 17 0x4>;
+                       };
+                       bu21013_tp@5d {
+                               touch-gpio = <&gpio2 20 0x4>;
+                               reset-gpio = <&gpio4 17 0x4>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts b/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts
new file mode 100644 (file)
index 0000000..d53cccd
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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
+ *
+ * Device Tree for the HREF version 60 or later with the TVK1281618 UIB
+ */
+
+/dts-v1/;
+#include "ste-hrefv60plus.dtsi"
+#include "ste-href-tvk1281618.dtsi"
+
+/ {
+       model = "ST-Ericsson HREF (v60+) and TVK1281618 UIB";
+       compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
+};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dts b/arch/arm/boot/dts/ste-hrefv60plus.dts
deleted file mode 100644 (file)
index 6e52ebb..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright 2012 ST-Ericsson AB
- *
- * 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 "ste-dbx5x0.dtsi"
-#include "ste-href.dtsi"
-#include "ste-stuib.dtsi"
-
-/ {
-       model = "ST-Ericsson HREF (v60+) platform with Device Tree";
-       compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
-
-       gpio_keys {
-               button@1 {
-                       gpios = <&gpio6 25 0x4>;
-               };
-       };
-
-       soc {
-               i2c@80110000 {
-                       bu21013_tp@0x5c {
-                               reset-gpio = <&gpio4 15 0x4>;
-                       };
-               };
-
-               // External Micro SD slot
-               sdi0_per1@80126000 {
-                       arm,primecell-periphid = <0x10480180>;
-                       max-frequency = <100000000>;
-                       bus-width = <4>;
-                       mmc-cap-sd-highspeed;
-                       mmc-cap-mmc-highspeed;
-                       vmmc-supply = <&ab8500_ldo_aux3_reg>;
-
-                       cd-gpios  = <&tc3589x_gpio 3 0x4>;
-
-                       status = "okay";
-               };
-
-               // WLAN SDIO channel
-               sdi1_per2@80118000 {
-                       arm,primecell-periphid = <0x10480180>;
-                       max-frequency = <100000000>;
-                       bus-width = <4>;
-
-                       status = "okay";
-               };
-
-               // PoP:ed eMMC
-               sdi2_per3@80005000 {
-                       arm,primecell-periphid = <0x10480180>;
-                       max-frequency = <100000000>;
-                       bus-width = <8>;
-                       mmc-cap-mmc-highspeed;
-
-                       status = "okay";
-               };
-
-               // On-board eMMC
-               sdi4_per2@80114000 {
-                       arm,primecell-periphid = <0x10480180>;
-                       max-frequency = <100000000>;
-                       bus-width = <8>;
-                       mmc-cap-mmc-highspeed;
-                       vmmc-supply = <&ab8500_ldo_aux2_reg>;
-
-                       status = "okay";
-               };
-
-               prcmu@80157000 {
-                       db8500-prcmu-regulators {
-                               db8500_vape_reg: db8500_vape {
-                                       regulator-name = "db8500-vape";
-                               };
-
-                               db8500_varm_reg: db8500_varm {
-                                       regulator-name = "db8500-varm";
-                               };
-
-                               db8500_vmodem_reg: db8500_vmodem {
-                                       regulator-name = "db8500-vmodem";
-                               };
-
-                               db8500_vpll_reg: db8500_vpll {
-                                       regulator-name = "db8500-vpll";
-                               };
-
-                               db8500_vsmps1_reg: db8500_vsmps1 {
-                                       regulator-name = "db8500-vsmps1";
-                               };
-
-                               db8500_vsmps2_reg: db8500_vsmps2 {
-                                       regulator-name = "db8500-vsmps2";
-                               };
-
-                               db8500_vsmps3_reg: db8500_vsmps3 {
-                                       regulator-name = "db8500-vsmps3";
-                               };
-
-                               db8500_vrf1_reg: db8500_vrf1 {
-                                       regulator-name = "db8500-vrf1";
-                               };
-
-                               db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
-                                       regulator-name = "db8500-sva-mmdsp";
-                               };
-
-                               db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
-                                       regulator-name = "db8500-sva-mmdsp-ret";
-                               };
-
-                               db8500_sva_pipe_reg: db8500_sva_pipe {
-                                       regulator-name = "db8500_sva_pipe";
-                               };
-
-                               db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
-                                       regulator-name = "db8500_sia_mmdsp";
-                               };
-
-                               db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
-                                       regulator-name = "db8500-sia-mmdsp-ret";
-                               };
-
-                               db8500_sia_pipe_reg: db8500_sia_pipe {
-                                       regulator-name = "db8500-sia-pipe";
-                               };
-
-                               db8500_sga_reg: db8500_sga {
-                                       regulator-name = "db8500-sga";
-                               };
-
-                               db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
-                                       regulator-name = "db8500-b2r2-mcde";
-                               };
-
-                               db8500_esram12_reg: db8500_esram12 {
-                                       regulator-name = "db8500-esram12";
-                               };
-
-                               db8500_esram12_ret_reg: db8500_esram12_ret {
-                                       regulator-name = "db8500-esram12-ret";
-                               };
-
-                               db8500_esram34_reg: db8500_esram34 {
-                                       regulator-name = "db8500-esram34";
-                               };
-
-                               db8500_esram34_ret_reg: db8500_esram34_ret {
-                                       regulator-name = "db8500-esram34-ret";
-                               };
-                       };
-
-                       ab8500 {
-                               ab8500-regulators {
-                                       ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
-                                               regulator-name = "V-DISPLAY";
-                                       };
-
-                                       ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
-                                               regulator-name = "V-eMMC1";
-                                       };
-
-                                       ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
-                                               regulator-name = "V-MMC-SD";
-                                       };
-
-                                       ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
-                                               regulator-name = "V-INTCORE";
-                                       };
-
-                                       ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
-                                               regulator-name = "V-TVOUT";
-                                       };
-
-                                       ab8500_ldo_usb_reg: ab8500_ldo_usb {
-                                               regulator-name = "dummy";
-                                       };
-
-                                       ab8500_ldo_audio_reg: ab8500_ldo_audio {
-                                               regulator-name = "V-AUD";
-                                       };
-
-                                       ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
-                                               regulator-name = "V-AMIC1";
-                                       };
-
-                                       ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
-                                               regulator-name = "V-AMIC2";
-                                       };
-
-                                       ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
-                                               regulator-name = "V-DMIC";
-                                       };
-
-                                       ab8500_ldo_ana_reg: ab8500_ldo_ana {
-                                               regulator-name = "V-CSI/DSI";
-                                       };
-                               };
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi
new file mode 100644 (file)
index 0000000..aed511b
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * 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 "ste-dbx5x0.dtsi"
+#include "ste-href.dtsi"
+
+/ {
+       model = "ST-Ericsson HREF (v60+) platform with Device Tree";
+       compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
+
+       gpio_keys {
+               button@1 {
+                       gpios = <&gpio5 25 0x4>;
+               };
+       };
+
+       soc {
+               // External Micro SD slot
+               sdi0_per1@80126000 {
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <100000000>;
+                       bus-width = <4>;
+                       mmc-cap-sd-highspeed;
+                       mmc-cap-mmc-highspeed;
+                       vmmc-supply = <&ab8500_ldo_aux3_reg>;
+
+                       cd-gpios  = <&gpio2 31 0x4>; // 95
+
+                       status = "okay";
+               };
+
+               // WLAN SDIO channel
+               sdi1_per2@80118000 {
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <100000000>;
+                       bus-width = <4>;
+
+                       status = "okay";
+               };
+
+               // PoP:ed eMMC
+               sdi2_per3@80005000 {
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <100000000>;
+                       bus-width = <8>;
+                       mmc-cap-mmc-highspeed;
+
+                       status = "okay";
+               };
+
+               // On-board eMMC
+               sdi4_per2@80114000 {
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <100000000>;
+                       bus-width = <8>;
+                       mmc-cap-mmc-highspeed;
+                       vmmc-supply = <&ab8500_ldo_aux2_reg>;
+
+                       status = "okay";
+               };
+       };
+};
index 9169d3025f39ed5fd2475f43f0d3cd261e71894d..79425e3836cec4e957ef6e9b21dd7f70e83fa394 100644 (file)
                reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                clocks = <&hclksmc>;
                status = "okay";
+               timings = /bits/ 8 <0 0 0 0x10 0x0a 0>;
 
                partition@0 {
                label = "X-Loader(NAND)";
                pinctrl-0 = <&i2c0_default_mux>, <&i2c0_default_mode>;
 
                stw4811@2d {
-                          compatible = "st,stw4811";
-                          reg = <0x2d>;
+                       compatible = "st,stw4811";
+                       reg = <0x2d>;
+                       vmmc_regulator: vmmc {
+                               compatible = "st,stw481x-vmmc";
+                               regulator-name = "VMMC";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
                };
        };
 
                        cd-inverted;
                        pinctrl-names = "default";
                        pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>;
+                       vmmc-supply = <&vmmc_regulator>;
                };
        };
 };
index f1fc128e249dd7d0dfbd337aeb40fc0dbdcc2c69..f0b39f835914beda02952a3cd9eb8860e38599ba 100644 (file)
                                vdd33a-supply = <&en_3v3_reg>;
                                vddvario-supply = <&db8500_vape_reg>;
 
-
                                reg-shift = <1>;
                                reg-io-width = <2>;
                                smsc,force-internal-phy;
                                smsc,irq-active-high;
                                smsc,irq-push-pull;
+
+                               clocks = <&prcc_pclk 3 0>;
                        };
                };
 
                };
 
                prcmu@80157000 {
-                       db8500-prcmu-regulators {
-                               db8500_vape_reg: db8500_vape {
-                                       regulator-name = "db8500-vape";
-                               };
-
-                               db8500_varm_reg: db8500_varm {
-                                       regulator-name = "db8500-varm";
-                               };
-
-                               db8500_vmodem_reg: db8500_vmodem {
-                                       regulator-name = "db8500-vmodem";
-                               };
-
-                               db8500_vpll_reg: db8500_vpll {
-                                       regulator-name = "db8500-vpll";
-                               };
-
-                               db8500_vsmps1_reg: db8500_vsmps1 {
-                                       regulator-name = "db8500-vsmps1";
-                               };
-
-                               db8500_vsmps2_reg: db8500_vsmps2 {
-                                       regulator-name = "db8500-vsmps2";
-                               };
-
-                               db8500_vsmps3_reg: db8500_vsmps3 {
-                                       regulator-name = "db8500-vsmps3";
-                               };
-
-                               db8500_vrf1_reg: db8500_vrf1 {
-                                       regulator-name = "db8500-vrf1";
-                               };
-
-                               db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
-                                       regulator-name = "db8500-sva-mmdsp";
-                               };
-
-                               db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
-                                       regulator-name = "db8500-sva-mmdsp-ret";
-                               };
-
-                               db8500_sva_pipe_reg: db8500_sva_pipe {
-                                       regulator-name = "db8500_sva_pipe";
-                               };
-
-                               db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
-                                       regulator-name = "db8500_sia_mmdsp";
-                               };
-
-                               db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
-                                       regulator-name = "db8500-sia-mmdsp-ret";
-                               };
-
-                               db8500_sia_pipe_reg: db8500_sia_pipe {
-                                       regulator-name = "db8500-sia-pipe";
-                               };
-
-                               db8500_sga_reg: db8500_sga {
-                                       regulator-name = "db8500-sga";
-                               };
-
-                               db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
-                                       regulator-name = "db8500-b2r2-mcde";
-                               };
-
-                               db8500_esram12_reg: db8500_esram12 {
-                                       regulator-name = "db8500-esram12";
-                               };
-
-                               db8500_esram12_ret_reg: db8500_esram12_ret {
-                                       regulator-name = "db8500-esram12-ret";
-                               };
-
-                               db8500_esram34_reg: db8500_esram34 {
-                                       regulator-name = "db8500-esram34";
-                               };
-
-                               db8500_esram34_ret_reg: db8500_esram34_ret {
-                                       regulator-name = "db8500-esram34-ret";
-                               };
+                       cpufreq {
+                               status = "okay";
                        };
 
                        thermal@801573c0 {
diff --git a/arch/arm/boot/dts/ste-stuib.dtsi b/arch/arm/boot/dts/ste-stuib.dtsi
deleted file mode 100644 (file)
index 524e332..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2012 ST-Ericsson AB
- *
- * 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 <dt-bindings/interrupt-controller/irq.h>
-
-/ {
-       soc {
-               i2c@80004000 {
-                       stmpe1601: stmpe1601@40 {
-                               compatible = "st,stmpe1601";
-                               reg = <0x40>;
-                               interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
-                               interrupt-parent = <&gpio6>;
-                               interrupt-controller;
-
-                               wakeup-source;
-                               st,autosleep-timeout = <1024>;
-
-                               stmpe_keypad {
-                                       compatible = "st,stmpe-keypad";
-
-                                       debounce-interval = <64>;
-                                       st,scan-count = <8>;
-                                       st,no-autorepeat;
-
-                                       linux,keymap = <0x205006b
-                                                       0x4010074
-                                                       0x3050072
-                                                       0x1030004
-                                                       0x502006a
-                                                       0x500000a
-                                                       0x5008b
-                                                       0x706001c
-                                                       0x405000b
-                                                       0x6070003
-                                                       0x3040067
-                                                       0x303006c
-                                                       0x60400e7
-                                                       0x602009e
-                                                       0x4020073
-                                                       0x5050002
-                                                       0x4030069
-                                                       0x3020008>;
-                               };
-                       };
-               };
-
-               i2c@80110000 {
-                       bu21013_tp@5c {
-                               compatible = "rohm,bu21013_tp";
-                               reg = <0x5c>;
-                               touch-gpio = <&gpio2 20 0x4>;
-                               avdd-supply = <&ab8500_ldo_aux1_reg>;
-
-                               rohm,touch-max-x = <384>;
-                               rohm,touch-max-y = <704>;
-                               rohm,flip-y;
-                       };
-
-                       bu21013_tp@5d {
-                               compatible = "rohm,bu21013_tp";
-                               reg = <0x5d>;
-                               touch-gpio = <&gpio2 20 0x4>;
-                               avdd-supply = <&ab8500_ldo_aux1_reg>;
-
-                               rohm,touch-max-x = <384>;
-                               rohm,touch-max-y = <704>;
-                               rohm,flip-y;
-                       };
-               };
-       };
-};
index c32770a28acfe823bf898bf2cf7388f22779aadc..319cc6b509da8e29ee657730497d87f1215745a8 100644 (file)
                        reg = <0x01c20c90 0x10>;
                };
 
+               sid: eeprom@01c23800 {
+                       compatible = "allwinner,sun4i-sid";
+                       reg = <0x01c23800 0x10>;
+               };
+
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
index 3b4a0574f0689798b070e96970a33afeddd491df..52476742a1043e5e9703505d03b2eae5d2a5bc1a 100644 (file)
                        reg = <0x01c20c90 0x10>;
                };
 
+               sid: eeprom@01c23800 {
+                       compatible = "allwinner,sun4i-sid";
+                       reg = <0x01c23800 0x10>;
+               };
+
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
index f6091dc0936ce68e68b6a9ceac4f9d720b9a57fa..ce8ef2a45be098a35521db6d7fa41c472cd0b85a 100644 (file)
                        reg = <0x01c20c90 0x10>;
                };
 
+               sid: eeprom@01c23800 {
+                       compatible = "allwinner,sun4i-sid";
+                       reg = <0x01c23800 0x10>;
+               };
+
                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
index f244f5f02365161706b2442acdad508d3e9c17ec..c1751a64889a615612101613d63145b15903bfc7 100644 (file)
                apb2_gates: apb2_gates@01c2006c {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun6i-a31-apb2-gates-clk";
-                       reg = <0x01c2006c 0x8>;
+                       reg = <0x01c2006c 0x4>;
                        clocks = <&apb2>;
                        clock-output-names = "apb2_i2c0", "apb2_i2c1",
                                        "apb2_i2c2", "apb2_i2c3", "apb2_uart0",
index 15e625eca3122e5038d0da909602e330363d6dba..5c51cb8a98b01bb49b7c189474eef501f6c864b5 100644 (file)
                        pinctrl-0 = <&uart0_pins_a>;
                        status = "okay";
                };
+
+               i2c0: i2c@01c2ac00 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c0_pins_a>;
+                       status = "okay";
+               };
+
+               i2c1: i2c@01c2b000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c1_pins_a>;
+                       status = "okay";
+               };
        };
 
        leds {
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
new file mode 100644 (file)
index 0000000..8a1009d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 Oliver Schinagl
+ *
+ * Oliver Schinagl <oliver@schinagl.nl>
+ *
+ * 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/ "sun7i-a20.dtsi"
+
+/ {
+       model = "Cubietech Cubietruck";
+       compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
+
+       soc@01c00000 {
+               pinctrl@01c20800 {
+                       led_pins_cubietruck: led_pins@0 {
+                               allwinner,pins = "PH7", "PH11", "PH20", "PH21";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+               };
+
+               uart0: serial@01c28000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&uart0_pins_a>;
+                       status = "okay";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_cubietruck>;
+
+               blue {
+                       label = "cubietruck:blue:usr";
+                       gpios = <&pio 7 21 0>;
+               };
+
+               orange {
+                       label = "cubietruck:orange:usr";
+                       gpios = <&pio 7 20 0>;
+               };
+
+               white {
+                       label = "cubietruck:white:usr";
+                       gpios = <&pio 7 11 0>;
+               };
+
+               green {
+                       label = "cubietruck:green:usr";
+                       gpios = <&pio 7 7 0>;
+               };
+       };
+};
index 9e778557fadb4b17eac49c86bf78d4855e229dc4..ead3013f9aca9db6a3a5e73b0539ba3698139784 100644 (file)
                        pinctrl-0 = <&uart7_pins_a>;
                        status = "okay";
                };
+
+               i2c0: i2c@01c2ac00 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c0_pins_a>;
+                       status = "okay";
+               };
+
+               i2c1: i2c@01c2b000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c1_pins_a>;
+                       status = "okay";
+               };
+
+               i2c2: i2c@01c2b400 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c2_pins_a>;
+                       status = "okay";
+               };
        };
 
        leds {
index 80559cbdbc879106d21e6794814f6e767d1653c1..e46cfedde74c220b698c829458dfa40cef916159 100644 (file)
                                allwinner,pull = <0>;
                        };
 
+                       i2c0_pins_a: i2c0@0 {
+                               allwinner,pins = "PB0", "PB1";
+                               allwinner,function = "i2c0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       i2c1_pins_a: i2c1@0 {
+                               allwinner,pins = "PB18", "PB19";
+                               allwinner,function = "i2c1";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       i2c2_pins_a: i2c2@0 {
+                               allwinner,pins = "PB20", "PB21";
+                               allwinner,function = "i2c2";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
                        emac_pins_a: emac0@0 {
                                allwinner,pins = "PA0", "PA1", "PA2",
                                                "PA3", "PA4", "PA5", "PA6",
                        reg = <0x01c20c90 0x10>;
                };
 
+               sid: eeprom@01c23800 {
+                       compatible = "allwinner,sun7i-a20-sid";
+                       reg = <0x01c23800 0x200>;
+               };
+
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
                        status = "disabled";
                };
 
+               i2c0: i2c@01c2ac00 {
+                       compatible = "allwinner,sun4i-i2c";
+                       reg = <0x01c2ac00 0x400>;
+                       interrupts = <0 7 1>;
+                       clocks = <&apb1_gates 0>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@01c2b000 {
+                       compatible = "allwinner,sun4i-i2c";
+                       reg = <0x01c2b000 0x400>;
+                       interrupts = <0 8 1>;
+                       clocks = <&apb1_gates 1>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@01c2b400 {
+                       compatible = "allwinner,sun4i-i2c";
+                       reg = <0x01c2b400 0x400>;
+                       interrupts = <0 9 1>;
+                       clocks = <&apb1_gates 2>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@01c2b800 {
+                       compatible = "allwinner,sun4i-i2c";
+                       reg = <0x01c2b800 0x400>;
+                       interrupts = <0 88 1>;
+                       clocks = <&apb1_gates 3>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@01c2bc00 {
+                       compatible = "allwinner,sun4i-i2c";
+                       reg = <0x01c2bc00 0x400>;
+                       interrupts = <0 89 1>;
+                       clocks = <&apb1_gates 15>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@01c81000 {
                        compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
                        reg = <0x01c81000 0x1000>,
index 60230288884b663ae8a17a32d3e1bda66ba4125b..cb5ec23b03a71b59e8fac5f3df740f3eaa730f32 100644 (file)
@@ -1,5 +1,6 @@
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
 #include "tegra114.dtsi"
 
 / {
                        realtek,ldo1-en-gpios =
                                <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
                };
+
+               temperature-sensor@4c {
+                       compatible = "onnn,nct1008";
+                       reg = <0x4c>;
+                       vcc-supply = <&palmas_ldo6_reg>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = <TEGRA_GPIO(O, 4) IRQ_TYPE_LEVEL_LOW>;
+               };
        };
 
        i2c@7000d000 {
                                                regulator-max-microvolt = <1800000>;
                                        };
 
-                                       ldo6 {
+                                       palmas_ldo6_reg: ldo6 {
                                                regulator-name = "vdd-sensor-2v85";
                                                regulator-min-microvolt = <2850000>;
                                                regulator-max-microvolt = <2850000>;
                                interrupt-parent = <&palmas>;
                                interrupts = <8 0>;
                        };
+
+                       pinmux {
+                               compatible = "ti,tps65913-pinctrl";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&palmas_default>;
+
+                               palmas_default: pinmux {
+                                       pin_gpio6 {
+                                               pins = "gpio6";
+                                               function = "gpio";
+                                       };
+                               };
+                       };
                };
        };
 
                home {
                        label = "Home";
                        gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
-                       linux,code = <102>; /* KEY_HOME */
+                       linux,code = <KEY_HOME>;
                };
 
                power {
                        label = "Power";
                        gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
-                       linux,code = <116>; /* KEY_POWER */
+                       linux,code = <KEY_POWER>;
                        gpio-key,wakeup;
                };
 
                volume_down {
                        label = "Volume Down";
                        gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW>;
-                       linux,code = <114>; /* KEY_VOLUMEDOWN */
+                       linux,code = <KEY_VOLUMEDOWN>;
                };
 
                volume_up {
                        label = "Volume Up";
                        gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW>;
-                       linux,code = <115>; /* KEY_VOLUMEUP */
+                       linux,code = <KEY_VOLUMEUP>;
                };
        };
 
index 2905145d8e59a4ad9c5d3ff88bb6fcbb10593b2e..8d42787c8ff172a0b8594899b8ef92dd08d2be10 100644 (file)
 
        iommu {
                compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
-               reg = <0x7000f010 0x02c
-                      0x7000f1f0 0x010
-                      0x7000f228 0x074>;
+               reg = <0x70019010 0x02c
+                      0x700191f0 0x010
+                      0x70019228 0x074>;
                nvidia,#asids = <4>;
                dma-window = <0 0x40000000>;
                nvidia,swgroups = <0x18659fe>;
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
new file mode 100644 (file)
index 0000000..431d67a
--- /dev/null
@@ -0,0 +1,27 @@
+/dts-v1/;
+
+#include "tegra124.dtsi"
+
+/ {
+       model = "NVIDIA Tegra124 Venice2";
+       compatible = "nvidia,venice2", "nvidia,tegra124";
+
+       memory {
+               reg = <0x80000000 0x80000000>;
+       };
+
+       serial@70006000 {
+               status = "okay";
+       };
+
+       pmc@7000e400 {
+               nvidia,invert-interrupt;
+               nvidia,suspend-mode = <1>;
+               nvidia,cpu-pwr-good-time = <500>;
+               nvidia,cpu-pwr-off-time = <300>;
+               nvidia,core-pwr-good-time = <641 3845>;
+               nvidia,core-pwr-off-time = <61036>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
+       };
+};
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
new file mode 100644 (file)
index 0000000..b741300
--- /dev/null
@@ -0,0 +1,149 @@
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "nvidia,tegra124";
+       interrupt-parent = <&gic>;
+
+       gic: interrupt-controller@50041000 {
+               compatible = "arm,cortex-a15-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x50041000 0x1000>,
+                     <0x50042000 0x1000>,
+                     <0x50044000 0x2000>,
+                     <0x50046000 0x2000>;
+               interrupts = <GIC_PPI 9
+                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       timer@60005000 {
+               compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer";
+               reg = <0x60005000 0x400>;
+               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       gpio: gpio@6000d000 {
+               compatible = "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
+               reg = <0x6000d000 0x1000>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       /*
+        * There are two serial driver i.e. 8250 based simple serial
+        * driver and APB DMA based serial driver for higher baudrate
+        * and performace. To enable the 8250 based driver, the compatible
+        * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable
+        * the APB DMA based serial driver, the comptible is
+        * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart".
+        */
+       serial@70006000 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x70006000 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       serial@70006040 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x70006040 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       serial@70006200 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x70006200 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       serial@70006300 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x70006300 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       serial@70006400 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x70006400 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       rtc@7000e000 {
+               compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
+               reg = <0x7000e000 0x100>;
+               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       pmc@7000e400 {
+               compatible = "nvidia,tegra124-pmc";
+               reg = <0x7000e400 0x400>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <1>;
+               };
+
+               cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <2>;
+               };
+
+               cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <3>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <GIC_PPI 13
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+};
index e19dbf238e5c8498878dc56492018585190830ce..5ea7dfa4d9fa5de680ead80110b9c9ad31737490 100644 (file)
                        };
                };
 
-               nct1008 {
+               temperature-sensor@4c {
                        compatible = "onnn,nct1008";
                        reg = <0x4c>;
+                       vcc-supply = <&sys_3v3_reg>;
                        interrupt-parent = <&gpio>;
                        interrupts = <TEGRA_GPIO(CC, 2) IRQ_TYPE_LEVEL_LOW>;
                };
index 0022c127e1d956c42badc2970887fca3b9d7511b..2bd55cfd88adcb4d3e525ae45ea471a6376a8e34 100644 (file)
                gr3d {
                        compatible = "nvidia,tegra30-gr3d";
                        reg = <0x54180000 0x00040000>;
-                       clocks = <&tegra_car 24 &tegra_car 98>;
+                       clocks = <&tegra_car TEGRA30_CLK_GR3D
+                                 &tegra_car TEGRA30_CLK_GR3D2>;
                        clock-names = "3d", "3d2";
                };
 
                dc@54200000 {
-                       compatible = "nvidia,tegra30-dc";
+                       compatible = "nvidia,tegra30-dc", "nvidia,tegra20-dc";
                        reg = <0x54200000 0x00040000>;
                        interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&tegra_car TEGRA30_CLK_DISP1>,
index ae6a17aed9ee224c85498b2bc6b1e0fa43e75e56..fb1b2ec8eaa99f4b366ccb29a5ed28f78a109571 100644 (file)
                compatible = "ti,twl4030-wdt";
        };
 
+       vaux1: regulator-vaux1 {
+               compatible = "ti,twl4030-vaux1";
+       };
+
+       vaux2: regulator-vaux2 {
+               compatible = "ti,twl4030-vaux2";
+       };
+
+       vaux3: regulator-vaux3 {
+               compatible = "ti,twl4030-vaux3";
+       };
+
+       vaux4: regulator-vaux4 {
+               compatible = "ti,twl4030-vaux4";
+       };
+
        vcc: regulator-vdd1 {
                compatible = "ti,twl4030-vdd1";
                regulator-min-microvolt = <600000>;
                regulator-max-microvolt = <1800000>;
        };
 
-       vpll2: regulator-vpll2 {
-               compatible = "ti,twl4030-vpll2";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
+       vio: regulator-vio {
+               compatible = "ti,twl4030-vio";
+       };
+
+       vintana1: regulator-vintana1 {
+               compatible = "ti,twl4030-vintana1";
+       };
+
+       vintana2: regulator-vintana2 {
+               compatible = "ti,twl4030-vintana2";
+       };
+
+       vintdig: regulator-vintdig {
+               compatible = "ti,twl4030-vintdig";
        };
 
        vmmc1: regulator-vmmc1 {
                compatible = "ti,twl4030-vusb3v1";
        };
 
+       vpll1: regulator-vpll1 {
+               compatible = "ti,twl4030-vpll1";
+       };
+
+       vpll2: regulator-vpll2 {
+               compatible = "ti,twl4030-vpll2";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
        vsim: regulator-vsim {
                compatible = "ti,twl4030-vsim";
                regulator-min-microvolt = <1800000>;
                usb1v8-supply = <&vusb1v8>;
                usb3v1-supply = <&vusb3v1>;
                usb_mode = <1>;
+               #phy-cells = <0>;
        };
 
        twl_pwm: pwm {
                compatible = "ti,twl4030-pwmled";
                #pwm-cells = <2>;
        };
+
+       twl_pwrbutton: pwrbutton {
+               compatible = "ti,twl4030-pwrbutton";
+               interrupts = <8>;
+       };
 };
diff --git a/arch/arm/boot/dts/twl6030_omap4.dtsi b/arch/arm/boot/dts/twl6030_omap4.dtsi
new file mode 100644 (file)
index 0000000..a4fa570
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ */
+
+&twl {
+       /*
+        * On most OMAP4 platforms, the twl6030 IRQ line is connected
+        * to the SYS_NIRQ1 line on OMAP and the twl6030 MSECURE line is
+        * connected to the fref_clk0_out.sys_drm_msecure line.
+        * Therefore, configure the defaults for the SYS_NIRQ1 and
+        * fref_clk0_out.sys_drm_msecure pins here.
+        */
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               &twl6030_pins
+               &twl6030_wkup_pins
+       >;
+};
+
+&omap4_pmx_wkup {
+       twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
+               pinctrl-single,pins = <
+                       0x14 (PIN_OUTPUT | MUX_MODE2)           /* fref_clk0_out.sys_drm_msecure */
+               >;
+       };
+};
+
+&omap4_pmx_core {
+       twl6030_pins: pinmux_twl6030_pins {
+               pinctrl-single,pins = <
+                       0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)        /* sys_nirq1.sys_nirq1 */
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/vf610-cosmic.dts b/arch/arm/boot/dts/vf610-cosmic.dts
new file mode 100644 (file)
index 0000000..c42e4f9
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013 Linaro Limited
+ *
+ * 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 "vf610.dtsi"
+
+/ {
+       model = "PHYTEC Cosmic/Cosmic+ Board";
+       compatible = "phytec,vf610-cosmic", "fsl,vf610";
+
+       chosen {
+               bootargs = "console=ttyLP1,115200";
+       };
+
+       memory {
+               reg = <0x80000000 0x10000000>;
+       };
+
+       clocks {
+               enet_ext {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <50000000>;
+               };
+       };
+
+};
+
+&fec1 {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1_1>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1_1>;
+       status = "okay";
+};
index 1a58678b93fa613c9de5524026f5777408c7dd05..c8047ca16501324aaed37981ab133c0207d682f7 100644 (file)
 
 };
 
+&dspi0 {
+       bus-num = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dspi0_1>;
+       status = "okay";
+
+       sflash: at26df081a@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "atmel,at26df081a";
+               spi-max-frequency = <16000000>;
+               spi-cpol;
+               spi-cpha;
+               reg = <0>;
+       };
+};
+
 &fec0 {
        phy-mode = "rmii";
        pinctrl-names = "default";
index 67d929cf98045235a1a39eeeb7c884c2b2bccddc..d31ce1b4a7b08df9dab864e633afe665a2400a59 100644 (file)
                                status = "disabled";
                        };
 
+                       dspi0: dspi0@4002c000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,vf610-dspi";
+                               reg = <0x4002c000 0x1000>;
+                               interrupts = <0 67 0x04>;
+                               clocks = <&clks VF610_CLK_DSPI0>;
+                               clock-names = "dspi";
+                               spi-num-chipselects = <5>;
+                               status = "disabled";
+                       };
+
                        sai2: sai@40031000 {
                                compatible = "fsl,vf610-sai";
                                reg = <0x40031000 0x1000>;
index 8c60f473e97625cb8c0bb068375da7368d1ff6fe..eaa9cf4705a7179dcb7221aa5f2a29a6c1883b78 100644 (file)
@@ -6,7 +6,6 @@ obj-y                           += firmware.o
 
 obj-$(CONFIG_ICST)             += icst.o
 obj-$(CONFIG_SA1111)           += sa1111.o
-obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
 obj-$(CONFIG_DMABOUNCE)                += dmabounce.o
 obj-$(CONFIG_SHARP_LOCOMO)     += locomo.o
 obj-$(CONFIG_SHARP_PARAM)      += sharpsl_param.o
diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
deleted file mode 100644 (file)
index 6cb362e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-
-
-#include <asm/mach/pci.h>
-
-#define MAX_SLOTS              7
-
-#define CONFIG_CMD(bus, devfn, where)   (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
-
-static int
-via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-                     int size, u32 *value)
-{
-       outl(CONFIG_CMD(bus,devfn,where),0xCF8);
-       switch (size) {
-       case 1:
-               *value=inb(0xCFC + (where&3));
-               break;
-       case 2:
-               *value=inw(0xCFC + (where&2));
-               break;
-       case 4:
-               *value=inl(0xCFC);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-                      int size, u32 value)
-{
-       outl(CONFIG_CMD(bus,devfn,where),0xCF8);
-       switch (size) {
-       case 1:
-               outb(value, 0xCFC + (where&3));
-               break;
-       case 2:
-               outw(value, 0xCFC + (where&2));
-               break;
-       case 4:
-               outl(value, 0xCFC);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops via82c505_ops = {
-       .read   = via82c505_read_config,
-       .write  = via82c505_write_config,
-};
-
-void __init via82c505_preinit(void)
-{
-       printk(KERN_DEBUG "PCI: VIA 82c505\n");
-       if (!request_region(0xA8,2,"via config")) {
-               printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
-               return;
-       }
-       if (!request_region(0xCF8,8,"pci config")) {
-               printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
-               release_region(0xA8, 2);
-               return;
-       }
-
-       /* Enable compatible Mode */
-       outb(0x96,0xA8);
-       outb(0x18,0xA9);
-       outb(0x93,0xA8);
-       outb(0xd0,0xA9);
-
-}
-
-int __init via82c505_setup(int nr, struct pci_sys_data *sys)
-{
-       return (nr == 0);
-}
index 6e4931097dd4de1896227e26095e25bfa3e2750d..287ac1d7aac75563ebf86197e5a26bbccdf50562 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
@@ -25,10 +24,9 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
 CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_MOBILE=y
 CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_ERRATA_743622=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
@@ -50,7 +48,6 @@ CONFIG_UNIX_DIAG=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
-CONFIG_ARPD=y
 CONFIG_SYN_COOKIES=y
 CONFIG_TCP_MD5SIG=y
 CONFIG_IPV6=y
@@ -95,7 +92,6 @@ CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_TEST=y
 CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_BCM_KONA=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
@@ -117,12 +113,12 @@ CONFIG_CONFIGFS_FS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110
 CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
-CONFIG_DEBUG_INFO=y
 # CONFIG_FTRACE is not set
 CONFIG_CRC_CCITT=y
 CONFIG_CRC_T10DIF=y
index e7e94948d19478729aeb60a8167c6a7cf2a8e7a7..b38cd107f82dfe5b1efffb4075e04fc39f9f41c5 100644 (file)
@@ -91,6 +91,10 @@ CONFIG_VIDEO_RCAR_VIN=y
 CONFIG_VIDEO_ML86V7667=y
 CONFIG_SPI=y
 CONFIG_SPI_SH_HSPI=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_RCAR=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
index 806005a4c4c15cdeac19cbc6802494df0ff4e982..6ac5ea73bd0a6852082187e38e6b02d4efdb9a59 100644 (file)
@@ -1,15 +1,14 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_EXPERT=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_EP93XX=y
 CONFIG_CRUNCH=y
@@ -47,11 +46,8 @@ CONFIG_IPV6=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
@@ -67,15 +63,14 @@ CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_EP93XX_ETH=y
 CONFIG_USB_RTL8150=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_AMBA_PL010=y
 CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -86,9 +81,9 @@ CONFIG_WATCHDOG=y
 CONFIG_EP93XX_WATCHDOG=y
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DYNAMIC_MINORS=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_SERIAL=y
 CONFIG_USB_SERIAL_CONSOLE=y
@@ -100,24 +95,18 @@ CONFIG_RTC_DRV_EP93XX=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SLAB=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_LIBCRC32C=y
index 5d488c24b13287303bebaa2ddbda22fe9b898f40..8d0c5a018ed72b720f0b235be8dff2ee9bf1e77a 100644 (file)
@@ -132,7 +132,6 @@ CONFIG_TOUCHSCREEN_MC13783=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MMA8450=y
 CONFIG_SERIO_SERPORT=m
-CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_IMX=y
@@ -188,22 +187,33 @@ CONFIG_SND_SOC_PHYCORE_AC97=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
 CONFIG_SND_SOC_IMX_WM8962=y
 CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_SPDIF=y
 CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_PHY=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_INTF_DEV_UIE_EMUL=y
 CONFIG_RTC_DRV_MC13XXX=y
@@ -246,7 +256,6 @@ CONFIG_UDF_FS=m
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=m
 CONFIG_JFFS2_FS=y
 CONFIG_UBIFS_FS=y
 CONFIG_NFS_FS=y
@@ -261,6 +270,7 @@ CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_UTF8=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
+CONFIG_PROVE_LOCKING=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FTRACE is not set
 # CONFIG_ARM_UNWIND is not set
index a8314c3ee84d554b3cbecb3fbb9b1cc4dd450c9a..5bae1955759125f954284ccf67b62e7dace5ba49 100644 (file)
@@ -1,15 +1,17 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
-CONFIG_TINY_RCU=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_INTEGRATOR=y
 CONFIG_ARCH_INTEGRATOR_AP=y
 CONFIG_ARCH_INTEGRATOR_CP=y
+CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_ARM922T=y
@@ -18,12 +20,9 @@ CONFIG_CPU_ARM1020=y
 CONFIG_CPU_ARM1022=y
 CONFIG_CPU_ARM1026=y
 CONFIG_PCI=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
+# CONFIG_ATAGS is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp"
@@ -44,24 +43,20 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_PHYSMAP=y
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
 CONFIG_E100=y
 CONFIG_SMC91X=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_AMBA_PL010=y
-CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
 CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_ARMCLCD=y
@@ -71,19 +66,23 @@ CONFIG_FB_MATROX_MYSTIQUE=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL030=y
+CONFIG_COMMON_CLK_DEBUG=y
 CONFIG_EXT2_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_MAGIC_SYSRQ=y
index 1f36b823905f1d6e1c16eeb9e0554efc1678bcf0..9943e5da74f18c8ffe89168829eb3326d0de1b47 100644 (file)
@@ -123,7 +123,9 @@ CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
 CONFIG_SPI=y
+CONFIG_SPI_DAVINCI=y
 CONFIG_SPI_SPIDEV=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
diff --git a/arch/arm/configs/koelsch_defconfig b/arch/arm/configs/koelsch_defconfig
new file mode 100644 (file)
index 0000000..825c16d
--- /dev/null
@@ -0,0 +1,54 @@
+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_BLOCK is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_R8A7791=y
+CONFIG_MACH_KOELSCH=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_CPU_BPREDICT_DISABLE=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_NR_CPUS=8
+CONFIG_AEABI=y
+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_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=20
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_RCAR_THERMAL=y
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_ARM_UNWIND is not set
index e777ef22b8016559a71ef6ac4d59dec9eb29918b..35bff5e0d57a26b799e4554497859dcf1f029e9b 100644 (file)
@@ -89,6 +89,8 @@ 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
index 000e9205b2b93ca0aed76dbcbf60f6eb815524b6..5cc6360340b1c683dfe5b31c15a54c61e457963a 100644 (file)
@@ -92,6 +92,8 @@ CONFIG_SOC_CAMERA=y
 CONFIG_VIDEO_RCAR_VIN=y
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=y
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=y
 CONFIG_USB=y
 CONFIG_USB_RCAR_PHY=y
 CONFIG_MMC=y
index 119fc378fc520f8ae5cb9074686570b6436bcd93..4a5903e048272429bf58d753419bddda18d2f586 100644 (file)
@@ -6,6 +6,7 @@ CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_MOBILE=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_ARCH_HIGHBANK=y
 CONFIG_ARCH_KEYSTONE=y
index 4555c025629a770c6f4b7a8fe2d97208b167fb7f..6150108e15de8526828e07272e44be49d0d938ca 100644 (file)
@@ -76,7 +76,6 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_TSC2007=m
 # CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
 CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
@@ -91,7 +90,6 @@ CONFIG_I2C_MXS=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=m
 CONFIG_SPI_MXS=y
-CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -115,9 +113,12 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_PHY=y
 CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
 CONFIG_MMC=y
 CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_MXS=y
index 254cf0539439b0ab87bb44dcd62e2d24c8120f0c..98a50c309b90ad72b710fdeddc4117208fa6c29c 100644 (file)
@@ -1,14 +1,13 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
@@ -20,22 +19,21 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_MULTI_V6=y
-CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX_DEBUG=y
 CONFIG_ARCH_OMAP2=y
 CONFIG_ARCH_OMAP3=y
 CONFIG_ARCH_OMAP4=y
+CONFIG_SOC_OMAP5=y
 CONFIG_SOC_AM33XX=y
-CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_ARCH_VEXPRESS_CA9X4=y
+CONFIG_SOC_DRA7XX=y
 CONFIG_ARM_THUMBEE=y
 CONFIG_ARM_ERRATA_411920=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
-CONFIG_LEDS=y
+CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
@@ -61,8 +59,6 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
 CONFIG_CAN=m
-CONFIG_CAN_RAW=m
-CONFIG_CAN_BCM=m
 CONFIG_CAN_C_CAN=m
 CONFIG_CAN_C_CAN_PLATFORM=m
 CONFIG_BT=m
@@ -77,14 +73,13 @@ CONFIG_MAC80211=m
 CONFIG_MAC80211_RC_PID=y
 CONFIG_MAC80211_RC_DEFAULT_PID=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CMA=y
-CONFIG_DMA_CMA=y
-CONFIG_CONNECTOR=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_OMAP_OCP2SCP=y
+CONFIG_CONNECTOR=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_OOPS=y
 CONFIG_MTD_CFI=y
@@ -98,32 +93,40 @@ CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_SENSORS_LIS3LV02D=m
 CONFIG_SENSORS_TSL2550=m
-CONFIG_SENSORS_LIS3_I2C=m
 CONFIG_BMP085_I2C=m
+CONFIG_SENSORS_LIS3_I2C=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_MD=y
 CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_SMSC911X=y
 CONFIG_KS8851=y
 CONFIG_KS8851_MLL=y
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_SDIO=m
-CONFIG_LIBERTAS_DEBUG=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_TI_CPSW=y
+CONFIG_AT803X_PHY=y
+CONFIG_SMSC_PHY=y
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC95XX=y
 CONFIG_USB_ALI_M5632=y
 CONFIG_USB_AN2720=y
 CONFIG_USB_EPSON2888=y
 CONFIG_USB_KC2190=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_DEBUG=y
+CONFIG_WL_TI=y
+CONFIG_WL12XX=m
+CONFIG_WL18XX=m
+CONFIG_WLCORE_SPI=m
+CONFIG_WLCORE_SDIO=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
 CONFIG_INPUT_JOYDEV=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
@@ -133,7 +136,6 @@ CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_TWL4030_PWRBUTTON=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
@@ -143,8 +145,7 @@ CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_OMAP=y
 CONFIG_SERIAL_OMAP_CONSOLE=y
 CONFIG_HW_RANDOM=y
@@ -158,31 +159,31 @@ CONFIG_GPIO_TWL4030=y
 CONFIG_W1=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_LM75=m
-CONFIG_WATCHDOG=y
 CONFIG_THERMAL=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
 CONFIG_THERMAL_GOV_FAIR_SHARE=y
-CONFIG_THERMAL_GOV_STEP_WISE=y
 CONFIG_THERMAL_GOV_USER_SPACE=y
-CONFIG_CPU_THERMAL=y
+CONFIG_TI_SOC_THERMAL=y
+CONFIG_OMAP4_THERMAL=y
+CONFIG_OMAP5_THERMAL=y
+CONFIG_DRA752_THERMAL=y
+CONFIG_WATCHDOG=y
 CONFIG_OMAP_WATCHDOG=y
 CONFIG_TWL4030_WATCHDOG=y
+CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65217=y
 CONFIG_MFD_TPS65910=y
 CONFIG_TWL6040_CORE=y
-CONFIG_REGULATOR_TWL4030=y
+CONFIG_REGULATOR_PALMAS=y
 CONFIG_REGULATOR_TPS65023=y
 CONFIG_REGULATOR_TPS6507X=y
 CONFIG_REGULATOR_TPS65217=y
 CONFIG_REGULATOR_TPS65910=y
+CONFIG_REGULATOR_TWL4030=y
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
-CONFIG_FB_OMAP_LCD_VGA=y
 CONFIG_OMAP2_DSS=m
-CONFIG_OMAP2_DSS_RFBI=y
 CONFIG_OMAP2_DSS_SDI=y
 CONFIG_OMAP2_DSS_DSI=y
 CONFIG_FB_OMAP2=m
@@ -194,12 +195,8 @@ CONFIG_DISPLAY_PANEL_DPI=m
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_PLATFORM=y
-CONFIG_DISPLAY_SUPPORT=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_SND=m
@@ -216,14 +213,14 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_WDM=y
 CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_DWC3=m
 CONFIG_USB_TEST=y
-CONFIG_USB_PHY=y
 CONFIG_NOP_USB_XCEIV=y
+CONFIG_OMAP_USB2=y
+CONFIG_OMAP_USB3=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
@@ -232,7 +229,6 @@ CONFIG_USB_ZERO=m
 CONFIG_MMC=y
 CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_SDIO_UART=y
-CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_OMAP=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NEW_LEDS=y
@@ -252,11 +248,8 @@ CONFIG_RTC_DRV_OMAP=y
 CONFIG_DMADEVICES=y
 CONFIG_TI_EDMA=y
 CONFIG_DMA_OMAP=y
-CONFIG_TI_SOC_THERMAL=y
-CONFIG_TI_THERMAL=y
-CONFIG_OMAP4_THERMAL=y
-CONFIG_OMAP5_THERMAL=y
-CONFIG_DRA752_THERMAL=y
+CONFIG_EXTCON=y
+CONFIG_EXTCON_PALMAS=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
@@ -275,23 +268,18 @@ CONFIG_JFFS2_RUBIN=y
 CONFIG_UBIFS_FS=y
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_PROVE_LOCKING=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SECURITY=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
@@ -300,9 +288,6 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=y
 CONFIG_CRC7=y
 CONFIG_LIBCRC32C=y
-CONFIG_SOC_OMAP5=y
-CONFIG_TI_DAVINCI_MDIO=y
-CONFIG_TI_DAVINCI_CPDMA=y
-CONFIG_TI_CPSW=y
-CONFIG_AT803X_PHY=y
-CONFIG_SOC_DRA7XX=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig
deleted file mode 100644 (file)
index e319b2c..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_SHARK=y
-CONFIG_LEDS=y
-CONFIG_LEDS_TIMER=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=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_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_STANDALONE is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
-CONFIG_CS89x0=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_PRINTER=m
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_CYBER2000=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=m
-CONFIG_SOUND_PRIME=m
-CONFIG_SOUND_OSS=m
-CONFIG_SOUND_SB=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_CMOS=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFSD=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ISO8859_1=m
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
new file mode 100644 (file)
index 0000000..d57a85b
--- /dev/null
@@ -0,0 +1,61 @@
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SMP=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_NETDEVICES=y
+CONFIG_SUN4I_EMAC=y
+# 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_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_8250_DW=y
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SUNXI_WATCHDOG=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_COMMON_CLK_DEBUG=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_NLS=y
index ea042e80e54d7c694a4486f95cbca565713ad181..4934295bb4f0905df99d302e4bd11eef2f4a659c 100644 (file)
@@ -27,6 +27,7 @@ CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_2x_SOC=y
 CONFIG_ARCH_TEGRA_3x_SOC=y
 CONFIG_ARCH_TEGRA_114_SOC=y
+CONFIG_ARCH_TEGRA_124_SOC=y
 CONFIG_TEGRA_EMC_SCALING_ENABLE=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
@@ -41,9 +42,11 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_KEXEC=y
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
+CONFIG_NEON=y
 CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -129,6 +132,7 @@ CONFIG_SPI=y
 CONFIG_SPI_TEGRA114=y
 CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
+CONFIG_PINCTRL_PALMAS=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_GPIO_TPS6586X=y
@@ -223,6 +227,7 @@ CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
+CONFIG_COMMON_CLK_DEBUG=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_MEMORY=y
index a0025dc13021af11af524e08e8466c826f802a4a..ac632cc38f249767bcedfc1232a4e4b8e6bc70d9 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_HIGHMEM=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
@@ -16,6 +15,9 @@ CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
@@ -68,8 +70,8 @@ CONFIG_CPU_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_TC3589X=y
-CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
@@ -78,10 +80,8 @@ CONFIG_SND_SOC_UX500_MACH_MOP500=y
 CONFIG_USB=y
 CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_MUSB_UX500=y
-CONFIG_USB_PHY=y
 CONFIG_AB8500_USB=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
 CONFIG_USB_ETH=m
 CONFIG_MMC=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -116,12 +116,12 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_INFO=y
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_DEV_UX500=y
index f2de51f0bd187630c3ae0c43a6bda4c11321648d..f489fdaa19b8ff127944d6bde8a7e0fa806848c4 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_IKCONFIG=y
@@ -8,11 +7,9 @@ CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 # CONFIG_UTS_NS is not set
 # CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
 # CONFIG_PID_NS is not set
 # CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_MODULES=y
@@ -23,14 +20,22 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_VEXPRESS_CA9X4=y
+CONFIG_ARCH_VEXPRESS_DCSCB=y
+CONFIG_ARCH_VEXPRESS_TC2_PM=y
 # CONFIG_SWP_EMULATE is not set
 CONFIG_SMP=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_MCPM=y
 CONFIG_VMSPLIT_2G=y
-CONFIG_HOTPLUG_CPU=y
+CONFIG_NR_CPUS=8
+CONFIG_ARM_PSCI=y
 CONFIG_AEABI=y
+CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
+CONFIG_CMDLINE="console=ttyAMA0"
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -44,37 +49,46 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_LRO is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_ARM_INTEGRATOR=y
-CONFIG_MISC_DEVICES=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_UBI=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_VIRTIO_BLK=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_SCSI_VIRTIO=y
 CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_VIRTIO_NET=y
+CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+CONFIG_I2C=y
+CONFIG_I2C_VERSATILE=y
+CONFIG_SENSORS_VEXPRESS=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_VEXPRESS=y
 CONFIG_FB=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -103,38 +117,45 @@ CONFIG_HID_THRUSTMASTER=y
 CONFIG_HID_ZEROPLUS=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-# CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_MON=y
 CONFIG_USB_ISP1760_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL031=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
 CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_9P_FS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_SCHED_DEBUG is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
index 454d642a407017e879f1e23a54d82ed6bf0faf7b..7fc42784becbf2ee4e4779d06b9345be6c8ccf06 100644 (file)
@@ -106,8 +106,4 @@ extern int dc21285_setup(int nr, struct pci_sys_data *);
 extern void dc21285_preinit(void);
 extern void dc21285_postinit(void);
 
-extern struct pci_ops via82c505_ops;
-extern int via82c505_setup(int nr, struct pci_sys_data *);
-extern void via82c505_init(void *sysdata);
-
 #endif /* __ASM_MACH_PCI_H */
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
deleted file mode 100644 (file)
index 2389b71..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* You shouldn't include this file. Use linux/sched_clock.h instead.
- * Temporary file until all asm/sched_clock.h users are gone
- */
-#include <linux/sched_clock.h>
diff --git a/arch/arm/include/debug/vf.S b/arch/arm/include/debug/vf.S
new file mode 100644 (file)
index 0000000..ba12cc4
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ */
+
+       .macro  addruart, rp, rv, tmp
+       ldr     \rp, =0x40028000        @ physical
+       ldr     \rv, =0xfe028000        @ virtual
+       .endm
+
+       .macro  senduart, rd, rx
+       strb    \rd, [\rx, #0x7]        @ Data Register
+       .endm
+
+       .macro  busyuart, rd, rx
+1001:  ldrb    \rd, [\rx, #0x4]        @ Status Register 1
+       tst     \rd, #1 << 6            @ TC
+       beq     1001b                   @ wait until transmit done
+       .endm
+
+       .macro  waituart,rd,rx
+       .endm
index 70ded3fb42d9887c71293755aff8354784220d64..570a48cc3d64b1714bd711c4b4cc4a6d1ab1358c 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/irqchip/arm-gic.h>
 #include <linux/smp.h>
 #include <linux/of.h>
 
index 98aee3258398663b1147e38372215c8fbfe8267e..829a96d4a179337019f1790ab2e50577f8cc3524 100644 (file)
  *  This file contains the ARM-specific time handling details:
  *  reading the RTC at bootup, etc...
  */
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/errno.h>
 #include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/profile.h>
 #include <linux/sched.h>
+#include <linux/sched_clock.h>
 #include <linux/smp.h>
+#include <linux/time.h>
 #include <linux/timex.h>
-#include <linux/errno.h>
-#include <linux/profile.h>
 #include <linux/timer.h>
-#include <linux/clocksource.h>
-#include <linux/irq.h>
-#include <linux/sched_clock.h>
 
-#include <asm/thread_info.h>
-#include <asm/stacktrace.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
+#include <asm/stacktrace.h>
+#include <asm/thread_info.h>
 
 #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \
     defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE)
@@ -116,8 +117,12 @@ int __init register_persistent_clock(clock_access_fn read_boot,
 
 void __init time_init(void)
 {
-       if (machine_desc->init_time)
+       if (machine_desc->init_time) {
                machine_desc->init_time();
-       else
+       } else {
+#ifdef CONFIG_COMMON_CLK
+               of_clk_init(NULL);
+#endif
                clocksource_of_init();
+       }
 }
index bd454b09133e38274d6af8fbe6ba2a36fab7dab7..47d7338561de3c93c19a1345226e7078f779b6c6 100644 (file)
@@ -41,7 +41,6 @@ else
 endif
 
 lib-$(CONFIG_ARCH_RPC)         += ecard.o io-acorn.o floppydma.o
-lib-$(CONFIG_ARCH_SHARK)       += io-shark.o
 
 $(obj)/csumpartialcopy.o:      $(obj)/csumpartialcopygeneric.S
 $(obj)/csumpartialcopyuser.o:  $(obj)/csumpartialcopygeneric.S
diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c
deleted file mode 100644 (file)
index 8242539..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- *  linux/arch/arm/lib/io-shark.c
- *
- *  by Alexander Schulz
- *
- * derived from:
- * linux/arch/arm/lib/io-ebsa.S
- * Copyright (C) 1995, 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
index c7d670d118025eaf71a4dd145d0d3a33d300a415..2d895a297739d85d4302ec8e9ec2e01cfb4f1c69 100644 (file)
@@ -169,6 +169,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk),
        CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk),
        CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc_clk),
+       CLKDEV_CON_DEV_ID(NULL, "f0010000.ssc", &ssc_clk),
        CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk),
        CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
        CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
index ade948b8266272d9ee1cadf85e713a4e5d1632c1..112e867c4abea764f19cb0470ba253f6e00585d2 100644 (file)
@@ -112,7 +112,7 @@ static struct spi_board_info cam60_spi_devices[] __initdata = {
 /*
  * MACB Ethernet device
  */
-static struct __initdata macb_platform_data cam60_macb_data = {
+static struct macb_platform_data cam60_macb_data __initdata = {
        .phy_irq_pin    = AT91_PIN_PB5,
        .is_rmii        = 0,
 };
index 3fcb6623a33edcaa66d94de8c9832dab28392e9d..3a185faee795b589725bffd222e2299eac5cffc3 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
-#include <linux/of_platform.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -36,11 +35,6 @@ static void __init at91rm9200_dt_init_irq(void)
        of_irq_init(irq_of_match);
 }
 
-static void __init at91rm9200_dt_device_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
 static const char *at91rm9200_dt_board_compat[] __initdata = {
        "atmel,at91rm9200",
        NULL
@@ -52,6 +46,5 @@ DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
        .handle_irq     = at91_aic_handle_irq,
        .init_early     = at91rm9200_dt_initialize,
        .init_irq       = at91rm9200_dt_init_irq,
-       .init_machine   = at91rm9200_dt_device_init,
        .dt_compat      = at91rm9200_dt_board_compat,
 MACHINE_END
index 8db30132abed165dc0c52737895789e532ee24a1..3dab868b02fad864fbc2ee537c7b846d563889b4 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
-#include <linux/of_platform.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -37,11 +36,6 @@ static void __init at91_dt_init_irq(void)
        of_irq_init(irq_of_match);
 }
 
-static void __init at91_dt_device_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
 static const char *at91_dt_board_compat[] __initdata = {
        "atmel,at91sam9",
        NULL
@@ -54,6 +48,5 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
        .handle_irq     = at91_aic_handle_irq,
        .init_early     = at91_dt_initialize,
        .init_irq       = at91_dt_init_irq,
-       .init_machine   = at91_dt_device_init,
        .dt_compat      = at91_dt_board_compat,
 MACHINE_END
index 048a57f76bd3bbbac837e543cd4a4a7048b5e3e0..c287307b9a3ba1a3efcd7b0c09605fef8c4c00e7 100644 (file)
 #define AT91_ADC_IER           0x24            /* Interrupt Enable Register */
 #define AT91_ADC_IDR           0x28            /* Interrupt Disable Register */
 #define AT91_ADC_IMR           0x2C            /* Interrupt Mask Register */
+#define                AT91_ADC_IER_PEN        (1 << 29)
+#define                AT91_ADC_IER_NOPEN      (1 << 30)
+#define                AT91_ADC_IER_XRDY       (1 << 20)
+#define                AT91_ADC_IER_YRDY       (1 << 21)
+#define                AT91_ADC_IER_PRDY       (1 << 22)
+#define                AT91_ADC_ISR_PENS       (1 << 31)
 
 #define AT91_ADC_CHR(n)                (0x30 + ((n) * 4))      /* Channel Data Register N */
 #define                AT91_ADC_DATA           (0x3ff)
 
 #define AT91_ADC_CDR0_9X5      (0x50)                  /* Channel Data Register 0 for 9X5 */
 
+#define AT91_ADC_ACR           0x94    /* Analog Control Register */
+#define                AT91_ADC_ACR_PENDETSENS (0x3 << 0)      /* pull-up resistor */
+
+#define AT91_ADC_TSMR          0xB0
+#define                AT91_ADC_TSMR_TSMODE    (3 << 0)        /* Touch Screen Mode */
+#define                        AT91_ADC_TSMR_TSMODE_NONE               (0 << 0)
+#define                        AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS     (1 << 0)
+#define                        AT91_ADC_TSMR_TSMODE_4WIRE_PRESS        (2 << 0)
+#define                        AT91_ADC_TSMR_TSMODE_5WIRE              (3 << 0)
+#define                AT91_ADC_TSMR_TSAV      (3 << 4)        /* Averages samples */
+#define                        AT91_ADC_TSMR_TSAV_(x)          ((x) << 4)
+#define                AT91_ADC_TSMR_SCTIM     (0x0f << 16)    /* Switch closure time */
+#define                AT91_ADC_TSMR_PENDBC    (0x0f << 28)    /* Pen Debounce time */
+#define                        AT91_ADC_TSMR_PENDBC_(x)        ((x) << 28)
+#define                AT91_ADC_TSMR_NOTSDMA   (1 << 22)       /* No Touchscreen DMA */
+#define                AT91_ADC_TSMR_PENDET_DIS        (0 << 24)       /* Pen contact detection disable */
+#define                AT91_ADC_TSMR_PENDET_ENA        (1 << 24)       /* Pen contact detection enable */
+
+#define AT91_ADC_TSXPOSR       0xB4
+#define AT91_ADC_TSYPOSR       0xB8
+#define AT91_ADC_TSPRESSR      0xBC
+
 #define AT91_ADC_TRGR_9260     AT91_ADC_MR
 #define AT91_ADC_TRGR_9G45     0x08
 #define AT91_ADC_TRGR_9X5      0xC0
 
+/* Trigger Register bit field */
+#define                AT91_ADC_TRGR_TRGPER    (0xffff << 16)
+#define                        AT91_ADC_TRGR_TRGPER_(x)        ((x) << 16)
+#define                AT91_ADC_TRGR_TRGMOD    (0x7 << 0)
+#define                        AT91_ADC_TRGR_MOD_PERIOD_TRIG   (5 << 0)
+
 #endif
index 69d67f714a2fc662901d15aa68b8530c32a2d9d4..9fe6d88737edebc51c66ffad7f02e7c7a42047ce 100644 (file)
@@ -1,5 +1,16 @@
 config ARCH_BCM
-       bool "Broadcom SoC" if ARCH_MULTI_V7
+       bool "Broadcom SoC Support"
+       depends on ARCH_MULTIPLATFORM
+       help
+         This enables support for Broadcom ARM based SoC
+          chips
+
+if ARCH_BCM
+
+menu "Broadcom SoC Selection"
+
+config ARCH_BCM_MOBILE
+       bool "Broadcom Mobile SoC" if ARCH_MULTI_V7
        depends on MMU
        select ARCH_REQUIRE_GPIOLIB
        select ARM_ERRATA_754322
@@ -9,12 +20,17 @@ config ARCH_BCM
        select CLKSRC_OF
        select GENERIC_CLOCKEVENTS
        select GENERIC_TIME
-       select GPIO_BCM
+       select GPIO_BCM_KONA
        select SPARSE_IRQ
        select TICK_ONESHOT
        select CACHE_L2X0
+       select HAVE_ARM_ARCH_TIMER
        help
-         This enables support for system based on Broadcom SoCs.
+         This enables support for systems based on Broadcom mobile SoCs.
          It currently supports the 'BCM281XX' family, which includes
          BCM11130, BCM11140, BCM11351, BCM28145 and
          BCM28155 variants.
+
+endmenu
+
+endif
index e3d03033a7e2749c30eb5f18e28ec45adf42d096..c2ccd5a0f77212ee4ba9389448bacba8ddc4faa6 100644 (file)
@@ -10,6 +10,6 @@
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-obj-$(CONFIG_ARCH_BCM)         := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
+obj-$(CONFIG_ARCH_BCM_MOBILE)  := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_bcm_kona_smc_asm.o      :=-Wa,-march=armv7-a$(plus_sec)
index 8d9f931164bb8544aa046f01d2938bb9703cb183..cb3dc364405c4eec94465adbb503b7763fe4887f 100644 (file)
@@ -67,8 +67,7 @@ static void __init board_init(void)
 
 static const char * const bcm11351_dt_compat[] = { "brcm,bcm11351", NULL, };
 
-DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor")
-       .init_time = clocksource_of_init,
+DT_MACHINE_START(BCM11351_DT, "BCM281xx Broadcom Application Processor")
        .init_machine = board_init,
        .restart = bcm_kona_restart,
        .dt_compat = bcm11351_dt_compat,
index 40686d7ef500223765a1a08f6beccfad9a2847f6..70f2f3925f0e8e08487abb20b55ba580c4026c43 100644 (file)
 
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/irqchip/bcm2835.h>
+#include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/clk/bcm2835.h>
-#include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -131,10 +130,8 @@ static const char * const bcm2835_compat[] = {
 
 DT_MACHINE_START(BCM2835, "BCM2835")
        .map_io = bcm2835_map_io,
-       .init_irq = bcm2835_init_irq,
-       .handle_irq = bcm2835_handle_irq,
+       .init_irq = irqchip_init,
        .init_machine = bcm2835_init,
-       .init_time = clocksource_of_init,
        .restart = bcm2835_restart,
        .dt_compat = bcm2835_compat
 MACHINE_END
index 4ca2f3ca2de42efe618530332885492e4e223385..134641d688bb12f201dd2d0cedcd166890a8ce71 100644 (file)
 #include <linux/clockchips.h>
 #include <linux/clocksource.h>
 #include <linux/clk-provider.h>
+#include <linux/sched_clock.h>
 
 #include <asm/exception.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <asm/sched_clock.h>
 #include <asm/system_misc.h>
 
 #include <mach/hardware.h>
index c4bdc0a1c36e7795a21862f8a69a7e8ead71a43b..40f15f133c55c3646d5eeac3ef3eec7764cae760 100644 (file)
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include <mach/common.h>
 #include <mach/cp_intc.h>
 #include <mach/mux.h>
-#include <linux/platform_data/mtd-davinci.h>
 #include <mach/da8xx.h>
-#include <linux/platform_data/usb-davinci.h>
-#include <linux/platform_data/mtd-davinci-aemif.h>
-#include <linux/platform_data/spi-davinci.h>
 
 #define DA830_EVM_PHY_ID               ""
 /*
@@ -74,7 +76,7 @@ static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
        if (handler != NULL) {
                da830_evm_usb_ocic_handler = handler;
 
-               error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
+               error = request_irq(irq, da830_evm_usb_ocic_irq,
                                    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                                    "OHCI over-current indicator", NULL);
                if (error)
@@ -591,6 +593,10 @@ static __init void da830_evm_init(void)
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        int ret;
 
+       ret = da830_register_gpio();
+       if (ret)
+               pr_warn("da830_evm_init: GPIO init failed: %d\n", ret);
+
        ret = da830_register_edma(da830_edma_rsv);
        if (ret)
                pr_warning("da830_evm_init: edma registration failed: %d\n",
index dd1fb24521aa85b16baa9d200b40d28774591cfc..df16cb88a26b643814af5385affb94a7a8220882 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
 #include <linux/platform_data/spi-davinci.h>
@@ -38,6 +39,7 @@
 #include <linux/spi/flash.h>
 #include <linux/wl12xx.h>
 
+#include <mach/common.h>
 #include <mach/cp_intc.h>
 #include <mach/da8xx.h>
 #include <mach/mux.h>
@@ -1437,6 +1439,10 @@ static __init void da850_evm_init(void)
 {
        int ret;
 
+       ret = da850_register_gpio();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
        ret = pmic_tps65070_init();
        if (ret)
                pr_warn("%s: TPS65070 PMIC init failed: %d\n", __func__, ret);
index 42b23a3194a05d9052026e2f14c4a0fe5a9cc67e..ecdc7d44fa70aef07279f552e98a6354ed6c3900 100644 (file)
 #include <media/tvp514x.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <linux/platform_data/i2c-davinci.h>
 #include <mach/serial.h>
-#include <linux/platform_data/mtd-davinci.h>
-#include <linux/platform_data/mmc-davinci.h>
-#include <linux/platform_data/usb-davinci.h>
+#include <mach/common.h>
 
 #include "davinci.h"
 
@@ -375,6 +377,11 @@ static struct spi_board_info dm355_evm_spi_info[] __initconst = {
 static __init void dm355_evm_init(void)
 {
        struct clk *aemif;
+       int ret;
+
+       ret = dm355_gpio_register();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
 
        gpio_request(1, "dm9000");
        gpio_direction_input(1);
index 65a984c52df6fce12732ee0ff1b09902bb23d81a..43bacbf153140f7a9e6be87ed5e8b3cbe4012570 100644 (file)
 #include <linux/clk.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <linux/platform_data/i2c-davinci.h>
+#include <mach/common.h>
 #include <mach/serial.h>
-#include <linux/platform_data/mtd-davinci.h>
-#include <linux/platform_data/mmc-davinci.h>
-#include <linux/platform_data/usb-davinci.h>
 
 #include "davinci.h"
 
@@ -234,6 +235,11 @@ static struct spi_board_info dm355_leopard_spi_info[] __initconst = {
 static __init void dm355_leopard_init(void)
 {
        struct clk *aemif;
+       int ret;
+
+       ret = dm355_gpio_register();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
 
        gpio_request(9, "dm9000");
        gpio_direction_input(9);
index 4078ba93776b24ef9438f0dcc73c2f42dd859bd9..f4a6c18912ea50abaac233fedf26cef69af06724 100644 (file)
@@ -743,6 +743,12 @@ static struct spi_board_info dm365_evm_spi_info[] __initconst = {
 
 static __init void dm365_evm_init(void)
 {
+       int ret;
+
+       ret = dm365_gpio_register();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
        evm_init_i2c();
        davinci_serial_init(dm365_serial_device);
 
index 40bb9b5b87e829c2d4b741625141a58732921d9f..9cc32c283b8b90af050de90411a9b1d168b3b050 100644 (file)
@@ -754,9 +754,14 @@ static int davinci_phy_fixup(struct phy_device *phydev)
 
 static __init void davinci_evm_init(void)
 {
+       int ret;
        struct clk *aemif_clk;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       ret = dm644x_gpio_register();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
        aemif_clk = clk_get(NULL, "aemif");
        clk_prepare_enable(aemif_clk);
 
index 2bc3651d56cc8f52757b3703c14daadf2360abeb..44b20191a9fed5359ed0b24344e0aeb15430d210 100644 (file)
 #include <linux/mtd/partitions.h>
 #include <linux/clk.h>
 #include <linux/export.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
+#include <mach/irqs.h>
 #include <mach/serial.h>
-#include <linux/platform_data/i2c-davinci.h>
-#include <linux/platform_data/mtd-davinci.h>
 #include <mach/clock.h>
 #include <mach/cdce949.h>
-#include <linux/platform_data/mtd-davinci-aemif.h>
 
 #include "davinci.h"
 #include "clock.h"
@@ -786,8 +788,13 @@ static struct edma_rsv_info dm646x_edma_rsv[] = {
 
 static __init void evm_init(void)
 {
+       int ret;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       ret = dm646x_gpio_register();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
        evm_init_i2c();
        davinci_serial_init(dm646x_serial_device);
        dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
index 46f336fca80384541257e667383d85080b718b1b..bb680af98374e2177702529fd179b0d78d377828 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/mtd/partitions.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/i2c-davinci.h>
+#include <linux/platform_data/mmc-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/usb-davinci.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include <linux/platform_data/i2c-davinci.h>
 #include <mach/serial.h>
 #include <mach/mux.h>
-#include <linux/platform_data/mtd-davinci.h>
-#include <linux/platform_data/mmc-davinci.h>
-#include <linux/platform_data/usb-davinci.h>
 
 #include "davinci.h"
 
@@ -169,9 +170,14 @@ static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
 
 static __init void davinci_ntosd2_init(void)
 {
+       int ret;
        struct clk *aemif_clk;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       ret = dm644x_gpio_register();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
        aemif_clk = clk_get(NULL, "aemif");
        clk_prepare_enable(aemif_clk);
 
index ab98c75cabb48b7ed2cee6518fddca615f58f6e3..2aac51d0e85325361d9406e2d5abd6b8f8b9383b 100644 (file)
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include <mach/common.h>
 #include <mach/cp_intc.h>
 #include <mach/da8xx.h>
 #include <mach/mux.h>
@@ -211,7 +213,7 @@ static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
                hawk_usb_ocic_handler = handler;
 
                error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
-                                       IRQF_DISABLED | IRQF_TRIGGER_RISING |
+                                       IRQF_TRIGGER_RISING |
                                        IRQF_TRIGGER_FALLING,
                                        "OHCI over-current indicator", NULL);
                if (error)
@@ -290,6 +292,10 @@ static __init void omapl138_hawk_init(void)
 {
        int ret;
 
+       ret = da850_register_gpio();
+       if (ret)
+               pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
+
        davinci_serial_init(da8xx_serial_device);
 
        omapl138_hawk_config_emac();
index d6c746e35ad9fe196e947994de330fefda3e1962..0813b5167e059e1c7c32d82374bbdb6470eb9370 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/clk.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
@@ -20,7 +21,6 @@
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -1151,6 +1151,16 @@ static struct davinci_id da830_ids[] = {
        },
 };
 
+static struct davinci_gpio_platform_data da830_gpio_platform_data = {
+       .ngpio = 128,
+       .intc_irq_num = DA830_N_CP_INTC_IRQ,
+};
+
+int __init da830_register_gpio(void)
+{
+       return da8xx_register_gpio(&da830_gpio_platform_data);
+}
+
 static struct davinci_timer_instance da830_timer_instance[2] = {
        {
                .base           = DA8XX_TIMER64P0_BASE,
@@ -1196,10 +1206,6 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
        .intc_irq_prios         = da830_default_priorities,
        .intc_irq_num           = DA830_N_CP_INTC_IRQ,
        .timer_info             = &da830_timer_info,
-       .gpio_type              = GPIO_TYPE_DAVINCI,
-       .gpio_base              = DA8XX_GPIO_BASE,
-       .gpio_num               = 128,
-       .gpio_irq               = IRQ_DA8XX_GPIO0,
        .emac_pdata             = &da8xx_emac_pdata,
 };
 
index f56e5fbfa2fd20ebd0a8fd18adaee48463e632b2..352984e1528a4ab08cdd2e52b072e841e6a895e1 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/cpufreq.h>
 #include <linux/regulator/consumer.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
@@ -28,7 +29,6 @@
 #include <mach/da8xx.h>
 #include <mach/cpufreq.h>
 #include <mach/pm.h>
-#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -1281,6 +1281,16 @@ int __init da850_register_vpif_capture(struct vpif_capture_config
        return platform_device_register(&da850_vpif_capture_dev);
 }
 
+static struct davinci_gpio_platform_data da850_gpio_platform_data = {
+       .ngpio = 144,
+       .intc_irq_num = DA850_N_CP_INTC_IRQ,
+};
+
+int __init da850_register_gpio(void)
+{
+       return da8xx_register_gpio(&da850_gpio_platform_data);
+}
+
 static struct davinci_soc_info davinci_soc_info_da850 = {
        .io_desc                = da850_io_desc,
        .io_desc_num            = ARRAY_SIZE(da850_io_desc),
@@ -1298,10 +1308,6 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
        .intc_irq_prios         = da850_default_priorities,
        .intc_irq_num           = DA850_N_CP_INTC_IRQ,
        .timer_info             = &da850_timer_info,
-       .gpio_type              = GPIO_TYPE_DAVINCI,
-       .gpio_base              = DA8XX_GPIO_BASE,
-       .gpio_num               = 144,
-       .gpio_irq               = IRQ_DA8XX_GPIO0,
        .emac_pdata             = &da8xx_emac_pdata,
        .sram_dma               = DA8XX_SHARED_RAM_BASE,
        .sram_len               = SZ_128K,
index 2ab5d577186f4177fd06c414b31d25c21d295f8f..2eebc433880223b0ed2c5fe18c56aa11807cd699 100644 (file)
@@ -53,6 +53,9 @@ extern void __iomem *davinci_sysmod_base;
 #define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x))
 void davinci_map_sysmod(void);
 
+#define DAVINCI_GPIO_BASE 0x01C67000
+int davinci_gpio_register(struct resource *res, int size, void *pdata);
+
 /* DM355 base addresses */
 #define DM355_ASYNC_EMIF_CONTROL_BASE  0x01e10000
 #define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
@@ -82,6 +85,7 @@ void dm355_init_spi0(unsigned chipselect_mask,
                const struct spi_board_info *info, unsigned len);
 void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
 int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
+int dm355_gpio_register(void);
 
 /* DM365 function declarations */
 void dm365_init(void);
@@ -92,11 +96,13 @@ void dm365_init_rtc(void);
 void dm365_init_spi0(unsigned chipselect_mask,
                        const struct spi_board_info *info, unsigned len);
 int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
+int dm365_gpio_register(void);
 
 /* DM644x function declarations */
 void dm644x_init(void);
 void dm644x_init_asp(struct snd_platform_data *pdata);
 int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
+int dm644x_gpio_register(void);
 
 /* DM646x function declarations */
 void dm646x_init(void);
@@ -106,6 +112,7 @@ int dm646x_init_edma(struct edma_rsv_info *rsv);
 void dm646x_video_init(void);
 void dm646x_setup_vpif(struct vpif_display_config *,
                       struct vpif_capture_config *);
+int dm646x_gpio_register(void);
 
 extern struct platform_device dm365_serial_device[];
 extern struct platform_device dm355_serial_device[];
index 2e473fefd71ebc2049d490f554da0f8a70d2578b..c46eccbbd51226f5ae6ab5a16e1c89668c35fa1d 100644 (file)
@@ -665,6 +665,32 @@ int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
        return platform_device_register(&da8xx_lcdc_device);
 }
 
+static struct resource da8xx_gpio_resources[] = {
+       { /* registers */
+               .start  = DA8XX_GPIO_BASE,
+               .end    = DA8XX_GPIO_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       { /* interrupt */
+               .start  = IRQ_DA8XX_GPIO0,
+               .end    = IRQ_DA8XX_GPIO8,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device da8xx_gpio_device = {
+       .name           = "davinci_gpio",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(da8xx_gpio_resources),
+       .resource       = da8xx_gpio_resources,
+};
+
+int __init da8xx_register_gpio(void *pdata)
+{
+       da8xx_gpio_device.dev.platform_data = pdata;
+       return platform_device_register(&da8xx_gpio_device);
+}
+
 static struct resource da8xx_mmcsd0_resources[] = {
        {               /* registers */
                .start  = DA8XX_MMCSD0_BASE,
index 111573c0aad144dacea6674a842ec15b2bfd110a..3996e98f52fbe0c4e8601bb2dc1b8d0932a8ffd9 100644 (file)
@@ -318,6 +318,19 @@ static void davinci_init_wdt(void)
        platform_device_register(&davinci_wdt_device);
 }
 
+static struct platform_device davinci_gpio_device = {
+       .name   = "davinci_gpio",
+       .id     = -1,
+};
+
+int davinci_gpio_register(struct resource *res, int size, void *pdata)
+{
+       davinci_gpio_device.resource = res;
+       davinci_gpio_device.num_resources = size;
+       davinci_gpio_device.dev.platform_data = pdata;
+       return platform_device_register(&davinci_gpio_device);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /*-------------------------------------------------------------------------*/
index 3eaa5f6b2160593517463c2b18c211bbad93605e..ef9ff1fb6f52a2533378ba37563c06e877b32ea3 100644 (file)
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-
 #include <linux/spi/spi.h>
+#include <linux/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/spi-davinci.h>
 
 #include <asm/mach/map.h>
 
@@ -25,9 +27,6 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <linux/platform_data/spi-davinci.h>
-#include <mach/gpio-davinci.h>
-#include <linux/platform_data/edma.h>
 
 #include "davinci.h"
 #include "clock.h"
@@ -886,6 +885,30 @@ static struct platform_device dm355_vpbe_dev = {
        },
 };
 
+static struct resource dm355_gpio_resources[] = {
+       {       /* registers */
+               .start  = DAVINCI_GPIO_BASE,
+               .end    = DAVINCI_GPIO_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {       /* interrupt */
+               .start  = IRQ_DM355_GPIOBNK0,
+               .end    = IRQ_DM355_GPIOBNK6,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct davinci_gpio_platform_data dm355_gpio_platform_data = {
+       .ngpio          = 104,
+       .intc_irq_num   = DAVINCI_N_AINTC_IRQ,
+};
+
+int __init dm355_gpio_register(void)
+{
+       return davinci_gpio_register(dm355_gpio_resources,
+                                    sizeof(dm355_gpio_resources),
+                                    &dm355_gpio_platform_data);
+}
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm355_io_desc[] = {
@@ -1005,10 +1028,6 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
        .intc_irq_prios         = dm355_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm355_timer_info,
-       .gpio_type              = GPIO_TYPE_DAVINCI,
-       .gpio_base              = DAVINCI_GPIO_BASE,
-       .gpio_num               = 104,
-       .gpio_irq               = IRQ_DM355_GPIOBNK0,
        .sram_dma               = 0x00010000,
        .sram_len               = SZ_32K,
 };
index c29e324eb0bb75012d227da960e96fd60c2141f9..1511a0680f9a1d399cf3094b538c3c52caa06547 100644 (file)
@@ -19,6 +19,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/spi/spi.h>
 #include <linux/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/keyscan-davinci.h>
+#include <linux/platform_data/spi-davinci.h>
 
 #include <asm/mach/map.h>
 
@@ -29,9 +32,6 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <linux/platform_data/keyscan-davinci.h>
-#include <linux/platform_data/spi-davinci.h>
-#include <mach/gpio-davinci.h>
 
 #include "davinci.h"
 #include "clock.h"
@@ -698,6 +698,32 @@ void __init dm365_init_spi0(unsigned chipselect_mask,
        platform_device_register(&dm365_spi0_device);
 }
 
+static struct resource dm365_gpio_resources[] = {
+       {       /* registers */
+               .start  = DAVINCI_GPIO_BASE,
+               .end    = DAVINCI_GPIO_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {       /* interrupt */
+               .start  = IRQ_DM365_GPIO0,
+               .end    = IRQ_DM365_GPIO7,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct davinci_gpio_platform_data dm365_gpio_platform_data = {
+       .ngpio          = 104,
+       .intc_irq_num   = DAVINCI_N_AINTC_IRQ,
+       .gpio_unbanked  = 8,
+};
+
+int __init dm365_gpio_register(void)
+{
+       return davinci_gpio_register(dm365_gpio_resources,
+                                    sizeof(dm365_gpio_resources),
+                                    &dm365_gpio_platform_data);
+}
+
 static struct emac_platform_data dm365_emac_pdata = {
        .ctrl_reg_offset        = DM365_EMAC_CNTRL_OFFSET,
        .ctrl_mod_reg_offset    = DM365_EMAC_CNTRL_MOD_OFFSET,
@@ -1105,11 +1131,6 @@ static struct davinci_soc_info davinci_soc_info_dm365 = {
        .intc_irq_prios         = dm365_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm365_timer_info,
-       .gpio_type              = GPIO_TYPE_DAVINCI,
-       .gpio_base              = DAVINCI_GPIO_BASE,
-       .gpio_num               = 104,
-       .gpio_irq               = IRQ_DM365_GPIO0,
-       .gpio_unbanked          = 8,    /* really 16 ... skip muxed GPIOs */
        .emac_pdata             = &dm365_emac_pdata,
        .sram_dma               = 0x00010000,
        .sram_len               = SZ_32K,
index 4f74682293d6f162125ac176c54721e2260bf9d8..143a3217e8efb8fde1aa417700c45840d242aac0 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
@@ -23,7 +24,6 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <mach/gpio-davinci.h>
 
 #include "davinci.h"
 #include "clock.h"
@@ -771,6 +771,30 @@ static struct platform_device dm644x_vpbe_dev = {
        },
 };
 
+static struct resource dm644_gpio_resources[] = {
+       {       /* registers */
+               .start  = DAVINCI_GPIO_BASE,
+               .end    = DAVINCI_GPIO_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {       /* interrupt */
+               .start  = IRQ_GPIOBNK0,
+               .end    = IRQ_GPIOBNK4,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct davinci_gpio_platform_data dm644_gpio_platform_data = {
+       .ngpio          = 71,
+       .intc_irq_num   = DAVINCI_N_AINTC_IRQ,
+};
+
+int __init dm644x_gpio_register(void)
+{
+       return davinci_gpio_register(dm644_gpio_resources,
+                                    sizeof(dm644_gpio_resources),
+                                    &dm644_gpio_platform_data);
+}
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm644x_io_desc[] = {
@@ -897,10 +921,6 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
        .intc_irq_prios         = dm644x_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm644x_timer_info,
-       .gpio_type              = GPIO_TYPE_DAVINCI,
-       .gpio_base              = DAVINCI_GPIO_BASE,
-       .gpio_num               = 71,
-       .gpio_irq               = IRQ_GPIOBNK0,
        .emac_pdata             = &dm644x_emac_pdata,
        .sram_dma               = 0x00008000,
        .sram_len               = SZ_16K,
index 68f8d1f1aca1620d864307a28f449de956e287e6..2a73f299c1d094615236359d6ac27959cdd16295 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/edma.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
@@ -24,7 +25,6 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <mach/gpio-davinci.h>
 
 #include "davinci.h"
 #include "clock.h"
@@ -748,6 +748,30 @@ static struct platform_device vpif_capture_dev = {
        .num_resources  = ARRAY_SIZE(vpif_capture_resource),
 };
 
+static struct resource dm646x_gpio_resources[] = {
+       {       /* registers */
+               .start  = DAVINCI_GPIO_BASE,
+               .end    = DAVINCI_GPIO_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {       /* interrupt */
+               .start  = IRQ_DM646X_GPIOBNK0,
+               .end    = IRQ_DM646X_GPIOBNK2,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct davinci_gpio_platform_data dm646x_gpio_platform_data = {
+       .ngpio          = 43,
+       .intc_irq_num   = DAVINCI_N_AINTC_IRQ,
+};
+
+int __init dm646x_gpio_register(void)
+{
+       return davinci_gpio_register(dm646x_gpio_resources,
+                                    sizeof(dm646x_gpio_resources),
+                                    &dm646x_gpio_platform_data);
+}
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm646x_io_desc[] = {
@@ -874,10 +898,6 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
        .intc_irq_prios         = dm646x_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm646x_timer_info,
-       .gpio_type              = GPIO_TYPE_DAVINCI,
-       .gpio_base              = DAVINCI_GPIO_BASE,
-       .gpio_num               = 43, /* Only 33 usable */
-       .gpio_irq               = IRQ_DM646X_GPIOBNK0,
        .emac_pdata             = &dm646x_emac_pdata,
        .sram_dma               = 0x10010000,
        .sram_len               = SZ_32K,
index aae53072c0eb602d536c1a0891258625347fc0df..39e58b48e826dc4350f54a0aa170444855723815 100644 (file)
@@ -97,6 +97,7 @@ int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
 int da850_register_mmcsd1(struct davinci_mmc_config *config);
 void da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
 int da8xx_register_rtc(void);
+int da8xx_register_gpio(void *pdata);
 int da850_register_cpufreq(char *async_clk);
 int da8xx_register_cpuidle(void);
 void __iomem *da8xx_get_mem_ctlr(void);
@@ -110,6 +111,8 @@ int da850_register_vpif_capture
 void da8xx_restart(enum reboot_mode mode, const char *cmd);
 void da8xx_rproc_reserve_cma(void);
 int da8xx_register_rproc(void);
+int da850_register_gpio(void);
+int da830_register_gpio(void);
 
 extern struct platform_device da8xx_serial_device[];
 extern struct emac_platform_data da8xx_emac_pdata;
diff --git a/arch/arm/mach-davinci/include/mach/gpio-davinci.h b/arch/arm/mach-davinci/include/mach/gpio-davinci.h
deleted file mode 100644 (file)
index 1fdd1fd..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * TI DaVinci GPIO Support
- *
- * Copyright (c) 2006 David Brownell
- * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.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.
- */
-
-#ifndef        __DAVINCI_DAVINCI_GPIO_H
-#define        __DAVINCI_DAVINCI_GPIO_H
-
-#include <linux/io.h>
-#include <linux/spinlock.h>
-
-#include <asm-generic/gpio.h>
-
-#include <mach/irqs.h>
-#include <mach/common.h>
-
-#define DAVINCI_GPIO_BASE 0x01C67000
-
-enum davinci_gpio_type {
-       GPIO_TYPE_DAVINCI = 0,
-       GPIO_TYPE_TNETV107X,
-};
-
-/*
- * basic gpio routines
- *
- * board-specific init should be done by arch/.../.../board-XXX.c (maybe
- * initializing banks together) rather than boot loaders; kexec() won't
- * go through boot loaders.
- *
- * the gpio clock will be turned on when gpios are used, and you may also
- * need to pay attention to PINMUX registers to be sure those pins are
- * used as gpios, not with other peripherals.
- *
- * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation,
- * and maybe for later updates, code may write GPIO(N).  These may be
- * all 1.8V signals, all 3.3V ones, or a mix of the two.  A given chip
- * may not support all the GPIOs in that range.
- *
- * GPIOs can also be on external chips, numbered after the ones built-in
- * to the DaVinci chip.  For now, they won't be usable as IRQ sources.
- */
-#define        GPIO(X)         (X)             /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
-
-/* Convert GPIO signal to GPIO pin number */
-#define GPIO_TO_PIN(bank, gpio)        (16 * (bank) + (gpio))
-
-struct davinci_gpio_controller {
-       struct gpio_chip        chip;
-       int                     irq_base;
-       spinlock_t              lock;
-       void __iomem            *regs;
-       void __iomem            *set_data;
-       void __iomem            *clr_data;
-       void __iomem            *in_data;
-};
-
-/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
- * with constant parameters; or in outlined code they execute at runtime.
- *
- * You'd access the controller directly when reading or writing more than
- * one gpio value at a time, and to support wired logic where the value
- * being driven by the cpu need not match the value read back.
- *
- * These are NOT part of the cross-platform GPIO interface
- */
-static inline struct davinci_gpio_controller *
-__gpio_to_controller(unsigned gpio)
-{
-       struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
-       int index = gpio / 32;
-
-       if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
-               return NULL;
-
-       return ctlrs + index;
-}
-
-static inline u32 __gpio_mask(unsigned gpio)
-{
-       return 1 << (gpio % 32);
-}
-
-#endif /* __DAVINCI_DAVINCI_GPIO_H */
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
deleted file mode 100644 (file)
index 960e9de..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * TI DaVinci GPIO Support
- *
- * Copyright (c) 2006 David Brownell
- * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.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.
- */
-
-#ifndef        __DAVINCI_GPIO_H
-#define        __DAVINCI_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#define __ARM_GPIOLIB_COMPLEX
-
-/* The inline versions use the static inlines in the driver header */
-#include "gpio-davinci.h"
-
-/*
- * The get/set/clear functions will inline when called with constant
- * parameters referencing built-in GPIOs, for low-overhead bitbanging.
- *
- * gpio_set_value() will inline only on traditional Davinci style controllers
- * with distinct set/clear registers.
- *
- * Otherwise, calls with variable parameters or referencing external
- * GPIOs (e.g. on GPIO expander chips) use outlined functions.
- */
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-       if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) {
-               struct davinci_gpio_controller *ctlr;
-               u32                             mask;
-
-               ctlr = __gpio_to_controller(gpio);
-
-               if (ctlr->set_data != ctlr->clr_data) {
-                       mask = __gpio_mask(gpio);
-                       if (value)
-                               __raw_writel(mask, ctlr->set_data);
-                       else
-                               __raw_writel(mask, ctlr->clr_data);
-                       return;
-               }
-       }
-
-       __gpio_set_value(gpio, value);
-}
-
-/* Returns zero or nonzero; works for gpios configured as inputs OR
- * as outputs, at least for built-in GPIOs.
- *
- * NOTE: for built-in GPIOs, changes in reported values are synchronized
- * to the GPIO clock.  This is easily seen after calling gpio_set_value()
- * and then immediately gpio_get_value(), where the gpio_get_value() will
- * return the old value until the GPIO clock ticks and the new value gets
- * latched.
- */
-static inline int gpio_get_value(unsigned gpio)
-{
-       struct davinci_gpio_controller *ctlr;
-
-       if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num)
-               return __gpio_get_value(gpio);
-
-       ctlr = __gpio_to_controller(gpio);
-       return __gpio_mask(gpio) & __raw_readl(ctlr->in_data);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
-       if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num)
-               return 0;
-       else
-               return __gpio_cansleep(gpio);
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-       /* don't support the reverse mapping */
-       return -ENOSYS;
-}
-
-#endif                         /* __DAVINCI_GPIO_H */
index 7a55b5c9597124a23345066771b9bb88a5893478..56c6eb5266adf8f5c18629db9cfb65018f5bad50 100644 (file)
@@ -181,7 +181,7 @@ static struct timer_s timers[] = {
                .name      = "clockevent",
                .opts      = TIMER_OPTS_DISABLED,
                .irqaction = {
-                       .flags   = IRQF_DISABLED | IRQF_TIMER,
+                       .flags   = IRQF_TIMER,
                        .handler = timer_interrupt,
                }
        },
@@ -190,7 +190,7 @@ static struct timer_s timers[] = {
                .period     = ~0,
                .opts       = TIMER_OPTS_PERIODIC,
                .irqaction = {
-                       .flags   = IRQF_DISABLED | IRQF_TIMER,
+                       .flags   = IRQF_TIMER,
                        .handler = freerun_interrupt,
                }
        },
@@ -331,7 +331,6 @@ static void davinci_set_mode(enum clock_event_mode mode,
 
 static struct clock_event_device clockevent_davinci = {
        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .shift          = 32,
        .set_next_event = davinci_set_next_event,
        .set_mode       = davinci_set_mode,
 };
@@ -397,14 +396,10 @@ void __init davinci_timer_init(void)
 
        /* setup clockevent */
        clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
-       clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
-                                        clockevent_davinci.shift);
-       clockevent_davinci.max_delta_ns =
-               clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
-       clockevent_davinci.min_delta_ns = 50000; /* 50 usec */
 
        clockevent_davinci.cpumask = cpumask_of(0);
-       clockevents_register_device(&clockevent_davinci);
+       clockevents_config_and_register(&clockevent_davinci,
+                                       davinci_clock_tick_rate, 1, 0xfffffffe);
 
        for (i=0; i< ARRAY_SIZE(timers); i++)
                timer32_config(&timers[i]);
index 49f72a848423a62d3ff44943cfae84751aee09c0..49fa9abd09daec9097c81d58d2633feccd8ec6f4 100644 (file)
 
 #include <linux/init.h>
 #include <linux/clk-provider.h>
-#include <linux/clocksource.h>
-#include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <linux/platform_data/usb-ehci-orion.h>
 #include <asm/hardware/cache-tauros2.h>
 #include <asm/mach/arch.h>
 #include <mach/dove.h>
 #include <mach/pm.h>
 #include <plat/common.h>
-#include <plat/irq.h>
 #include "common.h"
 
-/*
- * There are still devices that doesn't even know about DT,
- * get clock gates here and add a clock lookup.
- */
-static void __init dove_legacy_clk_init(void)
-{
-       struct device_node *np = of_find_compatible_node(NULL, NULL,
-                                        "marvell,dove-gating-clock");
-       struct of_phandle_args clkspec;
-
-       clkspec.np = np;
-       clkspec.args_count = 1;
-
-       clkspec.args[0] = CLOCK_GATING_BIT_PCIE0;
-       orion_clkdev_add("0", "pcie",
-                        of_clk_get_from_provider(&clkspec));
-
-       clkspec.args[0] = CLOCK_GATING_BIT_PCIE1;
-       orion_clkdev_add("1", "pcie",
-                        of_clk_get_from_provider(&clkspec));
-}
-
-static void __init dove_dt_time_init(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
-static void __init dove_dt_init_early(void)
-{
-       mvebu_mbus_init("marvell,dove-mbus",
-                       BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
-                       DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
-}
-
 static void __init dove_dt_init(void)
 {
        pr_info("Dove 88AP510 SoC\n");
@@ -65,14 +26,7 @@ static void __init dove_dt_init(void)
 #ifdef CONFIG_CACHE_TAUROS2
        tauros2_init(0);
 #endif
-       dove_setup_cpu_wins();
-
-       /* Setup clocks for legacy devices */
-       dove_legacy_clk_init();
-
-       /* Internal devices not ported to DT yet */
-       dove_pcie_init(1, 1);
-
+       BUG_ON(mvebu_mbus_dt_init());
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
@@ -83,8 +37,6 @@ static const char * const dove_dt_board_compat[] = {
 
 DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)")
        .map_io         = dove_map_io,
-       .init_early     = dove_dt_init_early,
-       .init_time      = dove_dt_time_init,
        .init_machine   = dove_dt_init,
        .restart        = dove_restart,
        .dt_compat      = dove_dt_board_compat,
index c95dbce2468e62010c8df64e3be4751869bd7abc..39ef3b613912f8888013c30d591e4ad4f0cd8095 100644 (file)
@@ -212,7 +212,7 @@ static struct clk_lookup clocks[] = {
        INIT_CK(NULL,                   "hclk",         &clk_h),
        INIT_CK(NULL,                   "apb_pclk",     &clk_p),
        INIT_CK(NULL,                   "pll2",         &clk_pll2),
-       INIT_CK("ep93xx-ohci",          NULL,           &clk_usb_host),
+       INIT_CK("ohci-platform",        NULL,           &clk_usb_host),
        INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
        INIT_CK("ep93xx-fb",            NULL,           &clk_video),
        INIT_CK("ep93xx-spi.0",         NULL,           &clk_spi),
index 3f12b885c083ac37424bdb9e44ca478f09a3c12b..d95ee28a616a3ed53c776dda2df2fa5da6f229f1 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/export.h>
 #include <linux/irqchip/arm-vic.h>
 #include <linux/reboot.h>
+#include <linux/usb/ohci_pdriver.h>
 
 #include <mach/hardware.h>
 #include <linux/platform_data/video-ep93xx.h>
@@ -297,25 +298,53 @@ static struct platform_device ep93xx_rtc_device = {
        .resource       = ep93xx_rtc_resource,
 };
 
+/*************************************************************************
+ * EP93xx OHCI USB Host
+ *************************************************************************/
+
+static struct clk *ep93xx_ohci_host_clock;
+
+static int ep93xx_ohci_power_on(struct platform_device *pdev)
+{
+       if (!ep93xx_ohci_host_clock) {
+               ep93xx_ohci_host_clock = devm_clk_get(&pdev->dev, NULL);
+               if (IS_ERR(ep93xx_ohci_host_clock))
+                       return PTR_ERR(ep93xx_ohci_host_clock);
+       }
+
+       return clk_enable(ep93xx_ohci_host_clock);
+}
+
+static void ep93xx_ohci_power_off(struct platform_device *pdev)
+{
+       clk_disable(ep93xx_ohci_host_clock);
+}
+
+static struct usb_ohci_pdata ep93xx_ohci_pdata = {
+       .power_on       = ep93xx_ohci_power_on,
+       .power_off      = ep93xx_ohci_power_off,
+       .power_suspend  = ep93xx_ohci_power_off,
+};
 
 static struct resource ep93xx_ohci_resources[] = {
        DEFINE_RES_MEM(EP93XX_USB_PHYS_BASE, 0x1000),
        DEFINE_RES_IRQ(IRQ_EP93XX_USB),
 };
 
+static u64 ep93xx_ohci_dma_mask = DMA_BIT_MASK(32);
 
 static struct platform_device ep93xx_ohci_device = {
-       .name           = "ep93xx-ohci",
+       .name           = "ohci-platform",
        .id             = -1,
+       .num_resources  = ARRAY_SIZE(ep93xx_ohci_resources),
+       .resource       = ep93xx_ohci_resources,
        .dev            = {
-               .dma_mask               = &ep93xx_ohci_device.dev.coherent_dma_mask,
+               .dma_mask               = &ep93xx_ohci_dma_mask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &ep93xx_ohci_pdata,
        },
-       .num_resources  = ARRAY_SIZE(ep93xx_ohci_resources),
-       .resource       = ep93xx_ohci_resources,
 };
 
-
 /*************************************************************************
  * EP93xx physmap'ed flash
  *************************************************************************/
index 56fe819ee10b0dd17919e61fdec71cd403b1d6de..f9d67a0acb2af170737db3aa60a0b54f1f4091dd 100644 (file)
@@ -14,19 +14,28 @@ menu "SAMSUNG EXYNOS SoCs Support"
 config ARCH_EXYNOS4
        bool "SAMSUNG EXYNOS4"
        default y
+       select ARM_AMBA
+       select CLKSRC_OF
+       select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210
+       select CPU_EXYNOS4210
        select GIC_NON_BANKED
+       select KEYBOARD_SAMSUNG if INPUT_KEYBOARD
        select HAVE_ARM_SCU if SMP
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
        select PINCTRL
+       select S5P_DEV_MFC
        help
          Samsung EXYNOS4 SoCs based systems
 
 config ARCH_EXYNOS5
        bool "SAMSUNG EXYNOS5"
+       select ARM_AMBA
+       select CLKSRC_OF
        select HAVE_ARM_SCU if SMP
        select HAVE_SMP
        select PINCTRL
+       select USB_ARCH_HAS_XHCI
        help
          Samsung EXYNOS5 (Cortex-A15) SoC based systems
 
@@ -110,35 +119,6 @@ config SOC_EXYNOS5440
        help
          Enable EXYNOS5440 SoC support
 
-comment "Flattened Device Tree based board for EXYNOS SoCs"
-
-config MACH_EXYNOS4_DT
-       bool "Samsung Exynos4 Machine using device tree"
-       default y
-       depends on ARCH_EXYNOS4
-       select ARM_AMBA
-       select CLKSRC_OF
-       select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210
-       select CPU_EXYNOS4210
-       select KEYBOARD_SAMSUNG if INPUT_KEYBOARD
-       select S5P_DEV_MFC
-       help
-         Machine support for Samsung Exynos4 machine with device tree enabled.
-         Select this if a fdt blob is available for the Exynos4 SoC based board.
-         Note: This is under development and not all peripherals can be supported
-         with this machine file.
-
-config MACH_EXYNOS5_DT
-       bool "SAMSUNG EXYNOS5 Machine using device tree"
-       default y
-       depends on ARCH_EXYNOS5
-       select ARM_AMBA
-       select CLKSRC_OF
-       select USB_ARCH_HAS_XHCI
-       help
-         Machine support for Samsung EXYNOS5 machine with device tree enabled.
-         Select this if a fdt blob is available for the EXYNOS5 SoC based board.
-
 endmenu
 
 endif
index 53696154aead3da032d710720cd45ca72e634827..8930b66b4abdba97b2d09aac81f28cf0df5fb21b 100644 (file)
@@ -32,5 +32,5 @@ AFLAGS_exynos-smc.o           :=-Wa,-march=armv7-a$(plus_sec)
 
 # machine support
 
-obj-$(CONFIG_MACH_EXYNOS4_DT)          += mach-exynos4-dt.o
-obj-$(CONFIG_MACH_EXYNOS5_DT)          += mach-exynos5-dt.o
+obj-$(CONFIG_ARCH_EXYNOS4)     += mach-exynos4-dt.o
+obj-$(CONFIG_ARCH_EXYNOS5)     += mach-exynos5-dt.o
index ba95e5db25011a0801c2ef1f7c27270b713280ee..a4e7ba82881025db51b05045a310f9c761e7dcf3 100644 (file)
@@ -26,8 +26,6 @@
 #include <linux/export.h>
 #include <linux/irqdomain.h>
 #include <linux/of_address.h>
-#include <linux/clocksource.h>
-#include <linux/clk-provider.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/irqchip/chained_irq.h>
 
@@ -367,12 +365,6 @@ static void __init exynos5_map_io(void)
                iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
 }
 
-void __init exynos_init_time(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
 struct bus_type exynos_subsys = {
        .name           = "exynos-core",
        .dev_name       = "exynos-core",
index 8646a141ae467b8175aed00d0acf39ae73f02097..f0fa2050d08d044288480c1b077cf1110e92cb62 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/of.h>
 
 void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1);
-void exynos_init_time(void);
 
 struct map_desc;
 void exynos_init_io(void);
index 57344b7e98ce03b8a46dc1a3698db60ef83b6dd9..2cdb63e8ce5c0eb352064f67c7c4d8dae8b43541 100644 (file)
 #define S5P_DAC_PHY_CONTROL                    S5P_PMUREG(0x070C)
 #define S5P_DAC_PHY_ENABLE                     (1 << 0)
 
-#define S5P_MIPI_DPHY_CONTROL(n)               S5P_PMUREG(0x0710 + (n) * 4)
-#define S5P_MIPI_DPHY_ENABLE                   (1 << 0)
-#define S5P_MIPI_DPHY_SRESETN                  (1 << 1)
-#define S5P_MIPI_DPHY_MRESETN                  (1 << 2)
-
 #define S5P_INFORM0                            S5P_PMUREG(0x0800)
 #define S5P_INFORM1                            S5P_PMUREG(0x0804)
 #define S5P_INFORM2                            S5P_PMUREG(0x0808)
index 0099c6c13bbaa9504dccd6fa760c21273de41d3f..4b8f6e2ca163b6660904882486306acd4e739e7d 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#include <linux/kernel.h>
 #include <linux/of_platform.h>
 #include <linux/of_fdt.h>
-#include <linux/serial_core.h>
-#include <linux/memblock.h>
-#include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
 #include <plat/mfc.h>
@@ -54,7 +50,6 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
        .init_early     = exynos_firmware_init,
        .init_machine   = exynos4_dt_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos_init_time,
        .dt_compat      = exynos4_dt_compat,
        .restart        = exynos4_restart,
        .reserve        = exynos4_reserve,
index f874b773ca134e231df3e21d3c5c5f65caac33a9..7976ab333192d3503e0d30b7d44148781a9da6c8 100644 (file)
 
 #include <linux/of_platform.h>
 #include <linux/of_fdt.h>
-#include <linux/memblock.h>
 #include <linux/io.h>
-#include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
 #include <mach/regs-pmu.h>
-
-#include <plat/cpu.h>
 #include <plat/mfc.h>
 
 #include "common.h"
@@ -76,7 +72,6 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
        .map_io         = exynos_init_io,
        .init_machine   = exynos5_dt_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos_init_time,
        .dt_compat      = exynos5_dt_compat,
        .restart        = exynos5_restart,
        .reserve        = exynos5_reserve,
index 21dc5a89d1c4b12e3ca2d385f8ade4e656e65fbe..0a63c4d25b64ec8acbd978b805f03d93b521a51f 100644 (file)
@@ -13,6 +13,8 @@
 #include <mach/hardware.h>
 #include <mach/global_reg.h>
 #include <asm/mach/time.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
 
 /*
  * Register definitions for the timers
 #define TIMER_3_CR_CLOCK               (1 << 7)
 #define TIMER_3_CR_INT                 (1 << 8)
 
+static unsigned int tick_rate;
+
+static int gemini_timer_set_next_event(unsigned long cycles,
+                                      struct clock_event_device *evt)
+{
+       u32 cr;
+
+       cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+       /* This may be overdoing it, feel free to test without this */
+       cr &= ~TIMER_2_CR_ENABLE;
+       cr &= ~TIMER_2_CR_INT;
+       writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+       /* Set next event */
+       writel(cycles, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+       writel(cycles, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+       cr |= TIMER_2_CR_ENABLE;
+       cr |= TIMER_2_CR_INT;
+       writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+       return 0;
+}
+
+static void gemini_timer_set_mode(enum clock_event_mode mode,
+                                 struct clock_event_device *evt)
+{
+       u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ);
+       u32 cr;
+
+       switch (mode) {
+        case CLOCK_EVT_MODE_PERIODIC:
+               /* Start the timer */
+               writel(period,
+                      TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+               writel(period,
+                      TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+               cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+               cr |= TIMER_2_CR_ENABLE;
+               cr |= TIMER_2_CR_INT;
+               writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+        case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               /*
+                * Disable also for oneshot: the set_next() call will
+                * arm the timer instead.
+                */
+               cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+               cr &= ~TIMER_2_CR_ENABLE;
+               cr &= ~TIMER_2_CR_INT;
+               writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+               break;
+       default:
+                break;
+       }
+}
+
+/* Use TIMER2 as clock event */
+static struct clock_event_device gemini_clockevent = {
+       .name           = "TIMER2",
+       .rating         = 300, /* Reasonably fast and accurate clock event */
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_next_event = gemini_timer_set_next_event,
+       .set_mode       = gemini_timer_set_mode,
+};
+
 /*
  * IRQ handler for the timer
  */
 static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id)
 {
-       timer_tick();
+       struct clock_event_device *evt = &gemini_clockevent;
 
+       evt->event_handler(evt);
        return IRQ_HANDLED;
 }
 
 static struct irqaction gemini_timer_irq = {
        .name           = "Gemini Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .flags          = IRQF_TIMER,
        .handler        = gemini_timer_interrupt,
 };
 
@@ -54,9 +126,9 @@ static struct irqaction gemini_timer_irq = {
  */
 void __init gemini_timer_init(void)
 {
-       unsigned int tick_rate, reg_v;
+       u32 reg_v;
 
-       reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));
+       reg_v = readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));
        tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000;
 
        printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000);
@@ -82,8 +154,17 @@ void __init gemini_timer_init(void)
         * Make irqs happen for the system timer
         */
        setup_irq(IRQ_TIMER2, &gemini_timer_irq);
-       /* Start the timer */
-       __raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
-       __raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
-       __raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+
+       /* Enable and use TIMER1 as clock source */
+       writel(0xffffffff, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)));
+       writel(0xffffffff, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER1_BASE)));
+       writel(TIMER_1_CR_ENABLE, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+       if (clocksource_mmio_init(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)),
+                                 "TIMER1", tick_rate, 300, 32,
+                                 clocksource_mmio_readl_up))
+               pr_err("timer: failed to initialize gemini clock source\n");
+
+       /* Configure and register the clockevent */
+       clockevents_config_and_register(&gemini_clockevent, tick_rate,
+                                       1, 0xffffffff);
 }
index 8e8437dea3ce7742da2cd8cae56df82efa2dfe93..fe98df44579cfa5c22c77ebd53dd9efbee15cf1e 100644 (file)
@@ -10,9 +10,9 @@ config ARCH_HIGHBANK
        select ARM_ERRATA_775420
        select ARM_ERRATA_798181
        select ARM_GIC
+       select ARM_PSCI
        select ARM_TIMER_SP804
        select CACHE_L2X0
-       select CLKDEV_LOOKUP
        select COMMON_CLK
        select CPU_V7
        select GENERIC_CLOCKEVENTS
index 8a1ef576d79fd3e88960e2ac1f1113e7ad698134..55840f414d3e04125f8c730ee916589e6eecb1fc 100644 (file)
@@ -3,6 +3,4 @@ obj-y                                   := highbank.o system.o smc.o
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_smc.o                           :=-Wa,-march=armv7-a$(plus_sec)
 
-obj-$(CONFIG_SMP)                      += platsmp.o
-obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
 obj-$(CONFIG_PM_SLEEP)                 += pm.o
index aea1ec5ab6f8ec51b318ef617e2b2cefebca3df4..7ec5edcd1336c06e7718517ce8fc9cc5b8ef213d 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <linux/reboot.h>
 
-extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
 extern void highbank_restart(enum reboot_mode, const char *);
 extern void __iomem *scu_base_addr;
 
@@ -14,8 +13,5 @@ static inline void highbank_pm_init(void) {}
 #endif
 
 extern void highbank_smc1(int fn, int arg);
-extern void highbank_cpu_die(unsigned int cpu);
-
-extern struct smp_operations highbank_smp_ops;
 
 #endif
index 8e63ccdb0de3c9c80923e46eadec91e6e9e1689e..b3d7e5634b83cb02ce568040099027007820a45b 100644 (file)
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/amba/bus.h>
-#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
 
-#include <asm/cacheflush.h>
-#include <asm/cputype.h>
-#include <asm/smp_plat.h>
+#include <asm/psci.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -49,17 +47,6 @@ static void __init highbank_scu_map_io(void)
        scu_base_addr = ioremap(base, SZ_4K);
 }
 
-#define HB_JUMP_TABLE_PHYS(cpu)                (0x40 + (0x10 * (cpu)))
-#define HB_JUMP_TABLE_VIRT(cpu)                phys_to_virt(HB_JUMP_TABLE_PHYS(cpu))
-
-void highbank_set_cpu_jump(int cpu, void *jump_addr)
-{
-       cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0);
-       writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu));
-       __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16);
-       outer_clean_range(HB_JUMP_TABLE_PHYS(cpu),
-                         HB_JUMP_TABLE_PHYS(cpu) + 15);
-}
 
 static void highbank_l2x0_disable(void)
 {
@@ -83,20 +70,6 @@ static void __init highbank_init_irq(void)
        }
 }
 
-static void __init highbank_timer_init(void)
-{
-       struct device_node *np;
-
-       /* Map system registers */
-       np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
-       sregs_base = of_iomap(np, 0);
-       WARN_ON(!sregs_base);
-
-       of_clk_init(NULL);
-
-       clocksource_of_init();
-}
-
 static void highbank_power_off(void)
 {
        highbank_set_pwr_shutdown();
@@ -153,8 +126,19 @@ static struct notifier_block highbank_platform_nb = {
        .notifier_call = highbank_platform_notifier,
 };
 
+static struct platform_device highbank_cpuidle_device = {
+       .name = "cpuidle-calxeda",
+};
+
 static void __init highbank_init(void)
 {
+       struct device_node *np;
+
+       /* Map system registers */
+       np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
+       sregs_base = of_iomap(np, 0);
+       WARN_ON(!sregs_base);
+
        pm_power_off = highbank_power_off;
        highbank_pm_init();
 
@@ -162,6 +146,9 @@ static void __init highbank_init(void)
        bus_register_notifier(&amba_bustype, &highbank_amba_nb);
 
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+       if (psci_ops.cpu_suspend)
+               platform_device_register(&highbank_cpuidle_device);
 }
 
 static const char *highbank_match[] __initconst = {
@@ -174,9 +161,7 @@ DT_MACHINE_START(HIGHBANK, "Highbank")
 #if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
        .dma_zone_size  = (4ULL * SZ_1G),
 #endif
-       .smp            = smp_ops(highbank_smp_ops),
        .init_irq       = highbank_init_irq,
-       .init_time      = highbank_timer_init,
        .init_machine   = highbank_init,
        .dt_compat      = highbank_match,
        .restart        = highbank_restart,
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c
deleted file mode 100644 (file)
index a019e4e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2011 Calxeda, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/kernel.h>
-#include <asm/cacheflush.h>
-
-#include "core.h"
-#include "sysregs.h"
-
-extern void secondary_startup(void);
-
-/*
- * platform-specific code to shutdown a CPU
- *
- */
-void __ref highbank_cpu_die(unsigned int cpu)
-{
-       highbank_set_cpu_jump(cpu, phys_to_virt(0));
-
-       flush_cache_louis();
-       highbank_set_core_pwr();
-
-       while (1)
-               cpu_do_idle();
-}
diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c
deleted file mode 100644 (file)
index 32d75cf..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2010-2011 Calxeda, Inc.
- * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/smp_scu.h>
-
-#include "core.h"
-
-extern void secondary_startup(void);
-
-static int highbank_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       highbank_set_cpu_jump(cpu, secondary_startup);
-       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-       return 0;
-}
-
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-static void __init highbank_smp_init_cpus(void)
-{
-       unsigned int i, ncores = 4;
-
-       /* sanity check */
-       if (ncores > NR_CPUS) {
-               printk(KERN_WARNING
-                      "highbank: no. of cores (%d) greater than configured "
-                      "maximum of %d - clipping\n",
-                      ncores, NR_CPUS);
-               ncores = NR_CPUS;
-       }
-
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
-}
-
-static void __init highbank_smp_prepare_cpus(unsigned int max_cpus)
-{
-       if (scu_base_addr)
-               scu_enable(scu_base_addr);
-}
-
-struct smp_operations highbank_smp_ops __initdata = {
-       .smp_init_cpus          = highbank_smp_init_cpus,
-       .smp_prepare_cpus       = highbank_smp_prepare_cpus,
-       .smp_boot_secondary     = highbank_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
-       .cpu_die                = highbank_cpu_die,
-#endif
-};
index 04eddb4f438095da0fff7caee5f4561b7fe2c1f3..7f2bd85eb9350de89cb8311e5a9926830bbd9f54 100644 (file)
 
 #include <linux/cpu_pm.h>
 #include <linux/init.h>
-#include <linux/io.h>
 #include <linux/suspend.h>
 
-#include <asm/cacheflush.h>
-#include <asm/proc-fns.h>
 #include <asm/suspend.h>
-
-#include "core.h"
-#include "sysregs.h"
+#include <asm/psci.h>
 
 static int highbank_suspend_finish(unsigned long val)
 {
-       outer_flush_all();
-       outer_disable();
-
-       highbank_set_pwr_suspend();
-
-       cpu_do_idle();
+       const struct psci_power_state ps = {
+               .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
+               .affinity_level = 1,
+       };
 
-       highbank_clear_pwr_request();
-       return 0;
+       return psci_ops.cpu_suspend(ps, __pa(cpu_resume));
 }
 
 static int highbank_pm_enter(suspend_state_t state)
@@ -44,15 +36,11 @@ static int highbank_pm_enter(suspend_state_t state)
        cpu_pm_enter();
        cpu_cluster_pm_enter();
 
-       highbank_set_cpu_jump(0, cpu_resume);
        cpu_suspend(0, highbank_suspend_finish);
 
        cpu_cluster_pm_exit();
        cpu_pm_exit();
 
-       highbank_smc1(0x102, 0x1);
-       if (scu_base_addr)
-               scu_enable(scu_base_addr);
        return 0;
 }
 
@@ -63,5 +51,8 @@ static const struct platform_suspend_ops highbank_pm_ops = {
 
 void __init highbank_pm_init(void)
 {
+       if (!psci_ops.cpu_suspend)
+               return;
+
        suspend_set_ops(&highbank_pm_ops);
 }
index 29a8af6922a87eeb445eacc6971c3aaa15f6bcf9..7a6e6f71006893a9c2a54d4a17166762c4647977 100644 (file)
@@ -4,13 +4,14 @@ config ARCH_MXC
        select ARM_CPU_SUSPEND if PM
        select ARM_PATCH_PHYS_VIRT
        select AUTO_ZRELADDR if !ZBOOT_ROM
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
+       select COMMON_CLK
        select GENERIC_ALLOCATOR
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
        select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7
        select MULTI_IRQ_HANDLER
+       select SOC_BUS
        select SPARSE_IRQ
        select USE_OF
        help
@@ -24,7 +25,7 @@ config MXC_IRQ_PRIOR
        help
          Select this if you want to use prioritized IRQ handling.
          This feature prevents higher priority ISR to be interrupted
-         by lower priority IRQ even IRQF_DISABLED flag is not set.
+         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.
@@ -92,14 +93,12 @@ config MACH_MX27
 config SOC_IMX1
        bool
        select ARCH_MX1
-       select COMMON_CLK
        select CPU_ARM920T
        select IMX_HAVE_IOMUX_V1
        select MXC_AVIC
 
 config SOC_IMX21
        bool
-       select COMMON_CLK
        select CPU_ARM926T
        select IMX_HAVE_IOMUX_V1
        select MXC_AVIC
@@ -108,7 +107,6 @@ config SOC_IMX25
        bool
        select ARCH_MX25
        select ARCH_MXC_IOMUX_V3
-       select COMMON_CLK
        select CPU_ARM926T
        select MXC_AVIC
 
@@ -116,7 +114,6 @@ config SOC_IMX27
        bool
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
-       select COMMON_CLK
        select CPU_ARM926T
        select IMX_HAVE_IOMUX_V1
        select MACH_MX27
@@ -124,7 +121,6 @@ config SOC_IMX27
 
 config SOC_IMX31
        bool
-       select COMMON_CLK
        select CPU_V6
        select IMX_HAVE_PLATFORM_MXC_RNGA
        select MXC_AVIC
@@ -133,7 +129,6 @@ config SOC_IMX31
 config SOC_IMX35
        bool
        select ARCH_MXC_IOMUX_V3
-       select COMMON_CLK
        select CPU_V6K
        select HAVE_EPIT
        select MXC_AVIC
@@ -144,7 +139,6 @@ config SOC_IMX5
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARCH_MXC_IOMUX_V3
-       select COMMON_CLK
        select CPU_V7
        select MXC_TZIC
 
@@ -791,7 +785,6 @@ config SOC_IMX6Q
        select ARM_ERRATA_764369 if SMP
        select ARM_ERRATA_775420
        select ARM_GIC
-       select COMMON_CLK
        select CPU_V7
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
@@ -801,6 +794,8 @@ config SOC_IMX6Q
        select HAVE_IMX_SRC
        select HAVE_SMP
        select MFD_SYSCON
+       select MIGHT_HAVE_PCI
+       select PCI_DOMAINS if PCI
        select PINCTRL
        select PINCTRL_IMX6Q
        select PL310_ERRATA_588369 if CACHE_PL310
index 5383c589ad719105d104c077bac14ff73e1933eb..bbe1f5bb799c1a0db3cd403f01767b2a7af4471b 100644 (file)
@@ -102,6 +102,8 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
 
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
+# i.MX6SL reuses pm-imx6q.c
+obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o
 endif
 
 # i.MX5 based machines
index ad3b755abb78a949d1b379757a11725a983f2d3b..4a40bbb46183a850af387151c58b73569f55182a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include "common.h"
+#include "hardware.h"
 
 #define REG_SET                0x4
 #define REG_CLR                0x8
@@ -26,6 +27,7 @@
 #define ANADIG_USB1_CHRG_DETECT        0x1b0
 #define ANADIG_USB2_CHRG_DETECT        0x210
 #define ANADIG_DIGPROG         0x260
+#define ANADIG_DIGPROG_IMX6SL  0x280
 
 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG   0x40000
 #define BM_ANADIG_REG_CORE_FET_ODRIVE          0x20000000
@@ -76,21 +78,38 @@ static void imx_anatop_usb_chrg_detect_disable(void)
                BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
 }
 
-u32 imx_anatop_get_digprog(void)
+void __init imx_init_revision_from_anatop(void)
 {
        struct device_node *np;
        void __iomem *anatop_base;
-       static u32 digprog;
-
-       if (digprog)
-               return digprog;
+       unsigned int revision;
+       u32 digprog;
+       u16 offset = ANADIG_DIGPROG;
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
        anatop_base = of_iomap(np, 0);
        WARN_ON(!anatop_base);
-       digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG);
+       if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
+               offset = ANADIG_DIGPROG_IMX6SL;
+       digprog = readl_relaxed(anatop_base + offset);
+       iounmap(anatop_base);
+
+       switch (digprog & 0xff) {
+       case 0:
+               revision = IMX_CHIP_REVISION_1_0;
+               break;
+       case 1:
+               revision = IMX_CHIP_REVISION_1_1;
+               break;
+       case 2:
+               revision = IMX_CHIP_REVISION_1_2;
+               break;
+       default:
+               revision = IMX_CHIP_REVISION_UNKNOWN;
+       }
 
-       return digprog;
+       mxc_set_cpu_type(digprog >> 16 & 0xff);
+       imx_set_soc_revision(revision);
 }
 
 void __init imx_anatop_init(void)
index 7c0dc4540aa4785270784e3f62ce2b643fd95664..ce37af26ff8c6931b62e9459d7ffb7df1daf81ab 100644 (file)
 #include <linux/clk.h>
 #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 "crm-regs-imx5.h"
 #include "clk.h"
@@ -131,8 +135,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
 {
        int i;
 
-       of_clk_init(NULL);
-
        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);
@@ -465,12 +467,17 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        return 0;
 }
 
-int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
-                       unsigned long rate_ckih1, unsigned long rate_ckih2)
+static void __init mx51_clocks_init_dt(struct device_node *np)
 {
-       int i;
+       mx51_clocks_init(0, 0, 0, 0);
+}
+CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init_dt);
+
+static void __init mx53_clocks_init(struct device_node *np)
+{
+       int i, irq;
        unsigned long r;
-       struct device_node *np;
+       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);
@@ -529,12 +536,11 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
                        pr_err("i.MX53 clk %d: register failed with %ld\n",
                                i, PTR_ERR(clk[i]));
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx53-ccm");
        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(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
+       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");
@@ -557,9 +563,6 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        clk_set_rate(clk[esdhc_a_podf], 200000000);
        clk_set_rate(clk[esdhc_b_podf], 200000000);
 
-       /* System timer */
-       mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT);
-
        clk_prepare_enable(clk[iim_gate]);
        imx_print_silicon_rev("i.MX53", mx53_revision());
        clk_disable_unprepare(clk[iim_gate]);
@@ -567,15 +570,10 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        r = clk_round_rate(clk[usboh3_per_gate], 54000000);
        clk_set_rate(clk[usboh3_per_gate], r);
 
-       return 0;
-}
-
-int __init mx51_clocks_init_dt(void)
-{
-       return mx51_clocks_init(0, 0, 0, 0);
-}
-
-int __init mx53_clocks_init_dt(void)
-{
-       return mx53_clocks_init(0, 0, 0, 0);
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx53-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(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
index 9181a241d3a8e543c41a2433b38cbfa6b774de02..d756d91fd74163852b810a0b0d578eaac5236552 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/types.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
-#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include "common.h"
 #include "hardware.h"
 
-#define CCR                            0x0
-#define BM_CCR_WB_COUNT                        (0x7 << 16)
-#define BM_CCR_RBC_BYPASS_COUNT                (0x3f << 21)
-#define BM_CCR_RBC_EN                  (0x1 << 27)
-
-#define CCGR0                          0x68
-#define CCGR1                          0x6c
-#define CCGR2                          0x70
-#define CCGR3                          0x74
-#define CCGR4                          0x78
-#define CCGR5                          0x7c
-#define CCGR6                          0x80
-#define CCGR7                          0x84
-
-#define CLPCR                          0x54
-#define BP_CLPCR_LPM                   0
-#define BM_CLPCR_LPM                   (0x3 << 0)
-#define BM_CLPCR_BYPASS_PMIC_READY     (0x1 << 2)
-#define BM_CLPCR_ARM_CLK_DIS_ON_LPM    (0x1 << 5)
-#define BM_CLPCR_SBYOS                 (0x1 << 6)
-#define BM_CLPCR_DIS_REF_OSC           (0x1 << 7)
-#define BM_CLPCR_VSTBY                 (0x1 << 8)
-#define BP_CLPCR_STBY_COUNT            9
-#define BM_CLPCR_STBY_COUNT            (0x3 << 9)
-#define BM_CLPCR_COSC_PWRDOWN          (0x1 << 11)
-#define BM_CLPCR_WB_PER_AT_LPM         (0x1 << 16)
-#define BM_CLPCR_WB_CORE_AT_LPM                (0x1 << 17)
-#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS   (0x1 << 19)
-#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS   (0x1 << 21)
-#define BM_CLPCR_MASK_CORE0_WFI                (0x1 << 22)
-#define BM_CLPCR_MASK_CORE1_WFI                (0x1 << 23)
-#define BM_CLPCR_MASK_CORE2_WFI                (0x1 << 24)
-#define BM_CLPCR_MASK_CORE3_WFI                (0x1 << 25)
-#define BM_CLPCR_MASK_SCU_IDLE         (0x1 << 26)
-#define BM_CLPCR_MASK_L2CC_IDLE                (0x1 << 27)
-
-#define CGPR                           0x64
-#define BM_CGPR_CHICKEN_BIT            (0x1 << 17)
-
-static void __iomem *ccm_base;
-
-void imx6q_set_chicken_bit(void)
-{
-       u32 val = readl_relaxed(ccm_base + CGPR);
-
-       val |= BM_CGPR_CHICKEN_BIT;
-       writel_relaxed(val, ccm_base + CGPR);
-}
-
-static void imx6q_enable_rbc(bool enable)
-{
-       u32 val;
-       static bool last_rbc_mode;
-
-       if (last_rbc_mode == enable)
-               return;
-       /*
-        * need to mask all interrupts in GPC before
-        * operating RBC configurations
-        */
-       imx_gpc_mask_all();
-
-       /* configure RBC enable bit */
-       val = readl_relaxed(ccm_base + CCR);
-       val &= ~BM_CCR_RBC_EN;
-       val |= enable ? BM_CCR_RBC_EN : 0;
-       writel_relaxed(val, ccm_base + CCR);
-
-       /* configure RBC count */
-       val = readl_relaxed(ccm_base + CCR);
-       val &= ~BM_CCR_RBC_BYPASS_COUNT;
-       val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
-       writel(val, ccm_base + CCR);
-
-       /*
-        * need to delay at least 2 cycles of CKIL(32K)
-        * due to hardware design requirement, which is
-        * ~61us, here we use 65us for safe
-        */
-       udelay(65);
-
-       /* restore GPC interrupt mask settings */
-       imx_gpc_restore_all();
-
-       last_rbc_mode = enable;
-}
-
-static void imx6q_enable_wb(bool enable)
-{
-       u32 val;
-       static bool last_wb_mode;
-
-       if (last_wb_mode == enable)
-               return;
-
-       /* configure well bias enable bit */
-       val = readl_relaxed(ccm_base + CLPCR);
-       val &= ~BM_CLPCR_WB_PER_AT_LPM;
-       val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
-       writel_relaxed(val, ccm_base + CLPCR);
-
-       /* configure well bias count */
-       val = readl_relaxed(ccm_base + CCR);
-       val &= ~BM_CCR_WB_COUNT;
-       val |= enable ? BM_CCR_WB_COUNT : 0;
-       writel_relaxed(val, ccm_base + CCR);
-
-       last_wb_mode = enable;
-}
-
-int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-{
-       u32 val = readl_relaxed(ccm_base + CLPCR);
-
-       val &= ~BM_CLPCR_LPM;
-       switch (mode) {
-       case WAIT_CLOCKED:
-               imx6q_enable_wb(false);
-               imx6q_enable_rbc(false);
-               break;
-       case WAIT_UNCLOCKED:
-               val |= 0x1 << BP_CLPCR_LPM;
-               val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
-               break;
-       case STOP_POWER_ON:
-               val |= 0x2 << BP_CLPCR_LPM;
-               break;
-       case WAIT_UNCLOCKED_POWER_OFF:
-               val |= 0x1 << BP_CLPCR_LPM;
-               val &= ~BM_CLPCR_VSTBY;
-               val &= ~BM_CLPCR_SBYOS;
-               break;
-       case STOP_POWER_OFF:
-               val |= 0x2 << BP_CLPCR_LPM;
-               val |= 0x3 << BP_CLPCR_STBY_COUNT;
-               val |= BM_CLPCR_VSTBY;
-               val |= BM_CLPCR_SBYOS;
-               imx6q_enable_wb(true);
-               imx6q_enable_rbc(true);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       writel_relaxed(val, ccm_base + CLPCR);
-
-       return 0;
-}
-
 static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
 static const char *pll1_sw_sels[]      = { "pll1_sys", "step", };
 static const char *periph_pre_sels[]   = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
@@ -182,7 +32,7 @@ static const char *periph2_clk2_sels[]       = { "pll3_usb_otg", "pll2_bus", };
 static const char *periph_sels[]       = { "periph_pre", "periph_clk2", };
 static const char *periph2_sels[]      = { "periph2_pre", "periph2_clk2", };
 static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
-static const char *audio_sels[]        = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
+static const char *audio_sels[]        = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
 static const char *gpu_axi_sels[]      = { "axi", "ahb", };
 static const char *gpu2d_core_sels[]   = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
 static const char *gpu3d_core_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
@@ -196,7 +46,7 @@ static const char *ipu2_di0_sels[]   = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di
 static const char *ipu2_di1_sels[]     = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *hsi_tx_sels[]       = { "pll3_120m", "pll2_pfd2_396m", };
 static const char *pcie_axi_sels[]     = { "axi", "ahb", };
-static const char *ssi_sels[]          = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", };
+static const char *ssi_sels[]          = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", };
 static const char *usdhc_sels[]        = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
 static const char *emi_sels[]          = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
@@ -205,7 +55,7 @@ static const char *vdo_axi_sels[]    = { "axi", "ahb", };
 static const char *vpu_axi_sels[]      = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
                                    "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
-                                   "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
+                                   "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", };
 static const char *cko2_sels[] = {
        "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1",
        "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi",
@@ -217,6 +67,11 @@ static const char *cko2_sels[] = {
        "uart_serial", "spdif", "asrc", "hsi_tx",
 };
 static const char *cko_sels[] = { "cko1", "cko2", };
+static const char *lvds_sels[] = {
+       "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+       "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
+       "pcie_ref", "sata_ref",
+};
 
 enum mx6q_clks {
        dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
@@ -251,7 +106,8 @@ enum mx6q_clks {
        ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
        sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
        usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
-       spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, clk_max
+       spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
+       lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -300,7 +156,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        WARN_ON(!base);
 
        /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
-       if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) {
+       if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
                post_div_table[1].div = 1;
                post_div_table[2].div = 1;
                video_div_table[1].div = 1;
@@ -342,6 +198,18 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
                        base + 0xe0, 0, 2, 0, clk_enet_ref_table,
                        &imx_ccm_lock);
 
+       clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+       clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+
+       /*
+        * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be
+        * independently configured as clock inputs or outputs.  We treat
+        * the "output_enable" bit as a gate, even though it's really just
+        * enabling clock output.
+        */
+       clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
+       clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
+
        /*                                name              parent_name        reg       idx */
        clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
        clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
@@ -359,13 +227,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[twd]       = imx_clk_fixed_factor("twd",       "arm",            1, 2);
 
        clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+       clk[pll4_audio_div] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
        clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
        clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
 
        np = ccm_node;
        base = of_iomap(np, 0);
        WARN_ON(!base);
-       ccm_base = base;
+
+       imx6q_pm_set_ccm_base(base);
 
        /*                                  name                reg       shift width parent_names     num_parents */
        clk[step]             = imx_clk_mux("step",             base + 0xc,  8,  1, step_sels,         ARRAY_SIZE(step_sels));
@@ -573,7 +443,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
        clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
 
-       if ((imx6q_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
+       if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
+           cpu_is_imx6dl()) {
                clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
                clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
        }
@@ -603,8 +474,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        if (ret)
                pr_warn("failed to set up CLKO: %d\n", ret);
 
-       /* Set initial power mode */
-       imx6q_set_lpm(WAIT_CLOCKED);
+       /* All existing boards with PCIe use LVDS1 */
+       if (IS_ENABLED(CONFIG_PCI_IMX6))
+               clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
        base = of_iomap(np, 0);
index a5c3c5d21aeedbcb324bca659730948f3e8d1a36..c0c4ef55e35bd7e522b4f83d038d50f752265db4 100644 (file)
@@ -127,6 +127,9 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
+       /* Reuse imx6q pm code */
+       imx6q_pm_set_ccm_base(base);
+
        /*                                              name                reg       shift width parent_names     num_parents */
        clks[IMX6SL_CLK_STEP]             = imx_clk_mux("step",             base + 0xc,  8,  1, step_sels,         ARRAY_SIZE(step_sels));
        clks[IMX6SL_CLK_PLL1_SW]          = imx_clk_mux("pll1_sw",          base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
index 4517fd760bfc6d0c55a160f7fa22f8f3e1ae778c..7cbe22d0c6e9c8ae4060e71c06d2c7eb73c0d389 100644 (file)
 
 #include <linux/reboot.h>
 
+struct irq_data;
 struct platform_device;
 struct pt_regs;
 struct clk;
 enum mxc_cpu_pwr_mode;
 
-extern void mx1_map_io(void);
-extern void mx21_map_io(void);
-extern void mx25_map_io(void);
-extern void mx27_map_io(void);
-extern void mx31_map_io(void);
-extern void mx35_map_io(void);
-extern void mx51_map_io(void);
-extern void mx53_map_io(void);
-extern void imx1_init_early(void);
-extern void imx21_init_early(void);
-extern void imx25_init_early(void);
-extern void imx27_init_early(void);
-extern void imx31_init_early(void);
-extern void imx35_init_early(void);
-extern void imx51_init_early(void);
-extern void imx53_init_early(void);
-extern void mxc_init_irq(void __iomem *);
-extern void tzic_init_irq(void __iomem *);
-extern void mx1_init_irq(void);
-extern void mx21_init_irq(void);
-extern void mx25_init_irq(void);
-extern void mx27_init_irq(void);
-extern void mx31_init_irq(void);
-extern void mx35_init_irq(void);
-extern void mx51_init_irq(void);
-extern void mx53_init_irq(void);
-extern void imx1_soc_init(void);
-extern void imx21_soc_init(void);
-extern void imx25_soc_init(void);
-extern void imx27_soc_init(void);
-extern void imx31_soc_init(void);
-extern void imx35_soc_init(void);
-extern void imx51_soc_init(void);
-extern void imx51_init_late(void);
-extern void imx53_init_late(void);
-extern void epit_timer_init(void __iomem *base, int irq);
-extern void mxc_timer_init(void __iomem *, int);
-extern int mx1_clocks_init(unsigned long fref);
-extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
-extern int mx25_clocks_init(void);
-extern int mx27_clocks_init(unsigned long fref);
-extern int mx31_clocks_init(unsigned long fref);
-extern int mx35_clocks_init(void);
-extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
+void mx1_map_io(void);
+void mx21_map_io(void);
+void mx25_map_io(void);
+void mx27_map_io(void);
+void mx31_map_io(void);
+void mx35_map_io(void);
+void mx51_map_io(void);
+void mx53_map_io(void);
+void imx1_init_early(void);
+void imx21_init_early(void);
+void imx25_init_early(void);
+void imx27_init_early(void);
+void imx31_init_early(void);
+void imx35_init_early(void);
+void imx51_init_early(void);
+void imx53_init_early(void);
+void mxc_init_irq(void __iomem *);
+void tzic_init_irq(void __iomem *);
+void mx1_init_irq(void);
+void mx21_init_irq(void);
+void mx25_init_irq(void);
+void mx27_init_irq(void);
+void mx31_init_irq(void);
+void mx35_init_irq(void);
+void mx51_init_irq(void);
+void mx53_init_irq(void);
+void imx1_soc_init(void);
+void imx21_soc_init(void);
+void imx25_soc_init(void);
+void imx27_soc_init(void);
+void imx31_soc_init(void);
+void imx35_soc_init(void);
+void imx51_soc_init(void);
+void imx51_init_late(void);
+void imx53_init_late(void);
+void epit_timer_init(void __iomem *base, int irq);
+void mxc_timer_init(void __iomem *, int);
+int mx1_clocks_init(unsigned long fref);
+int mx21_clocks_init(unsigned long lref, unsigned long fref);
+int mx25_clocks_init(void);
+int mx27_clocks_init(unsigned long fref);
+int mx31_clocks_init(unsigned long fref);
+int mx35_clocks_init(void);
+int mx51_clocks_init(unsigned long ckil, unsigned long osc,
                        unsigned long ckih1, unsigned long ckih2);
-extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
-                       unsigned long ckih1, unsigned long ckih2);
-extern int mx25_clocks_init_dt(void);
-extern int mx27_clocks_init_dt(void);
-extern int mx31_clocks_init_dt(void);
-extern int mx51_clocks_init_dt(void);
-extern int mx53_clocks_init_dt(void);
-extern struct platform_device *mxc_register_gpio(char *name, int id,
+int mx25_clocks_init_dt(void);
+int mx27_clocks_init_dt(void);
+int mx31_clocks_init_dt(void);
+struct platform_device *mxc_register_gpio(char *name, int id,
        resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
-extern void mxc_set_cpu_type(unsigned int type);
-extern void mxc_restart(enum reboot_mode, const char *);
-extern void mxc_arch_reset_init(void __iomem *);
-extern void mxc_arch_reset_init_dt(void);
-extern int mx53_revision(void);
-extern int imx6q_revision(void);
-extern int mx53_display_revision(void);
-extern void imx_set_aips(void __iomem *);
-extern int mxc_device_init(void);
+void mxc_set_cpu_type(unsigned int type);
+void mxc_restart(enum reboot_mode, const char *);
+void mxc_arch_reset_init(void __iomem *);
+void mxc_arch_reset_init_dt(void);
+int mx53_revision(void);
+void imx_set_aips(void __iomem *);
+int mxc_device_init(void);
+void imx_set_soc_revision(unsigned int rev);
+unsigned int imx_get_soc_revision(void);
+void imx_init_revision_from_anatop(void);
+struct device *imx_soc_device_init(void);
 
 enum mxc_cpu_pwr_mode {
        WAIT_CLOCKED,           /* wfi only */
@@ -97,8 +96,8 @@ enum mx3_cpu_pwr_mode {
        MX3_SLEEP,
 };
 
-extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
-extern void imx_print_silicon_rev(const char *cpu, int srev);
+void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
+void imx_print_silicon_rev(const char *cpu, int srev);
 
 void avic_handle_irq(struct pt_regs *);
 void tzic_handle_irq(struct pt_regs *);
@@ -112,54 +111,61 @@ void tzic_handle_irq(struct pt_regs *);
 #define imx51_handle_irq tzic_handle_irq
 #define imx53_handle_irq tzic_handle_irq
 
-extern void imx_enable_cpu(int cpu, bool enable);
-extern void imx_set_cpu_jump(int cpu, void *jump_addr);
-extern u32 imx_get_cpu_arg(int cpu);
-extern void imx_set_cpu_arg(int cpu, u32 arg);
-extern void v7_cpu_resume(void);
+void imx_enable_cpu(int cpu, bool enable);
+void imx_set_cpu_jump(int cpu, void *jump_addr);
+u32 imx_get_cpu_arg(int cpu);
+void imx_set_cpu_arg(int cpu, u32 arg);
+void v7_cpu_resume(void);
 #ifdef CONFIG_SMP
-extern void v7_secondary_startup(void);
-extern void imx_scu_map_io(void);
-extern void imx_smp_prepare(void);
-extern void imx_scu_standby_enable(void);
+void v7_secondary_startup(void);
+void imx_scu_map_io(void);
+void imx_smp_prepare(void);
+void imx_scu_standby_enable(void);
 #else
 static inline void imx_scu_map_io(void) {}
 static inline void imx_smp_prepare(void) {}
 static inline void imx_scu_standby_enable(void) {}
 #endif
-extern void imx_src_init(void);
-extern void imx_src_prepare_restart(void);
-extern void imx_gpc_init(void);
-extern void imx_gpc_pre_suspend(void);
-extern void imx_gpc_post_resume(void);
-extern void imx_gpc_mask_all(void);
-extern void imx_gpc_restore_all(void);
-extern void imx_anatop_init(void);
-extern void imx_anatop_pre_suspend(void);
-extern void imx_anatop_post_resume(void);
-extern u32 imx_anatop_get_digprog(void);
-extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
-extern void imx6q_set_chicken_bit(void);
-
-extern void imx_cpu_die(unsigned int cpu);
-extern int imx_cpu_kill(unsigned int cpu);
+void imx_src_init(void);
+#ifdef CONFIG_HAVE_IMX_SRC
+void imx_src_prepare_restart(void);
+#else
+static inline void imx_src_prepare_restart(void) {}
+#endif
+void imx_gpc_init(void);
+void imx_gpc_pre_suspend(void);
+void imx_gpc_post_resume(void);
+void imx_gpc_mask_all(void);
+void imx_gpc_restore_all(void);
+void imx_gpc_irq_mask(struct irq_data *d);
+void imx_gpc_irq_unmask(struct irq_data *d);
+void imx_anatop_init(void);
+void imx_anatop_pre_suspend(void);
+void imx_anatop_post_resume(void);
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
+void imx6q_set_chicken_bit(void);
+
+void imx_cpu_die(unsigned int cpu);
+int imx_cpu_kill(unsigned int cpu);
 
 #ifdef CONFIG_PM
-extern void imx6q_pm_init(void);
-extern void imx5_pm_init(void);
+void imx6q_pm_init(void);
+void imx6q_pm_set_ccm_base(void __iomem *base);
+void imx5_pm_init(void);
 #else
 static inline void imx6q_pm_init(void) {}
+static inline void imx6q_pm_set_ccm_base(void __iomem *base) {}
 static inline void imx5_pm_init(void) {}
 #endif
 
 #ifdef CONFIG_NEON
-extern int mx51_neon_fixup(void);
+int mx51_neon_fixup(void);
 #else
 static inline int mx51_neon_fixup(void) { return 0; }
 #endif
 
 #ifdef CONFIG_CACHE_L2X0
-extern void imx_init_l2cache(void);
+void imx_init_l2cache(void);
 #else
 static inline void imx_init_l2cache(void) {}
 #endif
index e70e3acbf9bd04516257010c86958e99da766e04..ba3b498a67ecc47e78198d756b21aa6197f46ebc 100644 (file)
@@ -1,6 +1,9 @@
-
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
 
 #include "hardware.h"
 #include "common.h"
 unsigned int __mxc_cpu_type;
 EXPORT_SYMBOL(__mxc_cpu_type);
 
+static unsigned int imx_soc_revision;
+
 void mxc_set_cpu_type(unsigned int type)
 {
        __mxc_cpu_type = type;
 }
 
+void imx_set_soc_revision(unsigned int rev)
+{
+       imx_soc_revision = rev;
+}
+
+unsigned int imx_get_soc_revision(void)
+{
+       return imx_soc_revision;
+}
+
 void imx_print_silicon_rev(const char *cpu, int srev)
 {
        if (srev == IMX_CHIP_REVISION_UNKNOWN)
@@ -44,3 +59,81 @@ void __init imx_set_aips(void __iomem *base)
        reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
        __raw_writel(reg, base + 0x50);
 }
+
+struct device * __init imx_soc_device_init(void)
+{
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device_node *root;
+       const char *soc_id;
+       int ret;
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return NULL;
+
+       soc_dev_attr->family = "Freescale i.MX";
+
+       root = of_find_node_by_path("/");
+       ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+       of_node_put(root);
+       if (ret)
+               goto free_soc;
+
+       switch (__mxc_cpu_type) {
+       case MXC_CPU_MX1:
+               soc_id = "i.MX1";
+               break;
+       case MXC_CPU_MX21:
+               soc_id = "i.MX21";
+               break;
+       case MXC_CPU_MX25:
+               soc_id = "i.MX25";
+               break;
+       case MXC_CPU_MX27:
+               soc_id = "i.MX27";
+               break;
+       case MXC_CPU_MX31:
+               soc_id = "i.MX31";
+               break;
+       case MXC_CPU_MX35:
+               soc_id = "i.MX35";
+               break;
+       case MXC_CPU_MX51:
+               soc_id = "i.MX51";
+               break;
+       case MXC_CPU_MX53:
+               soc_id = "i.MX53";
+               break;
+       case MXC_CPU_IMX6SL:
+               soc_id = "i.MX6SL";
+               break;
+       case MXC_CPU_IMX6DL:
+               soc_id = "i.MX6DL";
+               break;
+       case MXC_CPU_IMX6Q:
+               soc_id = "i.MX6Q";
+               break;
+       default:
+               soc_id = "Unknown";
+       }
+       soc_dev_attr->soc_id = soc_id;
+
+       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
+                                          (imx_soc_revision >> 4) & 0xf,
+                                          imx_soc_revision & 0xf);
+       if (!soc_dev_attr->revision)
+               goto free_soc;
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev))
+               goto free_rev;
+
+       return soc_device_to_device(soc_dev);
+
+free_rev:
+       kfree(soc_dev_attr->revision);
+free_soc:
+       kfree(soc_dev_attr);
+       return NULL;
+}
index e02de188ae83ba7a5e51b4184f1cc85c05c86d34..074b1a81ba764aa2caeecf6f973c3807e2f5b4a2 100644 (file)
@@ -171,7 +171,7 @@ static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction epit_timer_irq = {
        .name           = "i.MX EPIT Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = epit_timer_interrupt,
 };
 
index 44a65e9ff1fc9366bb62c35242c4f6dcc188a0d2..586e0171a65294200bb2d1a0c9115c73975fb2aa 100644 (file)
@@ -90,7 +90,7 @@ void imx_gpc_restore_all(void)
                writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
 }
 
-static void imx_gpc_irq_unmask(struct irq_data *d)
+void imx_gpc_irq_unmask(struct irq_data *d)
 {
        void __iomem *reg;
        u32 val;
@@ -105,7 +105,7 @@ static void imx_gpc_irq_unmask(struct irq_data *d)
        writel_relaxed(val, reg);
 }
 
-static void imx_gpc_irq_mask(struct irq_data *d)
+void imx_gpc_irq_mask(struct irq_data *d)
 {
        void __iomem *reg;
        u32 val;
index 3daf1ed90579a74a97f4d25f4292d8d09e50a1f5..b35e99cc5e5b4f20ae32b7968ad2698941591d98 100644 (file)
@@ -52,7 +52,9 @@ void imx_cpu_die(unsigned int cpu)
         * the register being cleared to kill the cpu.
         */
        imx_set_cpu_arg(cpu, ~0);
-       cpu_do_idle();
+
+       while (1)
+               cpu_do_idle();
 }
 
 int imx_cpu_kill(unsigned int cpu)
index 53e43e579dd79afbb755360d7ff8f8936dcc4d86..bece8a65e6f01893e9e58df0799b580b8c356365 100644 (file)
@@ -34,17 +34,11 @@ static const char *imx51_dt_board_compat[] __initdata = {
        NULL
 };
 
-static void __init imx51_timer_init(void)
-{
-       mx51_clocks_init_dt();
-}
-
 DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
        .map_io         = mx51_map_io,
        .init_early     = imx51_init_early,
        .init_irq       = mx51_init_irq,
        .handle_irq     = imx51_handle_irq,
-       .init_time      = imx51_timer_init,
        .init_machine   = imx51_dt_init,
        .init_late      = imx51_init_late,
        .dt_compat      = imx51_dt_board_compat,
index 368a6e3f5926b2d62c12e17fc6ecf8216e4be06c..58b864a3fc207a9df50c911e17930c00d93a584c 100644 (file)
@@ -404,8 +404,7 @@ static int armadillo5x0_sdhc1_init(struct device *dev,
 
        /* When supported the trigger type have to be BOTH */
        ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)),
-                         detect_irq,
-                         IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+                         detect_irq, IRQF_TRIGGER_FALLING,
                          "sdhc-detect", data);
 
        if (ret)
index 98c58944015a596db1431e770f5a5c9765300227..c9c4d8d96931daf05794c4bab73facedb9fb943c 100644 (file)
@@ -36,17 +36,11 @@ static const char *imx53_dt_board_compat[] __initdata = {
        NULL
 };
 
-static void __init imx53_timer_init(void)
-{
-       mx53_clocks_init_dt();
-}
-
 DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
        .map_io         = mx53_map_io,
        .init_early     = imx53_init_early,
        .init_irq       = mx53_init_irq,
        .handle_irq     = imx53_handle_irq,
-       .init_time      = imx53_timer_init,
        .init_machine   = imx53_dt_init,
        .init_late      = imx53_init_late,
        .dt_compat      = imx53_dt_board_compat,
index 90372a21087f9ef38535479ccc35aac9e37977dc..0f9f24116daaf21aed4041da8ff82fed4d331b53 100644 (file)
  */
 
 #include <linux/clk.h>
-#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
-#include <linux/clocksource.h>
 #include <linux/cpu.h>
-#include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include "cpuidle.h"
 #include "hardware.h"
 
-static u32 chip_revision;
-
-int imx6q_revision(void)
-{
-       return chip_revision;
-}
-
-static void __init imx6q_init_revision(void)
-{
-       u32 rev = imx_anatop_get_digprog();
-
-       switch (rev & 0xff) {
-       case 0:
-               chip_revision = IMX_CHIP_REVISION_1_0;
-               break;
-       case 1:
-               chip_revision = IMX_CHIP_REVISION_1_1;
-               break;
-       case 2:
-               chip_revision = IMX_CHIP_REVISION_1_2;
-               break;
-       default:
-               chip_revision = IMX_CHIP_REVISION_UNKNOWN;
-       }
-
-       mxc_set_cpu_type(rev >> 16 & 0xff);
-}
-
-static void imx6q_restart(enum reboot_mode mode, const char *cmd)
-{
-       struct device_node *np;
-       void __iomem *wdog_base;
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt");
-       wdog_base = of_iomap(np, 0);
-       if (!wdog_base)
-               goto soft;
-
-       imx_src_prepare_restart();
-
-       /* enable wdog */
-       writew_relaxed(1 << 2, wdog_base);
-       /* write twice to ensure the request will not get ignored */
-       writew_relaxed(1 << 2, wdog_base);
-
-       /* wait for reset to assert ... */
-       mdelay(500);
-
-       pr_err("Watchdog reset failed to assert reset\n");
-
-       /* delay to allow the serial port to show the message */
-       mdelay(50);
-
-soft:
-       /* we'll take a jump through zero as a poor second */
-       soft_restart(0);
-}
-
 /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
 static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 {
@@ -192,9 +131,20 @@ static void __init imx6q_1588_init(void)
 
 static void __init imx6q_init_machine(void)
 {
+       struct device *parent;
+
+       imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
+                             imx_get_soc_revision());
+
+       mxc_arch_reset_init_dt();
+
+       parent = imx_soc_device_init();
+       if (parent == NULL)
+               pr_warn("failed to initialize soc device\n");
+
        imx6q_enet_phy_init();
 
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
 
        imx_anatop_init();
        imx6q_pm_init();
@@ -269,7 +219,7 @@ static void __init imx6q_init_late(void)
         * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
         * to run cpuidle on them.
         */
-       if (imx6q_revision() > IMX_CHIP_REVISION_1_1)
+       if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
                imx6q_cpuidle_init();
 
        if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
@@ -286,21 +236,13 @@ static void __init imx6q_map_io(void)
 
 static void __init imx6q_init_irq(void)
 {
-       imx6q_init_revision();
+       imx_init_revision_from_anatop();
        imx_init_l2cache();
        imx_src_init();
        imx_gpc_init();
        irqchip_init();
 }
 
-static void __init imx6q_timer_init(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-       imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
-                             imx6q_revision());
-}
-
 static const char *imx6q_dt_compat[] __initdata = {
        "fsl,imx6dl",
        "fsl,imx6q",
@@ -311,9 +253,8 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
        .smp            = smp_ops(imx_smp_ops),
        .map_io         = imx6q_map_io,
        .init_irq       = imx6q_init_irq,
-       .init_time      = imx6q_timer_init,
        .init_machine   = imx6q_init_machine,
        .init_late      = imx6q_init_late,
        .dt_compat      = imx6q_dt_compat,
-       .restart        = imx6q_restart,
+       .restart        = mxc_restart,
 MACHINE_END
index 0d75dc54f71508fa48cf3a3096931aed8db31bce..2f952e3fcf899172b40ffc7e1cfff7aa94718bc2 100644 (file)
@@ -7,35 +7,60 @@
  *
  */
 
-#include <linux/clk-provider.h>
 #include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/regmap.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include "common.h"
 
+static void __init imx6sl_fec_init(void)
+{
+       struct regmap *gpr;
+
+       /* set FEC clock from internal PLL clock source */
+       gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sl-iomuxc-gpr");
+       if (!IS_ERR(gpr)) {
+               regmap_update_bits(gpr, IOMUXC_GPR1,
+                       IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0);
+               regmap_update_bits(gpr, IOMUXC_GPR1,
+                       IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
+       } else {
+               pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
+       }
+}
+
 static void __init imx6sl_init_machine(void)
 {
+       struct device *parent;
+
        mxc_arch_reset_init_dt();
 
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       parent = imx_soc_device_init();
+       if (parent == NULL)
+               pr_warn("failed to initialize soc device\n");
+
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
+
+       imx6sl_fec_init();
+       imx_anatop_init();
+       /* Reuse imx6q pm code */
+       imx6q_pm_init();
 }
 
 static void __init imx6sl_init_irq(void)
 {
+       imx_init_revision_from_anatop();
        imx_init_l2cache();
        imx_src_init();
        imx_gpc_init();
        irqchip_init();
 }
 
-static void __init imx6sl_timer_init(void)
-{
-       of_clk_init(NULL);
-}
-
 static const char *imx6sl_dt_compat[] __initdata = {
        "fsl,imx6sl",
        NULL,
@@ -44,7 +69,6 @@ static const char *imx6sl_dt_compat[] __initdata = {
 DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)")
        .map_io         = debug_ll_io_init,
        .init_irq       = imx6sl_init_irq,
-       .init_time      = imx6sl_timer_init,
        .init_machine   = imx6sl_init_machine,
        .dt_compat      = imx6sl_dt_compat,
        .restart        = mxc_restart,
index 1ed916175d41bf4f5ccfc10e5fc981b151234874..50044a21b388f76a97458a70e87d6166809c1b53 100644 (file)
@@ -311,7 +311,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev,
        }
 
        ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)),
-                         detect_irq, IRQF_DISABLED |
+                         detect_irq,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                          "sdhc1-detect", data);
        if (ret) {
index bc0261e99d398f1632986cccf9785a58519c809c..45303bd629022d66ef167d0830f5c6088c5c44d8 100644 (file)
@@ -371,8 +371,7 @@ static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
 #endif
 
        ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq,
-                       IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-                               "sdhc-detect", data);
+                       IRQF_TRIGGER_FALLING, "sdhc-detect", data);
        if (ret)
                goto err_gpio_free_2;
 
index 816991deb9b86ef9ba61139cf2ae17257f9b89a5..af0cb8a9dc4898827b1c569506b761fb4b476787 100644 (file)
@@ -8,9 +8,7 @@
  */
 
 #include <linux/of_platform.h>
-#include <linux/clocksource.h>
 #include <linux/irqchip.h>
-#include <linux/clk-provider.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/cache-l2x0.h>
 
@@ -28,12 +26,6 @@ static void __init vf610_init_irq(void)
        irqchip_init();
 }
 
-static void __init vf610_init_time(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
 static const char *vf610_dt_compat[] __initdata = {
        "fsl,vf610",
        NULL,
@@ -41,7 +33,6 @@ static const char *vf610_dt_compat[] __initdata = {
 
 DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
        .init_irq       = vf610_init_irq,
-       .init_time      = vf610_init_time,
        .init_machine   = vf610_init_machine,
        .dt_compat      = vf610_dt_compat,
        .restart        = mxc_restart,
index eb3cce38c70d3f09eb29d9b7d51343bca5327989..d1d52600f458c3604eb77c4bcfae51432b2a932c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/of_address.h>
 
 #include <asm/mach/map.h>
 
@@ -88,8 +89,15 @@ 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);
-       mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
+
+       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();
 }
 
@@ -100,7 +108,14 @@ void __init mx51_init_irq(void)
 
 void __init mx53_init_irq(void)
 {
-       tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR));
+       struct device_node *np;
+       void __iomem *base;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx53-tzic");
+       base = of_iomap(np, 0);
+       WARN_ON(!base);
+
+       tzic_init_irq(base);
 }
 
 static struct sdma_platform_data imx51_sdma_pdata __initdata = {
index d4361b80c5fba0c60d5436bbdd0401ffd97b9a3f..649fe49ce85eed34765474badbc1be36a9627b4b 100644 (file)
@@ -130,8 +130,7 @@ static int mxc_mmc1_init(struct device *dev,
        gpio_direction_input(gpio_wp);
 
        ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)),
-                         detect_irq,
-                         IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+                         detect_irq, IRQF_TRIGGER_FALLING,
                          "MMC detect", data);
        if (ret)
                goto exit_free_wp;
index 8629e5be7ecd19f665a13a10a554d4b3bedab00f..b08ab3ad4a6db2d09d4344ef0e319b8bc8a64cf1 100644 (file)
@@ -34,6 +34,7 @@
 #define MXC_CPU_MX35           35
 #define MXC_CPU_MX51           51
 #define MXC_CPU_MX53           53
+#define MXC_CPU_IMX6SL         0x60
 #define MXC_CPU_IMX6DL         0x61
 #define MXC_CPU_IMX6Q          0x63
 
@@ -152,6 +153,11 @@ extern unsigned int __mxc_cpu_type;
 #endif
 
 #ifndef __ASSEMBLY__
+static inline bool cpu_is_imx6sl(void)
+{
+       return __mxc_cpu_type == MXC_CPU_IMX6SL;
+}
+
 static inline bool cpu_is_imx6dl(void)
 {
        return __mxc_cpu_type == MXC_CPU_IMX6DL;
index 204942749e2199bbe4ff1632e974e17d4612d37b..aecd9f8037e0aab65e44482ffe817314b6bbd1be 100644 (file)
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
 #include <linux/suspend.h>
 #include <asm/cacheflush.h>
 #include <asm/proc-fns.h>
 #include "common.h"
 #include "hardware.h"
 
+#define CCR                            0x0
+#define BM_CCR_WB_COUNT                        (0x7 << 16)
+#define BM_CCR_RBC_BYPASS_COUNT                (0x3f << 21)
+#define BM_CCR_RBC_EN                  (0x1 << 27)
+
+#define CLPCR                          0x54
+#define BP_CLPCR_LPM                   0
+#define BM_CLPCR_LPM                   (0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY     (0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM    (0x1 << 5)
+#define BM_CLPCR_SBYOS                 (0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC           (0x1 << 7)
+#define BM_CLPCR_VSTBY                 (0x1 << 8)
+#define BP_CLPCR_STBY_COUNT            9
+#define BM_CLPCR_STBY_COUNT            (0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN          (0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM         (0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM                (0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS   (0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS   (0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI                (0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI                (0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI                (0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI                (0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE         (0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE                (0x1 << 27)
+
+#define CGPR                           0x64
+#define BM_CGPR_CHICKEN_BIT            (0x1 << 17)
+
+static void __iomem *ccm_base;
+
+void imx6q_set_chicken_bit(void)
+{
+       u32 val = readl_relaxed(ccm_base + CGPR);
+
+       val |= BM_CGPR_CHICKEN_BIT;
+       writel_relaxed(val, ccm_base + CGPR);
+}
+
+static void imx6q_enable_rbc(bool enable)
+{
+       u32 val;
+
+       /*
+        * need to mask all interrupts in GPC before
+        * operating RBC configurations
+        */
+       imx_gpc_mask_all();
+
+       /* configure RBC enable bit */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_RBC_EN;
+       val |= enable ? BM_CCR_RBC_EN : 0;
+       writel_relaxed(val, ccm_base + CCR);
+
+       /* configure RBC count */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_RBC_BYPASS_COUNT;
+       val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
+       writel(val, ccm_base + CCR);
+
+       /*
+        * need to delay at least 2 cycles of CKIL(32K)
+        * due to hardware design requirement, which is
+        * ~61us, here we use 65us for safe
+        */
+       udelay(65);
+
+       /* restore GPC interrupt mask settings */
+       imx_gpc_restore_all();
+}
+
+static void imx6q_enable_wb(bool enable)
+{
+       u32 val;
+
+       /* configure well bias enable bit */
+       val = readl_relaxed(ccm_base + CLPCR);
+       val &= ~BM_CLPCR_WB_PER_AT_LPM;
+       val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
+       writel_relaxed(val, ccm_base + CLPCR);
+
+       /* configure well bias count */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_WB_COUNT;
+       val |= enable ? BM_CCR_WB_COUNT : 0;
+       writel_relaxed(val, ccm_base + CCR);
+}
+
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
+{
+       struct irq_desc *iomuxc_irq_desc;
+       u32 val = readl_relaxed(ccm_base + CLPCR);
+
+       val &= ~BM_CLPCR_LPM;
+       switch (mode) {
+       case WAIT_CLOCKED:
+               break;
+       case WAIT_UNCLOCKED:
+               val |= 0x1 << BP_CLPCR_LPM;
+               val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
+               break;
+       case STOP_POWER_ON:
+               val |= 0x2 << BP_CLPCR_LPM;
+               break;
+       case WAIT_UNCLOCKED_POWER_OFF:
+               val |= 0x1 << BP_CLPCR_LPM;
+               val &= ~BM_CLPCR_VSTBY;
+               val &= ~BM_CLPCR_SBYOS;
+               break;
+       case STOP_POWER_OFF:
+               val |= 0x2 << BP_CLPCR_LPM;
+               val |= 0x3 << BP_CLPCR_STBY_COUNT;
+               val |= BM_CLPCR_VSTBY;
+               val |= BM_CLPCR_SBYOS;
+               if (cpu_is_imx6sl()) {
+                       val |= BM_CLPCR_BYPASS_PMIC_READY;
+                       val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+               } else {
+                       val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * Unmask the always pending IOMUXC interrupt #32 as wakeup source to
+        * deassert dsm_request signal, so that we can ensure dsm_request
+        * is not asserted when we're going to write CLPCR register to set LPM.
+        * After setting up LPM bits, we need to mask this wakeup source.
+        */
+       iomuxc_irq_desc = irq_to_desc(32);
+       imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
+       writel_relaxed(val, ccm_base + CLPCR);
+       imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
+
+       return 0;
+}
+
 static int imx6q_suspend_finish(unsigned long val)
 {
        cpu_do_idle();
@@ -33,14 +180,19 @@ static int imx6q_pm_enter(suspend_state_t state)
        switch (state) {
        case PM_SUSPEND_MEM:
                imx6q_set_lpm(STOP_POWER_OFF);
+               imx6q_enable_wb(true);
+               imx6q_enable_rbc(true);
                imx_gpc_pre_suspend();
                imx_anatop_pre_suspend();
                imx_set_cpu_jump(0, v7_cpu_resume);
                /* Zzz ... */
                cpu_suspend(0, imx6q_suspend_finish);
-               imx_smp_prepare();
+               if (cpu_is_imx6q() || cpu_is_imx6dl())
+                       imx_smp_prepare();
                imx_anatop_post_resume();
                imx_gpc_post_resume();
+               imx6q_enable_rbc(false);
+               imx6q_enable_wb(false);
                imx6q_set_lpm(WAIT_CLOCKED);
                break;
        default:
@@ -55,7 +207,29 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
        .valid = suspend_valid_only_mem,
 };
 
+void __init imx6q_pm_set_ccm_base(void __iomem *base)
+{
+       ccm_base = base;
+}
+
 void __init imx6q_pm_init(void)
 {
+       struct regmap *gpr;
+
+       WARN_ON(!ccm_base);
+
+       /*
+        * Force IOMUXC irq pending, so that the interrupt to GPC can be
+        * used to deassert dsm_request signal when the signal gets
+        * asserted unexpectedly.
+        */
+       gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+       if (!IS_ERR(gpr))
+               regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
+                                  IMX6Q_GPR1_GINT);
+
+       /* Set initial power mode */
+       imx6q_set_lpm(WAIT_CLOCKED);
+
        suspend_set_ops(&imx6q_pm_ops);
 }
index 10a6b1a8c5acee611c2ae0c74766866b70cffd67..4754373e7e7d3a97b29e5af8a143bb27379bb9a5 100644 (file)
@@ -91,6 +91,7 @@ void imx_enable_cpu(int cpu, bool enable)
        spin_lock(&scr_lock);
        val = readl_relaxed(src_base + SRC_SCR);
        val = enable ? val | mask : val & ~mask;
+       val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
        writel_relaxed(val, src_base + SRC_SCR);
        spin_unlock(&scr_lock);
 }
index 80c177c36c5f25665ada2fbf93cf2ac4b007eee6..e6edcd38b282fdaa74027731841c187ed93cda4d 100644 (file)
@@ -42,6 +42,9 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
 {
        unsigned int wcr_enable;
 
+       if (cpu_is_imx6q() || cpu_is_imx6dl())
+               imx_src_prepare_restart();
+
        if (wdog_clk)
                clk_enable(wdog_clk);
 
@@ -52,6 +55,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
 
        /* Assert SRS signal */
        __raw_writew(wcr_enable, wdog_base);
+       /* write twice to ensure the request will not get ignored */
+       __raw_writew(wcr_enable, wdog_base);
 
        /* wait for reset to assert... */
        mdelay(500);
index cd46529e9eaa1a8925129370fb25476a861908e8..9b6638aadeaa8958069f018c734c077593410044 100644 (file)
@@ -250,7 +250,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction mxc_timer_irq = {
        .name           = "i.MX Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = mxc_timer_interrupt,
 };
 
diff --git a/arch/arm/mach-integrator/cm.h b/arch/arm/mach-integrator/cm.h
new file mode 100644 (file)
index 0000000..4ecff7b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * access the core module control register.
+ */
+u32 cm_get(void);
+void cm_control(u32, u32);
+
+struct device_node;
+void cm_init(void);
+void cm_clear_irqs(void);
+
+#define CM_CTRL_LED                    (1 << 0)
+#define CM_CTRL_nMBDET                 (1 << 1)
+#define CM_CTRL_REMAP                  (1 << 2)
+#define CM_CTRL_RESET                  (1 << 3)
+
+/*
+ * Integrator/AP,PP2 specific
+ */
+#define CM_CTRL_HIGHVECTORS            (1 << 4)
+#define CM_CTRL_BIGENDIAN              (1 << 5)
+#define CM_CTRL_FASTBUS                        (1 << 6)
+#define CM_CTRL_SYNC                   (1 << 7)
+
+/*
+ * ARM926/946/966 Integrator/CP specific
+ */
+#define CM_CTRL_LCDBIASEN              (1 << 8)
+#define CM_CTRL_LCDBIASUP              (1 << 9)
+#define CM_CTRL_LCDBIASDN              (1 << 10)
+#define CM_CTRL_LCDMUXSEL_MASK         (7 << 11)
+#define CM_CTRL_LCDMUXSEL_GENLCD       (1 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA565_TFT555        (2 << 11)
+#define CM_CTRL_LCDMUXSEL_SHARPLCD     (3 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA555_TFT555        (4 << 11)
+#define CM_CTRL_LCDEN0                 (1 << 14)
+#define CM_CTRL_LCDEN1                 (1 << 15)
+#define CM_CTRL_STATIC1                        (1 << 16)
+#define CM_CTRL_STATIC2                        (1 << 17)
+#define CM_CTRL_STATIC                 (1 << 18)
+#define CM_CTRL_n24BITEN               (1 << 19)
+#define CM_CTRL_EBIWP                  (1 << 20)
index 4cdfd7365925f76ce9c1b8b021ce16b566855397..00ddf20ed91b384d892248238afe6f008758e303 100644 (file)
 #include <linux/amba/serial.h>
 #include <linux/io.h>
 #include <linux/stat.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <mach/cm.h>
-#include <mach/irqs.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
 #include <asm/pgtable.h>
 
+#include "cm.h"
 #include "common.h"
 
-#ifdef CONFIG_ATAGS
-
-#define INTEGRATOR_RTC_IRQ     { IRQ_RTCINT }
-#define INTEGRATOR_UART0_IRQ   { IRQ_UARTINT0 }
-#define INTEGRATOR_UART1_IRQ   { IRQ_UARTINT1 }
-#define KMI0_IRQ               { IRQ_KMIINT0 }
-#define KMI1_IRQ               { IRQ_KMIINT1 }
-
-static AMBA_APB_DEVICE(rtc, "rtc", 0,
-       INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
-
-static AMBA_APB_DEVICE(uart0, "uart0", 0,
-       INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);
-
-static AMBA_APB_DEVICE(uart1, "uart1", 0,
-       INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);
-
-static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
-static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
-
-static struct amba_device *amba_devs[] __initdata = {
-       &rtc_device,
-       &uart0_device,
-       &uart1_device,
-       &kmi0_device,
-       &kmi1_device,
-};
+static DEFINE_RAW_SPINLOCK(cm_lock);
+static void __iomem *cm_base;
 
-int __init integrator_init(bool is_cp)
+/**
+ * cm_get - get the value from the CM_CTRL register
+ */
+u32 cm_get(void)
 {
-       int i;
-
-       /*
-        * The Integrator/AP lacks necessary AMBA PrimeCell IDs, so we need to
-        * hard-code them. The Integator/CP and forward have proper cell IDs.
-        * Else we leave them undefined to the bus driver can autoprobe them.
-        */
-       if (!is_cp && IS_ENABLED(CONFIG_ARCH_INTEGRATOR_AP)) {
-               rtc_device.periphid     = 0x00041030;
-               uart0_device.periphid   = 0x00041010;
-               uart1_device.periphid   = 0x00041010;
-               kmi0_device.periphid    = 0x00041050;
-               kmi1_device.periphid    = 0x00041050;
-               uart0_device.dev.platform_data = &ap_uart_data;
-               uart1_device.dev.platform_data = &ap_uart_data;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-               struct amba_device *d = amba_devs[i];
-               amba_device_register(d, &iomem_resource);
-       }
-
-       return 0;
+       return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
 }
 
-#endif
-
-static DEFINE_RAW_SPINLOCK(cm_lock);
-
 /**
  * cm_control - update the CM_CTRL register.
  * @mask: bits to change
@@ -104,12 +57,80 @@ void cm_control(u32 mask, u32 set)
        u32 val;
 
        raw_spin_lock_irqsave(&cm_lock, flags);
-       val = readl(CM_CTRL) & ~mask;
-       writel(val | set, CM_CTRL);
+       val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask;
+       writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
        raw_spin_unlock_irqrestore(&cm_lock, flags);
 }
 
-EXPORT_SYMBOL(cm_control);
+static const char *integrator_arch_str(u32 id)
+{
+       switch ((id >> 16) & 0xff) {
+       case 0x00:
+               return "ASB little-endian";
+       case 0x01:
+               return "AHB little-endian";
+       case 0x03:
+               return "AHB-Lite system bus, bi-endian";
+       case 0x04:
+               return "AHB";
+       case 0x08:
+               return "AHB system bus, ASB processor bus";
+       default:
+               return "Unknown";
+       }
+}
+
+static const char *integrator_fpga_str(u32 id)
+{
+       switch ((id >> 12) & 0xf) {
+       case 0x01:
+               return "XC4062";
+       case 0x02:
+               return "XC4085";
+       case 0x03:
+               return "XVC600";
+       case 0x04:
+               return "EPM7256AE (Altera PLD)";
+       default:
+               return "Unknown";
+       }
+}
+
+void cm_clear_irqs(void)
+{
+       /* disable core module IRQs */
+       writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET +
+               IRQ_ENABLE_CLEAR);
+}
+
+static const struct of_device_id cm_match[] = {
+       { .compatible = "arm,core-module-integrator"},
+       { },
+};
+
+void cm_init(void)
+{
+       struct device_node *cm = of_find_matching_node(NULL, cm_match);
+       u32 val;
+
+       if (!cm) {
+               pr_crit("no core module node found in device tree\n");
+               return;
+       }
+       cm_base = of_iomap(cm, 0);
+       if (!cm_base) {
+               pr_crit("could not remap core module\n");
+               return;
+       }
+       cm_clear_irqs();
+       val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET);
+       pr_info("Detected ARM core module:\n");
+       pr_info("    Manufacturer: %02x\n", (val >> 24));
+       pr_info("    Architecture: %s\n", integrator_arch_str(val));
+       pr_info("    FPGA: %s\n", integrator_fpga_str(val));
+       pr_info("    Build: %02x\n", (val >> 4) & 0xFF);
+       pr_info("    Rev: %c\n", ('A' + (val & 0x03)));
+}
 
 /*
  * We need to stop things allocating the low memory; ideally we need a
@@ -145,27 +166,7 @@ static ssize_t intcp_get_arch(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
 {
-       const char *arch;
-
-       switch ((integrator_id >> 16) & 0xff) {
-       case 0x00:
-               arch = "ASB little-endian";
-               break;
-       case 0x01:
-               arch = "AHB little-endian";
-               break;
-       case 0x03:
-               arch = "AHB-Lite system bus, bi-endian";
-               break;
-       case 0x04:
-               arch = "AHB";
-               break;
-       default:
-               arch = "Unknown";
-               break;
-       }
-
-       return sprintf(buf, "%s\n", arch);
+       return sprintf(buf, "%s\n", integrator_arch_str(integrator_id));
 }
 
 static struct device_attribute intcp_arch_attr =
@@ -175,24 +176,7 @@ static ssize_t intcp_get_fpga(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
 {
-       const char *fpga;
-
-       switch ((integrator_id >> 12) & 0xf) {
-       case 0x01:
-               fpga = "XC4062";
-               break;
-       case 0x02:
-               fpga = "XC4085";
-               break;
-       case 0x04:
-               fpga = "EPM7256AE (Altera PLD)";
-               break;
-       default:
-               fpga = "Unknown";
-               break;
-       }
-
-       return sprintf(buf, "%s\n", fpga);
+       return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id));
 }
 
 static struct device_attribute intcp_fpga_attr =
diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/include/mach/cm.h
deleted file mode 100644 (file)
index 202e6a5..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * update the core module control register.
- */
-void cm_control(u32, u32);
-
-#define CM_CTRL        __io_address(INTEGRATOR_HDR_CTRL)
-
-#define CM_CTRL_LED                    (1 << 0)
-#define CM_CTRL_nMBDET                 (1 << 1)
-#define CM_CTRL_REMAP                  (1 << 2)
-#define CM_CTRL_RESET                  (1 << 3)
-
-/*
- * Integrator/AP,PP2 specific
- */
-#define CM_CTRL_HIGHVECTORS            (1 << 4)
-#define CM_CTRL_BIGENDIAN              (1 << 5)
-#define CM_CTRL_FASTBUS                        (1 << 6)
-#define CM_CTRL_SYNC                   (1 << 7)
-
-/*
- * ARM926/946/966 Integrator/CP specific
- */
-#define CM_CTRL_LCDBIASEN              (1 << 8)
-#define CM_CTRL_LCDBIASUP              (1 << 9)
-#define CM_CTRL_LCDBIASDN              (1 << 10)
-#define CM_CTRL_LCDMUXSEL_MASK         (7 << 11)
-#define CM_CTRL_LCDMUXSEL_GENLCD       (1 << 11)
-#define CM_CTRL_LCDMUXSEL_VGA565_TFT555        (2 << 11)
-#define CM_CTRL_LCDMUXSEL_SHARPLCD     (3 << 11)
-#define CM_CTRL_LCDMUXSEL_VGA555_TFT555        (4 << 11)
-#define CM_CTRL_LCDEN0                 (1 << 14)
-#define CM_CTRL_LCDEN1                 (1 << 15)
-#define CM_CTRL_STATIC1                        (1 << 16)
-#define CM_CTRL_STATIC2                        (1 << 17)
-#define CM_CTRL_STATIC                 (1 << 18)
-#define CM_CTRL_n24BITEN               (1 << 19)
-#define CM_CTRL_EBIWP                  (1 << 20)
diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h
deleted file mode 100644 (file)
index eff0ada..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *  arch/arm/mach-integrator/include/mach/irqs.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * 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
- */
-
-/*
- * Interrupt numbers, all of the above are just static reservations
- * used so they can be encoded into device resources. They will finally
- * be done away with when switching to device tree.
- */
-#define IRQ_PIC_START                  64
-#define IRQ_SOFTINT                    (IRQ_PIC_START+0)
-#define IRQ_UARTINT0                   (IRQ_PIC_START+1)
-#define IRQ_UARTINT1                   (IRQ_PIC_START+2)
-#define IRQ_KMIINT0                    (IRQ_PIC_START+3)
-#define IRQ_KMIINT1                    (IRQ_PIC_START+4)
-#define IRQ_TIMERINT0                  (IRQ_PIC_START+5)
-#define IRQ_TIMERINT1                  (IRQ_PIC_START+6)
-#define IRQ_TIMERINT2                  (IRQ_PIC_START+7)
-#define IRQ_RTCINT                     (IRQ_PIC_START+8)
-#define IRQ_AP_EXPINT0                 (IRQ_PIC_START+9)
-#define IRQ_AP_EXPINT1                 (IRQ_PIC_START+10)
-#define IRQ_AP_EXPINT2                 (IRQ_PIC_START+11)
-#define IRQ_AP_EXPINT3                 (IRQ_PIC_START+12)
-#define IRQ_AP_PCIINT0                 (IRQ_PIC_START+13)
-#define IRQ_AP_PCIINT1                 (IRQ_PIC_START+14)
-#define IRQ_AP_PCIINT2                 (IRQ_PIC_START+15)
-#define IRQ_AP_PCIINT3                 (IRQ_PIC_START+16)
-#define IRQ_AP_V3INT                   (IRQ_PIC_START+17)
-#define IRQ_AP_CPINT0                  (IRQ_PIC_START+18)
-#define IRQ_AP_CPINT1                  (IRQ_PIC_START+19)
-#define IRQ_AP_LBUSTIMEOUT             (IRQ_PIC_START+20)
-#define IRQ_AP_APCINT                  (IRQ_PIC_START+21)
-#define IRQ_CP_CLCDCINT                        (IRQ_PIC_START+22)
-#define IRQ_CP_MMCIINT0                        (IRQ_PIC_START+23)
-#define IRQ_CP_MMCIINT1                        (IRQ_PIC_START+24)
-#define IRQ_CP_AACIINT                 (IRQ_PIC_START+25)
-#define IRQ_CP_CPPLDINT                        (IRQ_PIC_START+26)
-#define IRQ_CP_ETHINT                  (IRQ_PIC_START+27)
-#define IRQ_CP_TSPENINT                        (IRQ_PIC_START+28)
-#define IRQ_PIC_END                    (IRQ_PIC_START+28)
-
-#define IRQ_CIC_START                  (IRQ_PIC_END+1)
-#define IRQ_CM_SOFTINT                 (IRQ_CIC_START+0)
-#define IRQ_CM_COMMRX                  (IRQ_CIC_START+1)
-#define IRQ_CM_COMMTX                  (IRQ_CIC_START+2)
-#define IRQ_CIC_END                    (IRQ_CIC_START+2)
-
-/*
- * IntegratorCP only
- */
-#define IRQ_SIC_START                  (IRQ_CIC_END+1)
-#define IRQ_SIC_CP_SOFTINT             (IRQ_SIC_START+0)
-#define IRQ_SIC_CP_RI0                 (IRQ_SIC_START+1)
-#define IRQ_SIC_CP_RI1                 (IRQ_SIC_START+2)
-#define IRQ_SIC_CP_CARDIN              (IRQ_SIC_START+3)
-#define IRQ_SIC_CP_LMINT0              (IRQ_SIC_START+4)
-#define IRQ_SIC_CP_LMINT1              (IRQ_SIC_START+5)
-#define IRQ_SIC_CP_LMINT2              (IRQ_SIC_START+6)
-#define IRQ_SIC_CP_LMINT3              (IRQ_SIC_START+7)
-#define IRQ_SIC_CP_LMINT4              (IRQ_SIC_START+8)
-#define IRQ_SIC_CP_LMINT5              (IRQ_SIC_START+9)
-#define IRQ_SIC_CP_LMINT6              (IRQ_SIC_START+10)
-#define IRQ_SIC_CP_LMINT7              (IRQ_SIC_START+11)
-#define IRQ_SIC_END                    (IRQ_SIC_START+11)
index d9e95e612fcbfaecf9855d4a39f5017d236edb6f..d50dc2dbfd89e53571a716b80e01bd567400ea36 100644 (file)
 #include <asm/mach-types.h>
 
 #include <mach/lm.h>
-#include <mach/irqs.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
+#include "cm.h"
 #include "common.h"
 #include "pci_v3.h"
 
@@ -146,7 +146,7 @@ static int irq_suspend(void)
 static void irq_resume(void)
 {
        /* disable all irq sources */
-       writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+       cm_clear_irqs();
        writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
        writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 
@@ -402,8 +402,6 @@ void __init ap_init_early(void)
 {
 }
 
-#ifdef CONFIG_OF
-
 static void __init ap_of_timer_init(void)
 {
        struct device_node *node;
@@ -450,8 +448,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = {
 
 static void __init ap_init_irq_of(void)
 {
-       /* disable core module IRQs */
-       writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+       cm_init();
        of_irq_init(fpga_irq_of_match);
        integrator_clk_init(false);
 }
@@ -473,6 +470,11 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
        { /* sentinel */ },
 };
 
+static const struct of_device_id ap_syscon_match[] = {
+       { .compatible = "arm,integrator-ap-syscon"},
+       { },
+};
+
 static void __init ap_init_of(void)
 {
        unsigned long sc_dec;
@@ -489,7 +491,8 @@ static void __init ap_init_of(void)
        root = of_find_node_by_path("/");
        if (!root)
                return;
-       syscon = of_find_node_by_path("/syscon");
+
+       syscon = of_find_matching_node(root, ap_syscon_match);
        if (!syscon)
                return;
 
@@ -541,7 +544,7 @@ static void __init ap_init_of(void)
                lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
                lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
                lmdev->resource.flags = IORESOURCE_MEM;
-               lmdev->irq = IRQ_AP_EXPINT0 + i;
+               lmdev->irq = irq_of_parse_and_map(syscon, i);
                lmdev->id = i;
 
                lm_device_register(lmdev);
@@ -564,136 +567,3 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
        .restart        = integrator_restart,
        .dt_compat      = ap_dt_board_compat,
 MACHINE_END
-
-#endif
-
-#ifdef CONFIG_ATAGS
-
-/*
- * For the ATAG boot some static mappings are needed. This will
- * go away with the ATAG support down the road.
- */
-
-static struct map_desc ap_io_desc_atag[] __initdata = {
-       {
-               .virtual        = IO_ADDRESS(INTEGRATOR_SC_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_SC_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       },
-};
-
-static void __init ap_map_io_atag(void)
-{
-       iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag));
-       ap_map_io();
-}
-
-/*
- * This is where non-devicetree initialization code is collected and stashed
- * for eventual deletion.
- */
-
-static struct platform_device pci_v3_device = {
-       .name           = "pci-v3",
-       .id             = 0,
-};
-
-static struct resource cfi_flash_resource = {
-       .start          = INTEGRATOR_FLASH_BASE,
-       .end            = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device cfi_flash_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &ap_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &cfi_flash_resource,
-};
-
-static void __init ap_timer_init(void)
-{
-       struct clk *clk;
-       unsigned long rate;
-
-       clk = clk_get_sys("ap_timer", NULL);
-       BUG_ON(IS_ERR(clk));
-       clk_prepare_enable(clk);
-       rate = clk_get_rate(clk);
-
-       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
-       integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
-       integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
-                               IRQ_TIMERINT1);
-}
-
-#define INTEGRATOR_SC_VALID_INT        0x003fffff
-
-static void __init ap_init_irq(void)
-{
-       /* Disable all interrupts initially. */
-       /* Do the core module ones */
-       writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
-
-       /* do the header card stuff next */
-       writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-       writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
-       fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
-               -1, INTEGRATOR_SC_VALID_INT, NULL);
-       integrator_clk_init(false);
-}
-
-static void __init ap_init(void)
-{
-       unsigned long sc_dec;
-       int i;
-
-       platform_device_register(&pci_v3_device);
-       platform_device_register(&cfi_flash_device);
-
-       ap_syscon_base = __io_address(INTEGRATOR_SC_BASE);
-       sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
-       for (i = 0; i < 4; i++) {
-               struct lm_device *lmdev;
-
-               if ((sc_dec & (16 << i)) == 0)
-                       continue;
-
-               lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
-               if (!lmdev)
-                       continue;
-
-               lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
-               lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
-               lmdev->resource.flags = IORESOURCE_MEM;
-               lmdev->irq = IRQ_AP_EXPINT0 + i;
-               lmdev->id = i;
-
-               lm_device_register(lmdev);
-       }
-
-       integrator_init(false);
-}
-
-MACHINE_START(INTEGRATOR, "ARM-Integrator")
-       /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-       .atag_offset    = 0x100,
-       .reserve        = integrator_reserve,
-       .map_io         = ap_map_io_atag,
-       .init_early     = ap_init_early,
-       .init_irq       = ap_init_irq,
-       .handle_irq     = fpga_handle_irq,
-       .init_time      = ap_timer_init,
-       .init_machine   = ap_init,
-       .restart        = integrator_restart,
-MACHINE_END
-
-#endif
index 8c60fcb08a98ff43db4f115c45306c83b5a3bb65..1df6e7602cadb75dac78a961352624b8f855d73f 100644 (file)
@@ -36,9 +36,7 @@
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
-#include <mach/cm.h>
 #include <mach/lm.h>
-#include <mach/irqs.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
@@ -50,6 +48,7 @@
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
 
+#include "cm.h"
 #include "common.h"
 
 /* Base address to the CP controller */
@@ -249,7 +248,6 @@ static void __init intcp_init_early(void)
 #endif
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
        { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
        { /* Sentinel */ }
@@ -257,6 +255,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = {
 
 static void __init intcp_init_irq_of(void)
 {
+       cm_init();
        of_irq_init(fpga_irq_of_match);
        integrator_clk_init(true);
 }
@@ -287,6 +286,11 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
        { /* sentinel */ },
 };
 
+static const struct of_device_id intcp_syscon_match[] = {
+       { .compatible = "arm,integrator-cp-syscon"},
+       { },
+};
+
 static void __init intcp_init_of(void)
 {
        struct device_node *root;
@@ -301,7 +305,8 @@ static void __init intcp_init_of(void)
        root = of_find_node_by_path("/");
        if (!root)
                return;
-       cpcon = of_find_node_by_path("/cpcon");
+
+       cpcon = of_find_matching_node(root, intcp_syscon_match);
        if (!cpcon)
                return;
 
@@ -354,175 +359,3 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
        .restart        = integrator_restart,
        .dt_compat      = intcp_dt_board_compat,
 MACHINE_END
-
-#endif
-
-#ifdef CONFIG_ATAGS
-
-/*
- * For the ATAG boot some static mappings are needed. This will
- * go away with the ATAG support down the road.
- */
-
-static struct map_desc intcp_io_desc_atag[] __initdata = {
-       {
-               .virtual        = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       },
-};
-
-static void __init intcp_map_io_atag(void)
-{
-       iotable_init(intcp_io_desc_atag, ARRAY_SIZE(intcp_io_desc_atag));
-       intcp_con_base = __io_address(INTEGRATOR_CP_CTL_BASE);
-       intcp_map_io();
-}
-
-
-/*
- * This is where non-devicetree initialization code is collected and stashed
- * for eventual deletion.
- */
-
-#define INTCP_FLASH_SIZE               SZ_32M
-
-static struct resource intcp_flash_resource = {
-       .start          = INTCP_PA_FLASH_BASE,
-       .end            = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device intcp_flash_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &intcp_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &intcp_flash_resource,
-};
-
-#define INTCP_ETH_SIZE                 0x10
-
-static struct resource smc91x_resources[] = {
-       [0] = {
-               .start  = INTEGRATOR_CP_ETH_BASE,
-               .end    = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_CP_ETHINT,
-               .end    = IRQ_CP_ETHINT,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device smc91x_device = {
-       .name           = "smc91x",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(smc91x_resources),
-       .resource       = smc91x_resources,
-};
-
-static struct platform_device *intcp_devs[] __initdata = {
-       &intcp_flash_device,
-       &smc91x_device,
-};
-
-#define INTCP_VA_CIC_BASE              __io_address(INTEGRATOR_HDR_BASE + 0x40)
-#define INTCP_VA_PIC_BASE              __io_address(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE              __io_address(INTEGRATOR_CP_SIC_BASE)
-
-static void __init intcp_init_irq(void)
-{
-       u32 pic_mask, cic_mask, sic_mask;
-
-       /* These masks are for the HW IRQ registers */
-       pic_mask = ~((~0u) << (11 - 0));
-       pic_mask |= (~((~0u) << (29 - 22))) << 22;
-       cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
-       sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
-
-       /*
-        * Disable all interrupt sources
-        */
-       writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
-       writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
-       writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
-       writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
-       writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
-       writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
-
-       fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
-                     -1, pic_mask, NULL);
-
-       fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
-                     -1, cic_mask, NULL);
-
-       fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
-                     IRQ_CP_CPPLDINT, sic_mask, NULL);
-
-       integrator_clk_init(true);
-}
-
-#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
-#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
-#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
-
-static void __init cp_timer_init(void)
-{
-       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
-       sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
-       sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
-}
-
-#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
-#define INTEGRATOR_CP_AACI_IRQS        { IRQ_CP_AACIINT }
-
-static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
-       INTEGRATOR_CP_MMC_IRQS, &mmc_data);
-
-static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
-       INTEGRATOR_CP_AACI_IRQS, NULL);
-
-static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
-       { IRQ_CP_CLCDCINT }, &clcd_data);
-
-static struct amba_device *amba_devs[] __initdata = {
-       &mmc_device,
-       &aaci_device,
-       &clcd_device,
-};
-
-static void __init intcp_init(void)
-{
-       int i;
-
-       platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
-
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-               struct amba_device *d = amba_devs[i];
-               amba_device_register(d, &iomem_resource);
-       }
-       integrator_init(true);
-}
-
-MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
-       /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-       .atag_offset    = 0x100,
-       .reserve        = integrator_reserve,
-       .map_io         = intcp_map_io_atag,
-       .init_early     = intcp_init_early,
-       .init_irq       = intcp_init_irq,
-       .handle_irq     = fpga_handle_irq,
-       .init_time      = cp_timer_init,
-       .init_machine   = intcp_init,
-       .restart        = integrator_restart,
-MACHINE_END
-
-#endif
index 7a7f6d3273bf165b515eb8c4454731848ef661f0..cb6ac58f5e078656e26936472a891c00ac3d4ecd 100644 (file)
 #include <linux/slab.h>
 #include <linux/leds.h>
 
-#include <mach/cm.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
 
+#include "cm.h"
+
 #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
 
 #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
@@ -78,7 +79,7 @@ static void cm_led_set(struct led_classdev *cdev,
 
 static enum led_brightness cm_led_get(struct led_classdev *cdev)
 {
-       u32 reg = readl(CM_CTRL);
+       u32 reg = cm_get();
 
        return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
 }
index bef100527c4214654627a825b150a4add94772c8..c9c5a33bc802bd2a4dc28f234006949a6a54d44b 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <mach/irqs.h>
 
 #include <asm/mach/map.h>
 #include <asm/signal.h>
@@ -605,7 +604,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        return 1;
 }
 
-static irqreturn_t v3_irq(int dummy, void *devid)
+static irqreturn_t v3_irq(int irq, void *devid)
 {
 #ifdef CONFIG_DEBUG_LL
        struct pt_regs *regs = get_irq_regs();
@@ -615,7 +614,7 @@ static irqreturn_t v3_irq(int dummy, void *devid)
        extern void printascii(const char *);
 
        sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
-               "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
+               "ISTAT=%02x\n", irq, pc, instr,
                __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
                __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
                v3_readb(V3_LB_ISTAT));
@@ -809,32 +808,6 @@ static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp)
        return pci_common_swizzle(dev, pinp);
 }
 
-static int irq_tab[4] __initdata = {
-       IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3
-};
-
-/*
- * map the specified device/slot/pin to an IRQ.  This works out such
- * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
- */
-static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int intnr = ((slot - 9) + (pin - 1)) & 3;
-
-       return irq_tab[intnr];
-}
-
-static struct hw_pci pci_v3 __initdata = {
-       .swizzle                = pci_v3_swizzle,
-       .setup                  = pci_v3_setup,
-       .nr_controllers         = 1,
-       .ops                    = &pci_v3_ops,
-       .preinit                = pci_v3_preinit,
-       .postinit               = pci_v3_postinit,
-};
-
-#ifdef CONFIG_OF
-
 static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct of_irq oirq;
@@ -851,14 +824,36 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
                                     oirq.size);
 }
 
-static int __init pci_v3_dtprobe(struct platform_device *pdev,
-                               struct device_node *np)
+static struct hw_pci pci_v3 __initdata = {
+       .swizzle                = pci_v3_swizzle,
+       .setup                  = pci_v3_setup,
+       .nr_controllers         = 1,
+       .ops                    = &pci_v3_ops,
+       .preinit                = pci_v3_preinit,
+       .postinit               = pci_v3_postinit,
+};
+
+static int __init pci_v3_probe(struct platform_device *pdev)
 {
+       struct device_node *np = pdev->dev.of_node;
        struct of_pci_range_parser parser;
        struct of_pci_range range;
        struct resource *res;
        int irq, ret;
 
+       /* Remap the Integrator system controller */
+       ap_syscon_base = devm_ioremap(&pdev->dev, INTEGRATOR_SC_BASE, 0x100);
+       if (!ap_syscon_base) {
+               dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
+               return -ENODEV;
+       }
+
+       /* Device tree probe path */
+       if (!np) {
+               dev_err(&pdev->dev, "no device tree node for PCIv3\n");
+               return -ENODEV;
+       }
+
        if (of_pci_range_parser_init(&parser, np))
                return -EINVAL;
 
@@ -925,76 +920,6 @@ static int __init pci_v3_dtprobe(struct platform_device *pdev,
        return 0;
 }
 
-#else
-
-static inline int pci_v3_dtprobe(struct platform_device *pdev,
-                                 struct device_node *np)
-{
-       return -EINVAL;
-}
-
-#endif
-
-static int __init pci_v3_probe(struct platform_device *pdev)
-{
-       struct device_node *np = pdev->dev.of_node;
-       int ret;
-
-       /* Remap the Integrator system controller */
-       ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
-       if (!ap_syscon_base) {
-               dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
-               return -ENODEV;
-       }
-
-       /* Device tree probe path */
-       if (np)
-               return pci_v3_dtprobe(pdev, np);
-
-       pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K);
-       if (!pci_v3_base) {
-               dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
-               return -ENODEV;
-       }
-
-       ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
-       if (ret) {
-               dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n",
-                       ret);
-               return -ENODEV;
-       }
-
-       conf_mem.name = "PCIv3 config";
-       conf_mem.start = PHYS_PCI_CONFIG_BASE;
-       conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1;
-       conf_mem.flags = IORESOURCE_MEM;
-
-       io_mem.name = "PCIv3 I/O";
-       io_mem.start = PHYS_PCI_IO_BASE;
-       io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1;
-       io_mem.flags = IORESOURCE_MEM;
-
-       non_mem_pci = 0x00000000;
-       non_mem_pci_sz = SZ_256M;
-       non_mem.name = "PCIv3 non-prefetched mem";
-       non_mem.start = PHYS_PCI_MEM_BASE;
-       non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1;
-       non_mem.flags = IORESOURCE_MEM;
-
-       pre_mem_pci = 0x10000000;
-       pre_mem_pci_sz = SZ_256M;
-       pre_mem.name = "PCIv3 prefetched mem";
-       pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M;
-       pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1;
-       pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-
-       pci_v3.map_irq = pci_v3_map_irq;
-
-       pci_common_init_dev(&pdev->dev, &pci_v3);
-
-       return 0;
-}
-
 static const struct of_device_id pci_ids[] = {
        { .compatible = "v3,v360epc-pci", },
        {},
index 366d1a3b418d4c513910aa7ec23283ab05d35295..f20c53e75ed934d78acd1bdcb758bdf34690adfb 100644 (file)
@@ -9,6 +9,8 @@ config ARCH_KEYSTONE
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_ERRATA_798181 if SMP
+       select COMMON_CLK_KEYSTONE
+       select TI_EDMA
        help
          Support for boards based on the Texas Instruments Keystone family of
          SoCs.
index ddc52b05dc84b01a5008e611739a0eb2117c1ea0..25d92396fbfa1df7f4f7a0ac983d830ead5caa31 100644 (file)
@@ -4,3 +4,6 @@ plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_smc.o                           :=-Wa,-march=armv7-a$(plus_sec)
 
 obj-$(CONFIG_SMP)                      += platsmp.o
+
+# PM domain driver for Keystone SOCs
+obj-$(CONFIG_ARCH_KEYSTONE)            += pm_domain.o
diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c
new file mode 100644 (file)
index 0000000..2962523
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * PM domain driver for Keystone2 devices
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ *     Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * Based on Kevins work on DAVINCI SOCs
+ *     Kevin Hilman <khilman@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+
+#ifdef CONFIG_PM_RUNTIME
+static int keystone_pm_runtime_suspend(struct device *dev)
+{
+       int ret;
+
+       dev_dbg(dev, "%s\n", __func__);
+
+       ret = pm_generic_runtime_suspend(dev);
+       if (ret)
+               return ret;
+
+       ret = pm_clk_suspend(dev);
+       if (ret) {
+               pm_generic_runtime_resume(dev);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int keystone_pm_runtime_resume(struct device *dev)
+{
+       dev_dbg(dev, "%s\n", __func__);
+
+       pm_clk_resume(dev);
+
+       return pm_generic_runtime_resume(dev);
+}
+#endif
+
+static struct dev_pm_domain keystone_pm_domain = {
+       .ops = {
+               SET_RUNTIME_PM_OPS(keystone_pm_runtime_suspend,
+                                  keystone_pm_runtime_resume, NULL)
+               USE_PLATFORM_PM_SLEEP_OPS
+       },
+};
+
+static struct pm_clk_notifier_block platform_domain_notifier = {
+       .pm_domain = &keystone_pm_domain,
+};
+
+static struct of_device_id of_keystone_table[] = {
+       {.compatible = "ti,keystone"},
+       { /* end of list */ },
+};
+
+int __init keystone_pm_runtime_init(void)
+{
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, of_keystone_table);
+       if (!np)
+               return 0;
+
+       of_clk_init(NULL);
+       pm_clk_add_notifier(&platform_bus_type, &platform_domain_notifier);
+
+       return 0;
+}
+subsys_initcall(keystone_pm_runtime_init);
index d1f8e3d0793bef6dea7f05cdf8368a981c999702..144b511029399dc58a0049405478570f293ae492 100644 (file)
@@ -1,5 +1,7 @@
 obj-y                          += common.o pcie.o
 obj-$(CONFIG_KIRKWOOD_LEGACY)  += irq.o mpp.o
+obj-$(CONFIG_PM)               += pm.o
+
 obj-$(CONFIG_MACH_D2NET_V2)            += d2net_v2-setup.o lacie_v2-common.o
 obj-$(CONFIG_MACH_NET2BIG_V2)          += netxbig_v2-setup.o lacie_v2-common.o
 obj-$(CONFIG_MACH_NET5BIG_V2)          += netxbig_v2-setup.o lacie_v2-common.o
index 82d3ad8e87cf91395c0c706b48ef7df684e1e644..9caa4fe95913c672a6b874c5b8b8d573294ae857 100644 (file)
 #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/clocksource.h>
 #include <linux/dma-mapping.h>
 #include <linux/irqchip.h>
 #include <linux/kexec.h>
@@ -44,14 +45,6 @@ static void __init kirkwood_legacy_clk_init(void)
        clkspec.np = np;
        clkspec.args_count = 1;
 
-       clkspec.args[0] = CGC_BIT_PEX0;
-       orion_clkdev_add("0", "pcie",
-                        of_clk_get_from_provider(&clkspec));
-
-       clkspec.args[0] = CGC_BIT_PEX1;
-       orion_clkdev_add("1", "pcie",
-                        of_clk_get_from_provider(&clkspec));
-
        /*
         * The ethernet interfaces forget the MAC address assigned by
         * u-boot if the clocks are turned off. Until proper DT support
@@ -66,17 +59,83 @@ static void __init kirkwood_legacy_clk_init(void)
        clk_prepare_enable(clk);
 }
 
-static void __init kirkwood_dt_time_init(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
+#define MV643XX_ETH_MAC_ADDR_LOW       0x0414
+#define MV643XX_ETH_MAC_ADDR_HIGH      0x0418
 
-static void __init kirkwood_dt_init_early(void)
+static void __init kirkwood_dt_eth_fixup(void)
 {
-       mvebu_mbus_init("marvell,kirkwood-mbus",
-                       BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
-                       DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
+       struct device_node *np;
+
+       /*
+        * The ethernet interfaces forget the MAC address assigned by u-boot
+        * if the clocks are turned off. Usually, u-boot on kirkwood boards
+        * has no DT support to properly set local-mac-address property.
+        * As a workaround, we get the MAC address from mv643xx_eth registers
+        * and update the port device node if no valid MAC address is set.
+        */
+       for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") {
+               struct device_node *pnp = of_get_parent(np);
+               struct clk *clk;
+               struct property *pmac;
+               void __iomem *io;
+               u8 *macaddr;
+               u32 reg;
+
+               if (!pnp)
+                       continue;
+
+               /* skip disabled nodes or nodes with valid MAC address*/
+               if (!of_device_is_available(pnp) || of_get_mac_address(np))
+                       goto eth_fixup_skip;
+
+               clk = of_clk_get(pnp, 0);
+               if (IS_ERR(clk))
+                       goto eth_fixup_skip;
+
+               io = of_iomap(pnp, 0);
+               if (!io)
+                       goto eth_fixup_no_map;
+
+               /* ensure port clock is not gated to not hang CPU */
+               clk_prepare_enable(clk);
+
+               /* store MAC address register contents in local-mac-address */
+               pr_err(FW_INFO "%s: local-mac-address is not set\n",
+                      np->full_name);
+
+               pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL);
+               if (!pmac)
+                       goto eth_fixup_no_mem;
+
+               pmac->value = pmac + 1;
+               pmac->length = 6;
+               pmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+               if (!pmac->name) {
+                       kfree(pmac);
+                       goto eth_fixup_no_mem;
+               }
+
+               macaddr = pmac->value;
+               reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH);
+               macaddr[0] = (reg >> 24) & 0xff;
+               macaddr[1] = (reg >> 16) & 0xff;
+               macaddr[2] = (reg >> 8) & 0xff;
+               macaddr[3] = reg & 0xff;
+
+               reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW);
+               macaddr[4] = (reg >> 8) & 0xff;
+               macaddr[5] = reg & 0xff;
+
+               of_update_property(np, pmac);
+
+eth_fixup_no_mem:
+               iounmap(io);
+               clk_disable_unprepare(clk);
+eth_fixup_no_map:
+               clk_put(clk);
+eth_fixup_skip:
+               of_node_put(pnp);
+       }
 }
 
 static void __init kirkwood_dt_init(void)
@@ -92,16 +151,16 @@ static void __init kirkwood_dt_init(void)
        writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
 
        BUG_ON(mvebu_mbus_dt_init());
-       kirkwood_setup_wins();
 
        kirkwood_l2_init();
 
        kirkwood_cpufreq_init();
-
+       kirkwood_cpuidle_init();
        /* Setup clocks for legacy devices */
        kirkwood_legacy_clk_init();
 
-       kirkwood_cpuidle_init();
+       kirkwood_pm_init();
+       kirkwood_dt_eth_fixup();
 
 #ifdef CONFIG_KEXEC
        kexec_reinit = kirkwood_enable_pcie;
@@ -121,8 +180,6 @@ static const char * const kirkwood_dt_board_compat[] = {
 DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
        /* Maintainer: Jason Cooper <jason@lakedaemon.net> */
        .map_io         = kirkwood_map_io,
-       .init_early     = kirkwood_dt_init_early,
-       .init_time      = kirkwood_dt_time_init,
        .init_machine   = kirkwood_dt_init,
        .restart        = kirkwood_restart,
        .dt_compat      = kirkwood_dt_board_compat,
index 176761134a66b161592fd371593277cbd2f2e725..f3407a5db216498e6d30994c5fad8a872d2ac6b6 100644 (file)
@@ -721,6 +721,7 @@ void __init kirkwood_init(void)
        kirkwood_xor1_init();
        kirkwood_crypto_init();
 
+       kirkwood_pm_init();
        kirkwood_cpuidle_init();
 #ifdef CONFIG_KEXEC
        kexec_reinit = kirkwood_enable_pcie;
index 1296de94febff5735d0998dd0f6d4587d8642346..05fd648df543a669d393462e6b3d739cd6992421 100644 (file)
@@ -58,6 +58,12 @@ void kirkwood_cpufreq_init(void);
 void kirkwood_restart(enum reboot_mode, const char *);
 void kirkwood_clk_init(void);
 
+#ifdef CONFIG_PM
+void kirkwood_pm_init(void);
+#else
+static inline void kirkwood_pm_init(void) {};
+#endif
+
 /* board init functions for boards not fully converted to fdt */
 #ifdef CONFIG_MACH_MV88F6281GTW_GE_DT
 void mv88f6281gtw_ge_init(void);
index 91242c944d7aeefc7f62cc51dd93b30486390f2e..8b9d1c9ff1996aa58da90edaa572700e794af73b 100644 (file)
@@ -78,4 +78,6 @@
 #define CGC_TDM                        (1 << 20)
 #define CGC_RESERVED           (0x6 << 21)
 
+#define MEMORY_PM_CTRL         (BRIDGE_VIRT_BASE + 0x118)
+
 #endif
diff --git a/arch/arm/mach-kirkwood/pm.c b/arch/arm/mach-kirkwood/pm.c
new file mode 100644 (file)
index 0000000..8783a71
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Power Management driver for Marvell Kirkwood SoCs
+ *
+ * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/bridge-regs.h>
+
+static void __iomem *ddr_operation_base;
+
+static void kirkwood_low_power(void)
+{
+       u32 mem_pm_ctrl;
+
+       mem_pm_ctrl = readl(MEMORY_PM_CTRL);
+
+       /* Set peripherals to low-power mode */
+       writel_relaxed(~0, MEMORY_PM_CTRL);
+
+       /* Set DDR in self-refresh */
+       writel_relaxed(0x7, ddr_operation_base);
+
+       /*
+        * Set CPU in wait-for-interrupt state.
+        * This disables the CPU core clocks,
+        * the array clocks, and also the L2 controller.
+        */
+       cpu_do_idle();
+
+       writel_relaxed(mem_pm_ctrl, MEMORY_PM_CTRL);
+}
+
+static int kirkwood_suspend_enter(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_STANDBY:
+               kirkwood_low_power();
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int kirkwood_pm_valid_standby(suspend_state_t state)
+{
+       return state == PM_SUSPEND_STANDBY;
+}
+
+static const struct platform_suspend_ops kirkwood_suspend_ops = {
+       .enter = kirkwood_suspend_enter,
+       .valid = kirkwood_pm_valid_standby,
+};
+
+int __init kirkwood_pm_init(void)
+{
+       ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
+       suspend_set_ops(&kirkwood_suspend_ops);
+       return 0;
+}
index 905efc8cac797d5d30ae0db0ff0e28eba7fa140d..2586c28658740f7ff1a19d1ce979f286a2e112b4 100644 (file)
@@ -1,12 +1,12 @@
 if ARCH_MSM
 
 comment "Qualcomm MSM SoC Type"
-       depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+       depends on ARCH_MSM_DT
 
 choice
        prompt "Qualcomm MSM SoC Type"
        default ARCH_MSM7X00A
-       depends on !(ARCH_MSM8X60 || ARCH_MSM8960)
+       depends on !ARCH_MSM_DT
 
 config ARCH_MSM7X00A
        bool "MSM7x00A / MSM7x01A"
@@ -49,7 +49,6 @@ config ARCH_MSM8X60
        select GPIO_MSM_V2
        select HAVE_SMP
        select MSM_SCM if SMP
-       select USE_OF
 
 config ARCH_MSM8960
        bool "MSM8960"
@@ -58,6 +57,11 @@ config ARCH_MSM8960
        select HAVE_SMP
        select GPIO_MSM_V2
        select MSM_SCM if SMP
+
+config ARCH_MSM_DT
+       def_bool y
+       depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+       select SPARSE_IRQ
        select USE_OF
 
 config MSM_HAS_DEBUG_UART_HS
@@ -68,6 +72,7 @@ config MSM_SOC_REV_A
 
 config  ARCH_MSM_ARM11
        bool
+
 config  ARCH_MSM_SCORPION
        bool
 
@@ -75,6 +80,7 @@ config  MSM_VIC
        bool
 
 menu "Qualcomm MSM Board Type"
+       depends on !ARCH_MSM_DT
 
 config MACH_HALIBUT
        depends on ARCH_MSM
@@ -122,6 +128,7 @@ config MSM_SMD
 
 config MSM_GPIOMUX
        bool
+       depends on !ARCH_MSM_DT
        help
          Support for MSM V1 TLMM GPIOMUX architecture.
 
index d872634c2f85f32b6f4944233232734ebe325ebf..7ed4c1b2bdd20fd24ffd090ee63f7b9607ba66cb 100644 (file)
@@ -26,7 +26,6 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o b
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-obj-$(CONFIG_ARCH_MSM8X60) += board-dt-8660.o
-obj-$(CONFIG_ARCH_MSM8960) += board-dt-8960.o
+obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
 obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
 obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff --git a/arch/arm/mach-msm/board-dt-8660.c b/arch/arm/mach-msm/board-dt-8660.c
deleted file mode 100644 (file)
index c294689..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2010-2012, 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/init.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-static void __init msm8x60_init_late(void)
-{
-       smd_debugfs_init();
-}
-
-static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = {
-       {}
-};
-
-static void __init msm8x60_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table,
-                       msm_auxdata_lookup, NULL);
-}
-
-static const char *msm8x60_fluid_match[] __initdata = {
-       "qcom,msm8660-fluid",
-       "qcom,msm8660-surf",
-       NULL
-};
-
-DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
-       .smp = smp_ops(msm_smp_ops),
-       .init_machine = msm8x60_dt_init,
-       .init_late = msm8x60_init_late,
-       .dt_compat = msm8x60_fluid_match,
-MACHINE_END
diff --git a/arch/arm/mach-msm/board-dt-8960.c b/arch/arm/mach-msm/board-dt-8960.c
deleted file mode 100644 (file)
index d4ca52c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2012, 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-static void __init msm_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const msm8960_dt_match[] __initconst = {
-       "qcom,msm8960-cdp",
-       NULL
-};
-
-DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)")
-       .smp = smp_ops(msm_smp_ops),
-       .init_machine = msm_dt_init,
-       .dt_compat = msm8960_dt_match,
-MACHINE_END
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
new file mode 100644 (file)
index 0000000..16e6183
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (c) 2010-2012,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/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+static const char * const msm_dt_match[] __initconst = {
+       "qcom,msm8660-fluid",
+       "qcom,msm8660-surf",
+       "qcom,msm8960-cdp",
+       NULL
+};
+
+DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
+       .smp = smp_ops(msm_smp_ops),
+       .dt_compat = msm_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-msm/include/mach/irqs-8960.h b/arch/arm/mach-msm/include/mach/irqs-8960.h
deleted file mode 100644 (file)
index 81ab2a6..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Copyright (c) 2011 Code Aurora Forum. 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.
- */
-
-#ifndef __ASM_ARCH_MSM_IRQS_8960_H
-#define __ASM_ARCH_MSM_IRQS_8960_H
-
-/* MSM ACPU Interrupt Numbers */
-
-/* 0-15:  STI/SGI (software triggered/generated interrupts)
-   16-31: PPI (private peripheral interrupts)
-   32+:   SPI (shared peripheral interrupts) */
-
-#define GIC_PPI_START 16
-#define GIC_SPI_START 32
-
-#define INT_VGIC                               (GIC_PPI_START + 0)
-#define INT_DEBUG_TIMER_EXP                    (GIC_PPI_START + 1)
-#define INT_GP_TIMER_EXP                       (GIC_PPI_START + 2)
-#define INT_GP_TIMER2_EXP                      (GIC_PPI_START + 3)
-#define WDT0_ACCSCSSNBARK_INT                  (GIC_PPI_START + 4)
-#define WDT1_ACCSCSSNBARK_INT                  (GIC_PPI_START + 5)
-#define AVS_SVICINT                            (GIC_PPI_START + 6)
-#define AVS_SVICINTSWDONE                      (GIC_PPI_START + 7)
-#define CPU_DBGCPUXCOMMRXFULL                  (GIC_PPI_START + 8)
-#define CPU_DBGCPUXCOMMTXEMPTY                 (GIC_PPI_START + 9)
-#define CPU_SICCPUXPERFMONIRPTREQ              (GIC_PPI_START + 10)
-#define SC_AVSCPUXDOWN                         (GIC_PPI_START + 11)
-#define SC_AVSCPUXUP                           (GIC_PPI_START + 12)
-#define SC_SICCPUXACGIRPTREQ                   (GIC_PPI_START + 13)
-#define SC_SICCPUXEXTFAULTIRPTREQ              (GIC_PPI_START + 14)
-/* PPI 15 is unused */
-
-#define SC_SICMPUIRPTREQ                       (GIC_SPI_START + 0)
-#define SC_SICL2IRPTREQ                                (GIC_SPI_START + 1)
-#define SC_SICL2PERFMONIRPTREQ                 (GIC_SPI_START + 2)
-#define SC_SICAGCIRPTREQ                       (GIC_SPI_START + 3)
-#define TLMM_APCC_DIR_CONN_IRQ_0               (GIC_SPI_START + 4)
-#define TLMM_APCC_DIR_CONN_IRQ_1               (GIC_SPI_START + 5)
-#define TLMM_APCC_DIR_CONN_IRQ_2               (GIC_SPI_START + 6)
-#define TLMM_APCC_DIR_CONN_IRQ_3               (GIC_SPI_START + 7)
-#define TLMM_APCC_DIR_CONN_IRQ_4               (GIC_SPI_START + 8)
-#define TLMM_APCC_DIR_CONN_IRQ_5               (GIC_SPI_START + 9)
-#define TLMM_APCC_DIR_CONN_IRQ_6               (GIC_SPI_START + 10)
-#define TLMM_APCC_DIR_CONN_IRQ_7               (GIC_SPI_START + 11)
-#define TLMM_APCC_DIR_CONN_IRQ_8               (GIC_SPI_START + 12)
-#define TLMM_APCC_DIR_CONN_IRQ_9               (GIC_SPI_START + 13)
-#define PM8921_SEC_IRQ_103                     (GIC_SPI_START + 14)
-#define PM8018_SEC_IRQ_106                     (GIC_SPI_START + 15)
-#define TLMM_APCC_SUMMARY_IRQ                  (GIC_SPI_START + 16)
-#define SPDM_RT_1_IRQ                          (GIC_SPI_START + 17)
-#define SPDM_DIAG_IRQ                          (GIC_SPI_START + 18)
-#define RPM_APCC_CPU0_GP_HIGH_IRQ              (GIC_SPI_START + 19)
-#define RPM_APCC_CPU0_GP_MEDIUM_IRQ            (GIC_SPI_START + 20)
-#define RPM_APCC_CPU0_GP_LOW_IRQ               (GIC_SPI_START + 21)
-#define RPM_APCC_CPU0_WAKE_UP_IRQ              (GIC_SPI_START + 22)
-#define RPM_APCC_CPU1_GP_HIGH_IRQ              (GIC_SPI_START + 23)
-#define RPM_APCC_CPU1_GP_MEDIUM_IRQ            (GIC_SPI_START + 24)
-#define RPM_APCC_CPU1_GP_LOW_IRQ               (GIC_SPI_START + 25)
-#define RPM_APCC_CPU1_WAKE_UP_IRQ              (GIC_SPI_START + 26)
-#define SSBI2_2_SC_CPU0_SECURE_IRQ             (GIC_SPI_START + 27)
-#define SSBI2_2_SC_CPU0_NON_SECURE_IRQ         (GIC_SPI_START + 28)
-#define SSBI2_1_SC_CPU0_SECURE_IRQ             (GIC_SPI_START + 29)
-#define SSBI2_1_SC_CPU0_NON_SECURE_IRQ         (GIC_SPI_START + 30)
-#define MSMC_SC_SEC_CE_IRQ                     (GIC_SPI_START + 31)
-#define MSMC_SC_PRI_CE_IRQ                     (GIC_SPI_START + 32)
-#define SLIMBUS0_CORE_EE1_IRQ                  (GIC_SPI_START + 33)
-#define SLIMBUS0_BAM_EE1_IRQ                   (GIC_SPI_START + 34)
-#define Q6FW_WDOG_EXPIRED_IRQ                  (GIC_SPI_START + 35)
-#define Q6SW_WDOG_EXPIRED_IRQ                  (GIC_SPI_START + 36)
-#define MSS_TO_APPS_IRQ_0                      (GIC_SPI_START + 37)
-#define MSS_TO_APPS_IRQ_1                      (GIC_SPI_START + 38)
-#define MSS_TO_APPS_IRQ_2                      (GIC_SPI_START + 39)
-#define MSS_TO_APPS_IRQ_3                      (GIC_SPI_START + 40)
-#define MSS_TO_APPS_IRQ_4                      (GIC_SPI_START + 41)
-#define MSS_TO_APPS_IRQ_5                      (GIC_SPI_START + 42)
-#define MSS_TO_APPS_IRQ_6                      (GIC_SPI_START + 43)
-#define MSS_TO_APPS_IRQ_7                      (GIC_SPI_START + 44)
-#define MSS_TO_APPS_IRQ_8                      (GIC_SPI_START + 45)
-#define MSS_TO_APPS_IRQ_9                      (GIC_SPI_START + 46)
-#define VPE_IRQ                                        (GIC_SPI_START + 47)
-#define VFE_IRQ                                        (GIC_SPI_START + 48)
-#define VCODEC_IRQ                             (GIC_SPI_START + 49)
-#define TV_ENC_IRQ                             (GIC_SPI_START + 50)
-#define SMMU_VPE_CB_SC_SECURE_IRQ              (GIC_SPI_START + 51)
-#define SMMU_VPE_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 52)
-#define SMMU_VFE_CB_SC_SECURE_IRQ              (GIC_SPI_START + 53)
-#define SMMU_VFE_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 54)
-#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ         (GIC_SPI_START + 55)
-#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ     (GIC_SPI_START + 56)
-#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ         (GIC_SPI_START + 57)
-#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ     (GIC_SPI_START + 58)
-#define SMMU_ROT_CB_SC_SECURE_IRQ              (GIC_SPI_START + 59)
-#define SMMU_ROT_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 60)
-#define SMMU_MDP1_CB_SC_SECURE_IRQ             (GIC_SPI_START + 61)
-#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ         (GIC_SPI_START + 62)
-#define SMMU_MDP0_CB_SC_SECURE_IRQ             (GIC_SPI_START + 63)
-#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ         (GIC_SPI_START + 64)
-#define SMMU_JPEGD_CB_SC_SECURE_IRQ            (GIC_SPI_START + 65)
-#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 66)
-#define SMMU_IJPEG_CB_SC_SECURE_IRQ            (GIC_SPI_START + 67)
-#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 68)
-#define SMMU_GFX3D_CB_SC_SECURE_IRQ            (GIC_SPI_START + 69)
-#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 70)
-#define SMMU_GFX2D0_CB_SC_SECURE_IRQ           (GIC_SPI_START + 71)
-#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ       (GIC_SPI_START + 72)
-#define ROT_IRQ                                        (GIC_SPI_START + 73)
-#define MMSS_FABRIC_IRQ                                (GIC_SPI_START + 74)
-#define MDP_IRQ                                        (GIC_SPI_START + 75)
-#define JPEGD_IRQ                              (GIC_SPI_START + 76)
-#define JPEG_IRQ                               (GIC_SPI_START + 77)
-#define MMSS_IMEM_IRQ                          (GIC_SPI_START + 78)
-#define HDMI_IRQ                               (GIC_SPI_START + 79)
-#define GFX3D_IRQ                              (GIC_SPI_START + 80)
-#define GFX2D0_IRQ                             (GIC_SPI_START + 81)
-#define DSI1_IRQ                               (GIC_SPI_START + 82)
-#define CSI_1_IRQ                              (GIC_SPI_START + 83)
-#define CSI_0_IRQ                              (GIC_SPI_START + 84)
-#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ           (GIC_SPI_START + 85)
-#define LPASS_SCSS_MIDI_IRQ                    (GIC_SPI_START + 86)
-#define LPASS_Q6SS_WDOG_EXPIRED                        (GIC_SPI_START + 87)
-#define LPASS_SCSS_GP_LOW_IRQ                  (GIC_SPI_START + 88)
-#define LPASS_SCSS_GP_MEDIUM_IRQ               (GIC_SPI_START + 89)
-#define LPASS_SCSS_GP_HIGH_IRQ                 (GIC_SPI_START + 90)
-#define TOP_IMEM_IRQ                           (GIC_SPI_START + 91)
-#define FABRIC_SYS_IRQ                         (GIC_SPI_START + 92)
-#define FABRIC_APPS_IRQ                                (GIC_SPI_START + 93)
-#define USB1_HS_BAM_IRQ                                (GIC_SPI_START + 94)
-#define SDC4_BAM_IRQ                           (GIC_SPI_START + 95)
-#define SDC3_BAM_IRQ                           (GIC_SPI_START + 96)
-#define SDC2_BAM_IRQ                           (GIC_SPI_START + 97)
-#define SDC1_BAM_IRQ                           (GIC_SPI_START + 98)
-#define FABRIC_SPS_IRQ                         (GIC_SPI_START + 99)
-#define USB1_HS_IRQ                            (GIC_SPI_START + 100)
-#define SDC4_IRQ_0                             (GIC_SPI_START + 101)
-#define SDC3_IRQ_0                             (GIC_SPI_START + 102)
-#define SDC2_IRQ_0                             (GIC_SPI_START + 103)
-#define SDC1_IRQ_0                             (GIC_SPI_START + 104)
-#define SPS_BAM_DMA_IRQ                                (GIC_SPI_START + 105)
-#define SPS_SEC_VIOL_IRQ                       (GIC_SPI_START + 106)
-#define SPS_MTI_0                              (GIC_SPI_START + 107)
-#define SPS_MTI_1                              (GIC_SPI_START + 108)
-#define SPS_MTI_2                              (GIC_SPI_START + 109)
-#define SPS_MTI_3                              (GIC_SPI_START + 110)
-#define SPS_MTI_4                              (GIC_SPI_START + 111)
-#define SPS_MTI_5                              (GIC_SPI_START + 112)
-#define SPS_MTI_6                              (GIC_SPI_START + 113)
-#define SPS_MTI_7                              (GIC_SPI_START + 114)
-#define SPS_MTI_8                              (GIC_SPI_START + 115)
-#define SPS_MTI_9                              (GIC_SPI_START + 116)
-#define SPS_MTI_10                             (GIC_SPI_START + 117)
-#define SPS_MTI_11                             (GIC_SPI_START + 118)
-#define SPS_MTI_12                             (GIC_SPI_START + 119)
-#define SPS_MTI_13                             (GIC_SPI_START + 120)
-#define SPS_MTI_14                             (GIC_SPI_START + 121)
-#define SPS_MTI_15                             (GIC_SPI_START + 122)
-#define SPS_MTI_16                             (GIC_SPI_START + 123)
-#define SPS_MTI_17                             (GIC_SPI_START + 124)
-#define SPS_MTI_18                             (GIC_SPI_START + 125)
-#define SPS_MTI_19                             (GIC_SPI_START + 126)
-#define SPS_MTI_20                             (GIC_SPI_START + 127)
-#define SPS_MTI_21                             (GIC_SPI_START + 128)
-#define SPS_MTI_22                             (GIC_SPI_START + 129)
-#define SPS_MTI_23                             (GIC_SPI_START + 130)
-#define SPS_MTI_24                             (GIC_SPI_START + 131)
-#define SPS_MTI_25                             (GIC_SPI_START + 132)
-#define SPS_MTI_26                             (GIC_SPI_START + 133)
-#define SPS_MTI_27                             (GIC_SPI_START + 134)
-#define SPS_MTI_28                             (GIC_SPI_START + 135)
-#define SPS_MTI_29                             (GIC_SPI_START + 136)
-#define SPS_MTI_30                             (GIC_SPI_START + 137)
-#define SPS_MTI_31                             (GIC_SPI_START + 138)
-#define CSIPHY_4LN_IRQ                         (GIC_SPI_START + 139)
-#define CSIPHY_2LN_IRQ                         (GIC_SPI_START + 140)
-#define USB2_IRQ                               (GIC_SPI_START + 141)
-#define USB1_IRQ                               (GIC_SPI_START + 142)
-#define TSSC_SSBI_IRQ                          (GIC_SPI_START + 143)
-#define TSSC_SAMPLE_IRQ                                (GIC_SPI_START + 144)
-#define TSSC_PENUP_IRQ                         (GIC_SPI_START + 145)
-#define GSBI1_UARTDM_IRQ                       (GIC_SPI_START + 146)
-#define GSBI1_QUP_IRQ                          (GIC_SPI_START + 147)
-#define GSBI2_UARTDM_IRQ                       (GIC_SPI_START + 148)
-#define GSBI2_QUP_IRQ                          (GIC_SPI_START + 149)
-#define GSBI3_UARTDM_IRQ                       (GIC_SPI_START + 150)
-#define GSBI3_QUP_IRQ                          (GIC_SPI_START + 151)
-#define GSBI4_UARTDM_IRQ                       (GIC_SPI_START + 152)
-#define GSBI4_QUP_IRQ                          (GIC_SPI_START + 153)
-#define GSBI5_UARTDM_IRQ                       (GIC_SPI_START + 154)
-#define GSBI5_QUP_IRQ                          (GIC_SPI_START + 155)
-#define GSBI6_UARTDM_IRQ                       (GIC_SPI_START + 156)
-#define GSBI6_QUP_IRQ                          (GIC_SPI_START + 157)
-#define GSBI7_UARTDM_IRQ                       (GIC_SPI_START + 158)
-#define GSBI7_QUP_IRQ                          (GIC_SPI_START + 159)
-#define GSBI8_UARTDM_IRQ                       (GIC_SPI_START + 160)
-#define GSBI8_QUP_IRQ                          (GIC_SPI_START + 161)
-#define TSIF_TSPP_IRQ                          (GIC_SPI_START + 162)
-#define TSIF_BAM_IRQ                           (GIC_SPI_START + 163)
-#define TSIF2_IRQ                              (GIC_SPI_START + 164)
-#define TSIF1_IRQ                              (GIC_SPI_START + 165)
-#define DSI2_IRQ                               (GIC_SPI_START + 166)
-#define ISPIF_IRQ                              (GIC_SPI_START + 167)
-#define MSMC_SC_SEC_TMR_IRQ                    (GIC_SPI_START + 168)
-#define MSMC_SC_SEC_WDOG_BARK_IRQ              (GIC_SPI_START + 169)
-#define INT_ADM0_SCSS_0_IRQ                    (GIC_SPI_START + 170)
-#define INT_ADM0_SCSS_1_IRQ                    (GIC_SPI_START + 171)
-#define INT_ADM0_SCSS_2_IRQ                    (GIC_SPI_START + 172)
-#define INT_ADM0_SCSS_3_IRQ                    (GIC_SPI_START + 173)
-#define CC_SCSS_WDT1CPU1BITEEXPIRED            (GIC_SPI_START + 174)
-#define CC_SCSS_WDT1CPU0BITEEXPIRED            (GIC_SPI_START + 175)
-#define CC_SCSS_WDT0CPU1BITEEXPIRED            (GIC_SPI_START + 176)
-#define CC_SCSS_WDT0CPU0BITEEXPIRED            (GIC_SPI_START + 177)
-#define TSENS_UPPER_LOWER_INT                  (GIC_SPI_START + 178)
-#define SSBI2_2_SC_CPU1_SECURE_INT             (GIC_SPI_START + 179)
-#define SSBI2_2_SC_CPU1_NON_SECURE_INT         (GIC_SPI_START + 180)
-#define SSBI2_1_SC_CPU1_SECURE_INT             (GIC_SPI_START + 181)
-#define SSBI2_1_SC_CPU1_NON_SECURE_INT         (GIC_SPI_START + 182)
-#define XPU_SUMMARY_IRQ                                (GIC_SPI_START + 183)
-#define BUS_EXCEPTION_SUMMARY_IRQ              (GIC_SPI_START + 184)
-#define HSDDRX_EBI1CH0_IRQ                     (GIC_SPI_START + 185)
-#define HSDDRX_EBI1CH1_IRQ                     (GIC_SPI_START + 186)
-#define SDC5_BAM_IRQ                           (GIC_SPI_START + 187)
-#define SDC5_IRQ_0                             (GIC_SPI_START + 188)
-#define GSBI9_UARTDM_IRQ                       (GIC_SPI_START + 189)
-#define GSBI9_QUP_IRQ                          (GIC_SPI_START + 190)
-#define GSBI10_UARTDM_IRQ                      (GIC_SPI_START + 191)
-#define GSBI10_QUP_IRQ                         (GIC_SPI_START + 192)
-#define GSBI11_UARTDM_IRQ                      (GIC_SPI_START + 193)
-#define GSBI11_QUP_IRQ                         (GIC_SPI_START + 194)
-#define GSBI12_UARTDM_IRQ                      (GIC_SPI_START + 195)
-#define GSBI12_QUP_IRQ                         (GIC_SPI_START + 196)
-#define RIVA_APSS_LTECOEX_IRQ                  (GIC_SPI_START + 197)
-#define RIVA_APSS_SPARE_IRQ                    (GIC_SPI_START + 198)
-#define RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ      (GIC_SPI_START + 199)
-#define RIVA_ASS_RESET_DONE_IRQ                        (GIC_SPI_START + 200)
-#define RIVA_APSS_ASIC_IRQ                     (GIC_SPI_START + 201)
-#define RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ       (GIC_SPI_START + 202)
-#define RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ      (GIC_SPI_START + 203)
-#define RIVA_APPS_WLAM_SMSM_IRQ                        (GIC_SPI_START + 204)
-#define RIVA_APPS_LOG_CTRL_IRQ                 (GIC_SPI_START + 205)
-#define RIVA_APPS_FM_CTRL_IRQ                  (GIC_SPI_START + 206)
-#define RIVA_APPS_HCI_IRQ                      (GIC_SPI_START + 207)
-#define RIVA_APPS_WLAN_CTRL_IRQ                        (GIC_SPI_START + 208)
-#define A2_BAM_IRQ                             (GIC_SPI_START + 209)
-#define SMMU_GFX2D1_CB_SC_SECURE_IRQ           (GIC_SPI_START + 210)
-#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ       (GIC_SPI_START + 211)
-#define GFX2D1_IRQ                             (GIC_SPI_START + 212)
-#define PPSS_WDOG_TIMER_IRQ                    (GIC_SPI_START + 213)
-#define SPS_SLIMBUS_CORE_EE0_IRQ               (GIC_SPI_START + 214)
-#define SPS_SLIMBUS_BAM_EE0_IRQ                        (GIC_SPI_START + 215)
-#define QDSS_ETB_IRQ                           (GIC_SPI_START + 216)
-#define QDSS_CTI2KPSS_CPU1_IRQ                 (GIC_SPI_START + 217)
-#define QDSS_CTI2KPSS_CPU0_IRQ                 (GIC_SPI_START + 218)
-#define TLMM_APCC_DIR_CONN_IRQ_16              (GIC_SPI_START + 219)
-#define TLMM_APCC_DIR_CONN_IRQ_17              (GIC_SPI_START + 220)
-#define TLMM_APCC_DIR_CONN_IRQ_18              (GIC_SPI_START + 221)
-#define TLMM_APCC_DIR_CONN_IRQ_19              (GIC_SPI_START + 222)
-#define TLMM_APCC_DIR_CONN_IRQ_20              (GIC_SPI_START + 223)
-#define TLMM_APCC_DIR_CONN_IRQ_21              (GIC_SPI_START + 224)
-#define PM8921_SEC_IRQ_104                     (GIC_SPI_START + 225)
-#define PM8018_SEC_IRQ_107                     (GIC_SPI_START + 226)
-
-/* For now, use the maximum number of interrupts until a pending GIC issue
- * is sorted out */
-#define NR_MSM_IRQS 1020
-#define NR_BOARD_IRQS 0
-#define NR_GPIO_IRQS 0
-
-#endif
-
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
deleted file mode 100644 (file)
index f65841c..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/* Copyright (c) 2010 Code Aurora Forum. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __ASM_ARCH_MSM_IRQS_8X60_H
-#define __ASM_ARCH_MSM_IRQS_8X60_H
-
-/* MSM ACPU Interrupt Numbers */
-
-/* 0-15:  STI/SGI (software triggered/generated interrupts)
- * 16-31: PPI (private peripheral interrupts)
- * 32+:   SPI (shared peripheral interrupts)
- */
-
-#define GIC_PPI_START 16
-#define GIC_SPI_START 32
-
-#define INT_DEBUG_TIMER_EXP                    (GIC_PPI_START + 0)
-#define INT_GP_TIMER_EXP                       (GIC_PPI_START + 1)
-#define INT_GP_TIMER2_EXP                      (GIC_PPI_START + 2)
-#define WDT0_ACCSCSSNBARK_INT                  (GIC_PPI_START + 3)
-#define WDT1_ACCSCSSNBARK_INT                  (GIC_PPI_START + 4)
-#define AVS_SVICINT                            (GIC_PPI_START + 5)
-#define AVS_SVICINTSWDONE                      (GIC_PPI_START + 6)
-#define CPU_DBGCPUXCOMMRXFULL                  (GIC_PPI_START + 7)
-#define CPU_DBGCPUXCOMMTXEMPTY                 (GIC_PPI_START + 8)
-#define CPU_SICCPUXPERFMONIRPTREQ              (GIC_PPI_START + 9)
-#define SC_AVSCPUXDOWN                         (GIC_PPI_START + 10)
-#define SC_AVSCPUXUP                           (GIC_PPI_START + 11)
-#define SC_SICCPUXACGIRPTREQ                   (GIC_PPI_START + 12)
-/* PPI 13 to 15 are unused */
-
-
-#define SC_SICMPUIRPTREQ                       (GIC_SPI_START + 0)
-#define SC_SICL2IRPTREQ                                (GIC_SPI_START + 1)
-#define SC_SICL2ACGIRPTREQ                     (GIC_SPI_START + 2)
-#define NC                                     (GIC_SPI_START + 3)
-#define TLMM_SCSS_DIR_CONN_IRQ_0               (GIC_SPI_START + 4)
-#define TLMM_SCSS_DIR_CONN_IRQ_1               (GIC_SPI_START + 5)
-#define TLMM_SCSS_DIR_CONN_IRQ_2               (GIC_SPI_START + 6)
-#define TLMM_SCSS_DIR_CONN_IRQ_3               (GIC_SPI_START + 7)
-#define TLMM_SCSS_DIR_CONN_IRQ_4               (GIC_SPI_START + 8)
-#define TLMM_SCSS_DIR_CONN_IRQ_5               (GIC_SPI_START + 9)
-#define TLMM_SCSS_DIR_CONN_IRQ_6               (GIC_SPI_START + 10)
-#define TLMM_SCSS_DIR_CONN_IRQ_7               (GIC_SPI_START + 11)
-#define TLMM_SCSS_DIR_CONN_IRQ_8               (GIC_SPI_START + 12)
-#define TLMM_SCSS_DIR_CONN_IRQ_9               (GIC_SPI_START + 13)
-#define PM8058_SEC_IRQ_N                       (GIC_SPI_START + 14)
-#define PM8901_SEC_IRQ_N                       (GIC_SPI_START + 15)
-#define TLMM_SCSS_SUMMARY_IRQ                  (GIC_SPI_START + 16)
-#define SPDM_RT_1_IRQ                          (GIC_SPI_START + 17)
-#define SPDM_DIAG_IRQ                          (GIC_SPI_START + 18)
-#define RPM_SCSS_CPU0_GP_HIGH_IRQ              (GIC_SPI_START + 19)
-#define RPM_SCSS_CPU0_GP_MEDIUM_IRQ            (GIC_SPI_START + 20)
-#define RPM_SCSS_CPU0_GP_LOW_IRQ               (GIC_SPI_START + 21)
-#define RPM_SCSS_CPU0_WAKE_UP_IRQ              (GIC_SPI_START + 22)
-#define RPM_SCSS_CPU1_GP_HIGH_IRQ              (GIC_SPI_START + 23)
-#define RPM_SCSS_CPU1_GP_MEDIUM_IRQ            (GIC_SPI_START + 24)
-#define RPM_SCSS_CPU1_GP_LOW_IRQ               (GIC_SPI_START + 25)
-#define RPM_SCSS_CPU1_WAKE_UP_IRQ              (GIC_SPI_START + 26)
-#define SSBI2_2_SC_CPU0_SECURE_INT             (GIC_SPI_START + 27)
-#define SSBI2_2_SC_CPU0_NON_SECURE_INT         (GIC_SPI_START + 28)
-#define SSBI2_1_SC_CPU0_SECURE_INT             (GIC_SPI_START + 29)
-#define SSBI2_1_SC_CPU0_NON_SECURE_INT         (GIC_SPI_START + 30)
-#define MSMC_SC_SEC_CE_IRQ                     (GIC_SPI_START + 31)
-#define MSMC_SC_PRI_CE_IRQ                     (GIC_SPI_START + 32)
-#define MARM_FIQ                               (GIC_SPI_START + 33)
-#define MARM_IRQ                               (GIC_SPI_START + 34)
-#define MARM_L2CC_IRQ                          (GIC_SPI_START + 35)
-#define MARM_WDOG_EXPIRED                      (GIC_SPI_START + 36)
-#define MARM_SCSS_GP_IRQ_0                     (GIC_SPI_START + 37)
-#define MARM_SCSS_GP_IRQ_1                     (GIC_SPI_START + 38)
-#define MARM_SCSS_GP_IRQ_2                     (GIC_SPI_START + 39)
-#define MARM_SCSS_GP_IRQ_3                     (GIC_SPI_START + 40)
-#define MARM_SCSS_GP_IRQ_4                     (GIC_SPI_START + 41)
-#define MARM_SCSS_GP_IRQ_5                     (GIC_SPI_START + 42)
-#define MARM_SCSS_GP_IRQ_6                     (GIC_SPI_START + 43)
-#define MARM_SCSS_GP_IRQ_7                     (GIC_SPI_START + 44)
-#define MARM_SCSS_GP_IRQ_8                     (GIC_SPI_START + 45)
-#define MARM_SCSS_GP_IRQ_9                     (GIC_SPI_START + 46)
-#define VPE_IRQ                                        (GIC_SPI_START + 47)
-#define VFE_IRQ                                        (GIC_SPI_START + 48)
-#define VCODEC_IRQ                             (GIC_SPI_START + 49)
-#define TV_ENC_IRQ                             (GIC_SPI_START + 50)
-#define SMMU_VPE_CB_SC_SECURE_IRQ              (GIC_SPI_START + 51)
-#define SMMU_VPE_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 52)
-#define SMMU_VFE_CB_SC_SECURE_IRQ              (GIC_SPI_START + 53)
-#define SMMU_VFE_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 54)
-#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ         (GIC_SPI_START + 55)
-#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ     (GIC_SPI_START + 56)
-#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ         (GIC_SPI_START + 57)
-#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ     (GIC_SPI_START + 58)
-#define SMMU_ROT_CB_SC_SECURE_IRQ              (GIC_SPI_START + 59)
-#define SMMU_ROT_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 60)
-#define SMMU_MDP1_CB_SC_SECURE_IRQ             (GIC_SPI_START + 61)
-#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ         (GIC_SPI_START + 62)
-#define SMMU_MDP0_CB_SC_SECURE_IRQ             (GIC_SPI_START + 63)
-#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ         (GIC_SPI_START + 64)
-#define SMMU_JPEGD_CB_SC_SECURE_IRQ            (GIC_SPI_START + 65)
-#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 66)
-#define SMMU_IJPEG_CB_SC_SECURE_IRQ            (GIC_SPI_START + 67)
-#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 68)
-#define SMMU_GFX3D_CB_SC_SECURE_IRQ            (GIC_SPI_START + 69)
-#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 70)
-#define SMMU_GFX2D0_CB_SC_SECURE_IRQ           (GIC_SPI_START + 71)
-#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ       (GIC_SPI_START + 72)
-#define ROT_IRQ                                        (GIC_SPI_START + 73)
-#define MMSS_FABRIC_IRQ                                (GIC_SPI_START + 74)
-#define MDP_IRQ                                        (GIC_SPI_START + 75)
-#define JPEGD_IRQ                              (GIC_SPI_START + 76)
-#define JPEG_IRQ                               (GIC_SPI_START + 77)
-#define MMSS_IMEM_IRQ                          (GIC_SPI_START + 78)
-#define HDMI_IRQ                               (GIC_SPI_START + 79)
-#define GFX3D_IRQ                              (GIC_SPI_START + 80)
-#define GFX2D0_IRQ                             (GIC_SPI_START + 81)
-#define DSI_IRQ                                        (GIC_SPI_START + 82)
-#define CSI_1_IRQ                              (GIC_SPI_START + 83)
-#define CSI_0_IRQ                              (GIC_SPI_START + 84)
-#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ           (GIC_SPI_START + 85)
-#define LPASS_SCSS_MIDI_IRQ                    (GIC_SPI_START + 86)
-#define LPASS_Q6SS_WDOG_EXPIRED                        (GIC_SPI_START + 87)
-#define LPASS_SCSS_GP_LOW_IRQ                  (GIC_SPI_START + 88)
-#define LPASS_SCSS_GP_MEDIUM_IRQ               (GIC_SPI_START + 89)
-#define LPASS_SCSS_GP_HIGH_IRQ                 (GIC_SPI_START + 90)
-#define TOP_IMEM_IRQ                           (GIC_SPI_START + 91)
-#define FABRIC_SYS_IRQ                         (GIC_SPI_START + 92)
-#define FABRIC_APPS_IRQ                                (GIC_SPI_START + 93)
-#define USB1_HS_BAM_IRQ                                (GIC_SPI_START + 94)
-#define SDC4_BAM_IRQ                           (GIC_SPI_START + 95)
-#define SDC3_BAM_IRQ                           (GIC_SPI_START + 96)
-#define SDC2_BAM_IRQ                           (GIC_SPI_START + 97)
-#define SDC1_BAM_IRQ                           (GIC_SPI_START + 98)
-#define FABRIC_SPS_IRQ                         (GIC_SPI_START + 99)
-#define USB1_HS_IRQ                            (GIC_SPI_START + 100)
-#define SDC4_IRQ_0                             (GIC_SPI_START + 101)
-#define SDC3_IRQ_0                             (GIC_SPI_START + 102)
-#define SDC2_IRQ_0                             (GIC_SPI_START + 103)
-#define SDC1_IRQ_0                             (GIC_SPI_START + 104)
-#define SPS_BAM_DMA_IRQ                                (GIC_SPI_START + 105)
-#define SPS_SEC_VIOL_IRQ                       (GIC_SPI_START + 106)
-#define SPS_MTI_0                              (GIC_SPI_START + 107)
-#define SPS_MTI_1                              (GIC_SPI_START + 108)
-#define SPS_MTI_2                              (GIC_SPI_START + 109)
-#define SPS_MTI_3                              (GIC_SPI_START + 110)
-#define SPS_MTI_4                              (GIC_SPI_START + 111)
-#define SPS_MTI_5                              (GIC_SPI_START + 112)
-#define SPS_MTI_6                              (GIC_SPI_START + 113)
-#define SPS_MTI_7                              (GIC_SPI_START + 114)
-#define SPS_MTI_8                              (GIC_SPI_START + 115)
-#define SPS_MTI_9                              (GIC_SPI_START + 116)
-#define SPS_MTI_10                             (GIC_SPI_START + 117)
-#define SPS_MTI_11                             (GIC_SPI_START + 118)
-#define SPS_MTI_12                             (GIC_SPI_START + 119)
-#define SPS_MTI_13                             (GIC_SPI_START + 120)
-#define SPS_MTI_14                             (GIC_SPI_START + 121)
-#define SPS_MTI_15                             (GIC_SPI_START + 122)
-#define SPS_MTI_16                             (GIC_SPI_START + 123)
-#define SPS_MTI_17                             (GIC_SPI_START + 124)
-#define SPS_MTI_18                             (GIC_SPI_START + 125)
-#define SPS_MTI_19                             (GIC_SPI_START + 126)
-#define SPS_MTI_20                             (GIC_SPI_START + 127)
-#define SPS_MTI_21                             (GIC_SPI_START + 128)
-#define SPS_MTI_22                             (GIC_SPI_START + 129)
-#define SPS_MTI_23                             (GIC_SPI_START + 130)
-#define SPS_MTI_24                             (GIC_SPI_START + 131)
-#define SPS_MTI_25                             (GIC_SPI_START + 132)
-#define SPS_MTI_26                             (GIC_SPI_START + 133)
-#define SPS_MTI_27                             (GIC_SPI_START + 134)
-#define SPS_MTI_28                             (GIC_SPI_START + 135)
-#define SPS_MTI_29                             (GIC_SPI_START + 136)
-#define SPS_MTI_30                             (GIC_SPI_START + 137)
-#define SPS_MTI_31                             (GIC_SPI_START + 138)
-#define UXMC_EBI2_WR_ER_DONE_IRQ               (GIC_SPI_START + 139)
-#define UXMC_EBI2_OP_DONE_IRQ                  (GIC_SPI_START + 140)
-#define USB2_IRQ                               (GIC_SPI_START + 141)
-#define USB1_IRQ                               (GIC_SPI_START + 142)
-#define TSSC_SSBI_IRQ                          (GIC_SPI_START + 143)
-#define TSSC_SAMPLE_IRQ                                (GIC_SPI_START + 144)
-#define TSSC_PENUP_IRQ                         (GIC_SPI_START + 145)
-#define INT_UART1DM_IRQ                                (GIC_SPI_START + 146)
-#define GSBI1_QUP_IRQ                          (GIC_SPI_START + 147)
-#define INT_UART2DM_IRQ                                (GIC_SPI_START + 148)
-#define GSBI2_QUP_IRQ                          (GIC_SPI_START + 149)
-#define INT_UART3DM_IRQ                                (GIC_SPI_START + 150)
-#define GSBI3_QUP_IRQ                          (GIC_SPI_START + 151)
-#define INT_UART4DM_IRQ                                (GIC_SPI_START + 152)
-#define GSBI4_QUP_IRQ                          (GIC_SPI_START + 153)
-#define INT_UART5DM_IRQ                                (GIC_SPI_START + 154)
-#define GSBI5_QUP_IRQ                          (GIC_SPI_START + 155)
-#define INT_UART6DM_IRQ                                (GIC_SPI_START + 156)
-#define GSBI6_QUP_IRQ                          (GIC_SPI_START + 157)
-#define INT_UART7DM_IRQ                                (GIC_SPI_START + 158)
-#define GSBI7_QUP_IRQ                          (GIC_SPI_START + 159)
-#define INT_UART8DM_IRQ                                (GIC_SPI_START + 160)
-#define GSBI8_QUP_IRQ                          (GIC_SPI_START + 161)
-#define TSIF_TSPP_IRQ                          (GIC_SPI_START + 162)
-#define TSIF_BAM_IRQ                           (GIC_SPI_START + 163)
-#define TSIF2_IRQ                              (GIC_SPI_START + 164)
-#define TSIF1_IRQ                              (GIC_SPI_START + 165)
-#define INT_ADM1_MASTER                                (GIC_SPI_START + 166)
-#define INT_ADM1_AARM                          (GIC_SPI_START + 167)
-#define INT_ADM1_SD2                           (GIC_SPI_START + 168)
-#define INT_ADM1_SD3                           (GIC_SPI_START + 169)
-#define INT_ADM0_MASTER                                (GIC_SPI_START + 170)
-#define INT_ADM0_AARM                          (GIC_SPI_START + 171)
-#define INT_ADM0_SD2                           (GIC_SPI_START + 172)
-#define INT_ADM0_SD3                           (GIC_SPI_START + 173)
-#define CC_SCSS_WDT1CPU1BITEEXPIRED            (GIC_SPI_START + 174)
-#define CC_SCSS_WDT1CPU0BITEEXPIRED            (GIC_SPI_START + 175)
-#define CC_SCSS_WDT0CPU1BITEEXPIRED            (GIC_SPI_START + 176)
-#define CC_SCSS_WDT0CPU0BITEEXPIRED            (GIC_SPI_START + 177)
-#define TSENS_UPPER_LOWER_INT                  (GIC_SPI_START + 178)
-#define SSBI2_2_SC_CPU1_SECURE_INT             (GIC_SPI_START + 179)
-#define SSBI2_2_SC_CPU1_NON_SECURE_INT         (GIC_SPI_START + 180)
-#define SSBI2_1_SC_CPU1_SECURE_INT             (GIC_SPI_START + 181)
-#define SSBI2_1_SC_CPU1_NON_SECURE_INT         (GIC_SPI_START + 182)
-#define XPU_SUMMARY_IRQ                                (GIC_SPI_START + 183)
-#define BUS_EXCEPTION_SUMMARY_IRQ              (GIC_SPI_START + 184)
-#define HSDDRX_SMICH0_IRQ                      (GIC_SPI_START + 185)
-#define HSDDRX_EBI1_IRQ                                (GIC_SPI_START + 186)
-#define SDC5_BAM_IRQ                           (GIC_SPI_START + 187)
-#define SDC5_IRQ_0                             (GIC_SPI_START + 188)
-#define INT_UART9DM_IRQ                                (GIC_SPI_START + 189)
-#define GSBI9_QUP_IRQ                          (GIC_SPI_START + 190)
-#define INT_UART10DM_IRQ                       (GIC_SPI_START + 191)
-#define GSBI10_QUP_IRQ                         (GIC_SPI_START + 192)
-#define INT_UART11DM_IRQ                       (GIC_SPI_START + 193)
-#define GSBI11_QUP_IRQ                         (GIC_SPI_START + 194)
-#define INT_UART12DM_IRQ                       (GIC_SPI_START + 195)
-#define GSBI12_QUP_IRQ                         (GIC_SPI_START + 196)
-
-/*SPI 197 to 209 arent used in 8x60*/
-#define SMMU_GFX2D1_CB_SC_SECURE_IRQ            (GIC_SPI_START + 210)
-#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ        (GIC_SPI_START + 211)
-
-/*SPI 212 to 216 arent used in 8x60*/
-#define SMPSS_SPARE_1                          (GIC_SPI_START + 217)
-#define SMPSS_SPARE_2                          (GIC_SPI_START + 218)
-#define SMPSS_SPARE_3                          (GIC_SPI_START + 219)
-#define SMPSS_SPARE_4                          (GIC_SPI_START + 220)
-#define SMPSS_SPARE_5                          (GIC_SPI_START + 221)
-#define SMPSS_SPARE_6                          (GIC_SPI_START + 222)
-#define SMPSS_SPARE_7                          (GIC_SPI_START + 223)
-
-#define NR_GPIO_IRQS 173
-#define NR_MSM_IRQS 256
-#define NR_BOARD_IRQS 0
-
-#endif
index 3cd78b165abb22b4ca53896ac825f03262d4ef55..164d355c96ea99d5a9b884de18b201f4461054f4 100644 (file)
 #elif defined(CONFIG_ARCH_QSD8X50)
 #include "irqs-8x50.h"
 #include "sirc.h"
-#elif defined(CONFIG_ARCH_MSM8X60)
-#include "irqs-8x60.h"
-#elif defined(CONFIG_ARCH_MSM8960)
-/* TODO: Make these not generic. */
-#include "irqs-8960.h"
 #elif defined(CONFIG_ARCH_MSM_ARM11)
 #include "irqs-7x00.h"
 #else
index 98f6e2adb53eaf39722f4988f43ce9d96c86ba50..1dc5acd4fc99bb7f0001217214d53199dd89174d 100644 (file)
@@ -13,8 +13,6 @@
 #include <linux/clk.h>
 #include <linux/clk/mxs.h>
 #include <linux/clkdev.h>
-#include <linux/clocksource.h>
-#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
@@ -332,6 +330,11 @@ static void __init crystalfontz_init(void)
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
 }
 
+static void __init m28cu3_init(void)
+{
+       update_fec_mac_prop(OUI_DENX);
+}
+
 static const char __init *mxs_get_soc_id(void)
 {
        struct device_node *np;
@@ -459,6 +462,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("msr,m28cu3"))
+               m28cu3_init();
 
        of_platform_populate(NULL, of_default_bus_match_table,
                             NULL, parent);
@@ -490,16 +495,6 @@ static void mxs_restart(enum reboot_mode mode, const char *cmd)
        soft_restart(0);
 }
 
-static void __init mxs_timer_init(void)
-{
-       if (of_machine_is_compatible("fsl,imx23"))
-               mx23_clocks_init();
-       else
-               mx28_clocks_init();
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
 static const char *mxs_dt_compat[] __initdata = {
        "fsl,imx28",
        "fsl,imx23",
@@ -508,7 +503,6 @@ static const char *mxs_dt_compat[] __initdata = {
 
 DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
        .handle_irq     = icoll_handle_irq,
-       .init_time      = mxs_timer_init,
        .init_machine   = mxs_machine_init,
        .init_late      = mxs_pm_init,
        .dt_compat      = mxs_dt_compat,
index 13e0df9c11cebb0794d108d06cf95b16d98e6628..cce2c9dfb5d13d73b92076bd675415de6ff85bc6 100644 (file)
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/dma-mapping.h>
-#include <linux/platform_data/clk-nomadik.h>
-#include <linux/clocksource.h>
 #include <linux/of_irq.h>
 #include <linux/of_gpio.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <linux/mtd/fsmc.h>
 #include <linux/gpio.h>
-#include <linux/amba/mmci.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -113,50 +109,6 @@ static void cpu8815_restart(enum reboot_mode mode, const char *cmd)
        writel(1, srcbase + 0x18);
 }
 
-/* Initial value for SRC control register: all timers use MXTAL/8 source */
-#define SRC_CR_INIT_MASK       0x00007fff
-#define SRC_CR_INIT_VAL                0x2aaa8000
-
-static void __init cpu8815_timer_init_of(void)
-{
-       struct device_node *mtu;
-       void __iomem *base;
-       int irq;
-       u32 src_cr;
-
-       /* We need this to be up now */
-       nomadik_clk_init();
-
-       mtu = of_find_node_by_path("/mtu@101e2000");
-       if (!mtu)
-               return;
-       base = of_iomap(mtu, 0);
-       if (WARN_ON(!base))
-               return;
-       irq = irq_of_parse_and_map(mtu, 0);
-
-       pr_info("Remapped MTU @ %p, irq: %d\n", base, irq);
-
-       /* Configure timer sources in "system reset controller" ctrl reg */
-       src_cr = readl(base);
-       src_cr &= SRC_CR_INIT_MASK;
-       src_cr |= SRC_CR_INIT_VAL;
-       writel(src_cr, base);
-
-       clocksource_of_init();
-}
-
-static struct fsmc_nand_timings cpu8815_nand_timings = {
-       .thiz   = 0,
-       .thold  = 0x10,
-       .twait  = 0x0A,
-       .tset   = 0,
-};
-
-static struct fsmc_nand_platform_data cpu8815_nand_data = {
-       .nand_timings = &cpu8815_nand_timings,
-};
-
 /*
  * The SMSC911x IRQ is connected to a GPIO pin, but the driver expects
  * to simply request an IRQ passed as a resource. So the GPIO pin needs
@@ -189,15 +141,6 @@ static int __init cpu8815_eth_init(void)
 }
 device_initcall(cpu8815_eth_init);
 
-/*
- * TODO:
- * cannot be set from device tree, convert to a proper DT
- * binding.
- */
-static struct mmci_platform_data mmcsd_plat_data = {
-       .ocr_mask = MMC_VDD_29_30,
-};
-
 /*
  * This GPIO pin turns on a line that is used to detect card insertion
  * on this board.
@@ -232,24 +175,13 @@ static int __init cpu8815_mmcsd_init(void)
 }
 device_initcall(cpu8815_mmcsd_init);
 
-
-/* These are mostly to get the right device names for the clock lookups */
-static struct of_dev_auxdata cpu8815_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("stericsson,fsmc-nand", NOMADIK_FSMC_BASE,
-               NULL, &cpu8815_nand_data),
-       OF_DEV_AUXDATA("arm,primecell", NOMADIK_SDI_BASE,
-               NULL, &mmcsd_plat_data),
-       { /* sentinel */ },
-};
-
 static void __init cpu8815_init_of(void)
 {
 #ifdef CONFIG_CACHE_L2X0
        /* At full speed latency must be >=2, so 0x249 in low bits */
        l2x0_of_init(0x00730249, 0xfe000fff);
 #endif
-       of_platform_populate(NULL, of_default_bus_match_table,
-                       cpu8815_auxdata_lookup, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static const char * cpu8815_board_compat[] = {
@@ -259,7 +191,6 @@ static const char * cpu8815_board_compat[] = {
 
 DT_MACHINE_START(NOMADIK_DT, "Nomadik STn8815")
        .map_io         = cpu8815_map_io,
-       .init_time      = cpu8815_timer_init_of,
        .init_machine   = cpu8815_init_of,
        .restart        = cpu8815_restart,
        .dt_compat      = cpu8815_board_compat,
index 99e26092a9f7d63b5b096e71895a7eebdf915290..4b2ed2e8352f4fd1433e8ac0e41da26d2b3bdbe5 100644 (file)
 #include <linux/of_platform.h>
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-vic.h>
-#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
-#include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
@@ -65,12 +63,6 @@ static void __init nspire_init(void)
                        nspire_auxdata, NULL);
 }
 
-static void __init nspire_init_time(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
 static void nspire_restart(char mode, const char *cmd)
 {
        void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K);
@@ -83,7 +75,6 @@ static void nspire_restart(char mode, const char *cmd)
 DT_MACHINE_START(NSPIRE, "TI-NSPIRE")
        .dt_compat      = nspire_dt_match,
        .map_io         = nspire_map_io,
-       .init_time      = nspire_init_time,
        .init_machine   = nspire_init,
        .restart        = nspire_restart,
 MACHINE_END
index abec019a528195516bdefe9bdf45d165ab50ac5d..732f8ee2fcd2ce544a28eabda14f5fdde8250e7a 100644 (file)
@@ -46,6 +46,9 @@ static inline void omap7xx_map_io(void)
 void omap1510_fpga_init_irq(void);
 void omap15xx_map_io(void);
 #else
+static inline void omap1510_fpga_init_irq(void)
+{
+}
 static inline void omap15xx_map_io(void)
 {
 }
index 8bd71b2d0967ced750781e1a9b9b25cbb520044f..3c0e42219200f51346584a5545b3e29a92170ec8 100644 (file)
@@ -135,8 +135,7 @@ static struct irq_chip omap_fpga_irq = {
  * mask_ack routine for all of the FPGA interrupts has been changed from
  * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt
  * being serviced is left unmasked.  We can do this because the FPGA cascade
- * interrupt is installed with the IRQF_DISABLED flag, which leaves all
- * interrupts masked at the CPU while an FPGA interrupt handler executes.
+ * interrupt is run with all interrupts masked.
  *
  * Limited testing indicates that this workaround appears to be effective
  * for the smc9194 Ethernet driver used on the Innovator.  It should work
index 02b3eb2e201c2fe63670a5b6f64c3a8161eb06fd..312a0924d7867a5a5e0c41cdea2de66cf1fbcdbb 100644 (file)
@@ -25,7 +25,7 @@
 #define OMAP1510_GPIO_BASE             0xFFFCE000
 
 /* gpio1 */
-static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
+static struct resource omap15xx_mpu_gpio_resources[] = {
        {
                .start  = OMAP1_MPUIO_VBASE,
                .end    = OMAP1_MPUIO_VBASE + SZ_2K - 1,
@@ -48,7 +48,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = {
        .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE,
 };
 
-static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
+static struct omap_gpio_platform_data omap15xx_mpu_gpio_config = {
        .is_mpuio               = true,
        .bank_width             = 16,
        .bank_stride            = 1,
@@ -66,7 +66,7 @@ static struct platform_device omap15xx_mpu_gpio = {
 };
 
 /* gpio2 */
-static struct __initdata resource omap15xx_gpio_resources[] = {
+static struct resource omap15xx_gpio_resources[] = {
        {
                .start  = OMAP1510_GPIO_BASE,
                .end    = OMAP1510_GPIO_BASE + SZ_2K - 1,
@@ -90,7 +90,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = {
        .pinctrl        = OMAP1510_GPIO_PIN_CONTROL,
 };
 
-static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
+static struct omap_gpio_platform_data omap15xx_gpio_config = {
        .bank_width             = 16,
        .regs                   = &omap15xx_gpio_regs,
 };
index b9952a258d8201aac40880c8ac01bc1cabdba008..6e6ec93dcbb3fd4a4f0d889b2e871737a38f028e 100644 (file)
@@ -31,7 +31,7 @@
 #define SYSCONFIG_WORD                 0x14
 
 /* mpu gpio */
-static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
+static struct resource omap16xx_mpu_gpio_resources[] = {
        {
                .start  = OMAP1_MPUIO_VBASE,
                .end    = OMAP1_MPUIO_VBASE + SZ_2K - 1,
@@ -54,7 +54,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {
        .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE,
 };
 
-static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
+static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = {
        .is_mpuio               = true,
        .bank_width             = 16,
        .bank_stride            = 1,
@@ -72,7 +72,7 @@ static struct platform_device omap16xx_mpu_gpio = {
 };
 
 /* gpio1 */
-static struct __initdata resource omap16xx_gpio1_resources[] = {
+static struct resource omap16xx_gpio1_resources[] = {
        {
                .start  = OMAP1610_GPIO1_BASE,
                .end    = OMAP1610_GPIO1_BASE + SZ_2K - 1,
@@ -100,7 +100,7 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = {
        .edgectrl2      = OMAP1610_GPIO_EDGE_CTRL2,
 };
 
-static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
+static struct omap_gpio_platform_data omap16xx_gpio1_config = {
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -116,7 +116,7 @@ static struct platform_device omap16xx_gpio1 = {
 };
 
 /* gpio2 */
-static struct __initdata resource omap16xx_gpio2_resources[] = {
+static struct resource omap16xx_gpio2_resources[] = {
        {
                .start  = OMAP1610_GPIO2_BASE,
                .end    = OMAP1610_GPIO2_BASE + SZ_2K - 1,
@@ -128,7 +128,7 @@ static struct __initdata resource omap16xx_gpio2_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
+static struct omap_gpio_platform_data omap16xx_gpio2_config = {
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -144,7 +144,7 @@ static struct platform_device omap16xx_gpio2 = {
 };
 
 /* gpio3 */
-static struct __initdata resource omap16xx_gpio3_resources[] = {
+static struct resource omap16xx_gpio3_resources[] = {
        {
                .start  = OMAP1610_GPIO3_BASE,
                .end    = OMAP1610_GPIO3_BASE + SZ_2K - 1,
@@ -156,7 +156,7 @@ static struct __initdata resource omap16xx_gpio3_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
+static struct omap_gpio_platform_data omap16xx_gpio3_config = {
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -172,7 +172,7 @@ static struct platform_device omap16xx_gpio3 = {
 };
 
 /* gpio4 */
-static struct __initdata resource omap16xx_gpio4_resources[] = {
+static struct resource omap16xx_gpio4_resources[] = {
        {
                .start  = OMAP1610_GPIO4_BASE,
                .end    = OMAP1610_GPIO4_BASE + SZ_2K - 1,
@@ -184,7 +184,7 @@ static struct __initdata resource omap16xx_gpio4_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
+static struct omap_gpio_platform_data omap16xx_gpio4_config = {
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -199,7 +199,7 @@ static struct platform_device omap16xx_gpio4 = {
        .resource = omap16xx_gpio4_resources,
 };
 
-static struct __initdata platform_device * omap16xx_gpio_dev[] = {
+static struct platform_device *omap16xx_gpio_dev[] __initdata = {
        &omap16xx_mpu_gpio,
        &omap16xx_gpio1,
        &omap16xx_gpio2,
index f5819b2b7cbec631c7012a5f64bb88b12ed3ab2b..4612d2506a2db5a6e7e22d06a643e6beb6747409 100644 (file)
@@ -30,7 +30,7 @@
 #define OMAP1_MPUIO_VBASE              OMAP1_MPUIO_BASE
 
 /* mpu gpio */
-static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
+static struct resource omap7xx_mpu_gpio_resources[] = {
        {
                .start  = OMAP1_MPUIO_VBASE,
                .end    = OMAP1_MPUIO_VBASE + SZ_2K - 1,
@@ -53,7 +53,7 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = {
        .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE >> 1,
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
+static struct omap_gpio_platform_data omap7xx_mpu_gpio_config = {
        .is_mpuio               = true,
        .bank_width             = 16,
        .bank_stride            = 2,
@@ -71,7 +71,7 @@ static struct platform_device omap7xx_mpu_gpio = {
 };
 
 /* gpio1 */
-static struct __initdata resource omap7xx_gpio1_resources[] = {
+static struct resource omap7xx_gpio1_resources[] = {
        {
                .start  = OMAP7XX_GPIO1_BASE,
                .end    = OMAP7XX_GPIO1_BASE + SZ_2K - 1,
@@ -94,7 +94,7 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = {
        .irqctrl        = OMAP7XX_GPIO_INT_CONTROL,
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
+static struct omap_gpio_platform_data omap7xx_gpio1_config = {
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -110,7 +110,7 @@ static struct platform_device omap7xx_gpio1 = {
 };
 
 /* gpio2 */
-static struct __initdata resource omap7xx_gpio2_resources[] = {
+static struct resource omap7xx_gpio2_resources[] = {
        {
                .start  = OMAP7XX_GPIO2_BASE,
                .end    = OMAP7XX_GPIO2_BASE + SZ_2K - 1,
@@ -122,7 +122,7 @@ static struct __initdata resource omap7xx_gpio2_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
+static struct omap_gpio_platform_data omap7xx_gpio2_config = {
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -138,7 +138,7 @@ static struct platform_device omap7xx_gpio2 = {
 };
 
 /* gpio3 */
-static struct __initdata resource omap7xx_gpio3_resources[] = {
+static struct resource omap7xx_gpio3_resources[] = {
        {
                .start  = OMAP7XX_GPIO3_BASE,
                .end    = OMAP7XX_GPIO3_BASE + SZ_2K - 1,
@@ -150,7 +150,7 @@ static struct __initdata resource omap7xx_gpio3_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
+static struct omap_gpio_platform_data omap7xx_gpio3_config = {
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -166,7 +166,7 @@ static struct platform_device omap7xx_gpio3 = {
 };
 
 /* gpio4 */
-static struct __initdata resource omap7xx_gpio4_resources[] = {
+static struct resource omap7xx_gpio4_resources[] = {
        {
                .start  = OMAP7XX_GPIO4_BASE,
                .end    = OMAP7XX_GPIO4_BASE + SZ_2K - 1,
@@ -178,7 +178,7 @@ static struct __initdata resource omap7xx_gpio4_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
+static struct omap_gpio_platform_data omap7xx_gpio4_config = {
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -194,7 +194,7 @@ static struct platform_device omap7xx_gpio4 = {
 };
 
 /* gpio5 */
-static struct __initdata resource omap7xx_gpio5_resources[] = {
+static struct resource omap7xx_gpio5_resources[] = {
        {
                .start  = OMAP7XX_GPIO5_BASE,
                .end    = OMAP7XX_GPIO5_BASE + SZ_2K - 1,
@@ -206,7 +206,7 @@ static struct __initdata resource omap7xx_gpio5_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
+static struct omap_gpio_platform_data omap7xx_gpio5_config = {
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -222,7 +222,7 @@ static struct platform_device omap7xx_gpio5 = {
 };
 
 /* gpio6 */
-static struct __initdata resource omap7xx_gpio6_resources[] = {
+static struct resource omap7xx_gpio6_resources[] = {
        {
                .start  = OMAP7XX_GPIO6_BASE,
                .end    = OMAP7XX_GPIO6_BASE + SZ_2K - 1,
@@ -234,7 +234,7 @@ static struct __initdata resource omap7xx_gpio6_resources[] = {
        },
 };
 
-static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
+static struct omap_gpio_platform_data omap7xx_gpio6_config = {
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -249,7 +249,7 @@ static struct platform_device omap7xx_gpio6 = {
        .resource = omap7xx_gpio6_resources,
 };
 
-static struct __initdata platform_device * omap7xx_gpio_dev[] = {
+static struct platform_device *omap7xx_gpio_dev[] __initdata = {
        &omap7xx_mpu_gpio,
        &omap7xx_gpio1,
        &omap7xx_gpio2,
index 358b82cb9f7876482c29d97653a7d2921c87852f..40a1ae31961027a5383123cca4da2f672003cd92 100644 (file)
@@ -628,7 +628,6 @@ static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
 
 static struct irqaction omap_wakeup_irq = {
        .name           = "peripheral wakeup",
-       .flags          = IRQF_DISABLED,
        .handler        = omap_wakeup_interrupt
 };
 
index 80603d2fef77035a8fe54f9fe99e5ef63fcfdcbf..6b5f298d66382abe2f380952c32fda20bcfdfa56 100644 (file)
@@ -160,7 +160,7 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
 
 static struct irqaction omap_mpu_timer1_irq = {
        .name           = "mpu_timer1",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = omap_mpu_timer1_interrupt,
 };
 
index 0b74246ba62c6bb3379e142a89ebfb49c932fa8b..107e7ab3edbabc48b8ea4ae15cfc7f4c86dcfa30 100644 (file)
@@ -156,7 +156,7 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction omap_32k_timer_irq = {
        .name           = "32KHz timer",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = omap_32k_timer_interrupt,
 };
 
index b5fb5f7992dfed4972be5a927934b9ccfa26ae9f..dc21df16616119f8341077fd5131537065590088 100644 (file)
@@ -8,7 +8,6 @@ config ARCH_OMAP2
        select CPU_V6
        select MULTI_IRQ_HANDLER
        select SOC_HAS_OMAP2_SDRC
-       select COMMON_CLK
 
 config ARCH_OMAP3
        bool "TI OMAP3"
@@ -22,7 +21,6 @@ config ARCH_OMAP3
        select PM_OPP if PM
        select PM_RUNTIME if CPU_IDLE
        select SOC_HAS_OMAP2_SDRC
-       select COMMON_CLK
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
 
 config ARCH_OMAP4
@@ -45,7 +43,6 @@ config ARCH_OMAP4
        select PM_OPP if PM
        select PM_RUNTIME if CPU_IDLE
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
-       select COMMON_CLK
        select ARM_ERRATA_754322
        select ARM_ERRATA_775420
 
@@ -59,7 +56,6 @@ config SOC_OMAP5
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if LOCAL_TIMERS
        select HAVE_SMP
-       select COMMON_CLK
        select HAVE_ARM_ARCH_TIMER
        select ARM_ERRATA_798181 if SMP
 
@@ -70,7 +66,6 @@ config SOC_AM33XX
        select ARM_CPU_SUSPEND if PM
        select CPU_V7
        select MULTI_IRQ_HANDLER
-       select COMMON_CLK
 
 config SOC_AM43XX
        bool "TI AM43x"
@@ -79,7 +74,6 @@ config SOC_AM43XX
        select ARCH_OMAP2PLUS
        select MULTI_IRQ_HANDLER
        select ARM_GIC
-       select COMMON_CLK
        select MACH_OMAP_GENERIC
 
 config ARCH_OMAP2PLUS
@@ -89,11 +83,11 @@ config ARCH_OMAP2PLUS
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_OMAP
        select ARCH_REQUIRE_GPIOLIB
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
+       select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select HAVE_CLK
+       select MACH_OMAP_GENERIC
        select OMAP_DM_TIMER
        select PINCTRL
        select PROC_DEVICETREE if PROC_FS
@@ -187,16 +181,11 @@ config OMAP_PACKAGE_CUS
 config OMAP_PACKAGE_CBP
        bool
 
-comment "OMAP Board Type"
+comment "OMAP Legacy Platform Data Board Type"
        depends on ARCH_OMAP2PLUS
 
 config MACH_OMAP_GENERIC
-       bool "Generic OMAP2+ board"
-       depends on ARCH_OMAP2PLUS
-       default y
-       help
-         Support for generic TI OMAP2+ boards using Flattened Device Tree.
-         More information at Documentation/devicetree
+       bool
 
 config MACH_OMAP2_TUSB6010
        bool
@@ -260,12 +249,6 @@ config MACH_OVERO
        default y
        select OMAP_PACKAGE_CBB
 
-config MACH_OMAP3EVM
-       bool "OMAP 3530 EVM board"
-       depends on ARCH_OMAP3
-       default y
-       select OMAP_PACKAGE_CBB
-
 config MACH_OMAP3517EVM
        bool "OMAP3517/ AM3517 EVM board"
        depends on ARCH_OMAP3
@@ -314,33 +297,12 @@ config MACH_NOKIA_N8X0
        select MACH_NOKIA_N810_WIMAX
        select OMAP_PACKAGE_ZAC
 
-config MACH_NOKIA_RM680
-       bool "Nokia N950 (RM-680) / N9 (RM-696) phones"
-       depends on ARCH_OMAP3
-       default y
-       select MACH_NOKIA_RM696
-       select OMAP_PACKAGE_CBB
-
 config MACH_NOKIA_RX51
        bool "Nokia N900 (RX-51) phone"
        depends on ARCH_OMAP3
        default y
        select OMAP_PACKAGE_CBB
 
-config MACH_OMAP_ZOOM2
-       bool "OMAP3 Zoom2 board"
-       depends on ARCH_OMAP3
-       default y
-       select OMAP_PACKAGE_CBB
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
-
-config MACH_OMAP_ZOOM3
-       bool "OMAP3630 Zoom3 board"
-       depends on ARCH_OMAP3
-       default y
-       select OMAP_PACKAGE_CBP
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
-
 config MACH_CM_T35
        bool "CompuLab CM-T35/CM-T3730 modules"
        depends on ARCH_OMAP3
@@ -357,31 +319,12 @@ config MACH_CM_T3517
 config MACH_CM_T3730
        bool
 
-config MACH_IGEP0020
-       bool "IGEP v2 board"
-       depends on ARCH_OMAP3
-       default y
-       select OMAP_PACKAGE_CBB
-
-config MACH_IGEP0030
-       bool "IGEP OMAP3 module"
-       depends on ARCH_OMAP3
-       default y
-       select MACH_IGEP0020
-       select OMAP_PACKAGE_CBB
-
 config MACH_SBC3530
        bool "OMAP3 SBC STALKER board"
        depends on ARCH_OMAP3
        default y
        select OMAP_PACKAGE_CUS
 
-config MACH_OMAP_3630SDP
-       bool "OMAP3630 SDP board"
-       depends on ARCH_OMAP3
-       default y
-       select OMAP_PACKAGE_CBP
-
 config MACH_TI8168EVM
        bool "TI8168 Evaluation Module"
        depends on SOC_TI81XX
index afb457c3135b18707ea23cc7019c68da0ec4c099..e15ac005ef17d02a102ad87def740ef1211d53d0 100644 (file)
@@ -8,7 +8,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \
         common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
-        omap_device.o sram.o
+        omap_device.o sram.o drm.o
 
 omap-2-3-common                                = irq.o
 hwmod-common                           = omap_hwmod.o omap_hwmod_reset.o \
@@ -112,13 +112,13 @@ obj-$(CONFIG_ARCH_OMAP2)          += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
 obj-$(CONFIG_ARCH_OMAP3)               += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)               += vc3xxx_data.o vp3xxx_data.o
 obj-$(CONFIG_SOC_AM33XX)               += prm33xx.o cm33xx.o
-obj-$(CONFIG_SOC_AM43XX)               += prm33xx.o cm33xx.o
 omap-prcm-4-5-common                   =  cminst44xx.o cm44xx.o prm44xx.o \
                                           prcm_mpu44xx.o prminst44xx.o \
                                           vc44xx_data.o vp44xx_data.o
 obj-$(CONFIG_ARCH_OMAP4)               += $(omap-prcm-4-5-common)
 obj-$(CONFIG_SOC_OMAP5)                        += $(omap-prcm-4-5-common)
 obj-$(CONFIG_SOC_DRA7XX)               += $(omap-prcm-4-5-common)
+obj-$(CONFIG_SOC_AM43XX)               += $(omap-prcm-4-5-common)
 
 # OMAP voltage domains
 voltagedomain-common                   := voltage.o vc.o vp.o
@@ -146,6 +146,7 @@ obj-$(CONFIG_ARCH_OMAP4)            += powerdomains44xx_data.o
 obj-$(CONFIG_SOC_AM33XX)               += $(powerdomain-common)
 obj-$(CONFIG_SOC_AM33XX)               += powerdomains33xx_data.o
 obj-$(CONFIG_SOC_AM43XX)               += $(powerdomain-common)
+obj-$(CONFIG_SOC_AM43XX)               += powerdomains43xx_data.o
 obj-$(CONFIG_SOC_OMAP5)                        += $(powerdomain-common)
 obj-$(CONFIG_SOC_OMAP5)                        += powerdomains54xx_data.o
 obj-$(CONFIG_SOC_DRA7XX)               += $(powerdomain-common)
@@ -165,6 +166,7 @@ obj-$(CONFIG_ARCH_OMAP4)            += clockdomains44xx_data.o
 obj-$(CONFIG_SOC_AM33XX)               += $(clockdomain-common)
 obj-$(CONFIG_SOC_AM33XX)               += clockdomains33xx_data.o
 obj-$(CONFIG_SOC_AM43XX)               += $(clockdomain-common)
+obj-$(CONFIG_SOC_AM43XX)               += clockdomains43xx_data.o
 obj-$(CONFIG_SOC_OMAP5)                        += $(clockdomain-common)
 obj-$(CONFIG_SOC_OMAP5)                        += clockdomains54xx_data.o
 obj-$(CONFIG_SOC_DRA7XX)               += $(clockdomain-common)
@@ -210,6 +212,11 @@ obj-$(CONFIG_ARCH_OMAP3)           += omap_hwmod_2xxx_3xxx_ipblock_data.o
 obj-$(CONFIG_ARCH_OMAP3)               += omap_hwmod_2xxx_3xxx_interconnect_data.o
 obj-$(CONFIG_ARCH_OMAP3)               += omap_hwmod_3xxx_data.o
 obj-$(CONFIG_SOC_AM33XX)               += omap_hwmod_33xx_data.o
+obj-$(CONFIG_SOC_AM33XX)               += omap_hwmod_33xx_43xx_interconnect_data.o
+obj-$(CONFIG_SOC_AM33XX)               += omap_hwmod_33xx_43xx_ipblock_data.o
+obj-$(CONFIG_SOC_AM43XX)               += omap_hwmod_43xx_data.o
+obj-$(CONFIG_SOC_AM43XX)               += omap_hwmod_33xx_43xx_interconnect_data.o
+obj-$(CONFIG_SOC_AM43XX)               += omap_hwmod_33xx_43xx_ipblock_data.o
 obj-$(CONFIG_ARCH_OMAP4)               += omap_hwmod_44xx_data.o
 obj-$(CONFIG_SOC_OMAP5)                        += omap_hwmod_54xx_data.o
 obj-$(CONFIG_SOC_DRA7XX)               += omap_hwmod_7xx_data.o
@@ -228,12 +235,8 @@ endif
 # OMAP2420 MSDI controller integration support ("MMC")
 obj-$(CONFIG_SOC_OMAP2420)             += msdi.o
 
-ifneq ($(CONFIG_DRM_OMAP),)
-obj-y                                  += drm.o
-endif
-
 # Specific board support
-obj-$(CONFIG_MACH_OMAP_GENERIC)                += board-generic.o
+obj-$(CONFIG_MACH_OMAP_GENERIC)                += board-generic.o pdata-quirks.o
 obj-$(CONFIG_MACH_OMAP_H4)             += board-h4.o
 obj-$(CONFIG_MACH_OMAP_2430SDP)                += board-2430sdp.o
 obj-$(CONFIG_MACH_OMAP3_BEAGLE)                += board-omap3beagle.o
@@ -242,26 +245,14 @@ obj-$(CONFIG_MACH_OMAP_LDP)               += board-ldp.o
 obj-$(CONFIG_MACH_OMAP3530_LV_SOM)      += board-omap3logic.o
 obj-$(CONFIG_MACH_OMAP3_TORPEDO)        += board-omap3logic.o
 obj-$(CONFIG_MACH_OVERO)               += board-overo.o
-obj-$(CONFIG_MACH_OMAP3EVM)            += board-omap3evm.o
 obj-$(CONFIG_MACH_OMAP3_PANDORA)       += board-omap3pandora.o
 obj-$(CONFIG_MACH_OMAP_3430SDP)                += board-3430sdp.o
 obj-$(CONFIG_MACH_NOKIA_N8X0)          += board-n8x0.o
-obj-$(CONFIG_MACH_NOKIA_RM680)         += board-rm680.o sdram-nokia.o
 obj-$(CONFIG_MACH_NOKIA_RX51)          += board-rx51.o sdram-nokia.o
 obj-$(CONFIG_MACH_NOKIA_RX51)          += board-rx51-peripherals.o
 obj-$(CONFIG_MACH_NOKIA_RX51)          += board-rx51-video.o
-obj-$(CONFIG_MACH_OMAP_ZOOM2)          += board-zoom.o board-zoom-peripherals.o
-obj-$(CONFIG_MACH_OMAP_ZOOM2)          += board-zoom-display.o
-obj-$(CONFIG_MACH_OMAP_ZOOM2)          += board-zoom-debugboard.o
-obj-$(CONFIG_MACH_OMAP_ZOOM3)          += board-zoom.o board-zoom-peripherals.o
-obj-$(CONFIG_MACH_OMAP_ZOOM3)          += board-zoom-display.o
-obj-$(CONFIG_MACH_OMAP_ZOOM3)          += board-zoom-debugboard.o
-obj-$(CONFIG_MACH_OMAP_3630SDP)                += board-3630sdp.o
-obj-$(CONFIG_MACH_OMAP_3630SDP)                += board-zoom-peripherals.o
-obj-$(CONFIG_MACH_OMAP_3630SDP)                += board-zoom-display.o
 obj-$(CONFIG_MACH_CM_T35)              += board-cm-t35.o
 obj-$(CONFIG_MACH_CM_T3517)            += board-cm-t3517.o
-obj-$(CONFIG_MACH_IGEP0020)            += board-igep0020.o
 obj-$(CONFIG_MACH_TOUCHBOOK)           += board-omap3touchbook.o
 
 obj-$(CONFIG_MACH_OMAP3517EVM)         += board-am3517evm.o
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
deleted file mode 100644 (file)
index 20d6d81..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/gpio.h>
-#include <linux/mtd/nand.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "gpmc-smc91x.h"
-
-#include "board-zoom.h"
-
-#include "board-flash.h"
-#include "mux.h"
-#include "sdram-hynix-h8mbx00u0mer-0em.h"
-
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-
-static struct omap_smc91x_platform_data board_smc91x_data = {
-       .cs             = 3,
-       .flags          = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
-};
-
-static void __init board_smc91x_init(void)
-{
-       board_smc91x_data.gpio_irq = 158;
-       gpmc_smc91x_init(&board_smc91x_data);
-}
-
-#else
-
-static inline void board_smc91x_init(void)
-{
-}
-
-#endif /* defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) */
-
-static void enable_board_wakeup_source(void)
-{
-       /* T2 interrupt line (keypad) */
-       omap_mux_init_signal("sys_nirq",
-               OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
-}
-
-static struct usbhs_phy_data phy_data[] __initdata = {
-       {
-               .port = 1,
-               .reset_gpio = 126,
-               .vcc_gpio = -EINVAL,
-       },
-       {
-               .port = 2,
-               .reset_gpio = 61,
-               .vcc_gpio = -EINVAL,
-       },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
-       .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-       { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-/*
- * SDP3630 CS organization
- * See also the Switch S8 settings in the comments.
- */
-static char chip_sel_sdp[][GPMC_CS_NUM] = {
-       {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */
-       {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */
-       {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */
-};
-
-static struct mtd_partition sdp_nor_partitions[] = {
-       /* bootloader (U-Boot, etc) in first sector */
-       {
-               .name           = "Bootloader-NOR",
-               .offset         = 0,
-               .size           = SZ_256K,
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-       },
-       /* bootloader params in the next sector */
-       {
-               .name           = "Params-NOR",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = SZ_256K,
-               .mask_flags     = 0,
-       },
-       /* kernel */
-       {
-               .name           = "Kernel-NOR",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = SZ_2M,
-               .mask_flags     = 0
-       },
-       /* file system */
-       {
-               .name           = "Filesystem-NOR",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = MTDPART_SIZ_FULL,
-               .mask_flags     = 0
-       }
-};
-
-static struct mtd_partition sdp_onenand_partitions[] = {
-       {
-               .name           = "X-Loader-OneNAND",
-               .offset         = 0,
-               .size           = 4 * (64 * 2048),
-               .mask_flags     = MTD_WRITEABLE  /* force read-only */
-       },
-       {
-               .name           = "U-Boot-OneNAND",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 2 * (64 * 2048),
-               .mask_flags     = MTD_WRITEABLE  /* force read-only */
-       },
-       {
-               .name           = "U-Boot Environment-OneNAND",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 1 * (64 * 2048),
-       },
-       {
-               .name           = "Kernel-OneNAND",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 16 * (64 * 2048),
-       },
-       {
-               .name           = "File System-OneNAND",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct mtd_partition sdp_nand_partitions[] = {
-       /* All the partition sizes are listed in terms of NAND block size */
-       {
-               .name           = "X-Loader-NAND",
-               .offset         = 0,
-               .size           = 4 * (64 * 2048),
-               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
-       },
-       {
-               .name           = "U-Boot-NAND",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
-               .size           = 10 * (64 * 2048),
-               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
-       },
-       {
-               .name           = "Boot Env-NAND",
-
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x1c0000 */
-               .size           = 6 * (64 * 2048),
-       },
-       {
-               .name           = "Kernel-NAND",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
-               .size           = 40 * (64 * 2048),
-       },
-       {
-               .name           = "File System - NAND",
-               .size           = MTDPART_SIZ_FULL,
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x780000 */
-       },
-};
-
-static struct flash_partitions sdp_flash_partitions[] = {
-       {
-               .parts = sdp_nor_partitions,
-               .nr_parts = ARRAY_SIZE(sdp_nor_partitions),
-       },
-       {
-               .parts = sdp_onenand_partitions,
-               .nr_parts = ARRAY_SIZE(sdp_onenand_partitions),
-       },
-       {
-               .parts = sdp_nand_partitions,
-               .nr_parts = ARRAY_SIZE(sdp_nand_partitions),
-       },
-};
-
-static void __init omap_sdp_init(void)
-{
-       omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
-       zoom_peripherals_init();
-       omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
-                                 h8mbx00u0mer0em_sdrc_params);
-       zoom_display_init();
-       board_smc91x_init();
-       board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
-       enable_board_wakeup_source();
-
-       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
-       usbhs_init(&usbhs_bdata);
-}
-
-MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap3630_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = omap_sdp_init,
-       .init_late      = omap3630_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
index 87162e1b94a59104a2bca07114da5d8a02816fba..19f1652e94cfbf5e1f09d2d4cc27e44087cc68d7 100644 (file)
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/irqdomain.h>
-#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 
 #include "common.h"
-#include "common-board-devices.h"
-#include "dss-common.h"
 
 #if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3))
 #define intc_of_init   NULL
@@ -36,40 +33,9 @@ static struct of_device_id omap_dt_match_table[] __initdata = {
        { }
 };
 
-/*
- * Create alias for USB host PHY clock.
- * Remove this when clock phandle can be provided via DT
- */
-static void __init legacy_init_ehci_clk(char *clkname)
-{
-       int ret;
-
-       ret = clk_add_alias("main_clk", NULL, clkname, NULL);
-       if (ret) {
-               pr_err("%s:Failed to add main_clk alias to %s :%d\n",
-                                               __func__, clkname, ret);
-       }
-}
-
 static void __init omap_generic_init(void)
 {
-       omap_sdrc_init(NULL, NULL);
-
-       of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
-
-       /*
-        * HACK: call display setup code for selected boards to enable omapdss.
-        * This will be removed when omapdss supports DT.
-        */
-       if (of_machine_is_compatible("ti,omap4-panda")) {
-               omap4_panda_display_init_of();
-               legacy_init_ehci_clk("auxclk3_ck");
-
-       }
-       else if (of_machine_is_compatible("ti,omap4-sdp"))
-               omap_4430sdp_display_init_of();
-       else if (of_machine_is_compatible("ti,omap5-uevm"))
-               legacy_init_ehci_clk("auxclk1_ck");
+       pdata_quirks_init(omap_dt_match_table);
 }
 
 #ifdef CONFIG_SOC_OMAP2420
@@ -180,6 +146,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
        .init_irq       = omap_intc_of_init,
        .handle_irq     = omap3_intc_handle_irq,
        .init_machine   = omap_generic_init,
+       .init_late      = am33xx_init_late,
        .init_time      = omap3_gptimer_timer_init,
        .dt_compat      = am33xx_boards_compat,
        .restart        = am33xx_restart,
@@ -219,6 +186,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
        .init_early     = omap5_init_early,
        .init_irq       = omap_gic_of_init,
        .init_machine   = omap_generic_init,
+       .init_late      = omap5_init_late,
        .init_time      = omap5_realtime_timer_init,
        .dt_compat      = omap5_boards_compat,
        .restart        = omap44xx_restart,
@@ -234,6 +202,7 @@ static const char *am43_boards_compat[] __initdata = {
 DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
        .map_io         = am33xx_map_io,
        .init_early     = am43xx_init_early,
+       .init_late      = am43xx_init_late,
        .init_irq       = omap_gic_of_init,
        .init_machine   = omap_generic_init,
        .init_time      = omap3_sync32k_timer_init,
@@ -252,6 +221,7 @@ DT_MACHINE_START(DRA7XX_DT, "Generic DRA7XX (Flattened Device Tree)")
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = omap5_map_io,
        .init_early     = dra7xx_init_early,
+       .init_late      = dra7xx_init_late,
        .init_irq       = omap_gic_of_init,
        .init_machine   = omap_generic_init,
        .init_time      = omap5_realtime_timer_init,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
deleted file mode 100644 (file)
index 06dbb2d..0000000
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (C) 2009 Integration Software and Electronic Engineering.
- *
- * Modified from mach-omap2/board-generic.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/usb/phy.h>
-
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/i2c/twl.h>
-#include <linux/mmc/host.h>
-
-#include <linux/mtd/nand.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include <video/omapdss.h>
-#include <video/omap-panel-data.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
-
-#include "common.h"
-#include "gpmc.h"
-#include "mux.h"
-#include "hsmmc.h"
-#include "sdram-numonyx-m65kxxxxam.h"
-#include "common-board-devices.h"
-#include "board-flash.h"
-#include "control.h"
-#include "gpmc-onenand.h"
-
-#define IGEP2_SMSC911X_CS       5
-#define IGEP2_SMSC911X_GPIO     176
-#define IGEP2_GPIO_USBH_NRESET  24
-#define IGEP2_GPIO_LED0_GREEN   26
-#define IGEP2_GPIO_LED0_RED     27
-#define IGEP2_GPIO_LED1_RED     28
-#define IGEP2_GPIO_DVI_PUP      170
-
-#define IGEP2_RB_GPIO_WIFI_NPD     94
-#define IGEP2_RB_GPIO_WIFI_NRESET  95
-#define IGEP2_RB_GPIO_BT_NRESET    137
-#define IGEP2_RC_GPIO_WIFI_NPD     138
-#define IGEP2_RC_GPIO_WIFI_NRESET  139
-#define IGEP2_RC_GPIO_BT_NRESET    137
-
-#define IGEP3_GPIO_LED0_GREEN  54
-#define IGEP3_GPIO_LED0_RED    53
-#define IGEP3_GPIO_LED1_RED    16
-#define IGEP3_GPIO_USBH_NRESET  183
-
-#define IGEP_SYSBOOT_MASK           0x1f
-#define IGEP_SYSBOOT_NAND           0x0f
-#define IGEP_SYSBOOT_ONENAND        0x10
-
-/*
- * IGEP2 Hardware Revision Table
- *
- *  --------------------------------------------------------------------------
- * | Id. | Hw Rev.            | HW0 (28) | WIFI_NPD | WIFI_NRESET | BT_NRESET |
- *  --------------------------------------------------------------------------
- * |  0  | B                  |   high   |  gpio94  |   gpio95    |     -     |
- * |  0  | B/C (B-compatible) |   high   |  gpio94  |   gpio95    |  gpio137  |
- * |  1  | C                  |   low    |  gpio138 |   gpio139   |  gpio137  |
- *  --------------------------------------------------------------------------
- */
-
-#define IGEP2_BOARD_HWREV_B    0
-#define IGEP2_BOARD_HWREV_C    1
-#define IGEP3_BOARD_HWREV      2
-
-static u8 hwrev;
-
-static void __init igep2_get_revision(void)
-{
-       u8 ret;
-
-       if (machine_is_igep0030()) {
-               hwrev = IGEP3_BOARD_HWREV;
-               return;
-       }
-
-       omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT);
-
-       if (gpio_request_one(IGEP2_GPIO_LED1_RED, GPIOF_IN, "GPIO_HW0_REV")) {
-               pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n");
-               pr_err("IGEP2: Unknown Hardware Revision\n");
-               return;
-       }
-
-       ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
-       if (ret == 0) {
-               pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
-               hwrev = IGEP2_BOARD_HWREV_C;
-       } else if (ret ==  1) {
-               pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
-               hwrev = IGEP2_BOARD_HWREV_B;
-       } else {
-               pr_err("IGEP2: Unknown Hardware Revision\n");
-               hwrev = -1;
-       }
-
-       gpio_free(IGEP2_GPIO_LED1_RED);
-}
-
-#if defined(CONFIG_MTD_ONENAND_OMAP2) ||               \
-       defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) ||     \
-       defined(CONFIG_MTD_NAND_OMAP2) ||               \
-       defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-
-#define ONENAND_MAP             0x20000000
-
-/* NAND04GR4E1A ( x2 Flash built-in COMBO POP MEMORY )
- * Since the device is equipped with two DataRAMs, and two-plane NAND
- * Flash memory array, these two component enables simultaneous program
- * of 4KiB. Plane1 has only even blocks such as block0, block2, block4
- * while Plane2 has only odd blocks such as block1, block3, block5.
- * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
- */
-
-static struct mtd_partition igep_flash_partitions[] = {
-       {
-               .name           = "X-Loader",
-               .offset         = 0,
-               .size           = 2 * (64*(2*2048))
-       },
-       {
-               .name           = "U-Boot",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 6 * (64*(2*2048)),
-       },
-       {
-               .name           = "Environment",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 2 * (64*(2*2048)),
-       },
-       {
-               .name           = "Kernel",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 12 * (64*(2*2048)),
-       },
-       {
-               .name           = "File System",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = MTDPART_SIZ_FULL,
-       },
-};
-
-static inline u32 igep_get_sysboot_value(void)
-{
-       return omap_ctrl_readl(OMAP343X_CONTROL_STATUS) & IGEP_SYSBOOT_MASK;
-}
-
-static void __init igep_flash_init(void)
-{
-       u32 mux;
-       mux = igep_get_sysboot_value();
-
-       if (mux == IGEP_SYSBOOT_NAND) {
-               pr_info("IGEP: initializing NAND memory device\n");
-               board_nand_init(igep_flash_partitions,
-                               ARRAY_SIZE(igep_flash_partitions),
-                               0, NAND_BUSWIDTH_16, nand_default_timings);
-       } else if (mux == IGEP_SYSBOOT_ONENAND) {
-               pr_info("IGEP: initializing OneNAND memory device\n");
-               board_onenand_init(igep_flash_partitions,
-                                  ARRAY_SIZE(igep_flash_partitions), 0);
-       } else {
-               pr_err("IGEP: Flash: unsupported sysboot sequence found\n");
-       }
-}
-
-#else
-static void __init igep_flash_init(void) {}
-#endif
-
-#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
-
-#include <linux/smsc911x.h>
-#include "gpmc-smsc911x.h"
-
-static struct omap_smsc911x_platform_data smsc911x_cfg = {
-       .cs             = IGEP2_SMSC911X_CS,
-       .gpio_irq       = IGEP2_SMSC911X_GPIO,
-       .gpio_reset     = -EINVAL,
-       .flags          = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-};
-
-static inline void __init igep2_init_smsc911x(void)
-{
-       gpmc_smsc911x_init(&smsc911x_cfg);
-}
-
-#else
-static inline void __init igep2_init_smsc911x(void) { }
-#endif
-
-static struct regulator_consumer_supply igep_vmmc1_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
-};
-
-/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
-static struct regulator_init_data igep_vmmc1 = {
-       .constraints = {
-               .min_uV                 = 1850000,
-               .max_uV                 = 3150000,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
-                                       | REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(igep_vmmc1_supply),
-       .consumer_supplies      = igep_vmmc1_supply,
-};
-
-static struct regulator_consumer_supply igep_vio_supply[] = {
-       REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"),
-};
-
-static struct regulator_init_data igep_vio = {
-       .constraints = {
-               .min_uV                 = 1800000,
-               .max_uV                 = 1800000,
-               .apply_uV               = 1,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
-                                       | REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(igep_vio_supply),
-       .consumer_supplies      = igep_vio_supply,
-};
-
-static struct regulator_consumer_supply igep_vmmc2_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
-};
-
-static struct regulator_init_data igep_vmmc2 = {
-       .constraints            = {
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL,
-               .always_on              = 1,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(igep_vmmc2_supply),
-       .consumer_supplies      = igep_vmmc2_supply,
-};
-
-static struct fixed_voltage_config igep_vwlan = {
-       .supply_name            = "vwlan",
-       .microvolts             = 3300000,
-       .gpio                   = -EINVAL,
-       .enabled_at_boot        = 1,
-       .init_data              = &igep_vmmc2,
-};
-
-static struct platform_device igep_vwlan_device = {
-       .name           = "reg-fixed-voltage",
-       .id             = 0,
-       .dev = {
-               .platform_data  = &igep_vwlan,
-       },
-};
-
-static struct omap2_hsmmc_info mmc[] = {
-       {
-               .mmc            = 1,
-               .caps           = MMC_CAP_4_BIT_DATA,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-               .deferred       = true,
-       },
-#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
-       {
-               .mmc            = 2,
-               .caps           = MMC_CAP_4_BIT_DATA,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-       },
-#endif
-       {}      /* Terminator */
-};
-
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-#include <linux/leds.h>
-
-static struct gpio_led igep_gpio_leds[] = {
-       [0] = {
-               .name                   = "omap3:red:user0",
-               .default_state          = 0,
-       },
-       [1] = {
-               .name                   = "omap3:green:boot",
-               .default_state          = 1,
-       },
-       [2] = {
-               .name                   = "omap3:red:user1",
-               .default_state          = 0,
-       },
-       [3] = {
-               .name                   = "omap3:green:user1",
-               .default_state          = 0,
-               .gpio                   = -EINVAL, /* gets replaced */
-               .active_low             = 1,
-       },
-};
-
-static struct gpio_led_platform_data igep_led_pdata = {
-       .leds           = igep_gpio_leds,
-       .num_leds       = ARRAY_SIZE(igep_gpio_leds),
-};
-
-static struct platform_device igep_led_device = {
-        .name   = "leds-gpio",
-        .id     = -1,
-        .dev    = {
-                .platform_data  =  &igep_led_pdata,
-       },
-};
-
-static void __init igep_leds_init(void)
-{
-       if (machine_is_igep0020()) {
-               igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
-               igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
-               igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
-       } else {
-               igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
-               igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
-               igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
-       }
-
-       platform_device_register(&igep_led_device);
-}
-
-#else
-static struct gpio igep_gpio_leds[] __initdata = {
-       { -EINVAL,      GPIOF_OUT_INIT_LOW, "gpio-led:red:d0"   },
-       { -EINVAL,      GPIOF_OUT_INIT_LOW, "gpio-led:green:d0" },
-       { -EINVAL,      GPIOF_OUT_INIT_LOW, "gpio-led:red:d1"   },
-};
-
-static inline void igep_leds_init(void)
-{
-       int i;
-
-       if (machine_is_igep0020()) {
-               igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
-               igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
-               igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
-       } else {
-               igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
-               igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
-               igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
-       }
-
-       if (gpio_request_array(igep_gpio_leds, ARRAY_SIZE(igep_gpio_leds))) {
-               pr_warning("IGEP v2: Could not obtain leds gpios\n");
-               return;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(igep_gpio_leds); i++)
-               gpio_export(igep_gpio_leds[i].gpio, 0);
-}
-#endif
-
-static struct gpio igep2_twl_gpios[] = {
-       { -EINVAL, GPIOF_IN,            "GPIO_EHCI_NOC"  },
-       { -EINVAL, GPIOF_OUT_INIT_LOW,  "GPIO_USBH_CPEN" },
-};
-
-static int igep_twl_gpio_setup(struct device *dev,
-               unsigned gpio, unsigned ngpio)
-{
-       int ret;
-
-       /* gpio + 0 is "mmc0_cd" (input/IRQ) */
-       mmc[0].gpio_cd = gpio + 0;
-       omap_hsmmc_late_init(mmc);
-
-       /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
-#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
-       ret = gpio_request_one(gpio + TWL4030_GPIO_MAX + 1, GPIOF_OUT_INIT_HIGH,
-                              "gpio-led:green:d1");
-       if (ret == 0)
-               gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
-       else
-               pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n");
-#else
-       igep_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
-#endif
-
-       if (machine_is_igep0030())
-               return 0;
-
-       /*
-        * REVISIT: need ehci-omap hooks for external VBUS
-        * power switch and overcurrent detect
-        */
-       igep2_twl_gpios[0].gpio = gpio + 1;
-
-       /* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */
-       igep2_twl_gpios[1].gpio = gpio + TWL4030_GPIO_MAX;
-
-       ret = gpio_request_array(igep2_twl_gpios, ARRAY_SIZE(igep2_twl_gpios));
-       if (ret < 0)
-               pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
-
-       return 0;
-};
-
-static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
-       .use_leds       = true,
-       .setup          = igep_twl_gpio_setup,
-};
-
-static struct connector_dvi_platform_data omap3stalker_dvi_connector_pdata = {
-       .name                   = "dvi",
-       .source                 = "tfp410.0",
-       .i2c_bus_num            = 3,
-};
-
-static struct platform_device omap3stalker_dvi_connector_device = {
-       .name                   = "connector-dvi",
-       .id                     = 0,
-       .dev.platform_data      = &omap3stalker_dvi_connector_pdata,
-};
-
-static struct encoder_tfp410_platform_data omap3stalker_tfp410_pdata = {
-       .name                   = "tfp410.0",
-       .source                 = "dpi.0",
-       .data_lines             = 24,
-       .power_down_gpio        = IGEP2_GPIO_DVI_PUP,
-};
-
-static struct platform_device omap3stalker_tfp410_device = {
-       .name                   = "tfp410",
-       .id                     = 0,
-       .dev.platform_data      = &omap3stalker_tfp410_pdata,
-};
-
-static struct omap_dss_board_info igep2_dss_data = {
-       .default_display_name = "dvi",
-};
-
-static struct platform_device *igep_devices[] __initdata = {
-       &igep_vwlan_device,
-       &omap3stalker_tfp410_device,
-       &omap3stalker_dvi_connector_device,
-};
-
-static int igep2_keymap[] = {
-       KEY(0, 0, KEY_LEFT),
-       KEY(0, 1, KEY_RIGHT),
-       KEY(0, 2, KEY_A),
-       KEY(0, 3, KEY_B),
-       KEY(1, 0, KEY_DOWN),
-       KEY(1, 1, KEY_UP),
-       KEY(1, 2, KEY_E),
-       KEY(1, 3, KEY_F),
-       KEY(2, 0, KEY_ENTER),
-       KEY(2, 1, KEY_I),
-       KEY(2, 2, KEY_J),
-       KEY(2, 3, KEY_K),
-       KEY(3, 0, KEY_M),
-       KEY(3, 1, KEY_N),
-       KEY(3, 2, KEY_O),
-       KEY(3, 3, KEY_P)
-};
-
-static struct matrix_keymap_data igep2_keymap_data = {
-       .keymap                 = igep2_keymap,
-       .keymap_size            = ARRAY_SIZE(igep2_keymap),
-};
-
-static struct twl4030_keypad_data igep2_keypad_pdata = {
-       .keymap_data    = &igep2_keymap_data,
-       .rows           = 4,
-       .cols           = 4,
-       .rep            = 1,
-};
-
-static struct twl4030_platform_data igep_twldata = {
-       /* platform_data for children goes here */
-       .gpio           = &igep_twl4030_gpio_pdata,
-       .vmmc1          = &igep_vmmc1,
-       .vio            = &igep_vio,
-};
-
-static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = {
-       {
-               I2C_BOARD_INFO("eeprom", 0x50),
-       },
-};
-
-static void __init igep_i2c_init(void)
-{
-       int ret;
-
-       omap3_pmic_get_config(&igep_twldata, TWL_COMMON_PDATA_USB,
-                             TWL_COMMON_REGULATOR_VPLL2);
-       igep_twldata.vpll2->constraints.apply_uV = true;
-       igep_twldata.vpll2->constraints.name = "VDVI";
-
-       if (machine_is_igep0020()) {
-               /*
-                * Bus 3 is attached to the DVI port where devices like the
-                * pico DLP projector don't work reliably with 400kHz
-                */
-               ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
-                                           ARRAY_SIZE(igep2_i2c3_boardinfo));
-               if (ret)
-                       pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
-
-               igep_twldata.keypad     = &igep2_keypad_pdata;
-               /* Get common pmic data */
-               omap3_pmic_get_config(&igep_twldata, TWL_COMMON_PDATA_AUDIO, 0);
-       }
-
-       omap3_pmic_init("twl4030", &igep_twldata);
-}
-
-static struct usbhs_phy_data igep2_phy_data[] __initdata = {
-       {
-               .port = 1,
-               .reset_gpio = IGEP2_GPIO_USBH_NRESET,
-               .vcc_gpio = -EINVAL,
-       },
-};
-
-static struct usbhs_phy_data igep3_phy_data[] __initdata = {
-       {
-               .port = 2,
-               .reset_gpio = IGEP3_GPIO_USBH_NRESET,
-               .vcc_gpio = -EINVAL,
-       },
-};
-
-static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = {
-       .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = {
-       .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-       /* Display Sub System */
-       OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-       /* TFP410 PanelBus DVI Transmitte (GPIO_170) */
-       OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-       /* SMSC9221 LAN Controller ETH IRQ (GPIO_176) */
-       OMAP3_MUX(MCSPI1_CS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-       { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
-static struct gpio igep_wlan_bt_gpios[] __initdata = {
-       { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NPD"    },
-       { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NRESET" },
-       { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_BT_NRESET"   },
-};
-
-static void __init igep_wlan_bt_init(void)
-{
-       int err;
-
-       /* GPIO's for WLAN-BT combo depends on hardware revision */
-       if (hwrev == IGEP2_BOARD_HWREV_B) {
-               igep_wlan_bt_gpios[0].gpio = IGEP2_RB_GPIO_WIFI_NPD;
-               igep_wlan_bt_gpios[1].gpio = IGEP2_RB_GPIO_WIFI_NRESET;
-               igep_wlan_bt_gpios[2].gpio = IGEP2_RB_GPIO_BT_NRESET;
-       } else if (hwrev == IGEP2_BOARD_HWREV_C || machine_is_igep0030()) {
-               igep_wlan_bt_gpios[0].gpio = IGEP2_RC_GPIO_WIFI_NPD;
-               igep_wlan_bt_gpios[1].gpio = IGEP2_RC_GPIO_WIFI_NRESET;
-               igep_wlan_bt_gpios[2].gpio = IGEP2_RC_GPIO_BT_NRESET;
-       } else
-               return;
-
-       /* Make sure that the GPIO pins are muxed correctly */
-       omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT);
-       omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT);
-       omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT);
-
-       err = gpio_request_array(igep_wlan_bt_gpios,
-                                ARRAY_SIZE(igep_wlan_bt_gpios));
-       if (err) {
-               pr_warning("IGEP2: Could not obtain WIFI/BT gpios\n");
-               return;
-       }
-
-       gpio_export(igep_wlan_bt_gpios[0].gpio, 0);
-       gpio_export(igep_wlan_bt_gpios[1].gpio, 0);
-       gpio_export(igep_wlan_bt_gpios[2].gpio, 0);
-
-       gpio_set_value(igep_wlan_bt_gpios[1].gpio, 0);
-       udelay(10);
-       gpio_set_value(igep_wlan_bt_gpios[1].gpio, 1);
-
-}
-#else
-static inline void __init igep_wlan_bt_init(void) { }
-#endif
-
-static struct regulator_consumer_supply dummy_supplies[] = {
-       REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
-       REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
-};
-
-static void __init igep_init(void)
-{
-       regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-       omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-
-       /* Get IGEP2 hardware revision */
-       igep2_get_revision();
-
-       omap_hsmmc_init(mmc);
-
-       /* Register I2C busses and drivers */
-       igep_i2c_init();
-       platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
-       omap_serial_init();
-       omap_sdrc_init(m65kxxxxam_sdrc_params,
-                                 m65kxxxxam_sdrc_params);
-       usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
-       usb_musb_init(NULL);
-
-       igep_flash_init();
-       igep_leds_init();
-       omap_twl4030_audio_init("igep2", NULL);
-
-       /*
-        * WLAN-BT combo module from MuRata which has a Marvell WLAN
-        * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
-        */
-       igep_wlan_bt_init();
-
-       if (machine_is_igep0020()) {
-               omap_display_init(&igep2_dss_data);
-               igep2_init_smsc911x();
-               usbhs_init_phys(igep2_phy_data, ARRAY_SIZE(igep2_phy_data));
-               usbhs_init(&igep2_usbhs_bdata);
-       } else {
-               usbhs_init_phys(igep3_phy_data, ARRAY_SIZE(igep3_phy_data));
-               usbhs_init(&igep3_usbhs_bdata);
-       }
-}
-
-MACHINE_START(IGEP0020, "IGEP v2 board")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap35xx_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = igep_init,
-       .init_late      = omap35xx_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
-
-MACHINE_START(IGEP0030, "IGEP OMAP3 module")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap35xx_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = igep_init,
-       .init_late      = omap35xx_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
index dd8da2c5399f34386baacd5d79eba2bdc41dc8c9..4ec8d82b0492f3e66e75bec0aa7cff8cd25a5faa 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
-#include "board-zoom.h"
 #include "gpmc.h"
 #include "gpmc-smsc911x.h"
 
@@ -406,7 +405,7 @@ static void __init omap_ldp_init(void)
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(NULL);
        board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions),
-                       ZOOM_NAND_CS, 0, nand_default_timings);
+                       0, 0, nand_default_timings);
 
        omap_hsmmc_init(mmc);
        ldp_display_init();
index f26918467efcf42cc13639317965ebdb6d34bf14..8b9cd0690ce79328d12c664e1ef2ef301ef0b7eb 100644 (file)
@@ -289,18 +289,12 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = {
 
 static struct gpio_led gpio_leds[];
 
-/* PHY's VCC regulator might be added later, so flag that we need it */
-static struct usb_phy_gen_xceiv_platform_data hsusb2_phy_data = {
-       .needs_vcc = true,
-};
-
 static struct usbhs_phy_data phy_data[] = {
        {
                .port = 2,
                .reset_gpio = 147,
                .vcc_gpio = -1,         /* updated in beagle_twl_gpio_setup */
                .vcc_polarity = 1,      /* updated in beagle_twl_gpio_setup */
-               .platform_data = &hsusb2_phy_data,
        },
 };
 
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
deleted file mode 100644 (file)
index 1814387..0000000
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-omap3evm.c
- *
- * Copyright (C) 2008 Texas Instruments
- *
- * Modified from mach-omap2/board-3430sdp.c
- *
- * Initial code: Syed Mohammed Khasim
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/input/matrix_keypad.h>
-#include <linux/leds.h>
-#include <linux/interrupt.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/nand.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
-#include <linux/i2c/twl.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/musb.h>
-#include <linux/usb/usb_phy_gen_xceiv.h>
-#include <linux/smsc911x.h>
-
-#include <linux/wl12xx.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/mmc/host.h>
-#include <linux/export.h>
-#include <linux/usb/phy.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <linux/platform_data/mtd-nand-omap2.h>
-#include "common.h"
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <video/omapdss.h>
-#include <video/omap-panel-data.h>
-
-#include "soc.h"
-#include "mux.h"
-#include "sdram-micron-mt46h32m32lf-6.h"
-#include "hsmmc.h"
-#include "common-board-devices.h"
-#include "board-flash.h"
-
-#define        NAND_CS                 0
-
-#define OMAP3_EVM_TS_GPIO      175
-#define OMAP3_EVM_EHCI_VBUS    22
-#define OMAP3_EVM_EHCI_SELECT  61
-
-#define OMAP3EVM_ETHR_START    0x2c000000
-#define OMAP3EVM_ETHR_SIZE     1024
-#define OMAP3EVM_ETHR_ID_REV   0x50
-#define OMAP3EVM_ETHR_GPIO_IRQ 176
-#define OMAP3EVM_SMSC911X_CS   5
-/*
- * Eth Reset signal
- *     64 = Generation 1 (<=RevD)
- *     7 = Generation 2 (>=RevE)
- */
-#define OMAP3EVM_GEN1_ETHR_GPIO_RST    64
-#define OMAP3EVM_GEN2_ETHR_GPIO_RST    7
-
-/*
- * OMAP35x EVM revision
- * Run time detection of EVM revision is done by reading Ethernet
- * PHY ID -
- *     GEN_1   = 0x01150000
- *     GEN_2   = 0x92200000
- */
-enum {
-       OMAP3EVM_BOARD_GEN_1 = 0,       /* EVM Rev between  A - D */
-       OMAP3EVM_BOARD_GEN_2,           /* EVM Rev >= Rev E */
-};
-
-static u8 omap3_evm_version;
-
-static u8 get_omap3_evm_rev(void)
-{
-       return omap3_evm_version;
-}
-
-static void __init omap3_evm_get_revision(void)
-{
-       void __iomem *ioaddr;
-       unsigned int smsc_id;
-
-       /* Ethernet PHY ID is stored at ID_REV register */
-       ioaddr = ioremap_nocache(OMAP3EVM_ETHR_START, SZ_1K);
-       if (!ioaddr)
-               return;
-       smsc_id = readl(ioaddr + OMAP3EVM_ETHR_ID_REV) & 0xFFFF0000;
-       iounmap(ioaddr);
-
-       switch (smsc_id) {
-       /*SMSC9115 chipset*/
-       case 0x01150000:
-               omap3_evm_version = OMAP3EVM_BOARD_GEN_1;
-               break;
-       /*SMSC 9220 chipset*/
-       case 0x92200000:
-       default:
-               omap3_evm_version = OMAP3EVM_BOARD_GEN_2;
-       }
-}
-
-#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
-#include "gpmc-smsc911x.h"
-
-static struct omap_smsc911x_platform_data smsc911x_cfg = {
-       .cs             = OMAP3EVM_SMSC911X_CS,
-       .gpio_irq       = OMAP3EVM_ETHR_GPIO_IRQ,
-       .gpio_reset     = -EINVAL,
-       .flags          = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-};
-
-static inline void __init omap3evm_init_smsc911x(void)
-{
-       /* Configure ethernet controller reset gpio */
-       if (cpu_is_omap3430()) {
-               if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1)
-                       smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST;
-               else
-                       smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST;
-       }
-
-       gpmc_smsc911x_init(&smsc911x_cfg);
-}
-
-#else
-static inline void __init omap3evm_init_smsc911x(void) { return; }
-#endif
-
-/*
- * OMAP3EVM LCD Panel control signals
- */
-#define OMAP3EVM_LCD_PANEL_LR          2
-#define OMAP3EVM_LCD_PANEL_UD          3
-#define OMAP3EVM_LCD_PANEL_INI         152
-#define OMAP3EVM_LCD_PANEL_QVGA                154
-#define OMAP3EVM_LCD_PANEL_RESB                155
-
-#define OMAP3EVM_LCD_PANEL_ENVDD       153
-#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO        210
-
-/*
- * OMAP3EVM DVI control signals
- */
-#define OMAP3EVM_DVI_PANEL_EN_GPIO     199
-
-#ifdef CONFIG_BROKEN
-static void __init omap3_evm_display_init(void)
-{
-       int r;
-
-       r = gpio_request_one(OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW,
-                               "lcd_panel_envdd");
-       if (r)
-               pr_err("failed to get lcd_panel_envdd GPIO\n");
-
-       r = gpio_request_one(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO,
-                               GPIOF_OUT_INIT_LOW, "lcd_panel_bklight");
-       if (r)
-               pr_err("failed to get lcd_panel_bklight GPIO\n");
-
-       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
-               gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
-       else
-               gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
-}
-#endif
-
-static struct panel_sharp_ls037v7dw01_platform_data omap3_evm_lcd_pdata = {
-       .name                   = "lcd",
-       .source                 = "dpi.0",
-
-       .data_lines             = 18,
-
-       .resb_gpio              = OMAP3EVM_LCD_PANEL_RESB,
-       .ini_gpio               = OMAP3EVM_LCD_PANEL_INI,
-       .mo_gpio                = OMAP3EVM_LCD_PANEL_QVGA,
-       .lr_gpio                = OMAP3EVM_LCD_PANEL_LR,
-       .ud_gpio                = OMAP3EVM_LCD_PANEL_UD,
-};
-
-static struct platform_device omap3_evm_lcd_device = {
-       .name                   = "panel-sharp-ls037v7dw01",
-       .id                     = 0,
-       .dev.platform_data      = &omap3_evm_lcd_pdata,
-};
-
-static struct connector_dvi_platform_data omap3_evm_dvi_connector_pdata = {
-       .name                   = "dvi",
-       .source                 = "tfp410.0",
-       .i2c_bus_num            = -1,
-};
-
-static struct platform_device omap3_evm_dvi_connector_device = {
-       .name                   = "connector-dvi",
-       .id                     = 0,
-       .dev.platform_data      = &omap3_evm_dvi_connector_pdata,
-};
-
-static struct encoder_tfp410_platform_data omap3_evm_tfp410_pdata = {
-       .name                   = "tfp410.0",
-       .source                 = "dpi.0",
-       .data_lines             = 24,
-       .power_down_gpio        = OMAP3EVM_DVI_PANEL_EN_GPIO,
-};
-
-static struct platform_device omap3_evm_tfp410_device = {
-       .name                   = "tfp410",
-       .id                     = 0,
-       .dev.platform_data      = &omap3_evm_tfp410_pdata,
-};
-
-static struct connector_atv_platform_data omap3_evm_tv_pdata = {
-       .name = "tv",
-       .source = "venc.0",
-       .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
-       .invert_polarity = false,
-};
-
-static struct platform_device omap3_evm_tv_connector_device = {
-       .name                   = "connector-analog-tv",
-       .id                     = 0,
-       .dev.platform_data      = &omap3_evm_tv_pdata,
-};
-
-static struct omap_dss_board_info omap3_evm_dss_data = {
-       .default_display_name = "lcd",
-};
-
-static struct regulator_consumer_supply omap3evm_vmmc1_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
-};
-
-static struct regulator_consumer_supply omap3evm_vsim_supply[] = {
-       REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
-};
-
-/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
-static struct regulator_init_data omap3evm_vmmc1 = {
-       .constraints = {
-               .min_uV                 = 1850000,
-               .max_uV                 = 3150000,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
-                                       | REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(omap3evm_vmmc1_supply),
-       .consumer_supplies      = omap3evm_vmmc1_supply,
-};
-
-/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
-static struct regulator_init_data omap3evm_vsim = {
-       .constraints = {
-               .min_uV                 = 1800000,
-               .max_uV                 = 3000000,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
-                                       | REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(omap3evm_vsim_supply),
-       .consumer_supplies      = omap3evm_vsim_supply,
-};
-
-static struct omap2_hsmmc_info mmc[] = {
-       {
-               .mmc            = 1,
-               .caps           = MMC_CAP_4_BIT_DATA,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = 63,
-               .deferred       = true,
-       },
-#ifdef CONFIG_WILINK_PLATFORM_DATA
-       {
-               .name           = "wl1271",
-               .mmc            = 2,
-               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
-               .gpio_wp        = -EINVAL,
-               .gpio_cd        = -EINVAL,
-               .nonremovable   = true,
-       },
-#endif
-       {}      /* Terminator */
-};
-
-static struct gpio_led gpio_leds[] = {
-       {
-               .name                   = "omap3evm::ledb",
-               /* normally not visible (board underside) */
-               .default_trigger        = "default-on",
-               .gpio                   = -EINVAL,      /* gets replaced */
-               .active_low             = true,
-       },
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
-       .leds           = gpio_leds,
-       .num_leds       = ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device leds_gpio = {
-       .name   = "leds-gpio",
-       .id     = -1,
-       .dev    = {
-               .platform_data  = &gpio_led_info,
-       },
-};
-
-
-static int omap3evm_twl_gpio_setup(struct device *dev,
-               unsigned gpio, unsigned ngpio)
-{
-       int r, lcd_bl_en;
-
-       /* gpio + 0 is "mmc0_cd" (input/IRQ) */
-       mmc[0].gpio_cd = gpio + 0;
-       omap_hsmmc_late_init(mmc);
-
-       /*
-        * Most GPIOs are for USB OTG.  Some are mostly sent to
-        * the P2 connector; notably LEDA for the LCD backlight.
-        */
-
-       /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
-       lcd_bl_en = get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2 ?
-               GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-       r = gpio_request_one(gpio + TWL4030_GPIO_MAX, lcd_bl_en, "EN_LCD_BKL");
-       if (r)
-               printk(KERN_ERR "failed to get/set lcd_bkl gpio\n");
-
-       /* gpio + 7 == DVI Enable */
-       gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
-
-       /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
-       gpio_leds[0].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
-       platform_device_register(&leds_gpio);
-
-       /* Enable VBUS switch by setting TWL4030.GPIO2DIR as output
-        * for starting USB tranceiver
-        */
-#ifdef CONFIG_TWL4030_CORE
-       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
-               u8 val;
-
-               twl_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR1);
-               val |= 0x04; /* TWL4030.GPIO2DIR BIT at GPIODATADIR1(0x9B) */
-               twl_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR1);
-       }
-#endif
-
-       return 0;
-}
-
-static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
-       .use_leds       = true,
-       .setup          = omap3evm_twl_gpio_setup,
-};
-
-static uint32_t board_keymap[] = {
-       KEY(0, 0, KEY_LEFT),
-       KEY(0, 1, KEY_DOWN),
-       KEY(0, 2, KEY_ENTER),
-       KEY(0, 3, KEY_M),
-
-       KEY(1, 0, KEY_RIGHT),
-       KEY(1, 1, KEY_UP),
-       KEY(1, 2, KEY_I),
-       KEY(1, 3, KEY_N),
-
-       KEY(2, 0, KEY_A),
-       KEY(2, 1, KEY_E),
-       KEY(2, 2, KEY_J),
-       KEY(2, 3, KEY_O),
-
-       KEY(3, 0, KEY_B),
-       KEY(3, 1, KEY_F),
-       KEY(3, 2, KEY_K),
-       KEY(3, 3, KEY_P)
-};
-
-static struct matrix_keymap_data board_map_data = {
-       .keymap                 = board_keymap,
-       .keymap_size            = ARRAY_SIZE(board_keymap),
-};
-
-static struct twl4030_keypad_data omap3evm_kp_data = {
-       .keymap_data    = &board_map_data,
-       .rows           = 4,
-       .cols           = 4,
-       .rep            = 1,
-};
-
-/* ads7846 on SPI */
-static struct regulator_consumer_supply omap3evm_vio_supply[] = {
-       REGULATOR_SUPPLY("vcc", "spi1.0"),
-};
-
-/* VIO for ads7846 */
-static struct regulator_init_data omap3evm_vio = {
-       .constraints = {
-               .min_uV                 = 1800000,
-               .max_uV                 = 1800000,
-               .apply_uV               = true,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(omap3evm_vio_supply),
-       .consumer_supplies      = omap3evm_vio_supply,
-};
-
-#ifdef CONFIG_WILINK_PLATFORM_DATA
-
-#define OMAP3EVM_WLAN_PMENA_GPIO       (150)
-#define OMAP3EVM_WLAN_IRQ_GPIO         (149)
-
-static struct regulator_consumer_supply omap3evm_vmmc2_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
-};
-
-/* VMMC2 for driving the WL12xx module */
-static struct regulator_init_data omap3evm_vmmc2 = {
-       .constraints = {
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(omap3evm_vmmc2_supply),
-       .consumer_supplies      = omap3evm_vmmc2_supply,
-};
-
-static struct fixed_voltage_config omap3evm_vwlan = {
-       .supply_name            = "vwl1271",
-       .microvolts             = 1800000, /* 1.80V */
-       .gpio                   = OMAP3EVM_WLAN_PMENA_GPIO,
-       .startup_delay          = 70000, /* 70ms */
-       .enable_high            = 1,
-       .enabled_at_boot        = 0,
-       .init_data              = &omap3evm_vmmc2,
-};
-
-static struct platform_device omap3evm_wlan_regulator = {
-       .name           = "reg-fixed-voltage",
-       .id             = 1,
-       .dev = {
-               .platform_data  = &omap3evm_vwlan,
-       },
-};
-
-struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
-       .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
-};
-#endif
-
-/* VAUX2 for USB */
-static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = {
-       REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),    /* OMAP ISP */
-       REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),    /* OMAP ISP */
-       REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"), /* hsusb port 2 */
-       REGULATOR_SUPPLY("vaux2", NULL),
-};
-
-static struct regulator_init_data omap3evm_vaux2 = {
-       .constraints = {
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = true,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies          = ARRAY_SIZE(omap3evm_vaux2_supplies),
-       .consumer_supplies              = omap3evm_vaux2_supplies,
-};
-
-static struct twl4030_platform_data omap3evm_twldata = {
-       /* platform_data for children goes here */
-       .keypad         = &omap3evm_kp_data,
-       .gpio           = &omap3evm_gpio_data,
-       .vio            = &omap3evm_vio,
-       .vmmc1          = &omap3evm_vmmc1,
-       .vsim           = &omap3evm_vsim,
-};
-
-static int __init omap3_evm_i2c_init(void)
-{
-       omap3_pmic_get_config(&omap3evm_twldata,
-                       TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
-                       TWL_COMMON_PDATA_AUDIO,
-                       TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
-
-       omap3evm_twldata.vdac->constraints.apply_uV = true;
-       omap3evm_twldata.vpll2->constraints.apply_uV = true;
-
-       omap3_pmic_init("twl4030", &omap3evm_twldata);
-       omap_register_i2c_bus(2, 400, NULL, 0);
-       omap_register_i2c_bus(3, 400, NULL, 0);
-       return 0;
-}
-
-static struct usbhs_phy_data phy_data[] __initdata = {
-       {
-               .port = 2,
-               .reset_gpio = -1,       /* set at runtime */
-               .vcc_gpio = -EINVAL,
-       },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-       .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux omap35x_board_mux[] __initdata = {
-       OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
-                               OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
-                               OMAP_PIN_OFF_WAKEUPENABLE),
-       OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
-                               OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
-                               OMAP_PIN_OFF_WAKEUPENABLE),
-       OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
-                               OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
-                               OMAP_PIN_OFF_NONE),
-#ifdef CONFIG_WILINK_PLATFORM_DATA
-       /* WLAN IRQ - GPIO 149 */
-       OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-
-       /* WLAN POWER ENABLE - GPIO 150 */
-       OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-
-       /* MMC2 SDIO pin muxes for WL12xx */
-       OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-#endif
-       { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-static struct omap_board_mux omap36x_board_mux[] __initdata = {
-       OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
-                               OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
-                               OMAP_PIN_OFF_WAKEUPENABLE),
-       OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
-                               OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
-                               OMAP_PIN_OFF_WAKEUPENABLE),
-       /* AM/DM37x EVM: DSS data bus muxed with sys_boot */
-       OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(SYS_BOOT0, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(SYS_BOOT1, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(SYS_BOOT3, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-       OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-#ifdef CONFIG_WILINK_PLATFORM_DATA
-       /* WLAN IRQ - GPIO 149 */
-       OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-
-       /* WLAN POWER ENABLE - GPIO 150 */
-       OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-
-       /* MMC2 SDIO pin muxes for WL12xx */
-       OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-#endif
-
-       { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap35x_board_mux      NULL
-#define omap36x_board_mux      NULL
-#endif
-
-static struct omap_musb_board_data musb_board_data = {
-       .interface_type         = MUSB_INTERFACE_ULPI,
-       .mode                   = MUSB_OTG,
-       .power                  = 100,
-};
-
-static struct gpio omap3_evm_ehci_gpios[] __initdata = {
-       { OMAP3_EVM_EHCI_VBUS,   GPIOF_OUT_INIT_HIGH,  "enable EHCI VBUS" },
-       { OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW,   "select EHCI port" },
-};
-
-static void __init omap3_evm_wl12xx_init(void)
-{
-#ifdef CONFIG_WILINK_PLATFORM_DATA
-       int ret;
-
-       /* WL12xx WLAN Init */
-       omap3evm_wlan_data.irq = gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO);
-       ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
-       if (ret)
-               pr_err("error setting wl12xx data: %d\n", ret);
-       ret = platform_device_register(&omap3evm_wlan_regulator);
-       if (ret)
-               pr_err("error registering wl12xx device: %d\n", ret);
-#endif
-}
-
-static struct regulator_consumer_supply dummy_supplies[] = {
-       REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
-       REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
-};
-
-static struct mtd_partition omap3evm_nand_partitions[] = {
-       /* All the partition sizes are listed in terms of NAND block size */
-       {
-               .name           = "X-Loader",
-               .offset         = 0,
-               .size           = 4*(SZ_128K),
-               .mask_flags     = MTD_WRITEABLE
-       },
-       {
-               .name           = "U-Boot",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 14*(SZ_128K),
-               .mask_flags     = MTD_WRITEABLE
-       },
-       {
-               .name           = "U-Boot Env",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 2*(SZ_128K)
-       },
-       {
-               .name           = "Kernel",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 40*(SZ_128K)
-       },
-       {
-               .name           = "File system",
-               .size           = MTDPART_SIZ_FULL,
-               .offset         = MTDPART_OFS_APPEND,
-       },
-};
-
-static void __init omap3_evm_init(void)
-{
-       struct omap_board_mux *obm;
-
-       omap3_evm_get_revision();
-       regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-
-       obm = (cpu_is_omap3630()) ? omap36x_board_mux : omap35x_board_mux;
-       omap3_mux_init(obm, OMAP_PACKAGE_CBB);
-
-       omap_mux_init_gpio(63, OMAP_PIN_INPUT);
-       omap_hsmmc_init(mmc);
-
-       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
-               omap3evm_twldata.vaux2 = &omap3evm_vaux2;
-
-       omap3_evm_i2c_init();
-
-       omap_display_init(&omap3_evm_dss_data);
-       platform_device_register(&omap3_evm_lcd_device);
-       platform_device_register(&omap3_evm_tfp410_device);
-       platform_device_register(&omap3_evm_dvi_connector_device);
-       platform_device_register(&omap3_evm_tv_connector_device);
-
-       omap_serial_init();
-       omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
-
-       /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
-       usb_nop_xceiv_register();
-
-       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
-               /* enable EHCI VBUS using GPIO22 */
-               omap_mux_init_gpio(OMAP3_EVM_EHCI_VBUS, OMAP_PIN_INPUT_PULLUP);
-               /* Select EHCI port on main board */
-               omap_mux_init_gpio(OMAP3_EVM_EHCI_SELECT,
-                                  OMAP_PIN_INPUT_PULLUP);
-               gpio_request_array(omap3_evm_ehci_gpios,
-                                  ARRAY_SIZE(omap3_evm_ehci_gpios));
-
-               /* setup EHCI phy reset config */
-               omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
-               phy_data[0].reset_gpio = 21;
-
-               /* EVM REV >= E can supply 500mA with EXTVBUS programming */
-               musb_board_data.power = 500;
-               musb_board_data.extvbus = 1;
-       } else {
-               /* setup EHCI phy reset on MDC */
-               omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
-               phy_data[0].reset_gpio = 135;
-       }
-       usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
-       usb_musb_init(&musb_board_data);
-
-       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
-       usbhs_init(&usbhs_bdata);
-       board_nand_init(omap3evm_nand_partitions,
-                       ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS,
-                       NAND_BUSWIDTH_16, NULL);
-
-       omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
-       omap3evm_init_smsc911x();
-#ifdef CONFIG_BROKEN
-       omap3_evm_display_init();
-#endif
-       omap3_evm_wl12xx_init();
-       omap_twl4030_audio_init("omap3evm", NULL);
-}
-
-MACHINE_START(OMAP3EVM, "OMAP3 EVM")
-       /* Maintainer: Syed Mohammed Khasim - Texas Instruments */
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap35xx_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = omap3_evm_init,
-       .init_late      = omap35xx_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
deleted file mode 100644 (file)
index 345e8c4..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Board support file for Nokia N950 (RM-680) / N9 (RM-696).
- *
- * Copyright (C) 2010 Nokia
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/i2c/twl.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/consumer.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
-#include <linux/usb/phy.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include "common.h"
-#include "mux.h"
-#include "gpmc.h"
-#include "mmc.h"
-#include "hsmmc.h"
-#include "sdram-nokia.h"
-#include "common-board-devices.h"
-#include "gpmc-onenand.h"
-
-static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
-};
-
-/* Fixed regulator for internal eMMC */
-static struct regulator_init_data rm680_vemmc = {
-       .constraints =  {
-               .name                   = "rm680_vemmc",
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_STATUS
-                                       | REGULATOR_CHANGE_MODE,
-       },
-       .num_consumer_supplies          = ARRAY_SIZE(rm680_vemmc_consumers),
-       .consumer_supplies              = rm680_vemmc_consumers,
-};
-
-static struct fixed_voltage_config rm680_vemmc_config = {
-       .supply_name            = "VEMMC",
-       .microvolts             = 2900000,
-       .gpio                   = 157,
-       .startup_delay          = 150,
-       .enable_high            = 1,
-       .init_data              = &rm680_vemmc,
-};
-
-static struct platform_device rm680_vemmc_device = {
-       .name                   = "reg-fixed-voltage",
-       .dev                    = {
-               .platform_data  = &rm680_vemmc_config,
-       },
-};
-
-static struct platform_device *rm680_peripherals_devices[] __initdata = {
-       &rm680_vemmc_device,
-};
-
-/* TWL */
-static struct twl4030_gpio_platform_data rm680_gpio_data = {
-       .pullups                = BIT(0),
-       .pulldowns              = BIT(1) | BIT(2) | BIT(8) | BIT(15),
-};
-
-static struct twl4030_platform_data rm680_twl_data = {
-       .gpio                   = &rm680_gpio_data,
-       /* add rest of the children here */
-};
-
-static void __init rm680_i2c_init(void)
-{
-       omap3_pmic_get_config(&rm680_twl_data, TWL_COMMON_PDATA_USB, 0);
-       omap_pmic_init(1, 2900, "twl5031", 7 + OMAP_INTC_START, &rm680_twl_data);
-       omap_register_i2c_bus(2, 400, NULL, 0);
-       omap_register_i2c_bus(3, 400, NULL, 0);
-}
-
-#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
-       defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
-static struct omap_onenand_platform_data board_onenand_data[] = {
-       {
-               .gpio_irq       = 65,
-               .flags          = ONENAND_SYNC_READWRITE,
-       }
-};
-#endif
-
-/* eMMC */
-static struct omap2_hsmmc_info mmc[] __initdata = {
-       {
-               .name           = "internal",
-               .mmc            = 2,
-               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-       },
-       { /* Terminator */ }
-};
-
-static void __init rm680_peripherals_init(void)
-{
-       platform_add_devices(rm680_peripherals_devices,
-                               ARRAY_SIZE(rm680_peripherals_devices));
-       rm680_i2c_init();
-       gpmc_onenand_init(board_onenand_data);
-       omap_hsmmc_init(mmc);
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-       { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static void __init rm680_init(void)
-{
-       struct omap_sdrc_params *sdrc_params;
-
-       omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-       omap_serial_init();
-
-       sdrc_params = nokia_get_sdram_timings();
-       omap_sdrc_init(sdrc_params, sdrc_params);
-
-       usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
-       usb_musb_init(NULL);
-       rm680_peripherals_init();
-}
-
-MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap3630_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = rm680_init,
-       .init_late      = omap3630_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
-
-MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap3630_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = rm680_init,
-       .init_late      = omap3630_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
index f6fe388af9895ef8c8b2859f9177a146a30fb965..5c0d0e12042099876be304992f66bc6934fb7ea4 100644 (file)
@@ -57,6 +57,8 @@
 #include "common-board-devices.h"
 #include "gpmc.h"
 #include "gpmc-onenand.h"
+#include "soc.h"
+#include "omap-secure.h"
 
 #define SYSTEM_REV_B_USES_VAUX3        0x1699
 #define SYSTEM_REV_S_USES_VAUX3 0x8
@@ -1298,6 +1300,22 @@ static void __init rx51_init_twl4030_hwmon(void)
        platform_device_register(&madc_hwmon);
 }
 
+static struct platform_device omap3_rom_rng_device = {
+       .name           = "omap3-rom-rng",
+       .id             = -1,
+       .dev    = {
+               .platform_data  = rx51_secure_rng_call,
+       },
+};
+
+static void __init rx51_init_omap3_rom_rng(void)
+{
+       if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
+               pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+               platform_device_register(&omap3_rom_rng_device);
+       }
+}
+
 void __init rx51_peripherals_init(void)
 {
        rx51_i2c_init();
@@ -1318,5 +1336,6 @@ void __init rx51_peripherals_init(void)
 
        rx51_charger_init();
        rx51_init_twl4030_hwmon();
+       rx51_init_omap3_rom_rng();
 }
 
index 7735105561d87dd218c436b357ade5211e5a6d2e..db168c9627a15e2ba5d0ea11bf02001cc73b83ff 100644 (file)
@@ -2,6 +2,8 @@
  * Board support file for Nokia N900 (aka RX-51).
  *
  * Copyright (C) 2007, 2008 Nokia
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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
@@ -31,7 +33,9 @@
 #include "mux.h"
 #include "gpmc.h"
 #include "pm.h"
+#include "soc.h"
 #include "sdram-nokia.h"
+#include "omap-secure.h"
 
 #define RX51_GPIO_SLEEP_IND 162
 
@@ -103,6 +107,14 @@ static void __init rx51_init(void)
        usb_musb_init(&musb_board_data);
        rx51_peripherals_init();
 
+       if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
+#ifdef CONFIG_ARM_ERRATA_430973
+               pr_info("RX-51: Enabling ARM errata 430973 workaround\n");
+               /* set IBE to 1 */
+               rx51_secure_update_aux_cr(BIT(6), 0);
+#endif
+       }
+
        /* Ensure SDRC pins are mux'd for self-refresh */
        omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
        omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
deleted file mode 100644 (file)
index 42e5f23..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments Inc.
- * Mikkel Christensen <mlc@ti.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.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/serial_8250.h>
-#include <linux/smsc911x.h>
-#include <linux/interrupt.h>
-
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-
-#include "gpmc.h"
-#include "gpmc-smsc911x.h"
-
-#include "board-zoom.h"
-
-#include "soc.h"
-#include "common.h"
-
-#define ZOOM_SMSC911X_CS       7
-#define ZOOM_SMSC911X_GPIO     158
-#define ZOOM_QUADUART_CS       3
-#define ZOOM_QUADUART_GPIO     102
-#define ZOOM_QUADUART_RST_GPIO 152
-#define QUART_CLK              1843200
-#define DEBUG_BASE             0x08000000
-#define ZOOM_ETHR_START        DEBUG_BASE
-
-static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = {
-       .cs             = ZOOM_SMSC911X_CS,
-       .gpio_irq       = ZOOM_SMSC911X_GPIO,
-       .gpio_reset     = -EINVAL,
-       .flags          = SMSC911X_USE_32BIT,
-};
-
-static inline void __init zoom_init_smsc911x(void)
-{
-       gpmc_smsc911x_init(&zoom_smsc911x_cfg);
-}
-
-static struct plat_serial8250_port serial_platform_data[] = {
-       {
-               .mapbase        = ZOOM_UART_BASE,
-               .flags          = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ,
-               .irqflags       = IRQF_SHARED | IRQF_TRIGGER_RISING,
-               .iotype         = UPIO_MEM,
-               .regshift       = 1,
-               .uartclk        = QUART_CLK,
-       }, {
-               .flags          = 0
-       }
-};
-
-static struct platform_device zoom_debugboard_serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = serial_platform_data,
-       },
-};
-
-static inline void __init zoom_init_quaduart(void)
-{
-       int quart_cs;
-       unsigned long cs_mem_base;
-       int quart_gpio = 0;
-
-       if (gpio_request_one(ZOOM_QUADUART_RST_GPIO,
-                               GPIOF_OUT_INIT_LOW,
-                               "TL16CP754C GPIO") < 0) {
-               pr_err("Failed to request GPIO%d for TL16CP754C\n",
-                       ZOOM_QUADUART_RST_GPIO);
-               return;
-       }
-
-       quart_cs = ZOOM_QUADUART_CS;
-
-       if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) {
-               pr_err("Failed to request GPMC mem for Quad UART(TL16CP754C)\n");
-               return;
-       }
-
-       quart_gpio = ZOOM_QUADUART_GPIO;
-
-       if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0)
-               printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
-                                                               quart_gpio);
-
-       serial_platform_data[0].irq = gpio_to_irq(102);
-}
-
-static inline int omap_zoom_debugboard_detect(void)
-{
-       int debug_board_detect = 0;
-       int ret = 1;
-
-       debug_board_detect = ZOOM_SMSC911X_GPIO;
-
-       if (gpio_request_one(debug_board_detect, GPIOF_IN,
-                            "Zoom debug board detect") < 0) {
-               pr_err("Failed to request GPIO%d for Zoom debug board detect\n",
-                      debug_board_detect);
-               return 0;
-       }
-
-       if (!gpio_get_value(debug_board_detect)) {
-               ret = 0;
-       }
-       gpio_free(debug_board_detect);
-       return ret;
-}
-
-static struct platform_device *zoom_devices[] __initdata = {
-       &zoom_debugboard_serial_device,
-};
-
-static struct regulator_consumer_supply dummy_supplies[] = {
-       REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
-       REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
-};
-
-int __init zoom_debugboard_init(void)
-{
-       if (!omap_zoom_debugboard_detect())
-               return 0;
-
-       regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-       zoom_init_smsc911x();
-       zoom_init_quaduart();
-       return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
-}
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c
deleted file mode 100644 (file)
index 3d8ecc1..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 Texas Instruments Inc.
- *
- * Modified from mach-omap2/board-zoom-peripherals.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <video/omapdss.h>
-#include <video/omap-panel-data.h>
-
-#include "board-zoom.h"
-#include "soc.h"
-#include "common.h"
-
-#define LCD_PANEL_RESET_GPIO_PROD      96
-#define LCD_PANEL_RESET_GPIO_PILOT     55
-#define LCD_PANEL_QVGA_GPIO            56
-
-static struct panel_nec_nl8048hl11_platform_data zoom_lcd_pdata = {
-       .name                   = "lcd",
-       .source                 = "dpi.0",
-
-       .data_lines             = 24,
-
-       .res_gpio               = -1,   /* filled in code */
-       .qvga_gpio              = LCD_PANEL_QVGA_GPIO,
-};
-
-static struct omap_dss_board_info zoom_dss_data = {
-       .default_display_name = "lcd",
-};
-
-static void __init zoom_lcd_panel_init(void)
-{
-       zoom_lcd_pdata.res_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
-                       LCD_PANEL_RESET_GPIO_PROD :
-                       LCD_PANEL_RESET_GPIO_PILOT;
-}
-
-static struct omap2_mcspi_device_config dss_lcd_mcspi_config = {
-       .turbo_mode             = 1,
-};
-
-static struct spi_board_info nec_8048_spi_board_info[] __initdata = {
-       [0] = {
-               .modalias               = "panel-nec-nl8048hl11",
-               .bus_num                = 1,
-               .chip_select            = 2,
-               .max_speed_hz           = 375000,
-               .controller_data        = &dss_lcd_mcspi_config,
-               .platform_data          = &zoom_lcd_pdata,
-       },
-};
-
-void __init zoom_display_init(void)
-{
-       omap_display_init(&zoom_dss_data);
-       zoom_lcd_panel_init();
-       spi_register_board_info(nec_8048_spi_board_info,
-                               ARRAY_SIZE(nec_8048_spi_board_info));
-}
-
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
deleted file mode 100644 (file)
index a90375d..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments Inc.
- *
- * Modified from mach-omap2/board-zoom2.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/input/matrix_keypad.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/wl12xx.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_data/gpio-omap.h>
-#include <linux/platform_data/omap-twl4030.h>
-#include <linux/usb/phy.h>
-#include <linux/pwm.h>
-#include <linux/leds_pwm.h>
-#include <linux/pwm_backlight.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-#include "board-zoom.h"
-
-#include "mux.h"
-#include "hsmmc.h"
-#include "common-board-devices.h"
-
-#define OMAP_ZOOM_WLAN_PMENA_GPIO      (101)
-#define OMAP_ZOOM_TSC2004_IRQ_GPIO     (153)
-#define OMAP_ZOOM_WLAN_IRQ_GPIO                (162)
-
-/* Zoom2 has Qwerty keyboard*/
-static uint32_t board_keymap[] = {
-       KEY(0, 0, KEY_E),
-       KEY(0, 1, KEY_R),
-       KEY(0, 2, KEY_T),
-       KEY(0, 3, KEY_HOME),
-       KEY(0, 6, KEY_I),
-       KEY(0, 7, KEY_LEFTSHIFT),
-       KEY(1, 0, KEY_D),
-       KEY(1, 1, KEY_F),
-       KEY(1, 2, KEY_G),
-       KEY(1, 3, KEY_SEND),
-       KEY(1, 6, KEY_K),
-       KEY(1, 7, KEY_ENTER),
-       KEY(2, 0, KEY_X),
-       KEY(2, 1, KEY_C),
-       KEY(2, 2, KEY_V),
-       KEY(2, 3, KEY_END),
-       KEY(2, 6, KEY_DOT),
-       KEY(2, 7, KEY_CAPSLOCK),
-       KEY(3, 0, KEY_Z),
-       KEY(3, 1, KEY_KPPLUS),
-       KEY(3, 2, KEY_B),
-       KEY(3, 3, KEY_F1),
-       KEY(3, 6, KEY_O),
-       KEY(3, 7, KEY_SPACE),
-       KEY(4, 0, KEY_W),
-       KEY(4, 1, KEY_Y),
-       KEY(4, 2, KEY_U),
-       KEY(4, 3, KEY_F2),
-       KEY(4, 4, KEY_VOLUMEUP),
-       KEY(4, 6, KEY_L),
-       KEY(4, 7, KEY_LEFT),
-       KEY(5, 0, KEY_S),
-       KEY(5, 1, KEY_H),
-       KEY(5, 2, KEY_J),
-       KEY(5, 3, KEY_F3),
-       KEY(5, 4, KEY_UNKNOWN),
-       KEY(5, 5, KEY_VOLUMEDOWN),
-       KEY(5, 6, KEY_M),
-       KEY(5, 7, KEY_RIGHT),
-       KEY(6, 0, KEY_Q),
-       KEY(6, 1, KEY_A),
-       KEY(6, 2, KEY_N),
-       KEY(6, 3, KEY_BACKSPACE),
-       KEY(6, 6, KEY_P),
-       KEY(6, 7, KEY_UP),
-       KEY(7, 0, KEY_PROG1),   /*MACRO 1 <User defined> */
-       KEY(7, 1, KEY_PROG2),   /*MACRO 2 <User defined> */
-       KEY(7, 2, KEY_PROG3),   /*MACRO 3 <User defined> */
-       KEY(7, 3, KEY_PROG4),   /*MACRO 4 <User defined> */
-       KEY(7, 6, KEY_SELECT),
-       KEY(7, 7, KEY_DOWN)
-};
-
-static struct matrix_keymap_data board_map_data = {
-       .keymap                 = board_keymap,
-       .keymap_size            = ARRAY_SIZE(board_keymap),
-};
-
-static struct twl4030_keypad_data zoom_kp_twl4030_data = {
-       .keymap_data    = &board_map_data,
-       .rows           = 8,
-       .cols           = 8,
-       .rep            = 1,
-};
-
-static struct regulator_consumer_supply zoom_vmmc1_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
-};
-
-static struct regulator_consumer_supply zoom_vsim_supply[] = {
-       REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
-};
-
-static struct regulator_consumer_supply zoom_vmmc2_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
-};
-
-static struct regulator_consumer_supply zoom_vmmc3_supply[] = {
-       REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"),
-};
-
-/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
-static struct regulator_init_data zoom_vmmc1 = {
-       .constraints = {
-               .min_uV                 = 1850000,
-               .max_uV                 = 3150000,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
-                                       | REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(zoom_vmmc1_supply),
-       .consumer_supplies      = zoom_vmmc1_supply,
-};
-
-/* VMMC2 for MMC2 card */
-static struct regulator_init_data zoom_vmmc2 = {
-       .constraints = {
-               .min_uV                 = 1850000,
-               .max_uV                 = 1850000,
-               .apply_uV               = true,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(zoom_vmmc2_supply),
-       .consumer_supplies      = zoom_vmmc2_supply,
-};
-
-/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
-static struct regulator_init_data zoom_vsim = {
-       .constraints = {
-               .min_uV                 = 1800000,
-               .max_uV                 = 3000000,
-               .valid_modes_mask       = REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
-                                       | REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(zoom_vsim_supply),
-       .consumer_supplies      = zoom_vsim_supply,
-};
-
-static struct regulator_init_data zoom_vmmc3 = {
-       .constraints = {
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(zoom_vmmc3_supply),
-       .consumer_supplies      = zoom_vmmc3_supply,
-};
-
-static struct fixed_voltage_config zoom_vwlan = {
-       .supply_name            = "vwl1271",
-       .microvolts             = 1800000, /* 1.8V */
-       .gpio                   = OMAP_ZOOM_WLAN_PMENA_GPIO,
-       .startup_delay          = 70000, /* 70msec */
-       .enable_high            = 1,
-       .enabled_at_boot        = 0,
-       .init_data              = &zoom_vmmc3,
-};
-
-static struct platform_device omap_vwlan_device = {
-       .name           = "reg-fixed-voltage",
-       .id             = 1,
-       .dev = {
-               .platform_data  = &zoom_vwlan,
-       },
-};
-
-static struct pwm_lookup zoom_pwm_lookup[] = {
-       PWM_LOOKUP("twl-pwm", 0, "leds_pwm", "zoom::keypad"),
-       PWM_LOOKUP("twl-pwm", 1, "pwm-backlight", "backlight"),
-};
-
-static struct led_pwm zoom_pwm_leds[] = {
-       {
-               .name           = "zoom::keypad",
-               .max_brightness = 127,
-               .pwm_period_ns  = 7812500,
-       },
-};
-
-static struct led_pwm_platform_data zoom_pwm_data = {
-       .num_leds       = ARRAY_SIZE(zoom_pwm_leds),
-       .leds           = zoom_pwm_leds,
-};
-
-static struct platform_device zoom_leds_pwm = {
-       .name   = "leds_pwm",
-       .id     = -1,
-       .dev    = {
-               .platform_data = &zoom_pwm_data,
-       },
-};
-
-static struct platform_pwm_backlight_data zoom_backlight_data = {
-       .pwm_id = 1,
-       .max_brightness = 127,
-       .dft_brightness = 127,
-       .pwm_period_ns = 7812500,
-};
-
-static struct platform_device zoom_backlight_pwm = {
-       .name   = "pwm-backlight",
-       .id     = -1,
-       .dev    = {
-               .platform_data = &zoom_backlight_data,
-       },
-};
-
-static struct platform_device *zoom_devices[] __initdata = {
-       &omap_vwlan_device,
-       &zoom_leds_pwm,
-       &zoom_backlight_pwm,
-};
-
-static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
-       .board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
-};
-
-static struct omap2_hsmmc_info mmc[] = {
-       {
-               .name           = "external",
-               .mmc            = 1,
-               .caps           = MMC_CAP_4_BIT_DATA,
-               .gpio_wp        = -EINVAL,
-               .power_saving   = true,
-               .deferred       = true,
-       },
-       {
-               .name           = "internal",
-               .mmc            = 2,
-               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-               .nonremovable   = true,
-               .power_saving   = true,
-       },
-       {
-               .name           = "wl1271",
-               .mmc            = 3,
-               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
-               .gpio_wp        = -EINVAL,
-               .gpio_cd        = -EINVAL,
-               .nonremovable   = true,
-       },
-       {}      /* Terminator */
-};
-
-static struct omap_tw4030_pdata omap_twl4030_audio_data = {
-       .voice_connected = true,
-       .custom_routing = true,
-
-       .has_hs         = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT,
-       .has_hf         = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT,
-
-       .has_mainmic    = true,
-       .has_submic     = true,
-       .has_hsmic      = true,
-       .has_linein     = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT,
-};
-
-static int zoom_twl_gpio_setup(struct device *dev,
-               unsigned gpio, unsigned ngpio)
-{
-       /* gpio + 0 is "mmc0_cd" (input/IRQ) */
-       mmc[0].gpio_cd = gpio + 0;
-       omap_hsmmc_late_init(mmc);
-
-       /* Audio setup */
-       omap_twl4030_audio_data.jack_detect = gpio + 2;
-       omap_twl4030_audio_init("Zoom2", &omap_twl4030_audio_data);
-
-       return 0;
-}
-
-static struct twl4030_gpio_platform_data zoom_gpio_data = {
-       .setup          = zoom_twl_gpio_setup,
-};
-
-static struct twl4030_platform_data zoom_twldata = {
-       /* platform_data for children goes here */
-       .gpio           = &zoom_gpio_data,
-       .keypad         = &zoom_kp_twl4030_data,
-       .vmmc1          = &zoom_vmmc1,
-       .vmmc2          = &zoom_vmmc2,
-       .vsim           = &zoom_vsim,
-};
-
-static int __init omap_i2c_init(void)
-{
-       omap3_pmic_get_config(&zoom_twldata,
-                       TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_BCI |
-                       TWL_COMMON_PDATA_MADC | TWL_COMMON_PDATA_AUDIO,
-                       TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
-
-       if (machine_is_omap_zoom2())
-               zoom_twldata.audio->codec->ramp_delay_value = 3; /* 161 ms */
-
-       omap_pmic_init(1, 2400, "twl5030", 7 + OMAP_INTC_START, &zoom_twldata);
-       omap_register_i2c_bus(2, 400, NULL, 0);
-       omap_register_i2c_bus(3, 400, NULL, 0);
-       return 0;
-}
-
-static void enable_board_wakeup_source(void)
-{
-       /* T2 interrupt line (keypad) */
-       omap_mux_init_signal("sys_nirq",
-               OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
-}
-
-void __init zoom_peripherals_init(void)
-{
-       int ret;
-
-       omap_zoom_wlan_data.irq = gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO);
-       ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
-
-       if (ret)
-               pr_err("error setting wl12xx data: %d\n", ret);
-
-       omap_hsmmc_init(mmc);
-       omap_i2c_init();
-       pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup));
-       platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
-       usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
-       usb_musb_init(NULL);
-       enable_board_wakeup_source();
-       omap_serial_init();
-}
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
deleted file mode 100644 (file)
index 1a3dd86..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Texas Instruments Inc.
- * Mikkel Christensen <mlc@ti.com>
- * Felipe Balbi <balbi@ti.com>
- *
- * Modified from mach-omap2/board-ldp.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-#include <linux/mtd/nand.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-
-#include "board-zoom.h"
-
-#include "board-flash.h"
-#include "mux.h"
-#include "sdram-micron-mt46h32m32lf-6.h"
-#include "sdram-hynix-h8mbx00u0mer-0em.h"
-
-#define ZOOM3_EHCI_RESET_GPIO          64
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-       /* WLAN IRQ - GPIO 162 */
-       OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-       /* WLAN POWER ENABLE - GPIO 101 */
-       OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-       /* WLAN SDIO: MMC3 CMD */
-       OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
-       /* WLAN SDIO: MMC3 CLK */
-       OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
-       /* WLAN SDIO: MMC3 DAT[0-3] */
-       OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
-       OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
-       { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static struct mtd_partition zoom_nand_partitions[] = {
-       /* All the partition sizes are listed in terms of NAND block size */
-       {
-               .name           = "X-Loader-NAND",
-               .offset         = 0,
-               .size           = 4 * (64 * 2048),      /* 512KB, 0x80000 */
-               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
-       },
-       {
-               .name           = "U-Boot-NAND",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
-               .size           = 10 * (64 * 2048),     /* 1.25MB, 0x140000 */
-               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
-       },
-       {
-               .name           = "Boot Env-NAND",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x1c0000 */
-               .size           = 2 * (64 * 2048),      /* 256KB, 0x40000 */
-       },
-       {
-               .name           = "Kernel-NAND",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x0200000*/
-               .size           = 240 * (64 * 2048),    /* 30M, 0x1E00000 */
-       },
-       {
-               .name           = "system",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x2000000 */
-               .size           = 3328 * (64 * 2048),   /* 416M, 0x1A000000 */
-       },
-       {
-               .name           = "userdata",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x1C000000*/
-               .size           = 256 * (64 * 2048),    /* 32M, 0x2000000 */
-       },
-       {
-               .name           = "cache",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x1E000000*/
-               .size           = 256 * (64 * 2048),    /* 32M, 0x2000000 */
-       },
-};
-
-static struct usbhs_phy_data phy_data[] __initdata = {
-       {
-               .port = 2,
-               .reset_gpio = ZOOM3_EHCI_RESET_GPIO,
-               .vcc_gpio = -EINVAL,
-       },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-       .port_mode[1]           = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static void __init omap_zoom_init(void)
-{
-       if (machine_is_omap_zoom2()) {
-               omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-       } else if (machine_is_omap_zoom3()) {
-               omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
-               omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT);
-
-               usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
-               usbhs_init(&usbhs_bdata);
-       }
-
-       board_nand_init(zoom_nand_partitions,
-                       ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS,
-                       NAND_BUSWIDTH_16, nand_default_timings);
-       zoom_debugboard_init();
-       zoom_peripherals_init();
-
-       if (machine_is_omap_zoom2())
-               omap_sdrc_init(mt46h32m32lf6_sdrc_params,
-                                         mt46h32m32lf6_sdrc_params);
-       else if (machine_is_omap_zoom3())
-               omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
-                                         h8mbx00u0mer0em_sdrc_params);
-
-       zoom_display_init();
-}
-
-MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap3430_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = omap_zoom_init,
-       .init_late      = omap3430_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
-
-MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
-       .atag_offset    = 0x100,
-       .reserve        = omap_reserve,
-       .map_io         = omap3_map_io,
-       .init_early     = omap3630_init_early,
-       .init_irq       = omap3_init_irq,
-       .handle_irq     = omap3_intc_handle_irq,
-       .init_machine   = omap_zoom_init,
-       .init_late      = omap3630_init_late,
-       .init_time      = omap3_sync32k_timer_init,
-       .restart        = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-zoom.h b/arch/arm/mach-omap2/board-zoom.h
deleted file mode 100644 (file)
index 2e94869..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Defines for zoom boards
- */
-#include <video/omapdss.h>
-
-#define ZOOM_NAND_CS    0
-
-extern int __init zoom_debugboard_init(void);
-extern void __init zoom_peripherals_init(void);
-extern void __init zoom_display_init(void);
index 334b76745900fb397e8d3fd5419dc1dd91e0bc63..03a2829beb8e4c69144dfd5e5eb639189b836b02 100644 (file)
@@ -3275,6 +3275,7 @@ static struct omap_clk omap36xx_clks[] = {
 static struct omap_clk omap34xx_omap36xx_clks[] = {
        CLK(NULL,       "aes1_ick",     &aes1_ick),
        CLK("omap_rng", "ick",          &rng_ick),
+       CLK("omap3-rom-rng",    "ick",  &rng_ick),
        CLK(NULL,       "sha11_ick",    &sha11_ick),
        CLK(NULL,       "des1_ick",     &des1_ick),
        CLK(NULL,       "cam_mclk",     &cam_mclk),
index 25b1feed480d8ae9089d63da213377dfd5d6dc5d..c78e893eba7d07febfd546e6a0b0fc50bbd41374 100644 (file)
@@ -52,7 +52,7 @@ static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
 
        apll_mask = EN_APLL_LOCKED << clk->enable_bit;
 
-       r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+       r = omap2xxx_cm_get_pll_status();
 
        return ((r & apll_mask) == apll_mask) ? true : false;
 }
@@ -126,7 +126,7 @@ u32 omap2xxx_get_apll_clkin(void)
 {
        u32 aplls, srate = 0;
 
-       aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+       aplls = omap2xxx_cm_get_pll_config();
        aplls &= OMAP24XX_APLLS_CLKIN_MASK;
        aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
 
index d8620105c42a3a0681c59de527b3f5d9c8e41b96..3ff32543493c58514149981a1f1017519a3445be 100644 (file)
@@ -60,8 +60,7 @@ unsigned long omap2xxx_clk_get_core_rate(void)
 
        core_clk = omap2_get_dpll_rate(dpll_core_ck);
 
-       v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-       v &= OMAP24XX_CORE_CLK_SRC_MASK;
+       v = omap2xxx_cm_get_core_clk_src();
 
        if (v == CORE_CLK_SRC_32K)
                core_clk = 32768;
@@ -79,8 +78,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
 {
        u32 high, low, core_clk_src;
 
-       core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-       core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+       core_clk_src = omap2xxx_cm_get_core_clk_src();
 
        if (core_clk_src == CORE_CLK_SRC_DPLL) {        /* DPLL clockout */
                high = curr_prcm_set->dpll_speed * 2;
@@ -120,8 +118,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
        const struct dpll_data *dd;
 
        cur_rate = omap2xxx_clk_get_core_rate();
-       mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-       mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+       mult = omap2xxx_cm_get_core_clk_src();
 
        if ((rate == (cur_rate / 2)) && (mult == 2)) {
                omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -145,7 +142,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
                tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
                                           dd->div1_mask);
                div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
-               tmpset.cm_clksel2_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+               tmpset.cm_clksel2_pll = omap2xxx_cm_get_core_pll_config();
                tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
                if (rate > low) {
                        tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
index ae2b35e76dc8e1e7592b1fd84d969d6f033e603a..b935ed2922d806725cd6916ce18bd429acf8e926 100644 (file)
@@ -98,7 +98,7 @@ long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
 int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
                            unsigned long parent_rate)
 {
-       u32 cur_rate, done_rate, bypass = 0, tmp;
+       u32 cur_rate, done_rate, bypass = 0;
        const struct prcm_config *prcm;
        unsigned long found_speed = 0;
        unsigned long flags;
@@ -141,23 +141,11 @@ int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
                else
                        done_rate = CORE_CLK_SRC_DPLL;
 
-               /* MPU divider */
-               omap2_cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
-
-               /* dsp + iva1 div(2420), iva2.1(2430) */
-               omap2_cm_write_mod_reg(prcm->cm_clksel_dsp,
-                                OMAP24XX_DSP_MOD, CM_CLKSEL);
-
-               omap2_cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
-
-               /* Major subsystem dividers */
-               tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
-               omap2_cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
-                                CM_CLKSEL1);
-
-               if (cpu_is_omap2430())
-                       omap2_cm_write_mod_reg(prcm->cm_clksel_mdm,
-                                        OMAP2430_MDM_MOD, CM_CLKSEL);
+               omap2xxx_cm_set_mod_dividers(prcm->cm_clksel_mpu,
+                                            prcm->cm_clksel_dsp,
+                                            prcm->cm_clksel_gfx,
+                                            prcm->cm_clksel1_core,
+                                            prcm->cm_clksel_mdm);
 
                /* x2 to enter omap2xxx_sdrc_init_params() */
                omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
index 0c38ca96c840ad596017b60f3d0801ae973a74c1..c7c5d31e90829141373662f32ffb39ce6c32637a 100644 (file)
@@ -542,6 +542,44 @@ int omap2_clk_disable_autoidle_all(void)
        return 0;
 }
 
+/**
+ * omap2_clk_deny_idle - disable autoidle on an OMAP clock
+ * @clk: struct clk * to disable autoidle for
+ *
+ * Disable autoidle on an OMAP clock.
+ */
+int omap2_clk_deny_idle(struct clk *clk)
+{
+       struct clk_hw_omap *c;
+
+       if (__clk_get_flags(clk) & CLK_IS_BASIC)
+               return -EINVAL;
+
+       c = to_clk_hw_omap(__clk_get_hw(clk));
+       if (c->ops && c->ops->deny_idle)
+               c->ops->deny_idle(c);
+       return 0;
+}
+
+/**
+ * omap2_clk_allow_idle - enable autoidle on an OMAP clock
+ * @clk: struct clk * to enable autoidle for
+ *
+ * Enable autoidle on an OMAP clock.
+ */
+int omap2_clk_allow_idle(struct clk *clk)
+{
+       struct clk_hw_omap *c;
+
+       if (__clk_get_flags(clk) & CLK_IS_BASIC)
+               return -EINVAL;
+
+       c = to_clk_hw_omap(__clk_get_hw(clk));
+       if (c->ops && c->ops->allow_idle)
+               c->ops->allow_idle(c);
+       return 0;
+}
+
 /**
  * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
  * @clk_names: ptr to an array of strings of clock names to enable
index 7aa32cd292f92bc5df52b0a108e99d49a3e3c019..82916cc82c920d6fb7d08dcec444dded07ede0bb 100644 (file)
@@ -411,6 +411,8 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
 void omap2_init_clk_hw_omap_clocks(struct clk *clk);
 int omap2_clk_enable_autoidle_all(void);
 int omap2_clk_disable_autoidle_all(void);
+int omap2_clk_allow_idle(struct clk *clk);
+int omap2_clk_deny_idle(struct clk *clk);
 void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
 int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
 void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
index 4b03394fa0c5307bdd31182c6bfd025d3c0aa2df..f17f00697cc054df682006d167264a43c959242d 100644 (file)
@@ -132,7 +132,7 @@ struct clockdomain {
        u8 _flags;
        const u8 dep_bit;
        const u8 prcm_partition;
-       const s16 cm_inst;
+       const u16 cm_inst;
        const u16 clkdm_offs;
        struct clkdm_dep *wkdep_srcs;
        struct clkdm_dep *sleepdep_srcs;
@@ -218,6 +218,7 @@ extern void __init am33xx_clockdomains_init(void);
 extern void __init omap44xx_clockdomains_init(void);
 extern void __init omap54xx_clockdomains_init(void);
 extern void __init dra7xx_clockdomains_init(void);
+void am43xx_clockdomains_init(void);
 
 extern void clkdm_add_autodeps(struct clockdomain *clkdm);
 extern void clkdm_del_autodeps(struct clockdomain *clkdm);
@@ -226,6 +227,7 @@ extern struct clkdm_ops omap2_clkdm_operations;
 extern struct clkdm_ops omap3_clkdm_operations;
 extern struct clkdm_ops omap4_clkdm_operations;
 extern struct clkdm_ops am33xx_clkdm_operations;
+extern struct clkdm_ops am43xx_clkdm_operations;
 
 extern struct clkdm_dep gfx_24xx_wkdeps[];
 extern struct clkdm_dep dsp_24xx_wkdeps[];
diff --git a/arch/arm/mach-omap2/clockdomains43xx_data.c b/arch/arm/mach-omap2/clockdomains43xx_data.c
new file mode 100644 (file)
index 0000000..6d71c60
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * AM43xx Clock domains framework
+ *
+ * Copyright (C) 2013 Texas Instruments, 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "prcm44xx.h"
+#include "prcm43xx.h"
+
+static struct clockdomain l4_cefuse_43xx_clkdm = {
+       .name             = "l4_cefuse_clkdm",
+       .pwrdm            = { .name = "cefuse_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_CEFUSE_INST,
+       .clkdm_offs       = AM43XX_CM_CEFUSE_CEFUSE_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mpu_43xx_clkdm = {
+       .name             = "mpu_clkdm",
+       .pwrdm            = { .name = "mpu_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_MPU_INST,
+       .clkdm_offs       = AM43XX_CM_MPU_MPU_CDOFFS,
+       .flags            = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4ls_43xx_clkdm = {
+       .name             = "l4ls_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_L4LS_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain tamper_43xx_clkdm = {
+       .name             = "tamper_clkdm",
+       .pwrdm            = { .name = "tamper_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_TAMPER_INST,
+       .clkdm_offs       = AM43XX_CM_TAMPER_TAMPER_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_rtc_43xx_clkdm = {
+       .name             = "l4_rtc_clkdm",
+       .pwrdm            = { .name = "rtc_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_RTC_INST,
+       .clkdm_offs       = AM43XX_CM_RTC_RTC_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain pruss_ocp_43xx_clkdm = {
+       .name             = "pruss_ocp_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_ICSS_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ocpwp_l3_43xx_clkdm = {
+       .name             = "ocpwp_l3_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_OCPWP_L3_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3s_tsc_43xx_clkdm = {
+       .name             = "l3s_tsc_clkdm",
+       .pwrdm            = { .name = "wkup_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_WKUP_INST,
+       .clkdm_offs       = AM43XX_CM_WKUP_L3S_TSC_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain dss_43xx_clkdm = {
+       .name             = "dss_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_DSS_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3_aon_43xx_clkdm = {
+       .name             = "l3_aon_clkdm",
+       .pwrdm            = { .name = "wkup_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_WKUP_INST,
+       .clkdm_offs       = AM43XX_CM_WKUP_L3_AON_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain emif_43xx_clkdm = {
+       .name             = "emif_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_EMIF_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_wkup_aon_43xx_clkdm = {
+       .name             = "l4_wkup_aon_clkdm",
+       .pwrdm            = { .name = "wkup_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_WKUP_INST,
+       .clkdm_offs       = AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS,
+};
+
+static struct clockdomain l3_43xx_clkdm = {
+       .name             = "l3_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_L3_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l4_wkup_43xx_clkdm = {
+       .name             = "l4_wkup_clkdm",
+       .pwrdm            = { .name = "wkup_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_WKUP_INST,
+       .clkdm_offs       = AM43XX_CM_WKUP_WKUP_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain cpsw_125mhz_43xx_clkdm = {
+       .name             = "cpsw_125mhz_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_CPSW_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain gfx_l3_43xx_clkdm = {
+       .name             = "gfx_l3_clkdm",
+       .pwrdm            = { .name = "gfx_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_GFX_INST,
+       .clkdm_offs       = AM43XX_CM_GFX_GFX_L3_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain l3s_43xx_clkdm = {
+       .name             = "l3s_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_L3S_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain *clockdomains_am43xx[] __initdata = {
+       &l4_cefuse_43xx_clkdm,
+       &mpu_43xx_clkdm,
+       &l4ls_43xx_clkdm,
+       &tamper_43xx_clkdm,
+       &l4_rtc_43xx_clkdm,
+       &pruss_ocp_43xx_clkdm,
+       &ocpwp_l3_43xx_clkdm,
+       &l3s_tsc_43xx_clkdm,
+       &dss_43xx_clkdm,
+       &l3_aon_43xx_clkdm,
+       &emif_43xx_clkdm,
+       &l4_wkup_aon_43xx_clkdm,
+       &l3_43xx_clkdm,
+       &l4_wkup_43xx_clkdm,
+       &cpsw_125mhz_43xx_clkdm,
+       &gfx_l3_43xx_clkdm,
+       &l3s_43xx_clkdm,
+       NULL
+};
+
+void __init am43xx_clockdomains_init(void)
+{
+       clkdm_register_platform_funcs(&am43xx_clkdm_operations);
+       clkdm_register_clkdms(clockdomains_am43xx);
+       clkdm_complete_init();
+}
index 6774a53a38746775385696e6ba31f719870c7885..ce25abbcffae1a7fae7bfe3bb0ee6855ec84b03e 100644 (file)
@@ -327,6 +327,73 @@ struct clkdm_ops omap2_clkdm_operations = {
        .clkdm_clk_disable      = omap2xxx_clkdm_clk_disable,
 };
 
+int omap2xxx_cm_fclks_active(void)
+{
+       u32 f1, f2;
+
+       f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+       f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+
+       return (f1 | f2) ? 1 : 0;
+}
+
+int omap2xxx_cm_mpu_retention_allowed(void)
+{
+       u32 l;
+
+       /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
+       l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+       if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK |
+                OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK |
+                OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK))
+               return 0;
+       /* Check for UART3. */
+       l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+       if (l & OMAP24XX_EN_UART3_MASK)
+               return 0;
+
+       return 1;
+}
+
+u32 omap2xxx_cm_get_core_clk_src(void)
+{
+       u32 v;
+
+       v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+       v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+       return v;
+}
+
+u32 omap2xxx_cm_get_core_pll_config(void)
+{
+       return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+}
+
+u32 omap2xxx_cm_get_pll_config(void)
+{
+       return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+}
+
+u32 omap2xxx_cm_get_pll_status(void)
+{
+       return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+}
+
+void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm)
+{
+       u32 tmp;
+
+       omap2_cm_write_mod_reg(mpu, MPU_MOD, CM_CLKSEL);
+       omap2_cm_write_mod_reg(dsp, OMAP24XX_DSP_MOD, CM_CLKSEL);
+       omap2_cm_write_mod_reg(gfx, GFX_MOD, CM_CLKSEL);
+       tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) &
+               OMAP24XX_CLKSEL_DSS2_MASK;
+       omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1);
+       if (cpu_is_omap2430())
+               omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL);
+}
+
 /*
  *
  */
index 4cbb39b051d295edc76b335425c9c3eba870007d..891d81c3c8f4b6bf7f50ff0a325298e54ed4c3ad 100644 (file)
@@ -62,6 +62,14 @@ extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
                                         u8 idlest_shift);
 extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
                                        s16 *prcm_inst, u8 *idlest_reg_id);
+extern int omap2xxx_cm_fclks_active(void);
+extern int omap2xxx_cm_mpu_retention_allowed(void);
+extern u32 omap2xxx_cm_get_core_clk_src(void);
+extern u32 omap2xxx_cm_get_core_pll_config(void);
+extern u32 omap2xxx_cm_get_pll_config(void);
+extern u32 omap2xxx_cm_get_pll_status(void);
+extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core,
+                                        u32 mdm);
 
 extern int __init omap2xxx_cm_init(void);
 
index 325a515765766c1757c5fd858e9bd8b3c226f44e..40a22e5649aeadb2d49ce1528b0e239894f5b8a9 100644 (file)
 /* Private functions */
 
 /* Read a register in a CM instance */
-static inline u32 am33xx_cm_read_reg(s16 inst, u16 idx)
+static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx)
 {
        return __raw_readl(cm_base + inst + idx);
 }
 
 /* Write into a register in a CM */
-static inline void am33xx_cm_write_reg(u32 val, s16 inst, u16 idx)
+static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx)
 {
        __raw_writel(val, cm_base + inst + idx);
 }
@@ -138,7 +138,7 @@ static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs)
  * @c must be the unshifted value for CLKTRCTRL - i.e., this function
  * will handle the shift itself.
  */
-static void _clktrctrl_write(u8 c, s16 inst, u16 cdoffs)
+static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs)
 {
        u32 v;
 
@@ -158,7 +158,7 @@ static void _clktrctrl_write(u8 c, s16 inst, u16 cdoffs)
  * Returns true if the clockdomain referred to by (@inst, @cdoffs)
  * is in hardware-supervised idle mode, or 0 otherwise.
  */
-bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs)
+bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs)
 {
        u32 v;
 
@@ -177,7 +177,7 @@ bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs)
  * Put a clockdomain referred to by (@inst, @cdoffs) into
  * hardware-supervised idle mode.  No return value.
  */
-void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs)
+void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs);
 }
@@ -191,7 +191,7 @@ void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs)
  * software-supervised idle mode, i.e., controlled manually by the
  * Linux OMAP clockdomain code.  No return value.
  */
-void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs)
+void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs);
 }
@@ -204,7 +204,7 @@ void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs)
  * Put a clockdomain referred to by (@inst, @cdoffs) into idle
  * No return value.
  */
-void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs)
+void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs);
 }
@@ -217,7 +217,7 @@ void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs)
  * Take a clockdomain referred to by (@inst, @cdoffs) out of idle,
  * waking it up.  No return value.
  */
-void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs)
+void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs);
 }
index 9d1f4fcdebbb436010fdf834b1003dfb5e347f51..cfb8891b0c0ec9ed5cac6cf8e8dc5bdb58377cb3 100644 (file)
 
 
 #ifndef __ASSEMBLER__
-extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs);
-extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs);
-extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs);
-extern void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs);
-extern void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs);
+bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs);
+void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs);
+void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs);
+void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs);
+void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs);
 
-#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
+#ifdef CONFIG_SOC_AM33XX
 extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs,
                                        u16 clkctrl_offs);
 extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs,
index 9061c307d915370f97d1969bace4220df5892a45..f6f028867bfe175f70cb6864e62bbf471125ec4f 100644 (file)
@@ -636,6 +636,28 @@ void omap3_cm_restore_context(void)
                               OMAP3_CM_CLKOUT_CTRL_OFFSET);
 }
 
+void omap3_cm_save_scratchpad_contents(u32 *ptr)
+{
+       *ptr++ = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
+       *ptr++ = omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
+       *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+       /*
+        * As per erratum i671, ROM code does not respect the PER DPLL
+        * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
+        * Then,  in anycase, clear these bits to avoid extra latencies.
+        */
+       *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
+               ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
+       *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
+       *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
+       *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
+       *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
+       *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+       *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
+       *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
+}
+
 /*
  *
  */
index e8e146f4a43f44c3723fe91872a40f9a2fe4dbb9..8224c91b4d7a849fa436d06cbff33613f695a2fc 100644 (file)
@@ -83,6 +83,7 @@ extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
 
 extern void omap3_cm_save_context(void);
 extern void omap3_cm_restore_context(void);
+extern void omap3_cm_save_scratchpad_contents(u32 *ptr);
 
 extern int __init omap3xxx_cm_init(void);
 
index f0290f5566fe0115cfc2bdf8476c85f84d000b3f..731ca134348c34906c2e8dc58e5f982aca04f1b5 100644 (file)
@@ -111,7 +111,7 @@ static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
 /* Public functions */
 
 /* Read a register in a CM instance */
-u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
+u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx)
 {
        BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
               part == OMAP4430_INVALID_PRCM_PARTITION ||
@@ -120,7 +120,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
 }
 
 /* Write into a register in a CM instance */
-void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
+void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx)
 {
        BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
               part == OMAP4430_INVALID_PRCM_PARTITION ||
@@ -129,7 +129,7 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
 }
 
 /* Read-modify-write a register in CM1. Caller must lock */
-u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
+u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst,
                                   s16 idx)
 {
        u32 v;
@@ -142,12 +142,12 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
        return v;
 }
 
-u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx)
+u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx)
 {
        return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx);
 }
 
-u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx)
+u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx)
 {
        return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx);
 }
@@ -177,7 +177,7 @@ u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask)
  * @c must be the unshifted value for CLKTRCTRL - i.e., this function
  * will handle the shift itself.
  */
-static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs)
+static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs)
 {
        u32 v;
 
@@ -196,7 +196,7 @@ static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs)
  * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs)
  * is in hardware-supervised idle mode, or 0 otherwise.
  */
-bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs)
+bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs)
 {
        u32 v;
 
@@ -216,7 +216,7 @@ bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs)
  * Put a clockdomain referred to by (@part, @inst, @cdoffs) into
  * hardware-supervised idle mode.  No return value.
  */
-void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs)
+void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs);
 }
@@ -231,7 +231,7 @@ void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs)
  * software-supervised idle mode, i.e., controlled manually by the
  * Linux OMAP clockdomain code.  No return value.
  */
-void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
+void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs);
 }
@@ -245,7 +245,7 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
  * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle,
  * waking it up.  No return value.
  */
-void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
+void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs)
 {
        _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs);
 }
@@ -483,3 +483,12 @@ struct clkdm_ops omap4_clkdm_operations = {
        .clkdm_clk_enable       = omap4_clkdm_clk_enable,
        .clkdm_clk_disable      = omap4_clkdm_clk_disable,
 };
+
+struct clkdm_ops am43xx_clkdm_operations = {
+       .clkdm_sleep            = omap4_clkdm_sleep,
+       .clkdm_wakeup           = omap4_clkdm_wakeup,
+       .clkdm_allow_idle       = omap4_clkdm_allow_idle,
+       .clkdm_deny_idle        = omap4_clkdm_deny_idle,
+       .clkdm_clk_enable       = omap4_clkdm_clk_enable,
+       .clkdm_clk_disable      = omap4_clkdm_clk_disable,
+};
index bd7bab889745f82ded937256ec6aff76ee7e9e26..7f56ea444bc46c89bf23f3c6fa0251b1e82477a3 100644 (file)
 #ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
 #define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
 
-extern bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs);
-extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs);
-extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
-extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
-extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);
+bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs);
+void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs);
+void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs);
+void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs);
+void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs);
 extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
 extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs,
                                         u16 clkctrl_offs);
@@ -27,14 +27,14 @@ extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
  * In an ideal world, we would not export these low-level functions,
  * but this will probably take some time to fix properly
  */
-extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx);
-extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
-extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
-                                          s16 inst, s16 idx);
-extern u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst,
-                                          s16 idx);
-extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
-                                          s16 idx);
+u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx);
+void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx);
+u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
+                                  u16 inst, s16 idx);
+u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst,
+                                  s16 idx);
+u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst,
+                                    s16 idx);
 extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
                                           u32 mask);
 
index 4a5684b96492099c18a010aef105ea5507860258..f7644febee81d7d41ae2cfc01e1fc362b972de02 100644 (file)
@@ -98,6 +98,7 @@ void am35xx_init_early(void);
 void ti81xx_init_early(void);
 void am33xx_init_early(void);
 void am43xx_init_early(void);
+void am43xx_init_late(void);
 void omap4430_init_early(void);
 void omap5_init_early(void);
 void omap3_init_late(void);    /* Do not use this one */
@@ -109,8 +110,11 @@ void omap35xx_init_late(void);
 void omap3630_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
+void am33xx_init_late(void);
+void omap5_init_late(void);
 int omap2_common_pm_late_init(void);
 void dra7xx_init_early(void);
+void dra7xx_init_late(void);
 
 #ifdef CONFIG_SOC_BUS
 void omap_soc_device_init(void);
@@ -288,6 +292,9 @@ static inline void omap4_cpu_resume(void)
 
 #endif
 
+void pdata_quirks_init(struct of_device_id *);
+void omap_pcs_legacy_init(int irq, void (*rearm)(void));
+
 struct omap_sdrc_params;
 extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
                                      struct omap_sdrc_params *sdrc_cs1);
index 31e0dfe4a4ea6f00a5db24191e7e701d9025c54c..44bb4d544dcf5ceb4463d554b345c3b58f9f7ade 100644 (file)
@@ -46,17 +46,7 @@ struct omap3_scratchpad {
 struct omap3_scratchpad_prcm_block {
        u32 prm_clksrc_ctrl;
        u32 prm_clksel;
-       u32 cm_clksel_core;
-       u32 cm_clksel_wkup;
-       u32 cm_clken_pll;
-       u32 cm_autoidle_pll;
-       u32 cm_clksel1_pll;
-       u32 cm_clksel2_pll;
-       u32 cm_clksel3_pll;
-       u32 cm_clken_pll_mpu;
-       u32 cm_autoidle_pll_mpu;
-       u32 cm_clksel1_pll_mpu;
-       u32 cm_clksel2_pll_mpu;
+       u32 cm_contents[11];
        u32 prcm_block_size;
 };
 
@@ -347,34 +337,9 @@ void omap3_save_scratchpad_contents(void)
        prcm_block_contents.prm_clksel =
                omap2_prm_read_mod_reg(OMAP3430_CCR_MOD,
                                       OMAP3_PRM_CLKSEL_OFFSET);
-       prcm_block_contents.cm_clksel_core =
-                       omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
-       prcm_block_contents.cm_clksel_wkup =
-                       omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
-       prcm_block_contents.cm_clken_pll =
-                       omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-       /*
-        * As per erratum i671, ROM code does not respect the PER DPLL
-        * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
-        * Then,  in anycase, clear these bits to avoid extra latencies.
-        */
-       prcm_block_contents.cm_autoidle_pll =
-                       omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
-                       ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
-       prcm_block_contents.cm_clksel1_pll =
-                       omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
-       prcm_block_contents.cm_clksel2_pll =
-                       omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
-       prcm_block_contents.cm_clksel3_pll =
-                       omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
-       prcm_block_contents.cm_clken_pll_mpu =
-                       omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
-       prcm_block_contents.cm_autoidle_pll_mpu =
-                       omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
-       prcm_block_contents.cm_clksel1_pll_mpu =
-                       omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
-       prcm_block_contents.cm_clksel2_pll_mpu =
-                       omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
+
+       omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents);
+
        prcm_block_contents.prcm_block_size = 0x0;
 
        /* Populate the SDRC block contents */
@@ -604,4 +569,15 @@ int omap3_ctrl_save_padconf(void)
        return 0;
 }
 
+/**
+ * omap3_ctrl_set_iva_bootmode_idle - sets the IVA2 bootmode to idle
+ *
+ * Sets the bootmode for IVA2 to idle. This is needed by the PM code to
+ * force disable IVA2 so that it does not prevent any low-power states.
+ */
+void omap3_ctrl_set_iva_bootmode_idle(void)
+{
+       omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
+                        OMAP343X_CONTROL_IVA2_BOOTMOD);
+}
 #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
index f7d7c2ef1b40f252c72f8ecdd87511168190d273..da054801b114d9baf0c9b9b2113622a1071ead43 100644 (file)
@@ -427,6 +427,7 @@ extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr);
 extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
 extern void omap3630_ctrl_disable_rta(void);
 extern int omap3_ctrl_save_padconf(void);
+extern void omap3_ctrl_set_iva_bootmode_idle(void);
 extern void omap2_set_globals_control(void __iomem *ctrl,
                                      void __iomem *ctrl_pad);
 #else
index 5c5315ba129b705b4af0c6b9f8af38e217e922cd..0dd6398bade4787510c4d5c62210b7a61cfb7595 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/of.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/omap4-keypad.h>
-#include <linux/wl12xx.h>
 #include <linux/platform_data/mailbox-omap.h>
 
 #include <asm/mach-types.h>
@@ -37,6 +36,7 @@
 #include "mux.h"
 #include "control.h"
 #include "devices.h"
+#include "display.h"
 
 #define L3_MODULES_MAX_LEN 12
 #define L3_MODULES 3
@@ -466,47 +466,13 @@ static struct platform_device omap_vout_device = {
        .resource       = &omap_vout_resource[0],
        .id             = -1,
 };
-static void omap_init_vout(void)
-{
-       if (platform_device_register(&omap_vout_device) < 0)
-               printk(KERN_ERR "Unable to register OMAP-VOUT device\n");
-}
-#else
-static inline void omap_init_vout(void) {}
-#endif
-
-#if IS_ENABLED(CONFIG_WL12XX)
 
-static struct wl12xx_platform_data wl12xx __initdata;
-
-void __init omap_init_wl12xx_of(void)
+int __init omap_init_vout(void)
 {
-       int ret;
-
-       if (!of_have_populated_dt())
-               return;
-
-       if (of_machine_is_compatible("ti,omap4-sdp")) {
-               wl12xx.board_ref_clock = WL12XX_REFCLOCK_26;
-               wl12xx.board_tcxo_clock = WL12XX_TCXOCLOCK_26;
-               wl12xx.irq = gpio_to_irq(53);
-       } else if (of_machine_is_compatible("ti,omap4-panda")) {
-               wl12xx.board_ref_clock = WL12XX_REFCLOCK_38;
-               wl12xx.irq = gpio_to_irq(53);
-       } else {
-               return;
-       }
-
-       ret = wl12xx_set_platform_data(&wl12xx);
-       if (ret) {
-               pr_err("error setting wl12xx data: %d\n", ret);
-               return;
-       }
+       return platform_device_register(&omap_vout_device);
 }
 #else
-static inline void omap_init_wl12xx_of(void)
-{
-}
+int __init omap_init_vout(void) { return 0; }
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -531,12 +497,8 @@ static int __init omap2_init_devices(void)
                omap_init_sham();
                omap_init_aes();
                omap_init_rng();
-       } else {
-               /* These can be removed when bindings are done */
-               omap_init_wl12xx_of();
        }
        omap_init_sti();
-       omap_init_vout();
 
        return 0;
 }
index 03a0516c7f678294d1f7a261901a61550c0f012a..a4e536b11ec9a997d8e640ff44745e6759c031fa 100644 (file)
@@ -416,6 +416,34 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
                }
        }
 
+       /* create DRM device */
+       r = omap_init_drm();
+       if (r < 0) {
+               pr_err("Unable to register omapdrm device\n");
+               return r;
+       }
+
+       /* create vrfb device */
+       r = omap_init_vrfb();
+       if (r < 0) {
+               pr_err("Unable to register omapvrfb device\n");
+               return r;
+       }
+
+       /* create FB device */
+       r = omap_init_fb();
+       if (r < 0) {
+               pr_err("Unable to register omapfb device\n");
+               return r;
+       }
+
+       /* create V4L2 display device */
+       r = omap_init_vout();
+       if (r < 0) {
+               pr_err("Unable to register omap_vout device\n");
+               return r;
+       }
+
        return 0;
 }
 
index b871b017b3522bc0bf61d9837efbf93bbdfd1111..f3d2ce4bc262350420d8ff57eb4805d2894ff87a 100644 (file)
@@ -26,4 +26,8 @@ struct omap_dss_dispc_dev_attr {
        bool    has_framedonetv_irq;
 };
 
+int omap_init_drm(void);
+int omap_init_vrfb(void);
+int omap_init_fb(void);
+int omap_init_vout(void);
 #endif
index 59a4af779f421986fc6ea097cf1f33040bdaadf7..facd7406a03d76b2643802e8fb8759c54ec729c7 100644 (file)
 #include <linux/platform_data/omap_drm.h>
 
 #include "soc.h"
-#include "omap_device.h"
-#include "omap_hwmod.h"
+#include "display.h"
 
-#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+#if defined(CONFIG_DRM_OMAP) || defined(CONFIG_DRM_OMAP_MODULE)
 
 static struct omap_drm_platform_data platform_data;
 
@@ -42,26 +41,13 @@ static struct platform_device omap_drm_device = {
        .id = 0,
 };
 
-static int __init omap_init_drm(void)
+int __init omap_init_drm(void)
 {
-       struct omap_hwmod *oh = NULL;
-       struct platform_device *pdev;
-
-       /* lookup and populate the DMM information, if present - OMAP4+ */
-       oh = omap_hwmod_lookup("dmm");
-
-       if (oh) {
-               pdev = omap_device_build(oh->name, -1, oh, NULL, 0);
-               WARN(IS_ERR(pdev), "Could not build omap_device for %s\n",
-                       oh->name);
-       }
-
        platform_data.omaprev = GET_OMAP_TYPE;
 
        return platform_device_register(&omap_drm_device);
 
 }
-
-omap_arch_initcall(omap_init_drm);
-
+#else
+int __init omap_init_drm(void) { return 0; }
 #endif
index bf89effa4c9988a45c770175307e632918790a4a..365bfd3d9c68b8486f23049a71889484c60eb793 100644 (file)
@@ -213,3 +213,47 @@ void __init omap_4430sdp_display_init_of(void)
        platform_device_register(&sdp4430_tpd_device);
        platform_device_register(&sdp4430_hdmi_connector_device);
 }
+
+
+/* OMAP3 IGEPv2 data */
+
+#define IGEP2_DVI_TFP410_POWER_DOWN_GPIO       170
+
+/* DVI Connector */
+static struct connector_dvi_platform_data omap3_igep2_dvi_connector_pdata = {
+       .name                   = "dvi",
+       .source                 = "tfp410.0",
+       .i2c_bus_num            = 3,
+};
+
+static struct platform_device omap3_igep2_dvi_connector_device = {
+       .name                   = "connector-dvi",
+       .id                     = 0,
+       .dev.platform_data      = &omap3_igep2_dvi_connector_pdata,
+};
+
+/* TFP410 DPI-to-DVI chip */
+static struct encoder_tfp410_platform_data omap3_igep2_tfp410_pdata = {
+       .name                   = "tfp410.0",
+       .source                 = "dpi.0",
+       .data_lines             = 24,
+       .power_down_gpio        = IGEP2_DVI_TFP410_POWER_DOWN_GPIO,
+};
+
+static struct platform_device omap3_igep2_tfp410_device = {
+       .name                   = "tfp410",
+       .id                     = 0,
+       .dev.platform_data      = &omap3_igep2_tfp410_pdata,
+};
+
+static struct omap_dss_board_info igep2_dss_data = {
+       .default_display_name = "dvi",
+};
+
+void __init omap3_igep2_display_init_of(void)
+{
+       omap_display_init(&igep2_dss_data);
+
+       platform_device_register(&omap3_igep2_tfp410_device);
+       platform_device_register(&omap3_igep2_dvi_connector_device);
+}
index c28fe3c035880c58ad6e749f123a01d4437024c8..a9becf0d5be84695f732f1e01a2e2215f9e5ed16 100644 (file)
@@ -8,5 +8,6 @@
 
 void __init omap4_panda_display_init_of(void);
 void __init omap_4430sdp_display_init_of(void);
+void __init omap3_igep2_display_init_of(void);
 
 #endif
index 2ca33cc0c484055a7c4f6543b9c2a1e35adeef87..26e28e94f62582d09b77134aca1ec2533b148856 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/mach/map.h>
 
 #include "soc.h"
+#include "display.h"
 
 #ifdef CONFIG_OMAP2_VRFB
 
@@ -64,7 +65,7 @@ static const struct resource omap3_vrfb_resources[] = {
        DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"),
 };
 
-static int __init omap_init_vrfb(void)
+int __init omap_init_vrfb(void)
 {
        struct platform_device *pdev;
        const struct resource *res;
@@ -85,8 +86,8 @@ static int __init omap_init_vrfb(void)
 
        return PTR_RET(pdev);
 }
-
-omap_arch_initcall(omap_init_vrfb);
+#else
+int __init omap_init_vrfb(void) { return 0; }
 #endif
 
 #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
@@ -105,11 +106,10 @@ static struct platform_device omap_fb_device = {
        .num_resources = 0,
 };
 
-static int __init omap_init_fb(void)
+int __init omap_init_fb(void)
 {
        return platform_device_register(&omap_fb_device);
 }
-
-omap_arch_initcall(omap_init_fb);
-
+#else
+int __init omap_init_fb(void) { return 0; }
 #endif
index 579697adaae7dfd373285979eebeb815658f4a1d..51525faa0aecde65beb9ff745cfc066a81bc62ad 100644 (file)
@@ -1521,6 +1521,42 @@ 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;
@@ -1564,6 +1600,8 @@ static int gpmc_probe_dt(struct platform_device *pdev)
                else if (of_node_cmp(child->name, "ethernet") == 0 ||
                         of_node_cmp(child->name, "nor") == 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 0289adcb6efb8dbc1f718a4e38a867afba414cfc..9428c5f9d4f2faa47e91a2caa193ecf39bba39fb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/random.h>
 #include <linux/slab.h>
 
 #ifdef CONFIG_SOC_BUS
@@ -130,6 +131,17 @@ void omap_get_die_id(struct omap_die_id *odi)
        odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
 }
 
+static int __init omap_feed_randpool(void)
+{
+       struct omap_die_id odi;
+
+       /* Throw the die ID into the entropy pool at boot */
+       omap_get_die_id(&odi);
+       add_device_randomness(&odi, sizeof(odi));
+       return 0;
+}
+omap_device_initcall(omap_feed_randpool);
+
 void __init omap2xxx_check_revision(void)
 {
        int i, j;
@@ -576,8 +588,8 @@ void __init omap5xxx_check_revision(void)
        case 0xb942:
                switch (rev) {
                case 0:
-                       omap_revision = OMAP5430_REV_ES1_0;
-                       break;
+                       /* No support for ES1.0 Test chip */
+                       BUG();
                case 1:
                default:
                        omap_revision = OMAP5430_REV_ES2_0;
@@ -587,8 +599,8 @@ void __init omap5xxx_check_revision(void)
        case 0xb998:
                switch (rev) {
                case 0:
-                       omap_revision = OMAP5432_REV_ES1_0;
-                       break;
+                       /* No support for ES1.0 Test chip */
+                       BUG();
                case 1:
                default:
                        omap_revision = OMAP5432_REV_ES2_0;
index ff2113ce40141ab87001c912b3924fe1803cdec3..cd22262a2cc09a1ad5b951254500a11afdfc8e30 100644 (file)
@@ -583,6 +583,11 @@ void __init am33xx_init_early(void)
        omap_hwmod_init_postsetup();
        omap_clk_init = am33xx_clk_init;
 }
+
+void __init am33xx_init_late(void)
+{
+       omap_common_late_init();
+}
 #endif
 
 #ifdef CONFIG_SOC_AM43XX
@@ -594,7 +599,18 @@ void __init am43xx_init_early(void)
                                  NULL);
        omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE));
        omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE), NULL);
+       omap_prm_base_init();
+       omap_cm_base_init();
        omap3xxx_check_revision();
+       am43xx_powerdomains_init();
+       am43xx_clockdomains_init();
+       am43xx_hwmod_init();
+       omap_hwmod_init_postsetup();
+}
+
+void __init am43xx_init_late(void)
+{
+       omap_common_late_init();
 }
 #endif
 
@@ -651,6 +667,11 @@ void __init omap5_init_early(void)
        omap54xx_hwmod_init();
        omap_hwmod_init_postsetup();
 }
+
+void __init omap5_init_late(void)
+{
+       omap_common_late_init();
+}
 #endif
 
 #ifdef CONFIG_SOC_DRA7XX
@@ -671,6 +692,11 @@ void __init dra7xx_init_early(void)
        dra7xx_hwmod_init();
        omap_hwmod_init_postsetup();
 }
+
+void __init dra7xx_init_late(void)
+{
+       omap_common_late_init();
+}
 #endif
 
 
index 3926f370448f91825fd07b4cdcaa0af09db74b2b..e022a869bff23894dd28f24274564026841e8608 100644 (file)
@@ -233,7 +233,7 @@ static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs
                        goto out;
 
                irqnr = readl_relaxed(base_addr + 0xd8);
-#ifdef CONFIG_SOC_TI81XX
+#if IS_ENABLED(CONFIG_SOC_TI81XX) || IS_ENABLED(CONFIG_SOC_AM33XX)
                if (irqnr)
                        goto out;
                irqnr = readl_relaxed(base_addr + 0xf8);
index 5d8768075dd977e4b92914c8141e9b7265588fee..b4ac3af1160c79b0ecc6c65391cbb6bab3ae6fd9 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "soc.h"
 #include "omap_device.h"
+#include "clock.h"
 
 /*
  * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
 #include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
 
+static struct clk *mcbsp_iclks[5];
+
 static int omap3_enable_st_clock(unsigned int id, bool enable)
 {
-       unsigned int w;
-
        /*
         * Sidetone uses McBSP ICLK - which must not idle when sidetones
         * are enabled or sidetones start sounding ugly.
         */
-       w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
        if (enable)
-               w &= ~(1 << (id - 2));
+               return omap2_clk_deny_idle(mcbsp_iclks[id]);
        else
-               w |= 1 << (id - 2);
-       omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
-
-       return 0;
+               return omap2_clk_allow_idle(mcbsp_iclks[id]);
 }
 
 static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
@@ -58,6 +55,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
        struct omap_hwmod *oh_device[2];
        struct omap_mcbsp_platform_data *pdata = NULL;
        struct platform_device *pdev;
+       char clk_name[11];
 
        sscanf(oh->name, "mcbsp%d", &id);
 
@@ -99,6 +97,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
                oh_device[1] = omap_hwmod_lookup((
                (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
                pdata->enable_st_clock = omap3_enable_st_clock;
+               sprintf(clk_name, "mcbsp%d_ick", id);
+               mcbsp_iclks[id] = clk_get(NULL, clk_name);
                count++;
        }
        pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
index f82cf878d6af41da87b8bb444acd609105af72a9..48094b58c88f775f592d77f8403b2a1d65cf1840 100644 (file)
@@ -811,6 +811,12 @@ int __init omap_mux_late_init(void)
                }
        }
 
+       omap_mux_dbg_init();
+
+       /* see pinctrl-single-omap for the wake-up interrupt handling */
+       if (of_have_populated_dt())
+               return 0;
+
        ret = request_irq(omap_prcm_event_to_irq("io"),
                omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
                        "hwmod_io", omap_mux_late_init);
@@ -818,8 +824,6 @@ int __init omap_mux_late_init(void)
        if (ret)
                pr_warning("mux: Failed to setup hwmod io irq %d\n", ret);
 
-       omap_mux_dbg_init();
-
        return 0;
 }
 
index b970440cffca0b5484c90dd7b6e08c7caf5b6bc2..5ac122e88f678b75d6c1060783738321d8b9c579 100644 (file)
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2011 Texas Instruments, Inc.
  *     Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
  *
  *
  * This program is free software,you can redistribute it and/or modify
@@ -70,3 +72,77 @@ phys_addr_t omap_secure_ram_mempool_base(void)
 {
        return omap_secure_memblock_base;
 }
+
+/**
+ * rx51_secure_dispatcher: Routine to dispatch secure PPA API calls
+ * @idx: The PPA API index
+ * @process: Process ID
+ * @flag: The flag indicating criticality of operation
+ * @nargs: Number of valid arguments out of four.
+ * @arg1, arg2, arg3 args4: Parameters passed to secure API
+ *
+ * Return the non-zero error value on failure.
+ *
+ * NOTE: rx51_secure_dispatcher differs from omap_secure_dispatcher because
+ *       it calling omap_smc3() instead omap_smc2() and param[0] is nargs+1
+ */
+u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
+                          u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+{
+       u32 ret;
+       u32 param[5];
+
+       param[0] = nargs+1; /* RX-51 needs number of arguments + 1 */
+       param[1] = arg1;
+       param[2] = arg2;
+       param[3] = arg3;
+       param[4] = arg4;
+
+       /*
+        * Secure API needs physical address
+        * pointer for the parameters
+        */
+       local_irq_disable();
+       local_fiq_disable();
+       flush_cache_all();
+       outer_clean_range(__pa(param), __pa(param + 5));
+       ret = omap_smc3(idx, process, flag, __pa(param));
+       flush_cache_all();
+       local_fiq_enable();
+       local_irq_enable();
+
+       return ret;
+}
+
+/**
+ * rx51_secure_update_aux_cr: Routine to modify the contents of Auxiliary Control Register
+ *  @set_bits: bits to set in ACR
+ *  @clr_bits: bits to clear in ACR
+ *
+ * Return the non-zero error value on failure.
+*/
+u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits)
+{
+       u32 acr;
+
+       /* Read ACR */
+       asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+       acr &= ~clear_bits;
+       acr |= set_bits;
+
+       return rx51_secure_dispatcher(RX51_PPA_WRITE_ACR,
+                                     0,
+                                     FLAG_START_CRITICAL,
+                                     1, acr, 0, 0, 0);
+}
+
+/**
+ * rx51_secure_rng_call: Routine for HW random generator
+ */
+u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag)
+{
+       return rx51_secure_dispatcher(RX51_PPA_HWRNG,
+                                     0,
+                                     NO_FLAG,
+                                     3, ptr, count, flag, 0);
+}
index 0e729170c46b81f2ee7a263c797853abc7d01ab3..8cc7d331437d844a3b0ba5b3d2afb844b2de5d06 100644 (file)
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2011 Texas Instruments, Inc.
  *     Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX   0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX  0x113
 
+#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX        0x109
+
 /* Secure PPA(Primary Protected Application) APIs */
 #define OMAP4_PPA_L2_POR_INDEX         0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX  0x25
 
+/* Secure RX-51 PPA (Primary Protected Application) APIs */
+#define RX51_PPA_HWRNG                 29
+#define RX51_PPA_L2_INVAL              40
+#define RX51_PPA_WRITE_ACR             42
+
 #ifndef __ASSEMBLER__
 
 extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
                                u32 arg1, u32 arg2, u32 arg3, u32 arg4);
 extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
+extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
 extern phys_addr_t omap_secure_ram_mempool_base(void);
 extern int omap_secure_ram_reserve_memblock(void);
 
+extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
+                                 u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
+extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
+
 #ifdef CONFIG_OMAP4_ERRATA_I688
 extern int omap_barrier_reserve_memblock(void);
 #else
 static inline void omap_barrier_reserve_memblock(void)
 { }
 #endif
+
+void set_cntfreq(void);
 #endif /* __ASSEMBLER__ */
 #endif /* OMAP_ARCH_OMAP_SECURE_H */
index f6441c13cd8ce35ba78fb526f2a33d1123064f91..fd90125bffc70ad6719bfc2b9f3e22d21b595367 100644 (file)
@@ -1,9 +1,11 @@
 /*
- * OMAP44xx secure APIs file.
+ * OMAP34xx and OMAP44xx secure APIs file.
  *
  * Copyright (C) 2010 Texas Instruments, Inc.
  * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
  *
+ * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg>
+ * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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
@@ -54,6 +56,23 @@ ENTRY(omap_smc2)
        ldmfd   sp!, {r4-r12, pc}
 ENDPROC(omap_smc2)
 
+/**
+ * u32 omap_smc3(u32 service_id, u32 process_id, u32 flag, u32 pargs)
+ * Low level common routine for secure HAL and PPA APIs via smc #1
+ * r0 - @service_id: Secure Service ID
+ * r1 - @process_id: Process ID
+ * r2 - @flag: Flag to indicate the criticality of operation
+ * r3 - @pargs: Physical address of parameter list
+ */
+ENTRY(omap_smc3)
+       stmfd   sp!, {r4-r11, lr}
+       mov     r12, r0         @ Copy the secure service ID
+       mov     r6, #0xff       @ Indicate new Task call
+       dsb                     @ Memory Barrier (not sure if needed, copied from omap_smc2)
+       smc     #1              @ Call PPA service
+       ldmfd   sp!, {r4-r11, pc}
+ENDPROC(omap_smc3)
+
 ENTRY(omap_modify_auxcoreboot0)
        stmfd   sp!, {r1-r12, lr}
        ldr     r12, =0x104
index 89121109329533b917561f4da6ce4b335872f4c4..75e95d4fb448cdc3747323576e1c3ea800a3886e 100644 (file)
@@ -65,6 +65,13 @@ static void omap4_secondary_init(unsigned int cpu)
                omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
                                                        4, 0, 0, 0, 0, 0);
 
+       /*
+        * Configure the CNTFRQ register for the secondary cpu's which
+        * indicates the frequency of the cpu local timers.
+        */
+       if (soc_is_omap54xx() || soc_is_dra7xx())
+               set_cntfreq();
+
        /*
         * Synchronise with the boot thread.
         */
index 813c61558a5fcc70dfafea59a2a7d14c5b893c10..3664562f91481e76487ff77ef8e133ccd7edfaab 100644 (file)
 #include "omap4-sar-layout.h"
 #include "common.h"
 
-#define MAX_NR_REG_BANKS       5
-#define MAX_IRQS               160
+#define AM43XX_NR_REG_BANKS    7
+#define AM43XX_IRQS            224
+#define MAX_NR_REG_BANKS       AM43XX_NR_REG_BANKS
+#define MAX_IRQS               AM43XX_IRQS
+#define DEFAULT_NR_REG_BANKS   5
+#define DEFAULT_IRQS           160
 #define WKG_MASK_ALL           0x00000000
 #define WKG_UNMASK_ALL         0xffffffff
 #define CPU_ENA_OFFSET         0x400
@@ -47,8 +51,8 @@ static void __iomem *wakeupgen_base;
 static void __iomem *sar_base;
 static DEFINE_RAW_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[MAX_IRQS];
-static unsigned int irq_banks = MAX_NR_REG_BANKS;
-static unsigned int max_irqs = MAX_IRQS;
+static unsigned int irq_banks = DEFAULT_NR_REG_BANKS;
+static unsigned int max_irqs = DEFAULT_IRQS;
 static unsigned int omap_secure_apis;
 
 /*
@@ -418,12 +422,16 @@ int __init omap_wakeupgen_init(void)
                irq_banks = OMAP4_NR_BANKS;
                max_irqs = OMAP4_NR_IRQS;
                omap_secure_apis = 1;
+       } else if (soc_is_am43xx()) {
+               irq_banks = AM43XX_NR_REG_BANKS;
+               max_irqs = AM43XX_IRQS;
        }
 
        /* Clear all IRQ bitmasks at wakeupGen level */
        for (i = 0; i < irq_banks; i++) {
                wakeupgen_writel(0, i, CPU0_ID);
-               wakeupgen_writel(0, i, CPU1_ID);
+               if (!soc_is_am43xx())
+                       wakeupgen_writel(0, i, CPU1_ID);
        }
 
        /*
index d9ee0ff094d4bcfdd395131601664be618367073..e3f0ecaf87dd76c3b075c389173ac89faff04a6a 100644 (file)
@@ -2357,25 +2357,29 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
 /**
  * _init_mpu_rt_base - populate the virtual address for a hwmod
  * @oh: struct omap_hwmod * to locate the virtual address
+ * @data: (unused, caller should pass NULL)
+ * @np: struct device_node * of the IP block's device node in the DT data
  *
  * Cache the virtual address used by the MPU to access this IP block's
  * registers.  This address is needed early so the OCP registers that
  * are part of the device's address space can be ioremapped properly.
- * No return value.
+ *
+ * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and
+ * -ENXIO on absent or invalid register target address space.
  */
-static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
+static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
+                                   struct device_node *np)
 {
        struct omap_hwmod_addr_space *mem;
        void __iomem *va_start = NULL;
-       struct device_node *np;
 
        if (!oh)
-               return;
+               return -EINVAL;
 
        _save_mpu_port_index(oh);
 
        if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
-               return;
+               return -ENXIO;
 
        mem = _find_mpu_rt_addr_space(oh);
        if (!mem) {
@@ -2383,25 +2387,24 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
                         oh->name);
 
                /* Extract the IO space from device tree blob */
-               if (!of_have_populated_dt())
-                       return;
+               if (!np)
+                       return -ENXIO;
 
-               np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
-               if (np)
-                       va_start = of_iomap(np, oh->mpu_rt_idx);
+               va_start = of_iomap(np, oh->mpu_rt_idx);
        } else {
                va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        }
 
        if (!va_start) {
                pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
-               return;
+               return -ENXIO;
        }
 
        pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
                 oh->name, va_start);
 
        oh->_mpu_rt_va = va_start;
+       return 0;
 }
 
 /**
@@ -2414,18 +2417,28 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
  * registered at this point.  This is the first of two phases for
  * hwmod initialization.  Code called here does not touch any hardware
  * registers, it simply prepares internal data structures.  Returns 0
- * upon success or if the hwmod isn't registered, or -EINVAL upon
- * failure.
+ * upon success or if the hwmod isn't registered or if the hwmod's
+ * address space is not defined, or -EINVAL upon failure.
  */
 static int __init _init(struct omap_hwmod *oh, void *data)
 {
        int r;
+       struct device_node *np = NULL;
 
        if (oh->_state != _HWMOD_STATE_REGISTERED)
                return 0;
 
-       if (oh->class->sysc)
-               _init_mpu_rt_base(oh, NULL);
+       if (of_have_populated_dt())
+               np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
+
+       if (oh->class->sysc) {
+               r = _init_mpu_rt_base(oh, NULL, np);
+               if (r < 0) {
+                       WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
+                            oh->name);
+                       return 0;
+               }
+       }
 
        r = _init_clocks(oh, NULL);
        if (r < 0) {
@@ -2433,6 +2446,12 @@ static int __init _init(struct omap_hwmod *oh, void *data)
                return -EINVAL;
        }
 
+       if (np)
+               if (of_find_property(np, "ti,no-reset-on-init", NULL))
+                       oh->flags |= HWMOD_INIT_NO_RESET;
+               if (of_find_property(np, "ti,no-idle-on-init", NULL))
+                       oh->flags |= HWMOD_INIT_NO_IDLE;
+
        oh->_state = _HWMOD_STATE_INITIALIZED;
 
        return 0;
@@ -4125,6 +4144,14 @@ void __init omap_hwmod_init(void)
                soc_ops.init_clkdm = _init_clkdm;
                soc_ops.update_context_lost = _omap4_update_context_lost;
                soc_ops.get_context_lost = _omap4_get_context_lost;
+       } else if (soc_is_am43xx()) {
+               soc_ops.enable_module = _omap4_enable_module;
+               soc_ops.disable_module = _omap4_disable_module;
+               soc_ops.wait_target_ready = _omap4_wait_target_ready;
+               soc_ops.assert_hardreset = _omap4_assert_hardreset;
+               soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
+               soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
+               soc_ops.init_clkdm = _init_clkdm;
        } else if (soc_is_am33xx()) {
                soc_ops.enable_module = _am33xx_enable_module;
                soc_ops.disable_module = _am33xx_disable_module;
index d02acf9308d3acc7deb06a42a830323774097572..0f97d635ff90db413b27168fefeecf039a934159 100644 (file)
@@ -752,6 +752,7 @@ extern int omap44xx_hwmod_init(void);
 extern int omap54xx_hwmod_init(void);
 extern int am33xx_hwmod_init(void);
 extern int dra7xx_hwmod_init(void);
+int am43xx_hwmod_init(void);
 
 extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois);
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
new file mode 100644 (file)
index 0000000..130332c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Data common for AM335x and AM43x
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H
+
+extern struct omap_hwmod_ocp_if am33xx_mpu__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_s;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr;
+extern struct omap_hwmod_ocp_if am33xx_mpu__prcm;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_pruss__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx;
+extern struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan0;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan1;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio1;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio2;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio3;
+extern struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0;
+extern struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0;
+extern struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0;
+extern struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1;
+extern struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1;
+extern struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1;
+extern struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2;
+extern struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2;
+extern struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2;
+extern struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c2;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c3;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__mailbox;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1;
+extern struct omap_hwmod_ocp_if am33xx_l3_s__mmc2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer3;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer4;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer5;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer6;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer7;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tpcc;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc0;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc1;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart2;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart3;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart4;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart5;
+extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart6;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0;
+extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0;
+
+extern struct omap_hwmod am33xx_l3_main_hwmod;
+extern struct omap_hwmod am33xx_l3_s_hwmod;
+extern struct omap_hwmod am33xx_l3_instr_hwmod;
+extern struct omap_hwmod am33xx_l4_ls_hwmod;
+extern struct omap_hwmod am33xx_l4_wkup_hwmod;
+extern struct omap_hwmod am33xx_mpu_hwmod;
+extern struct omap_hwmod am33xx_pruss_hwmod;
+extern struct omap_hwmod am33xx_gfx_hwmod;
+extern struct omap_hwmod am33xx_prcm_hwmod;
+extern struct omap_hwmod am33xx_aes0_hwmod;
+extern struct omap_hwmod am33xx_sha0_hwmod;
+extern struct omap_hwmod am33xx_ocmcram_hwmod;
+extern struct omap_hwmod am33xx_smartreflex0_hwmod;
+extern struct omap_hwmod am33xx_smartreflex1_hwmod;
+extern struct omap_hwmod am33xx_cpgmac0_hwmod;
+extern struct omap_hwmod am33xx_mdio_hwmod;
+extern struct omap_hwmod am33xx_dcan0_hwmod;
+extern struct omap_hwmod am33xx_dcan1_hwmod;
+extern struct omap_hwmod am33xx_elm_hwmod;
+extern struct omap_hwmod am33xx_epwmss0_hwmod;
+extern struct omap_hwmod am33xx_ecap0_hwmod;
+extern struct omap_hwmod am33xx_eqep0_hwmod;
+extern struct omap_hwmod am33xx_ehrpwm0_hwmod;
+extern struct omap_hwmod am33xx_epwmss1_hwmod;
+extern struct omap_hwmod am33xx_ecap1_hwmod;
+extern struct omap_hwmod am33xx_eqep1_hwmod;
+extern struct omap_hwmod am33xx_ehrpwm1_hwmod;
+extern struct omap_hwmod am33xx_epwmss2_hwmod;
+extern struct omap_hwmod am33xx_ecap2_hwmod;
+extern struct omap_hwmod am33xx_eqep2_hwmod;
+extern struct omap_hwmod am33xx_ehrpwm2_hwmod;
+extern struct omap_hwmod am33xx_gpio1_hwmod;
+extern struct omap_hwmod am33xx_gpio2_hwmod;
+extern struct omap_hwmod am33xx_gpio3_hwmod;
+extern struct omap_hwmod am33xx_gpmc_hwmod;
+extern struct omap_hwmod am33xx_i2c1_hwmod;
+extern struct omap_hwmod am33xx_i2c2_hwmod;
+extern struct omap_hwmod am33xx_i2c3_hwmod;
+extern struct omap_hwmod am33xx_mailbox_hwmod;
+extern struct omap_hwmod am33xx_mcasp0_hwmod;
+extern struct omap_hwmod am33xx_mcasp1_hwmod;
+extern struct omap_hwmod am33xx_mmc0_hwmod;
+extern struct omap_hwmod am33xx_mmc1_hwmod;
+extern struct omap_hwmod am33xx_mmc2_hwmod;
+extern struct omap_hwmod am33xx_rtc_hwmod;
+extern struct omap_hwmod am33xx_spi0_hwmod;
+extern struct omap_hwmod am33xx_spi1_hwmod;
+extern struct omap_hwmod am33xx_spinlock_hwmod;
+extern struct omap_hwmod am33xx_timer1_hwmod;
+extern struct omap_hwmod am33xx_timer2_hwmod;
+extern struct omap_hwmod am33xx_timer3_hwmod;
+extern struct omap_hwmod am33xx_timer4_hwmod;
+extern struct omap_hwmod am33xx_timer5_hwmod;
+extern struct omap_hwmod am33xx_timer6_hwmod;
+extern struct omap_hwmod am33xx_timer7_hwmod;
+extern struct omap_hwmod am33xx_tpcc_hwmod;
+extern struct omap_hwmod am33xx_tptc0_hwmod;
+extern struct omap_hwmod am33xx_tptc1_hwmod;
+extern struct omap_hwmod am33xx_tptc2_hwmod;
+extern struct omap_hwmod am33xx_uart1_hwmod;
+extern struct omap_hwmod am33xx_uart2_hwmod;
+extern struct omap_hwmod am33xx_uart3_hwmod;
+extern struct omap_hwmod am33xx_uart4_hwmod;
+extern struct omap_hwmod am33xx_uart5_hwmod;
+extern struct omap_hwmod am33xx_uart6_hwmod;
+extern struct omap_hwmod am33xx_wd_timer1_hwmod;
+
+extern struct omap_hwmod_class am33xx_l4_hwmod_class;
+extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class;
+extern struct omap_hwmod_class am33xx_control_hwmod_class;
+extern struct omap_hwmod_class am33xx_gpio_hwmod_class;
+extern struct omap_hwmod_class am33xx_timer_hwmod_class;
+extern struct omap_hwmod_class am33xx_epwmss_hwmod_class;
+extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class;
+extern struct omap_hwmod_class am33xx_spi_hwmod_class;
+
+extern struct omap_gpio_dev_attr gpio_dev_attr;
+extern struct omap2_mcspi_dev_attr mcspi_attrib;
+
+void omap_hwmod_am33xx_reg(void);
+void omap_hwmod_am43xx_reg(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
new file mode 100644 (file)
index 0000000..e2db378
--- /dev/null
@@ -0,0 +1,643 @@
+/*
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Interconnects common for AM335x and AM43x
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/sizes.h>
+#include "omap_hwmod.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+
+/* mpu -> l3 main */
+struct omap_hwmod_ocp_if am33xx_mpu__l3_main = {
+       .master         = &am33xx_mpu_hwmod,
+       .slave          = &am33xx_l3_main_hwmod,
+       .clk            = "dpll_mpu_m2_ck",
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 main -> l3 s */
+struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_l3_s_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 s -> l4 per/ls */
+struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am33xx_l4_ls_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 s -> l4 wkup */
+struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am33xx_l4_wkup_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> l3 instr */
+struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_l3_instr_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> prcm */
+struct omap_hwmod_ocp_if am33xx_mpu__prcm = {
+       .master         = &am33xx_mpu_hwmod,
+       .slave          = &am33xx_prcm_hwmod,
+       .clk            = "dpll_mpu_m2_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 s -> l3 main*/
+struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am33xx_l3_main_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* pru-icss -> l3 main */
+struct omap_hwmod_ocp_if am33xx_pruss__l3_main = {
+       .master         = &am33xx_pruss_hwmod,
+       .slave          = &am33xx_l3_main_hwmod,
+       .clk            = "l3_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gfx -> l3 main */
+struct omap_hwmod_ocp_if am33xx_gfx__l3_main = {
+       .master         = &am33xx_gfx_hwmod,
+       .slave          = &am33xx_l3_main_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> gfx */
+struct omap_hwmod_ocp_if am33xx_l3_main__gfx = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_gfx_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 wkup -> rtc */
+struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_rtc_hwmod,
+       .clk            = "clkdiv32k_ick",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per/ls -> DCAN0 */
+struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_dcan0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> DCAN1 */
+struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_dcan1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> GPIO2 */
+struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_gpio1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> gpio3 */
+struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_gpio2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 per/ls -> gpio4 */
+struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_gpio3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = {
+       .master         = &am33xx_cpgmac0_hwmod,
+       .slave          = &am33xx_mdio_hwmod,
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = {
+       {
+               .pa_start       = 0x48080000,
+               .pa_end         = 0x48080000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__elm = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_elm_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_elm_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = {
+       {
+               .pa_start       = 0x48300000,
+               .pa_end         = 0x48300000 + SZ_16 - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_epwmss0_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_epwmss0_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
+       .master         = &am33xx_epwmss0_hwmod,
+       .slave          = &am33xx_ecap0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
+       .master         = &am33xx_epwmss0_hwmod,
+       .slave          = &am33xx_eqep0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
+       .master         = &am33xx_epwmss0_hwmod,
+       .slave          = &am33xx_ehrpwm0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+
+static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = {
+       {
+               .pa_start       = 0x48302000,
+               .pa_end         = 0x48302000 + SZ_16 - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_epwmss1_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_epwmss1_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
+       .master         = &am33xx_epwmss1_hwmod,
+       .slave          = &am33xx_ecap1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
+       .master         = &am33xx_epwmss1_hwmod,
+       .slave          = &am33xx_eqep1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
+       .master         = &am33xx_epwmss1_hwmod,
+       .slave          = &am33xx_ehrpwm1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = {
+       {
+               .pa_start       = 0x48304000,
+               .pa_end         = 0x48304000 + SZ_16 - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_epwmss2_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_epwmss2_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
+       .master         = &am33xx_epwmss2_hwmod,
+       .slave          = &am33xx_ecap2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
+       .master         = &am33xx_epwmss2_hwmod,
+       .slave          = &am33xx_eqep2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
+       .master         = &am33xx_epwmss2_hwmod,
+       .slave          = &am33xx_ehrpwm2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l3s cfg -> gpmc */
+static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = {
+       {
+               .pa_start       = 0x50000000,
+               .pa_end         = 0x50000000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am33xx_gpmc_hwmod,
+       .clk            = "l3s_gclk",
+       .addr           = am33xx_gpmc_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* i2c2 */
+struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_i2c2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_i2c3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_mailbox_addrs[] = {
+       {
+               .pa_start       = 0x480C8000,
+               .pa_end         = 0x480C8000 + (SZ_4K - 1),
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+/* l4 ls -> mailbox */
+struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_mailbox_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_mailbox_addrs,
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> spinlock */
+struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_spinlock_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcasp0 */
+static struct omap_hwmod_addr_space am33xx_mcasp0_addr_space[] = {
+       {
+               .pa_start       = 0x48038000,
+               .pa_end         = 0x48038000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_mcasp0_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_mcasp0_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcasp1 */
+static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = {
+       {
+               .pa_start       = 0x4803C000,
+               .pa_end         = 0x4803C000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_mcasp1_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_mcasp1_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> mmc0 */
+static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = {
+       {
+               .pa_start       = 0x48060100,
+               .pa_end         = 0x48060100 + SZ_4K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_mmc0_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_mmc0_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> mmc1 */
+static struct omap_hwmod_addr_space am33xx_mmc1_addr_space[] = {
+       {
+               .pa_start       = 0x481d8100,
+               .pa_end         = 0x481d8100 + SZ_4K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_mmc1_hwmod,
+       .clk            = "l4ls_gclk",
+       .addr           = am33xx_mmc1_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 s -> mmc2 */
+static struct omap_hwmod_addr_space am33xx_mmc2_addr_space[] = {
+       {
+               .pa_start       = 0x47810100,
+               .pa_end         = 0x47810100 + SZ_64K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_s__mmc2 = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am33xx_mmc2_hwmod,
+       .clk            = "l3s_gclk",
+       .addr           = am33xx_mmc2_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcspi0 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_spi0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> mcspi1 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_spi1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per -> timer2 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_timer2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per -> timer3 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_timer3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per -> timer4 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_timer4_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per -> timer5 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_timer5_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per -> timer6 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_timer6_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 per -> timer7 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_timer7_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc */
+struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_tpcc_hwmod,
+       .clk            = "l3_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc0 */
+static struct omap_hwmod_addr_space am33xx_tptc0_addr_space[] = {
+       {
+               .pa_start       = 0x49800000,
+               .pa_end         = 0x49800000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_tptc0_hwmod,
+       .clk            = "l3_gclk",
+       .addr           = am33xx_tptc0_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc1 */
+static struct omap_hwmod_addr_space am33xx_tptc1_addr_space[] = {
+       {
+               .pa_start       = 0x49900000,
+               .pa_end         = 0x49900000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_tptc1_hwmod,
+       .clk            = "l3_gclk",
+       .addr           = am33xx_tptc1_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 main -> tpcc2 */
+static struct omap_hwmod_addr_space am33xx_tptc2_addr_space[] = {
+       {
+               .pa_start       = 0x49a00000,
+               .pa_end         = 0x49a00000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT,
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_tptc2_hwmod,
+       .clk            = "l3_gclk",
+       .addr           = am33xx_tptc2_addr_space,
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart2 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_uart2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart3 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_uart3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart4 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_uart4_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart5 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_uart5_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l4 ls -> uart6 */
+struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_uart6_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+/* l3 main -> ocmc */
+struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_ocmcram_hwmod,
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> sha0 HIB2 */
+static struct omap_hwmod_addr_space am33xx_sha0_addrs[] = {
+       {
+               .pa_start       = 0x53100000,
+               .pa_end         = 0x53100000 + SZ_512 - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_sha0_hwmod,
+       .clk            = "sha0_fck",
+       .addr           = am33xx_sha0_addrs,
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3 main -> AES0 HIB2 */
+static struct omap_hwmod_addr_space am33xx_aes0_addrs[] = {
+       {
+               .pa_start       = 0x53500000,
+               .pa_end         = 0x53500000 + SZ_1M - 1,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
+};
+
+struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_aes0_hwmod,
+       .clk            = "aes0_fck",
+       .addr           = am33xx_aes0_addrs,
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
new file mode 100644 (file)
index 0000000..0f17862
--- /dev/null
@@ -0,0 +1,1469 @@
+/*
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Hwmod common for AM335x and AM43x
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include "omap_hwmod.h"
+#include "i2c.h"
+#include "mmc.h"
+#include "wd_timer.h"
+#include "cm33xx.h"
+#include "prm33xx.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+#include "prcm43xx.h"
+
+#define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl))
+#define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl))
+#define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst))
+
+/*
+ * 'l3' class
+ * instance(s): l3_main, l3_s, l3_instr
+ */
+static struct omap_hwmod_class am33xx_l3_hwmod_class = {
+       .name           = "l3",
+};
+
+struct omap_hwmod am33xx_l3_main_hwmod = {
+       .name           = "l3_main",
+       .class          = &am33xx_l3_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* l3_s */
+struct omap_hwmod am33xx_l3_s_hwmod = {
+       .name           = "l3_s",
+       .class          = &am33xx_l3_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+};
+
+/* l3_instr */
+struct omap_hwmod am33xx_l3_instr_hwmod = {
+       .name           = "l3_instr",
+       .class          = &am33xx_l3_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw
+ */
+struct omap_hwmod_class am33xx_l4_hwmod_class = {
+       .name           = "l4",
+};
+
+/* l4_ls */
+struct omap_hwmod am33xx_l4_ls_hwmod = {
+       .name           = "l4_ls",
+       .class          = &am33xx_l4_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* l4_wkup */
+struct omap_hwmod am33xx_l4_wkup_hwmod = {
+       .name           = "l4_wkup",
+       .class          = &am33xx_l4_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * 'mpu' class
+ */
+static struct omap_hwmod_class am33xx_mpu_hwmod_class = {
+       .name   = "mpu",
+};
+
+struct omap_hwmod am33xx_mpu_hwmod = {
+       .name           = "mpu",
+       .class          = &am33xx_mpu_hwmod_class,
+       .clkdm_name     = "mpu_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "dpll_mpu_m2_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * 'wakeup m3' class
+ * Wakeup controller sub-system under wakeup domain
+ */
+struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = {
+       .name           = "wkup_m3",
+};
+
+/*
+ * 'pru-icss' class
+ * Programmable Real-Time Unit and Industrial Communication Subsystem
+ */
+static struct omap_hwmod_class am33xx_pruss_hwmod_class = {
+       .name   = "pruss",
+};
+
+static struct omap_hwmod_rst_info am33xx_pruss_resets[] = {
+       { .name = "pruss", .rst_shift = 1 },
+};
+
+/* pru-icss */
+/* Pseudo hwmod for reset control purpose only */
+struct omap_hwmod am33xx_pruss_hwmod = {
+       .name           = "pruss",
+       .class          = &am33xx_pruss_hwmod_class,
+       .clkdm_name     = "pruss_ocp_clkdm",
+       .main_clk       = "pruss_ocp_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .rst_lines      = am33xx_pruss_resets,
+       .rst_lines_cnt  = ARRAY_SIZE(am33xx_pruss_resets),
+};
+
+/* gfx */
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod_class am33xx_gfx_hwmod_class = {
+       .name   = "gfx",
+};
+
+static struct omap_hwmod_rst_info am33xx_gfx_resets[] = {
+       { .name = "gfx", .rst_shift = 0, .st_shift = 0},
+};
+
+struct omap_hwmod am33xx_gfx_hwmod = {
+       .name           = "gfx",
+       .class          = &am33xx_gfx_hwmod_class,
+       .clkdm_name     = "gfx_l3_clkdm",
+       .main_clk       = "gfx_fck_div_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .rst_lines      = am33xx_gfx_resets,
+       .rst_lines_cnt  = ARRAY_SIZE(am33xx_gfx_resets),
+};
+
+/*
+ * 'prcm' class
+ * power and reset manager (whole prcm infrastructure)
+ */
+static struct omap_hwmod_class am33xx_prcm_hwmod_class = {
+       .name   = "prcm",
+};
+
+/* prcm */
+struct omap_hwmod am33xx_prcm_hwmod = {
+       .name           = "prcm",
+       .class          = &am33xx_prcm_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+};
+
+/*
+ * 'aes0' class
+ */
+static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = {
+       .rev_offs       = 0x80,
+       .sysc_offs      = 0x84,
+       .syss_offs      = 0x88,
+       .sysc_flags     = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class am33xx_aes0_hwmod_class = {
+       .name           = "aes0",
+       .sysc           = &am33xx_aes0_sysc,
+};
+
+struct omap_hwmod am33xx_aes0_hwmod = {
+       .name           = "aes",
+       .class          = &am33xx_aes0_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .main_clk       = "aes0_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* sha0 HIB2 (the 'P' (public) device) */
+static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = {
+       .rev_offs       = 0x100,
+       .sysc_offs      = 0x110,
+       .syss_offs      = 0x114,
+       .sysc_flags     = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class am33xx_sha0_hwmod_class = {
+       .name           = "sha0",
+       .sysc           = &am33xx_sha0_sysc,
+};
+
+struct omap_hwmod am33xx_sha0_hwmod = {
+       .name           = "sham",
+       .class          = &am33xx_sha0_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* ocmcram */
+static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
+       .name = "ocmcram",
+};
+
+struct omap_hwmod am33xx_ocmcram_hwmod = {
+       .name           = "ocmcram",
+       .class          = &am33xx_ocmcram_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'smartreflex' class */
+static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = {
+       .name           = "smartreflex",
+};
+
+/* smartreflex0 */
+struct omap_hwmod am33xx_smartreflex0_hwmod = {
+       .name           = "smartreflex0",
+       .class          = &am33xx_smartreflex_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .main_clk       = "smartreflex0_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* smartreflex1 */
+struct omap_hwmod am33xx_smartreflex1_hwmod = {
+       .name           = "smartreflex1",
+       .class          = &am33xx_smartreflex_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .main_clk       = "smartreflex1_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * 'control' module class
+ */
+struct omap_hwmod_class am33xx_control_hwmod_class = {
+       .name           = "control",
+};
+
+/*
+ * 'cpgmac' class
+ * cpsw/cpgmac sub system
+ */
+static struct omap_hwmod_class_sysconfig am33xx_cpgmac_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x8,
+       .syss_offs      = 0x4,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+                          SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE |
+                          MSTANDBY_NO),
+       .sysc_fields    = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class am33xx_cpgmac0_hwmod_class = {
+       .name           = "cpgmac0",
+       .sysc           = &am33xx_cpgmac_sysc,
+};
+
+struct omap_hwmod am33xx_cpgmac0_hwmod = {
+       .name           = "cpgmac0",
+       .class          = &am33xx_cpgmac0_hwmod_class,
+       .clkdm_name     = "cpsw_125mhz_clkdm",
+       .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+       .main_clk       = "cpsw_125mhz_gclk",
+       .mpu_rt_idx     = 1,
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * mdio class
+ */
+static struct omap_hwmod_class am33xx_mdio_hwmod_class = {
+       .name           = "davinci_mdio",
+};
+
+struct omap_hwmod am33xx_mdio_hwmod = {
+       .name           = "davinci_mdio",
+       .class          = &am33xx_mdio_hwmod_class,
+       .clkdm_name     = "cpsw_125mhz_clkdm",
+       .main_clk       = "cpsw_125mhz_gclk",
+};
+
+/*
+ * dcan class
+ */
+static struct omap_hwmod_class am33xx_dcan_hwmod_class = {
+       .name = "d_can",
+};
+
+/* dcan0 */
+struct omap_hwmod am33xx_dcan0_hwmod = {
+       .name           = "d_can0",
+       .class          = &am33xx_dcan_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dcan0_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* dcan1 */
+struct omap_hwmod am33xx_dcan1_hwmod = {
+       .name           = "d_can1",
+       .class          = &am33xx_dcan_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dcan1_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* elm */
+static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+                       SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                       SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_elm_hwmod_class = {
+       .name           = "elm",
+       .sysc           = &am33xx_elm_sysc,
+};
+
+struct omap_hwmod am33xx_elm_hwmod = {
+       .name           = "elm",
+       .class          = &am33xx_elm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* pwmss  */
+static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x4,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                       SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+                       MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+struct omap_hwmod_class am33xx_epwmss_hwmod_class = {
+       .name           = "epwmss",
+       .sysc           = &am33xx_epwmss_sysc,
+};
+
+static struct omap_hwmod_class am33xx_ecap_hwmod_class = {
+       .name           = "ecap",
+};
+
+static struct omap_hwmod_class am33xx_eqep_hwmod_class = {
+       .name           = "eqep",
+};
+
+struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = {
+       .name           = "ehrpwm",
+};
+
+/* epwmss0 */
+struct omap_hwmod am33xx_epwmss0_hwmod = {
+       .name           = "epwmss0",
+       .class          = &am33xx_epwmss_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* ecap0 */
+struct omap_hwmod am33xx_ecap0_hwmod = {
+       .name           = "ecap0",
+       .class          = &am33xx_ecap_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* eqep0 */
+struct omap_hwmod am33xx_eqep0_hwmod = {
+       .name           = "eqep0",
+       .class          = &am33xx_eqep_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* ehrpwm0 */
+struct omap_hwmod am33xx_ehrpwm0_hwmod = {
+       .name           = "ehrpwm0",
+       .class          = &am33xx_ehrpwm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* epwmss1 */
+struct omap_hwmod am33xx_epwmss1_hwmod = {
+       .name           = "epwmss1",
+       .class          = &am33xx_epwmss_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* ecap1 */
+struct omap_hwmod am33xx_ecap1_hwmod = {
+       .name           = "ecap1",
+       .class          = &am33xx_ecap_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* eqep1 */
+struct omap_hwmod am33xx_eqep1_hwmod = {
+       .name           = "eqep1",
+       .class          = &am33xx_eqep_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* ehrpwm1 */
+struct omap_hwmod am33xx_ehrpwm1_hwmod = {
+       .name           = "ehrpwm1",
+       .class          = &am33xx_ehrpwm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* epwmss2 */
+struct omap_hwmod am33xx_epwmss2_hwmod = {
+       .name           = "epwmss2",
+       .class          = &am33xx_epwmss_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* ecap2 */
+struct omap_hwmod am33xx_ecap2_hwmod = {
+       .name           = "ecap2",
+       .class          = &am33xx_ecap_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* eqep2 */
+struct omap_hwmod am33xx_eqep2_hwmod = {
+       .name           = "eqep2",
+       .class          = &am33xx_eqep_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/* ehrpwm2 */
+struct omap_hwmod am33xx_ehrpwm2_hwmod = {
+       .name           = "ehrpwm2",
+       .class          = &am33xx_ehrpwm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+/*
+ * 'gpio' class: for gpio 0,1,2,3
+ */
+static struct omap_hwmod_class_sysconfig am33xx_gpio_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0114,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+                         SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+                         SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                         SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class am33xx_gpio_hwmod_class = {
+       .name           = "gpio",
+       .sysc           = &am33xx_gpio_sysc,
+       .rev            = 2,
+};
+
+struct omap_gpio_dev_attr gpio_dev_attr = {
+       .bank_width     = 32,
+       .dbck_flag      = true,
+};
+
+/* gpio1 */
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+struct omap_hwmod am33xx_gpio1_hwmod = {
+       .name           = "gpio2",
+       .class          = &am33xx_gpio_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = gpio1_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio1_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
+};
+
+/* gpio2 */
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+struct omap_hwmod am33xx_gpio2_hwmod = {
+       .name           = "gpio3",
+       .class          = &am33xx_gpio_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = gpio2_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio2_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
+};
+
+/* gpio3 */
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+struct omap_hwmod am33xx_gpio3_hwmod = {
+       .name           = "gpio4",
+       .class          = &am33xx_gpio_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = gpio3_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio3_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
+};
+
+/* gpmc */
+static struct omap_hwmod_class_sysconfig gpmc_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x10,
+       .syss_offs      = 0x14,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_gpmc_hwmod_class = {
+       .name           = "gpmc",
+       .sysc           = &gpmc_sysc,
+};
+
+struct omap_hwmod am33xx_gpmc_hwmod = {
+       .name           = "gpmc",
+       .class          = &am33xx_gpmc_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+       .main_clk       = "l3s_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'i2c' class */
+static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = {
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0090,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+                         SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+                         SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                         SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+       .name           = "i2c",
+       .sysc           = &am33xx_i2c_sysc,
+       .rev            = OMAP_I2C_IP_VERSION_2,
+       .reset          = &omap_i2c_reset,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+       .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+};
+
+/* i2c1 */
+struct omap_hwmod am33xx_i2c1_hwmod = {
+       .name           = "i2c1",
+       .class          = &i2c_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+       .main_clk       = "dpll_per_m2_div4_wkupdm_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &i2c_dev_attr,
+};
+
+/* i2c1 */
+struct omap_hwmod am33xx_i2c2_hwmod = {
+       .name           = "i2c2",
+       .class          = &i2c_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4 = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &i2c_dev_attr,
+};
+
+/* i2c3 */
+struct omap_hwmod am33xx_i2c3_hwmod = {
+       .name           = "i2c3",
+       .class          = &i2c_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &i2c_dev_attr,
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors using a
+ * queued mailbox-interrupt mechanism.
+ */
+static struct omap_hwmod_class_sysconfig am33xx_mailbox_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
+                         SYSC_HAS_SOFTRESET),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am33xx_mailbox_hwmod_class = {
+       .name   = "mailbox",
+       .sysc   = &am33xx_mailbox_sysc,
+};
+
+struct omap_hwmod am33xx_mailbox_hwmod = {
+       .name           = "mailbox",
+       .class          = &am33xx_mailbox_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm = {
+               .omap4 = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * 'mcasp' class
+ */
+static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x4,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE,
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class am33xx_mcasp_hwmod_class = {
+       .name           = "mcasp",
+       .sysc           = &am33xx_mcasp_sysc,
+};
+
+/* mcasp0 */
+struct omap_hwmod am33xx_mcasp0_hwmod = {
+       .name           = "mcasp0",
+       .class          = &am33xx_mcasp_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .main_clk       = "mcasp0_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* mcasp1 */
+struct omap_hwmod am33xx_mcasp1_hwmod = {
+       .name           = "mcasp1",
+       .class          = &am33xx_mcasp_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .main_clk       = "mcasp1_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'mmc' class */
+static struct omap_hwmod_class_sysconfig am33xx_mmc_sysc = {
+       .rev_offs       = 0x1fc,
+       .sysc_offs      = 0x10,
+       .syss_offs      = 0x14,
+       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+                         SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+                         SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_mmc_hwmod_class = {
+       .name           = "mmc",
+       .sysc           = &am33xx_mmc_sysc,
+};
+
+/* mmc0 */
+static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = {
+       .flags          = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+struct omap_hwmod am33xx_mmc0_hwmod = {
+       .name           = "mmc1",
+       .class          = &am33xx_mmc_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "mmc_clk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &am33xx_mmc0_dev_attr,
+};
+
+/* mmc1 */
+static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = {
+       .flags          = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+struct omap_hwmod am33xx_mmc1_hwmod = {
+       .name           = "mmc2",
+       .class          = &am33xx_mmc_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "mmc_clk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &am33xx_mmc1_dev_attr,
+};
+
+/* mmc2 */
+static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = {
+       .flags          = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+struct omap_hwmod am33xx_mmc2_hwmod = {
+       .name           = "mmc3",
+       .class          = &am33xx_mmc_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .main_clk       = "mmc_clk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &am33xx_mmc2_dev_attr,
+};
+
+/*
+ * 'rtc' class
+ * rtc subsystem
+ */
+static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = {
+       .rev_offs       = 0x0074,
+       .sysc_offs      = 0x0078,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE,
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO |
+                         SIDLE_SMART | SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class am33xx_rtc_hwmod_class = {
+       .name           = "rtc",
+       .sysc           = &am33xx_rtc_sysc,
+};
+
+struct omap_hwmod am33xx_rtc_hwmod = {
+       .name           = "rtc",
+       .class          = &am33xx_rtc_hwmod_class,
+       .clkdm_name     = "l4_rtc_clkdm",
+       .main_clk       = "clk_32768_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'spi' class */
+static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0110,
+       .syss_offs      = 0x0114,
+       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+                         SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                         SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class am33xx_spi_hwmod_class = {
+       .name           = "mcspi",
+       .sysc           = &am33xx_mcspi_sysc,
+       .rev            = OMAP4_MCSPI_REV,
+};
+
+/* spi0 */
+struct omap2_mcspi_dev_attr mcspi_attrib = {
+       .num_chipselect = 2,
+};
+struct omap_hwmod am33xx_spi0_hwmod = {
+       .name           = "spi0",
+       .class          = &am33xx_spi_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mcspi_attrib,
+};
+
+/* spi1 */
+struct omap_hwmod am33xx_spi1_hwmod = {
+       .name           = "spi1",
+       .class          = &am33xx_spi_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mcspi_attrib,
+};
+
+/*
+ * 'spinlock' class
+ * spinlock provides hardware assistance for synchronizing the
+ * processes running on multiple processors
+ */
+
+static struct omap_hwmod_class_sysconfig am33xx_spinlock_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+                          SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_spinlock_hwmod_class = {
+       .name           = "spinlock",
+       .sysc           = &am33xx_spinlock_sysc,
+};
+
+struct omap_hwmod am33xx_spinlock_hwmod = {
+       .name           = "spinlock",
+       .class          = &am33xx_spinlock_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'timer 2-7' class */
+static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                         SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+struct omap_hwmod_class am33xx_timer_hwmod_class = {
+       .name           = "timer",
+       .sysc           = &am33xx_timer_sysc,
+};
+
+/* timer1 1ms */
+static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+                       SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                       SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_timer1ms_hwmod_class = {
+       .name           = "timer",
+       .sysc           = &am33xx_timer1ms_sysc,
+};
+
+struct omap_hwmod am33xx_timer1_hwmod = {
+       .name           = "timer1",
+       .class          = &am33xx_timer1ms_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .main_clk       = "timer1_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_timer2_hwmod = {
+       .name           = "timer2",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer2_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_timer3_hwmod = {
+       .name           = "timer3",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer3_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_timer4_hwmod = {
+       .name           = "timer4",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer4_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_timer5_hwmod = {
+       .name           = "timer5",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer5_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_timer6_hwmod = {
+       .name           = "timer6",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer6_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_timer7_hwmod = {
+       .name           = "timer7",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer7_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* tpcc */
+static struct omap_hwmod_class am33xx_tpcc_hwmod_class = {
+       .name           = "tpcc",
+};
+
+struct omap_hwmod am33xx_tpcc_hwmod = {
+       .name           = "tpcc",
+       .class          = &am33xx_tpcc_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x10,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+                         SYSC_HAS_MIDLEMODE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+/* 'tptc' class */
+static struct omap_hwmod_class am33xx_tptc_hwmod_class = {
+       .name           = "tptc",
+       .sysc           = &am33xx_tptc_sysc,
+};
+
+/* tptc0 */
+struct omap_hwmod am33xx_tptc0_hwmod = {
+       .name           = "tptc0",
+       .class          = &am33xx_tptc_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* tptc1 */
+struct omap_hwmod am33xx_tptc1_hwmod = {
+       .name           = "tptc1",
+       .class          = &am33xx_tptc_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* tptc2 */
+struct omap_hwmod am33xx_tptc2_hwmod = {
+       .name           = "tptc2",
+       .class          = &am33xx_tptc_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
+       .main_clk       = "l3_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'uart' class */
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+       .rev_offs       = 0x50,
+       .sysc_offs      = 0x54,
+       .syss_offs      = 0x58,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+                         SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                         SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+       .name           = "uart",
+       .sysc           = &uart_sysc,
+};
+
+struct omap_hwmod am33xx_uart1_hwmod = {
+       .name           = "uart1",
+       .class          = &uart_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
+       .main_clk       = "dpll_per_m2_div4_wkupdm_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_uart2_hwmod = {
+       .name           = "uart2",
+       .class          = &uart_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* uart3 */
+struct omap_hwmod am33xx_uart3_hwmod = {
+       .name           = "uart3",
+       .class          = &uart_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_uart4_hwmod = {
+       .name           = "uart4",
+       .class          = &uart_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_uart5_hwmod = {
+       .name           = "uart5",
+       .class          = &uart_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+struct omap_hwmod am33xx_uart6_hwmod = {
+       .name           = "uart6",
+       .class          = &uart_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* 'wd_timer' class */
+static struct omap_hwmod_class_sysconfig wdt_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x10,
+       .syss_offs      = 0x14,
+       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                       SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = {
+       .name           = "wd_timer",
+       .sysc           = &wdt_sysc,
+       .pre_shutdown   = &omap2_wd_timer_disable,
+};
+
+/*
+ * XXX: device.c file uses hardcoded name for watchdog timer
+ * driver "wd_timer2, so we are also using same name as of now...
+ */
+struct omap_hwmod am33xx_wd_timer1_hwmod = {
+       .name           = "wd_timer2",
+       .class          = &am33xx_wd_timer_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE,
+       .main_clk       = "wdt1_fck",
+       .prcm           = {
+               .omap4  = {
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static void omap_hwmod_am33xx_clkctrl(void)
+{
+       CLKCTRL(am33xx_uart2_hwmod, AM33XX_CM_PER_UART1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart3_hwmod, AM33XX_CM_PER_UART2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart4_hwmod, AM33XX_CM_PER_UART3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart5_hwmod, AM33XX_CM_PER_UART4_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart6_hwmod, AM33XX_CM_PER_UART5_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_dcan1_hwmod, AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_elm_hwmod, AM33XX_CM_PER_ELM_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpio1_hwmod, AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpio2_hwmod, AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpio3_hwmod, AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_i2c2_hwmod, AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_i2c3_hwmod, AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mailbox_hwmod, AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mcasp0_hwmod, AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mcasp1_hwmod, AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mmc0_hwmod, AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mmc1_hwmod, AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer3_hwmod, AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer4_hwmod, AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer5_hwmod, AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer6_hwmod, AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer7_hwmod, AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_smartreflex0_hwmod,
+               AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_smartreflex1_hwmod,
+               AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart1_hwmod, AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tpcc_hwmod, AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tptc0_hwmod, AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tptc1_hwmod, AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tptc2_hwmod, AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gfx_hwmod, AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_cpgmac0_hwmod, AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_pruss_hwmod, AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET);
+}
+
+static void omap_hwmod_am33xx_rst(void)
+{
+       RSTCTRL(am33xx_pruss_hwmod, AM33XX_RM_PER_RSTCTRL_OFFSET);
+       RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET);
+       RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET);
+}
+
+void omap_hwmod_am33xx_reg(void)
+{
+       omap_hwmod_am33xx_clkctrl();
+       omap_hwmod_am33xx_rst();
+}
+
+static void omap_hwmod_am43xx_clkctrl(void)
+{
+       CLKCTRL(am33xx_uart2_hwmod, AM43XX_CM_PER_UART1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart3_hwmod, AM43XX_CM_PER_UART2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart4_hwmod, AM43XX_CM_PER_UART3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart5_hwmod, AM43XX_CM_PER_UART4_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart6_hwmod, AM43XX_CM_PER_UART5_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_dcan0_hwmod, AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_dcan1_hwmod, AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_elm_hwmod, AM43XX_CM_PER_ELM_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpio1_hwmod, AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpio2_hwmod, AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpio3_hwmod, AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_i2c2_hwmod, AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_i2c3_hwmod, AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mailbox_hwmod, AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mcasp0_hwmod, AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mcasp1_hwmod, AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mmc0_hwmod, AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mmc1_hwmod, AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer3_hwmod, AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer4_hwmod, AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer5_hwmod, AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer6_hwmod, AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer7_hwmod, AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_smartreflex0_hwmod,
+               AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_smartreflex1_hwmod,
+               AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_uart1_hwmod, AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_i2c1_hwmod, AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_wd_timer1_hwmod, AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mmc2_hwmod, AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tpcc_hwmod, AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tptc0_hwmod, AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tptc1_hwmod, AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_tptc2_hwmod, AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_gfx_hwmod, AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_cpgmac0_hwmod, AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_pruss_hwmod, AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET);
+       CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET);
+}
+
+static void omap_hwmod_am43xx_rst(void)
+{
+       RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET);
+       RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET);
+       RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET);
+}
+
+void omap_hwmod_am43xx_reg(void)
+{
+       omap_hwmod_am43xx_clkctrl();
+       omap_hwmod_am43xx_rst();
+}
index 215894f8910d407d30eac10f23b22ee0ee003fb1..6b406ca4bd3b49769884ce1534c1d132e224957a 100644 (file)
@@ -29,6 +29,7 @@
 #include "i2c.h"
 #include "mmc.h"
 #include "wd_timer.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
 
 /*
  * IP blocks
@@ -52,7 +53,7 @@ static struct omap_hwmod am33xx_emif_hwmod = {
        .name           = "emif",
        .class          = &am33xx_emif_hwmod_class,
        .clkdm_name     = "l3_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "dpll_ddr_m2_div2_ck",
        .prcm           = {
                .omap4  = {
@@ -62,79 +63,12 @@ static struct omap_hwmod am33xx_emif_hwmod = {
        },
 };
 
-/*
- * 'l3' class
- * instance(s): l3_main, l3_s, l3_instr
- */
-static struct omap_hwmod_class am33xx_l3_hwmod_class = {
-       .name           = "l3",
-};
-
-static struct omap_hwmod am33xx_l3_main_hwmod = {
-       .name           = "l3_main",
-       .class          = &am33xx_l3_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_L3_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* l3_s */
-static struct omap_hwmod am33xx_l3_s_hwmod = {
-       .name           = "l3_s",
-       .class          = &am33xx_l3_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-};
-
-/* l3_instr */
-static struct omap_hwmod am33xx_l3_instr_hwmod = {
-       .name           = "l3_instr",
-       .class          = &am33xx_l3_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'l4' class
- * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw
- */
-static struct omap_hwmod_class am33xx_l4_hwmod_class = {
-       .name           = "l4",
-};
-
-/* l4_ls */
-static struct omap_hwmod am33xx_l4_ls_hwmod = {
-       .name           = "l4_ls",
-       .class          = &am33xx_l4_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /* l4_hs */
 static struct omap_hwmod am33xx_l4_hs_hwmod = {
        .name           = "l4_hs",
        .class          = &am33xx_l4_hwmod_class,
        .clkdm_name     = "l4hs_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "l4hs_gclk",
        .prcm           = {
                .omap4  = {
@@ -144,50 +78,6 @@ static struct omap_hwmod am33xx_l4_hs_hwmod = {
        },
 };
 
-
-/* l4_wkup */
-static struct omap_hwmod am33xx_l4_wkup_hwmod = {
-       .name           = "l4_wkup",
-       .class          = &am33xx_l4_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mpu' class
- */
-static struct omap_hwmod_class am33xx_mpu_hwmod_class = {
-       .name   = "mpu",
-};
-
-static struct omap_hwmod am33xx_mpu_hwmod = {
-       .name           = "mpu",
-       .class          = &am33xx_mpu_hwmod_class,
-       .clkdm_name     = "mpu_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "dpll_mpu_m2_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'wakeup m3' class
- * Wakeup controller sub-system under wakeup domain
- */
-static struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = {
-       .name           = "wkup_m3",
-};
-
 static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = {
        { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 },
 };
@@ -212,78 +102,6 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = {
        .rst_lines_cnt  = ARRAY_SIZE(am33xx_wkup_m3_resets),
 };
 
-/*
- * 'pru-icss' class
- * Programmable Real-Time Unit and Industrial Communication Subsystem
- */
-static struct omap_hwmod_class am33xx_pruss_hwmod_class = {
-       .name   = "pruss",
-};
-
-static struct omap_hwmod_rst_info am33xx_pruss_resets[] = {
-       { .name = "pruss", .rst_shift = 1 },
-};
-
-/* pru-icss */
-/* Pseudo hwmod for reset control purpose only */
-static struct omap_hwmod am33xx_pruss_hwmod = {
-       .name           = "pruss",
-       .class          = &am33xx_pruss_hwmod_class,
-       .clkdm_name     = "pruss_ocp_clkdm",
-       .main_clk       = "pruss_ocp_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET,
-                       .rstctrl_offs   = AM33XX_RM_PER_RSTCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .rst_lines      = am33xx_pruss_resets,
-       .rst_lines_cnt  = ARRAY_SIZE(am33xx_pruss_resets),
-};
-
-/* gfx */
-/* Pseudo hwmod for reset control purpose only */
-static struct omap_hwmod_class am33xx_gfx_hwmod_class = {
-       .name   = "gfx",
-};
-
-static struct omap_hwmod_rst_info am33xx_gfx_resets[] = {
-       { .name = "gfx", .rst_shift = 0, .st_shift = 0},
-};
-
-static struct omap_hwmod am33xx_gfx_hwmod = {
-       .name           = "gfx",
-       .class          = &am33xx_gfx_hwmod_class,
-       .clkdm_name     = "gfx_l3_clkdm",
-       .main_clk       = "gfx_fck_div_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET,
-                       .rstctrl_offs   = AM33XX_RM_GFX_RSTCTRL_OFFSET,
-                       .rstst_offs     = AM33XX_RM_GFX_RSTST_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .rst_lines      = am33xx_gfx_resets,
-       .rst_lines_cnt  = ARRAY_SIZE(am33xx_gfx_resets),
-};
-
-/*
- * 'prcm' class
- * power and reset manager (whole prcm infrastructure)
- */
-static struct omap_hwmod_class am33xx_prcm_hwmod_class = {
-       .name   = "prcm",
-};
-
-/* prcm */
-static struct omap_hwmod am33xx_prcm_hwmod = {
-       .name           = "prcm",
-       .class          = &am33xx_prcm_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-};
-
 /*
  * 'adc/tsc' class
  * TouchScreen Controller (Anolog-To-Digital Converter)
@@ -387,79 +205,6 @@ static struct omap_hwmod am33xx_ocpwp_hwmod = {
 };
 #endif
 
-/*
- * 'aes0' class
- */
-static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = {
-       .rev_offs       = 0x80,
-       .sysc_offs      = 0x84,
-       .syss_offs      = 0x88,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class am33xx_aes0_hwmod_class = {
-       .name           = "aes0",
-       .sysc           = &am33xx_aes0_sysc,
-};
-
-static struct omap_hwmod am33xx_aes0_hwmod = {
-       .name           = "aes",
-       .class          = &am33xx_aes0_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .main_clk       = "aes0_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_AES0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* sha0 HIB2 (the 'P' (public) device) */
-static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = {
-       .rev_offs       = 0x100,
-       .sysc_offs      = 0x110,
-       .syss_offs      = 0x114,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class am33xx_sha0_hwmod_class = {
-       .name           = "sha0",
-       .sysc           = &am33xx_sha0_sysc,
-};
-
-static struct omap_hwmod am33xx_sha0_hwmod = {
-       .name           = "sham",
-       .class          = &am33xx_sha0_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* ocmcram */
-static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
-       .name = "ocmcram",
-};
-
-static struct omap_hwmod am33xx_ocmcram_hwmod = {
-       .name           = "ocmcram",
-       .class          = &am33xx_ocmcram_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /*
  * 'debugss' class
  * debug sub system
@@ -488,1619 +233,236 @@ static struct omap_hwmod am33xx_debugss_hwmod = {
        .opt_clks_cnt   = ARRAY_SIZE(debugss_opt_clks),
 };
 
-/* 'smartreflex' class */
-static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = {
-       .name           = "smartreflex",
-};
-
-/* smartreflex0 */
-static struct omap_hwmod am33xx_smartreflex0_hwmod = {
-       .name           = "smartreflex0",
-       .class          = &am33xx_smartreflex_hwmod_class,
+static struct omap_hwmod am33xx_control_hwmod = {
+       .name           = "control",
+       .class          = &am33xx_control_hwmod_class,
        .clkdm_name     = "l4_wkup_clkdm",
-       .main_clk       = "smartreflex0_fck",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "dpll_core_m4_div2_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET,
+                       .clkctrl_offs   = AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
-/* smartreflex1 */
-static struct omap_hwmod am33xx_smartreflex1_hwmod = {
-       .name           = "smartreflex1",
-       .class          = &am33xx_smartreflex_hwmod_class,
+/* gpio0 */
+static struct omap_hwmod_opt_clk gpio0_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio0_dbclk" },
+};
+
+static struct omap_hwmod am33xx_gpio0_hwmod = {
+       .name           = "gpio1",
+       .class          = &am33xx_gpio_hwmod_class,
        .clkdm_name     = "l4_wkup_clkdm",
-       .main_clk       = "smartreflex1_fck",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "dpll_core_m4_div2_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET,
+                       .clkctrl_offs   = AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
+       .opt_clks       = gpio0_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio0_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
 };
 
-/*
- * 'control' module class
- */
-static struct omap_hwmod_class am33xx_control_hwmod_class = {
-       .name           = "control",
+/* lcdc */
+static struct omap_hwmod_class_sysconfig lcdc_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x54,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
 };
 
-static struct omap_hwmod am33xx_control_hwmod = {
-       .name           = "control",
-       .class          = &am33xx_control_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "dpll_core_m4_div2_ck",
+static struct omap_hwmod_class am33xx_lcdc_hwmod_class = {
+       .name           = "lcdc",
+       .sysc           = &lcdc_sysc,
+};
+
+static struct omap_hwmod am33xx_lcdc_hwmod = {
+       .name           = "lcdc",
+       .class          = &am33xx_lcdc_hwmod_class,
+       .clkdm_name     = "lcdc_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+       .main_clk       = "lcd_gclk",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET,
+                       .clkctrl_offs   = AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
 /*
- * 'cpgmac' class
- * cpsw/cpgmac sub system
+ * 'usb_otg' class
+ * high-speed on-the-go universal serial bus (usb_otg) controller
  */
-static struct omap_hwmod_class_sysconfig am33xx_cpgmac_sysc = {
+static struct omap_hwmod_class_sysconfig am33xx_usbhsotg_sysc = {
        .rev_offs       = 0x0,
-       .sysc_offs      = 0x8,
-       .syss_offs      = 0x4,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE |
-                          MSTANDBY_NO),
-       .sysc_fields    = &omap_hwmod_sysc_type3,
+       .sysc_offs      = 0x10,
+       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                         MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
 };
 
-static struct omap_hwmod_class am33xx_cpgmac0_hwmod_class = {
-       .name           = "cpgmac0",
-       .sysc           = &am33xx_cpgmac_sysc,
+static struct omap_hwmod_class am33xx_usbotg_class = {
+       .name           = "usbotg",
+       .sysc           = &am33xx_usbhsotg_sysc,
 };
 
-static struct omap_hwmod am33xx_cpgmac0_hwmod = {
-       .name           = "cpgmac0",
-       .class          = &am33xx_cpgmac0_hwmod_class,
-       .clkdm_name     = "cpsw_125mhz_clkdm",
-       .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
-       .main_clk       = "cpsw_125mhz_gclk",
-       .mpu_rt_idx     = 1,
+static struct omap_hwmod am33xx_usbss_hwmod = {
+       .name           = "usb_otg_hs",
+       .class          = &am33xx_usbotg_class,
+       .clkdm_name     = "l3s_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+       .main_clk       = "usbotg_fck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET,
+                       .clkctrl_offs   = AM33XX_CM_PER_USB0_CLKCTRL_OFFSET,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
+
 /*
- * mdio class
+ * Interfaces
  */
-static struct omap_hwmod_class am33xx_mdio_hwmod_class = {
-       .name           = "davinci_mdio",
-};
 
-static struct omap_hwmod am33xx_mdio_hwmod = {
-       .name           = "davinci_mdio",
-       .class          = &am33xx_mdio_hwmod_class,
-       .clkdm_name     = "cpsw_125mhz_clkdm",
-       .main_clk       = "cpsw_125mhz_gclk",
+static struct omap_hwmod_addr_space am33xx_emif_addrs[] = {
+       {
+               .pa_start       = 0x4c000000,
+               .pa_end         = 0x4c000fff,
+               .flags          = ADDR_TYPE_RT
+       },
+       { }
 };
-
-/*
- * dcan class
- */
-static struct omap_hwmod_class am33xx_dcan_hwmod_class = {
-       .name = "d_can",
+/* l3 main -> emif */
+static struct omap_hwmod_ocp_if am33xx_l3_main__emif = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_emif_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .addr           = am33xx_emif_addrs,
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* dcan0 */
-static struct omap_hwmod am33xx_dcan0_hwmod = {
-       .name           = "d_can0",
-       .class          = &am33xx_dcan_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dcan0_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
+/* l3 main -> l4 hs */
+static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_l4_hs_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* dcan1 */
-static struct omap_hwmod am33xx_dcan1_hwmod = {
-       .name           = "d_can1",
-       .class          = &am33xx_dcan_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dcan1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
+/* wkup m3 -> l4 wkup */
+static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = {
+       .master         = &am33xx_wkup_m3_hwmod,
+       .slave          = &am33xx_l4_wkup_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* elm */
-static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
-                       SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
+/* l4 wkup -> wkup m3 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_wkup_m3_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_class am33xx_elm_hwmod_class = {
-       .name           = "elm",
-       .sysc           = &am33xx_elm_sysc,
+/* l4 hs -> pru-icss */
+static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = {
+       .master         = &am33xx_l4_hs_hwmod,
+       .slave          = &am33xx_pruss_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod am33xx_elm_hwmod = {
-       .name           = "elm",
-       .class          = &am33xx_elm_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_ELM_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* pwmss  */
-static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x4,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                       SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
-                       MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_epwmss_hwmod_class = {
-       .name           = "epwmss",
-       .sysc           = &am33xx_epwmss_sysc,
-};
-
-static struct omap_hwmod_class am33xx_ecap_hwmod_class = {
-       .name           = "ecap",
-};
-
-static struct omap_hwmod_class am33xx_eqep_hwmod_class = {
-       .name           = "eqep",
-};
-
-static struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = {
-       .name           = "ehrpwm",
-};
-
-/* epwmss0 */
-static struct omap_hwmod am33xx_epwmss0_hwmod = {
-       .name           = "epwmss0",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* ecap0 */
-static struct omap_hwmod am33xx_ecap0_hwmod = {
-       .name           = "ecap0",
-       .class          = &am33xx_ecap_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* eqep0 */
-static struct omap_hwmod am33xx_eqep0_hwmod = {
-       .name           = "eqep0",
-       .class          = &am33xx_eqep_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* ehrpwm0 */
-static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
-       .name           = "ehrpwm0",
-       .class          = &am33xx_ehrpwm_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* epwmss1 */
-static struct omap_hwmod am33xx_epwmss1_hwmod = {
-       .name           = "epwmss1",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* ecap1 */
-static struct omap_hwmod am33xx_ecap1_hwmod = {
-       .name           = "ecap1",
-       .class          = &am33xx_ecap_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* eqep1 */
-static struct omap_hwmod am33xx_eqep1_hwmod = {
-       .name           = "eqep1",
-       .class          = &am33xx_eqep_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* ehrpwm1 */
-static struct omap_hwmod am33xx_ehrpwm1_hwmod = {
-       .name           = "ehrpwm1",
-       .class          = &am33xx_ehrpwm_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* epwmss2 */
-static struct omap_hwmod am33xx_epwmss2_hwmod = {
-       .name           = "epwmss2",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* ecap2 */
-static struct omap_hwmod am33xx_ecap2_hwmod = {
-       .name           = "ecap2",
-       .class          = &am33xx_ecap_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* eqep2 */
-static struct omap_hwmod am33xx_eqep2_hwmod = {
-       .name           = "eqep2",
-       .class          = &am33xx_eqep_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/* ehrpwm2 */
-static struct omap_hwmod am33xx_ehrpwm2_hwmod = {
-       .name           = "ehrpwm2",
-       .class          = &am33xx_ehrpwm_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-};
-
-/*
- * 'gpio' class: for gpio 0,1,2,3
- */
-static struct omap_hwmod_class_sysconfig am33xx_gpio_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0114,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
-                         SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                         SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_gpio_hwmod_class = {
-       .name           = "gpio",
-       .sysc           = &am33xx_gpio_sysc,
-       .rev            = 2,
-};
-
-static struct omap_gpio_dev_attr gpio_dev_attr = {
-       .bank_width     = 32,
-       .dbck_flag      = true,
-};
-
-/* gpio0 */
-static struct omap_hwmod_opt_clk gpio0_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio0_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio0_hwmod = {
-       .name           = "gpio1",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "dpll_core_m4_div2_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio0_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio0_opt_clks),
-       .dev_attr       = &gpio_dev_attr,
-};
-
-/* gpio1 */
-static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio1_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio1_hwmod = {
-       .name           = "gpio2",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio1_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio1_opt_clks),
-       .dev_attr       = &gpio_dev_attr,
-};
-
-/* gpio2 */
-static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio2_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio2_hwmod = {
-       .name           = "gpio3",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio2_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio2_opt_clks),
-       .dev_attr       = &gpio_dev_attr,
-};
-
-/* gpio3 */
-static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio3_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio3_hwmod = {
-       .name           = "gpio4",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio3_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio3_opt_clks),
-       .dev_attr       = &gpio_dev_attr,
-};
-
-/* gpmc */
-static struct omap_hwmod_class_sysconfig gpmc_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x10,
-       .syss_offs      = 0x14,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_gpmc_hwmod_class = {
-       .name           = "gpmc",
-       .sysc           = &gpmc_sysc,
-};
-
-static struct omap_hwmod am33xx_gpmc_hwmod = {
-       .name           = "gpmc",
-       .class          = &am33xx_gpmc_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-       .main_clk       = "l3s_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* 'i2c' class */
-static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = {
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0090,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                         SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-                         SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class i2c_class = {
-       .name           = "i2c",
-       .sysc           = &am33xx_i2c_sysc,
-       .rev            = OMAP_I2C_IP_VERSION_2,
-       .reset          = &omap_i2c_reset,
-};
-
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-       .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
-};
-
-/* i2c1 */
-static struct omap_hwmod am33xx_i2c1_hwmod = {
-       .name           = "i2c1",
-       .class          = &i2c_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-       .main_clk       = "dpll_per_m2_div4_wkupdm_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &i2c_dev_attr,
-};
-
-/* i2c1 */
-static struct omap_hwmod am33xx_i2c2_hwmod = {
-       .name           = "i2c2",
-       .class          = &i2c_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4 = {
-                       .clkctrl_offs   = AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &i2c_dev_attr,
-};
-
-/* i2c3 */
-static struct omap_hwmod am33xx_i2c3_hwmod = {
-       .name           = "i2c3",
-       .class          = &i2c_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &i2c_dev_attr,
-};
-
-
-/* lcdc */
-static struct omap_hwmod_class_sysconfig lcdc_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x54,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_lcdc_hwmod_class = {
-       .name           = "lcdc",
-       .sysc           = &lcdc_sysc,
-};
-
-static struct omap_hwmod am33xx_lcdc_hwmod = {
-       .name           = "lcdc",
-       .class          = &am33xx_lcdc_hwmod_class,
-       .clkdm_name     = "lcdc_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-       .main_clk       = "lcd_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mailbox' class
- * mailbox module allowing communication between the on-chip processors using a
- * queued mailbox-interrupt mechanism.
- */
-static struct omap_hwmod_class_sysconfig am33xx_mailbox_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
-                         SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_mailbox_hwmod_class = {
-       .name   = "mailbox",
-       .sysc   = &am33xx_mailbox_sysc,
-};
-
-static struct omap_hwmod am33xx_mailbox_hwmod = {
-       .name           = "mailbox",
-       .class          = &am33xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs   = AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mcasp' class
- */
-static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x4,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type3,
-};
-
-static struct omap_hwmod_class am33xx_mcasp_hwmod_class = {
-       .name           = "mcasp",
-       .sysc           = &am33xx_mcasp_sysc,
-};
-
-/* mcasp0 */
-static struct omap_hwmod am33xx_mcasp0_hwmod = {
-       .name           = "mcasp0",
-       .class          = &am33xx_mcasp_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .main_clk       = "mcasp0_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* mcasp1 */
-static struct omap_hwmod am33xx_mcasp1_hwmod = {
-       .name           = "mcasp1",
-       .class          = &am33xx_mcasp_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .main_clk       = "mcasp1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* 'mmc' class */
-static struct omap_hwmod_class_sysconfig am33xx_mmc_sysc = {
-       .rev_offs       = 0x1fc,
-       .sysc_offs      = 0x10,
-       .syss_offs      = 0x14,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                         SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
-                         SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_mmc_hwmod_class = {
-       .name           = "mmc",
-       .sysc           = &am33xx_mmc_sysc,
-};
-
-/* mmc0 */
-static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = {
-       .flags          = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
-};
-
-static struct omap_hwmod am33xx_mmc0_hwmod = {
-       .name           = "mmc1",
-       .class          = &am33xx_mmc_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "mmc_clk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &am33xx_mmc0_dev_attr,
-};
-
-/* mmc1 */
-static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = {
-       .flags          = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
-};
-
-static struct omap_hwmod am33xx_mmc1_hwmod = {
-       .name           = "mmc2",
-       .class          = &am33xx_mmc_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "mmc_clk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &am33xx_mmc1_dev_attr,
-};
-
-/* mmc2 */
-static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = {
-       .flags          = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
-};
-static struct omap_hwmod am33xx_mmc2_hwmod = {
-       .name           = "mmc3",
-       .class          = &am33xx_mmc_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .main_clk       = "mmc_clk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &am33xx_mmc2_dev_attr,
-};
-
-/*
- * 'rtc' class
- * rtc subsystem
- */
-static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = {
-       .rev_offs       = 0x0074,
-       .sysc_offs      = 0x0078,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO |
-                         SIDLE_SMART | SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type3,
-};
-
-static struct omap_hwmod_class am33xx_rtc_hwmod_class = {
-       .name           = "rtc",
-       .sysc           = &am33xx_rtc_sysc,
-};
-
-static struct omap_hwmod am33xx_rtc_hwmod = {
-       .name           = "rtc",
-       .class          = &am33xx_rtc_hwmod_class,
-       .clkdm_name     = "l4_rtc_clkdm",
-       .main_clk       = "clk_32768_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* 'spi' class */
-static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0110,
-       .syss_offs      = 0x0114,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                         SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
-                         SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_spi_hwmod_class = {
-       .name           = "mcspi",
-       .sysc           = &am33xx_mcspi_sysc,
-       .rev            = OMAP4_MCSPI_REV,
-};
-
-/* spi0 */
-static struct omap2_mcspi_dev_attr mcspi_attrib = {
-       .num_chipselect = 2,
-};
-static struct omap_hwmod am33xx_spi0_hwmod = {
-       .name           = "spi0",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &mcspi_attrib,
-};
-
-/* spi1 */
-static struct omap_hwmod am33xx_spi1_hwmod = {
-       .name           = "spi1",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &mcspi_attrib,
-};
-
-/*
- * 'spinlock' class
- * spinlock provides hardware assistance for synchronizing the
- * processes running on multiple processors
- */
-static struct omap_hwmod_class am33xx_spinlock_hwmod_class = {
-       .name           = "spinlock",
-};
-
-static struct omap_hwmod am33xx_spinlock_hwmod = {
-       .name           = "spinlock",
-       .class          = &am33xx_spinlock_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* 'timer 2-7' class */
-static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_timer_hwmod_class = {
-       .name           = "timer",
-       .sysc           = &am33xx_timer_sysc,
-};
-
-/* timer1 1ms */
-static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
-                       SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_timer1ms_hwmod_class = {
-       .name           = "timer",
-       .sysc           = &am33xx_timer1ms_sysc,
-};
-
-static struct omap_hwmod am33xx_timer1_hwmod = {
-       .name           = "timer1",
-       .class          = &am33xx_timer1ms_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .main_clk       = "timer1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_timer2_hwmod = {
-       .name           = "timer2",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer2_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_timer3_hwmod = {
-       .name           = "timer3",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer3_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_timer4_hwmod = {
-       .name           = "timer4",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer4_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_timer5_hwmod = {
-       .name           = "timer5",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer5_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_timer6_hwmod = {
-       .name           = "timer6",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer6_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_timer7_hwmod = {
-       .name           = "timer7",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer7_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* tpcc */
-static struct omap_hwmod_class am33xx_tpcc_hwmod_class = {
-       .name           = "tpcc",
-};
-
-static struct omap_hwmod am33xx_tpcc_hwmod = {
-       .name           = "tpcc",
-       .class          = &am33xx_tpcc_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x10,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                         SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-/* 'tptc' class */
-static struct omap_hwmod_class am33xx_tptc_hwmod_class = {
-       .name           = "tptc",
-       .sysc           = &am33xx_tptc_sysc,
-};
-
-/* tptc0 */
-static struct omap_hwmod am33xx_tptc0_hwmod = {
-       .name           = "tptc0",
-       .class          = &am33xx_tptc_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* tptc1 */
-static struct omap_hwmod am33xx_tptc1_hwmod = {
-       .name           = "tptc1",
-       .class          = &am33xx_tptc_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* tptc2 */
-static struct omap_hwmod am33xx_tptc2_hwmod = {
-       .name           = "tptc2",
-       .class          = &am33xx_tptc_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .flags          = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* 'uart' class */
-static struct omap_hwmod_class_sysconfig uart_sysc = {
-       .rev_offs       = 0x50,
-       .sysc_offs      = 0x54,
-       .syss_offs      = 0x58,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
-                         SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class uart_class = {
-       .name           = "uart",
-       .sysc           = &uart_sysc,
-};
-
-/* uart1 */
-static struct omap_hwmod am33xx_uart1_hwmod = {
-       .name           = "uart1",
-       .class          = &uart_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
-       .main_clk       = "dpll_per_m2_div4_wkupdm_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_uart2_hwmod = {
-       .name           = "uart2",
-       .class          = &uart_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_UART1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* uart3 */
-static struct omap_hwmod am33xx_uart3_hwmod = {
-       .name           = "uart3",
-       .class          = &uart_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_UART2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_uart4_hwmod = {
-       .name           = "uart4",
-       .class          = &uart_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_UART3_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_uart5_hwmod = {
-       .name           = "uart5",
-       .class          = &uart_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_UART4_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am33xx_uart6_hwmod = {
-       .name           = "uart6",
-       .class          = &uart_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_UART5_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* 'wd_timer' class */
-static struct omap_hwmod_class_sysconfig wdt_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x10,
-       .syss_offs      = 0x14,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                       SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = {
-       .name           = "wd_timer",
-       .sysc           = &wdt_sysc,
-       .pre_shutdown   = &omap2_wd_timer_disable,
-};
-
-/*
- * XXX: device.c file uses hardcoded name for watchdog timer
- * driver "wd_timer2, so we are also using same name as of now...
- */
-static struct omap_hwmod am33xx_wd_timer1_hwmod = {
-       .name           = "wd_timer2",
-       .class          = &am33xx_wd_timer_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE,
-       .main_clk       = "wdt1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'usb_otg' class
- * high-speed on-the-go universal serial bus (usb_otg) controller
- */
-static struct omap_hwmod_class_sysconfig am33xx_usbhsotg_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x10,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_usbotg_class = {
-       .name           = "usbotg",
-       .sysc           = &am33xx_usbhsotg_sysc,
-};
-
-static struct omap_hwmod am33xx_usbss_hwmod = {
-       .name           = "usb_otg_hs",
-       .class          = &am33xx_usbotg_class,
-       .clkdm_name     = "l3s_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-       .main_clk       = "usbotg_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_USB0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-
-/*
- * Interfaces
- */
-
-static struct omap_hwmod_addr_space am33xx_emif_addrs[] = {
-       {
-               .pa_start       = 0x4c000000,
-               .pa_end         = 0x4c000fff,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-/* l3 main -> emif */
-static struct omap_hwmod_ocp_if am33xx_l3_main__emif = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_emif_hwmod,
-       .clk            = "dpll_core_m4_ck",
-       .addr           = am33xx_emif_addrs,
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* mpu -> l3 main */
-static struct omap_hwmod_ocp_if am33xx_mpu__l3_main = {
-       .master         = &am33xx_mpu_hwmod,
-       .slave          = &am33xx_l3_main_hwmod,
-       .clk            = "dpll_mpu_m2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-/* l3 main -> l4 hs */
-static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_l4_hs_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 main -> l3 s */
-static struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_l3_s_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 s -> l4 per/ls */
-static struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am33xx_l4_ls_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 s -> l4 wkup */
-static struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am33xx_l4_wkup_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 main -> l3 instr */
-static struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_l3_instr_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* mpu -> prcm */
-static struct omap_hwmod_ocp_if am33xx_mpu__prcm = {
-       .master         = &am33xx_mpu_hwmod,
-       .slave          = &am33xx_prcm_hwmod,
-       .clk            = "dpll_mpu_m2_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 s -> l3 main*/
-static struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am33xx_l3_main_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* pru-icss -> l3 main */
-static struct omap_hwmod_ocp_if am33xx_pruss__l3_main = {
-       .master         = &am33xx_pruss_hwmod,
-       .slave          = &am33xx_l3_main_hwmod,
-       .clk            = "l3_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* wkup m3 -> l4 wkup */
-static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = {
-       .master         = &am33xx_wkup_m3_hwmod,
-       .slave          = &am33xx_l4_wkup_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* gfx -> l3 main */
-static struct omap_hwmod_ocp_if am33xx_gfx__l3_main = {
-       .master         = &am33xx_gfx_hwmod,
-       .slave          = &am33xx_l3_main_hwmod,
-       .clk            = "dpll_core_m4_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 wkup -> wkup m3 */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_wkup_m3_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 hs -> pru-icss */
-static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = {
-       .master         = &am33xx_l4_hs_hwmod,
-       .slave          = &am33xx_pruss_hwmod,
-       .clk            = "dpll_core_m4_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 main -> gfx */
-static struct omap_hwmod_ocp_if am33xx_l3_main__gfx = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_gfx_hwmod,
-       .clk            = "dpll_core_m4_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3_main -> debugss */
-static struct omap_hwmod_addr_space am33xx_debugss_addrs[] = {
-       {
-               .pa_start       = 0x4b000000,
-               .pa_end         = 0x4b000000 + SZ_16M - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_main__debugss = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_debugss_hwmod,
-       .clk            = "dpll_core_m4_ck",
-       .addr           = am33xx_debugss_addrs,
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 wkup -> smartreflex0 */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_smartreflex0_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 wkup -> smartreflex1 */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_smartreflex1_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 wkup -> control */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_control_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 wkup -> rtc */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_rtc_hwmod,
-       .clk            = "clkdiv32k_ick",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per/ls -> DCAN0 */
-static struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_dcan0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 per/ls -> DCAN1 */
-static struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_dcan1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 per/ls -> GPIO2 */
-static struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_gpio1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 per/ls -> gpio3 */
-static struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_gpio2_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 per/ls -> gpio4 */
-static struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_gpio3_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* L4 WKUP -> I2C1 */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_i2c1_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-/* L4 WKUP -> GPIO1 */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__gpio0 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_gpio0_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* L4 WKUP -> ADC_TSC */
-static struct omap_hwmod_addr_space am33xx_adc_tsc_addrs[] = {
-       {
-               .pa_start       = 0x44E0D000,
-               .pa_end         = 0x44E0D000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__adc_tsc = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_adc_tsc_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .addr           = am33xx_adc_tsc_addrs,
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = {
-       .master         = &am33xx_l4_hs_hwmod,
-       .slave          = &am33xx_cpgmac0_hwmod,
-       .clk            = "cpsw_125mhz_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = {
-       .master         = &am33xx_cpgmac0_hwmod,
-       .slave          = &am33xx_mdio_hwmod,
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = {
-       {
-               .pa_start       = 0x48080000,
-               .pa_end         = 0x48080000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__elm = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_elm_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_elm_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = {
-       {
-               .pa_start       = 0x48300000,
-               .pa_end         = 0x48300000 + SZ_16 - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_epwmss0_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_epwmss0_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
-       .master         = &am33xx_epwmss0_hwmod,
-       .slave          = &am33xx_ecap0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
-       .master         = &am33xx_epwmss0_hwmod,
-       .slave          = &am33xx_eqep0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
-       .master         = &am33xx_epwmss0_hwmod,
-       .slave          = &am33xx_ehrpwm0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-
-static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = {
+/* l3_main -> debugss */
+static struct omap_hwmod_addr_space am33xx_debugss_addrs[] = {
        {
-               .pa_start       = 0x48302000,
-               .pa_end         = 0x48302000 + SZ_16 - 1,
+               .pa_start       = 0x4b000000,
+               .pa_end         = 0x4b000000 + SZ_16M - 1,
                .flags          = ADDR_TYPE_RT
        },
        { }
 };
 
-static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_epwmss1_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_epwmss1_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
-       .master         = &am33xx_epwmss1_hwmod,
-       .slave          = &am33xx_ecap1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
-       .master         = &am33xx_epwmss1_hwmod,
-       .slave          = &am33xx_eqep1_hwmod,
-       .clk            = "l4ls_gclk",
+static struct omap_hwmod_ocp_if am33xx_l3_main__debugss = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_debugss_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .addr           = am33xx_debugss_addrs,
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
-       .master         = &am33xx_epwmss1_hwmod,
-       .slave          = &am33xx_ehrpwm1_hwmod,
-       .clk            = "l4ls_gclk",
+/* l4 wkup -> smartreflex0 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_smartreflex0_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = {
-       {
-               .pa_start       = 0x48304000,
-               .pa_end         = 0x48304000 + SZ_16 - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_epwmss2_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_epwmss2_addr_space,
+/* l4 wkup -> smartreflex1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_smartreflex1_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
-       .master         = &am33xx_epwmss2_hwmod,
-       .slave          = &am33xx_ecap2_hwmod,
-       .clk            = "l4ls_gclk",
+/* l4 wkup -> control */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_control_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
-       .master         = &am33xx_epwmss2_hwmod,
-       .slave          = &am33xx_eqep2_hwmod,
-       .clk            = "l4ls_gclk",
+/* L4 WKUP -> I2C1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_i2c1_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
-       .master         = &am33xx_epwmss2_hwmod,
-       .slave          = &am33xx_ehrpwm2_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
+/* L4 WKUP -> GPIO1 */
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__gpio0 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_gpio0_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l3s cfg -> gpmc */
-static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = {
+/* L4 WKUP -> ADC_TSC */
+static struct omap_hwmod_addr_space am33xx_adc_tsc_addrs[] = {
        {
-               .pa_start       = 0x50000000,
-               .pa_end         = 0x50000000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT,
+               .pa_start       = 0x44E0D000,
+               .pa_end         = 0x44E0D000 + SZ_8K - 1,
+               .flags          = ADDR_TYPE_RT
        },
        { }
 };
 
-static struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am33xx_gpmc_hwmod,
-       .clk            = "l3s_gclk",
-       .addr           = am33xx_gpmc_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* i2c2 */
-static struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_i2c2_hwmod,
-       .clk            = "l4ls_gclk",
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__adc_tsc = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_adc_tsc_hwmod,
+       .clk            = "dpll_core_m4_div2_ck",
+       .addr           = am33xx_adc_tsc_addrs,
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_i2c3_hwmod,
-       .clk            = "l4ls_gclk",
+static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = {
+       .master         = &am33xx_l4_hs_hwmod,
+       .slave          = &am33xx_cpgmac0_hwmod,
+       .clk            = "cpsw_125mhz_gclk",
        .user           = OCP_USER_MPU,
 };
 
@@ -2121,138 +483,6 @@ static struct omap_hwmod_ocp_if am33xx_l3_main__lcdc = {
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_mailbox_addrs[] = {
-       {
-               .pa_start       = 0x480C8000,
-               .pa_end         = 0x480C8000 + (SZ_4K - 1),
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-/* l4 ls -> mailbox */
-static struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mailbox_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_mailbox_addrs,
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> spinlock */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_spinlock_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcasp0 */
-static struct omap_hwmod_addr_space am33xx_mcasp0_addr_space[] = {
-       {
-               .pa_start       = 0x48038000,
-               .pa_end         = 0x48038000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mcasp0_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_mcasp0_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcasp1 */
-static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = {
-       {
-               .pa_start       = 0x4803C000,
-               .pa_end         = 0x4803C000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mcasp1_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_mcasp1_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mmc0 */
-static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = {
-       {
-               .pa_start       = 0x48060100,
-               .pa_end         = 0x48060100 + SZ_4K - 1,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mmc0_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_mmc0_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mmc1 */
-static struct omap_hwmod_addr_space am33xx_mmc1_addr_space[] = {
-       {
-               .pa_start       = 0x481d8100,
-               .pa_end         = 0x481d8100 + SZ_4K - 1,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mmc1_hwmod,
-       .clk            = "l4ls_gclk",
-       .addr           = am33xx_mmc1_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l3 s -> mmc2 */
-static struct omap_hwmod_addr_space am33xx_mmc2_addr_space[] = {
-       {
-               .pa_start       = 0x47810100,
-               .pa_end         = 0x47810100 + SZ_64K - 1,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_s__mmc2 = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am33xx_mmc2_hwmod,
-       .clk            = "l3s_gclk",
-       .addr           = am33xx_mmc2_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcspi0 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_spi0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcspi1 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_spi1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 wkup -> timer1 */
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = {
        .master         = &am33xx_l4_wkup_hwmod,
@@ -2261,116 +491,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 per -> timer2 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer2_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer3 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer3_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer4 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer4_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer5 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer5_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer6 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer6_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer7 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer7_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l3 main -> tpcc */
-static struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_tpcc_hwmod,
-       .clk            = "l3_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l3 main -> tpcc0 */
-static struct omap_hwmod_addr_space am33xx_tptc0_addr_space[] = {
-       {
-               .pa_start       = 0x49800000,
-               .pa_end         = 0x49800000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_tptc0_hwmod,
-       .clk            = "l3_gclk",
-       .addr           = am33xx_tptc0_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l3 main -> tpcc1 */
-static struct omap_hwmod_addr_space am33xx_tptc1_addr_space[] = {
-       {
-               .pa_start       = 0x49900000,
-               .pa_end         = 0x49900000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_tptc1_hwmod,
-       .clk            = "l3_gclk",
-       .addr           = am33xx_tptc1_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
-/* l3 main -> tpcc2 */
-static struct omap_hwmod_addr_space am33xx_tptc2_addr_space[] = {
-       {
-               .pa_start       = 0x49a00000,
-               .pa_end         = 0x49a00000 + SZ_8K - 1,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_tptc2_hwmod,
-       .clk            = "l3_gclk",
-       .addr           = am33xx_tptc2_addr_space,
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 wkup -> uart1 */
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = {
        .master         = &am33xx_l4_wkup_hwmod,
@@ -2379,46 +499,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 ls -> uart2 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_uart2_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> uart3 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_uart3_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> uart4 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_uart4_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> uart5 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_uart5_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> uart6 */
-static struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_uart6_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 wkup -> wd_timer1 */
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = {
        .master         = &am33xx_l4_wkup_hwmod,
@@ -2437,47 +517,39 @@ static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
        .flags          = OCPIF_SWSUP_IDLE,
 };
 
-/* l3 main -> ocmc */
-static struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_ocmcram_hwmod,
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 main -> sha0 HIB2 */
-static struct omap_hwmod_addr_space am33xx_sha0_addrs[] = {
-       {
-               .pa_start       = 0x53100000,
-               .pa_end         = 0x53100000 + SZ_512 - 1,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
+/* rng */
+static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = {
+       .rev_offs       = 0x1fe0,
+       .sysc_offs      = 0x1fe4,
+       .sysc_flags     = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
+       .idlemodes      = SIDLE_FORCE | SIDLE_NO,
+       .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
-static struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_sha0_hwmod,
-       .clk            = "sha0_fck",
-       .addr           = am33xx_sha0_addrs,
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+static struct omap_hwmod_class am33xx_rng_hwmod_class = {
+       .name           = "rng",
+       .sysc           = &am33xx_rng_sysc,
 };
 
-/* l3 main -> AES0 HIB2 */
-static struct omap_hwmod_addr_space am33xx_aes0_addrs[] = {
-       {
-               .pa_start       = 0x53500000,
-               .pa_end         = 0x53500000 + SZ_1M - 1,
-               .flags          = ADDR_TYPE_RT
+static struct omap_hwmod am33xx_rng_hwmod = {
+       .name           = "rng",
+       .class          = &am33xx_rng_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE,
+       .main_clk       = "rng_fck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
        },
-       { }
 };
 
-static struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_aes0_hwmod,
-       .clk            = "aes0_fck",
-       .addr           = am33xx_aes0_addrs,
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+static struct omap_hwmod_ocp_if am33xx_l4_per__rng = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am33xx_rng_hwmod,
+       .clk            = "rng_fck",
+       .user           = OCP_USER_MPU,
 };
 
 static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
@@ -2559,11 +631,13 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_cpgmac0__mdio,
        &am33xx_l3_main__sha0,
        &am33xx_l3_main__aes0,
+       &am33xx_l4_per__rng,
        NULL,
 };
 
 int __init am33xx_hwmod_init(void)
 {
+       omap_hwmod_am33xx_reg();
        omap_hwmod_init();
        return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs);
 }
index 0c3a427da5445a5d2f990e05f2f3fcec50634143..9e56fabd7fa3b834fbe09a463facd521592107a7 100644 (file)
@@ -3693,6 +3693,53 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__aes = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/*
+ * 'ssi' class
+ * synchronous serial interface (multichannel and full-duplex serial if)
+ */
+
+static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE |
+                          SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
+                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                          SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+                          MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_ssi_hwmod_class = {
+       .name   = "ssi",
+       .sysc   = &omap34xx_ssi_sysc,
+};
+
+static struct omap_hwmod omap34xx_ssi_hwmod = {
+       .name           = "ssi",
+       .class          = &omap34xx_ssi_hwmod_class,
+       .clkdm_name     = "core_l4_clkdm",
+       .main_clk       = "ssi_ssr_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id            = 1,
+                       .module_bit             = OMAP3430_EN_SSI_SHIFT,
+                       .module_offs            = CORE_MOD,
+                       .idlest_reg_id          = 1,
+                       .idlest_idle_bit        = OMAP3430ES2_ST_SSI_IDLE_SHIFT,
+               },
+       },
+};
+
+/* L4 CORE -> SSI */
+static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = {
+       .master         = &omap3xxx_l4_core_hwmod,
+       .slave          = &omap34xx_ssi_hwmod,
+       .clk            = "ssi_ick",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l3_main__l4_core,
        &omap3xxx_l3_main__l4_per,
@@ -3818,6 +3865,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = {
 #ifdef CONFIG_OMAP_IOMMU_IVA2
        &omap3xxx_l3_main__mmu_iva,
 #endif
+       &omap34xx_l4_core__ssi,
        NULL
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
new file mode 100644 (file)
index 0000000..9002fca
--- /dev/null
@@ -0,0 +1,758 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ *
+ * Hwmod present only in AM43x and those that differ other than register
+ * offsets as compared to AM335x.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include "omap_hwmod.h"
+#include "omap_hwmod_33xx_43xx_common_data.h"
+#include "prcm43xx.h"
+
+/* IP blocks */
+static struct omap_hwmod am43xx_l4_hs_hwmod = {
+       .name           = "l4_hs",
+       .class          = &am33xx_l4_hwmod_class,
+       .clkdm_name     = "l3_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "l4hs_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = {
+       { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 },
+};
+
+static struct omap_hwmod am43xx_wkup_m3_hwmod = {
+       .name           = "wkup_m3",
+       .class          = &am33xx_wkup_m3_hwmod_class,
+       .clkdm_name     = "l4_wkup_aon_clkdm",
+       /* Keep hardreset asserted */
+       .flags          = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+       .main_clk       = "sys_clkin_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET,
+                       .rstctrl_offs   = AM43XX_RM_WKUP_RSTCTRL_OFFSET,
+                       .rstst_offs     = AM43XX_RM_WKUP_RSTST_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .rst_lines      = am33xx_wkup_m3_resets,
+       .rst_lines_cnt  = ARRAY_SIZE(am33xx_wkup_m3_resets),
+};
+
+static struct omap_hwmod am43xx_control_hwmod = {
+       .name           = "control",
+       .class          = &am33xx_control_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "sys_clkin_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_opt_clk gpio0_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio0_dbclk" },
+};
+
+static struct omap_hwmod am43xx_gpio0_hwmod = {
+       .name           = "gpio1",
+       .class          = &am33xx_gpio_hwmod_class,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "sys_clkin_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = gpio0_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio0_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x4,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE,
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am43xx_synctimer_hwmod_class = {
+       .name   = "synctimer",
+       .sysc   = &am43xx_synctimer_sysc,
+};
+
+static struct omap_hwmod am43xx_synctimer_hwmod = {
+       .name           = "counter_32k",
+       .class          = &am43xx_synctimer_hwmod_class,
+       .clkdm_name     = "l4_wkup_aon_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE,
+       .main_clk       = "synctimer_32kclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_timer8_hwmod = {
+       .name           = "timer8",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer8_fck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_timer9_hwmod = {
+       .name           = "timer9",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer9_fck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_timer10_hwmod = {
+       .name           = "timer10",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer10_fck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_timer11_hwmod = {
+       .name           = "timer11",
+       .class          = &am33xx_timer_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "timer11_fck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_epwmss3_hwmod = {
+       .name           = "epwmss3",
+       .class          = &am33xx_epwmss_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_ehrpwm3_hwmod = {
+       .name           = "ehrpwm3",
+       .class          = &am33xx_ehrpwm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+static struct omap_hwmod am43xx_epwmss4_hwmod = {
+       .name           = "epwmss4",
+       .class          = &am33xx_epwmss_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_ehrpwm4_hwmod = {
+       .name           = "ehrpwm4",
+       .class          = &am33xx_ehrpwm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+static struct omap_hwmod am43xx_epwmss5_hwmod = {
+       .name           = "epwmss5",
+       .class          = &am33xx_epwmss_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_ehrpwm5_hwmod = {
+       .name           = "ehrpwm5",
+       .class          = &am33xx_ehrpwm_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+};
+
+static struct omap_hwmod am43xx_spi2_hwmod = {
+       .name           = "spi2",
+       .class          = &am33xx_spi_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mcspi_attrib,
+};
+
+static struct omap_hwmod am43xx_spi3_hwmod = {
+       .name           = "spi3",
+       .class          = &am33xx_spi_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mcspi_attrib,
+};
+
+static struct omap_hwmod am43xx_spi4_hwmod = {
+       .name           = "spi4",
+       .class          = &am33xx_spi_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "dpll_per_m2_div4_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mcspi_attrib,
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod am43xx_gpio4_hwmod = {
+       .name           = "gpio5",
+       .class          = &am33xx_gpio_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = gpio4_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio4_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+       { .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod am43xx_gpio5_hwmod = {
+       .name           = "gpio6",
+       .class          = &am33xx_gpio_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+       .main_clk       = "l4ls_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+       .opt_clks       = gpio5_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(gpio5_opt_clks),
+       .dev_attr       = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = {
+       .name   = "ocp2scp",
+};
+
+static struct omap_hwmod am43xx_ocp2scp0_hwmod = {
+       .name           = "ocp2scp0",
+       .class          = &am43xx_ocp2scp_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_ocp2scp1_hwmod = {
+       .name           = "ocp2scp1",
+       .class          = &am43xx_ocp2scp_hwmod_class,
+       .clkdm_name     = "l4ls_clkdm",
+       .main_clk       = "l4ls_gclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs   = AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .sysc_flags     = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE |
+                               SYSC_HAS_SIDLEMODE),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                               SIDLE_SMART_WKUP | MSTANDBY_FORCE |
+                               MSTANDBY_NO | MSTANDBY_SMART |
+                               MSTANDBY_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_usb_otg_ss_hwmod_class = {
+       .name   = "usb_otg_ss",
+       .sysc   = &am43xx_usb_otg_ss_sysc,
+};
+
+static struct omap_hwmod am43xx_usb_otg_ss0_hwmod = {
+       .name           = "usb_otg_ss0",
+       .class          = &am43xx_usb_otg_ss_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .main_clk       = "l3s_gclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs   = AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = {
+       .name           = "usb_otg_ss1",
+       .class          = &am43xx_usb_otg_ss_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .main_clk       = "l3s_gclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs   = AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = {
+       .sysc_offs      = 0x0010,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE,
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                               SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_qspi_hwmod_class = {
+       .name   = "qspi",
+       .sysc   = &am43xx_qspi_sysc,
+};
+
+static struct omap_hwmod am43xx_qspi_hwmod = {
+       .name           = "qspi",
+       .class          = &am43xx_qspi_hwmod_class,
+       .clkdm_name     = "l3s_clkdm",
+       .main_clk       = "l3s_gclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/* Interfaces */
+static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am43xx_l4_hs_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_wkup_m3__l4_wkup = {
+       .master         = &am43xx_wkup_m3_hwmod,
+       .slave          = &am33xx_l4_wkup_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__wkup_m3 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am43xx_wkup_m3_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_main__pruss = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am33xx_pruss_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex0 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_smartreflex0_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_smartreflex1_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am43xx_control_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__i2c1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_i2c1_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am43xx_gpio0_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = {
+       .master         = &am43xx_l4_hs_hwmod,
+       .slave          = &am33xx_cpgmac0_hwmod,
+       .clk            = "cpsw_125mhz_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_timer1_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__uart1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_uart1_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_wkup__wd_timer1 = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am33xx_wd_timer1_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = {
+       .master         = &am33xx_l4_wkup_hwmod,
+       .slave          = &am43xx_synctimer_hwmod,
+       .clk            = "sys_clkin_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer8 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_timer8_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer9 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_timer9_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer10 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_timer10_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer11 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_timer11_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_epwmss3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = {
+       .master         = &am43xx_epwmss3_hwmod,
+       .slave          = &am43xx_ehrpwm3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_epwmss4_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = {
+       .master         = &am43xx_epwmss4_hwmod,
+       .slave          = &am43xx_ehrpwm4_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_epwmss5_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = {
+       .master         = &am43xx_epwmss5_hwmod,
+       .slave          = &am43xx_ehrpwm5_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_spi2_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi3 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_spi3_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi4 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_spi4_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio4 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_gpio4_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio5 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_gpio5_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp0 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_ocp2scp0_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp1 = {
+       .master         = &am33xx_l4_ls_hwmod,
+       .slave          = &am43xx_ocp2scp1_hwmod,
+       .clk            = "l4ls_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am43xx_usb_otg_ss0_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am43xx_usb_otg_ss1_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3_s__qspi = {
+       .master         = &am33xx_l3_s_hwmod,
+       .slave          = &am43xx_qspi_hwmod,
+       .clk            = "l3s_gclk",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
+       &am33xx_l4_wkup__synctimer,
+       &am43xx_l4_ls__timer8,
+       &am43xx_l4_ls__timer9,
+       &am43xx_l4_ls__timer10,
+       &am43xx_l4_ls__timer11,
+       &am43xx_l4_ls__epwmss3,
+       &am43xx_epwmss3__ehrpwm3,
+       &am43xx_l4_ls__epwmss4,
+       &am43xx_epwmss4__ehrpwm4,
+       &am43xx_l4_ls__epwmss5,
+       &am43xx_epwmss5__ehrpwm5,
+       &am43xx_l4_ls__mcspi2,
+       &am43xx_l4_ls__mcspi3,
+       &am43xx_l4_ls__mcspi4,
+       &am43xx_l4_ls__gpio4,
+       &am43xx_l4_ls__gpio5,
+       &am43xx_l3_main__pruss,
+       &am33xx_mpu__l3_main,
+       &am33xx_mpu__prcm,
+       &am33xx_l3_s__l4_ls,
+       &am33xx_l3_s__l4_wkup,
+       &am43xx_l3_main__l4_hs,
+       &am33xx_l3_main__l3_s,
+       &am33xx_l3_main__l3_instr,
+       &am33xx_l3_main__gfx,
+       &am33xx_l3_s__l3_main,
+       &am33xx_pruss__l3_main,
+       &am43xx_wkup_m3__l4_wkup,
+       &am33xx_gfx__l3_main,
+       &am43xx_l4_wkup__wkup_m3,
+       &am43xx_l4_wkup__control,
+       &am43xx_l4_wkup__smartreflex0,
+       &am43xx_l4_wkup__smartreflex1,
+       &am43xx_l4_wkup__uart1,
+       &am43xx_l4_wkup__timer1,
+       &am43xx_l4_wkup__i2c1,
+       &am43xx_l4_wkup__gpio0,
+       &am43xx_l4_wkup__wd_timer1,
+       &am43xx_l3_s__qspi,
+       &am33xx_l4_per__dcan0,
+       &am33xx_l4_per__dcan1,
+       &am33xx_l4_per__gpio1,
+       &am33xx_l4_per__gpio2,
+       &am33xx_l4_per__gpio3,
+       &am33xx_l4_per__i2c2,
+       &am33xx_l4_per__i2c3,
+       &am33xx_l4_per__mailbox,
+       &am33xx_l4_ls__mcasp0,
+       &am33xx_l4_ls__mcasp1,
+       &am33xx_l4_ls__mmc0,
+       &am33xx_l4_ls__mmc1,
+       &am33xx_l3_s__mmc2,
+       &am33xx_l4_ls__timer2,
+       &am33xx_l4_ls__timer3,
+       &am33xx_l4_ls__timer4,
+       &am33xx_l4_ls__timer5,
+       &am33xx_l4_ls__timer6,
+       &am33xx_l4_ls__timer7,
+       &am33xx_l3_main__tpcc,
+       &am33xx_l4_ls__uart2,
+       &am33xx_l4_ls__uart3,
+       &am33xx_l4_ls__uart4,
+       &am33xx_l4_ls__uart5,
+       &am33xx_l4_ls__uart6,
+       &am33xx_l4_ls__elm,
+       &am33xx_l4_ls__epwmss0,
+       &am33xx_epwmss0__ecap0,
+       &am33xx_epwmss0__eqep0,
+       &am33xx_epwmss0__ehrpwm0,
+       &am33xx_l4_ls__epwmss1,
+       &am33xx_epwmss1__ecap1,
+       &am33xx_epwmss1__eqep1,
+       &am33xx_epwmss1__ehrpwm1,
+       &am33xx_l4_ls__epwmss2,
+       &am33xx_epwmss2__ecap2,
+       &am33xx_epwmss2__eqep2,
+       &am33xx_epwmss2__ehrpwm2,
+       &am33xx_l3_s__gpmc,
+       &am33xx_l4_ls__mcspi0,
+       &am33xx_l4_ls__mcspi1,
+       &am33xx_l3_main__tptc0,
+       &am33xx_l3_main__tptc1,
+       &am33xx_l3_main__tptc2,
+       &am33xx_l3_main__ocmc,
+       &am43xx_l4_hs__cpgmac0,
+       &am33xx_cpgmac0__mdio,
+       &am33xx_l3_main__sha0,
+       &am33xx_l3_main__aes0,
+       &am43xx_l4_ls__ocp2scp0,
+       &am43xx_l4_ls__ocp2scp1,
+       &am43xx_l3_s__usbotgss0,
+       &am43xx_l3_s__usbotgss1,
+       NULL,
+};
+
+int __init am43xx_hwmod_init(void)
+{
+       omap_hwmod_am43xx_reg();
+       omap_hwmod_init();
+       return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs);
+}
index 9c3b504477d7b341b4492ec350bb3404769fa219..1e5b12cb8246290cc8e2865036e0f4a291513f9c 100644 (file)
@@ -914,7 +914,7 @@ static struct omap_hwmod omap44xx_emif1_hwmod = {
        .name           = "emif1",
        .class          = &omap44xx_emif_hwmod_class,
        .clkdm_name     = "l3_emif_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "ddrphy_ck",
        .prcm = {
                .omap4 = {
@@ -930,7 +930,7 @@ static struct omap_hwmod omap44xx_emif2_hwmod = {
        .name           = "emif2",
        .class          = &omap44xx_emif_hwmod_class,
        .clkdm_name     = "l3_emif_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "ddrphy_ck",
        .prcm = {
                .omap4 = {
@@ -2193,7 +2193,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
        .name           = "mpu",
        .class          = &omap44xx_mpu_hwmod_class,
        .clkdm_name     = "mpuss_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "dpll_mpu_m2_ck",
        .prcm = {
                .omap4 = {
index cde415570e0465caffebba3b4edbac1976cf92ed..9e08d6994a0b09c44760e03323c9543f720ad026 100644 (file)
@@ -352,7 +352,7 @@ static struct omap_hwmod omap54xx_emif1_hwmod = {
        .name           = "emif1",
        .class          = &omap54xx_emif_hwmod_class,
        .clkdm_name     = "emif_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "dpll_core_h11x2_ck",
        .prcm = {
                .omap4 = {
@@ -368,7 +368,7 @@ static struct omap_hwmod omap54xx_emif2_hwmod = {
        .name           = "emif2",
        .class          = &omap54xx_emif_hwmod_class,
        .clkdm_name     = "emif_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "dpll_core_h11x2_ck",
        .prcm = {
                .omap4 = {
@@ -1135,7 +1135,7 @@ static struct omap_hwmod omap54xx_mpu_hwmod = {
        .name           = "mpu",
        .class          = &omap54xx_mpu_hwmod_class,
        .clkdm_name     = "mpu_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE,
        .main_clk       = "dpll_mpu_m2_ck",
        .prcm = {
                .omap4 = {
@@ -1145,6 +1145,77 @@ static struct omap_hwmod omap54xx_mpu_hwmod = {
        },
 };
 
+/*
+ * 'spinlock' class
+ * spinlock provides hardware assistance for synchronizing the processes
+ * running on multiple processors
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_spinlock_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+                          SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_spinlock_hwmod_class = {
+       .name   = "spinlock",
+       .sysc   = &omap54xx_spinlock_sysc,
+};
+
+/* spinlock */
+static struct omap_hwmod omap54xx_spinlock_hwmod = {
+       .name           = "spinlock",
+       .class          = &omap54xx_spinlock_hwmod_class,
+       .clkdm_name     = "l4cfg_clkdm",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET,
+                       .context_offs = OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET,
+               },
+       },
+};
+
+/*
+ * 'ocp2scp' class
+ * bridge to transform ocp interface protocol to scp (serial control port)
+ * protocol
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_ocp2scp_hwmod_class = {
+       .name   = "ocp2scp",
+       .sysc   = &omap54xx_ocp2scp_sysc,
+};
+
+/* ocp2scp1 */
+static struct omap_hwmod omap54xx_ocp2scp1_hwmod = {
+       .name           = "ocp2scp1",
+       .class          = &omap54xx_ocp2scp_hwmod_class,
+       .clkdm_name     = "l3init_clkdm",
+       .main_clk       = "l4_root_clk_div",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET,
+                       .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET,
+                       .modulemode   = MODULEMODE_HWCTRL,
+               },
+       },
+};
+
 /*
  * 'timer' class
  * general purpose timer module with accurate 1ms tick
@@ -1464,6 +1535,123 @@ static struct omap_hwmod omap54xx_uart6_hwmod = {
        },
 };
 
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
+                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                          SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+                          MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_usb_host_hs_hwmod_class = {
+       .name   = "usb_host_hs",
+       .sysc   = &omap54xx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod omap54xx_usb_host_hs_hwmod = {
+       .name           = "usb_host_hs",
+       .class          = &omap54xx_usb_host_hs_hwmod_class,
+       .clkdm_name     = "l3init_clkdm",
+       /*
+        * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
+        * id: i660
+        *
+        * Description:
+        * In the following configuration :
+        * - USBHOST module is set to smart-idle mode
+        * - PRCM asserts idle_req to the USBHOST module ( This typically
+        *   happens when the system is going to a low power mode : all ports
+        *   have been suspended, the master part of the USBHOST module has
+        *   entered the standby state, and SW has cut the functional clocks)
+        * - an USBHOST interrupt occurs before the module is able to answer
+        *   idle_ack, typically a remote wakeup IRQ.
+        * Then the USB HOST module will enter a deadlock situation where it
+        * is no more accessible nor functional.
+        *
+        * Workaround:
+        * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE
+        */
+
+       /*
+        * Errata: USB host EHCI may stall when entering smart-standby mode
+        * Id: i571
+        *
+        * Description:
+        * When the USBHOST module is set to smart-standby mode, and when it is
+        * ready to enter the standby state (i.e. all ports are suspended and
+        * all attached devices are in suspend mode), then it can wrongly assert
+        * the Mstandby signal too early while there are still some residual OCP
+        * transactions ongoing. If this condition occurs, the internal state
+        * machine may go to an undefined state and the USB link may be stuck
+        * upon the next resume.
+        *
+        * Workaround:
+        * Don't use smart standby; use only force standby,
+        * hence HWMOD_SWSUP_MSTANDBY
+        */
+
+       /*
+        * During system boot; If the hwmod framework resets the module
+        * the module will have smart idle settings; which can lead to deadlock
+        * (above Errata Id:i660); so, dont reset the module during boot;
+        * Use HWMOD_INIT_NO_RESET.
+        */
+
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY |
+                         HWMOD_INIT_NO_RESET,
+       .main_clk       = "l3init_60m_fclk",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET,
+                       .context_offs = OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET,
+                       .modulemode   = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_usb_tll_hs_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+                          SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_usb_tll_hs_hwmod_class = {
+       .name   = "usb_tll_hs",
+       .sysc   = &omap54xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod omap54xx_usb_tll_hs_hwmod = {
+       .name           = "usb_tll_hs",
+       .class          = &omap54xx_usb_tll_hs_hwmod_class,
+       .clkdm_name     = "l3init_clkdm",
+       .main_clk       = "l4_root_clk_div",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET,
+                       .context_offs = OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET,
+                       .modulemode   = MODULEMODE_HWCTRL,
+               },
+       },
+};
+
 /*
  * 'usb_otg_ss' class
  * 2.0 super speed (usb_otg_ss) controller
@@ -1960,6 +2148,22 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_cfg -> spinlock */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__spinlock = {
+       .master         = &omap54xx_l4_cfg_hwmod,
+       .slave          = &omap54xx_spinlock_hwmod,
+       .clk            = "l4_root_clk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> ocp2scp1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = {
+       .master         = &omap54xx_l4_cfg_hwmod,
+       .slave          = &omap54xx_ocp2scp1_hwmod,
+       .clk            = "l4_root_clk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* l4_wkup -> timer1 */
 static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = {
        .master         = &omap54xx_l4_wkup_hwmod,
@@ -2096,6 +2300,22 @@ static struct omap_hwmod_ocp_if omap54xx_l4_per__uart6 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_cfg -> usb_host_hs */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = {
+       .master         = &omap54xx_l4_cfg_hwmod,
+       .slave          = &omap54xx_usb_host_hs_hwmod,
+       .clk            = "l3_iclk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_tll_hs */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_tll_hs = {
+       .master         = &omap54xx_l4_cfg_hwmod,
+       .slave          = &omap54xx_usb_tll_hs_hwmod,
+       .clk            = "l4_root_clk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* l4_cfg -> usb_otg_ss */
 static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = {
        .master         = &omap54xx_l4_cfg_hwmod,
@@ -2163,6 +2383,8 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l4_per__mmc4,
        &omap54xx_l4_per__mmc5,
        &omap54xx_l4_cfg__mpu,
+       &omap54xx_l4_cfg__spinlock,
+       &omap54xx_l4_cfg__ocp2scp1,
        &omap54xx_l4_wkup__timer1,
        &omap54xx_l4_per__timer2,
        &omap54xx_l4_per__timer3,
@@ -2180,6 +2402,8 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l4_per__uart4,
        &omap54xx_l4_per__uart5,
        &omap54xx_l4_per__uart6,
+       &omap54xx_l4_cfg__usb_host_hs,
+       &omap54xx_l4_cfg__usb_tll_hs,
        &omap54xx_l4_cfg__usb_otg_ss,
        &omap54xx_l4_wkup__wd_timer2,
        NULL,
index bd41d59a7cab08ecbca342a665f5f944aa67b6bc..82fd8c72f7506da9d273aec79c9f038bc04bdfaa 100644 (file)
@@ -17,6 +17,7 @@
  * GNU General Public License for more details.
  */
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/opp.h>
 #include <linux/cpu.h>
 
@@ -40,6 +41,9 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
 {
        int i, r;
 
+       if (of_have_populated_dt())
+               return -EINVAL;
+
        if (!opp_def || !opp_def_size) {
                pr_err("%s: invalid params!\n", __func__);
                return -EINVAL;
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
new file mode 100644 (file)
index 0000000..10c7145
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Legacy platform_data quirks
+ *
+ * Copyright (C) 2013 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <linux/wl12xx.h>
+
+#include <linux/platform_data/pinctrl-single.h>
+
+#include "common.h"
+#include "common-board-devices.h"
+#include "dss-common.h"
+#include "control.h"
+
+struct pdata_init {
+       const char *compatible;
+       void (*fn)(void);
+};
+
+/*
+ * Create alias for USB host PHY clock.
+ * Remove this when clock phandle can be provided via DT
+ */
+static void __init __used legacy_init_ehci_clk(char *clkname)
+{
+       int ret;
+
+       ret = clk_add_alias("main_clk", NULL, clkname, NULL);
+       if (ret)
+               pr_err("%s:Failed to add main_clk alias to %s :%d\n",
+                      __func__, clkname, ret);
+}
+
+#if IS_ENABLED(CONFIG_WL12XX)
+
+static struct wl12xx_platform_data wl12xx __initdata;
+
+static void __init __used legacy_init_wl12xx(unsigned ref_clock,
+                                            unsigned tcxo_clock,
+                                            int gpio)
+{
+       int res;
+
+       wl12xx.board_ref_clock = ref_clock;
+       wl12xx.board_tcxo_clock = tcxo_clock;
+       wl12xx.irq = gpio_to_irq(gpio);
+
+       res = wl12xx_set_platform_data(&wl12xx);
+       if (res) {
+               pr_err("error setting wl12xx data: %d\n", res);
+               return;
+       }
+}
+#else
+static inline void legacy_init_wl12xx(unsigned ref_clock,
+                                     unsigned tcxo_clock,
+                                     int gpio)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static void __init hsmmc2_internal_input_clk(void)
+{
+       u32 reg;
+
+       reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
+       reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+       omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1);
+}
+
+static void __init omap3_igep0020_legacy_init(void)
+{
+       omap3_igep2_display_init_of();
+}
+
+static void __init omap3_evm_legacy_init(void)
+{
+       legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149);
+}
+
+static void __init omap3_zoom_legacy_init(void)
+{
+       legacy_init_wl12xx(WL12XX_REFCLOCK_26, 0, 162);
+}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+#ifdef CONFIG_ARCH_OMAP4
+static void __init omap4_sdp_legacy_init(void)
+{
+       omap_4430sdp_display_init_of();
+       legacy_init_wl12xx(WL12XX_REFCLOCK_26,
+                          WL12XX_TCXOCLOCK_26, 53);
+}
+
+static void __init omap4_panda_legacy_init(void)
+{
+       omap4_panda_display_init_of();
+       legacy_init_ehci_clk("auxclk3_ck");
+       legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53);
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP5
+static void __init omap5_uevm_legacy_init(void)
+{
+       legacy_init_ehci_clk("auxclk1_ck");
+}
+#endif
+
+static struct pcs_pdata pcs_pdata;
+
+void omap_pcs_legacy_init(int irq, void (*rearm)(void))
+{
+       pcs_pdata.irq = irq;
+       pcs_pdata.rearm = rearm;
+}
+
+struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
+#ifdef CONFIG_ARCH_OMAP3
+       OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
+       OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata),
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+       OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
+       OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
+#endif
+       { /* sentinel */ },
+};
+
+static struct pdata_init pdata_quirks[] __initdata = {
+#ifdef CONFIG_ARCH_OMAP3
+       { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
+       { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
+       { "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
+       { "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
+       { "ti,omap3-zoom3", omap3_zoom_legacy_init, },
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+       { "ti,omap4-sdp", omap4_sdp_legacy_init, },
+       { "ti,omap4-panda", omap4_panda_legacy_init, },
+#endif
+#ifdef CONFIG_SOC_OMAP5
+       { "ti,omap5-uevm", omap5_uevm_legacy_init, },
+#endif
+       { /* sentinel */ },
+};
+
+void __init pdata_quirks_init(struct of_device_id *omap_dt_match_table)
+{
+       struct pdata_init *quirks = pdata_quirks;
+
+       omap_sdrc_init(NULL, NULL);
+       of_platform_populate(NULL, omap_dt_match_table,
+                            omap_auxdata_lookup, NULL);
+
+       while (quirks->compatible) {
+               if (of_machine_is_compatible(quirks->compatible)) {
+                       if (quirks->fn)
+                               quirks->fn();
+                       break;
+               }
+               quirks++;
+       }
+}
index e742118fcfd2b69adc367057e6f17670a5136903..360b2daf54ddb2be644925d5a13d7772e81307c1 100644 (file)
@@ -266,7 +266,12 @@ static void __init omap4_init_voltages(void)
 
 static inline void omap_init_cpufreq(void)
 {
-       struct platform_device_info devinfo = { .name = "omap-cpufreq", };
+       struct platform_device_info devinfo = { };
+
+       if (!of_have_populated_dt())
+               devinfo.name = "omap-cpufreq";
+       else
+               devinfo.name = "cpufreq-cpu0";
        platform_device_register_full(&devinfo);
 }
 
@@ -300,10 +305,11 @@ int __init omap2_common_pm_late_init(void)
                /* Smartreflex device init */
                omap_devinit_smartreflex();
 
-               /* cpufreq dummy device instantiation */
-               omap_init_cpufreq();
        }
 
+       /* cpufreq dummy device instantiation */
+       omap_init_cpufreq();
+
 #ifdef CONFIG_SUSPEND
        suspend_set_ops(&omap_pm_ops);
 #endif
index ce956b0a7ba4acfdfe3527547fa31582cf7bdf26..8c0759496c8d955c307cff12c5b208e5667c8f13 100644 (file)
@@ -62,16 +62,6 @@ static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm;
 
 static struct clk *osc_ck, *emul_ck;
 
-static int omap2_fclks_active(void)
-{
-       u32 f1, f2;
-
-       f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
-       f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
-
-       return (f1 | f2) ? 1 : 0;
-}
-
 static int omap2_enter_full_retention(void)
 {
        u32 l;
@@ -142,17 +132,7 @@ static int sti_console_enabled;
 
 static int omap2_allow_mpu_retention(void)
 {
-       u32 l;
-
-       /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
-       l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
-       if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK |
-                OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK |
-                OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK))
-               return 0;
-       /* Check for UART3. */
-       l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
-       if (l & OMAP24XX_EN_UART3_MASK)
+       if (!omap2xxx_cm_mpu_retention_allowed())
                return 0;
        if (sti_console_enabled)
                return 0;
@@ -188,7 +168,7 @@ static void omap2_enter_mpu_retention(void)
 
 static int omap2_can_sleep(void)
 {
-       if (omap2_fclks_active())
+       if (omap2xxx_cm_fclks_active())
                return 0;
        if (__clk_is_enabled(osc_ck))
                return 0;
index 5a2d8034c8def0462fc9464c0b765ba3d62f9efb..93b80e5da8d4d5888982b30ffed5d5dc5f2cc470 100644 (file)
@@ -430,8 +430,7 @@ static void __init omap3_iva_idle(void)
                         OMAP3430_IVA2_MOD, CM_FCLKEN);
 
        /* Set IVA2 boot mode to 'idle' */
-       omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
-                        OMAP343X_CONTROL_IVA2_BOOTMOD);
+       omap3_ctrl_set_iva_bootmode_idle();
 
        /* Un-reset IVA2 */
        omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
index baf3d8bf6beabcf51c50fca4d56ca4e33f667024..da5a59ae77b6d0f5b752ebf0be3ae950d71acb49 100644 (file)
@@ -257,6 +257,7 @@ extern void am33xx_powerdomains_init(void);
 extern void omap44xx_powerdomains_init(void);
 extern void omap54xx_powerdomains_init(void);
 extern void dra7xx_powerdomains_init(void);
+void am43xx_powerdomains_init(void);
 
 extern struct pwrdm_ops omap2_pwrdm_operations;
 extern struct pwrdm_ops omap3_pwrdm_operations;
diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c
new file mode 100644 (file)
index 0000000..95fee54
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * AM43xx Power domains framework
+ *
+ * Copyright (C) 2013 Texas Instruments, 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "powerdomain.h"
+
+#include "prcm-common.h"
+#include "prcm44xx.h"
+#include "prcm43xx.h"
+
+static struct powerdomain gfx_43xx_pwrdm = {
+       .name             = "gfx_pwrdm",
+       .voltdm           = { .name = "core" },
+       .prcm_offs        = AM43XX_PRM_GFX_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_OFF_ON,
+       .banks            = 1,
+       .pwrsts_mem_on  = {
+               [0] = PWRSTS_ON,        /* gfx_mem */
+       },
+       .flags            = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain mpu_43xx_pwrdm = {
+       .name             = "mpu_pwrdm",
+       .voltdm           = { .name = "mpu" },
+       .prcm_offs        = AM43XX_PRM_MPU_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRSTS_OFF_RET,
+       .banks            = 3,
+       .pwrsts_mem_ret = {
+               [0] = PWRSTS_OFF_RET,   /* mpu_l1 */
+               [1] = PWRSTS_OFF_RET,   /* mpu_l2 */
+               [2] = PWRSTS_OFF_RET,   /* mpu_ram */
+       },
+       .pwrsts_mem_on  = {
+               [0] = PWRSTS_ON,        /* mpu_l1 */
+               [1] = PWRSTS_ON,        /* mpu_l2 */
+               [2] = PWRSTS_ON,        /* mpu_ram */
+       },
+       .flags            = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain rtc_43xx_pwrdm = {
+       .name             = "rtc_pwrdm",
+       .voltdm           = { .name = "rtc" },
+       .prcm_offs        = AM43XX_PRM_RTC_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_ON,
+};
+
+static struct powerdomain wkup_43xx_pwrdm = {
+       .name             = "wkup_pwrdm",
+       .voltdm           = { .name = "core" },
+       .prcm_offs        = AM43XX_PRM_WKUP_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_ON,
+       .banks            = 1,
+       .pwrsts_mem_on  = {
+               [0] = PWRSTS_ON,        /* debugss_mem */
+       },
+};
+
+static struct powerdomain tamper_43xx_pwrdm = {
+       .name             = "tamper_pwrdm",
+       .voltdm           = { .name = "tamper" },
+       .prcm_offs        = AM43XX_PRM_TAMPER_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_ON,
+};
+
+static struct powerdomain cefuse_43xx_pwrdm = {
+       .name             = "cefuse_pwrdm",
+       .voltdm           = { .name = "core" },
+       .prcm_offs        = AM43XX_PRM_CEFUSE_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_OFF_ON,
+       .flags            = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain per_43xx_pwrdm = {
+       .name             = "per_pwrdm",
+       .voltdm           = { .name = "core" },
+       .prcm_offs        = AM43XX_PRM_PER_INST,
+       .prcm_partition   = AM43XX_PRM_PARTITION,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRSTS_OFF_RET,
+       .banks            = 4,
+       .pwrsts_mem_ret = {
+               [0] = PWRSTS_OFF_RET,   /* icss_mem */
+               [1] = PWRSTS_OFF_RET,   /* per_mem */
+               [2] = PWRSTS_OFF_RET,   /* ram1_mem */
+               [3] = PWRSTS_OFF_RET,   /* ram2_mem */
+       },
+       .pwrsts_mem_on  = {
+               [0] = PWRSTS_ON,        /* icss_mem */
+               [1] = PWRSTS_ON,        /* per_mem */
+               [2] = PWRSTS_ON,        /* ram1_mem */
+               [3] = PWRSTS_ON,        /* ram2_mem */
+       },
+       .flags            = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+static struct powerdomain *powerdomains_am43xx[] __initdata = {
+       &gfx_43xx_pwrdm,
+       &mpu_43xx_pwrdm,
+       &rtc_43xx_pwrdm,
+       &wkup_43xx_pwrdm,
+       &tamper_43xx_pwrdm,
+       &cefuse_43xx_pwrdm,
+       &per_43xx_pwrdm,
+       NULL
+};
+
+static int am43xx_check_vcvp(void)
+{
+       return 0;
+}
+
+void __init am43xx_powerdomains_init(void)
+{
+       omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp;
+       pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+       pwrdm_register_pwrdms(powerdomains_am43xx);
+       pwrdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h
new file mode 100644 (file)
index 0000000..7785be9
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * AM43x PRCM defines
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H
+
+#define AM43XX_PRM_PARTITION                           1
+#define AM43XX_CM_PARTITION                            1
+
+/* PRM instances */
+#define AM43XX_PRM_OCP_SOCKET_INST                     0x0000
+#define AM43XX_PRM_MPU_INST                            0x0300
+#define AM43XX_PRM_GFX_INST                            0x0400
+#define AM43XX_PRM_RTC_INST                            0x0500
+#define AM43XX_PRM_TAMPER_INST                         0x0600
+#define AM43XX_PRM_CEFUSE_INST                         0x0700
+#define AM43XX_PRM_PER_INST                            0x0800
+#define AM43XX_PRM_WKUP_INST                           0x2000
+#define AM43XX_PRM_DEVICE_INST                         0x4000
+
+/* RM RSTCTRL offsets */
+#define AM43XX_RM_PER_RSTCTRL_OFFSET                   0x0010
+#define AM43XX_RM_GFX_RSTCTRL_OFFSET                   0x0010
+#define AM43XX_RM_WKUP_RSTCTRL_OFFSET                  0x0010
+
+/* RM RSTST offsets */
+#define AM43XX_RM_GFX_RSTST_OFFSET                     0x0014
+#define AM43XX_RM_WKUP_RSTST_OFFSET                    0x0014
+
+/* CM instances */
+#define AM43XX_CM_WKUP_INST                            0x2800
+#define AM43XX_CM_DEVICE_INST                          0x4100
+#define AM43XX_CM_DPLL_INST                            0x4200
+#define AM43XX_CM_MPU_INST                             0x8300
+#define AM43XX_CM_GFX_INST                             0x8400
+#define AM43XX_CM_RTC_INST                             0x8500
+#define AM43XX_CM_TAMPER_INST                          0x8600
+#define AM43XX_CM_CEFUSE_INST                          0x8700
+#define AM43XX_CM_PER_INST                             0x8800
+
+/* CD offsets */
+#define AM43XX_CM_WKUP_L3_AON_CDOFFS                   0x0000
+#define AM43XX_CM_WKUP_L3S_TSC_CDOFFS                  0x0100
+#define AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS              0x0200
+#define AM43XX_CM_WKUP_WKUP_CDOFFS                     0x0300
+#define AM43XX_CM_MPU_MPU_CDOFFS                       0x0000
+#define AM43XX_CM_GFX_GFX_L3_CDOFFS                    0x0000
+#define AM43XX_CM_RTC_RTC_CDOFFS                       0x0000
+#define AM43XX_CM_TAMPER_TAMPER_CDOFFS                 0x0000
+#define AM43XX_CM_CEFUSE_CEFUSE_CDOFFS                 0x0000
+#define AM43XX_CM_PER_L3_CDOFFS                                0x0000
+#define AM43XX_CM_PER_L3S_CDOFFS                       0x0200
+#define AM43XX_CM_PER_ICSS_CDOFFS                      0x0300
+#define AM43XX_CM_PER_L4LS_CDOFFS                      0x0400
+#define AM43XX_CM_PER_EMIF_CDOFFS                      0x0700
+#define AM43XX_CM_PER_DSS_CDOFFS                       0x0a00
+#define AM43XX_CM_PER_CPSW_CDOFFS                      0x0b00
+#define AM43XX_CM_PER_OCPWP_L3_CDOFFS                  0x0c00
+
+/* CLK CTRL offsets */
+#define AM43XX_CM_PER_UART1_CLKCTRL_OFFSET             0x0580
+#define AM43XX_CM_PER_UART2_CLKCTRL_OFFSET             0x0588
+#define AM43XX_CM_PER_UART3_CLKCTRL_OFFSET             0x0590
+#define AM43XX_CM_PER_UART4_CLKCTRL_OFFSET             0x0598
+#define AM43XX_CM_PER_UART5_CLKCTRL_OFFSET             0x05a0
+#define AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET             0x0428
+#define AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET             0x0430
+#define AM43XX_CM_PER_ELM_CLKCTRL_OFFSET               0x0468
+#define AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET           0x0438
+#define AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET           0x0440
+#define AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET           0x0448
+#define AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET             0x0478
+#define AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET             0x0480
+#define AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET             0x0488
+#define AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET              0x04a8
+#define AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET              0x04b0
+#define AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET          0x04b8
+#define AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET              0x04c0
+#define AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET              0x04c8
+#define AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET              0x0500
+#define AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET              0x0508
+#define AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET          0x0528
+#define AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET            0x0530
+#define AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET            0x0538
+#define AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET            0x0540
+#define AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET            0x0548
+#define AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET            0x0550
+#define AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET            0x0558
+#define AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET          0x0228
+#define AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET          0x0360
+#define AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET     0x0350
+#define AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET     0x0358
+#define AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET            0x0348
+#define AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET           0x0328
+#define AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET             0x0340
+#define AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET            0x0368
+#define AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET          0x0120
+#define AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET             0x0338
+#define AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET           0x0220
+#define AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET               0x0020
+#define AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET              0x0248
+#define AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET               0x0258
+#define AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET              0x0220
+#define AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET            0x0238
+#define AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET            0x0240
+#define AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET              0x0420
+#define AM43XX_CM_PER_L3_CLKCTRL_OFFSET                        0x0020
+#define AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET              0x0078
+#define AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET             0x0080
+#define AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET             0x0088
+#define AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET             0x0090
+#define AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET           0x0b20
+#define AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET             0x0320
+#define AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET               0x0020
+#define AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET              0x00a0
+#define AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET               0x0020
+#define AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET          0x0040
+#define AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET           0x0050
+#define AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET              0x0058
+#define AM43XX_CM_PER_AES0_CLKCTRL_OFFSET              0x0028
+#define AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET            0x0560
+#define AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET            0x0568
+#define AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET           0x0570
+#define AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET           0x0578
+#define AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET                0x0230
+#define AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET           0x0450
+#define AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET           0x0458
+#define AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET           0x0460
+#define AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET              0x0510
+#define AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET              0x0518
+#define AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET              0x0520
+#define AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET             0x0490
+#define AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET             0x0498
+#define AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET       0x0260
+#define AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET    0x05B8
+#define AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET        0x0268
+#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET    0x05C0
+
+#endif
index 277f71794e61adc9016212de3f9ae05efb87fd1c..f8eb83323b1a068271c5e222471706bb5d1c1708 100644 (file)
@@ -144,7 +144,13 @@ extern u32 omap3_prm_vcvp_read(u8 offset);
 extern void omap3_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
-extern void omap3xxx_prm_reconfigure_io_chain(void);
+#ifdef CONFIG_ARCH_OMAP3
+void omap3xxx_prm_reconfigure_io_chain(void);
+#else
+static inline void omap3xxx_prm_reconfigure_io_chain(void)
+{
+}
+#endif
 
 /* PRM interrupt-related functions */
 extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
index 7cd22abb8f15b54628dbc96b872fea903c7cdb95..a085d9cc1f5d0c01fbe02e2f490e18037e450a33 100644 (file)
@@ -42,7 +42,13 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
 extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
-extern void omap44xx_prm_reconfigure_io_chain(void);
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+void omap44xx_prm_reconfigure_io_chain(void);
+#else
+static inline void omap44xx_prm_reconfigure_io_chain(void)
+{
+}
+#endif
 
 /* PRM interrupt-related functions */
 extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
index 228b850e632f6be77894b9d75a7162a105fd6889..a2e1174ad1b6a6632ad904e4a0b8c5f37dea1e79 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 
+#include "soc.h"
 #include "prm2xxx_3xxx.h"
 #include "prm2xxx.h"
 #include "prm3xxx.h"
@@ -322,6 +323,16 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
                prcm_irq_chips[i] = gc;
        }
 
+       if (of_have_populated_dt()) {
+               int irq = omap_prcm_event_to_irq("io");
+               if (cpu_is_omap34xx())
+                       omap_pcs_legacy_init(irq,
+                               omap3xxx_prm_reconfigure_io_chain);
+               else
+                       omap_pcs_legacy_init(irq,
+                               omap44xx_prm_reconfigure_io_chain);
+       }
+
        return 0;
 
 err:
index 4588df1447ed74bd4512ca6889a8f6f9a42102fb..076bd90a6ce0aca8d30914432c293dee1dbb071d 100644 (file)
@@ -455,9 +455,7 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define OMAP4470_REV_ES1_0     (OMAP447X_CLASS | (0x10 << 8))
 
 #define OMAP54XX_CLASS         0x54000054
-#define OMAP5430_REV_ES1_0     (OMAP54XX_CLASS | (0x30 << 16) | (0x10 << 8))
 #define OMAP5430_REV_ES2_0     (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8))
-#define OMAP5432_REV_ES1_0     (OMAP54XX_CLASS | (0x32 << 16) | (0x10 << 8))
 #define OMAP5432_REV_ES2_0     (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8))
 
 void omap2xxx_check_revision(void);
index ead48fa5715e16fb197dfa4fac56b0f71069bd20..3ca81e0ada5e228e083ed591f0976174e2e6b972 100644 (file)
@@ -55,6 +55,7 @@
 #include "soc.h"
 #include "common.h"
 #include "powerdomain.h"
+#include "omap-secure.h"
 
 #define REALTIME_COUNTER_BASE                          0x48243200
 #define INCREMENTER_NUMERATOR_OFFSET                   0x10
 static struct omap_dm_timer clkev;
 static struct clock_event_device clockevent_gpt;
 
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
+static unsigned long arch_timer_freq;
+
+void set_cntfreq(void)
+{
+       omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq);
+}
+#endif
+
 static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 {
        struct clock_event_device *evt = &clockevent_gpt;
@@ -78,7 +88,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction omap2_gp_timer_irq = {
        .name           = "gp_timer",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = omap2_gp_timer_interrupt,
 };
 
@@ -515,6 +525,10 @@ static void __init realtime_counter_init(void)
                num = 8;
                den = 25;
                break;
+       case 20000000:
+               num = 192;
+               den = 625;
+               break;
        case 2600000:
                num = 384;
                den = 1625;
@@ -542,6 +556,9 @@ static void __init realtime_counter_init(void)
        reg |= den;
        __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
 
+       arch_timer_freq = (rate / den) * num;
+       set_cntfreq();
+
        iounmap(base);
 }
 #else
index c05898fbd634a813542ab0c0b6e8b86586a6a0ee..b0d54dae1bcb536d818df84ad7642ba123a65ef5 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/i2c/twl.h>
 #include <linux/gpio.h>
 #include <linux/string.h>
+#include <linux/phy/phy.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 
@@ -90,8 +91,18 @@ void __init omap_pmic_late_init(void)
 }
 
 #if defined(CONFIG_ARCH_OMAP3)
+struct phy_consumer consumers[] = {
+       PHY_CONSUMER("musb-hdrc.0", "usb"),
+};
+
+struct phy_init_data init_data = {
+       .consumers = consumers,
+       .num_consumers = ARRAY_SIZE(consumers),
+};
+
 static struct twl4030_usb_data omap3_usb_pdata = {
        .usb_mode       = T2_USB_MODE_ULPI,
+       .init_data      = &init_data,
 };
 
 static int omap3_batt_table[] = {
index e83a6a4b184af23c315a5e509a56ba8362d820e7..10855eb4ccc1c7ed8bd712a22cf418f7265d6567 100644 (file)
@@ -435,6 +435,7 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
        struct platform_device *pdev;
        char *phy_id;
        struct platform_device_info pdevinfo;
+       struct usb_phy_gen_xceiv_platform_data nop_pdata;
 
        for (i = 0; i < num_phys; i++) {
 
@@ -455,11 +456,18 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
                        return -ENOMEM;
                }
 
+               /* set platform data */
+               memset(&nop_pdata, 0, sizeof(nop_pdata));
+               if (gpio_is_valid(phy->vcc_gpio))
+                       nop_pdata.needs_vcc = true;
+               nop_pdata.gpio_reset = phy->reset_gpio;
+               nop_pdata.type = USB_PHY_TYPE_USB2;
+
                /* create a NOP PHY device */
                memset(&pdevinfo, 0, sizeof(pdevinfo));
                pdevinfo.name = nop_name;
                pdevinfo.id = phy->port;
-               pdevinfo.data = phy->platform_data;
+               pdevinfo.data = &nop_pdata;
                pdevinfo.size_data =
                        sizeof(struct usb_phy_gen_xceiv_platform_data);
                scnprintf(phy_id, MAX_STR, "usb_phy_gen_xceiv.%d",
@@ -474,14 +482,6 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
 
                usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
 
-               /* Do we need RESET regulator ? */
-               if (gpio_is_valid(phy->reset_gpio)) {
-                       scnprintf(rail_name, MAX_STR,
-                                       "hsusb%d_reset", phy->port);
-                       usbhs_add_regulator(rail_name, phy_id, "reset",
-                                               phy->reset_gpio, 1);
-               }
-
                /* Do we need VCC regulator ? */
                if (gpio_is_valid(phy->vcc_gpio)) {
                        scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port);
index e7261ebcf7b02ba83c4e4fe672d132636aeb841e..4ba2ae759895a1e7db30edc440560cacf3f1b1c0 100644 (file)
@@ -58,7 +58,6 @@ struct usbhs_phy_data {
        int reset_gpio;
        int vcc_gpio;
        bool vcc_polarity;      /* 1 active high, 0 active low */
-       void *platform_data;
 };
 
 extern void usb_musb_init(struct omap_musb_board_data *board_data);
index e110b6d4ae8cd0fc81a654ac4af1113758836515..d49aff74de98a778c14dfc495718adfc6e15fdb6 100644 (file)
@@ -6,7 +6,6 @@
  * Licensed under GPLv2 or later.
  */
 
-#include <linux/clocksource.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <asm/sizes.h>
@@ -21,13 +20,6 @@ void __init sirfsoc_init_late(void)
        sirfsoc_pm_init();
 }
 
-static __init void sirfsoc_init_time(void)
-{
-       /* initialize clocking early, we want to set the OS timer */
-       sirfsoc_of_clk_init();
-       clocksource_of_init();
-}
-
 static __init void sirfsoc_map_io(void)
 {
        sirfsoc_map_lluart();
@@ -43,7 +35,6 @@ static const char *atlas6_dt_match[] __initdata = {
 DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)")
        /* Maintainer: Barry Song <baohua.song@csr.com> */
        .map_io         = sirfsoc_map_io,
-       .init_time      = sirfsoc_init_time,
        .init_late      = sirfsoc_init_late,
        .dt_compat      = atlas6_dt_match,
        .restart        = sirfsoc_restart,
@@ -59,7 +50,6 @@ static const char *prima2_dt_match[] __initdata = {
 DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
        /* Maintainer: Barry Song <baohua.song@csr.com> */
        .map_io         = sirfsoc_map_io,
-       .init_time      = sirfsoc_init_time,
        .dma_zone_size  = SZ_256M,
        .init_late      = sirfsoc_init_late,
        .dt_compat      = prima2_dt_match,
@@ -77,7 +67,6 @@ DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)")
        /* Maintainer: Barry Song <baohua.song@csr.com> */
        .smp            = smp_ops(sirfsoc_smp_ops),
        .map_io         = sirfsoc_map_io,
-       .init_time      = sirfsoc_init_time,
        .init_late      = sirfsoc_init_late,
        .dt_compat      = marco_dt_match,
        .restart        = sirfsoc_restart,
index a6304858474aa202c1d23860aee61329f713831b..4b768060a858e98c51a085e192cf0e6c43a3c198 100644 (file)
@@ -23,7 +23,6 @@ extern void sirfsoc_secondary_startup(void);
 extern void sirfsoc_cpu_die(unsigned int cpu);
 
 extern void __init sirfsoc_of_irq_init(void);
-extern void __init sirfsoc_of_clk_init(void);
 extern void sirfsoc_restart(enum reboot_mode, const char *);
 extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
 
index 25ee12b21f0180f8cfcbead0377f2a0c3e71d80a..cf073dea5784b3c0fa125f1931305c55706f81e3 100644 (file)
@@ -5,12 +5,13 @@ config ARCH_ROCKCHIP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_GIC
        select CACHE_L2X0
-       select HAVE_ARM_TWD if LOCAL_TIMERS
+       select HAVE_ARM_TWD if SMP
        select HAVE_SMP
-       select LOCAL_TIMERS if SMP
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select DW_APB_TIMER_OF
+       select ARM_GLOBAL_TIMER
+       select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
        help
          Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs
          containing the RK2928, RK30xx and RK31xx series.
index 724d2d81f976131d43a43704f009d948af0025eb..82c0b0709712465774b2824eef96a8572edb7f51 100644 (file)
 #include <linux/init.h>
 #include <linux/of_platform.h>
 #include <linux/irqchip.h>
-#include <linux/dw_apb_timer.h>
-#include <linux/clk-provider.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/cache-l2x0.h>
 
-static void __init rockchip_timer_init(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
 static void __init rockchip_dt_init(void)
 {
        l2x0_of_init(0, ~0UL);
@@ -47,6 +39,5 @@ static const char * const rockchip_board_dt_compat[] = {
 
 DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
        .init_machine   = rockchip_dt_init,
-       .init_time      = rockchip_timer_init,
        .dt_compat      = rockchip_board_dt_compat,
 MACHINE_END
index dba2173e70f3aceb69947dd06f9653b39deadbb7..8f1d327e0cd1566286a5f6530569dbf1bc530ca4 100644 (file)
@@ -28,6 +28,7 @@ config CPU_S3C2410
        select CPU_ARM920T
        select CPU_LLSERIAL_S3C2410
        select S3C2410_CLOCK
+       select S3C2410_DMA if S3C24XX_DMA
        select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
        select S3C2410_PM if PM
        select SAMSUNG_WDT_RESET
@@ -70,6 +71,7 @@ config CPU_S3C2442
        select CPU_ARM920T
        select CPU_LLSERIAL_S3C2440
        select S3C2410_CLOCK
+       select S3C2410_DMA if S3C24XX_DMA
        select S3C2410_PM if PM
        help
          Support for S3C2442 Samsung Mobile CPU based systems.
@@ -148,7 +150,6 @@ config S3C2410_DMA_DEBUG
 config S3C2410_DMA
        bool
        depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442)
-       default y if CPU_S3C2410 || CPU_S3C2442
        help
          DMA device selection for S3C2410 and compatible CPUs
 
index d8f253f2b4862383888f633a400c2209aac352f5..11b3b28457bbce9130309d876f9239905f82e7e2 100644 (file)
@@ -484,22 +484,22 @@ static struct clk init_clocks_disable[] = {
 
 static struct clk init_clocks[] = {
        {
-               .name           = "dma",
+               .name           = "dma.0",
                .parent         = &clk_h,
                .enable         = s3c2412_clkcon_enable,
                .ctrlbit        = S3C2412_CLKCON_DMA0,
        }, {
-               .name           = "dma",
+               .name           = "dma.1",
                .parent         = &clk_h,
                .enable         = s3c2412_clkcon_enable,
                .ctrlbit        = S3C2412_CLKCON_DMA1,
        }, {
-               .name           = "dma",
+               .name           = "dma.2",
                .parent         = &clk_h,
                .enable         = s3c2412_clkcon_enable,
                .ctrlbit        = S3C2412_CLKCON_DMA2,
        }, {
-               .name           = "dma",
+               .name           = "dma.3",
                .parent         = &clk_h,
                .enable         = s3c2412_clkcon_enable,
                .ctrlbit        = S3C2412_CLKCON_DMA3,
index f6b9f2ef01bdde960504230f36f6db6a594a05a6..65d3eef7309040d4ccc5a71af5da8618327d8b60 100644 (file)
@@ -438,32 +438,32 @@ static struct clk init_clocks_off[] = {
 
 static struct clk init_clocks[] = {
        {
-               .name           = "dma",
+               .name           = "dma.0",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_DMA0,
        }, {
-               .name           = "dma",
+               .name           = "dma.1",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_DMA1,
        }, {
-               .name           = "dma",
+               .name           = "dma.2",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_DMA2,
        }, {
-               .name           = "dma",
+               .name           = "dma.3",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_DMA3,
        }, {
-               .name           = "dma",
+               .name           = "dma.4",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_DMA4,
        }, {
-               .name           = "dma",
+               .name           = "dma.5",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_DMA5,
index 457261c984338815c7620c8c8eeed9c150b61e8d..4adaa4b43ffe5282f915d83dcdc3d4489c6eebe7 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/platform_data/dma-s3c24xx.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-clock.h>
@@ -44,6 +45,7 @@
 
 #include <mach/regs-gpio.h>
 #include <plat/regs-serial.h>
+#include <mach/dma.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
@@ -329,3 +331,207 @@ void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
        clk_p.rate = pclk;
        clk_f.rate = fclk;
 }
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+       defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dma_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
+       [1] = DEFINE_RES_IRQ(IRQ_DMA0),
+       [2] = DEFINE_RES_IRQ(IRQ_DMA1),
+       [3] = DEFINE_RES_IRQ(IRQ_DMA2),
+       [4] = DEFINE_RES_IRQ(IRQ_DMA3),
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2442)
+static struct s3c24xx_dma_channel s3c2410_dma_channels[DMACH_MAX] = {
+       [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), },
+       [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), },
+       [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) |
+                                               S3C24XX_DMA_CHANREQ(2, 2) |
+                                               S3C24XX_DMA_CHANREQ(1, 3),
+       },
+       [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), },
+       [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), },
+       [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), },
+       [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), },
+       [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), },
+       [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) |
+                                                S3C24XX_DMA_CHANREQ(3, 2) |
+                                                S3C24XX_DMA_CHANREQ(3, 3),
+       },
+       [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) |
+                                                 S3C24XX_DMA_CHANREQ(1, 2),
+       },
+       [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 2), },
+       [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), },
+       [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), },
+       [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), },
+       [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
+};
+
+static struct s3c24xx_dma_platdata s3c2410_dma_platdata = {
+       .num_phy_channels = 4,
+       .channels = s3c2410_dma_channels,
+       .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2410_device_dma = {
+       .name           = "s3c2410-dma",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c2410_dma_resource),
+       .resource       = s3c2410_dma_resource,
+       .dev    = {
+               .platform_data  = &s3c2410_dma_platdata,
+       },
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+static struct s3c24xx_dma_channel s3c2412_dma_channels[DMACH_MAX] = {
+       [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 },
+       [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 },
+       [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 },
+       [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 },
+       [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 },
+       [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 },
+       [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 },
+       [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 },
+       [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 },
+       [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 },
+       [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 },
+       [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 },
+       [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 },
+       [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 },
+       [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 },
+       [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 },
+       [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, 13 },
+       [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, 14 },
+       [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, 15 },
+       [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, 16 },
+};
+
+static struct s3c24xx_dma_platdata s3c2412_dma_platdata = {
+       .num_phy_channels = 4,
+       .channels = s3c2412_dma_channels,
+       .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2412_device_dma = {
+       .name           = "s3c2412-dma",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c2410_dma_resource),
+       .resource       = s3c2410_dma_resource,
+       .dev    = {
+               .platform_data  = &s3c2412_dma_platdata,
+       },
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct s3c24xx_dma_channel s3c2440_dma_channels[DMACH_MAX] = {
+       [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), },
+       [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), },
+       [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) |
+                                               S3C24XX_DMA_CHANREQ(6, 1) |
+                                               S3C24XX_DMA_CHANREQ(2, 2) |
+                                               S3C24XX_DMA_CHANREQ(1, 3),
+       },
+       [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), },
+       [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), },
+       [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), },
+       [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), },
+       [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), },
+       [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) |
+                                                S3C24XX_DMA_CHANREQ(3, 2) |
+                                                S3C24XX_DMA_CHANREQ(3, 3),
+       },
+       [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) |
+                                                 S3C24XX_DMA_CHANREQ(1, 2),
+       },
+       [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 0) |
+                                                  S3C24XX_DMA_CHANREQ(0, 2),
+       },
+       [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 0) |
+                                                 S3C24XX_DMA_CHANREQ(5, 2),
+       },
+       [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 1) |
+                                                 S3C24XX_DMA_CHANREQ(6, 3),
+       },
+       [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 2) |
+                                                 S3C24XX_DMA_CHANREQ(5, 3),
+       },
+       [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), },
+       [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), },
+       [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), },
+       [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
+};
+
+static struct s3c24xx_dma_platdata s3c2440_dma_platdata = {
+       .num_phy_channels = 4,
+       .channels = s3c2440_dma_channels,
+       .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2440_device_dma = {
+       .name           = "s3c2410-dma",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c2410_dma_resource),
+       .resource       = s3c2410_dma_resource,
+       .dev    = {
+               .platform_data  = &s3c2440_dma_platdata,
+       },
+};
+#endif
+
+#if defined(CONFIG_CPUS_3C2443) || defined(CONFIG_CPU_S3C2416)
+static struct resource s3c2443_dma_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
+       [1] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA0),
+       [2] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA1),
+       [3] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA2),
+       [4] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA3),
+       [5] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA4),
+       [6] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA5),
+};
+
+static struct s3c24xx_dma_channel s3c2443_dma_channels[DMACH_MAX] = {
+       [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 },
+       [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 },
+       [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 },
+       [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 },
+       [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 },
+       [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 },
+       [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 },
+       [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 },
+       [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 },
+       [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 },
+       [DMACH_UART3] = { S3C24XX_DMA_APB, true, 25 },
+       [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 },
+       [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 },
+       [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 },
+       [DMACH_UART3_SRC2] = { S3C24XX_DMA_APB, true, 26 },
+       [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 },
+       [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 },
+       [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 },
+       [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, 28 },
+       [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, 27 },
+       [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, 29 },
+};
+
+static struct s3c24xx_dma_platdata s3c2443_dma_platdata = {
+       .num_phy_channels = 6,
+       .channels = s3c2443_dma_channels,
+       .num_channels = DMACH_MAX,
+};
+
+struct platform_device s3c2443_device_dma = {
+       .name           = "s3c2443-dma",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c2443_dma_resource),
+       .resource       = s3c2443_dma_resource,
+       .dev    = {
+               .platform_data  = &s3c2443_dma_platdata,
+       },
+};
+#endif
index 84b280654f4cf331252199ae2c5b2b17fcc072da..e46c1041721669e3503555cadff0c6bbbcaaf3df 100644 (file)
@@ -109,4 +109,9 @@ extern void s3c2443_init_irq(void);
 
 extern struct syscore_ops s3c24xx_irq_syscore_ops;
 
+extern struct platform_device s3c2410_device_dma;
+extern struct platform_device s3c2412_device_dma;
+extern struct platform_device s3c2440_device_dma;
+extern struct platform_device s3c2443_device_dma;
+
 #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
index a45fcd8ccf796016c9007d0d7a44e089f30a9497..43c23e220f5b5823eb0831fe68f52430fb06f475 100644 (file)
@@ -466,6 +466,7 @@ static struct platform_device *jive_devices[] __initdata = {
        &jive_device_wm8750,
        &s3c_device_nand,
        &s3c_device_usbgadget,
+       &s3c2412_device_dma,
 };
 
 static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
index 8146e920f10d67313bbae45ddc81f47735eb67d1..c9d31ef28dd107073e63f5736437112804999ba9 100644 (file)
@@ -89,6 +89,7 @@ static struct platform_device *smdk2413_devices[] __initdata = {
        &s3c_device_i2c0,
        &s3c_device_iis,
        &s3c_device_usbgadget,
+       &s3c2412_device_dma,
 };
 
 static void __init smdk2413_fixup(struct tag *tags, char **cmdline,
index cb46847c66b4a71c50272a4d847ca49356266742..f88e672ad1e42786e57dc62cca8df9763fb0f5cc 100644 (file)
@@ -215,6 +215,7 @@ static struct platform_device *smdk2416_devices[] __initdata = {
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc1,
        &s3c_device_usb_hsudc,
+       &s3c2443_device_dma,
 };
 
 static void __init smdk2416_map_io(void)
index 9435c3bef18a91c53da53dcc29e68498bc834946..d9933fcc6cc8bb8526af7808c28a5250c2ae2be1 100644 (file)
@@ -115,6 +115,7 @@ static struct platform_device *smdk2443_devices[] __initdata = {
 #ifdef CONFIG_SND_SOC_SMDK2443_WM9710
        &s3c_device_ac97,
 #endif
+       &s3c2443_device_dma,
 };
 
 static void __init smdk2443_map_io(void)
index b66588428ec90e7b0d4c056f60e8ddc2e5dc36be..f7ec9c55078748782cd3110c8b4cea81a5afc408 100644 (file)
@@ -126,6 +126,7 @@ static struct platform_device *vstms_devices[] __initdata = {
        &s3c_device_iis,
        &s3c_device_rtc,
        &s3c_device_nand,
+       &s3c2412_device_dma,
 };
 
 static void __init vstms_fixup(struct tag *tags, char **cmdline,
index 041da5172423742277e778fdbb861dfee98c7e1a..2cb8dc55b50ecbc4aa612ab805b52f03efec3eb9 100644 (file)
@@ -3,16 +3,7 @@
 #
 # Licensed under GPLv2
 
-# temporary until we can eliminate all drivers using it.
-config PLAT_S3C64XX
-       bool
-       depends on ARCH_S3C64XX
-       default y
-       select PM_GENERIC_DOMAINS
-       select SAMSUNG_WAKEMASK
-       help
-         Base platform code for any Samsung S3C64XX device
-
+if ARCH_S3C64XX
 
 # Configuration options for the S3C6410 CPU
 
@@ -306,3 +297,21 @@ config MACH_WLF_CRAGG_6410
        select SAMSUNG_GPIO_EXTRA128
        help
          Machine support for the Wolfson Cragganmore S3C6410 variant.
+
+config MACH_S3C64XX_DT
+       bool "Samsung S3C6400/S3C6410 machine using Device Tree"
+       select CLKSRC_OF
+       select CPU_S3C6400
+       select CPU_S3C6410
+       select PINCTRL
+       select PINCTRL_S3C64XX
+       select USE_OF
+       help
+         Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
+         enabled.
+         Select this if a fdt blob is available for your S3C64XX SoC based
+         board.
+         Note: This is under development and not all peripherals can be
+         supported with this machine file.
+
+endif
index 31d0c9101272196e81f7da943bc25bfdd1420722..6faedcffce040d0cfc041c9d3b559ff1be94a207 100644 (file)
@@ -12,7 +12,7 @@ obj-                          :=
 
 # Core
 
-obj-y                          += common.o clock.o
+obj-y                          += common.o
 
 # Core support
 
@@ -57,3 +57,4 @@ obj-$(CONFIG_MACH_SMARTQ7)            += mach-smartq7.o
 obj-$(CONFIG_MACH_SMDK6400)            += mach-smdk6400.o
 obj-$(CONFIG_MACH_SMDK6410)            += mach-smdk6410.o
 obj-$(CONFIG_MACH_WLF_CRAGG_6410)      += mach-crag6410.o mach-crag6410-module.o
+obj-$(CONFIG_MACH_S3C64XX_DT)          += mach-s3c64xx-dt.o
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
deleted file mode 100644 (file)
index c1bcc4a..0000000
+++ /dev/null
@@ -1,1007 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/clock.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C64XX Base clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pll.h>
-
-#include "regs-sys.h"
-
-/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
- * ext_xtal_mux for want of an actual name from the manual.
-*/
-
-static struct clk clk_ext_xtal_mux = {
-       .name           = "ext_xtal",
-};
-
-#define clk_fin_apll clk_ext_xtal_mux
-#define clk_fin_mpll clk_ext_xtal_mux
-#define clk_fin_epll clk_ext_xtal_mux
-
-#define clk_fout_mpll  clk_mpll
-#define clk_fout_epll  clk_epll
-
-struct clk clk_h2 = {
-       .name           = "hclk2",
-       .rate           = 0,
-};
-
-struct clk clk_27m = {
-       .name           = "clk_27m",
-       .rate           = 27000000,
-};
-
-static int clk_48m_ctrl(struct clk *clk, int enable)
-{
-       unsigned long flags;
-       u32 val;
-
-       /* can't rely on clock lock, this register has other usages */
-       local_irq_save(flags);
-
-       val = __raw_readl(S3C64XX_OTHERS);
-       if (enable)
-               val |= S3C64XX_OTHERS_USBMASK;
-       else
-               val &= ~S3C64XX_OTHERS_USBMASK;
-
-       __raw_writel(val, S3C64XX_OTHERS);
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-struct clk clk_48m = {
-       .name           = "clk_48m",
-       .rate           = 48000000,
-       .enable         = clk_48m_ctrl,
-};
-
-struct clk clk_xusbxti = {
-       .name           = "xusbxti",
-       .rate           = 48000000,
-};
-
-static int inline s3c64xx_gate(void __iomem *reg,
-                               struct clk *clk,
-                               int enable)
-{
-       unsigned int ctrlbit = clk->ctrlbit;
-       u32 con;
-
-       con = __raw_readl(reg);
-
-       if (enable)
-               con |= ctrlbit;
-       else
-               con &= ~ctrlbit;
-
-       __raw_writel(con, reg);
-       return 0;
-}
-
-static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
-{
-       return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
-}
-
-static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
-{
-       return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
-}
-
-int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
-{
-       return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
-}
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "nand",
-               .parent         = &clk_h,
-       }, {
-               .name           = "rtc",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_RTC,
-       }, {
-               .name           = "adc",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_TSADC,
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.0",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_IIC,
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.1",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C6410_CLKCON_PCLK_I2C1,
-       }, {
-               .name           = "keypad",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_KEYPAD,
-       }, {
-               .name           = "spi",
-               .devname        = "s3c6410-spi.0",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_SPI0,
-       }, {
-               .name           = "spi",
-               .devname        = "s3c6410-spi.1",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_SPI1,
-       }, {
-               .name           = "48m",
-               .devname        = "s3c-sdhci.0",
-               .parent         = &clk_48m,
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_MMC0_48,
-       }, {
-               .name           = "48m",
-               .devname        = "s3c-sdhci.1",
-               .parent         = &clk_48m,
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_MMC1_48,
-       }, {
-               .name           = "48m",
-               .devname        = "s3c-sdhci.2",
-               .parent         = &clk_48m,
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_MMC2_48,
-       }, {
-               .name           = "ac97",
-               .parent         = &clk_p,
-               .ctrlbit        = S3C_CLKCON_PCLK_AC97,
-       }, {
-               .name           = "cfcon",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_IHOST,
-       }, {
-               .name           = "dma0",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_DMA0,
-       }, {
-               .name           = "dma1",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_DMA1,
-       }, {
-               .name           = "3dse",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_3DSE,
-       }, {
-               .name           = "hclk_secur",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_SECUR,
-       }, {
-               .name           = "sdma1",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_SDMA1,
-       }, {
-               .name           = "sdma0",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_SDMA0,
-       }, {
-               .name           = "hclk_jpeg",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_JPEG,
-       }, {
-               .name           = "camif",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_CAMIF,
-       }, {
-               .name           = "hclk_scaler",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_SCALER,
-       }, {
-               .name           = "2d",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_2D,
-       }, {
-               .name           = "tv",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_TV,
-       }, {
-               .name           = "post0",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_POST0,
-       }, {
-               .name           = "rot",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_ROT,
-       }, {
-               .name           = "hclk_mfc",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_MFC,
-       }, {
-               .name           = "pclk_mfc",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_MFC,
-       }, {
-               .name           = "dac27",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_DAC27,
-       }, {
-               .name           = "tv27",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_TV27,
-       }, {
-               .name           = "scaler27",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_SCALER27,
-       }, {
-               .name           = "sclk_scaler",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_SCALER,
-       }, {
-               .name           = "post0_27",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_POST0_27,
-       }, {
-               .name           = "secur",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_SECUR,
-       }, {
-               .name           = "sclk_mfc",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_MFC,
-       }, {
-               .name           = "sclk_jpeg",
-               .enable         = s3c64xx_sclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_SCLK_JPEG,
-       },
-};
-
-static struct clk clk_48m_spi0 = {
-       .name           = "spi_48m",
-       .devname        = "s3c6410-spi.0",
-       .parent         = &clk_48m,
-       .enable         = s3c64xx_sclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_SCLK_SPI0_48,
-};
-
-static struct clk clk_48m_spi1 = {
-       .name           = "spi_48m",
-       .devname        = "s3c6410-spi.1",
-       .parent         = &clk_48m,
-       .enable         = s3c64xx_sclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_SCLK_SPI1_48,
-};
-
-static struct clk clk_i2s0 = {
-       .name           = "iis",
-       .devname        = "samsung-i2s.0",
-       .parent         = &clk_p,
-       .enable         = s3c64xx_pclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_PCLK_IIS0,
-};
-
-static struct clk clk_i2s1 = {
-       .name           = "iis",
-       .devname        = "samsung-i2s.1",
-       .parent         = &clk_p,
-       .enable         = s3c64xx_pclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_PCLK_IIS1,
-};
-
-#ifdef CONFIG_CPU_S3C6410
-static struct clk clk_i2s2 = {
-       .name           = "iis",
-       .devname        = "samsung-i2s.2",
-       .parent         = &clk_p,
-       .enable         = s3c64xx_pclk_ctrl,
-       .ctrlbit        = S3C6410_CLKCON_PCLK_IIS2,
-};
-#endif
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "lcd",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_LCD,
-       }, {
-               .name           = "gpio",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_GPIO,
-       }, {
-               .name           = "usb-host",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_UHOST,
-       }, {
-               .name           = "otg",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_USB,
-       }, {
-               .name           = "timers",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_PWM,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c6400-uart.0",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_UART0,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c6400-uart.1",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_UART1,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c6400-uart.2",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_UART2,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c6400-uart.3",
-               .parent         = &clk_p,
-               .enable         = s3c64xx_pclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_PCLK_UART3,
-       }, {
-               .name           = "watchdog",
-               .parent         = &clk_p,
-               .ctrlbit        = S3C_CLKCON_PCLK_WDT,
-       },
-};
-
-static struct clk clk_hsmmc0 = {
-       .name           = "hsmmc",
-       .devname        = "s3c-sdhci.0",
-       .parent         = &clk_h,
-       .enable         = s3c64xx_hclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_HCLK_HSMMC0,
-};
-
-static struct clk clk_hsmmc1 = {
-       .name           = "hsmmc",
-       .devname        = "s3c-sdhci.1",
-       .parent         = &clk_h,
-       .enable         = s3c64xx_hclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_HCLK_HSMMC1,
-};
-
-static struct clk clk_hsmmc2 = {
-       .name           = "hsmmc",
-       .devname        = "s3c-sdhci.2",
-       .parent         = &clk_h,
-       .enable         = s3c64xx_hclk_ctrl,
-       .ctrlbit        = S3C_CLKCON_HCLK_HSMMC2,
-};
-
-static struct clk clk_fout_apll = {
-       .name           = "fout_apll",
-};
-
-static struct clk *clk_src_apll_list[] = {
-       [0] = &clk_fin_apll,
-       [1] = &clk_fout_apll,
-};
-
-static struct clksrc_sources clk_src_apll = {
-       .sources        = clk_src_apll_list,
-       .nr_sources     = ARRAY_SIZE(clk_src_apll_list),
-};
-
-static struct clksrc_clk clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1  },
-       .sources        = &clk_src_apll,
-};
-
-static struct clk *clk_src_epll_list[] = {
-       [0] = &clk_fin_epll,
-       [1] = &clk_fout_epll,
-};
-
-static struct clksrc_sources clk_src_epll = {
-       .sources        = clk_src_epll_list,
-       .nr_sources     = ARRAY_SIZE(clk_src_epll_list),
-};
-
-static struct clksrc_clk clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1  },
-       .sources        = &clk_src_epll,
-};
-
-static struct clk *clk_src_mpll_list[] = {
-       [0] = &clk_fin_mpll,
-       [1] = &clk_fout_mpll,
-};
-
-static struct clksrc_sources clk_src_mpll = {
-       .sources        = clk_src_mpll_list,
-       .nr_sources     = ARRAY_SIZE(clk_src_mpll_list),
-};
-
-static struct clksrc_clk clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1  },
-       .sources        = &clk_src_mpll,
-};
-
-static unsigned int armclk_mask;
-
-static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
-       u32 clkdiv;
-
-       /* divisor mask starts at bit0, so no need to shift */
-       clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
-
-       return rate / (clkdiv + 1);
-}
-
-static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
-                                               unsigned long rate)
-{
-       unsigned long parent = clk_get_rate(clk->parent);
-       u32 div;
-
-       if (parent < rate)
-               return parent;
-
-       div = (parent / rate) - 1;
-       if (div > armclk_mask)
-               div = armclk_mask;
-
-       return parent / (div + 1);
-}
-
-static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent = clk_get_rate(clk->parent);
-       u32 div;
-       u32 val;
-
-       if (rate < parent / (armclk_mask + 1))
-               return -EINVAL;
-
-       rate = clk_round_rate(clk, rate);
-       div = clk_get_rate(clk->parent) / rate;
-
-       val = __raw_readl(S3C_CLK_DIV0);
-       val &= ~armclk_mask;
-       val |= (div - 1);
-       __raw_writel(val, S3C_CLK_DIV0);
-
-       return 0;
-
-}
-
-static struct clk clk_arm = {
-       .name           = "armclk",
-       .parent         = &clk_mout_apll.clk,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c64xx_clk_arm_get_rate,
-               .set_rate       = s3c64xx_clk_arm_set_rate,
-               .round_rate     = s3c64xx_clk_arm_round_rate,
-       },
-};
-
-static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
-
-       printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-       if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
-               rate /= 2;
-
-       return rate;
-}
-
-static struct clk_ops clk_dout_ops = {
-       .get_rate       = s3c64xx_clk_doutmpll_get_rate,
-};
-
-static struct clk clk_dout_mpll = {
-       .name           = "dout_mpll",
-       .parent         = &clk_mout_mpll.clk,
-       .ops            = &clk_dout_ops,
-};
-
-static struct clk *clkset_spi_mmc_list[] = {
-       &clk_mout_epll.clk,
-       &clk_dout_mpll,
-       &clk_fin_epll,
-       &clk_27m,
-};
-
-static struct clksrc_sources clkset_spi_mmc = {
-       .sources        = clkset_spi_mmc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_spi_mmc_list),
-};
-
-static struct clk *clkset_irda_list[] = {
-       &clk_mout_epll.clk,
-       &clk_dout_mpll,
-       NULL,
-       &clk_27m,
-};
-
-static struct clksrc_sources clkset_irda = {
-       .sources        = clkset_irda_list,
-       .nr_sources     = ARRAY_SIZE(clkset_irda_list),
-};
-
-static struct clk *clkset_uart_list[] = {
-       &clk_mout_epll.clk,
-       &clk_dout_mpll,
-       NULL,
-       NULL
-};
-
-static struct clksrc_sources clkset_uart = {
-       .sources        = clkset_uart_list,
-       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clk *clkset_uhost_list[] = {
-       &clk_48m,
-       &clk_mout_epll.clk,
-       &clk_dout_mpll,
-       &clk_fin_epll,
-};
-
-static struct clksrc_sources clkset_uhost = {
-       .sources        = clkset_uhost_list,
-       .nr_sources     = ARRAY_SIZE(clkset_uhost_list),
-};
-
-/* The peripheral clocks are all controlled via clocksource followed
- * by an optional divider and gate stage. We currently roll this into
- * one clock which hides the intermediate clock from the mux.
- *
- * Note, the JPEG clock can only be an even divider...
- *
- * The scaler and LCD clocks depend on the S3C64XX version, and also
- * have a common parent divisor so are not included here.
- */
-
-/* clocks that feed other parts of the clock source tree */
-
-static struct clk clk_iis_cd0 = {
-       .name           = "iis_cdclk0",
-};
-
-static struct clk clk_iis_cd1 = {
-       .name           = "iis_cdclk1",
-};
-
-static struct clk clk_iisv4_cd = {
-       .name           = "iis_cdclk_v4",
-};
-
-static struct clk clk_pcm_cd = {
-       .name           = "pcm_cdclk",
-};
-
-static struct clk *clkset_audio0_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_dout_mpll,
-       [2] = &clk_fin_epll,
-       [3] = &clk_iis_cd0,
-       [4] = &clk_pcm_cd,
-};
-
-static struct clksrc_sources clkset_audio0 = {
-       .sources        = clkset_audio0_list,
-       .nr_sources     = ARRAY_SIZE(clkset_audio0_list),
-};
-
-static struct clk *clkset_audio1_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_dout_mpll,
-       [2] = &clk_fin_epll,
-       [3] = &clk_iis_cd1,
-       [4] = &clk_pcm_cd,
-};
-
-static struct clksrc_sources clkset_audio1 = {
-       .sources        = clkset_audio1_list,
-       .nr_sources     = ARRAY_SIZE(clkset_audio1_list),
-};
-
-#ifdef CONFIG_CPU_S3C6410
-static struct clk *clkset_audio2_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_dout_mpll,
-       [2] = &clk_fin_epll,
-       [3] = &clk_iisv4_cd,
-       [4] = &clk_pcm_cd,
-};
-
-static struct clksrc_sources clkset_audio2 = {
-       .sources        = clkset_audio2_list,
-       .nr_sources     = ARRAY_SIZE(clkset_audio2_list),
-};
-#endif
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk    = {
-                       .name           = "usb-bus-host",
-                       .ctrlbit        = S3C_CLKCON_SCLK_UHOST,
-                       .enable         = s3c64xx_sclk_ctrl,
-               },
-               .reg_src        = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2  },
-               .reg_div        = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4  },
-               .sources        = &clkset_uhost,
-       }, {
-               .clk    = {
-                       .name           = "irda-bus",
-                       .ctrlbit        = S3C_CLKCON_SCLK_IRDA,
-                       .enable         = s3c64xx_sclk_ctrl,
-               },
-               .reg_src        = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2  },
-               .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4  },
-               .sources        = &clkset_irda,
-       }, {
-               .clk    = {
-                       .name           = "camera",
-                       .ctrlbit        = S3C_CLKCON_SCLK_CAM,
-                       .enable         = s3c64xx_sclk_ctrl,
-                       .parent         = &clk_h2,
-               },
-               .reg_div        = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4  },
-       },
-};
-
-/* Where does UCLK0 come from? */
-static struct clksrc_clk clk_sclk_uclk = {
-       .clk    = {
-               .name           = "uclk1",
-               .ctrlbit        = S3C_CLKCON_SCLK_UART,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1  },
-       .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4  },
-       .sources        = &clkset_uart,
-};
-
-static struct clksrc_clk clk_sclk_mmc0 = {
-       .clk    = {
-               .name           = "mmc_bus",
-               .devname        = "s3c-sdhci.0",
-               .ctrlbit        = S3C_CLKCON_SCLK_MMC0,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2  },
-       .reg_div        = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4  },
-       .sources        = &clkset_spi_mmc,
-};
-
-static struct clksrc_clk clk_sclk_mmc1 = {
-       .clk    = {
-               .name           = "mmc_bus",
-               .devname        = "s3c-sdhci.1",
-               .ctrlbit        = S3C_CLKCON_SCLK_MMC1,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2  },
-       .reg_div        = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4  },
-       .sources        = &clkset_spi_mmc,
-};
-
-static struct clksrc_clk clk_sclk_mmc2 = {
-       .clk    = {
-               .name           = "mmc_bus",
-               .devname        = "s3c-sdhci.2",
-               .ctrlbit        = S3C_CLKCON_SCLK_MMC2,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2  },
-       .reg_div        = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4  },
-       .sources        = &clkset_spi_mmc,
-};
-
-static struct clksrc_clk clk_sclk_spi0 = {
-       .clk    = {
-               .name           = "spi-bus",
-               .devname        = "s3c6410-spi.0",
-               .ctrlbit        = S3C_CLKCON_SCLK_SPI0,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
-       .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
-       .sources = &clkset_spi_mmc,
-};
-
-static struct clksrc_clk clk_sclk_spi1 = {
-       .clk    = {
-               .name           = "spi-bus",
-               .devname        = "s3c6410-spi.1",
-               .ctrlbit        = S3C_CLKCON_SCLK_SPI1,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
-       .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
-       .sources = &clkset_spi_mmc,
-};
-
-static struct clksrc_clk clk_audio_bus0 = {
-       .clk    = {
-               .name           = "audio-bus",
-               .devname        = "samsung-i2s.0",
-               .ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3  },
-       .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4  },
-       .sources        = &clkset_audio0,
-};
-
-static struct clksrc_clk clk_audio_bus1 = {
-       .clk    = {
-               .name           = "audio-bus",
-               .devname        = "samsung-i2s.1",
-               .ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3  },
-       .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4  },
-       .sources        = &clkset_audio1,
-};
-
-#ifdef CONFIG_CPU_S3C6410
-static struct clksrc_clk clk_audio_bus2 = {
-       .clk    = {
-               .name           = "audio-bus",
-               .devname        = "samsung-i2s.2",
-               .ctrlbit        = S3C6410_CLKCON_SCLK_AUDIO2,
-               .enable         = s3c64xx_sclk_ctrl,
-       },
-       .reg_src        = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3  },
-       .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4  },
-       .sources        = &clkset_audio2,
-};
-#endif
-/* Clock initialisation code */
-
-static struct clksrc_clk *init_parents[] = {
-       &clk_mout_apll,
-       &clk_mout_epll,
-       &clk_mout_mpll,
-};
-
-static struct clksrc_clk *clksrc_cdev[] = {
-       &clk_sclk_uclk,
-       &clk_sclk_mmc0,
-       &clk_sclk_mmc1,
-       &clk_sclk_mmc2,
-       &clk_sclk_spi0,
-       &clk_sclk_spi1,
-       &clk_audio_bus0,
-       &clk_audio_bus1,
-};
-
-static struct clk *clk_cdev[] = {
-       &clk_hsmmc0,
-       &clk_hsmmc1,
-       &clk_hsmmc2,
-       &clk_48m_spi0,
-       &clk_48m_spi1,
-       &clk_i2s0,
-       &clk_i2s1,
-};
-
-static struct clk_lookup s3c64xx_clk_lookup[] = {
-       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
-       CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
-       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
-       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
-       CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
-       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
-       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
-       CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
-       CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
-       CLKDEV_INIT("s3c6410-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
-       CLKDEV_INIT("s3c6410-spi.0", "spi_busclk2", &clk_48m_spi0),
-       CLKDEV_INIT("s3c6410-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
-       CLKDEV_INIT("s3c6410-spi.1", "spi_busclk2", &clk_48m_spi1),
-       CLKDEV_INIT("samsung-i2s.0", "i2s_opclk0", &clk_i2s0),
-       CLKDEV_INIT("samsung-i2s.0", "i2s_opclk1", &clk_audio_bus0.clk),
-       CLKDEV_INIT("samsung-i2s.1", "i2s_opclk0", &clk_i2s1),
-       CLKDEV_INIT("samsung-i2s.1", "i2s_opclk1", &clk_audio_bus1.clk),
-#ifdef CONFIG_CPU_S3C6410
-       CLKDEV_INIT("samsung-i2s.2", "i2s_opclk0", &clk_i2s2),
-       CLKDEV_INIT("samsung-i2s.2", "i2s_opclk1", &clk_audio_bus2.clk),
-#endif
-};
-
-#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
-
-void __init_or_cpufreq s3c64xx_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long xtal;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long hclk2;
-       unsigned long pclk;
-       unsigned long epll;
-       unsigned long apll;
-       unsigned long mpll;
-       unsigned int ptr;
-       u32 clkdiv0;
-
-       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
-       clkdiv0 = __raw_readl(S3C_CLK_DIV0);
-       printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
-
-       xtal_clk = clk_get(NULL, "xtal");
-       BUG_ON(IS_ERR(xtal_clk));
-
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
-       /* For now assume the mux always selects the crystal */
-       clk_ext_xtal_mux.parent = xtal_clk;
-
-       epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0),
-                               __raw_readl(S3C_EPLL_CON1));
-       mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
-       apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
-
-       fclk = mpll;
-
-       printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
-              apll, mpll, epll);
-
-       if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL)
-               /* Synchronous mode */
-               hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
-       else
-               /* Asynchronous mode */
-               hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
-
-       hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
-       pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
-
-       printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
-              hclk2, hclk, pclk);
-
-       clk_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_apll.rate = apll;
-
-       clk_h2.rate = hclk2;
-       clk_h.rate = hclk;
-       clk_p.rate = pclk;
-       clk_f.rate = fclk;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-               s3c_set_clksrc(init_parents[ptr], true);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_set_clksrc(&clksrcs[ptr], true);
-}
-
-static struct clk *clks1[] __initdata = {
-       &clk_ext_xtal_mux,
-       &clk_iis_cd0,
-       &clk_iis_cd1,
-       &clk_iisv4_cd,
-       &clk_pcm_cd,
-       &clk_mout_epll.clk,
-       &clk_mout_mpll.clk,
-       &clk_dout_mpll,
-       &clk_arm,
-};
-
-static struct clk *clks[] __initdata = {
-       &clk_ext,
-       &clk_epll,
-       &clk_27m,
-       &clk_48m,
-       &clk_h2,
-       &clk_xusbxti,
-};
-
-/**
- * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410
- * @xtal: The rate for the clock crystal feeding the PLLs.
- * @armclk_divlimit: Divisor mask for ARMCLK.
- *
- * Register the clocks for the S3C6400 and S3C6410 SoC range, such
- * as ARMCLK as well as the necessary parent clocks.
- *
- * This call does not setup the clocks, which is left to the
- * s3c64xx_setup_clocks() call which may be needed by the cpufreq
- * or resume code to re-set the clocks if the bootloader has changed
- * them.
- */
-void __init s3c64xx_register_clocks(unsigned long xtal, 
-                                   unsigned armclk_divlimit)
-{
-       unsigned int cnt;
-
-       armclk_mask = armclk_divlimit;
-
-       s3c24xx_register_baseclocks(xtal);
-       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
-       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-       s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
-       for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++)
-               s3c_disable_clocks(clk_cdev[cnt], 1);
-
-       s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-       for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
-               s3c_register_clksrc(clksrc_cdev[cnt], 1);
-       clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
-}
index 73d79cf5e14118b1e99861c5bd79d6ffc9517164..7a3ce4c39e5fecd3470b06344295d766869b702e 100644 (file)
  * published by the Free Software Foundation.
  */
 
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/clk-provider.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
@@ -38,7 +43,6 @@
 #include <mach/regs-gpio.h>
 
 #include <plat/cpu.h>
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
 #include <plat/gpio-cfg.h>
 
 #include "common.h"
 
+/* External clock frequency */
+static unsigned long xtal_f = 12000000, xusbxti_f = 48000000;
+
+void __init s3c64xx_set_xtal_freq(unsigned long freq)
+{
+       xtal_f = freq;
+}
+
+void __init s3c64xx_set_xusbxti_freq(unsigned long freq)
+{
+       xusbxti_f = freq;
+}
+
 /* uart registration process */
 
 static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
@@ -67,7 +84,6 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idcode         = S3C6400_CPU_ID,
                .idmask         = S3C64XX_CPU_MASK,
                .map_io         = s3c6400_map_io,
-               .init_clocks    = s3c6400_init_clocks,
                .init_uarts     = s3c64xx_init_uarts,
                .init           = s3c6400_init,
                .name           = name_s3c6400,
@@ -75,7 +91,6 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idcode         = S3C6410_CPU_ID,
                .idmask         = S3C64XX_CPU_MASK,
                .map_io         = s3c6410_map_io,
-               .init_clocks    = s3c6410_init_clocks,
                .init_uarts     = s3c64xx_init_uarts,
                .init           = s3c6410_init,
                .name           = name_s3c6410,
@@ -192,6 +207,10 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 
 static __init int s3c64xx_dev_init(void)
 {
+       /* Not applicable when using DT. */
+       if (of_have_populated_dt())
+               return 0;
+
        subsys_system_register(&s3c64xx_subsys, NULL);
        return device_register(&s3c64xx_dev);
 }
@@ -213,8 +232,10 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
 {
        /*
         * FIXME: there is no better place to put this at the moment
-        * (samsung_wdt_reset_init needs clocks)
+        * (s3c64xx_clk_init needs ioremap and must happen before init_time
+        * samsung_wdt_reset_init needs clocks)
         */
+       s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);
        samsung_wdt_reset_init(S3C_VA_WATCHDOG);
 
        printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
@@ -391,6 +412,10 @@ static int __init s3c64xx_init_irq_eint(void)
 {
        int irq;
 
+       /* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
+       if (of_have_populated_dt())
+               return -ENODEV;
+
        for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
                irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);
                irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq));
index e8f990b37665b900d667c7332b6e26bf389beb93..bd3bd562011e1515198e924627fd7165f57cb3dd 100644 (file)
 void s3c64xx_init_irq(u32 vic0, u32 vic1);
 void s3c64xx_init_io(struct map_desc *mach_desc, int size);
 
-void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
-void s3c64xx_setup_clocks(void);
-
 void s3c64xx_restart(enum reboot_mode mode, const char *cmd);
 void s3c64xx_init_late(void);
 
+void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
+       unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base);
+void s3c64xx_set_xtal_freq(unsigned long freq);
+void s3c64xx_set_xusbxti_freq(unsigned long freq);
+
 #ifdef CONFIG_CPU_S3C6400
 
 extern  int s3c6400_init(void);
 extern void s3c6400_init_irq(void);
 extern void s3c6400_map_io(void);
-extern void s3c6400_init_clocks(int xtal);
 
 #else
-#define s3c6400_init_clocks NULL
 #define s3c6400_map_io NULL
 #define s3c6400_init NULL
 #endif
@@ -46,10 +46,8 @@ extern void s3c6400_init_clocks(int xtal);
 extern  int s3c6410_init(void);
 extern void s3c6410_init_irq(void);
 extern void s3c6410_map_io(void);
-extern void s3c6410_init_clocks(int xtal);
 
 #else
-#define s3c6410_init_clocks NULL
 #define s3c6410_map_io NULL
 #define s3c6410_init NULL
 #endif
index 759846c28d1296990bea0f1817ae782f46e042af..7e22c2113816a4c6bb897dc0c54a74e876da3f86 100644 (file)
  * published by the Free Software Foundation.
 */
 
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -24,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/amba/pl080.h>
+#include <linux/of.h>
 
 #include <mach/dma.h>
 #include <mach/map.h>
@@ -677,7 +682,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
                goto err_map;
        }
 
-       clk_enable(dmac->clk);
+       clk_prepare_enable(dmac->clk);
 
        dmac->regs = regs;
        dmac->chanbase = chbase;
@@ -711,7 +716,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
        return 0;
 
 err_clk:
-       clk_disable(dmac->clk);
+       clk_disable_unprepare(dmac->clk);
        clk_put(dmac->clk);
 err_map:
        iounmap(regs);
@@ -726,6 +731,10 @@ static int __init s3c64xx_dma_init(void)
 {
        int ret;
 
+       /* This driver is not supported when booting with device tree. */
+       if (of_have_populated_dt())
+               return -ENODEV;
+
        printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
 
        dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
index 05332b998ec07d36e1dba08453a265d7230ddba6..4f44aac770924134e735bf5e8b41eb6fe25c5920 100644 (file)
 #ifndef __PLAT_REGS_CLOCK_H
 #define __PLAT_REGS_CLOCK_H __FILE__
 
+/*
+ * FIXME: Remove remaining definitions
+ */
+
 #define S3C_CLKREG(x)          (S3C_VA_SYS + (x))
 
-#define S3C_APLL_LOCK          S3C_CLKREG(0x00)
-#define S3C_MPLL_LOCK          S3C_CLKREG(0x04)
-#define S3C_EPLL_LOCK          S3C_CLKREG(0x08)
-#define S3C_APLL_CON           S3C_CLKREG(0x0C)
-#define S3C_MPLL_CON           S3C_CLKREG(0x10)
-#define S3C_EPLL_CON0          S3C_CLKREG(0x14)
-#define S3C_EPLL_CON1          S3C_CLKREG(0x18)
-#define S3C_CLK_SRC            S3C_CLKREG(0x1C)
-#define S3C_CLK_DIV0           S3C_CLKREG(0x20)
-#define S3C_CLK_DIV1           S3C_CLKREG(0x24)
-#define S3C_CLK_DIV2           S3C_CLKREG(0x28)
-#define S3C_CLK_OUT            S3C_CLKREG(0x2C)
-#define S3C_HCLK_GATE          S3C_CLKREG(0x30)
 #define S3C_PCLK_GATE          S3C_CLKREG(0x34)
-#define S3C_SCLK_GATE          S3C_CLKREG(0x38)
-#define S3C_MEM0_GATE          S3C_CLKREG(0x3C)
 #define S3C6410_CLK_SRC2       S3C_CLKREG(0x10C)
 #define S3C_MEM_SYS_CFG                S3C_CLKREG(0x120)
 
-/* CLKDIV0 */
-#define S3C6400_CLKDIV0_PCLK_MASK      (0xf << 12)
-#define S3C6400_CLKDIV0_PCLK_SHIFT     (12)
-#define S3C6400_CLKDIV0_HCLK2_MASK     (0x7 << 9)
-#define S3C6400_CLKDIV0_HCLK2_SHIFT    (9)
-#define S3C6400_CLKDIV0_HCLK_MASK      (0x1 << 8)
-#define S3C6400_CLKDIV0_HCLK_SHIFT     (8)
-#define S3C6400_CLKDIV0_MPLL_MASK      (0x1 << 4)
-#define S3C6400_CLKDIV0_MPLL_SHIFT     (4)
-
-#define S3C6400_CLKDIV0_ARM_MASK       (0x7 << 0)
-#define S3C6410_CLKDIV0_ARM_MASK       (0xf << 0)
-#define S3C6400_CLKDIV0_ARM_SHIFT      (0)
-
-/* HCLK GATE Registers */
-#define S3C_CLKCON_HCLK_3DSE   (1<<31)
-#define S3C_CLKCON_HCLK_UHOST  (1<<29)
-#define S3C_CLKCON_HCLK_SECUR  (1<<28)
-#define S3C_CLKCON_HCLK_SDMA1  (1<<27)
-#define S3C_CLKCON_HCLK_SDMA0  (1<<26)
-#define S3C_CLKCON_HCLK_IROM   (1<<25)
-#define S3C_CLKCON_HCLK_DDR1   (1<<24)
-#define S3C_CLKCON_HCLK_DDR0   (1<<23)
-#define S3C_CLKCON_HCLK_MEM1   (1<<22)
-#define S3C_CLKCON_HCLK_MEM0   (1<<21)
-#define S3C_CLKCON_HCLK_USB    (1<<20)
-#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
-#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
-#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
-#define S3C_CLKCON_HCLK_MDP    (1<<16)
-#define S3C_CLKCON_HCLK_DHOST  (1<<15)
-#define S3C_CLKCON_HCLK_IHOST  (1<<14)
-#define S3C_CLKCON_HCLK_DMA1   (1<<13)
-#define S3C_CLKCON_HCLK_DMA0   (1<<12)
-#define S3C_CLKCON_HCLK_JPEG   (1<<11)
-#define S3C_CLKCON_HCLK_CAMIF  (1<<10)
-#define S3C_CLKCON_HCLK_SCALER (1<<9)
-#define S3C_CLKCON_HCLK_2D     (1<<8)
-#define S3C_CLKCON_HCLK_TV     (1<<7)
-#define S3C_CLKCON_HCLK_POST0  (1<<5)
-#define S3C_CLKCON_HCLK_ROT    (1<<4)
-#define S3C_CLKCON_HCLK_LCD    (1<<3)
-#define S3C_CLKCON_HCLK_TZIC   (1<<2)
-#define S3C_CLKCON_HCLK_INTC   (1<<1)
-#define S3C_CLKCON_HCLK_MFC    (1<<0)
-
 /* PCLK GATE Registers */
-#define S3C6410_CLKCON_PCLK_I2C1       (1<<27)
-#define S3C6410_CLKCON_PCLK_IIS2       (1<<26)
-#define S3C_CLKCON_PCLK_SKEY           (1<<24)
-#define S3C_CLKCON_PCLK_CHIPID         (1<<23)
-#define S3C_CLKCON_PCLK_SPI1           (1<<22)
-#define S3C_CLKCON_PCLK_SPI0           (1<<21)
-#define S3C_CLKCON_PCLK_HSIRX          (1<<20)
-#define S3C_CLKCON_PCLK_HSITX          (1<<19)
-#define S3C_CLKCON_PCLK_GPIO           (1<<18)
-#define S3C_CLKCON_PCLK_IIC            (1<<17)
-#define S3C_CLKCON_PCLK_IIS1           (1<<16)
-#define S3C_CLKCON_PCLK_IIS0           (1<<15)
-#define S3C_CLKCON_PCLK_AC97           (1<<14)
-#define S3C_CLKCON_PCLK_TZPC           (1<<13)
-#define S3C_CLKCON_PCLK_TSADC          (1<<12)
-#define S3C_CLKCON_PCLK_KEYPAD         (1<<11)
-#define S3C_CLKCON_PCLK_IRDA           (1<<10)
-#define S3C_CLKCON_PCLK_PCM1           (1<<9)
-#define S3C_CLKCON_PCLK_PCM0           (1<<8)
-#define S3C_CLKCON_PCLK_PWM            (1<<7)
-#define S3C_CLKCON_PCLK_RTC            (1<<6)
-#define S3C_CLKCON_PCLK_WDT            (1<<5)
 #define S3C_CLKCON_PCLK_UART3          (1<<4)
 #define S3C_CLKCON_PCLK_UART2          (1<<3)
 #define S3C_CLKCON_PCLK_UART1          (1<<2)
 #define S3C_CLKCON_PCLK_UART0          (1<<1)
-#define S3C_CLKCON_PCLK_MFC            (1<<0)
-
-/* SCLK GATE Registers */
-#define S3C_CLKCON_SCLK_UHOST          (1<<30)
-#define S3C_CLKCON_SCLK_MMC2_48                (1<<29)
-#define S3C_CLKCON_SCLK_MMC1_48                (1<<28)
-#define S3C_CLKCON_SCLK_MMC0_48                (1<<27)
-#define S3C_CLKCON_SCLK_MMC2           (1<<26)
-#define S3C_CLKCON_SCLK_MMC1           (1<<25)
-#define S3C_CLKCON_SCLK_MMC0           (1<<24)
-#define S3C_CLKCON_SCLK_SPI1_48        (1<<23)
-#define S3C_CLKCON_SCLK_SPI0_48        (1<<22)
-#define S3C_CLKCON_SCLK_SPI1           (1<<21)
-#define S3C_CLKCON_SCLK_SPI0           (1<<20)
-#define S3C_CLKCON_SCLK_DAC27          (1<<19)
-#define S3C_CLKCON_SCLK_TV27           (1<<18)
-#define S3C_CLKCON_SCLK_SCALER27       (1<<17)
-#define S3C_CLKCON_SCLK_SCALER         (1<<16)
-#define S3C_CLKCON_SCLK_LCD27          (1<<15)
-#define S3C_CLKCON_SCLK_LCD            (1<<14)
-#define S3C6400_CLKCON_SCLK_POST1_27   (1<<13)
-#define S3C6410_CLKCON_FIMC            (1<<13)
-#define S3C_CLKCON_SCLK_POST0_27       (1<<12)
-#define S3C6400_CLKCON_SCLK_POST1      (1<<11)
-#define S3C6410_CLKCON_SCLK_AUDIO2     (1<<11)
-#define S3C_CLKCON_SCLK_POST0          (1<<10)
-#define S3C_CLKCON_SCLK_AUDIO1         (1<<9)
-#define S3C_CLKCON_SCLK_AUDIO0         (1<<8)
-#define S3C_CLKCON_SCLK_SECUR          (1<<7)
-#define S3C_CLKCON_SCLK_IRDA           (1<<6)
-#define S3C_CLKCON_SCLK_UART           (1<<5)
-#define S3C_CLKCON_SCLK_ONENAND        (1<<4)
-#define S3C_CLKCON_SCLK_MFC            (1<<3)
-#define S3C_CLKCON_SCLK_CAM            (1<<2)
-#define S3C_CLKCON_SCLK_JPEG           (1<<1)
-
-/* CLKSRC */
-
-#define S3C6400_CLKSRC_APLL_MOUT       (1 << 0)
-#define S3C6400_CLKSRC_MPLL_MOUT       (1 << 1)
-#define S3C6400_CLKSRC_EPLL_MOUT       (1 << 2)
-#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
-#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
-#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
-#define S3C6400_CLKSRC_MFC             (1 << 4)
 
 /* MEM_SYS_CFG */
 #define MEM_SYS_CFG_INDEP_CF           0x4000
index c3da1b68d03e0b352490b0df0e5ee8f1741ad87f..1649c0d1c1b80ff6a40f83ceb84881e354a54b1f 100644 (file)
  * published by the Free Software Foundation.
  */
 
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
 #include <linux/kernel.h>
 #include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/serial_core.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/of.h>
 
 #include <mach/map.h>
 
@@ -101,6 +106,10 @@ static struct syscore_ops s3c64xx_irq_syscore_ops = {
 
 static __init int s3c64xx_syscore_init(void)
 {
+       /* Appropriate drivers (pinctrl, uart) handle this when using DT. */
+       if (of_have_populated_dt())
+               return 0;
+
        register_syscore_ops(&s3c64xx_irq_syscore_ops);
 
        return 0;
index 35e3f54574eff6773f5c2eca10b69d0d1e02cccc..d266dd5f7060ec37d0266205bf129bdf86177a3e 100644 (file)
@@ -207,7 +207,7 @@ static struct platform_device *anw6410_devices[] __initdata = {
 static void __init anw6410_map_io(void)
 {
        s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
index eb8e5a1aca420005fa5e0988a099e51eb8ec6f94..1a911df9e4519e4c2f6ca494b5a2b182a14e765b 100644 (file)
@@ -743,7 +743,7 @@ static struct s3c2410_platform_i2c i2c1_pdata = {
 static void __init crag6410_map_io(void)
 {
        s3c64xx_init_io(NULL, 0);
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
index f39569e0f2e6c4045f95e333a255c72d87be4c98..e8064044ef796d35a12bfcc0e06c86dea065dca1 100644 (file)
@@ -247,7 +247,7 @@ static struct platform_device *hmt_devices[] __initdata = {
 static void __init hmt_map_io(void)
 {
        s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
index fc043e3ecdf8a869ea77e27af42dad5c24222356..58d46a3d7b78936f88318824d1a378fea2532fc1 100644 (file)
@@ -231,7 +231,7 @@ static void __init mini6410_map_io(void)
        u32 tmp;
 
        s3c64xx_init_io(NULL, 0);
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
index 7e2c3908f1f87a2db546867d9ff8417e2051049e..2067b0bf55b43127eef766b52beb283a11db6431 100644 (file)
@@ -86,7 +86,7 @@ static struct map_desc ncp_iodesc[] __initdata = {};
 static void __init ncp_map_io(void)
 {
        s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
new file mode 100644 (file)
index 0000000..7eb9a10
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Samsung's S3C64XX flattened device tree enabled machine
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.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.
+*/
+
+#include <linux/clk-provider.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <plat/cpu.h>
+#include <plat/watchdog-reset.h>
+
+#include <mach/map.h>
+
+#include "common.h"
+
+/*
+ * IO mapping for shared system controller IP.
+ *
+ * FIXME: Make remaining drivers use dynamic mapping.
+ */
+static struct map_desc s3c64xx_dt_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_SYS,
+               .pfn            = __phys_to_pfn(S3C64XX_PA_SYSCON),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void __init s3c64xx_dt_map_io(void)
+{
+       debug_ll_io_init();
+       iotable_init(s3c64xx_dt_iodesc, ARRAY_SIZE(s3c64xx_dt_iodesc));
+
+       s3c64xx_init_cpu();
+
+       if (!soc_is_s3c64xx())
+               panic("SoC is not S3C64xx!");
+}
+
+static void __init s3c64xx_dt_init_irq(void)
+{
+       of_clk_init(NULL);
+       samsung_wdt_reset_of_init();
+       irqchip_init();
+};
+
+static void __init s3c64xx_dt_init_machine(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd)
+{
+       if (mode != REBOOT_SOFT)
+               samsung_wdt_reset();
+
+       /* if all else fails, or mode was for soft, jump to 0 */
+       soft_restart(0);
+}
+
+static char const *s3c64xx_dt_compat[] __initdata = {
+       "samsung,s3c6400",
+       "samsung,s3c6410",
+       NULL
+};
+
+DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
+       /* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */
+       .dt_compat      = s3c64xx_dt_compat,
+       .map_io         = s3c64xx_dt_map_io,
+       .init_irq       = s3c64xx_dt_init_irq,
+       .init_machine   = s3c64xx_dt_init_machine,
+       .restart        = s3c64xx_dt_restart,
+MACHINE_END
index 86d980b448fd0bc272e1e0cf1ab616f0e32ab24e..0f47237be3b2dd2286fe0582791548d16df3a786 100644 (file)
@@ -337,13 +337,6 @@ err:
        return ret;
 }
 
-static int __init smartq_usb_otg_init(void)
-{
-       clk_xusbxti.rate = 12000000;
-
-       return 0;
-}
-
 static int __init smartq_wifi_init(void)
 {
        int ret;
@@ -377,7 +370,8 @@ static struct map_desc smartq_iodesc[] __initdata = {};
 void __init smartq_map_io(void)
 {
        s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
+       s3c64xx_set_xusbxti_freq(12000000);
        s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -399,7 +393,6 @@ void __init smartq_machine_init(void)
        WARN_ON(smartq_lcd_setup_gpio());
        WARN_ON(smartq_power_off_init());
        WARN_ON(smartq_usb_host_init());
-       WARN_ON(smartq_usb_otg_init());
        WARN_ON(smartq_wifi_init());
 
        platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
index d70c0843aea2d8bca384cc814d0270e778def128..27381cfcabbedbe2a669272d3786f56db08f11ba 100644 (file)
@@ -65,7 +65,7 @@ static struct map_desc smdk6400_iodesc[] = {};
 static void __init smdk6400_map_io(void)
 {
        s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
index d90b450c5645bb9f9c10944a65e3086623e25b3b..2a7b32ca5c96a3037c007eeb032092cf2127bfec 100644 (file)
@@ -634,7 +634,7 @@ static void __init smdk6410_map_io(void)
        u32 tmp;
 
        s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
-       s3c24xx_init_clocks(12000000);
+       s3c64xx_set_xtal_freq(12000000);
        s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
index 6a1f91fea678e471fdbf5a161ed2bdbd08a26108..8cdb824a3b432456c39353b64e658ac920e3e353 100644 (file)
@@ -194,29 +194,8 @@ void s3c_pm_debug_smdkled(u32 set, u32 clear)
 #endif
 
 static struct sleep_save core_save[] = {
-       SAVE_ITEM(S3C_APLL_LOCK),
-       SAVE_ITEM(S3C_MPLL_LOCK),
-       SAVE_ITEM(S3C_EPLL_LOCK),
-       SAVE_ITEM(S3C_CLK_SRC),
-       SAVE_ITEM(S3C_CLK_DIV0),
-       SAVE_ITEM(S3C_CLK_DIV1),
-       SAVE_ITEM(S3C_CLK_DIV2),
-       SAVE_ITEM(S3C_CLK_OUT),
-       SAVE_ITEM(S3C_HCLK_GATE),
-       SAVE_ITEM(S3C_PCLK_GATE),
-       SAVE_ITEM(S3C_SCLK_GATE),
-       SAVE_ITEM(S3C_MEM0_GATE),
-
-       SAVE_ITEM(S3C_EPLL_CON1),
-       SAVE_ITEM(S3C_EPLL_CON0),
-
        SAVE_ITEM(S3C64XX_MEM0DRVCON),
        SAVE_ITEM(S3C64XX_MEM1DRVCON),
-
-#ifndef CONFIG_CPU_FREQ
-       SAVE_ITEM(S3C_APLL_CON),
-       SAVE_ITEM(S3C_MPLL_CON),
-#endif
 };
 
 static struct sleep_save misc_save[] = {
index 4869714c6f1bb015e4b6af08705837169bad2466..3db0c98222f7686574be92d880f1ee25e5369e3f 100644 (file)
@@ -9,6 +9,10 @@
  * published by the Free Software Foundation.
 */
 
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -20,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -58,12 +63,6 @@ void __init s3c6400_map_io(void)
        s3c64xx_onenand1_setname("s3c6400-onenand");
 }
 
-void __init s3c6400_init_clocks(int xtal)
-{
-       s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK);
-       s3c64xx_setup_clocks();
-}
-
 void __init s3c6400_init_irq(void)
 {
        /* VIC0 does not have IRQS 5..7,
@@ -82,6 +81,10 @@ static struct device s3c6400_dev = {
 
 static int __init s3c6400_core_init(void)
 {
+       /* Not applicable when using DT. */
+       if (of_have_populated_dt())
+               return 0;
+
        return subsys_system_register(&s3c6400_subsys, NULL);
 }
 
index 31c29fdf1800404948a9e9e207454dcf337b7f7e..72b2278953a896a6dad6ad892e3a1438fd62d882 100644 (file)
  * published by the Free Software Foundation.
 */
 
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -21,6 +25,7 @@
 #include <linux/device.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -62,13 +67,6 @@ void __init s3c6410_map_io(void)
        s3c_cfcon_setname("s3c64xx-pata");
 }
 
-void __init s3c6410_init_clocks(int xtal)
-{
-       printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
-       s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK);
-       s3c64xx_setup_clocks();
-}
-
 void __init s3c6410_init_irq(void)
 {
        /* VIC0 is missing IRQ7, VIC1 is fully populated. */
@@ -86,6 +84,10 @@ static struct device s3c6410_dev = {
 
 static int __init s3c6410_core_init(void)
 {
+       /* Not applicable when using DT. */
+       if (of_have_populated_dt())
+               return 0;
+
        return subsys_system_register(&s3c6410_subsys, NULL);
 }
 
index 032de66fb8be2817496da9c431a2f5fef69d66f9..e345584d4c34ccbd8363680038ad1511adf04b2a 100644 (file)
 #define S5P_HDMI_PHY_CONTROL   S5P_CLKREG(0xE804)
 #define S5P_USB_PHY_CONTROL    S5P_CLKREG(0xE80C)
 #define S5P_DAC_PHY_CONTROL    S5P_CLKREG(0xE810)
-#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
-#define S5P_MIPI_DPHY_ENABLE   (1 << 0)
-#define S5P_MIPI_DPHY_SRESETN  (1 << 1)
-#define S5P_MIPI_DPHY_MRESETN  (1 << 2)
 
 #define S5P_INFORM0            S5P_CLKREG(0xF000)
 #define S5P_INFORM1            S5P_CLKREG(0xF004)
diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile
deleted file mode 100644 (file)
index 2965718..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y                  := core.o dma.o irq.o pci.o leds.o
-obj-m                  :=
-obj-n                  :=
-obj-                   :=
diff --git a/arch/arm/mach-shark/Makefile.boot b/arch/arm/mach-shark/Makefile.boot
deleted file mode 100644 (file)
index e40e24e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-   zreladdr-y  += 0x08008000
-
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
deleted file mode 100644 (file)
index 1d32c5e..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  linux/arch/arm/mach-shark/arch.c
- *
- *  Architecture specific stuff.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/serial_8250.h>
-#include <linux/io.h>
-#include <linux/cpu.h>
-#include <linux/reboot.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/param.h>
-#include <asm/system_misc.h>
-
-#include <asm/mach/map.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
-#define ROMCARD_SIZE            0x08000000
-#define ROMCARD_START           0x10000000
-
-static void shark_restart(enum reboot_mode mode, const char *cmd)
-{
-        short temp;
-        /* Reset the Machine via pc[3] of the sequoia chipset */
-        outw(0x09,0x24);
-        temp=inw(0x26);
-        temp = temp | (1<<3) | (1<<10);
-        outw(0x09,0x24);
-        outw(temp,0x26);
-}
-
-static struct plat_serial8250_port serial_platform_data[] = {
-       {
-               .iobase         = 0x3f8,
-               .irq            = 4,
-               .uartclk        = 1843200,
-               .regshift       = 0,
-               .iotype         = UPIO_PORT,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-       },
-       {
-               .iobase         = 0x2f8,
-               .irq            = 3,
-               .uartclk        = 1843200,
-               .regshift       = 0,
-               .iotype         = UPIO_PORT,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-       },
-       { },
-};
-
-static struct platform_device serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = serial_platform_data,
-       },
-};
-
-static struct resource rtc_resources[] = {
-       [0] = {
-               .start  = 0x70,
-               .end    = 0x73,
-               .flags  = IORESOURCE_IO,
-       },
-       [1] = {
-               .start  = IRQ_ISA_RTC_ALARM,
-               .end    = IRQ_ISA_RTC_ALARM,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device rtc_device = {
-       .name           = "rtc_cmos",
-       .id             = -1,
-       .resource       = rtc_resources,
-       .num_resources  = ARRAY_SIZE(rtc_resources),
-};
-
-static int __init shark_init(void)
-{
-       int ret;
-
-       if (machine_is_shark())
-       {
-               ret = platform_device_register(&rtc_device);
-               if (ret) printk(KERN_ERR "Unable to register RTC device: %d\n", ret);
-               ret = platform_device_register(&serial_device);
-               if (ret) printk(KERN_ERR "Unable to register Serial device: %d\n", ret);
-       }
-       return 0;
-}
-
-arch_initcall(shark_init);
-
-extern void shark_init_irq(void);
-
-#define IRQ_TIMER 0
-#define HZ_TIME ((1193180 + HZ/2) / HZ)
-
-static irqreturn_t
-shark_timer_interrupt(int irq, void *dev_id)
-{
-       timer_tick();
-       return IRQ_HANDLED;
-}
-
-static struct irqaction shark_timer_irq = {
-       .name           = "Shark Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = shark_timer_interrupt,
-};
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-static void __init shark_timer_init(void)
-{
-       outb(0x34, 0x43);               /* binary, mode 0, LSB/MSB, Ch 0 */
-       outb(HZ_TIME & 0xff, 0x40);     /* LSB of count */
-       outb(HZ_TIME >> 8, 0x40);
-
-       setup_irq(IRQ_TIMER, &shark_timer_irq);
-}
-
-static void shark_init_early(void)
-{
-       cpu_idle_poll_ctrl(true);
-}
-
-MACHINE_START(SHARK, "Shark")
-       /* Maintainer: Alexander Schulz */
-       .atag_offset    = 0x3000,
-       .init_early     = shark_init_early,
-       .init_irq       = shark_init_irq,
-       .init_time      = shark_timer_init,
-       .dma_zone_size  = SZ_4M,
-       .restart        = shark_restart,
-MACHINE_END
diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c
deleted file mode 100644 (file)
index 10b5b8b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  linux/arch/arm/mach-shark/dma.c
- *
- *  by Alexander Schulz
- *
- *  derived from:
- *  arch/arm/kernel/dma-ebsa285.c
- *  Copyright (C) 1998 Phil Blundell
- */
-
-#include <linux/init.h>
-
-#include <asm/dma.h>
-#include <asm/mach/dma.h>
-
-static int __init shark_dma_init(void)
-{
-#ifdef CONFIG_ISA_DMA
-       isa_init_dma();
-#endif
-       return 0;
-}
-core_initcall(shark_dma_init);
diff --git a/arch/arm/mach-shark/include/mach/debug-macro.S b/arch/arm/mach-shark/include/mach/debug-macro.S
deleted file mode 100644 (file)
index d129119..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* arch/arm/mach-shark/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * 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.
- *
-*/
-
-               .macro  addruart, rp, rv, tmp
-               mov     \rp, #0x3f8
-               orr     \rv, \rp, #0xfe000000
-               orr     \rv, \rv, #0x00e00000
-               orr     \rp, \rp, #0x40000000
-               .endm
-
-               .macro  senduart,rd,rx
-               strb    \rd, [\rx]
-               .endm
-
-               .macro waituart,rd,rx
-               .endm
-
-               .macro  busyuart,rd,rx
-               mov     \rd, #0
-1001:          add     \rd, \rd, #1
-               teq     \rd, #0x10000
-               bne     1001b
-               .endm
-
diff --git a/arch/arm/mach-shark/include/mach/entry-macro.S b/arch/arm/mach-shark/include/mach/entry-macro.S
deleted file mode 100644 (file)
index c9e49f0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for Shark platform
- *
- * 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.
- */
-               .macro  get_irqnr_preamble, base, tmp
-               mov     \base, #0xfe000000
-               orr     \base, \base, #0x00e00000
-               .endm
-
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               mov     \irqstat, #0x0C
-               strb    \irqstat, [\base, #0x20]        @outb(0x0C, 0x20) /* Poll command */
-               ldrb    \irqnr, [\base, #0x20]          @irq = inb(0x20) & 7
-               and     \irqstat, \irqnr, #0x80
-               teq     \irqstat, #0
-               beq     43f
-               and     \irqnr, \irqnr, #7
-               teq     \irqnr, #2
-               bne     44f
-43:            mov     \irqstat, #0x0C
-               strb    \irqstat, [\base, #0xa0]        @outb(0x0C, 0xA0) /* Poll command */
-               ldrb    \irqnr, [\base, #0xa0]          @irq = (inb(0xA0) & 7) + 8
-               and     \irqstat, \irqnr, #0x80
-               teq     \irqstat, #0
-               beq     44f
-               and     \irqnr, \irqnr, #7
-               add     \irqnr, \irqnr, #8
-44:            teq     \irqstat, #0
-               .endm
-
diff --git a/arch/arm/mach-shark/include/mach/framebuffer.h b/arch/arm/mach-shark/include/mach/framebuffer.h
deleted file mode 100644 (file)
index 84a5bf6..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/framebuffer.h
- *
- * by Alexander Schulz
- *
- */
-
-#ifndef __ASM_ARCH_FRAMEBUFFER_H
-#define __ASM_ARCH_FRAMEBUFFER_H
-
-/* defines for the Framebuffer */
-#define FB_START               0x06000000
-#define FB_SIZE                        0x01000000
-
-#endif
-
diff --git a/arch/arm/mach-shark/include/mach/hardware.h b/arch/arm/mach-shark/include/mach/hardware.h
deleted file mode 100644 (file)
index 663f952..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/hardware.h
- *
- * by Alexander Schulz
- *
- * derived from:
- * arch/arm/mach-ebsa110/include/mach/hardware.h
- * Copyright (C) 1996-1999 Russell King.
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#define UNCACHEABLE_ADDR        0xdf010000
-
-#endif
-
diff --git a/arch/arm/mach-shark/include/mach/irqs.h b/arch/arm/mach-shark/include/mach/irqs.h
deleted file mode 100644 (file)
index c8e8a4e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/irqs.h
- *
- * by Alexander Schulz
- */
-
-#define NR_IRQS                        16
-
-#define IRQ_ISA_KEYBOARD        1
-#define IRQ_ISA_RTC_ALARM       8
-#define I8042_KBD_IRQ           1
-#define I8042_AUX_IRQ          12
-#define IRQ_HARDDISK            14
diff --git a/arch/arm/mach-shark/include/mach/isa-dma.h b/arch/arm/mach-shark/include/mach/isa-dma.h
deleted file mode 100644 (file)
index 96c43b8..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/isa-dma.h
- *
- * by Alexander Schulz
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_CHANNELS       8
-#define DMA_ISA_CASCADE         4
-
-#endif /* _ASM_ARCH_DMA_H */
-
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
deleted file mode 100644 (file)
index 1cf8d69..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/memory.h
- *
- * by Alexander Schulz
- *
- * derived from:
- * arch/arm/mach-ebsa110/include/mach/memory.h
- * Copyright (c) 1996-1999 Russell King.
- */
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#include <asm/sizes.h>
-
-/*
- * Physical DRAM offset.
- */
-#define PLAT_PHYS_OFFSET     UL(0x08000000)
-
-/*
- * Cache flushing area
- */
-#define FLUSH_BASE_PHYS                0x80000000
-#define FLUSH_BASE             0xdf000000
-
-#endif
diff --git a/arch/arm/mach-shark/include/mach/timex.h b/arch/arm/mach-shark/include/mach/timex.h
deleted file mode 100644 (file)
index bb6eeae..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/timex.h
- *
- * by Alexander Schulz
- */
-
-#define CLOCK_TICK_RATE 1193180
diff --git a/arch/arm/mach-shark/include/mach/uncompress.h b/arch/arm/mach-shark/include/mach/uncompress.h
deleted file mode 100644 (file)
index a168435..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/uncompress.h
- * by Alexander Schulz
- *
- * derived from:
- * arch/arm/mach-footbridge/include/mach/uncompress.h
- * Copyright (C) 1996,1997,1998 Russell King
- */
-
-#define SERIAL_BASE ((volatile unsigned char *)0x400003f8)
-
-static inline void putc(int c)
-{
-       volatile int t;
-
-       SERIAL_BASE[0] = c;
-       t=0x10000;
-       while (t--);
-}
-
-static inline void flush(void)
-{
-}
-
-#ifdef DEBUG
-static void putn(unsigned long z)
-{
-       int i;
-       char x;
-
-       putc('0');
-       putc('x');
-       for (i=0;i<8;i++) {
-               x='0'+((z>>((7-i)*4))&0xf);
-               if (x>'9') x=x-'0'+'A'-10;
-               putc(x);
-       }
-}
-
-static void putr()
-{
-       putc('\n');
-       putc('\r');
-}
-#endif
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
deleted file mode 100644 (file)
index 5dce13e..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  linux/arch/arm/mach-shark/irq.c
- *
- * by Alexander Schulz
- *
- * derived from linux/arch/ppc/kernel/i8259.c and:
- * arch/arm/mach-ebsa110/include/mach/irq.h
- * Copyright (C) 1996-1998 Russell King
- */
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-/*
- * 8259A PIC functions to handle ISA devices:
- */
-
-/*
- * This contains the irq mask for both 8259A irq controllers,
- * Let through the cascade-interrupt no. 2 (ff-(1<<2)==fb)
- */
-static unsigned char cached_irq_mask[2] = { 0xfb, 0xff };
-
-/*
- * These have to be protected by the irq controller spinlock
- * before being called.
- */
-static void shark_disable_8259A_irq(struct irq_data *d)
-{
-       unsigned int mask;
-       if (d->irq<8) {
-         mask = 1 << d->irq;
-         cached_irq_mask[0] |= mask;
-         outb(cached_irq_mask[1],0xA1);
-       } else {
-         mask = 1 << (d->irq-8);
-         cached_irq_mask[1] |= mask;
-         outb(cached_irq_mask[0],0x21);
-       }
-}
-
-static void shark_enable_8259A_irq(struct irq_data *d)
-{
-       unsigned int mask;
-       if (d->irq<8) {
-         mask = ~(1 << d->irq);
-         cached_irq_mask[0] &= mask;
-         outb(cached_irq_mask[0],0x21);
-       } else {
-         mask = ~(1 << (d->irq-8));
-         cached_irq_mask[1] &= mask;
-         outb(cached_irq_mask[1],0xA1);
-       }
-}
-
-static void shark_ack_8259A_irq(struct irq_data *d){}
-
-static irqreturn_t bogus_int(int irq, void *dev_id)
-{
-       printk("Got interrupt %i!\n",irq);
-       return IRQ_NONE;
-}
-
-static struct irqaction cascade;
-
-static struct irq_chip fb_chip = {
-       .name           = "XT-PIC",
-       .irq_ack        = shark_ack_8259A_irq,
-       .irq_mask       = shark_disable_8259A_irq,
-       .irq_unmask     = shark_enable_8259A_irq,
-};
-
-void __init shark_init_irq(void)
-{
-       int irq;
-
-       for (irq = 0; irq < NR_IRQS; irq++) {
-               irq_set_chip_and_handler(irq, &fb_chip, handle_edge_irq);
-               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-       }
-
-       /* init master interrupt controller */
-       outb(0x11, 0x20); /* Start init sequence, edge triggered (level: 0x19)*/
-       outb(0x00, 0x21); /* Vector base */
-       outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */
-       outb(0x03, 0x21); /* Select 8086 mode , auto eoi*/
-       outb(0x0A, 0x20);
-       /* init slave interrupt controller */
-       outb(0x11, 0xA0); /* Start init sequence, edge triggered */
-       outb(0x08, 0xA1); /* Vector base */
-       outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */
-       outb(0x03, 0xA1); /* Select 8086 mode, auto eoi */
-       outb(0x0A, 0xA0);
-       outb(cached_irq_mask[1],0xA1);
-       outb(cached_irq_mask[0],0x21);
-       //request_region(0x20,0x2,"pic1");
-       //request_region(0xA0,0x2,"pic2");
-
-       cascade.handler = bogus_int;
-       cascade.name = "cascade";
-       setup_irq(2,&cascade);
-}
-
diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
deleted file mode 100644 (file)
index 081c778..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * DIGITAL Shark LED control routines.
- *
- * Driver for the 3 user LEDs found on the Shark
- * Based on Versatile and RealView machine LED code
- *
- * License terms: GNU General Public License (GPL) version 2
- * Author: Bryan Wu <bryan.wu@canonical.com>
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/leds.h>
-
-#include <asm/mach-types.h>
-
-#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
-struct shark_led {
-       struct led_classdev cdev;
-       u8 mask;
-};
-
-/*
- * The triggers lines up below will only be used if the
- * LED triggers are compiled in.
- */
-static const struct {
-       const char *name;
-       const char *trigger;
-} shark_leds[] = {
-       { "shark:amber0", "default-on", },      /* Bit 5 */
-       { "shark:green", "heartbeat", },        /* Bit 6 */
-       { "shark:amber1", "cpu0" },             /* Bit 7 */
-};
-
-static u16 led_reg_read(void)
-{
-       outw(0x09, 0x24);
-       return inw(0x26);
-}
-
-static void led_reg_write(u16 value)
-{
-       outw(0x09, 0x24);
-       outw(value, 0x26);
-}
-
-static void shark_led_set(struct led_classdev *cdev,
-                             enum led_brightness b)
-{
-       struct shark_led *led = container_of(cdev,
-                                                struct shark_led, cdev);
-       u16 reg = led_reg_read();
-
-       if (b != LED_OFF)
-               reg |= led->mask;
-       else
-               reg &= ~led->mask;
-
-       led_reg_write(reg);
-}
-
-static enum led_brightness shark_led_get(struct led_classdev *cdev)
-{
-       struct shark_led *led = container_of(cdev,
-                                                struct shark_led, cdev);
-       u16 reg = led_reg_read();
-
-       return (reg & led->mask) ? LED_FULL : LED_OFF;
-}
-
-static int __init shark_leds_init(void)
-{
-       int i;
-       u16 reg;
-
-       if (!machine_is_shark())
-               return -ENODEV;
-
-       for (i = 0; i < ARRAY_SIZE(shark_leds); i++) {
-               struct shark_led *led;
-
-               led = kzalloc(sizeof(*led), GFP_KERNEL);
-               if (!led)
-                       break;
-
-               led->cdev.name = shark_leds[i].name;
-               led->cdev.brightness_set = shark_led_set;
-               led->cdev.brightness_get = shark_led_get;
-               led->cdev.default_trigger = shark_leds[i].trigger;
-
-               /* Count in 5 bits offset */
-               led->mask = BIT(i + 5);
-
-               if (led_classdev_register(NULL, &led->cdev) < 0) {
-                       kfree(led);
-                       break;
-               }
-       }
-
-       /* Make LEDs independent of power-state */
-       request_region(0x24, 4, "led_reg");
-       reg = led_reg_read();
-       reg |= 1 << 10;
-       led_reg_write(reg);
-
-       return 0;
-}
-
-/*
- * Since we may have triggers on any subsystem, defer registration
- * until after subsystem_init.
- */
-fs_initcall(shark_leds_init);
-#endif
diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c
deleted file mode 100644 (file)
index 6d91a91..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  linux/arch/arm/mach-shark/pci.c
- *
- *  PCI bios-type initialisation for PCI machines
- *
- *  Bits taken from various places.
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <video/vga.h>
-
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-#define IO_START       0x40000000
-
-static int __init shark_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       if (dev->bus->number == 0)
-               if (dev->devfn == 0)
-                       return 255;
-               else
-                       return 11;
-       else
-               return 255;
-}
-
-extern void __init via82c505_preinit(void);
-
-static struct hw_pci shark_pci __initdata = {
-       .setup          = via82c505_setup,
-       .map_irq        = shark_map_irq,
-       .nr_controllers = 1,
-       .ops            = &via82c505_ops,
-       .preinit        = via82c505_preinit,
-};
-
-static int __init shark_pci_init(void)
-{
-       if (!machine_is_shark())
-               return -ENODEV;
-
-       pcibios_min_io = 0x6000;
-       pcibios_min_mem = 0x50000000;
-       vga_base = 0xe8000000;
-
-       pci_ioremap_io(0, IO_START);
-
-       pci_common_init(&shark_pci);
-
-       return 0;
-}
-
-subsys_initcall(shark_pci_init);
index 1f94c310c4775f3a40e168e84845d4da6dbd40ab..a4a4b75109b218c53fc2cb8357f2465fb90b18d7 100644 (file)
@@ -22,16 +22,10 @@ config ARCH_EMEV2
 
 comment "SH-Mobile Board Type"
 
-config MACH_KZM9D_REFERENCE
-       bool "KZM9D board - Reference Device Tree Implementation"
+config MACH_KZM9D
+       bool "KZM9D board"
        depends on ARCH_EMEV2
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       ---help---
-          Use reference implementation of KZM9D board support
-          which makes a greater use of device tree at the expense
-          of not supporting a number of devices.
-
-          This is intended to aid developers
 
 comment "SH-Mobile System Configuration"
 endif
@@ -101,12 +95,24 @@ config ARCH_R8A7790
        select SH_CLK_CPG
        select RENESAS_IRQC
 
+config ARCH_R8A7791
+       bool "R-Car M2 (R8A77910)"
+       select ARM_GIC
+       select CPU_V7
+       select SH_CLK_CPG
+
 config ARCH_EMEV2
        bool "Emma Mobile EV2"
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
        select CPU_V7
 
+config ARCH_R7S72100
+       bool "RZ/A1H (R7S72100)"
+       select ARM_GIC
+       select CPU_V7
+       select SH_CLK_CPG
+
 comment "SH-Mobile Board Type"
 
 config MACH_APE6EVM
@@ -162,6 +168,8 @@ config MACH_BOCKW
        select RENESAS_INTC_IRQPIN
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
        select USE_OF
+       select SND_SOC_AK4554 if SND_SIMPLE_CARD
+       select SND_SOC_AK4642 if SND_SIMPLE_CARD
 
 config MACH_BOCKW_REFERENCE
        bool "BOCK-W  - Reference Device Tree Implementation"
@@ -177,6 +185,11 @@ config MACH_BOCKW_REFERENCE
 
           This is intended to aid developers
 
+config MACH_GENMAI
+       bool "Genmai board"
+       depends on ARCH_R7S72100
+       select USE_OF
+
 config MACH_MARZEN
        bool "MARZEN board"
        depends on ARCH_R8A7779
@@ -213,23 +226,16 @@ config MACH_LAGER_REFERENCE
 
           This is intended to aid developers
 
-config MACH_KZM9D
-       bool "KZM9D board"
-       depends on ARCH_EMEV2
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
+config MACH_KOELSCH
+       bool "Koelsch board"
+       depends on ARCH_R8A7791
        select USE_OF
 
-config MACH_KZM9D_REFERENCE
-       bool "KZM9D board - Reference Device Tree Implementation"
+config MACH_KZM9D
+       bool "KZM9D board"
        depends on ARCH_EMEV2
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
        select USE_OF
-       ---help---
-          Use reference implementation of KZM9D board support
-          which makes a greater use of device tree at the expense
-          of not supporting a number of devices.
-
-          This is intended to aid developers
 
 config MACH_KZM9G
        bool "KZM-A9-GT board"
index 2705bfa8c113161d0368e11e7f7158a294cb26a6..51db2bcafabf028f97cb4ffc5e32def8ef1aad77 100644 (file)
@@ -15,7 +15,10 @@ obj-$(CONFIG_ARCH_R8A7740)   += setup-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7778)     += setup-r8a7778.o
 obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o
+obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o setup-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7791)     += setup-r8a7791.o setup-rcar-gen2.o
 obj-$(CONFIG_ARCH_EMEV2)       += setup-emev2.o
+obj-$(CONFIG_ARCH_R7S72100)    += setup-r7s72100.o
 
 # Clock objects
 ifndef CONFIG_COMMON_CLK
@@ -27,13 +30,17 @@ obj-$(CONFIG_ARCH_R8A7740)  += clock-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7778)     += clock-r8a7778.o
 obj-$(CONFIG_ARCH_R8A7779)     += clock-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)     += clock-r8a7790.o
+obj-$(CONFIG_ARCH_R8A7791)     += clock-r8a7791.o
 obj-$(CONFIG_ARCH_EMEV2)       += clock-emev2.o
+obj-$(CONFIG_ARCH_R7S72100)    += clock-r7s72100.o
 endif
 
 # SMP objects
 smp-y                          := platsmp.o headsmp.o
 smp-$(CONFIG_ARCH_SH73A0)      += smp-sh73a0.o headsmp-scu.o platsmp-scu.o
 smp-$(CONFIG_ARCH_R8A7779)     += smp-r8a7779.o headsmp-scu.o platsmp-scu.o
+smp-$(CONFIG_ARCH_R8A7790)     += smp-r8a7790.o platsmp-apmu.o
+smp-$(CONFIG_ARCH_R8A7791)     += smp-r8a7791.o platsmp-apmu.o
 smp-$(CONFIG_ARCH_EMEV2)       += smp-emev2.o headsmp-scu.o platsmp-scu.o
 
 # IRQ objects
@@ -48,21 +55,26 @@ obj-$(CONFIG_ARCH_R8A7740)  += pm-r8a7740.o pm-rmobile.o
 obj-$(CONFIG_ARCH_R8A7779)     += pm-r8a7779.o
 
 # Board objects
+ifdef CONFIG_ARCH_SHMOBILE_MULTI
+obj-$(CONFIG_MACH_KZM9D)       += board-kzm9d-reference.o
+else
 obj-$(CONFIG_MACH_APE6EVM)     += board-ape6evm.o
 obj-$(CONFIG_MACH_APE6EVM_REFERENCE)   += board-ape6evm-reference.o
 obj-$(CONFIG_MACH_MACKEREL)    += board-mackerel.o
 obj-$(CONFIG_MACH_BOCKW)       += board-bockw.o
 obj-$(CONFIG_MACH_BOCKW_REFERENCE)     += board-bockw-reference.o
+obj-$(CONFIG_MACH_GENMAI)      += board-genmai.o
 obj-$(CONFIG_MACH_MARZEN)      += board-marzen.o
 obj-$(CONFIG_MACH_MARZEN_REFERENCE)    += board-marzen-reference.o
 obj-$(CONFIG_MACH_LAGER)       += board-lager.o
 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_KZM9D_REFERENCE)     += board-kzm9d-reference.o
 obj-$(CONFIG_MACH_KZM9G)       += board-kzm9g.o
 obj-$(CONFIG_MACH_KZM9G_REFERENCE)     += board-kzm9g-reference.o
+endif
 
 # Framework support
 obj-$(CONFIG_SMP)              += $(smp-y)
index 6a504fe7d86c45cb1c9c43a746bfe5beecfca7bb..391d72a5536ceb473acee7eaf2f0312ef268b6ce 100644 (file)
@@ -6,8 +6,9 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000
 loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000
 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_KZM9D_REFERENCE) += 0x40008000
 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
 loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
 loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
index a23fa714f7ac5c12016916cbbad0ffc8b68dccab..3276afcf3cc92de2c0ab94548a7f9d6bac039e37 100644 (file)
@@ -57,7 +57,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(APE6EVM_DT, "ape6evm")
-       .init_early     = r8a73a4_init_delay,
+       .init_early     = r8a73a4_init_early,
        .init_machine   = ape6evm_add_standard_devices,
        .dt_compat      = ape6evm_boards_compat_dt,
 MACHINE_END
index 24b87eea9da36d2f029a668a4bbacd7223c40683..0fa068e30a3001992952a41230cf9ca609793c72 100644 (file)
@@ -86,7 +86,7 @@ static struct gpio_keys_button gpio_buttons[] = {
        GPIO_KEY(KEY_VOLUMEDOWN,        329,    "S21"),
 };
 
-static struct __initdata gpio_keys_platform_data ape6evm_keys_pdata = {
+static struct gpio_keys_platform_data ape6evm_keys_pdata __initdata = {
        .buttons        = gpio_buttons,
        .nbuttons       = ARRAY_SIZE(gpio_buttons),
 };
@@ -113,22 +113,58 @@ static const struct smsc911x_platform_config lan9220_data __initconst = {
 };
 
 /*
- * On APE6EVM power is supplied to MMCIF by a tps80032 regulator. For now we
- * model a VDD supply to MMCIF, using a fixed 3.3V regulator. Also use the
- * static power supply for SDHI0 and SDHI1, whereas SDHI0's VccQ is also
- * supplied by the same tps80032 regulator and thus can also be adjusted
- * dynamically.
+ * MMC0 power supplies:
+ * Both Vcc and VccQ to eMMC on APE6EVM are supplied by a tps80032 voltage
+ * regulator. Until support for it is added to this file we simulate the
+ * Vcc supply by a fixed always-on regulator
  */
-static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+static struct regulator_consumer_supply vcc_mmc0_consumers[] =
 {
        REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+};
+
+/*
+ * SDHI0 power supplies:
+ * Vcc to SDHI0 on APE6EVM is supplied by a GPIO-switchable regulator. VccQ is
+ * provided by the same tps80032 regulator as both MMC0 voltages - see comment
+ * above
+ */
+static struct regulator_consumer_supply vcc_sdhi0_consumers[] =
+{
        REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data vcc_sdhi0_init_data = {
+       .constraints = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(vcc_sdhi0_consumers),
+       .consumer_supplies      = vcc_sdhi0_consumers,
+};
+
+static const struct fixed_voltage_config vcc_sdhi0_info __initconst = {
+       .supply_name = "SDHI0 Vcc",
+       .microvolts = 3300000,
+       .gpio = 76,
+       .enable_high = 1,
+       .init_data = &vcc_sdhi0_init_data,
+};
+
+/*
+ * SDHI1 power supplies:
+ * Vcc and VccQ to SDHI1 on APE6EVM are both fixed at 3.3V
+ */
+static struct regulator_consumer_supply vcc_sdhi1_consumers[] =
+{
        REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
 };
 
 /* MMCIF */
 static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = {
        .caps           = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+       .slave_id_tx    = SHDMA_SLAVE_MMCIF0_TX,
+       .slave_id_rx    = SHDMA_SLAVE_MMCIF0_RX,
+       .ccs_unsupported = true,
 };
 
 static const struct resource mmcif0_resources[] __initconst = {
@@ -215,14 +251,19 @@ static void __init ape6evm_add_standard_devices(void)
        platform_device_register_resndata(&platform_bus, "smsc911x", -1,
                                          lan9220_res, ARRAY_SIZE(lan9220_res),
                                          &lan9220_data, sizeof(lan9220_data));
-       regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
-                                    ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+       regulator_register_always_on(1, "MMC0 Vcc", vcc_mmc0_consumers,
+                                    ARRAY_SIZE(vcc_mmc0_consumers), 2800000);
        platform_device_register_resndata(&platform_bus, "sh_mmcif", 0,
                                          mmcif0_resources, ARRAY_SIZE(mmcif0_resources),
                                          &mmcif0_pdata, sizeof(mmcif0_pdata));
+       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2,
+                                     &vcc_sdhi0_info, sizeof(vcc_sdhi0_info));
        platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0,
                                          sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
                                          &sdhi0_pdata, sizeof(sdhi0_pdata));
+       regulator_register_always_on(3, "SDHI1 Vcc", vcc_sdhi1_consumers,
+                                    ARRAY_SIZE(vcc_sdhi1_consumers), 3300000);
        platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1,
                                          sdhi1_resources, ARRAY_SIZE(sdhi1_resources),
                                          &sdhi1_pdata, sizeof(sdhi1_pdata));
@@ -240,7 +281,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(APE6EVM_DT, "ape6evm")
-       .init_early     = r8a73a4_init_delay,
+       .init_early     = r8a73a4_init_early,
        .init_machine   = ape6evm_add_standard_devices,
        .dt_compat      = ape6evm_boards_compat_dt,
 MACHINE_END
index 7f8f6076d3609e82382bb98f116df3bfc59049ed..8bc8e4c5884767f381c09da79ffcf2b52e2ffdc9 100644 (file)
@@ -823,6 +823,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
        .caps           = MMC_CAP_4_BIT_DATA |
                          MMC_CAP_8_BIT_DATA |
                          MMC_CAP_NONREMOVABLE,
+       .ccs_unsupported = true,
        .slave_id_tx    = SHDMA_SLAVE_MMCIF_TX,
        .slave_id_rx    = SHDMA_SLAVE_MMCIF_RX,
 };
index 1a7c893e1a529d1cfd293575a1b75c62eebfb00c..ae88fdad4b3a9921ea02f9c1db001348753bb98a 100644 (file)
@@ -36,15 +36,35 @@ static const struct pinctrl_map bockw_pinctrl_map[] = {
                                  "scif0_ctrl", "scif0"),
 };
 
+#define FPGA   0x18200000
+#define IRQ0MR 0x30
+#define COMCTLR        0x101c
 static void __init bockw_init(void)
 {
+       static void __iomem *fpga;
+
        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);
+       if (fpga) {
+               /*
+                * CAUTION
+                *
+                * IRQ0/1 is cascaded interrupt from FPGA.
+                * it should be cared in the future
+                * Now, it is assuming IRQ0 was used only from SMSC.
+                */
+               u16 val = ioread16(fpga + IRQ0MR);
+               val &= ~(1 << 4); /* enable SMSC911x */
+               iowrite16(val, fpga + IRQ0MR);
+       }
+
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
index 6b9faf3908f72b2f23bd3a1a3b07887c6581bc9b..38611526fe9a55953372afcd2662aa668b34e080 100644 (file)
 #include <linux/smsc911x.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/usb/renesas_usbhs.h>
 #include <media/soc_camera.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r8a7778.h>
 #include <asm/mach/arch.h>
+#include <sound/rcar_snd.h>
+#include <sound/simple_card.h>
+
+#define FPGA   0x18200000
+#define IRQ0MR 0x30
+#define COMCTLR        0x101c
+static void __iomem *fpga;
 
 /*
  *     CN9(Upper side) SCIF/RCAN selection
  * SW19        (MMC)   1 pin
  */
 
+/*
+ *     SSI settings
+ *
+ * SW45: 1-4 side      (SSI5 out, ROUT/LOUT CN19 Mid)
+ * SW46: 1101          (SSI6 Recorde)
+ * SW47: 1110          (SSI5 Playback)
+ * SW48: 11            (Recorde power)
+ * SW49: 1             (SSI slave mode)
+ * SW50: 1111          (SSI7, SSI8)
+ * SW51: 1111          (SSI3, SSI4)
+ * SW54: 1pin          (ak4554 FPGA control)
+ * SW55: 1             (CLKB is 24.5760MHz)
+ * SW60: 1pin          (ak4554 FPGA control)
+ * SW61: 3pin          (use X11 clock)
+ * SW78: 3-6           (ak4642 connects I2C0)
+ *
+ * You can use sound as
+ *
+ * hw0: CN19: SSI56-AK4643
+ * hw1: CN21: SSI3-AK4554(playback)
+ * hw2: CN21: SSI4-AK4554(capture)
+ * hw3: CN20: SSI7-AK4554(playback)
+ * hw4: CN20: SSI8-AK4554(capture)
+ *
+ * this command is required when playback on hw0.
+ *
+ * # amixer set "LINEOUT Mixer DACL" on
+ */
+
+/*
+ * USB
+ *
+ * USB1 (CN29) can be Host/Function
+ *
+ *             Host    Func
+ * SW98                1       2
+ * SW99                1       3
+ */
+
 /* Dummy supplies, where voltage doesn't matter */
 static struct regulator_consumer_supply dummy_supplies[] = {
        REGULATOR_SUPPLY("vddvario", "smsc911x"),
@@ -81,16 +128,76 @@ static struct resource smsc911x_resources[] __initdata = {
        DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */
 };
 
+#if IS_ENABLED(CONFIG_USB_RENESAS_USBHS_UDC)
+/*
+ * When USB1 is Func
+ */
+static int usbhsf_get_id(struct platform_device *pdev)
+{
+       return USBHS_GADGET;
+}
+
+#define SUSPMODE       0x102
+static int usbhsf_power_ctrl(struct platform_device *pdev,
+                            void __iomem *base, int enable)
+{
+       enable = !!enable;
+
+       r8a7778_usb_phy_power(enable);
+
+       iowrite16(enable << 14, base + SUSPMODE);
+
+       return 0;
+}
+
+static struct resource usbhsf_resources[] __initdata = {
+       DEFINE_RES_MEM(0xffe60000, 0x110),
+       DEFINE_RES_IRQ(gic_iid(0x4f)),
+};
+
+static struct renesas_usbhs_platform_info usbhs_info __initdata = {
+       .platform_callback = {
+               .get_id         = usbhsf_get_id,
+               .power_ctrl     = usbhsf_power_ctrl,
+       },
+       .driver_param = {
+               .buswait_bwait  = 4,
+       },
+};
+
+#define USB_PHY_SETTING {.port1_func = 1, .ovc_pin[1].active_high = 1,}
+#define USB1_DEVICE    "renesas_usbhs"
+#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE()                      \
+       platform_device_register_resndata(                      \
+               &platform_bus, "renesas_usbhs", -1,             \
+               usbhsf_resources,                               \
+               ARRAY_SIZE(usbhsf_resources),                   \
+               &usbhs_info, sizeof(struct renesas_usbhs_platform_info))
+
+#else
+/*
+ * When USB1 is Host
+ */
+#define USB_PHY_SETTING { }
+#define USB1_DEVICE    "ehci-platform"
+#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE()
+
+#endif
+
 /* USB */
 static struct resource usb_phy_resources[] __initdata = {
        DEFINE_RES_MEM(0xffe70800, 0x100),
        DEFINE_RES_MEM(0xffe76000, 0x100),
 };
 
-static struct rcar_phy_platform_data usb_phy_platform_data __initdata;
+static struct rcar_phy_platform_data usb_phy_platform_data __initdata =
+       USB_PHY_SETTING;
+
 
 /* SDHI */
 static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
+       .dma_slave_tx   = HPBDMA_SLAVE_SDHI0_TX,
+       .dma_slave_rx   = HPBDMA_SLAVE_SDHI0_RX,
        .tmio_caps      = MMC_CAP_SD_HIGHSPEED,
        .tmio_ocr_mask  = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
        .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT,
@@ -101,6 +208,12 @@ static struct resource sdhi0_resources[] __initdata = {
        DEFINE_RES_IRQ(gic_iid(0x77)),
 };
 
+/* Ether */
+static struct resource ether_resources[] __initdata = {
+       DEFINE_RES_MEM(0xfde00000, 0x400),
+       DEFINE_RES_IRQ(gic_iid(0x89)),
+};
+
 static struct sh_eth_plat_data ether_platform_data __initdata = {
        .phy            = 0x01,
        .edmac_endian   = EDMAC_LITTLE_ENDIAN,
@@ -118,7 +231,9 @@ static struct sh_eth_plat_data ether_platform_data __initdata = {
 static struct i2c_board_info i2c0_devices[] = {
        {
                I2C_BOARD_INFO("rx8581", 0x51),
-       },
+       }, {
+               I2C_BOARD_INFO("ak4643", 0x12),
+       }
 };
 
 /* HSPI*/
@@ -162,10 +277,6 @@ static struct sh_mmcif_plat_data sh_mmcif_plat __initdata = {
                          MMC_CAP_NEEDS_POLL,
 };
 
-static struct rcar_vin_platform_data vin_platform_data __initdata = {
-       .flags  = RCAR_VIN_BT656,
-};
-
 /* In the default configuration both decoders reside on I2C bus 0 */
 #define BOCKW_CAMERA(idx)                                              \
 static struct i2c_board_info camera##idx##_info = {                    \
@@ -181,7 +292,237 @@ static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = {      \
 BOCKW_CAMERA(0);
 BOCKW_CAMERA(1);
 
+/* VIN */
+static struct rcar_vin_platform_data vin_platform_data __initdata = {
+       .flags  = RCAR_VIN_BT656,
+};
+
+#define R8A7778_VIN(idx)                                               \
+static struct resource vin##idx##_resources[] __initdata = {           \
+       DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000),            \
+       DEFINE_RES_IRQ(gic_iid(0x5a)),                                  \
+};                                                                     \
+                                                                       \
+static struct platform_device_info vin##idx##_info __initdata = {      \
+       .parent         = &platform_bus,                                \
+       .name           = "r8a7778-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),                    \
+}
+R8A7778_VIN(0);
+R8A7778_VIN(1);
+
+/* Sound */
+static struct resource rsnd_resources[] __initdata = {
+       [RSND_GEN1_SRU] = DEFINE_RES_MEM(0xffd90000, 0x1000),
+       [RSND_GEN1_SSI] = DEFINE_RES_MEM(0xffd91000, 0x1240),
+       [RSND_GEN1_ADG] = DEFINE_RES_MEM(0xfffe0000, 0x24),
+};
+
+static struct rsnd_ssi_platform_info rsnd_ssi[] = {
+       RSND_SSI_UNUSED, /* SSI 0 */
+       RSND_SSI_UNUSED, /* SSI 1 */
+       RSND_SSI_UNUSED, /* SSI 2 */
+       RSND_SSI_SET(1, 0, gic_iid(0x85), RSND_SSI_PLAY),
+       RSND_SSI_SET(2, 0, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG),
+       RSND_SSI_SET(0, 0, gic_iid(0x86), RSND_SSI_PLAY),
+       RSND_SSI_SET(0, 0, gic_iid(0x86), 0),
+       RSND_SSI_SET(3, 0, gic_iid(0x86), RSND_SSI_PLAY),
+       RSND_SSI_SET(4, 0, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG),
+};
+
+static struct rsnd_scu_platform_info rsnd_scu[9] = {
+       /* no member at this point */
+};
+
+enum {
+       AK4554_34 = 0,
+       AK4643_56,
+       AK4554_78,
+       SOUND_MAX,
+};
+
+static int rsnd_codec_power(int id, int enable)
+{
+       static int sound_user[SOUND_MAX] = {0, 0, 0};
+       int *usr = NULL;
+       u32 bit;
+
+       switch (id) {
+       case 3:
+       case 4:
+               usr = sound_user + AK4554_34;
+               bit = (1 << 10);
+               break;
+       case 5:
+       case 6:
+               usr = sound_user + AK4643_56;
+               bit = (1 << 6);
+               break;
+       case 7:
+       case 8:
+               usr = sound_user + AK4554_78;
+               bit = (1 << 7);
+               break;
+       }
+
+       if (!usr)
+               return -EIO;
+
+       if (enable) {
+               if (*usr == 0) {
+                       u32 val = ioread16(fpga + COMCTLR);
+                       val &= ~bit;
+                       iowrite16(val, fpga + COMCTLR);
+               }
+
+               (*usr)++;
+       } else {
+               if (*usr == 0)
+                       return 0;
+
+               (*usr)--;
+
+               if (*usr == 0) {
+                       u32 val = ioread16(fpga + COMCTLR);
+                       val |= bit;
+                       iowrite16(val, fpga + COMCTLR);
+               }
+       }
+
+       return 0;
+}
+
+static int rsnd_start(int id)
+{
+       return rsnd_codec_power(id, 1);
+}
+
+static int rsnd_stop(int id)
+{
+       return rsnd_codec_power(id, 0);
+}
+
+static struct rcar_snd_info rsnd_info = {
+       .flags          = RSND_GEN1,
+       .ssi_info       = rsnd_ssi,
+       .ssi_info_nr    = ARRAY_SIZE(rsnd_ssi),
+       .scu_info       = rsnd_scu,
+       .scu_info_nr    = ARRAY_SIZE(rsnd_scu),
+       .start          = rsnd_start,
+       .stop           = rsnd_stop,
+};
+
+static struct asoc_simple_card_info rsnd_card_info[] = {
+       /* SSI5, SSI6 */
+       {
+               .name           = "AK4643",
+               .card           = "SSI56-AK4643",
+               .codec          = "ak4642-codec.0-0012",
+               .platform       = "rcar_sound",
+               .daifmt         = SND_SOC_DAIFMT_LEFT_J,
+               .cpu_dai = {
+                       .name   = "rsnd-dai.0",
+                       .fmt    = SND_SOC_DAIFMT_CBS_CFS,
+               },
+               .codec_dai = {
+                       .name   = "ak4642-hifi",
+                       .fmt    = SND_SOC_DAIFMT_CBM_CFM,
+                       .sysclk = 11289600,
+               },
+       },
+       /* SSI3 */
+       {
+               .name           = "AK4554",
+               .card           = "SSI3-AK4554(playback)",
+               .codec          = "ak4554-adc-dac.0",
+               .platform       = "rcar_sound",
+               .cpu_dai = {
+                       .name   = "rsnd-dai.1",
+                       .fmt    = SND_SOC_DAIFMT_CBM_CFM |
+                                 SND_SOC_DAIFMT_RIGHT_J,
+               },
+               .codec_dai = {
+                       .name   = "ak4554-hifi",
+               },
+       },
+       /* SSI4 */
+       {
+               .name           = "AK4554",
+               .card           = "SSI4-AK4554(capture)",
+               .codec          = "ak4554-adc-dac.0",
+               .platform       = "rcar_sound",
+               .cpu_dai = {
+                       .name   = "rsnd-dai.2",
+                       .fmt    = SND_SOC_DAIFMT_CBM_CFM |
+                                 SND_SOC_DAIFMT_LEFT_J,
+               },
+               .codec_dai = {
+                       .name   = "ak4554-hifi",
+               },
+       },
+       /* SSI7 */
+       {
+               .name           = "AK4554",
+               .card           = "SSI7-AK4554(playback)",
+               .codec          = "ak4554-adc-dac.1",
+               .platform       = "rcar_sound",
+               .cpu_dai = {
+                       .name   = "rsnd-dai.3",
+                       .fmt    = SND_SOC_DAIFMT_CBM_CFM |
+                                 SND_SOC_DAIFMT_RIGHT_J,
+               },
+               .codec_dai = {
+                       .name   = "ak4554-hifi",
+               },
+       },
+       /* SSI8 */
+       {
+               .name           = "AK4554",
+               .card           = "SSI8-AK4554(capture)",
+               .codec          = "ak4554-adc-dac.1",
+               .platform       = "rcar_sound",
+               .cpu_dai = {
+                       .name   = "rsnd-dai.4",
+                       .fmt    = SND_SOC_DAIFMT_CBM_CFM |
+                                 SND_SOC_DAIFMT_LEFT_J,
+               },
+               .codec_dai = {
+                       .name   = "ak4554-hifi",
+               },
+       }
+};
+
 static const struct pinctrl_map bockw_pinctrl_map[] = {
+       /* AUDIO */
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "audio_clk_a", "audio_clk"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "audio_clk_b", "audio_clk"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi34_ctrl", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi3_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi4_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi5_ctrl", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi5_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi6_ctrl", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi6_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi78_ctrl", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi7_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778",
+                                 "ssi8_data", "ssi"),
        /* Ether */
        PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778",
                                  "ether_rmii", "ether"),
@@ -201,7 +542,7 @@ static const struct pinctrl_map bockw_pinctrl_map[] = {
        /* USB */
        PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778",
                                  "usb0", "usb0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778",
+       PIN_MAP_MUX_GROUP_DEFAULT(USB1_DEVICE, "pfc-r8a7778",
                                  "usb1", "usb1"),
        /* SDHI0 */
        PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
@@ -224,22 +565,28 @@ static const struct pinctrl_map bockw_pinctrl_map[] = {
                                  "vin1_data8", "vin1"),
 };
 
-#define FPGA   0x18200000
-#define IRQ0MR 0x30
 #define PFC    0xfffc0000
 #define PUPR4  0x110
 static void __init bockw_init(void)
 {
        void __iomem *base;
+       struct clk *clk;
+       int i;
 
        r8a7778_clock_init();
        r8a7778_init_irq_extpin(1);
        r8a7778_add_standard_devices();
-       r8a7778_add_ether_device(&ether_platform_data);
-       r8a7778_add_vin_device(0, &vin_platform_data);
+
+       platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
+                                         ether_resources,
+                                         ARRAY_SIZE(ether_resources),
+                                         &ether_platform_data,
+                                         sizeof(ether_platform_data));
+
+       platform_device_register_full(&vin0_info);
        /* VIN1 has a pin conflict with Ether */
        if (!IS_ENABLED(CONFIG_SH_ETH))
-               r8a7778_add_vin_device(1, &vin_platform_data);
+               platform_device_register_full(&vin1_info);
        platform_device_register_data(&platform_bus, "soc-camera-pdrv", 0,
                                      &iclink0_ml86v7667,
                                      sizeof(iclink0_ml86v7667));
@@ -269,8 +616,8 @@ static void __init bockw_init(void)
 
 
        /* for SMSC */
-       base = ioremap_nocache(FPGA, SZ_1M);
-       if (base) {
+       fpga = ioremap_nocache(FPGA, SZ_1M);
+       if (fpga) {
                /*
                 * CAUTION
                 *
@@ -278,10 +625,9 @@ static void __init bockw_init(void)
                 * it should be cared in the future
                 * Now, it is assuming IRQ0 was used only from SMSC.
                 */
-               u16 val = ioread16(base + IRQ0MR);
+               u16 val = ioread16(fpga + IRQ0MR);
                val &= ~(1 << 4); /* enable SMSC911x */
-               iowrite16(val, base + IRQ0MR);
-               iounmap(base);
+               iowrite16(val, fpga + IRQ0MR);
 
                regulator_register_fixed(0, dummy_supplies,
                                         ARRAY_SIZE(dummy_supplies));
@@ -308,6 +654,42 @@ static void __init bockw_init(void)
                        sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
                        &sdhi0_info, sizeof(struct sh_mobile_sdhi_info));
        }
+
+       /* for Audio */
+       clk = clk_get(NULL, "audio_clk_b");
+       clk_set_rate(clk, 24576000);
+       clk_put(clk);
+       rsnd_codec_power(5, 1); /* enable ak4642 */
+
+       platform_device_register_simple(
+               "ak4554-adc-dac", 0, NULL, 0);
+
+       platform_device_register_simple(
+               "ak4554-adc-dac", 1, NULL, 0);
+
+       platform_device_register_resndata(
+               &platform_bus, "rcar_sound", -1,
+               rsnd_resources, ARRAY_SIZE(rsnd_resources),
+               &rsnd_info, sizeof(rsnd_info));
+
+       for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) {
+               struct platform_device_info cardinfo = {
+                       .parent         = &platform_bus,
+                       .name           = "asoc-simple-card",
+                       .id             = i,
+                       .data           = &rsnd_card_info[i],
+                       .size_data      = sizeof(struct asoc_simple_card_info),
+                       .dma_mask       = ~0,
+               };
+
+               platform_device_register_full(&cardinfo);
+       }
+}
+
+static void __init bockw_init_late(void)
+{
+       r8a7778_init_late();
+       ADD_USB_FUNC_DEVICE_IF_POSSIBLE();
 }
 
 static const char *bockw_boards_compat_dt[] __initdata = {
@@ -320,5 +702,5 @@ DT_MACHINE_START(BOCKW_DT, "bockw")
        .init_irq       = r8a7778_init_irq_dt,
        .init_machine   = bockw_init,
        .dt_compat      = bockw_boards_compat_dt,
-       .init_late      = r8a7778_init_late,
+       .init_late      = bockw_init_late,
 MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c
new file mode 100644 (file)
index 0000000..3e92e3c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Genmai board support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  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/platform_device.h>
+#include <mach/common.h>
+#include <mach/r7s72100.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static void __init genmai_add_standard_devices(void)
+{
+       r7s72100_clock_init();
+       r7s72100_add_dt_devices();
+}
+
+static const char * const genmai_boards_compat_dt[] __initconst = {
+       "renesas,genmai",
+       NULL,
+};
+
+DT_MACHINE_START(GENMAI_DT, "genmai")
+       .init_early     = r7s72100_init_early,
+       .init_machine   = genmai_add_standard_devices,
+       .dt_compat      = genmai_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c
new file mode 100644 (file)
index 0000000..ace1711
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Koelsch board support
+ *
+ * Copyright (C) 2013  Renesas Electronics Corporation
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  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/platform_device.h>
+#include <mach/common.h>
+#include <mach/r8a7791.h>
+#include <mach/rcar-gen2.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static void __init koelsch_add_standard_devices(void)
+{
+       r8a7791_clock_init();
+       r8a7791_add_standard_devices();
+}
+
+static const char * const koelsch_boards_compat_dt[] __initconst = {
+       "renesas,koelsch",
+       NULL,
+};
+
+DT_MACHINE_START(KOELSCH_DT, "koelsch")
+       .smp            = smp_ops(r8a7791_smp_ops),
+       .init_early     = r8a7791_init_early,
+       .init_machine   = koelsch_add_standard_devices,
+       .init_time      = rcar_gen2_timer_init,
+       .dt_compat      = koelsch_boards_compat_dt,
+MACHINE_END
index 8f8bb2fab07697413486d9ac07b4004b528a05bf..054d8d5c8fc1a5b743962e0c0ee6be920e9f981d 100644 (file)
@@ -33,6 +33,7 @@ static void __init kzm9d_add_standard_devices(void)
 }
 
 static const char *kzm9d_boards_compat_dt[] __initdata = {
+       "renesas,kzm9d",
        "renesas,kzm9d-reference",
        NULL,
 };
index f1994968d303eac3bf022501c2d8007343b261e0..fe689b7fdc9e715ecd724edcc746913010627fb4 100644 (file)
@@ -366,6 +366,7 @@ static struct resource sh_mmcif_resources[] = {
 static struct sh_mmcif_plat_data sh_mmcif_platdata = {
        .ocr            = MMC_VDD_165_195,
        .caps           = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+       .ccs_unsupported = true,
        .slave_id_tx    = SHDMA_SLAVE_MMCIF_TX,
        .slave_id_rx    = SHDMA_SLAVE_MMCIF_RX,
 };
index 9c316a1b2e32a32b2e48e579e3af78da97f3a729..1a1a4a888632afb67fa47a532d3c251d3818fd65 100644 (file)
@@ -38,8 +38,9 @@ static const char *lager_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(LAGER_DT, "lager")
-       .init_early     = r8a7790_init_delay,
+       .smp            = smp_ops(r8a7790_smp_ops),
+       .init_early     = r8a7790_init_early,
+       .init_time      = rcar_gen2_timer_init,
        .init_machine   = lager_add_standard_devices,
-       .init_time      = r8a7790_timer_init,
        .dt_compat      = lager_boards_compat_dt,
 MACHINE_END
index 5930af8d434fb90c4a79fd8b0f8c225be9b93b58..a8d3ce646fb900514fa983964bf8d70d0e88c278 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mmc/sh_mmcif.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/gpio-rcar.h>
+#include <linux/platform_data/rcar-du.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/regulator/fixed.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+/* DU */
+static struct rcar_du_encoder_data lager_du_encoders[] = {
+       {
+               .type = RCAR_DU_ENCODER_VGA,
+               .output = RCAR_DU_OUTPUT_DPAD0,
+       }, {
+               .type = RCAR_DU_ENCODER_NONE,
+               .output = RCAR_DU_OUTPUT_LVDS1,
+               .connector.lvds.panel = {
+                       .width_mm = 210,
+                       .height_mm = 158,
+                       .mode = {
+                               .clock = 65000,
+                               .hdisplay = 1024,
+                               .hsync_start = 1048,
+                               .hsync_end = 1184,
+                               .htotal = 1344,
+                               .vdisplay = 768,
+                               .vsync_start = 771,
+                               .vsync_end = 777,
+                               .vtotal = 806,
+                               .flags = 0,
+                       },
+               },
+       },
+};
+
+static const struct rcar_du_platform_data lager_du_pdata __initconst = {
+       .encoders = lager_du_encoders,
+       .num_encoders = ARRAY_SIZE(lager_du_encoders),
+};
+
+static const struct resource du_resources[] __initconst = {
+       DEFINE_RES_MEM(0xfeb00000, 0x70000),
+       DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
+       DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"),
+       DEFINE_RES_IRQ(gic_spi(256)),
+       DEFINE_RES_IRQ(gic_spi(268)),
+       DEFINE_RES_IRQ(gic_spi(269)),
+};
+
+static void __init lager_add_du_device(void)
+{
+       struct platform_device_info info = {
+               .name = "rcar-du-r8a7790",
+               .id = -1,
+               .res = du_resources,
+               .num_res = ARRAY_SIZE(du_resources),
+               .data = &lager_du_pdata,
+               .size_data = sizeof(lager_du_pdata),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+
+       platform_device_register_full(&info);
+}
+
 /* LEDS */
 static struct gpio_led lager_leds[] = {
        {
@@ -56,7 +113,7 @@ static struct gpio_led lager_leds[] = {
        },
 };
 
-static __initdata struct gpio_led_platform_data lager_leds_pdata = {
+static const struct gpio_led_platform_data lager_leds_pdata __initconst = {
        .leds           = lager_leds,
        .num_leds       = ARRAY_SIZE(lager_leds),
 };
@@ -72,7 +129,7 @@ static struct gpio_keys_button gpio_buttons[] = {
        GPIO_KEY(KEY_1,         RCAR_GP_PIN(1, 14),     "SW2-pin1"),
 };
 
-static __initdata struct gpio_keys_platform_data lager_keys_pdata = {
+static const struct gpio_keys_platform_data lager_keys_pdata __initconst = {
        .buttons        = gpio_buttons,
        .nbuttons       = ARRAY_SIZE(gpio_buttons),
 };
@@ -84,29 +141,38 @@ static struct regulator_consumer_supply fixed3v3_power_consumers[] =
 };
 
 /* MMCIF */
-static struct sh_mmcif_plat_data mmcif1_pdata __initdata = {
+static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = {
        .caps           = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+       .clk_ctrl2_present = true,
+       .ccs_unsupported = true,
 };
 
-static struct resource mmcif1_resources[] __initdata = {
+static const struct resource mmcif1_resources[] __initconst = {
        DEFINE_RES_MEM_NAMED(0xee220000, 0x80, "MMCIF1"),
        DEFINE_RES_IRQ(gic_spi(170)),
 };
 
 /* Ether */
-static struct sh_eth_plat_data ether_pdata __initdata = {
+static const struct sh_eth_plat_data ether_pdata __initconst = {
        .phy                    = 0x1,
        .edmac_endian           = EDMAC_LITTLE_ENDIAN,
        .phy_interface          = PHY_INTERFACE_MODE_RMII,
        .ether_link_active_low  = 1,
 };
 
-static struct resource ether_resources[] __initdata = {
+static const struct resource ether_resources[] __initconst = {
        DEFINE_RES_MEM(0xee700000, 0x400),
        DEFINE_RES_IRQ(gic_spi(162)),
 };
 
 static const struct pinctrl_map lager_pinctrl_map[] = {
+       /* DU (CN10: ARGB0, CN13: LVDS) */
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
+                                 "du_rgb666", "du"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
+                                 "du_sync_1", "du"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
+                                 "du_clk_out_0", "du"),
        /* SCIF0 (CN19: DEBUG SERIAL0) */
        PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790",
                                  "scif0_data", "scif0"),
@@ -154,6 +220,8 @@ static void __init lager_add_standard_devices(void)
                                          ether_resources,
                                          ARRAY_SIZE(ether_resources),
                                          &ether_pdata, sizeof(ether_pdata));
+
+       lager_add_du_device();
 }
 
 /*
@@ -180,14 +248,15 @@ static void __init lager_init(void)
        phy_register_fixup_for_id("r8a7790-ether-ff:01", lager_ksz8041_fixup);
 }
 
-static const char *lager_boards_compat_dt[] __initdata = {
+static const char * const lager_boards_compat_dt[] __initconst = {
        "renesas,lager",
        NULL,
 };
 
 DT_MACHINE_START(LAGER_DT, "lager")
-       .init_early     = r8a7790_init_delay,
-       .init_time      = r8a7790_timer_init,
+       .smp            = smp_ops(r8a7790_smp_ops),
+       .init_early     = r8a7790_init_early,
+       .init_time      = rcar_gen2_timer_init,
        .init_machine   = lager_init,
        .dt_compat      = lager_boards_compat_dt,
 MACHINE_END
index 3f4250a2d4eb50f86a6b0ed4ff5b837b741dcd6e..2773936bf7dcffab9be79f2c8e7deed9c12e8093 100644 (file)
@@ -28,6 +28,7 @@
 static void __init marzen_init(void)
 {
        r8a7779_add_standard_devices_dt();
+       r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */
 }
 
 static const char *marzen_boards_compat_dt[] __initdata = {
index 3f5044fda4e30ec20610c677188f9647430f1bf0..da1352f5f71b6195969d17ef0de30ba9d4c8e7fe 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/gpio-rcar.h>
+#include <linux/platform_data/rcar-du.h>
 #include <linux/platform_data/usb-rcar-phy.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
@@ -124,6 +125,8 @@ static struct resource sdhi0_resources[] = {
 };
 
 static struct sh_mobile_sdhi_info sdhi0_platform_data = {
+       .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX,
+       .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX,
        .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
        .tmio_caps = MMC_CAP_SD_HIGHSPEED,
 };
@@ -169,6 +172,63 @@ static struct platform_device hspi_device = {
        .num_resources  = ARRAY_SIZE(hspi_resources),
 };
 
+/*
+ * DU
+ *
+ * The panel only specifies the [hv]display and [hv]total values. The position
+ * and width of the sync pulses don't matter, they're copied from VESA timings.
+ */
+static struct rcar_du_encoder_data du_encoders[] = {
+       {
+               .type = RCAR_DU_ENCODER_VGA,
+               .output = RCAR_DU_OUTPUT_DPAD0,
+       }, {
+               .type = RCAR_DU_ENCODER_LVDS,
+               .output = RCAR_DU_OUTPUT_DPAD1,
+               .connector.lvds.panel = {
+                       .width_mm = 210,
+                       .height_mm = 158,
+                       .mode = {
+                               .clock = 65000,
+                               .hdisplay = 1024,
+                               .hsync_start = 1048,
+                               .hsync_end = 1184,
+                               .htotal = 1344,
+                               .vdisplay = 768,
+                               .vsync_start = 771,
+                               .vsync_end = 777,
+                               .vtotal = 806,
+                               .flags = 0,
+                       },
+               },
+       },
+};
+
+static const struct rcar_du_platform_data du_pdata __initconst = {
+       .encoders = du_encoders,
+       .num_encoders = ARRAY_SIZE(du_encoders),
+};
+
+static const struct resource du_resources[] __initconst = {
+       DEFINE_RES_MEM(0xfff80000, 0x40000),
+       DEFINE_RES_IRQ(gic_iid(0x3f)),
+};
+
+static void __init marzen_add_du_device(void)
+{
+       struct platform_device_info info = {
+               .name = "rcar-du-r8a7779",
+               .id = -1,
+               .res = du_resources,
+               .num_res = ARRAY_SIZE(du_resources),
+               .data = &du_pdata,
+               .size_data = sizeof(du_pdata),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+
+       platform_device_register_full(&info);
+}
+
 /* LEDS */
 static struct gpio_led marzen_leds[] = {
        {
@@ -237,6 +297,19 @@ static struct platform_device *marzen_devices[] __initdata = {
 };
 
 static const struct pinctrl_map marzen_pinctrl_map[] = {
+       /* DU (CN10: ARGB0, CN13: LVDS) */
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+                                 "du0_rgb888", "du0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+                                 "du0_sync_1", "du0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+                                 "du0_clk_out_0", "du0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+                                 "du1_rgb666", "du1"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+                                 "du1_sync_1", "du1"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
+                                 "du1_clk_out", "du1"),
        /* HSPI0 */
        PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779",
                                  "hspi0", "hspi0"),
@@ -297,6 +370,7 @@ static void __init marzen_init(void)
        r8a7779_add_vin_device(1, &vin_platform_data);
        r8a7779_add_vin_device(3, &vin_platform_data);
        platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
+       marzen_add_du_device();
 }
 
 static const char *marzen_boards_compat_dt[] __initdata = {
diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c
new file mode 100644 (file)
index 0000000..4aba20c
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * r7a72100 clock framework support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2012  Phil Edworthy
+ * Copyright (C) 2011  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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+#include <mach/r7s72100.h>
+
+/* registers */
+#define FRQCR          0xfcfe0010
+#define FRQCR2         0xfcfe0014
+#define STBCR3         0xfcfe0420
+#define STBCR4         0xfcfe0424
+
+#define PLL_RATE 30
+
+static struct clk_mapping cpg_mapping = {
+       .phys   = 0xfcfe0000,
+       .len    = 0x1000,
+};
+
+/* Fixed 32 KHz root clock for RTC */
+static struct clk r_clk = {
+       .rate           = 32768,
+};
+
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk extal_clk = {
+       .rate           = 13330000,
+       .mapping        = &cpg_mapping,
+};
+
+static unsigned long pll_recalc(struct clk *clk)
+{
+       return clk->parent->rate * PLL_RATE;
+}
+
+static struct sh_clk_ops pll_clk_ops = {
+       .recalc         = pll_recalc,
+};
+
+static struct clk pll_clk = {
+       .ops            = &pll_clk_ops,
+       .parent         = &extal_clk,
+       .flags          = CLK_ENABLE_ON_INIT,
+};
+
+static unsigned long bus_recalc(struct clk *clk)
+{
+       return clk->parent->rate * 2 / 3;
+}
+
+static struct sh_clk_ops bus_clk_ops = {
+       .recalc         = bus_recalc,
+};
+
+static struct clk bus_clk = {
+       .ops            = &bus_clk_ops,
+       .parent         = &pll_clk,
+       .flags          = CLK_ENABLE_ON_INIT,
+};
+
+static unsigned long peripheral0_recalc(struct clk *clk)
+{
+       return clk->parent->rate / 12;
+}
+
+static struct sh_clk_ops peripheral0_clk_ops = {
+       .recalc         = peripheral0_recalc,
+};
+
+static struct clk peripheral0_clk = {
+       .ops            = &peripheral0_clk_ops,
+       .parent         = &pll_clk,
+       .flags          = CLK_ENABLE_ON_INIT,
+};
+
+static unsigned long peripheral1_recalc(struct clk *clk)
+{
+       return clk->parent->rate / 6;
+}
+
+static struct sh_clk_ops peripheral1_clk_ops = {
+       .recalc         = peripheral1_recalc,
+};
+
+static struct clk peripheral1_clk = {
+       .ops            = &peripheral1_clk_ops,
+       .parent         = &pll_clk,
+       .flags          = CLK_ENABLE_ON_INIT,
+};
+
+struct clk *main_clks[] = {
+       &r_clk,
+       &extal_clk,
+       &pll_clk,
+       &bus_clk,
+       &peripheral0_clk,
+       &peripheral1_clk,
+};
+
+static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */
+static int multipliers[] = { 1, 2, 1, 1 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+       .divisors = div2,
+       .nr_divisors = ARRAY_SIZE(div2),
+       .multipliers = multipliers,
+       .nr_multipliers = ARRAY_SIZE(multipliers),
+};
+
+static struct clk_div4_table div4_table = {
+       .div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_I,
+       DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+       SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
+
+/* The mask field specifies the div2 entries that are valid */
+struct clk div4_clks[DIV4_NR] = {
+       [DIV4_I]  = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT
+                                       | CLK_ENABLE_ON_INIT),
+};
+
+enum { MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40,
+       MSTP33, MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+       [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */
+       [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */
+       [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */
+       [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */
+       [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */
+       [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */
+       [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */
+       [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */
+       [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */
+};
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("rclk", &r_clk),
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+       CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+       /* MSTP clocks */
+       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]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]),
+       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]),
+};
+
+void __init r7s72100_clock_init(void)
+{
+       int k, ret = 0;
+
+       for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+               ret = clk_register(main_clks[k]);
+
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+       if (!ret)
+               ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+       if (!ret)
+               ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+       if (!ret)
+               shmobile_clk_init();
+       else
+               panic("failed to setup rza1 clocks\n");
+}
index 5bd2e851e3c7f2d03cd7ae4dd647ec1cc7d9c537..571409b611d386b5067236248d129d2f0ca154a1 100644 (file)
@@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = {
 
 /* MSTP */
 enum {
-       MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
+       MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
        MSTP329, MSTP323, MSTP318, MSTP317, MSTP316,
        MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300,
        MSTP411, MSTP410, MSTP409,
@@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],  SMSTPCR2, 7, 0), /* SCIFB1 */
        [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],  SMSTPCR2, 16, 0), /* SCIFB2 */
        [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],  SMSTPCR2, 17, 0), /* SCIFB3 */
+       [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 18, 0), /* DMAC */
        [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 0, 0), /* IIC2 */
        [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */
        [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */
@@ -578,6 +579,8 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]),
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
        CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]),
+       CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
+       CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]),
        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]),
index c4bf2d8fb111aba4bbddb54a2fdb95287f784582..fb6af83858e3f0210f9eeaae2c2794a5a618ca48 100644 (file)
@@ -69,6 +69,15 @@ static struct clk extal_clk = {
        .mapping = &cpg_mapping,
 };
 
+static struct clk audio_clk_a = {
+};
+
+static struct clk audio_clk_b = {
+};
+
+static struct clk audio_clk_c = {
+};
+
 /*
  * clock ratio of these clock will be updated
  * on r8a7778_clock_init()
@@ -100,18 +109,23 @@ static struct clk *main_clks[] = {
        &p_clk,
        &g_clk,
        &z_clk,
+       &audio_clk_a,
+       &audio_clk_b,
+       &audio_clk_c,
 };
 
 enum {
        MSTP331,
        MSTP323, MSTP322, MSTP321,
+       MSTP311, MSTP310,
+       MSTP309, MSTP308, MSTP307,
        MSTP114,
        MSTP110, MSTP109,
        MSTP100,
        MSTP030,
        MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
-       MSTP016, MSTP015,
-       MSTP007,
+       MSTP016, MSTP015, MSTP012, MSTP011, MSTP010,
+       MSTP009, MSTP008, MSTP007,
        MSTP_NR };
 
 static struct clk mstp_clks[MSTP_NR] = {
@@ -119,6 +133,11 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
        [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
        [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
+       [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */
+       [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */
+       [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  9, 0), /* SSI6 */
+       [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  8, 0), /* SSI7 */
+       [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  7, 0), /* SSI8 */
        [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
        [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */
        [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1,  9, 0), /* VIN1 */
@@ -135,11 +154,20 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
        [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
        [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
+       [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */
+       [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */
+       [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */
+       [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  9, 0), /* SSI3 */
+       [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  8, 0), /* SRU */
        [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  7, 0), /* HSPI */
 };
 
 static struct clk_lookup lookups[] = {
        /* main */
+       CLKDEV_CON_ID("audio_clk_a",    &audio_clk_a),
+       CLKDEV_CON_ID("audio_clk_b",    &audio_clk_b),
+       CLKDEV_CON_ID("audio_clk_c",    &audio_clk_c),
+       CLKDEV_CON_ID("audio_clk_internal",     &s1_clk),
        CLKDEV_CON_ID("shyway_clk",     &s_clk),
        CLKDEV_CON_ID("peripheral_clk", &p_clk),
 
@@ -153,6 +181,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
        CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
        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("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
        CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
@@ -168,6 +197,17 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
        CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
        CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
+       CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
+
+       CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
+       CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]),
+       CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]),
+       CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]),
+       CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]),
+       CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]),
+       CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]),
+       CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]),
+       CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]),
 };
 
 void __init r8a7778_clock_init(void)
index bd6ad922eb7ec6c4213607031810310dd2a289bd..1f7080fab0a53556a4ce5efb3cbf3368dce71465 100644 (file)
@@ -200,7 +200,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
-       CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */
+       CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
 };
 
 void __init r8a7779_clock_init(void)
index fc36d3db0b4d9541d9b8ca08c47b4530a8891c29..a64f965c7da142b118ab42a52afadeb5038dff81 100644 (file)
@@ -52,6 +52,7 @@
 #define SMSTPCR5 0xe6150144
 #define SMSTPCR7 0xe615014c
 #define SMSTPCR8 0xe6150990
+#define SMSTPCR9 0xe6150994
 
 #define SDCKCR         0xE6150074
 #define SD2CKCR                0xE6150078
@@ -181,8 +182,9 @@ static struct clk div6_clks[DIV6_NR] = {
 
 /* MSTP */
 enum {
+       MSTP931, MSTP930, MSTP929, MSTP928,
        MSTP813,
-       MSTP721, MSTP720,
+       MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
        MSTP717, MSTP716,
        MSTP522,
        MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
@@ -192,7 +194,16 @@ 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 */
        [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 */
+       [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
+       [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
+       [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */
        [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
        [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
        [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
@@ -251,6 +262,11 @@ 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]),
@@ -261,6 +277,10 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
        CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
        CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
+       CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]),
+       CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]),
+       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("rcar_thermal", &mstp_clks[MSTP522]),
        CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
@@ -290,7 +310,7 @@ static struct clk_lookup lookups[] = {
 
 void __init r8a7790_clock_init(void)
 {
-       u32 mode = r8a7790_read_mode_pins();
+       u32 mode = rcar_gen2_read_mode_pins();
        int k, ret = 0;
 
        switch (mode & (MD(14) | MD(13))) {
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c
new file mode 100644 (file)
index 0000000..c9a26f1
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * r8a7791 clock framework support
+ *
+ * Copyright (C) 2013  Renesas Electronics Corporation
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  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/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/clock.h>
+#include <mach/common.h>
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)           *1      *1
+ *---------------------------------------------------
+ * 0  0  0     15 x 1          x172/2  x208/2  x106
+ * 0  0  1     15 x 1          x172/2  x208/2  x88
+ * 0  1  0     20 x 1          x130/2  x156/2  x80
+ * 0  1  1     20 x 1          x130/2  x156/2  x66
+ * 1  0  0     26 / 2          x200/2  x240/2  x122
+ * 1  0  1     26 / 2          x200/2  x240/2  x102
+ * 1  1  0     30 / 2          x172/2  x208/2  x106
+ * 1  1  1     30 / 2          x172/2  x208/2  x88
+ *
+ * *1 :        Table 7.6 indicates VCO ouput (PLLx = VCO/2)
+ *     see "p1 / 2" on R8A7791_CLOCK_ROOT() below
+ */
+
+#define MD(nr) (1 << nr)
+
+#define CPG_BASE 0xe6150000
+#define CPG_LEN 0x1000
+
+#define SMSTPCR0       0xE6150130
+#define SMSTPCR1       0xE6150134
+#define SMSTPCR2       0xe6150138
+#define SMSTPCR3       0xE615013C
+#define SMSTPCR5       0xE6150144
+#define SMSTPCR7       0xe615014c
+#define SMSTPCR8       0xE6150990
+#define SMSTPCR9       0xE6150994
+#define SMSTPCR10      0xE6150998
+#define SMSTPCR11      0xE615099C
+
+#define MODEMR         0xE6160060
+#define SDCKCR         0xE6150074
+#define SD2CKCR                0xE6150078
+#define SD3CKCR                0xE615007C
+#define MMC0CKCR       0xE6150240
+#define MMC1CKCR       0xE6150244
+#define SSPCKCR                0xE6150248
+#define SSPRSCKCR      0xE615024C
+
+static struct clk_mapping cpg_mapping = {
+       .phys   = CPG_BASE,
+       .len    = CPG_LEN,
+};
+
+static struct clk extal_clk = {
+       /* .rate will be updated on r8a7791_clock_init() */
+       .mapping        = &cpg_mapping,
+};
+
+static struct sh_clk_ops followparent_clk_ops = {
+       .recalc = followparent_recalc,
+};
+
+static struct clk main_clk = {
+       /* .parent will be set r8a73a4_clock_init */
+       .ops    = &followparent_clk_ops,
+};
+
+/*
+ * clock ratio of these clock will be updated
+ * on r8a7791_clock_init()
+ */
+SH_FIXED_RATIO_CLK_SET(pll1_clk,               main_clk,       1, 1);
+SH_FIXED_RATIO_CLK_SET(pll3_clk,               main_clk,       1, 1);
+
+/* fixed ratio clock */
+SH_FIXED_RATIO_CLK_SET(extal_div2_clk,         extal_clk,      1, 2);
+SH_FIXED_RATIO_CLK_SET(cp_clk,                 extal_clk,      1, 2);
+
+SH_FIXED_RATIO_CLK_SET(pll1_div2_clk,          pll1_clk,       1, 2);
+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);
+
+static struct clk *main_clks[] = {
+       &extal_clk,
+       &extal_div2_clk,
+       &main_clk,
+       &pll1_clk,
+       &pll1_div2_clk,
+       &pll3_clk,
+       &hp_clk,
+       &p_clk,
+       &rclk_clk,
+       &mp_clk,
+       &cp_clk,
+};
+
+/* MSTP */
+enum {
+       MSTP721, MSTP720,
+       MSTP719, MSTP718, MSTP715, MSTP714,
+       MSTP216, MSTP207, MSTP206,
+       MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107,
+       MSTP124,
+       MSTP_NR
+};
+
+static struct clk mstp_clks[MSTP_NR] = {
+       [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 */
+       [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 */
+       [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
+       [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
+       [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
+       [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */
+       [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */
+       [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */
+       [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */
+};
+
+static struct clk_lookup lookups[] = {
+
+       /* main clocks */
+       CLKDEV_CON_ID("extal",          &extal_clk),
+       CLKDEV_CON_ID("extal_div2",     &extal_div2_clk),
+       CLKDEV_CON_ID("main",           &main_clk),
+       CLKDEV_CON_ID("pll1",           &pll1_clk),
+       CLKDEV_CON_ID("pll1_div2",      &pll1_div2_clk),
+       CLKDEV_CON_ID("pll3",           &pll3_clk),
+       CLKDEV_CON_ID("hp",             &hp_clk),
+       CLKDEV_CON_ID("p",              &p_clk),
+       CLKDEV_CON_ID("rclk",           &rclk_clk),
+       CLKDEV_CON_ID("mp",             &mp_clk),
+       CLKDEV_CON_ID("cp",             &cp_clk),
+       CLKDEV_CON_ID("peripheral_clk", &hp_clk),
+
+       /* MSTP */
+       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 */
+       CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */
+       CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */
+       CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */
+       CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */
+       CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */
+       CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */
+       CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */
+       CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */
+       CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */
+       CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
+       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]),
+};
+
+#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31)             \
+       extal_clk.rate  = e * 1000 * 1000;                      \
+       main_clk.parent = m;                                    \
+       SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1);           \
+       if (mode & MD(19))                                      \
+               SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1);      \
+       else                                                    \
+               SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
+
+
+void __init r8a7791_clock_init(void)
+{
+       void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
+       u32 mode;
+       int k, ret = 0;
+
+       BUG_ON(!modemr);
+       mode = ioread32(modemr);
+       iounmap(modemr);
+
+       switch (mode & (MD(14) | MD(13))) {
+       case 0:
+               R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
+               break;
+       case MD(13):
+               R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
+               break;
+       case MD(14):
+               R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
+               break;
+       case MD(13) | MD(14):
+               R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
+               break;
+       }
+
+       for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+               ret = clk_register(main_clks[k]);
+
+       if (!ret)
+               ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+       if (!ret)
+               shmobile_clk_init();
+       else
+               goto epanic;
+
+       return;
+
+epanic:
+       panic("failed to setup r8a7791 clocks\n");
+}
index f93751caf5cbf5f4d34e2099d494249b0eac02e8..e5be5c88644b70aa8bb6196807bff7f000085658 100644 (file)
@@ -40,6 +40,9 @@ shmobile_boot_fn:
        .globl  shmobile_boot_arg
 shmobile_boot_arg:
 2:     .space  4
+       .globl  shmobile_boot_size
+shmobile_boot_size:
+       .long   . - shmobile_boot_vector
 
 /*
  * Per-CPU SMP boot function/argument selection code based on MPIDR
index 7b938681e7569d29231b232d2be8f46d81f6be39..e31980590eb452bbc209400d303e9d6d016181d7 100644 (file)
@@ -9,16 +9,23 @@ extern void shmobile_setup_console(void);
 extern void shmobile_boot_vector(void);
 extern unsigned long shmobile_boot_fn;
 extern unsigned long shmobile_boot_arg;
+extern unsigned long shmobile_boot_size;
 extern void shmobile_smp_boot(void);
 extern void shmobile_smp_sleep(void);
 extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
                              unsigned long arg);
+extern int shmobile_smp_cpu_disable(unsigned int cpu);
+extern void shmobile_invalidate_start(void);
 extern void shmobile_boot_scu(void);
 extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus);
-extern int shmobile_smp_scu_boot_secondary(unsigned int cpu,
-                                          struct task_struct *idle);
 extern void shmobile_smp_scu_cpu_die(unsigned int cpu);
 extern int shmobile_smp_scu_cpu_kill(unsigned int cpu);
+extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus);
+extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
+                                           struct task_struct *idle);
+extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
+extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
+extern void shmobile_invalidate_start(void);
 struct clk;
 extern int shmobile_clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
@@ -39,7 +46,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; }
 #endif
 
 extern void __iomem *shmobile_scu_base;
-extern void shmobile_smp_init_cpus(unsigned int ncores);
 
 static inline void __init shmobile_init_late(void)
 {
diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h
new file mode 100644 (file)
index 0000000..5f34b20
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __ASM_R7S72100_H__
+#define __ASM_R7S72100_H__
+
+void r7s72100_add_dt_devices(void);
+void r7s72100_clock_init(void);
+void r7s72100_init_early(void);
+
+#endif /* __ASM_R7S72100_H__ */
index f3a9b702da56f326055029c8ffb81275b619d2ec..ce8bdd1d8a8a029616bb4b5929c55ba1f8726f8f 100644 (file)
@@ -1,10 +1,19 @@
 #ifndef __ASM_R8A73A4_H__
 #define __ASM_R8A73A4_H__
 
+/* DMA slave IDs */
+enum {
+       SHDMA_SLAVE_INVALID,
+       SHDMA_SLAVE_MMCIF0_TX,
+       SHDMA_SLAVE_MMCIF0_RX,
+       SHDMA_SLAVE_MMCIF1_TX,
+       SHDMA_SLAVE_MMCIF1_RX,
+};
+
 void r8a73a4_add_standard_devices(void);
 void r8a73a4_add_dt_devices(void);
 void r8a73a4_clock_init(void);
 void r8a73a4_pinmux_init(void);
-void r8a73a4_init_delay(void);
+void r8a73a4_init_early(void);
 
 #endif /* __ASM_R8A73A4_H__ */
index adfcf51b163dcd0503f51ec4961647534428daa5..441886c9714baddffb609247b872fca7054c514a 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2013  Cogent Embedded, 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
 #include <linux/sh_eth.h>
 #include <linux/platform_data/camera-rcar.h>
 
+/* HPB-DMA slave IDs */
+enum {
+       HPBDMA_SLAVE_DUMMY,
+       HPBDMA_SLAVE_SDHI0_TX,
+       HPBDMA_SLAVE_SDHI0_RX,
+};
+
 extern void r8a7778_add_standard_devices(void);
 extern void r8a7778_add_standard_devices_dt(void);
-extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata);
-extern void r8a7778_add_vin_device(int id,
-                                  struct rcar_vin_platform_data *pdata);
 extern void r8a7778_add_dt_devices(void);
 
 extern void r8a7778_init_late(void);
@@ -33,6 +38,9 @@ extern void r8a7778_init_delay(void);
 extern void r8a7778_init_irq_dt(void);
 extern void r8a7778_clock_init(void);
 extern void r8a7778_init_irq_extpin(int irlm);
+extern void r8a7778_init_irq_extpin_dt(int irlm);
 extern void r8a7778_pinmux_init(void);
 
+extern int r8a7778_usb_phy_power(bool enable);
+
 #endif /* __ASM_R8A7778_H__ */
index 11c740047e14cae3d8cef131e30961ee04e7bcd9..17af34ed89c801553b248f12f0d3c39336553854 100644 (file)
@@ -6,6 +6,13 @@
 #include <linux/sh_eth.h>
 #include <linux/platform_data/camera-rcar.h>
 
+/* HPB-DMA slave IDs */
+enum {
+       HPBDMA_SLAVE_DUMMY,
+       HPBDMA_SLAVE_SDHI0_TX,
+       HPBDMA_SLAVE_SDHI0_RX,
+};
+
 struct platform_device;
 
 struct r8a7779_pm_ch {
@@ -26,6 +33,7 @@ static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d)
 
 extern void r8a7779_init_delay(void);
 extern void r8a7779_init_irq_extpin(int irlm);
+extern void r8a7779_init_irq_extpin_dt(int irlm);
 extern void r8a7779_init_irq_dt(void);
 extern void r8a7779_map_io(void);
 extern void r8a7779_earlytimer_init(void);
index 788d55952091b3f04ddd47f8b1847f2638503c92..5fbfa28b40b64353d5f801c4999395ee76f819b0 100644 (file)
@@ -1,14 +1,13 @@
 #ifndef __ASM_R8A7790_H__
 #define __ASM_R8A7790_H__
 
+#include <mach/rcar-gen2.h>
+
 void r8a7790_add_standard_devices(void);
 void r8a7790_add_dt_devices(void);
 void r8a7790_clock_init(void);
 void r8a7790_pinmux_init(void);
-void r8a7790_init_delay(void);
-void r8a7790_timer_init(void);
-
-#define MD(nr) BIT(nr)
-u32 r8a7790_read_mode_pins(void);
+void r8a7790_init_early(void);
+extern struct smp_operations r8a7790_smp_ops;
 
 #endif /* __ASM_R8A7790_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h
new file mode 100644 (file)
index 0000000..051ead3
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __ASM_R8A7791_H__
+#define __ASM_R8A7791_H__
+
+void r8a7791_add_standard_devices(void);
+void r8a7791_add_dt_devices(void);
+void r8a7791_clock_init(void);
+void r8a7791_init_early(void);
+extern struct smp_operations r8a7791_smp_ops;
+
+#endif /* __ASM_R8A7791_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/rcar-gen2.h b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h
new file mode 100644 (file)
index 0000000..43f606e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __ASM_RCAR_GEN2_H__
+#define __ASM_RCAR_GEN2_H__
+
+void rcar_gen2_timer_init(void);
+#define MD(nr) BIT(nr)
+u32 rcar_gen2_read_mode_pins(void);
+
+#endif /* __ASM_RCAR_GEN2_H__ */
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
new file mode 100644 (file)
index 0000000..1da5a72
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * SMP support for SoCs with APMU
+ *
+ * Copyright (C) 2013  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+#include <mach/common.h>
+
+static struct {
+       void __iomem *iomem;
+       int bit;
+} apmu_cpus[CONFIG_NR_CPUS];
+
+#define WUPCR_OFFS 0x10
+#define PSTR_OFFS 0x40
+#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n)))
+
+static int apmu_power_on(void __iomem *p, int bit)
+{
+       /* request power on */
+       writel_relaxed(BIT(bit), p + WUPCR_OFFS);
+
+       /* wait for APMU to finish */
+       while (readl_relaxed(p + WUPCR_OFFS) != 0)
+               ;
+
+       return 0;
+}
+
+static int apmu_power_off(void __iomem *p, int bit)
+{
+       /* request Core Standby for next WFI */
+       writel_relaxed(3, p + CPUNCR_OFFS(bit));
+       return 0;
+}
+
+static int apmu_power_off_poll(void __iomem *p, int bit)
+{
+       int k;
+
+       for (k = 0; k < 1000; k++) {
+               if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3)
+                       return 1;
+
+               mdelay(1);
+       }
+
+       return 0;
+}
+
+static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu))
+{
+       void __iomem *p = apmu_cpus[cpu].iomem;
+
+       return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
+}
+
+static void apmu_init_cpu(struct resource *res, int cpu, int bit)
+{
+       if (apmu_cpus[cpu].iomem)
+               return;
+
+       apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res));
+       apmu_cpus[cpu].bit = bit;
+
+       pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit,
+                res->start, resource_size(res));
+}
+
+static struct {
+       struct resource iomem;
+       int cpus[4];
+} apmu_config[] = {
+       {
+               .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
+               .cpus = { 0, 1, 2, 3 },
+       },
+       {
+               .iomem = DEFINE_RES_MEM(0xe6151000, 0x88),
+               .cpus = { 0x100, 0x101, 0x102, 0x103 },
+       }
+};
+
+static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit))
+{
+       u32 id;
+       int k;
+       int bit, index;
+       bool is_allowed;
+
+       for (k = 0; k < ARRAY_SIZE(apmu_config); k++) {
+               /* only enable the cluster that includes the boot CPU */
+               is_allowed = false;
+               for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
+                       id = apmu_config[k].cpus[bit];
+                       if (id >= 0) {
+                               if (id == cpu_logical_map(0))
+                                       is_allowed = true;
+                       }
+               }
+               if (!is_allowed)
+                       continue;
+
+               for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
+                       id = apmu_config[k].cpus[bit];
+                       if (id >= 0) {
+                               index = get_logical_index(id);
+                               if (index >= 0)
+                                       fn(&apmu_config[k].iomem, index, bit);
+                       }
+               }
+       }
+}
+
+void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus)
+{
+       /* install boot code shared by all CPUs */
+       shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
+       shmobile_boot_arg = MPIDR_HWID_BITMASK;
+
+       /* perform per-cpu setup */
+       apmu_parse_cfg(apmu_init_cpu);
+}
+
+int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       /* For this particular CPU register boot vector */
+       shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0);
+
+       return apmu_wrap(cpu, apmu_power_on);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/* nicked from arch/arm/mach-exynos/hotplug.c */
+static inline void cpu_enter_lowpower_a15(void)
+{
+       unsigned int v;
+
+       asm volatile(
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+               : "=&r" (v)
+               : "Ir" (CR_C)
+               : "cc");
+
+       flush_cache_louis();
+
+       asm volatile(
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+               : "=&r" (v)
+               : "Ir" (0x40)
+               : "cc");
+
+       isb();
+       dsb();
+}
+
+void shmobile_smp_apmu_cpu_die(unsigned int cpu)
+{
+       /* For this particular CPU deregister boot vector */
+       shmobile_smp_hook(cpu, 0, 0);
+
+       /* Select next sleep mode using the APMU */
+       apmu_wrap(cpu, apmu_power_off);
+
+       /* Do ARM specific CPU shutdown */
+       cpu_enter_lowpower_a15();
+
+       /* jump to shared mach-shmobile sleep / reset code */
+       shmobile_smp_sleep();
+}
+
+int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
+{
+       return apmu_wrap(cpu, apmu_power_off_poll);
+}
+#endif
index c96f50160be69eb8c0be9798c95374e664163615..673ad6e808694f1cab787fe6430090900efc8150 100644 (file)
@@ -7,6 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <asm/smp_scu.h>
 #include <mach/common.h>
 
+static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb,
+                                         unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (long)hcpu;
+
+       switch (action) {
+       case CPU_UP_PREPARE:
+               /* For this particular CPU register SCU SMP boot vector */
+               shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu),
+                                 (unsigned long)shmobile_scu_base);
+               break;
+       };
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block shmobile_smp_scu_notifier = {
+       .notifier_call = shmobile_smp_scu_notifier_call,
+};
+
 void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus)
 {
        /* install boot code shared by all CPUs */
@@ -25,14 +46,9 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus)
        /* enable SCU and cache coherency on booting CPU */
        scu_enable(shmobile_scu_base);
        scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
-}
 
-int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       /* For this particular CPU register SCU boot vector */
-       shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu),
-                         (unsigned long)shmobile_scu_base);
-       return 0;
+       /* Use CPU notifier for reset vector control */
+       register_cpu_notifier(&shmobile_smp_scu_notifier);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index d4ae616bcedb4f09c4342a8e19a0d9c7dc98f581..9ebc246b8d7dd7fc46505ba40691a0ff8e4dbb4f 100644 (file)
  * published by the Free Software Foundation.
  */
 #include <linux/init.h>
-#include <linux/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 #include <mach/common.h>
 
-void __init shmobile_smp_init_cpus(unsigned int ncores)
-{
-       unsigned int i;
-
-       if (ncores > nr_cpu_ids) {
-               pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-                       ncores, nr_cpu_ids);
-               ncores = nr_cpu_ids;
-       }
-
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
-}
-
 extern unsigned long shmobile_smp_fn[];
 extern unsigned long shmobile_smp_arg[];
 extern unsigned long shmobile_smp_mpidr[];
@@ -44,3 +29,10 @@ void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg)
        shmobile_smp_arg[cpu] = arg;
        flush_cache_all();
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+int shmobile_smp_cpu_disable(unsigned int cpu)
+{
+       return 0; /* Hotplug of any CPU is supported */
+}
+#endif
diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c
new file mode 100644 (file)
index 0000000..d4eb509
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * r7s72100 processor support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  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/irq.h>
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <linux/serial_sci.h>
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/r7s72100.h>
+#include <asm/mach/arch.h>
+
+#define SCIF_DATA(index, baseaddr, irq)                                        \
+[index] = {                                                            \
+       .type           = PORT_SCIF,                                    \
+       .regtype        = SCIx_SH2_SCIF_FIFODATA_REGTYPE,               \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,              \
+       .scbrr_algo_id  = SCBRR_ALGO_2,                                 \
+       .scscr          = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \
+                         SCSCR_REIE,                                   \
+       .mapbase        = baseaddr,                                     \
+       .irqs           = { irq + 1, irq + 2, irq + 3, irq },           \
+}
+
+enum { SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7 };
+
+static const struct plat_sci_port scif[] __initconst = {
+       SCIF_DATA(SCIF0, 0xe8007000, gic_iid(221)), /* SCIF0 */
+       SCIF_DATA(SCIF1, 0xe8007800, gic_iid(225)), /* SCIF1 */
+       SCIF_DATA(SCIF2, 0xe8008000, gic_iid(229)), /* SCIF2 */
+       SCIF_DATA(SCIF3, 0xe8008800, gic_iid(233)), /* SCIF3 */
+       SCIF_DATA(SCIF4, 0xe8009000, gic_iid(237)), /* SCIF4 */
+       SCIF_DATA(SCIF5, 0xe8009800, gic_iid(241)), /* SCIF5 */
+       SCIF_DATA(SCIF6, 0xe800a000, gic_iid(245)), /* SCIF6 */
+       SCIF_DATA(SCIF7, 0xe800a800, gic_iid(249)), /* SCIF7 */
+};
+
+static inline void r7s72100_register_scif(int idx)
+{
+       platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx],
+                                     sizeof(struct plat_sci_port));
+}
+
+void __init r7s72100_add_dt_devices(void)
+{
+       r7s72100_register_scif(SCIF0);
+       r7s72100_register_scif(SCIF1);
+       r7s72100_register_scif(SCIF2);
+       r7s72100_register_scif(SCIF3);
+       r7s72100_register_scif(SCIF4);
+       r7s72100_register_scif(SCIF5);
+       r7s72100_register_scif(SCIF6);
+       r7s72100_register_scif(SCIF7);
+}
+
+void __init r7s72100_init_early(void)
+{
+       shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */
+}
+
+#ifdef CONFIG_USE_OF
+static const char *r7s72100_boards_compat_dt[] __initdata = {
+       "renesas,r7s72100",
+       NULL,
+};
+
+DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)")
+       .init_early     = r7s72100_init_early,
+       .dt_compat      = r7s72100_boards_compat_dt,
+MACHINE_END
+#endif /* CONFIG_USE_OF */
index 89491700afb78b8c706aba61b638ffb699031610..b0f2749071bec3feee42e44a82c52449a8494e81 100644 (file)
 #include <linux/of_platform.h>
 #include <linux/platform_data/irq-renesas-irqc.h>
 #include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
 #include <linux/sh_timer.h>
 #include <mach/common.h>
+#include <mach/dma-register.h>
 #include <mach/irqs.h>
 #include <mach/r8a73a4.h>
 #include <asm/mach/arch.h>
@@ -199,15 +201,104 @@ void __init r8a73a4_add_dt_devices(void)
        r8a7790_register_cmt(10);
 }
 
+/* DMA */
+static const struct sh_dmae_slave_config dma_slaves[] = {
+       {
+               .slave_id       = SHDMA_SLAVE_MMCIF0_TX,
+               .addr           = 0xee200034,
+               .chcr           = CHCR_TX(XMIT_SZ_32BIT),
+               .mid_rid        = 0xd1,
+       }, {
+               .slave_id       = SHDMA_SLAVE_MMCIF0_RX,
+               .addr           = 0xee200034,
+               .chcr           = CHCR_RX(XMIT_SZ_32BIT),
+               .mid_rid        = 0xd2,
+       }, {
+               .slave_id       = SHDMA_SLAVE_MMCIF1_TX,
+               .addr           = 0xee220034,
+               .chcr           = CHCR_TX(XMIT_SZ_32BIT),
+               .mid_rid        = 0xe1,
+       }, {
+               .slave_id       = SHDMA_SLAVE_MMCIF1_RX,
+               .addr           = 0xee220034,
+               .chcr           = CHCR_RX(XMIT_SZ_32BIT),
+               .mid_rid        = 0xe2,
+       },
+};
+
+#define DMAE_CHANNEL(a, b)                             \
+       {                                               \
+               .offset         = (a) - 0x20,           \
+               .dmars          = (a) - 0x20 + 0x40,    \
+               .chclr_bit      = (b),                  \
+               .chclr_offset   = 0x80 - 0x20,          \
+       }
+
+static const struct sh_dmae_channel dma_channels[] = {
+       DMAE_CHANNEL(0x8000, 0),
+       DMAE_CHANNEL(0x8080, 1),
+       DMAE_CHANNEL(0x8100, 2),
+       DMAE_CHANNEL(0x8180, 3),
+       DMAE_CHANNEL(0x8200, 4),
+       DMAE_CHANNEL(0x8280, 5),
+       DMAE_CHANNEL(0x8300, 6),
+       DMAE_CHANNEL(0x8380, 7),
+       DMAE_CHANNEL(0x8400, 8),
+       DMAE_CHANNEL(0x8480, 9),
+       DMAE_CHANNEL(0x8500, 10),
+       DMAE_CHANNEL(0x8580, 11),
+       DMAE_CHANNEL(0x8600, 12),
+       DMAE_CHANNEL(0x8680, 13),
+       DMAE_CHANNEL(0x8700, 14),
+       DMAE_CHANNEL(0x8780, 15),
+       DMAE_CHANNEL(0x8800, 16),
+       DMAE_CHANNEL(0x8880, 17),
+       DMAE_CHANNEL(0x8900, 18),
+       DMAE_CHANNEL(0x8980, 19),
+};
+
+static const struct sh_dmae_pdata dma_pdata = {
+       .slave          = dma_slaves,
+       .slave_num      = ARRAY_SIZE(dma_slaves),
+       .channel        = dma_channels,
+       .channel_num    = ARRAY_SIZE(dma_channels),
+       .ts_low_shift   = TS_LOW_SHIFT,
+       .ts_low_mask    = TS_LOW_BIT << TS_LOW_SHIFT,
+       .ts_high_shift  = TS_HI_SHIFT,
+       .ts_high_mask   = TS_HI_BIT << TS_HI_SHIFT,
+       .ts_shift       = dma_ts_shift,
+       .ts_shift_num   = ARRAY_SIZE(dma_ts_shift),
+       .dmaor_init     = DMAOR_DME,
+       .chclr_present  = 1,
+       .chclr_bitwise  = 1,
+};
+
+static struct resource dma_resources[] = {
+       DEFINE_RES_MEM(0xe6700020, 0x89e0),
+       DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"),
+       {
+               /* IRQ for channels 0-19 */
+               .start  = gic_spi(200),
+               .end    = gic_spi(219),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+#define r8a73a4_register_dmac()                                                        \
+       platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0,    \
+                               dma_resources, ARRAY_SIZE(dma_resources),       \
+                               &dma_pdata, sizeof(dma_pdata))
+
 void __init r8a73a4_add_standard_devices(void)
 {
        r8a73a4_add_dt_devices();
        r8a73a4_register_irqc(0);
        r8a73a4_register_irqc(1);
        r8a73a4_register_thermal();
+       r8a73a4_register_dmac();
 }
 
-void __init r8a73a4_init_delay(void)
+void __init r8a73a4_init_early(void)
 {
 #ifndef CONFIG_ARM_ARCH_TIMER
        shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */
@@ -222,7 +313,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
-       .init_early     = r8a73a4_init_delay,
+       .init_early     = r8a73a4_init_early,
        .dt_compat      = r8a73a4_boards_compat_dt,
 MACHINE_END
 #endif /* CONFIG_USE_OF */
index 6a2657ebd19775c4a9c79bae91f7aa0dac2bc812..03fcc5974ef92170c5002bf857ddb35e95a49d57 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/irqchip/arm-gic.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/dma-rcar-hpbdma.h>
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-intc-irqpin.h>
 #include <linux/platform_device.h>
@@ -95,29 +96,46 @@ static struct sh_timer_config sh_tmu1_platform_data __initdata = {
                &sh_tmu##idx##_platform_data,           \
                sizeof(sh_tmu##idx##_platform_data))
 
-/* USB */
-static struct usb_phy *phy;
+int r8a7778_usb_phy_power(bool enable)
+{
+       static struct usb_phy *phy = NULL;
+       int ret = 0;
 
+       if (!phy)
+               phy = usb_get_phy(USB_PHY_TYPE_USB2);
+
+       if (IS_ERR(phy)) {
+               pr_err("kernel doesn't have usb phy driver\n");
+               return PTR_ERR(phy);
+       }
+
+       if (enable)
+               ret = usb_phy_init(phy);
+       else
+               usb_phy_shutdown(phy);
+
+       return ret;
+}
+
+/* USB */
 static int usb_power_on(struct platform_device *pdev)
 {
-       if (IS_ERR(phy))
-               return PTR_ERR(phy);
+       int ret = r8a7778_usb_phy_power(true);
+
+       if (ret)
+               return ret;
 
        pm_runtime_enable(&pdev->dev);
        pm_runtime_get_sync(&pdev->dev);
 
-       usb_phy_init(phy);
-
        return 0;
 }
 
 static void usb_power_off(struct platform_device *pdev)
 {
-       if (IS_ERR(phy))
+       if (r8a7778_usb_phy_power(false))
                return;
 
-       usb_phy_shutdown(phy);
-
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 }
@@ -174,20 +192,6 @@ static struct platform_device_info hci##_info __initdata = {       \
 USB_PLATFORM_INFO(ehci);
 USB_PLATFORM_INFO(ohci);
 
-/* Ether */
-static struct resource ether_resources[] __initdata = {
-       DEFINE_RES_MEM(0xfde00000, 0x400),
-       DEFINE_RES_IRQ(gic_iid(0x89)),
-};
-
-void __init r8a7778_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));
-}
-
 /* PFC/GPIO */
 static struct resource pfc_resources[] __initdata = {
        DEFINE_RES_MEM(0xfffc0000, 0x118),
@@ -272,7 +276,7 @@ static struct resource hspi_resources[] __initdata = {
        DEFINE_RES_IRQ(gic_iid(0x75)),
 };
 
-void __init r8a7778_register_hspi(int id)
+static void __init r8a7778_register_hspi(int id)
 {
        BUG_ON(id < 0 || id > 2);
 
@@ -281,40 +285,6 @@ void __init r8a7778_register_hspi(int id)
                hspi_resources + (2 * id), 2);
 }
 
-/* VIN */
-#define R8A7778_VIN(idx)                                               \
-static struct resource vin##idx##_resources[] __initdata = {           \
-       DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000),            \
-       DEFINE_RES_IRQ(gic_iid(0x5a)),                                  \
-};                                                                     \
-                                                                       \
-static struct platform_device_info vin##idx##_info __initdata = {      \
-       .parent         = &platform_bus,                                \
-       .name           = "r8a7778-vin",                                \
-       .id             = idx,                                          \
-       .res            = vin##idx##_resources,                         \
-       .num_res        = ARRAY_SIZE(vin##idx##_resources),             \
-       .dma_mask       = DMA_BIT_MASK(32),                             \
-}
-
-R8A7778_VIN(0);
-R8A7778_VIN(1);
-
-static struct platform_device_info *vin_info_table[] __initdata = {
-       &vin0_info,
-       &vin1_info,
-};
-
-void __init r8a7778_add_vin_device(int id, struct rcar_vin_platform_data *pdata)
-{
-       BUG_ON(id < 0 || id > 1);
-
-       vin_info_table[id]->data = pdata;
-       vin_info_table[id]->size_data = sizeof(*pdata);
-
-       platform_device_register_full(vin_info_table[id]);
-}
-
 void __init r8a7778_add_dt_devices(void)
 {
        int i;
@@ -339,6 +309,88 @@ void __init r8a7778_add_dt_devices(void)
        r8a7778_register_tmu(1);
 }
 
+/* HPB-DMA */
+
+/* Asynchronous mode register (ASYNCMDR) bits */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MASK  BIT(2)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE        BIT(2)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MASK  BIT(1)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE        BIT(1)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0       /* SDHI0 */
+
+static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
+       {
+               .id     = HPBDMA_SLAVE_SDHI0_TX,
+               .addr   = 0xffe4c000 + 0x30,
+               .dcr    = HPB_DMAE_DCR_SPDS_16BIT |
+                         HPB_DMAE_DCR_DMDL |
+                         HPB_DMAE_DCR_DPDS_16BIT,
+               .rstr   = HPB_DMAE_ASYNCRSTR_ASRST21 |
+                         HPB_DMAE_ASYNCRSTR_ASRST22 |
+                         HPB_DMAE_ASYNCRSTR_ASRST23,
+               .mdr    = HPB_DMAE_ASYNCMDR_ASMD21_MULTI,
+               .mdm    = HPB_DMAE_ASYNCMDR_ASMD21_MASK,
+               .port   = 0x0D0C,
+               .flags  = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+               .dma_ch = 21,
+       }, {
+               .id     = HPBDMA_SLAVE_SDHI0_RX,
+               .addr   = 0xffe4c000 + 0x30,
+               .dcr    = HPB_DMAE_DCR_SMDL |
+                         HPB_DMAE_DCR_SPDS_16BIT |
+                         HPB_DMAE_DCR_DPDS_16BIT,
+               .rstr   = HPB_DMAE_ASYNCRSTR_ASRST21 |
+                         HPB_DMAE_ASYNCRSTR_ASRST22 |
+                         HPB_DMAE_ASYNCRSTR_ASRST23,
+               .mdr    = HPB_DMAE_ASYNCMDR_ASMD22_MULTI,
+               .mdm    = HPB_DMAE_ASYNCMDR_ASMD22_MASK,
+               .port   = 0x0D0C,
+               .flags  = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+               .dma_ch = 22,
+       },
+};
+
+static const struct hpb_dmae_channel hpb_dmae_channels[] = {
+       HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
+       HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
+};
+
+static struct hpb_dmae_pdata dma_platform_data __initdata = {
+       .slaves                 = hpb_dmae_slaves,
+       .num_slaves             = ARRAY_SIZE(hpb_dmae_slaves),
+       .channels               = hpb_dmae_channels,
+       .num_channels           = ARRAY_SIZE(hpb_dmae_channels),
+       .ts_shift               = {
+               [XMIT_SZ_8BIT]  = 0,
+               [XMIT_SZ_16BIT] = 1,
+               [XMIT_SZ_32BIT] = 2,
+       },
+       .num_hw_channels        = 39,
+};
+
+static struct resource hpb_dmae_resources[] __initdata = {
+       /* Channel registers */
+       DEFINE_RES_MEM(0xffc08000, 0x1000),
+       /* Common registers */
+       DEFINE_RES_MEM(0xffc09000, 0x170),
+       /* Asynchronous reset registers */
+       DEFINE_RES_MEM(0xffc00300, 4),
+       /* Asynchronous mode registers */
+       DEFINE_RES_MEM(0xffc00400, 4),
+       /* IRQ for DMA channels */
+       DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ),
+};
+
+static void __init r8a7778_register_hpb_dmae(void)
+{
+       platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
+                                         hpb_dmae_resources,
+                                         ARRAY_SIZE(hpb_dmae_resources),
+                                         &dma_platform_data,
+                                         sizeof(dma_platform_data));
+}
+
 void __init r8a7778_add_standard_devices(void)
 {
        r8a7778_add_dt_devices();
@@ -349,12 +401,12 @@ void __init r8a7778_add_standard_devices(void)
        r8a7778_register_hspi(0);
        r8a7778_register_hspi(1);
        r8a7778_register_hspi(2);
+
+       r8a7778_register_hpb_dmae();
 }
 
 void __init r8a7778_init_late(void)
 {
-       phy = usb_get_phy(USB_PHY_TYPE_USB2);
-
        platform_device_register_full(&ehci_info);
        platform_device_register_full(&ohci_info);
 }
@@ -376,7 +428,7 @@ static struct resource irqpin_resources[] __initdata = {
        DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */
 };
 
-void __init r8a7778_init_irq_extpin(int irlm)
+void __init r8a7778_init_irq_extpin_dt(int irlm)
 {
        void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
        unsigned long tmp;
@@ -394,7 +446,11 @@ void __init r8a7778_init_irq_extpin(int irlm)
        tmp |= (1 << 21); /* LVLMODE = 1 */
        iowrite32(tmp, icr0);
        iounmap(icr0);
+}
 
+void __init r8a7778_init_irq_extpin(int irlm)
+{
+       r8a7778_init_irq_extpin_dt(irlm);
        if (irlm)
                platform_device_register_resndata(
                        &platform_bus, "renesas_intc_irqpin", -1,
index ecd0148ee1e1711144eb2fd75bc146d97a582bb6..13049e9d691ca17d7be5d5d3dc9b8b565b42a3e3 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/dma-rcar-hpbdma.h>
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-intc-irqpin.h>
 #include <linux/platform_device.h>
@@ -97,7 +98,7 @@ static struct resource irqpin0_resources[] __initdata = {
        DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
 };
 
-void __init r8a7779_init_irq_extpin(int irlm)
+void __init r8a7779_init_irq_extpin_dt(int irlm)
 {
        void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
        u32 tmp;
@@ -115,7 +116,11 @@ void __init r8a7779_init_irq_extpin(int irlm)
        tmp |= (1 << 21); /* LVLMODE = 1 */
        iowrite32(tmp, icr0);
        iounmap(icr0);
+}
 
+void __init r8a7779_init_irq_extpin(int irlm)
+{
+       r8a7779_init_irq_extpin_dt(irlm);
        if (irlm)
                platform_device_register_resndata(
                        &platform_bus, "renesas_intc_irqpin", -1,
@@ -632,6 +637,158 @@ static struct platform_device_info *vin_info_table[] __initdata = {
        &vin3_info,
 };
 
+/* HPB-DMA */
+
+/* Asynchronous mode register bits */
+#define HPB_DMAE_ASYNCMDR_ASMD43_MASK          BIT(23) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE                BIT(23) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI         0       /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK                BIT(22) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST       BIT(22) /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST      0       /* MMC1 */
+#define HPB_DMAE_ASYNCMDR_ASMD24_MASK          BIT(21) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE                BIT(21) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI         0       /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK                BIT(20) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST       BIT(20) /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST      0       /* MMC0 */
+#define HPB_DMAE_ASYNCMDR_ASMD41_MASK          BIT(19) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE                BIT(19) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI         0       /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK                BIT(18) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST       BIT(18) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST      0       /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD40_MASK          BIT(17) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE                BIT(17) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI         0       /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK                BIT(16) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST       BIT(16) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST      0       /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD39_MASK          BIT(15) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE                BIT(15) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI         0       /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK                BIT(14) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST       BIT(14) /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST      0       /* SDHI3 */
+#define HPB_DMAE_ASYNCMDR_ASMD27_MASK          BIT(13) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE                BIT(13) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI         0       /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK                BIT(12) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST       BIT(12) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST      0       /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD26_MASK          BIT(11) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE                BIT(11) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI         0       /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK                BIT(10) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST       BIT(10) /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST      0       /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD25_MASK          BIT(9)  /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE                BIT(9)  /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI         0       /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK                BIT(8)  /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST       BIT(8)  /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST      0       /* SDHI2 */
+#define HPB_DMAE_ASYNCMDR_ASMD23_MASK          BIT(7)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE                BIT(7)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI         0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK                BIT(6)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST       BIT(6)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST      0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MASK          BIT(5)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE                BIT(5)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI         0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK                BIT(4)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST       BIT(4)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST      0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MASK          BIT(3)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE                BIT(3)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI         0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK                BIT(2)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST       BIT(2)  /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST      0       /* SDHI0 */
+#define HPB_DMAE_ASYNCMDR_ASMD20_MASK          BIT(1)  /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE                BIT(1)  /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI         0       /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK                BIT(0)  /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST       BIT(0)  /* SDHI1 */
+#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST      0       /* SDHI1 */
+
+static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
+       {
+               .id     = HPBDMA_SLAVE_SDHI0_TX,
+               .addr   = 0xffe4c000 + 0x30,
+               .dcr    = HPB_DMAE_DCR_SPDS_16BIT |
+                         HPB_DMAE_DCR_DMDL |
+                         HPB_DMAE_DCR_DPDS_16BIT,
+               .rstr   = HPB_DMAE_ASYNCRSTR_ASRST21 |
+                         HPB_DMAE_ASYNCRSTR_ASRST22 |
+                         HPB_DMAE_ASYNCRSTR_ASRST23,
+               .mdr    = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE |
+                         HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST,
+               .mdm    = HPB_DMAE_ASYNCMDR_ASMD21_MASK |
+                         HPB_DMAE_ASYNCMDR_ASBTMD21_MASK,
+               .port   = 0x0D0C,
+               .flags  = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+               .dma_ch = 21,
+       }, {
+               .id     = HPBDMA_SLAVE_SDHI0_RX,
+               .addr   = 0xffe4c000 + 0x30,
+               .dcr    = HPB_DMAE_DCR_SMDL |
+                         HPB_DMAE_DCR_SPDS_16BIT |
+                         HPB_DMAE_DCR_DPDS_16BIT,
+               .rstr   = HPB_DMAE_ASYNCRSTR_ASRST21 |
+                         HPB_DMAE_ASYNCRSTR_ASRST22 |
+                         HPB_DMAE_ASYNCRSTR_ASRST23,
+               .mdr    = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE |
+                         HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST,
+               .mdm    = HPB_DMAE_ASYNCMDR_ASMD22_MASK |
+                         HPB_DMAE_ASYNCMDR_ASBTMD22_MASK,
+               .port   = 0x0D0C,
+               .flags  = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+               .dma_ch = 22,
+       },
+};
+
+static const struct hpb_dmae_channel hpb_dmae_channels[] = {
+       HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
+       HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
+};
+
+static struct hpb_dmae_pdata dma_platform_data __initdata = {
+       .slaves                 = hpb_dmae_slaves,
+       .num_slaves             = ARRAY_SIZE(hpb_dmae_slaves),
+       .channels               = hpb_dmae_channels,
+       .num_channels           = ARRAY_SIZE(hpb_dmae_channels),
+       .ts_shift               = {
+               [XMIT_SZ_8BIT]  = 0,
+               [XMIT_SZ_16BIT] = 1,
+               [XMIT_SZ_32BIT] = 2,
+       },
+       .num_hw_channels        = 44,
+};
+
+static struct resource hpb_dmae_resources[] __initdata = {
+       /* Channel registers */
+       DEFINE_RES_MEM(0xffc08000, 0x1000),
+       /* Common registers */
+       DEFINE_RES_MEM(0xffc09000, 0x170),
+       /* Asynchronous reset registers */
+       DEFINE_RES_MEM(0xffc00300, 4),
+       /* Asynchronous mode registers */
+       DEFINE_RES_MEM(0xffc00400, 4),
+       /* IRQ for DMA channels */
+       DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ),
+};
+
+static void __init r8a7779_register_hpb_dmae(void)
+{
+       platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
+                                         hpb_dmae_resources,
+                                         ARRAY_SIZE(hpb_dmae_resources),
+                                         &dma_platform_data,
+                                         sizeof(dma_platform_data));
+}
+
 static struct platform_device *r8a7779_devices_dt[] __initdata = {
        &scif0_device,
        &scif1_device,
@@ -665,6 +822,7 @@ void __init r8a7779_add_standard_devices(void)
                            ARRAY_SIZE(r8a7779_devices_dt));
        platform_add_devices(r8a7779_standard_devices,
                            ARRAY_SIZE(r8a7779_standard_devices));
+       r8a7779_register_hpb_dmae();
 }
 
 void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
index d0f5c9f9349a186412da1f912fc9dbcac0e851d0..c47bcebbcb00bbfa229d16c9d2fcad2430ef631e 100644 (file)
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/clocksource.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
 #include <mach/r8a7790.h>
 #include <asm/mach/arch.h>
 
-static struct resource pfc_resources[] __initdata = {
+static const struct resource pfc_resources[] __initconst = {
        DEFINE_RES_MEM(0xe6060000, 0x250),
 };
 
 #define R8A7790_GPIO(idx)                                              \
-static struct resource r8a7790_gpio##idx##_resources[] __initdata = {  \
+static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \
        DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50),              \
        DEFINE_RES_IRQ(gic_spi(4 + (idx))),                             \
 };                                                                     \
                                                                        \
-static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = {        \
+static const struct gpio_rcar_config                                   \
+r8a7790_gpio##idx##_platform_data __initconst = {                      \
        .gpio_base      = 32 * (idx),                                   \
        .irq_base       = 0,                                            \
        .number_of_pins = 32,                                           \
@@ -112,7 +112,7 @@ void __init r8a7790_pinmux_init(void)
 enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1,
        HSCIF0, HSCIF1 };
 
-static struct plat_sci_port scif[] __initdata = {
+static const struct plat_sci_port scif[] __initconst = {
        SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
        SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */
        SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */
@@ -131,11 +131,11 @@ static inline void r8a7790_register_scif(int idx)
                                      sizeof(struct plat_sci_port));
 }
 
-static struct renesas_irqc_config irqc0_data __initdata = {
+static const struct renesas_irqc_config irqc0_data __initconst = {
        .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
 };
 
-static struct resource irqc0_resources[] __initdata = {
+static const struct resource irqc0_resources[] __initconst = {
        DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
        DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
        DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
@@ -150,7 +150,7 @@ static struct resource irqc0_resources[] __initdata = {
                                          &irqc##idx##_data,            \
                                          sizeof(struct renesas_irqc_config))
 
-static struct resource thermal_resources[] __initdata = {
+static const struct resource thermal_resources[] __initconst = {
        DEFINE_RES_MEM(0xe61f0000, 0x14),
        DEFINE_RES_MEM(0xe61f0100, 0x38),
        DEFINE_RES_IRQ(gic_spi(69)),
@@ -161,13 +161,13 @@ static struct resource thermal_resources[] __initdata = {
                                        thermal_resources,              \
                                        ARRAY_SIZE(thermal_resources))
 
-static struct sh_timer_config cmt00_platform_data __initdata = {
+static const struct sh_timer_config cmt00_platform_data __initconst = {
        .name = "CMT00",
        .timer_bit = 0,
        .clockevent_rating = 80,
 };
 
-static struct resource cmt00_resources[] __initdata = {
+static const struct resource cmt00_resources[] __initconst = {
        DEFINE_RES_MEM(0xffca0510, 0x0c),
        DEFINE_RES_MEM(0xffca0500, 0x04),
        DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
@@ -202,72 +202,7 @@ void __init r8a7790_add_standard_devices(void)
        r8a7790_register_thermal();
 }
 
-#define MODEMR 0xe6160060
-
-u32 __init r8a7790_read_mode_pins(void)
-{
-       void __iomem *modemr = ioremap_nocache(MODEMR, 4);
-       u32 mode;
-
-       BUG_ON(!modemr);
-       mode = ioread32(modemr);
-       iounmap(modemr);
-
-       return mode;
-}
-
-#define CNTCR 0
-#define CNTFID0 0x20
-
-void __init r8a7790_timer_init(void)
-{
-#ifdef CONFIG_ARM_ARCH_TIMER
-       u32 mode = r8a7790_read_mode_pins();
-       void __iomem *base;
-       int extal_mhz = 0;
-       u32 freq;
-
-       /* At Linux boot time the r8a7790 arch timer comes up
-        * with the counter disabled. Moreover, it may also report
-        * a potentially incorrect fixed 13 MHz frequency. To be
-        * correct these registers need to be updated to use the
-        * frequency EXTAL / 2 which can be determined by the MD pins.
-        */
-
-       switch (mode & (MD(14) | MD(13))) {
-       case 0:
-               extal_mhz = 15;
-               break;
-       case MD(13):
-               extal_mhz = 20;
-               break;
-       case MD(14):
-               extal_mhz = 26;
-               break;
-       case MD(13) | MD(14):
-               extal_mhz = 30;
-               break;
-       }
-
-       /* The arch timer frequency equals EXTAL / 2 */
-       freq = extal_mhz * (1000000 / 2);
-
-       /* Remap "armgcnt address map" space */
-       base = ioremap(0xe6080000, PAGE_SIZE);
-
-       /* Update registers with correct frequency */
-       iowrite32(freq, base + CNTFID0);
-       asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
-
-       /* make sure arch timer is started by setting bit 0 of CNTCR */
-       iowrite32(1, base + CNTCR);
-       iounmap(base);
-#endif /* CONFIG_ARM_ARCH_TIMER */
-
-       clocksource_of_init();
-}
-
-void __init r8a7790_init_delay(void)
+void __init r8a7790_init_early(void)
 {
 #ifndef CONFIG_ARM_ARCH_TIMER
        shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */
@@ -276,14 +211,15 @@ void __init r8a7790_init_delay(void)
 
 #ifdef CONFIG_USE_OF
 
-static const char *r8a7790_boards_compat_dt[] __initdata = {
+static const char * const r8a7790_boards_compat_dt[] __initconst = {
        "renesas,r8a7790",
        NULL,
 };
 
 DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
-       .init_early     = r8a7790_init_delay,
-       .init_time      = r8a7790_timer_init,
+       .smp            = smp_ops(r8a7790_smp_ops),
+       .init_early     = r8a7790_init_early,
+       .init_time      = rcar_gen2_timer_init,
        .dt_compat      = r8a7790_boards_compat_dt,
 MACHINE_END
 #endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
new file mode 100644 (file)
index 0000000..d9393d6
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * r8a7791 processor support
+ *
+ * Copyright (C) 2013  Renesas Electronics Corporation
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  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/irq.h>
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/irq-renesas-irqc.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/r8a7791.h>
+#include <mach/rcar-gen2.h>
+#include <asm/mach/arch.h>
+
+#define SCIF_COMMON(scif_type, baseaddr, irq)                  \
+       .type           = scif_type,                            \
+       .mapbase        = baseaddr,                             \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,      \
+       .irqs           = SCIx_IRQ_MUXED(irq)
+
+#define SCIFA_DATA(index, baseaddr, irq)               \
+[index] = {                                            \
+       SCIF_COMMON(PORT_SCIFA, baseaddr, irq),         \
+       .scbrr_algo_id  = SCBRR_ALGO_4,                 \
+       .scscr = SCSCR_RE | SCSCR_TE,   \
+}
+
+#define SCIFB_DATA(index, baseaddr, irq)       \
+[index] = {                                    \
+       SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \
+       .scbrr_algo_id  = SCBRR_ALGO_4,         \
+       .scscr = SCSCR_RE | SCSCR_TE,           \
+}
+
+#define SCIF_DATA(index, baseaddr, irq)                \
+[index] = {                                            \
+       SCIF_COMMON(PORT_SCIF, baseaddr, irq),          \
+       .scbrr_algo_id  = SCBRR_ALGO_2,                 \
+       .scscr = SCSCR_RE | SCSCR_TE,   \
+}
+
+#define HSCIF_DATA(index, baseaddr, irq)               \
+[index] = {                                            \
+       SCIF_COMMON(PORT_HSCIF, baseaddr, irq),         \
+       .scbrr_algo_id  = SCBRR_ALGO_6,                 \
+       .scscr = SCSCR_RE | SCSCR_TE,   \
+}
+
+enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1,
+       SCIF2, SCIF3, SCIF4, SCIF5, SCIFA3, SCIFA4, SCIFA5 };
+
+static const struct plat_sci_port scif[] __initconst = {
+       SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
+       SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */
+       SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */
+       SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */
+       SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */
+       SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */
+       SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */
+       SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */
+       SCIF_DATA(SCIF2, 0xe6e58000, gic_spi(22)), /* SCIF2 */
+       SCIF_DATA(SCIF3, 0xe6ea8000, gic_spi(23)), /* SCIF3 */
+       SCIF_DATA(SCIF4, 0xe6ee0000, gic_spi(24)), /* SCIF4 */
+       SCIF_DATA(SCIF5, 0xe6ee8000, gic_spi(25)), /* SCIF5 */
+       SCIFA_DATA(SCIFA3, 0xe6c70000, gic_spi(29)), /* SCIFA3 */
+       SCIFA_DATA(SCIFA4, 0xe6c78000, gic_spi(30)), /* SCIFA4 */
+       SCIFA_DATA(SCIFA5, 0xe6c80000, gic_spi(31)), /* SCIFA5 */
+};
+
+static inline void r8a7791_register_scif(int idx)
+{
+       platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx],
+                                     sizeof(struct plat_sci_port));
+}
+
+static const struct sh_timer_config cmt00_platform_data __initconst = {
+       .name = "CMT00",
+       .timer_bit = 0,
+       .clockevent_rating = 80,
+};
+
+static const struct resource cmt00_resources[] __initconst = {
+       DEFINE_RES_MEM(0xffca0510, 0x0c),
+       DEFINE_RES_MEM(0xffca0500, 0x04),
+       DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
+};
+
+#define r8a7791_register_cmt(idx)                                      \
+       platform_device_register_resndata(&platform_bus, "sh_cmt",      \
+                                         idx, cmt##idx##_resources,    \
+                                         ARRAY_SIZE(cmt##idx##_resources), \
+                                         &cmt##idx##_platform_data,    \
+                                         sizeof(struct sh_timer_config))
+
+static struct renesas_irqc_config irqc0_data = {
+       .irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */
+};
+
+static struct resource irqc0_resources[] = {
+       DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
+       DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
+       DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
+       DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */
+       DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */
+       DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */
+       DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */
+       DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */
+       DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */
+       DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */
+       DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */
+};
+
+#define r8a7791_register_irqc(idx)                                     \
+       platform_device_register_resndata(&platform_bus, "renesas_irqc", \
+                                         idx, irqc##idx##_resources,   \
+                                         ARRAY_SIZE(irqc##idx##_resources), \
+                                         &irqc##idx##_data,            \
+                                         sizeof(struct renesas_irqc_config))
+
+void __init r8a7791_add_dt_devices(void)
+{
+       r8a7791_register_scif(SCIFA0);
+       r8a7791_register_scif(SCIFA1);
+       r8a7791_register_scif(SCIFB0);
+       r8a7791_register_scif(SCIFB1);
+       r8a7791_register_scif(SCIFB2);
+       r8a7791_register_scif(SCIFA2);
+       r8a7791_register_scif(SCIF0);
+       r8a7791_register_scif(SCIF1);
+       r8a7791_register_scif(SCIF2);
+       r8a7791_register_scif(SCIF3);
+       r8a7791_register_scif(SCIF4);
+       r8a7791_register_scif(SCIF5);
+       r8a7791_register_scif(SCIFA3);
+       r8a7791_register_scif(SCIFA4);
+       r8a7791_register_scif(SCIFA5);
+       r8a7791_register_cmt(00);
+}
+
+void __init r8a7791_add_standard_devices(void)
+{
+       r8a7791_add_dt_devices();
+       r8a7791_register_irqc(0);
+}
+
+void __init r8a7791_init_early(void)
+{
+#ifndef CONFIG_ARM_ARCH_TIMER
+       shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */
+#endif
+}
+
+#ifdef CONFIG_USE_OF
+static const char *r8a7791_boards_compat_dt[] __initdata = {
+       "renesas,r8a7791",
+       NULL,
+};
+
+DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
+       .smp            = smp_ops(r8a7791_smp_ops),
+       .init_early     = r8a7791_init_early,
+       .init_time      = rcar_gen2_timer_init,
+       .dt_compat      = r8a7791_boards_compat_dt,
+MACHINE_END
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
new file mode 100644 (file)
index 0000000..5734c24
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * R-Car Generation 2 support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  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/clocksource.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/common.h>
+#include <mach/rcar-gen2.h>
+#include <asm/mach/arch.h>
+
+#define MODEMR 0xe6160060
+
+u32 __init rcar_gen2_read_mode_pins(void)
+{
+       void __iomem *modemr = ioremap_nocache(MODEMR, 4);
+       u32 mode;
+
+       BUG_ON(!modemr);
+       mode = ioread32(modemr);
+       iounmap(modemr);
+
+       return mode;
+}
+
+#define CNTCR 0
+#define CNTFID0 0x20
+
+void __init rcar_gen2_timer_init(void)
+{
+#ifdef CONFIG_ARM_ARCH_TIMER
+       u32 mode = rcar_gen2_read_mode_pins();
+       void __iomem *base;
+       int extal_mhz = 0;
+       u32 freq;
+
+       /* At Linux boot time the r8a7790 arch timer comes up
+        * with the counter disabled. Moreover, it may also report
+        * a potentially incorrect fixed 13 MHz frequency. To be
+        * correct these registers need to be updated to use the
+        * frequency EXTAL / 2 which can be determined by the MD pins.
+        */
+
+       switch (mode & (MD(14) | MD(13))) {
+       case 0:
+               extal_mhz = 15;
+               break;
+       case MD(13):
+               extal_mhz = 20;
+               break;
+       case MD(14):
+               extal_mhz = 26;
+               break;
+       case MD(13) | MD(14):
+               extal_mhz = 30;
+               break;
+       }
+
+       /* The arch timer frequency equals EXTAL / 2 */
+       freq = extal_mhz * (1000000 / 2);
+
+       /* Remap "armgcnt address map" space */
+       base = ioremap(0xe6080000, PAGE_SIZE);
+
+       /* Update registers with correct frequency */
+       iowrite32(freq, base + CNTFID0);
+       asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+
+       /* make sure arch timer is started by setting bit 0 of CNTCR */
+       iowrite32(1, base + CNTCR);
+       iounmap(base);
+#endif /* CONFIG_ARM_ARCH_TIMER */
+
+       clocksource_of_init();
+}
index 522de5ebb55fd727004e3934e4a38d8e2357462c..f2ca92308f7568f851289626fddd9c25c6064fee 100644 (file)
 
 static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       int ret;
-
-       ret = shmobile_smp_scu_boot_secondary(cpu, idle);
-       if (ret)
-               return ret;
-
        arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu)));
        return 0;
 }
index 0f05e9fb722fbfd0c3b921b6caa5a85d68b5d25d..627c1f0d9478b36ff79342d25053b9557d429189 100644 (file)
@@ -87,10 +87,6 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
        unsigned int lcpu = cpu_logical_map(cpu);
        int ret;
 
-       ret = shmobile_smp_scu_boot_secondary(cpu, idle);
-       if (ret)
-               return ret;
-
        if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu))
                ch = r8a7779_ch_cpu[lcpu];
 
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c
new file mode 100644 (file)
index 0000000..015e275
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * SMP support for r8a7790
+ *
+ * Copyright (C) 2012-2013 Renesas Solutions Corp.
+ * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.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.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/smp_plat.h>
+#include <mach/common.h>
+
+#define RST            0xe6160000
+#define CA15BAR                0x0020
+#define CA7BAR         0x0030
+#define CA15RESCNT     0x0040
+#define CA7RESCNT      0x0044
+#define MERAM          0xe8080000
+
+static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
+{
+       void __iomem *p;
+       u32 bar;
+
+       /* let APMU code install data related to shmobile_boot_vector */
+       shmobile_smp_apmu_prepare_cpus(max_cpus);
+
+       /* MERAM for jump stub, because BAR requires 256KB aligned address */
+       p = ioremap_nocache(MERAM, shmobile_boot_size);
+       memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
+       iounmap(p);
+
+       /* setup reset vectors */
+       p = ioremap_nocache(RST, 0x63);
+       bar = (MERAM >> 8) & 0xfffffc00;
+       writel_relaxed(bar, p + CA15BAR);
+       writel_relaxed(bar, p + CA7BAR);
+       writel_relaxed(bar | 0x10, p + CA15BAR);
+       writel_relaxed(bar | 0x10, p + CA7BAR);
+
+       /* enable clocks to all CPUs */
+       writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000,
+                      p + CA15RESCNT);
+       writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000,
+                      p + CA7RESCNT);
+       iounmap(p);
+}
+
+struct smp_operations r8a7790_smp_ops __initdata = {
+       .smp_prepare_cpus       = r8a7790_smp_prepare_cpus,
+       .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_disable            = shmobile_smp_cpu_disable,
+       .cpu_die                = shmobile_smp_apmu_cpu_die,
+       .cpu_kill               = shmobile_smp_apmu_cpu_kill,
+#endif
+};
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c
new file mode 100644 (file)
index 0000000..2df5bd1
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * SMP support for r8a7791
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/smp_plat.h>
+#include <mach/common.h>
+#include <mach/r8a7791.h>
+
+#define RST            0xe6160000
+#define CA15BAR                0x0020
+#define CA15RESCNT     0x0040
+#define RAM            0xe6300000
+
+static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
+{
+       void __iomem *p;
+       u32 bar;
+
+       /* let APMU code install data related to shmobile_boot_vector */
+       shmobile_smp_apmu_prepare_cpus(max_cpus);
+
+       /* RAM for jump stub, because BAR requires 256KB aligned address */
+       p = ioremap_nocache(RAM, shmobile_boot_size);
+       memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
+       iounmap(p);
+
+       /* setup reset vectors */
+       p = ioremap_nocache(RST, 0x63);
+       bar = (RAM >> 8) & 0xfffffc00;
+       writel_relaxed(bar, p + CA15BAR);
+       writel_relaxed(bar | 0x10, p + CA15BAR);
+
+       /* enable clocks to all CPUs */
+       writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000,
+                      p + CA15RESCNT);
+       iounmap(p);
+}
+
+struct smp_operations r8a7791_smp_ops __initdata = {
+       .smp_prepare_cpus       = r8a7791_smp_prepare_cpus,
+       .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_disable            = shmobile_smp_cpu_disable,
+       .cpu_die                = shmobile_smp_apmu_cpu_die,
+       .cpu_kill               = shmobile_smp_apmu_cpu_kill,
+#endif
+};
index 0baa24443793402b2313969e8a2bdb0ac81e0038..13ba36a6831fb2374ff62dcfc967cf426b98ae3c 100644 (file)
@@ -46,11 +46,6 @@ void __init sh73a0_register_twd(void)
 static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
        unsigned int lcpu = cpu_logical_map(cpu);
-       int ret;
-
-       ret = shmobile_smp_scu_boot_secondary(cpu, idle);
-       if (ret)
-               return ret;
 
        if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3)
                __raw_writel(1 << lcpu, WUPCR); /* wake up */
@@ -71,18 +66,11 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
        shmobile_smp_scu_prepare_cpus(max_cpus);
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
-static int sh73a0_cpu_disable(unsigned int cpu)
-{
-       return 0; /* CPU0 and CPU1 supported */
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
 struct smp_operations sh73a0_smp_ops __initdata = {
        .smp_prepare_cpus       = sh73a0_smp_prepare_cpus,
        .smp_boot_secondary     = sh73a0_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
-       .cpu_disable            = sh73a0_cpu_disable,
+       .cpu_disable            = shmobile_smp_cpu_disable,
        .cpu_die                = shmobile_smp_scu_cpu_die,
        .cpu_kill               = shmobile_smp_scu_cpu_kill,
 #endif
index dd86db467521956f6a1d06f5a157f77ce7ac4e5e..037100a1563aca5f52dd2e68f42c711dc71484c2 100644 (file)
@@ -4,7 +4,6 @@ config ARCH_SOCFPGA
        select ARM_AMBA
        select ARM_GIC
        select CACHE_L2X0
-       select CLKDEV_LOOKUP
        select COMMON_CLK
        select CPU_V7
        select DW_APB_TIMER_OF
index bfce9641e32f76299aa8555b997fe2e55fb142ad..dd0d49cdbe097c09fb15d0a652f2aa6d10e60db9 100644 (file)
@@ -14,7 +14,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <linux/clk-provider.h>
 #include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
@@ -107,7 +106,6 @@ static void __init socfpga_cyclone5_init(void)
 {
        l2x0_of_init(0, ~0UL);
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-       of_clk_init(NULL);
        socfpga_init_clocks();
 }
 
index df0d59afeb402a63ba2dad7bd86a81e12211e1b3..ac1710e64d9afbda6e9cb9f68ac1302eb38b4661 100644 (file)
@@ -7,11 +7,9 @@ menuconfig PLAT_SPEAR
        default PLAT_SPEAR_SINGLE
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
-       select HAVE_CLK
 
 if PLAT_SPEAR
 
index 8fe6f0c464809691c4be22c040ce4d3a3b72c22e..1217fb598cfdc7dacd877e9df8a8fee3dc83ba43 100644 (file)
@@ -7,9 +7,8 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/clk-provider.h>
-#include <linux/clocksource.h>
 #include <linux/irq.h>
+#include <linux/of_platform.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 
@@ -28,11 +27,10 @@ void __init stih41x_l2x0_init(void)
        l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
 }
 
-static void __init stih41x_timer_init(void)
+static void __init stih41x_machine_init(void)
 {
-       of_clk_init(NULL);
-       clocksource_of_init();
        stih41x_l2x0_init();
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static const char *stih41x_dt_match[] __initdata = {
@@ -42,7 +40,7 @@ static const char *stih41x_dt_match[] __initdata = {
 };
 
 DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
-       .init_time      = stih41x_timer_init,
+       .init_machine   = stih41x_machine_init,
        .smp            = smp_ops(sti_smp_ops),
        .dt_compat      = stih41x_dt_match,
 MACHINE_END
index 3ab2f65f8a50387d814b4eb4e810cac1bd681563..c9e72c89066ad78b4f7890dcdcebc28157835e79 100644 (file)
@@ -1,14 +1,14 @@
 config ARCH_SUNXI
        bool "Allwinner A1X SOCs" if ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
+       select ARM_GIC
        select CLKSRC_MMIO
        select CLKSRC_OF
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
+       select HAVE_SMP
        select PINCTRL
+       select PINCTRL_SUNXI
        select SPARSE_IRQ
        select SUN4I_TIMER
-       select PINCTRL_SUNXI
-       select ARM_GIC
-       select HAVE_SMP
index e79fb3469341d1f6907d39b66aa7c08be5f80940..61d3a387f01c52f746568f7d075f92704a471ce6 100644 (file)
@@ -10,7 +10,6 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -20,8 +19,6 @@
 #include <linux/io.h>
 #include <linux/reboot.h>
 
-#include <linux/clk/sunxi.h>
-
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
@@ -93,14 +90,13 @@ static void sun6i_restart(enum reboot_mode mode, const char *cmd)
 }
 
 static struct of_device_id sunxi_restart_ids[] = {
-       { .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart },
-       { .compatible = "allwinner,sun6i-wdt", .data = sun6i_restart },
+       { .compatible = "allwinner,sun4i-wdt" },
+       { .compatible = "allwinner,sun6i-wdt" },
        { /*sentinel*/ }
 };
 
 static void sunxi_setup_restart(void)
 {
-       const struct of_device_id *of_id;
        struct device_node *np;
 
        np = of_find_matching_node(NULL, sunxi_restart_ids);
@@ -109,17 +105,6 @@ static void sunxi_setup_restart(void)
 
        wdt_base = of_iomap(np, 0);
        WARN(!wdt_base, "failed to map watchdog base address");
-
-       of_id = of_match_node(sunxi_restart_ids, np);
-       WARN(!of_id, "restart function not available");
-
-       arm_pm_restart = of_id->data;
-}
-
-static void __init sunxi_timer_init(void)
-{
-       sunxi_init_clocks();
-       clocksource_of_init();
 }
 
 static void __init sunxi_dt_init(void)
@@ -133,13 +118,33 @@ static const char * const sunxi_board_dt_compat[] = {
        "allwinner,sun4i-a10",
        "allwinner,sun5i-a10s",
        "allwinner,sun5i-a13",
-       "allwinner,sun6i-a31",
-       "allwinner,sun7i-a20",
        NULL,
 };
 
 DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
        .init_machine   = sunxi_dt_init,
-       .init_time      = sunxi_timer_init,
        .dt_compat      = sunxi_board_dt_compat,
+       .restart        = sun4i_restart,
+MACHINE_END
+
+static const char * const sun6i_board_dt_compat[] = {
+       "allwinner,sun6i-a31",
+       NULL,
+};
+
+DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
+       .init_machine   = sunxi_dt_init,
+       .dt_compat      = sun6i_board_dt_compat,
+       .restart        = sun6i_restart,
+MACHINE_END
+
+static const char * const sun7i_board_dt_compat[] = {
+       "allwinner,sun7i-a20",
+       NULL,
+};
+
+DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family")
+       .init_machine   = sunxi_dt_init,
+       .dt_compat      = sun7i_board_dt_compat,
+       .restart        = sun4i_restart,
 MACHINE_END
index 67a76f2dfb9f62b99351e0e7ecb4d8c877b08d4b..0bf04a0bca9d5c4d5d831b730de89cff332bb7b4 100644 (file)
@@ -3,7 +3,6 @@ config ARCH_TEGRA
        select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ARM_GIC
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select CLKSRC_OF
        select COMMON_CLK
@@ -11,7 +10,6 @@ config ARCH_TEGRA
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_CLK
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
        select MIGHT_HAVE_PCI
@@ -53,14 +51,22 @@ config ARCH_TEGRA_3x_SOC
 
 config ARCH_TEGRA_114_SOC
        bool "Enable support for Tegra114 family"
-       select HAVE_ARM_ARCH_TIMER
        select ARM_ERRATA_798181
        select ARM_L1_CACHE_SHIFT_6
+       select HAVE_ARM_ARCH_TIMER
        select PINCTRL_TEGRA114
        help
          Support for NVIDIA Tegra T114 processor family, based on the
          ARM CortexA15MP CPU
 
+config ARCH_TEGRA_124_SOC
+       bool "Enable support for Tegra124 family"
+       select ARM_L1_CACHE_SHIFT_6
+       select HAVE_ARM_ARCH_TIMER
+       help
+         Support for NVIDIA Tegra T124 processor family, based on the
+         ARM CortexA15MP CPU
+
 config TEGRA_AHB
        bool "Enable AHB driver for NVIDIA Tegra SoCs"
        default y
index e7e5f45c6558d6a004b653be43b8a664694e7b1d..019bb175866294227f4197633d58d32a7b89004c 100644 (file)
@@ -1,6 +1,5 @@
 asflags-y                              += -march=armv7-a
 
-obj-y                                   += common.o
 obj-y                                   += io.o
 obj-y                                   += irq.o
 obj-y                                  += fuse.o
@@ -36,5 +35,10 @@ obj-$(CONFIG_ARCH_TEGRA_114_SOC)     += pm-tegra30.o
 ifeq ($(CONFIG_CPU_IDLE),y)
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += cpuidle-tegra114.o
 endif
+obj-$(CONFIG_ARCH_TEGRA_124_SOC)       += sleep-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC)       += pm-tegra30.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_124_SOC)       += cpuidle-tegra114.o
+endif
 
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += board-paz00.o
index 740e16f64728f5c457cb2ccd303718b9278abaf8..06f024070dab6ef9a826a2090d068328adeeea50 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/rfkill-gpio.h>
 #include "board.h"
-#include "board-paz00.h"
 
 static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
        .name           = "wifi_rfkill",
-       .reset_gpio     = TEGRA_WIFI_RST,
-       .shutdown_gpio  = TEGRA_WIFI_PWRN,
+       .reset_gpio     = 25, /* PD1 */
+       .shutdown_gpio  = 85, /* PK5 */
        .type   = RFKILL_TYPE_WLAN,
 };
 
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
deleted file mode 100644 (file)
index 25c08ec..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-tegra/board-paz00.h
- *
- * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _MACH_TEGRA_BOARD_PAZ00_H
-#define _MACH_TEGRA_BOARD_PAZ00_H
-
-#include "gpio-names.h"
-
-#define TEGRA_WIFI_PWRN                        TEGRA_GPIO_PK5
-#define TEGRA_WIFI_RST                 TEGRA_GPIO_PD1
-
-#endif
index db6810dc0b3d21d300576a7ced765195d56db26e..bcf5dbf69d5891edde4df4f202b7c93cab9f24d7 100644 (file)
 #include <linux/types.h>
 #include <linux/reboot.h>
 
-void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd);
-
-void __init tegra_init_early(void);
 void __init tegra_map_common_io(void);
 void __init tegra_init_irq(void);
-void __init tegra_dt_init_irq(void);
-
-void tegra_init_late(void);
-
-#ifdef CONFIG_DEBUG_FS
-int tegra_clk_debugfs_init(void);
-#else
-static inline int tegra_clk_debugfs_init(void) { return 0; }
-#endif
 
 int __init tegra_powergate_init(void);
 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) && defined(CONFIG_DEBUG_FS)
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
deleted file mode 100644 (file)
index 94a119a..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * arch/arm/mach-tegra/common.c
- *
- * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
- * Copyright (C) 2010 Google, Inc.
- *
- * Author:
- *     Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/irqchip.h>
-#include <linux/clk-provider.h>
-
-#include <asm/hardware/cache-l2x0.h>
-
-#include "board.h"
-#include "common.h"
-#include "cpuidle.h"
-#include "fuse.h"
-#include "iomap.h"
-#include "irq.h"
-#include "pmc.h"
-#include "apbio.h"
-#include "sleep.h"
-#include "pm.h"
-#include "reset.h"
-
-/*
- * Storage for debug-macro.S's state.
- *
- * This must be in .data not .bss so that it gets initialized each time the
- * kernel is loaded. The data is declared here rather than debug-macro.S so
- * that multiple inclusions of debug-macro.S point at the same data.
- */
-u32 tegra_uart_config[4] = {
-       /* Debug UART initialization required */
-       1,
-       /* Debug UART physical address */
-       0,
-       /* Debug UART virtual address */
-       0,
-       /* Scratch space for debug macro */
-       0,
-};
-
-#ifdef CONFIG_OF
-void __init tegra_dt_init_irq(void)
-{
-       of_clk_init(NULL);
-       tegra_pmc_init();
-       tegra_init_irq();
-       irqchip_init();
-       tegra_legacy_irq_syscore_init();
-}
-#endif
-
-void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd)
-{
-       void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0);
-       u32 reg;
-
-       reg = readl_relaxed(reset);
-       reg |= 0x10;
-       writel_relaxed(reg, reset);
-}
-
-static void __init tegra_init_cache(void)
-{
-#ifdef CONFIG_CACHE_L2X0
-       int ret;
-       void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
-       u32 aux_ctrl, cache_type;
-
-       cache_type = readl(p + L2X0_CACHE_TYPE);
-       aux_ctrl = (cache_type & 0x700) << (17-8);
-       aux_ctrl |= 0x7C400001;
-
-       ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
-       if (!ret)
-               l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
-#endif
-
-}
-
-void __init tegra_init_early(void)
-{
-       tegra_cpu_reset_handler_init();
-       tegra_apb_io_init();
-       tegra_init_fuse();
-       tegra_init_cache();
-       tegra_powergate_init();
-       tegra_hotplug_init();
-}
-
-void __init tegra_init_late(void)
-{
-       tegra_init_suspend();
-       tegra_cpuidle_init();
-       tegra_powergate_debugfs_init();
-}
index 0961dfcf83a4af4e2395f114a3608f6d35ac4349..7bc5d8d667fe166e119ae797f5f4eb04007096cc 100644 (file)
@@ -39,7 +39,9 @@ void __init tegra_cpuidle_init(void)
                        tegra30_cpuidle_init();
                break;
        case TEGRA114:
-               if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+       case TEGRA124:
+               if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
                        tegra114_cpuidle_init();
                break;
        }
index 5348543382bfa292bded606815256e038281e75e..ce8ab8abf0616551416f5becbe8fcbd9317f6e18 100644 (file)
@@ -87,6 +87,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
                break;
        case TEGRA30:
        case TEGRA114:
+       case TEGRA124:
                /* clear wfe bitmap */
                reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
                /* clear wfi bitmap */
@@ -125,6 +126,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
                break;
        case TEGRA30:
        case TEGRA114:
+       case TEGRA124:
                /* clear wfe bitmap */
                reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
                /* clear wfi bitmap */
index e035cd284a6eb5e3bf1268acb00da3c5784e5ced..d4639c5066222ea785f3dab068f46874fd52513c 100644 (file)
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/export.h>
+#include <linux/random.h>
 #include <linux/tegra-soc.h>
 
 #include "fuse.h"
 #include "iomap.h"
 #include "apbio.h"
 
+/* Tegra20 only */
 #define FUSE_UID_LOW           0x108
 #define FUSE_UID_HIGH          0x10c
+
+/* Tegra30 and later */
+#define FUSE_VENDOR_CODE       0x200
+#define FUSE_FAB_CODE          0x204
+#define FUSE_LOT_CODE_0                0x208
+#define FUSE_LOT_CODE_1                0x20c
+#define FUSE_WAFER_ID          0x210
+#define FUSE_X_COORDINATE      0x214
+#define FUSE_Y_COORDINATE      0x218
+
 #define FUSE_SKU_INFO          0x110
 
 #define TEGRA20_FUSE_SPARE_BIT         0x200
@@ -112,21 +124,51 @@ u32 tegra_read_chipid(void)
        return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
 }
 
-void tegra_init_fuse(void)
+static void __init tegra20_fuse_init_randomness(void)
+{
+       u32 randomness[2];
+
+       randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
+       randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
+
+       add_device_randomness(randomness, sizeof(randomness));
+}
+
+/* Applies to Tegra30 or later */
+static void __init tegra30_fuse_init_randomness(void)
+{
+       u32 randomness[7];
+
+       randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
+       randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
+       randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
+       randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
+       randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
+       randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
+       randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
+
+       add_device_randomness(randomness, sizeof(randomness));
+}
+
+void __init tegra_init_fuse(void)
 {
        u32 id;
+       u32 randomness[5];
 
        u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
        reg |= 1 << 28;
        writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
 
        reg = tegra_fuse_readl(FUSE_SKU_INFO);
+       randomness[0] = reg;
        tegra_sku_id = reg & 0xFF;
 
        reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
+       randomness[1] = reg;
        tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
 
        id = tegra_read_chipid();
+       randomness[2] = id;
        tegra_chip_id = (id >> 8) & 0xff;
 
        switch (tegra_chip_id) {
@@ -149,6 +191,18 @@ void tegra_init_fuse(void)
 
        tegra_revision = tegra_get_revision(id);
        tegra_init_speedo_data();
+       randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
+       randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
+
+       add_device_randomness(randomness, sizeof(randomness));
+       switch (tegra_chip_id) {
+       case TEGRA20:
+               tegra20_fuse_init_randomness();
+       case TEGRA30:
+       case TEGRA114:
+       default:
+               tegra30_fuse_init_randomness();
+       }
 
        pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
                tegra_revision_name[tegra_revision],
index def79683bef62d2af19d6b17d8b93063c8b2d508..c01d04785d6716cc93a064bc812168e8eafb55b7 100644 (file)
@@ -29,6 +29,7 @@
 #define TEGRA20                0x20
 #define TEGRA30                0x30
 #define TEGRA114       0x35
+#define TEGRA124       0x40
 
 #ifndef __ASSEMBLY__
 enum tegra_revision {
diff --git a/arch/arm/mach-tegra/gpio-names.h b/arch/arm/mach-tegra/gpio-names.h
deleted file mode 100644 (file)
index f28220a..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/gpio-names.h
- *
- * Copyright (c) 2010 Google, Inc
- *
- * Author:
- *     Erik Gilling <konkers@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __MACH_TEGRA_GPIO_NAMES_H
-#define __MACH_TEGRA_GPIO_NAMES_H
-
-#define TEGRA_GPIO_PA0         0
-#define TEGRA_GPIO_PA1         1
-#define TEGRA_GPIO_PA2         2
-#define TEGRA_GPIO_PA3         3
-#define TEGRA_GPIO_PA4         4
-#define TEGRA_GPIO_PA5         5
-#define TEGRA_GPIO_PA6         6
-#define TEGRA_GPIO_PA7         7
-#define TEGRA_GPIO_PB0         8
-#define TEGRA_GPIO_PB1         9
-#define TEGRA_GPIO_PB2         10
-#define TEGRA_GPIO_PB3         11
-#define TEGRA_GPIO_PB4         12
-#define TEGRA_GPIO_PB5         13
-#define TEGRA_GPIO_PB6         14
-#define TEGRA_GPIO_PB7         15
-#define TEGRA_GPIO_PC0         16
-#define TEGRA_GPIO_PC1         17
-#define TEGRA_GPIO_PC2         18
-#define TEGRA_GPIO_PC3         19
-#define TEGRA_GPIO_PC4         20
-#define TEGRA_GPIO_PC5         21
-#define TEGRA_GPIO_PC6         22
-#define TEGRA_GPIO_PC7         23
-#define TEGRA_GPIO_PD0         24
-#define TEGRA_GPIO_PD1         25
-#define TEGRA_GPIO_PD2         26
-#define TEGRA_GPIO_PD3         27
-#define TEGRA_GPIO_PD4         28
-#define TEGRA_GPIO_PD5         29
-#define TEGRA_GPIO_PD6         30
-#define TEGRA_GPIO_PD7         31
-#define TEGRA_GPIO_PE0         32
-#define TEGRA_GPIO_PE1         33
-#define TEGRA_GPIO_PE2         34
-#define TEGRA_GPIO_PE3         35
-#define TEGRA_GPIO_PE4         36
-#define TEGRA_GPIO_PE5         37
-#define TEGRA_GPIO_PE6         38
-#define TEGRA_GPIO_PE7         39
-#define TEGRA_GPIO_PF0         40
-#define TEGRA_GPIO_PF1         41
-#define TEGRA_GPIO_PF2         42
-#define TEGRA_GPIO_PF3         43
-#define TEGRA_GPIO_PF4         44
-#define TEGRA_GPIO_PF5         45
-#define TEGRA_GPIO_PF6         46
-#define TEGRA_GPIO_PF7         47
-#define TEGRA_GPIO_PG0         48
-#define TEGRA_GPIO_PG1         49
-#define TEGRA_GPIO_PG2         50
-#define TEGRA_GPIO_PG3         51
-#define TEGRA_GPIO_PG4         52
-#define TEGRA_GPIO_PG5         53
-#define TEGRA_GPIO_PG6         54
-#define TEGRA_GPIO_PG7         55
-#define TEGRA_GPIO_PH0         56
-#define TEGRA_GPIO_PH1         57
-#define TEGRA_GPIO_PH2         58
-#define TEGRA_GPIO_PH3         59
-#define TEGRA_GPIO_PH4         60
-#define TEGRA_GPIO_PH5         61
-#define TEGRA_GPIO_PH6         62
-#define TEGRA_GPIO_PH7         63
-#define TEGRA_GPIO_PI0         64
-#define TEGRA_GPIO_PI1         65
-#define TEGRA_GPIO_PI2         66
-#define TEGRA_GPIO_PI3         67
-#define TEGRA_GPIO_PI4         68
-#define TEGRA_GPIO_PI5         69
-#define TEGRA_GPIO_PI6         70
-#define TEGRA_GPIO_PI7         71
-#define TEGRA_GPIO_PJ0         72
-#define TEGRA_GPIO_PJ1         73
-#define TEGRA_GPIO_PJ2         74
-#define TEGRA_GPIO_PJ3         75
-#define TEGRA_GPIO_PJ4         76
-#define TEGRA_GPIO_PJ5         77
-#define TEGRA_GPIO_PJ6         78
-#define TEGRA_GPIO_PJ7         79
-#define TEGRA_GPIO_PK0         80
-#define TEGRA_GPIO_PK1         81
-#define TEGRA_GPIO_PK2         82
-#define TEGRA_GPIO_PK3         83
-#define TEGRA_GPIO_PK4         84
-#define TEGRA_GPIO_PK5         85
-#define TEGRA_GPIO_PK6         86
-#define TEGRA_GPIO_PK7         87
-#define TEGRA_GPIO_PL0         88
-#define TEGRA_GPIO_PL1         89
-#define TEGRA_GPIO_PL2         90
-#define TEGRA_GPIO_PL3         91
-#define TEGRA_GPIO_PL4         92
-#define TEGRA_GPIO_PL5         93
-#define TEGRA_GPIO_PL6         94
-#define TEGRA_GPIO_PL7         95
-#define TEGRA_GPIO_PM0         96
-#define TEGRA_GPIO_PM1         97
-#define TEGRA_GPIO_PM2         98
-#define TEGRA_GPIO_PM3         99
-#define TEGRA_GPIO_PM4         100
-#define TEGRA_GPIO_PM5         101
-#define TEGRA_GPIO_PM6         102
-#define TEGRA_GPIO_PM7         103
-#define TEGRA_GPIO_PN0         104
-#define TEGRA_GPIO_PN1         105
-#define TEGRA_GPIO_PN2         106
-#define TEGRA_GPIO_PN3         107
-#define TEGRA_GPIO_PN4         108
-#define TEGRA_GPIO_PN5         109
-#define TEGRA_GPIO_PN6         110
-#define TEGRA_GPIO_PN7         111
-#define TEGRA_GPIO_PO0         112
-#define TEGRA_GPIO_PO1         113
-#define TEGRA_GPIO_PO2         114
-#define TEGRA_GPIO_PO3         115
-#define TEGRA_GPIO_PO4         116
-#define TEGRA_GPIO_PO5         117
-#define TEGRA_GPIO_PO6         118
-#define TEGRA_GPIO_PO7         119
-#define TEGRA_GPIO_PP0         120
-#define TEGRA_GPIO_PP1         121
-#define TEGRA_GPIO_PP2         122
-#define TEGRA_GPIO_PP3         123
-#define TEGRA_GPIO_PP4         124
-#define TEGRA_GPIO_PP5         125
-#define TEGRA_GPIO_PP6         126
-#define TEGRA_GPIO_PP7         127
-#define TEGRA_GPIO_PQ0         128
-#define TEGRA_GPIO_PQ1         129
-#define TEGRA_GPIO_PQ2         130
-#define TEGRA_GPIO_PQ3         131
-#define TEGRA_GPIO_PQ4         132
-#define TEGRA_GPIO_PQ5         133
-#define TEGRA_GPIO_PQ6         134
-#define TEGRA_GPIO_PQ7         135
-#define TEGRA_GPIO_PR0         136
-#define TEGRA_GPIO_PR1         137
-#define TEGRA_GPIO_PR2         138
-#define TEGRA_GPIO_PR3         139
-#define TEGRA_GPIO_PR4         140
-#define TEGRA_GPIO_PR5         141
-#define TEGRA_GPIO_PR6         142
-#define TEGRA_GPIO_PR7         143
-#define TEGRA_GPIO_PS0         144
-#define TEGRA_GPIO_PS1         145
-#define TEGRA_GPIO_PS2         146
-#define TEGRA_GPIO_PS3         147
-#define TEGRA_GPIO_PS4         148
-#define TEGRA_GPIO_PS5         149
-#define TEGRA_GPIO_PS6         150
-#define TEGRA_GPIO_PS7         151
-#define TEGRA_GPIO_PT0         152
-#define TEGRA_GPIO_PT1         153
-#define TEGRA_GPIO_PT2         154
-#define TEGRA_GPIO_PT3         155
-#define TEGRA_GPIO_PT4         156
-#define TEGRA_GPIO_PT5         157
-#define TEGRA_GPIO_PT6         158
-#define TEGRA_GPIO_PT7         159
-#define TEGRA_GPIO_PU0         160
-#define TEGRA_GPIO_PU1         161
-#define TEGRA_GPIO_PU2         162
-#define TEGRA_GPIO_PU3         163
-#define TEGRA_GPIO_PU4         164
-#define TEGRA_GPIO_PU5         165
-#define TEGRA_GPIO_PU6         166
-#define TEGRA_GPIO_PU7         167
-#define TEGRA_GPIO_PV0         168
-#define TEGRA_GPIO_PV1         169
-#define TEGRA_GPIO_PV2         170
-#define TEGRA_GPIO_PV3         171
-#define TEGRA_GPIO_PV4         172
-#define TEGRA_GPIO_PV5         173
-#define TEGRA_GPIO_PV6         174
-#define TEGRA_GPIO_PV7         175
-#define TEGRA_GPIO_PW0         176
-#define TEGRA_GPIO_PW1         177
-#define TEGRA_GPIO_PW2         178
-#define TEGRA_GPIO_PW3         179
-#define TEGRA_GPIO_PW4         180
-#define TEGRA_GPIO_PW5         181
-#define TEGRA_GPIO_PW6         182
-#define TEGRA_GPIO_PW7         183
-#define TEGRA_GPIO_PX0         184
-#define TEGRA_GPIO_PX1         185
-#define TEGRA_GPIO_PX2         186
-#define TEGRA_GPIO_PX3         187
-#define TEGRA_GPIO_PX4         188
-#define TEGRA_GPIO_PX5         189
-#define TEGRA_GPIO_PX6         190
-#define TEGRA_GPIO_PX7         191
-#define TEGRA_GPIO_PY0         192
-#define TEGRA_GPIO_PY1         193
-#define TEGRA_GPIO_PY2         194
-#define TEGRA_GPIO_PY3         195
-#define TEGRA_GPIO_PY4         196
-#define TEGRA_GPIO_PY5         197
-#define TEGRA_GPIO_PY6         198
-#define TEGRA_GPIO_PY7         199
-#define TEGRA_GPIO_PZ0         200
-#define TEGRA_GPIO_PZ1         201
-#define TEGRA_GPIO_PZ2         202
-#define TEGRA_GPIO_PZ3         203
-#define TEGRA_GPIO_PZ4         204
-#define TEGRA_GPIO_PZ5         205
-#define TEGRA_GPIO_PZ6         206
-#define TEGRA_GPIO_PZ7         207
-#define TEGRA_GPIO_PAA0                208
-#define TEGRA_GPIO_PAA1                209
-#define TEGRA_GPIO_PAA2                210
-#define TEGRA_GPIO_PAA3                211
-#define TEGRA_GPIO_PAA4                212
-#define TEGRA_GPIO_PAA5                213
-#define TEGRA_GPIO_PAA6                214
-#define TEGRA_GPIO_PAA7                215
-#define TEGRA_GPIO_PBB0                216
-#define TEGRA_GPIO_PBB1                217
-#define TEGRA_GPIO_PBB2                218
-#define TEGRA_GPIO_PBB3                219
-#define TEGRA_GPIO_PBB4                220
-#define TEGRA_GPIO_PBB5                221
-#define TEGRA_GPIO_PBB6                222
-#define TEGRA_GPIO_PBB7                223
-
-#endif
index 04de2e8609237fbd8133b4e8341a588db47c7a33..ff26af26bd0ce7b15d7a9308f3a36d240ec0a8a1 100644 (file)
@@ -57,4 +57,6 @@ void __init tegra_hotplug_init(void)
                tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
        if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
                tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)
+               tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
 }
index 3f5fa0749bde4a50f98d0ea2e70501ca3cc6bf59..26b1c2ad0cebfd30a50573138808b7df17cd34cf 100644 (file)
 #define TEGRA_IRAM_BASE                        0x40000000
 #define TEGRA_IRAM_SIZE                        SZ_256K
 
-#define TEGRA_IRAM_CODE_AREA           (TEGRA_IRAM_BASE + SZ_4K)
-
-#define TEGRA_HOST1X_BASE              0x50000000
-#define TEGRA_HOST1X_SIZE              0x24000
-
 #define TEGRA_ARM_PERIF_BASE           0x50040000
 #define TEGRA_ARM_PERIF_SIZE           SZ_8K
 
-#define TEGRA_ARM_PL310_BASE           0x50043000
-#define TEGRA_ARM_PL310_SIZE           SZ_4K
-
 #define TEGRA_ARM_INT_DIST_BASE                0x50041000
 #define TEGRA_ARM_INT_DIST_SIZE                SZ_4K
 
-#define TEGRA_MPE_BASE                 0x54040000
-#define TEGRA_MPE_SIZE                 SZ_256K
-
-#define TEGRA_VI_BASE                  0x54080000
-#define TEGRA_VI_SIZE                  SZ_256K
-
-#define TEGRA_ISP_BASE                 0x54100000
-#define TEGRA_ISP_SIZE                 SZ_256K
-
-#define TEGRA_DISPLAY_BASE             0x54200000
-#define TEGRA_DISPLAY_SIZE             SZ_256K
-
-#define TEGRA_DISPLAY2_BASE            0x54240000
-#define TEGRA_DISPLAY2_SIZE            SZ_256K
-
-#define TEGRA_HDMI_BASE                        0x54280000
-#define TEGRA_HDMI_SIZE                        SZ_256K
-
-#define TEGRA_GART_BASE                        0x58000000
-#define TEGRA_GART_SIZE                        SZ_32M
-
-#define TEGRA_RES_SEMA_BASE            0x60001000
-#define TEGRA_RES_SEMA_SIZE            SZ_4K
-
 #define TEGRA_PRIMARY_ICTLR_BASE       0x60004000
 #define TEGRA_PRIMARY_ICTLR_SIZE       SZ_64
 
 #define TEGRA_FLOW_CTRL_BASE           0x60007000
 #define TEGRA_FLOW_CTRL_SIZE           20
 
-#define TEGRA_AHB_DMA_BASE             0x60008000
-#define TEGRA_AHB_DMA_SIZE             SZ_4K
-
-#define TEGRA_AHB_DMA_CH0_BASE         0x60009000
-#define TEGRA_AHB_DMA_CH0_SIZE         32
-
-#define TEGRA_APB_DMA_BASE             0x6000A000
-#define TEGRA_APB_DMA_SIZE             SZ_4K
-
-#define TEGRA_APB_DMA_CH0_BASE         0x6000B000
-#define TEGRA_APB_DMA_CH0_SIZE         32
-
-#define TEGRA_AHB_GIZMO_BASE           0x6000C004
-#define TEGRA_AHB_GIZMO_SIZE           0x10C
-
 #define TEGRA_SB_BASE                  0x6000C200
 #define TEGRA_SB_SIZE                  256
 
-#define TEGRA_STATMON_BASE             0x6000C400
-#define TEGRA_STATMON_SIZE             SZ_1K
-
-#define TEGRA_GPIO_BASE                        0x6000D000
-#define TEGRA_GPIO_SIZE                        SZ_4K
-
 #define TEGRA_EXCEPTION_VECTORS_BASE    0x6000F000
 #define TEGRA_EXCEPTION_VECTORS_SIZE    SZ_4K
 
 #define TEGRA_APB_MISC_BASE            0x70000000
 #define TEGRA_APB_MISC_SIZE            SZ_4K
 
-#define TEGRA_APB_MISC_DAS_BASE                0x70000c00
-#define TEGRA_APB_MISC_DAS_SIZE                SZ_128
-
-#define TEGRA_AC97_BASE                        0x70002000
-#define TEGRA_AC97_SIZE                        SZ_512
-
-#define TEGRA_SPDIF_BASE               0x70002400
-#define TEGRA_SPDIF_SIZE               SZ_512
-
-#define TEGRA_I2S1_BASE                        0x70002800
-#define TEGRA_I2S1_SIZE                        SZ_256
-
-#define TEGRA_I2S2_BASE                        0x70002A00
-#define TEGRA_I2S2_SIZE                        SZ_256
-
 #define TEGRA_UARTA_BASE               0x70006000
 #define TEGRA_UARTA_SIZE               SZ_64
 
 #define TEGRA_UARTE_BASE               0x70006400
 #define TEGRA_UARTE_SIZE               SZ_256
 
-#define TEGRA_NAND_BASE                        0x70008000
-#define TEGRA_NAND_SIZE                        SZ_256
-
-#define TEGRA_HSMMC_BASE               0x70008500
-#define TEGRA_HSMMC_SIZE               SZ_256
-
-#define TEGRA_SNOR_BASE                        0x70009000
-#define TEGRA_SNOR_SIZE                        SZ_4K
-
-#define TEGRA_PWFM_BASE                        0x7000A000
-#define TEGRA_PWFM_SIZE                        SZ_256
-
-#define TEGRA_PWFM0_BASE               0x7000A000
-#define TEGRA_PWFM0_SIZE               4
-
-#define TEGRA_PWFM1_BASE               0x7000A010
-#define TEGRA_PWFM1_SIZE               4
-
-#define TEGRA_PWFM2_BASE               0x7000A020
-#define TEGRA_PWFM2_SIZE               4
-
-#define TEGRA_PWFM3_BASE               0x7000A030
-#define TEGRA_PWFM3_SIZE               4
-
-#define TEGRA_MIPI_BASE                        0x7000B000
-#define TEGRA_MIPI_SIZE                        SZ_256
-
-#define TEGRA_I2C_BASE                 0x7000C000
-#define TEGRA_I2C_SIZE                 SZ_256
-
-#define TEGRA_TWC_BASE                 0x7000C100
-#define TEGRA_TWC_SIZE                 SZ_256
-
-#define TEGRA_SPI_BASE                 0x7000C380
-#define TEGRA_SPI_SIZE                 48
-
-#define TEGRA_I2C2_BASE                        0x7000C400
-#define TEGRA_I2C2_SIZE                        SZ_256
-
-#define TEGRA_I2C3_BASE                        0x7000C500
-#define TEGRA_I2C3_SIZE                        SZ_256
-
-#define TEGRA_OWR_BASE                 0x7000C600
-#define TEGRA_OWR_SIZE                 80
-
-#define TEGRA_DVC_BASE                 0x7000D000
-#define TEGRA_DVC_SIZE                 SZ_512
-
-#define TEGRA_SPI1_BASE                        0x7000D400
-#define TEGRA_SPI1_SIZE                        SZ_512
-
-#define TEGRA_SPI2_BASE                        0x7000D600
-#define TEGRA_SPI2_SIZE                        SZ_512
-
-#define TEGRA_SPI3_BASE                        0x7000D800
-#define TEGRA_SPI3_SIZE                        SZ_512
-
-#define TEGRA_SPI4_BASE                        0x7000DA00
-#define TEGRA_SPI4_SIZE                        SZ_512
-
-#define TEGRA_RTC_BASE                 0x7000E000
-#define TEGRA_RTC_SIZE                 SZ_256
-
-#define TEGRA_KBC_BASE                 0x7000E200
-#define TEGRA_KBC_SIZE                 SZ_256
-
 #define TEGRA_PMC_BASE                 0x7000E400
 #define TEGRA_PMC_SIZE                 SZ_256
 
-#define TEGRA_MC_BASE                  0x7000F000
-#define TEGRA_MC_SIZE                  SZ_1K
-
 #define TEGRA_EMC_BASE                 0x7000F400
 #define TEGRA_EMC_SIZE                 SZ_1K
 
 #define TEGRA_FUSE_BASE                        0x7000F800
 #define TEGRA_FUSE_SIZE                        SZ_1K
 
-#define TEGRA_KFUSE_BASE               0x7000FC00
-#define TEGRA_KFUSE_SIZE               SZ_1K
-
 #define TEGRA_EMC0_BASE                        0x7001A000
 #define TEGRA_EMC0_SIZE                        SZ_2K
 
 #define TEGRA_EMC1_BASE                        0x7001A800
 #define TEGRA_EMC1_SIZE                        SZ_2K
 
+#define TEGRA124_EMC_BASE              0x7001B000
+#define TEGRA124_EMC_SIZE              SZ_2K
+
 #define TEGRA_CSITE_BASE               0x70040000
 #define TEGRA_CSITE_SIZE               SZ_256K
 
-#define TEGRA_SDMMC1_BASE              0xC8000000
-#define TEGRA_SDMMC1_SIZE              SZ_512
-
-#define TEGRA_SDMMC2_BASE              0xC8000200
-#define TEGRA_SDMMC2_SIZE              SZ_512
-
-#define TEGRA_SDMMC3_BASE              0xC8000400
-#define TEGRA_SDMMC3_SIZE              SZ_512
-
-#define TEGRA_SDMMC4_BASE              0xC8000600
-#define TEGRA_SDMMC4_SIZE              SZ_512
-
 /* On TEGRA, many peripherals are very closely packed in
  * two 256MB io windows (that actually only use about 64KB
  * at the start of each).
index 501952a8434455af70aeea381aeb6cca63b7d6b4..e32e1742c9a11730bd287ecc93cd09f2c1b33f6d 100644 (file)
 #define TEGRA_IRAM_RESET_HANDLER_OFFSET        0
 #define TEGRA_IRAM_RESET_HANDLER_SIZE  SZ_1K
 
+/*
+ * This area is used for LPx resume vector, only while LPx power state is
+ * active. At other times, the AVP may use this area for arbitrary purposes
+ */
+#define TEGRA_IRAM_LPx_RESUME_AREA     (TEGRA_IRAM_BASE + SZ_4K)
+
 #endif
index 2d0203627fbb418a10357ffe0b922d907df7809a..eb72ae709124e4978167b2c38c96a63d44543b46 100644 (file)
@@ -176,6 +176,8 @@ static int tegra_boot_secondary(unsigned int cpu,
                return tegra30_boot_secondary(cpu, idle);
        if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
                return tegra114_boot_secondary(cpu, idle);
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)
+               return tegra114_boot_secondary(cpu, idle);
 
        return -EINVAL;
 }
index ed294a04e1d39d11ef3548c8e0710a06128abccd..4ae0286b468db6209311d14d13cd9cc673fb200b 100644 (file)
@@ -59,8 +59,10 @@ static void tegra_tear_down_cpu_init(void)
                break;
        case TEGRA30:
        case TEGRA114:
+       case TEGRA124:
                if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
-                   IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
                        tegra_tear_down_cpu = tegra30_tear_down_cpu;
                break;
        }
@@ -216,8 +218,10 @@ static bool tegra_lp1_iram_hook(void)
                break;
        case TEGRA30:
        case TEGRA114:
+       case TEGRA124:
                if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
-                   IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
                        tegra30_lp1_iram_hook();
                break;
        default:
@@ -244,8 +248,10 @@ static bool tegra_sleep_core_init(void)
                break;
        case TEGRA30:
        case TEGRA114:
+       case TEGRA124:
                if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
-                   IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+                   IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
                        tegra30_sleep_core_init();
                break;
        default:
@@ -263,10 +269,10 @@ static void tegra_suspend_enter_lp1(void)
        tegra_pmc_suspend();
 
        /* copy the reset vector & SDRAM shutdown code into IRAM */
-       memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_CODE_AREA),
-               iram_save_size);
-       memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), tegra_lp1_iram.start_addr,
+       memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
                iram_save_size);
+       memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
+               tegra_lp1_iram.start_addr, iram_save_size);
 
        *((u32 *)tegra_cpu_lp1_mask) = 1;
 }
@@ -276,7 +282,7 @@ static void tegra_suspend_exit_lp1(void)
        tegra_pmc_resume();
 
        /* restore IRAM */
-       memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), iram_save_addr,
+       memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr,
                iram_save_size);
 
        *(u32 *)tegra_cpu_lp1_mask = 0;
index fe204e5256e761c781b375272162412a5c2119c5..6e92a7c2ecbd164c5be483b457e18b3bae1cab8d 100644 (file)
@@ -37,9 +37,6 @@ void tegra30_sleep_core_init(void);
 
 extern unsigned long l2x0_saved_regs_addr;
 
-void save_cpu_arch_register(void);
-void restore_cpu_arch_register(void);
-
 void tegra_clear_cpu_in_lp2(void);
 bool tegra_set_cpu_in_lp2(void);
 
index 8acb881f7cfe5c8025f4c133cb5a1a60d2ec9181..fb7920201ab4de46c654321409c39df1066e5641 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/tegra-powergate.h>
 
 #include "flowctrl.h"
 #include "fuse.h"
 #define PMC_CPUPWRGOOD_TIMER   0xc8
 #define PMC_CPUPWROFF_TIMER    0xcc
 
-#define TEGRA_POWERGATE_PCIE   3
-#define TEGRA_POWERGATE_VDEC   4
-#define TEGRA_POWERGATE_CPU1   9
-#define TEGRA_POWERGATE_CPU2   10
-#define TEGRA_POWERGATE_CPU3   11
-
 static u8 tegra_cpu_domains[] = {
        0xFF,                   /* not available for CPU0 */
        TEGRA_POWERGATE_CPU1,
@@ -166,6 +161,15 @@ int tegra_pmc_cpu_remove_clamping(int cpuid)
        return tegra_pmc_powergate_remove_clamping(id);
 }
 
+void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
+{
+       u32 val;
+
+       val = tegra_pmc_readl(0);
+       val |= 0x10;
+       tegra_pmc_writel(val, 0);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate)
 {
@@ -279,19 +283,17 @@ void tegra_pmc_suspend_init(void)
 #endif
 
 static const struct of_device_id matches[] __initconst = {
+       { .compatible = "nvidia,tegra124-pmc" },
        { .compatible = "nvidia,tegra114-pmc" },
        { .compatible = "nvidia,tegra30-pmc" },
        { .compatible = "nvidia,tegra20-pmc" },
        { }
 };
 
-static void __init tegra_pmc_parse_dt(void)
+void __init tegra_pmc_init_irq(void)
 {
        struct device_node *np;
-       u32 prop;
-       enum tegra_suspend_mode suspend_mode;
-       u32 core_good_time[2] = {0, 0};
-       u32 lp0_vec[2] = {0, 0};
+       u32 val;
 
        np = of_find_matching_node(NULL, matches);
        BUG_ON(!np);
@@ -300,6 +302,26 @@ static void __init tegra_pmc_parse_dt(void)
 
        tegra_pmc_invert_interrupt = of_property_read_bool(np,
                                     "nvidia,invert-interrupt");
+
+       val = tegra_pmc_readl(PMC_CTRL);
+       if (tegra_pmc_invert_interrupt)
+               val |= PMC_CTRL_INTR_LOW;
+       else
+               val &= ~PMC_CTRL_INTR_LOW;
+       tegra_pmc_writel(val, PMC_CTRL);
+}
+
+void __init tegra_pmc_init(void)
+{
+       struct device_node *np;
+       u32 prop;
+       enum tegra_suspend_mode suspend_mode;
+       u32 core_good_time[2] = {0, 0};
+       u32 lp0_vec[2] = {0, 0};
+
+       np = of_find_matching_node(NULL, matches);
+       BUG_ON(!np);
+
        tegra_pclk = of_clk_get_by_name(np, "pclk");
        WARN_ON(IS_ERR(tegra_pclk));
 
@@ -365,17 +387,3 @@ static void __init tegra_pmc_parse_dt(void)
 
        pmc_pm_data.suspend_mode = suspend_mode;
 }
-
-void __init tegra_pmc_init(void)
-{
-       u32 val;
-
-       tegra_pmc_parse_dt();
-
-       val = tegra_pmc_readl(PMC_CTRL);
-       if (tegra_pmc_invert_interrupt)
-               val |= PMC_CTRL_INTR_LOW;
-       else
-               val &= ~PMC_CTRL_INTR_LOW;
-       tegra_pmc_writel(val, PMC_CTRL);
-}
index 549f8c7b762c970530d434c35345c2e2f45472e9..59e19c3442987f420c62fe18e683f08e90e38318 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef __MACH_TEGRA_PMC_H
 #define __MACH_TEGRA_PMC_H
 
+#include <linux/reboot.h>
+
 enum tegra_suspend_mode {
        TEGRA_SUSPEND_NONE = 0,
        TEGRA_SUSPEND_LP2,      /* CPU voltage off */
@@ -39,6 +41,9 @@ bool tegra_pmc_cpu_is_powered(int cpuid);
 int tegra_pmc_cpu_power_on(int cpuid);
 int tegra_pmc_cpu_remove_clamping(int cpuid);
 
+void tegra_pmc_restart(enum reboot_mode mode, const char *cmd);
+
+void tegra_pmc_init_irq(void);
 void tegra_pmc_init(void);
 
 #endif
index f076f0f80fcd325e836061605f5a628efbd05626..85d28e756bb77e8d3b4b66342608e136716288b3 100644 (file)
 
 static int tegra_num_powerdomains;
 static int tegra_num_cpu_domains;
-static u8 *tegra_cpu_domains;
-static u8 tegra30_cpu_domains[] = {
+static const u8 *tegra_cpu_domains;
+
+static const u8 tegra30_cpu_domains[] = {
+       TEGRA_POWERGATE_CPU,
+       TEGRA_POWERGATE_CPU1,
+       TEGRA_POWERGATE_CPU2,
+       TEGRA_POWERGATE_CPU3,
+};
+
+static const u8 tegra114_cpu_domains[] = {
        TEGRA_POWERGATE_CPU0,
        TEGRA_POWERGATE_CPU1,
        TEGRA_POWERGATE_CPU2,
@@ -189,6 +197,11 @@ int __init tegra_powergate_init(void)
                tegra_num_cpu_domains = 4;
                tegra_cpu_domains = tegra30_cpu_domains;
                break;
+       case TEGRA114:
+               tegra_num_powerdomains = 23;
+               tegra_num_cpu_domains = 4;
+               tegra_cpu_domains = tegra114_cpu_domains;
+               break;
        default:
                /* Unknown Tegra variant. Disable powergating */
                tegra_num_powerdomains = 0;
@@ -229,6 +242,27 @@ static const char * const powergate_name_t30[] = {
        [TEGRA_POWERGATE_3D1]   = "3d1",
 };
 
+static const char * const powergate_name_t114[] = {
+       [TEGRA_POWERGATE_CPU]   = "cpu0",
+       [TEGRA_POWERGATE_3D]    = "3d",
+       [TEGRA_POWERGATE_VENC]  = "venc",
+       [TEGRA_POWERGATE_VDEC]  = "vdec",
+       [TEGRA_POWERGATE_MPE]   = "mpe",
+       [TEGRA_POWERGATE_HEG]   = "heg",
+       [TEGRA_POWERGATE_CPU1]  = "cpu1",
+       [TEGRA_POWERGATE_CPU2]  = "cpu2",
+       [TEGRA_POWERGATE_CPU3]  = "cpu3",
+       [TEGRA_POWERGATE_CELP]  = "celp",
+       [TEGRA_POWERGATE_CPU0]  = "cpu0",
+       [TEGRA_POWERGATE_C0NC]  = "c0nc",
+       [TEGRA_POWERGATE_C1NC]  = "c1nc",
+       [TEGRA_POWERGATE_DIS]   = "dis",
+       [TEGRA_POWERGATE_DISB]  = "disb",
+       [TEGRA_POWERGATE_XUSBA] = "xusba",
+       [TEGRA_POWERGATE_XUSBB] = "xusbb",
+       [TEGRA_POWERGATE_XUSBC] = "xusbc",
+};
+
 static int powergate_show(struct seq_file *s, void *data)
 {
        int i;
@@ -236,9 +270,14 @@ static int powergate_show(struct seq_file *s, void *data)
        seq_printf(s, " powergate powered\n");
        seq_printf(s, "------------------\n");
 
-       for (i = 0; i < tegra_num_powerdomains; i++)
+       for (i = 0; i < tegra_num_powerdomains; i++) {
+               if (!powergate_name[i])
+                       continue;
+
                seq_printf(s, " %9s %7s\n", powergate_name[i],
                        tegra_powergate_is_powered(i) ? "yes" : "no");
+       }
+
        return 0;
 }
 
@@ -265,6 +304,9 @@ int __init tegra_powergate_debugfs_init(void)
        case TEGRA30:
                powergate_name = powergate_name_t30;
                break;
+       case TEGRA114:
+               powergate_name = powergate_name_t114;
+               break;
        }
 
        if (powergate_name) {
index f527b2c2dea779be4f8f26d654e14ba3282369ee..8c1ba4fea384b732d3c4724b118304a5dafd55a5 100644 (file)
 ENTRY(tegra_resume)
        check_cpu_part_num 0xc09, r8, r9
        bleq    v7_invalidate_l1
-       blne    tegra_init_l2_for_a15
 
        cpu_id  r0
-       tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
-       cmp     r6, #TEGRA114
-       beq     no_cpu0_chk
-
        cmp     r0, #0                          @ CPU0?
  THUMB(        it      ne )
        bne     cpu_resume                      @ no
-no_cpu0_chk:
 
        /* Are we on Tegra20? */
        cmp     r6, #TEGRA20
@@ -75,7 +69,7 @@ no_cpu0_chk:
 
        mov32   r9, 0xc09
        cmp     r8, r9
-       bne     not_ca9
+       bne     end_ca9_scu_l2_resume
 #ifdef CONFIG_HAVE_ARM_SCU
        /* enable SCU */
        mov32   r0, TEGRA_ARM_PERIF_BASE
@@ -86,7 +80,10 @@ no_cpu0_chk:
 
        /* L2 cache resume & re-enable */
        l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
-not_ca9:
+end_ca9_scu_l2_resume:
+       mov32   r9, 0xc0f
+       cmp     r8, r9
+       bleq    tegra_init_l2_for_a15
 
        b       cpu_resume
 ENDPROC(tegra_resume)
index fd0bbf8a6c948494efaa497facc51f15aaba8f5f..568f5bbf979da4429e677430dd582d2a6c2f9f29 100644 (file)
@@ -82,7 +82,7 @@ void __init tegra_cpu_reset_handler_init(void)
 
 #ifdef CONFIG_PM_SLEEP
        __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
-               TEGRA_IRAM_CODE_AREA;
+               TEGRA_IRAM_LPx_RESUME_AREA;
        __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
                virt_to_phys((void *)tegra_resume);
 #endif
index 5c3bd11c98387da88e5c3eccd36e23eab5d68d78..aaaf3abd2688e85269271d45c2b32eecf5944cb5 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/cp15.h>
 #include <asm/cache.h>
 
+#include "irammap.h"
 #include "sleep.h"
 #include "flowctrl.h"
 
@@ -235,7 +236,7 @@ ENTRY(tegra20_sleep_core_finish)
        mov32   r0, tegra20_tear_down_core
        mov32   r1, tegra20_iram_start
        sub     r0, r0, r1
-       mov32   r1, TEGRA_IRAM_CODE_AREA
+       mov32   r1, TEGRA_IRAM_LPx_RESUME_AREA
        add     r0, r0, r1
 
        mov     pc, r3
@@ -328,7 +329,7 @@ tegra20_iram_start:
  * The physical address of tegra_resume expected to be stored in
  * PMC_SCRATCH41.
  *
- * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA.
+ * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
  */
 ENTRY(tegra20_lp1_reset)
        /*
index 63fa91b5fafb9ad1293ca2d18798324d6fa886db..b16d4a57fa59dd529e2ae97bd8890521bf543fe6 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 
+#include "irammap.h"
 #include "fuse.h"
 #include "sleep.h"
 #include "flowctrl.h"
@@ -262,7 +263,7 @@ ENTRY(tegra30_sleep_core_finish)
        mov32   r0, tegra30_tear_down_core
        mov32   r1, tegra30_iram_start
        sub     r0, r0, r1
-       mov32   r1, TEGRA_IRAM_CODE_AREA
+       mov32   r1, TEGRA_IRAM_LPx_RESUME_AREA
        add     r0, r0, r1
 
        mov     pc, r3
@@ -314,7 +315,7 @@ tegra30_iram_start:
  * The physical address of tegra_resume expected to be stored in
  * PMC_SCRATCH41.
  *
- * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA.
+ * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
  */
 ENTRY(tegra30_lp1_reset)
        /*
@@ -382,7 +383,7 @@ _pll_m_c_x_done:
        add     r1, r1, #LOCK_DELAY
        wait_until r1, r7, r3
 
-       adr     r5, tegra30_sdram_pad_save
+       adr     r5, tegra_sdram_pad_save
 
        ldr     r4, [r5, #0x18]         @ restore CLK_SOURCE_MSELECT
        str     r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
@@ -407,8 +408,12 @@ _pll_m_c_x_done:
        cmp     r10, #TEGRA30
        movweq  r0, #:lower16:TEGRA_EMC_BASE    @ r0 reserved for emc base
        movteq  r0, #:upper16:TEGRA_EMC_BASE
-       movwne  r0, #:lower16:TEGRA_EMC0_BASE
-       movtne  r0, #:upper16:TEGRA_EMC0_BASE
+       cmp     r10, #TEGRA114
+       movweq  r0, #:lower16:TEGRA_EMC0_BASE
+       movteq  r0, #:upper16:TEGRA_EMC0_BASE
+       cmp     r10, #TEGRA124
+       movweq  r0, #:lower16:TEGRA124_EMC_BASE
+       movteq  r0, #:upper16:TEGRA124_EMC_BASE
 
 exit_self_refresh:
        ldr     r1, [r5, #0xC]          @ restore EMC_XM2VTTGENPADCTRL
@@ -537,6 +542,7 @@ tegra30_sdram_pad_address:
        .word   TEGRA_PMC_BASE + PMC_IO_DPD_STATUS                      @0x14
        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT     @0x18
        .word   TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST             @0x1c
+tegra30_sdram_pad_address_end:
 
 tegra114_sdram_pad_address:
        .word   TEGRA_EMC0_BASE + EMC_CFG                               @0x0
@@ -552,16 +558,28 @@ tegra114_sdram_pad_address:
        .word   TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL                 @0x28
        .word   TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL                  @0x2c
        .word   TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2                 @0x30
+tegra114_sdram_pad_adress_end:
+
+tegra124_sdram_pad_address:
+       .word   TEGRA124_EMC_BASE + EMC_CFG                             @0x0
+       .word   TEGRA124_EMC_BASE + EMC_ZCAL_INTERVAL                   @0x4
+       .word   TEGRA124_EMC_BASE + EMC_AUTO_CAL_INTERVAL               @0x8
+       .word   TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL                @0xc
+       .word   TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL2               @0x10
+       .word   TEGRA_PMC_BASE + PMC_IO_DPD_STATUS                      @0x14
+       .word   TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT     @0x18
+       .word   TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST             @0x1c
+tegra124_sdram_pad_address_end:
 
 tegra30_sdram_pad_size:
-       .word   tegra114_sdram_pad_address - tegra30_sdram_pad_address
+       .word   tegra30_sdram_pad_address_end - tegra30_sdram_pad_address
 
 tegra114_sdram_pad_size:
-       .word   tegra30_sdram_pad_size - tegra114_sdram_pad_address
+       .word   tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address
 
-       .type   tegra30_sdram_pad_save, %object
-tegra30_sdram_pad_save:
-       .rept (tegra30_sdram_pad_size - tegra114_sdram_pad_address) / 4
+       .type   tegra_sdram_pad_save, %object
+tegra_sdram_pad_save:
+       .rept (tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address) / 4
        .long   0
        .endr
 
@@ -692,13 +710,18 @@ halted:
  */
 tegra30_sdram_self_refresh:
 
-       adr     r8, tegra30_sdram_pad_save
+       adr     r8, tegra_sdram_pad_save
        tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
        cmp     r10, #TEGRA30
        adreq   r2, tegra30_sdram_pad_address
        ldreq   r3, tegra30_sdram_pad_size
-       adrne   r2, tegra114_sdram_pad_address
-       ldrne   r3, tegra114_sdram_pad_size
+       cmp     r10, #TEGRA114
+       adreq   r2, tegra114_sdram_pad_address
+       ldreq   r3, tegra114_sdram_pad_size
+       cmp     r10, #TEGRA124
+       adreq   r2, tegra124_sdram_pad_address
+       ldreq   r3, tegra30_sdram_pad_size
+
        mov     r9, #0
 
 padsave:
@@ -716,7 +739,10 @@ padsave_done:
 
        cmp     r10, #TEGRA30
        ldreq   r0, =TEGRA_EMC_BASE     @ r0 reserved for emc base addr
-       ldrne   r0, =TEGRA_EMC0_BASE
+       cmp     r10, #TEGRA114
+       ldreq   r0, =TEGRA_EMC0_BASE
+       cmp     r10, #TEGRA124
+       ldreq   r0, =TEGRA124_EMC_BASE
 
 enter_self_refresh:
        cmp     r10, #TEGRA30
index 5b8605547a09113a65daaf65b902d9a6098fe522..ce553d557c31caf1670e50ceadad19c067d2864c 100644 (file)
@@ -16,7 +16,6 @@
  *
  */
 
-#include <linux/clocksource.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/sys_soc.h>
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clk/tegra.h>
+#include <linux/irqchip.h>
 
+#include <asm/hardware/cache-l2x0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/setup.h>
 
+#include "apbio.h"
 #include "board.h"
 #include "common.h"
+#include "cpuidle.h"
 #include "fuse.h"
 #include "iomap.h"
+#include "irq.h"
+#include "pmc.h"
+#include "pm.h"
+#include "reset.h"
+#include "sleep.h"
+
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+u32 tegra_uart_config[4] = {
+       /* Debug UART initialization required */
+       1,
+       /* Debug UART physical address */
+       0,
+       /* Debug UART virtual address */
+       0,
+       /* Scratch space for debug macro */
+       0,
+};
+
+static void __init tegra_init_cache(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+       int ret;
+       void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+       u32 aux_ctrl, cache_type;
+
+       cache_type = readl(p + L2X0_CACHE_TYPE);
+       aux_ctrl = (cache_type & 0x700) << (17-8);
+       aux_ctrl |= 0x7C400001;
+
+       ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
+       if (!ret)
+               l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
+#endif
+}
+
+static void __init tegra_init_early(void)
+{
+       tegra_cpu_reset_handler_init();
+       tegra_apb_io_init();
+       tegra_init_fuse();
+       tegra_init_cache();
+       tegra_powergate_init();
+       tegra_hotplug_init();
+}
+
+static void __init tegra_dt_init_irq(void)
+{
+       tegra_pmc_init_irq();
+       tegra_init_irq();
+       irqchip_init();
+       tegra_legacy_irq_syscore_init();
+}
 
 static void __init tegra_dt_init(void)
 {
@@ -51,6 +112,8 @@ static void __init tegra_dt_init(void)
        struct soc_device *soc_dev;
        struct device *parent = NULL;
 
+       tegra_pmc_init();
+
        tegra_clocks_apply_init_table();
 
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
@@ -97,7 +160,9 @@ static void __init tegra_dt_init_late(void)
 {
        int i;
 
-       tegra_init_late();
+       tegra_init_suspend();
+       tegra_cpuidle_init();
+       tegra_powergate_debugfs_init();
 
        for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
                if (of_machine_is_compatible(board_init_funcs[i].machine)) {
@@ -108,6 +173,7 @@ static void __init tegra_dt_init_late(void)
 }
 
 static const char * const tegra_dt_board_compat[] = {
+       "nvidia,tegra124",
        "nvidia,tegra114",
        "nvidia,tegra30",
        "nvidia,tegra20",
@@ -119,9 +185,8 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
        .smp            = smp_ops(tegra_smp_ops),
        .init_early     = tegra_init_early,
        .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
        .init_machine   = tegra_dt_init,
        .init_late      = tegra_dt_init_late,
-       .restart        = tegra_assert_system_reset,
+       .restart        = tegra_pmc_restart,
        .dt_compat      = tegra_dt_board_compat,
 MACHINE_END
index a1659863bfd5cb650338d6d8919ab0b145da1d57..8e23071bd1b34ff2a47f729c60721a6fa4a9ec5b 100644 (file)
@@ -5,7 +5,6 @@ config ARCH_U300
        select ARM_AMBA
        select ARM_PATCH_PHYS_VIRT
        select ARM_VIC
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select CLKSRC_OF
        select COMMON_CLK
index 99a28d62829742d9103764c47abcb5ff24894fbf..c67f8ad5ccd5d89eb087fbbf3a4ff75cc5039775 100644 (file)
@@ -1,37 +1,32 @@
 config ARCH_U8500
        bool "ST-Ericsson U8500 Series" if ARCH_MULTI_V7
        depends on MMU
+       select AB8500_CORE
+       select ABX500_CORE
        select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
-       select CLKDEV_LOOKUP
+       select ARM_ERRATA_754322
+       select ARM_ERRATA_764369 if SMP
+       select ARM_GIC
+       select CACHE_L2X0
+       select CLKSRC_NOMADIK_MTU
+       select COMMON_CLK
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
+       select PINCTRL
+       select PINCTRL_ABX500
+       select PINCTRL_NOMADIK
+       select PL310_ERRATA_753970 if CACHE_PL310
        help
          Support for ST-Ericsson's Ux500 architecture
 
 if ARCH_U8500
 
-config UX500_SOC_COMMON
-       bool
-       default y
-       select ABX500_CORE
-       select AB8500_CORE
-       select ARM_ERRATA_754322
-       select ARM_ERRATA_764369 if SMP
-       select ARM_GIC
-       select CACHE_L2X0
-       select CLKSRC_NOMADIK_MTU
-       select COMMON_CLK
-       select PINCTRL
-       select PINCTRL_NOMADIK
-       select PINCTRL_ABX500
-       select PL310_ERRATA_753970 if CACHE_PL310
-
 config UX500_SOC_DB8500
        bool
        select CPU_FREQ_TABLE if CPU_FREQ
index fe1f3e26b88b114b2c47ecb082b358a6a220bea7..616b96e86ad4fb067395ad4d2411cb8befcb92b8 100644 (file)
@@ -2,14 +2,11 @@
 # Makefile for the linux kernel, U8500 machine.
 #
 
-obj-y                          := cpu.o devices.o devices-common.o \
-                                  id.o usb.o timer.o pm.o
+obj-y                          := cpu.o devices.o id.o timer.o pm.o
 obj-$(CONFIG_CACHE_L2X0)       += cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
 obj-$(CONFIG_MACH_MOP500)      += board-mop500.o board-mop500-sdi.o \
                                board-mop500-regulators.o \
-                               board-mop500-uib.o board-mop500-stuib.o \
-                               board-mop500-u8500uib.o \
                                board-mop500-pins.o \
                                board-mop500-audio.o
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
index ec0807247e60cb1a40d1f4f8dbdb23b266932b31..154e15f59702c1010af74cce8fed51077c78e111 100644 (file)
@@ -68,40 +68,6 @@ static struct stedma40_chan_cfg msp2_dma_tx = {
        .phy_channel = 1,
 };
 
-static struct platform_device *db8500_add_msp_i2s(struct device *parent,
-                       int id,
-                       resource_size_t base, int irq,
-                       struct msp_i2s_platform_data *pdata)
-{
-       struct platform_device *pdev;
-       struct resource res[] = {
-               DEFINE_RES_MEM(base, SZ_4K),
-               DEFINE_RES_IRQ(irq),
-       };
-
-       pr_info("Register platform-device 'ux500-msp-i2s', id %d, irq %d\n",
-               id, irq);
-       pdev = platform_device_register_resndata(parent, "ux500-msp-i2s", id,
-                                               res, ARRAY_SIZE(res),
-                                               pdata, sizeof(*pdata));
-       if (!pdev) {
-               pr_err("Failed to register platform-device 'ux500-msp-i2s.%d'!\n",
-                       id);
-               return NULL;
-       }
-
-       return pdev;
-}
-
-/* Platform device for ASoC MOP500 machine */
-static struct platform_device snd_soc_mop500 = {
-       .name = "snd-soc-mop500",
-       .id = 0,
-       .dev = {
-               .platform_data = NULL,
-       },
-};
-
 struct msp_i2s_platform_data msp2_platform_data = {
        .id = MSP_I2S_2,
        .msp_i2s_dma_rx = &msp2_dma_rx,
@@ -113,19 +79,3 @@ struct msp_i2s_platform_data msp3_platform_data = {
        .msp_i2s_dma_rx = &msp1_dma_rx,
        .msp_i2s_dma_tx = NULL,
 };
-
-void mop500_audio_init(struct device *parent)
-{
-       pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__);
-       platform_device_register(&snd_soc_mop500);
-
-       pr_info("Initialize MSP I2S-devices.\n");
-       db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
-                          &msp0_platform_data);
-       db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
-                          &msp1_platform_data);
-       db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2,
-                          &msp2_platform_data);
-       db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
-                          &msp3_platform_data);
-}
index b3e61a38e5c8aee776c5eff883b770d80529fe10..26600a1c53190ad3ae3724456a17dd7b8a35009d 100644 (file)
@@ -65,18 +65,6 @@ struct mmci_platform_data mop500_sdi0_data = {
 #endif
 };
 
-static void sdi0_configure(struct device *parent)
-{
-       /* Add the device, force v2 to subrevision 1 */
-       db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
-}
-
-void mop500_sdi_tc35892_init(struct device *parent)
-{
-       mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
-       sdi0_configure(parent);
-}
-
 /*
  * SDI1 (SDIO WLAN)
  */
@@ -178,42 +166,3 @@ struct mmci_platform_data mop500_sdi4_data = {
        .dma_tx_param   = &mop500_sdi4_dma_cfg_tx,
 #endif
 };
-
-void __init mop500_sdi_init(struct device *parent)
-{
-       /* PoP:ed eMMC */
-       db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
-       /* On-board eMMC */
-       db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
-
-       /*
-        * On boards with the TC35892 GPIO expander, sdi0 will finally
-        * be added when the TC35892 initializes and calls
-        * mop500_sdi_tc35892_init() above.
-        */
-}
-
-void __init snowball_sdi_init(struct device *parent)
-{
-       /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
-       mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
-       /* On-board eMMC */
-       db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
-       /* External Micro SD slot */
-       mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
-       mop500_sdi0_data.cd_invert = true;
-       sdi0_configure(parent);
-}
-
-void __init hrefv60_sdi_init(struct device *parent)
-{
-       /* PoP:ed eMMC */
-       db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
-       /* On-board eMMC */
-       db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
-       /* External Micro SD slot */
-       mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
-       sdi0_configure(parent);
-       /* WLAN SDIO channel */
-       db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
-}
diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c
deleted file mode 100644 (file)
index 7e1f294..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License terms: GNU General Public License (GPL), version 2
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mfd/stmpe.h>
-#include <linux/input/bu21013.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/input/matrix_keypad.h>
-#include <asm/mach-types.h>
-
-#include "board-mop500.h"
-
-/* STMPE/SKE keypad use this key layout */
-static const unsigned int mop500_keymap[] = {
-       KEY(2, 5, KEY_END),
-       KEY(4, 1, KEY_POWER),
-       KEY(3, 5, KEY_VOLUMEDOWN),
-       KEY(1, 3, KEY_3),
-       KEY(5, 2, KEY_RIGHT),
-       KEY(5, 0, KEY_9),
-
-       KEY(0, 5, KEY_MENU),
-       KEY(7, 6, KEY_ENTER),
-       KEY(4, 5, KEY_0),
-       KEY(6, 7, KEY_2),
-       KEY(3, 4, KEY_UP),
-       KEY(3, 3, KEY_DOWN),
-
-       KEY(6, 4, KEY_SEND),
-       KEY(6, 2, KEY_BACK),
-       KEY(4, 2, KEY_VOLUMEUP),
-       KEY(5, 5, KEY_1),
-       KEY(4, 3, KEY_LEFT),
-       KEY(3, 2, KEY_7),
-};
-
-static const struct matrix_keymap_data mop500_keymap_data = {
-       .keymap         = mop500_keymap,
-       .keymap_size    = ARRAY_SIZE(mop500_keymap),
-};
-/*
- * STMPE1601
- */
-static struct stmpe_keypad_platform_data stmpe1601_keypad_data = {
-       .debounce_ms    = 64,
-       .scan_count     = 8,
-       .no_autorepeat  = true,
-       .keymap_data    = &mop500_keymap_data,
-};
-
-static struct stmpe_platform_data stmpe1601_data = {
-       .id             = 1,
-       .blocks         = STMPE_BLOCK_KEYPAD,
-       .irq_trigger    = IRQF_TRIGGER_FALLING,
-       .irq_base       = MOP500_STMPE1601_IRQ(0),
-       .keypad         = &stmpe1601_keypad_data,
-       .autosleep      = true,
-       .autosleep_timeout = 1024,
-};
-
-static struct i2c_board_info __initdata mop500_i2c0_devices_stuib[] = {
-       {
-               I2C_BOARD_INFO("stmpe1601", 0x40),
-               .irq = NOMADIK_GPIO_TO_IRQ(218),
-               .platform_data = &stmpe1601_data,
-               .flags = I2C_CLIENT_WAKE,
-       },
-};
-
-/*
- * BU21013 ROHM touchscreen interface on the STUIBs
- */
-
-#define TOUCH_GPIO_PIN  84
-
-#define TOUCH_XMAX     384
-#define TOUCH_YMAX     704
-
-#define PRCMU_CLOCK_OCR                0x1CC
-#define TSC_EXT_CLOCK_9_6MHZ   0x840000
-
-static struct bu21013_platform_device tsc_plat_device = {
-       .touch_pin = TOUCH_GPIO_PIN,
-       .touch_x_max = TOUCH_XMAX,
-       .touch_y_max = TOUCH_YMAX,
-       .ext_clk = false,
-       .x_flip = false,
-       .y_flip = true,
-};
-
-static struct i2c_board_info __initdata u8500_i2c3_devices_stuib[] = {
-       {
-               I2C_BOARD_INFO("bu21013_tp", 0x5C),
-               .platform_data = &tsc_plat_device,
-       },
-       {
-               I2C_BOARD_INFO("bu21013_tp", 0x5D),
-               .platform_data = &tsc_plat_device,
-       },
-};
-
-void __init mop500_stuib_init(void)
-{
-       if (machine_is_hrefv60())
-               tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO;
-       else
-               tsc_plat_device.cs_pin = GPIO_BU21013_CS;
-
-       mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib,
-                       ARRAY_SIZE(mop500_i2c0_devices_stuib));
-
-       mop500_uib_i2c_add(3, u8500_i2c3_devices_stuib,
-                       ARRAY_SIZE(u8500_i2c3_devices_stuib));
-}
diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c
deleted file mode 100644 (file)
index d397c19..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Board data for the U8500 UIB, also known as the New UIB
- * License terms: GNU General Public License (GPL), version 2
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/tc3589x.h>
-#include <linux/input/matrix_keypad.h>
-
-#include "irqs.h"
-
-#include "board-mop500.h"
-
-static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = {
-       {
-               I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B),
-               .irq = NOMADIK_GPIO_TO_IRQ(84),
-       },
-};
-
-/*
- * TC35893
- */
-static const unsigned int u8500_keymap[] = {
-       KEY(3, 1, KEY_END),
-       KEY(4, 1, KEY_POWER),
-       KEY(6, 4, KEY_VOLUMEDOWN),
-       KEY(4, 2, KEY_EMAIL),
-       KEY(3, 3, KEY_RIGHT),
-       KEY(2, 5, KEY_BACKSPACE),
-
-       KEY(6, 7, KEY_MENU),
-       KEY(5, 0, KEY_ENTER),
-       KEY(4, 3, KEY_0),
-       KEY(3, 4, KEY_DOT),
-       KEY(5, 2, KEY_UP),
-       KEY(3, 5, KEY_DOWN),
-
-       KEY(4, 5, KEY_SEND),
-       KEY(0, 5, KEY_BACK),
-       KEY(6, 2, KEY_VOLUMEUP),
-       KEY(1, 3, KEY_SPACE),
-       KEY(7, 6, KEY_LEFT),
-       KEY(5, 5, KEY_SEARCH),
-};
-
-static struct matrix_keymap_data u8500_keymap_data = {
-       .keymap         = u8500_keymap,
-       .keymap_size    = ARRAY_SIZE(u8500_keymap),
-};
-
-static struct tc3589x_keypad_platform_data tc35893_data = {
-       .krow = TC_KPD_ROWS,
-       .kcol = TC_KPD_COLUMNS,
-       .debounce_period = TC_KPD_DEBOUNCE_PERIOD,
-       .settle_time = TC_KPD_SETTLE_TIME,
-       .irqtype = IRQF_TRIGGER_FALLING,
-       .enable_wakeup = true,
-       .keymap_data    = &u8500_keymap_data,
-       .no_autorepeat  = true,
-};
-
-static struct tc3589x_platform_data tc3589x_keypad_data = {
-       .block = TC3589x_BLOCK_KEYPAD,
-       .keypad = &tc35893_data,
-       .irq_base = MOP500_EGPIO_IRQ_BASE,
-};
-
-static struct i2c_board_info __initdata mop500_i2c0_devices_u8500[] = {
-       {
-               I2C_BOARD_INFO("tc3589x", 0x44),
-               .platform_data = &tc3589x_keypad_data,
-               .irq = NOMADIK_GPIO_TO_IRQ(218),
-               .flags = I2C_CLIENT_WAKE,
-       },
-};
-
-
-void __init mop500_u8500uib_init(void)
-{
-       mop500_uib_i2c_add(3, mop500_i2c3_devices_u8500,
-                       ARRAY_SIZE(mop500_i2c3_devices_u8500));
-
-       mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500,
-                       ARRAY_SIZE(mop500_i2c0_devices_u8500));
-
-}
diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c
deleted file mode 100644 (file)
index bdaa422..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- * License terms: GNU General Public License (GPL), version 2
- */
-
-#define pr_fmt(fmt)    "mop500-uib: " fmt
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-
-#include "board-mop500.h"
-#include "id.h"
-
-enum mop500_uib {
-       STUIB,
-       U8500UIB,
-};
-
-struct uib {
-       const char *name;
-       const char *option;
-       void (*init)(void);
-};
-
-static struct uib __initdata mop500_uibs[] = {
-       [STUIB] = {
-               .name   = "ST-UIB",
-               .option = "stuib",
-               .init   = mop500_stuib_init,
-       },
-       [U8500UIB] = {
-               .name   = "U8500-UIB",
-               .option = "u8500uib",
-               .init   = mop500_u8500uib_init,
-       },
-};
-
-static struct uib *mop500_uib;
-
-static int __init mop500_uib_setup(char *str)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mop500_uibs); i++) {
-               struct uib *uib = &mop500_uibs[i];
-
-               if (!strcmp(str, uib->option)) {
-                       mop500_uib = uib;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(mop500_uibs))
-               pr_err("invalid uib= option (%s)\n", str);
-
-       return 1;
-}
-__setup("uib=", mop500_uib_setup);
-
-/*
- * The UIBs are detected after the I2C host controllers are registered, so
- * i2c_register_board_info() can't be used.
- */
-void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
-               unsigned n)
-{
-       struct i2c_adapter *adap;
-       struct i2c_client *client;
-       int i;
-
-       adap = i2c_get_adapter(busnum);
-       if (!adap) {
-               pr_err("failed to get adapter i2c%d\n", busnum);
-               return;
-       }
-
-       for (i = 0; i < n; i++) {
-               client = i2c_new_device(adap, &info[i]);
-               if (!client)
-                       pr_err("failed to register %s to i2c%d\n",
-                                       info[i].type, busnum);
-       }
-
-       i2c_put_adapter(adap);
-}
-
-static void __init __mop500_uib_init(struct uib *uib, const char *why)
-{
-       pr_info("%s (%s)\n", uib->name, why);
-       uib->init();
-}
-
-/*
- * Detect the UIB attached based on the presence or absence of i2c devices.
- */
-int __init mop500_uib_init(void)
-{
-       struct uib *uib = mop500_uib;
-       struct i2c_adapter *i2c0;
-       int ret;
-
-       if (!cpu_is_u8500_family())
-               return -ENODEV;
-
-       if (uib) {
-               __mop500_uib_init(uib, "from uib= boot argument");
-               return 0;
-       }
-
-       i2c0 = i2c_get_adapter(0);
-       if (!i2c0) {
-               __mop500_uib_init(&mop500_uibs[STUIB],
-                               "fallback, could not get i2c0");
-               return -ENODEV;
-       }
-
-       /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */
-       ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0,
-                       I2C_SMBUS_QUICK, NULL);
-       i2c_put_adapter(i2c0);
-
-       if (ret == 0)
-               uib = &mop500_uibs[U8500UIB];
-       else
-               uib = &mop500_uibs[STUIB];
-
-       __mop500_uib_init(uib, "detected");
-
-       return 0;
-}
index ad0806eff7624da302513909ab41a3af400ed820..514d40b625a4604c16c179b9562aa54b84f4d27e 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/platform_data/i2c-nomadik.h>
 #include <linux/platform_data/db8500_thermal.h>
-#include <linux/gpio.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
-#include <linux/amba/serial.h>
-#include <linux/spi/spi.h>
 #include <linux/mfd/abx500/ab8500.h>
 #include <linux/regulator/ab8500.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/driver.h>
-#include <linux/regulator/gpio-regulator.h>
-#include <linux/mfd/tc3589x.h>
 #include <linux/mfd/tps6105x.h>
-#include <linux/mfd/abx500/ab8500-gpio.h>
-#include <linux/mfd/abx500/ab8500-codec.h>
 #include <linux/platform_data/leds-lp55xx.h>
 #include <linux/input.h>
-#include <linux/smsc911x.h>
-#include <linux/gpio_keys.h>
 #include <linux/delay.h>
 #include <linux/leds.h>
 #include <linux/pinctrl/consumer.h>
@@ -46,7 +35,6 @@
 #include "setup.h"
 #include "devices.h"
 #include "irqs.h"
-#include <linux/platform_data/crypto-ux500.h>
 
 #include "ste-dma40-db8500.h"
 #include "db8500-regs.h"
 #include "board-mop500.h"
 #include "board-mop500-regulators.h"
 
-static struct gpio_led snowball_led_array[] = {
-       {
-               .name = "user_led",
-               .default_trigger = "heartbeat",
-               .gpio = 142,
-       },
-};
-
-static struct gpio_led_platform_data snowball_led_data = {
-       .leds = snowball_led_array,
-       .num_leds = ARRAY_SIZE(snowball_led_array),
-};
-
-static struct platform_device snowball_led_dev = {
-       .name = "leds-gpio",
-       .dev = {
-               .platform_data = &snowball_led_data,
-       },
-};
-
-static struct fixed_voltage_config snowball_gpio_en_3v3_data = {
-       .supply_name            = "EN-3V3",
-       .gpio                   = SNOWBALL_EN_3V3_ETH_GPIO,
-       .microvolts             = 3300000,
-       .enable_high            = 1,
-       .init_data              = &gpio_en_3v3_regulator,
-       .startup_delay          = 5000, /* 1200us */
-};
-
-static struct platform_device snowball_gpio_en_3v3_regulator_dev = {
-       .name   = "reg-fixed-voltage",
-       .id     = 1,
-       .dev    = {
-               .platform_data  = &snowball_gpio_en_3v3_data,
-       },
-};
-
-/* Dynamically populated. */
-static struct gpio sdi0_reg_gpios[] = {
-       { 0, GPIOF_OUT_INIT_LOW, "mmci_vsel" },
-};
-
-static struct gpio_regulator_state sdi0_reg_states[] = {
-       { .value = 2900000, .gpios = (0 << 0) },
-       { .value = 1800000, .gpios = (1 << 0) },
-};
-
-static struct gpio_regulator_config sdi0_reg_info = {
-       .supply_name            = "ext-mmc-level-shifter",
-       .gpios                  = sdi0_reg_gpios,
-       .nr_gpios               = ARRAY_SIZE(sdi0_reg_gpios),
-       .states                 = sdi0_reg_states,
-       .nr_states              = ARRAY_SIZE(sdi0_reg_states),
-       .type                   = REGULATOR_VOLTAGE,
-       .enable_high            = 1,
-       .enabled_at_boot        = 0,
-       .init_data              = &sdi0_reg_init_data,
-       .startup_delay          = 100,
-};
-
-static struct platform_device sdi0_regulator = {
-       .name = "gpio-regulator",
-       .id   = -1,
-       .dev  = {
-               .platform_data = &sdi0_reg_info,
-       },
-};
-
-static struct abx500_gpio_platform_data ab8500_gpio_pdata = {
-       .gpio_base              = MOP500_AB8500_PIN_GPIO(1),
-};
-
-/* ab8500-codec */
-static struct ab8500_codec_platform_data ab8500_codec_pdata = {
-       .amics =  {
-               .mic1_type = AMIC_TYPE_DIFFERENTIAL,
-               .mic2_type = AMIC_TYPE_DIFFERENTIAL,
-               .mic1a_micbias = AMIC_MICBIAS_VAMIC1,
-               .mic1b_micbias = AMIC_MICBIAS_VAMIC1,
-               .mic2_micbias = AMIC_MICBIAS_VAMIC2
-       },
-       .ear_cmv = EAR_CMV_0_95V
-};
-
-static struct gpio_keys_button snowball_key_array[] = {
-       {
-               .gpio           = 32,
-               .type           = EV_KEY,
-               .code           = KEY_1,
-               .desc           = "userpb",
-               .active_low     = 1,
-               .debounce_interval = 50,
-               .wakeup         = 1,
-       },
-       {
-               .gpio           = 151,
-               .type           = EV_KEY,
-               .code           = KEY_2,
-               .desc           = "extkb1",
-               .active_low     = 1,
-               .debounce_interval = 50,
-               .wakeup         = 1,
-       },
-       {
-               .gpio           = 152,
-               .type           = EV_KEY,
-               .code           = KEY_3,
-               .desc           = "extkb2",
-               .active_low     = 1,
-               .debounce_interval = 50,
-               .wakeup         = 1,
-       },
-       {
-               .gpio           = 161,
-               .type           = EV_KEY,
-               .code           = KEY_4,
-               .desc           = "extkb3",
-               .active_low     = 1,
-               .debounce_interval = 50,
-               .wakeup         = 1,
-       },
-       {
-               .gpio           = 162,
-               .type           = EV_KEY,
-               .code           = KEY_5,
-               .desc           = "extkb4",
-               .active_low     = 1,
-               .debounce_interval = 50,
-               .wakeup         = 1,
-       },
-};
-
-static struct gpio_keys_platform_data snowball_key_data = {
-       .buttons        = snowball_key_array,
-       .nbuttons       = ARRAY_SIZE(snowball_key_array),
-};
-
-static struct platform_device snowball_key_dev = {
-       .name           = "gpio-keys",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &snowball_key_data,
-       }
-};
-
-static struct smsc911x_platform_config snowball_sbnet_cfg = {
-       .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
-       .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
-       .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
-       .shift = 1,
-};
-
-static struct resource sbnet_res[] = {
-       {
-               .name = "smsc911x-memory",
-               .start = (0x5000 << 16),
-               .end  =  (0x5000 << 16) + 0xffff,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .start = NOMADIK_GPIO_TO_IRQ(140),
-               .end = NOMADIK_GPIO_TO_IRQ(140),
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-       },
-};
-
-static struct platform_device snowball_sbnet_dev = {
-       .name           = "smsc911x",
-       .num_resources  = ARRAY_SIZE(sbnet_res),
-       .resource       = sbnet_res,
-       .dev            = {
-               .platform_data = &snowball_sbnet_cfg,
-       },
-};
-
 struct ab8500_platform_data ab8500_platdata = {
        .irq_base       = MOP500_AB8500_IRQ_BASE,
        .regulator      = &ab8500_regulator_plat_data,
-       .gpio           = &ab8500_gpio_pdata,
-       .codec          = &ab8500_codec_pdata,
-};
-
-static struct platform_device u8500_cpufreq_cooling_device = {
-       .name           = "db8500-cpufreq-cooling",
-};
-
-/*
- * TPS61052
- */
-
-static struct tps6105x_platform_data mop500_tps61052_data = {
-       .mode = TPS6105X_MODE_VOLTAGE,
-       .regulator_data = &tps61052_regulator,
-};
-
-/*
- * TC35892
- */
-
-static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
-{
-       struct device *parent = NULL;
-#if 0
-       /* FIXME: Is the sdi actually part of tc3589x? */
-       parent = tc3589x->dev;
-#endif
-       mop500_sdi_tc35892_init(parent);
-}
-
-static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
-       .gpio_base      = MOP500_EGPIO(0),
-       .setup          = mop500_tc35892_init,
-};
-
-static struct tc3589x_platform_data mop500_tc35892_data = {
-       .block          = TC3589x_BLOCK_GPIO,
-       .gpio           = &mop500_tc35892_gpio_data,
-       .irq_base       = MOP500_EGPIO_IRQ_BASE,
-};
-
-static struct lp55xx_led_config lp5521_pri_led[] = {
-       [0] = {
-              .chan_nr = 0,
-              .led_current = 0x2f,
-              .max_current = 0x5f,
-       },
-       [1] = {
-              .chan_nr = 1,
-              .led_current = 0x2f,
-              .max_current = 0x5f,
-       },
-       [2] = {
-              .chan_nr = 2,
-              .led_current = 0x2f,
-              .max_current = 0x5f,
-       },
-};
-
-static struct lp55xx_platform_data __initdata lp5521_pri_data = {
-       .label = "lp5521_pri",
-       .led_config     = &lp5521_pri_led[0],
-       .num_channels   = 3,
-       .clock_mode     = LP55XX_CLOCK_EXT,
-};
-
-static struct lp55xx_led_config lp5521_sec_led[] = {
-       [0] = {
-              .chan_nr = 0,
-              .led_current = 0x2f,
-              .max_current = 0x5f,
-       },
-       [1] = {
-              .chan_nr = 1,
-              .led_current = 0x2f,
-              .max_current = 0x5f,
-       },
-       [2] = {
-              .chan_nr = 2,
-              .led_current = 0x2f,
-              .max_current = 0x5f,
-       },
-};
-
-static struct lp55xx_platform_data __initdata lp5521_sec_data = {
-       .label = "lp5521_sec",
-       .led_config     = &lp5521_sec_led[0],
-       .num_channels   = 3,
-       .clock_mode     = LP55XX_CLOCK_EXT,
-};
-
-/* I2C0 devices only available on the first HREF/MOP500 */
-static struct i2c_board_info __initdata mop500_i2c0_devices[] = {
-       {
-               I2C_BOARD_INFO("tc3589x", 0x42),
-               .irq            = NOMADIK_GPIO_TO_IRQ(217),
-               .platform_data  = &mop500_tc35892_data,
-       },
-       {
-               I2C_BOARD_INFO("tps61052", 0x33),
-               .platform_data  = &mop500_tps61052_data,
-       },
-};
-
-static struct i2c_board_info __initdata mop500_i2c2_devices[] = {
-       {
-               /* lp5521 LED driver, 1st device */
-               I2C_BOARD_INFO("lp5521", 0x33),
-               .platform_data = &lp5521_pri_data,
-       },
-       {
-               /* lp5521 LED driver, 2st device */
-               I2C_BOARD_INFO("lp5521", 0x34),
-               .platform_data = &lp5521_sec_data,
-       },
-       {
-               /* Light sensor Rohm BH1780GLI */
-               I2C_BOARD_INFO("bh1780", 0x29),
-       },
-};
-
-static int __init mop500_i2c_board_init(void)
-{
-       if (machine_is_u8500())
-               mop500_uib_i2c_add(0, mop500_i2c0_devices,
-                                  ARRAY_SIZE(mop500_i2c0_devices));
-       mop500_uib_i2c_add(2, mop500_i2c2_devices,
-                          ARRAY_SIZE(mop500_i2c2_devices));
-       return 0;
-}
-device_initcall(mop500_i2c_board_init);
-
-static void __init mop500_i2c_init(struct device *parent)
-{
-       db8500_add_i2c0(parent, NULL);
-       db8500_add_i2c1(parent, NULL);
-       db8500_add_i2c2(parent, NULL);
-       db8500_add_i2c3(parent, NULL);
-}
-
-static struct gpio_keys_button mop500_gpio_keys[] = {
-       {
-               .desc                   = "SFH7741 Proximity Sensor",
-               .type                   = EV_SW,
-               .code                   = SW_FRONT_PROXIMITY,
-               .active_low             = 0,
-               .can_disable            = 1,
-       }
-};
-
-static struct regulator *prox_regulator;
-static int mop500_prox_activate(struct device *dev);
-static void mop500_prox_deactivate(struct device *dev);
-
-static struct gpio_keys_platform_data mop500_gpio_keys_data = {
-       .buttons        = mop500_gpio_keys,
-       .nbuttons       = ARRAY_SIZE(mop500_gpio_keys),
-       .enable         = mop500_prox_activate,
-       .disable        = mop500_prox_deactivate,
-};
-
-static struct platform_device mop500_gpio_keys_device = {
-       .name   = "gpio-keys",
-       .id     = 0,
-       .dev    = {
-               .platform_data  = &mop500_gpio_keys_data,
-       },
-};
-
-static int mop500_prox_activate(struct device *dev)
-{
-       prox_regulator = regulator_get(&mop500_gpio_keys_device.dev,
-                                               "vcc");
-       if (IS_ERR(prox_regulator)) {
-               dev_err(&mop500_gpio_keys_device.dev,
-                       "no regulator\n");
-               return PTR_ERR(prox_regulator);
-       }
-
-       return regulator_enable(prox_regulator);
-}
-
-static void mop500_prox_deactivate(struct device *dev)
-{
-       regulator_disable(prox_regulator);
-       regulator_put(prox_regulator);
-}
-
-static struct cryp_platform_data u8500_cryp1_platform_data = {
-               .mem_to_engine = {
-                               .dir = DMA_MEM_TO_DEV,
-                               .dev_type = DB8500_DMA_DEV48_CAC1,
-                               .mode = STEDMA40_MODE_LOGICAL,
-               },
-               .engine_to_mem = {
-                               .dir = DMA_DEV_TO_MEM,
-                               .dev_type = DB8500_DMA_DEV48_CAC1,
-                               .mode = STEDMA40_MODE_LOGICAL,
-               }
-};
-
-static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = {
-               .dir = DMA_MEM_TO_DEV,
-               .dev_type = DB8500_DMA_DEV50_HAC1_TX,
-               .mode = STEDMA40_MODE_LOGICAL,
-};
-
-static struct hash_platform_data u8500_hash1_platform_data = {
-               .mem_to_engine = &u8500_hash_dma_cfg_tx,
-               .dma_filter = stedma40_filter,
-};
-
-/* add any platform devices here - TODO */
-static struct platform_device *mop500_platform_devs[] __initdata = {
-       &mop500_gpio_keys_device,
-       &sdi0_regulator,
 };
 
 #ifdef CONFIG_STE_DMA40
@@ -480,236 +76,3 @@ struct pl022_ssp_controller ssp0_plat = {
         */
        .num_chipselect = 5,
 };
-
-static void __init mop500_spi_init(struct device *parent)
-{
-       db8500_add_ssp0(parent, &ssp0_plat);
-}
-
-#ifdef CONFIG_STE_DMA40
-static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
-       .mode = STEDMA40_MODE_LOGICAL,
-       .dir = DMA_DEV_TO_MEM,
-       .dev_type = DB8500_DMA_DEV13_UART0,
-};
-
-static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
-       .mode = STEDMA40_MODE_LOGICAL,
-       .dir = DMA_MEM_TO_DEV,
-       .dev_type = DB8500_DMA_DEV13_UART0,
-};
-
-static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
-       .mode = STEDMA40_MODE_LOGICAL,
-       .dir = DMA_DEV_TO_MEM,
-       .dev_type = DB8500_DMA_DEV12_UART1,
-};
-
-static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
-       .mode = STEDMA40_MODE_LOGICAL,
-       .dir = DMA_MEM_TO_DEV,
-       .dev_type = DB8500_DMA_DEV12_UART1,
-};
-
-static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
-       .mode = STEDMA40_MODE_LOGICAL,
-       .dir = DMA_DEV_TO_MEM,
-       .dev_type = DB8500_DMA_DEV11_UART2,
-};
-
-static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
-       .mode = STEDMA40_MODE_LOGICAL,
-       .dir = DMA_MEM_TO_DEV,
-       .dev_type = DB8500_DMA_DEV11_UART2,
-};
-#endif
-
-struct amba_pl011_data uart0_plat = {
-#ifdef CONFIG_STE_DMA40
-       .dma_filter = stedma40_filter,
-       .dma_rx_param = &uart0_dma_cfg_rx,
-       .dma_tx_param = &uart0_dma_cfg_tx,
-#endif
-};
-
-struct amba_pl011_data uart1_plat = {
-#ifdef CONFIG_STE_DMA40
-       .dma_filter = stedma40_filter,
-       .dma_rx_param = &uart1_dma_cfg_rx,
-       .dma_tx_param = &uart1_dma_cfg_tx,
-#endif
-};
-
-struct amba_pl011_data uart2_plat = {
-#ifdef CONFIG_STE_DMA40
-       .dma_filter = stedma40_filter,
-       .dma_rx_param = &uart2_dma_cfg_rx,
-       .dma_tx_param = &uart2_dma_cfg_tx,
-#endif
-};
-
-static void __init mop500_uart_init(struct device *parent)
-{
-       db8500_add_uart0(parent, &uart0_plat);
-       db8500_add_uart1(parent, &uart1_plat);
-       db8500_add_uart2(parent, &uart2_plat);
-}
-
-static void __init u8500_cryp1_hash1_init(struct device *parent)
-{
-       db8500_add_cryp1(parent, &u8500_cryp1_platform_data);
-       db8500_add_hash1(parent, &u8500_hash1_platform_data);
-}
-
-static struct platform_device *snowball_platform_devs[] __initdata = {
-       &snowball_led_dev,
-       &snowball_key_dev,
-       &snowball_sbnet_dev,
-       &snowball_gpio_en_3v3_regulator_dev,
-       &u8500_cpufreq_cooling_device,
-       &sdi0_regulator,
-};
-
-static void __init mop500_init_machine(void)
-{
-       struct device *parent = NULL;
-       int i;
-
-       platform_device_register(&db8500_prcmu_device);
-       mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
-
-       sdi0_reg_info.enable_gpio = GPIO_SDMMC_EN;
-       sdi0_reg_info.gpios[0].gpio = GPIO_SDMMC_1V8_3V_SEL;
-
-       mop500_pinmaps_init();
-       parent = u8500_init_devices();
-
-       for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
-               mop500_platform_devs[i]->dev.parent = parent;
-
-       platform_add_devices(mop500_platform_devs,
-                       ARRAY_SIZE(mop500_platform_devs));
-
-       mop500_i2c_init(parent);
-       mop500_sdi_init(parent);
-       mop500_spi_init(parent);
-       mop500_audio_init(parent);
-       mop500_uart_init(parent);
-       u8500_cryp1_hash1_init(parent);
-
-       /* This board has full regulator constraints */
-       regulator_has_full_constraints();
-}
-
-
-static void __init snowball_init_machine(void)
-{
-       struct device *parent = NULL;
-       int i;
-
-       platform_device_register(&db8500_prcmu_device);
-
-       sdi0_reg_info.enable_gpio = SNOWBALL_SDMMC_EN_GPIO;
-       sdi0_reg_info.gpios[0].gpio = SNOWBALL_SDMMC_1V8_3V_GPIO;
-
-       snowball_pinmaps_init();
-       parent = u8500_init_devices();
-
-       for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
-               snowball_platform_devs[i]->dev.parent = parent;
-
-       platform_add_devices(snowball_platform_devs,
-                       ARRAY_SIZE(snowball_platform_devs));
-
-       mop500_i2c_init(parent);
-       snowball_sdi_init(parent);
-       mop500_spi_init(parent);
-       mop500_audio_init(parent);
-       mop500_uart_init(parent);
-
-       u8500_cryp1_hash1_init(parent);
-
-       /* This board has full regulator constraints */
-       regulator_has_full_constraints();
-}
-
-static void __init hrefv60_init_machine(void)
-{
-       struct device *parent = NULL;
-       int i;
-
-       platform_device_register(&db8500_prcmu_device);
-       /*
-        * The HREFv60 board removed a GPIO expander and routed
-        * all these GPIO pins to the internal GPIO controller
-        * instead.
-        */
-       mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
-
-       sdi0_reg_info.enable_gpio = HREFV60_SDMMC_EN_GPIO;
-       sdi0_reg_info.gpios[0].gpio = HREFV60_SDMMC_1V8_3V_GPIO;
-
-       hrefv60_pinmaps_init();
-       parent = u8500_init_devices();
-
-       for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
-               mop500_platform_devs[i]->dev.parent = parent;
-
-       platform_add_devices(mop500_platform_devs,
-                       ARRAY_SIZE(mop500_platform_devs));
-
-       mop500_i2c_init(parent);
-       hrefv60_sdi_init(parent);
-       mop500_spi_init(parent);
-       mop500_audio_init(parent);
-       mop500_uart_init(parent);
-
-       /* This board has full regulator constraints */
-       regulator_has_full_constraints();
-}
-
-MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
-       /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
-       .atag_offset    = 0x100,
-       .smp            = smp_ops(ux500_smp_ops),
-       .map_io         = u8500_map_io,
-       .init_irq       = ux500_init_irq,
-       /* we re-use nomadik timer here */
-       .init_time      = ux500_timer_init,
-       .init_machine   = mop500_init_machine,
-       .init_late      = ux500_init_late,
-       .restart        = ux500_restart,
-MACHINE_END
-
-MACHINE_START(U8520, "ST-Ericsson U8520 Platform HREFP520")
-       .atag_offset    = 0x100,
-       .map_io         = u8500_map_io,
-       .init_irq       = ux500_init_irq,
-       .init_time      = ux500_timer_init,
-       .init_machine   = mop500_init_machine,
-       .init_late      = ux500_init_late,
-       .restart        = ux500_restart,
-MACHINE_END
-
-MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
-       .atag_offset    = 0x100,
-       .smp            = smp_ops(ux500_smp_ops),
-       .map_io         = u8500_map_io,
-       .init_irq       = ux500_init_irq,
-       .init_time      = ux500_timer_init,
-       .init_machine   = hrefv60_init_machine,
-       .init_late      = ux500_init_late,
-       .restart        = ux500_restart,
-MACHINE_END
-
-MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
-       .atag_offset    = 0x100,
-       .smp            = smp_ops(ux500_smp_ops),
-       .map_io         = u8500_map_io,
-       .init_irq       = ux500_init_irq,
-       /* we re-use nomadik timer here */
-       .init_time      = ux500_timer_init,
-       .init_machine   = snowball_init_machine,
-       .init_late      = NULL,
-       .restart        = ux500_restart,
-MACHINE_END
index d6fab166cbf113b36e52306c8fc62632a984be89..511d6febbe9996ac7f4831ba6d878435765c2869 100644 (file)
@@ -79,7 +79,6 @@
 #define SNOWBALL_EN_3V3_ETH_GPIO       MOP500_AB8500_PIN_GPIO(26)      /* GPIO26 */
 
 struct device;
-struct i2c_board_info;
 extern struct mmci_platform_data mop500_sdi0_data;
 extern struct mmci_platform_data mop500_sdi1_data;
 extern struct mmci_platform_data mop500_sdi2_data;
@@ -88,25 +87,10 @@ extern struct msp_i2s_platform_data msp0_platform_data;
 extern struct msp_i2s_platform_data msp1_platform_data;
 extern struct msp_i2s_platform_data msp2_platform_data;
 extern struct msp_i2s_platform_data msp3_platform_data;
-extern struct arm_pmu_platdata db8500_pmu_platdata;
-extern struct amba_pl011_data uart0_plat;
-extern struct amba_pl011_data uart1_plat;
-extern struct amba_pl011_data uart2_plat;
 extern struct pl022_ssp_controller ssp0_plat;
-extern struct stedma40_platform_data dma40_plat_data;
 
-extern void mop500_sdi_init(struct device *parent);
-extern void snowball_sdi_init(struct device *parent);
-extern void hrefv60_sdi_init(struct device *parent);
-extern void mop500_sdi_tc35892_init(struct device *parent);
-void __init mop500_u8500uib_init(void);
-void __init mop500_stuib_init(void);
 void __init mop500_pinmaps_init(void);
 void __init snowball_pinmaps_init(void);
 void __init hrefv60_pinmaps_init(void);
-void mop500_audio_init(struct device *parent);
 
-int __init mop500_uib_init(void);
-void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
-               unsigned n);
 #endif
index 301c3460d96af48f8bed5f3f89378cad8893c486..2e85c1e72535138a1b90c543ec3e95e2b36a6fa6 100644 (file)
@@ -32,7 +32,6 @@
 #include "irqs.h"
 
 #include "devices-db8500.h"
-#include "ste-dma40-db8500.h"
 #include "db8500-regs.h"
 #include "board-mop500.h"
 #include "id.h"
@@ -93,14 +92,6 @@ void __init u8500_map_io(void)
                iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
 }
 
-static struct resource db8500_pmu_resources[] = {
-       [0] = {
-               .start          = IRQ_DB8500_PMU,
-               .end            = IRQ_DB8500_PMU,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
 /*
  * The PMU IRQ lines of two cores are wired together into a single interrupt.
  * Bounce the interrupt to the other core if it's not ours.
@@ -125,54 +116,6 @@ struct arm_pmu_platdata db8500_pmu_platdata = {
        .handle_irq             = db8500_pmu_handler,
 };
 
-static struct platform_device db8500_pmu_device = {
-       .name                   = "arm-pmu",
-       .id                     = -1,
-       .num_resources          = ARRAY_SIZE(db8500_pmu_resources),
-       .resource               = db8500_pmu_resources,
-       .dev.platform_data      = &db8500_pmu_platdata,
-};
-
-static struct platform_device *platform_devs[] __initdata = {
-       &u8500_dma40_device,
-       &db8500_pmu_device,
-};
-
-static resource_size_t __initdata db8500_gpio_base[] = {
-       U8500_GPIOBANK0_BASE,
-       U8500_GPIOBANK1_BASE,
-       U8500_GPIOBANK2_BASE,
-       U8500_GPIOBANK3_BASE,
-       U8500_GPIOBANK4_BASE,
-       U8500_GPIOBANK5_BASE,
-       U8500_GPIOBANK6_BASE,
-       U8500_GPIOBANK7_BASE,
-       U8500_GPIOBANK8_BASE,
-};
-
-static void __init db8500_add_gpios(struct device *parent)
-{
-       struct nmk_gpio_platform_data pdata = {
-               .supports_sleepmode = true,
-       };
-
-       dbx500_add_gpios(parent, db8500_gpio_base,
-                        ARRAY_SIZE(db8500_gpio_base),
-                        IRQ_DB8500_GPIO0, &pdata);
-       dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE);
-}
-
-static int usb_db8500_dma_cfg[] = {
-       DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9,
-       DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10,
-       DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11,
-       DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12,
-       DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13,
-       DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14,
-       DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15,
-       DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8
-};
-
 static const char *db8500_read_soc_id(void)
 {
        void __iomem *uid = __io_address(U8500_BB_UID_BASE);
@@ -192,60 +135,22 @@ static struct device * __init db8500_soc_device_init(void)
        return ux500_soc_device_init(soc_id);
 }
 
-/*
- * This function is called from the board init
- */
-struct device * __init u8500_init_devices(void)
-{
-       struct device *parent;
-       int i;
-
-       parent = db8500_soc_device_init();
-
-       db8500_add_rtc(parent);
-       db8500_add_gpios(parent);
-       db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg);
-
-       for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
-               platform_devs[i]->dev.parent = parent;
-
-       platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
-
-       return parent;
-}
-
 #ifdef CONFIG_MACH_UX500_DT
 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,pl011", 0x80120000, "uart0", NULL),
-       OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", NULL),
-       OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", NULL),
-       OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0",  &ssp0_plat),
-       OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0",  NULL),
-       OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1",  NULL),
-       OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2",  NULL),
-       OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4",  NULL),
-       /* Requires clock name bindings. */
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL),
-       OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL),
-       OF_DEV_AUXDATA("st,nomadik-i2c", 0x80004000, "nmk-i2c.0", NULL),
-       OF_DEV_AUXDATA("st,nomadik-i2c", 0x80122000, "nmk-i2c.1", NULL),
-       OF_DEV_AUXDATA("st,nomadik-i2c", 0x80128000, "nmk-i2c.2", NULL),
-       OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
-       OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
-       OF_DEV_AUXDATA("stericsson,db8500-musb", 0xa03e0000, "musb-ux500.0", NULL),
+       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
+                      "ux500-msp-i2s.0", &msp0_platform_data),
+       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
+                      "ux500-msp-i2s.1", &msp1_platform_data),
+       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000,
+                      "ux500-msp-i2s.2", &msp2_platform_data),
+       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
+                      "ux500-msp-i2s.3", &msp3_platform_data),
+       /* Requires non-DT:able platform data. */
        OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
                        &db8500_prcmu_pdata),
-       OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x.0", NULL),
        OF_DEV_AUXDATA("stericsson,ux500-cryp", 0xa03cb000, "cryp1", NULL),
        OF_DEV_AUXDATA("stericsson,ux500-hash", 0xa03c2000, "hash1", NULL),
        OF_DEV_AUXDATA("stericsson,snd-soc-mop500", 0, "snd-soc-mop500.0",
@@ -253,17 +158,6 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
        /* Requires device name bindings. */
        OF_DEV_AUXDATA("stericsson,db8500-pinctrl", U8500_PRCMU_BASE,
                "pinctrl-db8500", NULL),
-       /* Requires clock name and DMA bindings. */
-       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
-               "ux500-msp-i2s.0", &msp0_platform_data),
-       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
-               "ux500-msp-i2s.1", &msp1_platform_data),
-       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000,
-               "ux500-msp-i2s.2", &msp2_platform_data),
-       OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
-               "ux500-msp-i2s.3", &msp3_platform_data),
-       /* Requires clock name bindings and channel address lookup table. */
-       OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL),
        {},
 };
 
index 5d7eebcabc63a12e6a699ecbe047099d95482496..f84d4397896b39705e0227dac27555542c1d9cc0 100644 (file)
@@ -78,9 +78,17 @@ void __init ux500_init_irq(void)
        if (cpu_is_u8500_family()) {
                prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
                ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
-               u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
-                              U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
-                              U8500_CLKRST6_BASE);
+
+               if (of_have_populated_dt())
+                       u8500_of_clk_init(U8500_CLKRST1_BASE,
+                                         U8500_CLKRST2_BASE,
+                                         U8500_CLKRST3_BASE,
+                                         U8500_CLKRST5_BASE,
+                                         U8500_CLKRST6_BASE);
+               else
+                       u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
+                                      U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
+                                      U8500_CLKRST6_BASE);
        } else if (cpu_is_u9540()) {
                prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
                ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
@@ -96,11 +104,6 @@ void __init ux500_init_irq(void)
        }
 }
 
-void __init ux500_init_late(void)
-{
-       mop500_uib_init();
-}
-
 static const char * __init ux500_get_machine(void)
 {
        return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber());
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
deleted file mode 100644 (file)
index f71b3d7..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- * License terms: GNU General Public License (GPL), version 2.
- */
-
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/err.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/pinctrl-nomadik.h>
-
-#include "irqs.h"
-
-#include "devices-common.h"
-
-static struct platform_device *
-dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq,
-               struct nmk_gpio_platform_data *pdata)
-{
-       struct resource resources[] = {
-               {
-                       .start  = addr,
-                       .end    = addr + 127,
-                       .flags  = IORESOURCE_MEM,
-               },
-               {
-                       .start  = irq,
-                       .end    = irq,
-                       .flags  = IORESOURCE_IRQ,
-               }
-       };
-
-       return platform_device_register_resndata(
-               parent,
-               "gpio",
-               id,
-               resources,
-               ARRAY_SIZE(resources),
-               pdata,
-               sizeof(*pdata));
-}
-
-void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
-                     int irq, struct nmk_gpio_platform_data *pdata)
-{
-       int first = 0;
-       int i;
-
-       for (i = 0; i < num; i++, first += 32, irq++) {
-               pdata->first_gpio = first;
-               pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
-               pdata->num_gpio = 32;
-
-               dbx500_add_gpio(parent, i, base[i], irq, pdata);
-       }
-}
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
deleted file mode 100644 (file)
index 96fa4ac..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- * License terms: GNU General Public License (GPL), version 2.
- */
-
-#ifndef __DEVICES_COMMON_H
-#define __DEVICES_COMMON_H
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/sys_soc.h>
-#include <linux/amba/bus.h>
-#include <linux/platform_data/i2c-nomadik.h>
-#include <linux/platform_data/crypto-ux500.h>
-
-struct spi_master_cntlr;
-
-static inline struct amba_device *
-dbx500_add_msp_spi(struct device *parent, const char *name,
-                  resource_size_t base, int irq,
-                  struct spi_master_cntlr *pdata)
-{
-       return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0,
-                                  pdata, 0);
-}
-
-static inline struct amba_device *
-dbx500_add_spi(struct device *parent, const char *name, resource_size_t base,
-              int irq, struct spi_master_cntlr *pdata,
-              u32 periphid)
-{
-       return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0,
-                                  pdata, periphid);
-}
-
-struct mmci_platform_data;
-
-static inline struct amba_device *
-dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base,
-              int irq, struct mmci_platform_data *pdata, u32 periphid)
-{
-       return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0,
-                                  pdata, periphid);
-}
-
-struct amba_pl011_data;
-
-static inline struct amba_device *
-dbx500_add_uart(struct device *parent, const char *name, resource_size_t base,
-               int irq, struct amba_pl011_data *pdata)
-{
-       return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0);
-}
-
-struct nmk_i2c_controller;
-
-static inline struct amba_device *
-dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq,
-              struct nmk_i2c_controller *data)
-{
-       /* Conjure a name similar to what the platform device used to have */
-       char name[16];
-
-       snprintf(name, sizeof(name), "nmk-i2c.%d", id);
-       return amba_apb_device_add(parent, name, base, SZ_4K, irq, 0, data, 0);
-}
-
-static inline struct amba_device *
-dbx500_add_rtc(struct device *parent, resource_size_t base, int irq)
-{
-       return amba_apb_device_add(parent, "rtc-pl031", base, SZ_4K, irq,
-                               0, NULL, 0);
-}
-
-struct cryp_platform_data;
-
-static inline struct platform_device *
-dbx500_add_cryp1(struct device *parent, int id, resource_size_t base, int irq,
-               struct cryp_platform_data *pdata)
-{
-       struct resource res[] = {
-                       DEFINE_RES_MEM(base, SZ_4K),
-                       DEFINE_RES_IRQ(irq),
-       };
-
-       struct platform_device_info pdevinfo = {
-                       .parent = parent,
-                       .name = "cryp1",
-                       .id = id,
-                       .res = res,
-                       .num_res = ARRAY_SIZE(res),
-                       .data = pdata,
-                       .size_data = sizeof(*pdata),
-                       .dma_mask = DMA_BIT_MASK(32),
-       };
-
-       return platform_device_register_full(&pdevinfo);
-}
-
-struct hash_platform_data;
-
-static inline struct platform_device *
-dbx500_add_hash1(struct device *parent, int id, resource_size_t base,
-               struct hash_platform_data *pdata)
-{
-       struct resource res[] = {
-                       DEFINE_RES_MEM(base, SZ_4K),
-       };
-
-       struct platform_device_info pdevinfo = {
-                       .parent = parent,
-                       .name = "hash1",
-                       .id = id,
-                       .res = res,
-                       .num_res = ARRAY_SIZE(res),
-                       .data = pdata,
-                       .size_data = sizeof(*pdata),
-                       .dma_mask = DMA_BIT_MASK(32),
-       };
-
-       return platform_device_register_full(&pdevinfo);
-}
-
-struct nmk_gpio_platform_data;
-
-void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
-                     int irq, struct nmk_gpio_platform_data *pdata);
-
-static inline void
-dbx500_add_pinctrl(struct device *parent, const char *name,
-                  resource_size_t base)
-{
-       struct resource res[] = {
-               DEFINE_RES_MEM(base, SZ_8K),
-       };
-       struct platform_device_info pdevinfo = {
-               .parent = parent,
-               .name = name,
-               .id = -1,
-               .res = res,
-               .num_res = ARRAY_SIZE(res),
-       };
-
-       platform_device_register_full(&pdevinfo);
-}
-
-#endif
index bc316062e0c23661c118429036207e50911ffebb..c59f89d058ff4499c6d7dd33b6464d086a8fdd0b 100644 (file)
@@ -9,10 +9,8 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
-#include <linux/platform_data/dma-ste-dma40.h>
 #include <linux/mfd/dbx500-prcmu.h>
 
 #include "setup.h"
 
 #include "db8500-regs.h"
 #include "devices-db8500.h"
-#include "ste-dma40-db8500.h"
-
-static struct resource dma40_resources[] = {
-       [0] = {
-               .start = U8500_DMA_BASE,
-               .end   = U8500_DMA_BASE + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-               .name  = "base",
-       },
-       [1] = {
-               .start = U8500_DMA_LCPA_BASE,
-               .end   = U8500_DMA_LCPA_BASE + 2 * SZ_1K - 1,
-               .flags = IORESOURCE_MEM,
-               .name  = "lcpa",
-       },
-       [2] = {
-               .start = IRQ_DB8500_DMA,
-               .end   = IRQ_DB8500_DMA,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-struct stedma40_platform_data dma40_plat_data = {
-       .disabled_channels = {-1},
-};
-
-struct platform_device u8500_dma40_device = {
-       .dev = {
-               .platform_data = &dma40_plat_data,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-       .name = "dma40",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(dma40_resources),
-       .resource = dma40_resources
-};
-
-struct resource keypad_resources[] = {
-       [0] = {
-               .start = U8500_SKE_BASE,
-               .end = U8500_SKE_BASE + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_DB8500_KB,
-               .end = IRQ_DB8500_KB,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device u8500_ske_keypad_device = {
-       .name = "nmk-ske-keypad",
-       .id = -1,
-       .num_resources = ARRAY_SIZE(keypad_resources),
-       .resource = keypad_resources,
-};
 
 struct prcmu_pdata db8500_prcmu_pdata = {
        .ab_platdata    = &ab8500_platdata,
@@ -84,39 +26,3 @@ struct prcmu_pdata db8500_prcmu_pdata = {
        .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET,
        .legacy_offset  = DB8500_PRCMU_LEGACY_OFFSET,
 };
-
-static struct resource db8500_prcmu_res[] = {
-       {
-               .name  = "prcmu",
-               .start = U8500_PRCMU_BASE,
-               .end   = U8500_PRCMU_BASE + SZ_8K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .name  = "prcmu-tcdm",
-               .start = U8500_PRCMU_TCDM_BASE,
-               .end   = U8500_PRCMU_TCDM_BASE + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       {
-               .name  = "irq",
-               .start = IRQ_DB8500_PRCMU1,
-               .end   = IRQ_DB8500_PRCMU1,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name  = "prcmu-tcpm",
-               .start = U8500_PRCMU_TCPM_BASE,
-               .end   = U8500_PRCMU_TCPM_BASE + SZ_32K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-};
-
-struct platform_device db8500_prcmu_device = {
-       .name                   = "db8500-prcmu",
-       .resource               = db8500_prcmu_res,
-       .num_resources          = ARRAY_SIZE(db8500_prcmu_res),
-       .dev = {
-               .platform_data = &db8500_prcmu_pdata,
-       },
-};
index 321998320f98536abf4ef603b498d430ab0e1ac0..b8ffc9979bb2db763738a2cf8f39cf441edd3887 100644 (file)
 #ifndef __DEVICES_DB8500_H
 #define __DEVICES_DB8500_H
 
-#include <linux/platform_data/usb-musb-ux500.h>
 #include "irqs.h"
 #include "db8500-regs.h"
-#include "devices-common.h"
 
-struct ske_keypad_platform_data;
-struct pl022_ssp_controller;
 struct platform_device;
 
 extern struct ab8500_platform_data ab8500_platdata;
 extern struct prcmu_pdata db8500_prcmu_pdata;
-extern struct platform_device db8500_prcmu_device;
 
-static inline struct platform_device *
-db8500_add_ske_keypad(struct device *parent,
-                     struct ske_keypad_platform_data *pdata,
-                     size_t size)
-{
-       struct resource resources[] = {
-               DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K),
-               DEFINE_RES_IRQ(IRQ_DB8500_KB),
-       };
-
-       return platform_device_register_resndata(parent, "nmk-ske-keypad", -1,
-                                                resources, 2, pdata, size);
-}
-
-static inline struct amba_device *
-db8500_add_ssp(struct device *parent, const char *name, resource_size_t base,
-              int irq, struct pl022_ssp_controller *pdata)
-{
-       return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0);
-}
-
-#define db8500_add_i2c0(parent, pdata) \
-       dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
-#define db8500_add_i2c1(parent, pdata) \
-       dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
-#define db8500_add_i2c2(parent, pdata) \
-       dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
-#define db8500_add_i2c3(parent, pdata) \
-       dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
-#define db8500_add_i2c4(parent, pdata) \
-       dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
-
-#define db8500_add_msp0_spi(parent, pdata) \
-       dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \
-                          IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_spi(parent, pdata) \
-       dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \
-                          IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_spi(parent, pdata) \
-       dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \
-                          IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_spi(parent, pdata) \
-       dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \
-                          IRQ_DB8500_MSP1, pdata)
-
-#define db8500_add_rtc(parent) \
-       dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC);
-
-#define db8500_add_usb(parent, rx_cfg, tx_cfg) \
-       ux500_add_usb(parent, U8500_USBOTG_BASE, \
-                     IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
-
-#define db8500_add_sdi0(parent, pdata, pid) \
-       dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \
-                      IRQ_DB8500_SDMMC0, pdata, pid)
-#define db8500_add_sdi1(parent, pdata, pid) \
-       dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \
-                      IRQ_DB8500_SDMMC1, pdata, pid)
-#define db8500_add_sdi2(parent, pdata, pid) \
-       dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \
-                      IRQ_DB8500_SDMMC2, pdata, pid)
-#define db8500_add_sdi3(parent, pdata, pid) \
-       dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \
-                      IRQ_DB8500_SDMMC3, pdata, pid)
-#define db8500_add_sdi4(parent, pdata, pid) \
-       dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \
-                      IRQ_DB8500_SDMMC4, pdata, pid)
-#define db8500_add_sdi5(parent, pdata, pid) \
-       dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \
-                      IRQ_DB8500_SDMMC5, pdata, pid)
-
-#define db8500_add_ssp0(parent, pdata) \
-       db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \
-                      IRQ_DB8500_SSP0, pdata)
-#define db8500_add_ssp1(parent, pdata) \
-       db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \
-                      IRQ_DB8500_SSP1, pdata)
-
-#define db8500_add_spi0(parent, pdata) \
-       dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \
-                      IRQ_DB8500_SPI0, pdata, 0)
-#define db8500_add_spi1(parent, pdata) \
-       dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \
-                      IRQ_DB8500_SPI1, pdata, 0)
-#define db8500_add_spi2(parent, pdata) \
-       dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \
-                      IRQ_DB8500_SPI2, pdata, 0)
-#define db8500_add_spi3(parent, pdata) \
-       dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \
-                      IRQ_DB8500_SPI3, pdata, 0)
-
-#define db8500_add_uart0(parent, pdata) \
-       dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \
-                       IRQ_DB8500_UART0, pdata)
-#define db8500_add_uart1(parent, pdata) \
-       dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \
-                       IRQ_DB8500_UART1, pdata)
-#define db8500_add_uart2(parent, pdata) \
-       dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \
-                       IRQ_DB8500_UART2, pdata)
-
-#define db8500_add_cryp1(parent, pdata) \
-       dbx500_add_cryp1(parent, -1, U8500_CRYP1_BASE, IRQ_DB8500_CRYP1, pdata)
-#define db8500_add_hash1(parent, pdata) \
-       dbx500_add_hash1(parent, -1, U8500_HASH1_BASE, pdata)
 #endif
index cbc6f1e4104ddc2c9b8c0bd7c3b96f662167f24f..5bca7c605cd6c1a0cc5bffb54df3f006ff338a52 100644 (file)
 struct platform_device;
 struct amba_device;
 
-extern struct platform_device u8500_gpio_devs[];
-
 extern struct amba_device ux500_pl031_device;
 
-extern struct platform_device ux500_hash1_device;
-extern struct platform_device ux500_cryp1_device;
-
-extern struct platform_device u8500_dma40_device;
-extern struct platform_device ux500_ske_keypad_device;
-
 #endif
index 656324aad18e229d67a3abaf36af2c04d6c85c3c..bdb356498a748563091d7563525db015500dbfc1 100644 (file)
@@ -24,7 +24,6 @@ extern void __init u8500_map_io(void);
 extern struct device * __init u8500_init_devices(void);
 
 extern void __init ux500_init_irq(void);
-extern void __init ux500_init_late(void);
 
 extern struct device *ux500_soc_device_init(const char *soc_id);
 
index b6bd0efcbe64465bed83d2814e01f57483a03c92..05a4ff78b3bd9e73deaf4c0e814f79cdae8e971e 100644 (file)
@@ -97,8 +97,8 @@ dt_fail:
         * sched_clock with higher rating then MTU since is always-on.
         *
         */
-
-       nmdk_timer_init(mtu_timer_base, IRQ_MTU0);
+       if (!of_have_populated_dt())
+               nmdk_timer_init(mtu_timer_base, IRQ_MTU0);
        clksrc_dbx500_prcmu_init(prcmu_timer_base);
        ux500_twd_init();
 }
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c
deleted file mode 100644 (file)
index b7bd8d3..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-#include <linux/platform_device.h>
-#include <linux/usb/musb.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_data/usb-musb-ux500.h>
-#include <linux/platform_data/dma-ste-dma40.h>
-
-#include "db8500-regs.h"
-
-#define MUSB_DMA40_RX_CH { \
-               .mode = STEDMA40_MODE_LOGICAL, \
-               .dir = DMA_DEV_TO_MEM, \
-       }
-
-#define MUSB_DMA40_TX_CH { \
-               .mode = STEDMA40_MODE_LOGICAL, \
-               .dir = DMA_MEM_TO_DEV, \
-       }
-
-static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
-       = {
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH,
-       MUSB_DMA40_RX_CH
-};
-
-static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
-       = {
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-       MUSB_DMA40_TX_CH,
-};
-
-static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
-       &musb_dma_rx_ch[0],
-       &musb_dma_rx_ch[1],
-       &musb_dma_rx_ch[2],
-       &musb_dma_rx_ch[3],
-       &musb_dma_rx_ch[4],
-       &musb_dma_rx_ch[5],
-       &musb_dma_rx_ch[6],
-       &musb_dma_rx_ch[7]
-};
-
-static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
-       &musb_dma_tx_ch[0],
-       &musb_dma_tx_ch[1],
-       &musb_dma_tx_ch[2],
-       &musb_dma_tx_ch[3],
-       &musb_dma_tx_ch[4],
-       &musb_dma_tx_ch[5],
-       &musb_dma_tx_ch[6],
-       &musb_dma_tx_ch[7]
-};
-
-static struct ux500_musb_board_data musb_board_data = {
-       .dma_rx_param_array = ux500_dma_rx_param_array,
-       .dma_tx_param_array = ux500_dma_tx_param_array,
-       .dma_filter = stedma40_filter,
-};
-
-static struct musb_hdrc_platform_data musb_platform_data = {
-       .mode = MUSB_OTG,
-       .board_data = &musb_board_data,
-};
-
-static struct resource usb_resources[] = {
-       [0] = {
-               .name   = "usb-mem",
-               .flags  =  IORESOURCE_MEM,
-       },
-
-       [1] = {
-               .name   = "mc", /* hard-coded in musb */
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device ux500_musb_device = {
-       .name = "musb-ux500",
-       .id = 0,
-       .dev = {
-               .platform_data = &musb_platform_data,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-       .num_resources = ARRAY_SIZE(usb_resources),
-       .resource = usb_resources,
-};
-
-static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type)
-{
-       u32 idx;
-
-       for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
-               musb_dma_rx_ch[idx].dev_type = dev_type[idx];
-}
-
-static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type)
-{
-       u32 idx;
-
-       for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
-               musb_dma_tx_ch[idx].dev_type = dev_type[idx];
-}
-
-void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
-                  int *dma_rx_cfg, int *dma_tx_cfg)
-{
-       ux500_musb_device.resource[0].start = base;
-       ux500_musb_device.resource[0].end = base + SZ_64K - 1;
-       ux500_musb_device.resource[1].start = irq;
-       ux500_musb_device.resource[1].end = irq;
-
-       ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
-       ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);
-
-       ux500_musb_device.dev.parent = parent;
-
-       platform_device_register(&ux500_musb_device);
-}
index 36579544780493706381c22008c64577bc04fde2..d7e7422527cac791938e4006873bad4fc8883d64 100644 (file)
@@ -4,14 +4,12 @@ config ARCH_VEXPRESS
        select ARM_AMBA
        select ARM_GIC
        select ARM_TIMER_SP804
-       select CLKDEV_LOOKUP
        select COMMON_CLK
        select COMMON_CLK_VERSATILE
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_CLK
        select HAVE_PATA_PLATFORM
        select HAVE_SMP
        select ICST
index 95a469e23e378078af77ffcd9eecc9b29e5ff264..4f8b8cb17ff50560c751058b2f44980294482428 100644 (file)
@@ -1,12 +1,10 @@
 /*
  * Versatile Express V2M Motherboard Support
  */
-#include <linux/clocksource.h>
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/mmci.h>
 #include <linux/io.h>
-#include <linux/clocksource.h>
 #include <linux/smp.h>
 #include <linux/init.h>
 #include <linux/of_address.h>
@@ -22,7 +20,6 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/vexpress.h>
-#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 
 #include <asm/mach-types.h>
@@ -422,16 +419,8 @@ void __init v2m_dt_init_early(void)
                        pr_warning("vexpress: DT HBI (%x) is not matching "
                                        "hardware (%x)!\n", dt_hbi, hbi);
        }
-}
-
-static void __init v2m_dt_timer_init(void)
-{
-       of_clk_init(NULL);
 
-       clocksource_of_init();
-
-       versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
-                               24000000);
+       versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
 }
 
 static const struct of_device_id v2m_dt_bus_match[] __initconst = {
@@ -458,6 +447,5 @@ DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
        .smp_init       = smp_init_ops(vexpress_smp_init_ops),
        .map_io         = v2m_dt_map_io,
        .init_early     = v2m_dt_init_early,
-       .init_time      = v2m_dt_timer_init,
        .init_machine   = v2m_dt_init,
 MACHINE_END
index 9b252934b2065f60f21888f5bc76ffd7c609326e..927be93b692ec37fff6e5944649d1237c25617d8 100644 (file)
@@ -5,7 +5,6 @@ config ARCH_VT8500
        select CLKDEV_LOOKUP
        select CLKSRC_OF
        select GENERIC_CLOCKEVENTS
-       select HAVE_CLK
        select VT8500_TIMER
        select PINCTRL
        help
diff --git a/arch/arm/mach-vt8500/common.h b/arch/arm/mach-vt8500/common.h
deleted file mode 100644 (file)
index 087787a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* linux/arch/arm/mach-vt8500/dt_common.h
- *
- * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __ARCH_ARM_MACH_VT8500_DT_COMMON_H
-#define __ARCH_ARM_MACH_VT8500_DT_COMMON_H
-
-#include <linux/of.h>
-
-/* defined in drivers/clk/clk-vt8500.c */
-void __init vtwm_clk_init(void __iomem *pmc_base);
-
-#endif
index eefaa60d6614c72ca20608fd2636bf18cc12b65f..4a73464cb11b4f449aa15c55628a0f35bab06d3a 100644 (file)
@@ -18,7 +18,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <linux/clocksource.h>
 #include <linux/io.h>
 #include <linux/pm.h>
 #include <linux/reboot.h>
@@ -33,8 +32,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 
-#include "common.h"
-
 #define LEGACY_GPIO_BASE       0xD8110000
 #define LEGACY_PMC_BASE                0xD8130000
 
@@ -162,8 +159,6 @@ void __init vt8500_init(void)
        else
                pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__);
 
-       vtwm_clk_init(pmc_base);
-
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
@@ -180,7 +175,6 @@ DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)")
        .dt_compat      = vt8500_dt_compat,
        .map_io         = vt8500_map_io,
        .init_machine   = vt8500_init,
-       .init_time      = clocksource_of_init,
        .restart        = vt8500_restart,
 MACHINE_END
 
index 037660633fa4caab075722bc693cb638419d0082..01619c2910e364271ab565f49c8644850b9fc70b 100644 (file)
@@ -1965,7 +1965,6 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
 static struct irqaction omap24xx_dma_irq = {
        .name = "DMA",
        .handler = omap2_dma_irq_handler,
-       .flags = IRQF_DISABLED
 };
 
 #else
index 7dfba937d8fc34b017bf953b6761abd7f4f5f45c..6d95d60276d623bee59f28391d499f0e213730d5 100644 (file)
@@ -382,11 +382,6 @@ config S5P_DEV_TV
        help
          Compile in platform device definition for TV interface
 
-config S5P_DEV_USB_EHCI
-       bool
-       help
-         Compile in platform device definition for USB EHCI
-
 config S3C24XX_PWM
        bool "PWM device support"
        select PWM
@@ -395,11 +390,6 @@ config S3C24XX_PWM
          Support for exporting the PWM timer blocks via the pwm device
          system
 
-config S5P_SETUP_MIPIPHY
-       bool
-       help
-         Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
-
 config S3C_SETUP_CAMIF
        bool
        help
index 498c7c23e9f4cd8088eddc1ae937bfcae733d71e..9267d29549b47bd29c2ed6b76f98bd0c8180ce51 100644 (file)
@@ -38,7 +38,6 @@ obj-$(CONFIG_S5P_DEV_UART)    += s5p-dev-uart.o
 obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)    += dev-backlight.o
 
 obj-$(CONFIG_S3C_SETUP_CAMIF)  += setup-camif.o
-obj-$(CONFIG_S5P_SETUP_MIPIPHY)        += setup-mipiphy.o
 
 # DMA support
 
index 8ce0ac007eb96397d0c16a67fe9014d12f7d6901..99a3590f034949cc45bc99df724857e096888e51 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/ioport.h>
 #include <linux/platform_data/s3c-hsudc.h>
 #include <linux/platform_data/s3c-hsotg.h>
+#include <linux/platform_data/dma-s3c24xx.h>
 
 #include <media/s5p_hdmi.h>
 
@@ -49,7 +50,6 @@
 #include <plat/devs.h>
 #include <plat/adc.h>
 #include <linux/platform_data/ata-samsung_cf.h>
-#include <linux/platform_data/usb-ehci-s5p.h>
 #include <plat/fb.h>
 #include <plat/fb-s3c2410.h>
 #include <plat/hdmi.h>
@@ -1359,39 +1359,6 @@ void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
 }
 #endif /* CONFIG_PLAT_S3C24XX */
 
-/* USB EHCI Host Controller */
-
-#ifdef CONFIG_S5P_DEV_USB_EHCI
-static struct resource s5p_ehci_resource[] = {
-       [0] = DEFINE_RES_MEM(S5P_PA_EHCI, SZ_256),
-       [1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
-};
-
-struct platform_device s5p_device_ehci = {
-       .name           = "s5p-ehci",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s5p_ehci_resource),
-       .resource       = s5p_ehci_resource,
-       .dev            = {
-               .dma_mask               = &samsung_device_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       }
-};
-
-void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
-{
-       struct s5p_ehci_platdata *npd;
-
-       npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
-                       &s5p_device_ehci);
-
-       if (!npd->phy_init)
-               npd->phy_init = s5p_usb_phy_init;
-       if (!npd->phy_exit)
-               npd->phy_exit = s5p_usb_phy_exit;
-}
-#endif /* CONFIG_S5P_DEV_USB_EHCI */
-
 /* USB HSOTG */
 
 #ifdef CONFIG_S3C_DEV_USB_HSOTG
@@ -1499,8 +1466,10 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
        pd.num_cs = num_cs;
        pd.src_clk_nr = src_clk_nr;
        pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
-#ifdef CONFIG_PL330_DMA
+#if defined(CONFIG_PL330_DMA)
        pd.filter = pl330_filter;
+#elif defined(CONFIG_S3C24XX_DMAC)
+       pd.filter = s3c24xx_dma_filter;
 #endif
 
        s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
index 4fb1f03a10d1f718b9f99d1e5309c9732ebc0a1f..335beb3413556637510b10ced41cc7f0a62f0b48 100644 (file)
@@ -87,8 +87,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
 #endif
 
 #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c6400()      is_samsung_s3c6400()
+# define soc_is_s3c6410()      is_samsung_s3c6410()
 # define soc_is_s3c64xx()      (is_samsung_s3c6400() || is_samsung_s3c6410())
 #else
+# define soc_is_s3c6400()      0
+# define soc_is_s3c6410()      0
 # define soc_is_s3c64xx()      0
 #endif
 
index 0dc4ac4909b09fc9a111ff3547b9be41dd33e3cc..eece188ed18826db7a6079f4ce18041752a98918 100644 (file)
@@ -75,7 +75,6 @@ extern struct platform_device s3c_device_usb_hsotg;
 extern struct platform_device s3c_device_usb_hsudc;
 extern struct platform_device s3c_device_wdt;
 
-extern struct platform_device s5p_device_ehci;
 extern struct platform_device s5p_device_fimc0;
 extern struct platform_device s5p_device_fimc1;
 extern struct platform_device s5p_device_fimc2;
index 50a3ea0037db10d2032e2ce020688b6fa74614b0..aa9511b6914a40c92e1cb99c2b544740a8407c24 100644 (file)
  * published by the Free Software Foundation.
 */
 
+/*
+ * NOTE: Code in this file is not used on S3C64xx when booting with
+ * Device Tree support.
+ */
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <mach/hardware.h>
 
@@ -148,8 +154,12 @@ static int __init s3c_arch_init(void)
 
        // do the correct init for cpu
 
-       if (cpu == NULL)
+       if (cpu == NULL) {
+               /* Not needed when booting with device tree. */
+               if (of_have_populated_dt())
+                       return 0;
                panic("s3c_arch_init: NULL cpu\n");
+       }
 
        ret = (cpu->init)();
        if (ret != 0)
diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
deleted file mode 100644 (file)
index 66df315..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <mach/regs-clock.h>
-
-static int __s5p_mipi_phy_control(int id, bool on, u32 reset)
-{
-       static DEFINE_SPINLOCK(lock);
-       void __iomem *addr;
-       unsigned long flags;
-       u32 cfg;
-
-       id = max(0, id);
-       if (id > 1)
-               return -EINVAL;
-
-       addr = S5P_MIPI_DPHY_CONTROL(id);
-
-       spin_lock_irqsave(&lock, flags);
-
-       cfg = __raw_readl(addr);
-       cfg = on ? (cfg | reset) : (cfg & ~reset);
-       __raw_writel(cfg, addr);
-
-       if (on) {
-               cfg |= S5P_MIPI_DPHY_ENABLE;
-       } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN |
-                           S5P_MIPI_DPHY_MRESETN) & ~reset)) {
-               cfg &= ~S5P_MIPI_DPHY_ENABLE;
-       }
-
-       __raw_writel(cfg, addr);
-       spin_unlock_irqrestore(&lock, flags);
-
-       return 0;
-}
-
-int s5p_csis_phy_enable(int id, bool on)
-{
-       return __s5p_mipi_phy_control(id, on, S5P_MIPI_DPHY_SRESETN);
-}
-EXPORT_SYMBOL(s5p_csis_phy_enable);
-
-int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
-{
-       return __s5p_mipi_phy_control(pdev->id, on, S5P_MIPI_DPHY_MRESETN);
-}
-EXPORT_SYMBOL(s5p_dsim_phy_enable);
index c04454876bcbe6520a52ada910a7d193ff884e85..ce6ae94974921b267b75a71a07345c2d9318016c 100644 (file)
@@ -1,6 +1,7 @@
 config ARM64
        def_bool y
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+       select ARCH_USE_CMPXCHG_LOCKREF
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
        select ARCH_WANT_FRAME_POINTERS
@@ -61,10 +62,6 @@ config LOCKDEP_SUPPORT
 config TRACE_IRQFLAGS_SUPPORT
        def_bool y
 
-config GENERIC_LOCKBREAK
-       def_bool y
-       depends on SMP && PREEMPT
-
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
@@ -138,6 +135,11 @@ config ARM64_64K_PAGES
          look-up. AArch32 emulation is not available when this feature
          is enabled.
 
+config CPU_BIG_ENDIAN
+       bool "Build big-endian kernel"
+       help
+         Say Y if you plan on running a kernel in big-endian mode.
+
 config SMP
        bool "Symmetric Multi-Processing"
        select USE_GENERIC_SMP_HELPERS
@@ -160,6 +162,13 @@ config NR_CPUS
        default "8" if ARCH_XGENE
        default "4"
 
+config HOTPLUG_CPU
+       bool "Support for hot-pluggable CPUs"
+       depends on SMP
+       help
+         Say Y here to experiment with turning CPUs off and on.  CPUs
+         can be controlled through /sys/devices/system/cpu.
+
 source kernel/Kconfig.preempt
 
 config HZ
index d90cf79f233a952cf8a164ce78deffea7b65cace..2fceb71ac3b7a826f03e4870ac49d5e1e99cd2c3 100644 (file)
@@ -20,9 +20,15 @@ LIBGCC               := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 KBUILD_DEFCONFIG := defconfig
 
 KBUILD_CFLAGS  += -mgeneral-regs-only
+ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
+KBUILD_CPPFLAGS        += -mbig-endian
+AS             += -EB
+LD             += -EB
+else
 KBUILD_CPPFLAGS        += -mlittle-endian
 AS             += -EL
 LD             += -EL
+endif
 
 comma = ,
 
index 31c81e9b792e21b5078ada9f4299fc55e3071f86..84139be62ae66348e3f9654b4cd14cabac4ba4eb 100644 (file)
@@ -26,7 +26,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_XGENE=y
 CONFIG_SMP=y
-CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_PREEMPT=y
 CONFIG_CMDLINE="console=ttyAMA0"
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
index 5aceb83b3f5c3c5dd9dc1168a157bb0e41f1c8e9..fd3e3924041bf92e38cd825c815eead447e30613 100644 (file)
@@ -115,3 +115,34 @@ lr .req    x30             // link register
        .align  7
        b       \label
        .endm
+
+/*
+ * Select code when configured for BE.
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define CPU_BE(code...) code
+#else
+#define CPU_BE(code...)
+#endif
+
+/*
+ * Select code when configured for LE.
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define CPU_LE(code...)
+#else
+#define CPU_LE(code...) code
+#endif
+
+/*
+ * Define a macro that constructs a 64-bit value by concatenating two
+ * 32-bit registers. Note that on big endian systems the order of the
+ * registers is swapped.
+ */
+#ifndef CONFIG_CPU_BIG_ENDIAN
+       .macro  regs_to_64, rd, lbits, hbits
+#else
+       .macro  regs_to_64, rd, hbits, lbits
+#endif
+       orr     \rd, \lbits, \hbits, lsl #32
+       .endm
index 8a8ce0e73a38234968e4cde566455284af5887a6..3914c0dcd09cf0d9ed3ceff35f3b5716762acc5a 100644 (file)
@@ -173,4 +173,6 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
 #define cmpxchg64(ptr,o,n)             cmpxchg((ptr),(o),(n))
 #define cmpxchg64_local(ptr,o,n)       cmpxchg_local((ptr),(o),(n))
 
+#define cmpxchg64_relaxed(ptr,o,n)     cmpxchg_local((ptr),(o),(n))
+
 #endif /* __ASM_CMPXCHG_H */
index 899af807ef0ff3d789491d6e0ee8d9684886f849..fda2704b3f9f9a49354e12dc6b55aaa81638cd5a 100644 (file)
 #include <linux/ptrace.h>
 
 #define COMPAT_USER_HZ         100
+#ifdef __AARCH64EB__
+#define COMPAT_UTS_MACHINE     "armv8b\0\0"
+#else
 #define COMPAT_UTS_MACHINE     "armv8l\0\0"
+#endif
 
 typedef u32            compat_size_t;
 typedef s32            compat_ssize_t;
@@ -73,13 +77,23 @@ struct compat_timeval {
 };
 
 struct compat_stat {
+#ifdef __AARCH64EB__
+       short           st_dev;
+       short           __pad1;
+#else
        compat_dev_t    st_dev;
+#endif
        compat_ino_t    st_ino;
        compat_mode_t   st_mode;
        compat_ushort_t st_nlink;
        __compat_uid16_t        st_uid;
        __compat_gid16_t        st_gid;
+#ifdef __AARCH64EB__
+       short           st_rdev;
+       short           __pad2;
+#else
        compat_dev_t    st_rdev;
+#endif
        compat_off_t    st_size;
        compat_off_t    st_blksize;
        compat_off_t    st_blocks;
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
new file mode 100644 (file)
index 0000000..c4cdb5e
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_CPU_OPS_H
+#define __ASM_CPU_OPS_H
+
+#include <linux/init.h>
+#include <linux/threads.h>
+
+struct device_node;
+
+/**
+ * struct cpu_operations - Callback operations for hotplugging CPUs.
+ *
+ * @name:      Name of the property as appears in a devicetree cpu node's
+ *             enable-method property.
+ * @cpu_init:  Reads any data necessary for a specific enable-method from the
+ *             devicetree, for a given cpu node and proposed logical id.
+ * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
+ *             mechanism for doing so, tests whether it is possible to boot
+ *             the given CPU.
+ * @cpu_boot:  Boots a cpu into the kernel.
+ * @cpu_postboot: Optionally, perform any post-boot cleanup or necesary
+ *             synchronisation. Called from the cpu being booted.
+ * @cpu_disable: Prepares a cpu to die. May fail for some mechanism-specific
+ *             reason, which will cause the hot unplug to be aborted. Called
+ *             from the cpu to be killed.
+ * @cpu_die:   Makes a cpu leave the kernel. Must not fail. Called from the
+ *             cpu being killed.
+ */
+struct cpu_operations {
+       const char      *name;
+       int             (*cpu_init)(struct device_node *, unsigned int);
+       int             (*cpu_prepare)(unsigned int);
+       int             (*cpu_boot)(unsigned int);
+       void            (*cpu_postboot)(void);
+#ifdef CONFIG_HOTPLUG_CPU
+       int             (*cpu_disable)(unsigned int cpu);
+       void            (*cpu_die)(unsigned int cpu);
+#endif
+};
+
+extern const struct cpu_operations *cpu_ops[NR_CPUS];
+extern int __init cpu_read_ops(struct device_node *dn, int cpu);
+extern void __init cpu_read_bootcpu_ops(void);
+
+#endif /* ifndef __ASM_CPU_OPS_H */
index e7fa87f9201b8f109d1a69bb8dc9c2376619d637..01d3aab64b79f3c13fdd602b9e8a16bf14a8fda8 100644 (file)
@@ -90,11 +90,24 @@ typedef struct user_fpsimd_state elf_fpregset_t;
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS      ELFCLASS64
+#ifdef __AARCH64EB__
+#define ELF_DATA       ELFDATA2MSB
+#else
 #define ELF_DATA       ELFDATA2LSB
+#endif
 #define ELF_ARCH       EM_AARCH64
 
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ */
 #define ELF_PLATFORM_SIZE      16
+#ifdef __AARCH64EB__
+#define ELF_PLATFORM           ("aarch64_be")
+#else
 #define ELF_PLATFORM           ("aarch64")
+#endif
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
@@ -149,7 +162,12 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
 #ifdef CONFIG_COMPAT
+
+#ifdef __AARCH64EB__
+#define COMPAT_ELF_PLATFORM            ("v8b")
+#else
 #define COMPAT_ELF_PLATFORM            ("v8l")
+#endif
 
 #define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 / 3))
 
index 1d12f89140ba0a24bf1975b5425490b7dffb1fc9..b56e5b5df881e514ffeb21b227ebbd8b54fe3d29 100644 (file)
@@ -224,6 +224,7 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
  */
 extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
 extern void __iounmap(volatile void __iomem *addr);
+extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 
 #define PROT_DEFAULT           (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
 #define PROT_DEVICE_nGnRE      (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
@@ -233,7 +234,6 @@ extern void __iounmap(volatile void __iomem *addr);
 #define ioremap(addr, size)            __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_nocache(addr, size)    __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)         __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
-#define ioremap_cached(addr, size)     __ioremap((addr), (size), __pgprot(PROT_NORMAL))
 #define iounmap                                __iounmap
 
 #define PROT_SECT_DEFAULT      (PMD_TYPE_SECT | PMD_SECT_AF)
index 0332fc077f6e656f134f3297c28ef744d9616d1e..e1f7ecdde11ffd6103bd41ab19e625a9c76c2f85 100644 (file)
@@ -4,6 +4,7 @@
 #include <asm-generic/irq.h>
 
 extern void (*handle_arch_irq)(struct pt_regs *);
+extern void migrate_irqs(void);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
 #endif
index 20925bcf4e2a10485d724c5017c0ac639093390a..37762175896fe64d6887ce8d4abf689da5f81471 100644 (file)
 #define UL(x) _AC(x, UL)
 
 /*
- * PAGE_OFFSET - the virtual address of the start of the kernel image.
+ * PAGE_OFFSET - the virtual address of the start of the kernel image (top
+ *              (VA_BITS - 1))
  * VA_BITS - the maximum number of bits for virtual addresses.
  * TASK_SIZE - the maximum size of a user space task.
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 128MB of the kernel text.
  */
-#define PAGE_OFFSET            UL(0xffffffc000000000)
+#ifdef CONFIG_ARM64_64K_PAGES
+#define VA_BITS                        (42)
+#else
+#define VA_BITS                        (39)
+#endif
+#define PAGE_OFFSET            (UL(0xffffffffffffffff) << (VA_BITS - 1))
 #define MODULES_END            (PAGE_OFFSET)
 #define MODULES_VADDR          (MODULES_END - SZ_64M)
 #define EARLYCON_IOBASE                (MODULES_VADDR - SZ_4M)
-#define VA_BITS                        (39)
 #define TASK_SIZE_64           (UL(1) << VA_BITS)
 
 #ifdef CONFIG_COMPAT
index 0a8ed3f94e93c3a8e53875ac84c7859ed166e8d8..2593b490c56a319f49946757491851f902ea71e2 100644 (file)
  * 8192 entries of 8 bytes each, occupying a 64KB page. Levels 0 and 1 are not
  * used. The 2nd level table (PGD for Linux) can cover a range of 4TB, each
  * entry representing 512MB. The user and kernel address spaces are limited to
- * 512GB and therefore we only use 1024 entries in the PGD.
+ * 4TB in the 64KB page configuration.
  */
 #define PTRS_PER_PTE           8192
-#define PTRS_PER_PGD           1024
+#define PTRS_PER_PGD           8192
 
 /*
  * PGDIR_SHIFT determines the size a top-level page table entry can map.
index f0bebc5e22cdb662577ab63828d56d105ae18770..17bd3af0a1177d094f27a9a4294dd6eae5103098 100644 (file)
@@ -33,7 +33,7 @@
 /*
  * VMALLOC and SPARSEMEM_VMEMMAP ranges.
  */
-#define VMALLOC_START          UL(0xffffff8000000000)
+#define VMALLOC_START          (UL(0xffffffffffffffff) << VA_BITS)
 #define VMALLOC_END            (PAGE_OFFSET - UL(0x400000000) - SZ_64K)
 
 #define vmemmap                        ((struct page *)(VMALLOC_END + SZ_64K))
index ab239b2c456fa7c0e5950f92490166f0c38de9cf..45b20cd6cbca3ff1bc33df88f46858be36df8e15 100644 (file)
@@ -107,6 +107,11 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
        regs->pstate = COMPAT_PSR_MODE_USR;
        if (pc & 1)
                regs->pstate |= COMPAT_PSR_T_BIT;
+
+#ifdef __AARCH64EB__
+       regs->pstate |= COMPAT_PSR_E_BIT;
+#endif
+
        regs->compat_sp = sp;
 }
 #endif
index 0604237ecd992a6ad41a80587b4533ca987db62c..e5312ea0ec1a59bdd92934926da81155a6ce3e12 100644 (file)
 #ifndef __ASM_PSCI_H
 #define __ASM_PSCI_H
 
-#define PSCI_POWER_STATE_TYPE_STANDBY          0
-#define PSCI_POWER_STATE_TYPE_POWER_DOWN       1
-
-struct psci_power_state {
-       u16     id;
-       u8      type;
-       u8      affinity_level;
-};
-
-struct psci_operations {
-       int (*cpu_suspend)(struct psci_power_state state,
-                          unsigned long entry_point);
-       int (*cpu_off)(struct psci_power_state state);
-       int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
-       int (*migrate)(unsigned long cpuid);
-};
-
-extern struct psci_operations psci_ops;
-
 int psci_init(void);
 
 #endif /* __ASM_PSCI_H */
index 0dacbbf9458b9297ba1a67720665e8a7448a036e..0e7fa49637359ab3cd4757565174d4e63f191cf0 100644 (file)
@@ -42,6 +42,7 @@
 #define COMPAT_PSR_MODE_UND    0x0000001b
 #define COMPAT_PSR_MODE_SYS    0x0000001f
 #define COMPAT_PSR_T_BIT       0x00000020
+#define COMPAT_PSR_E_BIT       0x00000200
 #define COMPAT_PSR_F_BIT       0x00000040
 #define COMPAT_PSR_I_BIT       0x00000080
 #define COMPAT_PSR_A_BIT       0x00000100
index 4b8023c5d14619d23b329cd169b226f412a0e6c3..a498f2cd2c2ad606d612a2192d09c93475bb1ded 100644 (file)
@@ -60,21 +60,14 @@ struct secondary_data {
        void *stack;
 };
 extern struct secondary_data secondary_data;
-extern void secondary_holding_pen(void);
-extern volatile unsigned long secondary_holding_pen_release;
+extern void secondary_entry(void);
 
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
-struct device_node;
+extern int __cpu_disable(void);
 
-struct smp_enable_ops {
-       const char      *name;
-       int             (*init_cpu)(struct device_node *, int);
-       int             (*prepare_cpu)(int);
-};
-
-extern const struct smp_enable_ops smp_spin_table_ops;
-extern const struct smp_enable_ops smp_psci_ops;
+extern void __cpu_die(unsigned int cpu);
+extern void cpu_die(void);
 
 #endif /* ifndef __ASM_SMP_H */
index 0defa0728a9b85f6c82d104f8c3bdb6ea3bf716f..3d5cf064d7a1702992cb89d0fe0914475ae4b1ee 100644 (file)
 /*
  * Spinlock implementation.
  *
- * The old value is read exclusively and the new one, if unlocked, is written
- * exclusively. In case of failure, the loop is restarted.
- *
  * The memory barriers are implicit with the load-acquire and store-release
  * instructions.
- *
- * Unlocked value: 0
- * Locked value: 1
  */
 
-#define arch_spin_is_locked(x)         ((x)->lock != 0)
 #define arch_spin_unlock_wait(lock) \
        do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
 
 static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
        unsigned int tmp;
+       arch_spinlock_t lockval, newval;
 
        asm volatile(
-       "       sevl\n"
-       "1:     wfe\n"
-       "2:     ldaxr   %w0, %1\n"
-       "       cbnz    %w0, 1b\n"
-       "       stxr    %w0, %w2, %1\n"
-       "       cbnz    %w0, 2b\n"
-       : "=&r" (tmp), "+Q" (lock->lock)
-       : "r" (1)
-       : "cc", "memory");
+       /* Atomically increment the next ticket. */
+"      prfm    pstl1strm, %3\n"
+"1:    ldaxr   %w0, %3\n"
+"      add     %w1, %w0, %w5\n"
+"      stxr    %w2, %w1, %3\n"
+"      cbnz    %w2, 1b\n"
+       /* Did we get the lock? */
+"      eor     %w1, %w0, %w0, ror #16\n"
+"      cbz     %w1, 3f\n"
+       /*
+        * No: spin on the owner. Send a local event to avoid missing an
+        * unlock before the exclusive load.
+        */
+"      sevl\n"
+"2:    wfe\n"
+"      ldaxrh  %w2, %4\n"
+"      eor     %w1, %w2, %w0, lsr #16\n"
+"      cbnz    %w1, 2b\n"
+       /* We got the lock. Critical section starts here. */
+"3:"
+       : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock)
+       : "Q" (lock->owner), "I" (1 << TICKET_SHIFT)
+       : "memory");
 }
 
 static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
        unsigned int tmp;
+       arch_spinlock_t lockval;
 
        asm volatile(
-       "2:     ldaxr   %w0, %1\n"
-       "       cbnz    %w0, 1f\n"
-       "       stxr    %w0, %w2, %1\n"
-       "       cbnz    %w0, 2b\n"
-       "1:\n"
-       : "=&r" (tmp), "+Q" (lock->lock)
-       : "r" (1)
-       : "cc", "memory");
+"      prfm    pstl1strm, %2\n"
+"1:    ldaxr   %w0, %2\n"
+"      eor     %w1, %w0, %w0, ror #16\n"
+"      cbnz    %w1, 2f\n"
+"      add     %w0, %w0, %3\n"
+"      stxr    %w1, %w0, %2\n"
+"      cbnz    %w1, 1b\n"
+"2:"
+       : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
+       : "I" (1 << TICKET_SHIFT)
+       : "memory");
 
        return !tmp;
 }
@@ -74,9 +86,28 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
 static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
        asm volatile(
-       "       stlr    %w1, %0\n"
-       : "=Q" (lock->lock) : "r" (0) : "memory");
+"      stlrh   %w1, %0\n"
+       : "=Q" (lock->owner)
+       : "r" (lock->owner + 1)
+       : "memory");
+}
+
+static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
+{
+       return lock.owner == lock.next;
+}
+
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+       return !arch_spin_value_unlocked(ACCESS_ONCE(*lock));
+}
+
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+       arch_spinlock_t lockval = ACCESS_ONCE(*lock);
+       return (lockval.next - lockval.owner) > 1;
 }
+#define arch_spin_is_contended arch_spin_is_contended
 
 /*
  * Write lock implementation.
index 9a494346efede851956b6e24b7c20c6f09415733..b8d383665f56b04a2d44d85664660a5d46b6e40e 100644 (file)
 # error "please don't include this file directly"
 #endif
 
-/* We only require natural alignment for exclusive accesses. */
-#define __lock_aligned
+#define TICKET_SHIFT   16
 
 typedef struct {
-       volatile unsigned int lock;
-} arch_spinlock_t;
+#ifdef __AARCH64EB__
+       u16 next;
+       u16 owner;
+#else
+       u16 owner;
+       u16 next;
+#endif
+} __aligned(4) arch_spinlock_t;
 
-#define __ARCH_SPIN_LOCK_UNLOCKED      { 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED      { 0 , 0 }
 
 typedef struct {
        volatile unsigned int lock;
index 89c047f9a9717efe1d3a83db3988c1c621aa2882..70ba9d4ee9782503fa8c626dd3d405d5e36b93c4 100644 (file)
@@ -59,6 +59,9 @@ static inline void syscall_get_arguments(struct task_struct *task,
                                         unsigned int i, unsigned int n,
                                         unsigned long *args)
 {
+       if (n == 0)
+               return;
+
        if (i + n > SYSCALL_MAX_ARGS) {
                unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
                unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
@@ -82,6 +85,9 @@ static inline void syscall_set_arguments(struct task_struct *task,
                                         unsigned int i, unsigned int n,
                                         const unsigned long *args)
 {
+       if (n == 0)
+               return;
+
        if (i + n > SYSCALL_MAX_ARGS) {
                pr_warning("%s called with max args %d, handling only %d\n",
                           __func__, i + n, SYSCALL_MAX_ARGS);
index 26e310c5434446c7bfc0a9a3f9b443139ffa3368..130e2be952cf6e0ebb6fe137afa93832746724fe 100644 (file)
@@ -18,7 +18,8 @@
 #ifndef __ASM__VIRT_H
 #define __ASM__VIRT_H
 
-#define BOOT_CPU_MODE_EL2      (0x0e12b007)
+#define BOOT_CPU_MODE_EL1      (0xe11)
+#define BOOT_CPU_MODE_EL2      (0xe12)
 
 #ifndef __ASSEMBLY__
 #include <asm/cacheflush.h>
index 2b92046aafc5297ab97a8e91cbbc25b462594bad..dc19e9537f0decad3662b5036aa592466373c5e1 100644 (file)
 #ifndef __ASM_BYTEORDER_H
 #define __ASM_BYTEORDER_H
 
+#ifdef __AARCH64EB__
+#include <linux/byteorder/big_endian.h>
+#else
 #include <linux/byteorder/little_endian.h>
+#endif
 
 #endif /* __ASM_BYTEORDER_H */
index 7b4b564961d48c4be4fa0df2e1e7ad49c7a57224..5ba2fd43a75bd21f64a23c0d41fe61b42091c3e6 100644 (file)
@@ -9,12 +9,12 @@ AFLAGS_head.o         := -DTEXT_OFFSET=$(TEXT_OFFSET)
 arm64-obj-y            := cputable.o debug-monitors.o entry.o irq.o fpsimd.o   \
                           entry-fpsimd.o process.o ptrace.o setup.o signal.o   \
                           sys.o stacktrace.o time.o traps.o io.o vdso.o        \
-                          hyp-stub.o psci.o
+                          hyp-stub.o psci.o cpu_ops.o
 
 arm64-obj-$(CONFIG_COMPAT)             += sys32.o kuser32.o signal32.o         \
                                           sys_compat.o
 arm64-obj-$(CONFIG_MODULES)            += arm64ksyms.o module.o
-arm64-obj-$(CONFIG_SMP)                        += smp.o smp_spin_table.o smp_psci.o
+arm64-obj-$(CONFIG_SMP)                        += smp.o smp_spin_table.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)     += perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)       += early_printk.o
index 41b4f626d5548c10985313839892de44ad81e1ec..e7ee770c06978dcf12181e2393fc89186562990d 100644 (file)
@@ -39,6 +39,7 @@ EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(__copy_from_user);
 EXPORT_SYMBOL(__copy_to_user);
 EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(__copy_in_user);
 
        /* physical memory */
 EXPORT_SYMBOL(memstart_addr);
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
new file mode 100644 (file)
index 0000000..d62d12f
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * CPU kernel entry/exit control
+ *
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <asm/cpu_ops.h>
+#include <asm/smp_plat.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/string.h>
+
+extern const struct cpu_operations smp_spin_table_ops;
+extern const struct cpu_operations cpu_psci_ops;
+
+const struct cpu_operations *cpu_ops[NR_CPUS];
+
+static const struct cpu_operations *supported_cpu_ops[] __initconst = {
+#ifdef CONFIG_SMP
+       &smp_spin_table_ops,
+       &cpu_psci_ops,
+#endif
+       NULL,
+};
+
+static const struct cpu_operations * __init cpu_get_ops(const char *name)
+{
+       const struct cpu_operations **ops = supported_cpu_ops;
+
+       while (*ops) {
+               if (!strcmp(name, (*ops)->name))
+                       return *ops;
+
+               ops++;
+       }
+
+       return NULL;
+}
+
+/*
+ * Read a cpu's enable method from the device tree and record it in cpu_ops.
+ */
+int __init cpu_read_ops(struct device_node *dn, int cpu)
+{
+       const char *enable_method = of_get_property(dn, "enable-method", NULL);
+       if (!enable_method) {
+               /*
+                * The boot CPU may not have an enable method (e.g. when
+                * spin-table is used for secondaries). Don't warn spuriously.
+                */
+               if (cpu != 0)
+                       pr_err("%s: missing enable-method property\n",
+                               dn->full_name);
+               return -ENOENT;
+       }
+
+       cpu_ops[cpu] = cpu_get_ops(enable_method);
+       if (!cpu_ops[cpu]) {
+               pr_warn("%s: unsupported enable-method property: %s\n",
+                       dn->full_name, enable_method);
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+void __init cpu_read_bootcpu_ops(void)
+{
+       struct device_node *dn = of_get_cpu_node(0, NULL);
+       if (!dn) {
+               pr_err("Failed to find device node for boot cpu\n");
+               return;
+       }
+       cpu_read_ops(dn, 0);
+}
index 63cfc4a43f4eeb86b9d0137db0d878d5abdce0d1..fd3993cb060f774d513671ceea1c599c8004ddde 100644 (file)
@@ -22,7 +22,7 @@
 
 extern unsigned long __cpu_setup(void);
 
-struct cpu_info __initdata cpu_table[] = {
+struct cpu_info cpu_table[] = {
        {
                .cpu_id_val     = 0x000f0000,
                .cpu_id_mask    = 0x000f0000,
index 3881fd115ebb14b4b01e872575cbcfd769c76c07..e1166145ca29b59801c84420e1f98225650f4580 100644 (file)
@@ -311,14 +311,14 @@ el1_irq:
 #endif
 #ifdef CONFIG_PREEMPT
        get_thread_info tsk
-       ldr     x24, [tsk, #TI_PREEMPT]         // get preempt count
-       add     x0, x24, #1                     // increment it
-       str     x0, [tsk, #TI_PREEMPT]
+       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     x24, [tsk, #TI_PREEMPT]         // restore preempt count
-       cbnz    x24, 1f                         // preempt count != 0
+       str     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?
        bl      el1_preempt
@@ -509,15 +509,15 @@ el0_irq_naked:
 #endif
        get_thread_info tsk
 #ifdef CONFIG_PREEMPT
-       ldr     x24, [tsk, #TI_PREEMPT]         // get preempt count
-       add     x23, x24, #1                    // increment it
-       str     x23, [tsk, #TI_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     x0, [tsk, #TI_PREEMPT]
-       str     x24, [tsk, #TI_PREEMPT]
-       cmp     x0, x23
+       ldr     w0, [tsk, #TI_PREEMPT]
+       str     w24, [tsk, #TI_PREEMPT]
+       cmp     w0, w23
        b.eq    1f
        mov     x1, #0
        str     x1, [x1]                        // BUG
index 7090c126797cb27e3db102e830d5de72c14c3310..7009387348b7c416f9dc8732a18c7563eac4af4e 100644 (file)
 
 ENTRY(stext)
        mov     x21, x0                         // x21=FDT
+       bl      el2_setup                       // Drop to EL1, w20=cpu_boot_mode
        bl      __calc_phys_offset              // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
-       bl      el2_setup                       // Drop to EL1
+       bl      set_cpu_boot_mode_flag
        mrs     x22, midr_el1                   // x22=cpuid
        mov     x0, x22
        bl      lookup_processor_type
@@ -150,21 +151,30 @@ ENDPROC(stext)
 /*
  * If we're fortunate enough to boot at EL2, ensure that the world is
  * sane before dropping to EL1.
+ *
+ * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if
+ * booted in EL1 or EL2 respectively.
  */
 ENTRY(el2_setup)
        mrs     x0, CurrentEL
        cmp     x0, #PSR_MODE_EL2t
        ccmp    x0, #PSR_MODE_EL2h, #0x4, ne
-       ldr     x0, =__boot_cpu_mode            // Compute __boot_cpu_mode
-       add     x0, x0, x28
-       b.eq    1f
-       str     wzr, [x0]                       // Remember we don't have EL2...
+       b.ne    1f
+       mrs     x0, sctlr_el2
+CPU_BE(        orr     x0, x0, #(1 << 25)      )       // Set the EE bit for EL2
+CPU_LE(        bic     x0, x0, #(1 << 25)      )       // Clear the EE bit for EL2
+       msr     sctlr_el2, x0
+       b       2f
+1:     mrs     x0, sctlr_el1
+CPU_BE(        orr     x0, x0, #(3 << 24)      )       // Set the EE and E0E bits for EL1
+CPU_LE(        bic     x0, x0, #(3 << 24)      )       // Clear the EE and E0E bits for EL1
+       msr     sctlr_el1, x0
+       mov     w20, #BOOT_CPU_MODE_EL1         // This cpu booted in EL1
+       isb
        ret
 
        /* Hyp configuration. */
-1:     ldr     w1, =BOOT_CPU_MODE_EL2
-       str     w1, [x0, #4]                    // This CPU has EL2
-       mov     x0, #(1 << 31)                  // 64-bit EL1
+2:     mov     x0, #(1 << 31)                  // 64-bit EL1
        msr     hcr_el2, x0
 
        /* Generic timers. */
@@ -181,7 +191,8 @@ ENTRY(el2_setup)
 
        /* sctlr_el1 */
        mov     x0, #0x0800                     // Set/clear RES{1,0} bits
-       movk    x0, #0x30d0, lsl #16
+CPU_BE(        movk    x0, #0x33d0, lsl #16    )       // Set EE and E0E on BE systems
+CPU_LE(        movk    x0, #0x30d0, lsl #16    )       // Clear EE and E0E on LE systems
        msr     sctlr_el1, x0
 
        /* Coprocessor traps. */
@@ -204,9 +215,24 @@ ENTRY(el2_setup)
                      PSR_MODE_EL1h)
        msr     spsr_el2, x0
        msr     elr_el2, lr
+       mov     w20, #BOOT_CPU_MODE_EL2         // This CPU booted in EL2
        eret
 ENDPROC(el2_setup)
 
+/*
+ * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
+ * in x20. See arch/arm64/include/asm/virt.h for more info.
+ */
+ENTRY(set_cpu_boot_mode_flag)
+       ldr     x1, =__boot_cpu_mode            // Compute __boot_cpu_mode
+       add     x1, x1, x28
+       cmp     w20, #BOOT_CPU_MODE_EL2
+       b.ne    1f
+       add     x1, x1, #4
+1:     str     w20, [x1]                       // This CPU has booted in EL1
+       ret
+ENDPROC(set_cpu_boot_mode_flag)
+
 /*
  * We need to find out the CPU boot mode long after boot, so we need to
  * store it in a writable variable.
@@ -225,7 +251,6 @@ ENTRY(__boot_cpu_mode)
        .quad   PAGE_OFFSET
 
 #ifdef CONFIG_SMP
-       .pushsection    .smp.pen.text, "ax"
        .align  3
 1:     .quad   .
        .quad   secondary_holding_pen_release
@@ -235,8 +260,9 @@ ENTRY(__boot_cpu_mode)
         * cores are held until we're ready for them to initialise.
         */
 ENTRY(secondary_holding_pen)
-       bl      __calc_phys_offset              // x24=phys offset
-       bl      el2_setup                       // Drop to EL1
+       bl      el2_setup                       // Drop to EL1, w20=cpu_boot_mode
+       bl      __calc_phys_offset              // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
+       bl      set_cpu_boot_mode_flag
        mrs     x0, mpidr_el1
        ldr     x1, =MPIDR_HWID_BITMASK
        and     x0, x0, x1
@@ -250,7 +276,16 @@ pen:       ldr     x4, [x3]
        wfe
        b       pen
 ENDPROC(secondary_holding_pen)
-       .popsection
+
+       /*
+        * Secondary entry point that jumps straight into the kernel. Only to
+        * be used where CPUs are brought online dynamically by the kernel.
+        */
+ENTRY(secondary_entry)
+       bl      __calc_phys_offset              // x2=phys offset
+       bl      el2_setup                       // Drop to EL1
+       b       secondary_startup
+ENDPROC(secondary_entry)
 
 ENTRY(secondary_startup)
        /*
index ecb3354292ed2af479aa7d3df33c1d3100dfdd4e..473e5dbf8f39a39e8eaa7a0740e54ee4d6bacb59 100644 (file)
@@ -81,3 +81,64 @@ void __init init_IRQ(void)
        if (!handle_arch_irq)
                panic("No interrupt controller found.");
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+static bool migrate_one_irq(struct irq_desc *desc)
+{
+       struct irq_data *d = irq_desc_get_irq_data(desc);
+       const struct cpumask *affinity = d->affinity;
+       struct irq_chip *c;
+       bool ret = false;
+
+       /*
+        * If this is a per-CPU interrupt, or the affinity does not
+        * include this CPU, then we have nothing to do.
+        */
+       if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
+               return false;
+
+       if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+               affinity = cpu_online_mask;
+               ret = true;
+       }
+
+       c = irq_data_get_irq_chip(d);
+       if (!c->irq_set_affinity)
+               pr_debug("IRQ%u: unable to set affinity\n", d->irq);
+       else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret)
+               cpumask_copy(d->affinity, affinity);
+
+       return ret;
+}
+
+/*
+ * The current 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.
+ *
+ * Note: we must iterate over all IRQs, whether they have an attached
+ * action structure or not, as we need to get chained interrupts too.
+ */
+void migrate_irqs(void)
+{
+       unsigned int i;
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       for_each_irq_desc(i, desc) {
+               bool affinity_broken;
+
+               raw_spin_lock(&desc->lock);
+               affinity_broken = migrate_one_irq(desc);
+               raw_spin_unlock(&desc->lock);
+
+               if (affinity_broken)
+                       pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n",
+                                           i, smp_processor_id());
+       }
+
+       local_irq_restore(flags);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
index 8b69ecb1d8bc232a70ca16f24475d9aacb9597a2..63c48ffdf230125dedea62d631b3067f4d7a28e1 100644 (file)
@@ -27,6 +27,9 @@
  *
  * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
  */
+
+#include <asm/unistd32.h>
+
        .align  5
        .globl  __kuser_helper_start
 __kuser_helper_start:
@@ -35,33 +38,30 @@ __kuser_cmpxchg64:                  // 0xffff0f60
        .inst   0xe92d00f0              //      push            {r4, r5, r6, r7}
        .inst   0xe1c040d0              //      ldrd            r4, r5, [r0]
        .inst   0xe1c160d0              //      ldrd            r6, r7, [r1]
-       .inst   0xf57ff05f              //      dmb             sy
-       .inst   0xe1b20f9f              // 1:   ldrexd          r0, r1, [r2]
+       .inst   0xe1b20e9f              // 1:   ldaexd          r0, r1, [r2]
        .inst   0xe0303004              //      eors            r3, r0, r4
        .inst   0x00313005              //      eoreqs          r3, r1, r5
-       .inst   0x01a23f96              //      strexdeq        r3, r6, [r2]
+       .inst   0x01a23e96              //      stlexdeq        r3, r6, [r2]
        .inst   0x03330001              //      teqeq           r3, #1
        .inst   0x0afffff9              //      beq             1b
-       .inst   0xf57ff05f              //      dmb             sy
        .inst   0xe2730000              //      rsbs            r0, r3, #0
        .inst   0xe8bd00f0              //      pop             {r4, r5, r6, r7}
        .inst   0xe12fff1e              //      bx              lr
 
        .align  5
 __kuser_memory_barrier:                        // 0xffff0fa0
-       .inst   0xf57ff05f              //      dmb             sy
+       .inst   0xf57ff05b              //      dmb             ish
        .inst   0xe12fff1e              //      bx              lr
 
        .align  5
 __kuser_cmpxchg:                       // 0xffff0fc0
-       .inst   0xf57ff05f              //      dmb             sy
-       .inst   0xe1923f9f              // 1:   ldrex           r3, [r2]
+       .inst   0xe1923e9f              // 1:   ldaex           r3, [r2]
        .inst   0xe0533000              //      subs            r3, r3, r0
-       .inst   0x01823f91              //      strexeq r3, r1, [r2]
+       .inst   0x01823e91              //      stlexeq         r3, r1, [r2]
        .inst   0x03330001              //      teqeq           r3, #1
        .inst   0x0afffffa              //      beq             1b
        .inst   0xe2730000              //      rsbs            r0, r3, #0
-       .inst   0xeaffffef              //      b               <__kuser_memory_barrier>
+       .inst   0xe12fff1e              //      bx              lr
 
        .align  5
 __kuser_get_tls:                       // 0xffff0fe0
@@ -75,3 +75,42 @@ __kuser_helper_version:                      // 0xffff0ffc
        .word   ((__kuser_helper_end - __kuser_helper_start) >> 5)
        .globl  __kuser_helper_end
 __kuser_helper_end:
+
+/*
+ * AArch32 sigreturn code
+ *
+ * For ARM syscalls, the syscall number has to be loaded into r7.
+ * We do not support an OABI userspace.
+ *
+ * For Thumb syscalls, we also pass the syscall number via r7. We therefore
+ * need two 16-bit instructions.
+ */
+       .globl __aarch32_sigret_code_start
+__aarch32_sigret_code_start:
+
+       /*
+        * ARM Code
+        */
+       .byte   __NR_compat_sigreturn, 0x70, 0xa0, 0xe3 // mov  r7, #__NR_compat_sigreturn
+       .byte   __NR_compat_sigreturn, 0x00, 0x00, 0xef // svc  #__NR_compat_sigreturn
+
+       /*
+        * Thumb code
+        */
+       .byte   __NR_compat_sigreturn, 0x27                     // svc  #__NR_compat_sigreturn
+       .byte   __NR_compat_sigreturn, 0xdf                     // mov  r7, #__NR_compat_sigreturn
+
+       /*
+        * ARM code
+        */
+       .byte   __NR_compat_rt_sigreturn, 0x70, 0xa0, 0xe3      // mov  r7, #__NR_compat_rt_sigreturn
+       .byte   __NR_compat_rt_sigreturn, 0x00, 0x00, 0xef      // svc  #__NR_compat_rt_sigreturn
+
+       /*
+        * Thumb code
+        */
+       .byte   __NR_compat_rt_sigreturn, 0x27                  // svc  #__NR_compat_rt_sigreturn
+       .byte   __NR_compat_rt_sigreturn, 0xdf                  // mov  r7, #__NR_compat_rt_sigreturn
+
+        .globl __aarch32_sigret_code_end
+__aarch32_sigret_code_end:
index ca0e3d55da998fe5b302530bad487f52a7127938..2c28a6cf93e610a9484442f662c5975a180b7790 100644 (file)
@@ -111,6 +111,9 @@ static u32 encode_insn_immediate(enum aarch64_imm_type type, u32 insn, u64 imm)
        u32 immlo, immhi, lomask, himask, mask;
        int shift;
 
+       /* The instruction stream is always little endian. */
+       insn = le32_to_cpu(insn);
+
        switch (type) {
        case INSN_IMM_MOVNZ:
                /*
@@ -179,7 +182,7 @@ static u32 encode_insn_immediate(enum aarch64_imm_type type, u32 insn, u64 imm)
        insn &= ~(mask << shift);
        insn |= (imm & mask) << shift;
 
-       return insn;
+       return cpu_to_le32(insn);
 }
 
 static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val,
index cea1594ff933e92e304a6996a4642f18f322487a..5d14470452ac5959712ef9927b3a093bf8975bf3 100644 (file)
@@ -784,8 +784,8 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 /*
  * PMXEVTYPER: Event selection reg
  */
-#define        ARMV8_EVTYPE_MASK       0xc80000ff      /* Mask for writable bits */
-#define        ARMV8_EVTYPE_EVENT      0xff            /* Mask for EVENT bits */
+#define        ARMV8_EVTYPE_MASK       0xc80003ff      /* Mask for writable bits */
+#define        ARMV8_EVTYPE_EVENT      0x3ff           /* Mask for EVENT bits */
 
 /*
  * Event filters for PMUv3
@@ -1175,7 +1175,8 @@ static void armv8pmu_reset(void *info)
 static int armv8_pmuv3_map_event(struct perf_event *event)
 {
        return map_cpu_event(event, &armv8_pmuv3_perf_map,
-                               &armv8_pmuv3_perf_cache_map, 0xFF);
+                               &armv8_pmuv3_perf_cache_map,
+                               ARMV8_EVTYPE_EVENT);
 }
 
 static struct arm_pmu armv8pmu = {
index 7ae8a1f00c3c82bf256f716aee79aaf24fac8f1b..de17c89985dbe6c69aecbb8248155f439fc41c11 100644 (file)
@@ -102,6 +102,13 @@ void arch_cpu_idle(void)
        local_irq_enable();
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void arch_cpu_idle_dead(void)
+{
+       cpu_die();
+}
+#endif
+
 void machine_shutdown(void)
 {
 #ifdef CONFIG_SMP
index 14f73c445ff5076061d865c5a9f0a39cd02226c7..4f97db3d73633294f6a6310e54e626972debc9a2 100644 (file)
 
 #include <linux/init.h>
 #include <linux/of.h>
+#include <linux/smp.h>
 
 #include <asm/compiler.h>
+#include <asm/cpu_ops.h>
 #include <asm/errno.h>
 #include <asm/psci.h>
+#include <asm/smp_plat.h>
 
-struct psci_operations psci_ops;
+#define PSCI_POWER_STATE_TYPE_STANDBY          0
+#define PSCI_POWER_STATE_TYPE_POWER_DOWN       1
+
+struct psci_power_state {
+       u16     id;
+       u8      type;
+       u8      affinity_level;
+};
+
+struct psci_operations {
+       int (*cpu_suspend)(struct psci_power_state state,
+                          unsigned long entry_point);
+       int (*cpu_off)(struct psci_power_state state);
+       int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
+       int (*migrate)(unsigned long cpuid);
+};
+
+static struct psci_operations psci_ops;
 
 static int (*invoke_psci_fn)(u64, u64, u64, u64);
 
@@ -209,3 +229,68 @@ out_put_node:
        of_node_put(np);
        return err;
 }
+
+#ifdef CONFIG_SMP
+
+static int __init cpu_psci_cpu_init(struct device_node *dn, unsigned int cpu)
+{
+       return 0;
+}
+
+static int __init cpu_psci_cpu_prepare(unsigned int cpu)
+{
+       if (!psci_ops.cpu_on) {
+               pr_err("no cpu_on method, not booting CPU%d\n", cpu);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int cpu_psci_cpu_boot(unsigned int cpu)
+{
+       int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry));
+       if (err)
+               pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err);
+
+       return err;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int cpu_psci_cpu_disable(unsigned int cpu)
+{
+       /* Fail early if we don't have CPU_OFF support */
+       if (!psci_ops.cpu_off)
+               return -EOPNOTSUPP;
+       return 0;
+}
+
+static void cpu_psci_cpu_die(unsigned int cpu)
+{
+       int ret;
+       /*
+        * There are no known implementations of PSCI actually using the
+        * power state field, pass a sensible default for now.
+        */
+       struct psci_power_state state = {
+               .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
+       };
+
+       ret = psci_ops.cpu_off(state);
+
+       pr_crit("psci: unable to power off CPU%u (%d)\n", cpu, ret);
+}
+#endif
+
+const struct cpu_operations cpu_psci_ops = {
+       .name           = "psci",
+       .cpu_init       = cpu_psci_cpu_init,
+       .cpu_prepare    = cpu_psci_cpu_prepare,
+       .cpu_boot       = cpu_psci_cpu_boot,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_disable    = cpu_psci_cpu_disable,
+       .cpu_die        = cpu_psci_cpu_die,
+#endif
+};
+
+#endif
index 055cfb80e05c5d8d352880cb6db85d2cdea38241..9cf30f49610d4cc29ff0d728cb7ec8c8a50336f4 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/cputype.h>
 #include <asm/elf.h>
 #include <asm/cputable.h>
+#include <asm/cpu_ops.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
@@ -97,6 +98,11 @@ void __init early_print(const char *str, ...)
        printk("%s", buf);
 }
 
+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+       return phys_id == cpu_logical_map(cpu);
+}
+
 static void __init setup_processor(void)
 {
        struct cpu_info *cpu_info;
@@ -118,7 +124,7 @@ static void __init setup_processor(void)
        printk("CPU: %s [%08x] revision %d\n",
               cpu_name, read_cpuid_id(), read_cpuid_id() & 15);
 
-       sprintf(init_utsname()->machine, "aarch64");
+       sprintf(init_utsname()->machine, ELF_PLATFORM);
        elf_hwcap = 0;
 }
 
@@ -264,6 +270,7 @@ void __init setup_arch(char **cmdline_p)
        psci_init();
 
        cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
+       cpu_read_bootcpu_ops();
 #ifdef CONFIG_SMP
        smp_init_cpus();
 #endif
index e393174fe859721e7f6538bc377577cb69bb68aa..e51bbe79f5b5b9c850207a577e42018caf5fa846 100644 (file)
@@ -100,34 +100,6 @@ struct compat_rt_sigframe {
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/*
- * For ARM syscalls, the syscall number has to be loaded into r7.
- * We do not support an OABI userspace.
- */
-#define MOV_R7_NR_SIGRETURN    (0xe3a07000 | __NR_compat_sigreturn)
-#define SVC_SYS_SIGRETURN      (0xef000000 | __NR_compat_sigreturn)
-#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_compat_rt_sigreturn)
-#define SVC_SYS_RT_SIGRETURN   (0xef000000 | __NR_compat_rt_sigreturn)
-
-/*
- * For Thumb syscalls, we also pass the syscall number via r7. We therefore
- * need two 16-bit instructions.
- */
-#define SVC_THUMB_SIGRETURN    (((0xdf00 | __NR_compat_sigreturn) << 16) | \
-                                  0x2700 | __NR_compat_sigreturn)
-#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_compat_rt_sigreturn) << 16) | \
-                                  0x2700 | __NR_compat_rt_sigreturn)
-
-const compat_ulong_t aarch32_sigret_code[6] = {
-       /*
-        * AArch32 sigreturn code.
-        * We don't construct an OABI SWI - instead we just set the imm24 field
-        * to the EABI syscall number so that we create a sane disassembly.
-        */
-       MOV_R7_NR_SIGRETURN,    SVC_SYS_SIGRETURN,    SVC_THUMB_SIGRETURN,
-       MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN,
-};
-
 static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
 {
        compat_sigset_t cset;
@@ -474,12 +446,13 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
        /* Check if the handler is written for ARM or Thumb */
        thumb = handler & 1;
 
-       if (thumb) {
+       if (thumb)
                spsr |= COMPAT_PSR_T_BIT;
-               spsr &= ~COMPAT_PSR_IT_MASK;
-       } else {
+       else
                spsr &= ~COMPAT_PSR_T_BIT;
-       }
+
+       /* The IT state must be cleared for both ARM and Thumb-2 */
+       spsr &= ~COMPAT_PSR_IT_MASK;
 
        if (ka->sa.sa_flags & SA_RESTORER) {
                retcode = ptr_to_compat(ka->sa.sa_restorer);
index 78db90dcc910c7cdcd112644ded112dbe14acb43..a5aeefab03c3e9cd2c0a241d4f4632bb0933b31f 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
+#include <asm/cpu_ops.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -54,7 +55,6 @@
  * where to place its SVC stack
  */
 struct secondary_data secondary_data;
-volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
 
 enum ipi_msg_type {
        IPI_RESCHEDULE,
@@ -63,61 +63,16 @@ enum ipi_msg_type {
        IPI_CPU_STOP,
 };
 
-static DEFINE_RAW_SPINLOCK(boot_lock);
-
-/*
- * Write secondary_holding_pen_release in a way that is guaranteed to be
- * visible to all observers, irrespective of whether they're taking part
- * in coherency or not.  This is necessary for the hotplug code to work
- * reliably.
- */
-static void write_pen_release(u64 val)
-{
-       void *start = (void *)&secondary_holding_pen_release;
-       unsigned long size = sizeof(secondary_holding_pen_release);
-
-       secondary_holding_pen_release = val;
-       __flush_dcache_area(start, size);
-}
-
 /*
  * Boot a secondary CPU, and assign it the specified idle task.
  * This also gives us the initial stack to use for this CPU.
  */
 static int boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       unsigned long timeout;
-
-       /*
-        * Set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       raw_spin_lock(&boot_lock);
-
-       /*
-        * Update the pen release flag.
-        */
-       write_pen_release(cpu_logical_map(cpu));
-
-       /*
-        * Send an event, causing the secondaries to read pen_release.
-        */
-       sev();
-
-       timeout = jiffies + (1 * HZ);
-       while (time_before(jiffies, timeout)) {
-               if (secondary_holding_pen_release == INVALID_HWID)
-                       break;
-               udelay(10);
-       }
-
-       /*
-        * Now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
-        */
-       raw_spin_unlock(&boot_lock);
+       if (cpu_ops[cpu]->cpu_boot)
+               return cpu_ops[cpu]->cpu_boot(cpu);
 
-       return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0;
+       return -EOPNOTSUPP;
 }
 
 static DECLARE_COMPLETION(cpu_running);
@@ -187,17 +142,13 @@ asmlinkage void secondary_start_kernel(void)
        preempt_disable();
        trace_hardirqs_off();
 
-       /*
-        * Let the primary processor know we're out of the
-        * pen, then head off into the C entry point
-        */
-       write_pen_release(INVALID_HWID);
+       if (cpu_ops[cpu]->cpu_postboot)
+               cpu_ops[cpu]->cpu_postboot();
 
        /*
-        * Synchronise with the boot thread.
+        * Enable GIC and timers.
         */
-       raw_spin_lock(&boot_lock);
-       raw_spin_unlock(&boot_lock);
+       notify_cpu_starting(cpu);
 
        /*
         * OK, now it's safe to let the boot CPU continue.  Wait for
@@ -207,11 +158,6 @@ asmlinkage void secondary_start_kernel(void)
        set_cpu_online(cpu, true);
        complete(&cpu_running);
 
-       /*
-        * Enable GIC and timers.
-        */
-       notify_cpu_starting(cpu);
-
        local_irq_enable();
        local_fiq_enable();
 
@@ -221,39 +167,113 @@ asmlinkage void secondary_start_kernel(void)
        cpu_startup_entry(CPUHP_ONLINE);
 }
 
-void __init smp_cpus_done(unsigned int max_cpus)
+#ifdef CONFIG_HOTPLUG_CPU
+static int op_cpu_disable(unsigned int cpu)
 {
-       pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
+       /*
+        * If we don't have a cpu_die method, abort before we reach the point
+        * of no return. CPU0 may not have an cpu_ops, so test for it.
+        */
+       if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_die)
+               return -EOPNOTSUPP;
+
+       /*
+        * We may need to abort a hot unplug for some other mechanism-specific
+        * reason.
+        */
+       if (cpu_ops[cpu]->cpu_disable)
+               return cpu_ops[cpu]->cpu_disable(cpu);
+
+       return 0;
 }
 
-void __init smp_prepare_boot_cpu(void)
+/*
+ * __cpu_disable runs on the processor to be shutdown.
+ */
+int __cpu_disable(void)
 {
-}
+       unsigned int cpu = smp_processor_id();
+       int ret;
 
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+       ret = op_cpu_disable(cpu);
+       if (ret)
+               return ret;
 
-static const struct smp_enable_ops *enable_ops[] __initconst = {
-       &smp_spin_table_ops,
-       &smp_psci_ops,
-       NULL,
-};
+       /*
+        * 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();
 
-static const struct smp_enable_ops *smp_enable_ops[NR_CPUS];
+       /*
+        * Remove this CPU from the vm mask set of all processes.
+        */
+       clear_tasks_mm_cpumask(cpu);
 
-static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name)
-{
-       const struct smp_enable_ops **ops = enable_ops;
+       return 0;
+}
 
-       while (*ops) {
-               if (!strcmp(name, (*ops)->name))
-                       return *ops;
+static DECLARE_COMPLETION(cpu_died);
 
-               ops++;
+/*
+ * 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)
+{
+       if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
+               pr_crit("CPU%u: cpu didn't die\n", cpu);
+               return;
        }
+       pr_notice("CPU%u: shutdown\n", cpu);
+}
+
+/*
+ * 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 cpu_die(void)
+{
+       unsigned int cpu = smp_processor_id();
+
+       idle_task_exit();
 
-       return NULL;
+       local_irq_disable();
+
+       /* Tell __cpu_die() that this CPU is now safe to dispose of */
+       complete(&cpu_died);
+
+       /*
+        * Actually shutdown the CPU. This must never fail. The specific hotplug
+        * mechanism must perform all required cache maintenance to ensure that
+        * no dirty lines are lost in the process of shutting down the CPU.
+        */
+       cpu_ops[cpu]->cpu_die(cpu);
+
+       BUG();
+}
+#endif
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+       pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
 }
 
+void __init smp_prepare_boot_cpu(void)
+{
+}
+
+static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+
 /*
  * Enumerate the possible CPU set from the device tree and build the
  * cpu logical map array containing MPIDR values related to logical
@@ -261,9 +281,8 @@ static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name)
  */
 void __init smp_init_cpus(void)
 {
-       const char *enable_method;
        struct device_node *dn = NULL;
-       int i, cpu = 1;
+       unsigned int i, cpu = 1;
        bool bootcpu_valid = false;
 
        while ((dn = of_find_node_by_type(dn, "cpu"))) {
@@ -332,25 +351,10 @@ void __init smp_init_cpus(void)
                if (cpu >= NR_CPUS)
                        goto next;
 
-               /*
-                * We currently support only the "spin-table" enable-method.
-                */
-               enable_method = of_get_property(dn, "enable-method", NULL);
-               if (!enable_method) {
-                       pr_err("%s: missing enable-method property\n",
-                               dn->full_name);
+               if (cpu_read_ops(dn, cpu) != 0)
                        goto next;
-               }
-
-               smp_enable_ops[cpu] = smp_get_enable_ops(enable_method);
-
-               if (!smp_enable_ops[cpu]) {
-                       pr_err("%s: invalid enable-method property: %s\n",
-                              dn->full_name, enable_method);
-                       goto next;
-               }
 
-               if (smp_enable_ops[cpu]->init_cpu(dn, cpu))
+               if (cpu_ops[cpu]->cpu_init(dn, cpu))
                        goto next;
 
                pr_debug("cpu logical map 0x%llx\n", hwid);
@@ -380,8 +384,8 @@ next:
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-       int cpu, err;
-       unsigned int ncores = num_possible_cpus();
+       int err;
+       unsigned int cpu, ncores = num_possible_cpus();
 
        /*
         * are we trying to boot more cores than exist?
@@ -408,10 +412,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                if (cpu == smp_processor_id())
                        continue;
 
-               if (!smp_enable_ops[cpu])
+               if (!cpu_ops[cpu])
                        continue;
 
-               err = smp_enable_ops[cpu]->prepare_cpu(cpu);
+               err = cpu_ops[cpu]->cpu_prepare(cpu);
                if (err)
                        continue;
 
@@ -451,7 +455,7 @@ void show_ipi_list(struct seq_file *p, int prec)
        for (i = 0; i < NR_IPI; i++) {
                seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
                           prec >= 4 ? " " : "");
-               for_each_present_cpu(cpu)
+               for_each_online_cpu(cpu)
                        seq_printf(p, "%10u ",
                                   __get_irq_stat(cpu, ipi_irqs[i]));
                seq_printf(p, "      %s\n", ipi_types[i]);
diff --git a/arch/arm64/kernel/smp_psci.c b/arch/arm64/kernel/smp_psci.c
deleted file mode 100644 (file)
index 0c53330..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * PSCI SMP initialisation
- *
- * Copyright (C) 2013 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/smp.h>
-
-#include <asm/psci.h>
-#include <asm/smp_plat.h>
-
-static int __init smp_psci_init_cpu(struct device_node *dn, int cpu)
-{
-       return 0;
-}
-
-static int __init smp_psci_prepare_cpu(int cpu)
-{
-       int err;
-
-       if (!psci_ops.cpu_on) {
-               pr_err("psci: no cpu_on method, not booting CPU%d\n", cpu);
-               return -ENODEV;
-       }
-
-       err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_holding_pen));
-       if (err) {
-               pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err);
-               return err;
-       }
-
-       return 0;
-}
-
-const struct smp_enable_ops smp_psci_ops __initconst = {
-       .name           = "psci",
-       .init_cpu       = smp_psci_init_cpu,
-       .prepare_cpu    = smp_psci_prepare_cpu,
-};
index 7c35fa682f76de7674af23e079b522fc4ac22298..44c22805d2e2ad7e16895dc248bb9e861105fe07 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cpu_ops.h>
+#include <asm/cputype.h>
+#include <asm/smp_plat.h>
+
+extern void secondary_holding_pen(void);
+volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
 
 static phys_addr_t cpu_release_addr[NR_CPUS];
+static DEFINE_RAW_SPINLOCK(boot_lock);
+
+/*
+ * Write secondary_holding_pen_release in a way that is guaranteed to be
+ * visible to all observers, irrespective of whether they're taking part
+ * in coherency or not.  This is necessary for the hotplug code to work
+ * reliably.
+ */
+static void write_pen_release(u64 val)
+{
+       void *start = (void *)&secondary_holding_pen_release;
+       unsigned long size = sizeof(secondary_holding_pen_release);
 
-static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu)
+       secondary_holding_pen_release = val;
+       __flush_dcache_area(start, size);
+}
+
+
+static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu)
 {
        /*
         * Determine the address from which the CPU is polling.
@@ -40,7 +64,7 @@ static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu)
        return 0;
 }
 
-static int __init smp_spin_table_prepare_cpu(int cpu)
+static int smp_spin_table_cpu_prepare(unsigned int cpu)
 {
        void **release_addr;
 
@@ -48,7 +72,16 @@ static int __init smp_spin_table_prepare_cpu(int cpu)
                return -ENODEV;
 
        release_addr = __va(cpu_release_addr[cpu]);
-       release_addr[0] = (void *)__pa(secondary_holding_pen);
+
+       /*
+        * We write the release address as LE regardless of the native
+        * endianess of the kernel. Therefore, any boot-loaders that
+        * read this address need to convert this address to the
+        * boot-loader's endianess before jumping. This is mandated by
+        * the boot protocol.
+        */
+       release_addr[0] = (void *) cpu_to_le64(__pa(secondary_holding_pen));
+
        __flush_dcache_area(release_addr, sizeof(release_addr[0]));
 
        /*
@@ -59,8 +92,60 @@ static int __init smp_spin_table_prepare_cpu(int cpu)
        return 0;
 }
 
-const struct smp_enable_ops smp_spin_table_ops __initconst = {
+static int smp_spin_table_cpu_boot(unsigned int cpu)
+{
+       unsigned long timeout;
+
+       /*
+        * Set synchronisation state between this boot processor
+        * and the secondary one
+        */
+       raw_spin_lock(&boot_lock);
+
+       /*
+        * Update the pen release flag.
+        */
+       write_pen_release(cpu_logical_map(cpu));
+
+       /*
+        * Send an event, causing the secondaries to read pen_release.
+        */
+       sev();
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               if (secondary_holding_pen_release == INVALID_HWID)
+                       break;
+               udelay(10);
+       }
+
+       /*
+        * Now the secondary core is starting up let it run its
+        * calibrations, then wait for it to finish
+        */
+       raw_spin_unlock(&boot_lock);
+
+       return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0;
+}
+
+void smp_spin_table_cpu_postboot(void)
+{
+       /*
+        * Let the primary processor know we're out of the pen.
+        */
+       write_pen_release(INVALID_HWID);
+
+       /*
+        * Synchronise with the boot thread.
+        */
+       raw_spin_lock(&boot_lock);
+       raw_spin_unlock(&boot_lock);
+}
+
+const struct cpu_operations smp_spin_table_ops = {
        .name           = "spin-table",
-       .init_cpu       = smp_spin_table_init_cpu,
-       .prepare_cpu    = smp_spin_table_prepare_cpu,
+       .cpu_init       = smp_spin_table_cpu_init,
+       .cpu_prepare    = smp_spin_table_cpu_prepare,
+       .cpu_boot       = smp_spin_table_cpu_boot,
+       .cpu_postboot   = smp_spin_table_cpu_postboot,
 };
index a1b19ed7467cf1c026147acaa2539b1dc6f60817..423a5b3fc2be0d6736edec7f291175ad5f6df29b 100644 (file)
@@ -59,48 +59,48 @@ ENDPROC(compat_sys_fstatfs64_wrapper)
  * extension.
  */
 compat_sys_pread64_wrapper:
-       orr     x3, x4, x5, lsl #32
+       regs_to_64      x3, x4, x5
        b       sys_pread64
 ENDPROC(compat_sys_pread64_wrapper)
 
 compat_sys_pwrite64_wrapper:
-       orr     x3, x4, x5, lsl #32
+       regs_to_64      x3, x4, x5
        b       sys_pwrite64
 ENDPROC(compat_sys_pwrite64_wrapper)
 
 compat_sys_truncate64_wrapper:
-       orr     x1, x2, x3, lsl #32
+       regs_to_64      x1, x2, x3
        b       sys_truncate
 ENDPROC(compat_sys_truncate64_wrapper)
 
 compat_sys_ftruncate64_wrapper:
-       orr     x1, x2, x3, lsl #32
+       regs_to_64      x1, x2, x3
        b       sys_ftruncate
 ENDPROC(compat_sys_ftruncate64_wrapper)
 
 compat_sys_readahead_wrapper:
-       orr     x1, x2, x3, lsl #32
+       regs_to_64      x1, x2, x3
        mov     w2, w4
        b       sys_readahead
 ENDPROC(compat_sys_readahead_wrapper)
 
 compat_sys_fadvise64_64_wrapper:
        mov     w6, w1
-       orr     x1, x2, x3, lsl #32
-       orr     x2, x4, x5, lsl #32
+       regs_to_64      x1, x2, x3
+       regs_to_64      x2, x4, x5
        mov     w3, w6
        b       sys_fadvise64_64
 ENDPROC(compat_sys_fadvise64_64_wrapper)
 
 compat_sys_sync_file_range2_wrapper:
-       orr     x2, x2, x3, lsl #32
-       orr     x3, x4, x5, lsl #32
+       regs_to_64      x2, x2, x3
+       regs_to_64      x3, x4, x5
        b       sys_sync_file_range2
 ENDPROC(compat_sys_sync_file_range2_wrapper)
 
 compat_sys_fallocate_wrapper:
-       orr     x2, x2, x3, lsl #32
-       orr     x3, x4, x5, lsl #32
+       regs_to_64      x2, x2, x3
+       regs_to_64      x3, x4, x5
        b       sys_fallocate
 ENDPROC(compat_sys_fallocate_wrapper)
 
index 6a389dc1bd499c5de57c1a572bb22fb1a81c1494..65d40cf6945ac20bb501ca65e95450d0458e78ff 100644 (file)
@@ -58,7 +58,10 @@ static struct page *vectors_page[1];
 static int alloc_vectors_page(void)
 {
        extern char __kuser_helper_start[], __kuser_helper_end[];
+       extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];
+
        int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+       int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;
        unsigned long vpage;
 
        vpage = get_zeroed_page(GFP_ATOMIC);
@@ -72,7 +75,7 @@ static int alloc_vectors_page(void)
 
        /* sigreturn code */
        memcpy((void *)vpage + AARCH32_KERN_SIGRET_CODE_OFFSET,
-               aarch32_sigret_code, sizeof(aarch32_sigret_code));
+               __aarch32_sigret_code_start, sigret_sz);
 
        flush_icache_range(vpage, vpage + PAGE_SIZE);
        vectors_page[0] = virt_to_page(vpage);
index f8ab9d8e2ea3343a0b185d1c5d6cd306afa99fc2..5161ad9920910038d710bbf54815503c01b68494 100644 (file)
@@ -54,7 +54,6 @@ SECTIONS
        }
        .text : {                       /* Real text segment            */
                _stext = .;             /* Text and read-only data      */
-                       *(.smp.pen.text)
                        __exception_text_start = .;
                        *(.exception.text)
                        __exception_text_end = .;
@@ -97,30 +96,13 @@ SECTIONS
        PERCPU_SECTION(64)
 
        __init_end = .;
-       . = ALIGN(THREAD_SIZE);
-       __data_loc = .;
-
-       .data : AT(__data_loc) {
-               _data = .;              /* address in memory */
-               _sdata = .;
-
-               /*
-                * first, the init task union, aligned
-                * to an 8192 byte boundary.
-                */
-               INIT_TASK_DATA(THREAD_SIZE)
-               NOSAVE_DATA
-               CACHELINE_ALIGNED_DATA(64)
-               READ_MOSTLY_DATA(64)
-
-               /*
-                * and the usual data section
-                */
-               DATA_DATA
-               CONSTRUCTORS
-
-               _edata = .;
-       }
+
+       . = ALIGN(PAGE_SIZE);
+       _data = .;
+       __data_loc = _data - LOAD_OFFSET;
+       _sdata = .;
+       RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE)
+       _edata = .;
        _edata_loc = __data_loc + SIZEOF(.data);
 
        BSS_SECTION(0, 0, 0)
index ba84e6705e200a063ee40e05d0ff3bc5cb1bf35d..2b0244d65c16f5c68dde0770f555bbadf4a5b073 100644 (file)
@@ -74,7 +74,10 @@ __do_hyp_init:
        msr     mair_el2, x4
        isb
 
-       mov     x4, #SCTLR_EL2_FLAGS
+       mrs     x4, sctlr_el2
+       and     x4, x4, #SCTLR_EL2_EE   // preserve endianness of EL2
+       ldr     x5, =SCTLR_EL2_FLAGS
+       orr     x4, x4, x5
        msr     sctlr_el2, x4
        isb
 
index 1ac0bbbdddb27976ada4376fe4d28538fee7ccc4..3b47c36e10ffcdac920a08277ee9e3e1df00a211 100644 (file)
@@ -403,6 +403,14 @@ __kvm_hyp_code_start:
        ldr     w9, [x2, #GICH_ELRSR0]
        ldr     w10, [x2, #GICH_ELRSR1]
        ldr     w11, [x2, #GICH_APR]
+CPU_BE(        rev     w4,  w4  )
+CPU_BE(        rev     w5,  w5  )
+CPU_BE(        rev     w6,  w6  )
+CPU_BE(        rev     w7,  w7  )
+CPU_BE(        rev     w8,  w8  )
+CPU_BE(        rev     w9,  w9  )
+CPU_BE(        rev     w10, w10 )
+CPU_BE(        rev     w11, w11 )
 
        str     w4, [x3, #VGIC_CPU_HCR]
        str     w5, [x3, #VGIC_CPU_VMCR]
@@ -421,6 +429,7 @@ __kvm_hyp_code_start:
        ldr     w4, [x3, #VGIC_CPU_NR_LR]
        add     x3, x3, #VGIC_CPU_LR
 1:     ldr     w5, [x2], #4
+CPU_BE(        rev     w5, w5 )
        str     w5, [x3], #4
        sub     w4, w4, #1
        cbnz    w4, 1b
@@ -446,6 +455,9 @@ __kvm_hyp_code_start:
        ldr     w4, [x3, #VGIC_CPU_HCR]
        ldr     w5, [x3, #VGIC_CPU_VMCR]
        ldr     w6, [x3, #VGIC_CPU_APR]
+CPU_BE(        rev     w4, w4 )
+CPU_BE(        rev     w5, w5 )
+CPU_BE(        rev     w6, w6 )
 
        str     w4, [x2, #GICH_HCR]
        str     w5, [x2, #GICH_VMCR]
@@ -456,6 +468,7 @@ __kvm_hyp_code_start:
        ldr     w4, [x3, #VGIC_CPU_NR_LR]
        add     x3, x3, #VGIC_CPU_LR
 1:     ldr     w5, [x3], #4
+CPU_BE(        rev     w5, w5 )
        str     w5, [x2], #4
        sub     w4, w4, #1
        cbnz    w4, 1b
index 1725cd6db37a8f5e6a76f84192ef704838efb446..2bb1d586664cc98ce88a0e19db8cb55c6b8b1c53 100644 (file)
@@ -77,8 +77,24 @@ EXPORT_SYMBOL(__ioremap);
 
 void __iounmap(volatile void __iomem *io_addr)
 {
-       void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
+       unsigned long addr = (unsigned long)io_addr & PAGE_MASK;
 
-       vunmap(addr);
+       /*
+        * We could get an address outside vmalloc range in case
+        * of ioremap_cache() reusing a RAM mapping.
+        */
+       if (VMALLOC_START <= addr && addr < VMALLOC_END)
+               vunmap((void *)addr);
 }
 EXPORT_SYMBOL(__iounmap);
+
+void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
+{
+       /* For normal memory we already have a cacheable mapping. */
+       if (pfn_valid(__phys_to_pfn(phys_addr)))
+               return (void __iomem *)__phys_to_virt(phys_addr);
+
+       return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL),
+                               __builtin_return_address(0));
+}
+EXPORT_SYMBOL(ioremap_cache);
index b1b31bbc967b43cceaabaee71d850a6619d2a158..421b99fd635dfae60c36d4c45837d73ca71a7187 100644 (file)
@@ -162,9 +162,9 @@ ENDPROC(__cpu_setup)
         *       CE0      XWHW CZ     ME TEEA S
         * .... .IEE .... NEAI TE.I ..AD DEN0 ACAM
         * 0011 0... 1101 ..0. ..0. 10.. .... .... < hardware reserved
-        * .... .100 .... 01.1 11.1 ..01 0001 1101 < software settings
+        * .... .1.. .... 01.1 11.1 ..01 0001 1101 < software settings
         */
        .type   crval, #object
 crval:
-       .word   0x030802e2                      // clear
+       .word   0x000802e2                      // clear
        .word   0x0405d11d                      // set
index 697d50393dd07d8db81b73e22544aa3fc325d24d..47365b1ccbecfeb9c87f807ad5ab345649572114 100644 (file)
@@ -85,7 +85,7 @@ static int fd_request_irq(void)
 {
        if(MACH_IS_Q40)
                return request_irq(FLOPPY_IRQ, floppy_hardint,
-                                  IRQF_DISABLED, "floppy", floppy_hardint);
+                                  0, "floppy", floppy_hardint);
        else if(MACH_IS_SUN3X)
                return sun3xflop_request_irq();
        return -ENXIO;
index 95231e2f9d646efb00181fbcac41d1cbc637002c..a02ea3a7bb20a0299e0f1bd2bf2306c484a4bc92 100644 (file)
@@ -207,7 +207,7 @@ static int sun3xflop_request_irq(void)
        if(!once) {
                once = 1;
                error = request_irq(FLOPPY_IRQ, sun3xflop_hardint,
-                                   IRQF_DISABLED, "floppy", NULL);
+                                   0, "floppy", NULL);
                return ((error == 0) ? 0 : -1);
        } else return 0;
 }
index 639c731568b0046d2150af8da76c991a55a45855..3fadc4a93d977ec96456bf194b7a34a97daa495e 100644 (file)
@@ -3,3 +3,10 @@
 #else
 #include <asm/uaccess_mm.h>
 #endif
+
+#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
+#include <asm-generic/uaccess-unaligned.h>
+#else
+#define __get_user_unaligned(x, ptr)   __get_user((x), (ptr))
+#define __put_user_unaligned(x, ptr)   __put_user((x), (ptr))
+#endif
index ec30acbfe6db0507a74e2495db5ea24b31ca0e8d..99a98698bc959035fb89c2d004a02800abcf81a4 100644 (file)
@@ -70,7 +70,7 @@ static irqreturn_t hw_tick(int irq, void *dummy)
 
 static struct irqaction m68328_timer_irq = {
        .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = hw_tick,
 };
 
index 0570741e5500b221003e3295f4596673cfa53b4b..d493ac43fe3f900fe1b6ecd999e3452e96bdbfd3 100644 (file)
@@ -59,7 +59,7 @@ static irqreturn_t hw_tick(int irq, void *dummy)
 
 static struct irqaction m68360_timer_irq = {
        .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = hw_tick,
 };
 
index e8f3b97b0f7706ddcbc8dfa33bd412d4c4f84c20..493b3111d4c12b6d96e139a2e96afb84d022f558 100644 (file)
@@ -118,7 +118,7 @@ static irqreturn_t pit_tick(int irq, void *dummy)
 
 static struct irqaction pit_irq = {
        .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = pit_tick,
 };
 
index bb5a25ada84872420e1ac518e85ac647dc5aa818..831a08cf6f40d7e6e6c28594035a75e0c6a8b1c7 100644 (file)
@@ -51,7 +51,7 @@ irqreturn_t mcfslt_profile_tick(int irq, void *dummy)
 
 static struct irqaction mcfslt_profile_irq = {
        .name    = "profile timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = mcfslt_profile_tick,
 };
 
@@ -93,7 +93,7 @@ static irqreturn_t mcfslt_tick(int irq, void *dummy)
 
 static struct irqaction mcfslt_timer_irq = {
        .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = mcfslt_tick,
 };
 
index d06068e457643fc804f0b068679da230e640becb..cd496a20fcc7ced7b802e705badcae2417eb2256 100644 (file)
@@ -83,7 +83,7 @@ static irqreturn_t mcftmr_tick(int irq, void *dummy)
 
 static struct irqaction mcftmr_timer_irq = {
        .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = mcftmr_tick,
 };
 
@@ -171,7 +171,7 @@ irqreturn_t coldfire_profile_tick(int irq, void *dummy)
 
 static struct irqaction coldfire_profile_irq = {
        .name    = "profile timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .flags   = IRQF_TIMER,
        .handler = coldfire_profile_tick,
 };
 
index 2a2c9d55187e075375e892abbc4e23139f63bf86..3b4b7f6c0950ef89d975dc4c1e1845333a6d0fe9 100644 (file)
@@ -159,44 +159,30 @@ void irq_ctx_exit(int cpu)
 
 extern asmlinkage void __do_softirq(void);
 
-asmlinkage void do_softirq(void)
+void do_softirq_own_stack(void)
 {
-       unsigned long flags;
        struct thread_info *curctx;
        union irq_ctx *irqctx;
        u32 *isp;
 
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       if (local_softirq_pending()) {
-               curctx = current_thread_info();
-               irqctx = softirq_ctx[smp_processor_id()];
-               irqctx->tinfo.task = curctx->task;
-
-               /* build the stack frame on the softirq stack */
-               isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info));
-
-               asm volatile (
-                       "MOV   D0.5,%0\n"
-                       "SWAP  A0StP,D0.5\n"
-                       "CALLR D1RtP,___do_softirq\n"
-                       "MOV   A0StP,D0.5\n"
-                       :
-                       : "r" (isp)
-                       : "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4",
-                         "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
-                         "D0.5"
-                       );
-               /*
-                * Shouldn't happen, we returned above if in_interrupt():
-                */
-               WARN_ON_ONCE(softirq_count());
-       }
-
-       local_irq_restore(flags);
+       curctx = current_thread_info();
+       irqctx = softirq_ctx[smp_processor_id()];
+       irqctx->tinfo.task = curctx->task;
+
+       /* build the stack frame on the softirq stack */
+       isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info));
+
+       asm volatile (
+               "MOV   D0.5,%0\n"
+               "SWAP  A0StP,D0.5\n"
+               "CALLR D1RtP,___do_softirq\n"
+               "MOV   A0StP,D0.5\n"
+               :
+               : "r" (isp)
+               : "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4",
+                 "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
+                 "D0.5"
+               );
 }
 #endif
 
index d9d81c2192534b48062fb3f4923ee8ed994dcc7a..6e239123d6fe05e4a4ab2118f76816971c9a522a 100644 (file)
@@ -20,7 +20,6 @@ platforms += mti-sead3
 platforms += netlogic
 platforms += pmcs-msp71xx
 platforms += pnx833x
-platforms += powertv
 platforms += ralink
 platforms += rb532
 platforms += sgi-ip22
index f75ab4a2f2460a0d5652cbcacf25c2b68a2d24c3..17cc7ff8458ce2d16f9f8a3be5a4bdfee752030c 100644 (file)
@@ -8,6 +8,7 @@ config MIPS
        select HAVE_PERF_EVENTS
        select PERF_USE_VMALLOC
        select HAVE_ARCH_KGDB
+       select HAVE_ARCH_TRACEHOOK
        select ARCH_HAVE_CUSTOM_GPIO_H
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
@@ -18,6 +19,7 @@ config MIPS
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select HAVE_DEBUG_KMEMLEAK
+       select HAVE_SYSCALL_TRACEPOINTS
        select ARCH_BINFMT_ELF_RANDOMIZE_PIE
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
        select RTC_LIB if !MACH_LOONGSON
@@ -146,6 +148,7 @@ config MIPS_COBALT
        select CSRC_R4K
        select CEVT_GT641XX
        select DMA_NONCOHERENT
+       select EARLY_PRINTK_8250 if EARLY_PRINTK
        select HW_HAS_PCI
        select I8253
        select I8259
@@ -412,23 +415,6 @@ config PMC_MSP
          of integrated peripherals, interfaces and DSPs in addition to
          a variety of MIPS cores.
 
-config POWERTV
-       bool "Cisco PowerTV"
-       select BOOT_ELF32
-       select CEVT_R4K
-       select CPU_MIPSR2_IRQ_VI
-       select CPU_MIPSR2_IRQ_EI
-       select CSRC_POWERTV
-       select DMA_NONCOHERENT
-       select HW_HAS_PCI
-       select SYS_HAS_CPU_MIPS32_R2
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_BIG_ENDIAN
-       select SYS_SUPPORTS_HIGHMEM
-       select USB_OHCI_LITTLE_ENDIAN
-       help
-         This enables support for the Cisco PowerTV Platform.
-
 config RALINK
        bool "Ralink based machines"
        select CEVT_R4K
@@ -811,7 +797,6 @@ source "arch/mips/jz4740/Kconfig"
 source "arch/mips/lantiq/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmcs-msp71xx/Kconfig"
-source "arch/mips/powertv/Kconfig"
 source "arch/mips/ralink/Kconfig"
 source "arch/mips/sgi-ip27/Kconfig"
 source "arch/mips/sibyte/Kconfig"
@@ -890,9 +875,6 @@ config CSRC_BCM1480
 config CSRC_IOASIC
        bool
 
-config CSRC_POWERTV
-       bool
-
 config CSRC_R4K
        bool
 
@@ -1489,8 +1471,10 @@ config SYS_SUPPORTS_ZBOOT
        bool
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_BZIP2
+       select HAVE_KERNEL_LZ4
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_LZO
+       select HAVE_KERNEL_XZ
 
 config SYS_SUPPORTS_ZBOOT_UART16550
        bool
@@ -1977,6 +1961,7 @@ config MIPS_VPE_APSP_API
 config MIPS_CMP
        bool "MIPS CMP framework support"
        depends on SYS_SUPPORTS_MIPS_CMP
+       select SMP
        select SYNC_R4K
        select SYS_SUPPORTS_SMP
        select SYS_SUPPORTS_SCHED_SMT if SMP
index 37871f0de15eca8c817f38b6dcdbb2b3b9c056b4..b147e7038ff0cb26042555ee6d10eafd8d070ca2 100644 (file)
@@ -20,6 +20,14 @@ config EARLY_PRINTK
          doesn't cooperate with an X server. You should normally say N here,
          unless you want to debug such a crash.
 
+config EARLY_PRINTK_8250
+       bool "8250/16550 and compatible serial early printk driver"
+       depends on EARLY_PRINTK
+       default n
+       help
+         If you say Y here, it will be possible to use a 8250/16550 serial
+         port as the boot console.
+
 config CMDLINE_BOOL
        bool "Built-in kernel command line"
        default n
index ca8f8340d75f535b1cad5c1c8eed14bbc71f9634..de300b9936076faad63463c884687d9e19ea914f 100644 (file)
@@ -285,15 +285,19 @@ endif
 # Other need ECOFF, so we build a 32-bit ELF binary for them which we then
 # convert to ECOFF using elf2ecoff.
 #
+quiet_cmd_32 = OBJCOPY $@
+       cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
 vmlinux.32: vmlinux
-       $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+       $(call cmd,32)
 
 #
 # The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
 # ELF files from 32-bit files by conversion.
 #
+quiet_cmd_64 = OBJCOPY $@
+       cmd_64 = $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
 vmlinux.64: vmlinux
-       $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
+       $(call cmd,64)
 
 all:   $(all-y)
 
@@ -302,10 +306,16 @@ $(boot-y): $(vmlinux-32) FORCE
        $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \
                $(bootvars-y) arch/mips/boot/$@
 
+ifdef CONFIG_SYS_SUPPORTS_ZBOOT
 # boot/compressed
 $(bootz-y): $(vmlinux-32) FORCE
        $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
                $(bootvars-y) 32bit-bfd=$(32bit-bfd) $@
+else
+vmlinuz: FORCE
+       @echo '   CONFIG_SYS_SUPPORTS_ZBOOT is not enabled'
+       /bin/false
+endif
 
 
 CLEAN_FILES += vmlinux.32 vmlinux.64
index c76a90f7866427724d74a4df340ab3de9fdf6d9d..bac19dc43d1ddf6c101ffafaa18c590ccde8d523 100644 (file)
@@ -59,7 +59,7 @@ void __init board_setup(void)
                ret = -ENODEV;
        }
        if (ret)
-               panic("cannot initialize board support\n");
+               panic("cannot initialize board support");
 }
 
 int __init db1235_arch_init(void)
index c3b04c929f29b552014013f253d18e8500faae5b..516225d207eeed9cd934a00c8665cc936061fc1d 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
-#include <asm/mach-ath79/ar933x_uart_platform.h>
 #include "common.h"
 #include "dev-common.h"
 
@@ -68,15 +67,11 @@ static struct resource ar933x_uart_resources[] = {
        },
 };
 
-static struct ar933x_uart_platform_data ar933x_uart_data;
 static struct platform_device ar933x_uart_device = {
        .name           = "ar933x-uart",
        .id             = -1,
        .resource       = ar933x_uart_resources,
        .num_resources  = ARRAY_SIZE(ar933x_uart_resources),
-       .dev = {
-               .platform_data  = &ar933x_uart_data,
-       },
 };
 
 void __init ath79_register_uart(void)
@@ -93,7 +88,6 @@ void __init ath79_register_uart(void)
                ath79_uart_data[0].uartclk = uart_clk_rate;
                platform_device_register(&ath79_uart_device);
        } else if (soc_is_ar933x()) {
-               ar933x_uart_data.uartclk = uart_clk_rate;
                platform_device_register(&ar933x_uart_device);
        } else {
                BUG();
index f3bf6d5bfb9d9430023d001e98c7468fa342b1eb..c52daf9b05c638afbe4062ea204bb6522c15ccd1 100644 (file)
@@ -4,4 +4,5 @@
 #
 
 obj-y                          += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
+obj-y                          += board.o
 obj-$(CONFIG_BCM47XX_SSB)      += wgt634u.o
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c
new file mode 100644 (file)
index 0000000..f3f6bfe
--- /dev/null
@@ -0,0 +1,309 @@
+#include <linux/export.h>
+#include <linux/string.h>
+#include <bcm47xx_board.h>
+#include <bcm47xx_nvram.h>
+
+struct bcm47xx_board_type {
+       const enum bcm47xx_board board;
+       const char *name;
+};
+
+struct bcm47xx_board_type_list1 {
+       struct bcm47xx_board_type board;
+       const char *value1;
+};
+
+struct bcm47xx_board_type_list2 {
+       struct bcm47xx_board_type board;
+       const char *value1;
+       const char *value2;
+};
+
+struct bcm47xx_board_type_list3 {
+       struct bcm47xx_board_type board;
+       const char *value1;
+       const char *value2;
+       const char *value3;
+};
+
+struct bcm47xx_board_store {
+       enum bcm47xx_board board;
+       char name[BCM47XX_BOARD_MAX_NAME];
+};
+
+/* model_name */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = {
+       {{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"},
+       {{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"},
+       { {0}, 0},
+};
+
+/* model_no */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_model_no[] __initconst = {
+       {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "WL700"},
+       { {0}, 0},
+};
+
+/* machine_name */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = {
+       {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "WRTSL54GS"},
+       { {0}, 0},
+};
+
+/* hardware_version */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
+       {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"},
+       {{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"},
+       {{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"},
+       {{BCM47XX_BOARD_ASUS_WL500GD, "Asus WL500GD"}, "WL500gd-"},
+       {{BCM47XX_BOARD_ASUS_WL500GPV1, "Asus WL500GP V1"}, "WL500gp-"},
+       {{BCM47XX_BOARD_ASUS_WL500GPV2, "Asus WL500GP V2"}, "WL500GPV2-"},
+       {{BCM47XX_BOARD_ASUS_WL500W, "Asus WL500W"}, "WL500gW-"},
+       {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"},
+       {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"},
+       {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"},
+       { {0}, 0},
+};
+
+/* productid */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
+       {{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"},
+       {{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"},
+       {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"},
+       {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RT-N10U"},
+       {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
+       {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RT-N12B1"},
+       {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RT-N12C1"},
+       {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RT-N12D1"},
+       {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RT-N12HP"},
+       {{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"},
+       {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"},
+       {{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"},
+       {{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"},
+       {{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"},
+       {{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"},
+       { {0}, 0},
+};
+
+/* ModelId */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = {
+       {{BCM47XX_BOARD_DELL_TM2300, "Dell WX-5565"}, "WX-5565"},
+       {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"},
+       {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"},
+       {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"},
+       { {0}, 0},
+};
+
+/* melco_id or buf1falo_id */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_melco_id[] __initconst = {
+       {{BCM47XX_BOARD_BUFFALO_WBR2_G54, "Buffalo WBR2-G54"}, "29bb0332"},
+       {{BCM47XX_BOARD_BUFFALO_WHR2_A54G54, "Buffalo WHR2-A54G54"}, "290441dd"},
+       {{BCM47XX_BOARD_BUFFALO_WHR_G125, "Buffalo WHR-G125"}, "32093"},
+       {{BCM47XX_BOARD_BUFFALO_WHR_G54S, "Buffalo WHR-G54S"}, "30182"},
+       {{BCM47XX_BOARD_BUFFALO_WHR_HP_G54, "Buffalo WHR-HP-G54"}, "30189"},
+       {{BCM47XX_BOARD_BUFFALO_WLA2_G54L, "Buffalo WLA2-G54L"}, "29129"},
+       {{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"},
+       {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"},
+       {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"},
+       { {0}, 0},
+};
+
+/* boot_hw_model, boot_hw_ver */
+static const
+struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = {
+       /* like WRT160N v3.0 */
+       {{BCM47XX_BOARD_CISCO_M10V1, "Cisco M10"}, "M10", "1.0"},
+       /* like WRT310N v2.0 */
+       {{BCM47XX_BOARD_CISCO_M20V1, "Cisco M20"}, "M20", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_E900V1, "Linksys E900 V1"}, "E900", "1.0"},
+       /* like WRT160N v3.0 */
+       {{BCM47XX_BOARD_LINKSYS_E1000V1, "Linksys E1000 V1"}, "E100", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_E1000V2, "Linksys E1000 V2"}, "E1000", "2.0"},
+       {{BCM47XX_BOARD_LINKSYS_E1000V21, "Linksys E1000 V2.1"}, "E1000", "2.1"},
+       {{BCM47XX_BOARD_LINKSYS_E1200V2, "Linksys E1200 V2"}, "E1200", "2.0"},
+       {{BCM47XX_BOARD_LINKSYS_E2000V1, "Linksys E2000 V1"}, "Linksys E2000", "1.0"},
+       /* like WRT610N v2.0 */
+       {{BCM47XX_BOARD_LINKSYS_E3000V1, "Linksys E3000 V1"}, "E300", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_E3200V1, "Linksys E3200 V1"}, "E3200", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_E4200V1, "Linksys E4200 V1"}, "E4200", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT150NV11, "Linksys WRT150N V1.1"}, "WRT150N", "1.1"},
+       {{BCM47XX_BOARD_LINKSYS_WRT150NV1, "Linksys WRT150N V1"}, "WRT150N", "1"},
+       {{BCM47XX_BOARD_LINKSYS_WRT160NV1, "Linksys WRT160N V1"}, "WRT160N", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT160NV3, "Linksys WRT160N V3"}, "WRT160N", "3.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT300NV11, "Linksys WRT300N V1.1"}, "WRT300N", "1.1"},
+       {{BCM47XX_BOARD_LINKSYS_WRT310NV1, "Linksys WRT310N V1"}, "WRT310N", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT310NV2, "Linksys WRT310N V2"}, "WRT310N", "2.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"},
+       {{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"},
+       { {0}, 0},
+};
+
+/* board_id */
+static const
+struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
+       {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR3300, "Netgear WNDR3300"}, "U12H093T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR3400V1, "Netgear WNDR3400 V1"}, "U12H155T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR3400V2, "Netgear WNDR3400 V2"}, "U12H187T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR3400VCNA, "Netgear WNDR3400 Vcna"}, "U12H155T01_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR3700V3, "Netgear WNDR3700 V3"}, "U12H194T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR4000, "Netgear WNDR4000"}, "U12H181T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR4500V1, "Netgear WNDR4500 V1"}, "U12H189T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR4500V2, "Netgear WNDR4500 V2"}, "U12H224T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNR2000, "Netgear WNR2000"}, "U12H114T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "U12H136T99_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNR3500U, "Netgear WNR3500U"}, "U12H136T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"},
+       { {0}, 0},
+};
+
+/* boardtype, boardnum, boardrev */
+static const
+struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
+       {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"},
+       {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
+       {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
+       { {0}, 0},
+};
+
+static const
+struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = {
+       {BCM47XX_BOARD_UNKNOWN, "Unknown Board"},
+};
+
+static struct bcm47xx_board_store bcm47xx_board = {BCM47XX_BOARD_NO, "Unknown Board"};
+
+static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
+{
+       char buf1[30];
+       char buf2[30];
+       char buf3[30];
+       const struct bcm47xx_board_type_list1 *e1;
+       const struct bcm47xx_board_type_list2 *e2;
+       const struct bcm47xx_board_type_list3 *e3;
+
+       if (bcm47xx_nvram_getenv("model_name", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_model_name; e1->value1; e1++) {
+                       if (!strcmp(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("model_no", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_model_no; e1->value1; e1++) {
+                       if (strstarts(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("machine_name", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_machine_name; e1->value1; e1++) {
+                       if (strstarts(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) {
+                       if (strstarts(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) {
+                       if (!strcmp(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("ModelId", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_ModelId; e1->value1; e1++) {
+                       if (!strcmp(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("melco_id", buf1, sizeof(buf1)) >= 0 ||
+           bcm47xx_nvram_getenv("buf1falo_id", buf1, sizeof(buf1)) >= 0) {
+               /* buffalo hardware, check id for specific hardware matches */
+               for (e1 = bcm47xx_board_list_melco_id; e1->value1; e1++) {
+                       if (!strcmp(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("boot_hw_model", buf1, sizeof(buf1)) >= 0 &&
+           bcm47xx_nvram_getenv("boot_hw_ver", buf2, sizeof(buf2)) >= 0) {
+               for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
+                       if (!strcmp(buf1, e2->value1) &&
+                           !strcmp(buf2, e2->value2))
+                               return &e2->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("board_id", buf1, sizeof(buf1)) >= 0) {
+               for (e1 = bcm47xx_board_list_board_id; e1->value1; e1++) {
+                       if (!strcmp(buf1, e1->value1))
+                               return &e1->board;
+               }
+       }
+
+       if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 &&
+           bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0 &&
+           bcm47xx_nvram_getenv("boardrev", buf3, sizeof(buf3)) >= 0) {
+               for (e3 = bcm47xx_board_list_board; e3->value1; e3++) {
+                       if (!strcmp(buf1, e3->value1) &&
+                           !strcmp(buf2, e3->value2) &&
+                           !strcmp(buf3, e3->value3))
+                               return &e3->board;
+               }
+       }
+       return bcm47xx_board_unknown;
+}
+
+void __init bcm47xx_board_detect(void)
+{
+       int err;
+       char buf[10];
+       const struct bcm47xx_board_type *board_detected;
+
+       if (bcm47xx_board.board != BCM47XX_BOARD_NO)
+               return;
+
+       /* check if the nvram is available */
+       err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
+
+       /* init of nvram failed, probably too early now */
+       if (err == -ENXIO) {
+               return;
+       }
+
+       board_detected = bcm47xx_board_get_nvram();
+       bcm47xx_board.board = board_detected->board;
+       strlcpy(bcm47xx_board.name, board_detected->name,
+               BCM47XX_BOARD_MAX_NAME);
+}
+
+enum bcm47xx_board bcm47xx_board_get(void)
+{
+       return bcm47xx_board.board;
+}
+EXPORT_SYMBOL(bcm47xx_board_get);
+
+const char *bcm47xx_board_get_name(void)
+{
+       return bcm47xx_board.name;
+}
+EXPORT_SYMBOL(bcm47xx_board_get_name);
index cc40b74940f5f6531e4e74cfcf4c665a7b13a9fd..b4c585b1c62eb6279504daea7e1f3a2e7d0b777d 100644 (file)
@@ -190,3 +190,23 @@ int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len)
        return -ENOENT;
 }
 EXPORT_SYMBOL(bcm47xx_nvram_getenv);
+
+int bcm47xx_nvram_gpio_pin(const char *name)
+{
+       int i, err;
+       char nvram_var[10];
+       char buf[30];
+
+       for (i = 0; i < 16; i++) {
+               err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
+               if (err <= 0)
+                       continue;
+               err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf));
+               if (err <= 0)
+                       continue;
+               if (!strcmp(name, buf))
+                       return i;
+       }
+       return -ENOENT;
+}
+EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
index 8c155afb1299e7eda1a413cf4fe4fff3e3d2f093..5cba318bc1cd8e1ce32a8535ecbf79acf1000bf5 100644 (file)
 #include <asm/bootinfo.h>
 #include <asm/fw/cfe/cfe_api.h>
 #include <asm/fw/cfe/cfe_error.h>
+#include <bcm47xx.h>
+#include <bcm47xx_board.h>
 
 static int cfe_cons_handle;
 
+static u16 get_chip_id(void)
+{
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               return bcm47xx_bus.ssb.chip_id;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return bcm47xx_bus.bcma.bus.chipinfo.id;
+#endif
+       }
+       return 0;
+}
+
 const char *get_system_type(void)
 {
-       return "Broadcom BCM47XX";
+       static char buf[50];
+       u16 chip_id = get_chip_id();
+
+       snprintf(buf, sizeof(buf),
+                (chip_id > 0x9999) ? "Broadcom BCM%d (%s)" :
+                                     "Broadcom BCM%04X (%s)",
+                chip_id, bcm47xx_board_get_name());
+
+       return buf;
 }
 
 void prom_putchar(char c)
index b2246cd9ca1283eeccddbc8309c49eca28364c9a..1f30571968e78194ad6338b4f0ac3cb3b64332bc 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/time.h>
 #include <bcm47xx.h>
 #include <bcm47xx_nvram.h>
+#include <bcm47xx_board.h>
 
 union bcm47xx_bus bcm47xx_bus;
 EXPORT_SYMBOL(bcm47xx_bus);
@@ -221,6 +222,7 @@ void __init plat_mem_setup(void)
        _machine_restart = bcm47xx_machine_restart;
        _machine_halt = bcm47xx_machine_halt;
        pm_power_off = bcm47xx_machine_halt;
+       bcm47xx_board_detect();
 }
 
 static int __init bcm47xx_register_bus_complete(void)
index 536374dcba78995981b2a0bc04ab7ae62941aa00..2c85d9254b5e91d017e6a36351294e0c7b931d74 100644 (file)
 #include <linux/ssb/ssb.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
+#include <bcm47xx_nvram.h>
+#include <bcm47xx_board.h>
 
 void __init plat_time_init(void)
 {
        unsigned long hz = 0;
+       u16 chip_id = 0;
+       char buf[10];
+       int len;
+       enum bcm47xx_board board = bcm47xx_board_get();
 
        /*
         * Use deterministic values for initial counter interrupt
@@ -43,15 +49,32 @@ void __init plat_time_init(void)
 #ifdef CONFIG_BCM47XX_SSB
        case BCM47XX_BUS_TYPE_SSB:
                hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
+               chip_id = bcm47xx_bus.ssb.chip_id;
                break;
 #endif
 #ifdef CONFIG_BCM47XX_BCMA
        case BCM47XX_BUS_TYPE_BCMA:
                hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
+               chip_id = bcm47xx_bus.bcma.bus.chipinfo.id;
                break;
 #endif
        }
 
+       if (chip_id == 0x5354) {
+               len = bcm47xx_nvram_getenv("clkfreq", buf, sizeof(buf));
+               if (len >= 0 && !strncmp(buf, "200", 4))
+                       hz = 100000000;
+       }
+
+       switch (board) {
+       case BCM47XX_BOARD_ASUS_WL520GC:
+       case BCM47XX_BOARD_ASUS_WL520GU:
+               hz = 100000000;
+               break;
+       default:
+               break;
+       }
+
        if (!hz)
                hz = 100000000;
 
index 0048c08978965428a32a03bf211c3f86909c12fb..ca0c343c9ea5ed024b87a5e314b4118d9ecff04e 100644 (file)
@@ -37,6 +37,10 @@ vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
 vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY)                += $(obj)/uart-alchemy.o
 endif
 
+ifdef CONFIG_KERNEL_XZ
+vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o
+endif
+
 targets += vmlinux.bin
 OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
 $(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
@@ -44,8 +48,10 @@ $(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
 
 tool_$(CONFIG_KERNEL_GZIP)    = gzip
 tool_$(CONFIG_KERNEL_BZIP2)   = bzip2
+tool_$(CONFIG_KERNEL_LZ4)     = lz4
 tool_$(CONFIG_KERNEL_LZMA)    = lzma
 tool_$(CONFIG_KERNEL_LZO)     = lzo
+tool_$(CONFIG_KERNEL_XZ)      = xzkern
 
 targets += vmlinux.bin.z
 $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
index 2c9573098c0dab7889895de68c2dae5bb9ad9ba8..a8c6fd6a440667cf58c35d4655862783de7d271f 100644 (file)
@@ -43,7 +43,8 @@ void error(char *x)
 /* activate the code for pre-boot environment */
 #define STATIC static
 
-#ifdef CONFIG_KERNEL_GZIP
+#if defined(CONFIG_KERNEL_GZIP) || defined(CONFIG_KERNEL_XZ) || \
+       defined(CONFIG_KERNEL_LZ4)
 void *memcpy(void *dest, const void *src, size_t n)
 {
        int i;
@@ -54,6 +55,8 @@ void *memcpy(void *dest, const void *src, size_t n)
                d[i] = s[i];
        return dest;
 }
+#endif
+#ifdef CONFIG_KERNEL_GZIP
 #include "../../../../lib/decompress_inflate.c"
 #endif
 
@@ -70,6 +73,10 @@ void *memset(void *s, int c, size_t n)
 #include "../../../../lib/decompress_bunzip2.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
@@ -78,6 +85,10 @@ void *memset(void *s, int c, size_t n)
 #include "../../../../lib/decompress_unlzo.c"
 #endif
 
+#ifdef CONFIG_KERNEL_XZ
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
 void decompress_kernel(unsigned long boot_heap_start)
 {
        unsigned long zimage_start, zimage_size;
index 8e6b07ca2f5e6924b68b8ce177aa7c9e7119e80e..5a33409c7f63b09bf7599ed77a4dd762c99f8ead 100644 (file)
@@ -8,6 +8,9 @@
 
 OUTPUT_ARCH(mips)
 ENTRY(start)
+PHDRS {
+       text PT_LOAD FLAGS(7); /* RWX */
+}
 SECTIONS
 {
        /* Text and read-only data */
@@ -15,7 +18,7 @@ SECTIONS
        .text : {
                *(.text)
                *(.rodata)
-       }
+       }: text
        /* End of text section */
 
        /* Writable data */
index 83e5c3813d676f168887ceb6af739700fea28734..7a75ce2c1bcdb99060a3392b04b3d5d5863a7729 100644 (file)
@@ -12,7 +12,6 @@ typedef struct filehdr {
 } FILHDR;
 #define FILHSZ sizeof(FILHDR)
 
-#define OMAGIC         0407
 #define MIPSEBMAGIC    0x160
 #define MIPSELMAGIC    0x162
 
index b212ae12e5ac7dc8ca35dfb24324ba638353f85e..331b837cec57d284d704282aec779056c7f623be 100644 (file)
@@ -999,7 +999,7 @@ void __init plat_mem_setup(void)
 
        if (total == 0)
                panic("Unable to allocate memory from "
-                     "cvmx_bootmem_phy_alloc\n");
+                     "cvmx_bootmem_phy_alloc");
 }
 
 /*
@@ -1081,7 +1081,7 @@ void __init device_tree_init(void)
        /* Copy the default tree from init memory. */
        initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
        if (initial_boot_params == NULL)
-               panic("Could not allocate initial_boot_params\n");
+               panic("Could not allocate initial_boot_params");
        memcpy(initial_boot_params, fdt, dt_size);
 
        if (do_prune) {
index 61a334ac43ac7c52565713e4a45ed882da57132d..558e94977942033dc8247bcc510ebb705aa9698a 100644 (file)
@@ -5,5 +5,4 @@
 obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o
 
 obj-$(CONFIG_PCI)              += pci.o
-obj-$(CONFIG_EARLY_PRINTK)     += console.o
 obj-$(CONFIG_MTD_PHYSMAP)      += mtd.o
diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c
deleted file mode 100644 (file)
index d1ba701..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * (C) P. Horton 2006
- */
-#include <linux/io.h>
-#include <linux/serial_reg.h>
-
-#include <cobalt.h>
-
-#define UART_BASE      ((void __iomem *)CKSEG1ADDR(0x1c800000))
-
-void prom_putchar(char c)
-{
-       if (cobalt_board_id <= COBALT_BRD_ID_QUBE1)
-               return;
-
-       while (!(readb(UART_BASE + UART_LSR) & UART_LSR_THRE))
-               ;
-
-       writeb(c, UART_BASE + UART_TX);
-}
index ec3b2c417f7cc42b1d3390355cd1067547664022..9a8c2fe8d3345a95a644787668e118bbfa51fedb 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
+#include <asm/setup.h>
 #include <asm/gt64120.h>
 
 #include <cobalt.h>
@@ -112,6 +113,8 @@ void __init prom_init(void)
        }
 
        add_memory_region(0x0, memsz, BOOT_MEM_RAM);
+
+       setup_8250_early_printk_port(CKSEG1ADDR(0x1c800000), 0, 0);
 }
 
 void __init prom_free_prom_memory(void)
diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig
deleted file mode 100644 (file)
index 7fda0ce..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-CONFIG_POWERTV=y
-CONFIG_BOOTLOADER_FAMILY="R2"
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_1000=y
-CONFIG_PREEMPT=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE=""
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_RD_GZIP is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS_ALL=y
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_EPOLL is not set
-# CONFIG_SIGNALFD is not set
-# CONFIG_EVENTFD is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_SLUB_DEBUG is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_PNP=y
-CONFIG_SYN_COOKIES=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=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-CONFIG_IPV6_TUNNEL=y
-CONFIG_NETFILTER=y
-# CONFIG_BRIDGE_NETFILTER is not set
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP6_NF_IPTABLES=y
-CONFIG_IP6_NF_FILTER=y
-CONFIG_BRIDGE=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_TBF=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_MISC_DEVICES is not set
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_ATA=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_WLAN is not set
-CONFIG_USB_RTL8150=y
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
-# CONFIG_VGA_ARB is not set
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_CP210X=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_FUSE_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_EARLY_PRINTK is not set
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
index 22afed16ccde293a741e88c9f2fd9f56b733ccd1..41a2fa1fa12e549f75f094505ca044a19b56088d 100644 (file)
  *            7        FPU/R4k timer
  *
  * We handle the IRQ according to _our_ priority (see setup.c),
- * then we just return.         If multiple IRQs are pending then we will
+ * then we just return.  If multiple IRQs are pending then we will
  * just take another exception, big deal.
  */
                .align  5
                /*
                 * Find irq with highest priority
                 */
-                PTR_LA t1,cpu_mask_nr_tbl
+                PTR_LA t1,cpu_mask_nr_tbl
 1:             lw      t2,(t1)
                nop
                and     t2,t0
                /*
                 * Find irq with highest priority
                 */
-                PTR_LA t1,asic_mask_nr_tbl
+                PTR_LA t1,asic_mask_nr_tbl
 2:             lw      t2,(t1)
                nop
                and     t2,t0
                FEXPORT(cpu_all_int)            # HALT, timers, software junk
                li      a0,DEC_CPU_IRQ_BASE
                srl     t0,CAUSEB_IP
-               li      t1,CAUSEF_IP>>CAUSEB_IP # mask
+               li      t1,CAUSEF_IP>>CAUSEB_IP # mask
                b       1f
                 li     t2,4                    # nr of bits / 2
 
index 4b3e3a4375a6756b2af743c3f163d50055fb2c45..e04d973ce5aa24cd832771b417b0b5ce23f14ac4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     DEC I/O ASIC interrupts.
  *
- *     Copyright (c) 2002, 2003  Maciej W. Rozycki
+ *     Copyright (c) 2002, 2003, 2013  Maciej W. Rozycki
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -51,22 +51,51 @@ static struct irq_chip ioasic_irq_type = {
        .irq_unmask = unmask_ioasic_irq,
 };
 
-void clear_ioasic_dma_irq(unsigned int irq)
+static void clear_ioasic_dma_irq(struct irq_data *d)
 {
        u32 sir;
 
-       sir = ~(1 << (irq - ioasic_irq_base));
+       sir = ~(1 << (d->irq - ioasic_irq_base));
        ioasic_write(IO_REG_SIR, sir);
+       fast_iob();
 }
 
 static struct irq_chip ioasic_dma_irq_type = {
        .name = "IO-ASIC-DMA",
-       .irq_ack = ack_ioasic_irq,
+       .irq_ack = clear_ioasic_dma_irq,
        .irq_mask = mask_ioasic_irq,
-       .irq_mask_ack = ack_ioasic_irq,
        .irq_unmask = unmask_ioasic_irq,
+       .irq_eoi = clear_ioasic_dma_irq,
 };
 
+/*
+ * I/O ASIC implements two kinds of DMA interrupts, informational and
+ * error interrupts.
+ *
+ * The formers do not stop DMA and should be cleared as soon as possible
+ * so that if they retrigger before the handler has completed, usually as
+ * a side effect of actions taken by the handler, then they are reissued.
+ * These use the `handle_edge_irq' handler that clears the request right
+ * away.
+ *
+ * The latters stop DMA and do not resume it until the interrupt has been
+ * cleared.  This cannot be done until after a corrective action has been
+ * taken and this also means they will not retrigger.  Therefore they use
+ * the `handle_fasteoi_irq' handler that only clears the request on the
+ * way out.  Because MIPS processor interrupt inputs, one of which the I/O
+ * ASIC is cascaded to, are level-triggered it is recommended that error
+ * DMA interrupt action handlers are registered with the IRQF_ONESHOT flag
+ * set so that they are run with the interrupt line masked.
+ *
+ * This mask has `1' bits in the positions of informational interrupts.
+ */
+#define IO_IRQ_DMA_INFO                                                        \
+       (IO_IRQ_MASK(IO_INR_SCC0A_RXDMA) |                              \
+        IO_IRQ_MASK(IO_INR_SCC1A_RXDMA) |                              \
+        IO_IRQ_MASK(IO_INR_ISDN_TXDMA) |                               \
+        IO_IRQ_MASK(IO_INR_ISDN_RXDMA) |                               \
+        IO_IRQ_MASK(IO_INR_ASC_DMA))
+
 void __init init_ioasic_irqs(int base)
 {
        int i;
@@ -79,7 +108,9 @@ void __init init_ioasic_irqs(int base)
                irq_set_chip_and_handler(i, &ioasic_irq_type,
                                         handle_level_irq);
        for (; i < base + IO_IRQ_LINES; i++)
-               irq_set_chip(i, &ioasic_dma_irq_type);
+               irq_set_chip_and_handler(i, &ioasic_dma_irq_type,
+                                        1 << (i - base) & IO_IRQ_DMA_INFO ?
+                                        handle_edge_irq : handle_fasteoi_irq);
 
        ioasic_irq_base = base;
 }
index c0d1522d448f91591e06131454598232f931198a..8c8498159e434fa039f7ecae3e290ee0c31d6677 100644 (file)
@@ -14,7 +14,7 @@
 
 /* Maximum number of arguments supported.  Must be even!  */
 #define O32_ARGC       32
-/* Number of static registers we save. */
+/* Number of static registers we save.  */
 #define O32_STATC      11
 /* Frame size for both of the above.  */
 #define O32_FRAMESZ    (4 * O32_ARGC + SZREG * O32_STATC)
index 468f665de7bb731e5d8cf71dcef5c1461c146e48..4e1761e0a09af73a8e9477e09e0ce34e7a981a0e 100644 (file)
@@ -104,7 +104,7 @@ void __init prom_init(void)
        if (prom_is_rex(magic))
                rex_clear_cache();
 
-       /* Register the early console.  */
+       /* Register the early console.  */
        register_prom_console();
 
        /* Were we compiled with the right CPU option? */
index 0aadac74290031dffd4d49a3d80de9054118e93a..8c62316f22f438b4b9cc18b23585f3e0ad8b7258 100644 (file)
@@ -22,7 +22,7 @@ volatile unsigned long mem_err;               /* So we know an error occurred */
 
 /*
  * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
- * off the end of real memory. Only suitable for the 2100/3100's (PMAX).
+ * off the end of real memory.  Only suitable for the 2100/3100's (PMAX).
  */
 
 #define CHUNK_SIZE 0x400000
index 741cb4235bde2106e2e152bcd1caa2ca63c020b9..56e6e2c23683b328c22f51831908414750cf710a 100644 (file)
@@ -65,7 +65,7 @@ EXPORT_SYMBOL(ioasic_base);
 /*
  * IRQ routing and priority tables.  Priorites are set as follows:
  *
- *             KN01    KN230   KN02    KN02-BA KN02-CA KN03
+ *             KN01    KN230   KN02    KN02-BA KN02-CA KN03
  *
  * MEMORY      CPU     CPU     CPU     ASIC    CPU     CPU
  * RTC         CPU     CPU     CPU     ASIC    CPU     CPU
@@ -413,7 +413,7 @@ static void __init dec_init_kn02(void)
 
 /*
  * Machine-specific initialisation for KN02-BA, aka DS5000/1xx
- * (xx = 20, 25, 33), aka 3min.         Also applies to KN04(-BA), aka
+ * (xx = 20, 25, 33), aka 3min.  Also applies to KN04(-BA), aka
  * DS5000/150, aka 4min.
  */
 static int kn02ba_interrupt[DEC_NR_INTS] __initdata = {
index 13d61c002e4fc329ec6de191c31d43afb9020885..3f745459fdb58ee53e228a71cb27a737db4f7800 100644 (file)
@@ -58,7 +58,7 @@
 
 /*
  * Memory segments (64bit kernel mode addresses)
- * The compatibility segments use the full 64-bit sign extended value. Note
+ * The compatibility segments use the full 64-bit sign extended value.  Note
  * the R8000 doesn't have them so don't reference these in generic MIPS code.
  */
 #define XKUSEG                 _CONST64_(0x0000000000000000)
 
 /*
  * The ultimate limited of the 64-bit MIPS architecture:  2 bits for selecting
- * the region, 3 bits for the CCA mode.         This leaves 59 bits of which the
+ * the region, 3 bits for the CCA mode.  This leaves 59 bits of which the
  * R8000 implements most with its 48-bit physical address space.
  */
 #define TO_PHYS_MASK   _CONST64_(0x07ffffffffffffff)   /* 2^^59 - 1 */
index 08b607969a16978055f2b5e5cd1bf833fb8a4618..7eed2f261710c54932ef3b031653c37dce7d6380 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Atomic operations that C can't guarantee us.         Useful for
+ * Atomic operations that C can't guarantee us.  Useful for
  * resource counting etc..
  *
  * But use these as seldom as possible since they are much more slower
index 314ab5532019603545add2b96249d98397d0c08e..f26d8e1bf3c37575b4b42144282587caaa1c6a3f 100644 (file)
@@ -18,7 +18,7 @@
  * over this barrier.  All reads preceding this primitive are guaranteed
  * to access memory (but not necessarily other CPUs' caches) before any
  * reads following this primitive that depend on the data return by
- * any of the preceding reads. This primitive is much lighter weight than
+ * any of the preceding reads.  This primitive is much lighter weight than
  * rmb() on most CPUs, and is never heavier weight than is
  * rmb().
  *
@@ -43,7 +43,7 @@
  * </programlisting>
  *
  * because the read of "*q" depends on the read of "p" and these
- * two reads are separated by a read_barrier_depends().         However,
+ * two reads are separated by a read_barrier_depends().  However,
  * the following code, with the same initial values for "a" and "b":
  *
  * <programlisting>
@@ -57,7 +57,7 @@
  * </programlisting>
  *
  * does not enforce ordering, since there is no data dependency between
- * the read of "a" and the read of "b".         Therefore, on some CPUs, such
+ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
  * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
  * in cases like this where there are no data dependencies.
  */
index 68f37e3eccc7f5032e98a7aa854eeceeb1783ace..c75025f27c201f02a9b85f65c2fdbbc529768325 100644 (file)
 /*
  * Cache Operations available on all MIPS processors with R4000-style caches
  */
-#define Index_Invalidate_I     0x00
-#define Index_Writeback_Inv_D  0x01
-#define Index_Load_Tag_I       0x04
-#define Index_Load_Tag_D       0x05
-#define Index_Store_Tag_I      0x08
-#define Index_Store_Tag_D      0x09
-#if defined(CONFIG_CPU_LOONGSON2)
-#define Hit_Invalidate_I       0x00
-#else
-#define Hit_Invalidate_I       0x10
-#endif
-#define Hit_Invalidate_D       0x11
-#define Hit_Writeback_Inv_D    0x15
+#define Index_Invalidate_I             0x00
+#define Index_Writeback_Inv_D          0x01
+#define Index_Load_Tag_I               0x04
+#define Index_Load_Tag_D               0x05
+#define Index_Store_Tag_I              0x08
+#define Index_Store_Tag_D              0x09
+#define Hit_Invalidate_I               0x10
+#define Hit_Invalidate_D               0x11
+#define Hit_Writeback_Inv_D            0x15
 
 /*
  * R4000-specific cacheops
  */
-#define Create_Dirty_Excl_D    0x0d
-#define Fill                   0x14
-#define Hit_Writeback_I                0x18
-#define Hit_Writeback_D                0x19
+#define Create_Dirty_Excl_D            0x0d
+#define Fill                           0x14
+#define Hit_Writeback_I                        0x18
+#define Hit_Writeback_D                        0x19
 
 /*
  * R4000SC and R4400SC-specific cacheops
  */
-#define Index_Invalidate_SI    0x02
-#define Index_Writeback_Inv_SD 0x03
-#define Index_Load_Tag_SI      0x06
-#define Index_Load_Tag_SD      0x07
-#define Index_Store_Tag_SI     0x0A
-#define Index_Store_Tag_SD     0x0B
-#define Create_Dirty_Excl_SD   0x0f
-#define Hit_Invalidate_SI      0x12
-#define Hit_Invalidate_SD      0x13
-#define Hit_Writeback_Inv_SD   0x17
-#define Hit_Writeback_SD       0x1b
-#define Hit_Set_Virtual_SI     0x1e
-#define Hit_Set_Virtual_SD     0x1f
+#define Index_Invalidate_SI            0x02
+#define Index_Writeback_Inv_SD         0x03
+#define Index_Load_Tag_SI              0x06
+#define Index_Load_Tag_SD              0x07
+#define Index_Store_Tag_SI             0x0A
+#define Index_Store_Tag_SD             0x0B
+#define Create_Dirty_Excl_SD           0x0f
+#define Hit_Invalidate_SI              0x12
+#define Hit_Invalidate_SD              0x13
+#define Hit_Writeback_Inv_SD           0x17
+#define Hit_Writeback_SD               0x1b
+#define Hit_Set_Virtual_SI             0x1e
+#define Hit_Set_Virtual_SD             0x1f
 
 /*
  * R5000-specific cacheops
  */
-#define R5K_Page_Invalidate_S  0x17
+#define R5K_Page_Invalidate_S          0x17
 
 /*
  * RM7000-specific cacheops
  */
-#define Page_Invalidate_T      0x16
-#define Index_Store_Tag_T      0x0a
-#define Index_Load_Tag_T       0x06
+#define Page_Invalidate_T              0x16
+#define Index_Store_Tag_T              0x0a
+#define Index_Load_Tag_T               0x06
 
 /*
  * R10000-specific cacheops
  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
  * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
  */
-#define Index_Writeback_Inv_S  0x03
-#define Index_Load_Tag_S       0x07
-#define Index_Store_Tag_S      0x0B
-#define Hit_Invalidate_S       0x13
-#define Cache_Barrier          0x14
-#define Hit_Writeback_Inv_S    0x17
-#define Index_Load_Data_I      0x18
-#define Index_Load_Data_D      0x19
-#define Index_Load_Data_S      0x1b
-#define Index_Store_Data_I     0x1c
-#define Index_Store_Data_D     0x1d
-#define Index_Store_Data_S     0x1f
+#define Index_Writeback_Inv_S          0x03
+#define Index_Load_Tag_S               0x07
+#define Index_Store_Tag_S              0x0B
+#define Hit_Invalidate_S               0x13
+#define Cache_Barrier                  0x14
+#define Hit_Writeback_Inv_S            0x17
+#define Index_Load_Data_I              0x18
+#define Index_Load_Data_D              0x19
+#define Index_Load_Data_S              0x1b
+#define Index_Store_Data_I             0x1c
+#define Index_Store_Data_D             0x1d
+#define Index_Store_Data_S             0x1f
+
+/*
+ * Loongson2-specific cacheops
+ */
+#define Hit_Invalidate_I_Loongson23    0x00
 
 #endif /* __ASM_CACHEOPS_H */
index a6e505a0e44b4b119a6967fd5f8938ffb211a73e..be4d62a5a10ee203c8d2c9b16dc4ffda9551a493 100644 (file)
@@ -31,8 +31,6 @@ static inline u32 ioasic_read(unsigned int reg)
        return ioasic_base[reg / 4];
 }
 
-extern void clear_ioasic_dma_irq(unsigned int irq);
-
 extern void init_ioasic_irqs(int base);
 
 extern int dec_ioasic_clocksource_init(void);
index a8665a7611c2af3141313c8f21ad32eeae128dc2..8bd95971fe2dc98030565c6d41766ae1eb2b966a 100644 (file)
@@ -40,7 +40,7 @@
 #define IOASIC_FLOPPY  (11*IOASIC_SLOT_SIZE)   /* FDC (maxine) */
 #define IOASIC_SCSI    (12*IOASIC_SLOT_SIZE)   /* ASC SCSI */
 #define IOASIC_FDC_DMA (13*IOASIC_SLOT_SIZE)   /* FDC DMA (maxine) */
-#define IOASIC_SCSI_DMA (14*IOASIC_SLOT_SIZE)  /* ??? */
+#define IOASIC_SCSI_DMA        (14*IOASIC_SLOT_SIZE)   /* ??? */
 #define IOASIC_RES_15  (15*IOASIC_SLOT_SIZE)   /* unused? */
 
 
index 0eb3241de7060883d6b72e2878da258d9b41caf2..88d9ffd742588b41c99975943c7769fb75f18d25 100644 (file)
 /*
  * System Control & Status Register bits.
  */
-#define KN01_CSR_MNFMOD                (1<<15) /* MNFMOD manufacturing jumper */
-#define KN01_CSR_STATUS                (1<<14) /* self-test result status output */
-#define KN01_CSR_PARDIS                (1<<13) /* parity error disable */
-#define KN01_CSR_CRSRTST       (1<<12) /* PCC test output */
-#define KN01_CSR_MONO          (1<<11) /* mono/color fb SIMM installed */
-#define KN01_CSR_MEMERR                (1<<10) /* write timeout error status & ack*/
+#define KN01_CSR_MNFMOD                (1<<15) /* MNFMOD manufacturing jumper */
+#define KN01_CSR_STATUS                (1<<14) /* self-test result status output */
+#define KN01_CSR_PARDIS                (1<<13) /* parity error disable */
+#define KN01_CSR_CRSRTST       (1<<12) /* PCC test output */
+#define KN01_CSR_MONO          (1<<11) /* mono/color fb SIMM installed */
+#define KN01_CSR_MEMERR                (1<<10) /* write timeout error status & ack*/
 #define KN01_CSR_VINT          (1<<9)  /* PCC area detect #2 status & ack */
 #define KN01_CSR_TXDIS         (1<<8)  /* DZ11 transmit disable */
 #define KN01_CSR_VBGTRG                (1<<2)  /* blue DAC voltage over green (r/o) */
index 69dc2a9a2d0f5602d91c4b83306f6f0952572a52..92c0fe2560997e901908eac961e8b27d34097f46 100644 (file)
@@ -68,7 +68,7 @@
 #define KN03CA_IO_SSR_ISDN_RST (1<<12)         /* ~ISDN (Am79C30A) reset */
 
 #define KN03CA_IO_SSR_FLOPPY_RST (1<<7)                /* ~FDC (82077) reset */
-#define KN03CA_IO_SSR_VIDEO_RST (1<<6)         /* ~framebuffer reset */
+#define KN03CA_IO_SSR_VIDEO_RST        (1<<6)          /* ~framebuffer reset */
 #define KN03CA_IO_SSR_AB_RST   (1<<5)          /* ACCESS.bus reset */
 #define KN03CA_IO_SSR_RES_4    (1<<4)          /* unused */
 #define KN03CA_IO_SSR_RES_3    (1<<4)          /* unused */
index 446577712bee23d45be3f9375a6d8ee8f2806a2e..c0ead63138453c04d3b20918fbcfb1e1c02c5c3c 100644 (file)
@@ -49,7 +49,7 @@
 
 #ifdef CONFIG_64BIT
 
-#define prom_is_rex(magic)     1       /* KN04 and KN05 are REX PROMs.  */
+#define prom_is_rex(magic)     1       /* KN04 and KN05 are REX PROMs.  */
 
 #else /* !CONFIG_64BIT */
 
index cf3ae2480b1d25f5dfd77e8e328e5745b413e2be..a66359ef4ece770e3ed1a6518e96b79e733b4afa 100644 (file)
@@ -331,6 +331,7 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs)                  \
        dump_task_fpu(tsk, elf_fpregs)
 
+#define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE      PAGE_SIZE
 
 /* This yields a mask that user programs can use to figure out what
diff --git a/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h b/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h
deleted file mode 100644 (file)
index 6cb30f2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *  Platform data definition for Atheros AR933X UART
- *
- *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.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 _AR933X_UART_PLATFORM_H
-#define _AR933X_UART_PLATFORM_H
-
-struct ar933x_uart_platform_data {
-       unsigned        uartclk;
-};
-
-#endif /* _AR933X_UART_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
new file mode 100644 (file)
index 0000000..00867dd
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef __BCM47XX_BOARD_H
+#define __BCM47XX_BOARD_H
+
+enum bcm47xx_board {
+       BCM47XX_BOARD_ASUS_RTAC66U,
+       BCM47XX_BOARD_ASUS_RTN10,
+       BCM47XX_BOARD_ASUS_RTN10D,
+       BCM47XX_BOARD_ASUS_RTN10U,
+       BCM47XX_BOARD_ASUS_RTN12,
+       BCM47XX_BOARD_ASUS_RTN12B1,
+       BCM47XX_BOARD_ASUS_RTN12C1,
+       BCM47XX_BOARD_ASUS_RTN12D1,
+       BCM47XX_BOARD_ASUS_RTN12HP,
+       BCM47XX_BOARD_ASUS_RTN15U,
+       BCM47XX_BOARD_ASUS_RTN16,
+       BCM47XX_BOARD_ASUS_RTN53,
+       BCM47XX_BOARD_ASUS_RTN66U,
+       BCM47XX_BOARD_ASUS_WL300G,
+       BCM47XX_BOARD_ASUS_WL320GE,
+       BCM47XX_BOARD_ASUS_WL330GE,
+       BCM47XX_BOARD_ASUS_WL500GD,
+       BCM47XX_BOARD_ASUS_WL500GPV1,
+       BCM47XX_BOARD_ASUS_WL500GPV2,
+       BCM47XX_BOARD_ASUS_WL500W,
+       BCM47XX_BOARD_ASUS_WL520GC,
+       BCM47XX_BOARD_ASUS_WL520GU,
+       BCM47XX_BOARD_ASUS_WL700GE,
+       BCM47XX_BOARD_ASUS_WLHDD,
+
+       BCM47XX_BOARD_BELKIN_F7D4301,
+
+       BCM47XX_BOARD_BUFFALO_WBR2_G54,
+       BCM47XX_BOARD_BUFFALO_WHR2_A54G54,
+       BCM47XX_BOARD_BUFFALO_WHR_G125,
+       BCM47XX_BOARD_BUFFALO_WHR_G54S,
+       BCM47XX_BOARD_BUFFALO_WHR_HP_G54,
+       BCM47XX_BOARD_BUFFALO_WLA2_G54L,
+       BCM47XX_BOARD_BUFFALO_WZR_G300N,
+       BCM47XX_BOARD_BUFFALO_WZR_RS_G54,
+       BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP,
+
+       BCM47XX_BOARD_CISCO_M10V1,
+       BCM47XX_BOARD_CISCO_M20V1,
+
+       BCM47XX_BOARD_DELL_TM2300,
+
+       BCM47XX_BOARD_DLINK_DIR130,
+       BCM47XX_BOARD_DLINK_DIR330,
+
+       BCM47XX_BOARD_HUAWEI_E970,
+
+       BCM47XX_BOARD_LINKSYS_E900V1,
+       BCM47XX_BOARD_LINKSYS_E1000V1,
+       BCM47XX_BOARD_LINKSYS_E1000V2,
+       BCM47XX_BOARD_LINKSYS_E1000V21,
+       BCM47XX_BOARD_LINKSYS_E1200V2,
+       BCM47XX_BOARD_LINKSYS_E2000V1,
+       BCM47XX_BOARD_LINKSYS_E3000V1,
+       BCM47XX_BOARD_LINKSYS_E3200V1,
+       BCM47XX_BOARD_LINKSYS_E4200V1,
+       BCM47XX_BOARD_LINKSYS_WRT150NV1,
+       BCM47XX_BOARD_LINKSYS_WRT150NV11,
+       BCM47XX_BOARD_LINKSYS_WRT160NV1,
+       BCM47XX_BOARD_LINKSYS_WRT160NV3,
+       BCM47XX_BOARD_LINKSYS_WRT300NV11,
+       BCM47XX_BOARD_LINKSYS_WRT310NV1,
+       BCM47XX_BOARD_LINKSYS_WRT310NV2,
+       BCM47XX_BOARD_LINKSYS_WRT54G3GV2,
+       BCM47XX_BOARD_LINKSYS_WRT610NV1,
+       BCM47XX_BOARD_LINKSYS_WRT610NV2,
+       BCM47XX_BOARD_LINKSYS_WRTSL54GS,
+
+       BCM47XX_BOARD_MOTOROLA_WE800G,
+       BCM47XX_BOARD_MOTOROLA_WR850GP,
+       BCM47XX_BOARD_MOTOROLA_WR850GV2V3,
+
+       BCM47XX_BOARD_NETGEAR_WGR614V8,
+       BCM47XX_BOARD_NETGEAR_WGR614V9,
+       BCM47XX_BOARD_NETGEAR_WNDR3300,
+       BCM47XX_BOARD_NETGEAR_WNDR3400V1,
+       BCM47XX_BOARD_NETGEAR_WNDR3400V2,
+       BCM47XX_BOARD_NETGEAR_WNDR3400VCNA,
+       BCM47XX_BOARD_NETGEAR_WNDR3700V3,
+       BCM47XX_BOARD_NETGEAR_WNDR4000,
+       BCM47XX_BOARD_NETGEAR_WNDR4500V1,
+       BCM47XX_BOARD_NETGEAR_WNDR4500V2,
+       BCM47XX_BOARD_NETGEAR_WNR2000,
+       BCM47XX_BOARD_NETGEAR_WNR3500L,
+       BCM47XX_BOARD_NETGEAR_WNR3500U,
+       BCM47XX_BOARD_NETGEAR_WNR3500V2,
+       BCM47XX_BOARD_NETGEAR_WNR3500V2VC,
+       BCM47XX_BOARD_NETGEAR_WNR834BV2,
+
+       BCM47XX_BOARD_PHICOMM_M1,
+
+       BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE,
+
+       BCM47XX_BOARD_ZTE_H218N,
+
+       BCM47XX_BOARD_UNKNOWN,
+       BCM47XX_BOARD_NO,
+};
+
+#define BCM47XX_BOARD_MAX_NAME 30
+
+void bcm47xx_board_detect(void);
+enum bcm47xx_board bcm47xx_board_get(void);
+const char *bcm47xx_board_get_name(void);
+
+#endif /* __BCM47XX_BOARD_H */
index b8e7be8f34dd472076b7ffd10d7de2d14c11b638..36a3fc1aa3ae326def39379e03db8258c24d82d3 100644 (file)
@@ -48,4 +48,6 @@ static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
                printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
 }
 
+int bcm47xx_nvram_gpio_pin(const char *name);
+
 #endif /* __BCM47XX_NVRAM_H */
index 47fb247f9663b501796a7c255b32525c225cffed..f9f448650505bc95dc2b5e426c3acf4869ffbfc5 100644 (file)
@@ -52,23 +52,11 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 0;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-       BUG();
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 1;
 }
 
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       BUG();
-       return 0;
-}
-
 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 
diff --git a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..acce27f
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *     CPU feature overrides for DECstation systems.  Two variations
+ *     are generally applicable.
+ *
+ *     Copyright (C) 2013  Maciej W. Rozycki
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_DEC_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_DEC_CPU_FEATURE_OVERRIDES_H
+
+/* Generic ones first.  */
+#define cpu_has_tlb                    1
+#define cpu_has_tx39_cache             0
+#define cpu_has_fpu                    1
+#define cpu_has_divec                  0
+#define cpu_has_prefetch               0
+#define cpu_has_mcheck                 0
+#define cpu_has_ejtag                  0
+#define cpu_has_mips16                 0
+#define cpu_has_mdmx                   0
+#define cpu_has_mips3d                 0
+#define cpu_has_smartmips              0
+#define cpu_has_rixi                   0
+#define cpu_has_vtag_icache            0
+#define cpu_has_ic_fills_f_dc          0
+#define cpu_has_pindexed_dcache                0
+#define cpu_has_local_ebase            0
+#define cpu_icache_snoops_remote_store 1
+#define cpu_has_mips_4                 0
+#define cpu_has_mips_5                 0
+#define cpu_has_mips32r1               0
+#define cpu_has_mips32r2               0
+#define cpu_has_mips64r1               0
+#define cpu_has_mips64r2               0
+#define cpu_has_dsp                    0
+#define cpu_has_mipsmt                 0
+#define cpu_has_userlocal              0
+
+/* R3k-specific ones.  */
+#ifdef CONFIG_CPU_R3000
+#define cpu_has_4kex                   0
+#define cpu_has_3k_cache               1
+#define cpu_has_4k_cache               0
+#define cpu_has_32fpr                  0
+#define cpu_has_counter                        0
+#define cpu_has_watch                  0
+#define cpu_has_vce                    0
+#define cpu_has_cache_cdex_p           0
+#define cpu_has_cache_cdex_s           0
+#define cpu_has_llsc                   0
+#define cpu_has_dc_aliases             0
+#define cpu_has_mips_2                 0
+#define cpu_has_mips_3                 0
+#define cpu_has_nofpuex                        1
+#define cpu_has_inclusive_pcaches      0
+#define cpu_dcache_line_size()         4
+#define cpu_icache_line_size()         4
+#define cpu_scache_line_size()         0
+#endif /* CONFIG_CPU_R3000 */
+
+/* R4k-specific ones.  */
+#ifdef CONFIG_CPU_R4X00
+#define cpu_has_4kex                   1
+#define cpu_has_3k_cache               0
+#define cpu_has_4k_cache               1
+#define cpu_has_32fpr                  1
+#define cpu_has_counter                        1
+#define cpu_has_watch                  1
+#define cpu_has_vce                    1
+#define cpu_has_cache_cdex_p           1
+#define cpu_has_cache_cdex_s           1
+#define cpu_has_llsc                   1
+#define cpu_has_dc_aliases             (PAGE_SIZE < 0x4000)
+#define cpu_has_mips_2                 1
+#define cpu_has_mips_3                 1
+#define cpu_has_nofpuex                        0
+#define cpu_has_inclusive_pcaches      1
+#define cpu_dcache_line_size()         16
+#define cpu_icache_line_size()         16
+#define cpu_scache_line_size()         32
+#endif /* CONFIG_CPU_R4X00 */
+
+#endif /* __ASM_MACH_DEC_CPU_FEATURE_OVERRIDES_H */
index 74cb99257d5b9b25dda5aec6fa1eaa1553612086..a9e8f6b62b0b9c9fa2a073f1aeb5c08f1d5a6894 100644 (file)
@@ -47,16 +47,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 #ifdef CONFIG_DMA_COHERENT
index 06c441968e6ed4fcb31f6c71f506063d198bfb28..4ffddfdb50623bbbcbc2f5eec3ad9aabb7f78bcc 100644 (file)
@@ -58,16 +58,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 1;               /* IP27 non-cohernet mode is unsupported */
index 073f0c4760ba8cc3cc7cf59380dfbc58c6a409bd..104cfbc3ed63291ec51a6e13152257516cd1d85c 100644 (file)
@@ -80,17 +80,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-       return;
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 0;               /* IP32 is non-cohernet */
index 9fc1e9ad7038879840d73fc142d7a88b4ebde218..949003ef97b37d0d4023f3da08694c4409139a17 100644 (file)
@@ -48,16 +48,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 0;
index e1433055fe98b5f6e876313bbdb98b23a2021e75..aeb2c05d61456de8b0143984fe1c9626e8acae6d 100644 (file)
@@ -53,16 +53,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 0;
diff --git a/arch/mips/include/asm/mach-powertv/asic.h b/arch/mips/include/asm/mach-powertv/asic.h
deleted file mode 100644 (file)
index b341108..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _ASM_MACH_POWERTV_ASIC_H
-#define _ASM_MACH_POWERTV_ASIC_H
-
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <asm/mach-powertv/asic_regs.h>
-
-#define DVR_CAPABLE    (1<<0)
-#define PCIE_CAPABLE   (1<<1)
-#define FFS_CAPABLE    (1<<2)
-#define DISPLAY_CAPABLE (1<<3)
-
-/* Platform Family types
- * For compitability, the new value must be added in the end */
-enum family_type {
-       FAMILY_8500,
-       FAMILY_8500RNG,
-       FAMILY_4500,
-       FAMILY_1500,
-       FAMILY_8600,
-       FAMILY_4600,
-       FAMILY_4600VZA,
-       FAMILY_8600VZB,
-       FAMILY_1500VZE,
-       FAMILY_1500VZF,
-       FAMILY_8700,
-       FAMILIES
-};
-
-/* Register maps for each ASIC */
-extern const struct register_map calliope_register_map;
-extern const struct register_map cronus_register_map;
-extern const struct register_map gaia_register_map;
-extern const struct register_map zeus_register_map;
-
-extern struct resource dvr_cronus_resources[];
-extern struct resource dvr_gaia_resources[];
-extern struct resource dvr_zeus_resources[];
-extern struct resource non_dvr_calliope_resources[];
-extern struct resource non_dvr_cronus_resources[];
-extern struct resource non_dvr_cronuslite_resources[];
-extern struct resource non_dvr_gaia_resources[];
-extern struct resource non_dvr_vz_calliope_resources[];
-extern struct resource non_dvr_vze_calliope_resources[];
-extern struct resource non_dvr_vzf_calliope_resources[];
-extern struct resource non_dvr_zeus_resources[];
-
-extern void powertv_platform_init(void);
-extern void platform_alloc_bootmem(void);
-extern enum asic_type platform_get_asic(void);
-extern enum family_type platform_get_family(void);
-extern int platform_supports_dvr(void);
-extern int platform_supports_ffs(void);
-extern int platform_supports_pcie(void);
-extern int platform_supports_display(void);
-extern void configure_platform(void);
-
-/* Platform Resources */
-#define ASIC_RESOURCE_GET_EXISTS 1
-extern struct resource *asic_resource_get(const char *name);
-extern void platform_release_memory(void *baddr, int size);
-
-/* USB configuration */
-struct usb_hcd;                        /* Forward reference */
-extern void platform_configure_usb_ehci(void);
-extern void platform_unconfigure_usb_ehci(void);
-extern void platform_configure_usb_ohci(void);
-extern void platform_unconfigure_usb_ohci(void);
-
-/* Resource for ASIC registers */
-extern struct resource asic_resource;
-extern int platform_usb_devices_init(struct platform_device **echi_dev,
-       struct platform_device **ohci_dev);
-
-/* Reboot Cause */
-extern void set_reboot_cause(char code, unsigned int data, unsigned int data2);
-extern void set_locked_reboot_cause(char code, unsigned int data,
-       unsigned int data2);
-
-enum sys_reboot_type {
-       sys_unknown_reboot = 0x00,      /* Unknown reboot cause */
-       sys_davic_change = 0x01,        /* Reboot due to change in DAVIC
-                                        * mode */
-       sys_user_reboot = 0x02,         /* Reboot initiated by user */
-       sys_system_reboot = 0x03,       /* Reboot initiated by OS */
-       sys_trap_reboot = 0x04,         /* Reboot due to a CPU trap */
-       sys_silent_reboot = 0x05,       /* Silent reboot */
-       sys_boot_ldr_reboot = 0x06,     /* Bootloader reboot */
-       sys_power_up_reboot = 0x07,     /* Power on bootup.  Older
-                                        * drivers may report as
-                                        * userReboot. */
-       sys_code_change = 0x08,         /* Reboot to take code change.
-                                        * Older drivers may report as
-                                        * userReboot. */
-       sys_hardware_reset = 0x09,      /* HW watchdog or front-panel
-                                        * reset button reset.  Older
-                                        * drivers may report as
-                                        * userReboot. */
-       sys_watchdogInterrupt = 0x0A    /* Pre-watchdog interrupt */
-};
-
-#endif /* _ASM_MACH_POWERTV_ASIC_H */
diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
deleted file mode 100644 (file)
index 20348e8..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *                             asic_reg_map.h
- *
- * A macro-enclosed list of the elements for the register_map structure for
- * use in defining and manipulating the structure.
- *
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-REGISTER_MAP_ELEMENT(eic_slow0_strt_add)
-REGISTER_MAP_ELEMENT(eic_cfg_bits)
-REGISTER_MAP_ELEMENT(eic_ready_status)
-REGISTER_MAP_ELEMENT(chipver3)
-REGISTER_MAP_ELEMENT(chipver2)
-REGISTER_MAP_ELEMENT(chipver1)
-REGISTER_MAP_ELEMENT(chipver0)
-REGISTER_MAP_ELEMENT(uart1_intstat)
-REGISTER_MAP_ELEMENT(uart1_inten)
-REGISTER_MAP_ELEMENT(uart1_config1)
-REGISTER_MAP_ELEMENT(uart1_config2)
-REGISTER_MAP_ELEMENT(uart1_divisorhi)
-REGISTER_MAP_ELEMENT(uart1_divisorlo)
-REGISTER_MAP_ELEMENT(uart1_data)
-REGISTER_MAP_ELEMENT(uart1_status)
-REGISTER_MAP_ELEMENT(int_stat_3)
-REGISTER_MAP_ELEMENT(int_stat_2)
-REGISTER_MAP_ELEMENT(int_stat_1)
-REGISTER_MAP_ELEMENT(int_stat_0)
-REGISTER_MAP_ELEMENT(int_config)
-REGISTER_MAP_ELEMENT(int_int_scan)
-REGISTER_MAP_ELEMENT(ien_int_3)
-REGISTER_MAP_ELEMENT(ien_int_2)
-REGISTER_MAP_ELEMENT(ien_int_1)
-REGISTER_MAP_ELEMENT(ien_int_0)
-REGISTER_MAP_ELEMENT(int_level_3_3)
-REGISTER_MAP_ELEMENT(int_level_3_2)
-REGISTER_MAP_ELEMENT(int_level_3_1)
-REGISTER_MAP_ELEMENT(int_level_3_0)
-REGISTER_MAP_ELEMENT(int_level_2_3)
-REGISTER_MAP_ELEMENT(int_level_2_2)
-REGISTER_MAP_ELEMENT(int_level_2_1)
-REGISTER_MAP_ELEMENT(int_level_2_0)
-REGISTER_MAP_ELEMENT(int_level_1_3)
-REGISTER_MAP_ELEMENT(int_level_1_2)
-REGISTER_MAP_ELEMENT(int_level_1_1)
-REGISTER_MAP_ELEMENT(int_level_1_0)
-REGISTER_MAP_ELEMENT(int_level_0_3)
-REGISTER_MAP_ELEMENT(int_level_0_2)
-REGISTER_MAP_ELEMENT(int_level_0_1)
-REGISTER_MAP_ELEMENT(int_level_0_0)
-REGISTER_MAP_ELEMENT(int_docsis_en)
-REGISTER_MAP_ELEMENT(mips_pll_setup)
-REGISTER_MAP_ELEMENT(fs432x4b4_usb_ctl)
-REGISTER_MAP_ELEMENT(test_bus)
-REGISTER_MAP_ELEMENT(crt_spare)
-REGISTER_MAP_ELEMENT(usb2_ohci_int_mask)
-REGISTER_MAP_ELEMENT(usb2_strap)
-REGISTER_MAP_ELEMENT(ehci_hcapbase)
-REGISTER_MAP_ELEMENT(ohci_hc_revision)
-REGISTER_MAP_ELEMENT(bcm1_bs_lmi_steer)
-REGISTER_MAP_ELEMENT(usb2_control)
-REGISTER_MAP_ELEMENT(usb2_stbus_obc)
-REGISTER_MAP_ELEMENT(usb2_stbus_mess_size)
-REGISTER_MAP_ELEMENT(usb2_stbus_chunk_size)
-REGISTER_MAP_ELEMENT(pcie_regs)
-REGISTER_MAP_ELEMENT(tim_ch)
-REGISTER_MAP_ELEMENT(tim_cl)
-REGISTER_MAP_ELEMENT(gpio_dout)
-REGISTER_MAP_ELEMENT(gpio_din)
-REGISTER_MAP_ELEMENT(gpio_dir)
-REGISTER_MAP_ELEMENT(watchdog)
-REGISTER_MAP_ELEMENT(front_panel)
-REGISTER_MAP_ELEMENT(misc_clk_ctl1)
-REGISTER_MAP_ELEMENT(misc_clk_ctl2)
-REGISTER_MAP_ELEMENT(crt_ext_ctl)
-REGISTER_MAP_ELEMENT(register_maps)
diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h
deleted file mode 100644 (file)
index 06712ab..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef __ASM_MACH_POWERTV_ASIC_H_
-#define __ASM_MACH_POWERTV_ASIC_H_
-#include <linux/io.h>
-
-/* ASIC types */
-enum asic_type {
-       ASIC_UNKNOWN,
-       ASIC_ZEUS,
-       ASIC_CALLIOPE,
-       ASIC_CRONUS,
-       ASIC_CRONUSLITE,
-       ASIC_GAIA,
-       ASICS                   /* Number of supported ASICs */
-};
-
-/* hardcoded values read from Chip Version registers */
-#define CRONUS_10      0x0B4C1C20
-#define CRONUS_11      0x0B4C1C21
-#define CRONUSLITE_10  0x0B4C1C40
-
-#define NAND_FLASH_BASE                0x03000000
-#define CALLIOPE_IO_BASE       0x08000000
-#define GAIA_IO_BASE           0x09000000
-#define CRONUS_IO_BASE         0x09000000
-#define ZEUS_IO_BASE           0x09000000
-
-#define ASIC_IO_SIZE           0x01000000
-
-/* Definitions for backward compatibility */
-#define UART1_INTSTAT  uart1_intstat
-#define UART1_INTEN    uart1_inten
-#define UART1_CONFIG1  uart1_config1
-#define UART1_CONFIG2  uart1_config2
-#define UART1_DIVISORHI uart1_divisorhi
-#define UART1_DIVISORLO uart1_divisorlo
-#define UART1_DATA     uart1_data
-#define UART1_STATUS   uart1_status
-
-/* ASIC register enumeration */
-union register_map_entry {
-       unsigned long phys;
-       u32 *virt;
-};
-
-#define REGISTER_MAP_ELEMENT(x) union register_map_entry x;
-struct register_map {
-#include <asm/mach-powertv/asic_reg_map.h>
-};
-#undef REGISTER_MAP_ELEMENT
-
-/**
- * register_map_offset_phys - add an offset to the physical address
- * @map:       Pointer to the &struct register_map
- * @offset:    Value to add
- *
- * Only adds the base to non-zero physical addresses
- */
-static inline void register_map_offset_phys(struct register_map *map,
-       unsigned long offset)
-{
-#define REGISTER_MAP_ELEMENT(x)                do {                            \
-               if (map->x.phys != 0)                                   \
-                       map->x.phys += offset;                          \
-       } while (false);
-
-#include <asm/mach-powertv/asic_reg_map.h>
-#undef REGISTER_MAP_ELEMENT
-}
-
-/**
- * register_map_virtualize - Convert &register_map to virtual addresses
- * @map:       Pointer to &register_map to virtualize
- */
-static inline void register_map_virtualize(struct register_map *map)
-{
-#define REGISTER_MAP_ELEMENT(x)                do {                            \
-               map->x.virt = (!map->x.phys) ? NULL :                   \
-                       UNCAC_ADDR(phys_to_virt(map->x.phys));          \
-       } while (false);
-
-#include <asm/mach-powertv/asic_reg_map.h>
-#undef REGISTER_MAP_ELEMENT
-}
-
-extern struct register_map _asic_register_map;
-extern unsigned long asic_phy_base;
-
-/*
- * Macros to interface to registers through their ioremapped address
- * asic_reg_phys_addr  Returns the physical address of the given register
- * asic_reg_addr       Returns the iomapped virtual address of the given
- *                     register.
- */
-#define asic_reg_addr(x)       (_asic_register_map.x.virt)
-#define asic_reg_phys_addr(x)  (virt_to_phys((void *) CAC_ADDR(        \
-                                       (unsigned long) asic_reg_addr(x))))
-
-/*
- * The asic_reg macro is gone. It should be replaced by either asic_read or
- * asic_write, as appropriate.
- */
-
-#define asic_read(x)           readl(asic_reg_addr(x))
-#define asic_write(v, x)       writel(v, asic_reg_addr(x))
-
-extern void asic_irq_init(void);
-#endif
diff --git a/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h b/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h
deleted file mode 100644 (file)
index 58c76ec..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _ASM_MACH_POWERTV_CPU_FEATURE_OVERRIDES_H_
-#define _ASM_MACH_POWERTV_CPU_FEATURE_OVERRIDES_H_
-#define cpu_has_tlb                    1
-#define cpu_has_4kex                   1
-#define cpu_has_3k_cache               0
-#define cpu_has_4k_cache               1
-#define cpu_has_tx39_cache             0
-#define cpu_has_fpu                    0
-#define cpu_has_counter                        1
-#define cpu_has_watch                  1
-#define cpu_has_divec                  1
-#define cpu_has_vce                    0
-#define cpu_has_cache_cdex_p           0
-#define cpu_has_cache_cdex_s           0
-#define cpu_has_mcheck                 1
-#define cpu_has_ejtag                  1
-#define cpu_has_llsc                   1
-#define cpu_has_mips16                 0
-#define cpu_has_mdmx                   0
-#define cpu_has_mips3d                 0
-#define cpu_has_smartmips              0
-#define cpu_has_vtag_icache            0
-#define cpu_has_dc_aliases             0
-#define cpu_has_ic_fills_f_dc          0
-#define cpu_has_mips32r1               0
-#define cpu_has_mips32r2               1
-#define cpu_has_mips64r1               0
-#define cpu_has_mips64r2               0
-#define cpu_has_dsp                    0
-#define cpu_has_dsp2                   0
-#define cpu_has_mipsmt                 0
-#define cpu_has_userlocal              0
-#define cpu_has_nofpuex                        0
-#define cpu_has_64bits                 0
-#define cpu_has_64bit_zero_reg         0
-#define cpu_has_vint                   1
-#define cpu_has_veic                   1
-#define cpu_has_inclusive_pcaches      0
-
-#define cpu_dcache_line_size()         32
-#define cpu_icache_line_size()         32
-#endif
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
deleted file mode 100644 (file)
index f831672..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.
- *
- * Version from mach-generic modified to support PowerTV port
- * Portions Copyright (C) 2009 Cisco Systems, Inc.
- * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
- *
- */
-
-#ifndef __ASM_MACH_POWERTV_DMA_COHERENCE_H
-#define __ASM_MACH_POWERTV_DMA_COHERENCE_H
-
-#include <linux/sched.h>
-#include <linux/device.h>
-#include <asm/mach-powertv/asic.h>
-
-static inline bool is_kseg2(void *addr)
-{
-       return (unsigned long)addr >= KSEG2;
-}
-
-static inline unsigned long virt_to_phys_from_pte(void *addr)
-{
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *ptep, pte;
-
-       unsigned long virt_addr = (unsigned long)addr;
-       unsigned long phys_addr = 0UL;
-
-       /* get the page global directory. */
-       pgd = pgd_offset_k(virt_addr);
-
-       if (!pgd_none(*pgd)) {
-               /* get the page upper directory */
-               pud = pud_offset(pgd, virt_addr);
-               if (!pud_none(*pud)) {
-                       /* get the page middle directory */
-                       pmd = pmd_offset(pud, virt_addr);
-                       if (!pmd_none(*pmd)) {
-                               /* get a pointer to the page table entry */
-                               ptep = pte_offset(pmd, virt_addr);
-                               pte = *ptep;
-                               /* check for a valid page */
-                               if (pte_present(pte)) {
-                                       /* get the physical address the page is
-                                        * referring to */
-                                       phys_addr = (unsigned long)
-                                               page_to_phys(pte_page(pte));
-                                       /* add the offset within the page */
-                                       phys_addr |= (virt_addr & ~PAGE_MASK);
-                               }
-                       }
-               }
-       }
-
-       return phys_addr;
-}
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-       size_t size)
-{
-       if (is_kseg2(addr))
-               return phys_to_dma(virt_to_phys_from_pte(addr));
-       else
-               return phys_to_dma(virt_to_phys(addr));
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-       struct page *page)
-{
-       return phys_to_dma(page_to_phys(page));
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-       dma_addr_t dma_addr)
-{
-       return dma_to_phys(dma_addr);
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-       size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s,
-        * so we can't guarantee allocations that must be
-        * within a tighter range than GFP_DMA..
-        */
-       if (mask < DMA_BIT_MASK(24))
-               return 0;
-
-       return 1;
-}
-
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-       return 0;
-}
-
-#endif /* __ASM_MACH_POWERTV_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-powertv/interrupts.h b/arch/mips/include/asm/mach-powertv/interrupts.h
deleted file mode 100644 (file)
index 6c463be..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _ASM_MACH_POWERTV_INTERRUPTS_H_
-#define _ASM_MACH_POWERTV_INTERRUPTS_H_
-
-/*
- * Defines for all of the interrupt lines
- */
-
-/* Definitions for backward compatibility */
-#define kIrq_Uart1             irq_uart1
-
-#define ibase 0
-
-/*------------- Register: int_stat_3 */
-/* 126 unused (bit 31) */
-#define irq_asc2video          (ibase+126)     /* ASC 2 Video Interrupt */
-#define irq_asc1video          (ibase+125)     /* ASC 1 Video Interrupt */
-#define irq_comms_block_wd     (ibase+124)     /* ASC 1 Video Interrupt */
-#define irq_fdma_mailbox       (ibase+123)     /* FDMA Mailbox Output */
-#define irq_fdma_gp            (ibase+122)     /* FDMA GP Output */
-#define irq_mips_pic           (ibase+121)     /* MIPS Performance Counter
-                                                * Interrupt */
-#define irq_mips_timer         (ibase+120)     /* MIPS Timer Interrupt */
-#define irq_memory_protect     (ibase+119)     /* Memory Protection Interrupt
-                                                * -- Ored by glue logic inside
-                                                *  SPARC ILC (see
-                                                *  INT_MEM_PROT_STAT, below,
-                                                *  for individual interrupts)
-                                                */
-/* 118 unused (bit 22) */
-#define irq_sbag               (ibase+117)     /* SBAG Interrupt -- Ored by
-                                                * glue logic inside SPARC ILC
-                                                * (see INT_SBAG_STAT, below,
-                                                * for individual interrupts) */
-#define irq_qam_b_fec          (ibase+116)     /* QAM  B FEC Interrupt */
-#define irq_qam_a_fec          (ibase+115)     /* QAM A FEC Interrupt */
-/* 114 unused  (bit 18) */
-#define irq_mailbox            (ibase+113)     /* Mailbox Debug Interrupt  --
-                                                * Ored by glue logic inside
-                                                * SPARC ILC (see
-                                                * INT_MAILBOX_STAT, below, for
-                                                * individual interrupts) */
-#define irq_fuse_stat1         (ibase+112)     /* Fuse Status 1 */
-#define irq_fuse_stat2         (ibase+111)     /* Fuse Status 2 */
-#define irq_fuse_stat3         (ibase+110)     /* Blitter Interrupt / Fuse
-                                                * Status 3 */
-#define irq_blitter            (ibase+110)     /* Blitter Interrupt / Fuse
-                                                * Status 3 */
-#define irq_avc1_pp0           (ibase+109)     /* AVC Decoder #1 PP0
-                                                * Interrupt */
-#define irq_avc1_pp1           (ibase+108)     /* AVC Decoder #1 PP1
-                                                * Interrupt */
-#define irq_avc1_mbe           (ibase+107)     /* AVC Decoder #1 MBE
-                                                * Interrupt */
-#define irq_avc2_pp0           (ibase+106)     /* AVC Decoder #2 PP0
-                                                * Interrupt */
-#define irq_avc2_pp1           (ibase+105)     /* AVC Decoder #2 PP1
-                                                * Interrupt */
-#define irq_avc2_mbe           (ibase+104)     /* AVC Decoder #2 MBE
-                                                * Interrupt */
-#define irq_zbug_spi           (ibase+103)     /* Zbug SPI Slave Interrupt */
-#define irq_qam_mod2           (ibase+102)     /* QAM Modulator 2 DMA
-                                                * Interrupt */
-#define irq_ir_rx              (ibase+101)     /* IR RX 2 Interrupt */
-#define irq_aud_dsp2           (ibase+100)     /* Audio DSP #2 Interrupt */
-#define irq_aud_dsp1           (ibase+99)      /* Audio DSP #1 Interrupt */
-#define irq_docsis             (ibase+98)      /* DOCSIS Debug Interrupt */
-#define irq_sd_dvp1            (ibase+97)      /* SD DVP #1 Interrupt */
-#define irq_sd_dvp2            (ibase+96)      /* SD DVP #2 Interrupt */
-/*------------- Register: int_stat_2 */
-#define irq_hd_dvp             (ibase+95)      /* HD DVP Interrupt */
-#define kIrq_Prewatchdog       (ibase+94)      /* watchdog Pre-Interrupt */
-#define irq_timer2             (ibase+93)      /* Programmable Timer
-                                                * Interrupt 2 */
-#define irq_1394               (ibase+92)      /* 1394 Firewire Interrupt */
-#define irq_usbohci            (ibase+91)      /* USB 2.0 OHCI Interrupt */
-#define irq_usbehci            (ibase+90)      /* USB 2.0 EHCI Interrupt */
-#define irq_pciexp             (ibase+89)      /* PCI Express 0 Interrupt */
-#define irq_pciexp0            (ibase+89)      /* PCI Express 0 Interrupt */
-#define irq_afe1               (ibase+88)      /* AFE 1 Interrupt */
-#define irq_sata               (ibase+87)      /* SATA 1 Interrupt */
-#define irq_sata1              (ibase+87)      /* SATA 1 Interrupt */
-#define irq_dtcp               (ibase+86)      /* DTCP Interrupt */
-#define irq_pciexp1            (ibase+85)      /* PCI Express 1 Interrupt */
-/* 84 unused   (bit 20) */
-/* 83 unused   (bit 19) */
-/* 82 unused   (bit 18) */
-#define irq_sata2              (ibase+81)      /* SATA2 Interrupt */
-#define irq_uart2              (ibase+80)      /* UART2 Interrupt */
-#define irq_legacy_usb         (ibase+79)      /* Legacy USB Host ISR (1.1
-                                                * Host module) */
-#define irq_pod                        (ibase+78)      /* POD Interrupt */
-#define irq_slave_usb          (ibase+77)      /* Slave USB */
-#define irq_denc1              (ibase+76)      /* DENC #1 VTG Interrupt */
-#define irq_vbi_vtg            (ibase+75)      /* VBI VTG Interrupt */
-#define irq_afe2               (ibase+74)      /* AFE 2 Interrupt */
-#define irq_denc2              (ibase+73)      /* DENC #2 VTG Interrupt */
-#define irq_asc2               (ibase+72)      /* ASC #2 Interrupt */
-#define irq_asc1               (ibase+71)      /* ASC #1 Interrupt */
-#define irq_mod_dma            (ibase+70)      /* Modulator DMA Interrupt */
-#define irq_byte_eng1          (ibase+69)      /* Byte Engine Interrupt [1] */
-#define irq_byte_eng0          (ibase+68)      /* Byte Engine Interrupt [0] */
-/* 67 unused   (bit 03) */
-/* 66 unused   (bit 02) */
-/* 65 unused   (bit 01) */
-/* 64 unused   (bit 00) */
-/*------------- Register: int_stat_1 */
-/* 63 unused   (bit 31) */
-/* 62 unused   (bit 30) */
-/* 61 unused   (bit 29) */
-/* 60 unused   (bit 28) */
-/* 59 unused   (bit 27) */
-/* 58 unused   (bit 26) */
-/* 57 unused   (bit 25) */
-/* 56 unused   (bit 24) */
-#define irq_buf_dma_mem2mem    (ibase+55)      /* BufDMA Memory to Memory
-                                                * Interrupt */
-#define irq_buf_dma_usbtransmit (ibase+54)     /* BufDMA USB Transmit
-                                                * Interrupt */
-#define irq_buf_dma_qpskpodtransmit (ibase+53) /* BufDMA QPSK/POD Tramsit
-                                                * Interrupt */
-#define irq_buf_dma_transmit_error (ibase+52)  /* BufDMA Transmit Error
-                                                * Interrupt */
-#define irq_buf_dma_usbrecv    (ibase+51)      /* BufDMA USB Receive
-                                                * Interrupt */
-#define irq_buf_dma_qpskpodrecv (ibase+50)     /* BufDMA QPSK/POD Receive
-                                                * Interrupt */
-#define irq_buf_dma_recv_error (ibase+49)      /* BufDMA Receive Error
-                                                * Interrupt */
-#define irq_qamdma_transmit_play (ibase+48)    /* QAMDMA Transmit/Play
-                                                * Interrupt */
-#define irq_qamdma_transmit_error (ibase+47)   /* QAMDMA Transmit Error
-                                                * Interrupt */
-#define irq_qamdma_recv2high   (ibase+46)      /* QAMDMA Receive 2 High
-                                                * (Chans 63-32) */
-#define irq_qamdma_recv2low    (ibase+45)      /* QAMDMA Receive 2 Low
-                                                * (Chans 31-0) */
-#define irq_qamdma_recv1high   (ibase+44)      /* QAMDMA Receive 1 High
-                                                * (Chans 63-32) */
-#define irq_qamdma_recv1low    (ibase+43)      /* QAMDMA Receive 1 Low
-                                                * (Chans 31-0) */
-#define irq_qamdma_recv_error  (ibase+42)      /* QAMDMA Receive Error
-                                                * Interrupt */
-#define irq_mpegsplice         (ibase+41)      /* MPEG Splice Interrupt */
-#define irq_deinterlace_rdy    (ibase+40)      /* Deinterlacer Frame Ready
-                                                * Interrupt */
-#define irq_ext_in0            (ibase+39)      /* External Interrupt irq_in0 */
-#define irq_gpio3              (ibase+38)      /* GP I/O IRQ 3 - From GP I/O
-                                                * Module */
-#define irq_gpio2              (ibase+37)      /* GP I/O IRQ 2 - From GP I/O
-                                                * Module (ABE_intN) */
-#define irq_pcrcmplt1          (ibase+36)      /* PCR Capture Complete  or
-                                                * Discontinuity 1 */
-#define irq_pcrcmplt2          (ibase+35)      /* PCR Capture Complete or
-                                                * Discontinuity 2 */
-#define irq_parse_peierr       (ibase+34)      /* PID Parser Error Detect
-                                                * (PEI) */
-#define irq_parse_cont_err     (ibase+33)      /* PID Parser continuity error
-                                                * detect */
-#define irq_ds1framer          (ibase+32)      /* DS1 Framer Interrupt */
-/*------------- Register: int_stat_0 */
-#define irq_gpio1              (ibase+31)      /* GP I/O IRQ 1 - From GP I/O
-                                                * Module */
-#define irq_gpio0              (ibase+30)      /* GP I/O IRQ 0 - From GP I/O
-                                                * Module */
-#define irq_qpsk_out_aloha     (ibase+29)      /* QPSK Output Slotted Aloha
-                                                * (chan 3) Transmission
-                                                * Completed OK */
-#define irq_qpsk_out_tdma      (ibase+28)      /* QPSK Output TDMA (chan 2)
-                                                * Transmission Completed OK */
-#define irq_qpsk_out_reserve   (ibase+27)      /* QPSK Output Reservation
-                                                * (chan 1) Transmission
-                                                * Completed OK */
-#define irq_qpsk_out_aloha_err (ibase+26)      /* QPSK Output Slotted Aloha
-                                                * (chan 3)Transmission
-                                                * completed with Errors. */
-#define irq_qpsk_out_tdma_err  (ibase+25)      /* QPSK Output TDMA (chan 2)
-                                                * Transmission completed with
-                                                * Errors. */
-#define irq_qpsk_out_rsrv_err  (ibase+24)      /* QPSK Output Reservation
-                                                * (chan 1) Transmission
-                                                * completed with Errors */
-#define irq_aloha_fail         (ibase+23)      /* Unsuccessful Resend of Aloha
-                                                * for N times. Aloha retry
-                                                * timeout for channel 3. */
-#define irq_timer1             (ibase+22)      /* Programmable Timer
-                                                * Interrupt */
-#define irq_keyboard           (ibase+21)      /* Keyboard Module Interrupt */
-#define irq_i2c                        (ibase+20)      /* I2C Module Interrupt */
-#define irq_spi                        (ibase+19)      /* SPI Module Interrupt */
-#define irq_irblaster          (ibase+18)      /* IR Blaster Interrupt */
-#define irq_splice_detect      (ibase+17)      /* PID Key Change Interrupt or
-                                                * Splice Detect Interrupt */
-#define irq_se_micro           (ibase+16)      /* Secure Micro I/F Module
-                                                * Interrupt */
-#define irq_uart1              (ibase+15)      /* UART Interrupt */
-#define irq_irrecv             (ibase+14)      /* IR Receiver Interrupt */
-#define irq_host_int1          (ibase+13)      /* Host-to-Host Interrupt 1 */
-#define irq_host_int0          (ibase+12)      /* Host-to-Host Interrupt 0 */
-#define irq_qpsk_hecerr                (ibase+11)      /* QPSK HEC Error Interrupt */
-#define irq_qpsk_crcerr                (ibase+10)      /* QPSK AAL-5 CRC Error
-                                                * Interrupt */
-/* 9 unused    (bit 09) */
-/* 8 unused    (bit 08) */
-#define irq_psicrcerr          (ibase+7)       /* QAM PSI CRC Error
-                                                * Interrupt */
-#define irq_psilength_err      (ibase+6)       /* QAM PSI Length Error
-                                                * Interrupt */
-#define irq_esfforward         (ibase+5)       /* ESF Interrupt Mark From
-                                                * Forward Path Reference -
-                                                * every 3ms when forward Mbits
-                                                * and forward slot control
-                                                * bytes are updated. */
-#define irq_esfreverse         (ibase+4)       /* ESF Interrupt Mark from
-                                                * Reverse Path Reference -
-                                                * delayed from forward mark by
-                                                * the ranging delay plus a
-                                                * fixed amount. When reverse
-                                                * Mbits and reverse slot
-                                                * control bytes are updated.
-                                                * Occurs every 3ms for 3.0M and
-                                                * 1.554 M upstream rates and
-                                                * every 6 ms for 256K upstream
-                                                * rate. */
-#define irq_aloha_timeout      (ibase+3)       /* Slotted-Aloha timeout on
-                                                * Channel 1. */
-#define irq_reservation                (ibase+2)       /* Partial (or Incremental)
-                                                * Reservation Message Completed
-                                                * or Slotted aloha verify for
-                                                * channel 1. */
-#define irq_aloha3             (ibase+1)       /* Slotted-Aloha Message Verify
-                                                * Interrupt or Reservation
-                                                * increment completed for
-                                                * channel 3. */
-#define irq_mpeg_d             (ibase+0)       /* MPEG Decoder Interrupt */
-#endif /* _ASM_MACH_POWERTV_INTERRUPTS_H_ */
diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h
deleted file mode 100644 (file)
index c86ef09..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- *     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.
- *
- * Portions Copyright (C)  Cisco Systems, Inc.
- */
-#ifndef __ASM_MACH_POWERTV_IOREMAP_H
-#define __ASM_MACH_POWERTV_IOREMAP_H
-
-#include <linux/types.h>
-#include <linux/log2.h>
-#include <linux/compiler.h>
-
-#include <asm/pgtable-bits.h>
-#include <asm/addrspace.h>
-
-/* We're going to mess with bits, so get sizes */
-#define IOR_BPC                        8                       /* Bits per char */
-#define IOR_PHYS_BITS          (IOR_BPC * sizeof(phys_addr_t))
-#define IOR_DMA_BITS           (IOR_BPC * sizeof(dma_addr_t))
-
-/*
- * Define the granularity of physical/DMA mapping in terms of the number
- * of bits that defines the offset within a grain. These will be the
- * least significant bits of the address. The rest of a physical or DMA
- * address will be used to index into an appropriate table to find the
- * offset to add to the address to yield the corresponding DMA or physical
- * address, respectively.
- */
-#define IOR_LSBITS             22                      /* Bits in a grain */
-
-/*
- * Compute the number of most significant address bits after removing those
- * used for the offset within a grain and then compute the number of table
- * entries for the conversion.
- */
-#define IOR_PHYS_MSBITS                (IOR_PHYS_BITS - IOR_LSBITS)
-#define IOR_NUM_PHYS_TO_DMA    ((phys_addr_t) 1 << IOR_PHYS_MSBITS)
-
-#define IOR_DMA_MSBITS         (IOR_DMA_BITS - IOR_LSBITS)
-#define IOR_NUM_DMA_TO_PHYS    ((dma_addr_t) 1 << IOR_DMA_MSBITS)
-
-/*
- * Define data structures used as elements in the arrays for the conversion
- * between physical and DMA addresses. We do some slightly fancy math to
- * compute the width of the offset element of the conversion tables so
- * that we can have the smallest conversion tables. Next, round up the
- * sizes to the next higher power of two, i.e. the offset element will have
- * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any
- * bits.  Finally, we compute a shift value that puts the most significant
- * bits of the offset into the most significant bits of the offset element.
- * This makes it more efficient on processors without barrel shifters and
- * easier to see the values if the conversion table is dumped in binary.
- */
-#define _IOR_OFFSET_WIDTH(n)   (1 << order_base_2(n))
-#define IOR_OFFSET_WIDTH(n) \
-       (_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n))
-
-#define IOR_PHYS_OFFSET_BITS   IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS)
-#define IOR_PHYS_SHIFT         (IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS)
-
-#define IOR_DMA_OFFSET_BITS    IOR_OFFSET_WIDTH(IOR_DMA_MSBITS)
-#define IOR_DMA_SHIFT          (IOR_DMA_BITS - IOR_DMA_OFFSET_BITS)
-
-struct ior_phys_to_dma {
-       dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed
-               __aligned((IOR_DMA_OFFSET_BITS / IOR_BPC));
-};
-
-struct ior_dma_to_phys {
-       dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed
-               __aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC));
-};
-
-extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
-extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
-
-static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys)
-{
-       return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset;
-}
-
-static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma)
-{
-       return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset;
-}
-
-/* These are not portable and should not be used in drivers. Drivers should
- * be using ioremap() and friends to map physical addresses to virtual
- * addresses and dma_map*() and friends to map virtual addresses into DMA
- * addresses and back.
- */
-static inline dma_addr_t phys_to_dma(phys_addr_t phys)
-{
-       return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT);
-}
-
-static inline phys_addr_t dma_to_phys(dma_addr_t dma)
-{
-       return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT);
-}
-
-extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias,
-       dma_addr_t size);
-
-/*
- * Allow physical addresses to be fixed up to help peripherals located
- * outside the low 32-bit range -- generic pass-through version.
- */
-static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
-{
-       return phys_addr;
-}
-
-/*
- * Handle the special case of addresses the area aliased into the first
- * 512 MiB of the processor's physical address space. These turn into either
- * kseg0 or kseg1 addresses, depending on flags.
- */
-static inline void __iomem *plat_ioremap(phys_t start, unsigned long size,
-       unsigned long flags)
-{
-       phys_addr_t start_offset;
-       void __iomem *result = NULL;
-
-       /* Start by checking to see whether this is an aliased address */
-       start_offset = _dma_to_phys_offset_raw(start);
-
-       /*
-        * If:
-        * o    the memory is aliased into the first 512 MiB, and
-        * o    the start and end are in the same RAM bank, and
-        * o    we don't have a zero size or wrap around, and
-        * o    we are supposed to create an uncached mapping,
-        *      handle this is a kseg0 or kseg1 address
-        */
-       if (start_offset != 0) {
-               phys_addr_t last;
-               dma_addr_t dma_to_phys_offset;
-
-               last = start + size - 1;
-               dma_to_phys_offset =
-                       _dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT;
-
-               if (dma_to_phys_offset == start_offset &&
-                       size != 0 && start <= last) {
-                       phys_t adjusted_start;
-                       adjusted_start = start + start_offset;
-                       if (flags == _CACHE_UNCACHED)
-                               result = (void __iomem *) (unsigned long)
-                                       CKSEG1ADDR(adjusted_start);
-                       else
-                               result = (void __iomem *) (unsigned long)
-                                       CKSEG0ADDR(adjusted_start);
-               }
-       }
-
-       return result;
-}
-
-static inline int plat_iounmap(const volatile void __iomem *addr)
-{
-       return 0;
-}
-#endif /* __ASM_MACH_POWERTV_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-powertv/irq.h b/arch/mips/include/asm/mach-powertv/irq.h
deleted file mode 100644 (file)
index 4bd5d0c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _ASM_MACH_POWERTV_IRQ_H
-#define _ASM_MACH_POWERTV_IRQ_H
-#include <asm/mach-powertv/interrupts.h>
-
-#define MIPS_CPU_IRQ_BASE      ibase
-#define NR_IRQS                        127
-#endif
diff --git a/arch/mips/include/asm/mach-powertv/powertv-clock.h b/arch/mips/include/asm/mach-powertv/powertv-clock.h
deleted file mode 100644 (file)
index 6f3e9a0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-/*
- * Local definitions for the powertv PCI code
- */
-
-#ifndef _POWERTV_PCI_POWERTV_PCI_H_
-#define _POWERTV_PCI_POWERTV_PCI_H_
-extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
-extern int asic_pcie_init(void);
-extern int asic_pcie_init(void);
-
-extern int log_level;
-#endif
diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h
deleted file mode 100644 (file)
index c5651c8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- *
- * This version for the PowerTV platform copied from the Malta version.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- */
-#ifndef __ASM_MACH_POWERTV_WAR_H
-#define __ASM_MACH_POWERTV_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       1
-#define MIPS_CACHE_SYNC_WAR            1
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  1
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MACH_POWERTV_WAR_H */
index a02596cf1abd418a80653b5ef36bdda6cbbb4bbd..e33227998713e644a53e21c2e11c3e5fa174c970 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
 #ifndef __ASM_MIPS_BOARDS_PIIX4_H
 #define __ASM_MIPS_BOARDS_PIIX4_H
 
-/************************************************************************
- *  IO register offsets
- ************************************************************************/
-#define PIIX4_ICTLR1_ICW1      0x20
-#define PIIX4_ICTLR1_ICW2      0x21
-#define PIIX4_ICTLR1_ICW3      0x21
-#define PIIX4_ICTLR1_ICW4      0x21
-#define PIIX4_ICTLR2_ICW1      0xa0
-#define PIIX4_ICTLR2_ICW2      0xa1
-#define PIIX4_ICTLR2_ICW3      0xa1
-#define PIIX4_ICTLR2_ICW4      0xa1
-#define PIIX4_ICTLR1_OCW1      0x21
-#define PIIX4_ICTLR1_OCW2      0x20
-#define PIIX4_ICTLR1_OCW3      0x20
-#define PIIX4_ICTLR1_OCW4      0x20
-#define PIIX4_ICTLR2_OCW1      0xa1
-#define PIIX4_ICTLR2_OCW2      0xa0
-#define PIIX4_ICTLR2_OCW3      0xa0
-#define PIIX4_ICTLR2_OCW4      0xa0
-
-
-/************************************************************************
- *  Register encodings.
- ************************************************************************/
-#define PIIX4_OCW2_NSEOI       (0x1 << 5)
-#define PIIX4_OCW2_SEOI                (0x3 << 5)
-#define PIIX4_OCW2_RNSEOI      (0x5 << 5)
-#define PIIX4_OCW2_RAEOIS      (0x4 << 5)
-#define PIIX4_OCW2_RAEOIC      (0x0 << 5)
-#define PIIX4_OCW2_RSEOI       (0x7 << 5)
-#define PIIX4_OCW2_SP          (0x6 << 5)
-#define PIIX4_OCW2_NOP         (0x2 << 5)
-
-#define PIIX4_OCW2_SEL         (0x0 << 3)
-
-#define PIIX4_OCW2_ILS_0       0
-#define PIIX4_OCW2_ILS_1       1
-#define PIIX4_OCW2_ILS_2       2
-#define PIIX4_OCW2_ILS_3       3
-#define PIIX4_OCW2_ILS_4       4
-#define PIIX4_OCW2_ILS_5       5
-#define PIIX4_OCW2_ILS_6       6
-#define PIIX4_OCW2_ILS_7       7
-#define PIIX4_OCW2_ILS_8       0
-#define PIIX4_OCW2_ILS_9       1
-#define PIIX4_OCW2_ILS_10      2
-#define PIIX4_OCW2_ILS_11      3
-#define PIIX4_OCW2_ILS_12      4
-#define PIIX4_OCW2_ILS_13      5
-#define PIIX4_OCW2_ILS_14      6
-#define PIIX4_OCW2_ILS_15      7
-
-#define PIIX4_OCW3_SEL         (0x1 << 3)
-
-#define PIIX4_OCW3_IRR         0x2
-#define PIIX4_OCW3_ISR         0x3
+/* PIRQX Route Control */
+#define PIIX4_FUNC0_PIRQRC                     0x60
+#define   PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_DISABLE       (1 << 7)
+#define   PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MASK          0xf
+#define   PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX           16
+/* Top Of Memory */
+#define PIIX4_FUNC0_TOM                                0x69
+#define   PIIX4_FUNC0_TOM_TOP_OF_MEMORY_MASK           0xf0
+/* Deterministic Latency Control */
+#define PIIX4_FUNC0_DLC                                0x82
+#define   PIIX4_FUNC0_DLC_USBPR_EN                     (1 << 2)
+#define   PIIX4_FUNC0_DLC_PASSIVE_RELEASE_EN           (1 << 1)
+#define   PIIX4_FUNC0_DLC_DELAYED_TRANSACTION_EN       (1 << 0)
+
+/* IDE Timing */
+#define PIIX4_FUNC1_IDETIM_PRIMARY_LO          0x40
+#define PIIX4_FUNC1_IDETIM_PRIMARY_HI          0x41
+#define   PIIX4_FUNC1_IDETIM_PRIMARY_HI_IDE_DECODE_EN  (1 << 7)
+#define PIIX4_FUNC1_IDETIM_SECONDARY_LO                0x42
+#define PIIX4_FUNC1_IDETIM_SECONDARY_HI                0x43
+#define   PIIX4_FUNC1_IDETIM_SECONDARY_HI_IDE_DECODE_EN        (1 << 7)
 
 #endif /* __ASM_MIPS_BOARDS_PIIX4_H */
index 3b29079b5424b4fe0f78588ab1b8821aef0a1237..e277bbad28713d3a510cf5e5dec337316f0a745a 100644 (file)
 #endif /* SMTC */
 #include <asm-generic/mm_hooks.h>
 
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-
 #define TLBMISS_HANDLER_SETUP_PGD(pgd)                                 \
 do {                                                                   \
        extern void tlbmiss_handler_setup_pgd(unsigned long);           \
        tlbmiss_handler_setup_pgd((unsigned long)(pgd));                \
 } while (0)
 
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 #define TLBMISS_HANDLER_SETUP()                                                \
        do {                                                            \
                TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);              \
-               write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+               write_c0_xcontext((unsigned long) smp_processor_id() << \
+                                               SMP_CPUID_REGSHIFT);    \
        } while (0)
 
-#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
+#else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
 
 /*
  * For the fast tlb miss handlers, we keep a per cpu array of pointers
@@ -47,21 +47,11 @@ do {                                                                        \
  */
 extern unsigned long pgd_current[];
 
-#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
-       pgd_current[smp_processor_id()] = (unsigned long)(pgd)
-
-#ifdef CONFIG_32BIT
 #define TLBMISS_HANDLER_SETUP()                                                \
-       write_c0_context((unsigned long) smp_processor_id() << 25);     \
+       write_c0_context((unsigned long) smp_processor_id() <<          \
+                                               SMP_CPUID_REGSHIFT);    \
        back_to_back_c0_hazard();                                       \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
-#ifdef CONFIG_64BIT
-#define TLBMISS_HANDLER_SETUP()                                                \
-       write_c0_context((unsigned long) smp_processor_id() << 26);     \
-       back_to_back_c0_hazard();                                       \
-       TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
index 5e6cd0947393295ea87cba5191c5a6fbf728c527..7bba9da110afab3f9c92eb02a52161ac23642d29 100644 (file)
@@ -81,7 +81,6 @@ static inline long regs_return_value(struct pt_regs *regs)
 
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 #define profile_pc(regs) instruction_pointer(regs)
-#define user_stack_pointer(r) ((r)->regs[29])
 
 extern asmlinkage void syscall_trace_enter(struct pt_regs *regs);
 extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
@@ -100,4 +99,17 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs)
        (struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1;      \
 })
 
+/* Helpers for working with the user stack pointer */
+
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+       return regs->regs[29];
+}
+
+static inline void user_stack_pointer_set(struct pt_regs *regs,
+       unsigned long val)
+{
+       regs->regs[29] = val;
+}
+
 #endif /* _ASM_PTRACE_H */
index a0b2650516ac9a2837a362f4c5768ce609767216..34d1a19171257ff8d8e602988615b8b8e2878ff9 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/asm.h>
 #include <asm/cacheops.h>
 #include <asm/cpu-features.h>
+#include <asm/cpu-type.h>
 #include <asm/mipsmtregs.h>
 
 /*
@@ -162,7 +163,15 @@ static inline void flush_scache_line_indexed(unsigned long addr)
 static inline void flush_icache_line(unsigned long addr)
 {
        __iflush_prologue
-       cache_op(Hit_Invalidate_I, addr);
+       switch (boot_cpu_type()) {
+       case CPU_LOONGSON2:
+               cache_op(Hit_Invalidate_I_Loongson23, addr);
+               break;
+
+       default:
+               cache_op(Hit_Invalidate_I, addr);
+               break;
+       }
        __iflush_epilogue
 }
 
@@ -208,7 +217,15 @@ static inline void flush_scache_line(unsigned long addr)
  */
 static inline void protected_flush_icache_line(unsigned long addr)
 {
-       protected_cache_op(Hit_Invalidate_I, addr);
+       switch (boot_cpu_type()) {
+       case CPU_LOONGSON2:
+               protected_cache_op(Hit_Invalidate_I_Loongson23, addr);
+               break;
+
+       default:
+               protected_cache_op(Hit_Invalidate_I, addr);
+               break;
+       }
 }
 
 /*
@@ -412,8 +429,8 @@ __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64
 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
 
 /* build blast_xxx_range, protected_blast_xxx_range */
-#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \
-static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
+#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra)       \
+static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, \
                                                    unsigned long end)  \
 {                                                                      \
        unsigned long lsize = cpu_##desc##_line_size();                 \
@@ -432,13 +449,15 @@ static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
        __##pfx##flush_epilogue                                         \
 }
 
-__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_)
-__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_)
-__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_)
-__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, )
-__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )
+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, )
+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, )
+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, )
+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I_Loongson23, \
+       protected_, loongson23_)
+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , )
+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , )
 /* blast_inv_dcache_range */
-__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
-__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
+__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
+__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
 
 #endif /* _ASM_R4KCACHE_H */
index e26589ef36eee12a9d5a957edf0df6d59ae7217e..d7bfdeba9e845acfa83270f01bb280a687d785ad 100644 (file)
@@ -5,6 +5,14 @@
 
 extern void setup_early_printk(void);
 
+#ifdef CONFIG_EARLY_PRINTK_8250
+extern void setup_8250_early_printk_port(unsigned long base,
+       unsigned int reg_shift, unsigned int timeout);
+#else
+static inline void setup_8250_early_printk_port(unsigned long base,
+       unsigned int reg_shift, unsigned int timeout) {}
+#endif
+
 extern void set_handler(unsigned long offset, void *addr, unsigned long len);
 extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
 
index 23fc95e65673bcb5d907a77f83714c424092add6..4857e2c8df5ae2eae1ac4bcca27b7dca586842aa 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/asmmacro.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
 
 /*
  * For SMTC kernel, global IE should be left set, and interrupts
                .endm
 
 #ifdef CONFIG_SMP
-#ifdef CONFIG_MIPS_MT_SMTC
-#define PTEBASE_SHIFT  19      /* TCBIND */
-#define CPU_ID_REG CP0_TCBIND
-#define CPU_ID_MFC0 mfc0
-#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
-#define PTEBASE_SHIFT  48      /* XCONTEXT */
-#define CPU_ID_REG CP0_XCONTEXT
-#define CPU_ID_MFC0 MFC0
-#else
-#define PTEBASE_SHIFT  23      /* CONTEXT */
-#define CPU_ID_REG CP0_CONTEXT
-#define CPU_ID_MFC0 MFC0
-#endif
                .macro  get_saved_sp    /* SMP variation */
-               CPU_ID_MFC0     k0, CPU_ID_REG
+               ASM_CPUID_MFC0  k0, ASM_SMP_CPUID_REG
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
                lui     k1, %hi(kernelsp)
 #else
                daddiu  k1, %hi(kernelsp)
                dsll    k1, 16
 #endif
-               LONG_SRL        k0, PTEBASE_SHIFT
+               LONG_SRL        k0, SMP_CPUID_PTRSHIFT
                LONG_ADDU       k1, k0
                LONG_L  k1, %lo(kernelsp)(k1)
                .endm
 
                .macro  set_saved_sp stackp temp temp2
-               CPU_ID_MFC0     \temp, CPU_ID_REG
-               LONG_SRL        \temp, PTEBASE_SHIFT
+               ASM_CPUID_MFC0  \temp, ASM_SMP_CPUID_REG
+               LONG_SRL        \temp, SMP_CPUID_PTRSHIFT
                LONG_S  \stackp, kernelsp(\temp)
                .endm
-#else
+#else /* !CONFIG_SMP */
                .macro  get_saved_sp    /* Uniprocessor variation */
 #ifdef CONFIG_CPU_JUMP_WORKAROUNDS
                /*
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..81c8913
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * 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.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ *
+ * Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org>
+ */
+
+#ifndef __ASM_MIPS_SYSCALL_H
+#define __ASM_MIPS_SYSCALL_H
+
+#include <linux/audit.h>
+#include <linux/elf-em.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <asm/ptrace.h>
+
+static inline long syscall_get_nr(struct task_struct *task,
+                                 struct pt_regs *regs)
+{
+       return regs->regs[2];
+}
+
+static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
+       struct task_struct *task, struct pt_regs *regs, unsigned int n)
+{
+       unsigned long usp = regs->regs[29];
+
+       switch (n) {
+       case 0: case 1: case 2: case 3:
+               *arg = regs->regs[4 + n];
+
+               return 0;
+
+#ifdef CONFIG_32BIT
+       case 4: case 5: case 6: case 7:
+               return get_user(*arg, (int *)usp + 4 * n);
+#endif
+
+#ifdef CONFIG_64BIT
+       case 4: case 5: case 6: case 7:
+#ifdef CONFIG_MIPS32_O32
+               if (test_thread_flag(TIF_32BIT_REGS))
+                       return get_user(*arg, (int *)usp + 4 * n);
+               else
+#endif
+                       *arg = regs->regs[4 + n];
+
+               return 0;
+#endif
+
+       default:
+               BUG();
+       }
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+                                           struct pt_regs *regs)
+{
+       return regs->regs[2];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+                                           struct pt_regs *regs,
+                                           int error, long val)
+{
+       if (error) {
+               regs->regs[2] = -error;
+               regs->regs[7] = -1;
+       } else {
+               regs->regs[2] = val;
+               regs->regs[7] = 0;
+       }
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+       unsigned long arg;
+       int ret;
+
+       while (n--)
+               ret |= mips_get_syscall_arg(&arg, task, regs, i++);
+
+       /*
+        * No way to communicate an error because this is a void function.
+        */
+#if 0
+       return ret;
+#endif
+}
+
+extern const unsigned long sys_call_table[];
+extern const unsigned long sys32_call_table[];
+extern const unsigned long sysn32_call_table[];
+
+static inline int __syscall_get_arch(void)
+{
+       int arch = EM_MIPS;
+#ifdef CONFIG_64BIT
+       arch |=  __AUDIT_ARCH_64BIT;
+#endif
+#if defined(__LITTLE_ENDIAN)
+       arch |=  __AUDIT_ARCH_LE;
+#endif
+       return arch;
+}
+
+#endif /* __ASM_MIPS_SYSCALL_H */
index 61215a34acc68ff87da07665c65c8dc0f6dbfcc1..f9b24bfbdbae96f8cc31d58d7cb0318130ceab9f 100644 (file)
@@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_32BIT_ADDR         23      /* 32-bit address space (o32/n32) */
 #define TIF_FPUBOUND           24      /* thread bound to FPU-full CPU set */
 #define TIF_LOAD_WATCH         25      /* If set, load watch registers */
+#define TIF_SYSCALL_TRACEPOINT 26      /* syscall tracepoint instrumentation */
 #define TIF_SYSCALL_TRACE      31      /* syscall trace active */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -132,21 +133,54 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_32BIT_ADDR                (1<<TIF_32BIT_ADDR)
 #define _TIF_FPUBOUND          (1<<TIF_FPUBOUND)
 #define _TIF_LOAD_WATCH                (1<<TIF_LOAD_WATCH)
+#define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 
 #define _TIF_WORK_SYSCALL_ENTRY        (_TIF_NOHZ | _TIF_SYSCALL_TRACE |       \
-                                _TIF_SYSCALL_AUDIT)
+                                _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
 
 /* work to do in syscall_trace_leave() */
 #define _TIF_WORK_SYSCALL_EXIT (_TIF_NOHZ | _TIF_SYSCALL_TRACE |       \
-                                _TIF_SYSCALL_AUDIT)
+                                _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK         \
        (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK      (_TIF_NOHZ | _TIF_WORK_MASK |           \
-                                _TIF_WORK_SYSCALL_EXIT)
+                                _TIF_WORK_SYSCALL_EXIT |               \
+                                _TIF_SYSCALL_TRACEPOINT)
 
-#endif /* __KERNEL__ */
+/*
+ * We stash processor id into a COP0 register to retrieve it fast
+ * at kernel exception entry.
+ */
+#if defined(CONFIG_MIPS_MT_SMTC)
+#define SMP_CPUID_REG          2, 2    /* TCBIND */
+#define ASM_SMP_CPUID_REG      $2, 2
+#define SMP_CPUID_PTRSHIFT     19
+#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
+#define SMP_CPUID_REG          20, 0   /* XCONTEXT */
+#define ASM_SMP_CPUID_REG      $20
+#define SMP_CPUID_PTRSHIFT     48
+#else
+#define SMP_CPUID_REG          4, 0    /* CONTEXT */
+#define ASM_SMP_CPUID_REG      $4
+#define SMP_CPUID_PTRSHIFT     23
+#endif
 
+#ifdef CONFIG_64BIT
+#define SMP_CPUID_REGSHIFT     (SMP_CPUID_PTRSHIFT + 3)
+#else
+#define SMP_CPUID_REGSHIFT     (SMP_CPUID_PTRSHIFT + 2)
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#define ASM_CPUID_MFC0         mfc0
+#define UASM_i_CPUID_MFC0      uasm_i_mfc0
+#else
+#define ASM_CPUID_MFC0         MFC0
+#define UASM_i_CPUID_MFC0      UASM_i_MFC0
+#endif
+
+#endif /* __KERNEL__ */
 #endif /* _ASM_THREAD_INFO_H */
index 2d7b9df4542dd478d53f53d8151d3381d1c58aee..24f534a7fbc3bd84c7bd3b3bda2238e3ce183943 100644 (file)
@@ -75,7 +75,7 @@ extern int init_r4k_clocksource(void);
 
 static inline int init_mips_clocksource(void)
 {
-#if defined(CONFIG_CSRC_R4K) && !defined(CONFIG_CSRC_GIC)
+#ifdef CONFIG_CSRC_R4K
        return init_r4k_clocksource();
 #else
        return 0;
index 63c9c886173a68c6a89857b7f7d28046cb712e56..4d3b92886665799d2ca2b746d8efc310cc0c1168 100644 (file)
 
 #include <uapi/asm/unistd.h>
 
+#ifdef CONFIG_MIPS32_N32
+#define NR_syscalls  (__NR_N32_Linux + __NR_N32_Linux_syscalls)
+#elif defined(CONFIG_64BIT)
+#define NR_syscalls  (__NR_64_Linux + __NR_64_Linux_syscalls)
+#else
+#define NR_syscalls  (__NR_O32_Linux + __NR_O32_Linux_syscalls)
+#endif
 
 #ifndef __ASSEMBLY__
 
index 88e292b7719e99963f74692f0ffbd36e60e79c83..e81174432bab0eb7c1e41093e6bdd5ed833fc851 100644 (file)
@@ -33,6 +33,8 @@ struct siginfo;
 #error _MIPS_SZLONG neither 32 nor 64
 #endif
 
+#define __ARCH_SIGSYS
+
 #include <asm-generic/siginfo.h>
 
 typedef struct siginfo {
@@ -97,6 +99,13 @@ typedef struct siginfo {
                        __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
                        int _fd;
                } _sigpoll;
+
+               /* SIGSYS */
+               struct {
+                       void __user *_call_addr; /* calling user insn */
+                       int _syscall;   /* triggering system call number */
+                       unsigned int _arch;     /* AUDIT_ARCH_* of syscall */
+               } _sigsys;
        } _sifields;
 } siginfo_t;
 
index 423d871a946ba15ae5b5ea70338530949fa8d166..1c1b71752c84cbc26dc2c0f81cc778e0a749a495 100644 (file)
@@ -26,7 +26,6 @@ obj-$(CONFIG_CEVT_TXX9)               += cevt-txx9.o
 obj-$(CONFIG_CSRC_BCM1480)     += csrc-bcm1480.o
 obj-$(CONFIG_CSRC_GIC)         += csrc-gic.o
 obj-$(CONFIG_CSRC_IOASIC)      += csrc-ioasic.o
-obj-$(CONFIG_CSRC_POWERTV)     += csrc-powertv.o
 obj-$(CONFIG_CSRC_R4K)         += csrc-r4k.o
 obj-$(CONFIG_CSRC_SB1250)      += csrc-sb1250.o
 obj-$(CONFIG_SYNC_R4K)         += sync-r4k.o
@@ -35,6 +34,7 @@ obj-$(CONFIG_STACKTRACE)      += stacktrace.o
 obj-$(CONFIG_MODULES)          += mips_ksyms.o module.o
 obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
 
+obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
 obj-$(CONFIG_FUNCTION_TRACER)  += mcount.o ftrace.o
 
 obj-$(CONFIG_CPU_R4K_FPU)      += r4k_fpu.o r4k_switch.o
@@ -84,6 +84,7 @@ obj-$(CONFIG_GPIO_TXX9)               += gpio_txx9.o
 obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
+obj-$(CONFIG_EARLY_PRINTK_8250)        += early_printk_8250.o
 obj-$(CONFIG_SPINLOCK_TEST)    += spinlock_test.o
 obj-$(CONFIG_MIPS_MACHINE)     += mips_machine.o
 
index 5465dc183e5ac4d26e36d300b1df36fb4cf4d2b5..c814287bdf5d10d8a44a9e6a843b3acd5ab30ff8 100644 (file)
@@ -376,13 +376,33 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                                __cpu_name[cpu] = "R4000PC";
                        }
                } else {
+                       int cca = read_c0_config() & CONF_CM_CMASK;
+                       int mc;
+
+                       /*
+                        * SC and MC versions can't be reliably told apart,
+                        * but only the latter support coherent caching
+                        * modes so assume the firmware has set the KSEG0
+                        * coherency attribute reasonably (if uncached, we
+                        * assume SC).
+                        */
+                       switch (cca) {
+                       case CONF_CM_CACHABLE_CE:
+                       case CONF_CM_CACHABLE_COW:
+                       case CONF_CM_CACHABLE_CUW:
+                               mc = 1;
+                               break;
+                       default:
+                               mc = 0;
+                               break;
+                       }
                        if ((c->processor_id & PRID_REV_MASK) >=
                            PRID_REV_R4400) {
-                               c->cputype = CPU_R4400SC;
-                               __cpu_name[cpu] = "R4400SC";
+                               c->cputype = mc ? CPU_R4400MC : CPU_R4400SC;
+                               __cpu_name[cpu] = mc ? "R4400MC" : "R4400SC";
                        } else {
-                               c->cputype = CPU_R4000SC;
-                               __cpu_name[cpu] = "R4000SC";
+                               c->cputype = mc ? CPU_R4000MC : CPU_R4000SC;
+                               __cpu_name[cpu] = mc ? "R4000MC" : "R4000SC";
                        }
                }
 
@@ -1079,8 +1099,8 @@ void cpu_report(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
 
-       printk(KERN_INFO "CPU revision is: %08x (%s)\n",
-              c->processor_id, cpu_name_string());
+       pr_info("CPU%d revision is: %08x (%s)\n",
+               smp_processor_id(), c->processor_id, cpu_name_string());
        if (c->options & MIPS_CPU_FPU)
                printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
 }
diff --git a/arch/mips/kernel/csrc-powertv.c b/arch/mips/kernel/csrc-powertv.c
deleted file mode 100644 (file)
index abd99ea..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2008 Scientific-Atlanta, 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; 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.
- */
-/*
- * The file comes from kernel/csrc-r4k.c
- */
-#include <linux/clocksource.h>
-#include <linux/init.h>
-
-#include <asm/time.h>                  /* Not included in linux/time.h */
-
-#include <asm/mach-powertv/asic_regs.h>
-#include "powertv-clock.h"
-
-/* MIPS PLL Register Definitions */
-#define PLL_GET_M(x)           (((x) >> 8) & 0x000000FF)
-#define PLL_GET_N(x)           (((x) >> 16) & 0x000000FF)
-#define PLL_GET_P(x)           (((x) >> 24) & 0x00000007)
-
-/*
- * returns:  Clock frequency in kHz
- */
-unsigned int __init mips_get_pll_freq(void)
-{
-       unsigned int pll_reg, m, n, p;
-       unsigned int fin = 54000; /* Base frequency in kHz */
-       unsigned int fout;
-
-       /* Read PLL register setting */
-       pll_reg = asic_read(mips_pll_setup);
-       m = PLL_GET_M(pll_reg);
-       n = PLL_GET_N(pll_reg);
-       p = PLL_GET_P(pll_reg);
-       pr_info("MIPS PLL Register:0x%x  M=%d  N=%d  P=%d\n", pll_reg, m, n, p);
-
-       /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */
-       fout = ((2 * n * fin) / (m * (0x01 << p)));
-
-       pr_info("MIPS Clock Freq=%d kHz\n", fout);
-
-       return fout;
-}
-
-static cycle_t c0_hpt_read(struct clocksource *cs)
-{
-       return read_c0_count();
-}
-
-static struct clocksource clocksource_mips = {
-       .name           = "powertv-counter",
-       .read           = c0_hpt_read,
-       .mask           = CLOCKSOURCE_MASK(32),
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static void __init powertv_c0_hpt_clocksource_init(void)
-{
-       unsigned int pll_freq = mips_get_pll_freq();
-
-       pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000,
-               (pll_freq % 1000) * 100 / 1000);
-
-       mips_hpt_frequency = pll_freq / 2 * 1000;
-
-       clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-
-       clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
-}
-
-/**
- * struct tim_c - free running counter
- * @hi: High 16 bits of the counter
- * @lo: Low 32 bits of the counter
- *
- * Lays out the structure of the free running counter in memory. This counter
- * increments at a rate of 27 MHz/8 on all platforms.
- */
-struct tim_c {
-       unsigned int hi;
-       unsigned int lo;
-};
-
-static struct tim_c *tim_c;
-
-static cycle_t tim_c_read(struct clocksource *cs)
-{
-       unsigned int hi;
-       unsigned int next_hi;
-       unsigned int lo;
-
-       hi = readl(&tim_c->hi);
-
-       for (;;) {
-               lo = readl(&tim_c->lo);
-               next_hi = readl(&tim_c->hi);
-               if (next_hi == hi)
-                       break;
-               hi = next_hi;
-       }
-
-pr_crit("%s: read %llx\n", __func__, ((u64) hi << 32) | lo);
-       return ((u64) hi << 32) | lo;
-}
-
-#define TIM_C_SIZE             48              /* # bits in the timer */
-
-static struct clocksource clocksource_tim_c = {
-       .name           = "powertv-tim_c",
-       .read           = tim_c_read,
-       .mask           = CLOCKSOURCE_MASK(TIM_C_SIZE),
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/**
- * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
- *
- * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
- * 1 / (27,000,000/8) seconds.
- */
-static void __init powertv_tim_c_clocksource_init(void)
-{
-       const unsigned long     counts_per_second = 27000000 / 8;
-
-       clocksource_tim_c.rating = 200;
-
-       clocksource_register_hz(&clocksource_tim_c, counts_per_second);
-       tim_c = (struct tim_c *) asic_reg_addr(tim_ch);
-}
-
-/**
- powertv_clocksource_init - initialize all clocksources
- */
-void __init powertv_clocksource_init(void)
-{
-       powertv_c0_hpt_clocksource_init();
-       powertv_tim_c_clocksource_init();
-}
diff --git a/arch/mips/kernel/early_printk_8250.c b/arch/mips/kernel/early_printk_8250.c
new file mode 100644 (file)
index 0000000..83cea37
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  8250/16550-type serial ports prom_putchar()
+ *
+ *  Copyright (C) 2010  Yoichi Yuasa <yuasa@linux-mips.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.
+ *
+ *  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 <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+static void __iomem *serial8250_base;
+static unsigned int serial8250_reg_shift;
+static unsigned int serial8250_tx_timeout;
+
+void setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift,
+                                 unsigned int timeout)
+{
+       serial8250_base = (void __iomem *)base;
+       serial8250_reg_shift = reg_shift;
+       serial8250_tx_timeout = timeout;
+}
+
+static inline u8 serial_in(int offset)
+{
+       return readb(serial8250_base + (offset << serial8250_reg_shift));
+}
+
+static inline void serial_out(int offset, char value)
+{
+       writeb(value, serial8250_base + (offset << serial8250_reg_shift));
+}
+
+void prom_putchar(char c)
+{
+       unsigned int timeout;
+       int status, bits;
+
+       if (!serial8250_base)
+               return;
+
+       timeout = serial8250_tx_timeout;
+       bits = UART_LSR_TEMT | UART_LSR_THRE;
+
+       do {
+               status = serial_in(UART_LSR);
+
+               if (--timeout == 0)
+                       break;
+       } while ((status & bits) != bits);
+
+       if (timeout)
+               serial_out(UART_TX, c);
+}
index dba90ec0dc385ffcad5cc09eda51031d4e9a0fcc..185ba258361b979ee9531bd18d38b0242e1de979 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/init.h>
 #include <linux/ftrace.h>
+#include <linux/syscalls.h>
 
 #include <asm/asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/cacheflush.h>
+#include <asm/syscall.h>
 #include <asm/uasm.h>
+#include <asm/unistd.h>
 
 #include <asm-generic/sections.h>
 
@@ -364,3 +367,33 @@ out:
        WARN_ON(1);
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+#ifdef CONFIG_32BIT
+unsigned long __init arch_syscall_addr(int nr)
+{
+       return (unsigned long)sys_call_table[nr - __NR_O32_Linux];
+}
+#endif
+
+#ifdef CONFIG_64BIT
+
+unsigned long __init arch_syscall_addr(int nr)
+{
+#ifdef CONFIG_MIPS32_N32
+       if (nr >= __NR_N32_Linux && nr <= __NR_N32_Linux + __NR_N32_Linux_syscalls)
+               return (unsigned long)sysn32_call_table[nr - __NR_N32_Linux];
+#endif
+       if (nr >= __NR_64_Linux  && nr <= __NR_64_Linux + __NR_64_Linux_syscalls)
+               return (unsigned long)sys_call_table[nr - __NR_64_Linux];
+#ifdef CONFIG_MIPS32_O32
+       if (nr >= __NR_O32_Linux && nr <= __NR_O32_Linux + __NR_O32_Linux_syscalls)
+               return (unsigned long)sys32_call_table[nr - __NR_O32_Linux];
+#endif
+
+       return (unsigned long) &sys_ni_syscall;
+}
+#endif
+
+#endif /* CONFIG_FTRACE_SYSCALLS */
index 31fa856829cbf2620521317e5247d42b9e3fb087..47d7583cd67ff7de77d5010c89d8bcbba234c2d0 100644 (file)
@@ -374,12 +374,20 @@ NESTED(except_vec_nmi, 0, sp)
 NESTED(nmi_handler, PT_SIZE, sp)
        .set    push
        .set    noat
+       /*
+        * Clear ERL - restore segment mapping
+        * Clear BEV - required for page fault exception handler to work
+        */
+       mfc0    k0, CP0_STATUS
+       ori     k0, k0, ST0_EXL
+       li      k1, ~(ST0_BEV | ST0_ERL)
+       and     k0, k0, k1
+       mtc0    k0, CP0_STATUS
+       _ehb
        SAVE_ALL
        move    a0, sp
        jal     nmi_exception_handler
-       RESTORE_ALL
-       .set    mips3
-       eret
+       /* nmi_exception_handler never returns */
        .set    pop
        END(nmi_handler)
 
index 72ef2d25cbf21ab5bebb1a93b0c0bf6e4e4fdff7..e498f2b3646a167e73f36e0f74857a5e6da6308e 100644 (file)
@@ -150,7 +150,7 @@ int __init mips_cpu_intc_init(struct device_node *of_node,
        domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
                                       &mips_cpu_intc_irq_domain_ops, NULL);
        if (!domain)
-               panic("Failed to add irqdomain for MIPS CPU\n");
+               panic("Failed to add irqdomain for MIPS CPU");
 
        return 0;
 }
index 977a623d9253ca3580084652ee264b3c4f59a6c2..2a52568dbcd6786cf0ca3c7100f056abba8ed08b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
 #include <linux/mm.h>
+#include <linux/numa.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/fs.h>
@@ -46,7 +47,7 @@ static DEFINE_SPINLOCK(dbe_lock);
 void *module_alloc(unsigned long size)
 {
        return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
-                               GFP_KERNEL, PAGE_KERNEL, -1,
+                               GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE,
                                __builtin_return_address(0));
 }
 #endif
index 45f1ffcf1a4b6299b181cf99e9d08cac59da6cfb..24cdf64789c39dcf8be4a4c214b02540aa02370b 100644 (file)
@@ -971,11 +971,11 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
 [C(LL)] = {
        [C(OP_READ)] = {
                [C(RESULT_ACCESS)]      = { 0x1c, CNTR_ODD, P },
-               [C(RESULT_MISS)]        = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+               [C(RESULT_MISS)]        = { 0x1d, CNTR_EVEN, P },
        },
        [C(OP_WRITE)] = {
                [C(RESULT_ACCESS)]      = { 0x1c, CNTR_ODD, P },
-               [C(RESULT_MISS)]        = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+               [C(RESULT_MISS)]        = { 0x1d, CNTR_EVEN, P },
        },
 },
 [C(ITLB)] = {
index 8ae1ebef8b71e67fd5e205646bd10adcdb1b0299..b52e1d2b33e03836002b495328124225ebba29db 100644 (file)
  */
 #include <linux/compiler.h>
 #include <linux/context_tracking.h>
+#include <linux/elf.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
+#include <linux/regset.h>
 #include <linux/smp.h>
 #include <linux/user.h>
 #include <linux/security.h>
+#include <linux/tracehook.h>
 #include <linux/audit.h>
 #include <linux/seccomp.h>
+#include <linux/ftrace.h>
 
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/mipsmtregs.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/syscall.h>
 #include <asm/uaccess.h>
 #include <asm/bootinfo.h>
 #include <asm/reg.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -255,6 +263,133 @@ int ptrace_set_watch_regs(struct task_struct *child,
        return 0;
 }
 
+/* regset get/set implementations */
+
+static int gpr_get(struct task_struct *target,
+                  const struct user_regset *regset,
+                  unsigned int pos, unsigned int count,
+                  void *kbuf, void __user *ubuf)
+{
+       struct pt_regs *regs = task_pt_regs(target);
+
+       return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                  regs, 0, sizeof(*regs));
+}
+
+static int gpr_set(struct task_struct *target,
+                  const struct user_regset *regset,
+                  unsigned int pos, unsigned int count,
+                  const void *kbuf, const void __user *ubuf)
+{
+       struct pt_regs newregs;
+       int ret;
+
+       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                &newregs,
+                                0, sizeof(newregs));
+       if (ret)
+               return ret;
+
+       *task_pt_regs(target) = newregs;
+
+       return 0;
+}
+
+static int fpr_get(struct task_struct *target,
+                  const struct user_regset *regset,
+                  unsigned int pos, unsigned int count,
+                  void *kbuf, void __user *ubuf)
+{
+       return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                  &target->thread.fpu,
+                                  0, sizeof(elf_fpregset_t));
+       /* XXX fcr31  */
+}
+
+static int fpr_set(struct task_struct *target,
+                  const struct user_regset *regset,
+                  unsigned int pos, unsigned int count,
+                  const void *kbuf, const void __user *ubuf)
+{
+       return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                 &target->thread.fpu,
+                                 0, sizeof(elf_fpregset_t));
+       /* XXX fcr31  */
+}
+
+enum mips_regset {
+       REGSET_GPR,
+       REGSET_FPR,
+};
+
+static const struct user_regset mips_regsets[] = {
+       [REGSET_GPR] = {
+               .core_note_type = NT_PRSTATUS,
+               .n              = ELF_NGREG,
+               .size           = sizeof(unsigned int),
+               .align          = sizeof(unsigned int),
+               .get            = gpr_get,
+               .set            = gpr_set,
+       },
+       [REGSET_FPR] = {
+               .core_note_type = NT_PRFPREG,
+               .n              = ELF_NFPREG,
+               .size           = sizeof(elf_fpreg_t),
+               .align          = sizeof(elf_fpreg_t),
+               .get            = fpr_get,
+               .set            = fpr_set,
+       },
+};
+
+static const struct user_regset_view user_mips_view = {
+       .name           = "mips",
+       .e_machine      = ELF_ARCH,
+       .ei_osabi       = ELF_OSABI,
+       .regsets        = mips_regsets,
+       .n              = ARRAY_SIZE(mips_regsets),
+};
+
+static const struct user_regset mips64_regsets[] = {
+       [REGSET_GPR] = {
+               .core_note_type = NT_PRSTATUS,
+               .n              = ELF_NGREG,
+               .size           = sizeof(unsigned long),
+               .align          = sizeof(unsigned long),
+               .get            = gpr_get,
+               .set            = gpr_set,
+       },
+       [REGSET_FPR] = {
+               .core_note_type = NT_PRFPREG,
+               .n              = ELF_NFPREG,
+               .size           = sizeof(elf_fpreg_t),
+               .align          = sizeof(elf_fpreg_t),
+               .get            = fpr_get,
+               .set            = fpr_set,
+       },
+};
+
+static const struct user_regset_view user_mips64_view = {
+       .name           = "mips",
+       .e_machine      = ELF_ARCH,
+       .ei_osabi       = ELF_OSABI,
+       .regsets        = mips64_regsets,
+       .n              = ARRAY_SIZE(mips_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+#ifdef CONFIG_32BIT
+       return &user_mips_view;
+#endif
+
+#ifdef CONFIG_MIPS32_O32
+               if (test_thread_flag(TIF_32BIT_REGS))
+                       return &user_mips_view;
+#endif
+
+       return &user_mips64_view;
+}
+
 long arch_ptrace(struct task_struct *child, long request,
                 unsigned long addr, unsigned long data)
 {
@@ -517,52 +652,27 @@ long arch_ptrace(struct task_struct *child, long request,
        return ret;
 }
 
-static inline int audit_arch(void)
-{
-       int arch = EM_MIPS;
-#ifdef CONFIG_64BIT
-       arch |=  __AUDIT_ARCH_64BIT;
-#endif
-#if defined(__LITTLE_ENDIAN)
-       arch |=  __AUDIT_ARCH_LE;
-#endif
-       return arch;
-}
-
 /*
  * Notification of system call entry/exit
  * - triggered by current->work.syscall_trace
  */
 asmlinkage void syscall_trace_enter(struct pt_regs *regs)
 {
+       long ret = 0;
        user_exit();
 
        /* do the secure computing check first */
        secure_computing_strict(regs->regs[2]);
 
-       if (!(current->ptrace & PT_PTRACED))
-               goto out;
-
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               goto out;
+       if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+           tracehook_report_syscall_entry(regs))
+               ret = -1;
 
-       /* The 0x80 provides a way for the tracing parent to distinguish
-          between a syscall stop and SIGTRAP delivery */
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
-                                0x80 : 0));
-
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
+       if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+               trace_sys_enter(regs, regs->regs[2]);
 
-out:
-       audit_syscall_entry(audit_arch(), regs->regs[2],
+       audit_syscall_entry(__syscall_get_arch(),
+                           regs->regs[2],
                            regs->regs[4], regs->regs[5],
                            regs->regs[6], regs->regs[7]);
 }
@@ -582,26 +692,11 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
 
        audit_syscall_exit(regs);
 
-       if (!(current->ptrace & PT_PTRACED))
-               return;
-
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
-
-       /* The 0x80 provides a way for the tracing parent to distinguish
-          between a syscall stop and SIGTRAP delivery */
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
-                                0x80 : 0));
+       if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+               trace_sys_exit(regs, regs->regs[2]);
 
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(regs, 0);
 
        user_enter();
 }
index e774bb1088b5f16970feaea1bddf6eaead240a01..e8e541b40d86be37a2e1fe9c693bbfe912581bfb 100644 (file)
@@ -40,17 +40,58 @@ NESTED(handle_sys, PT_SIZE, sp)
        sw      t1, PT_EPC(sp)
        beqz    t0, illegal_syscall
 
-       sll     t0, v0, 3
+       sll     t0, v0, 2
        la      t1, sys_call_table
        addu    t1, t0
        lw      t2, (t1)                # syscall routine
-       lw      t3, 4(t1)               # >= 0 if we need stack arguments
        beqz    t2, illegal_syscall
 
        sw      a3, PT_R26(sp)          # save a3 for syscall restarting
-       bgez    t3, stackargs
 
-stack_done:
+       /*
+        * More than four arguments.  Try to deal with it by copying the
+        * stack arguments from the user stack to the kernel stack.
+        * This Sucks (TM).
+        */
+       lw      t0, PT_R29(sp)          # get old user stack pointer
+
+       /*
+        * We intentionally keep the kernel stack a little below the top of
+        * userspace so we don't have to do a slower byte accurate check here.
+        */
+       lw      t5, TI_ADDR_LIMIT($28)
+       addu    t4, t0, 32
+       and     t5, t4
+       bltz    t5, bad_stack           # -> sp is bad
+
+       /*
+        * Ok, copy the args from the luser stack to the kernel stack.
+        * t3 is the precomputed number of instruction bytes needed to
+        * load or store arguments 6-8.
+        */
+
+       .set    push
+       .set    noreorder
+       .set    nomacro
+
+1:     lw      t5, 16(t0)              # argument #5 from usp
+4:     lw      t6, 20(t0)              # argument #6 from usp
+3:     lw      t7, 24(t0)              # argument #7 from usp
+2:     lw      t8, 28(t0)              # argument #8 from usp
+
+       sw      t5, 16(sp)              # argument #5 to ksp
+       sw      t6, 20(sp)              # argument #6 to ksp
+       sw      t7, 24(sp)              # argument #7 to ksp
+       sw      t8, 28(sp)              # argument #8 to ksp
+       .set    pop
+
+       .section __ex_table,"a"
+       PTR     1b,bad_stack
+       PTR     2b,bad_stack
+       PTR     3b,bad_stack
+       PTR     4b,bad_stack
+       .previous
+
        lw      t0, TI_FLAGS($28)       # syscall tracing enabled?
        li      t1, _TIF_WORK_SYSCALL_ENTRY
        and     t0, t1
@@ -101,66 +142,6 @@ syscall_trace_entry:
 
 /* ------------------------------------------------------------------------ */
 
-       /*
-        * More than four arguments.  Try to deal with it by copying the
-        * stack arguments from the user stack to the kernel stack.
-        * This Sucks (TM).
-        */
-stackargs:
-       lw      t0, PT_R29(sp)          # get old user stack pointer
-
-       /*
-        * We intentionally keep the kernel stack a little below the top of
-        * userspace so we don't have to do a slower byte accurate check here.
-        */
-       lw      t5, TI_ADDR_LIMIT($28)
-       addu    t4, t0, 32
-       and     t5, t4
-       bltz    t5, bad_stack           # -> sp is bad
-
-       /* Ok, copy the args from the luser stack to the kernel stack.
-        * t3 is the precomputed number of instruction bytes needed to
-        * load or store arguments 6-8.
-        */
-
-       la      t1, 5f                  # load up to 3 arguments
-       subu    t1, t3
-1:     lw      t5, 16(t0)              # argument #5 from usp
-       .set    push
-       .set    noreorder
-       .set    nomacro
-       jr      t1
-        addiu  t1, 6f - 5f
-
-2:     lw      t8, 28(t0)              # argument #8 from usp
-3:     lw      t7, 24(t0)              # argument #7 from usp
-4:     lw      t6, 20(t0)              # argument #6 from usp
-5:     jr      t1
-        sw     t5, 16(sp)              # argument #5 to ksp
-
-#ifdef CONFIG_CPU_MICROMIPS
-       sw      t8, 28(sp)              # argument #8 to ksp
-       nop
-       sw      t7, 24(sp)              # argument #7 to ksp
-       nop
-       sw      t6, 20(sp)              # argument #6 to ksp
-       nop
-#else
-       sw      t8, 28(sp)              # argument #8 to ksp
-       sw      t7, 24(sp)              # argument #7 to ksp
-       sw      t6, 20(sp)              # argument #6 to ksp
-#endif
-6:     j       stack_done              # go back
-        nop
-       .set    pop
-
-       .section __ex_table,"a"
-       PTR     1b,bad_stack
-       PTR     2b,bad_stack
-       PTR     3b,bad_stack
-       PTR     4b,bad_stack
-       .previous
-
        /*
         * The stackpointer for a call with more than 4 arguments is bad.
         * We probably should handle this case a bit more drastic.
@@ -187,7 +168,7 @@ illegal_syscall:
        subu    t0, a0, __NR_O32_Linux  # check syscall number
        sltiu   v0, t0, __NR_O32_Linux_syscalls + 1
        beqz    t0, einval              # do not recurse
-       sll     t1, t0, 3
+       sll     t1, t0, 2
        beqz    v0, einval
        lw      t2, sys_call_table(t1)          # syscall routine
 
@@ -218,260 +199,248 @@ einval: li      v0, -ENOSYS
        jr      ra
        END(sys_syscall)
 
-       .macro  fifty ptr, nargs, from=1, to=50
-       sys     \ptr            \nargs
-       .if     \to-\from
-       fifty   \ptr,\nargs,"(\from+1)",\to
-       .endif
-       .endm
-
-       .macro  mille ptr, nargs, from=1, to=20
-       fifty   \ptr,\nargs
-       .if     \to-\from
-       mille   \ptr,\nargs,"(\from+1)",\to
-       .endif
-       .endm
-
-       .macro  syscalltable
-       sys     sys_syscall             8       /* 4000 */
-       sys     sys_exit                1
-       sys     __sys_fork              0
-       sys     sys_read                3
-       sys     sys_write               3
-       sys     sys_open                3       /* 4005 */
-       sys     sys_close               1
-       sys     sys_waitpid             3
-       sys     sys_creat               2
-       sys     sys_link                2
-       sys     sys_unlink              1       /* 4010 */
-       sys     sys_execve              0
-       sys     sys_chdir               1
-       sys     sys_time                1
-       sys     sys_mknod               3
-       sys     sys_chmod               2       /* 4015 */
-       sys     sys_lchown              3
-       sys     sys_ni_syscall          0
-       sys     sys_ni_syscall          0       /* was sys_stat */
-       sys     sys_lseek               3
-       sys     sys_getpid              0       /* 4020 */
-       sys     sys_mount               5
-       sys     sys_oldumount           1
-       sys     sys_setuid              1
-       sys     sys_getuid              0
-       sys     sys_stime               1       /* 4025 */
-       sys     sys_ptrace              4
-       sys     sys_alarm               1
-       sys     sys_ni_syscall          0       /* was sys_fstat */
-       sys     sys_pause               0
-       sys     sys_utime               2       /* 4030 */
-       sys     sys_ni_syscall          0
-       sys     sys_ni_syscall          0
-       sys     sys_access              2
-       sys     sys_nice                1
-       sys     sys_ni_syscall          0       /* 4035 */
-       sys     sys_sync                0
-       sys     sys_kill                2
-       sys     sys_rename              2
-       sys     sys_mkdir               2
-       sys     sys_rmdir               1       /* 4040 */
-       sys     sys_dup                 1
-       sys     sysm_pipe               0
-       sys     sys_times               1
-       sys     sys_ni_syscall          0
-       sys     sys_brk                 1       /* 4045 */
-       sys     sys_setgid              1
-       sys     sys_getgid              0
-       sys     sys_ni_syscall          0       /* was signal(2) */
-       sys     sys_geteuid             0
-       sys     sys_getegid             0       /* 4050 */
-       sys     sys_acct                1
-       sys     sys_umount              2
-       sys     sys_ni_syscall          0
-       sys     sys_ioctl               3
-       sys     sys_fcntl               3       /* 4055 */
-       sys     sys_ni_syscall          2
-       sys     sys_setpgid             2
-       sys     sys_ni_syscall          0
-       sys     sys_olduname            1
-       sys     sys_umask               1       /* 4060 */
-       sys     sys_chroot              1
-       sys     sys_ustat               2
-       sys     sys_dup2                2
-       sys     sys_getppid             0
-       sys     sys_getpgrp             0       /* 4065 */
-       sys     sys_setsid              0
-       sys     sys_sigaction           3
-       sys     sys_sgetmask            0
-       sys     sys_ssetmask            1
-       sys     sys_setreuid            2       /* 4070 */
-       sys     sys_setregid            2
-       sys     sys_sigsuspend          0
-       sys     sys_sigpending          1
-       sys     sys_sethostname         2
-       sys     sys_setrlimit           2       /* 4075 */
-       sys     sys_getrlimit           2
-       sys     sys_getrusage           2
-       sys     sys_gettimeofday        2
-       sys     sys_settimeofday        2
-       sys     sys_getgroups           2       /* 4080 */
-       sys     sys_setgroups           2
-       sys     sys_ni_syscall          0       /* old_select */
-       sys     sys_symlink             2
-       sys     sys_ni_syscall          0       /* was sys_lstat */
-       sys     sys_readlink            3       /* 4085 */
-       sys     sys_uselib              1
-       sys     sys_swapon              2
-       sys     sys_reboot              3
-       sys     sys_old_readdir         3
-       sys     sys_mips_mmap           6       /* 4090 */
-       sys     sys_munmap              2
-       sys     sys_truncate            2
-       sys     sys_ftruncate           2
-       sys     sys_fchmod              2
-       sys     sys_fchown              3       /* 4095 */
-       sys     sys_getpriority         2
-       sys     sys_setpriority         3
-       sys     sys_ni_syscall          0
-       sys     sys_statfs              2
-       sys     sys_fstatfs             2       /* 4100 */
-       sys     sys_ni_syscall          0       /* was ioperm(2) */
-       sys     sys_socketcall          2
-       sys     sys_syslog              3
-       sys     sys_setitimer           3
-       sys     sys_getitimer           2       /* 4105 */
-       sys     sys_newstat             2
-       sys     sys_newlstat            2
-       sys     sys_newfstat            2
-       sys     sys_uname               1
-       sys     sys_ni_syscall          0       /* 4110 was iopl(2) */
-       sys     sys_vhangup             0
-       sys     sys_ni_syscall          0       /* was sys_idle() */
-       sys     sys_ni_syscall          0       /* was sys_vm86 */
-       sys     sys_wait4               4
-       sys     sys_swapoff             1       /* 4115 */
-       sys     sys_sysinfo             1
-       sys     sys_ipc                 6
-       sys     sys_fsync               1
-       sys     sys_sigreturn           0
-       sys     __sys_clone             6       /* 4120 */
-       sys     sys_setdomainname       2
-       sys     sys_newuname            1
-       sys     sys_ni_syscall          0       /* sys_modify_ldt */
-       sys     sys_adjtimex            1
-       sys     sys_mprotect            3       /* 4125 */
-       sys     sys_sigprocmask         3
-       sys     sys_ni_syscall          0       /* was create_module */
-       sys     sys_init_module         5
-       sys     sys_delete_module       1
-       sys     sys_ni_syscall          0       /* 4130 was get_kernel_syms */
-       sys     sys_quotactl            4
-       sys     sys_getpgid             1
-       sys     sys_fchdir              1
-       sys     sys_bdflush             2
-       sys     sys_sysfs               3       /* 4135 */
-       sys     sys_personality         1
-       sys     sys_ni_syscall          0       /* for afs_syscall */
-       sys     sys_setfsuid            1
-       sys     sys_setfsgid            1
-       sys     sys_llseek              5       /* 4140 */
-       sys     sys_getdents            3
-       sys     sys_select              5
-       sys     sys_flock               2
-       sys     sys_msync               3
-       sys     sys_readv               3       /* 4145 */
-       sys     sys_writev              3
-       sys     sys_cacheflush          3
-       sys     sys_cachectl            3
-       sys     sys_sysmips             4
-       sys     sys_ni_syscall          0       /* 4150 */
-       sys     sys_getsid              1
-       sys     sys_fdatasync           1
-       sys     sys_sysctl              1
-       sys     sys_mlock               2
-       sys     sys_munlock             2       /* 4155 */
-       sys     sys_mlockall            1
-       sys     sys_munlockall          0
-       sys     sys_sched_setparam      2
-       sys     sys_sched_getparam      2
-       sys     sys_sched_setscheduler  3       /* 4160 */
-       sys     sys_sched_getscheduler  1
-       sys     sys_sched_yield         0
-       sys     sys_sched_get_priority_max 1
-       sys     sys_sched_get_priority_min 1
-       sys     sys_sched_rr_get_interval 2     /* 4165 */
-       sys     sys_nanosleep,          2
-       sys     sys_mremap,             5
-       sys     sys_accept              3
-       sys     sys_bind                3
-       sys     sys_connect             3       /* 4170 */
-       sys     sys_getpeername         3
-       sys     sys_getsockname         3
-       sys     sys_getsockopt          5
-       sys     sys_listen              2
-       sys     sys_recv                4       /* 4175 */
-       sys     sys_recvfrom            6
-       sys     sys_recvmsg             3
-       sys     sys_send                4
-       sys     sys_sendmsg             3
-       sys     sys_sendto              6       /* 4180 */
-       sys     sys_setsockopt          5
-       sys     sys_shutdown            2
-       sys     sys_socket              3
-       sys     sys_socketpair          4
-       sys     sys_setresuid           3       /* 4185 */
-       sys     sys_getresuid           3
-       sys     sys_ni_syscall          0       /* was sys_query_module */
-       sys     sys_poll                3
-       sys     sys_ni_syscall          0       /* was nfsservctl */
-       sys     sys_setresgid           3       /* 4190 */
-       sys     sys_getresgid           3
-       sys     sys_prctl               5
-       sys     sys_rt_sigreturn        0
-       sys     sys_rt_sigaction        4
-       sys     sys_rt_sigprocmask      4       /* 4195 */
-       sys     sys_rt_sigpending       2
-       sys     sys_rt_sigtimedwait     4
-       sys     sys_rt_sigqueueinfo     3
-       sys     sys_rt_sigsuspend       0
-       sys     sys_pread64             6       /* 4200 */
-       sys     sys_pwrite64            6
-       sys     sys_chown               3
-       sys     sys_getcwd              2
-       sys     sys_capget              2
-       sys     sys_capset              2       /* 4205 */
-       sys     sys_sigaltstack         0
-       sys     sys_sendfile            4
-       sys     sys_ni_syscall          0
-       sys     sys_ni_syscall          0
-       sys     sys_mips_mmap2          6       /* 4210 */
-       sys     sys_truncate64          4
-       sys     sys_ftruncate64         4
-       sys     sys_stat64              2
-       sys     sys_lstat64             2
-       sys     sys_fstat64             2       /* 4215 */
-       sys     sys_pivot_root          2
-       sys     sys_mincore             3
-       sys     sys_madvise             3
-       sys     sys_getdents64          3
-       sys     sys_fcntl64             3       /* 4220 */
-       sys     sys_ni_syscall          0
-       sys     sys_gettid              0
-       sys     sys_readahead           5
-       sys     sys_setxattr            5
-       sys     sys_lsetxattr           5       /* 4225 */
-       sys     sys_fsetxattr           5
-       sys     sys_getxattr            4
-       sys     sys_lgetxattr           4
-       sys     sys_fgetxattr           4
-       sys     sys_listxattr           3       /* 4230 */
-       sys     sys_llistxattr          3
-       sys     sys_flistxattr          3
-       sys     sys_removexattr         2
-       sys     sys_lremovexattr        2
-       sys     sys_fremovexattr        2       /* 4235 */
-       sys     sys_tkill               2
-       sys     sys_sendfile64          5
-       sys     sys_futex               6
+       .align  2
+       .type   sys_call_table, @object
+EXPORT(sys_call_table)
+       PTR     sys_syscall                     /* 4000 */
+       PTR     sys_exit
+       PTR     __sys_fork
+       PTR     sys_read
+       PTR     sys_write
+       PTR     sys_open                        /* 4005 */
+       PTR     sys_close
+       PTR     sys_waitpid
+       PTR     sys_creat
+       PTR     sys_link
+       PTR     sys_unlink                      /* 4010 */
+       PTR     sys_execve
+       PTR     sys_chdir
+       PTR     sys_time
+       PTR     sys_mknod
+       PTR     sys_chmod                       /* 4015 */
+       PTR     sys_lchown
+       PTR     sys_ni_syscall
+       PTR     sys_ni_syscall                  /* was sys_stat */
+       PTR     sys_lseek
+       PTR     sys_getpid                      /* 4020 */
+       PTR     sys_mount
+       PTR     sys_oldumount
+       PTR     sys_setuid
+       PTR     sys_getuid
+       PTR     sys_stime                       /* 4025 */
+       PTR     sys_ptrace
+       PTR     sys_alarm
+       PTR     sys_ni_syscall                  /* was sys_fstat */
+       PTR     sys_pause
+       PTR     sys_utime                       /* 4030 */
+       PTR     sys_ni_syscall
+       PTR     sys_ni_syscall
+       PTR     sys_access
+       PTR     sys_nice
+       PTR     sys_ni_syscall                  /* 4035 */
+       PTR     sys_sync
+       PTR     sys_kill
+       PTR     sys_rename
+       PTR     sys_mkdir
+       PTR     sys_rmdir                       /* 4040 */
+       PTR     sys_dup
+       PTR     sysm_pipe
+       PTR     sys_times
+       PTR     sys_ni_syscall
+       PTR     sys_brk                         /* 4045 */
+       PTR     sys_setgid
+       PTR     sys_getgid
+       PTR     sys_ni_syscall                  /* was signal(2) */
+       PTR     sys_geteuid
+       PTR     sys_getegid                     /* 4050 */
+       PTR     sys_acct
+       PTR     sys_umount
+       PTR     sys_ni_syscall
+       PTR     sys_ioctl
+       PTR     sys_fcntl                       /* 4055 */
+       PTR     sys_ni_syscall
+       PTR     sys_setpgid
+       PTR     sys_ni_syscall
+       PTR     sys_olduname
+       PTR     sys_umask                       /* 4060 */
+       PTR     sys_chroot
+       PTR     sys_ustat
+       PTR     sys_dup2
+       PTR     sys_getppid
+       PTR     sys_getpgrp                     /* 4065 */
+       PTR     sys_setsid
+       PTR     sys_sigaction
+       PTR     sys_sgetmask
+       PTR     sys_ssetmask
+       PTR     sys_setreuid                    /* 4070 */
+       PTR     sys_setregid
+       PTR     sys_sigsuspend
+       PTR     sys_sigpending
+       PTR     sys_sethostname
+       PTR     sys_setrlimit                   /* 4075 */
+       PTR     sys_getrlimit
+       PTR     sys_getrusage
+       PTR     sys_gettimeofday
+       PTR     sys_settimeofday
+       PTR     sys_getgroups                   /* 4080 */
+       PTR     sys_setgroups
+       PTR     sys_ni_syscall                  /* old_select */
+       PTR     sys_symlink
+       PTR     sys_ni_syscall                  /* was sys_lstat */
+       PTR     sys_readlink                    /* 4085 */
+       PTR     sys_uselib
+       PTR     sys_swapon
+       PTR     sys_reboot
+       PTR     sys_old_readdir
+       PTR     sys_mips_mmap                   /* 4090 */
+       PTR     sys_munmap
+       PTR     sys_truncate
+       PTR     sys_ftruncate
+       PTR     sys_fchmod
+       PTR     sys_fchown                      /* 4095 */
+       PTR     sys_getpriority
+       PTR     sys_setpriority
+       PTR     sys_ni_syscall
+       PTR     sys_statfs
+       PTR     sys_fstatfs                     /* 4100 */
+       PTR     sys_ni_syscall                  /* was ioperm(2) */
+       PTR     sys_socketcall
+       PTR     sys_syslog
+       PTR     sys_setitimer
+       PTR     sys_getitimer                   /* 4105 */
+       PTR     sys_newstat
+       PTR     sys_newlstat
+       PTR     sys_newfstat
+       PTR     sys_uname
+       PTR     sys_ni_syscall                  /* 4110 was iopl(2) */
+       PTR     sys_vhangup
+       PTR     sys_ni_syscall                  /* was sys_idle() */
+       PTR     sys_ni_syscall                  /* was sys_vm86 */
+       PTR     sys_wait4
+       PTR     sys_swapoff                     /* 4115 */
+       PTR     sys_sysinfo
+       PTR     sys_ipc
+       PTR     sys_fsync
+       PTR     sys_sigreturn
+       PTR     __sys_clone                     /* 4120 */
+       PTR     sys_setdomainname
+       PTR     sys_newuname
+       PTR     sys_ni_syscall                  /* sys_modify_ldt */
+       PTR     sys_adjtimex
+       PTR     sys_mprotect                    /* 4125 */
+       PTR     sys_sigprocmask
+       PTR     sys_ni_syscall                  /* was create_module */
+       PTR     sys_init_module
+       PTR     sys_delete_module
+       PTR     sys_ni_syscall                  /* 4130 was get_kernel_syms */
+       PTR     sys_quotactl
+       PTR     sys_getpgid
+       PTR     sys_fchdir
+       PTR     sys_bdflush
+       PTR     sys_sysfs                       /* 4135 */
+       PTR     sys_personality
+       PTR     sys_ni_syscall                  /* for afs_syscall */
+       PTR     sys_setfsuid
+       PTR     sys_setfsgid
+       PTR     sys_llseek                      /* 4140 */
+       PTR     sys_getdents
+       PTR     sys_select
+       PTR     sys_flock
+       PTR     sys_msync
+       PTR     sys_readv                       /* 4145 */
+       PTR     sys_writev
+       PTR     sys_cacheflush
+       PTR     sys_cachectl
+       PTR     sys_sysmips
+       PTR     sys_ni_syscall                  /* 4150 */
+       PTR     sys_getsid
+       PTR     sys_fdatasync
+       PTR     sys_sysctl
+       PTR     sys_mlock
+       PTR     sys_munlock                     /* 4155 */
+       PTR     sys_mlockall
+       PTR     sys_munlockall
+       PTR     sys_sched_setparam
+       PTR     sys_sched_getparam
+       PTR     sys_sched_setscheduler          /* 4160 */
+       PTR     sys_sched_getscheduler
+       PTR     sys_sched_yield
+       PTR     sys_sched_get_priority_max
+       PTR     sys_sched_get_priority_min
+       PTR     sys_sched_rr_get_interval       /* 4165 */
+       PTR     sys_nanosleep
+       PTR     sys_mremap
+       PTR     sys_accept
+       PTR     sys_bind
+       PTR     sys_connect                     /* 4170 */
+       PTR     sys_getpeername
+       PTR     sys_getsockname
+       PTR     sys_getsockopt
+       PTR     sys_listen
+       PTR     sys_recv                        /* 4175 */
+       PTR     sys_recvfrom
+       PTR     sys_recvmsg
+       PTR     sys_send
+       PTR     sys_sendmsg
+       PTR     sys_sendto                      /* 4180 */
+       PTR     sys_setsockopt
+       PTR     sys_shutdown
+       PTR     sys_socket
+       PTR     sys_socketpair
+       PTR     sys_setresuid                   /* 4185 */
+       PTR     sys_getresuid
+       PTR     sys_ni_syscall                  /* was sys_query_module */
+       PTR     sys_poll
+       PTR     sys_ni_syscall                  /* was nfsservctl */
+       PTR     sys_setresgid                   /* 4190 */
+       PTR     sys_getresgid
+       PTR     sys_prctl
+       PTR     sys_rt_sigreturn
+       PTR     sys_rt_sigaction
+       PTR     sys_rt_sigprocmask              /* 4195 */
+       PTR     sys_rt_sigpending
+       PTR     sys_rt_sigtimedwait
+       PTR     sys_rt_sigqueueinfo
+       PTR     sys_rt_sigsuspend
+       PTR     sys_pread64                     /* 4200 */
+       PTR     sys_pwrite64
+       PTR     sys_chown
+       PTR     sys_getcwd
+       PTR     sys_capget
+       PTR     sys_capset                      /* 4205 */
+       PTR     sys_sigaltstack
+       PTR     sys_sendfile
+       PTR     sys_ni_syscall
+       PTR     sys_ni_syscall
+       PTR     sys_mips_mmap2                  /* 4210 */
+       PTR     sys_truncate64
+       PTR     sys_ftruncate64
+       PTR     sys_stat64
+       PTR     sys_lstat64
+       PTR     sys_fstat64                     /* 4215 */
+       PTR     sys_pivot_root
+       PTR     sys_mincore
+       PTR     sys_madvise
+       PTR     sys_getdents64
+       PTR     sys_fcntl64                     /* 4220 */
+       PTR     sys_ni_syscall
+       PTR     sys_gettid
+       PTR     sys_readahead
+       PTR     sys_setxattr
+       PTR     sys_lsetxattr                   /* 4225 */
+       PTR     sys_fsetxattr
+       PTR     sys_getxattr
+       PTR     sys_lgetxattr
+       PTR     sys_fgetxattr
+       PTR     sys_listxattr                   /* 4230 */
+       PTR     sys_llistxattr
+       PTR     sys_flistxattr
+       PTR     sys_removexattr
+       PTR     sys_lremovexattr
+       PTR     sys_fremovexattr                /* 4235 */
+       PTR     sys_tkill
+       PTR     sys_sendfile64
+       PTR     sys_futex
 #ifdef CONFIG_MIPS_MT_FPAFF
        /*
         * For FPU affinity scheduling on MIPS MT processors, we need to
@@ -480,132 +449,117 @@ einval: li      v0, -ENOSYS
         * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
         * atm.
         */
-       sys     mipsmt_sys_sched_setaffinity    3
-       sys     mipsmt_sys_sched_getaffinity    3
+       PTR     mipsmt_sys_sched_setaffinity
+       PTR     mipsmt_sys_sched_getaffinity
 #else
-       sys     sys_sched_setaffinity   3
-       sys     sys_sched_getaffinity   3       /* 4240 */
+       PTR     sys_sched_setaffinity
+       PTR     sys_sched_getaffinity           /* 4240 */
 #endif /* CONFIG_MIPS_MT_FPAFF */
-       sys     sys_io_setup            2
-       sys     sys_io_destroy          1
-       sys     sys_io_getevents        5
-       sys     sys_io_submit           3
-       sys     sys_io_cancel           3       /* 4245 */
-       sys     sys_exit_group          1
-       sys     sys_lookup_dcookie      4
-       sys     sys_epoll_create        1
-       sys     sys_epoll_ctl           4
-       sys     sys_epoll_wait          4       /* 4250 */
-       sys     sys_remap_file_pages    5
-       sys     sys_set_tid_address     1
-       sys     sys_restart_syscall     0
-       sys     sys_fadvise64_64        7
-       sys     sys_statfs64            3       /* 4255 */
-       sys     sys_fstatfs64           2
-       sys     sys_timer_create        3
-       sys     sys_timer_settime       4
-       sys     sys_timer_gettime       2
-       sys     sys_timer_getoverrun    1       /* 4260 */
-       sys     sys_timer_delete        1
-       sys     sys_clock_settime       2
-       sys     sys_clock_gettime       2
-       sys     sys_clock_getres        2
-       sys     sys_clock_nanosleep     4       /* 4265 */
-       sys     sys_tgkill              3
-       sys     sys_utimes              2
-       sys     sys_mbind               4
-       sys     sys_ni_syscall          0       /* sys_get_mempolicy */
-       sys     sys_ni_syscall          0       /* 4270 sys_set_mempolicy */
-       sys     sys_mq_open             4
-       sys     sys_mq_unlink           1
-       sys     sys_mq_timedsend        5
-       sys     sys_mq_timedreceive     5
-       sys     sys_mq_notify           2       /* 4275 */
-       sys     sys_mq_getsetattr       3
-       sys     sys_ni_syscall          0       /* sys_vserver */
-       sys     sys_waitid              5
-       sys     sys_ni_syscall          0       /* available, was setaltroot */
-       sys     sys_add_key             5       /* 4280 */
-       sys     sys_request_key         4
-       sys     sys_keyctl              5
-       sys     sys_set_thread_area     1
-       sys     sys_inotify_init        0
-       sys     sys_inotify_add_watch   3       /* 4285 */
-       sys     sys_inotify_rm_watch    2
-       sys     sys_migrate_pages       4
-       sys     sys_openat              4
-       sys     sys_mkdirat             3
-       sys     sys_mknodat             4       /* 4290 */
-       sys     sys_fchownat            5
-       sys     sys_futimesat           3
-       sys     sys_fstatat64           4
-       sys     sys_unlinkat            3
-       sys     sys_renameat            4       /* 4295 */
-       sys     sys_linkat              5
-       sys     sys_symlinkat           3
-       sys     sys_readlinkat          4
-       sys     sys_fchmodat            3
-       sys     sys_faccessat           3       /* 4300 */
-       sys     sys_pselect6            6
-       sys     sys_ppoll               5
-       sys     sys_unshare             1
-       sys     sys_splice              6
-       sys     sys_sync_file_range     7       /* 4305 */
-       sys     sys_tee                 4
-       sys     sys_vmsplice            4
-       sys     sys_move_pages          6
-       sys     sys_set_robust_list     2
-       sys     sys_get_robust_list     3       /* 4310 */
-       sys     sys_kexec_load          4
-       sys     sys_getcpu              3
-       sys     sys_epoll_pwait         6
-       sys     sys_ioprio_set          3
-       sys     sys_ioprio_get          2       /* 4315 */
-       sys     sys_utimensat           4
-       sys     sys_signalfd            3
-       sys     sys_ni_syscall          0       /* was timerfd */
-       sys     sys_eventfd             1
-       sys     sys_fallocate           6       /* 4320 */
-       sys     sys_timerfd_create      2
-       sys     sys_timerfd_gettime     2
-       sys     sys_timerfd_settime     4
-       sys     sys_signalfd4           4
-       sys     sys_eventfd2            2       /* 4325 */
-       sys     sys_epoll_create1       1
-       sys     sys_dup3                3
-       sys     sys_pipe2               2
-       sys     sys_inotify_init1       1
-       sys     sys_preadv              6       /* 4330 */
-       sys     sys_pwritev             6
-       sys     sys_rt_tgsigqueueinfo   4
-       sys     sys_perf_event_open     5
-       sys     sys_accept4             4
-       sys     sys_recvmmsg            5       /* 4335 */
-       sys     sys_fanotify_init       2
-       sys     sys_fanotify_mark       6
-       sys     sys_prlimit64           4
-       sys     sys_name_to_handle_at   5
-       sys     sys_open_by_handle_at   3       /* 4340 */
-       sys     sys_clock_adjtime       2
-       sys     sys_syncfs              1
-       sys     sys_sendmmsg            4
-       sys     sys_setns               2
-       sys     sys_process_vm_readv    6       /* 4345 */
-       sys     sys_process_vm_writev   6
-       sys     sys_kcmp                5
-       sys     sys_finit_module        3
-       .endm
-
-       /* We pre-compute the number of _instruction_ bytes needed to
-          load or store the arguments 6-8. Negative values are ignored. */
-
-       .macro  sys function, nargs
-       PTR     \function
-       LONG    (\nargs << 2) - (5 << 2)
-       .endm
-
-       .align  3
-       .type   sys_call_table,@object
-EXPORT(sys_call_table)
-       syscalltable
-       .size   sys_call_table, . - sys_call_table
+       PTR     sys_io_setup
+       PTR     sys_io_destroy
+       PTR     sys_io_getevents
+       PTR     sys_io_submit
+       PTR     sys_io_cancel                   /* 4245 */
+       PTR     sys_exit_group
+       PTR     sys_lookup_dcookie
+       PTR     sys_epoll_create
+       PTR     sys_epoll_ctl
+       PTR     sys_epoll_wait                  /* 4250 */
+       PTR     sys_remap_file_pages
+       PTR     sys_set_tid_address
+       PTR     sys_restart_syscall
+       PTR     sys_fadvise64_64
+       PTR     sys_statfs64                    /* 4255 */
+       PTR     sys_fstatfs64
+       PTR     sys_timer_create
+       PTR     sys_timer_settime
+       PTR     sys_timer_gettime
+       PTR     sys_timer_getoverrun            /* 4260 */
+       PTR     sys_timer_delete
+       PTR     sys_clock_settime
+       PTR     sys_clock_gettime
+       PTR     sys_clock_getres
+       PTR     sys_clock_nanosleep             /* 4265 */
+       PTR     sys_tgkill
+       PTR     sys_utimes
+       PTR     sys_mbind
+       PTR     sys_ni_syscall                  /* sys_get_mempolicy */
+       PTR     sys_ni_syscall                  /* 4270 sys_set_mempolicy */
+       PTR     sys_mq_open
+       PTR     sys_mq_unlink
+       PTR     sys_mq_timedsend
+       PTR     sys_mq_timedreceive
+       PTR     sys_mq_notify                   /* 4275 */
+       PTR     sys_mq_getsetattr
+       PTR     sys_ni_syscall                  /* sys_vserver */
+       PTR     sys_waitid
+       PTR     sys_ni_syscall                  /* available, was setaltroot */
+       PTR     sys_add_key                     /* 4280 */
+       PTR     sys_request_key
+       PTR     sys_keyctl
+       PTR     sys_set_thread_area
+       PTR     sys_inotify_init
+       PTR     sys_inotify_add_watch           /* 4285 */
+       PTR     sys_inotify_rm_watch
+       PTR     sys_migrate_pages
+       PTR     sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat                     /* 4290 */
+       PTR     sys_fchownat
+       PTR     sys_futimesat
+       PTR     sys_fstatat64
+       PTR     sys_unlinkat
+       PTR     sys_renameat                    /* 4295 */
+       PTR     sys_linkat
+       PTR     sys_symlinkat
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat                   /* 4300 */
+       PTR     sys_pselect6
+       PTR     sys_ppoll
+       PTR     sys_unshare
+       PTR     sys_splice
+       PTR     sys_sync_file_range             /* 4305 */
+       PTR     sys_tee
+       PTR     sys_vmsplice
+       PTR     sys_move_pages
+       PTR     sys_set_robust_list
+       PTR     sys_get_robust_list             /* 4310 */
+       PTR     sys_kexec_load
+       PTR     sys_getcpu
+       PTR     sys_epoll_pwait
+       PTR     sys_ioprio_set
+       PTR     sys_ioprio_get                  /* 4315 */
+       PTR     sys_utimensat
+       PTR     sys_signalfd
+       PTR     sys_ni_syscall                  /* was timerfd */
+       PTR     sys_eventfd
+       PTR     sys_fallocate                   /* 4320 */
+       PTR     sys_timerfd_create
+       PTR     sys_timerfd_gettime
+       PTR     sys_timerfd_settime
+       PTR     sys_signalfd4
+       PTR     sys_eventfd2                    /* 4325 */
+       PTR     sys_epoll_create1
+       PTR     sys_dup3
+       PTR     sys_pipe2
+       PTR     sys_inotify_init1
+       PTR     sys_preadv                      /* 4330 */
+       PTR     sys_pwritev
+       PTR     sys_rt_tgsigqueueinfo
+       PTR     sys_perf_event_open
+       PTR     sys_accept4
+       PTR     sys_recvmmsg                    /* 4335 */
+       PTR     sys_fanotify_init
+       PTR     sys_fanotify_mark
+       PTR     sys_prlimit64
+       PTR     sys_name_to_handle_at
+       PTR     sys_open_by_handle_at           /* 4340 */
+       PTR     sys_clock_adjtime
+       PTR     sys_syncfs
+       PTR     sys_sendmmsg
+       PTR     sys_setns
+       PTR     sys_process_vm_readv            /* 4345 */
+       PTR     sys_process_vm_writev
+       PTR     sys_kcmp
+       PTR     sys_finit_module
index be6627ead619e72b35bea9f8d031af3b21a2b06a..57e3742fec59a19083eb3cb5f802b9e43a90b66b 100644 (file)
@@ -114,7 +114,8 @@ illegal_syscall:
        END(handle_sys64)
 
        .align  3
-sys_call_table:
+       .type   sys_call_table, @object
+EXPORT(sys_call_table)
        PTR     sys_read                        /* 5000 */
        PTR     sys_write
        PTR     sys_open
index cab150789c8d8412409506c99143a45f04717e80..2f48f5934399e3b48a14cd88f2bf84fba0d46894 100644 (file)
@@ -103,6 +103,7 @@ not_n32_scall:
 
        END(handle_sysn32)
 
+       .type   sysn32_call_table, @object
 EXPORT(sysn32_call_table)
        PTR     sys_read                        /* 6000 */
        PTR     sys_write
index 37605dc8eef7a9c72d5743ad3ad5d1f50088fdfb..f1acdb429f4fa1d89ee8db664f5fd25005c978a1 100644 (file)
@@ -53,7 +53,7 @@ NESTED(handle_sys, PT_SIZE, sp)
        sll     a3, a3, 0
 
        dsll    t0, v0, 3               # offset into table
-       ld      t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
+       ld      t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
 
        sd      a3, PT_R26(sp)          # save a3 for syscall restarting
 
@@ -168,7 +168,7 @@ LEAF(sys32_syscall)
        beqz    t0, einval              # do not recurse
        dsll    t1, t0, 3
        beqz    v0, einval
-       ld      t2, sys_call_table(t1)          # syscall routine
+       ld      t2, sys32_call_table(t1)                # syscall routine
 
        move    a0, a1                  # shift argument registers
        move    a1, a2
@@ -190,8 +190,8 @@ einval: li  v0, -ENOSYS
        END(sys32_syscall)
 
        .align  3
-       .type   sys_call_table,@object
-sys_call_table:
+       .type   sys32_call_table,@object
+EXPORT(sys32_call_table)
        PTR     sys32_syscall                   /* 4000 */
        PTR     sys_exit
        PTR     __sys_fork
@@ -541,4 +541,4 @@ sys_call_table:
        PTR     compat_sys_process_vm_writev
        PTR     sys_kcmp
        PTR     sys_finit_module
-       .size   sys_call_table,.-sys_call_table
+       .size   sys32_call_table,.-sys32_call_table
index c538d6e01b7b744cb4af330a5de15b78963cfa7f..a842154d57dc466eaba000039b3fd5e436c6cb69 100644 (file)
@@ -300,12 +300,13 @@ static void __init bootmem_init(void)
        int i;
 
        /*
-        * Init any data related to initrd. It's a nop if INITRD is
-        * not selected. Once that done we can determine the low bound
-        * of usable memory.
+        * Sanity check any INITRD first. We don't take it into account
+        * for bootmem setup initially, rely on the end-of-kernel-code
+        * as our memory range starting point. Once bootmem is inited we
+        * will reserve the area used for the initrd.
         */
-       reserved_end = max(init_initrd(),
-                          (unsigned long) PFN_UP(__pa_symbol(&_end)));
+       init_initrd();
+       reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end));
 
        /*
         * max_low_pfn is not a number of pages. The number of pages
@@ -362,6 +363,14 @@ static void __init bootmem_init(void)
                max_low_pfn = PFN_DOWN(HIGHMEM_START);
        }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+       /*
+        * mapstart should be after initrd_end
+        */
+       if (initrd_end)
+               mapstart = max(mapstart, (unsigned long)PFN_UP(__pa(initrd_end)));
+#endif
+
        /*
         * Initialize the boot-time allocator with low memory only.
         */
index 126da74d4c5559faf40962b80bddef9a39721757..2362665ba4965f2b3ff272a34bb5aca6360f8897 100644 (file)
@@ -136,10 +136,10 @@ static void bmips_prepare_cpus(unsigned int max_cpus)
 {
        if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
                        "smp_ipi0", NULL))
-               panic("Can't request IPI0 interrupt\n");
+               panic("Can't request IPI0 interrupt");
        if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
                        "smp_ipi1", NULL))
-               panic("Can't request IPI1 interrupt\n");
+               panic("Can't request IPI1 interrupt");
 }
 
 /*
index 5c208ed8f8561b461e3b2a8b1f0e49a8a458f8d2..0a022ee33b2a15c5c9722e2e9aa5504358ba05f4 100644 (file)
@@ -150,7 +150,6 @@ asmlinkage void start_secondary(void)
 void __irq_entry smp_call_function_interrupt(void)
 {
        irq_enter();
-       generic_smp_call_function_single_interrupt();
        generic_smp_call_function_interrupt();
        irq_exit();
 }
index 524841f0280370600966d20f38b41d0eefdb4744..f9c8746be8d66d78b3ad1fc500d72674d486cdb9 100644 (file)
@@ -330,6 +330,7 @@ void show_regs(struct pt_regs *regs)
 void show_registers(struct pt_regs *regs)
 {
        const int field = 2 * sizeof(unsigned long);
+       mm_segment_t old_fs = get_fs();
 
        __show_regs(regs);
        print_modules();
@@ -344,9 +345,13 @@ void show_registers(struct pt_regs *regs)
                        printk("*HwTLS: %0*lx\n", field, tls);
        }
 
+       if (!user_mode(regs))
+               /* Necessary for getting the correct stack content */
+               set_fs(KERNEL_DS);
        show_stacktrace(current, regs);
        show_code((unsigned int __user *) regs->cp0_epc);
        printk("\n");
+       set_fs(old_fs);
 }
 
 static int regs_to_trapnr(struct pt_regs *regs)
@@ -366,7 +371,8 @@ void __noreturn die(const char *str, struct pt_regs *regs)
 
        oops_enter();
 
-       if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
+       if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs),
+                      SIGSEGV) == NOTIFY_STOP)
                sig = 0;
 
        console_verbose();
@@ -457,8 +463,8 @@ asmlinkage void do_be(struct pt_regs *regs)
        printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
               data ? "Data" : "Instruction",
               field, regs->cp0_epc, field, regs->regs[31]);
-       if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
-           == NOTIFY_STOP)
+       if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs),
+                      SIGBUS) == NOTIFY_STOP)
                goto out;
 
        die_if_kernel("Oops", regs);
@@ -727,8 +733,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
        siginfo_t info = {0};
 
        prev_state = exception_enter();
-       if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
-           == NOTIFY_STOP)
+       if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
+                      SIGFPE) == NOTIFY_STOP)
                goto out;
        die_if_kernel("FP exception in kernel code", regs);
 
@@ -798,7 +804,8 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
                return;
 #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
 
-       if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+       if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs),
+                      SIGTRAP) == NOTIFY_STOP)
                return;
 
        /*
@@ -892,12 +899,14 @@ asmlinkage void do_bp(struct pt_regs *regs)
         */
        switch (bcode) {
        case BRK_KPROBE_BP:
-               if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+               if (notify_die(DIE_BREAK, "debug", regs, bcode,
+                              regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
                        goto out;
                else
                        break;
        case BRK_KPROBE_SSTEPBP:
-               if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+               if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode,
+                              regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
                        goto out;
                else
                        break;
@@ -961,8 +970,8 @@ asmlinkage void do_ri(struct pt_regs *regs)
        int status = -1;
 
        prev_state = exception_enter();
-       if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
-           == NOTIFY_STOP)
+       if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs),
+                      SIGILL) == NOTIFY_STOP)
                goto out;
 
        die_if_kernel("Reserved instruction in kernel code", regs);
@@ -1488,10 +1497,14 @@ int register_nmi_notifier(struct notifier_block *nb)
 
 void __noreturn nmi_exception_handler(struct pt_regs *regs)
 {
+       char str[100];
+
        raw_notifier_call_chain(&nmi_chain, 0, regs);
        bust_spinlocks(1);
-       printk("NMI taken!!!!\n");
-       die("NMI", regs);
+       snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n",
+                smp_processor_id(), regs->cp0_epc);
+       regs->cp0_epc = read_c0_errorepc();
+       die(str, regs);
 }
 
 #define VECTORSPACING 0x100    /* for EI/VI mode */
@@ -1554,7 +1567,6 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
        unsigned char *b;
 
        BUG_ON(!cpu_has_veic && !cpu_has_vint);
-       BUG_ON((n < 0) && (n > 9));
 
        if (addr == NULL) {
                handler = (unsigned long) do_default_vi;
index eb3e186596304f480987400ae731f30726923564..85685e1cdb89479ac57de4e3614e69bf6b7cbb2c 100644 (file)
@@ -390,7 +390,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
                ret = of_irq_to_resource_table(eiu_node,
                                                ltq_eiu_irq, exin_avail);
                if (ret != exin_avail)
-                       panic("failed to load external irq resources\n");
+                       panic("failed to load external irq resources");
 
                if (request_mem_region(res.start, resource_size(&res),
                                                        res.name) < 0)
index c24924fe087da2cf05f7f1828d183c79e8f810ad..51804b10a0360317392ebdbc902e59b8e7f4343d 100644 (file)
@@ -128,7 +128,7 @@ static int pmu_enable(struct clk *clk)
        do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits));
 
        if (!retry)
-               panic("activating PMU module failed!\n");
+               panic("activating PMU module failed!");
 
        return 0;
 }
index bc6f96fcb529d53d16a04b09754a9e4395fd457f..62ffd20ea86909be81906691dd1531a35733c410 100644 (file)
@@ -346,14 +346,8 @@ static void r4k_blast_scache_setup(void)
 
 static inline void local_r4k___flush_cache_all(void * args)
 {
-#if defined(CONFIG_CPU_LOONGSON2)
-       r4k_blast_scache();
-       return;
-#endif
-       r4k_blast_dcache();
-       r4k_blast_icache();
-
        switch (current_cpu_type()) {
+       case CPU_LOONGSON2:
        case CPU_R4000SC:
        case CPU_R4000MC:
        case CPU_R4400SC:
@@ -361,7 +355,18 @@ static inline void local_r4k___flush_cache_all(void * args)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+               /*
+                * These caches are inclusive caches, that is, if something
+                * is not cached in the S-cache, we know it also won't be
+                * in one of the primary caches.
+                */
                r4k_blast_scache();
+               break;
+
+       default:
+               r4k_blast_dcache();
+               r4k_blast_icache();
+               break;
        }
 }
 
@@ -572,8 +577,17 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo
 
        if (end - start > icache_size)
                r4k_blast_icache();
-       else
-               protected_blast_icache_range(start, end);
+       else {
+               switch (boot_cpu_type()) {
+               case CPU_LOONGSON2:
+                       protected_blast_icache_range(start, end);
+                       break;
+
+               default:
+                       protected_loongson23_blast_icache_range(start, end);
+                       break;
+               }
+       }
 }
 
 static inline void local_r4k_flush_icache_range_ipi(void *args)
@@ -1109,15 +1123,14 @@ static void probe_pcache(void)
        case CPU_ALCHEMY:
                c->icache.flags |= MIPS_CACHE_IC_F_DC;
                break;
-       }
 
-#ifdef CONFIG_CPU_LOONGSON2
-       /*
-        * LOONGSON2 has 4 way icache, but when using indexed cache op,
-        * one op will act on all 4 ways
-        */
-       c->icache.ways = 1;
-#endif
+       case CPU_LOONGSON2:
+               /*
+                * LOONGSON2 has 4 way icache, but when using indexed cache op,
+                * one op will act on all 4 ways
+                */
+               c->icache.ways = 1;
+       }
 
        printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
               icache_size >> 10,
@@ -1193,7 +1206,6 @@ static int probe_scache(void)
        return 1;
 }
 
-#if defined(CONFIG_CPU_LOONGSON2)
 static void __init loongson2_sc_init(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
@@ -1209,7 +1221,6 @@ static void __init loongson2_sc_init(void)
 
        c->options |= MIPS_CPU_INCLUSIVE_CACHES;
 }
-#endif
 
 extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
@@ -1259,11 +1270,10 @@ static void setup_scache(void)
 #endif
                return;
 
-#if defined(CONFIG_CPU_LOONGSON2)
        case CPU_LOONGSON2:
                loongson2_sc_init();
                return;
-#endif
+
        case CPU_XLP:
                /* don't need to worry about L2, fully coherent */
                return;
index 5f8b955125801935f33370559476ca93f640c4df..2e9418562258754dacb511341b499965022760aa 100644 (file)
@@ -297,7 +297,6 @@ static void mips_dma_sync_single_for_cpu(struct device *dev,
 static void mips_dma_sync_single_for_device(struct device *dev,
        dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-       plat_extra_sync_for_device(dev);
        if (!plat_device_is_coherent(dev))
                __dma_sync(dma_addr_to_page(dev, dma_handle),
                           dma_handle & ~PAGE_MASK, size, direction);
@@ -327,7 +326,7 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
 
 int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
-       return plat_dma_mapping_error(dev, dma_addr);
+       return 0;
 }
 
 int mips_dma_supported(struct device *dev, u64 mask)
@@ -340,7 +339,6 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 {
        BUG_ON(direction == DMA_NONE);
 
-       plat_extra_sync_for_device(dev);
        if (!plat_device_is_coherent(dev))
                __dma_sync_virtual(vaddr, size, direction);
 }
index 79bca3130bd15f51bccae23012fa9a821cadb653..30a494db99c2a0eb4d51aa64ca410de956801837 100644 (file)
 
 #define FASTPATH_SIZE  128
 
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 LEAF(tlbmiss_handler_setup_pgd)
        .space          16 * 4
 END(tlbmiss_handler_setup_pgd)
 EXPORT(tlbmiss_handler_setup_pgd_end)
-#endif
 
 LEAF(handle_tlbm)
        .space          FASTPATH_SIZE * 4
index bb3a5f643e974a27a7d81246d4d7bb6b5f13a390..da3b0b9c9eae0a9800dfbbd20f6717709e72bfed 100644 (file)
@@ -52,21 +52,26 @@ extern void build_tlb_refill_handler(void);
 
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-#if defined(CONFIG_CPU_LOONGSON2)
 /*
  * LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
  * unfortrunately, itlb is not totally transparent to software.
  */
-#define FLUSH_ITLB write_c0_diag(4);
-
-#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC)  write_c0_diag(4); }
-
-#else
-
-#define FLUSH_ITLB
-#define FLUSH_ITLB_VM(vma)
+static inline void flush_itlb(void)
+{
+       switch (current_cpu_type()) {
+       case CPU_LOONGSON2:
+               write_c0_diag(4);
+               break;
+       default:
+               break;
+       }
+}
 
-#endif
+static inline void flush_itlb_vm(struct vm_area_struct *vma)
+{
+       if (vma->vm_flags & VM_EXEC)
+               flush_itlb();
+}
 
 void local_flush_tlb_all(void)
 {
@@ -93,7 +98,7 @@ void local_flush_tlb_all(void)
        }
        tlbw_use_hazard();
        write_c0_entryhi(old_ctx);
-       FLUSH_ITLB;
+       flush_itlb();
        EXIT_CRITICAL(flags);
 }
 EXPORT_SYMBOL(local_flush_tlb_all);
@@ -155,7 +160,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                } else {
                        drop_mmu_context(mm, cpu);
                }
-               FLUSH_ITLB;
+               flush_itlb();
                EXIT_CRITICAL(flags);
        }
 }
@@ -197,7 +202,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
        } else {
                local_flush_tlb_all();
        }
-       FLUSH_ITLB;
+       flush_itlb();
        EXIT_CRITICAL(flags);
 }
 
@@ -230,7 +235,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 
        finish:
                write_c0_entryhi(oldpid);
-               FLUSH_ITLB_VM(vma);
+               flush_itlb_vm(vma);
                EXIT_CRITICAL(flags);
        }
 }
@@ -262,7 +267,7 @@ void local_flush_tlb_one(unsigned long page)
                tlbw_use_hazard();
        }
        write_c0_entryhi(oldpid);
-       FLUSH_ITLB;
+       flush_itlb();
        EXIT_CRITICAL(flags);
 }
 
@@ -335,7 +340,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
                        tlb_write_indexed();
        }
        tlbw_use_hazard();
-       FLUSH_ITLB_VM(vma);
+       flush_itlb_vm(vma);
        EXIT_CRITICAL(flags);
 }
 
index 9bb3a9363b0618df3e19a43fafc68eb91dff18ba..183f2b583e4dbc7798411c4fd8c6c3927bff607f 100644 (file)
@@ -340,10 +340,6 @@ static struct work_registers build_get_work_registers(u32 **p)
 {
        struct work_registers r;
 
-       int smp_processor_id_reg;
-       int smp_processor_id_sel;
-       int smp_processor_id_shift;
-
        if (scratch_reg >= 0) {
                /* Save in CPU local C0_KScratch? */
                UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg);
@@ -354,25 +350,9 @@ static struct work_registers build_get_work_registers(u32 **p)
        }
 
        if (num_possible_cpus() > 1) {
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-               smp_processor_id_shift = 51;
-               smp_processor_id_reg = 20; /* XContext */
-               smp_processor_id_sel = 0;
-#else
-# ifdef CONFIG_32BIT
-               smp_processor_id_shift = 25;
-               smp_processor_id_reg = 4; /* Context */
-               smp_processor_id_sel = 0;
-# endif
-# ifdef CONFIG_64BIT
-               smp_processor_id_shift = 26;
-               smp_processor_id_reg = 4; /* Context */
-               smp_processor_id_sel = 0;
-# endif
-#endif
                /* Get smp_processor_id */
-               UASM_i_MFC0(p, K0, smp_processor_id_reg, smp_processor_id_sel);
-               UASM_i_SRL_SAFE(p, K0, K0, smp_processor_id_shift);
+               UASM_i_CPUID_MFC0(p, K0, SMP_CPUID_REG);
+               UASM_i_SRL_SAFE(p, K0, K0, SMP_CPUID_REGSHIFT);
 
                /* handler_reg_save index in K0 */
                UASM_i_SLL(p, K0, K0, ilog2(sizeof(struct tlb_reg_save)));
@@ -819,11 +799,11 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
        }
        /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
        if (pgd_reg != -1) {
                /* pgd is in pgd_reg */
                UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
        } else {
+#if defined(CONFIG_MIPS_PGD_C0_CONTEXT)
                /*
                 * &pgd << 11 stored in CONTEXT [23..63].
                 */
@@ -835,30 +815,18 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
                /* 1 0  1 0 1  << 6  xkphys cached */
                uasm_i_ori(p, ptr, ptr, 0x540);
                uasm_i_drotr(p, ptr, ptr, 11);
-       }
 #elif defined(CONFIG_SMP)
-# ifdef         CONFIG_MIPS_MT_SMTC
-       /*
-        * SMTC uses TCBind value as "CPU" index
-        */
-       uasm_i_mfc0(p, ptr, C0_TCBIND);
-       uasm_i_dsrl_safe(p, ptr, ptr, 19);
-# else
-       /*
-        * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
-        * stored in CONTEXT.
-        */
-       uasm_i_dmfc0(p, ptr, C0_CONTEXT);
-       uasm_i_dsrl_safe(p, ptr, ptr, 23);
-# endif
-       UASM_i_LA_mostly(p, tmp, pgdc);
-       uasm_i_daddu(p, ptr, ptr, tmp);
-       uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-       uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
+               UASM_i_CPUID_MFC0(p, ptr, SMP_CPUID_REG);
+               uasm_i_dsrl_safe(p, ptr, ptr, SMP_CPUID_PTRSHIFT);
+               UASM_i_LA_mostly(p, tmp, pgdc);
+               uasm_i_daddu(p, ptr, ptr, tmp);
+               uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+               uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
 #else
-       UASM_i_LA_mostly(p, ptr, pgdc);
-       uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
+               UASM_i_LA_mostly(p, ptr, pgdc);
+               uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
 #endif
+       }
 
        uasm_l_vmalloc_done(l, *p);
 
@@ -953,31 +921,25 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 static void __maybe_unused
 build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
 {
-       long pgdc = (long)pgd_current;
+       if (pgd_reg != -1) {
+               /* pgd is in pgd_reg */
+               uasm_i_mfc0(p, ptr, c0_kscratch(), pgd_reg);
+               uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+       } else {
+               long pgdc = (long)pgd_current;
 
-       /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
+               /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
 #ifdef CONFIG_SMP
-#ifdef CONFIG_MIPS_MT_SMTC
-       /*
-        * SMTC uses TCBind value as "CPU" index
-        */
-       uasm_i_mfc0(p, ptr, C0_TCBIND);
-       UASM_i_LA_mostly(p, tmp, pgdc);
-       uasm_i_srl(p, ptr, ptr, 19);
-#else
-       /*
-        * smp_processor_id() << 2 is stored in CONTEXT.
-        */
-       uasm_i_mfc0(p, ptr, C0_CONTEXT);
-       UASM_i_LA_mostly(p, tmp, pgdc);
-       uasm_i_srl(p, ptr, ptr, 23);
-#endif
-       uasm_i_addu(p, ptr, tmp, ptr);
+               uasm_i_mfc0(p, ptr, SMP_CPUID_REG);
+               UASM_i_LA_mostly(p, tmp, pgdc);
+               uasm_i_srl(p, ptr, ptr, SMP_CPUID_PTRSHIFT);
+               uasm_i_addu(p, ptr, tmp, ptr);
 #else
-       UASM_i_LA_mostly(p, ptr, pgdc);
+               UASM_i_LA_mostly(p, ptr, pgdc);
 #endif
-       uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
-       uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+               uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+               uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+       }
        uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
        uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
        uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
@@ -1349,95 +1311,100 @@ static void build_r4000_tlb_refill_handler(void)
         * need three, with the second nop'ed and the third being
         * unused.
         */
-       /* Loongson2 ebase is different than r4k, we have more space */
-#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
-       if ((p - tlb_handler) > 64)
-               panic("TLB refill handler space exceeded");
-#else
-       if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1)
-           || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3)
-               && uasm_insn_has_bdelay(relocs,
-                                       tlb_handler + MIPS64_REFILL_INSNS - 3)))
-               panic("TLB refill handler space exceeded");
-#endif
-
-       /*
-        * Now fold the handler in the TLB refill handler space.
-        */
-#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
-       f = final_handler;
-       /* Simplest case, just copy the handler. */
-       uasm_copy_handler(relocs, labels, tlb_handler, p, f);
-       final_len = p - tlb_handler;
-#else /* CONFIG_64BIT */
-       f = final_handler + MIPS64_REFILL_INSNS;
-       if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) {
-               /* Just copy the handler. */
-               uasm_copy_handler(relocs, labels, tlb_handler, p, f);
-               final_len = p - tlb_handler;
-       } else {
-#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
-               const enum label_id ls = label_tlb_huge_update;
-#else
-               const enum label_id ls = label_vmalloc;
-#endif
-               u32 *split;
-               int ov = 0;
-               int i;
-
-               for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++)
-                       ;
-               BUG_ON(i == ARRAY_SIZE(labels));
-               split = labels[i].addr;
-
-               /*
-                * See if we have overflown one way or the other.
-                */
-               if (split > tlb_handler + MIPS64_REFILL_INSNS ||
-                   split < p - MIPS64_REFILL_INSNS)
-                       ov = 1;
-
-               if (ov) {
+       switch (boot_cpu_type()) {
+       default:
+               if (sizeof(long) == 4) {
+       case CPU_LOONGSON2:
+               /* Loongson2 ebase is different than r4k, we have more space */
+                       if ((p - tlb_handler) > 64)
+                               panic("TLB refill handler space exceeded");
                        /*
-                        * Split two instructions before the end.  One
-                        * for the branch and one for the instruction
-                        * in the delay slot.
+                        * Now fold the handler in the TLB refill handler space.
                         */
-                       split = tlb_handler + MIPS64_REFILL_INSNS - 2;
-
+                       f = final_handler;
+                       /* Simplest case, just copy the handler. */
+                       uasm_copy_handler(relocs, labels, tlb_handler, p, f);
+                       final_len = p - tlb_handler;
+                       break;
+               } else {
+                       if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1)
+                           || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3)
+                               && uasm_insn_has_bdelay(relocs,
+                                                       tlb_handler + MIPS64_REFILL_INSNS - 3)))
+                               panic("TLB refill handler space exceeded");
                        /*
-                        * If the branch would fall in a delay slot,
-                        * we must back up an additional instruction
-                        * so that it is no longer in a delay slot.
+                        * Now fold the handler in the TLB refill handler space.
                         */
-                       if (uasm_insn_has_bdelay(relocs, split - 1))
-                               split--;
-               }
-               /* Copy first part of the handler. */
-               uasm_copy_handler(relocs, labels, tlb_handler, split, f);
-               f += split - tlb_handler;
-
-               if (ov) {
-                       /* Insert branch. */
-                       uasm_l_split(&l, final_handler);
-                       uasm_il_b(&f, &r, label_split);
-                       if (uasm_insn_has_bdelay(relocs, split))
-                               uasm_i_nop(&f);
-                       else {
-                               uasm_copy_handler(relocs, labels,
-                                                 split, split + 1, f);
-                               uasm_move_labels(labels, f, f + 1, -1);
-                               f++;
-                               split++;
+                       f = final_handler + MIPS64_REFILL_INSNS;
+                       if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) {
+                               /* Just copy the handler. */
+                               uasm_copy_handler(relocs, labels, tlb_handler, p, f);
+                               final_len = p - tlb_handler;
+                       } else {
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+                               const enum label_id ls = label_tlb_huge_update;
+#else
+                               const enum label_id ls = label_vmalloc;
+#endif
+                               u32 *split;
+                               int ov = 0;
+                               int i;
+
+                               for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++)
+                                       ;
+                               BUG_ON(i == ARRAY_SIZE(labels));
+                               split = labels[i].addr;
+
+                               /*
+                                * See if we have overflown one way or the other.
+                                */
+                               if (split > tlb_handler + MIPS64_REFILL_INSNS ||
+                                   split < p - MIPS64_REFILL_INSNS)
+                                       ov = 1;
+
+                               if (ov) {
+                                       /*
+                                        * Split two instructions before the end.  One
+                                        * for the branch and one for the instruction
+                                        * in the delay slot.
+                                        */
+                                       split = tlb_handler + MIPS64_REFILL_INSNS - 2;
+
+                                       /*
+                                        * If the branch would fall in a delay slot,
+                                        * we must back up an additional instruction
+                                        * so that it is no longer in a delay slot.
+                                        */
+                                       if (uasm_insn_has_bdelay(relocs, split - 1))
+                                               split--;
+                               }
+                               /* Copy first part of the handler. */
+                               uasm_copy_handler(relocs, labels, tlb_handler, split, f);
+                               f += split - tlb_handler;
+
+                               if (ov) {
+                                       /* Insert branch. */
+                                       uasm_l_split(&l, final_handler);
+                                       uasm_il_b(&f, &r, label_split);
+                                       if (uasm_insn_has_bdelay(relocs, split))
+                                               uasm_i_nop(&f);
+                                       else {
+                                               uasm_copy_handler(relocs, labels,
+                                                                 split, split + 1, f);
+                                               uasm_move_labels(labels, f, f + 1, -1);
+                                               f++;
+                                               split++;
+                                       }
+                               }
+
+                               /* Copy the rest of the handler. */
+                               uasm_copy_handler(relocs, labels, split, p, final_handler);
+                               final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) +
+                                           (p - split);
                        }
                }
-
-               /* Copy the rest of the handler. */
-               uasm_copy_handler(relocs, labels, split, p, final_handler);
-               final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) +
-                           (p - split);
+               break;
        }
-#endif /* CONFIG_64BIT */
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB refill handler (%u instructions).\n",
@@ -1451,28 +1418,30 @@ static void build_r4000_tlb_refill_handler(void)
 extern u32 handle_tlbl[], handle_tlbl_end[];
 extern u32 handle_tlbs[], handle_tlbs_end[];
 extern u32 handle_tlbm[], handle_tlbm_end[];
-
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[];
 
-static void build_r4000_setup_pgd(void)
+static void build_setup_pgd(void)
 {
        const int a0 = 4;
-       const int a1 = 5;
+       const int __maybe_unused a1 = 5;
+       const int __maybe_unused a2 = 6;
        u32 *p = tlbmiss_handler_setup_pgd;
        const int tlbmiss_handler_setup_pgd_size =
                tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd;
-       struct uasm_label *l = labels;
-       struct uasm_reloc *r = relocs;
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+       long pgdc = (long)pgd_current;
+#endif
 
        memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size *
                                        sizeof(tlbmiss_handler_setup_pgd[0]));
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
-
        pgd_reg = allocate_kscratch();
-
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
        if (pgd_reg == -1) {
+               struct uasm_label *l = labels;
+               struct uasm_reloc *r = relocs;
+
                /* PGD << 11 in c0_Context */
                /*
                 * If it is a ckseg0 address, convert to a physical
@@ -1494,6 +1463,26 @@ static void build_r4000_setup_pgd(void)
                uasm_i_jr(&p, 31);
                UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
        }
+#else
+#ifdef CONFIG_SMP
+       /* Save PGD to pgd_current[smp_processor_id()] */
+       UASM_i_CPUID_MFC0(&p, a1, SMP_CPUID_REG);
+       UASM_i_SRL_SAFE(&p, a1, a1, SMP_CPUID_PTRSHIFT);
+       UASM_i_LA_mostly(&p, a2, pgdc);
+       UASM_i_ADDU(&p, a2, a2, a1);
+       UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2);
+#else
+       UASM_i_LA_mostly(&p, a2, pgdc);
+       UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2);
+#endif /* SMP */
+       uasm_i_jr(&p, 31);
+
+       /* if pgd_reg is allocated, save PGD also to scratch register */
+       if (pgd_reg != -1)
+               UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
+       else
+               uasm_i_nop(&p);
+#endif
        if (p >= tlbmiss_handler_setup_pgd_end)
                panic("tlbmiss_handler_setup_pgd space exceeded");
 
@@ -1504,7 +1493,6 @@ static void build_r4000_setup_pgd(void)
        dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd,
                                        tlbmiss_handler_setup_pgd_size);
 }
-#endif
 
 static void
 iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
@@ -2197,10 +2185,8 @@ static void flush_tlb_handlers(void)
                           (unsigned long)handle_tlbs_end);
        local_flush_icache_range((unsigned long)handle_tlbm,
                           (unsigned long)handle_tlbm_end);
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
        local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
                           (unsigned long)tlbmiss_handler_setup_pgd_end);
-#endif
 }
 
 void build_tlb_refill_handler(void)
@@ -2232,6 +2218,7 @@ void build_tlb_refill_handler(void)
                if (!run_once) {
                        if (!cpu_has_local_ebase)
                                build_r3000_tlb_refill_handler();
+                       build_setup_pgd();
                        build_r3000_tlb_load_handler();
                        build_r3000_tlb_store_handler();
                        build_r3000_tlb_modify_handler();
@@ -2255,9 +2242,7 @@ void build_tlb_refill_handler(void)
        default:
                if (!run_once) {
                        scratch_reg = allocate_kscratch();
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-                       build_r4000_setup_pgd();
-#endif
+                       build_setup_pgd();
                        build_r4000_tlb_load_handler();
                        build_r4000_tlb_store_handler();
                        build_r4000_tlb_modify_handler();
index c69da37346995e94a5e5d4a33dafce0585b84ed9..0892575f829da5a5cb71218265fe81da24d14cfb 100644 (file)
@@ -37,7 +37,6 @@
 #include <asm/irq_regs.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
-#include <asm/mips-boards/piix4.h>
 #include <asm/gt64120.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/msc01_pci.h>
@@ -473,7 +472,7 @@ static void __init fill_ipi_map(void)
 {
        int cpu;
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+       for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
                fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1);
                fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2);
        }
@@ -574,8 +573,9 @@ void __init arch_init_irq(void)
                /* FIXME */
                int i;
 #if defined(CONFIG_MIPS_MT_SMP)
-               gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
-               gic_resched_int_base = gic_call_int_base - NR_CPUS;
+               gic_call_int_base = GIC_NUM_INTRS -
+                       (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids;
+               gic_resched_int_base = gic_call_int_base - nr_cpu_ids;
                fill_ipi_map();
 #endif
                gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
@@ -599,7 +599,7 @@ void __init arch_init_irq(void)
                printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status());
                write_c0_status(0x1100dc00);
                printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
-               for (i = 0; i < NR_CPUS; i++) {
+               for (i = 0; i < nr_cpu_ids; i++) {
                        arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
                                         GIC_RESCHED_INT(i), &irq_resched);
                        arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
index 6f8feb9efcff9e64174534233133b6d097d957fc..c0eded01fde96ef23676eabc28e72ceb286467ad 100644 (file)
@@ -245,7 +245,7 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask)
        return threadmode;
 
 unsupp:
-       panic("Unsupported CPU mask %lx\n",
+       panic("Unsupported CPU mask %lx",
                (unsigned long)cpumask_bits(wakeup_mask)[0]);
        return 0;
 }
index 07ada7f8441ead44606e732f179a9d2dc4d0e00e..df36e2327c54572cca76848547cbbbf030c554ac 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <asm/mips-boards/piix4.h>
 
 /* PCI interrupt pins */
 #define PCIA           1
@@ -53,7 +54,8 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
 static void malta_piix_func0_fixup(struct pci_dev *pdev)
 {
        unsigned char reg_val;
-       static int piixirqmap[16] = {  /* PIIX PIRQC[A:D] irq mappings */
+       /* PIIX PIRQC[A:D] irq mappings */
+       static int piixirqmap[PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX] = {
                0,  0,  0,  3,
                4,  5,  6,  7,
                0,  9, 10, 11,
@@ -63,11 +65,12 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev)
 
        /* Interrogate PIIX4 to get PCI IRQ mapping */
        for (i = 0; i <= 3; i++) {
-               pci_read_config_byte(pdev, 0x60+i, &reg_val);
-               if (reg_val & 0x80)
+               pci_read_config_byte(pdev, PIIX4_FUNC0_PIRQRC+i, &reg_val);
+               if (reg_val & PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_DISABLE)
                        pci_irq[PCIA+i] = 0;    /* Disabled */
                else
-                       pci_irq[PCIA+i] = piixirqmap[reg_val & 15];
+                       pci_irq[PCIA+i] = piixirqmap[reg_val &
+                               PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MASK];
        }
 
        /* Done by YAMON 2.00 onwards */
@@ -76,8 +79,9 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev)
                 * Set top of main memory accessible by ISA or DMA
                 * devices to 16 Mb.
                 */
-               pci_read_config_byte(pdev, 0x69, &reg_val);
-               pci_write_config_byte(pdev, 0x69, reg_val | 0xf0);
+               pci_read_config_byte(pdev, PIIX4_FUNC0_TOM, &reg_val);
+               pci_write_config_byte(pdev, PIIX4_FUNC0_TOM, reg_val |
+                               PIIX4_FUNC0_TOM_TOP_OF_MEMORY_MASK);
        }
 }
 
@@ -93,10 +97,14 @@ static void malta_piix_func1_fixup(struct pci_dev *pdev)
                /*
                 * IDE Decode enable.
                 */
-               pci_read_config_byte(pdev, 0x41, &reg_val);
-               pci_write_config_byte(pdev, 0x41, reg_val|0x80);
-               pci_read_config_byte(pdev, 0x43, &reg_val);
-               pci_write_config_byte(pdev, 0x43, reg_val|0x80);
+               pci_read_config_byte(pdev, PIIX4_FUNC1_IDETIM_PRIMARY_HI,
+                       &reg_val);
+               pci_write_config_byte(pdev, PIIX4_FUNC1_IDETIM_PRIMARY_HI,
+                       reg_val|PIIX4_FUNC1_IDETIM_PRIMARY_HI_IDE_DECODE_EN);
+               pci_read_config_byte(pdev, PIIX4_FUNC1_IDETIM_SECONDARY_HI,
+                       &reg_val);
+               pci_write_config_byte(pdev, PIIX4_FUNC1_IDETIM_SECONDARY_HI,
+                       reg_val|PIIX4_FUNC1_IDETIM_SECONDARY_HI_IDE_DECODE_EN);
        }
 }
 
@@ -108,10 +116,12 @@ static void quirk_dlcsetup(struct pci_dev *dev)
 {
        u8 odlc, ndlc;
 
-       (void) pci_read_config_byte(dev, 0x82, &odlc);
+       (void) pci_read_config_byte(dev, PIIX4_FUNC0_DLC, &odlc);
        /* Enable passive releases and delayed transaction */
-       ndlc = odlc | 7;
-       (void) pci_write_config_byte(dev, 0x82, ndlc);
+       ndlc = odlc | PIIX4_FUNC0_DLC_USBPR_EN |
+                     PIIX4_FUNC0_DLC_PASSIVE_RELEASE_EN |
+                     PIIX4_FUNC0_DLC_DELAYED_TRANSACTION_EN;
+       (void) pci_write_config_byte(dev, PIIX4_FUNC0_DLC, ndlc);
 }
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
index 18517dd0f7090987fe182df3d2a4dbe4e62842cf..d471a26dd5f891664fbed0bcc6d330f73027cffd 100644 (file)
@@ -363,9 +363,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev)
        spin_lock_init(&apc->lock);
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
-       if (!res)
-               return -EINVAL;
-
        apc->cfg_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(apc->cfg_base))
                return PTR_ERR(apc->cfg_base);
index 65ec032fa0b442367c93b70cf8599fb5bd03fdd1..785b2659b519bce10085ee6bd42831937c616d4b 100644 (file)
@@ -362,25 +362,16 @@ static int ar724x_pci_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
-       if (!res)
-               return -EINVAL;
-
        apc->ctrl_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(apc->ctrl_base))
                return PTR_ERR(apc->ctrl_base);
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
-       if (!res)
-               return -EINVAL;
-
        apc->devcfg_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(apc->devcfg_base))
                return PTR_ERR(apc->devcfg_base);
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base");
-       if (!res)
-               return -EINVAL;
-
        apc->crp_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(apc->crp_base))
                return PTR_ERR(apc->crp_base);
index 33e7aa52d9c4451ca352221921e27c134246a52d..1bf60b12737746d19cfec9c8b0512e6c419a2a5c 100644 (file)
@@ -120,51 +120,37 @@ static void pcibios_scanbus(struct pci_controller *hose)
 #ifdef CONFIG_OF
 void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node)
 {
-       const __be32 *ranges;
-       int rlen;
-       int pna = of_n_addr_cells(node);
-       int np = pna + 5;
+       struct of_pci_range range;
+       struct of_pci_range_parser parser;
 
        pr_info("PCI host bridge %s ranges:\n", node->full_name);
-       ranges = of_get_property(node, "ranges", &rlen);
-       if (ranges == NULL)
-               return;
        hose->of_node = node;
 
-       while ((rlen -= np * 4) >= 0) {
-               u32 pci_space;
+       if (of_pci_range_parser_init(&parser, node))
+               return;
+
+       for_each_of_pci_range(&parser, &range) {
                struct resource *res = NULL;
-               u64 addr, size;
-
-               pci_space = be32_to_cpup(&ranges[0]);
-               addr = of_translate_address(node, ranges + 3);
-               size = of_read_number(ranges + pna + 3, 2);
-               ranges += np;
-               switch ((pci_space >> 24) & 0x3) {
-               case 1:         /* PCI IO space */
+
+               switch (range.flags & IORESOURCE_TYPE_BITS) {
+               case IORESOURCE_IO:
                        pr_info("  IO 0x%016llx..0x%016llx\n",
-                                       addr, addr + size - 1);
+                               range.cpu_addr,
+                               range.cpu_addr + range.size - 1);
                        hose->io_map_base =
-                               (unsigned long)ioremap(addr, size);
+                               (unsigned long)ioremap(range.cpu_addr,
+                                                      range.size);
                        res = hose->io_resource;
-                       res->flags = IORESOURCE_IO;
                        break;
-               case 2:         /* PCI Memory space */
-               case 3:         /* PCI 64 bits Memory space */
+               case IORESOURCE_MEM:
                        pr_info(" MEM 0x%016llx..0x%016llx\n",
-                                       addr, addr + size - 1);
+                               range.cpu_addr,
+                               range.cpu_addr + range.size - 1);
                        res = hose->mem_resource;
-                       res->flags = IORESOURCE_MEM;
                        break;
                }
-               if (res != NULL) {
-                       res->start = addr;
-                       res->name = node->full_name;
-                       res->end = res->start + size - 1;
-                       res->parent = NULL;
-                       res->sibling = NULL;
-                       res->child = NULL;
-               }
+               if (res != NULL)
+                       of_pci_range_to_resource(&range, node, res);
        }
 }
 
diff --git a/arch/mips/powertv/Kconfig b/arch/mips/powertv/Kconfig
deleted file mode 100644 (file)
index dd91fba..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-config BOOTLOADER_FAMILY
-       string "POWERTV Bootloader Family string"
-       default "85"
-       depends on POWERTV
-       help
-         This value should be specified when the bootloader driver is disabled
-         and must be exactly two characters long. Families supported are:
-           R1 - RNG-100  R2 - RNG-200
-           A1 - Class A  B1 - Class B
-           E1 - Class E  F1 - Class F
-           44 - 45xx     46 - 46xx
-           85 - 85xx     86 - 86xx
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
deleted file mode 100644 (file)
index 39ca9f8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Carsten Langgaard, carstenl@mips.com
-# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
-#
-# Carsten Langgaard, carstenl@mips.com
-# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-# Portions copyright (C)  2009 Cisco Systems, Inc.
-#
-# This program is free software; you can distribute 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 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.
-#
-# Makefile for the Cisco PowerTV-specific kernel interface routines
-# under Linux.
-#
-
-obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \
-       asic/ pci/
-
-obj-$(CONFIG_USB) += powertv-usb.o
diff --git a/arch/mips/powertv/Platform b/arch/mips/powertv/Platform
deleted file mode 100644 (file)
index 4eb5af1..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Cisco PowerTV Platform
-#
-platform-$(CONFIG_POWERTV)     += powertv/
-cflags-$(CONFIG_POWERTV)       +=                                      \
-               -I$(srctree)/arch/mips/include/asm/mach-powertv
-load-$(CONFIG_POWERTV)         += 0xffffffff90800000
diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile
deleted file mode 100644 (file)
index 35dcc53..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (C) 2009  Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-
-obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \
-       asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \
-       prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c
deleted file mode 100644 (file)
index 2f539b4..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Locations of devices in the Calliope ASIC.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- *
- * Description:         Defines the platform resources for the SA settop.
- */
-
-#include <linux/init.h>
-#include <asm/mach-powertv/asic.h>
-
-#define CALLIOPE_ADDR(x)       (CALLIOPE_IO_BASE + (x))
-
-const struct register_map calliope_register_map __initconst = {
-       .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)},
-       .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)},
-       .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)},
-
-       .chipver3 = {.phys = CALLIOPE_ADDR(0xA00800)},
-       .chipver2 = {.phys = CALLIOPE_ADDR(0xA00804)},
-       .chipver1 = {.phys = CALLIOPE_ADDR(0xA00808)},
-       .chipver0 = {.phys = CALLIOPE_ADDR(0xA0080c)},
-
-       /* The registers of IRBlaster */
-       .uart1_intstat = {.phys = CALLIOPE_ADDR(0xA01800)},
-       .uart1_inten = {.phys = CALLIOPE_ADDR(0xA01804)},
-       .uart1_config1 = {.phys = CALLIOPE_ADDR(0xA01808)},
-       .uart1_config2 = {.phys = CALLIOPE_ADDR(0xA0180C)},
-       .uart1_divisorhi = {.phys = CALLIOPE_ADDR(0xA01810)},
-       .uart1_divisorlo = {.phys = CALLIOPE_ADDR(0xA01814)},
-       .uart1_data = {.phys = CALLIOPE_ADDR(0xA01818)},
-       .uart1_status = {.phys = CALLIOPE_ADDR(0xA0181C)},
-
-       .int_stat_3 = {.phys = CALLIOPE_ADDR(0xA02800)},
-       .int_stat_2 = {.phys = CALLIOPE_ADDR(0xA02804)},
-       .int_stat_1 = {.phys = CALLIOPE_ADDR(0xA02808)},
-       .int_stat_0 = {.phys = CALLIOPE_ADDR(0xA0280c)},
-       .int_config = {.phys = CALLIOPE_ADDR(0xA02810)},
-       .int_int_scan = {.phys = CALLIOPE_ADDR(0xA02818)},
-       .ien_int_3 = {.phys = CALLIOPE_ADDR(0xA02830)},
-       .ien_int_2 = {.phys = CALLIOPE_ADDR(0xA02834)},
-       .ien_int_1 = {.phys = CALLIOPE_ADDR(0xA02838)},
-       .ien_int_0 = {.phys = CALLIOPE_ADDR(0xA0283c)},
-       .int_level_3_3 = {.phys = CALLIOPE_ADDR(0xA02880)},
-       .int_level_3_2 = {.phys = CALLIOPE_ADDR(0xA02884)},
-       .int_level_3_1 = {.phys = CALLIOPE_ADDR(0xA02888)},
-       .int_level_3_0 = {.phys = CALLIOPE_ADDR(0xA0288c)},
-       .int_level_2_3 = {.phys = CALLIOPE_ADDR(0xA02890)},
-       .int_level_2_2 = {.phys = CALLIOPE_ADDR(0xA02894)},
-       .int_level_2_1 = {.phys = CALLIOPE_ADDR(0xA02898)},
-       .int_level_2_0 = {.phys = CALLIOPE_ADDR(0xA0289c)},
-       .int_level_1_3 = {.phys = CALLIOPE_ADDR(0xA028a0)},
-       .int_level_1_2 = {.phys = CALLIOPE_ADDR(0xA028a4)},
-       .int_level_1_1 = {.phys = CALLIOPE_ADDR(0xA028a8)},
-       .int_level_1_0 = {.phys = CALLIOPE_ADDR(0xA028ac)},
-       .int_level_0_3 = {.phys = CALLIOPE_ADDR(0xA028b0)},
-       .int_level_0_2 = {.phys = CALLIOPE_ADDR(0xA028b4)},
-       .int_level_0_1 = {.phys = CALLIOPE_ADDR(0xA028b8)},
-       .int_level_0_0 = {.phys = CALLIOPE_ADDR(0xA028bc)},
-       .int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)},
-
-       .mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)},
-       .fs432x4b4_usb_ctl = {.phys = CALLIOPE_ADDR(0x980030)},
-       .test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)},
-       .crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)},
-       .usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)},
-       .usb2_strap = {.phys = CALLIOPE_ADDR(0x9A0014)},
-       .ehci_hcapbase = {.phys = CALLIOPE_ADDR(0x9BFE00)},
-       .ohci_hc_revision = {.phys = CALLIOPE_ADDR(0x9BFC00)},
-       .bcm1_bs_lmi_steer = {.phys = CALLIOPE_ADDR(0x9E0004)},
-       .usb2_control = {.phys = CALLIOPE_ADDR(0x9E0054)},
-       .usb2_stbus_obc = {.phys = CALLIOPE_ADDR(0x9BFF00)},
-       .usb2_stbus_mess_size = {.phys = CALLIOPE_ADDR(0x9BFF04)},
-       .usb2_stbus_chunk_size = {.phys = CALLIOPE_ADDR(0x9BFF08)},
-
-       .pcie_regs = {.phys = 0x000000},        /* -doesn't exist- */
-       .tim_ch = {.phys = CALLIOPE_ADDR(0xA02C10)},
-       .tim_cl = {.phys = CALLIOPE_ADDR(0xA02C14)},
-       .gpio_dout = {.phys = CALLIOPE_ADDR(0xA02c20)},
-       .gpio_din = {.phys = CALLIOPE_ADDR(0xA02c24)},
-       .gpio_dir = {.phys = CALLIOPE_ADDR(0xA02c2C)},
-       .watchdog = {.phys = CALLIOPE_ADDR(0xA02c30)},
-       .front_panel = {.phys = 0x000000},      /* -not used- */
-};
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c
deleted file mode 100644 (file)
index 7f8f342..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Locations of devices in the Cronus ASIC
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- *
- * Description:         Defines the platform resources for the SA settop.
- */
-
-#include <linux/init.h>
-#include <asm/mach-powertv/asic.h>
-
-#define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x))
-
-const struct register_map cronus_register_map __initconst = {
-       .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)},
-       .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)},
-       .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)},
-
-       .chipver3 = {.phys = CRONUS_ADDR(0x2A0800)},
-       .chipver2 = {.phys = CRONUS_ADDR(0x2A0804)},
-       .chipver1 = {.phys = CRONUS_ADDR(0x2A0808)},
-       .chipver0 = {.phys = CRONUS_ADDR(0x2A080C)},
-
-       /* The registers of IRBlaster */
-       .uart1_intstat = {.phys = CRONUS_ADDR(0x2A1800)},
-       .uart1_inten = {.phys = CRONUS_ADDR(0x2A1804)},
-       .uart1_config1 = {.phys = CRONUS_ADDR(0x2A1808)},
-       .uart1_config2 = {.phys = CRONUS_ADDR(0x2A180C)},
-       .uart1_divisorhi = {.phys = CRONUS_ADDR(0x2A1810)},
-       .uart1_divisorlo = {.phys = CRONUS_ADDR(0x2A1814)},
-       .uart1_data = {.phys = CRONUS_ADDR(0x2A1818)},
-       .uart1_status = {.phys = CRONUS_ADDR(0x2A181C)},
-
-       .int_stat_3 = {.phys = CRONUS_ADDR(0x2A2800)},
-       .int_stat_2 = {.phys = CRONUS_ADDR(0x2A2804)},
-       .int_stat_1 = {.phys = CRONUS_ADDR(0x2A2808)},
-       .int_stat_0 = {.phys = CRONUS_ADDR(0x2A280C)},
-       .int_config = {.phys = CRONUS_ADDR(0x2A2810)},
-       .int_int_scan = {.phys = CRONUS_ADDR(0x2A2818)},
-       .ien_int_3 = {.phys = CRONUS_ADDR(0x2A2830)},
-       .ien_int_2 = {.phys = CRONUS_ADDR(0x2A2834)},
-       .ien_int_1 = {.phys = CRONUS_ADDR(0x2A2838)},
-       .ien_int_0 = {.phys = CRONUS_ADDR(0x2A283C)},
-       .int_level_3_3 = {.phys = CRONUS_ADDR(0x2A2880)},
-       .int_level_3_2 = {.phys = CRONUS_ADDR(0x2A2884)},
-       .int_level_3_1 = {.phys = CRONUS_ADDR(0x2A2888)},
-       .int_level_3_0 = {.phys = CRONUS_ADDR(0x2A288C)},
-       .int_level_2_3 = {.phys = CRONUS_ADDR(0x2A2890)},
-       .int_level_2_2 = {.phys = CRONUS_ADDR(0x2A2894)},
-       .int_level_2_1 = {.phys = CRONUS_ADDR(0x2A2898)},
-       .int_level_2_0 = {.phys = CRONUS_ADDR(0x2A289C)},
-       .int_level_1_3 = {.phys = CRONUS_ADDR(0x2A28A0)},
-       .int_level_1_2 = {.phys = CRONUS_ADDR(0x2A28A4)},
-       .int_level_1_1 = {.phys = CRONUS_ADDR(0x2A28A8)},
-       .int_level_1_0 = {.phys = CRONUS_ADDR(0x2A28AC)},
-       .int_level_0_3 = {.phys = CRONUS_ADDR(0x2A28B0)},
-       .int_level_0_2 = {.phys = CRONUS_ADDR(0x2A28B4)},
-       .int_level_0_1 = {.phys = CRONUS_ADDR(0x2A28B8)},
-       .int_level_0_0 = {.phys = CRONUS_ADDR(0x2A28BC)},
-       .int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)},
-
-       .mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)},
-       .fs432x4b4_usb_ctl = {.phys = CRONUS_ADDR(0x1C0028)},
-       .test_bus = {.phys = CRONUS_ADDR(0x1C00CC)},
-       .crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)},
-       .usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)},
-       .usb2_strap = {.phys = CRONUS_ADDR(0x200014)},
-       .ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)},
-       .ohci_hc_revision = {.phys = CRONUS_ADDR(0x21fc00)},
-       .bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)},
-       .usb2_control = {.phys = CRONUS_ADDR(0x2E004C)},
-       .usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)},
-       .usb2_stbus_mess_size = {.phys = CRONUS_ADDR(0x21FF04)},
-       .usb2_stbus_chunk_size = {.phys = CRONUS_ADDR(0x21FF08)},
-
-       .pcie_regs = {.phys = CRONUS_ADDR(0x220000)},
-       .tim_ch = {.phys = CRONUS_ADDR(0x2A2C10)},
-       .tim_cl = {.phys = CRONUS_ADDR(0x2A2C14)},
-       .gpio_dout = {.phys = CRONUS_ADDR(0x2A2C20)},
-       .gpio_din = {.phys = CRONUS_ADDR(0x2A2C24)},
-       .gpio_dir = {.phys = CRONUS_ADDR(0x2A2C2C)},
-       .watchdog = {.phys = CRONUS_ADDR(0x2A2C30)},
-       .front_panel = {.phys = CRONUS_ADDR(0x2A3800)},
-};
diff --git a/arch/mips/powertv/asic/asic-gaia.c b/arch/mips/powertv/asic/asic-gaia.c
deleted file mode 100644 (file)
index 1265b49..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Locations of devices in the Gaia ASIC
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      David VomLehn
- */
-
-#include <linux/init.h>
-#include <asm/mach-powertv/asic.h>
-
-const struct register_map gaia_register_map __initconst = {
-       .eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000},
-       .eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038},
-       .eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C},
-
-       .chipver3 = {.phys = GAIA_IO_BASE + 0x2A0800},
-       .chipver2 = {.phys = GAIA_IO_BASE + 0x2A0804},
-       .chipver1 = {.phys = GAIA_IO_BASE + 0x2A0808},
-       .chipver0 = {.phys = GAIA_IO_BASE + 0x2A080C},
-
-       /* The registers of IRBlaster */
-       .uart1_intstat = {.phys = GAIA_IO_BASE + 0x2A1800},
-       .uart1_inten = {.phys = GAIA_IO_BASE + 0x2A1804},
-       .uart1_config1 = {.phys = GAIA_IO_BASE + 0x2A1808},
-       .uart1_config2 = {.phys = GAIA_IO_BASE + 0x2A180C},
-       .uart1_divisorhi = {.phys = GAIA_IO_BASE + 0x2A1810},
-       .uart1_divisorlo = {.phys = GAIA_IO_BASE + 0x2A1814},
-       .uart1_data = {.phys = GAIA_IO_BASE + 0x2A1818},
-       .uart1_status = {.phys = GAIA_IO_BASE + 0x2A181C},
-
-       .int_stat_3 = {.phys = GAIA_IO_BASE + 0x2A2800},
-       .int_stat_2 = {.phys = GAIA_IO_BASE + 0x2A2804},
-       .int_stat_1 = {.phys = GAIA_IO_BASE + 0x2A2808},
-       .int_stat_0 = {.phys = GAIA_IO_BASE + 0x2A280C},
-       .int_config = {.phys = GAIA_IO_BASE + 0x2A2810},
-       .int_int_scan = {.phys = GAIA_IO_BASE + 0x2A2818},
-       .ien_int_3 = {.phys = GAIA_IO_BASE + 0x2A2830},
-       .ien_int_2 = {.phys = GAIA_IO_BASE + 0x2A2834},
-       .ien_int_1 = {.phys = GAIA_IO_BASE + 0x2A2838},
-       .ien_int_0 = {.phys = GAIA_IO_BASE + 0x2A283C},
-       .int_level_3_3 = {.phys = GAIA_IO_BASE + 0x2A2880},
-       .int_level_3_2 = {.phys = GAIA_IO_BASE + 0x2A2884},
-       .int_level_3_1 = {.phys = GAIA_IO_BASE + 0x2A2888},
-       .int_level_3_0 = {.phys = GAIA_IO_BASE + 0x2A288C},
-       .int_level_2_3 = {.phys = GAIA_IO_BASE + 0x2A2890},
-       .int_level_2_2 = {.phys = GAIA_IO_BASE + 0x2A2894},
-       .int_level_2_1 = {.phys = GAIA_IO_BASE + 0x2A2898},
-       .int_level_2_0 = {.phys = GAIA_IO_BASE + 0x2A289C},
-       .int_level_1_3 = {.phys = GAIA_IO_BASE + 0x2A28A0},
-       .int_level_1_2 = {.phys = GAIA_IO_BASE + 0x2A28A4},
-       .int_level_1_1 = {.phys = GAIA_IO_BASE + 0x2A28A8},
-       .int_level_1_0 = {.phys = GAIA_IO_BASE + 0x2A28AC},
-       .int_level_0_3 = {.phys = GAIA_IO_BASE + 0x2A28B0},
-       .int_level_0_2 = {.phys = GAIA_IO_BASE + 0x2A28B4},
-       .int_level_0_1 = {.phys = GAIA_IO_BASE + 0x2A28B8},
-       .int_level_0_0 = {.phys = GAIA_IO_BASE + 0x2A28BC},
-       .int_docsis_en = {.phys = GAIA_IO_BASE + 0x2A28F4},
-
-       .mips_pll_setup = {.phys = GAIA_IO_BASE + 0x1C0000},
-       .fs432x4b4_usb_ctl = {.phys = GAIA_IO_BASE + 0x1C0024},
-       .test_bus = {.phys = GAIA_IO_BASE + 0x1C00CC},
-       .crt_spare = {.phys = GAIA_IO_BASE + 0x1c0108},
-       .usb2_ohci_int_mask = {.phys = GAIA_IO_BASE + 0x20000C},
-       .usb2_strap = {.phys = GAIA_IO_BASE + 0x200014},
-       .ehci_hcapbase = {.phys = GAIA_IO_BASE + 0x21FE00},
-       .ohci_hc_revision = {.phys = GAIA_IO_BASE + 0x21fc00},
-       .bcm1_bs_lmi_steer = {.phys = GAIA_IO_BASE + 0x2E0004},
-       .usb2_control = {.phys = GAIA_IO_BASE + 0x2E004C},
-       .usb2_stbus_obc = {.phys = GAIA_IO_BASE + 0x21FF00},
-       .usb2_stbus_mess_size = {.phys = GAIA_IO_BASE + 0x21FF04},
-       .usb2_stbus_chunk_size = {.phys = GAIA_IO_BASE + 0x21FF08},
-
-       .pcie_regs = {.phys = GAIA_IO_BASE + 0x220000},
-       .tim_ch = {.phys = GAIA_IO_BASE + 0x2A2C10},
-       .tim_cl = {.phys = GAIA_IO_BASE + 0x2A2C14},
-       .gpio_dout = {.phys = GAIA_IO_BASE + 0x2A2C20},
-       .gpio_din = {.phys = GAIA_IO_BASE + 0x2A2C24},
-       .gpio_dir = {.phys = GAIA_IO_BASE + 0x2A2C2C},
-       .watchdog = {.phys = GAIA_IO_BASE + 0x2A2C30},
-       .front_panel = {.phys = GAIA_IO_BASE + 0x2A3800},
-};
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c
deleted file mode 100644 (file)
index 14e7de1..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Locations of devices in the Zeus ASIC
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- *
- * Description:         Defines the platform resources for the SA settop.
- */
-
-#include <linux/init.h>
-#include <asm/mach-powertv/asic.h>
-
-#define ZEUS_ADDR(x)   (ZEUS_IO_BASE + (x))
-
-const struct register_map zeus_register_map __initconst = {
-       .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)},
-       .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)},
-       .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)},
-
-       .chipver3 = {.phys = ZEUS_ADDR(0x280800)},
-       .chipver2 = {.phys = ZEUS_ADDR(0x280804)},
-       .chipver1 = {.phys = ZEUS_ADDR(0x280808)},
-       .chipver0 = {.phys = ZEUS_ADDR(0x28080c)},
-
-       /* The registers of IRBlaster */
-       .uart1_intstat = {.phys = ZEUS_ADDR(0x281800)},
-       .uart1_inten = {.phys = ZEUS_ADDR(0x281804)},
-       .uart1_config1 = {.phys = ZEUS_ADDR(0x281808)},
-       .uart1_config2 = {.phys = ZEUS_ADDR(0x28180C)},
-       .uart1_divisorhi = {.phys = ZEUS_ADDR(0x281810)},
-       .uart1_divisorlo = {.phys = ZEUS_ADDR(0x281814)},
-       .uart1_data = {.phys = ZEUS_ADDR(0x281818)},
-       .uart1_status = {.phys = ZEUS_ADDR(0x28181C)},
-
-       .int_stat_3 = {.phys = ZEUS_ADDR(0x282800)},
-       .int_stat_2 = {.phys = ZEUS_ADDR(0x282804)},
-       .int_stat_1 = {.phys = ZEUS_ADDR(0x282808)},
-       .int_stat_0 = {.phys = ZEUS_ADDR(0x28280c)},
-       .int_config = {.phys = ZEUS_ADDR(0x282810)},
-       .int_int_scan = {.phys = ZEUS_ADDR(0x282818)},
-       .ien_int_3 = {.phys = ZEUS_ADDR(0x282830)},
-       .ien_int_2 = {.phys = ZEUS_ADDR(0x282834)},
-       .ien_int_1 = {.phys = ZEUS_ADDR(0x282838)},
-       .ien_int_0 = {.phys = ZEUS_ADDR(0x28283c)},
-       .int_level_3_3 = {.phys = ZEUS_ADDR(0x282880)},
-       .int_level_3_2 = {.phys = ZEUS_ADDR(0x282884)},
-       .int_level_3_1 = {.phys = ZEUS_ADDR(0x282888)},
-       .int_level_3_0 = {.phys = ZEUS_ADDR(0x28288c)},
-       .int_level_2_3 = {.phys = ZEUS_ADDR(0x282890)},
-       .int_level_2_2 = {.phys = ZEUS_ADDR(0x282894)},
-       .int_level_2_1 = {.phys = ZEUS_ADDR(0x282898)},
-       .int_level_2_0 = {.phys = ZEUS_ADDR(0x28289c)},
-       .int_level_1_3 = {.phys = ZEUS_ADDR(0x2828a0)},
-       .int_level_1_2 = {.phys = ZEUS_ADDR(0x2828a4)},
-       .int_level_1_1 = {.phys = ZEUS_ADDR(0x2828a8)},
-       .int_level_1_0 = {.phys = ZEUS_ADDR(0x2828ac)},
-       .int_level_0_3 = {.phys = ZEUS_ADDR(0x2828b0)},
-       .int_level_0_2 = {.phys = ZEUS_ADDR(0x2828b4)},
-       .int_level_0_1 = {.phys = ZEUS_ADDR(0x2828b8)},
-       .int_level_0_0 = {.phys = ZEUS_ADDR(0x2828bc)},
-       .int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)},
-
-       .mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)},
-       .fs432x4b4_usb_ctl = {.phys = ZEUS_ADDR(0x1a0018)},
-       .test_bus = {.phys = ZEUS_ADDR(0x1a0238)},
-       .crt_spare = {.phys = ZEUS_ADDR(0x1a0090)},
-       .usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)},
-       .usb2_strap = {.phys = ZEUS_ADDR(0x1e0014)},
-       .ehci_hcapbase = {.phys = ZEUS_ADDR(0x1FFE00)},
-       .ohci_hc_revision = {.phys = ZEUS_ADDR(0x1FFC00)},
-       .bcm1_bs_lmi_steer = {.phys = ZEUS_ADDR(0x2C0008)},
-       .usb2_control = {.phys = ZEUS_ADDR(0x2c01a0)},
-       .usb2_stbus_obc = {.phys = ZEUS_ADDR(0x1FFF00)},
-       .usb2_stbus_mess_size = {.phys = ZEUS_ADDR(0x1FFF04)},
-       .usb2_stbus_chunk_size = {.phys = ZEUS_ADDR(0x1FFF08)},
-
-       .pcie_regs = {.phys = ZEUS_ADDR(0x200000)},
-       .tim_ch = {.phys = ZEUS_ADDR(0x282C10)},
-       .tim_cl = {.phys = ZEUS_ADDR(0x282C14)},
-       .gpio_dout = {.phys = ZEUS_ADDR(0x282c20)},
-       .gpio_din = {.phys = ZEUS_ADDR(0x282c24)},
-       .gpio_dir = {.phys = ZEUS_ADDR(0x282c2C)},
-       .watchdog = {.phys = ZEUS_ADDR(0x282c30)},
-       .front_panel = {.phys = ZEUS_ADDR(0x283800)},
-};
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
deleted file mode 100644 (file)
index 8380605..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- *
- * Description:         Defines the platform resources for Gaia-based settops.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * NOTE: The bootloader allocates persistent memory at an address which is
- * 16 MiB below the end of the highest address in KSEG0. All fixed
- * address memory reservations must avoid this region.
- */
-
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/resource.h>
-#include <linux/serial_reg.h>
-#include <linux/io.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <asm/page.h>
-#include <linux/swap.h>
-#include <linux/highmem.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/mach-powertv/asic.h>
-#include <asm/mach-powertv/asic_regs.h>
-#include <asm/mach-powertv/interrupts.h>
-
-#ifdef CONFIG_BOOTLOADER_DRIVER
-#include <asm/mach-powertv/kbldr.h>
-#endif
-#include <asm/bootinfo.h>
-
-#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
-
-/*
- * Forward Prototypes
- */
-static void pmem_setup_resource(void);
-
-/*
- * Global Variables
- */
-enum asic_type asic;
-
-unsigned int platform_features;
-unsigned int platform_family;
-struct register_map _asic_register_map;
-EXPORT_SYMBOL(_asic_register_map);             /* Exported for testing */
-unsigned long asic_phy_base;
-unsigned long asic_base;
-EXPORT_SYMBOL(asic_base);                      /* Exported for testing */
-struct resource *gp_resources;
-
-/*
- * Don't recommend to use it directly, it is usually used by kernel internally.
- * Portable code should be using interfaces such as ioremp, dma_map_single, etc.
- */
-unsigned long phys_to_dma_offset;
-EXPORT_SYMBOL(phys_to_dma_offset);
-
-/*
- *
- * IO Resource Definition
- *
- */
-
-struct resource asic_resource = {
-       .name  = "ASIC Resource",
-       .start = 0,
-       .end   = ASIC_IO_SIZE,
-       .flags = IORESOURCE_MEM,
-};
-
-/*
- * Allow override of bootloader-specified model
- * Returns zero on success, a negative errno value on failure. This parameter
- * allows overriding of the bootloader-specified model.
- */
-static char __initdata cmdline[COMMAND_LINE_SIZE];
-
-#define FORCEFAMILY_PARAM      "forcefamily"
-
-/*
- * check_forcefamily - check for, and parse, forcefamily command line parameter
- * @forced_family:     Pointer to two-character array in which to store the
- *                     value of the forcedfamily parameter, if any.
- */
-static __init int check_forcefamily(unsigned char forced_family[2])
-{
-       const char *p;
-
-       forced_family[0] = '\0';
-       forced_family[1] = '\0';
-
-       /* Check the command line for a forcefamily directive */
-       strncpy(cmdline, arcs_cmdline, COMMAND_LINE_SIZE - 1);
-       p = strstr(cmdline, FORCEFAMILY_PARAM);
-       if (p && (p != cmdline) && (*(p - 1) != ' '))
-               p = strstr(p, " " FORCEFAMILY_PARAM "=");
-
-       if (p) {
-               p += strlen(FORCEFAMILY_PARAM "=");
-
-               if (*p == '\0' || *(p + 1) == '\0' ||
-                       (*(p + 2) != '\0' && *(p + 2) != ' '))
-                       pr_err(FORCEFAMILY_PARAM " must be exactly two "
-                               "characters long, ignoring value\n");
-
-               else {
-                       forced_family[0] = *p;
-                       forced_family[1] = *(p + 1);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * platform_set_family - determine major platform family type.
- *
- * Returns family type; -1 if none
- * Returns the family type; -1 if none
- *
- */
-static __init noinline void platform_set_family(void)
-{
-       unsigned char forced_family[2];
-       unsigned short bootldr_family;
-
-       if (check_forcefamily(forced_family) == 0)
-               bootldr_family = BOOTLDRFAMILY(forced_family[0],
-                       forced_family[1]);
-       else
-               bootldr_family = (unsigned short) BOOTLDRFAMILY(
-                       CONFIG_BOOTLOADER_FAMILY[0],
-                       CONFIG_BOOTLOADER_FAMILY[1]);
-
-       pr_info("Bootloader Family = 0x%04X\n", bootldr_family);
-
-       switch (bootldr_family) {
-       case BOOTLDRFAMILY('R', '1'):
-               platform_family = FAMILY_1500;
-               break;
-       case BOOTLDRFAMILY('4', '4'):
-               platform_family = FAMILY_4500;
-               break;
-       case BOOTLDRFAMILY('4', '6'):
-               platform_family = FAMILY_4600;
-               break;
-       case BOOTLDRFAMILY('A', '1'):
-               platform_family = FAMILY_4600VZA;
-               break;
-       case BOOTLDRFAMILY('8', '5'):
-               platform_family = FAMILY_8500;
-               break;
-       case BOOTLDRFAMILY('R', '2'):
-               platform_family = FAMILY_8500RNG;
-               break;
-       case BOOTLDRFAMILY('8', '6'):
-               platform_family = FAMILY_8600;
-               break;
-       case BOOTLDRFAMILY('B', '1'):
-               platform_family = FAMILY_8600VZB;
-               break;
-       case BOOTLDRFAMILY('E', '1'):
-               platform_family = FAMILY_1500VZE;
-               break;
-       case BOOTLDRFAMILY('F', '1'):
-               platform_family = FAMILY_1500VZF;
-               break;
-       case BOOTLDRFAMILY('8', '7'):
-               platform_family = FAMILY_8700;
-               break;
-       default:
-               platform_family = -1;
-       }
-}
-
-unsigned int platform_get_family(void)
-{
-       return platform_family;
-}
-EXPORT_SYMBOL(platform_get_family);
-
-/*
- * platform_get_asic - determine the ASIC type.
- *
- * Returns the ASIC type, or ASIC_UNKNOWN if unknown
- *
- */
-enum asic_type platform_get_asic(void)
-{
-       return asic;
-}
-EXPORT_SYMBOL(platform_get_asic);
-
-/*
- * set_register_map - set ASIC register configuration
- * @phys_base: Physical address of the base of the ASIC registers
- * @map:       Description of key ASIC registers
- */
-static void __init set_register_map(unsigned long phys_base,
-       const struct register_map *map)
-{
-       asic_phy_base = phys_base;
-       _asic_register_map = *map;
-       register_map_virtualize(&_asic_register_map);
-       asic_base = (unsigned long)ioremap_nocache(phys_base, ASIC_IO_SIZE);
-}
-
-/**
- * configure_platform - configuration based on platform type.
- */
-void __init configure_platform(void)
-{
-       platform_set_family();
-
-       switch (platform_family) {
-       case FAMILY_1500:
-       case FAMILY_1500VZE:
-       case FAMILY_1500VZF:
-               platform_features = FFS_CAPABLE;
-               asic = ASIC_CALLIOPE;
-               set_register_map(CALLIOPE_IO_BASE, &calliope_register_map);
-
-               if (platform_family == FAMILY_1500VZE) {
-                       gp_resources = non_dvr_vze_calliope_resources;
-                       pr_info("Platform: 1500/Vz Class E - "
-                               "CALLIOPE, NON_DVR_CAPABLE\n");
-               } else if (platform_family == FAMILY_1500VZF) {
-                       gp_resources = non_dvr_vzf_calliope_resources;
-                       pr_info("Platform: 1500/Vz Class F - "
-                               "CALLIOPE, NON_DVR_CAPABLE\n");
-               } else {
-                       gp_resources = non_dvr_calliope_resources;
-                       pr_info("Platform: 1500/RNG100 - CALLIOPE, "
-                               "NON_DVR_CAPABLE\n");
-               }
-               break;
-
-       case FAMILY_4500:
-               platform_features = FFS_CAPABLE | PCIE_CAPABLE |
-                       DISPLAY_CAPABLE;
-               asic = ASIC_ZEUS;
-               set_register_map(ZEUS_IO_BASE, &zeus_register_map);
-               gp_resources = non_dvr_zeus_resources;
-
-               pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n");
-               break;
-
-       case FAMILY_4600:
-       {
-               unsigned int chipversion = 0;
-
-               /* The settop has PCIE but it isn't used, so don't advertise
-                * it*/
-               platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
-
-               /* Cronus and Cronus Lite have the same register map */
-               set_register_map(CRONUS_IO_BASE, &cronus_register_map);
-
-               /* ASIC version will determine if this is a real CronusLite or
-                * Castrati(Cronus) */
-               chipversion  = asic_read(chipver3) << 24;
-               chipversion |= asic_read(chipver2) << 16;
-               chipversion |= asic_read(chipver1) << 8;
-               chipversion |= asic_read(chipver0);
-
-               if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11))
-                       asic = ASIC_CRONUS;
-               else
-                       asic = ASIC_CRONUSLITE;
-
-               gp_resources = non_dvr_cronuslite_resources;
-               pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
-                       "chipversion=0x%08X\n",
-                       (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE",
-                       chipversion);
-               break;
-       }
-       case FAMILY_4600VZA:
-               platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
-               asic = ASIC_CRONUS;
-               set_register_map(CRONUS_IO_BASE, &cronus_register_map);
-               gp_resources = non_dvr_cronus_resources;
-
-               pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n");
-               break;
-
-       case FAMILY_8500:
-       case FAMILY_8500RNG:
-               platform_features = DVR_CAPABLE | PCIE_CAPABLE |
-                       DISPLAY_CAPABLE;
-               asic = ASIC_ZEUS;
-               set_register_map(ZEUS_IO_BASE, &zeus_register_map);
-               gp_resources = dvr_zeus_resources;
-
-               pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n");
-               break;
-
-       case FAMILY_8600:
-       case FAMILY_8600VZB:
-               platform_features = DVR_CAPABLE | PCIE_CAPABLE |
-                       DISPLAY_CAPABLE;
-               asic = ASIC_CRONUS;
-               set_register_map(CRONUS_IO_BASE, &cronus_register_map);
-               gp_resources = dvr_cronus_resources;
-
-               pr_info("Platform: 8600/Vz Class B - CRONUS, "
-                       "DVR_CAPABLE\n");
-               break;
-
-       case FAMILY_8700:
-               platform_features = FFS_CAPABLE | PCIE_CAPABLE;
-               asic = ASIC_GAIA;
-               set_register_map(GAIA_IO_BASE, &gaia_register_map);
-               gp_resources = dvr_gaia_resources;
-
-               pr_info("Platform: 8700 - GAIA, DVR_CAPABLE\n");
-               break;
-
-       default:
-               pr_crit("Platform:  UNKNOWN PLATFORM\n");
-               break;
-       }
-
-       switch (asic) {
-       case ASIC_ZEUS:
-               phys_to_dma_offset = 0x30000000;
-               break;
-       case ASIC_CALLIOPE:
-               phys_to_dma_offset = 0x10000000;
-               break;
-       case ASIC_CRONUSLITE:
-               /* Fall through */
-       case ASIC_CRONUS:
-               /*
-                * TODO: We suppose 0x10000000 aliases into 0x20000000-
-                * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
-                * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
-                */
-               phys_to_dma_offset = 0x10000000;
-               break;
-       default:
-               phys_to_dma_offset = 0x00000000;
-               break;
-       }
-}
-
-/*
- * RESOURCE ALLOCATION
- *
- */
-/*
- * Allocates/reserves the Platform memory resources early in the boot process.
- * This ignores any resources that are designated IORESOURCE_IO
- */
-void __init platform_alloc_bootmem(void)
-{
-       int i;
-       int total = 0;
-
-       /* Get persistent memory data from command line before allocating
-        * resources. This need to happen before normal command line parsing
-        * has been done */
-       pmem_setup_resource();
-
-       /* Loop through looking for resources that want a particular address */
-       for (i = 0; gp_resources[i].flags != 0; i++) {
-               int size = resource_size(&gp_resources[i]);
-               if ((gp_resources[i].start != 0) &&
-                       ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
-                       reserve_bootmem(dma_to_phys(gp_resources[i].start),
-                               size, 0);
-                       total += resource_size(&gp_resources[i]);
-                       pr_info("reserve resource %s at %08x (%u bytes)\n",
-                               gp_resources[i].name, gp_resources[i].start,
-                               resource_size(&gp_resources[i]));
-               }
-       }
-
-       /* Loop through assigning addresses for those that are left */
-       for (i = 0; gp_resources[i].flags != 0; i++) {
-               int size = resource_size(&gp_resources[i]);
-               if ((gp_resources[i].start == 0) &&
-                       ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
-                       void *mem = alloc_bootmem_pages(size);
-
-                       if (mem == NULL)
-                               pr_err("Unable to allocate bootmem pages "
-                                       "for %s\n", gp_resources[i].name);
-
-                       else {
-                               gp_resources[i].start =
-                                       phys_to_dma(virt_to_phys(mem));
-                               gp_resources[i].end =
-                                       gp_resources[i].start + size - 1;
-                               total += size;
-                               pr_info("allocate resource %s at %08x "
-                                               "(%u bytes)\n",
-                                       gp_resources[i].name,
-                                       gp_resources[i].start, size);
-                       }
-               }
-       }
-
-       pr_info("Total Platform driver memory allocation: 0x%08x\n", total);
-
-       /* indicate resources that are platform I/O related */
-       for (i = 0; gp_resources[i].flags != 0; i++) {
-               if ((gp_resources[i].start != 0) &&
-                       ((gp_resources[i].flags & IORESOURCE_IO) != 0)) {
-                       pr_info("reserved platform resource %s at %08x\n",
-                               gp_resources[i].name, gp_resources[i].start);
-               }
-       }
-}
-
-/*
- *
- * PERSISTENT MEMORY (PMEM) CONFIGURATION
- *
- */
-static unsigned long pmemaddr __initdata;
-
-static int __init early_param_pmemaddr(char *p)
-{
-       pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0);
-       return 0;
-}
-early_param("pmemaddr", early_param_pmemaddr);
-
-static long pmemlen __initdata;
-
-static int __init early_param_pmemlen(char *p)
-{
-/* TODO: we can use this code when and if the bootloader ever changes this */
-#if 0
-       pmemlen = (unsigned long)simple_strtoul(p, NULL, 0);
-#else
-       pmemlen = 0x20000;
-#endif
-       return 0;
-}
-early_param("pmemlen", early_param_pmemlen);
-
-/*
- * Set up persistent memory. If we were given values, we patch the array of
- * resources. Otherwise, persistent memory may be allocated anywhere at all.
- */
-static void __init pmem_setup_resource(void)
-{
-       struct resource *resource;
-       resource = asic_resource_get("DiagPersistentMemory");
-
-       if (resource && pmemaddr && pmemlen) {
-               /* The address provided by bootloader is in kseg0. Convert to
-                * a bus address. */
-               resource->start = phys_to_dma(pmemaddr - 0x80000000);
-               resource->end = resource->start + pmemlen - 1;
-
-               pr_info("persistent memory: start=0x%x  end=0x%x\n",
-                       resource->start, resource->end);
-       }
-}
-
-/*
- *
- * RESOURCE ACCESS FUNCTIONS
- *
- */
-
-/**
- * asic_resource_get - retrieves parameters for a platform resource.
- * @name:      string to match resource
- *
- * Returns a pointer to a struct resource corresponding to the given name.
- *
- * CANNOT BE NAMED platform_resource_get, which would be the obvious choice,
- * as this function name is already declared
- */
-struct resource *asic_resource_get(const char *name)
-{
-       int i;
-
-       for (i = 0; gp_resources[i].flags != 0; i++) {
-               if (strcmp(gp_resources[i].name, name) == 0)
-                       return &gp_resources[i];
-       }
-
-       return NULL;
-}
-EXPORT_SYMBOL(asic_resource_get);
-
-/**
- * platform_release_memory - release pre-allocated memory
- * @ptr:       pointer to memory to release
- * @size:      size of resource
- *
- * This must only be called for memory allocated or reserved via the boot
- * memory allocator.
- */
-void platform_release_memory(void *ptr, int size)
-{
-       free_reserved_area(ptr, ptr + size, -1, NULL);
-}
-EXPORT_SYMBOL(platform_release_memory);
-
-/*
- *
- * FEATURE AVAILABILITY FUNCTIONS
- *
- */
-int platform_supports_dvr(void)
-{
-       return (platform_features & DVR_CAPABLE) != 0;
-}
-
-int platform_supports_ffs(void)
-{
-       return (platform_features & FFS_CAPABLE) != 0;
-}
-
-int platform_supports_pcie(void)
-{
-       return (platform_features & PCIE_CAPABLE) != 0;
-}
-
-int platform_supports_display(void)
-{
-       return (platform_features & DISPLAY_CAPABLE) != 0;
-}
diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c
deleted file mode 100644 (file)
index f44cd92..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
- * Copyright (C) 2001 Ralf Baechle
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- *  This program is free software; you can distribute 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 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.
- *
- * Routines for generic manipulation of the interrupts found on the PowerTV
- * platform.
- *
- * The interrupt controller is located in the South Bridge a PIIX4 device
- * with two internal 82C95 interrupt controllers.
- */
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/kernel.h>
-#include <linux/random.h>
-
-#include <asm/irq_cpu.h>
-#include <linux/io.h>
-#include <asm/irq_regs.h>
-#include <asm/setup.h>
-#include <asm/mips-boards/generic.h>
-
-#include <asm/mach-powertv/asic_regs.h>
-
-static DEFINE_RAW_SPINLOCK(asic_irq_lock);
-
-static inline int get_int(void)
-{
-       unsigned long flags;
-       int irq;
-
-       raw_spin_lock_irqsave(&asic_irq_lock, flags);
-
-       irq = (asic_read(int_int_scan) >> 4) - 1;
-
-       if (irq == 0 || irq >= NR_IRQS)
-               irq = -1;
-
-       raw_spin_unlock_irqrestore(&asic_irq_lock, flags);
-
-       return irq;
-}
-
-static void asic_irqdispatch(void)
-{
-       int irq;
-
-       irq = get_int();
-       if (irq < 0)
-               return;  /* interrupt has already been cleared */
-
-       do_IRQ(irq);
-}
-
-static inline int clz(unsigned long x)
-{
-       __asm__(
-       "       .set    push                                    \n"
-       "       .set    mips32                                  \n"
-       "       clz     %0, %1                                  \n"
-       "       .set    pop                                     \n"
-       : "=r" (x)
-       : "r" (x));
-
-       return x;
-}
-
-/*
- * Version of ffs that only looks at bits 12..15.
- */
-static inline unsigned int irq_ffs(unsigned int pending)
-{
-       return fls(pending) - 1 + CAUSEB_IP;
-}
-
-/*
- * TODO: check how it works under EIC mode.
- */
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-       int irq;
-
-       irq = irq_ffs(pending);
-
-       if (irq == CAUSEF_IP3)
-               asic_irqdispatch();
-       else if (irq >= 0)
-               do_IRQ(irq);
-       else
-               spurious_interrupt();
-}
-
-void __init arch_init_irq(void)
-{
-       int i;
-
-       asic_irq_init();
-
-       /*
-        * Initialize interrupt exception vectors.
-        */
-       if (cpu_has_veic || cpu_has_vint) {
-               int nvec = cpu_has_veic ? 64 : 8;
-               for (i = 0; i < nvec; i++)
-                       set_vi_handler(i, asic_irqdispatch);
-       }
-}
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
deleted file mode 100644 (file)
index 9344902..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Portions copyright (C) 2005-2009 Scientific Atlanta
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- * Modified from arch/mips/kernel/irq-rm7000.c:
- * Copyright (C) 2003 Ralf Baechle
- *
- * 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/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/irq.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-
-#include <asm/mach-powertv/asic_regs.h>
-
-static inline void unmask_asic_irq(struct irq_data *d)
-{
-       unsigned long enable_bit;
-       unsigned int irq = d->irq;
-
-       enable_bit = (1 << (irq & 0x1f));
-
-       switch (irq >> 5) {
-       case 0:
-               asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
-               break;
-       case 1:
-               asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
-               break;
-       case 2:
-               asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
-               break;
-       case 3:
-               asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
-               break;
-       default:
-               BUG();
-       }
-}
-
-static inline void mask_asic_irq(struct irq_data *d)
-{
-       unsigned long disable_mask;
-       unsigned int irq = d->irq;
-
-       disable_mask = ~(1 << (irq & 0x1f));
-
-       switch (irq >> 5) {
-       case 0:
-               asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
-               break;
-       case 1:
-               asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
-               break;
-       case 2:
-               asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
-               break;
-       case 3:
-               asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
-               break;
-       default:
-               BUG();
-       }
-}
-
-static struct irq_chip asic_irq_chip = {
-       .name = "ASIC Level",
-       .irq_mask = mask_asic_irq,
-       .irq_unmask = unmask_asic_irq,
-};
-
-void __init asic_irq_init(void)
-{
-       int i;
-
-       /* set priority to 0 */
-       write_c0_status(read_c0_status() & ~(0x0000fc00));
-
-       asic_write(0, ien_int_0);
-       asic_write(0, ien_int_1);
-       asic_write(0, ien_int_2);
-       asic_write(0, ien_int_3);
-
-       asic_write(0x0fffffff, int_level_3_3);
-       asic_write(0xffffffff, int_level_3_2);
-       asic_write(0xffffffff, int_level_3_1);
-       asic_write(0xffffffff, int_level_3_0);
-       asic_write(0xffffffff, int_level_2_3);
-       asic_write(0xffffffff, int_level_2_2);
-       asic_write(0xffffffff, int_level_2_1);
-       asic_write(0xffffffff, int_level_2_0);
-       asic_write(0xffffffff, int_level_1_3);
-       asic_write(0xffffffff, int_level_1_2);
-       asic_write(0xffffffff, int_level_1_1);
-       asic_write(0xffffffff, int_level_1_0);
-       asic_write(0xffffffff, int_level_0_3);
-       asic_write(0xffffffff, int_level_0_2);
-       asic_write(0xffffffff, int_level_0_1);
-       asic_write(0xffffffff, int_level_0_0);
-
-       asic_write(0xf, int_int_scan);
-
-       /*
-        * Initialize interrupt handlers.
-        */
-       for (i = 0; i < NR_IRQS; i++)
-               irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
-}
diff --git a/arch/mips/powertv/asic/prealloc-calliope.c b/arch/mips/powertv/asic/prealloc-calliope.c
deleted file mode 100644 (file)
index 98dc516..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Memory pre-allocations for Calliope boxes.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- */
-
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/mach-powertv/asic.h>
-#include "prealloc.h"
-
-/*
- * NON_DVR_CAPABLE CALLIOPE RESOURCES
- */
-struct resource non_dvr_calliope_resources[] __initdata =
-{
-       /*
-        * VIDEO / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~36.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26700000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        */
-       /* 6MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * DOCSIS Subsystem
-        */
-       /* 7MiB */
-       PREALLOC_DOCSIS("Docsis", 0x27500000, 0x27c00000-1, IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x26700000, 0x26700000+(14*1048576)-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer (don't need recording buffers)
-        */
-       /* 680KiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * AVFS: player HAL memory
-        */
-       /* 945K * 3 for playback */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * NAND Flash
-        */
-       /* 10KiB */
-       PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Synopsys GMAC Memory Region
-        */
-       /* 64KiB */
-       PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * TFTPBuffer
-        *
-        *  This buffer is used in some minimal configurations (e.g. two-way
-        *  loader) for storing software images
-        */
-       PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
-
-
-struct resource non_dvr_vze_calliope_resources[] __initdata =
-{
-       /*
-        * VIDEO / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x22000000, 0x22200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x22200000, 0x22202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (10.12MiB) */
-       PREALLOC_NORMAL("MediaMemory1", 0x22202000, 0x22C20B85-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (16KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (16KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        */
-       /* 3.125MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x20396000, 0x206B6000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (2.59MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x20100000, 0x20396000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x206B6000, 0x206D6000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer (don't need recording buffers)
-        */
-       /* 680KiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * NAND Flash
-        */
-       /* 10KiB */
-       PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Synopsys GMAC Memory Region
-        */
-       /* 64KiB */
-       PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
-
-struct resource non_dvr_vzf_calliope_resources[] __initdata =
-{
-       /*
-        * VIDEO / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~19.4 (21.5MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x25580000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        */
-       /* 4.5MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00480000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x25600000, 0x25600000+(14*1048576)-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer (don't need recording buffers)
-        */
-       /* 680KiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit1
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * AVFS: player HAL memory
-        */
-       /* 945K * 3 for playback */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * NAND Flash
-        */
-       /* 10KiB */
-       PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Synopsys GMAC Memory Region
-        */
-       /* 64KiB */
-       PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
diff --git a/arch/mips/powertv/asic/prealloc-cronus.c b/arch/mips/powertv/asic/prealloc-cronus.c
deleted file mode 100644 (file)
index 7c6ce75..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Memory pre-allocations for Cronus boxes.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- */
-
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/mach-powertv/asic.h>
-#include "prealloc.h"
-
-/*
- * DVR_CAPABLE CRONUS RESOURCES
- */
-struct resource dvr_cronus_resources[] __initdata =
-{
-       /*
-        * VIDEO1 / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * VIDEO2 / LX2
-        */
-       /* Delta-Mu 2 image (2MiB) */
-       PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 2 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        *
-        *  This memory area is used for allocating buffers for Video decoding
-        *  purposes.  Allocation/De-allocation within this buffer is managed
-        *  by the STAVMEM driver of the STAPI.  They could be Decimated
-        *  Picture Buffers, Intermediate Buffers, as deemed necessary for
-        *  video decoding purposes, for any video decoders on Zeus.
-        */
-       /* 12MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DOCSIS Subsystem
-        */
-       /* 7MiB */
-       PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer
-        */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x002EA000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit1
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * ITFS
-        */
-       /* 815,104 bytes each for 2 ITFS partitions. */
-       PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1, IORESOURCE_MEM)
-
-       /*
-        * AVFS
-        */
-       /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1,
-               IORESOURCE_MEM)
-
-       /* 4KiB */
-       PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
-               IORESOURCE_MEM)
-
-       /*
-        * KAVNET
-        */
-       /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */
-       PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1,
-               IORESOURCE_MEM)
-       /* NP Image - must be video bank 1 (320KiB) */
-       PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM)
-       /* NP IPC - must be video bank 2 (512KiB) */
-       PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM)
-
-       /*
-        * TFTPBuffer
-        *
-        *  This buffer is used in some minimal configurations (e.g. two-way
-        *  loader) for storing software images
-        */
-       PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
-
-/*
- * NON_DVR_CAPABLE CRONUS RESOURCES
- */
-struct resource non_dvr_cronus_resources[] __initdata =
-{
-       /*
-        * VIDEO1 / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * VIDEO2 / LX2
-        */
-       /* Delta-Mu 2 image (2MiB) */
-       PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 2 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        *
-        *  This memory area is used for allocating buffers for Video decoding
-        *  purposes.  Allocation/De-allocation within this buffer is managed
-        *  by the STAVMEM driver of the STAPI.  They could be Decimated
-        *  Picture Buffers, Intermediate Buffers, as deemed necessary for
-        *  video decoding purposes, for any video decoders on Zeus.
-        */
-       /* 12MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DOCSIS Subsystem
-        */
-       /* 7MiB */
-       PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer (don't need recording buffers)
-        */
-       /* 680KiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit1
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * AVFS: player HAL memory
-        */
-       /* 945K * 3 for playback */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, IORESOURCE_MEM)
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM)
-
-       /*
-        * KAVNET
-        */
-       /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */
-       PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1,
-               IORESOURCE_MEM)
-       /* NP Image - must be video bank 1 (320KiB) */
-       PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM)
-       /* NP IPC - must be video bank 2 (512KiB) */
-       PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM)
-
-       /*
-        * NAND Flash
-        */
-       /* 10KiB */
-       PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
diff --git a/arch/mips/powertv/asic/prealloc-cronuslite.c b/arch/mips/powertv/asic/prealloc-cronuslite.c
deleted file mode 100644 (file)
index a7937ba..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Memory pre-allocations for Cronus Lite boxes.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- */
-
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/mach-powertv/asic.h>
-#include "prealloc.h"
-
-/*
- * NON_DVR_CAPABLE CRONUSLITE RESOURCES
- */
-struct resource non_dvr_cronuslite_resources[] __initdata =
-{
-       /*
-        * VIDEO2 / LX2
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x60000000, 0x60200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x60200000, 0x60202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x60202000, 0x62000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (128KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        *
-        *  This memory area is used for allocating buffers for Video decoding
-        *  purposes.  Allocation/De-allocation within this buffer is managed
-        *  by the STAVMEM driver of the STAPI.  They could be Decimated
-        *  Picture Buffers, Intermediate Buffers, as deemed necessary for
-        *  video decoding purposes, for any video decoders on Zeus.
-        */
-       /* 6MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DOCSIS Subsystem
-        */
-       /* 7MiB */
-       PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer (don't need recording buffers)
-        */
-       /* 680KiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit1
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * AVFS: player HAL memory
-        */
-       /* 945K * 3 for playback */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM)
-
-       /*
-        * KAVNET
-        */
-       /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */
-       PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1,
-               IORESOURCE_MEM)
-       /* NP Image - must be video bank 1 (320KiB) */
-       PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM)
-       /* NP IPC - must be video bank 2 (512KiB) */
-       PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM)
-
-       /*
-        * NAND Flash
-        */
-       /* 10KiB */
-       PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
-               IORESOURCE_MEM)
-
-       /*
-        * TFTPBuffer
-        *
-        *  This buffer is used in some minimal configurations (e.g. two-way
-        *  loader) for storing software images
-        */
-       PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
diff --git a/arch/mips/powertv/asic/prealloc-gaia.c b/arch/mips/powertv/asic/prealloc-gaia.c
deleted file mode 100644 (file)
index 2303bbf..0000000
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Memory pre-allocations for Gaia boxes.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      David VomLehn
- */
-
-#include <linux/init.h>
-#include <asm/mach-powertv/asic.h>
-
-/*
- * DVR_CAPABLE GAIA RESOURCES
- */
-struct resource dvr_gaia_resources[] __initdata = {
-       /*
-        *
-        * VIDEO1 / LX1
-        *
-        */
-       {
-               .name   = "ST231aImage",        /* Delta-Mu 1 image and ram */
-               .start  = 0x24000000,
-               .end    = 0x241FFFFF,           /* 2MiB */
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ST231aMonitor",      /* 8KiB block ST231a monitor */
-               .start  = 0x24200000,
-               .end    = 0x24201FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "MediaMemory1",
-               .start  = 0x24202000,
-               .end    = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * VIDEO2 / LX2
-        *
-        */
-       {
-               .name   = "ST231bImage",        /* Delta-Mu 2 image and ram */
-               .start  = 0x60000000,
-               .end    = 0x601FFFFF,           /* 2MiB */
-               .flags  = IORESOURCE_IO,
-       },
-       {
-               .name   = "ST231bMonitor",      /* 8KiB block ST231b monitor */
-               .start  = 0x60200000,
-               .end    = 0x60201FFF,
-               .flags  = IORESOURCE_IO,
-       },
-       {
-               .name   = "MediaMemory2",
-               .start  = 0x60202000,
-               .end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * Sysaudio Driver
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  DSP_Image_Buff - DSP code and data images (1MB)
-        *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
-        *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
-        *  ADSC_Main_Buff - ADSC Main buffer (16KB)
-        *
-        */
-       {
-               .name   = "DSP_Image_Buff",
-               .start  = 0x00000000,
-               .end    = 0x000FFFFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ADSC_CPU_PCM_Buff",
-               .start  = 0x00000000,
-               .end    = 0x00009FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ADSC_AUX_Buff",
-               .start  = 0x00000000,
-               .end    = 0x00003FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ADSC_Main_Buff",
-               .start  = 0x00000000,
-               .end    = 0x00003FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * STAVEM driver/STAPI
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  This memory area is used for allocating buffers for Video decoding
-        *  purposes.  Allocation/De-allocation within this buffer is managed
-        *  by the STAVMEM driver of the STAPI.  They could be Decimated
-        *  Picture Buffers, Intermediate Buffers, as deemed necessary for
-        *  video decoding purposes, for any video decoders on Zeus.
-        *
-        */
-       {
-               .name   = "AVMEMPartition0",
-               .start  = 0x63580000,
-               .end    = 0x64180000 - 1,  /* 12 MB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * DOCSIS Subsystem
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "Docsis",
-               .start  = 0x62000000,
-               .end    = 0x62700000 - 1,       /* 7 MB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * GHW HAL Driver
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  GraphicsHeap - PowerTV Graphics Heap
-        *
-        */
-       {
-               .name   = "GraphicsHeap",
-               .start  = 0x62700000,
-               .end    = 0x63500000 - 1,       /* 14 MB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * multi com buffer area
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "MulticomSHM",
-               .start  = 0x26000000,
-               .end    = 0x26020000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * DMA Ring buffer
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "BMM_Buffer",
-               .start  = 0x00000000,
-               .end    = 0x00280000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * Display bins buffer for unit0
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Display Bins for unit0
-        *
-        */
-       {
-               .name   = "DisplayBins0",
-               .start  = 0x00000000,
-               .end    = 0x00000FFF,           /* 4 KB total */
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * Display bins buffer
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Display Bins for unit1
-        *
-        */
-       {
-               .name   = "DisplayBins1",
-               .start  = 0x64AD4000,
-               .end    = 0x64AD5000 - 1,  /* 4 KB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * ITFS
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "ITFS",
-               .start  = 0x64180000,
-               /* 815,104 bytes each for 2 ITFS partitions. */
-               .end    = 0x6430DFFF,
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * AVFS
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "AvfsDmaMem",
-               .start  = 0x6430E000,
-               /* (945K * 8) = (128K *3) 5 playbacks / 3 server */
-               .end    = 0x64AD0000 - 1,
-               .flags  = IORESOURCE_IO,
-       },
-       {
-               .name   = "AvfsFileSys",
-               .start  = 0x64AD0000,
-               .end    = 0x64AD1000 - 1,  /* 4K */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * Smartcard
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Read and write buffers for Internal/External cards
-        *
-        */
-       {
-               .name   = "SmartCardInfo",
-               .start  = 0x64AD1000,
-               .end    = 0x64AD3800 - 1,
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * KAVNET
-        *    NP Reset Vector - must be of the form xxCxxxxx
-        *         NP Image - must be video bank 1
-        *         NP IPC - must be video bank 2
-        */
-       {
-               .name   = "NP_Reset_Vector",
-               .start  = 0x27c00000,
-               .end    = 0x27c01000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "NP_Image",
-               .start  = 0x27020000,
-               .end    = 0x27060000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "NP_IPC",
-               .start  = 0x63500000,
-               .end    = 0x63580000 - 1,
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        * Add other resources here
-        */
-       { },
-};
-
-/*
- * NON_DVR_CAPABLE GAIA RESOURCES
- */
-struct resource non_dvr_gaia_resources[] __initdata = {
-       /*
-        *
-        * VIDEO1 / LX1
-        *
-        */
-       {
-               .name   = "ST231aImage",        /* Delta-Mu 1 image and ram */
-               .start  = 0x24000000,
-               .end    = 0x241FFFFF,           /* 2MiB */
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ST231aMonitor",      /* 8KiB block ST231a monitor */
-               .start  = 0x24200000,
-               .end    = 0x24201FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "MediaMemory1",
-               .start  = 0x24202000,
-               .end    = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * VIDEO2 / LX2
-        *
-        */
-       {
-               .name   = "ST231bImage",        /* Delta-Mu 2 image and ram */
-               .start  = 0x60000000,
-               .end    = 0x601FFFFF,           /* 2MiB */
-               .flags  = IORESOURCE_IO,
-       },
-       {
-               .name   = "ST231bMonitor",      /* 8KiB block ST231b monitor */
-               .start  = 0x60200000,
-               .end    = 0x60201FFF,
-               .flags  = IORESOURCE_IO,
-       },
-       {
-               .name   = "MediaMemory2",
-               .start  = 0x60202000,
-               .end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * Sysaudio Driver
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  DSP_Image_Buff - DSP code and data images (1MB)
-        *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
-        *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
-        *  ADSC_Main_Buff - ADSC Main buffer (16KB)
-        *
-        */
-       {
-               .name   = "DSP_Image_Buff",
-               .start  = 0x00000000,
-               .end    = 0x000FFFFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ADSC_CPU_PCM_Buff",
-               .start  = 0x00000000,
-               .end    = 0x00009FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ADSC_AUX_Buff",
-               .start  = 0x00000000,
-               .end    = 0x00003FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "ADSC_Main_Buff",
-               .start  = 0x00000000,
-               .end    = 0x00003FFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * STAVEM driver/STAPI
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  This memory area is used for allocating buffers for Video decoding
-        *  purposes.  Allocation/De-allocation within this buffer is managed
-        *  by the STAVMEM driver of the STAPI.  They could be Decimated
-        *  Picture Buffers, Intermediate Buffers, as deemed necessary for
-        *  video decoding purposes, for any video decoders on Zeus.
-        *
-        */
-       {
-               .name   = "AVMEMPartition0",
-               .start  = 0x63580000,
-               .end    = 0x64180000 - 1,  /* 12 MB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * DOCSIS Subsystem
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "Docsis",
-               .start  = 0x62000000,
-               .end    = 0x62700000 - 1,       /* 7 MB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * GHW HAL Driver
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  GraphicsHeap - PowerTV Graphics Heap
-        *
-        */
-       {
-               .name   = "GraphicsHeap",
-               .start  = 0x62700000,
-               .end    = 0x63500000 - 1,       /* 14 MB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * multi com buffer area
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "MulticomSHM",
-               .start  = 0x26000000,
-               .end    = 0x26020000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * DMA Ring buffer
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Docsis -
-        *
-        */
-       {
-               .name   = "BMM_Buffer",
-               .start  = 0x00000000,
-               .end    = 0x000AA000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * Display bins buffer for unit0
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Display Bins for unit0
-        *
-        */
-       {
-               .name   = "DisplayBins0",
-               .start  = 0x00000000,
-               .end    = 0x00000FFF,           /* 4 KB total */
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * Display bins buffer
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Display Bins for unit1
-        *
-        */
-       {
-               .name   = "DisplayBins1",
-               .start  = 0x64AD4000,
-               .end    = 0x64AD5000 - 1,  /* 4 KB total */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * AVFS: player HAL memory
-        *
-        *
-        */
-       {
-               .name   = "AvfsDmaMem",
-               .start  = 0x6430E000,
-               .end    = 0x645D2C00 - 1,  /* 945K * 3 for playback */
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * PMEM
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Persistent memory for diagnostics.
-        *
-        */
-       {
-               .name   = "DiagPersistentMemory",
-               .start  = 0x00000000,
-               .end    = 0x10000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       /*
-        *
-        * Smartcard
-        *
-        * This driver requires:
-        *
-        * Arbitrary Based Buffers:
-        *  Read and write buffers for Internal/External cards
-        *
-        */
-       {
-               .name   = "SmartCardInfo",
-               .start  = 0x64AD1000,
-               .end    = 0x64AD3800 - 1,
-               .flags  = IORESOURCE_IO,
-       },
-       /*
-        *
-        * KAVNET
-        *    NP Reset Vector - must be of the form xxCxxxxx
-        *         NP Image - must be video bank 1
-        *         NP IPC - must be video bank 2
-        */
-       {
-               .name   = "NP_Reset_Vector",
-               .start  = 0x27c00000,
-               .end    = 0x27c01000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "NP_Image",
-               .start  = 0x27020000,
-               .end    = 0x27060000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "NP_IPC",
-               .start  = 0x63500000,
-               .end    = 0x63580000 - 1,
-               .flags  = IORESOURCE_IO,
-       },
-       { },
-};
diff --git a/arch/mips/powertv/asic/prealloc-zeus.c b/arch/mips/powertv/asic/prealloc-zeus.c
deleted file mode 100644 (file)
index 6e76f09..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Memory pre-allocations for Zeus boxes.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- */
-
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/mach-powertv/asic.h>
-#include "prealloc.h"
-
-/*
- * DVR_CAPABLE RESOURCES
- */
-struct resource dvr_zeus_resources[] __initdata =
-{
-       /*
-        * VIDEO1 / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * VIDEO2 / LX2
-        */
-       /* Delta-Mu 2 image (2MiB) */
-       PREALLOC_NORMAL("ST231bImage", 0x30000000, 0x30200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 2 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231bMonitor", 0x30200000, 0x30202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory2", 0x30202000, 0x32000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (16KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (16KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        *
-        *  This memory area is used for allocating buffers for Video decoding
-        *  purposes.  Allocation/De-allocation within this buffer is managed
-        *  by the STAVMEM driver of the STAPI.  They could be Decimated
-        *  Picture Buffers, Intermediate Buffers, as deemed necessary for
-        *  video decoding purposes, for any video decoders on Zeus.
-        */
-       /* 12MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * DOCSIS Subsystem
-        */
-       /* 7MiB */
-       PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer
-        */
-       /* 2.5MiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit1
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * ITFS
-        */
-       /* 815,104 bytes each for 2 ITFS partitions. */
-       PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * AVFS
-        */
-       /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* 4KiB */
-       PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * TFTPBuffer
-        *
-        *  This buffer is used in some minimal configurations (e.g. two-way
-        *  loader) for storing software images
-        */
-       PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
-
-/*
- * NON_DVR_CAPABLE ZEUS RESOURCES
- */
-struct resource non_dvr_zeus_resources[] __initdata =
-{
-       /*
-        * VIDEO1 / LX1
-        */
-       /* Delta-Mu 1 image (2MiB) */
-       PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 monitor (8KiB) */
-       PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1,
-               IORESOURCE_MEM)
-       /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
-       PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * Sysaudio Driver
-        */
-       /* DSP code and data images (1MiB) */
-       PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC CPU PCM buffer (40KiB) */
-       PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC AUX buffer (16KiB) */
-       PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-       /* ADSC Main buffer (16KiB) */
-       PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * STAVEM driver/STAPI
-        */
-       /* 6MiB */
-       PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * DOCSIS Subsystem
-        */
-       /* 7MiB */
-       PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM)
-
-       /*
-        * GHW HAL Driver
-        */
-       /* PowerTV Graphics Heap (14MiB) */
-       PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * multi com buffer area
-        */
-       /* 128KiB */
-       PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1,
-               IORESOURCE_MEM)
-
-       /*
-        * DMA Ring buffer
-        */
-       /* 2.5MiB */
-       PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Display bins buffer for unit0
-        */
-       /* 4KiB */
-       PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * AVFS: player HAL memory
-        */
-       /* 945K * 3 for playback */
-       PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * PMEM
-        */
-       /* Persistent memory for diagnostics (64KiB) */
-       PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
-            (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Smartcard
-        */
-       /* Read and write buffers for Internal/External cards (10KiB) */
-       PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * NAND Flash
-        */
-       /* 10KiB */
-       PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
-               IORESOURCE_MEM)
-
-       /*
-        * TFTPBuffer
-        *
-        *  This buffer is used in some minimal configurations (e.g. two-way
-        *  loader) for storing software images
-        */
-       PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
-               (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
-
-       /*
-        * Add other resources here
-        */
-
-       /*
-        * End of Resource marker
-        */
-       {
-               .flags  = 0,
-       },
-};
diff --git a/arch/mips/powertv/asic/prealloc.h b/arch/mips/powertv/asic/prealloc.h
deleted file mode 100644 (file)
index 8e682df..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Definitions for memory preallocations
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H
-#define _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H
-
-#define KIBIBYTE(n) ((n) * 1024)    /* Number of kibibytes */
-#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
-
-/* "struct resource" array element definition */
-#define PREALLOC(NAME, START, END, FLAGS) {    \
-               .name = (NAME),                 \
-               .start = (START),               \
-               .end = (END),                   \
-               .flags = (FLAGS)                \
-       },
-
-/* Individual resources in the preallocated resource arrays are defined using
- *  macros.  These macros are conditionally defined based on their
- *  corresponding kernel configuration flag:
- *    - CONFIG_PREALLOC_NORMAL: preallocate resources for a normal settop box
- *    - CONFIG_PREALLOC_TFTP: preallocate the TFTP download resource
- *    - CONFIG_PREALLOC_DOCSIS: preallocate the DOCSIS resource
- *    - CONFIG_PREALLOC_PMEM: reserve space for persistent memory
- */
-#ifdef CONFIG_PREALLOC_NORMAL
-#define PREALLOC_NORMAL(name, start, end, flags) \
-   PREALLOC(name, start, end, flags)
-#else
-#define PREALLOC_NORMAL(name, start, end, flags)
-#endif
-
-#ifdef CONFIG_PREALLOC_TFTP
-#define PREALLOC_TFTP(name, start, end, flags) \
-   PREALLOC(name, start, end, flags)
-#else
-#define PREALLOC_TFTP(name, start, end, flags)
-#endif
-
-#ifdef CONFIG_PREALLOC_DOCSIS
-#define PREALLOC_DOCSIS(name, start, end, flags) \
-   PREALLOC(name, start, end, flags)
-#else
-#define PREALLOC_DOCSIS(name, start, end, flags)
-#endif
-
-#ifdef CONFIG_PREALLOC_PMEM
-#define PREALLOC_PMEM(name, start, end, flags) \
-   PREALLOC(name, start, end, flags)
-#else
-#define PREALLOC_PMEM(name, start, end, flags)
-#endif
-#endif
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
deleted file mode 100644 (file)
index 4989263..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 1999, 2000, 2004, 2005         MIPS Technologies, Inc.
- *     All rights reserved.
- *     Authors: Carsten Langgaard <carstenl@mips.com>
- *              Maciej W. Rozycki <macro@mips.com>
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- *  This program is free software; you can distribute 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 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.
- *
- * PROM library initialisation code.
- */
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-#include <asm/bootinfo.h>
-#include <linux/io.h>
-#include <asm/cacheflush.h>
-#include <asm/traps.h>
-
-#include <asm/mips-boards/generic.h>
-#include <asm/mach-powertv/asic.h>
-
-#include "init.h"
-
-static int *_prom_envp;
-unsigned long _prom_memsize;
-
-/*
- * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
- * This macro take care of sign extension, if running in 64-bit mode.
- */
-#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
-
-char *prom_getenv(char *envname)
-{
-       char *result = NULL;
-
-       if (_prom_envp != NULL) {
-               /*
-                * Return a pointer to the given environment variable.
-                * In 64-bit mode: we're using 64-bit pointers, but all pointers
-                * in the PROM structures are only 32-bit, so we need some
-                * workarounds, if we are running in 64-bit mode.
-                */
-               int i, index = 0;
-
-               i = strlen(envname);
-
-               while (prom_envp(index)) {
-                       if (strncmp(envname, prom_envp(index), i) == 0) {
-                               result = prom_envp(index + 1);
-                               break;
-                       }
-                       index += 2;
-               }
-       }
-
-       return result;
-}
-
-void __init prom_init(void)
-{
-       int prom_argc;
-       char *prom_argv;
-
-       prom_argc = fw_arg0;
-       prom_argv = (char *) fw_arg1;
-       _prom_envp = (int *) fw_arg2;
-       _prom_memsize = (unsigned long) fw_arg3;
-
-       if (prom_argc == 1) {
-               strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
-               strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE);
-       }
-
-       configure_platform();
-       prom_meminit();
-}
diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h
deleted file mode 100644 (file)
index c1a8bd0..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Definitions from powertv init.c file
- *
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Author: David VomLehn
- */
-
-#ifndef _POWERTV_INIT_H
-#define _POWERTV_INIT_H
-extern unsigned long _prom_memsize;
-extern void prom_meminit(void);
-extern char *prom_getenv(char *name);
-#endif
diff --git a/arch/mips/powertv/ioremap.c b/arch/mips/powertv/ioremap.c
deleted file mode 100644 (file)
index d060478..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *                     ioremap.c
- *
- * Support for mapping between dma_addr_t values a phys_addr_t values.
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      David VomLehn <dvomlehn@cisco.com>
- *
- * Description:         Defines the platform resources for the SA settop.
- *
- * NOTE: The bootloader allocates persistent memory at an address which is
- * 16 MiB below the end of the highest address in KSEG0. All fixed
- * address memory reservations must avoid this region.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/mach-powertv/ioremap.h>
-
-/*
- * Define the sizes of and masks for grains in physical and DMA space. The
- * values are the same but the types are not.
- */
-#define IOR_PHYS_GRAIN         ((phys_addr_t) 1 << IOR_LSBITS)
-#define IOR_PHYS_GRAIN_MASK    (IOR_PHYS_GRAIN - 1)
-
-#define IOR_DMA_GRAIN          ((dma_addr_t) 1 << IOR_LSBITS)
-#define IOR_DMA_GRAIN_MASK     (IOR_DMA_GRAIN - 1)
-
-/*
- * Values that, when accessed by an index derived from a phys_addr_t and
- * added to phys_addr_t value, yield a DMA address
- */
-struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
-EXPORT_SYMBOL(_ior_phys_to_dma);
-
-/*
- * Values that, when accessed by an index derived from a dma_addr_t and
- * added to that dma_addr_t value, yield a physical address
- */
-struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
-EXPORT_SYMBOL(_ior_dma_to_phys);
-
-/**
- * setup_dma_to_phys - set up conversion from DMA to physical addresses
- * @dma_idx:   Top IOR_LSBITS bits of the DMA address, i.e. an index
- *             into the array _dma_to_phys.
- * @delta:     Value that, when added to the DMA address, will yield the
- *             physical address
- * @s:         Number of bytes in the section of memory with the given delta
- *             between DMA and physical addresses.
- */
-static void setup_dma_to_phys(dma_addr_t dma, phys_addr_t delta, dma_addr_t s)
-{
-       int dma_idx, first_idx, last_idx;
-       phys_addr_t first, last;
-
-       /*
-        * Calculate the first and last indices, rounding the first up and
-        * the second down.
-        */
-       first = dma & ~IOR_DMA_GRAIN_MASK;
-       last = (dma + s - 1) & ~IOR_DMA_GRAIN_MASK;
-       first_idx = first >> IOR_LSBITS;                /* Convert to indices */
-       last_idx = last >> IOR_LSBITS;
-
-       for (dma_idx = first_idx; dma_idx <= last_idx; dma_idx++)
-               _ior_dma_to_phys[dma_idx].offset = delta >> IOR_DMA_SHIFT;
-}
-
-/**
- * setup_phys_to_dma - set up conversion from DMA to physical addresses
- * @phys_idx:  Top IOR_LSBITS bits of the DMA address, i.e. an index
- *             into the array _phys_to_dma.
- * @delta:     Value that, when added to the DMA address, will yield the
- *             physical address
- * @s:         Number of bytes in the section of memory with the given delta
- *             between DMA and physical addresses.
- */
-static void setup_phys_to_dma(phys_addr_t phys, dma_addr_t delta, phys_addr_t s)
-{
-       int phys_idx, first_idx, last_idx;
-       phys_addr_t first, last;
-
-       /*
-        * Calculate the first and last indices, rounding the first up and
-        * the second down.
-        */
-       first = phys & ~IOR_PHYS_GRAIN_MASK;
-       last = (phys + s - 1) & ~IOR_PHYS_GRAIN_MASK;
-       first_idx = first >> IOR_LSBITS;                /* Convert to indices */
-       last_idx = last >> IOR_LSBITS;
-
-       for (phys_idx = first_idx; phys_idx <= last_idx; phys_idx++)
-               _ior_phys_to_dma[phys_idx].offset = delta >> IOR_PHYS_SHIFT;
-}
-
-/**
- * ioremap_add_map - add to the physical and DMA address conversion arrays
- * @phys:      Process's view of the address of the start of the memory chunk
- * @dma:       DMA address of the start of the memory chunk
- * @size:      Size, in bytes, of the chunk of memory
- *
- * NOTE: It might be obvious, but the assumption is that all @size bytes have
- * the same offset between the physical address and the DMA address.
- */
-void ioremap_add_map(phys_addr_t phys, phys_addr_t dma, phys_addr_t size)
-{
-       if (size == 0)
-               return;
-
-       if ((dma & IOR_DMA_GRAIN_MASK) != 0 ||
-               (phys & IOR_PHYS_GRAIN_MASK) != 0 ||
-               (size & IOR_PHYS_GRAIN_MASK) != 0)
-               pr_crit("Memory allocation must be in chunks of 0x%x bytes\n",
-                       IOR_PHYS_GRAIN);
-
-       setup_dma_to_phys(dma, phys - dma, size);
-       setup_phys_to_dma(phys, dma - phys, size);
-}
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c
deleted file mode 100644 (file)
index bc2f3ca..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- *  This program is free software; you can distribute 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 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.
- *
- * Apparently originally from arch/mips/malta-memory.c. Modified to work
- * with the PowerTV bootloader.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/pfn.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/sections.h>
-
-#include <asm/mach-powertv/asic.h>
-#include <asm/mach-powertv/ioremap.h>
-
-#include "init.h"
-
-/* Memory constants */
-#define KIBIBYTE(n)            ((n) * 1024)    /* Number of kibibytes */
-#define MEBIBYTE(n)            ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
-#define DEFAULT_MEMSIZE                MEBIBYTE(128)   /* If no memsize provided */
-
-#define BLDR_SIZE      KIBIBYTE(256)           /* Memory reserved for bldr */
-#define RV_SIZE                MEBIBYTE(4)             /* Size of reset vector */
-
-#define LOW_MEM_END    0x20000000              /* Highest low memory address */
-#define BLDR_ALIAS     0x10000000              /* Bootloader address */
-#define RV_PHYS                0x1fc00000              /* Reset vector address */
-#define LOW_RAM_END    RV_PHYS                 /* End of real RAM in low mem */
-
-/*
- * Very low-level conversion from processor physical address to device
- * DMA address for the first bank of memory.
- */
-#define PHYS_TO_DMA(paddr)     ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS))
-
-unsigned long ptv_memsize;
-
-/*
- * struct low_mem_reserved - Items in low memory that are reserved
- * @start:     Physical address of item
- * @size:      Size, in bytes, of this item
- * @is_aliased: True if this is RAM aliased from another location. If false,
- *             it is something other than aliased RAM and the RAM in the
- *             unaliased address is still visible outside of low memory.
- */
-struct low_mem_reserved {
-       phys_addr_t     start;
-       phys_addr_t     size;
-       bool            is_aliased;
-};
-
-/*
- * Must be in ascending address order
- */
-struct low_mem_reserved low_mem_reserved[] = {
-       {BLDR_ALIAS, BLDR_SIZE, true},  /* Bootloader RAM */
-       {RV_PHYS, RV_SIZE, false},      /* Reset vector */
-};
-
-/*
- * struct mem_layout - layout of a piece of the system RAM
- * @phys:      Physical address of the start of this piece of RAM. This is the
- *             address at which both the processor and I/O devices see the
- *             RAM.
- * @alias:     Alias of this piece of memory in order to make it appear in
- *             the low memory part of the processor's address space. I/O
- *             devices don't see anything here.
- * @size:      Size, in bytes, of this piece of RAM
- */
-struct mem_layout {
-       phys_addr_t     phys;
-       phys_addr_t     alias;
-       phys_addr_t     size;
-};
-
-/*
- * struct mem_layout_list - list descriptor for layouts of system RAM pieces
- * @family:    Specifies the family being described
- * @n:         Number of &struct mem_layout elements
- * @layout:    Pointer to the list of &mem_layout structures
- */
-struct mem_layout_list {
-       enum family_type        family;
-       size_t                  n;
-       struct mem_layout       *layout;
-};
-
-static struct mem_layout f1500_layout[] = {
-       {0x20000000, 0x10000000, MEBIBYTE(256)},
-};
-
-static struct mem_layout f4500_layout[] = {
-       {0x40000000, 0x10000000, MEBIBYTE(256)},
-       {0x20000000, 0x20000000, MEBIBYTE(32)},
-};
-
-static struct mem_layout f8500_layout[] = {
-       {0x40000000, 0x10000000, MEBIBYTE(256)},
-       {0x20000000, 0x20000000, MEBIBYTE(32)},
-       {0x30000000, 0x30000000, MEBIBYTE(32)},
-};
-
-static struct mem_layout fx600_layout[] = {
-       {0x20000000, 0x10000000, MEBIBYTE(256)},
-       {0x60000000, 0x60000000, MEBIBYTE(128)},
-};
-
-static struct mem_layout_list layout_list[] = {
-       {FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout},
-       {FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout},
-       {FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout},
-       {FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout},
-       {FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout},
-       {FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout},
-       {FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout},
-       {FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout},
-       {FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout},
-       {FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout},
-};
-
-/* If we can't determine the layout, use this */
-static struct mem_layout default_layout[] = {
-       {0x20000000, 0x10000000, MEBIBYTE(128)},
-};
-
-/**
- * register_non_ram - register low memory not available for RAM usage
- */
-static __init void register_non_ram(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++)
-               add_memory_region(low_mem_reserved[i].start,
-                       low_mem_reserved[i].size, BOOT_MEM_RESERVED);
-}
-
-/**
- * get_memsize - get the size of memory as a single bank
- */
-static phys_addr_t get_memsize(void)
-{
-       static char cmdline[COMMAND_LINE_SIZE] __initdata;
-       phys_addr_t memsize = 0;
-       char *memsize_str;
-       char *ptr;
-
-       /* Check the command line first for a memsize directive */
-       strcpy(cmdline, arcs_cmdline);
-       ptr = strstr(cmdline, "memsize=");
-       if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
-               ptr = strstr(ptr, " memsize=");
-
-       if (ptr) {
-               memsize = memparse(ptr + 8, &ptr);
-       } else {
-               /* otherwise look in the environment */
-               memsize_str = prom_getenv("memsize");
-
-               if (memsize_str != NULL) {
-                       pr_info("prom memsize = %s\n", memsize_str);
-                       memsize = simple_strtol(memsize_str, NULL, 0);
-               }
-
-               if (memsize == 0) {
-                       if (_prom_memsize != 0) {
-                               memsize = _prom_memsize;
-                               pr_info("_prom_memsize = 0x%x\n", memsize);
-                               /* add in memory that the bootloader doesn't
-                                * report */
-                               memsize += BLDR_SIZE;
-                       } else {
-                               memsize = DEFAULT_MEMSIZE;
-                               pr_info("Memsize not passed by bootloader, "
-                                       "defaulting to 0x%x\n", memsize);
-                       }
-               }
-       }
-
-       return memsize;
-}
-
-/**
- * register_low_ram - register an aliased section of RAM
- * @p:         Alias address of memory
- * @n:         Number of bytes in this section of memory
- *
- * Returns the number of bytes registered
- *
- */
-static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n)
-{
-       phys_addr_t s;
-       int i;
-       phys_addr_t orig_n;
-
-       orig_n = n;
-
-       BUG_ON(p + n > RV_PHYS);
-
-       for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) {
-               phys_addr_t start;
-               phys_addr_t size;
-
-               start = low_mem_reserved[i].start;
-               size = low_mem_reserved[i].size;
-
-               /* Handle memory before this low memory section */
-               if (p < start) {
-                       phys_addr_t s;
-                       s = min(n, start - p);
-                       add_memory_region(p, s, BOOT_MEM_RAM);
-                       p += s;
-                       n -= s;
-               }
-
-               /* Handle the low memory section itself. If it's aliased,
-                * we reduce the number of byes left, but if not, the RAM
-                * is available elsewhere and we don't reduce the number of
-                * bytes remaining. */
-               if (p == start) {
-                       if (low_mem_reserved[i].is_aliased) {
-                               s = min(n, size);
-                               n -= s;
-                               p += s;
-                       } else
-                               p += n;
-               }
-       }
-
-       return orig_n - n;
-}
-
-/*
- * register_ram - register real RAM
- * @p: Address of memory as seen by devices
- * @alias:     If the memory is seen at an additional address by the processor,
- *             this will be the address, otherwise it is the same as @p.
- * @n:         Number of bytes in this section of memory
- */
-static __init void register_ram(phys_addr_t p, phys_addr_t alias,
-       phys_addr_t n)
-{
-       /*
-        * If some or all of this memory has an alias, break it into the
-        * aliased and non-aliased portion.
-        */
-       if (p != alias) {
-               phys_addr_t alias_size;
-               phys_addr_t registered;
-
-               alias_size = min(n, LOW_RAM_END - alias);
-               registered = register_low_ram(alias, alias_size);
-               ioremap_add_map(alias, p, n);
-               n -= registered;
-               p += registered;
-       }
-
-#ifdef CONFIG_HIGHMEM
-       if (n != 0) {
-               add_memory_region(p, n, BOOT_MEM_RAM);
-               ioremap_add_map(p, p, n);
-       }
-#endif
-}
-
-/**
- * register_address_space - register things in the address space
- * @memsize:   Number of bytes of RAM installed
- *
- * Takes the given number of bytes of RAM and registers as many of the regions,
- * or partial regions, as it can. So, the default configuration might have
- * two regions with 256 MiB each. If the memsize passed in on the command line
- * is 384 MiB, it will register the first region with 256 MiB and the second
- * with 128 MiB.
- */
-static __init void register_address_space(phys_addr_t memsize)
-{
-       int i;
-       phys_addr_t size;
-       size_t n;
-       struct mem_layout *layout;
-       enum family_type family;
-
-       /*
-        * Register all of the things that aren't available to the kernel as
-        * memory.
-        */
-       register_non_ram();
-
-       /* Find the appropriate memory description */
-       family = platform_get_family();
-
-       for (i = 0; i < ARRAY_SIZE(layout_list); i++) {
-               if (layout_list[i].family == family)
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(layout_list)) {
-               n = ARRAY_SIZE(default_layout);
-               layout = default_layout;
-       } else {
-               n = layout_list[i].n;
-               layout = layout_list[i].layout;
-       }
-
-       for (i = 0; memsize != 0 && i < n; i++) {
-               size = min(memsize, layout[i].size);
-               register_ram(layout[i].phys, layout[i].alias, size);
-               memsize -= size;
-       }
-}
-
-void __init prom_meminit(void)
-{
-       ptv_memsize = get_memsize();
-       register_address_space(ptv_memsize);
-}
-
-void __init prom_free_prom_memory(void)
-{
-       unsigned long addr;
-       int i;
-
-       for (i = 0; i < boot_mem_map.nr_map; i++) {
-               if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-                       continue;
-
-               addr = boot_mem_map.map[i].addr;
-               free_init_pages("prom memory",
-                               addr, addr + boot_mem_map.map[i].size);
-       }
-}
diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile
deleted file mode 100644 (file)
index 2610a6a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2009  Scientific-Atlanta, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-
-obj-$(CONFIG_PCI)      += fixup-powertv.o
diff --git a/arch/mips/powertv/pci/fixup-powertv.c b/arch/mips/powertv/pci/fixup-powertv.c
deleted file mode 100644 (file)
index d7ecbae..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/pci.h>
-#include <asm/mach-powertv/interrupts.h>
-#include "powertv-pci.h"
-
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       return asic_pcie_map_irq(dev, slot, pin);
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
-
-/*
- * asic_pcie_map_irq
- *
- * Parameters:
- * *dev - pointer to a pci_dev structure  (not used)
- * slot - slot number  (not used)
- * pin - pin number  (not used)
- *
- * Return Value:
- * Returns: IRQ number (always the PCI Express IRQ number)
- *
- * Description:
- * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt.
- *
- */
-int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       return irq_pciexp;
-}
-EXPORT_SYMBOL(asic_pcie_map_irq);
diff --git a/arch/mips/powertv/pci/powertv-pci.h b/arch/mips/powertv/pci/powertv-pci.h
deleted file mode 100644 (file)
index 1b5886b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *                             powertv-pci.c
- *
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-/*
- * Local definitions for the powertv PCI code
- */
-
-#ifndef _POWERTV_PCI_POWERTV_PCI_H_
-#define _POWERTV_PCI_POWERTV_PCI_H_
-extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
-extern int asic_pcie_init(void);
-extern int asic_pcie_init(void);
-
-extern int log_level;
-#endif
diff --git a/arch/mips/powertv/powertv-clock.h b/arch/mips/powertv/powertv-clock.h
deleted file mode 100644 (file)
index d94c543..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Author: David VomLehn
- */
-
-#ifndef _POWERTV_POWERTV_CLOCK_H
-#define _POWERTV_POWERTV_CLOCK_H
-extern int powertv_clockevent_init(void);
-extern void powertv_clocksource_init(void);
-extern unsigned int mips_get_pll_freq(void);
-#endif
diff --git a/arch/mips/powertv/powertv-usb.c b/arch/mips/powertv/powertv-usb.c
deleted file mode 100644 (file)
index d845eac..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- *                             powertv-usb.c
- *
- * Description:         ASIC-specific USB device setup and shutdown
- *
- * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
- * Copyright (C) 2009 Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author:      Ken Eppinett
- *              David Schleef <ds@schleef.org>
- *
- * NOTE: The bootloader allocates persistent memory at an address which is
- * 16 MiB below the end of the highest address in KSEG0. All fixed
- * address memory reservations must avoid this region.
- */
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <asm/mach-powertv/asic.h>
-#include <asm/mach-powertv/interrupts.h>
-
-/* misc_clk_ctl1 values */
-#define MCC1_30MHZ_POWERUP_SELECT      (1 << 14)
-#define MCC1_DIV9                      (1 << 13)
-#define MCC1_ETHMIPS_POWERUP_SELECT    (1 << 11)
-#define MCC1_USB_POWERUP_SELECT                (1 << 1)
-#define MCC1_CLOCK108_POWERUP_SELECT   (1 << 0)
-
-/* Possible values for clock select */
-#define MCC1_USB_CLOCK_HIGH_Z          (0 << 4)
-#define MCC1_USB_CLOCK_48MHZ           (1 << 4)
-#define MCC1_USB_CLOCK_24MHZ           (2 << 4)
-#define MCC1_USB_CLOCK_6MHZ            (3 << 4)
-
-#define MCC1_CONFIG    (MCC1_30MHZ_POWERUP_SELECT |            \
-                        MCC1_DIV9 |                            \
-                        MCC1_ETHMIPS_POWERUP_SELECT |          \
-                        MCC1_USB_POWERUP_SELECT |              \
-                        MCC1_CLOCK108_POWERUP_SELECT)
-
-/* misc_clk_ctl2 values */
-#define MCC2_GMII_GCLK_TO_PAD          (1 << 31)
-#define MCC2_ETHER125_0_CLOCK_SELECT   (1 << 29)
-#define MCC2_RMII_0_CLOCK_SELECT       (1 << 28)
-#define MCC2_GMII_TX0_CLOCK_SELECT     (1 << 27)
-#define MCC2_GMII_RX0_CLOCK_SELECT     (1 << 26)
-#define MCC2_ETHER125_1_CLOCK_SELECT   (1 << 24)
-#define MCC2_RMII_1_CLOCK_SELECT       (1 << 23)
-#define MCC2_GMII_TX1_CLOCK_SELECT     (1 << 22)
-#define MCC2_GMII_RX1_CLOCK_SELECT     (1 << 21)
-#define MCC2_ETHER125_2_CLOCK_SELECT   (1 << 19)
-#define MCC2_RMII_2_CLOCK_SELECT       (1 << 18)
-#define MCC2_GMII_TX2_CLOCK_SELECT     (1 << 17)
-#define MCC2_GMII_RX2_CLOCK_SELECT     (1 << 16)
-
-#define ETHER_CLK_CONFIG       (MCC2_GMII_GCLK_TO_PAD |        \
-                                MCC2_ETHER125_0_CLOCK_SELECT | \
-                                MCC2_RMII_0_CLOCK_SELECT |     \
-                                MCC2_GMII_TX0_CLOCK_SELECT |   \
-                                MCC2_GMII_RX0_CLOCK_SELECT |   \
-                                MCC2_ETHER125_1_CLOCK_SELECT | \
-                                MCC2_RMII_1_CLOCK_SELECT |     \
-                                MCC2_GMII_TX1_CLOCK_SELECT |   \
-                                MCC2_GMII_RX1_CLOCK_SELECT |   \
-                                MCC2_ETHER125_2_CLOCK_SELECT | \
-                                MCC2_RMII_2_CLOCK_SELECT |     \
-                                MCC2_GMII_TX2_CLOCK_SELECT |   \
-                                MCC2_GMII_RX2_CLOCK_SELECT)
-
-/* misc_clk_ctl2 definitions for Gaia */
-#define FSX4A_REF_SELECT               (1 << 16)
-#define FSX4B_REF_SELECT               (1 << 17)
-#define FSX4C_REF_SELECT               (1 << 18)
-#define DDR_PLL_REF_SELECT             (1 << 19)
-#define MIPS_PLL_REF_SELECT            (1 << 20)
-
-/* Definitions for the QAM frequency select register FS432X4A4_QAM_CTL */
-#define QAM_FS_SDIV_SHIFT              29
-#define QAM_FS_MD_SHIFT                        24
-#define QAM_FS_MD_MASK                 0x1f    /* Cut down to 5 bits */
-#define QAM_FS_PE_SHIFT                        8
-
-#define QAM_FS_DISABLE_DIVIDE_BY_3             (1 << 5)
-#define QAM_FS_ENABLE_PROGRAM                  (1 << 4)
-#define QAM_FS_ENABLE_OUTPUT                   (1 << 3)
-#define QAM_FS_SELECT_TEST_BYPASS              (1 << 2)
-#define QAM_FS_DISABLE_DIGITAL_STANDBY         (1 << 1)
-#define QAM_FS_CHOOSE_FS                       (1 << 0)
-
-/* Definitions for fs432x4a_ctl register */
-#define QAM_FS_NSDIV_54MHZ                     (1 << 2)
-
-/* Definitions for bcm1_usb2_ctl register */
-#define BCM1_USB2_CTL_BISTOK                           (1 << 11)
-#define BCM1_USB2_CTL_PORT2_SHIFT_JK                   (1 << 7)
-#define BCM1_USB2_CTL_PORT1_SHIFT_JK                   (1 << 6)
-#define BCM1_USB2_CTL_PORT2_FAST_EDGE                  (1 << 5)
-#define BCM1_USB2_CTL_PORT1_FAST_EDGE                  (1 << 4)
-#define BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH         (1 << 1)
-#define BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH    (1 << 0)
-
-/* Definitions for crt_spare register */
-#define CRT_SPARE_PORT2_SHIFT_JK                       (1 << 21)
-#define CRT_SPARE_PORT1_SHIFT_JK                       (1 << 20)
-#define CRT_SPARE_PORT2_FAST_EDGE                      (1 << 19)
-#define CRT_SPARE_PORT1_FAST_EDGE                      (1 << 18)
-#define CRT_SPARE_DIVIDE_BY_9_FROM_432                 (1 << 17)
-#define CRT_SPARE_USB_DIVIDE_BY_9                      (1 << 16)
-
-/* Definitions for usb2_stbus_obc register */
-#define USB_STBUS_OBC_STORE32_LOAD32                   0x3
-
-/* Definitions for usb2_stbus_mess_size register */
-#define USB2_STBUS_MESS_SIZE_2                         0x1     /* 2 packets */
-
-/* Definitions for usb2_stbus_chunk_size register */
-#define USB2_STBUS_CHUNK_SIZE_2                                0x1     /* 2 packets */
-
-/* Definitions for usb2_strap register */
-#define USB2_STRAP_HFREQ_SELECT                                0x1
-
-/*
- * USB Host Resource Definition
- */
-
-static struct resource ehci_resources[] = {
-       {
-               .parent = &asic_resource,
-               .start  = 0,
-               .end    = 0xff,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = irq_usbehci,
-               .end    = irq_usbehci,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 ehci_dmamask = 0xffffffffULL;
-
-static struct platform_device ehci_device = {
-       .name = "powertv-ehci",
-       .id = 0,
-       .num_resources = 2,
-       .resource = ehci_resources,
-       .dev = {
-               .dma_mask = &ehci_dmamask,
-               .coherent_dma_mask = 0xffffffff,
-       },
-};
-
-static struct resource ohci_resources[] = {
-       {
-               .parent = &asic_resource,
-               .start  = 0,
-               .end    = 0xff,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = irq_usbohci,
-               .end    = irq_usbohci,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 ohci_dmamask = 0xffffffffULL;
-
-static struct platform_device ohci_device = {
-       .name = "powertv-ohci",
-       .id = 0,
-       .num_resources = 2,
-       .resource = ohci_resources,
-       .dev = {
-               .dma_mask = &ohci_dmamask,
-               .coherent_dma_mask = 0xffffffff,
-       },
-};
-
-static unsigned usb_users;
-static DEFINE_SPINLOCK(usb_regs_lock);
-
-/*
- *
- * fs_update - set frequency synthesizer for USB
- * @pe_bits            Phase tap setting
- * @md_bits            Coarse selector bus for algorithm of phase tap
- * @sdiv_bits          Output divider setting
- * @disable_div_by_3   Either QAM_FS_DISABLE_DIVIDE_BY_3 or zero
- * @standby            Either QAM_FS_DISABLE_DIGITAL_STANDBY or zero
- *
- * QAM frequency selection code, which affects the frequency at which USB
- * runs. The frequency is calculated as:
- *                            2^15 * ndiv * Fin
- * Fout = ------------------------------------------------------------
- *       (sdiv * (ipe * (1 + md/32) - (ipe - 2^15)*(1 + (md + 1)/32)))
- * where:
- * Fin         54 MHz
- * ndiv                QAM_FS_NSDIV_54MHZ ? 8 : 16
- * sdiv                1 << (sdiv_bits + 1)
- * ipe         Same as pe_bits
- * md          A five-bit, two's-complement integer (range [-16, 15]), which
- *             is the lower 5 bits of md_bits.
- */
-static void fs_update(u32 pe_bits, int md_bits, u32 sdiv_bits,
-       u32 disable_div_by_3, u32 standby)
-{
-       u32 val;
-
-       val = ((sdiv_bits << QAM_FS_SDIV_SHIFT) |
-               ((md_bits & QAM_FS_MD_MASK) << QAM_FS_MD_SHIFT) |
-               (pe_bits << QAM_FS_PE_SHIFT) |
-               QAM_FS_ENABLE_OUTPUT |
-               standby |
-               disable_div_by_3);
-       asic_write(val, fs432x4b4_usb_ctl);
-       asic_write(val | QAM_FS_ENABLE_PROGRAM, fs432x4b4_usb_ctl);
-       asic_write(val | QAM_FS_ENABLE_PROGRAM | QAM_FS_CHOOSE_FS,
-               fs432x4b4_usb_ctl);
-}
-
-/*
- * usb_eye_configure - for optimizing the shape USB eye waveform
- * @set:       Bits to set in the register
- * @clear:     Bits to clear in the register; each bit with a one will
- *             be set in the register, zero bits will not be modified
- */
-static void usb_eye_configure(u32 set, u32 clear)
-{
-       u32 old;
-
-       old = asic_read(crt_spare);
-       old |= set;
-       old &= ~clear;
-       asic_write(old, crt_spare);
-}
-
-/*
- * platform_configure_usb - usb configuration based on platform type.
- */
-static void platform_configure_usb(void)
-{
-       u32 bcm1_usb2_ctl_value;
-       enum asic_type asic_type;
-       unsigned long flags;
-
-       spin_lock_irqsave(&usb_regs_lock, flags);
-       usb_users++;
-
-       if (usb_users != 1) {
-               spin_unlock_irqrestore(&usb_regs_lock, flags);
-               return;
-       }
-
-       asic_type = platform_get_asic();
-
-       switch (asic_type) {
-       case ASIC_ZEUS:
-               fs_update(0x0000, -15, 0x02, 0, 0);
-               bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
-                       BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
-               break;
-
-       case ASIC_CRONUS:
-       case ASIC_CRONUSLITE:
-               usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9);
-               fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
-                       QAM_FS_DISABLE_DIGITAL_STANDBY);
-               bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
-                       BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
-               break;
-
-       case ASIC_CALLIOPE:
-               fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3,
-                       QAM_FS_DISABLE_DIGITAL_STANDBY);
-
-               switch (platform_get_family()) {
-               case FAMILY_1500VZE:
-                       break;
-
-               case FAMILY_1500VZF:
-                       usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
-                               CRT_SPARE_PORT1_SHIFT_JK |
-                               CRT_SPARE_PORT2_FAST_EDGE |
-                               CRT_SPARE_PORT1_FAST_EDGE, 0);
-                       break;
-
-               default:
-                       usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
-                               CRT_SPARE_PORT1_SHIFT_JK, 0);
-                       break;
-               }
-
-               bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
-                       BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
-                       BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
-               break;
-
-       case ASIC_GAIA:
-               fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
-                       QAM_FS_DISABLE_DIGITAL_STANDBY);
-               bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
-                       BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
-                       BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
-               break;
-
-       default:
-               pr_err("Unknown ASIC type: %d\n", asic_type);
-               bcm1_usb2_ctl_value = 0;
-               break;
-       }
-
-       /* turn on USB power */
-       asic_write(0, usb2_strap);
-       /* Enable all OHCI interrupts */
-       asic_write(bcm1_usb2_ctl_value, usb2_control);
-       /* usb2_stbus_obc store32/load32 */
-       asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc);
-       /* usb2_stbus_mess_size 2 packets */
-       asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size);
-       /* usb2_stbus_chunk_size 2 packets */
-       asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size);
-       spin_unlock_irqrestore(&usb_regs_lock, flags);
-}
-
-static void platform_unconfigure_usb(void)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&usb_regs_lock, flags);
-       usb_users--;
-       if (usb_users == 0)
-               asic_write(USB2_STRAP_HFREQ_SELECT, usb2_strap);
-       spin_unlock_irqrestore(&usb_regs_lock, flags);
-}
-
-/*
- * Set up the USB EHCI interface
- */
-void platform_configure_usb_ehci()
-{
-       platform_configure_usb();
-}
-EXPORT_SYMBOL(platform_configure_usb_ehci);
-
-/*
- * Set up the USB OHCI interface
- */
-void platform_configure_usb_ohci()
-{
-       platform_configure_usb();
-}
-EXPORT_SYMBOL(platform_configure_usb_ohci);
-
-/*
- * Shut the USB EHCI interface down
- */
-void platform_unconfigure_usb_ehci()
-{
-       platform_unconfigure_usb();
-}
-EXPORT_SYMBOL(platform_unconfigure_usb_ehci);
-
-/*
- * Shut the USB OHCI interface down
- */
-void platform_unconfigure_usb_ohci()
-{
-       platform_unconfigure_usb();
-}
-EXPORT_SYMBOL(platform_unconfigure_usb_ohci);
-
-/**
- * platform_devices_init - sets up USB device resourse.
- */
-int __init platform_usb_devices_init(struct platform_device **ehci_dev,
-       struct platform_device **ohci_dev)
-{
-       *ehci_dev = &ehci_device;
-       ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
-       ehci_resources[0].end += ehci_resources[0].start;
-
-       *ohci_dev = &ohci_device;
-       ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
-       ohci_resources[0].end += ohci_resources[0].start;
-
-       return 0;
-}
diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c
deleted file mode 100644 (file)
index 24689bf..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/screen_info.h>
-#include <linux/notifier.h>
-#include <linux/etherdevice.h>
-#include <linux/if_ether.h>
-#include <linux/ctype.h>
-#include <linux/cpu.h>
-#include <linux/time.h>
-
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/dma.h>
-#include <asm/asm.h>
-#include <asm/traps.h>
-#include <asm/asm-offsets.h>
-#include "reset.h"
-
-#define VAL(n)         STR(n)
-
-/*
- * Macros for loading addresses and storing registers:
- * LONG_L_     Stringified version of LONG_L for use in asm() statement
- * LONG_S_     Stringified version of LONG_S for use in asm() statement
- * PTR_LA_     Stringified version of PTR_LA for use in asm() statement
- * REG_SIZE    Number of 8-bit bytes in a full width register
- */
-#define LONG_L_                VAL(LONG_L) " "
-#define LONG_S_                VAL(LONG_S) " "
-#define PTR_LA_                VAL(PTR_LA) " "
-
-#ifdef CONFIG_64BIT
-#warning TODO: 64-bit code needs to be verified
-#define REG_SIZE       "8"             /* In bytes */
-#endif
-
-#ifdef CONFIG_32BIT
-#define REG_SIZE       "4"             /* In bytes */
-#endif
-
-static void register_panic_notifier(void);
-static int panic_handler(struct notifier_block *notifier_block,
-       unsigned long event, void *cause_string);
-
-const char *get_system_type(void)
-{
-       return "PowerTV";
-}
-
-void __init plat_mem_setup(void)
-{
-       panic_on_oops = 1;
-       register_panic_notifier();
-
-#if 0
-       mips_pcibios_init();
-#endif
-       mips_reboot_setup();
-}
-
-/*
- * Install a panic notifier for platform-specific diagnostics
- */
-static void register_panic_notifier()
-{
-       static struct notifier_block panic_notifier = {
-               .notifier_call = panic_handler,
-               .next = NULL,
-               .priority       = INT_MAX
-       };
-       atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
-}
-
-static int panic_handler(struct notifier_block *notifier_block,
-       unsigned long event, void *cause_string)
-{
-       struct pt_regs  my_regs;
-
-       /* Save all of the registers */
-       {
-               unsigned long   at, v0, v1; /* Must be on the stack */
-
-               /* Start by saving $at and v0 on the stack. We use $at
-                * ourselves, but it looks like the compiler may use v0 or v1
-                * to load the address of the pt_regs structure. We'll come
-                * back later to store the registers in the pt_regs
-                * structure. */
-               __asm__ __volatile__ (
-                       ".set   noat\n"
-                       LONG_S_         "$at, %[at]\n"
-                       LONG_S_         "$2, %[v0]\n"
-                       LONG_S_         "$3, %[v1]\n"
-               :
-                       [at] "=m" (at),
-                       [v0] "=m" (v0),
-                       [v1] "=m" (v1)
-               :
-               :       "at"
-               );
-
-               __asm__ __volatile__ (
-                       ".set   noat\n"
-                       "move           $at, %[pt_regs]\n"
-
-                       /* Argument registers */
-                       LONG_S_         "$4, " VAL(PT_R4) "($at)\n"
-                       LONG_S_         "$5, " VAL(PT_R5) "($at)\n"
-                       LONG_S_         "$6, " VAL(PT_R6) "($at)\n"
-                       LONG_S_         "$7, " VAL(PT_R7) "($at)\n"
-
-                       /* Temporary regs */
-                       LONG_S_         "$8, " VAL(PT_R8) "($at)\n"
-                       LONG_S_         "$9, " VAL(PT_R9) "($at)\n"
-                       LONG_S_         "$10, " VAL(PT_R10) "($at)\n"
-                       LONG_S_         "$11, " VAL(PT_R11) "($at)\n"
-                       LONG_S_         "$12, " VAL(PT_R12) "($at)\n"
-                       LONG_S_         "$13, " VAL(PT_R13) "($at)\n"
-                       LONG_S_         "$14, " VAL(PT_R14) "($at)\n"
-                       LONG_S_         "$15, " VAL(PT_R15) "($at)\n"
-
-                       /* "Saved" registers */
-                       LONG_S_         "$16, " VAL(PT_R16) "($at)\n"
-                       LONG_S_         "$17, " VAL(PT_R17) "($at)\n"
-                       LONG_S_         "$18, " VAL(PT_R18) "($at)\n"
-                       LONG_S_         "$19, " VAL(PT_R19) "($at)\n"
-                       LONG_S_         "$20, " VAL(PT_R20) "($at)\n"
-                       LONG_S_         "$21, " VAL(PT_R21) "($at)\n"
-                       LONG_S_         "$22, " VAL(PT_R22) "($at)\n"
-                       LONG_S_         "$23, " VAL(PT_R23) "($at)\n"
-
-                       /* Add'l temp regs */
-                       LONG_S_         "$24, " VAL(PT_R24) "($at)\n"
-                       LONG_S_         "$25, " VAL(PT_R25) "($at)\n"
-
-                       /* Kernel temp regs */
-                       LONG_S_         "$26, " VAL(PT_R26) "($at)\n"
-                       LONG_S_         "$27, " VAL(PT_R27) "($at)\n"
-
-                       /* Global pointer, stack pointer, frame pointer and
-                        * return address */
-                       LONG_S_         "$gp, " VAL(PT_R28) "($at)\n"
-                       LONG_S_         "$sp, " VAL(PT_R29) "($at)\n"
-                       LONG_S_         "$fp, " VAL(PT_R30) "($at)\n"
-                       LONG_S_         "$ra, " VAL(PT_R31) "($at)\n"
-
-                       /* Now we can get the $at and v0 registers back and
-                        * store them */
-                       LONG_L_         "$8, %[at]\n"
-                       LONG_S_         "$8, " VAL(PT_R1) "($at)\n"
-                       LONG_L_         "$8, %[v0]\n"
-                       LONG_S_         "$8, " VAL(PT_R2) "($at)\n"
-                       LONG_L_         "$8, %[v1]\n"
-                       LONG_S_         "$8, " VAL(PT_R3) "($at)\n"
-               :
-               :
-                       [at] "m" (at),
-                       [v0] "m" (v0),
-                       [v1] "m" (v1),
-                       [pt_regs] "r" (&my_regs)
-               :       "at", "t0"
-               );
-
-               /* Set the current EPC value to be the current location in this
-                * function */
-               __asm__ __volatile__ (
-                       ".set   noat\n"
-               "1:\n"
-                       PTR_LA_         "$at, 1b\n"
-                       LONG_S_         "$at, %[cp0_epc]\n"
-               :
-                       [cp0_epc] "=m" (my_regs.cp0_epc)
-               :
-               :       "at"
-               );
-
-               my_regs.cp0_cause = read_c0_cause();
-               my_regs.cp0_status = read_c0_status();
-       }
-
-       pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
-               "zzzz... \n");
-
-       return NOTIFY_DONE;
-}
-
-/* Information about the RF MAC address, if one was supplied on the
- * command line. */
-static bool have_rfmac;
-static u8 rfmac[ETH_ALEN];
-
-static int rfmac_param(char *p)
-{
-       u8      *q;
-       bool    is_high_nibble;
-       int     c;
-
-       /* Skip a leading "0x", if present */
-       if (*p == '0' && *(p+1) == 'x')
-               p += 2;
-
-       q = rfmac;
-       is_high_nibble = true;
-
-       for (c = (unsigned char) *p++;
-               isxdigit(c) && q - rfmac < ETH_ALEN;
-               c = (unsigned char) *p++) {
-               int     nibble;
-
-               nibble = (isdigit(c) ? (c - '0') :
-                       (isupper(c) ? c - 'A' + 10 : c - 'a' + 10));
-
-               if (is_high_nibble)
-                       *q = nibble << 4;
-               else
-                       *q++ |= nibble;
-
-               is_high_nibble = !is_high_nibble;
-       }
-
-       /* If we parsed all the way to the end of the parameter value and
-        * parsed all ETH_ALEN bytes, we have a usable RF MAC address */
-       have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN);
-
-       return 0;
-}
-
-early_param("rfmac", rfmac_param);
-
-/*
- * Generate an Ethernet MAC address that has a good chance of being unique.
- * @addr:      Pointer to six-byte array containing the Ethernet address
- * Generates an Ethernet MAC address that is highly likely to be unique for
- * this particular system on a network with other systems of the same type.
- *
- * The problem we are solving is that, when eth_random_addr() is used to
- * generate MAC addresses at startup, there isn't much entropy for the random
- * number generator to use and the addresses it produces are fairly likely to
- * be the same as those of other identical systems on the same local network.
- * This is true even for relatively small numbers of systems (for the reason
- * why, see the Wikipedia entry for "Birthday problem" at:
- *     http://en.wikipedia.org/wiki/Birthday_problem
- *
- * The good news is that we already have a MAC address known to be unique, the
- * RF MAC address. The bad news is that this address is already in use on the
- * RF interface. Worse, the obvious trick, taking the RF MAC address and
- * turning on the locally managed bit, has already been used for other devices.
- * Still, this does give us something to work with.
- *
- * The approach we take is:
- * 1.  If we can't get the RF MAC Address, just call eth_random_addr.
- * 2.  Use the 24-bit NIC-specific bits of the RF MAC address as the last 24
- *     bits of the new address. This is very likely to be unique, except for
- *     the current box.
- * 3.  To avoid using addresses already on the current box, we set the top
- *     six bits of the address with a value different from any currently
- *     registered Scientific Atlanta organizationally unique identifyer
- *     (OUI). This avoids duplication with any addresses on the system that
- *     were generated from valid Scientific Atlanta-registered address by
- *     simply flipping the locally managed bit.
- * 4.  We aren't generating a multicast address, so we leave the multicast
- *     bit off. Since we aren't using a registered address, we have to set
- *     the locally managed bit.
- * 5.  We then randomly generate the remaining 16-bits. This does two
- *     things:
- *     a.      It allows us to call this function for more than one device
- *             in this system
- *     b.      It ensures that things will probably still work even if
- *             some device on the device network has a locally managed
- *             address that matches the top six bits from step 2.
- */
-void platform_random_ether_addr(u8 addr[ETH_ALEN])
-{
-       const int num_random_bytes = 2;
-       const unsigned char non_sciatl_oui_bits = 0xc0u;
-       const unsigned char mac_addr_locally_managed = (1 << 1);
-
-       if (!have_rfmac) {
-               pr_warning("rfmac not available on command line; "
-                       "generating random MAC address\n");
-               eth_random_addr(addr);
-       }
-
-       else {
-               int     i;
-
-               /* Set the first byte to something that won't match a Scientific
-                * Atlanta OUI, is locally managed, and isn't a multicast
-                * address */
-               addr[0] = non_sciatl_oui_bits | mac_addr_locally_managed;
-
-               /* Get some bytes of random address information */
-               get_random_bytes(&addr[1], num_random_bytes);
-
-               /* Copy over the NIC-specific bits of the RF MAC address */
-               for (i = 1 + num_random_bytes; i < ETH_ALEN; i++)
-                       addr[i] = rfmac[i];
-       }
-}
diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c
deleted file mode 100644 (file)
index 11c32fb..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/pm.h>
-
-#include <linux/io.h>
-#include <asm/reboot.h>                        /* Not included by linux/reboot.h */
-
-#include <asm/mach-powertv/asic_regs.h>
-#include "reset.h"
-
-static void mips_machine_restart(char *command)
-{
-       writel(0x1, asic_reg_addr(watchdog));
-}
-
-void mips_reboot_setup(void)
-{
-       _machine_restart = mips_machine_restart;
-}
diff --git a/arch/mips/powertv/reset.h b/arch/mips/powertv/reset.h
deleted file mode 100644 (file)
index 888fd09..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Definitions from powertv reset.c file
- *
- * Copyright (C) 2009  Cisco Systems, 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; 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Author: David VomLehn
- */
-
-#ifndef _POWERTV_POWERTV_RESET_H
-#define _POWERTV_POWERTV_RESET_H
-extern void mips_reboot_setup(void);
-#endif
diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c
deleted file mode 100644 (file)
index f38b0d4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- * Portions copyright (C) 2009 Cisco Systems, Inc.
- *
- *  This program is free software; you can distribute 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 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.
- *
- * Setting up the clock on the MIPS boards.
- */
-
-#include <linux/init.h>
-#include <asm/mach-powertv/interrupts.h>
-#include <asm/time.h>
-
-#include "powertv-clock.h"
-
-unsigned int get_c0_compare_int(void)
-{
-       return irq_mips_timer;
-}
-
-void __init plat_time_init(void)
-{
-       powertv_clocksource_init();
-}
index bba0cdfd83bcd37b2278dce3fdec6f8980bfbb19..5d0983d47161c183033b9943eada1edb93b797a3 100644 (file)
@@ -26,7 +26,7 @@ void ralink_clk_add(const char *dev, unsigned long rate)
        struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
 
        if (!clk)
-               panic("failed to add clock\n");
+               panic("failed to add clock");
 
        clk->cl.dev_id = dev;
        clk->cl.clk = clk;
index d217509e530093f0154783c32f8b016ff419f8a4..a3ad56c2372d0fcd261a1ff9dfea333a528f601f 100644 (file)
@@ -350,7 +350,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
                name = "MT7620A";
                soc_info->compatible = "ralink,mt7620a-soc";
        } else {
-               panic("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+               panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1);
        }
 
        rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
index ce38d11f9da5bdb3baaec1821dec2a6a25ae4836..15f21ea96121023b60d005045a3115bac48c5622 100644 (file)
@@ -108,7 +108,7 @@ static int __init plat_of_setup(void)
        strncpy(of_ids[1].compatible, "palmbus", len);
 
        if (of_platform_populate(NULL, of_ids, NULL, NULL))
-               panic("failed to populate DT\n");
+               panic("failed to populate DT");
 
        /* make sure ithat the reset controller is setup early */
        ralink_rst_init();
index ca7ee3a33790fc074ed4788f8fb1e1412babe187..bb82a82da9e70736160bb911a432477b3a81fdfe 100644 (file)
@@ -276,7 +276,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
                name = "RT5350";
                soc_info->compatible = "ralink,rt5350-soc";
        } else {
-               panic("rt305x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+               panic("rt305x: unknown SoC, n0:%08x n1:%08x", n0, n1);
        }
 
        id = __raw_readl(sysc + SYSC_REG_CHIP_ID);
index e49241a2c39a3b4d359f8d77eb6063f26ea89be0..202785709441c0a704b7cf1110e151834e9219c3 100644 (file)
@@ -126,7 +126,7 @@ static int rt_timer_probe(struct platform_device *pdev)
                return -ENOENT;
        }
 
-       rt->membase = devm_request_and_ioremap(&pdev->dev, res);
+       rt->membase = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(rt->membase))
                return PTR_ERR(rt->membase);
 
index ad2ce8dab9963c4dd6867ee83064460576084089..7dcde539d61e08b0bc586aa220b19ed31654c89c 100644 (file)
@@ -287,6 +287,9 @@ config SYSVIPC_COMPAT
        def_bool y
        depends on COMPAT && SYSVIPC
 
+config AUDIT_ARCH
+       def_bool y
+
 config HPUX
        bool "Support for HP-UX binaries"
        depends on !64BIT
index e02f665f804a53ae73761fa3546880150eff766f..7187664034c3499b92c62210d0d347b22ae24adc 100644 (file)
@@ -94,7 +94,7 @@ PALOCONF := $(shell if [ -f $(src)/palo.conf ]; then echo $(src)/palo.conf; \
        else echo $(obj)/palo.conf; \
        fi)
 
-palo: vmlinuz
+palo lifimage: vmlinuz
        @if test ! -x "$(PALO)"; then \
                echo 'ERROR: Please install palo first (apt-get install palo)';\
                echo 'or build it from source and install it somewhere in your $$PATH';\
@@ -109,16 +109,23 @@ palo: vmlinuz
        fi
        $(PALO) -f $(PALOCONF)
 
-# Shorthands for known targets not supported by parisc, use vmlinux/vmlinuz as default
+BOOT_TARGETS    = zImage Image palo lifimage
+INSTALL_TARGETS = zinstall install
+
+PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
+
+bzImage zImage: vmlinuz
 Image: vmlinux
-zImage bzImage: vmlinuz
 
 vmlinuz: vmlinux
        @gzip -cf -9 $< > $@
 
-install: vmlinuz
-       sh $(src)/arch/parisc/install.sh \
-                       $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
+install:
+       $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \
+                       $(KERNELRELEASE) vmlinux System.map "$(INSTALL_PATH)"
+zinstall:
+       $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \
+                       $(KERNELRELEASE) vmlinuz System.map "$(INSTALL_PATH)"
 
 CLEAN_FILES    += lifimage
 MRPROPER_FILES += palo.conf
@@ -127,10 +134,11 @@ define archhelp
        @echo  '* vmlinux       - Uncompressed kernel image (./vmlinux)'
        @echo  '  vmlinuz       - Compressed kernel image (./vmlinuz)'
        @echo  '  palo          - Bootable image (./lifimage)'
-       @echo  '  install       - Install kernel using'
+       @echo  '  install       - Install uncompressed vmlinux kernel using'
        @echo  '                  (your) ~/bin/$(INSTALLKERNEL) or'
        @echo  '                  (distribution) /sbin/$(INSTALLKERNEL) or'
        @echo  '                  copy to $$(INSTALL_PATH)'
+       @echo  '  zinstall      - Install compressed vmlinuz kernel'
 endef
 
 # we require gcc 3.3 or above to compile the kernel
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig
new file mode 100644 (file)
index 0000000..33b148f
--- /dev/null
@@ -0,0 +1,328 @@
+CONFIG_LOCALVERSION="-32bit"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PA7100LC=y
+CONFIG_SMP=y
+CONFIG_HZ_100=y
+CONFIG_IOMMU_CCIO=y
+CONFIG_GSC_LASI=y
+CONFIG_GSC_WAX=y
+CONFIG_EISA=y
+CONFIG_PCI=y
+CONFIG_GSC_DINO=y
+CONFIG_PCI_LBA=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
+# CONFIG_PDC_CHASSIS is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+# 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=m
+CONFIG_LLC2=m
+# 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_PARPORT=y
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_1284=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_NS87415=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_LASI700=y
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_ZALON=y
+CONFIG_SCSI_DH=y
+CONFIG_ATA=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_TUN=m
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+CONFIG_NET_TULIP=y
+CONFIG_TULIP=y
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_LASI_82596=y
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_POLLDEV=y
+CONFIG_KEYBOARD_HIL_OLD=m
+CONFIG_KEYBOARD_HIL=m
+CONFIG_MOUSE_SERIAL=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_LEGACY_PTY_COUNT=64
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_PRINTER=m
+CONFIG_PPDEV=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_HWMON is not set
+CONFIG_AGP=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_VOODOO1=m
+CONFIG_DUMMY_CONSOLE_COLUMNS=128
+CONFIG_DUMMY_CONSOLE_ROWS=48
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_AD1889=m
+CONFIG_SND_HARMONY=m
+CONFIG_HIDRAW=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_LOGITECH_DJ=m
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_DMADEVICES=y
+CONFIG_AUXDISPLAY=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_RT=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V2=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_NFS_FS=m
+# CONFIG_NFS_V2 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_CIFS=m
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_RT_MUTEX_TESTER=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_RCU_CPU_STALL_INFO=y
+CONFIG_LATENCYTOP=y
+CONFIG_LKDTM=m
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_FONTS=y
diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig
new file mode 100644 (file)
index 0000000..5874ceb
--- /dev/null
@@ -0,0 +1,346 @@
+CONFIG_LOCALVERSION="-64bit"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+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
+CONFIG_HPPB=y
+CONFIG_IOMMU_CCIO=y
+CONFIG_GSC_LASI=y
+CONFIG_GSC_WAX=y
+CONFIG_PCI=y
+CONFIG_PCI_STUB=m
+CONFIG_PCI_IOV=y
+CONFIG_GSC_DINO=y
+CONFIG_PCI_LBA=y
+CONFIG_BINFMT_MISC=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=m
+CONFIG_INET_DIAG=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_DCB=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_IDE=y
+CONFIG_IDE_GD=m
+CONFIG_IDE_GD_ATAPI=y
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_NS87415=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_SCSI_ISCSI_ATTRS=y
+CONFIG_SCSI_SRP_ATTRS=y
+CONFIG_ISCSI_BOOT_SYSFS=y
+CONFIG_SCSI_MPT2SAS=y
+CONFIG_SCSI_LASI700=m
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_ZALON=y
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_DH=y
+CONFIG_ATA=y
+CONFIG_ATA_GENERIC=y
+CONFIG_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_RAID=m
+CONFIG_DM_UEVENT=y
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_SAS=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_TUN=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+CONFIG_NET_TULIP=y
+CONFIG_TULIP=y
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+CONFIG_HP100=m
+CONFIG_E1000=y
+CONFIG_LASI_82596=y
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+CONFIG_QLA3XXX=m
+CONFIG_QLCNIC=m
+CONFIG_QLGE=m
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_NATIONAL_PHY=m
+CONFIG_STE10XP=m
+CONFIG_LSI_ET1011C_PHY=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_HIL_OLD is not set
+# CONFIG_KEYBOARD_HIL is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_HP_SDC is not set
+CONFIG_SERIO_RAW=m
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_NOZOMI=m
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_JSM=m
+CONFIG_IPMI_HANDLER=y
+CONFIG_IPMI_DEVICE_INTERFACE=y
+CONFIG_IPMI_SI=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_TCG_TPM=m
+CONFIG_TCG_ATMEL=m
+CONFIG_PTP_1588_CLOCK=m
+CONFIG_SENSORS_I5K_AMB=m
+CONFIG_SENSORS_F71882FG=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_WATCHDOG=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_SSB=m
+CONFIG_SSB_DRIVER_PCICORE=y
+CONFIG_HTC_PASIC3=m
+CONFIG_LPC_SCH=m
+CONFIG_MFD_SM501=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=m
+CONFIG_REGULATOR_USERSPACE_CONSUMER=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_AGP=y
+CONFIG_AGP_PARISC=y
+CONFIG_DRM=y
+CONFIG_DRM_RADEON=y
+CONFIG_DRM_RADEON_UMS=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+CONFIG_HID=m
+CONFIG_HIDRAW=y
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_KYE=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_HID_NTRIG=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB_HID=m
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_MON=m
+CONFIG_USB_WUSB_CBAF=m
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+CONFIG_STAGING=y
+# CONFIG_NET_VENDOR_SILICOM is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V2=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_ISO9660_FS=y
+CONFIG_UDF_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_SYSV_FS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V4=m
+CONFIG_NFS_V4_1=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=m
+CONFIG_LIBCRC32C=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
index 0da848232344fc41d9583cc10f8510a54a7d6a16..b3069fd83468c5972f98d19f8f17dfa9bfb5e0cf 100644 (file)
        nop     /* 7 */
        .endm
 
+       /*
+        * ASM_EXCEPTIONTABLE_ENTRY
+        *
+        * Creates an exception table entry.
+        * Do not convert to a assembler macro. This won't work.
+        */
+#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr)      \
+       .section __ex_table,"aw"                        !       \
+       ASM_ULONG_INSN  fault_addr, except_addr         !       \
+       .previous
+
+
 #endif /* __ASSEMBLY__ */
 #endif
index 912ee7e6a579fb6dbf04fd848a96b0e24c8cb07d..08e58e679e3e4e7c0bc19237c3ed944574cdd24e 100644 (file)
@@ -1,15 +1,5 @@
-#ifndef _PARISC_DELAY_H
-#define _PARISC_DELAY_H
-
-#include <asm/special_insns.h>    /* for mfctl() */
-#include <asm/processor.h> /* for boot_cpu_data */
-
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines
- */
+#ifndef _ASM_PARISC_DELAY_H
+#define _ASM_PARISC_DELAY_H
 
 static __inline__ void __delay(unsigned long loops) {
        asm volatile(
@@ -19,25 +9,14 @@ static __inline__ void __delay(unsigned long loops) {
                : "=r" (loops) : "0" (loops));
 }
 
-static __inline__ void __cr16_delay(unsigned long clocks) {
-       unsigned long start;
-
-       /*
-        * Note: Due to unsigned math, cr16 rollovers shouldn't be
-        * a problem here. However, on 32 bit, we need to make sure
-        * we don't pass in too big a value. The current default
-        * value of MAX_UDELAY_MS should help prevent this.
-        */
+extern void __udelay(unsigned long usecs);
+extern void __udelay_bad(unsigned long usecs);
 
-       start = mfctl(16);
-       while ((mfctl(16) - start) < clocks)
-           ;
+static inline void udelay(unsigned long usecs)
+{
+       if (__builtin_constant_p(usecs) && (usecs) > 20000)
+               __udelay_bad(usecs);
+       __udelay(usecs);
 }
 
-static __inline__ void __udelay(unsigned long usecs) {
-       __cr16_delay(usecs * ((unsigned long)boot_cpu_data.cpu_hz / 1000000UL));
-}
-
-#define udelay(n) __udelay(n)
-
-#endif /* defined(_PARISC_DELAY_H) */
+#endif /* _ASM_PARISC_DELAY_H */
index 241c34518465d9404f56b786a86554a1e89824a3..9b3bd039a609d57663cbe3374d5863a95415cac3 100644 (file)
@@ -21,7 +21,6 @@ typedef struct {
        unsigned int irq_stack_usage;
 #ifdef CONFIG_SMP
        unsigned int irq_resched_count;
-       unsigned int irq_call_count;
 #endif
        unsigned int irq_unaligned_count;
        unsigned int irq_fpassist_count;
index a2db278a5def69c4a6ac4745c3685e45600df156..3c3cb004b7e225344c9850805cce04192655e7d2 100644 (file)
@@ -19,5 +19,9 @@
 #define user_stack_pointer(regs)       ((regs)->gr[30])
 unsigned long profile_pc(struct pt_regs *);
 
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+       return regs->gr[20];
+}
 
 #endif
index 540c88fa8f863d44adcc254fe9a3917cf015aa4d..bc7cf120106b30e477264850e373f346eeb9bf82 100644 (file)
@@ -59,6 +59,7 @@ struct thread_info {
 #define TIF_32BIT               4       /* 32 bit binary */
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    6       /* restore saved signal mask */
+#define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
 #define TIF_NOTIFY_RESUME      8       /* callback before returning to user */
 #define TIF_SINGLESTEP         9       /* single stepping? */
 #define TIF_BLOCKSTEP          10      /* branch stepping? */
@@ -68,6 +69,7 @@ struct thread_info {
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_32BIT             (1 << TIF_32BIT)
+#define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
@@ -75,7 +77,7 @@ struct thread_info {
 #define _TIF_USER_WORK_MASK     (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
                                  _TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP |        \
-                                _TIF_BLOCKSTEP)
+                                _TIF_BLOCKSTEP | _TIF_SYSCALL_AUDIT)
 
 #endif /* __KERNEL__ */
 
index e0a82358517e032677cd563ae7aad33e37fef11f..63f4dd0b49c29c758807b68bbf9b7bf9b71911c3 100644 (file)
@@ -4,11 +4,14 @@
 /*
  * User space memory access functions
  */
+#include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/cache.h>
 #include <asm/errno.h>
 #include <asm-generic/uaccess-unaligned.h>
 
+#include <linux/sched.h>
+
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
 
@@ -33,12 +36,43 @@ extern int __get_user_bad(void);
 extern int __put_kernel_bad(void);
 extern int __put_user_bad(void);
 
-static inline long access_ok(int type, const void __user * addr,
-               unsigned long size)
+
+/*
+ * Test whether a block of memory is a valid user space address.
+ * Returns 0 if the range is valid, nonzero otherwise.
+ */
+static inline int __range_not_ok(unsigned long addr, unsigned long size,
+                                unsigned long limit)
 {
-       return 1;
+       unsigned long __newaddr = addr + size;
+       return (__newaddr < addr || __newaddr > limit || size > limit);
 }
 
+/**
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
+ *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ *        to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block may be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * Note that, depending on architecture, this function probably just
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
+#define access_ok(type, addr, size)                                    \
+(      __chk_user_ptr(addr),                                           \
+       !__range_not_ok((unsigned long) (__force void *) (addr),        \
+                       size, user_addr_max())                          \
+)
+
 #define put_user __put_user
 #define get_user __get_user
 
@@ -59,12 +93,13 @@ static inline long access_ok(int type, const void __user * addr,
 /*
  * The exception table contains two values: the first is an address
  * for an instruction that is allowed to fault, and the second is
- * the address to the fixup routine. 
+ * the address to the fixup routine. Even on a 64bit kernel we could
+ * use a 32bit (unsigned int) address here.
  */
 
 struct exception_table_entry {
-       unsigned long insn;  /* address of insn that is allowed to fault.   */
-       long fixup;          /* fixup routine */
+       unsigned long insn;     /* address of insn that is allowed to fault. */
+       unsigned long fixup;    /* fixup routine */
 };
 
 #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
@@ -218,7 +253,11 @@ extern long lstrnlen_user(const char __user *,long);
 /*
  * Complex access routines -- macros
  */
-#define user_addr_max() (~0UL)
+#ifdef CONFIG_COMPAT
+#define user_addr_max() (TASK_SIZE)
+#else
+#define user_addr_max() (DEFAULT_TASK_SIZE)
+#endif
 
 #define strnlen_user lstrnlen_user
 #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
index 4da682b466d06fd0806b4b3fd515f02fbacd4009..6f68784fea25f9141b195db9ec7b532f3f01da9c 100644 (file)
 #   $4 - default install path (blank if root directory)
 #
 
+verify () {
+       if [ ! -f "$1" ]; then
+               echo ""                                                   1>&2
+               echo " *** Missing file: $1"                              1>&2
+               echo ' *** You need to run "make" before "make install".' 1>&2
+               echo ""                                                   1>&2
+               exit 1
+       fi
+}
+
+# Make sure the files actually exist
+
+verify "$2"
+verify "$3"
+
 # User may have a custom install script
 
-if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
-if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
+if [ -n "${INSTALLKERNEL}" ]; then
+  if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
+  if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
+fi
 
 # Default install
 
-if [ -f $4/vmlinuz ]; then
-       mv $4/vmlinuz $4/vmlinuz.old
+if [ "$(basename $2)" = "zImage" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  base=vmlinuz
+else
+# Normal install
+  echo "Installing normal kernel"
+  base=vmlinux
+fi
+
+if [ -f $4/$base-$1 ]; then
+  mv $4/$base-$1 $4/$base-$1.old
 fi
+cat $2 > $4/$base-$1
 
-if [ -f $4/System.map ]; then
-       mv $4/System.map $4/System.old
+# Install system map file
+if [ -f $4/System.map-$1 ]; then
+  mv $4/System.map-$1 $4/System.map-$1.old
 fi
+cp $3 $4/System.map-$1
 
-cat $2 > $4/vmlinuz
-cp $3 $4/System.map
index 66ee3f12df5880db00852baad257c9ad895d11a4..ff87b4603e3dc7d2b60caa2a0047e3eada177397 100644 (file)
@@ -29,7 +29,9 @@ obj-$(CONFIG_PCI)     += pci.o
 obj-$(CONFIG_MODULES)  += module.o
 obj-$(CONFIG_64BIT)    += binfmt_elf32.o sys_parisc32.o signal32.o
 obj-$(CONFIG_STACKTRACE)+= stacktrace.o
+obj-$(CONFIG_AUDIT)    += audit.o
+obj64-$(CONFIG_AUDIT)  += compat_audit.o
 # only supported for PCX-W/U in 64-bit mode at the moment
-obj-$(CONFIG_64BIT)    += perf.o perf_asm.o
+obj-$(CONFIG_64BIT)    += perf.o perf_asm.o $(obj64-y)
 obj-$(CONFIG_FUNCTION_TRACER)          += ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)    += ftrace.o
diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c
new file mode 100644 (file)
index 0000000..eb64a61
--- /dev/null
@@ -0,0 +1,81 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_COMPAT
+       if (arch == AUDIT_ARCH_PARISC)
+               return 1;
+#endif
+       return 0;
+}
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_COMPAT
+       extern int parisc32_classify_syscall(unsigned);
+       if (abi == AUDIT_ARCH_PARISC)
+               return parisc32_classify_syscall(syscall);
+#endif
+       switch (syscall) {
+       case __NR_open:
+               return 2;
+       case __NR_openat:
+               return 3;
+       case __NR_execve:
+               return 5;
+       default:
+               return 0;
+       }
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_COMPAT
+       extern __u32 parisc32_dir_class[];
+       extern __u32 parisc32_write_class[];
+       extern __u32 parisc32_read_class[];
+       extern __u32 parisc32_chattr_class[];
+       extern __u32 parisc32_signal_class[];
+       audit_register_class(AUDIT_CLASS_WRITE_32, parisc32_write_class);
+       audit_register_class(AUDIT_CLASS_READ_32, parisc32_read_class);
+       audit_register_class(AUDIT_CLASS_DIR_WRITE_32, parisc32_dir_class);
+       audit_register_class(AUDIT_CLASS_CHATTR_32, parisc32_chattr_class);
+       audit_register_class(AUDIT_CLASS_SIGNAL_32, parisc32_signal_class);
+#endif
+       audit_register_class(AUDIT_CLASS_WRITE, write_class);
+       audit_register_class(AUDIT_CLASS_READ, read_class);
+       audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+       audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+       audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
+       return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/parisc/kernel/compat_audit.c b/arch/parisc/kernel/compat_audit.c
new file mode 100644 (file)
index 0000000..c74478f
--- /dev/null
@@ -0,0 +1,40 @@
+#include <asm/unistd.h>
+
+unsigned int parisc32_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned int parisc32_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned int parisc32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned int parisc32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+unsigned int parisc32_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int parisc32_classify_syscall(unsigned syscall)
+{
+       switch (syscall) {
+       case __NR_open:
+               return 2;
+       case __NR_openat:
+               return 3;
+       case __NR_execve:
+               return 5;
+       default:
+               return 1;
+       }
+}
index 2e6443b1e9228426ba94d8602c8956c5daec93c2..8ceac4785609279079e321384ec8e6b59a2b4cc7 100644 (file)
@@ -179,10 +179,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
        seq_puts(p, "  Rescheduling interrupts\n");
-       seq_printf(p, "%*s: ", prec, "CAL");
-       for_each_online_cpu(j)
-               seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
-       seq_puts(p, "  Function call interrupts\n");
 #endif
        seq_printf(p, "%*s: ", prec, "UAH");
        for_each_online_cpu(j)
@@ -499,22 +495,9 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
        *irq_stack_in_use = 1;
 }
 
-asmlinkage void do_softirq(void)
+void do_softirq_own_stack(void)
 {
-       __u32 pending;
-       unsigned long flags;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       pending = local_softirq_pending();
-
-       if (pending)
-               execute_on_irq_stack(__do_softirq, 0);
-
-       local_irq_restore(flags);
+       execute_on_irq_stack(__do_softirq, 0);
 }
 #endif /* CONFIG_IRQSTACKS */
 
index 534abd4936e1ecf96a8f872d9ba90f930c1aff9e..e842ee233db44ef902899280fbadd456175a4de3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/security.h>
 #include <linux/compat.h>
 #include <linux/signal.h>
+#include <linux/audit.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -267,11 +268,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 long do_syscall_trace_enter(struct pt_regs *regs)
 {
+       long ret = 0;
+
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
            tracehook_report_syscall_entry(regs))
-               return -1L;
-
-       return regs->gr[20];
+               ret = -1L;
+
+#ifdef CONFIG_64BIT
+       if (!is_compat_task())
+               audit_syscall_entry(AUDIT_ARCH_PARISC64,
+                       regs->gr[20],
+                       regs->gr[26], regs->gr[25],
+                       regs->gr[24], regs->gr[23]);
+       else
+#endif
+               audit_syscall_entry(AUDIT_ARCH_PARISC,
+                       regs->gr[20] & 0xffffffff,
+                       regs->gr[26] & 0xffffffff,
+                       regs->gr[25] & 0xffffffff,
+                       regs->gr[24] & 0xffffffff,
+                       regs->gr[23] & 0xffffffff);
+
+       return ret ? : regs->gr[20];
 }
 
 void do_syscall_trace_exit(struct pt_regs *regs)
@@ -279,6 +297,8 @@ void do_syscall_trace_exit(struct pt_regs *regs)
        int stepping = test_thread_flag(TIF_SINGLESTEP) ||
                test_thread_flag(TIF_BLOCKSTEP);
 
+       audit_syscall_exit(regs);
+
        if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
                tracehook_report_syscall_exit(regs, stepping);
 }
index 7349a3fedfc7644631d153427cef5bb2f69712ff..72a3c658ad7bdbc3a0429f4c85f1d890b914e38c 100644 (file)
@@ -318,8 +318,12 @@ static int __init parisc_init(void)
        pdc_stable_write(0x40, &osid, sizeof(osid));
        
        processor_init();
-       printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
-                       num_present_cpus(),
+#ifdef CONFIG_SMP
+       pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n",
+               num_online_cpus(), num_present_cpus(),
+#else
+       pr_info("CPU(s): 1 x %s at %d.%06d MHz\n",
+#endif
                        boot_cpu_data.cpu_name,
                        boot_cpu_data.cpu_hz / 1000000,
                        boot_cpu_data.cpu_hz % 1000000  );
index 2b96602e812ff9648f0ce9ec66b52e103ddb8a3e..ceda229ea6c2ef60cee170db5d6efe58f0df801b 100644 (file)
@@ -125,11 +125,6 @@ ipi_interrupt(int irq, void *dev_id)
        unsigned long ops;
        unsigned long flags;
 
-       /* Count this now; we may make a call that never returns. */
-       inc_irq_stat(irq_call_count);
-
-       mb();   /* Order interrupt and bit testing. */
-
        for (;;) {
                spinlock_t *lock = &per_cpu(ipi_lock, this_cpu);
                spin_lock_irqsave(lock, flags);
index e767ab733e321e5619b919a9b8684ac70c35ba9b..a63bb179f79a1fcd56a7bcf1adbe759f46587b71 100644 (file)
@@ -649,10 +649,8 @@ cas_action:
        /* Two exception table entries, one for the load,
           the other for the store. Either return -EFAULT.
           Each of the entries must be relocated. */
-       .section __ex_table,"aw"
-       ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page)
-       ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page)
-       .previous
+       ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page)
+       ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page)
 
 
        /* Make sure nothing else is placed on this page */
index 5651536ac733929b44efe69d131562eab125b215..8fa92b8d839abb98efb59bb4ac7689a40aeaf602 100644 (file)
@@ -3,6 +3,6 @@
 #
 
 lib-y  := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \
-          ucmpdi2.o
+          ucmpdi2.o delay.o
 
 obj-y  := iomap.o
diff --git a/arch/parisc/lib/delay.c b/arch/parisc/lib/delay.c
new file mode 100644 (file)
index 0000000..ec9255f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *     Precise Delay Loops for parisc
+ *
+ *     based on code by:
+ *     Copyright (C) 1993 Linus Torvalds
+ *     Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *     Copyright (C) 2008 Jiri Hladky <hladky _dot_ jiri _at_ gmail _dot_ com>
+ *
+ *     parisc implementation:
+ *     Copyright (C) 2013 Helge Deller <deller@gmx.de>
+ */
+
+
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/init.h>
+
+#include <asm/processor.h>
+#include <asm/delay.h>
+
+#include <asm/special_insns.h>    /* for mfctl() */
+#include <asm/processor.h> /* for boot_cpu_data */
+
+/* CR16 based delay: */
+static void __cr16_delay(unsigned long __loops)
+{
+       /*
+        * Note: Due to unsigned math, cr16 rollovers shouldn't be
+        * a problem here. However, on 32 bit, we need to make sure
+        * we don't pass in too big a value. The current default
+        * value of MAX_UDELAY_MS should help prevent this.
+        */
+       u32 bclock, now, loops = __loops;
+       int cpu;
+
+       preempt_disable();
+       cpu = smp_processor_id();
+       bclock = mfctl(16);
+       for (;;) {
+               now = mfctl(16);
+               if ((now - bclock) >= loops)
+                       break;
+
+               /* Allow RT tasks to run */
+               preempt_enable();
+               asm volatile("  nop\n");
+               barrier();
+               preempt_disable();
+
+               /*
+                * It is possible that we moved to another CPU, and
+                * since CR16's are per-cpu we need to calculate
+                * that. The delay must guarantee that we wait "at
+                * least" the amount of time. Being moved to another
+                * CPU could make the wait longer but we just need to
+                * make sure we waited long enough. Rebalance the
+                * counter for this CPU.
+                */
+               if (unlikely(cpu != smp_processor_id())) {
+                       loops -= (now - bclock);
+                       cpu = smp_processor_id();
+                       bclock = mfctl(16);
+               }
+       }
+       preempt_enable();
+}
+
+
+void __udelay(unsigned long usecs)
+{
+       __cr16_delay(usecs * ((unsigned long)boot_cpu_data.cpu_hz / 1000000UL));
+}
+EXPORT_SYMBOL(__udelay);
index 6f2d9355efe25af6ab90d4205a216c1c649c39a9..a512f07d4feba9bc2dd36f2f1d2f96ee26734348 100644 (file)
@@ -88,9 +88,7 @@ ENDPROC(lclear_user)
        ldo        1(%r25),%r25
        .previous
 
-       .section __ex_table,"aw"
-       ASM_ULONG_INSN 1b,2b
-       .previous
+       ASM_EXCEPTIONTABLE_ENTRY(1b,2b)
 
        .procend
 
@@ -129,10 +127,8 @@ ENDPROC(lstrnlen_user)
        copy        %r24,%r26    /* reset r26 so 0 is returned on fault */
        .previous
 
-       .section __ex_table,"aw"
-       ASM_ULONG_INSN 1b,3b
-       ASM_ULONG_INSN 2b,3b
-       .previous
+       ASM_EXCEPTIONTABLE_ENTRY(1b,3b)
+       ASM_EXCEPTIONTABLE_ENTRY(2b,3b)
 
        .procend
 
index ce76f6dfa25b0995424c31363580771a1f8a3746..7a51f97e72e690042fcdfbd2195507d2a3459194 100644 (file)
@@ -484,7 +484,6 @@ typedef int VOID;
  * |                                                     |G|L|E|U|X|
  * +-------+-------+-------+-------+-------+-------+-------+-------+
  */
-#define Allexception(object) (object)
 #define Greaterthanbit(object) Bitfield_extract( 27, 1,object)
 #define Lessthanbit(object) Bitfield_extract( 28, 1,object)
 #define Equalbit(object) Bitfield_extract( 29, 1,object)
index 0293588d5b8cb8e2d594406c51bbb524b319888b..7584a5df0fa4a76f5e2815fac25a38436a587955 100644 (file)
@@ -142,6 +142,12 @@ int fixup_exception(struct pt_regs *regs)
 {
        const struct exception_table_entry *fix;
 
+       /* If we only stored 32bit addresses in the exception table we can drop
+        * out if we faulted on a 64bit address. */
+       if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn))
+               && (regs->iaoq[0] >> 32))
+                       return 0;
+
        fix = search_exception_tables(regs->iaoq[0]);
        if (fix) {
                struct exception_data *d;
@@ -274,12 +280,22 @@ bad_area:
                }
                show_regs(regs);
 #endif
-               /* FIXME: actually we need to get the signo and code correct */
-               si.si_signo = SIGSEGV;
+               switch (code) {
+               case 15:        /* Data TLB miss fault/Data page fault */
+               case 17:        /* NA data TLB miss / page fault */
+               case 18:        /* Unaligned access - PCXS only */
+                       si.si_signo = SIGBUS;
+                       si.si_code = BUS_ADRERR;
+                       break;
+               case 16:        /* Non-access instruction TLB miss fault */
+               case 26:        /* PCXL: Data memory access rights trap */
+               default:
+                       si.si_signo = SIGSEGV;
+                       si.si_code = SEGV_MAPERR;
+               }
                si.si_errno = 0;
-               si.si_code = SEGV_MAPERR;
                si.si_addr = (void __user *) address;
-               force_sig_info(SIGSEGV, &si, current);
+               force_sig_info(si.si_signo, &si, current);
                return;
        }
 
index 38f3b7e47ec5efd190018de0d9bba1d2ef5b4011..b365d5cbb722ce9ef712a6066695a409f9e0c627 100644 (file)
@@ -138,6 +138,7 @@ config PPC
        select OLD_SIGSUSPEND
        select OLD_SIGACTION if PPC32
        select HAVE_DEBUG_STACKOVERFLOW
+       select HAVE_IRQ_EXIT_ON_IRQ_STACK
 
 config EARLY_PRINTK
        bool
index 23016020915e765edd720d315a0480d139e25ffd..75c6ecdb8f3728a175bd61808cad34a9689fd47e 100644 (file)
@@ -37,6 +37,7 @@ typedef ppc_opcode_t uprobe_opcode_t;
 struct arch_uprobe {
        union {
                u8      insn[MAX_UINSN_BYTES];
+               u8      ixol[MAX_UINSN_BYTES];
                u32     ainsn;
        };
 };
@@ -45,11 +46,4 @@ struct arch_uprobe_task {
        unsigned long   saved_trap_nr;
 };
 
-extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
-extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
-extern int  arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
-extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs);
 #endif /* _ASM_UPROBES_H */
index 16a7c2326d48d217b3f163777f3cfc473bb02fe1..1114d13ac19f6ec5e0294a2d197e2db3ec8e6814 100644 (file)
@@ -292,6 +292,7 @@ out:
                return rc;
        return count;
 }
+static BUS_ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe);
 
 static ssize_t ibmebus_store_remove(struct bus_type *bus,
                                    const char *buf, size_t count)
@@ -317,13 +318,14 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
                return -ENODEV;
        }
 }
+static BUS_ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove);
 
-
-static struct bus_attribute ibmebus_bus_attrs[] = {
-       __ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe),
-       __ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove),
-       __ATTR_NULL
+static struct attribute *ibmbus_bus_attrs[] = {
+       &bus_attr_probe.attr,
+       &bus_attr_remove.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(ibmbus_bus);
 
 static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv)
 {
@@ -713,7 +715,7 @@ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = {
 struct bus_type ibmebus_bus_type = {
        .name      = "ibmebus",
        .uevent    = of_device_uevent_modalias,
-       .bus_attrs = ibmebus_bus_attrs,
+       .bus_groups = ibmbus_bus_groups,
        .match     = ibmebus_bus_bus_match,
        .probe     = ibmebus_bus_device_probe,
        .remove    = ibmebus_bus_device_remove,
index c7cb8c232d2f4fdedf9129ec691d8471736e2fc7..ba0165615215577be84a8a576283a5fd6df12e51 100644 (file)
@@ -594,7 +594,7 @@ void irq_ctx_init(void)
        }
 }
 
-static inline void do_softirq_onstack(void)
+void do_softirq_own_stack(void)
 {
        struct thread_info *curtp, *irqtp;
 
@@ -612,21 +612,6 @@ static inline void do_softirq_onstack(void)
                set_bits(irqtp->flags, &curtp->flags);
 }
 
-void do_softirq(void)
-{
-       unsigned long flags;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       if (local_softirq_pending())
-               do_softirq_onstack();
-
-       local_irq_restore(flags);
-}
-
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
        struct irq_data *irq_data = irq_get_irq_data(virq);
index d38cc08b16c7f23831e3af558bfe35908e14af47..408956fbf4f617b67a284e9bd19f22c2fb86abd4 100644 (file)
@@ -997,21 +997,36 @@ static struct device_attribute vio_cmo_dev_attrs[] = {
 /* sysfs bus functions and data structures for CMO */
 
 #define viobus_cmo_rd_attr(name)                                        \
-static ssize_t                                                          \
-viobus_cmo_##name##_show(struct bus_type *bt, char *buf)                \
+static ssize_t cmo_##name##_show(struct bus_type *bt, char *buf)        \
 {                                                                       \
        return sprintf(buf, "%lu\n", vio_cmo.name);                     \
-}
+}                                                                       \
+static BUS_ATTR_RO(cmo_##name)
 
 #define viobus_cmo_pool_rd_attr(name, var)                              \
 static ssize_t                                                          \
-viobus_cmo_##name##_pool_show_##var(struct bus_type *bt, char *buf)     \
+cmo_##name##_##var##_show(struct bus_type *bt, char *buf)               \
 {                                                                       \
        return sprintf(buf, "%lu\n", vio_cmo.name.var);                 \
+}                                                                       \
+static BUS_ATTR_RO(cmo_##name##_##var)
+
+viobus_cmo_rd_attr(entitled);
+viobus_cmo_rd_attr(spare);
+viobus_cmo_rd_attr(min);
+viobus_cmo_rd_attr(desired);
+viobus_cmo_rd_attr(curr);
+viobus_cmo_pool_rd_attr(reserve, size);
+viobus_cmo_pool_rd_attr(excess, size);
+viobus_cmo_pool_rd_attr(excess, free);
+
+static ssize_t cmo_high_show(struct bus_type *bt, char *buf)
+{
+       return sprintf(buf, "%lu\n", vio_cmo.high);
 }
 
-static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf,
-                                     size_t count)
+static ssize_t cmo_high_store(struct bus_type *bt, const char *buf,
+                             size_t count)
 {
        unsigned long flags;
 
@@ -1021,35 +1036,26 @@ static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf,
 
        return count;
 }
-
-viobus_cmo_rd_attr(entitled);
-viobus_cmo_pool_rd_attr(reserve, size);
-viobus_cmo_pool_rd_attr(excess, size);
-viobus_cmo_pool_rd_attr(excess, free);
-viobus_cmo_rd_attr(spare);
-viobus_cmo_rd_attr(min);
-viobus_cmo_rd_attr(desired);
-viobus_cmo_rd_attr(curr);
-viobus_cmo_rd_attr(high);
-
-static struct bus_attribute vio_cmo_bus_attrs[] = {
-       __ATTR(cmo_entitled, S_IRUGO, viobus_cmo_entitled_show, NULL),
-       __ATTR(cmo_reserve_size, S_IRUGO, viobus_cmo_reserve_pool_show_size, NULL),
-       __ATTR(cmo_excess_size, S_IRUGO, viobus_cmo_excess_pool_show_size, NULL),
-       __ATTR(cmo_excess_free, S_IRUGO, viobus_cmo_excess_pool_show_free, NULL),
-       __ATTR(cmo_spare,   S_IRUGO, viobus_cmo_spare_show,   NULL),
-       __ATTR(cmo_min,     S_IRUGO, viobus_cmo_min_show,     NULL),
-       __ATTR(cmo_desired, S_IRUGO, viobus_cmo_desired_show, NULL),
-       __ATTR(cmo_curr,    S_IRUGO, viobus_cmo_curr_show,    NULL),
-       __ATTR(cmo_high,    S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH,
-              viobus_cmo_high_show, viobus_cmo_high_reset),
-       __ATTR_NULL
+static BUS_ATTR_RW(cmo_high);
+
+static struct attribute *vio_bus_attrs[] = {
+       &bus_attr_cmo_entitled.attr,
+       &bus_attr_cmo_spare.attr,
+       &bus_attr_cmo_min.attr,
+       &bus_attr_cmo_desired.attr,
+       &bus_attr_cmo_curr.attr,
+       &bus_attr_cmo_high.attr,
+       &bus_attr_cmo_reserve_size.attr,
+       &bus_attr_cmo_excess_size.attr,
+       &bus_attr_cmo_excess_free.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(vio_bus);
 
 static void vio_cmo_sysfs_init(void)
 {
        vio_bus_type.dev_attrs = vio_cmo_dev_attrs;
-       vio_bus_type.bus_attrs = vio_cmo_bus_attrs;
+       vio_bus_type.bus_groups = vio_bus_groups;
 }
 #else /* CONFIG_PPC_SMLPAR */
 int vio_cmo_entitlement_update(size_t new_entitlement) { return 0; }
index 7143793859fadf0cbc66c1b2119c5cbaee6368c8..f75d7e517927694c3782036c64de5842a4852d9d 100644 (file)
@@ -99,6 +99,7 @@ config S390
        select CLONE_BACKWARDS2
        select GENERIC_CLOCKEVENTS
        select GENERIC_CPU_DEVICES if !SMP
+       select GENERIC_FIND_FIRST_BIT
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL_OLD
        select HAVE_ALIGNED_STRUCT_PAGE if SLUB
@@ -237,6 +238,67 @@ config MARCH_ZEC12
 
 endchoice
 
+config MARCH_G5_TUNE
+       def_bool TUNE_G5 || MARCH_G5 && TUNE_DEFAULT
+
+config MARCH_Z900_TUNE
+       def_bool TUNE_Z900 || MARCH_Z900 && TUNE_DEFAULT
+
+config MARCH_Z990_TUNE
+       def_bool TUNE_Z990 || MARCH_Z990 && TUNE_DEFAULT
+
+config MARCH_Z9_109_TUNE
+       def_bool TUNE_Z9_109 || MARCH_Z9_109 && TUNE_DEFAULT
+
+config MARCH_Z10_TUNE
+       def_bool TUNE_Z10 || MARCH_Z10 && TUNE_DEFAULT
+
+config MARCH_Z196_TUNE
+       def_bool TUNE_Z196 || MARCH_Z196 && TUNE_DEFAULT
+
+config MARCH_ZEC12_TUNE
+       def_bool TUNE_ZEC12 || MARCH_ZEC12 && TUNE_DEFAULT
+
+choice
+       prompt "Tune code generation"
+       default TUNE_DEFAULT
+       help
+         Cause the compiler to tune (-mtune) the generated code for a machine.
+         This will make the code run faster on the selected machine but
+         somewhat slower on other machines.
+         This option only changes how the compiler emits instructions, not the
+         selection of instructions itself, so the resulting kernel will run on
+         all other machines.
+
+config TUNE_DEFAULT
+       bool "Default"
+       help
+         Tune the generated code for the target processor for which the kernel
+         will be compiled.
+
+config TUNE_G5
+       bool "System/390 model G5 and G6"
+
+config TUNE_Z900
+       bool "IBM zSeries model z800 and z900"
+
+config TUNE_Z990
+       bool "IBM zSeries model z890 and z990"
+
+config TUNE_Z9_109
+       bool "IBM System z9"
+
+config TUNE_Z10
+       bool "IBM System z10"
+
+config TUNE_Z196
+       bool "IBM zEnterprise 114 and 196"
+
+config TUNE_ZEC12
+       bool "IBM zBC12 and zEC12"
+
+endchoice
+
 config 64BIT
        def_bool y
        prompt "64 bit kernel"
index a7d68a467ce884d77a9c615db5fcba0cdb251e71..874e6d6e9c5fe41e035f4fafb08f0cba44f92760 100644 (file)
@@ -35,13 +35,21 @@ endif
 
 export LD_BFD
 
-cflags-$(CONFIG_MARCH_G5)   += $(call cc-option,-march=g5)
-cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
-cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
-cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109)
-cflags-$(CONFIG_MARCH_Z10) += $(call cc-option,-march=z10)
-cflags-$(CONFIG_MARCH_Z196) += $(call cc-option,-march=z196)
-cflags-$(CONFIG_MARCH_ZEC12) += $(call cc-option,-march=zEC12)
+cflags-$(CONFIG_MARCH_G5)     += -march=g5
+cflags-$(CONFIG_MARCH_Z900)   += -march=z900
+cflags-$(CONFIG_MARCH_Z990)   += -march=z990
+cflags-$(CONFIG_MARCH_Z9_109) += -march=z9-109
+cflags-$(CONFIG_MARCH_Z10)    += -march=z10
+cflags-$(CONFIG_MARCH_Z196)   += -march=z196
+cflags-$(CONFIG_MARCH_ZEC12)  += -march=zEC12
+
+cflags-$(CONFIG_MARCH_G5_TUNE)         += -mtune=g5
+cflags-$(CONFIG_MARCH_Z900_TUNE)       += -mtune=z900
+cflags-$(CONFIG_MARCH_Z990_TUNE)       += -mtune=z990
+cflags-$(CONFIG_MARCH_Z9_109_TUNE)     += -mtune=z9-109
+cflags-$(CONFIG_MARCH_Z10_TUNE)                += -mtune=z10
+cflags-$(CONFIG_MARCH_Z196_TUNE)       += -mtune=z196
+cflags-$(CONFIG_MARCH_ZEC12_TUNE)      += -mtune=zEC12
 
 #KBUILD_IMAGE is necessary for make rpm
 KBUILD_IMAGE   :=arch/s390/boot/image
index 87a22092b68f8b152a7df862d4c47604e10edee5..4c4a1cef52087bf359c28d9077e315196f7630eb 100644 (file)
@@ -48,9 +48,9 @@ static struct platform_device *appldata_pdev;
  * /proc entries (sysctl)
  */
 static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata";
-static int appldata_timer_handler(ctl_table *ctl, int write,
+static int appldata_timer_handler(struct ctl_table *ctl, int write,
                                  void __user *buffer, size_t *lenp, loff_t *ppos);
-static int appldata_interval_handler(ctl_table *ctl, int write,
+static int appldata_interval_handler(struct ctl_table *ctl, int write,
                                         void __user *buffer,
                                         size_t *lenp, loff_t *ppos);
 
@@ -201,10 +201,10 @@ static void __appldata_vtimer_setup(int cmd)
  * Start/Stop timer, show status of timer (0 = not active, 1 = active)
  */
 static int
-appldata_timer_handler(ctl_table *ctl, int write,
+appldata_timer_handler(struct ctl_table *ctl, int write,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int len;
+       unsigned int len;
        char buf[2];
 
        if (!*lenp || *ppos) {
@@ -243,10 +243,11 @@ out:
  * current timer interval.
  */
 static int
-appldata_interval_handler(ctl_table *ctl, int write,
+appldata_interval_handler(struct ctl_table *ctl, int write,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int len, interval;
+       unsigned int len;
+       int interval;
        char buf[16];
 
        if (!*lenp || *ppos) {
@@ -286,11 +287,12 @@ out:
  * monitoring (0 = not in process, 1 = in process)
  */
 static int
-appldata_generic_handler(ctl_table *ctl, int write,
+appldata_generic_handler(struct ctl_table *ctl, int write,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct appldata_ops *ops = NULL, *tmp_ops;
-       int rc, len, found;
+       unsigned int len;
+       int rc, found;
        char buf[2];
        struct list_head *lh;
 
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
new file mode 100644 (file)
index 0000000..e0af2ee
--- /dev/null
@@ -0,0 +1,655 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_MARCH_Z9_109=y
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_S390=y
+CONFIG_CHSC_SCH=y
+CONFIG_CRASH_DUMP=y
+CONFIG_ZFCPDUMP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_HIBERNATION=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT_IPV4=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
+CONFIG_NET_SCTPPROBE=m
+CONFIG_RDS=m
+CONFIG_RDS_RDMA=m
+CONFIG_RDS_TCP=m
+CONFIG_RDS_DEBUG=y
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_DNS_RESOLVER=y
+CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_TCPPROBE=m
+CONFIG_DEVTMPFS=y
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_XIP=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_LIBFCOE=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_ZFCP=y
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+CONFIG_DM_SWITCH=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+CONFIG_VHOST_NET=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_MLX4_EN=m
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_RAW_DRIVER=m
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_TN3270_FS=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ZVM_WATCHDOG=m
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_VIRTIO_BALLOON=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JBD_DEBUG=y
+CONFIG_JBD2_DEBUG=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_JFS_STATISTICS=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_XFS_DEBUG=y
+CONFIG_GFS2_FS=m
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_FANOTIFY=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_SWAP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_READABLE_ASM=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_SLUB_STATS=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_VM_RB=y
+CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
+CONFIG_DEBUG_PER_CPU_MAPS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_RT_MUTEX_TESTER=y
+CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCK_STAT=y
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
+CONFIG_DEBUG_WRITECOUNT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_DEBUG_CREDENTIALS=y
+CONFIG_PROVE_RCU=y
+CONFIG_RCU_TORTURE_TEST=m
+CONFIG_RCU_CPU_STALL_TIMEOUT=300
+CONFIG_NOTIFIER_ERROR_INJECTION=m
+CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
+CONFIG_PM_NOTIFIER_ERROR_INJECT=m
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAIL_MAKE_REQUEST=y
+CONFIG_FAIL_IO_TIMEOUT=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_LATENCYTOP=y
+CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_KPROBE_EVENT is not set
+CONFIG_LKDTM=m
+CONFIG_KPROBES_SANITY_TEST=y
+CONFIG_RBTREE_TEST=m
+CONFIG_INTERVAL_TREE_TEST=m
+CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_DMA_API_DEBUG=y
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_S390_PTDUMP=y
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_IMA=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_USER=m
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_ZCRYPT=m
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512_S390=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_GHASH_S390=m
+CONFIG_ASYMMETRIC_KEY_TYPE=m
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
+CONFIG_PUBLIC_KEY_ALGO_RSA=m
+CONFIG_X509_CERTIFICATE_PARSER=m
+CONFIG_CRC7=m
+CONFIG_CRC8=m
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_CORDIC=m
+CONFIG_CMM=m
+CONFIG_APPLDATA_BASE=y
+CONFIG_KVM=m
+CONFIG_KVM_S390_UCONTROL=y
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig
new file mode 100644 (file)
index 0000000..b9f6b4c
--- /dev/null
@@ -0,0 +1,618 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_PERF=y
+CONFIG_BLK_CGROUP=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_GCOV_KERNEL=y
+CONFIG_GCOV_PROFILE_ALL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_MARCH_Z9_109=y
+CONFIG_HZ_100=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_PCI=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_S390=y
+CONFIG_CHSC_SCH=y
+CONFIG_CRASH_DUMP=y
+CONFIG_ZFCPDUMP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_HIBERNATION=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT_IPV4=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
+CONFIG_NET_SCTPPROBE=m
+CONFIG_RDS=m
+CONFIG_RDS_RDMA=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_DNS_RESOLVER=y
+CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_TCPPROBE=m
+CONFIG_DEVTMPFS=y
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_XIP=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_LIBFCOE=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_ZFCP=y
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+CONFIG_DM_SWITCH=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+CONFIG_VHOST_NET=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_MLX4_EN=m
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_RAW_DRIVER=m
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_TN3270_FS=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ZVM_WATCHDOG=m
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_VIRTIO_BALLOON=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JBD_DEBUG=y
+CONFIG_JBD2_DEBUG=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_JFS_STATISTICS=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_GFS2_FS=m
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_FANOTIFY=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_SWAP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
+CONFIG_TIMER_STATS=y
+CONFIG_RCU_TORTURE_TEST=m
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_NOTIFIER_ERROR_INJECTION=m
+CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
+CONFIG_PM_NOTIFIER_ERROR_INJECT=m
+CONFIG_LATENCYTOP=y
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_KPROBE_EVENT is not set
+CONFIG_LKDTM=m
+CONFIG_RBTREE_TEST=m
+CONFIG_INTERVAL_TREE_TEST=m
+CONFIG_ATOMIC64_SELFTEST=y
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_S390_PTDUMP=y
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_IMA=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_USER=m
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_ZCRYPT=m
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512_S390=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_GHASH_S390=m
+CONFIG_ASYMMETRIC_KEY_TYPE=m
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
+CONFIG_PUBLIC_KEY_ALGO_RSA=m
+CONFIG_X509_CERTIFICATE_PARSER=m
+CONFIG_CRC7=m
+CONFIG_CRC8=m
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_CORDIC=m
+CONFIG_CMM=m
+CONFIG_APPLDATA_BASE=y
+CONFIG_KVM=m
+CONFIG_KVM_S390_UCONTROL=y
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
new file mode 100644 (file)
index 0000000..91087b4
--- /dev/null
@@ -0,0 +1,610 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_PERF=y
+CONFIG_BLK_CGROUP=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_MARCH_Z9_109=y
+CONFIG_HZ_100=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_PCI=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_S390=y
+CONFIG_CHSC_SCH=y
+CONFIG_CRASH_DUMP=y
+CONFIG_ZFCPDUMP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_HIBERNATION=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT_IPV4=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
+CONFIG_NET_SCTPPROBE=m
+CONFIG_RDS=m
+CONFIG_RDS_RDMA=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_DNS_RESOLVER=y
+CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_TCPPROBE=m
+CONFIG_DEVTMPFS=y
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_XIP=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_LIBFCOE=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_ZFCP=y
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+CONFIG_DM_SWITCH=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+CONFIG_VHOST_NET=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_MLX4_EN=m
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_RAW_DRIVER=m
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_TN3270_FS=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ZVM_WATCHDOG=m
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_VIRTIO_BALLOON=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JBD_DEBUG=y
+CONFIG_JBD2_DEBUG=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_JFS_STATISTICS=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_GFS2_FS=m
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_FANOTIFY=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_SWAP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_TIMER_STATS=y
+CONFIG_RCU_TORTURE_TEST=m
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_LATENCYTOP=y
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_KPROBE_EVENT is not set
+CONFIG_LKDTM=m
+CONFIG_ATOMIC64_SELFTEST=y
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_S390_PTDUMP=y
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_IMA=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_USER=m
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_ZCRYPT=m
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512_S390=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_GHASH_S390=m
+CONFIG_ASYMMETRIC_KEY_TYPE=m
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
+CONFIG_PUBLIC_KEY_ALGO_RSA=m
+CONFIG_X509_CERTIFICATE_PARSER=m
+CONFIG_CRC7=m
+CONFIG_CRC8=m
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_CORDIC=m
+CONFIG_CMM=m
+CONFIG_APPLDATA_BASE=y
+CONFIG_KVM=m
+CONFIG_KVM_S390_UCONTROL=y
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig
new file mode 100644 (file)
index 0000000..d725c4d
--- /dev/null
@@ -0,0 +1,86 @@
+# CONFIG_SWAP is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_MARCH_Z9_109=y
+# CONFIG_COMPAT is not set
+CONFIG_NR_CPUS=2
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_HZ_100=y
+# CONFIG_COMPACTION is not set
+# CONFIG_MIGRATION is not set
+# CONFIG_CHECK_STACK is not set
+# CONFIG_CHSC_SCH is not set
+# CONFIG_SCM_BUS is not set
+CONFIG_CRASH_DUMP=y
+CONFIG_ZFCPDUMP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_IUCV is not set
+CONFIG_ATM=y
+CONFIG_ATM_LANE=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_BLK_DEV_XPRAM is not set
+# CONFIG_DCSSBLK is not set
+# CONFIG_DASD is not set
+CONFIG_ENCLOSURE_SERVICES=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_ENCLOSURE=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SRP_ATTRS=y
+CONFIG_ZFCP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_HVC_IUCV is not set
+CONFIG_RAW_DRIVER=y
+# CONFIG_SCLP_ASYNC is not set
+# CONFIG_HMC_DRV is not set
+# CONFIG_S390_TAPE is not set
+# CONFIG_VMCP is not set
+# CONFIG_MONWRITER is not set
+# CONFIG_S390_VMUR is not set
+# CONFIG_HID is not set
+CONFIG_MEMSTICK=y
+CONFIG_MEMSTICK_DEBUG=y
+CONFIG_MEMSTICK_UNSAFE_RESUME=y
+CONFIG_MSPRO_BLOCK=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_INOTIFY_USER is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_FTRACE is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+# CONFIG_PFAULT is not set
+# CONFIG_S390_HYPFS_FS is not set
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_S390_GUEST is not set
index b4dbade8ca247c52106ecd72036983c850369431..46cae138ece2efa3617447d1fccf82fa504d4e7d 100644 (file)
@@ -725,6 +725,8 @@ static struct crypto_alg xts_aes_alg = {
        }
 };
 
+static int xts_aes_alg_reg;
+
 static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
                           unsigned int key_len)
 {
@@ -846,6 +848,8 @@ static struct crypto_alg ctr_aes_alg = {
        }
 };
 
+static int ctr_aes_alg_reg;
+
 static int __init aes_s390_init(void)
 {
        int ret;
@@ -884,6 +888,7 @@ static int __init aes_s390_init(void)
                ret = crypto_register_alg(&xts_aes_alg);
                if (ret)
                        goto xts_aes_err;
+               xts_aes_alg_reg = 1;
        }
 
        if (crypt_s390_func_available(KMCTR_AES_128_ENCRYPT,
@@ -902,6 +907,7 @@ static int __init aes_s390_init(void)
                        free_page((unsigned long) ctrblk);
                        goto ctr_aes_err;
                }
+               ctr_aes_alg_reg = 1;
        }
 
 out:
@@ -921,9 +927,12 @@ aes_err:
 
 static void __exit aes_s390_fini(void)
 {
-       crypto_unregister_alg(&ctr_aes_alg);
-       free_page((unsigned long) ctrblk);
-       crypto_unregister_alg(&xts_aes_alg);
+       if (ctr_aes_alg_reg) {
+               crypto_unregister_alg(&ctr_aes_alg);
+               free_page((unsigned long) ctrblk);
+       }
+       if (xts_aes_alg_reg)
+               crypto_unregister_alg(&xts_aes_alg);
        crypto_unregister_alg(&cbc_aes_alg);
        crypto_unregister_alg(&ecb_aes_alg);
        crypto_unregister_alg(&aes_alg);
index d204c65bf722cf7ad35d12d3643830cee5880d8c..33f57514f4245a3835438801c99e11c749ac33a3 100644 (file)
@@ -38,13 +38,14 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
-# CONFIG_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEADLINE=y
+CONFIG_MARCH_Z196=y
 CONFIG_HZ_100=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CMA=y
 CONFIG_CRASH_DUMP=y
 CONFIG_BINFMT_MISC=m
 CONFIG_HIBERNATION=y
@@ -152,6 +153,7 @@ CONFIG_CRYPTO_CMAC=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_CRCT10DIF=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
index c797832daa5f596bac9da8f5075d1bd2e006559c..fa9aaf7144b7325d3b9b826bdea85b6f7968622a 100644 (file)
 
 #define ATOMIC_INIT(i)  { (i) }
 
-#define __CS_LOOP(ptr, op_val, op_string) ({                           \
+#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
+
+#define __ATOMIC_OR    "lao"
+#define __ATOMIC_AND   "lan"
+#define __ATOMIC_ADD   "laa"
+
+#define __ATOMIC_LOOP(ptr, op_val, op_string)                          \
+({                                                                     \
+       int old_val;                                                    \
+                                                                       \
+       typecheck(atomic_t *, ptr);                                     \
+       asm volatile(                                                   \
+               op_string "     %0,%2,%1\n"                             \
+               : "=d" (old_val), "+Q" ((ptr)->counter)                 \
+               : "d" (op_val)                                          \
+               : "cc", "memory");                                      \
+       old_val;                                                        \
+})
+
+#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
+
+#define __ATOMIC_OR    "or"
+#define __ATOMIC_AND   "nr"
+#define __ATOMIC_ADD   "ar"
+
+#define __ATOMIC_LOOP(ptr, op_val, op_string)                          \
+({                                                                     \
        int old_val, new_val;                                           \
+                                                                       \
+       typecheck(atomic_t *, ptr);                                     \
        asm volatile(                                                   \
                "       l       %0,%2\n"                                \
                "0:     lr      %1,%0\n"                                \
                op_string "     %1,%3\n"                                \
                "       cs      %0,%1,%2\n"                             \
                "       jl      0b"                                     \
-               : "=&d" (old_val), "=&d" (new_val),                     \
-                 "=Q" (((atomic_t *)(ptr))->counter)                   \
-               : "d" (op_val),  "Q" (((atomic_t *)(ptr))->counter)     \
+               : "=&d" (old_val), "=&d" (new_val), "+Q" ((ptr)->counter)\
+               : "d" (op_val)                                          \
                : "cc", "memory");                                      \
-       new_val;                                                        \
+       old_val;                                                        \
 })
 
+#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
+
 static inline int atomic_read(const atomic_t *v)
 {
        int c;
@@ -53,32 +82,45 @@ static inline void atomic_set(atomic_t *v, int i)
 
 static inline int atomic_add_return(int i, atomic_t *v)
 {
-       return __CS_LOOP(v, i, "ar");
+       return __ATOMIC_LOOP(v, i, __ATOMIC_ADD) + i;
 }
-#define atomic_add(_i, _v)             atomic_add_return(_i, _v)
-#define atomic_add_negative(_i, _v)    (atomic_add_return(_i, _v) < 0)
-#define atomic_inc(_v)                 atomic_add_return(1, _v)
-#define atomic_inc_return(_v)          atomic_add_return(1, _v)
-#define atomic_inc_and_test(_v)                (atomic_add_return(1, _v) == 0)
 
-static inline int atomic_sub_return(int i, atomic_t *v)
+static inline void atomic_add(int i, atomic_t *v)
 {
-       return __CS_LOOP(v, i, "sr");
+#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
+       if (__builtin_constant_p(i) && (i > -129) && (i < 128)) {
+               asm volatile(
+                       "asi    %0,%1\n"
+                       : "+Q" (v->counter)
+                       : "i" (i)
+                       : "cc", "memory");
+       } else {
+               atomic_add_return(i, v);
+       }
+#else
+       atomic_add_return(i, v);
+#endif
 }
-#define atomic_sub(_i, _v)             atomic_sub_return(_i, _v)
+
+#define atomic_add_negative(_i, _v)    (atomic_add_return(_i, _v) < 0)
+#define atomic_inc(_v)                 atomic_add(1, _v)
+#define atomic_inc_return(_v)          atomic_add_return(1, _v)
+#define atomic_inc_and_test(_v)                (atomic_add_return(1, _v) == 0)
+#define atomic_sub(_i, _v)             atomic_add(-(int)(_i), _v)
+#define atomic_sub_return(_i, _v)      atomic_add_return(-(int)(_i), _v)
 #define atomic_sub_and_test(_i, _v)    (atomic_sub_return(_i, _v) == 0)
-#define atomic_dec(_v)                 atomic_sub_return(1, _v)
+#define atomic_dec(_v)                 atomic_sub(1, _v)
 #define atomic_dec_return(_v)          atomic_sub_return(1, _v)
 #define atomic_dec_and_test(_v)                (atomic_sub_return(1, _v) == 0)
 
-static inline void atomic_clear_mask(unsigned long mask, atomic_t *v)
+static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
 {
-       __CS_LOOP(v, ~mask, "nr");
+       __ATOMIC_LOOP(v, ~mask, __ATOMIC_AND);
 }
 
-static inline void atomic_set_mask(unsigned long mask, atomic_t *v)
+static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
 {
-       __CS_LOOP(v, mask, "or");
+       __ATOMIC_LOOP(v, mask, __ATOMIC_OR);
 }
 
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
@@ -87,8 +129,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
        asm volatile(
                "       cs      %0,%2,%1"
-               : "+d" (old), "=Q" (v->counter)
-               : "d" (new), "Q" (v->counter)
+               : "+d" (old), "+Q" (v->counter)
+               : "d" (new)
                : "cc", "memory");
        return old;
 }
@@ -109,27 +151,56 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 }
 
 
-#undef __CS_LOOP
+#undef __ATOMIC_LOOP
 
 #define ATOMIC64_INIT(i)  { (i) }
 
 #ifdef CONFIG_64BIT
 
-#define __CSG_LOOP(ptr, op_val, op_string) ({                          \
+#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
+
+#define __ATOMIC64_OR  "laog"
+#define __ATOMIC64_AND "lang"
+#define __ATOMIC64_ADD "laag"
+
+#define __ATOMIC64_LOOP(ptr, op_val, op_string)                                \
+({                                                                     \
+       long long old_val;                                              \
+                                                                       \
+       typecheck(atomic64_t *, ptr);                                   \
+       asm volatile(                                                   \
+               op_string "     %0,%2,%1\n"                             \
+               : "=d" (old_val), "+Q" ((ptr)->counter)                 \
+               : "d" (op_val)                                          \
+               : "cc", "memory");                                      \
+       old_val;                                                        \
+})
+
+#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
+
+#define __ATOMIC64_OR  "ogr"
+#define __ATOMIC64_AND "ngr"
+#define __ATOMIC64_ADD "agr"
+
+#define __ATOMIC64_LOOP(ptr, op_val, op_string)                                \
+({                                                                     \
        long long old_val, new_val;                                     \
+                                                                       \
+       typecheck(atomic64_t *, ptr);                                   \
        asm volatile(                                                   \
                "       lg      %0,%2\n"                                \
                "0:     lgr     %1,%0\n"                                \
                op_string "     %1,%3\n"                                \
                "       csg     %0,%1,%2\n"                             \
                "       jl      0b"                                     \
-               : "=&d" (old_val), "=&d" (new_val),                     \
-                 "=Q" (((atomic_t *)(ptr))->counter)                   \
-               : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter)      \
+               : "=&d" (old_val), "=&d" (new_val), "+Q" ((ptr)->counter)\
+               : "d" (op_val)                                          \
                : "cc", "memory");                                      \
-       new_val;                                                        \
+       old_val;                                                        \
 })
 
+#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
+
 static inline long long atomic64_read(const atomic64_t *v)
 {
        long long c;
@@ -149,22 +220,17 @@ static inline void atomic64_set(atomic64_t *v, long long i)
 
 static inline long long atomic64_add_return(long long i, atomic64_t *v)
 {
-       return __CSG_LOOP(v, i, "agr");
-}
-
-static inline long long atomic64_sub_return(long long i, atomic64_t *v)
-{
-       return __CSG_LOOP(v, i, "sgr");
+       return __ATOMIC64_LOOP(v, i, __ATOMIC64_ADD) + i;
 }
 
 static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v)
 {
-       __CSG_LOOP(v, ~mask, "ngr");
+       __ATOMIC64_LOOP(v, ~mask, __ATOMIC64_AND);
 }
 
 static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v)
 {
-       __CSG_LOOP(v, mask, "ogr");
+       __ATOMIC64_LOOP(v, mask, __ATOMIC64_OR);
 }
 
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
@@ -174,13 +240,13 @@ static inline long long atomic64_cmpxchg(atomic64_t *v,
 {
        asm volatile(
                "       csg     %0,%2,%1"
-               : "+d" (old), "=Q" (v->counter)
-               : "d" (new), "Q" (v->counter)
+               : "+d" (old), "+Q" (v->counter)
+               : "d" (new)
                : "cc", "memory");
        return old;
 }
 
-#undef __CSG_LOOP
+#undef __ATOMIC64_LOOP
 
 #else /* CONFIG_64BIT */
 
@@ -216,8 +282,8 @@ static inline long long atomic64_xchg(atomic64_t *v, long long new)
                "       lm      %0,%N0,%1\n"
                "0:     cds     %0,%2,%1\n"
                "       jl      0b\n"
-               : "=&d" (rp_old), "=Q" (v->counter)
-               : "d" (rp_new), "Q" (v->counter)
+               : "=&d" (rp_old), "+Q" (v->counter)
+               : "d" (rp_new)
                : "cc");
        return rp_old.pair;
 }
@@ -230,8 +296,8 @@ static inline long long atomic64_cmpxchg(atomic64_t *v,
 
        asm volatile(
                "       cds     %0,%2,%1"
-               : "+&d" (rp_old), "=Q" (v->counter)
-               : "d" (rp_new), "Q" (v->counter)
+               : "+&d" (rp_old), "+Q" (v->counter)
+               : "d" (rp_new)
                : "cc");
        return rp_old.pair;
 }
@@ -248,17 +314,6 @@ static inline long long atomic64_add_return(long long i, atomic64_t *v)
        return new;
 }
 
-static inline long long atomic64_sub_return(long long i, atomic64_t *v)
-{
-       long long old, new;
-
-       do {
-               old = atomic64_read(v);
-               new = old - i;
-       } while (atomic64_cmpxchg(v, old, new) != old);
-       return new;
-}
-
 static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v)
 {
        long long old, new;
@@ -281,7 +336,24 @@ static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v)
 
 #endif /* CONFIG_64BIT */
 
-static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+static inline void atomic64_add(long long i, atomic64_t *v)
+{
+#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
+       if (__builtin_constant_p(i) && (i > -129) && (i < 128)) {
+               asm volatile(
+                       "agsi   %0,%1\n"
+                       : "+Q" (v->counter)
+                       : "i" (i)
+                       : "cc", "memory");
+       } else {
+               atomic64_add_return(i, v);
+       }
+#else
+       atomic64_add_return(i, v);
+#endif
+}
+
+static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u)
 {
        long long c, old;
 
@@ -289,7 +361,7 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
        for (;;) {
                if (unlikely(c == u))
                        break;
-               old = atomic64_cmpxchg(v, c, c + a);
+               old = atomic64_cmpxchg(v, c, c + i);
                if (likely(old == c))
                        break;
                c = old;
@@ -314,14 +386,14 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v)
        return dec;
 }
 
-#define atomic64_add(_i, _v)           atomic64_add_return(_i, _v)
 #define atomic64_add_negative(_i, _v)  (atomic64_add_return(_i, _v) < 0)
-#define atomic64_inc(_v)               atomic64_add_return(1, _v)
+#define atomic64_inc(_v)               atomic64_add(1, _v)
 #define atomic64_inc_return(_v)                atomic64_add_return(1, _v)
 #define atomic64_inc_and_test(_v)      (atomic64_add_return(1, _v) == 0)
-#define atomic64_sub(_i, _v)           atomic64_sub_return(_i, _v)
+#define atomic64_sub_return(_i, _v)    atomic64_add_return(-(long long)(_i), _v)
+#define atomic64_sub(_i, _v)           atomic64_add(-(long long)(_i), _v)
 #define atomic64_sub_and_test(_i, _v)  (atomic64_sub_return(_i, _v) == 0)
-#define atomic64_dec(_v)               atomic64_sub_return(1, _v)
+#define atomic64_dec(_v)               atomic64_sub(1, _v)
 #define atomic64_dec_return(_v)                atomic64_sub_return(1, _v)
 #define atomic64_dec_and_test(_v)      (atomic64_sub_return(1, _v) == 0)
 #define atomic64_inc_not_zero(v)       atomic64_add_unless((v), 1, 0)
index 10135a38673c04894c69e36ee244a756ec28d30e..6e6ad06808293b7e88949351f647e516af8f16b2 100644 (file)
@@ -1,10 +1,40 @@
 /*
- *  S390 version
- *    Copyright IBM Corp. 1999
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *    Copyright IBM Corp. 1999,2013
  *
- *  Derived from "include/asm-i386/bitops.h"
- *    Copyright (C) 1992, Linus Torvalds
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *
+ * The description below was taken in large parts from the powerpc
+ * bitops header file:
+ * Within a word, bits are numbered LSB first.  Lot's of places make
+ * this assumption by directly testing bits with (val & (1<<nr)).
+ * This can cause confusion for large (> 1 word) bitmaps on a
+ * big-endian system because, unlike little endian, the number of each
+ * bit depends on the word size.
+ *
+ * The bitop functions are defined to work on unsigned longs, so for an
+ * s390x system the bits end up numbered:
+ *   |63..............0|127............64|191...........128|255...........196|
+ * and on s390:
+ *   |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224|
+ *
+ * There are a few little-endian macros used mostly for filesystem
+ * bitmaps, these work on similar bit arrays layouts, but
+ * byte-oriented:
+ *   |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
+ *
+ * The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit
+ * number field needs to be reversed compared to the big-endian bit
+ * fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b).
+ *
+ * We also have special functions which work with an MSB0 encoding:
+ * on an s390x system the bits are numbered:
+ *   |0..............63|64............127|128...........191|192...........255|
+ * and on s390:
+ *   |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255|
+ *
+ * The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit
+ * number field needs to be reversed compared to the LSB0 encoded bit
+ * fields. This can be achieved by XOR with 0x3f (64b) or 0x1f (32b).
  *
  */
 
 #error only <linux/bitops.h> can be included directly
 #endif
 
+#include <linux/typecheck.h>
 #include <linux/compiler.h>
 
-/*
- * 32 bit bitops format:
- * bit 0 is the LSB of *addr; bit 31 is the MSB of *addr;
- * bit 32 is the LSB of *(addr+4). That combined with the
- * big endian byte order on S390 give the following bit
- * order in memory:
- *    1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 \
- *    0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
- * after that follows the next long with bit numbers
- *    3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30
- *    2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20
- * The reason for this bit ordering is the fact that
- * in the architecture independent code bits operations
- * of the form "flags |= (1 << bitnr)" are used INTERMIXED
- * with operation of the form "set_bit(bitnr, flags)".
- *
- * 64 bit bitops format:
- * bit 0 is the LSB of *addr; bit 63 is the MSB of *addr;
- * bit 64 is the LSB of *(addr+8). That combined with the
- * big endian byte order on S390 give the following bit
- * order in memory:
- *    3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30
- *    2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20
- *    1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10
- *    0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
- * after that follows the next long with bit numbers
- *    7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70
- *    6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60
- *    5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50
- *    4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40
- * The reason for this bit ordering is the fact that
- * in the architecture independent code bits operations
- * of the form "flags |= (1 << bitnr)" are used INTERMIXED
- * with operation of the form "set_bit(bitnr, flags)".
- */
-
-/* bitmap tables from arch/s390/kernel/bitmap.c */
-extern const char _oi_bitmap[];
-extern const char _ni_bitmap[];
-extern const char _zb_findmap[];
-extern const char _sb_findmap[];
-
 #ifndef CONFIG_64BIT
 
 #define __BITOPS_OR            "or"
 #define __BITOPS_AND           "nr"
 #define __BITOPS_XOR           "xr"
 
-#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)        \
+#define __BITOPS_LOOP(__addr, __val, __op_string)              \
+({                                                             \
+       unsigned long __old, __new;                             \
+                                                               \
+       typecheck(unsigned long *, (__addr));                   \
        asm volatile(                                           \
                "       l       %0,%2\n"                        \
                "0:     lr      %1,%0\n"                        \
                __op_string "   %1,%3\n"                        \
                "       cs      %0,%1,%2\n"                     \
                "       jl      0b"                             \
-               : "=&d" (__old), "=&d" (__new),                 \
-                 "=Q" (*(unsigned long *) __addr)              \
-               : "d" (__val), "Q" (*(unsigned long *) __addr)  \
-               : "cc");
+               : "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\
+               : "d" (__val)                                   \
+               : "cc");                                        \
+       __old;                                                  \
+})
 
 #else /* CONFIG_64BIT */
 
+#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
+
+#define __BITOPS_OR            "laog"
+#define __BITOPS_AND           "lang"
+#define __BITOPS_XOR           "laxg"
+
+#define __BITOPS_LOOP(__addr, __val, __op_string)              \
+({                                                             \
+       unsigned long __old;                                    \
+                                                               \
+       typecheck(unsigned long *, (__addr));                   \
+       asm volatile(                                           \
+               __op_string "   %0,%2,%1\n"                     \
+               : "=d" (__old), "+Q" (*(__addr))                \
+               : "d" (__val)                                   \
+               : "cc");                                        \
+       __old;                                                  \
+})
+
+#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
+
 #define __BITOPS_OR            "ogr"
 #define __BITOPS_AND           "ngr"
 #define __BITOPS_XOR           "xgr"
 
-#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)        \
+#define __BITOPS_LOOP(__addr, __val, __op_string)              \
+({                                                             \
+       unsigned long __old, __new;                             \
+                                                               \
+       typecheck(unsigned long *, (__addr));                   \
        asm volatile(                                           \
                "       lg      %0,%2\n"                        \
                "0:     lgr     %1,%0\n"                        \
                __op_string "   %1,%3\n"                        \
                "       csg     %0,%1,%2\n"                     \
                "       jl      0b"                             \
-               : "=&d" (__old), "=&d" (__new),                 \
-                 "=Q" (*(unsigned long *) __addr)              \
-               : "d" (__val), "Q" (*(unsigned long *) __addr)  \
-               : "cc");
+               : "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\
+               : "d" (__val)                                   \
+               : "cc");                                        \
+       __old;                                                  \
+})
+
+#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
 
 #endif /* CONFIG_64BIT */
 
 #define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
 
-#ifdef CONFIG_SMP
-/*
- * SMP safe set_bit routine based on compare and swap (CS)
- */
-static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
+static inline unsigned long *
+__bitops_word(unsigned long nr, volatile unsigned long *ptr)
+{
+       unsigned long addr;
+
+       addr = (unsigned long)ptr + ((nr ^ (nr & (BITS_PER_LONG - 1))) >> 3);
+       return (unsigned long *)addr;
+}
+
+static inline unsigned char *
+__bitops_byte(unsigned long nr, volatile unsigned long *ptr)
 {
-        unsigned long addr, old, new, mask;
+       return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
+}
+
+static inline void set_bit(unsigned long nr, volatile unsigned long *ptr)
+{
+       unsigned long *addr = __bitops_word(nr, ptr);
+       unsigned long mask;
 
-       addr = (unsigned long) ptr;
-       /* calculate address for CS */
-       addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3;
-       /* make OR mask */
+#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
+       if (__builtin_constant_p(nr)) {
+               unsigned char *caddr = __bitops_byte(nr, ptr);
+
+               asm volatile(
+                       "oi     %0,%b1\n"
+                       : "+Q" (*caddr)
+                       : "i" (1 << (nr & 7))
+                       : "cc");
+               return;
+       }
+#endif
        mask = 1UL << (nr & (BITS_PER_LONG - 1));
-       /* Do the atomic update. */
-       __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR);
+       __BITOPS_LOOP(addr, mask, __BITOPS_OR);
 }
 
-/*
- * SMP safe clear_bit routine based on compare and swap (CS)
- */
-static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
+static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-        unsigned long addr, old, new, mask;
+       unsigned long *addr = __bitops_word(nr, ptr);
+       unsigned long mask;
+
+#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
+       if (__builtin_constant_p(nr)) {
+               unsigned char *caddr = __bitops_byte(nr, ptr);
 
-       addr = (unsigned long) ptr;
-       /* calculate address for CS */
-       addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3;
-       /* make AND mask */
+               asm volatile(
+                       "ni     %0,%b1\n"
+                       : "+Q" (*caddr)
+                       : "i" (~(1 << (nr & 7)))
+                       : "cc");
+               return;
+       }
+#endif
        mask = ~(1UL << (nr & (BITS_PER_LONG - 1)));
-       /* Do the atomic update. */
-       __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND);
+       __BITOPS_LOOP(addr, mask, __BITOPS_AND);
 }
 
-/*
- * SMP safe change_bit routine based on compare and swap (CS)
- */
-static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
+static inline void change_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-        unsigned long addr, old, new, mask;
+       unsigned long *addr = __bitops_word(nr, ptr);
+       unsigned long mask;
+
+#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
+       if (__builtin_constant_p(nr)) {
+               unsigned char *caddr = __bitops_byte(nr, ptr);
 
-       addr = (unsigned long) ptr;
-       /* calculate address for CS */
-       addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3;
-       /* make XOR mask */
+               asm volatile(
+                       "xi     %0,%b1\n"
+                       : "+Q" (*caddr)
+                       : "i" (1 << (nr & 7))
+                       : "cc");
+               return;
+       }
+#endif
        mask = 1UL << (nr & (BITS_PER_LONG - 1));
-       /* Do the atomic update. */
-       __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR);
+       __BITOPS_LOOP(addr, mask, __BITOPS_XOR);
 }
 
-/*
- * SMP safe test_and_set_bit routine based on compare and swap (CS)
- */
 static inline int
-test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
+test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-        unsigned long addr, old, new, mask;
+       unsigned long *addr = __bitops_word(nr, ptr);
+       unsigned long old, mask;
 
-       addr = (unsigned long) ptr;
-       /* calculate address for CS */
-       addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3;
-       /* make OR/test mask */
        mask = 1UL << (nr & (BITS_PER_LONG - 1));
-       /* Do the atomic update. */
-       __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR);
+       old = __BITOPS_LOOP(addr, mask, __BITOPS_OR);
        barrier();
        return (old & mask) != 0;
 }
 
-/*
- * SMP safe test_and_clear_bit routine based on compare and swap (CS)
- */
 static inline int
-test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
+test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-        unsigned long addr, old, new, mask;
+       unsigned long *addr = __bitops_word(nr, ptr);
+       unsigned long old, mask;
 
-       addr = (unsigned long) ptr;
-       /* calculate address for CS */
-       addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3;
-       /* make AND/test mask */
        mask = ~(1UL << (nr & (BITS_PER_LONG - 1)));
-       /* Do the atomic update. */
-       __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND);
+       old = __BITOPS_LOOP(addr, mask, __BITOPS_AND);
        barrier();
-       return (old ^ new) != 0;
+       return (old & ~mask) != 0;
 }
 
-/*
- * SMP safe test_and_change_bit routine based on compare and swap (CS) 
- */
 static inline int
-test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
+test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-        unsigned long addr, old, new, mask;
+       unsigned long *addr = __bitops_word(nr, ptr);
+       unsigned long old, mask;
 
-       addr = (unsigned long) ptr;
-       /* calculate address for CS */
-       addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3;
-       /* make XOR/test mask */
        mask = 1UL << (nr & (BITS_PER_LONG - 1));
-       /* Do the atomic update. */
-       __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR);
+       old = __BITOPS_LOOP(addr, mask, __BITOPS_XOR);
        barrier();
        return (old & mask) != 0;
 }
-#endif /* CONFIG_SMP */
 
-/*
- * fast, non-SMP set_bit routine
- */
 static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-       unsigned long addr;
-
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       asm volatile(
-               "       oc      %O0(1,%R0),%1"
-               : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc");
-}
-
-static inline void 
-__constant_set_bit(const unsigned long nr, volatile unsigned long *ptr)
-{
-       unsigned long addr;
+       unsigned char *addr = __bitops_byte(nr, ptr);
 
-       addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       *(unsigned char *) addr |= 1 << (nr & 7);
+       *addr |= 1 << (nr & 7);
 }
 
-#define set_bit_simple(nr,addr) \
-(__builtin_constant_p((nr)) ? \
- __constant_set_bit((nr),(addr)) : \
- __set_bit((nr),(addr)) )
-
-/*
- * fast, non-SMP clear_bit routine
- */
 static inline void 
 __clear_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-       unsigned long addr;
-
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       asm volatile(
-               "       nc      %O0(1,%R0),%1"
-               : "+Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc");
-}
-
-static inline void 
-__constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr)
-{
-       unsigned long addr;
+       unsigned char *addr = __bitops_byte(nr, ptr);
 
-       addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       *(unsigned char *) addr &= ~(1 << (nr & 7));
+       *addr &= ~(1 << (nr & 7));
 }
 
-#define clear_bit_simple(nr,addr) \
-(__builtin_constant_p((nr)) ? \
- __constant_clear_bit((nr),(addr)) : \
- __clear_bit((nr),(addr)) )
-
-/* 
- * fast, non-SMP change_bit routine 
- */
 static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-       unsigned long addr;
-
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       asm volatile(
-               "       xc      %O0(1,%R0),%1"
-               : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc");
-}
-
-static inline void 
-__constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) 
-{
-       unsigned long addr;
+       unsigned char *addr = __bitops_byte(nr, ptr);
 
-       addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       *(unsigned char *) addr ^= 1 << (nr & 7);
+       *addr ^= 1 << (nr & 7);
 }
 
-#define change_bit_simple(nr,addr) \
-(__builtin_constant_p((nr)) ? \
- __constant_change_bit((nr),(addr)) : \
- __change_bit((nr),(addr)) )
-
-/*
- * fast, non-SMP test_and_set_bit routine
- */
 static inline int
-test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr)
+__test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-       unsigned long addr;
+       unsigned char *addr = __bitops_byte(nr, ptr);
        unsigned char ch;
 
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       ch = *(unsigned char *) addr;
-       asm volatile(
-               "       oc      %O0(1,%R0),%1"
-               : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7])
-               : "cc", "memory");
+       ch = *addr;
+       *addr |= 1 << (nr & 7);
        return (ch >> (nr & 7)) & 1;
 }
-#define __test_and_set_bit(X,Y)                test_and_set_bit_simple(X,Y)
 
-/*
- * fast, non-SMP test_and_clear_bit routine
- */
 static inline int
-test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr)
+__test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-       unsigned long addr;
+       unsigned char *addr = __bitops_byte(nr, ptr);
        unsigned char ch;
 
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       ch = *(unsigned char *) addr;
-       asm volatile(
-               "       nc      %O0(1,%R0),%1"
-               : "+Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7])
-               : "cc", "memory");
+       ch = *addr;
+       *addr &= ~(1 << (nr & 7));
        return (ch >> (nr & 7)) & 1;
 }
-#define __test_and_clear_bit(X,Y)      test_and_clear_bit_simple(X,Y)
 
-/*
- * fast, non-SMP test_and_change_bit routine
- */
 static inline int
-test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr)
+__test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
 {
-       unsigned long addr;
+       unsigned char *addr = __bitops_byte(nr, ptr);
        unsigned char ch;
 
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       ch = *(unsigned char *) addr;
-       asm volatile(
-               "       xc      %O0(1,%R0),%1"
-               : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7])
-               : "cc", "memory");
+       ch = *addr;
+       *addr ^= 1 << (nr & 7);
        return (ch >> (nr & 7)) & 1;
 }
-#define __test_and_change_bit(X,Y)     test_and_change_bit_simple(X,Y)
-
-#ifdef CONFIG_SMP
-#define set_bit             set_bit_cs
-#define clear_bit           clear_bit_cs
-#define change_bit          change_bit_cs
-#define test_and_set_bit    test_and_set_bit_cs
-#define test_and_clear_bit  test_and_clear_bit_cs
-#define test_and_change_bit test_and_change_bit_cs
-#else
-#define set_bit             set_bit_simple
-#define clear_bit           clear_bit_simple
-#define change_bit          change_bit_simple
-#define test_and_set_bit    test_and_set_bit_simple
-#define test_and_clear_bit  test_and_clear_bit_simple
-#define test_and_change_bit test_and_change_bit_simple
-#endif
-
-
-/*
- * This routine doesn't need to be atomic.
- */
 
-static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr)
+static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr)
 {
-       unsigned long addr;
-       unsigned char ch;
-
-       addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
-       ch = *(volatile unsigned char *) addr;
-       return (ch >> (nr & 7)) & 1;
-}
+       const volatile unsigned char *addr;
 
-static inline int 
-__constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
-    return (((volatile char *) addr)
-           [(nr^(BITS_PER_LONG-8))>>3] & (1<<(nr&7))) != 0;
+       addr = ((const volatile unsigned char *)ptr);
+       addr += (nr ^ (BITS_PER_LONG - 8)) >> 3;
+       return (*addr >> (nr & 7)) & 1;
 }
 
-#define test_bit(nr,addr) \
-(__builtin_constant_p((nr)) ? \
- __constant_test_bit((nr),(addr)) : \
- __test_bit((nr),(addr)) )
-
 /*
- * Optimized find bit helper functions.
- */
-
-/**
- * __ffz_word_loop - find byte offset of first long != -1UL
- * @addr: pointer to array of unsigned long
- * @size: size of the array in bits
+ * Functions which use MSB0 bit numbering.
+ * On an s390x system the bits are numbered:
+ *   |0..............63|64............127|128...........191|192...........255|
+ * and on s390:
+ *   |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255|
  */
-static inline unsigned long __ffz_word_loop(const unsigned long *addr,
-                                           unsigned long size)
-{
-       typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
-       unsigned long bytes = 0;
-
-       asm volatile(
-#ifndef CONFIG_64BIT
-               "       ahi     %1,-1\n"
-               "       sra     %1,5\n"
-               "       jz      1f\n"
-               "0:     c       %2,0(%0,%3)\n"
-               "       jne     1f\n"
-               "       la      %0,4(%0)\n"
-               "       brct    %1,0b\n"
-               "1:\n"
-#else
-               "       aghi    %1,-1\n"
-               "       srag    %1,%1,6\n"
-               "       jz      1f\n"
-               "0:     cg      %2,0(%0,%3)\n"
-               "       jne     1f\n"
-               "       la      %0,8(%0)\n"
-               "       brct    %1,0b\n"
-               "1:\n"
-#endif
-               : "+&a" (bytes), "+&d" (size)
-               : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr)
-               : "cc" );
-       return bytes;
-}
+unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size);
+unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
+                               unsigned long offset);
 
-/**
- * __ffs_word_loop - find byte offset of first long != 0UL
- * @addr: pointer to array of unsigned long
- * @size: size of the array in bits
- */
-static inline unsigned long __ffs_word_loop(const unsigned long *addr,
-                                           unsigned long size)
+static inline void set_bit_inv(unsigned long nr, volatile unsigned long *ptr)
 {
-       typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
-       unsigned long bytes = 0;
-
-       asm volatile(
-#ifndef CONFIG_64BIT
-               "       ahi     %1,-1\n"
-               "       sra     %1,5\n"
-               "       jz      1f\n"
-               "0:     c       %2,0(%0,%3)\n"
-               "       jne     1f\n"
-               "       la      %0,4(%0)\n"
-               "       brct    %1,0b\n"
-               "1:\n"
-#else
-               "       aghi    %1,-1\n"
-               "       srag    %1,%1,6\n"
-               "       jz      1f\n"
-               "0:     cg      %2,0(%0,%3)\n"
-               "       jne     1f\n"
-               "       la      %0,8(%0)\n"
-               "       brct    %1,0b\n"
-               "1:\n"
-#endif
-               : "+&a" (bytes), "+&a" (size)
-               : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr)
-               : "cc" );
-       return bytes;
+       return set_bit(nr ^ (BITS_PER_LONG - 1), ptr);
 }
 
-/**
- * __ffz_word - add number of the first unset bit
- * @nr: base value the bit number is added to
- * @word: the word that is searched for unset bits
- */
-static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
+static inline void clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
 {
-#ifdef CONFIG_64BIT
-       if ((word & 0xffffffff) == 0xffffffff) {
-               word >>= 32;
-               nr += 32;
-       }
-#endif
-       if ((word & 0xffff) == 0xffff) {
-               word >>= 16;
-               nr += 16;
-       }
-       if ((word & 0xff) == 0xff) {
-               word >>= 8;
-               nr += 8;
-       }
-       return nr + _zb_findmap[(unsigned char) word];
+       return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
 }
 
-/**
- * __ffs_word - add number of the first set bit
- * @nr: base value the bit number is added to
- * @word: the word that is searched for set bits
- */
-static inline unsigned long __ffs_word(unsigned long nr, unsigned long word)
+static inline void __set_bit_inv(unsigned long nr, volatile unsigned long *ptr)
 {
-#ifdef CONFIG_64BIT
-       if ((word & 0xffffffff) == 0) {
-               word >>= 32;
-               nr += 32;
-       }
-#endif
-       if ((word & 0xffff) == 0) {
-               word >>= 16;
-               nr += 16;
-       }
-       if ((word & 0xff) == 0) {
-               word >>= 8;
-               nr += 8;
-       }
-       return nr + _sb_findmap[(unsigned char) word];
+       return __set_bit(nr ^ (BITS_PER_LONG - 1), ptr);
 }
 
-
-/**
- * __load_ulong_be - load big endian unsigned long
- * @p: pointer to array of unsigned long
- * @offset: byte offset of source value in the array
- */
-static inline unsigned long __load_ulong_be(const unsigned long *p,
-                                           unsigned long offset)
+static inline void __clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
 {
-       p = (unsigned long *)((unsigned long) p + offset);
-       return *p;
+       return __clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
 }
 
-/**
- * __load_ulong_le - load little endian unsigned long
- * @p: pointer to array of unsigned long
- * @offset: byte offset of source value in the array
- */
-static inline unsigned long __load_ulong_le(const unsigned long *p,
-                                           unsigned long offset)
+static inline int test_bit_inv(unsigned long nr,
+                              const volatile unsigned long *ptr)
 {
-       unsigned long word;
-
-       p = (unsigned long *)((unsigned long) p + offset);
-#ifndef CONFIG_64BIT
-       asm volatile(
-               "       ic      %0,%O1(%R1)\n"
-               "       icm     %0,2,%O1+1(%R1)\n"
-               "       icm     %0,4,%O1+2(%R1)\n"
-               "       icm     %0,8,%O1+3(%R1)"
-               : "=&d" (word) : "Q" (*p) : "cc");
-#else
-       asm volatile(
-               "       lrvg    %0,%1"
-               : "=d" (word) : "m" (*p) );
-#endif
-       return word;
+       return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
 }
 
-/*
- * The various find bit functions.
- */
+#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
 
-/*
- * ffz - find first zero in word.
- * @word: The word to search
+/**
+ * __flogr - find leftmost one
+ * @word - The word to search
  *
- * Undefined if no zero exists, so code should check against ~0UL first.
- */
-static inline unsigned long ffz(unsigned long word)
-{
-       return __ffz_word(0, word);
+ * Returns the bit number of the most significant bit set,
+ * where the most significant bit has bit number 0.
+ * If no bit is set this function returns 64.
+ */
+static inline unsigned char __flogr(unsigned long word)
+{
+       if (__builtin_constant_p(word)) {
+               unsigned long bit = 0;
+
+               if (!word)
+                       return 64;
+               if (!(word & 0xffffffff00000000UL)) {
+                       word <<= 32;
+                       bit += 32;
+               }
+               if (!(word & 0xffff000000000000UL)) {
+                       word <<= 16;
+                       bit += 16;
+               }
+               if (!(word & 0xff00000000000000UL)) {
+                       word <<= 8;
+                       bit += 8;
+               }
+               if (!(word & 0xf000000000000000UL)) {
+                       word <<= 4;
+                       bit += 4;
+               }
+               if (!(word & 0xc000000000000000UL)) {
+                       word <<= 2;
+                       bit += 2;
+               }
+               if (!(word & 0x8000000000000000UL)) {
+                       word <<= 1;
+                       bit += 1;
+               }
+               return bit;
+       } else {
+               register unsigned long bit asm("4") = word;
+               register unsigned long out asm("5");
+
+               asm volatile(
+                       "       flogr   %[bit],%[bit]\n"
+                       : [bit] "+d" (bit), [out] "=d" (out) : : "cc");
+               return bit;
+       }
 }
 
 /**
@@ -573,337 +395,83 @@ static inline unsigned long ffz(unsigned long word)
  *
  * Undefined if no bit exists, so code should check against 0 first.
  */
-static inline unsigned long __ffs (unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
 {
-       return __ffs_word(0, word);
+       return __flogr(-word & word) ^ (BITS_PER_LONG - 1);
 }
 
 /**
  * ffs - find first bit set
- * @x: the word to search
+ * @word: the word to search
  *
- * This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * This is defined the same way as the libc and
+ * compiler builtin ffs routines (man ffs).
  */
-static inline int ffs(int x)
+static inline int ffs(int word)
 {
-       if (!x)
-               return 0;
-       return __ffs_word(1, x);
+       unsigned long mask = 2 * BITS_PER_LONG - 1;
+       unsigned int val = (unsigned int)word;
+
+       return (1 + (__flogr(-val & val) ^ (BITS_PER_LONG - 1))) & mask;
 }
 
 /**
- * find_first_zero_bit - find the first zero bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
  *
- * Returns the bit-number of the first zero bit, not the number of the byte
- * containing a bit.
+ * Undefined if no set bit exists, so code should check against 0 first.
  */
-static inline unsigned long find_first_zero_bit(const unsigned long *addr,
-                                               unsigned long size)
+static inline unsigned long __fls(unsigned long word)
 {
-       unsigned long bytes, bits;
-
-        if (!size)
-                return 0;
-       bytes = __ffz_word_loop(addr, size);
-       bits = __ffz_word(bytes*8, __load_ulong_be(addr, bytes));
-       return (bits < size) ? bits : size;
+       return __flogr(word) ^ (BITS_PER_LONG - 1);
 }
-#define find_first_zero_bit find_first_zero_bit
 
 /**
- * find_first_bit - find the first set bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
+ * fls64 - find last set bit in a 64-bit word
+ * @word: the word to search
  *
- * Returns the bit-number of the first set bit, not the number of the byte
- * containing a bit.
- */
-static inline unsigned long find_first_bit(const unsigned long * addr,
-                                          unsigned long size)
-{
-       unsigned long bytes, bits;
-
-        if (!size)
-                return 0;
-       bytes = __ffs_word_loop(addr, size);
-       bits = __ffs_word(bytes*8, __load_ulong_be(addr, bytes));
-       return (bits < size) ? bits : size;
-}
-#define find_first_bit find_first_bit
-
-/*
- * Big endian variant whichs starts bit counting from left using
- * the flogr (find leftmost one) instruction.
- */
-static inline unsigned long __flo_word(unsigned long nr, unsigned long val)
-{
-       register unsigned long bit asm("2") = val;
-       register unsigned long out asm("3");
-
-       asm volatile (
-               "       .insn   rre,0xb9830000,%[bit],%[bit]\n"
-               : [bit] "+d" (bit), [out] "=d" (out) : : "cc");
-       return nr + bit;
-}
-
-/*
- * 64 bit special left bitops format:
- * order in memory:
- *    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
- *    10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
- *    20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
- *    30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
- * after that follows the next long with bit numbers
- *    40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
- *    50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
- *    60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
- *    70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
- * The reason for this bit ordering is the fact that
- * the hardware sets bits in a bitmap starting at bit 0
- * and we don't want to scan the bitmap from the 'wrong
- * end'.
+ * This is defined in a similar way as the libc and compiler builtin
+ * ffsll, but returns the position of the most significant set bit.
+ *
+ * fls64(value) returns 0 if value is 0 or the position of the last
+ * set bit if value is nonzero. The last (most significant) bit is
+ * at position 64.
  */
-static inline unsigned long find_first_bit_left(const unsigned long *addr,
-                                               unsigned long size)
-{
-       unsigned long bytes, bits;
-
-       if (!size)
-               return 0;
-       bytes = __ffs_word_loop(addr, size);
-       bits = __flo_word(bytes * 8, __load_ulong_be(addr, bytes));
-       return (bits < size) ? bits : size;
-}
-
-static inline int find_next_bit_left(const unsigned long *addr,
-                                    unsigned long size,
-                                    unsigned long offset)
+static inline int fls64(unsigned long word)
 {
-       const unsigned long *p;
-       unsigned long bit, set;
-
-       if (offset >= size)
-               return size;
-       bit = offset & (BITS_PER_LONG - 1);
-       offset -= bit;
-       size -= offset;
-       p = addr + offset / BITS_PER_LONG;
-       if (bit) {
-               set = __flo_word(0, *p & (~0UL >> bit));
-               if (set >= size)
-                       return size + offset;
-               if (set < BITS_PER_LONG)
-                       return set + offset;
-               offset += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-               p++;
-       }
-       return offset + find_first_bit_left(p, size);
-}
-
-#define for_each_set_bit_left(bit, addr, size)                         \
-       for ((bit) = find_first_bit_left((addr), (size));               \
-            (bit) < (size);                                            \
-            (bit) = find_next_bit_left((addr), (size), (bit) + 1))
-
-/* same as for_each_set_bit() but use bit as value to start with */
-#define for_each_set_bit_left_cont(bit, addr, size)                    \
-       for ((bit) = find_next_bit_left((addr), (size), (bit));         \
-            (bit) < (size);                                            \
-            (bit) = find_next_bit_left((addr), (size), (bit) + 1))
+       unsigned long mask = 2 * BITS_PER_LONG - 1;
 
-/**
- * find_next_zero_bit - find the first zero bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-static inline int find_next_zero_bit (const unsigned long * addr,
-                                     unsigned long size,
-                                     unsigned long offset)
-{
-        const unsigned long *p;
-       unsigned long bit, set;
-
-       if (offset >= size)
-               return size;
-       bit = offset & (BITS_PER_LONG - 1);
-       offset -= bit;
-       size -= offset;
-       p = addr + offset / BITS_PER_LONG;
-       if (bit) {
-               /*
-                * __ffz_word returns BITS_PER_LONG
-                * if no zero bit is present in the word.
-                */
-               set = __ffz_word(bit, *p >> bit);
-               if (set >= size)
-                       return size + offset;
-               if (set < BITS_PER_LONG)
-                       return set + offset;
-               offset += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-               p++;
-       }
-       return offset + find_first_zero_bit(p, size);
+       return (1 + (__flogr(word) ^ (BITS_PER_LONG - 1))) & mask;
 }
-#define find_next_zero_bit find_next_zero_bit
 
 /**
- * find_next_bit - find the first set bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
+ * fls - find last (most-significant) bit set
+ * @word: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static inline int find_next_bit (const unsigned long * addr,
-                                unsigned long size,
-                                unsigned long offset)
+static inline int fls(int word)
 {
-        const unsigned long *p;
-       unsigned long bit, set;
-
-       if (offset >= size)
-               return size;
-       bit = offset & (BITS_PER_LONG - 1);
-       offset -= bit;
-       size -= offset;
-       p = addr + offset / BITS_PER_LONG;
-       if (bit) {
-               /*
-                * __ffs_word returns BITS_PER_LONG
-                * if no one bit is present in the word.
-                */
-               set = __ffs_word(0, *p & (~0UL << bit));
-               if (set >= size)
-                       return size + offset;
-               if (set < BITS_PER_LONG)
-                       return set + offset;
-               offset += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-               p++;
-       }
-       return offset + find_first_bit(p, size);
+       return fls64((unsigned int)word);
 }
-#define find_next_bit find_next_bit
 
-/*
- * Every architecture must define this function. It's the fastest
- * way of searching a 140-bit bitmap where the first 100 bits are
- * unlikely to be set. It's guaranteed that at least one of the 140
- * bits is cleared.
- */
-static inline int sched_find_first_bit(unsigned long *b)
-{
-       return find_first_bit(b, 140);
-}
+#else /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */
 
-#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls.h>
 #include <asm-generic/bitops/fls64.h>
 
+#endif /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
-
-/*
- * ATTENTION: intel byte ordering convention for ext2 and minix !!
- * bit 0 is the LSB of addr; bit 31 is the MSB of addr;
- * bit 32 is the LSB of (addr+4).
- * That combined with the little endian byte order of Intel gives the
- * following bit order in memory:
- *    07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 \
- *    23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
- */
-
-static inline int find_first_zero_bit_le(void *vaddr, unsigned int size)
-{
-       unsigned long bytes, bits;
-
-        if (!size)
-                return 0;
-       bytes = __ffz_word_loop(vaddr, size);
-       bits = __ffz_word(bytes*8, __load_ulong_le(vaddr, bytes));
-       return (bits < size) ? bits : size;
-}
-#define find_first_zero_bit_le find_first_zero_bit_le
-
-static inline int find_next_zero_bit_le(void *vaddr, unsigned long size,
-                                         unsigned long offset)
-{
-        unsigned long *addr = vaddr, *p;
-       unsigned long bit, set;
-
-        if (offset >= size)
-                return size;
-       bit = offset & (BITS_PER_LONG - 1);
-       offset -= bit;
-       size -= offset;
-       p = addr + offset / BITS_PER_LONG;
-        if (bit) {
-               /*
-                * s390 version of ffz returns BITS_PER_LONG
-                * if no zero bit is present in the word.
-                */
-               set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit);
-               if (set >= size)
-                       return size + offset;
-               if (set < BITS_PER_LONG)
-                       return set + offset;
-               offset += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-               p++;
-        }
-       return offset + find_first_zero_bit_le(p, size);
-}
-#define find_next_zero_bit_le find_next_zero_bit_le
-
-static inline unsigned long find_first_bit_le(void *vaddr, unsigned long size)
-{
-       unsigned long bytes, bits;
-
-       if (!size)
-               return 0;
-       bytes = __ffs_word_loop(vaddr, size);
-       bits = __ffs_word(bytes*8, __load_ulong_le(vaddr, bytes));
-       return (bits < size) ? bits : size;
-}
-#define find_first_bit_le find_first_bit_le
-
-static inline int find_next_bit_le(void *vaddr, unsigned long size,
-                                    unsigned long offset)
-{
-       unsigned long *addr = vaddr, *p;
-       unsigned long bit, set;
-
-       if (offset >= size)
-               return size;
-       bit = offset & (BITS_PER_LONG - 1);
-       offset -= bit;
-       size -= offset;
-       p = addr + offset / BITS_PER_LONG;
-       if (bit) {
-               /*
-                * s390 version of ffz returns BITS_PER_LONG
-                * if no zero bit is present in the word.
-                */
-               set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit));
-               if (set >= size)
-                       return size + offset;
-               if (set < BITS_PER_LONG)
-                       return set + offset;
-               offset += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-               p++;
-       }
-       return offset + find_first_bit_le(p, size);
-}
-#define find_next_bit_le find_next_bit_le
-
+#include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/le.h>
-
 #include <asm-generic/bitops/ext2-atomic-setbit.h>
 
 #endif /* _S390_BITOPS_H */
index c1e7c646727cd4c71c56a5040a477a6d8618d565..4bf9da03591e7abda64ab4632f511c16b7734d16 100644 (file)
@@ -22,6 +22,7 @@
 #define PSW32_MASK_ASC         0x0000C000UL
 #define PSW32_MASK_CC          0x00003000UL
 #define PSW32_MASK_PM          0x00000f00UL
+#define PSW32_MASK_RI          0x00000080UL
 
 #define PSW32_MASK_USER                0x0000FF00UL
 
@@ -35,7 +36,9 @@
 #define PSW32_ASC_SECONDARY    0x00008000UL
 #define PSW32_ASC_HOME         0x0000C000UL
 
-extern u32 psw32_user_bits;
+#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \
+                        PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \
+                        PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | PSW32_ASC_HOME)
 
 #define COMPAT_USER_HZ         100
 #define COMPAT_UTS_MACHINE     "s390\0\0\0\0"
index debfda33d1f86d88a8b3bce89e6b23962c643489..9b69c0befdcaafcb46565056e10c36e884ab8065 100644 (file)
@@ -8,69 +8,59 @@
 #define __ASM_CTL_REG_H
 
 #ifdef CONFIG_64BIT
-
-#define __ctl_load(array, low, high) ({                                \
-       typedef struct { char _[sizeof(array)]; } addrtype;     \
-       asm volatile(                                           \
-               "       lctlg   %1,%2,%0\n"                     \
-               : : "Q" (*(addrtype *)(&array)),                \
-                   "i" (low), "i" (high));                     \
-       })
-
-#define __ctl_store(array, low, high) ({                       \
-       typedef struct { char _[sizeof(array)]; } addrtype;     \
-       asm volatile(                                           \
-               "       stctg   %1,%2,%0\n"                     \
-               : "=Q" (*(addrtype *)(&array))                  \
-               : "i" (low), "i" (high));                       \
-       })
-
-#else /* CONFIG_64BIT */
-
-#define __ctl_load(array, low, high) ({                                \
-       typedef struct { char _[sizeof(array)]; } addrtype;     \
-       asm volatile(                                           \
-               "       lctl    %1,%2,%0\n"                     \
-               : : "Q" (*(addrtype *)(&array)),                \
-                   "i" (low), "i" (high));                     \
-})
-
-#define __ctl_store(array, low, high) ({                       \
-       typedef struct { char _[sizeof(array)]; } addrtype;     \
-       asm volatile(                                           \
-               "       stctl   %1,%2,%0\n"                     \
-               : "=Q" (*(addrtype *)(&array))                  \
-               : "i" (low), "i" (high));                       \
-       })
-
-#endif /* CONFIG_64BIT */
-
-#define __ctl_set_bit(cr, bit) ({      \
-       unsigned long __dummy;          \
-       __ctl_store(__dummy, cr, cr);   \
-       __dummy |= 1UL << (bit);        \
-       __ctl_load(__dummy, cr, cr);    \
-})
-
-#define __ctl_clear_bit(cr, bit) ({    \
-       unsigned long __dummy;          \
-       __ctl_store(__dummy, cr, cr);   \
-       __dummy &= ~(1UL << (bit));     \
-       __ctl_load(__dummy, cr, cr);    \
-})
+# define __CTL_LOAD    "lctlg"
+# define __CTL_STORE   "stctg"
+#else
+# define __CTL_LOAD    "lctl"
+# define __CTL_STORE   "stctl"
+#endif
+
+#define __ctl_load(array, low, high) {                                 \
+       typedef struct { char _[sizeof(array)]; } addrtype;             \
+                                                                       \
+       BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\
+       asm volatile(                                                   \
+               __CTL_LOAD " %1,%2,%0\n"                                \
+               : : "Q" (*(addrtype *)(&array)), "i" (low), "i" (high));\
+}
+
+#define __ctl_store(array, low, high) {                                        \
+       typedef struct { char _[sizeof(array)]; } addrtype;             \
+                                                                       \
+       BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\
+       asm volatile(                                                   \
+               __CTL_STORE " %1,%2,%0\n"                               \
+               : "=Q" (*(addrtype *)(&array))                          \
+               : "i" (low), "i" (high));                               \
+}
+
+static inline void __ctl_set_bit(unsigned int cr, unsigned int bit)
+{
+       unsigned long reg;
+
+       __ctl_store(reg, cr, cr);
+       reg |= 1UL << bit;
+       __ctl_load(reg, cr, cr);
+}
+
+static inline void __ctl_clear_bit(unsigned int cr, unsigned int bit)
+{
+       unsigned long reg;
+
+       __ctl_store(reg, cr, cr);
+       reg &= ~(1UL << bit);
+       __ctl_load(reg, cr, cr);
+}
+
+void smp_ctl_set_bit(int cr, int bit);
+void smp_ctl_clear_bit(int cr, int bit);
 
 #ifdef CONFIG_SMP
-
-extern void smp_ctl_set_bit(int cr, int bit);
-extern void smp_ctl_clear_bit(int cr, int bit);
-#define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
-#define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
-
+# define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
+# define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
 #else
-
-#define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
-#define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)
-
-#endif /* CONFIG_SMP */
+# define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
+# define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)
+#endif
 
 #endif /* __ASM_CTL_REG_H */
index 188c5052a20ab663f878afc2c23889ec53384d8e..530c15eb01e99ad5970b556234c65d34a8bdf141 100644 (file)
@@ -107,6 +107,11 @@ void debug_set_level(debug_info_t* id, int new_level);
 void debug_set_critical(void);
 void debug_stop_all(void);
 
+static inline bool debug_level_enabled(debug_info_t* id, int level)
+{
+       return level <= id->level;
+}
+
 static inline debug_entry_t*
 debug_event(debug_info_t* id, int level, void* data, int length)
 {
diff --git a/arch/s390/include/asm/dis.h b/arch/s390/include/asm/dis.h
new file mode 100644 (file)
index 0000000..04a83f5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Disassemble s390 instructions.
+ *
+ * Copyright IBM Corp. 2007
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ */
+
+#ifndef __ASM_S390_DIS_H__
+#define __ASM_S390_DIS_H__
+
+/* Type of operand */
+#define OPERAND_GPR    0x1     /* Operand printed as %rx */
+#define OPERAND_FPR    0x2     /* Operand printed as %fx */
+#define OPERAND_AR     0x4     /* Operand printed as %ax */
+#define OPERAND_CR     0x8     /* Operand printed as %cx */
+#define OPERAND_DISP   0x10    /* Operand printed as displacement */
+#define OPERAND_BASE   0x20    /* Operand printed as base register */
+#define OPERAND_INDEX  0x40    /* Operand printed as index register */
+#define OPERAND_PCREL  0x80    /* Operand printed as pc-relative symbol */
+#define OPERAND_SIGNED 0x100   /* Operand printed as signed value */
+#define OPERAND_LENGTH 0x200   /* Operand printed as length (+1) */
+
+
+struct s390_operand {
+       int bits;               /* The number of bits in the operand. */
+       int shift;              /* The number of bits to shift. */
+       int flags;              /* One bit syntax flags. */
+};
+
+struct s390_insn {
+       const char name[5];
+       unsigned char opfrag;
+       unsigned char format;
+};
+
+
+static inline int insn_length(unsigned char code)
+{
+       return ((((int) code + 64) >> 7) + 1) << 1;
+}
+
+void show_code(struct pt_regs *regs);
+void print_fn_code(unsigned char *code, unsigned long len);
+int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len);
+struct s390_insn *find_insn(unsigned char *code);
+
+static inline int is_known_insn(unsigned char *code)
+{
+       return !!find_insn(code);
+}
+
+#endif /* __ASM_S390_DIS_H__ */
index ef61709950765bbdd72879c473b49d509c7adf0a..7ecb92b469b67bc45a099d9fea8bb72e375fc704 100644 (file)
@@ -12,9 +12,9 @@
 
 #define TCW_FORMAT_DEFAULT             0
 #define TCW_TIDAW_FORMAT_DEFAULT       0
-#define TCW_FLAGS_INPUT_TIDA           1 << (23 - 5)
-#define TCW_FLAGS_TCCB_TIDA            1 << (23 - 6)
-#define TCW_FLAGS_OUTPUT_TIDA          1 << (23 - 7)
+#define TCW_FLAGS_INPUT_TIDA           (1 << (23 - 5))
+#define TCW_FLAGS_TCCB_TIDA            (1 << (23 - 6))
+#define TCW_FLAGS_OUTPUT_TIDA          (1 << (23 - 7))
 #define TCW_FLAGS_TIDAW_FORMAT(x)      ((x) & 3) << (23 - 9)
 #define TCW_FLAGS_GET_TIDAW_FORMAT(x)  (((x) >> (23 - 9)) & 3)
 
@@ -54,11 +54,11 @@ struct tcw {
        u32 intrg;
 } __attribute__ ((packed, aligned(64)));
 
-#define TIDAW_FLAGS_LAST               1 << (7 - 0)
-#define TIDAW_FLAGS_SKIP               1 << (7 - 1)
-#define TIDAW_FLAGS_DATA_INT           1 << (7 - 2)
-#define TIDAW_FLAGS_TTIC               1 << (7 - 3)
-#define TIDAW_FLAGS_INSERT_CBC         1 << (7 - 4)
+#define TIDAW_FLAGS_LAST               (1 << (7 - 0))
+#define TIDAW_FLAGS_SKIP               (1 << (7 - 1))
+#define TIDAW_FLAGS_DATA_INT           (1 << (7 - 2))
+#define TIDAW_FLAGS_TTIC               (1 << (7 - 3))
+#define TIDAW_FLAGS_INSERT_CBC         (1 << (7 - 4))
 
 /**
  * struct tidaw - Transport-Indirect-Addressing Word (TIDAW)
@@ -106,9 +106,9 @@ struct tsa_ddpc {
        u8 sense[32];
 } __attribute__ ((packed));
 
-#define TSA_INTRG_FLAGS_CU_STATE_VALID         1 << (7 - 0)
-#define TSA_INTRG_FLAGS_DEV_STATE_VALID                1 << (7 - 1)
-#define TSA_INTRG_FLAGS_OP_STATE_VALID         1 << (7 - 2)
+#define TSA_INTRG_FLAGS_CU_STATE_VALID         (1 << (7 - 0))
+#define TSA_INTRG_FLAGS_DEV_STATE_VALID                (1 << (7 - 1))
+#define TSA_INTRG_FLAGS_OP_STATE_VALID         (1 << (7 - 2))
 
 /**
  * struct tsa_intrg - Interrogate Transport-Status Area (Intrg. TSA)
@@ -140,10 +140,10 @@ struct tsa_intrg {
 #define TSB_FORMAT_DDPC                2
 #define TSB_FORMAT_INTRG       3
 
-#define TSB_FLAGS_DCW_OFFSET_VALID     1 << (7 - 0)
-#define TSB_FLAGS_COUNT_VALID          1 << (7 - 1)
-#define TSB_FLAGS_CACHE_MISS           1 << (7 - 2)
-#define TSB_FLAGS_TIME_VALID           1 << (7 - 3)
+#define TSB_FLAGS_DCW_OFFSET_VALID     (1 << (7 - 0))
+#define TSB_FLAGS_COUNT_VALID          (1 << (7 - 1))
+#define TSB_FLAGS_CACHE_MISS           (1 << (7 - 2))
+#define TSB_FLAGS_TIME_VALID           (1 << (7 - 3))
 #define TSB_FLAGS_FORMAT(x)            ((x) & 7)
 #define TSB_FORMAT(t)                  ((t)->flags & 7)
 
@@ -179,9 +179,9 @@ struct tsb {
 #define DCW_INTRG_RCQ_PRIMARY          1
 #define DCW_INTRG_RCQ_SECONDARY                2
 
-#define DCW_INTRG_FLAGS_MPM            1 < (7 - 0)
-#define DCW_INTRG_FLAGS_PPR            1 < (7 - 1)
-#define DCW_INTRG_FLAGS_CRIT           1 < (7 - 2)
+#define DCW_INTRG_FLAGS_MPM            (1 << (7 - 0))
+#define DCW_INTRG_FLAGS_PPR            (1 << (7 - 1))
+#define DCW_INTRG_FLAGS_CRIT           (1 << (7 - 2))
 
 /**
  * struct dcw_intrg_data - Interrogate DCW data
@@ -216,7 +216,7 @@ struct dcw_intrg_data {
        u8  prog_data[0];
 } __attribute__ ((packed));
 
-#define DCW_FLAGS_CC           1 << (7 - 1)
+#define DCW_FLAGS_CC           (1 << (7 - 1))
 
 #define DCW_CMD_WRITE          0x01
 #define DCW_CMD_READ           0x02
index 2bd6cb897b90e86f129a6ae2b4eeca6bd495de95..2fcccc0c997cc3102dcb67e5ea2f60fc4f4200b2 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef _ASM_S390_IPL_H
 #define _ASM_S390_IPL_H
 
+#include <asm/lowcore.h>
 #include <asm/types.h>
 #include <asm/cio.h>
 #include <asm/setup.h>
@@ -86,7 +87,14 @@ struct ipl_parameter_block {
  */
 extern u32 ipl_flags;
 extern u32 dump_prefix_page;
-extern unsigned int zfcpdump_prefix_array[];
+
+struct dump_save_areas {
+       struct save_area **areas;
+       int count;
+};
+
+extern struct dump_save_areas dump_save_areas;
+struct save_area *dump_save_area_create(int cpu);
 
 extern void do_reipl(void);
 extern void do_halt(void);
index 9f973d8de90ea91fbde12f11cff70c8470bf8a81..5d1f950704dc6272ec368279b2a01f82274fe220 100644 (file)
@@ -40,14 +40,8 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
        pgd_t *pgd = mm->pgd;
 
        S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
-       if (s390_user_mode != HOME_SPACE_MODE) {
-               /* Load primary space page table origin. */
-               asm volatile(LCTL_OPCODE" 1,1,%0\n"
-                            : : "m" (S390_lowcore.user_asce) );
-       } else
-               /* Load home space page table origin. */
-               asm volatile(LCTL_OPCODE" 13,13,%0"
-                            : : "m" (S390_lowcore.user_asce) );
+       /* Load primary space page table origin. */
+       asm volatile(LCTL_OPCODE" 1,1,%0\n" : : "m" (S390_lowcore.user_asce));
        set_fs(current->thread.mm_segment);
 }
 
index 1e51f2915b2eea6a1396c7dfb2d63ffc2f671ee9..316c8503a3b4fda3824ca071065f145038b34a0c 100644 (file)
 #include <asm/setup.h>
 #ifndef __ASSEMBLY__
 
-void storage_key_init_range(unsigned long start, unsigned long end);
+static inline void storage_key_init_range(unsigned long start, unsigned long end)
+{
+#if PAGE_DEFAULT_KEY
+       __storage_key_init_range(start, end);
+#endif
+}
 
 static inline void clear_page(void *page)
 {
index 1ca5d1047c71742f5e3c5681c89a4b98e4e87530..ac24b26fc065be9bad9443fc7a86cd1e24ab3abe 100644 (file)
@@ -6,14 +6,9 @@
 extern debug_info_t *pci_debug_msg_id;
 extern debug_info_t *pci_debug_err_id;
 
-#ifdef CONFIG_PCI_DEBUG
 #define zpci_dbg(imp, fmt, args...)                            \
        debug_sprintf_event(pci_debug_msg_id, imp, fmt, ##args)
 
-#else /* !CONFIG_PCI_DEBUG */
-#define zpci_dbg(imp, fmt, args...) do { } while (0)
-#endif
-
 #define zpci_err(text...)                                                      \
        do {                                                                    \
                char debug_buffer[16];                                          \
index df6eac9f0cb4e324069e3bae65246a7a99f02888..649eb62c52b3784ec0214e47482b87442d3081dd 100644 (file)
 struct zpci_fib {
        u32 fmt         :  8;   /* format */
        u32             : 24;
-       u32 reserved1;
+       u32             : 32;
        u8 fc;                  /* function controls */
-       u8 reserved2;
-       u16 reserved3;
-       u32 reserved4;
+       u64             : 56;
        u64 pba;                /* PCI base address */
        u64 pal;                /* PCI address limit */
        u64 iota;               /* I/O Translation Anchor */
@@ -70,14 +68,13 @@ struct zpci_fib {
        u32 sum         :  1;   /* Adapter int summary bit enabled */
        u32             :  1;
        u32 aisbo       :  6;   /* Adapter int summary bit offset */
-       u32 reserved5;
+       u32             : 32;
        u64 aibv;               /* Adapter int bit vector address */
        u64 aisb;               /* Adapter int summary bit address */
        u64 fmb_addr;           /* Function measurement block address and key */
-       u64 reserved6;
-       u64 reserved7;
-} __packed;
-
+       u32             : 32;
+       u32 gd;
+} __packed __aligned(8);
 
 int zpci_mod_fc(u64 req, struct zpci_fib *fib);
 int zpci_refresh_trans(u64 fn, u64 addr, u64 range);
index 86fe0ee2cee5945beacca37f563d6d118fae0a12..fa91e0097458d8d56cd3d41f24fd0a5a9f42d72a 100644 (file)
  */
 #define __my_cpu_offset S390_lowcore.percpu_offset
 
+#ifdef CONFIG_64BIT
+
 /*
  * For 64 bit module code, the module may be more than 4G above the
  * per cpu area, use weak definitions to force the compiler to
  * generate external references.
  */
-#if defined(CONFIG_SMP) && defined(CONFIG_64BIT) && defined(MODULE)
+#if defined(CONFIG_SMP) && defined(MODULE)
 #define ARCH_NEEDS_WEAK_PER_CPU
 #endif
 
-#define arch_this_cpu_to_op(pcp, val, op)                              \
+/*
+ * We use a compare-and-swap loop since that uses less cpu cycles than
+ * disabling and enabling interrupts like the generic variant would do.
+ */
+#define arch_this_cpu_to_op_simple(pcp, val, op)                       \
 ({                                                                     \
        typedef typeof(pcp) pcp_op_T__;                                 \
        pcp_op_T__ old__, new__, prev__;                                \
        do {                                                            \
                old__ = prev__;                                         \
                new__ = old__ op (val);                                 \
-               switch (sizeof(*ptr__)) {                               \
-               case 8:                                                 \
-                       prev__ = cmpxchg64(ptr__, old__, new__);        \
-                       break;                                          \
-               default:                                                \
-                       prev__ = cmpxchg(ptr__, old__, new__);          \
-               }                                                       \
+               prev__ = cmpxchg(ptr__, old__, new__);                  \
        } while (prev__ != old__);                                      \
        preempt_enable();                                               \
        new__;                                                          \
 })
 
-#define this_cpu_add_1(pcp, val) arch_this_cpu_to_op(pcp, val, +)
-#define this_cpu_add_2(pcp, val) arch_this_cpu_to_op(pcp, val, +)
-#define this_cpu_add_4(pcp, val) arch_this_cpu_to_op(pcp, val, +)
-#define this_cpu_add_8(pcp, val) arch_this_cpu_to_op(pcp, val, +)
+#define this_cpu_add_1(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_add_2(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_add_return_1(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_add_return_2(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_and_1(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, &)
+#define this_cpu_and_2(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, &)
+#define this_cpu_or_1(pcp, val)                arch_this_cpu_to_op_simple(pcp, val, |)
+#define this_cpu_or_2(pcp, val)                arch_this_cpu_to_op_simple(pcp, val, |)
+
+#ifndef CONFIG_HAVE_MARCH_Z196_FEATURES
+
+#define this_cpu_add_4(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_add_8(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_add_return_4(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_add_return_8(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +)
+#define this_cpu_and_4(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, &)
+#define this_cpu_and_8(pcp, val)       arch_this_cpu_to_op_simple(pcp, val, &)
+#define this_cpu_or_4(pcp, val)                arch_this_cpu_to_op_simple(pcp, val, |)
+#define this_cpu_or_8(pcp, val)                arch_this_cpu_to_op_simple(pcp, val, |)
+
+#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
+
+#define arch_this_cpu_add(pcp, val, op1, op2, szcast)                  \
+{                                                                      \
+       typedef typeof(pcp) pcp_op_T__;                                 \
+       pcp_op_T__ val__ = (val);                                       \
+       pcp_op_T__ old__, *ptr__;                                       \
+       preempt_disable();                                              \
+       ptr__ = __this_cpu_ptr(&(pcp));                                 \
+       if (__builtin_constant_p(val__) &&                              \
+           ((szcast)val__ > -129) && ((szcast)val__ < 128)) {          \
+               asm volatile(                                           \
+                       op2 "   %[ptr__],%[val__]\n"                    \
+                       : [ptr__] "+Q" (*ptr__)                         \
+                       : [val__] "i" ((szcast)val__)                   \
+                       : "cc");                                        \
+       } else {                                                        \
+               asm volatile(                                           \
+                       op1 "   %[old__],%[val__],%[ptr__]\n"           \
+                       : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__)   \
+                       : [val__] "d" (val__)                           \
+                       : "cc");                                        \
+       }                                                               \
+       preempt_enable();                                               \
+}
 
-#define this_cpu_add_return_1(pcp, val) arch_this_cpu_to_op(pcp, val, +)
-#define this_cpu_add_return_2(pcp, val) arch_this_cpu_to_op(pcp, val, +)
-#define this_cpu_add_return_4(pcp, val) arch_this_cpu_to_op(pcp, val, +)
-#define this_cpu_add_return_8(pcp, val) arch_this_cpu_to_op(pcp, val, +)
+#define this_cpu_add_4(pcp, val) arch_this_cpu_add(pcp, val, "laa", "asi", int)
+#define this_cpu_add_8(pcp, val) arch_this_cpu_add(pcp, val, "laag", "agsi", long)
 
-#define this_cpu_and_1(pcp, val) arch_this_cpu_to_op(pcp, val, &)
-#define this_cpu_and_2(pcp, val) arch_this_cpu_to_op(pcp, val, &)
-#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, &)
-#define this_cpu_and_8(pcp, val) arch_this_cpu_to_op(pcp, val, &)
+#define arch_this_cpu_add_return(pcp, val, op)                         \
+({                                                                     \
+       typedef typeof(pcp) pcp_op_T__;                                 \
+       pcp_op_T__ val__ = (val);                                       \
+       pcp_op_T__ old__, *ptr__;                                       \
+       preempt_disable();                                              \
+       ptr__ = __this_cpu_ptr(&(pcp));                                 \
+       asm volatile(                                                   \
+               op "    %[old__],%[val__],%[ptr__]\n"                   \
+               : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__)           \
+               : [val__] "d" (val__)                                   \
+               : "cc");                                                \
+       preempt_enable();                                               \
+       old__ + val__;                                                  \
+})
 
-#define this_cpu_or_1(pcp, val) arch_this_cpu_to_op(pcp, val, |)
-#define this_cpu_or_2(pcp, val) arch_this_cpu_to_op(pcp, val, |)
-#define this_cpu_or_4(pcp, val) arch_this_cpu_to_op(pcp, val, |)
-#define this_cpu_or_8(pcp, val) arch_this_cpu_to_op(pcp, val, |)
+#define this_cpu_add_return_4(pcp, val) arch_this_cpu_add_return(pcp, val, "laa")
+#define this_cpu_add_return_8(pcp, val) arch_this_cpu_add_return(pcp, val, "laag")
 
-#define this_cpu_xor_1(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
-#define this_cpu_xor_2(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
-#define this_cpu_xor_4(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
-#define this_cpu_xor_8(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
+#define arch_this_cpu_to_op(pcp, val, op)                              \
+{                                                                      \
+       typedef typeof(pcp) pcp_op_T__;                                 \
+       pcp_op_T__ val__ = (val);                                       \
+       pcp_op_T__ old__, *ptr__;                                       \
+       preempt_disable();                                              \
+       ptr__ = __this_cpu_ptr(&(pcp));                                 \
+       asm volatile(                                                   \
+               op "    %[old__],%[val__],%[ptr__]\n"                   \
+               : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__)           \
+               : [val__] "d" (val__)                                   \
+               : "cc");                                                \
+       preempt_enable();                                               \
+}
+
+#define this_cpu_and_4(pcp, val)       arch_this_cpu_to_op(pcp, val, "lan")
+#define this_cpu_and_8(pcp, val)       arch_this_cpu_to_op(pcp, val, "lang")
+#define this_cpu_or_4(pcp, val)                arch_this_cpu_to_op(pcp, val, "lao")
+#define this_cpu_or_8(pcp, val)                arch_this_cpu_to_op(pcp, val, "laog")
+
+#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
 
 #define arch_this_cpu_cmpxchg(pcp, oval, nval)                         \
 ({                                                                     \
        pcp_op_T__ *ptr__;                                              \
        preempt_disable();                                              \
        ptr__ = __this_cpu_ptr(&(pcp));                                 \
-       switch (sizeof(*ptr__)) {                                       \
-       case 8:                                                         \
-               ret__ = cmpxchg64(ptr__, oval, nval);                   \
-               break;                                                  \
-       default:                                                        \
-               ret__ = cmpxchg(ptr__, oval, nval);                     \
-       }                                                               \
+       ret__ = cmpxchg(ptr__, oval, nval);                             \
        preempt_enable();                                               \
        ret__;                                                          \
 })
 #define this_cpu_xchg_1(pcp, nval) arch_this_cpu_xchg(pcp, nval)
 #define this_cpu_xchg_2(pcp, nval) arch_this_cpu_xchg(pcp, nval)
 #define this_cpu_xchg_4(pcp, nval) arch_this_cpu_xchg(pcp, nval)
-#ifdef CONFIG_64BIT
 #define this_cpu_xchg_8(pcp, nval) arch_this_cpu_xchg(pcp, nval)
-#endif
 
 #define arch_this_cpu_cmpxchg_double(pcp1, pcp2, o1, o2, n1, n2)       \
 ({                                                                     \
 })
 
 #define this_cpu_cmpxchg_double_4 arch_this_cpu_cmpxchg_double
-#ifdef CONFIG_64BIT
 #define this_cpu_cmpxchg_double_8 arch_this_cpu_cmpxchg_double
-#endif
+
+#endif /* CONFIG_64BIT */
 
 #include <asm-generic/percpu.h>
 
index ca7821f07260301f26c2ff9314432b193ad8bebf..0a876bc543d36f3c121a39f4acf1a351233c1667 100644 (file)
@@ -134,19 +134,17 @@ struct stack_frame {
  * Do necessary setup to start up a new thread.
  */
 #define start_thread(regs, new_psw, new_stackp) do {                   \
-       regs->psw.mask  = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;    \
+       regs->psw.mask  = PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA;    \
        regs->psw.addr  = new_psw | PSW_ADDR_AMODE;                     \
        regs->gprs[15]  = new_stackp;                                   \
        execve_tail();                                                  \
 } while (0)
 
 #define start_thread31(regs, new_psw, new_stackp) do {                 \
-       regs->psw.mask  = psw_user_bits | PSW_MASK_BA;                  \
+       regs->psw.mask  = PSW_USER_BITS | PSW_MASK_BA;                  \
        regs->psw.addr  = new_psw | PSW_ADDR_AMODE;                     \
        regs->gprs[15]  = new_stackp;                                   \
-       __tlb_flush_mm(current->mm);                                    \
        crst_table_downgrade(current->mm, 1UL << 31);                   \
-       update_mm(current->mm, current);                                \
        execve_tail();                                                  \
 } while (0)
 
@@ -169,17 +167,15 @@ extern void release_thread(struct task_struct *);
  */
 extern unsigned long thread_saved_pc(struct task_struct *t);
 
-extern void show_code(struct pt_regs *regs);
-extern void print_fn_code(unsigned char *code, unsigned long len);
-extern int insn_to_mnemonic(unsigned char *instruction, char *buf,
-                           unsigned int len);
-
 unsigned long get_wchan(struct task_struct *p);
 #define task_pt_regs(tsk) ((struct pt_regs *) \
         (task_stack_page(tsk) + THREAD_SIZE) - 1)
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->psw.addr)
 #define KSTK_ESP(tsk)  (task_pt_regs(tsk)->gprs[15])
 
+/* Has task runtime instrumentation enabled ? */
+#define is_ri_task(tsk) (!!(tsk)->thread.ri_cb)
+
 static inline unsigned short stap(void)
 {
        unsigned short cpu_address;
@@ -348,9 +344,9 @@ __set_psw_mask(unsigned long mask)
 }
 
 #define local_mcck_enable() \
-       __set_psw_mask(psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK)
+       __set_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK)
 #define local_mcck_disable() \
-       __set_psw_mask(psw_kernel_bits | PSW_MASK_DAT)
+       __set_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT)
 
 /*
  * Basic Machine Check/Program Check Handler.
index 52b56533c57cda08f4d8283253ed682a13536f5c..9c82cebddabd78938b1d66baef004c74f3bd97ec 100644 (file)
 
 #ifndef __ASSEMBLY__
 
-extern long psw_kernel_bits;
-extern long psw_user_bits;
+#define PSW_KERNEL_BITS        (PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_HOME | \
+                        PSW_MASK_EA | PSW_MASK_BA)
+#define PSW_USER_BITS  (PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | \
+                        PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK | \
+                        PSW_MASK_PSTATE | PSW_ASC_PRIMARY)
 
 /*
  * The pt_regs struct defines the way the registers are stored on
index 59880dbaf360a6f39563990506e3c6a5af648aae..df802ee14af6f76591cebdc54030488b42c3d0cc 100644 (file)
@@ -48,13 +48,6 @@ void detect_memory_layout(struct mem_chunk chunk[], unsigned long maxsize);
 void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr,
                     unsigned long size);
 
-#define PRIMARY_SPACE_MODE     0
-#define ACCESS_REGISTER_MODE   1
-#define SECONDARY_SPACE_MODE   2
-#define HOME_SPACE_MODE                3
-
-extern unsigned int s390_user_mode;
-
 /*
  * Machine features detected in head.S
  */
index b64f15c3b4cc739a13e76ec3c1287328315ecb74..ac9bed8e103fa741f85b3aecc64fcc9a18511c82 100644 (file)
@@ -14,7 +14,6 @@
 #define raw_smp_processor_id() (S390_lowcore.cpu_nr)
 
 extern struct mutex smp_cpu_state_mutex;
-extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
 
 extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
 
index 6dbd559763c9996c099f14e4ce6926e15930b7f8..29c81f82705e139dc53a9af3f72b0db3d9e14695 100644 (file)
 extern struct task_struct *__switch_to(void *, void *);
 extern void update_cr_regs(struct task_struct *task);
 
-static inline void save_fp_regs(s390_fp_regs *fpregs)
+static inline int test_fp_ctl(u32 fpc)
 {
+       u32 orig_fpc;
+       int rc;
+
+       if (!MACHINE_HAS_IEEE)
+               return 0;
+
        asm volatile(
-               "       std     0,%O0+8(%R0)\n"
-               "       std     2,%O0+24(%R0)\n"
-               "       std     4,%O0+40(%R0)\n"
-               "       std     6,%O0+56(%R0)"
-               : "=Q" (*fpregs) : "Q" (*fpregs));
+               "       efpc    %1\n"
+               "       sfpc    %2\n"
+               "0:     sfpc    %1\n"
+               "       la      %0,0\n"
+               "1:\n"
+               EX_TABLE(0b,1b)
+               : "=d" (rc), "=d" (orig_fpc)
+               : "d" (fpc), "0" (-EINVAL));
+       return rc;
+}
+
+static inline void save_fp_ctl(u32 *fpc)
+{
        if (!MACHINE_HAS_IEEE)
                return;
+
        asm volatile(
-               "       stfpc   %0\n"
-               "       std     1,%O0+16(%R0)\n"
-               "       std     3,%O0+32(%R0)\n"
-               "       std     5,%O0+48(%R0)\n"
-               "       std     7,%O0+64(%R0)\n"
-               "       std     8,%O0+72(%R0)\n"
-               "       std     9,%O0+80(%R0)\n"
-               "       std     10,%O0+88(%R0)\n"
-               "       std     11,%O0+96(%R0)\n"
-               "       std     12,%O0+104(%R0)\n"
-               "       std     13,%O0+112(%R0)\n"
-               "       std     14,%O0+120(%R0)\n"
-               "       std     15,%O0+128(%R0)\n"
-               : "=Q" (*fpregs) : "Q" (*fpregs));
+               "       stfpc   %0\n"
+               : "+Q" (*fpc));
 }
 
-static inline void restore_fp_regs(s390_fp_regs *fpregs)
+static inline int restore_fp_ctl(u32 *fpc)
 {
+       int rc;
+
+       if (!MACHINE_HAS_IEEE)
+               return 0;
+
        asm volatile(
-               "       ld      0,%O0+8(%R0)\n"
-               "       ld      2,%O0+24(%R0)\n"
-               "       ld      4,%O0+40(%R0)\n"
-               "       ld      6,%O0+56(%R0)"
-               : : "Q" (*fpregs));
+               "0:     lfpc    %1\n"
+               "       la      %0,0\n"
+               "1:\n"
+               EX_TABLE(0b,1b)
+               : "=d" (rc) : "Q" (*fpc), "0" (-EINVAL));
+       return rc;
+}
+
+static inline void save_fp_regs(freg_t *fprs)
+{
+       asm volatile("std 0,%0" : "=Q" (fprs[0]));
+       asm volatile("std 2,%0" : "=Q" (fprs[2]));
+       asm volatile("std 4,%0" : "=Q" (fprs[4]));
+       asm volatile("std 6,%0" : "=Q" (fprs[6]));
        if (!MACHINE_HAS_IEEE)
                return;
-       asm volatile(
-               "       lfpc    %0\n"
-               "       ld      1,%O0+16(%R0)\n"
-               "       ld      3,%O0+32(%R0)\n"
-               "       ld      5,%O0+48(%R0)\n"
-               "       ld      7,%O0+64(%R0)\n"
-               "       ld      8,%O0+72(%R0)\n"
-               "       ld      9,%O0+80(%R0)\n"
-               "       ld      10,%O0+88(%R0)\n"
-               "       ld      11,%O0+96(%R0)\n"
-               "       ld      12,%O0+104(%R0)\n"
-               "       ld      13,%O0+112(%R0)\n"
-               "       ld      14,%O0+120(%R0)\n"
-               "       ld      15,%O0+128(%R0)\n"
-               : : "Q" (*fpregs));
+       asm volatile("std 1,%0" : "=Q" (fprs[1]));
+       asm volatile("std 3,%0" : "=Q" (fprs[3]));
+       asm volatile("std 5,%0" : "=Q" (fprs[5]));
+       asm volatile("std 7,%0" : "=Q" (fprs[7]));
+       asm volatile("std 8,%0" : "=Q" (fprs[8]));
+       asm volatile("std 9,%0" : "=Q" (fprs[9]));
+       asm volatile("std 10,%0" : "=Q" (fprs[10]));
+       asm volatile("std 11,%0" : "=Q" (fprs[11]));
+       asm volatile("std 12,%0" : "=Q" (fprs[12]));
+       asm volatile("std 13,%0" : "=Q" (fprs[13]));
+       asm volatile("std 14,%0" : "=Q" (fprs[14]));
+       asm volatile("std 15,%0" : "=Q" (fprs[15]));
+}
+
+static inline void restore_fp_regs(freg_t *fprs)
+{
+       asm volatile("ld 0,%0" : : "Q" (fprs[0]));
+       asm volatile("ld 2,%0" : : "Q" (fprs[2]));
+       asm volatile("ld 4,%0" : : "Q" (fprs[4]));
+       asm volatile("ld 6,%0" : : "Q" (fprs[6]));
+       if (!MACHINE_HAS_IEEE)
+               return;
+       asm volatile("ld 1,%0" : : "Q" (fprs[1]));
+       asm volatile("ld 3,%0" : : "Q" (fprs[3]));
+       asm volatile("ld 5,%0" : : "Q" (fprs[5]));
+       asm volatile("ld 7,%0" : : "Q" (fprs[7]));
+       asm volatile("ld 8,%0" : : "Q" (fprs[8]));
+       asm volatile("ld 9,%0" : : "Q" (fprs[9]));
+       asm volatile("ld 10,%0" : : "Q" (fprs[10]));
+       asm volatile("ld 11,%0" : : "Q" (fprs[11]));
+       asm volatile("ld 12,%0" : : "Q" (fprs[12]));
+       asm volatile("ld 13,%0" : : "Q" (fprs[13]));
+       asm volatile("ld 14,%0" : : "Q" (fprs[14]));
+       asm volatile("ld 15,%0" : : "Q" (fprs[15]));
 }
 
 static inline void save_access_regs(unsigned int *acrs)
@@ -83,12 +119,14 @@ static inline void restore_access_regs(unsigned int *acrs)
 
 #define switch_to(prev,next,last) do {                                 \
        if (prev->mm) {                                                 \
-               save_fp_regs(&prev->thread.fp_regs);                    \
+               save_fp_ctl(&prev->thread.fp_regs.fpc);                 \
+               save_fp_regs(prev->thread.fp_regs.fprs);                \
                save_access_regs(&prev->thread.acrs[0]);                \
                save_ri_cb(prev->thread.ri_cb);                         \
        }                                                               \
        if (next->mm) {                                                 \
-               restore_fp_regs(&next->thread.fp_regs);                 \
+               restore_fp_ctl(&next->thread.fp_regs.fpc);              \
+               restore_fp_regs(next->thread.fp_regs.fprs);             \
                restore_access_regs(&next->thread.acrs[0]);             \
                restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);  \
                update_cr_regs(next);                                   \
index 819b94d2272054d318fdd12c31b8718a9e4bb0bd..8beee1cceba4ed17831736a11c6f5167155335d6 100644 (file)
@@ -71,9 +71,11 @@ static inline void local_tick_enable(unsigned long long comp)
 
 typedef unsigned long long cycles_t;
 
-static inline void get_tod_clock_ext(char *clk)
+static inline void get_tod_clock_ext(char clk[16])
 {
-       asm volatile("stcke %0" : "=Q" (*clk) : : "cc");
+       typedef struct { char _[sizeof(clk)]; } addrtype;
+
+       asm volatile("stcke %0" : "=Q" (*(addrtype *) clk) : : "cc");
 }
 
 static inline unsigned long long get_tod_clock(void)
index 9c33ed4e666f5cd920933f6ad9fa5463d83dd1c1..79330af9a5f85442745110001defbaa2a1964bb8 100644 (file)
@@ -94,9 +94,7 @@ static inline unsigned long extable_fixup(const struct exception_table_entry *x)
 
 struct uaccess_ops {
        size_t (*copy_from_user)(size_t, const void __user *, void *);
-       size_t (*copy_from_user_small)(size_t, const void __user *, void *);
        size_t (*copy_to_user)(size_t, void __user *, const void *);
-       size_t (*copy_to_user_small)(size_t, void __user *, const void *);
        size_t (*copy_in_user)(size_t, void __user *, const void __user *);
        size_t (*clear_user)(size_t, void __user *);
        size_t (*strnlen_user)(size_t, const char __user *);
@@ -106,22 +104,20 @@ struct uaccess_ops {
 };
 
 extern struct uaccess_ops uaccess;
-extern struct uaccess_ops uaccess_std;
 extern struct uaccess_ops uaccess_mvcos;
-extern struct uaccess_ops uaccess_mvcos_switch;
 extern struct uaccess_ops uaccess_pt;
 
 extern int __handle_fault(unsigned long, unsigned long, int);
 
 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
 {
-       size = uaccess.copy_to_user_small(size, ptr, x);
+       size = uaccess.copy_to_user(size, ptr, x);
        return size ? -EFAULT : size;
 }
 
 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
 {
-       size = uaccess.copy_from_user_small(size, ptr, x);
+       size = uaccess.copy_from_user(size, ptr, x);
        return size ? -EFAULT : size;
 }
 
@@ -226,10 +222,7 @@ extern int __get_user_bad(void) __attribute__((noreturn));
 static inline unsigned long __must_check
 __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-       if (__builtin_constant_p(n) && (n <= 256))
-               return uaccess.copy_to_user_small(n, to, from);
-       else
-               return uaccess.copy_to_user(n, to, from);
+       return uaccess.copy_to_user(n, to, from);
 }
 
 #define __copy_to_user_inatomic __copy_to_user
@@ -275,10 +268,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
 static inline unsigned long __must_check
 __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-       if (__builtin_constant_p(n) && (n <= 256))
-               return uaccess.copy_from_user_small(n, from, to);
-       else
-               return uaccess.copy_from_user(n, from, to);
+       return uaccess.copy_from_user(n, from, to);
 }
 
 extern void copy_from_user_overflow(void)
index 7a84619e315e804af6d7c6a535c4df7981e082e3..7e0b498a2c2ba95c8ca56537e673b18c4a0065d3 100644 (file)
@@ -199,6 +199,7 @@ typedef union
 typedef struct
 {
        __u32   fpc;
+       __u32   pad;
        freg_t  fprs[NUM_FPRS];              
 } s390_fp_regs;
 
@@ -206,7 +207,6 @@ typedef struct
 #define FPC_FLAGS_MASK          0x00F80000
 #define FPC_DXC_MASK            0x0000FF00
 #define FPC_RM_MASK             0x00000003
-#define FPC_VALID_MASK          0xF8F8FF03
 
 /* this typedef defines how a Program Status Word looks like */
 typedef struct 
@@ -263,7 +263,7 @@ typedef struct
 #define PSW_MASK_EA            0x0000000100000000UL
 #define PSW_MASK_BA            0x0000000080000000UL
 
-#define PSW_MASK_USER          0x0000FF8180000000UL
+#define PSW_MASK_USER          0x0000FF0180000000UL
 
 #define PSW_ADDR_AMODE         0x0000000000000000UL
 #define PSW_ADDR_INSN          0xFFFFFFFFFFFFFFFFUL
index 584787f6ce44d88569b964bf8543a5c74475e030..b30de9c01bbedad00c5e15ff52ffa8d19b06c824 100644 (file)
@@ -49,6 +49,7 @@ typedef struct
 typedef struct
 {
        unsigned int fpc;
+       unsigned int pad;
        double   fprs[__NUM_FPRS];
 } _s390_fp_regs;
 
index 4bb2a46561631ab361c027fdcfc8a1dfd0504cb5..2403303cfed708d3ae73a0b0091cab67c21f6f9f 100644 (file)
@@ -28,7 +28,7 @@ CFLAGS_ptrace.o               += -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
 CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
 
-obj-y  := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o
+obj-y  := traps.o time.o process.o base.o early.o setup.o vtime.o
 obj-y  += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
 obj-y  += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o
 obj-y  += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
diff --git a/arch/s390/kernel/bitmap.c b/arch/s390/kernel/bitmap.c
deleted file mode 100644 (file)
index 102da5e..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *    Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
- *    See include/asm/{bitops.h|posix_types.h} for details
- *
- *    Copyright IBM Corp. 1999, 2009
- *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
- */
-
-#include <linux/bitops.h>
-#include <linux/module.h>
-
-const char _oi_bitmap[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
-EXPORT_SYMBOL(_oi_bitmap);
-
-const char _ni_bitmap[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
-EXPORT_SYMBOL(_ni_bitmap);
-
-const char _zb_findmap[] = {
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
-       0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 };
-EXPORT_SYMBOL(_zb_findmap);
-
-const char _sb_findmap[] = {
-       8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
-       4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 };
-EXPORT_SYMBOL(_sb_findmap);
index dd62071624be349ca1913ed4404e826ecd6b673e..3a414c0f93edcd08d69d3a1aa2af645c098327c9 100644 (file)
@@ -146,15 +146,14 @@ static void __init cache_build_info(void)
        ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0);
        for (level = 0; level < CACHE_MAX_LEVEL; level++) {
                switch (ct.ci[level].scope) {
-               case CACHE_SCOPE_NOTEXISTS:
-               case CACHE_SCOPE_RESERVED:
-                       return;
                case CACHE_SCOPE_SHARED:
                        private = 0;
                        break;
                case CACHE_SCOPE_PRIVATE:
                        private = 1;
                        break;
+               default:
+                       return;
                }
                if (ct.ci[level].type == CACHE_TYPE_SEPARATE) {
                        rc  = cache_add(level, private, CACHE_TYPE_DATA);
index 1f1b8c70ab97ce9e5b9445d5dc020f8a75bfac77..e030d2bdec1b6aa2b9f29288b28c6600710ecfd1 100644 (file)
 
 #include "compat_linux.h"
 
-u32 psw32_user_bits = PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT |
-                     PSW32_DEFAULT_KEY | PSW32_MASK_BASE | PSW32_MASK_MCHECK |
-                     PSW32_MASK_PSTATE | PSW32_ASC_HOME;
 /* For this source file, we want overflow handling. */
 
 #undef high2lowuid
index 976518c0592aa96a29565bac78d58fa8fcfdd846..1bfda3eca37909988c26564b11398b6b75302c50 100644 (file)
@@ -27,6 +27,7 @@ typedef union
 typedef struct
 {
        unsigned int    fpc;
+       unsigned int    pad;
        freg_t32        fprs[__NUM_FPRS];              
 } _s390_fp_regs32;
 
index adaa9e9478d83fb77a2e91a41de0934f84acfb66..5a3ab5c191fdaf7f370a14cc69d52eb9d3052647 100644 (file)
@@ -153,57 +153,66 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 
 static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
 {
-       _s390_regs_common32 regs32;
-       int err, i;
+       _sigregs32 user_sregs;
+       int i;
 
-       regs32.psw.mask = psw32_user_bits |
-               ((__u32)(regs->psw.mask >> 32) & PSW32_MASK_USER);
-       regs32.psw.addr = (__u32) regs->psw.addr |
+       user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
+       user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
+       user_sregs.regs.psw.mask |= PSW32_USER_BITS;
+       user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
                (__u32)(regs->psw.mask & PSW_MASK_BA);
        for (i = 0; i < NUM_GPRS; i++)
-               regs32.gprs[i] = (__u32) regs->gprs[i];
+               user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
        save_access_regs(current->thread.acrs);
-       memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs));
-       err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
-       if (err)
-               return err;
-       save_fp_regs(&current->thread.fp_regs);
-       /* s390_fp_regs and _s390_fp_regs32 are the same ! */
-       return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
-                             sizeof(_s390_fp_regs32));
+       memcpy(&user_sregs.regs.acrs, current->thread.acrs,
+              sizeof(user_sregs.regs.acrs));
+       save_fp_ctl(&current->thread.fp_regs.fpc);
+       save_fp_regs(current->thread.fp_regs.fprs);
+       memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
+              sizeof(user_sregs.fpregs));
+       if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
+               return -EFAULT;
+       return 0;
 }
 
 static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
 {
-       _s390_regs_common32 regs32;
-       int err, i;
+       _sigregs32 user_sregs;
+       int i;
 
        /* Alwys make any pending restarted system call return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
-       err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
-       if (err)
-               return err;
+       if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
+               return -EFAULT;
+
+       if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI))
+               return -EINVAL;
+
+       /* Loading the floating-point-control word can fail. Do that first. */
+       if (restore_fp_ctl(&user_sregs.fpregs.fpc))
+               return -EINVAL;
+
+       /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
-               (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
-               (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE);
+               (__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);
        /* Check for invalid user address space control. */
-       if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
-               regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
+       if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
+               regs->psw.mask = PSW_ASC_PRIMARY |
                        (regs->psw.mask & ~PSW_MASK_ASC);
-       regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
+       regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
        for (i = 0; i < NUM_GPRS; i++)
-               regs->gprs[i] = (__u64) regs32.gprs[i];
-       memcpy(current->thread.acrs, regs32.acrs, sizeof(current->thread.acrs));
+               regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
+       memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
+              sizeof(current->thread.acrs));
        restore_access_regs(current->thread.acrs);
 
-       err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
-                              sizeof(_s390_fp_regs32));
-       current->thread.fp_regs.fpc &= FPC_VALID_MASK;
-       if (err)
-               return err;
+       memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
+              sizeof(current->thread.fp_regs));
 
-       restore_fp_regs(&current->thread.fp_regs);
+       restore_fp_regs(current->thread.fp_regs.fprs);
        clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
        return 0;
 }
@@ -215,18 +224,18 @@ static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
 
        for (i = 0; i < NUM_GPRS; i++)
                gprs_high[i] = regs->gprs[i] >> 32;
-
-       return __copy_to_user(uregs, &gprs_high, sizeof(gprs_high));
+       if (__copy_to_user(uregs, &gprs_high, sizeof(gprs_high)))
+               return -EFAULT;
+       return 0;
 }
 
 static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
 {
        __u32 gprs_high[NUM_GPRS];
-       int err, i;
+       int i;
 
-       err = __copy_from_user(&gprs_high, uregs, sizeof(gprs_high));
-       if (err)
-               return err;
+       if (__copy_from_user(&gprs_high, uregs, sizeof(gprs_high)))
+               return -EFAULT;
        for (i = 0; i < NUM_GPRS; i++)
                *(__u32 *)&regs->gprs[i] = gprs_high[i];
        return 0;
@@ -348,7 +357,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
        regs->gprs[15] = (__force __u64) frame;
        /* Force 31 bit amode and default user address space control. */
        regs->psw.mask = PSW_MASK_BA |
-               (psw_user_bits & PSW_MASK_ASC) |
+               (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
        regs->psw.addr = (__force __u64) ka->sa.sa_handler;
 
@@ -415,7 +424,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->gprs[15] = (__force __u64) frame;
        /* Force 31 bit amode and default user address space control. */
        regs->psw.mask = PSW_MASK_BA |
-               (psw_user_bits & PSW_MASK_ASC) |
+               (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
        regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
 
index 7dd21720e5b002d03ff406afb12faf546f09e9f3..f45b2ab0cb81ae425ce2d72c2de9b6fa4fa241a3 100644 (file)
 #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
 #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y))))
 
+struct dump_save_areas dump_save_areas;
+
+/*
+ * Allocate and add a save area for a CPU
+ */
+struct save_area *dump_save_area_create(int cpu)
+{
+       struct save_area **save_areas, *save_area;
+
+       save_area = kmalloc(sizeof(*save_area), GFP_KERNEL);
+       if (!save_area)
+               return NULL;
+       if (cpu + 1 > dump_save_areas.count) {
+               dump_save_areas.count = cpu + 1;
+               save_areas = krealloc(dump_save_areas.areas,
+                                     dump_save_areas.count * sizeof(void *),
+                                     GFP_KERNEL | __GFP_ZERO);
+               if (!save_areas) {
+                       kfree(save_area);
+                       return NULL;
+               }
+               dump_save_areas.areas = save_areas;
+       }
+       dump_save_areas.areas[cpu] = save_area;
+       return save_area;
+}
 
 /*
  * Return physical address for virtual address
@@ -45,7 +71,6 @@ static inline void *load_real_addr(void *addr)
 static int copy_from_realmem(void *dest, void *src, size_t count)
 {
        unsigned long size;
-       int rc;
 
        if (!count)
                return 0;
@@ -451,8 +476,8 @@ static int get_cpu_cnt(void)
 {
        int i, cpus = 0;
 
-       for (i = 0; zfcpdump_save_areas[i]; i++) {
-               if (zfcpdump_save_areas[i]->pref_reg == 0)
+       for (i = 0; i < dump_save_areas.count; i++) {
+               if (dump_save_areas.areas[i]->pref_reg == 0)
                        continue;
                cpus++;
        }
@@ -523,8 +548,8 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
 
        ptr = nt_prpsinfo(ptr);
 
-       for (i = 0; zfcpdump_save_areas[i]; i++) {
-               sa = zfcpdump_save_areas[i];
+       for (i = 0; i < dump_save_areas.count; i++) {
+               sa = dump_save_areas.areas[i];
                if (sa->pref_reg == 0)
                        continue;
                ptr = fill_cpu_elf_notes(ptr, sa);
index 17d62fe5d7b70554c36b8f85b34da23d86c90407..ee8390da6ea712943209af03e2d0e9bc3c0106f1 100644 (file)
@@ -889,7 +889,7 @@ static int debug_active=1;
  * if debug_active is already off
  */
 static int
-s390dbf_procactive(ctl_table *table, int write,
+s390dbf_procactive(struct ctl_table *table, int write,
                      void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        if (!write || debug_stoppable || !debug_active)
index be87d3e05a5be69265a6100f87afe2fa60d51137..993efe6a887c2c31d4bcd90b02bccbb3c0234ae9 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kdebug.h>
 
 #include <asm/uaccess.h>
+#include <asm/dis.h>
 #include <asm/io.h>
 #include <linux/atomic.h>
 #include <asm/mathemu.h>
 #define ONELONG "%016lx: "
 #endif /* CONFIG_64BIT */
 
-#define OPERAND_GPR    0x1     /* Operand printed as %rx */
-#define OPERAND_FPR    0x2     /* Operand printed as %fx */
-#define OPERAND_AR     0x4     /* Operand printed as %ax */
-#define OPERAND_CR     0x8     /* Operand printed as %cx */
-#define OPERAND_DISP   0x10    /* Operand printed as displacement */
-#define OPERAND_BASE   0x20    /* Operand printed as base register */
-#define OPERAND_INDEX  0x40    /* Operand printed as index register */
-#define OPERAND_PCREL  0x80    /* Operand printed as pc-relative symbol */
-#define OPERAND_SIGNED 0x100   /* Operand printed as signed value */
-#define OPERAND_LENGTH 0x200   /* Operand printed as length (+1) */
-
 enum {
        UNUSED, /* Indicates the end of the operand list */
        R_8,    /* GPR starting at position 8 */
@@ -155,19 +145,7 @@ enum {
        INSTR_S_00, INSTR_S_RD,
 };
 
-struct operand {
-       int bits;               /* The number of bits in the operand. */
-       int shift;              /* The number of bits to shift. */
-       int flags;              /* One bit syntax flags. */
-};
-
-struct insn {
-       const char name[5];
-       unsigned char opfrag;
-       unsigned char format;
-};
-
-static const struct operand operands[] =
+static const struct s390_operand operands[] =
 {
        [UNUSED]  = { 0, 0, 0 },
        [R_8]    = {  4,  8, OPERAND_GPR },
@@ -479,7 +457,7 @@ static char *long_insn_name[] = {
        [LONG_INSN_PCISTB] = "pcistb",
 };
 
-static struct insn opcode[] = {
+static struct s390_insn opcode[] = {
 #ifdef CONFIG_64BIT
        { "bprp", 0xc5, INSTR_MII_UPI },
        { "bpp", 0xc7, INSTR_SMI_U0RDP },
@@ -668,7 +646,7 @@ static struct insn opcode[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_01[] = {
+static struct s390_insn opcode_01[] = {
 #ifdef CONFIG_64BIT
        { "ptff", 0x04, INSTR_E },
        { "pfpo", 0x0a, INSTR_E },
@@ -684,7 +662,7 @@ static struct insn opcode_01[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_a5[] = {
+static struct s390_insn opcode_a5[] = {
 #ifdef CONFIG_64BIT
        { "iihh", 0x00, INSTR_RI_RU },
        { "iihl", 0x01, INSTR_RI_RU },
@@ -706,7 +684,7 @@ static struct insn opcode_a5[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_a7[] = {
+static struct s390_insn opcode_a7[] = {
 #ifdef CONFIG_64BIT
        { "tmhh", 0x02, INSTR_RI_RU },
        { "tmhl", 0x03, INSTR_RI_RU },
@@ -728,7 +706,7 @@ static struct insn opcode_a7[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_aa[] = {
+static struct s390_insn opcode_aa[] = {
 #ifdef CONFIG_64BIT
        { { 0, LONG_INSN_RINEXT }, 0x00, INSTR_RI_RI },
        { "rion", 0x01, INSTR_RI_RI },
@@ -739,7 +717,7 @@ static struct insn opcode_aa[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_b2[] = {
+static struct s390_insn opcode_b2[] = {
 #ifdef CONFIG_64BIT
        { "stckf", 0x7c, INSTR_S_RD },
        { "lpp", 0x80, INSTR_S_RD },
@@ -851,7 +829,7 @@ static struct insn opcode_b2[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_b3[] = {
+static struct s390_insn opcode_b3[] = {
 #ifdef CONFIG_64BIT
        { "maylr", 0x38, INSTR_RRF_F0FF },
        { "mylr", 0x39, INSTR_RRF_F0FF },
@@ -1034,7 +1012,7 @@ static struct insn opcode_b3[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_b9[] = {
+static struct s390_insn opcode_b9[] = {
 #ifdef CONFIG_64BIT
        { "lpgr", 0x00, INSTR_RRE_RR },
        { "lngr", 0x01, INSTR_RRE_RR },
@@ -1167,7 +1145,7 @@ static struct insn opcode_b9[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_c0[] = {
+static struct s390_insn opcode_c0[] = {
 #ifdef CONFIG_64BIT
        { "lgfi", 0x01, INSTR_RIL_RI },
        { "xihf", 0x06, INSTR_RIL_RU },
@@ -1187,7 +1165,7 @@ static struct insn opcode_c0[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_c2[] = {
+static struct s390_insn opcode_c2[] = {
 #ifdef CONFIG_64BIT
        { "msgfi", 0x00, INSTR_RIL_RI },
        { "msfi", 0x01, INSTR_RIL_RI },
@@ -1205,7 +1183,7 @@ static struct insn opcode_c2[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_c4[] = {
+static struct s390_insn opcode_c4[] = {
 #ifdef CONFIG_64BIT
        { "llhrl", 0x02, INSTR_RIL_RP },
        { "lghrl", 0x04, INSTR_RIL_RP },
@@ -1222,7 +1200,7 @@ static struct insn opcode_c4[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_c6[] = {
+static struct s390_insn opcode_c6[] = {
 #ifdef CONFIG_64BIT
        { "exrl", 0x00, INSTR_RIL_RP },
        { "pfdrl", 0x02, INSTR_RIL_UP },
@@ -1240,7 +1218,7 @@ static struct insn opcode_c6[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_c8[] = {
+static struct s390_insn opcode_c8[] = {
 #ifdef CONFIG_64BIT
        { "mvcos", 0x00, INSTR_SSF_RRDRD },
        { "ectg", 0x01, INSTR_SSF_RRDRD },
@@ -1251,7 +1229,7 @@ static struct insn opcode_c8[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_cc[] = {
+static struct s390_insn opcode_cc[] = {
 #ifdef CONFIG_64BIT
        { "brcth", 0x06, INSTR_RIL_RP },
        { "aih", 0x08, INSTR_RIL_RI },
@@ -1263,7 +1241,7 @@ static struct insn opcode_cc[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_e3[] = {
+static struct s390_insn opcode_e3[] = {
 #ifdef CONFIG_64BIT
        { "ltg", 0x02, INSTR_RXY_RRRD },
        { "lrag", 0x03, INSTR_RXY_RRRD },
@@ -1369,7 +1347,7 @@ static struct insn opcode_e3[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_e5[] = {
+static struct s390_insn opcode_e5[] = {
 #ifdef CONFIG_64BIT
        { "strag", 0x02, INSTR_SSE_RDRD },
        { "mvhhi", 0x44, INSTR_SIL_RDI },
@@ -1391,7 +1369,7 @@ static struct insn opcode_e5[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_eb[] = {
+static struct s390_insn opcode_eb[] = {
 #ifdef CONFIG_64BIT
        { "lmg", 0x04, INSTR_RSY_RRRD },
        { "srag", 0x0a, INSTR_RSY_RRRD },
@@ -1465,7 +1443,7 @@ static struct insn opcode_eb[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_ec[] = {
+static struct s390_insn opcode_ec[] = {
 #ifdef CONFIG_64BIT
        { "brxhg", 0x44, INSTR_RIE_RRP },
        { "brxlg", 0x45, INSTR_RIE_RRP },
@@ -1504,7 +1482,7 @@ static struct insn opcode_ec[] = {
        { "", 0, INSTR_INVALID }
 };
 
-static struct insn opcode_ed[] = {
+static struct s390_insn opcode_ed[] = {
 #ifdef CONFIG_64BIT
        { "mayl", 0x38, INSTR_RXF_FRRDF },
        { "myl", 0x39, INSTR_RXF_FRRDF },
@@ -1572,7 +1550,7 @@ static struct insn opcode_ed[] = {
 
 /* Extracts an operand value from an instruction.  */
 static unsigned int extract_operand(unsigned char *code,
-                                   const struct operand *operand)
+                                   const struct s390_operand *operand)
 {
        unsigned int val;
        int bits;
@@ -1608,16 +1586,11 @@ static unsigned int extract_operand(unsigned char *code,
        return val;
 }
 
-static inline int insn_length(unsigned char code)
-{
-       return ((((int) code + 64) >> 7) + 1) << 1;
-}
-
-static struct insn *find_insn(unsigned char *code)
+struct s390_insn *find_insn(unsigned char *code)
 {
        unsigned char opfrag = code[1];
        unsigned char opmask;
-       struct insn *table;
+       struct s390_insn *table;
 
        switch (code[0]) {
        case 0x01:
@@ -1706,7 +1679,7 @@ static struct insn *find_insn(unsigned char *code)
  */
 int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len)
 {
-       struct insn *insn;
+       struct s390_insn *insn;
 
        insn = find_insn(instruction);
        if (!insn)
@@ -1722,9 +1695,9 @@ EXPORT_SYMBOL_GPL(insn_to_mnemonic);
 
 static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
 {
-       struct insn *insn;
+       struct s390_insn *insn;
        const unsigned char *ops;
-       const struct operand *operand;
+       const struct s390_operand *operand;
        unsigned int value;
        char separator;
        char *ptr;
index 99e7f6035895e0cceccbc0ae6bf123a871a5d6a3..e6af9406987c9982689e5f500612f14d49c1b0b0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <asm/processor.h>
 #include <asm/debug.h>
+#include <asm/dis.h>
 #include <asm/ipl.h>
 
 #ifndef CONFIG_64BIT
index dc8770d7173c83aec5b3475d748eee99d99e60b7..96543ac400a7820ede40f22bf9636753920456b7 100644 (file)
@@ -206,6 +206,7 @@ static noinline __init void clear_bss_section(void)
  */
 static noinline __init void init_kernel_storage_key(void)
 {
+#if PAGE_DEFAULT_KEY
        unsigned long end_pfn, init_pfn;
 
        end_pfn = PFN_UP(__pa(&_end));
@@ -213,6 +214,7 @@ static noinline __init void init_kernel_storage_key(void)
        for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
                page_set_storage_key(init_pfn << PAGE_SHIFT,
                                     PAGE_DEFAULT_KEY, 0);
+#endif
 }
 
 static __initdata char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE);
index e9b04c33d38306781f1c5d3ead2c5a3ba3b0d009..cb533f78c09ed5795ee365eec00374c5db662a9c 100644 (file)
@@ -23,7 +23,6 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
 
 void do_protection_exception(struct pt_regs *regs);
 void do_dat_exception(struct pt_regs *regs);
-void do_asce_exception(struct pt_regs *regs);
 
 void addressing_exception(struct pt_regs *regs);
 void data_exception(struct pt_regs *regs);
index 1014ad5f7693eda79c3caa4ad8b7e8b5edb5f3fc..224db03e95182adc3976aecb3b20f0de5d2b0b13 100644 (file)
@@ -151,14 +151,13 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent,
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                goto out;
        ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE;
-       if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
-               goto out;
        trace.func = ip;
+       trace.depth = current->curr_ret_stack + 1;
        /* Only trace if the calling function expects to. */
-       if (!ftrace_graph_entry(&trace)) {
-               current->curr_ret_stack--;
+       if (!ftrace_graph_entry(&trace))
+               goto out;
+       if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
                goto out;
-       }
        parent = (unsigned long) return_to_handler;
 out:
        return parent;
index fd8db63dfc942a211d9dfe95b8c2bff88b90ed8d..429afcc480cb2e86c7e684e81c6f1f1160ee3b05 100644 (file)
@@ -437,7 +437,7 @@ ENTRY(startup_kdump)
 
 #if defined(CONFIG_64BIT)
 #if defined(CONFIG_MARCH_ZEC12)
-       .long 3, 0xc100efe3, 0xf46ce000, 0x00400000
+       .long 3, 0xc100efe3, 0xf46ce800, 0x00400000
 #elif defined(CONFIG_MARCH_Z196)
        .long 2, 0xc100efe3, 0xf46c0000
 #elif defined(CONFIG_MARCH_Z10)
index feb719d3c85160b586dd6af4d936f363936c4419..633ca7504536c10a517667b5f582653f763390e3 100644 (file)
@@ -2051,12 +2051,12 @@ void s390_reset_system(void (*func)(void *), void *data)
        __ctl_clear_bit(0,28);
 
        /* Set new machine check handler */
-       S390_lowcore.mcck_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT;
+       S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
        S390_lowcore.mcck_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
 
        /* Set new program check handler */
-       S390_lowcore.program_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT;
+       S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
        S390_lowcore.program_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 
index 8ac2097f13d4e99eeaf913baca503f4532e3a055..bb27a262c44aa8076dfe7eb9cb5a243d8c315079 100644 (file)
@@ -157,39 +157,29 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 /*
  * Switch to the asynchronous interrupt stack for softirq execution.
  */
-asmlinkage void do_softirq(void)
+void do_softirq_own_stack(void)
 {
-       unsigned long flags, old, new;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       if (local_softirq_pending()) {
-               /* Get current stack pointer. */
-               asm volatile("la %0,0(15)" : "=a" (old));
-               /* Check against async. stack address range. */
-               new = S390_lowcore.async_stack;
-               if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) {
-                       /* Need to switch to the async. stack. */
-                       new -= STACK_FRAME_OVERHEAD;
-                       ((struct stack_frame *) new)->back_chain = old;
-
-                       asm volatile("   la    15,0(%0)\n"
-                                    "   basr  14,%2\n"
-                                    "   la    15,0(%1)\n"
-                                    : : "a" (new), "a" (old),
-                                        "a" (__do_softirq)
-                                    : "0", "1", "2", "3", "4", "5", "14",
-                                      "cc", "memory" );
-               } else {
-                       /* We are already on the async stack. */
-                       __do_softirq();
-               }
+       unsigned long old, new;
+
+       /* Get current stack pointer. */
+       asm volatile("la %0,0(15)" : "=a" (old));
+       /* Check against async. stack address range. */
+       new = S390_lowcore.async_stack;
+       if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) {
+               /* Need to switch to the async. stack. */
+               new -= STACK_FRAME_OVERHEAD;
+               ((struct stack_frame *) new)->back_chain = old;
+               asm volatile("   la    15,0(%0)\n"
+                            "   basr  14,%2\n"
+                            "   la    15,0(%1)\n"
+                            : : "a" (new), "a" (old),
+                                "a" (__do_softirq)
+                            : "0", "1", "2", "3", "4", "5", "14",
+                              "cc", "memory" );
+       } else {
+               /* We are already on the async stack. */
+               __do_softirq();
        }
-
-       local_irq_restore(flags);
 }
 
 /*
index d86e64eddb42efdedf44078cc8e29a51247eba87..59a9c35c4598ae3265c60f69f8f87ca0a1538c2d 100644 (file)
 #include <linux/stop_machine.h>
 #include <linux/kdebug.h>
 #include <linux/uaccess.h>
-#include <asm/cacheflush.h>
-#include <asm/sections.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/hardirq.h>
+#include <asm/cacheflush.h>
+#include <asm/sections.h>
+#include <asm/dis.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe);
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -59,6 +60,8 @@ struct kprobe_insn_cache kprobe_dmainsn_slots = {
 
 static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn)
 {
+       if (!is_known_insn((unsigned char *)insn))
+               return -EINVAL;
        switch (insn[0] >> 8) {
        case 0x0c:      /* bassm */
        case 0x0b:      /* bsm   */
@@ -208,7 +211,7 @@ static void __kprobes copy_instruction(struct kprobe *p)
        s64 disp, new_disp;
        u64 addr, new_addr;
 
-       memcpy(p->ainsn.insn, p->addr, ((p->opcode >> 14) + 3) & -2);
+       memcpy(p->ainsn.insn, p->addr, insn_length(p->opcode >> 8));
        if (!is_insn_relative_long(p->ainsn.insn))
                return;
        /*
@@ -252,7 +255,7 @@ static int __kprobes s390_get_insn_slot(struct kprobe *p)
        p->ainsn.insn = NULL;
        if (is_kernel_addr(p->addr))
                p->ainsn.insn = get_dmainsn_slot();
-       if (is_module_addr(p->addr))
+       else if (is_module_addr(p->addr))
                p->ainsn.insn = get_insn_slot();
        return p->ainsn.insn ? 0 : -ENOMEM;
 }
@@ -608,7 +611,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
                ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn;
 
        if (fixup & FIXUP_BRANCH_NOT_TAKEN) {
-               int ilen = ((p->ainsn.insn[0] >> 14) + 3) & -2;
+               int ilen = insn_length(p->ainsn.insn[0] >> 8);
                if (ip - (unsigned long) p->ainsn.insn == ilen)
                        ip = (unsigned long) p->addr + ilen;
        }
index 14bdecb619238b6994f890e9263a10cd515189f1..4a460c44e17ec15763da0cf24207ed048fa929f9 100644 (file)
@@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT                     /* 34 */
 PGM_CHECK_DEFAULT                      /* 35 */
 PGM_CHECK_DEFAULT                      /* 36 */
 PGM_CHECK_DEFAULT                      /* 37 */
-PGM_CHECK_64BIT(do_asce_exception)     /* 38 */
+PGM_CHECK_DEFAULT                      /* 38 */
 PGM_CHECK_64BIT(do_dat_exception)      /* 39 */
 PGM_CHECK_64BIT(do_dat_exception)      /* 3a */
 PGM_CHECK_64BIT(do_dat_exception)      /* 3b */
index c5dbb335716d5e2cdc864fc6b189a46af74ba5d3..7ed0d4e2a435452733173767b56af52163334980 100644 (file)
@@ -139,7 +139,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
        if (unlikely(p->flags & PF_KTHREAD)) {
                /* kernel thread */
                memset(&frame->childregs, 0, sizeof(struct pt_regs));
-               frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
+               frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT |
                                PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
                frame->childregs.psw.addr = PSW_ADDR_AMODE |
                                (unsigned long) kernel_thread_starter;
@@ -165,7 +165,8 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
         * save fprs to current->thread.fp_regs to merge them with
         * the emulated registers and then copy the result to the child.
         */
-       save_fp_regs(&current->thread.fp_regs);
+       save_fp_ctl(&current->thread.fp_regs.fpc);
+       save_fp_regs(current->thread.fp_regs.fprs);
        memcpy(&p->thread.fp_regs, &current->thread.fp_regs,
               sizeof(s390_fp_regs));
        /* Set a new TLS ?  */
@@ -173,7 +174,9 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
                p->thread.acrs[0] = frame->childregs.gprs[6];
 #else /* CONFIG_64BIT */
        /* Save the fpu registers to new thread structure. */
-       save_fp_regs(&p->thread.fp_regs);
+       save_fp_ctl(&p->thread.fp_regs.fpc);
+       save_fp_regs(p->thread.fp_regs.fprs);
+       p->thread.fp_regs.pad = 0;
        /* Set a new TLS ?  */
        if (clone_flags & CLONE_SETTLS) {
                unsigned long tls = frame->childregs.gprs[6];
@@ -205,10 +208,12 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
         * save fprs to current->thread.fp_regs to merge them with
         * the emulated registers and then copy the result to the dump.
         */
-       save_fp_regs(&current->thread.fp_regs);
+       save_fp_ctl(&current->thread.fp_regs.fpc);
+       save_fp_regs(current->thread.fp_regs.fprs);
        memcpy(fpregs, &current->thread.fp_regs, sizeof(s390_fp_regs));
 #else /* CONFIG_64BIT */
-       save_fp_regs(fpregs);
+       save_fp_ctl(&fpregs->fpc);
+       save_fp_regs(fpregs->fprs);
 #endif /* CONFIG_64BIT */
        return 1;
 }
index 9556905bd3ce42c046052a54aa32ed5b07d9d559..e65c91c591e8b99e4189f31b403a35ad06837f4f 100644 (file)
@@ -198,9 +198,11 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
                 * psw and gprs are stored on the stack
                 */
                tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
-               if (addr == (addr_t) &dummy->regs.psw.mask)
+               if (addr == (addr_t) &dummy->regs.psw.mask) {
                        /* Return a clean psw mask. */
-                       tmp = psw_user_bits | (tmp & PSW_MASK_USER);
+                       tmp &= PSW_MASK_USER | PSW_MASK_RI;
+                       tmp |= PSW_USER_BITS;
+               }
 
        } else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
                /*
@@ -239,8 +241,7 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
                offset = addr - (addr_t) &dummy->regs.fp_regs;
                tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
                if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
-                       tmp &= (unsigned long) FPC_VALID_MASK
-                               << (BITS_PER_LONG - 32);
+                       tmp <<= BITS_PER_LONG - 32;
 
        } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
                /*
@@ -321,11 +322,15 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                /*
                 * psw and gprs are stored on the stack
                 */
-               if (addr == (addr_t) &dummy->regs.psw.mask &&
-                   ((data & ~PSW_MASK_USER) != psw_user_bits ||
-                    ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))))
-                       /* Invalid psw mask. */
-                       return -EINVAL;
+               if (addr == (addr_t) &dummy->regs.psw.mask) {
+                       unsigned long mask = PSW_MASK_USER;
+
+                       mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
+                       if ((data & ~mask) != PSW_USER_BITS)
+                               return -EINVAL;
+                       if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
+                               return -EINVAL;
+               }
                *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
 
        } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
@@ -363,10 +368,10 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                /*
                 * floating point regs. are stored in the thread structure
                 */
-               if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
-                   (data & ~((unsigned long) FPC_VALID_MASK
-                             << (BITS_PER_LONG - 32))) != 0)
-                       return -EINVAL;
+               if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
+                       if ((unsigned int) data != 0 ||
+                           test_fp_ctl(data >> (BITS_PER_LONG - 32)))
+                               return -EINVAL;
                offset = addr - (addr_t) &dummy->regs.fp_regs;
                *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
 
@@ -557,7 +562,8 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
                if (addr == (addr_t) &dummy32->regs.psw.mask) {
                        /* Fake a 31 bit psw mask. */
                        tmp = (__u32)(regs->psw.mask >> 32);
-                       tmp = psw32_user_bits | (tmp & PSW32_MASK_USER);
+                       tmp &= PSW32_MASK_USER | PSW32_MASK_RI;
+                       tmp |= PSW32_USER_BITS;
                } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
                        /* Fake a 31 bit psw address. */
                        tmp = (__u32) regs->psw.addr |
@@ -654,13 +660,16 @@ static int __poke_user_compat(struct task_struct *child,
                 * psw, gprs, acrs and orig_gpr2 are stored on the stack
                 */
                if (addr == (addr_t) &dummy32->regs.psw.mask) {
+                       __u32 mask = PSW32_MASK_USER;
+
+                       mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
                        /* Build a 64 bit psw mask from 31 bit mask. */
-                       if ((tmp & ~PSW32_MASK_USER) != psw32_user_bits)
+                       if ((tmp & ~mask) != PSW32_USER_BITS)
                                /* Invalid psw mask. */
                                return -EINVAL;
                        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
                                (regs->psw.mask & PSW_MASK_BA) |
-                               (__u64)(tmp & PSW32_MASK_USER) << 32;
+                               (__u64)(tmp & mask) << 32;
                } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
                        /* Build a 64 bit psw address from 31 bit address. */
                        regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN;
@@ -696,8 +705,7 @@ static int __poke_user_compat(struct task_struct *child,
                 * floating point regs. are stored in the thread structure 
                 */
                if (addr == (addr_t) &dummy32->regs.fp_regs.fpc &&
-                   (tmp & ~FPC_VALID_MASK) != 0)
-                       /* Invalid floating point control. */
+                   test_fp_ctl(tmp))
                        return -EINVAL;
                offset = addr - (addr_t) &dummy32->regs.fp_regs;
                *(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp;
@@ -895,8 +903,10 @@ static int s390_fpregs_get(struct task_struct *target,
                           const struct user_regset *regset, unsigned int pos,
                           unsigned int count, void *kbuf, void __user *ubuf)
 {
-       if (target == current)
-               save_fp_regs(&target->thread.fp_regs);
+       if (target == current) {
+               save_fp_ctl(&target->thread.fp_regs.fpc);
+               save_fp_regs(target->thread.fp_regs.fprs);
+       }
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                   &target->thread.fp_regs, 0, -1);
@@ -909,19 +919,21 @@ static int s390_fpregs_set(struct task_struct *target,
 {
        int rc = 0;
 
-       if (target == current)
-               save_fp_regs(&target->thread.fp_regs);
+       if (target == current) {
+               save_fp_ctl(&target->thread.fp_regs.fpc);
+               save_fp_regs(target->thread.fp_regs.fprs);
+       }
 
        /* If setting FPC, must validate it first. */
        if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) {
-               u32 fpc[2] = { target->thread.fp_regs.fpc, 0 };
-               rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpc,
+               u32 ufpc[2] = { target->thread.fp_regs.fpc, 0 };
+               rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ufpc,
                                        0, offsetof(s390_fp_regs, fprs));
                if (rc)
                        return rc;
-               if ((fpc[0] & ~FPC_VALID_MASK) != 0 || fpc[1] != 0)
+               if (ufpc[1] != 0 || test_fp_ctl(ufpc[0]))
                        return -EINVAL;
-               target->thread.fp_regs.fpc = fpc[0];
+               target->thread.fp_regs.fpc = ufpc[0];
        }
 
        if (rc == 0 && count > 0)
@@ -929,8 +941,10 @@ static int s390_fpregs_set(struct task_struct *target,
                                        target->thread.fp_regs.fprs,
                                        offsetof(s390_fp_regs, fprs), -1);
 
-       if (rc == 0 && target == current)
-               restore_fp_regs(&target->thread.fp_regs);
+       if (rc == 0 && target == current) {
+               restore_fp_ctl(&target->thread.fp_regs.fpc);
+               restore_fp_regs(target->thread.fp_regs.fprs);
+       }
 
        return rc;
 }
index e1c9d1c292fa2ce4afa9a7d777b2d1db08024044..d817cce7e72de862081f57a2ef6b0936c64fcc60 100644 (file)
@@ -40,8 +40,6 @@ static void disable_runtime_instr(void)
 static void init_runtime_instr_cb(struct runtime_instr_cb *cb)
 {
        cb->buf_limit = 0xfff;
-       if (s390_user_mode == HOME_SPACE_MODE)
-               cb->home_space = 1;
        cb->int_requested = 1;
        cb->pstate = 1;
        cb->pstate_set_buf = 1;
index aeed8a61fa0d4f1b4862a98cab44e29beda63699..ffe1c53264a708352622d0159f437f1e176d2a75 100644 (file)
 #include <asm/sclp.h>
 #include "entry.h"
 
-long psw_kernel_bits   = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
-                         PSW_MASK_EA | PSW_MASK_BA;
-long psw_user_bits     = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT |
-                         PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK |
-                         PSW_MASK_PSTATE | PSW_ASC_HOME;
-
 /*
  * User copy operations.
  */
@@ -300,43 +294,14 @@ static int __init parse_vmalloc(char *arg)
 }
 early_param("vmalloc", parse_vmalloc);
 
-unsigned int s390_user_mode = PRIMARY_SPACE_MODE;
-EXPORT_SYMBOL_GPL(s390_user_mode);
-
-static void __init set_user_mode_primary(void)
-{
-       psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME;
-       psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY;
-#ifdef CONFIG_COMPAT
-       psw32_user_bits =
-               (psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY;
-#endif
-       uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos_switch : uaccess_pt;
-}
-
 static int __init early_parse_user_mode(char *p)
 {
-       if (p && strcmp(p, "primary") == 0)
-               s390_user_mode = PRIMARY_SPACE_MODE;
-       else if (!p || strcmp(p, "home") == 0)
-               s390_user_mode = HOME_SPACE_MODE;
-       else
-               return 1;
-       return 0;
+       if (!p || strcmp(p, "primary") == 0)
+               return 0;
+       return 1;
 }
 early_param("user_mode", early_parse_user_mode);
 
-static void __init setup_addressing_mode(void)
-{
-       if (s390_user_mode != PRIMARY_SPACE_MODE)
-               return;
-       set_user_mode_primary();
-       if (MACHINE_HAS_MVCOS)
-               pr_info("Address spaces switched, mvcos available\n");
-       else
-               pr_info("Address spaces switched, mvcos not available\n");
-}
-
 void *restart_stack __attribute__((__section__(".data")));
 
 static void __init setup_lowcore(void)
@@ -348,24 +313,24 @@ static void __init setup_lowcore(void)
         */
        BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
        lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
-       lc->restart_psw.mask = psw_kernel_bits;
+       lc->restart_psw.mask = PSW_KERNEL_BITS;
        lc->restart_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
-       lc->external_new_psw.mask = psw_kernel_bits |
+       lc->external_new_psw.mask = PSW_KERNEL_BITS |
                PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->external_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
-       lc->svc_new_psw.mask = psw_kernel_bits |
+       lc->svc_new_psw.mask = PSW_KERNEL_BITS |
                PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
        lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
-       lc->program_new_psw.mask = psw_kernel_bits |
+       lc->program_new_psw.mask = PSW_KERNEL_BITS |
                PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->program_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) pgm_check_handler;
-       lc->mcck_new_psw.mask = psw_kernel_bits;
+       lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
        lc->mcck_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
-       lc->io_new_psw.mask = psw_kernel_bits |
+       lc->io_new_psw.mask = PSW_KERNEL_BITS |
                PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
        lc->clock_comparator = -1ULL;
@@ -1043,10 +1008,7 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data = (unsigned long) &_edata;
        init_mm.brk = (unsigned long) &_end;
 
-       if (MACHINE_HAS_MVCOS)
-               memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
-       else
-               memcpy(&uaccess, &uaccess_std, sizeof(uaccess));
+       uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos : uaccess_pt;
 
        parse_early_param();
        detect_memory_layout(memory_chunk, memory_end);
@@ -1054,7 +1016,6 @@ void __init setup_arch(char **cmdline_p)
        setup_ipl();
        reserve_oldmem();
        setup_memory_end();
-       setup_addressing_mode();
        reserve_crashkernel();
        setup_memory();
        setup_resources();
index c45becf82e0179e17fcc9b1372b1ba25ef7c2131..fb535874a2464853168c9a9182620acf10e37c74 100644 (file)
@@ -57,40 +57,48 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
 
        /* Copy a 'clean' PSW mask to the user to avoid leaking
           information about whether PER is currently on.  */
-       user_sregs.regs.psw.mask = psw_user_bits |
-               (regs->psw.mask & PSW_MASK_USER);
+       user_sregs.regs.psw.mask = PSW_USER_BITS |
+               (regs->psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
        user_sregs.regs.psw.addr = regs->psw.addr;
        memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
        memcpy(&user_sregs.regs.acrs, current->thread.acrs,
-              sizeof(sregs->regs.acrs));
+              sizeof(user_sregs.regs.acrs));
        /* 
         * We have to store the fp registers to current->thread.fp_regs
         * to merge them with the emulated registers.
         */
-       save_fp_regs(&current->thread.fp_regs);
+       save_fp_ctl(&current->thread.fp_regs.fpc);
+       save_fp_regs(current->thread.fp_regs.fprs);
        memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
-              sizeof(s390_fp_regs));
-       return __copy_to_user(sregs, &user_sregs, sizeof(_sigregs));
+              sizeof(user_sregs.fpregs));
+       if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs)))
+               return -EFAULT;
+       return 0;
 }
 
-/* Returns positive number on error */
 static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
 {
-       int err;
        _sigregs user_sregs;
 
        /* Alwys make any pending restarted system call return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
-       err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
-       if (err)
-               return err;
-       /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */
+       if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs)))
+               return -EFAULT;
+
+       if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI))
+               return -EINVAL;
+
+       /* Loading the floating-point-control word can fail. Do that first. */
+       if (restore_fp_ctl(&user_sregs.fpregs.fpc))
+               return -EINVAL;
+
+       /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
-               (user_sregs.regs.psw.mask & PSW_MASK_USER);
+               (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_kernel_bits & PSW_MASK_ASC))
-               regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
+       if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
+               regs->psw.mask = PSW_ASC_PRIMARY |
                        (regs->psw.mask & ~PSW_MASK_ASC);
        /* Check for invalid amode */
        if (regs->psw.mask & PSW_MASK_EA)
@@ -98,14 +106,13 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
        regs->psw.addr = user_sregs.regs.psw.addr;
        memcpy(&regs->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
        memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
-              sizeof(sregs->regs.acrs));
+              sizeof(current->thread.acrs));
        restore_access_regs(current->thread.acrs);
 
        memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
-              sizeof(s390_fp_regs));
-       current->thread.fp_regs.fpc &= FPC_VALID_MASK;
+              sizeof(current->thread.fp_regs));
 
-       restore_fp_regs(&current->thread.fp_regs);
+       restore_fp_regs(current->thread.fp_regs.fprs);
        clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
        return 0;
 }
@@ -224,7 +231,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
        regs->gprs[15] = (unsigned long) frame;
        /* Force default amode and default user address space control. */
        regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
-               (psw_user_bits & PSW_MASK_ASC) |
+               (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
        regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
 
@@ -295,7 +302,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->gprs[15] = (unsigned long) frame;
        /* Force default amode and default user address space control. */
        regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
-               (psw_user_bits & PSW_MASK_ASC) |
+               (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
        regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
 
index 1a4313a1b60f76e20ac50ff31b5c0d2e0bf95492..dc4a534650604a972967ab5dedd2c1b7155c29ad 100644 (file)
@@ -283,7 +283,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
        struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
        unsigned long source_cpu = stap();
 
-       __load_psw_mask(psw_kernel_bits);
+       __load_psw_mask(PSW_KERNEL_BITS);
        if (pcpu->address == source_cpu)
                func(data);     /* should not return */
        /* Stop target cpu (if func returns this stops the current cpu). */
@@ -395,7 +395,7 @@ void smp_send_stop(void)
        int cpu;
 
        /* Disable all interrupts/machine checks */
-       __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
+       __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT);
        trace_hardirqs_off();
 
        debug_set_critical();
@@ -533,9 +533,6 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
 
 #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_CRASH_DUMP)
 
-struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
-EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
-
 static void __init smp_get_save_area(int cpu, u16 address)
 {
        void *lc = pcpu_devices[0].lowcore;
@@ -546,15 +543,9 @@ static void __init smp_get_save_area(int cpu, u16 address)
        if (!OLDMEM_BASE && (address == boot_cpu_address ||
                             ipl_info.type != IPL_TYPE_FCP_DUMP))
                return;
-       if (cpu >= NR_CPUS) {
-               pr_warning("CPU %i exceeds the maximum %i and is excluded "
-                          "from the dump\n", cpu, NR_CPUS - 1);
-               return;
-       }
-       save_area = kmalloc(sizeof(struct save_area), GFP_KERNEL);
+       save_area = dump_save_area_create(cpu);
        if (!save_area)
                panic("could not allocate memory for save area\n");
-       zfcpdump_save_areas[cpu] = save_area;
 #ifdef CONFIG_CRASH_DUMP
        if (address == boot_cpu_address) {
                /* Copy the registers of the boot cpu. */
@@ -693,7 +684,7 @@ static void smp_start_secondary(void *cpuvoid)
        S390_lowcore.restart_source = -1UL;
        restore_access_regs(S390_lowcore.access_regs_save_area);
        __ctl_load(S390_lowcore.cregs_save_area, 0, 15);
-       __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
+       __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT);
        cpu_init();
        preempt_disable();
        init_cpu_timer();
@@ -929,7 +920,7 @@ static ssize_t show_idle_count(struct device *dev,
                idle_count = ACCESS_ONCE(idle->idle_count);
                if (ACCESS_ONCE(idle->clock_idle_enter))
                        idle_count++;
-       } while ((sequence & 1) || (idle->sequence != sequence));
+       } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence));
        return sprintf(buf, "%llu\n", idle_count);
 }
 static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
@@ -947,7 +938,7 @@ static ssize_t show_idle_time(struct device *dev,
                idle_time = ACCESS_ONCE(idle->idle_time);
                idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
                idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
-       } while ((sequence & 1) || (idle->sequence != sequence));
+       } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence));
        idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
        return sprintf(buf, "%llu\n", idle_time >> 12);
 }
index 05d75c413137879a30fded476638b0b9c4a001f5..a84476f2a9bb3ae488eb7a936021a744a822dd31 100644 (file)
@@ -84,8 +84,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
  */
 static void vdso_init_data(struct vdso_data *vd)
 {
-       vd->ectg_available =
-               s390_user_mode != HOME_SPACE_MODE && test_facility(31);
+       vd->ectg_available = test_facility(31);
 }
 
 #ifdef CONFIG_64BIT
@@ -102,7 +101,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
 
        lowcore->vdso_per_cpu_data = __LC_PASTE;
 
-       if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
+       if (!vdso_enabled)
                return 0;
 
        segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
@@ -147,7 +146,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore)
        unsigned long segment_table, page_table, page_frame;
        u32 *psal, *aste;
 
-       if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
+       if (!vdso_enabled)
                return;
 
        psal = (u32 *)(addr_t) lowcore->paste[4];
@@ -165,7 +164,7 @@ static void vdso_init_cr5(void)
 {
        unsigned long cr5;
 
-       if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
+       if (!vdso_enabled)
                return;
        cr5 = offsetof(struct _lowcore, paste);
        __ctl_load(cr5, 5, 5);
index abcfab55f99b37e5d4f79903be716e67896d5c79..8c34363d6f1e88571074b01593b1efaa80c007d0 100644 (file)
@@ -161,7 +161,7 @@ void __kprobes vtime_stop_cpu(void)
        trace_hardirqs_on();
 
        /* Wait for external, I/O or machine check interrupt. */
-       psw_mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_DAT |
+       psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
                PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
        idle->nohz_delay = 0;
 
@@ -191,7 +191,7 @@ cputime64_t s390_get_idle_time(int cpu)
                sequence = ACCESS_ONCE(idle->sequence);
                idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
                idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
-       } while ((sequence & 1) || (idle->sequence != sequence));
+       } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence));
        return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0;
 }
 
index 776dafe918db30b8c3f4823b8bf11c461bed6f5f..ed8064cb5c4921424d5981b890e6fd9b07f9ed02 100644 (file)
@@ -343,10 +343,11 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
-       save_fp_regs(&vcpu->arch.host_fpregs);
+       save_fp_ctl(&vcpu->arch.host_fpregs.fpc);
+       save_fp_regs(vcpu->arch.host_fpregs.fprs);
        save_access_regs(vcpu->arch.host_acrs);
-       vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
-       restore_fp_regs(&vcpu->arch.guest_fpregs);
+       restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
+       restore_fp_regs(vcpu->arch.guest_fpregs.fprs);
        restore_access_regs(vcpu->run->s.regs.acrs);
        gmap_enable(vcpu->arch.gmap);
        atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
@@ -356,9 +357,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
        atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
        gmap_disable(vcpu->arch.gmap);
-       save_fp_regs(&vcpu->arch.guest_fpregs);
+       save_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
+       save_fp_regs(vcpu->arch.guest_fpregs.fprs);
        save_access_regs(vcpu->run->s.regs.acrs);
-       restore_fp_regs(&vcpu->arch.host_fpregs);
+       restore_fp_ctl(&vcpu->arch.host_fpregs.fpc);
+       restore_fp_regs(vcpu->arch.host_fpregs.fprs);
        restore_access_regs(vcpu->arch.host_acrs);
 }
 
@@ -618,9 +621,12 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
+       if (test_fp_ctl(fpu->fpc))
+               return -EINVAL;
        memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
-       vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
-       restore_fp_regs(&vcpu->arch.guest_fpregs);
+       vcpu->arch.guest_fpregs.fpc = fpu->fpc;
+       restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
+       restore_fp_regs(vcpu->arch.guest_fpregs.fprs);
        return 0;
 }
 
@@ -876,7 +882,8 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
         * copying in vcpu load/put. Lets update our copies before we save
         * it into the save area
         */
-       save_fp_regs(&vcpu->arch.guest_fpregs);
+       save_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
+       save_fp_regs(vcpu->arch.guest_fpregs.fprs);
        save_access_regs(vcpu->run->s.regs.acrs);
 
        if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
index c2f582bb1cb262e421072a9b1500c961f4e7426a..0c991c6748ab3a4d860c890b7c1b1526808d4ed6 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/tracepoint.h>
 #include <asm/sigp.h>
 #include <asm/debug.h>
+#include <asm/dis.h>
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM kvm
index 20b0e97a7df2e204f9a680be4d95c86e0944652d..b068729e50ace9711774adab984f03a8a41e9338 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for s390-specific library files..
 #
 
-lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
+lib-y += delay.o string.o uaccess_pt.o find.o
 obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o
 obj-$(CONFIG_64BIT) += mem64.o
 lib-$(CONFIG_64BIT) += uaccess_mvcos.o
diff --git a/arch/s390/lib/find.c b/arch/s390/lib/find.c
new file mode 100644 (file)
index 0000000..620d34d
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * MSB0 numbered special bitops handling.
+ *
+ * On s390x the bits are numbered:
+ *   |0..............63|64............127|128...........191|192...........255|
+ * and on s390:
+ *   |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255|
+ *
+ * The reason for this bit numbering is the fact that the hardware sets bits
+ * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap
+ * from the 'wrong end'.
+ */
+
+#include <linux/compiler.h>
+#include <linux/bitops.h>
+#include <linux/export.h>
+
+unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size)
+{
+       const unsigned long *p = addr;
+       unsigned long result = 0;
+       unsigned long tmp;
+
+       while (size & ~(BITS_PER_LONG - 1)) {
+               if ((tmp = *(p++)))
+                       goto found;
+               result += BITS_PER_LONG;
+               size -= BITS_PER_LONG;
+       }
+       if (!size)
+               return result;
+       tmp = (*p) & (~0UL << (BITS_PER_LONG - size));
+       if (!tmp)               /* Are any bits set? */
+               return result + size;   /* Nope. */
+found:
+       return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
+}
+EXPORT_SYMBOL(find_first_bit_inv);
+
+unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
+                               unsigned long offset)
+{
+       const unsigned long *p = addr + (offset / BITS_PER_LONG);
+       unsigned long result = offset & ~(BITS_PER_LONG - 1);
+       unsigned long tmp;
+
+       if (offset >= size)
+               return size;
+       size -= result;
+       offset %= BITS_PER_LONG;
+       if (offset) {
+               tmp = *(p++);
+               tmp &= (~0UL >> offset);
+               if (size < BITS_PER_LONG)
+                       goto found_first;
+               if (tmp)
+                       goto found_middle;
+               size -= BITS_PER_LONG;
+               result += BITS_PER_LONG;
+       }
+       while (size & ~(BITS_PER_LONG-1)) {
+               if ((tmp = *(p++)))
+                       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)               /* Are any bits set? */
+               return result + size;   /* Nope. */
+found_middle:
+       return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
+}
+EXPORT_SYMBOL(find_next_bit_inv);
index 1829742bf4793fae0060dbb4bd31b4e0bfbacc4f..4b7993bf69b96bd42f503e8772f29caedf5dd4b0 100644 (file)
@@ -65,13 +65,6 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
        return size;
 }
 
-static size_t copy_from_user_mvcos_check(size_t size, const void __user *ptr, void *x)
-{
-       if (size <= 256)
-               return copy_from_user_std(size, ptr, x);
-       return copy_from_user_mvcos(size, ptr, x);
-}
-
 static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
 {
        register unsigned long reg0 asm("0") = 0x810000UL;
@@ -101,14 +94,6 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
        return size;
 }
 
-static size_t copy_to_user_mvcos_check(size_t size, void __user *ptr,
-                                      const void *x)
-{
-       if (size <= 256)
-               return copy_to_user_std(size, ptr, x);
-       return copy_to_user_mvcos(size, ptr, x);
-}
-
 static size_t copy_in_user_mvcos(size_t size, void __user *to,
                                 const void __user *from)
 {
@@ -201,23 +186,8 @@ static size_t strncpy_from_user_mvcos(size_t count, const char __user *src,
 }
 
 struct uaccess_ops uaccess_mvcos = {
-       .copy_from_user = copy_from_user_mvcos_check,
-       .copy_from_user_small = copy_from_user_std,
-       .copy_to_user = copy_to_user_mvcos_check,
-       .copy_to_user_small = copy_to_user_std,
-       .copy_in_user = copy_in_user_mvcos,
-       .clear_user = clear_user_mvcos,
-       .strnlen_user = strnlen_user_std,
-       .strncpy_from_user = strncpy_from_user_std,
-       .futex_atomic_op = futex_atomic_op_std,
-       .futex_atomic_cmpxchg = futex_atomic_cmpxchg_std,
-};
-
-struct uaccess_ops uaccess_mvcos_switch = {
        .copy_from_user = copy_from_user_mvcos,
-       .copy_from_user_small = copy_from_user_mvcos,
        .copy_to_user = copy_to_user_mvcos,
-       .copy_to_user_small = copy_to_user_mvcos,
        .copy_in_user = copy_in_user_mvcos,
        .clear_user = clear_user_mvcos,
        .strnlen_user = strnlen_user_mvcos,
index 1694d738b17527aad71850c8fc772e755d26ca54..97e03caf782598a20857ab276ff03df701c4c3f9 100644 (file)
@@ -461,9 +461,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
 
 struct uaccess_ops uaccess_pt = {
        .copy_from_user         = copy_from_user_pt,
-       .copy_from_user_small   = copy_from_user_pt,
        .copy_to_user           = copy_to_user_pt,
-       .copy_to_user_small     = copy_to_user_pt,
        .copy_in_user           = copy_in_user_pt,
        .clear_user             = clear_user_pt,
        .strnlen_user           = strnlen_user_pt,
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
deleted file mode 100644 (file)
index 4a75d47..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- *  Standard user space access functions based on mvcp/mvcs and doing
- *  interesting things in the secondary space mode.
- *
- *    Copyright IBM Corp. 2006
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *              Gerald Schaefer (gerald.schaefer@de.ibm.com)
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <asm/futex.h>
-#include "uaccess.h"
-
-#ifndef CONFIG_64BIT
-#define AHI    "ahi"
-#define ALR    "alr"
-#define CLR    "clr"
-#define LHI    "lhi"
-#define SLR    "slr"
-#else
-#define AHI    "aghi"
-#define ALR    "algr"
-#define CLR    "clgr"
-#define LHI    "lghi"
-#define SLR    "slgr"
-#endif
-
-size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
-{
-       unsigned long tmp1, tmp2;
-
-       tmp1 = -256UL;
-       asm volatile(
-               "0: mvcp  0(%0,%2),0(%1),%3\n"
-               "10:jz    8f\n"
-               "1:"ALR"  %0,%3\n"
-               "   la    %1,256(%1)\n"
-               "   la    %2,256(%2)\n"
-               "2: mvcp  0(%0,%2),0(%1),%3\n"
-               "11:jnz   1b\n"
-               "   j     8f\n"
-               "3: la    %4,255(%1)\n" /* %4 = ptr + 255 */
-               "  "LHI"  %3,-4096\n"
-               "   nr    %4,%3\n"      /* %4 = (ptr + 255) & -4096 */
-               "  "SLR"  %4,%1\n"
-               "  "CLR"  %0,%4\n"      /* copy crosses next page boundary? */
-               "   jnh   5f\n"
-               "4: mvcp  0(%4,%2),0(%1),%3\n"
-               "12:"SLR"  %0,%4\n"
-               "  "ALR"  %2,%4\n"
-               "5:"LHI"  %4,-1\n"
-               "  "ALR"  %4,%0\n"      /* copy remaining size, subtract 1 */
-               "   bras  %3,7f\n"      /* memset loop */
-               "   xc    0(1,%2),0(%2)\n"
-               "6: xc    0(256,%2),0(%2)\n"
-               "   la    %2,256(%2)\n"
-               "7:"AHI"  %4,-256\n"
-               "   jnm   6b\n"
-               "   ex    %4,0(%3)\n"
-               "   j     9f\n"
-               "8:"SLR"  %0,%0\n"
-               "9: \n"
-               EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b)
-               EX_TABLE(10b,3b) EX_TABLE(11b,3b) EX_TABLE(12b,5b)
-               : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
-               : : "cc", "memory");
-       return size;
-}
-
-static size_t copy_from_user_std_check(size_t size, const void __user *ptr,
-                                      void *x)
-{
-       if (size <= 1024)
-               return copy_from_user_std(size, ptr, x);
-       return copy_from_user_pt(size, ptr, x);
-}
-
-size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
-{
-       unsigned long tmp1, tmp2;
-
-       tmp1 = -256UL;
-       asm volatile(
-               "0: mvcs  0(%0,%1),0(%2),%3\n"
-               "7: jz    5f\n"
-               "1:"ALR"  %0,%3\n"
-               "   la    %1,256(%1)\n"
-               "   la    %2,256(%2)\n"
-               "2: mvcs  0(%0,%1),0(%2),%3\n"
-               "8: jnz   1b\n"
-               "   j     5f\n"
-               "3: la    %4,255(%1)\n" /* %4 = ptr + 255 */
-               "  "LHI"  %3,-4096\n"
-               "   nr    %4,%3\n"      /* %4 = (ptr + 255) & -4096 */
-               "  "SLR"  %4,%1\n"
-               "  "CLR"  %0,%4\n"      /* copy crosses next page boundary? */
-               "   jnh   6f\n"
-               "4: mvcs  0(%4,%1),0(%2),%3\n"
-               "9:"SLR"  %0,%4\n"
-               "   j     6f\n"
-               "5:"SLR"  %0,%0\n"
-               "6: \n"
-               EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
-               EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b)
-               : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
-               : : "cc", "memory");
-       return size;
-}
-
-static size_t copy_to_user_std_check(size_t size, void __user *ptr,
-                                    const void *x)
-{
-       if (size <= 1024)
-               return copy_to_user_std(size, ptr, x);
-       return copy_to_user_pt(size, ptr, x);
-}
-
-static size_t copy_in_user_std(size_t size, void __user *to,
-                              const void __user *from)
-{
-       unsigned long tmp1;
-
-       asm volatile(
-               "   sacf  256\n"
-               "  "AHI"  %0,-1\n"
-               "   jo    5f\n"
-               "   bras  %3,3f\n"
-               "0:"AHI"  %0,257\n"
-               "1: mvc   0(1,%1),0(%2)\n"
-               "   la    %1,1(%1)\n"
-               "   la    %2,1(%2)\n"
-               "  "AHI"  %0,-1\n"
-               "   jnz   1b\n"
-               "   j     5f\n"
-               "2: mvc   0(256,%1),0(%2)\n"
-               "   la    %1,256(%1)\n"
-               "   la    %2,256(%2)\n"
-               "3:"AHI"  %0,-256\n"
-               "   jnm   2b\n"
-               "4: ex    %0,1b-0b(%3)\n"
-               "5: "SLR"  %0,%0\n"
-               "6: sacf  0\n"
-               EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
-               : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
-               : : "cc", "memory");
-       return size;
-}
-
-static size_t clear_user_std(size_t size, void __user *to)
-{
-       unsigned long tmp1, tmp2;
-
-       asm volatile(
-               "   sacf  256\n"
-               "  "AHI"  %0,-1\n"
-               "   jo    5f\n"
-               "   bras  %3,3f\n"
-               "   xc    0(1,%1),0(%1)\n"
-               "0:"AHI"  %0,257\n"
-               "   la    %2,255(%1)\n" /* %2 = ptr + 255 */
-               "   srl   %2,12\n"
-               "   sll   %2,12\n"      /* %2 = (ptr + 255) & -4096 */
-               "  "SLR"  %2,%1\n"
-               "  "CLR"  %0,%2\n"      /* clear crosses next page boundary? */
-               "   jnh   5f\n"
-               "  "AHI"  %2,-1\n"
-               "1: ex    %2,0(%3)\n"
-               "  "AHI"  %2,1\n"
-               "  "SLR"  %0,%2\n"
-               "   j     5f\n"
-               "2: xc    0(256,%1),0(%1)\n"
-               "   la    %1,256(%1)\n"
-               "3:"AHI"  %0,-256\n"
-               "   jnm   2b\n"
-               "4: ex    %0,0(%3)\n"
-               "5: "SLR"  %0,%0\n"
-               "6: sacf  0\n"
-               EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
-               : "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2)
-               : : "cc", "memory");
-       return size;
-}
-
-size_t strnlen_user_std(size_t size, const char __user *src)
-{
-       register unsigned long reg0 asm("0") = 0UL;
-       unsigned long tmp1, tmp2;
-
-       if (unlikely(!size))
-               return 0;
-       asm volatile(
-               "   la    %2,0(%1)\n"
-               "   la    %3,0(%0,%1)\n"
-               "  "SLR"  %0,%0\n"
-               "   sacf  256\n"
-               "0: srst  %3,%2\n"
-               "   jo    0b\n"
-               "   la    %0,1(%3)\n"   /* strnlen_user results includes \0 */
-               "  "SLR"  %0,%1\n"
-               "1: sacf  0\n"
-               EX_TABLE(0b,1b)
-               : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
-               : "d" (reg0) : "cc", "memory");
-       return size;
-}
-
-size_t strncpy_from_user_std(size_t count, const char __user *src, char *dst)
-{
-       size_t done, len, offset, len_str;
-
-       if (unlikely(!count))
-               return 0;
-       done = 0;
-       do {
-               offset = (size_t)src & ~PAGE_MASK;
-               len = min(count - done, PAGE_SIZE - offset);
-               if (copy_from_user_std(len, src, dst))
-                       return -EFAULT;
-               len_str = strnlen(dst, len);
-               done += len_str;
-               src += len_str;
-               dst += len_str;
-       } while ((len_str == len) && (done < count));
-       return done;
-}
-
-#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg)     \
-       asm volatile(                                                   \
-               "   sacf  256\n"                                        \
-               "0: l     %1,0(%6)\n"                                   \
-               "1:"insn                                                \
-               "2: cs    %1,%2,0(%6)\n"                                \
-               "3: jl    1b\n"                                         \
-               "   lhi   %0,0\n"                                       \
-               "4: sacf  0\n"                                          \
-               EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b)         \
-               : "=d" (ret), "=&d" (oldval), "=&d" (newval),           \
-                 "=m" (*uaddr)                                         \
-               : "0" (-EFAULT), "d" (oparg), "a" (uaddr),              \
-                 "m" (*uaddr) : "cc");
-
-int futex_atomic_op_std(int op, u32 __user *uaddr, int oparg, int *old)
-{
-       int oldval = 0, newval, ret;
-
-       switch (op) {
-       case FUTEX_OP_SET:
-               __futex_atomic_op("lr %2,%5\n",
-                                 ret, oldval, newval, uaddr, oparg);
-               break;
-       case FUTEX_OP_ADD:
-               __futex_atomic_op("lr %2,%1\nar %2,%5\n",
-                                 ret, oldval, newval, uaddr, oparg);
-               break;
-       case FUTEX_OP_OR:
-               __futex_atomic_op("lr %2,%1\nor %2,%5\n",
-                                 ret, oldval, newval, uaddr, oparg);
-               break;
-       case FUTEX_OP_ANDN:
-               __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
-                                 ret, oldval, newval, uaddr, oparg);
-               break;
-       case FUTEX_OP_XOR:
-               __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
-                                 ret, oldval, newval, uaddr, oparg);
-               break;
-       default:
-               ret = -ENOSYS;
-       }
-       *old = oldval;
-       return ret;
-}
-
-int futex_atomic_cmpxchg_std(u32 *uval, u32 __user *uaddr,
-                            u32 oldval, u32 newval)
-{
-       int ret;
-
-       asm volatile(
-               "   sacf 256\n"
-               "0: cs   %1,%4,0(%5)\n"
-               "1: la   %0,0\n"
-               "2: sacf 0\n"
-               EX_TABLE(0b,2b) EX_TABLE(1b,2b)
-               : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
-               : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
-               : "cc", "memory" );
-       *uval = oldval;
-       return ret;
-}
-
-struct uaccess_ops uaccess_std = {
-       .copy_from_user = copy_from_user_std_check,
-       .copy_from_user_small = copy_from_user_std,
-       .copy_to_user = copy_to_user_std_check,
-       .copy_to_user_small = copy_to_user_std,
-       .copy_in_user = copy_in_user_std,
-       .clear_user = clear_user_std,
-       .strnlen_user = strnlen_user_std,
-       .strncpy_from_user = strncpy_from_user_std,
-       .futex_atomic_op = futex_atomic_op_std,
-       .futex_atomic_cmpxchg = futex_atomic_cmpxchg_std,
-};
index 58bff541fde9c95edcd0db4f49da3aa8629371b9..a6ba0d7243356649e6882b5dc16a85c445ed120e 100644 (file)
@@ -19,6 +19,8 @@
 #include <math-emu/double.h>
 #include <math-emu/quad.h>
 
+#define FPC_VALID_MASK         0xF8F8FF03
+
 /*
  * I miss a macro to round a floating point number to the
  * nearest integer in the same floating point format.
index 9d84a1feefef0e57005f6a31ae50079ebec3a15b..79ddd580d60539dbcdb7114bf1523290fa300aa2 100644 (file)
@@ -253,12 +253,12 @@ static int cmm_skip_blanks(char *cp, char **endp)
 
 static struct ctl_table cmm_table[];
 
-static int cmm_pages_handler(ctl_table *ctl, int write, void __user *buffer,
-                            size_t *lenp, loff_t *ppos)
+static int cmm_pages_handler(struct ctl_table *ctl, int write,
+                            void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        char buf[16], *p;
+       unsigned int len;
        long nr;
-       int len;
 
        if (!*lenp || (*ppos && !write)) {
                *lenp = 0;
@@ -293,12 +293,12 @@ static int cmm_pages_handler(ctl_table *ctl, int write, void __user *buffer,
        return 0;
 }
 
-static int cmm_timeout_handler(ctl_table *ctl, int write,  void __user *buffer,
-                              size_t *lenp, loff_t *ppos)
+static int cmm_timeout_handler(struct ctl_table *ctl, int write,
+                              void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        char buf[64], *p;
        long nr, seconds;
-       int len;
+       unsigned int len;
 
        if (!*lenp || (*ppos && !write)) {
                *lenp = 0;
index fc6679210d83249e9b34c2f44070ab1021852e91..d95265b2719f8e7fb0b15305b49a52130069aebd 100644 (file)
@@ -115,13 +115,8 @@ static inline int user_space_fault(unsigned long trans_exc_code)
        if (trans_exc_code == 2)
                /* Access via secondary space, set_fs setting decides */
                return current->thread.mm_segment.ar4;
-       if (s390_user_mode == HOME_SPACE_MODE)
-               /* User space if the access has been done via home space. */
-               return trans_exc_code == 3;
        /*
-        * If the user space is not the home space the kernel runs in home
-        * space. Access via secondary space has already been covered,
-        * access via primary space or access register is from user space
+        * Access via primary space or access register is from user space
         * and access via home space is from the kernel.
         */
        return trans_exc_code != 3;
@@ -428,50 +423,13 @@ void __kprobes do_dat_exception(struct pt_regs *regs)
                do_fault_error(regs, fault);
 }
 
-#ifdef CONFIG_64BIT
-void __kprobes do_asce_exception(struct pt_regs *regs)
-{
-       struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
-       unsigned long trans_exc_code;
-
-       /*
-        * The instruction that caused the program check has
-        * been nullified. Don't signal single step via SIGTRAP.
-        */
-       clear_tsk_thread_flag(current, TIF_PER_TRAP);
-
-       trans_exc_code = regs->int_parm_long;
-       if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
-               goto no_context;
-
-       down_read(&mm->mmap_sem);
-       vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK);
-       up_read(&mm->mmap_sem);
-
-       if (vma) {
-               update_mm(mm, current);
-               return;
-       }
-
-       /* User mode accesses just cause a SIGSEGV */
-       if (user_mode(regs)) {
-               do_sigsegv(regs, SEGV_MAPERR);
-               return;
-       }
-
-no_context:
-       do_no_context(regs);
-}
-#endif
-
 int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
 {
        struct pt_regs regs;
        int access, fault;
 
        /* Emulate a uaccess fault from kernel mode. */
-       regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK;
+       regs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK;
        if (!irqs_disabled())
                regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
        regs.psw.addr = (unsigned long) __builtin_return_address(0);
index 5d758db27bdced58d929d736363bcafc09c199ab..639fce464008854cf3d23c22f6dcbe4a970add68 100644 (file)
@@ -180,9 +180,15 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
        addr = start;
        len = (unsigned long) nr_pages << PAGE_SHIFT;
        end = start + len;
-       if ((end < start) || (end > TASK_SIZE))
+       if ((end <= start) || (end > TASK_SIZE))
                return 0;
-
+       /*
+        * local_irq_save() doesn't prevent pagetable teardown, but does
+        * prevent the pagetables from being freed on s390.
+        *
+        * So long as we atomically load page table pointers versus teardown,
+        * we can follow the address down to the the page and take a ref on it.
+        */
        local_irq_save(flags);
        pgdp = pgd_offset(mm, addr);
        do {
@@ -219,63 +225,22 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
                        struct page **pages)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long addr, len, end;
-       unsigned long next;
-       pgd_t *pgdp, pgd;
-       int nr = 0;
+       int nr, ret;
 
        start &= PAGE_MASK;
-       addr = start;
-       len = (unsigned long) nr_pages << PAGE_SHIFT;
-       end = start + len;
-       if ((end < start) || (end > TASK_SIZE))
-               goto slow_irqon;
-
-       /*
-        * local_irq_disable() doesn't prevent pagetable teardown, but does
-        * prevent the pagetables from being freed on s390.
-        *
-        * So long as we atomically load page table pointers versus teardown,
-        * we can follow the address down to the the page and take a ref on it.
-        */
-       local_irq_disable();
-       pgdp = pgd_offset(mm, addr);
-       do {
-               pgd = *pgdp;
-               barrier();
-               next = pgd_addr_end(addr, end);
-               if (pgd_none(pgd))
-                       goto slow;
-               if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr))
-                       goto slow;
-       } while (pgdp++, addr = next, addr != end);
-       local_irq_enable();
-
-       VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
-       return nr;
-
-       {
-               int ret;
-slow:
-               local_irq_enable();
-slow_irqon:
-               /* Try to get the remaining pages with get_user_pages */
-               start += nr << PAGE_SHIFT;
-               pages += nr;
-
-               down_read(&mm->mmap_sem);
-               ret = get_user_pages(current, mm, start,
-                       (end - start) >> PAGE_SHIFT, write, 0, pages, NULL);
-               up_read(&mm->mmap_sem);
-
-               /* Have to be a bit careful with return values */
-               if (nr > 0) {
-                       if (ret < 0)
-                               ret = nr;
-                       else
-                               ret += nr;
-               }
-
-               return ret;
-       }
+       nr = __get_user_pages_fast(start, nr_pages, write, pages);
+       if (nr == nr_pages)
+               return nr;
+
+       /* Try to get the remaining pages with get_user_pages */
+       start += nr << PAGE_SHIFT;
+       pages += nr;
+       down_read(&mm->mmap_sem);
+       ret = get_user_pages(current, mm, start,
+                            nr_pages - nr, write, 0, pages, NULL);
+       up_read(&mm->mmap_sem);
+       /* Have to be a bit careful with return values */
+       if (nr > 0)
+               ret = (ret < 0) ? nr : ret + nr;
+       return ret;
 }
index 40023290ee5b43dea2cf72b68c97f9495b6c59fd..6bcb045d2bd2f8ab3b1234e13f00be719dc0441e 100644 (file)
@@ -101,18 +101,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 
 int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
 {
-       int rc;
-
        if (is_compat_task() || (TASK_SIZE >= (1UL << 53)))
                return 0;
        if (!(flags & MAP_FIXED))
                addr = 0;
-       if ((addr + len) >= TASK_SIZE) {
-               rc = crst_table_upgrade(current->mm, 1UL << 53);
-               if (rc)
-                       return rc;
-               update_mm(current->mm, current);
-       }
+       if ((addr + len) >= TASK_SIZE)
+               return crst_table_upgrade(current->mm, 1UL << 53);
        return 0;
 }
 
@@ -132,7 +126,6 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
                rc = crst_table_upgrade(mm, 1UL << 53);
                if (rc)
                        return (unsigned long) rc;
-               update_mm(mm, current);
                area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
        }
        return area;
@@ -155,7 +148,6 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
                rc = crst_table_upgrade(mm, 1UL << 53);
                if (rc)
                        return (unsigned long) rc;
-               update_mm(mm, current);
                area = arch_get_unmapped_area_topdown(filp, addr, len,
                                                      pgoff, flags);
        }
index 990397420e6bcf8262b92806b5f5b57bff273373..8400f494623f4591a5de3e5ea6442a08fe767ed4 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 
+#if PAGE_DEFAULT_KEY
 static inline unsigned long sske_frame(unsigned long addr, unsigned char skey)
 {
        asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0"
@@ -16,7 +17,7 @@ static inline unsigned long sske_frame(unsigned long addr, unsigned char skey)
        return addr;
 }
 
-void storage_key_init_range(unsigned long start, unsigned long end)
+void __storage_key_init_range(unsigned long start, unsigned long end)
 {
        unsigned long boundary, size;
 
@@ -36,6 +37,7 @@ void storage_key_init_range(unsigned long start, unsigned long end)
                start += PAGE_SIZE;
        }
 }
+#endif
 
 static pte_t *walk_page_table(unsigned long addr)
 {
index de8cbc30dcd1be13cb34dd0fc0e7ad5a8a68372e..0a2e5e086749c00b98bbcba84446377935fd87df 100644 (file)
@@ -48,12 +48,23 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table)
 }
 
 #ifdef CONFIG_64BIT
+static void __crst_table_upgrade(void *arg)
+{
+       struct mm_struct *mm = arg;
+
+       if (current->active_mm == mm)
+               update_mm(mm, current);
+       __tlb_flush_local();
+}
+
 int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
 {
        unsigned long *table, *pgd;
        unsigned long entry;
+       int flush;
 
        BUG_ON(limit > (1UL << 53));
+       flush = 0;
 repeat:
        table = crst_table_alloc(mm);
        if (!table)
@@ -79,12 +90,15 @@ repeat:
                mm->pgd = (pgd_t *) table;
                mm->task_size = mm->context.asce_limit;
                table = NULL;
+               flush = 1;
        }
        spin_unlock_bh(&mm->page_table_lock);
        if (table)
                crst_table_free(mm, table);
        if (mm->context.asce_limit < limit)
                goto repeat;
+       if (flush)
+               on_each_cpu(__crst_table_upgrade, mm, 0);
        return 0;
 }
 
@@ -92,6 +106,8 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
 {
        pgd_t *pgd;
 
+       if (current->active_mm == mm)
+               __tlb_flush_mm(mm);
        while (mm->context.asce_limit > limit) {
                pgd = mm->pgd;
                switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
@@ -114,6 +130,8 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
                mm->task_size = mm->context.asce_limit;
                crst_table_free(mm, (unsigned long *) pgd);
        }
+       if (current->active_mm == mm)
+               update_mm(mm, current);
 }
 #endif
 
@@ -1087,10 +1105,9 @@ again:
                        continue;
                /* Allocate new page table with pgstes */
                new = page_table_alloc_pgste(mm, addr);
-               if (!new) {
-                       mm->context.has_pgste = 0;
-                       continue;
-               }
+               if (!new)
+                       return -ENOMEM;
+
                spin_lock(&mm->page_table_lock);
                if (likely((unsigned long *) pmd_deref(*pmd) == table)) {
                        /* Nuke pmd entry pointing to the "short" page table */
@@ -1128,13 +1145,15 @@ static unsigned long page_table_realloc_pud(struct mmu_gather *tlb,
                if (pud_none_or_clear_bad(pud))
                        continue;
                next = page_table_realloc_pmd(tlb, mm, pud, addr, next);
+               if (unlikely(IS_ERR_VALUE(next)))
+                       return next;
        } while (pud++, addr = next, addr != end);
 
        return addr;
 }
 
-static void page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm,
-                              unsigned long addr, unsigned long end)
+static unsigned long page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm,
+                                       unsigned long addr, unsigned long end)
 {
        unsigned long next;
        pgd_t *pgd;
@@ -1145,7 +1164,11 @@ static void page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm,
                if (pgd_none_or_clear_bad(pgd))
                        continue;
                next = page_table_realloc_pud(tlb, mm, pgd, addr, next);
+               if (unlikely(IS_ERR_VALUE(next)))
+                       return next;
        } while (pgd++, addr = next, addr != end);
+
+       return 0;
 }
 
 /*
@@ -1157,10 +1180,6 @@ int s390_enable_sie(void)
        struct mm_struct *mm = tsk->mm;
        struct mmu_gather tlb;
 
-       /* Do we have switched amode? If no, we cannot do sie */
-       if (s390_user_mode == HOME_SPACE_MODE)
-               return -EINVAL;
-
        /* Do we have pgstes? if yes, we are done */
        if (mm_has_pgste(tsk->mm))
                return 0;
@@ -1169,9 +1188,9 @@ int s390_enable_sie(void)
        /* split thp mappings and disable thp for future mappings */
        thp_split_mm(mm);
        /* Reallocate the page tables with pgstes */
-       mm->context.has_pgste = 1;
        tlb_gather_mmu(&tlb, mm, 0, TASK_SIZE);
-       page_table_realloc(&tlb, mm, 0, TASK_SIZE);
+       if (!page_table_realloc(&tlb, mm, 0, TASK_SIZE))
+               mm->context.has_pgste = 1;
        tlb_finish_mmu(&tlb, 0, TASK_SIZE);
        up_write(&mm->mmap_sem);
        return mm->context.has_pgste ? 0 : -ENOMEM;
index a5df511e27a220cf102d8ffee6b7b57f903eb8c3..16871da3737164d986412ff40cc8fb95c2c7119b 100644 (file)
@@ -12,8 +12,8 @@
 #include <linux/random.h>
 #include <linux/init.h>
 #include <asm/cacheflush.h>
-#include <asm/processor.h>
 #include <asm/facility.h>
+#include <asm/dis.h>
 
 /*
  * Conventions:
@@ -156,8 +156,8 @@ static void bpf_jit_prologue(struct bpf_jit *jit)
                EMIT6(0xeb8ff058, 0x0024);
                /* lgr %r14,%r15 */
                EMIT4(0xb90400ef);
-               /* ahi %r15,<offset> */
-               EMIT4_IMM(0xa7fa0000, (jit->seen & SEEN_MEM) ? -112 : -80);
+               /* aghi %r15,<offset> */
+               EMIT4_IMM(0xa7fb0000, (jit->seen & SEEN_MEM) ? -112 : -80);
                /* stg %r14,152(%r15) */
                EMIT6(0xe3e0f098, 0x0024);
        } else if ((jit->seen & SEEN_XREG) && (jit->seen & SEEN_LITERAL))
index f17a8343e3609d7d644b1d5896fd49bf4fca9e88..0c9a17780e4b9be96288a75a356444761f0085d5 100644 (file)
@@ -120,26 +120,17 @@ EXPORT_SYMBOL_GPL(pci_proc_domain);
 static int zpci_set_airq(struct zpci_dev *zdev)
 {
        u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT);
-       struct zpci_fib *fib;
-       int rc;
-
-       fib = (void *) get_zeroed_page(GFP_KERNEL);
-       if (!fib)
-               return -ENOMEM;
+       struct zpci_fib fib = {0};
 
-       fib->isc = PCI_ISC;
-       fib->sum = 1;           /* enable summary notifications */
-       fib->noi = airq_iv_end(zdev->aibv);
-       fib->aibv = (unsigned long) zdev->aibv->vector;
-       fib->aibvo = 0;         /* each zdev has its own interrupt vector */
-       fib->aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8;
-       fib->aisbo = zdev->aisb & 63;
+       fib.isc = PCI_ISC;
+       fib.sum = 1;            /* enable summary notifications */
+       fib.noi = airq_iv_end(zdev->aibv);
+       fib.aibv = (unsigned long) zdev->aibv->vector;
+       fib.aibvo = 0;          /* each zdev has its own interrupt vector */
+       fib.aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8;
+       fib.aisbo = zdev->aisb & 63;
 
-       rc = zpci_mod_fc(req, fib);
-       pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi);
-
-       free_page((unsigned long) fib);
-       return rc;
+       return zpci_mod_fc(req, &fib);
 }
 
 struct mod_pci_args {
@@ -152,22 +143,14 @@ struct mod_pci_args {
 static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
 {
        u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn);
-       struct zpci_fib *fib;
-       int rc;
-
-       /* The FIB must be available even if it's not used */
-       fib = (void *) get_zeroed_page(GFP_KERNEL);
-       if (!fib)
-               return -ENOMEM;
+       struct zpci_fib fib = {0};
 
-       fib->pba = args->base;
-       fib->pal = args->limit;
-       fib->iota = args->iota;
-       fib->fmb_addr = args->fmb_addr;
+       fib.pba = args->base;
+       fib.pal = args->limit;
+       fib.iota = args->iota;
+       fib.fmb_addr = args->fmb_addr;
 
-       rc = zpci_mod_fc(req, fib);
-       free_page((unsigned long) fib);
-       return rc;
+       return zpci_mod_fc(req, &fib);
 }
 
 /* Modify PCI: Register I/O address translation parameters */
@@ -424,7 +407,6 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
        struct msi_msg msg;
        int rc;
 
-       pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec);
        if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI)
                return -EINVAL;
        msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX);
@@ -489,7 +471,6 @@ out_msi:
 out_si:
        airq_iv_free_bit(zpci_aisb_iv, aisb);
 out:
-       dev_err(&pdev->dev, "register MSI failed with: %d\n", rc);
        return rc;
 }
 
@@ -499,14 +480,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
        struct msi_desc *msi;
        int rc;
 
-       pr_info("%s: on pdev: %p\n", __func__, pdev);
-
        /* Disable adapter interrupts */
        rc = zpci_clear_airq(zdev);
-       if (rc) {
-               dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc);
+       if (rc)
                return;
-       }
 
        /* Release MSI interrupts */
        list_for_each_entry(msi, &pdev->msi_list, list) {
@@ -625,8 +602,11 @@ static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned lo
        r->name = name;
 
        rc = request_resource(&iomem_resource, r);
-       if (rc)
-               pr_debug("request resource %pR failed\n", r);
+       if (rc) {
+               kfree(r->name);
+               kfree(r);
+               return ERR_PTR(-ENOMEM);
+       }
        return r;
 }
 
@@ -708,6 +688,47 @@ void pcibios_disable_device(struct pci_dev *pdev)
        zdev->pdev = NULL;
 }
 
+#ifdef CONFIG_HIBERNATE_CALLBACKS
+static int zpci_restore(struct device *dev)
+{
+       struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
+       int ret = 0;
+
+       if (zdev->state != ZPCI_FN_STATE_ONLINE)
+               goto out;
+
+       ret = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
+       if (ret)
+               goto out;
+
+       zpci_map_resources(zdev);
+       zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,
+                          zdev->start_dma + zdev->iommu_size - 1,
+                          (u64) zdev->dma_table);
+
+out:
+       return ret;
+}
+
+static int zpci_freeze(struct device *dev)
+{
+       struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
+
+       if (zdev->state != ZPCI_FN_STATE_ONLINE)
+               return 0;
+
+       zpci_unregister_ioat(zdev, 0);
+       return clp_disable_fh(zdev);
+}
+
+struct dev_pm_ops pcibios_pm_ops = {
+       .thaw_noirq = zpci_restore,
+       .freeze_noirq = zpci_freeze,
+       .restore_noirq = zpci_restore,
+       .poweroff_noirq = zpci_freeze,
+};
+#endif /* CONFIG_HIBERNATE_CALLBACKS */
+
 static int zpci_scan_bus(struct zpci_dev *zdev)
 {
        struct resource *res;
@@ -781,7 +802,6 @@ int zpci_enable_device(struct zpci_dev *zdev)
        rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
        if (rc)
                goto out;
-       pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid);
 
        rc = zpci_dma_init_device(zdev);
        if (rc)
@@ -901,10 +921,6 @@ static int __init pci_base_init(void)
            || !test_facility(71) || !test_facility(72))
                return 0;
 
-       pr_info("Probing PCI hardware: PCI:%d  SID:%d  AEN:%d\n",
-               test_facility(69), test_facility(70),
-               test_facility(71));
-
        rc = zpci_debug_init();
        if (rc)
                goto out;
index 475563c3d1e40d401417c6503946f1933457980d..84147984224a996fca36b72d3aff574df229f1c8 100644 (file)
 #include <asm/pci_debug.h>
 #include <asm/pci_clp.h>
 
+static inline void zpci_err_clp(unsigned int rsp, int rc)
+{
+       struct {
+               unsigned int rsp;
+               int rc;
+       } __packed data = {rsp, rc};
+
+       zpci_err_hex(&data, sizeof(data));
+}
+
 /*
  * Call Logical Processor
  * Retry logic is handled by the caller.
@@ -54,7 +64,6 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
        zdev->msi_addr = response->msia;
        zdev->fmb_update = response->mui;
 
-       pr_debug("Supported number of MSI vectors: %u\n", response->noi);
        switch (response->version) {
        case 1:
                zdev->max_bus_speed = PCIE_SPEED_5_0GT;
@@ -84,8 +93,8 @@ static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid)
        if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
                clp_store_query_pci_fngrp(zdev, &rrb->response);
        else {
-               pr_err("Query PCI FNGRP failed with response: %x  cc: %d\n",
-                       rrb->response.hdr.rsp, rc);
+               zpci_err("Q PCI FGRP:\n");
+               zpci_err_clp(rrb->response.hdr.rsp, rc);
                rc = -EIO;
        }
        clp_free_block(rrb);
@@ -131,8 +140,8 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
                if (rrb->response.pfgid)
                        rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid);
        } else {
-               pr_err("Query PCI failed with response: %x  cc: %d\n",
-                        rrb->response.hdr.rsp, rc);
+               zpci_err("Q PCI FN:\n");
+               zpci_err_clp(rrb->response.hdr.rsp, rc);
                rc = -EIO;
        }
 out:
@@ -206,8 +215,8 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command)
        if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
                *fh = rrb->response.fh;
        else {
-               zpci_dbg(0, "SPF fh:%x, cc:%d, resp:%x\n", *fh, rc,
-                        rrb->response.hdr.rsp);
+               zpci_err("Set PCI FN:\n");
+               zpci_err_clp(rrb->response.hdr.rsp, rc);
                rc = -EIO;
        }
        clp_free_block(rrb);
@@ -262,8 +271,8 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb,
                /* Get PCI function handle list */
                rc = clp_instr(rrb);
                if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
-                       pr_err("List PCI failed with response: 0x%x  cc: %d\n",
-                               rrb->response.hdr.rsp, rc);
+                       zpci_err("List PCI FN:\n");
+                       zpci_err_clp(rrb->response.hdr.rsp, rc);
                        rc = -EIO;
                        goto out;
                }
@@ -273,17 +282,11 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb,
 
                entries = (rrb->response.hdr.len - LIST_PCI_HDR_LEN) /
                        rrb->response.entry_size;
-               pr_info("Detected number of PCI functions: %u\n", entries);
 
-               /* Store the returned resume token as input for the next call */
                resume_token = rrb->response.resume_token;
-
                for (i = 0; i < entries; i++)
                        cb(&rrb->response.fh_list[i]);
        } while (resume_token);
-
-       pr_debug("Maximum number of supported PCI functions: %u\n",
-               rrb->response.max_fn);
 out:
        return rc;
 }
index 7e5573acb06375791ef82582d400ede99f8fe069..9b83d080902dfb6d406c1fb026c95414d7494a53 100644 (file)
@@ -145,10 +145,8 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
                return -EINVAL;
 
        spin_lock_irqsave(&zdev->dma_table_lock, irq_flags);
-       if (!zdev->dma_table) {
-               dev_err(&zdev->pdev->dev, "Missing DMA table\n");
+       if (!zdev->dma_table)
                goto no_refresh;
-       }
 
        for (i = 0; i < nr_pages; i++) {
                dma_update_cpu_trans(zdev, page_addr, dma_addr, flags);
@@ -280,11 +278,8 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
        size = nr_pages * PAGE_SIZE;
 
        dma_addr = zdev->start_dma + iommu_page_index * PAGE_SIZE;
-       if (dma_addr + size > zdev->end_dma) {
-               dev_err(dev, "(dma_addr: 0x%16.16LX + size: 0x%16.16lx) > end_dma: 0x%16.16Lx\n",
-                        dma_addr, size, zdev->end_dma);
+       if (dma_addr + size > zdev->end_dma)
                goto out_free;
-       }
 
        if (direction == DMA_NONE || direction == DMA_TO_DEVICE)
                flags |= ZPCI_TABLE_PROTECTED;
@@ -297,7 +292,8 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
 out_free:
        dma_free_iommu(zdev, iommu_page_index, nr_pages);
 out_err:
-       dev_err(dev, "Failed to map addr: %lx\n", pa);
+       zpci_err("map error:\n");
+       zpci_err_hex(&pa, sizeof(pa));
        return DMA_ERROR_CODE;
 }
 
@@ -312,8 +308,10 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
        npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
        dma_addr = dma_addr & PAGE_MASK;
        if (dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE,
-                            ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID))
-               dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr);
+                            ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) {
+               zpci_err("unmap error:\n");
+               zpci_err_hex(&dma_addr, sizeof(dma_addr));
+       }
 
        atomic64_add(npages, (atomic64_t *) &zdev->fmb->unmapped_pages);
        iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
index 0aecaf9548458e4a88dd450edd65f78d3b1d0449..278e671ec9ac22b977c0598aaa31552d3e32b567 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <asm/pci_debug.h>
 
 /* Content Code Description for PCI Function Error */
 struct zpci_ccdf_err {
@@ -41,25 +42,15 @@ struct zpci_ccdf_avail {
        u16 pec;                        /* PCI event code */
 } __packed;
 
-static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
-{
-       struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
-
-       zpci_err("SEI error CCD:\n");
-       zpci_err_hex(ccdf, sizeof(*ccdf));
-       dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec);
-}
-
 static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
 {
        struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+       struct pci_dev *pdev = zdev ? zdev->pdev : NULL;
 
-       pr_err("%s%s: availability event: fh: 0x%x  fid: 0x%x  event code: 0x%x  reason:",
-               (zdev) ? dev_driver_string(&zdev->pdev->dev) : "?",
-               (zdev) ? dev_name(&zdev->pdev->dev) : "?",
-               ccdf->fh, ccdf->fid, ccdf->pec);
-       print_hex_dump(KERN_CONT, "ccdf", DUMP_PREFIX_OFFSET,
-                      16, 1, ccdf, sizeof(*ccdf), false);
+       pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n",
+               pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
+       zpci_err("avail CCDF:\n");
+       zpci_err_hex(ccdf, sizeof(*ccdf));
 
        switch (ccdf->pec) {
        case 0x0301:
@@ -79,14 +70,16 @@ static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
 void zpci_event_error(void *data)
 {
        struct zpci_ccdf_err *ccdf = data;
-       struct zpci_dev *zdev;
+       struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+
+       zpci_err("error CCDF:\n");
+       zpci_err_hex(ccdf, sizeof(*ccdf));
 
-       zpci_event_log_err(ccdf);
-       zdev = get_zdev_by_fid(ccdf->fid);
-       if (!zdev) {
-               pr_err("Error event for unknown fid: %x", ccdf->fid);
+       if (!zdev)
                return;
-       }
+
+       pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
+              pci_name(zdev->pdev), ccdf->pec, ccdf->fid);
 }
 
 void zpci_event_availability(void *data)
index 063af10ff3c1eb9e76c4724d3977b6bd9421b9fe..0833736afa3238185196bb10e408ebf9328e35ea 100644 (file)
@@ -149,47 +149,32 @@ void irq_ctx_exit(int cpu)
        hardirq_ctx[cpu] = NULL;
 }
 
-asmlinkage void do_softirq(void)
+void do_softirq_own_stack(void)
 {
-       unsigned long flags;
        struct thread_info *curctx;
        union irq_ctx *irqctx;
        u32 *isp;
 
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       if (local_softirq_pending()) {
-               curctx = current_thread_info();
-               irqctx = softirq_ctx[smp_processor_id()];
-               irqctx->tinfo.task = curctx->task;
-               irqctx->tinfo.previous_sp = current_stack_pointer;
-
-               /* build the stack frame on the softirq stack */
-               isp = (u32 *)((char *)irqctx + sizeof(*irqctx));
-
-               __asm__ __volatile__ (
-                       "mov    r15, r9         \n"
-                       "jsr    @%0             \n"
-                       /* switch to the softirq stack */
-                       " mov   %1, r15         \n"
-                       /* restore the thread stack */
-                       "mov    r9, r15         \n"
-                       : /* no outputs */
-                       : "r" (__do_softirq), "r" (isp)
-                       : "memory", "r0", "r1", "r2", "r3", "r4",
-                         "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
-               );
-
-               /*
-                * Shouldn't happen, we returned above if in_interrupt():
-                */
-               WARN_ON_ONCE(softirq_count());
-       }
-
-       local_irq_restore(flags);
+       curctx = current_thread_info();
+       irqctx = softirq_ctx[smp_processor_id()];
+       irqctx->tinfo.task = curctx->task;
+       irqctx->tinfo.previous_sp = current_stack_pointer;
+
+       /* build the stack frame on the softirq stack */
+       isp = (u32 *)((char *)irqctx + sizeof(*irqctx));
+
+       __asm__ __volatile__ (
+               "mov    r15, r9         \n"
+               "jsr    @%0             \n"
+               /* switch to the softirq stack */
+               " mov   %1, r15         \n"
+               /* restore the thread stack */
+               "mov    r9, r15         \n"
+               : /* no outputs */
+               : "r" (__do_softirq), "r" (isp)
+               : "memory", "r0", "r1", "r2", "r3", "r4",
+                 "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
+       );
 }
 #else
 static inline void handle_one_irq(unsigned int irq)
index d4840cec2c55c156203463ec27e3d8d716f0e309..666193f4e8bb414fcf64e45a15f89ebf0ab2f628 100644 (file)
@@ -698,30 +698,19 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs)
        set_irq_regs(old_regs);
 }
 
-void do_softirq(void)
+void do_softirq_own_stack(void)
 {
-       unsigned long flags;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
+       void *orig_sp, *sp = softirq_stack[smp_processor_id()];
 
-       if (local_softirq_pending()) {
-               void *orig_sp, *sp = softirq_stack[smp_processor_id()];
-
-               sp += THREAD_SIZE - 192 - STACK_BIAS;
-
-               __asm__ __volatile__("mov %%sp, %0\n\t"
-                                    "mov %1, %%sp"
-                                    : "=&r" (orig_sp)
-                                    : "r" (sp));
-               __do_softirq();
-               __asm__ __volatile__("mov %0, %%sp"
-                                    : : "r" (orig_sp));
-       }
+       sp += THREAD_SIZE - 192 - STACK_BIAS;
 
-       local_irq_restore(flags);
+       __asm__ __volatile__("mov %%sp, %0\n\t"
+                            "mov %1, %%sp"
+                            : "=&r" (orig_sp)
+                            : "r" (sp));
+       __do_softirq();
+       __asm__ __volatile__("mov %0, %%sp"
+                            : : "r" (orig_sp));
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index f67e839f06c845e406d81c8b2be285ced8b57448..5cd6eea9b7b35707e6b905bba1955be75370b9ac 100644 (file)
@@ -123,6 +123,7 @@ config X86
        select COMPAT_OLD_SIGACTION if IA32_EMULATION
        select RTC_LIB
        select HAVE_DEBUG_STACKOVERFLOW
+       select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64
 
 config INSTRUCTION_DECODER
        def_bool y
index 6e5197910fd87b178921e3dd2ecf883ae3fb0894..3087ea9c5f2e86dfcf9c596258a3d1df6f22bc90 100644 (file)
@@ -35,7 +35,10 @@ typedef u8 uprobe_opcode_t;
 
 struct arch_uprobe {
        u16                             fixups;
-       u8                              insn[MAX_UINSN_BYTES];
+       union {
+               u8                      insn[MAX_UINSN_BYTES];
+               u8                      ixol[MAX_UINSN_BYTES];
+       };
 #ifdef CONFIG_X86_64
        unsigned long                   rip_rela_target_address;
 #endif
@@ -49,11 +52,4 @@ struct arch_uprobe_task {
        unsigned int                    saved_tf;
 };
 
-extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
-extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
-extern int  arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
-extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs);
 #endif /* _ASM_UPROBES_H */
index 9d8449158cf989af3009c6606b7a878c827f5d32..8e132931614d618b03b9f7d69a492b793a27bc30 100644 (file)
@@ -1276,16 +1276,16 @@ void perf_events_lapic_init(void)
 static int __kprobes
 perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
 {
-       int ret;
        u64 start_clock;
        u64 finish_clock;
+       int ret;
 
        if (!atomic_read(&active_events))
                return NMI_DONE;
 
-       start_clock = local_clock();
+       start_clock = sched_clock();
        ret = x86_pmu.handle_irq(regs);
-       finish_clock = local_clock();
+       finish_clock = sched_clock();
 
        perf_sample_event_took(finish_clock - start_clock);
 
@@ -1989,7 +1989,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
                frame.return_address = 0;
 
                bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
-               if (bytes != sizeof(frame))
+               if (bytes != 0)
                        break;
 
                if (!valid_user_frame(fp, sizeof(frame)))
@@ -2041,7 +2041,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
                frame.return_address = 0;
 
                bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
-               if (bytes != sizeof(frame))
+               if (bytes != 0)
                        break;
 
                if (!valid_user_frame(fp, sizeof(frame)))
index cc16faae0538431073b01dfa0bd5c96ab4383ae1..fd00bb29425d4da50194241c6ae3835775e12e6e 100644 (file)
@@ -163,6 +163,11 @@ struct cpu_hw_events {
        u64                             intel_ctrl_host_mask;
        struct perf_guest_switch_msr    guest_switch_msrs[X86_PMC_IDX_MAX];
 
+       /*
+        * Intel checkpoint mask
+        */
+       u64                             intel_cp_status;
+
        /*
         * manage shared (per-core, per-cpu) registers
         * used on Intel NHM/WSM/SNB
@@ -440,6 +445,7 @@ struct x86_pmu {
        int             lbr_nr;                    /* hardware stack size */
        u64             lbr_sel_mask;              /* LBR_SELECT valid bits */
        const int       *lbr_sel_map;              /* lbr_select mappings */
+       bool            lbr_double_abort;          /* duplicated lbr aborts */
 
        /*
         * Extra registers for events
index f31a1655d1ff5bd602239e211b14bdd28d95a79a..0fa4f242f0504ad53297360966e957b84a0edab8 100644 (file)
@@ -190,9 +190,9 @@ static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
        EVENT_EXTRA_END
 };
 
-EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
-EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
-EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
+EVENT_ATTR_STR(mem-loads,      mem_ld_nhm,     "event=0x0b,umask=0x10,ldlat=3");
+EVENT_ATTR_STR(mem-loads,      mem_ld_snb,     "event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores,     mem_st_snb,     "event=0xcd,umask=0x2");
 
 struct attribute *nhm_events_attrs[] = {
        EVENT_PTR(mem_ld_nhm),
@@ -1184,6 +1184,11 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
        wrmsrl(hwc->config_base, ctrl_val);
 }
 
+static inline bool event_is_checkpointed(struct perf_event *event)
+{
+       return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0;
+}
+
 static void intel_pmu_disable_event(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
@@ -1197,6 +1202,7 @@ static void intel_pmu_disable_event(struct perf_event *event)
 
        cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
        cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
+       cpuc->intel_cp_status &= ~(1ull << hwc->idx);
 
        /*
         * must disable before any actual event
@@ -1271,6 +1277,9 @@ static void intel_pmu_enable_event(struct perf_event *event)
        if (event->attr.exclude_guest)
                cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
 
+       if (unlikely(event_is_checkpointed(event)))
+               cpuc->intel_cp_status |= (1ull << hwc->idx);
+
        if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
                intel_pmu_enable_fixed(hwc);
                return;
@@ -1289,6 +1298,17 @@ static void intel_pmu_enable_event(struct perf_event *event)
 int intel_pmu_save_and_restart(struct perf_event *event)
 {
        x86_perf_event_update(event);
+       /*
+        * For a checkpointed counter always reset back to 0.  This
+        * avoids a situation where the counter overflows, aborts the
+        * transaction and is then set back to shortly before the
+        * overflow, and overflows and aborts again.
+        */
+       if (unlikely(event_is_checkpointed(event))) {
+               /* No race with NMIs because the counter should not be armed */
+               wrmsrl(event->hw.event_base, 0);
+               local64_set(&event->hw.prev_count, 0);
+       }
        return x86_perf_event_set_period(event);
 }
 
@@ -1372,6 +1392,13 @@ again:
                x86_pmu.drain_pebs(regs);
        }
 
+       /*
+        * Checkpointed counters can lead to 'spurious' PMIs because the
+        * rollback caused by the PMI will have cleared the overflow status
+        * bit. Therefore always force probe these counters.
+        */
+       status |= cpuc->intel_cp_status;
+
        for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
                struct perf_event *event = cpuc->events[bit];
 
@@ -1837,6 +1864,20 @@ static int hsw_hw_config(struct perf_event *event)
              event->attr.precise_ip > 0))
                return -EOPNOTSUPP;
 
+       if (event_is_checkpointed(event)) {
+               /*
+                * Sampling of checkpointed events can cause situations where
+                * the CPU constantly aborts because of a overflow, which is
+                * then checkpointed back and ignored. Forbid checkpointing
+                * for sampling.
+                *
+                * But still allow a long sampling period, so that perf stat
+                * from KVM works.
+                */
+               if (event->attr.sample_period > 0 &&
+                   event->attr.sample_period < 0x7fffffff)
+                       return -EOPNOTSUPP;
+       }
        return 0;
 }
 
@@ -2182,10 +2223,36 @@ static __init void intel_nehalem_quirk(void)
        }
 }
 
-EVENT_ATTR_STR(mem-loads,      mem_ld_hsw,     "event=0xcd,umask=0x1,ldlat=3");
-EVENT_ATTR_STR(mem-stores,     mem_st_hsw,     "event=0xd0,umask=0x82")
+EVENT_ATTR_STR(mem-loads,      mem_ld_hsw,     "event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores,     mem_st_hsw,     "event=0xd0,umask=0x82")
+
+/* Haswell special events */
+EVENT_ATTR_STR(tx-start,       tx_start,       "event=0xc9,umask=0x1");
+EVENT_ATTR_STR(tx-commit,      tx_commit,      "event=0xc9,umask=0x2");
+EVENT_ATTR_STR(tx-abort,       tx_abort,       "event=0xc9,umask=0x4");
+EVENT_ATTR_STR(tx-capacity,    tx_capacity,    "event=0x54,umask=0x2");
+EVENT_ATTR_STR(tx-conflict,    tx_conflict,    "event=0x54,umask=0x1");
+EVENT_ATTR_STR(el-start,       el_start,       "event=0xc8,umask=0x1");
+EVENT_ATTR_STR(el-commit,      el_commit,      "event=0xc8,umask=0x2");
+EVENT_ATTR_STR(el-abort,       el_abort,       "event=0xc8,umask=0x4");
+EVENT_ATTR_STR(el-capacity,    el_capacity,    "event=0x54,umask=0x2");
+EVENT_ATTR_STR(el-conflict,    el_conflict,    "event=0x54,umask=0x1");
+EVENT_ATTR_STR(cycles-t,       cycles_t,       "event=0x3c,in_tx=1");
+EVENT_ATTR_STR(cycles-ct,      cycles_ct,      "event=0x3c,in_tx=1,in_tx_cp=1");
 
 static struct attribute *hsw_events_attrs[] = {
+       EVENT_PTR(tx_start),
+       EVENT_PTR(tx_commit),
+       EVENT_PTR(tx_abort),
+       EVENT_PTR(tx_capacity),
+       EVENT_PTR(tx_conflict),
+       EVENT_PTR(el_start),
+       EVENT_PTR(el_commit),
+       EVENT_PTR(el_abort),
+       EVENT_PTR(el_capacity),
+       EVENT_PTR(el_conflict),
+       EVENT_PTR(cycles_t),
+       EVENT_PTR(cycles_ct),
        EVENT_PTR(mem_ld_hsw),
        EVENT_PTR(mem_st_hsw),
        NULL
@@ -2452,6 +2519,7 @@ __init int intel_pmu_init(void)
                x86_pmu.hw_config = hsw_hw_config;
                x86_pmu.get_event_constraints = hsw_get_event_constraints;
                x86_pmu.cpu_events = hsw_events_attrs;
+               x86_pmu.lbr_double_abort = true;
                pr_cont("Haswell events, ");
                break;
 
index ab3ba1c1b7dd2c425dd5edf4c2b5091d76355b34..ae96cfa5eddd74a30780e4062fae9af8f34ecd82 100644 (file)
@@ -12,6 +12,7 @@
 
 #define BTS_BUFFER_SIZE                (PAGE_SIZE << 4)
 #define PEBS_BUFFER_SIZE       PAGE_SIZE
+#define PEBS_FIXUP_SIZE                PAGE_SIZE
 
 /*
  * pebs_record_32 for p4 and core not supported
@@ -182,18 +183,32 @@ struct pebs_record_nhm {
  * Same as pebs_record_nhm, with two additional fields.
  */
 struct pebs_record_hsw {
-       struct pebs_record_nhm nhm;
-       /*
-        * Real IP of the event. In the Intel documentation this
-        * is called eventingrip.
-        */
-       u64 real_ip;
-       /*
-        * TSX tuning information field: abort cycles and abort flags.
-        */
-       u64 tsx_tuning;
+       u64 flags, ip;
+       u64 ax, bx, cx, dx;
+       u64 si, di, bp, sp;
+       u64 r8,  r9,  r10, r11;
+       u64 r12, r13, r14, r15;
+       u64 status, dla, dse, lat;
+       u64 real_ip, tsx_tuning;
+};
+
+union hsw_tsx_tuning {
+       struct {
+               u32 cycles_last_block     : 32,
+                   hle_abort             : 1,
+                   rtm_abort             : 1,
+                   instruction_abort     : 1,
+                   non_instruction_abort : 1,
+                   retry                 : 1,
+                   data_conflict         : 1,
+                   capacity_writes       : 1,
+                   capacity_reads        : 1;
+       };
+       u64         value;
 };
 
+#define PEBS_HSW_TSX_FLAGS     0xff00000000ULL
+
 void init_debug_store_on_cpu(int cpu)
 {
        struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
@@ -214,12 +229,14 @@ void fini_debug_store_on_cpu(int cpu)
        wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
 }
 
+static DEFINE_PER_CPU(void *, insn_buffer);
+
 static int alloc_pebs_buffer(int cpu)
 {
        struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
        int node = cpu_to_node(cpu);
        int max, thresh = 1; /* always use a single PEBS record */
-       void *buffer;
+       void *buffer, *ibuffer;
 
        if (!x86_pmu.pebs)
                return 0;
@@ -228,6 +245,19 @@ static int alloc_pebs_buffer(int cpu)
        if (unlikely(!buffer))
                return -ENOMEM;
 
+       /*
+        * HSW+ already provides us the eventing ip; no need to allocate this
+        * buffer then.
+        */
+       if (x86_pmu.intel_cap.pebs_format < 2) {
+               ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
+               if (!ibuffer) {
+                       kfree(buffer);
+                       return -ENOMEM;
+               }
+               per_cpu(insn_buffer, cpu) = ibuffer;
+       }
+
        max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
 
        ds->pebs_buffer_base = (u64)(unsigned long)buffer;
@@ -248,6 +278,9 @@ static void release_pebs_buffer(int cpu)
        if (!ds || !x86_pmu.pebs)
                return;
 
+       kfree(per_cpu(insn_buffer, cpu));
+       per_cpu(insn_buffer, cpu) = NULL;
+
        kfree((void *)(unsigned long)ds->pebs_buffer_base);
        ds->pebs_buffer_base = 0;
 }
@@ -715,6 +748,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
        unsigned long old_to, to = cpuc->lbr_entries[0].to;
        unsigned long ip = regs->ip;
        int is_64bit = 0;
+       void *kaddr;
 
        /*
         * We don't need to fixup if the PEBS assist is fault like
@@ -738,7 +772,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
         * unsigned math, either ip is before the start (impossible) or
         * the basic block is larger than 1 page (sanity)
         */
-       if ((ip - to) > PAGE_SIZE)
+       if ((ip - to) > PEBS_FIXUP_SIZE)
                return 0;
 
        /*
@@ -749,29 +783,33 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
                return 1;
        }
 
+       if (!kernel_ip(ip)) {
+               int size, bytes;
+               u8 *buf = this_cpu_read(insn_buffer);
+
+               size = ip - to; /* Must fit our buffer, see above */
+               bytes = copy_from_user_nmi(buf, (void __user *)to, size);
+               if (bytes != 0)
+                       return 0;
+
+               kaddr = buf;
+       } else {
+               kaddr = (void *)to;
+       }
+
        do {
                struct insn insn;
-               u8 buf[MAX_INSN_SIZE];
-               void *kaddr;
 
                old_to = to;
-               if (!kernel_ip(ip)) {
-                       int bytes, size = MAX_INSN_SIZE;
-
-                       bytes = copy_from_user_nmi(buf, (void __user *)to, size);
-                       if (bytes != size)
-                               return 0;
-
-                       kaddr = buf;
-               } else
-                       kaddr = (void *)to;
 
 #ifdef CONFIG_X86_64
                is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
 #endif
                insn_init(&insn, kaddr, is_64bit);
                insn_get_length(&insn);
+
                to += insn.length;
+               kaddr += insn.length;
        } while (to < ip);
 
        if (to == ip) {
@@ -786,16 +824,34 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
        return 0;
 }
 
+static inline u64 intel_hsw_weight(struct pebs_record_hsw *pebs)
+{
+       if (pebs->tsx_tuning) {
+               union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning };
+               return tsx.cycles_last_block;
+       }
+       return 0;
+}
+
+static inline u64 intel_hsw_transaction(struct pebs_record_hsw *pebs)
+{
+       u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
+
+       /* For RTM XABORTs also log the abort code from AX */
+       if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1))
+               txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
+       return txn;
+}
+
 static void __intel_pmu_pebs_event(struct perf_event *event,
                                   struct pt_regs *iregs, void *__pebs)
 {
        /*
-        * We cast to pebs_record_nhm to get the load latency data
-        * if extra_reg MSR_PEBS_LD_LAT_THRESHOLD used
+        * We cast to the biggest pebs_record but are careful not to
+        * unconditionally access the 'extra' entries.
         */
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct pebs_record_nhm *pebs = __pebs;
-       struct pebs_record_hsw *pebs_hsw = __pebs;
+       struct pebs_record_hsw *pebs = __pebs;
        struct perf_sample_data data;
        struct pt_regs regs;
        u64 sample_type;
@@ -854,7 +910,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
        regs.sp = pebs->sp;
 
        if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
-               regs.ip = pebs_hsw->real_ip;
+               regs.ip = pebs->real_ip;
                regs.flags |= PERF_EFLAGS_EXACT;
        } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
                regs.flags |= PERF_EFLAGS_EXACT;
@@ -862,9 +918,18 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
                regs.flags &= ~PERF_EFLAGS_EXACT;
 
        if ((event->attr.sample_type & PERF_SAMPLE_ADDR) &&
-               x86_pmu.intel_cap.pebs_format >= 1)
+           x86_pmu.intel_cap.pebs_format >= 1)
                data.addr = pebs->dla;
 
+       if (x86_pmu.intel_cap.pebs_format >= 2) {
+               /* Only set the TSX weight when no memory weight. */
+               if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) && !fll)
+                       data.weight = intel_hsw_weight(pebs);
+
+               if (event->attr.sample_type & PERF_SAMPLE_TRANSACTION)
+                       data.txn = intel_hsw_transaction(pebs);
+       }
+
        if (has_branch_stack(event))
                data.br_stack = &cpuc->lbr_stack;
 
@@ -913,17 +978,34 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
        __intel_pmu_pebs_event(event, iregs, at);
 }
 
-static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at,
-                                       void *top)
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        struct debug_store *ds = cpuc->ds;
        struct perf_event *event = NULL;
+       void *at, *top;
        u64 status = 0;
        int bit;
 
+       if (!x86_pmu.pebs_active)
+               return;
+
+       at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+       top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
        ds->pebs_index = ds->pebs_buffer_base;
 
+       if (unlikely(at > top))
+               return;
+
+       /*
+        * Should not happen, we program the threshold at 1 and do not
+        * set a reset value.
+        */
+       WARN_ONCE(top - at > x86_pmu.max_pebs_events * x86_pmu.pebs_record_size,
+                 "Unexpected number of pebs records %ld\n",
+                 (long)(top - at) / x86_pmu.pebs_record_size);
+
        for (; at < top; at += x86_pmu.pebs_record_size) {
                struct pebs_record_nhm *p = at;
 
@@ -951,61 +1033,6 @@ static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at,
        }
 }
 
-static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct debug_store *ds = cpuc->ds;
-       struct pebs_record_nhm *at, *top;
-       int n;
-
-       if (!x86_pmu.pebs_active)
-               return;
-
-       at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
-       top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
-
-       ds->pebs_index = ds->pebs_buffer_base;
-
-       n = top - at;
-       if (n <= 0)
-               return;
-
-       /*
-        * Should not happen, we program the threshold at 1 and do not
-        * set a reset value.
-        */
-       WARN_ONCE(n > x86_pmu.max_pebs_events,
-                 "Unexpected number of pebs records %d\n", n);
-
-       return __intel_pmu_drain_pebs_nhm(iregs, at, top);
-}
-
-static void intel_pmu_drain_pebs_hsw(struct pt_regs *iregs)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct debug_store *ds = cpuc->ds;
-       struct pebs_record_hsw *at, *top;
-       int n;
-
-       if (!x86_pmu.pebs_active)
-               return;
-
-       at  = (struct pebs_record_hsw *)(unsigned long)ds->pebs_buffer_base;
-       top = (struct pebs_record_hsw *)(unsigned long)ds->pebs_index;
-
-       n = top - at;
-       if (n <= 0)
-               return;
-       /*
-        * Should not happen, we program the threshold at 1 and do not
-        * set a reset value.
-        */
-       WARN_ONCE(n > x86_pmu.max_pebs_events,
-                 "Unexpected number of pebs records %d\n", n);
-
-       return __intel_pmu_drain_pebs_nhm(iregs, at, top);
-}
-
 /*
  * BTS, PEBS probe and setup
  */
@@ -1040,7 +1067,7 @@ void intel_ds_init(void)
                case 2:
                        pr_cont("PEBS fmt2%c, ", pebs_type);
                        x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
-                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_hsw;
+                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
                        break;
 
                default:
index d5be06a5005e99eb9ac8dbe808f565013bddc929..d82d155aca8c7c6c44c9ba7150dae39e88e16fad 100644 (file)
@@ -284,6 +284,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
        int lbr_format = x86_pmu.intel_cap.lbr_format;
        u64 tos = intel_pmu_lbr_tos();
        int i;
+       int out = 0;
 
        for (i = 0; i < x86_pmu.lbr_nr; i++) {
                unsigned long lbr_idx = (tos - i) & mask;
@@ -306,15 +307,27 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
                }
                from = (u64)((((s64)from) << skip) >> skip);
 
-               cpuc->lbr_entries[i].from       = from;
-               cpuc->lbr_entries[i].to         = to;
-               cpuc->lbr_entries[i].mispred    = mis;
-               cpuc->lbr_entries[i].predicted  = pred;
-               cpuc->lbr_entries[i].in_tx      = in_tx;
-               cpuc->lbr_entries[i].abort      = abort;
-               cpuc->lbr_entries[i].reserved   = 0;
+               /*
+                * Some CPUs report duplicated abort records,
+                * with the second entry not having an abort bit set.
+                * Skip them here. This loop runs backwards,
+                * so we need to undo the previous record.
+                * If the abort just happened outside the window
+                * the extra entry cannot be removed.
+                */
+               if (abort && x86_pmu.lbr_double_abort && out > 0)
+                       out--;
+
+               cpuc->lbr_entries[out].from      = from;
+               cpuc->lbr_entries[out].to        = to;
+               cpuc->lbr_entries[out].mispred   = mis;
+               cpuc->lbr_entries[out].predicted = pred;
+               cpuc->lbr_entries[out].in_tx     = in_tx;
+               cpuc->lbr_entries[out].abort     = abort;
+               cpuc->lbr_entries[out].reserved  = 0;
+               out++;
        }
-       cpuc->lbr_stack.nr = i;
+       cpuc->lbr_stack.nr = out;
 }
 
 void intel_pmu_lbr_read(void)
@@ -478,7 +491,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
 
                /* may fail if text not present */
                bytes = copy_from_user_nmi(buf, (void __user *)from, size);
-               if (bytes != size)
+               if (bytes != 0)
                        return X86_BR_NONE;
 
                addr = buf;
index 4118f9f683151e99402740f1882b205a261a1465..29c248799cede4432ac2d57ca8689a215c35d0cc 100644 (file)
@@ -997,6 +997,20 @@ static int snbep_pci2phy_map_init(int devid)
                }
        }
 
+       if (!err) {
+               /*
+                * For PCI bus with no UBOX device, find the next bus
+                * that has UBOX device and use its mapping.
+                */
+               i = -1;
+               for (bus = 255; bus >= 0; bus--) {
+                       if (pcibus_to_physid[bus] >= 0)
+                               i = pcibus_to_physid[bus];
+                       else
+                               pcibus_to_physid[bus] = i;
+               }
+       }
+
        if (ubox_dev)
                pci_dev_put(ubox_dev);
 
@@ -1099,6 +1113,24 @@ static struct attribute *ivt_uncore_qpi_formats_attr[] = {
        &format_attr_umask.attr,
        &format_attr_edge.attr,
        &format_attr_thresh8.attr,
+       &format_attr_match_rds.attr,
+       &format_attr_match_rnid30.attr,
+       &format_attr_match_rnid4.attr,
+       &format_attr_match_dnid.attr,
+       &format_attr_match_mc.attr,
+       &format_attr_match_opc.attr,
+       &format_attr_match_vnw.attr,
+       &format_attr_match0.attr,
+       &format_attr_match1.attr,
+       &format_attr_mask_rds.attr,
+       &format_attr_mask_rnid30.attr,
+       &format_attr_mask_rnid4.attr,
+       &format_attr_mask_dnid.attr,
+       &format_attr_mask_mc.attr,
+       &format_attr_mask_opc.attr,
+       &format_attr_mask_vnw.attr,
+       &format_attr_mask0.attr,
+       &format_attr_mask1.attr,
        NULL,
 };
 
@@ -1312,17 +1344,83 @@ static struct intel_uncore_type ivt_uncore_imc = {
        IVT_UNCORE_PCI_COMMON_INIT(),
 };
 
+/* registers in IRP boxes are not properly aligned */
+static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
+static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
+
+static void ivt_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+       struct pci_dev *pdev = box->pci_dev;
+       struct hw_perf_event *hwc = &event->hw;
+
+       pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx],
+                              hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+       struct pci_dev *pdev = box->pci_dev;
+       struct hw_perf_event *hwc = &event->hw;
+
+       pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config);
+}
+
+static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+       struct pci_dev *pdev = box->pci_dev;
+       struct hw_perf_event *hwc = &event->hw;
+       u64 count = 0;
+
+       pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
+       pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
+
+       return count;
+}
+
+static struct intel_uncore_ops ivt_uncore_irp_ops = {
+       .init_box       = ivt_uncore_pci_init_box,
+       .disable_box    = snbep_uncore_pci_disable_box,
+       .enable_box     = snbep_uncore_pci_enable_box,
+       .disable_event  = ivt_uncore_irp_disable_event,
+       .enable_event   = ivt_uncore_irp_enable_event,
+       .read_counter   = ivt_uncore_irp_read_counter,
+};
+
+static struct intel_uncore_type ivt_uncore_irp = {
+       .name                   = "irp",
+       .num_counters           = 4,
+       .num_boxes              = 1,
+       .perf_ctr_bits          = 48,
+       .event_mask             = IVT_PMON_RAW_EVENT_MASK,
+       .box_ctl                = SNBEP_PCI_PMON_BOX_CTL,
+       .ops                    = &ivt_uncore_irp_ops,
+       .format_group           = &ivt_uncore_format_group,
+};
+
+static struct intel_uncore_ops ivt_uncore_qpi_ops = {
+       .init_box       = ivt_uncore_pci_init_box,
+       .disable_box    = snbep_uncore_pci_disable_box,
+       .enable_box     = snbep_uncore_pci_enable_box,
+       .disable_event  = snbep_uncore_pci_disable_event,
+       .enable_event   = snbep_qpi_enable_event,
+       .read_counter   = snbep_uncore_pci_read_counter,
+       .hw_config      = snbep_qpi_hw_config,
+       .get_constraint = uncore_get_constraint,
+       .put_constraint = uncore_put_constraint,
+};
+
 static struct intel_uncore_type ivt_uncore_qpi = {
-       .name           = "qpi",
-       .num_counters   = 4,
-       .num_boxes      = 3,
-       .perf_ctr_bits  = 48,
-       .perf_ctr       = SNBEP_PCI_PMON_CTR0,
-       .event_ctl      = SNBEP_PCI_PMON_CTL0,
-       .event_mask     = IVT_QPI_PCI_PMON_RAW_EVENT_MASK,
-       .box_ctl        = SNBEP_PCI_PMON_BOX_CTL,
-       .ops            = &ivt_uncore_pci_ops,
-       .format_group   = &ivt_uncore_qpi_format_group,
+       .name                   = "qpi",
+       .num_counters           = 4,
+       .num_boxes              = 3,
+       .perf_ctr_bits          = 48,
+       .perf_ctr               = SNBEP_PCI_PMON_CTR0,
+       .event_ctl              = SNBEP_PCI_PMON_CTL0,
+       .event_mask             = IVT_QPI_PCI_PMON_RAW_EVENT_MASK,
+       .box_ctl                = SNBEP_PCI_PMON_BOX_CTL,
+       .num_shared_regs        = 1,
+       .ops                    = &ivt_uncore_qpi_ops,
+       .format_group           = &ivt_uncore_qpi_format_group,
 };
 
 static struct intel_uncore_type ivt_uncore_r2pcie = {
@@ -1346,6 +1444,7 @@ static struct intel_uncore_type ivt_uncore_r3qpi = {
 enum {
        IVT_PCI_UNCORE_HA,
        IVT_PCI_UNCORE_IMC,
+       IVT_PCI_UNCORE_IRP,
        IVT_PCI_UNCORE_QPI,
        IVT_PCI_UNCORE_R2PCIE,
        IVT_PCI_UNCORE_R3QPI,
@@ -1354,6 +1453,7 @@ enum {
 static struct intel_uncore_type *ivt_pci_uncores[] = {
        [IVT_PCI_UNCORE_HA]     = &ivt_uncore_ha,
        [IVT_PCI_UNCORE_IMC]    = &ivt_uncore_imc,
+       [IVT_PCI_UNCORE_IRP]    = &ivt_uncore_irp,
        [IVT_PCI_UNCORE_QPI]    = &ivt_uncore_qpi,
        [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie,
        [IVT_PCI_UNCORE_R3QPI]  = &ivt_uncore_r3qpi,
@@ -1401,6 +1501,10 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
                .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7),
        },
+       { /* IRP */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0),
+       },
        { /* QPI0 Port 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
                .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0),
@@ -1429,6 +1533,16 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
                .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2),
        },
+       { /* QPI Port 0 filter  */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
+               .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+                                                  SNBEP_PCI_QPI_PORT0_FILTER),
+       },
+       { /* QPI Port 0 filter  */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
+               .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+                                                  SNBEP_PCI_QPI_PORT1_FILTER),
+       },
        { /* end: all zeroes */ }
 };
 
index 1a2cc64abcd74177f41d4e1634833fb1456a0b9d..603be7c70675fc7146a8dc08117b9d1b682dc77c 100644 (file)
@@ -1340,7 +1340,7 @@ bad_gs:
        .previous
 
 /* Call softirq on interrupt stack. Interrupts are off. */
-ENTRY(call_softirq)
+ENTRY(do_softirq_own_stack)
        CFI_STARTPROC
        pushq_cfi %rbp
        CFI_REL_OFFSET rbp,0
@@ -1357,7 +1357,7 @@ ENTRY(call_softirq)
        decl PER_CPU_VAR(irq_count)
        ret
        CFI_ENDPROC
-END(call_softirq)
+END(do_softirq_own_stack)
 
 #ifdef CONFIG_XEN
 zeroentry xen_hypervisor_callback xen_do_hypervisor_callback
index 9a5c460404dca563a1e5ac32aeeb90ba2cdaafbf..2e977b5d61ddee4e00d599f04236d70e8714fee0 100644 (file)
@@ -312,8 +312,7 @@ static void init_8259A(int auto_eoi)
         */
        outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
 
-       /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 on x86-64,
-          to 0x20-0x27 on i386 */
+       /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */
        outb_pic(IRQ0_VECTOR, PIC_MASTER_IMR);
 
        /* 8259A-1 (the master) has a slave on IR2 */
index 3fe066359ac08df2693928f66323ca3db3c2e925..d7fcbedc9c43fa9659b7f2f2c687b8402a826dd2 100644 (file)
@@ -145,35 +145,21 @@ void irq_ctx_init(int cpu)
               cpu, per_cpu(hardirq_ctx, cpu),  per_cpu(softirq_ctx, cpu));
 }
 
-asmlinkage void do_softirq(void)
+void do_softirq_own_stack(void)
 {
-       unsigned long flags;
        struct thread_info *curctx;
        union irq_ctx *irqctx;
        u32 *isp;
 
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       if (local_softirq_pending()) {
-               curctx = current_thread_info();
-               irqctx = __this_cpu_read(softirq_ctx);
-               irqctx->tinfo.task = curctx->task;
-               irqctx->tinfo.previous_esp = current_stack_pointer;
-
-               /* build the stack frame on the softirq stack */
-               isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
+       curctx = current_thread_info();
+       irqctx = __this_cpu_read(softirq_ctx);
+       irqctx->tinfo.task = curctx->task;
+       irqctx->tinfo.previous_esp = current_stack_pointer;
 
-               call_on_stack(__do_softirq, isp);
-               /*
-                * Shouldn't happen, we returned above if in_interrupt():
-                */
-               WARN_ON_ONCE(softirq_count());
-       }
+       /* build the stack frame on the softirq stack */
+       isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
 
-       local_irq_restore(flags);
+       call_on_stack(__do_softirq, isp);
 }
 
 bool handle_irq(unsigned irq, struct pt_regs *regs)
index d04d3ecded6299ab2abb7183089908439c2a0e6a..4d1c746892eb9a9aae2e38dedfec88868f347cff 100644 (file)
@@ -87,24 +87,3 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
        generic_handle_irq_desc(irq, desc);
        return true;
 }
-
-
-extern void call_softirq(void);
-
-asmlinkage void do_softirq(void)
-{
-       __u32 pending;
-       unsigned long flags;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-       pending = local_softirq_pending();
-       /* Switch to interrupt stack */
-       if (pending) {
-               call_softirq();
-               WARN_ON_ONCE(softirq_count());
-       }
-       local_irq_restore(flags);
-}
index ba77ebc2c35321dc4085c06a106f715ec18d9a21..6fcb49ce50a1260d1f4bfdf0b5a065dd4f6d77c7 100644 (file)
@@ -113,10 +113,10 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2
                u64 before, delta, whole_msecs;
                int remainder_ns, decimal_msecs, thishandled;
 
-               before = local_clock();
+               before = sched_clock();
                thishandled = a->handler(type, regs);
                handled += thishandled;
-               delta = local_clock() - before;
+               delta = sched_clock() - before;
                trace_nmi_handler(a->handler, (int)delta, thishandled);
 
                if (delta < nmi_longest_ns)
index 4f74d94c8d9727f013b3ebed6fe5da6e3975ac93..ddf9ecb53cc3e23171ea889dc47339e67ba5d2c8 100644 (file)
 #include <linux/sched.h>
 
 /*
- * best effort, GUP based copy_from_user() that is NMI-safe
+ * We rely on the nested NMI work to allow atomic faults from the NMI path; the
+ * nested NMI paths are careful to preserve CR2.
  */
 unsigned long
 copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
 {
-       unsigned long offset, addr = (unsigned long)from;
-       unsigned long size, len = 0;
-       struct page *page;
-       void *map;
-       int ret;
+       unsigned long ret;
 
        if (__range_not_ok(from, n, TASK_SIZE))
-               return len;
-
-       do {
-               ret = __get_user_pages_fast(addr, 1, 0, &page);
-               if (!ret)
-                       break;
-
-               offset = addr & (PAGE_SIZE - 1);
-               size = min(PAGE_SIZE - offset, n - len);
-
-               map = kmap_atomic(page);
-               memcpy(to, map+offset, size);
-               kunmap_atomic(map);
-               put_page(page);
-
-               len  += size;
-               to   += size;
-               addr += size;
-
-       } while (len < n);
-
-       return len;
+               return 0;
+
+       /*
+        * Even though this function is typically called from NMI/IRQ context
+        * disable pagefaults so that its behaviour is consistent even when
+        * called form other contexts.
+        */
+       pagefault_disable();
+       ret = __copy_from_user_inatomic(to, from, n);
+       pagefault_enable();
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(copy_from_user_nmi);
index 3aaeffcfd67a6d9ae3b3e89514fed55c31e2ea4d..7a517bb410600ffc6d741973ff865c7c1d8382e1 100644 (file)
@@ -51,7 +51,7 @@ kmmio_fault(struct pt_regs *regs, unsigned long addr)
        return 0;
 }
 
-static inline int __kprobes notify_page_fault(struct pt_regs *regs)
+static inline int __kprobes kprobes_fault(struct pt_regs *regs)
 {
        int ret = 0;
 
@@ -1048,7 +1048,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
                        return;
 
                /* kprobes don't want to hook the spurious faults: */
-               if (notify_page_fault(regs))
+               if (kprobes_fault(regs))
                        return;
                /*
                 * Don't take the mm semaphore here. If we fixup a prefetch
@@ -1060,23 +1060,8 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
        }
 
        /* kprobes don't want to hook the spurious faults: */
-       if (unlikely(notify_page_fault(regs)))
+       if (unlikely(kprobes_fault(regs)))
                return;
-       /*
-        * It's safe to allow irq's after cr2 has been saved and the
-        * vmalloc fault has been handled.
-        *
-        * User-mode registers count as a user access even for any
-        * potential system fault or CPU buglet:
-        */
-       if (user_mode_vm(regs)) {
-               local_irq_enable();
-               error_code |= PF_USER;
-               flags |= FAULT_FLAG_USER;
-       } else {
-               if (regs->flags & X86_EFLAGS_IF)
-                       local_irq_enable();
-       }
 
        if (unlikely(error_code & PF_RSVD))
                pgtable_bad(regs, error_code, address);
@@ -1088,8 +1073,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
                }
        }
 
-       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
-
        /*
         * If we're in an interrupt, have no user context or are running
         * in an atomic region then we must not take the fault:
@@ -1099,6 +1082,24 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
                return;
        }
 
+       /*
+        * It's safe to allow irq's after cr2 has been saved and the
+        * vmalloc fault has been handled.
+        *
+        * User-mode registers count as a user access even for any
+        * potential system fault or CPU buglet:
+        */
+       if (user_mode_vm(regs)) {
+               local_irq_enable();
+               error_code |= PF_USER;
+               flags |= FAULT_FLAG_USER;
+       } else {
+               if (regs->flags & X86_EFLAGS_IF)
+                       local_irq_enable();
+       }
+
+       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+
        if (error_code & PF_WRITE)
                flags |= FAULT_FLAG_WRITE;
 
index d6aa6e8315d13ac718615947077f2b6fd113cb35..5d04be5efb6401b1b7512f4ca519a24a016b20d2 100644 (file)
@@ -47,7 +47,7 @@ dump_user_backtrace_32(struct stack_frame_ia32 *head)
        unsigned long bytes;
 
        bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
-       if (bytes != sizeof(bufhead))
+       if (bytes != 0)
                return NULL;
 
        fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame);
@@ -93,7 +93,7 @@ static struct stack_frame *dump_user_backtrace(struct stack_frame *head)
        unsigned long bytes;
 
        bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
-       if (bytes != sizeof(bufhead))
+       if (bytes != 0)
                return NULL;
 
        oprofile_add_trace(bufhead[0].return_address);
index aa43b911ccef582c78e70a914106ba454de2c05b..8f451449abd3dc05651414483bceba221d6136f0 100644 (file)
@@ -166,4 +166,6 @@ source "drivers/reset/Kconfig"
 
 source "drivers/fmc/Kconfig"
 
+source "drivers/phy/Kconfig"
+
 endmenu
index ab93de8297f1338fc2440967ce8934a7ff6bc043..687da899cadb5b0bbe1dd7e04ec6b56d1d000022 100644 (file)
@@ -8,6 +8,8 @@
 obj-y                          += irqchip/
 obj-y                          += bus/
 
+obj-$(CONFIG_GENERIC_PHY)      += phy/
+
 # GPIO must come after pinctrl as gpios may need to mux pins etc
 obj-y                          += pinctrl/
 obj-y                          += gpio/
index 4c289ab91357531373c25889b5911bff33ae3d64..73f6c2925281f43ab752e0a374c059133e2f61ef 100644 (file)
@@ -591,37 +591,6 @@ void bus_remove_device(struct device *dev)
        bus_put(dev->bus);
 }
 
-static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv)
-{
-       int error = 0;
-       int i;
-
-       if (bus->drv_attrs) {
-               for (i = 0; bus->drv_attrs[i].attr.name; i++) {
-                       error = driver_create_file(drv, &bus->drv_attrs[i]);
-                       if (error)
-                               goto err;
-               }
-       }
-done:
-       return error;
-err:
-       while (--i >= 0)
-               driver_remove_file(drv, &bus->drv_attrs[i]);
-       goto done;
-}
-
-static void driver_remove_attrs(struct bus_type *bus,
-                               struct device_driver *drv)
-{
-       int i;
-
-       if (bus->drv_attrs) {
-               for (i = 0; bus->drv_attrs[i].attr.name; i++)
-                       driver_remove_file(drv, &bus->drv_attrs[i]);
-       }
-}
-
 static int __must_check add_bind_files(struct device_driver *drv)
 {
        int ret;
@@ -720,16 +689,12 @@ int bus_add_driver(struct device_driver *drv)
                printk(KERN_ERR "%s: uevent attr (%s) failed\n",
                        __func__, drv->name);
        }
-       error = driver_add_attrs(bus, drv);
+       error = driver_add_groups(drv, bus->drv_groups);
        if (error) {
                /* How the hell do we get out of this pickle? Give up */
-               printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
-                       __func__, drv->name);
-       }
-       error = driver_add_groups(drv, bus->drv_groups);
-       if (error)
                printk(KERN_ERR "%s: driver_create_groups(%s) failed\n",
                        __func__, drv->name);
+       }
 
        if (!drv->suppress_bind_attrs) {
                error = add_bind_files(drv);
@@ -766,7 +731,6 @@ void bus_remove_driver(struct device_driver *drv)
 
        if (!drv->suppress_bind_attrs)
                remove_bind_files(drv);
-       driver_remove_attrs(drv->bus, drv);
        driver_remove_groups(drv, drv->bus->drv_groups);
        driver_remove_file(drv, &driver_attr_uevent);
        klist_remove(&drv->p->knode_bus);
@@ -846,42 +810,6 @@ struct bus_type *find_bus(char *name)
 }
 #endif  /*  0  */
 
-
-/**
- * bus_add_attrs - Add default attributes for this bus.
- * @bus: Bus that has just been registered.
- */
-
-static int bus_add_attrs(struct bus_type *bus)
-{
-       int error = 0;
-       int i;
-
-       if (bus->bus_attrs) {
-               for (i = 0; bus->bus_attrs[i].attr.name; i++) {
-                       error = bus_create_file(bus, &bus->bus_attrs[i]);
-                       if (error)
-                               goto err;
-               }
-       }
-done:
-       return error;
-err:
-       while (--i >= 0)
-               bus_remove_file(bus, &bus->bus_attrs[i]);
-       goto done;
-}
-
-static void bus_remove_attrs(struct bus_type *bus)
-{
-       int i;
-
-       if (bus->bus_attrs) {
-               for (i = 0; bus->bus_attrs[i].attr.name; i++)
-                       bus_remove_file(bus, &bus->bus_attrs[i]);
-       }
-}
-
 static int bus_add_groups(struct bus_type *bus,
                          const struct attribute_group **groups)
 {
@@ -983,9 +911,6 @@ int bus_register(struct bus_type *bus)
        if (retval)
                goto bus_probe_files_fail;
 
-       retval = bus_add_attrs(bus);
-       if (retval)
-               goto bus_attrs_fail;
        retval = bus_add_groups(bus, bus->bus_groups);
        if (retval)
                goto bus_groups_fail;
@@ -994,8 +919,6 @@ int bus_register(struct bus_type *bus)
        return 0;
 
 bus_groups_fail:
-       bus_remove_attrs(bus);
-bus_attrs_fail:
        remove_probe_files(bus);
 bus_probe_files_fail:
        kset_unregister(bus->p->drivers_kset);
@@ -1024,7 +947,6 @@ void bus_unregister(struct bus_type *bus)
        pr_debug("bus: '%s': unregistering\n", bus->name);
        if (bus->dev_root)
                device_unregister(bus->dev_root);
-       bus_remove_attrs(bus);
        bus_remove_groups(bus, bus->bus_groups);
        remove_probe_files(bus);
        kset_unregister(bus->p->drivers_kset);
index 8b7818b800569b287536cb366080af3e92f393f2..f96f70419a785a722283336a4ca71a73015574b9 100644 (file)
@@ -47,18 +47,6 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
        return ret;
 }
 
-static const void *class_attr_namespace(struct kobject *kobj,
-                                       const struct attribute *attr)
-{
-       struct class_attribute *class_attr = to_class_attr(attr);
-       struct subsys_private *cp = to_subsys_private(kobj);
-       const void *ns = NULL;
-
-       if (class_attr->namespace)
-               ns = class_attr->namespace(cp->class, class_attr);
-       return ns;
-}
-
 static void class_release(struct kobject *kobj)
 {
        struct subsys_private *cp = to_subsys_private(kobj);
@@ -86,7 +74,6 @@ static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject
 static const struct sysfs_ops class_sysfs_ops = {
        .show      = class_attr_show,
        .store     = class_attr_store,
-       .namespace = class_attr_namespace,
 };
 
 static struct kobj_type class_ktype = {
@@ -99,21 +86,23 @@ static struct kobj_type class_ktype = {
 static struct kset *class_kset;
 
 
-int class_create_file(struct class *cls, const struct class_attribute *attr)
+int class_create_file_ns(struct class *cls, const struct class_attribute *attr,
+                        const void *ns)
 {
        int error;
        if (cls)
-               error = sysfs_create_file(&cls->p->subsys.kobj,
-                                         &attr->attr);
+               error = sysfs_create_file_ns(&cls->p->subsys.kobj,
+                                            &attr->attr, ns);
        else
                error = -EINVAL;
        return error;
 }
 
-void class_remove_file(struct class *cls, const struct class_attribute *attr)
+void class_remove_file_ns(struct class *cls, const struct class_attribute *attr,
+                         const void *ns)
 {
        if (cls)
-               sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr);
+               sysfs_remove_file_ns(&cls->p->subsys.kobj, &attr->attr, ns);
 }
 
 static struct class *class_get(struct class *cls)
@@ -600,8 +589,8 @@ int __init classes_init(void)
        return 0;
 }
 
-EXPORT_SYMBOL_GPL(class_create_file);
-EXPORT_SYMBOL_GPL(class_remove_file);
+EXPORT_SYMBOL_GPL(class_create_file_ns);
+EXPORT_SYMBOL_GPL(class_remove_file_ns);
 EXPORT_SYMBOL_GPL(class_unregister);
 EXPORT_SYMBOL_GPL(class_destroy);
 
index 34abf4d8a45ff4f3f6d25787887a8bc787779133..67b180d855b2c7baf365e5174802581b3c766745 100644 (file)
@@ -455,64 +455,6 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RW(online);
 
-static int device_add_attributes(struct device *dev,
-                                struct device_attribute *attrs)
-{
-       int error = 0;
-       int i;
-
-       if (attrs) {
-               for (i = 0; attrs[i].attr.name; i++) {
-                       error = device_create_file(dev, &attrs[i]);
-                       if (error)
-                               break;
-               }
-               if (error)
-                       while (--i >= 0)
-                               device_remove_file(dev, &attrs[i]);
-       }
-       return error;
-}
-
-static void device_remove_attributes(struct device *dev,
-                                    struct device_attribute *attrs)
-{
-       int i;
-
-       if (attrs)
-               for (i = 0; attrs[i].attr.name; i++)
-                       device_remove_file(dev, &attrs[i]);
-}
-
-static int device_add_bin_attributes(struct device *dev,
-                                    struct bin_attribute *attrs)
-{
-       int error = 0;
-       int i;
-
-       if (attrs) {
-               for (i = 0; attrs[i].attr.name; i++) {
-                       error = device_create_bin_file(dev, &attrs[i]);
-                       if (error)
-                               break;
-               }
-               if (error)
-                       while (--i >= 0)
-                               device_remove_bin_file(dev, &attrs[i]);
-       }
-       return error;
-}
-
-static void device_remove_bin_attributes(struct device *dev,
-                                        struct bin_attribute *attrs)
-{
-       int i;
-
-       if (attrs)
-               for (i = 0; attrs[i].attr.name; i++)
-                       device_remove_bin_file(dev, &attrs[i]);
-}
-
 int device_add_groups(struct device *dev, const struct attribute_group **groups)
 {
        return sysfs_create_groups(&dev->kobj, groups);
@@ -534,18 +476,12 @@ static int device_add_attrs(struct device *dev)
                error = device_add_groups(dev, class->dev_groups);
                if (error)
                        return error;
-               error = device_add_attributes(dev, class->dev_attrs);
-               if (error)
-                       goto err_remove_class_groups;
-               error = device_add_bin_attributes(dev, class->dev_bin_attrs);
-               if (error)
-                       goto err_remove_class_attrs;
        }
 
        if (type) {
                error = device_add_groups(dev, type->groups);
                if (error)
-                       goto err_remove_class_bin_attrs;
+                       goto err_remove_class_groups;
        }
 
        error = device_add_groups(dev, dev->groups);
@@ -563,12 +499,6 @@ static int device_add_attrs(struct device *dev)
  err_remove_type_groups:
        if (type)
                device_remove_groups(dev, type->groups);
- err_remove_class_bin_attrs:
-       if (class)
-               device_remove_bin_attributes(dev, class->dev_bin_attrs);
- err_remove_class_attrs:
-       if (class)
-               device_remove_attributes(dev, class->dev_attrs);
  err_remove_class_groups:
        if (class)
                device_remove_groups(dev, class->dev_groups);
@@ -587,11 +517,8 @@ static void device_remove_attrs(struct device *dev)
        if (type)
                device_remove_groups(dev, type->groups);
 
-       if (class) {
-               device_remove_attributes(dev, class->dev_attrs);
-               device_remove_bin_attributes(dev, class->dev_bin_attrs);
+       if (class)
                device_remove_groups(dev, class->dev_groups);
-       }
 }
 
 static ssize_t dev_show(struct device *dev, struct device_attribute *attr,
@@ -1881,6 +1808,7 @@ EXPORT_SYMBOL_GPL(device_destroy);
  */
 int device_rename(struct device *dev, const char *new_name)
 {
+       struct kobject *kobj = &dev->kobj;
        char *old_device_name = NULL;
        int error;
 
@@ -1888,8 +1816,7 @@ int device_rename(struct device *dev, const char *new_name)
        if (!dev)
                return -EINVAL;
 
-       pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev),
-                __func__, new_name);
+       dev_dbg(dev, "renaming to %s\n", new_name);
 
        old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
        if (!old_device_name) {
@@ -1898,13 +1825,14 @@ int device_rename(struct device *dev, const char *new_name)
        }
 
        if (dev->class) {
-               error = sysfs_rename_link(&dev->class->p->subsys.kobj,
-                       &dev->kobj, old_device_name, new_name);
+               error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj,
+                                            kobj, old_device_name,
+                                            new_name, kobject_namespace(kobj));
                if (error)
                        goto out;
        }
 
-       error = kobject_rename(&dev->kobj, new_name);
+       error = kobject_rename(kobj, new_name);
        if (error)
                goto out;
 
index 507379e7b763781816ae5e4c65858b3b0b977a7b..545c4de412c3e0ba5a2680d9143e059a9c475dbd 100644 (file)
@@ -91,7 +91,8 @@ static __always_inline struct devres * alloc_dr(dr_release_t release,
        if (unlikely(!dr))
                return NULL;
 
-       memset(dr, 0, tot_size);
+       memset(dr, 0, offsetof(struct devres, data));
+
        INIT_LIST_HEAD(&dr->node.entry);
        dr->node.release = release;
        return dr;
@@ -110,7 +111,7 @@ void * __devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
 {
        struct devres *dr;
 
-       dr = alloc_dr(release, size, gfp);
+       dr = alloc_dr(release, size, gfp | __GFP_ZERO);
        if (unlikely(!dr))
                return NULL;
        set_node_dbginfo(&dr->node, name, size);
@@ -135,7 +136,7 @@ void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
 {
        struct devres *dr;
 
-       dr = alloc_dr(release, size, gfp);
+       dr = alloc_dr(release, size, gfp | __GFP_ZERO);
        if (unlikely(!dr))
                return NULL;
        return dr->data;
@@ -745,58 +746,62 @@ void devm_remove_action(struct device *dev, void (*action)(void *), void *data)
 EXPORT_SYMBOL_GPL(devm_remove_action);
 
 /*
- * Managed kzalloc/kfree
+ * Managed kmalloc/kfree
  */
-static void devm_kzalloc_release(struct device *dev, void *res)
+static void devm_kmalloc_release(struct device *dev, void *res)
 {
        /* noop */
 }
 
-static int devm_kzalloc_match(struct device *dev, void *res, void *data)
+static int devm_kmalloc_match(struct device *dev, void *res, void *data)
 {
        return res == data;
 }
 
 /**
- * devm_kzalloc - Resource-managed kzalloc
+ * devm_kmalloc - Resource-managed kmalloc
  * @dev: Device to allocate memory for
  * @size: Allocation size
  * @gfp: Allocation gfp flags
  *
- * Managed kzalloc.  Memory allocated with this function is
+ * Managed kmalloc.  Memory allocated with this function is
  * automatically freed on driver detach.  Like all other devres
  * resources, guaranteed alignment is unsigned long long.
  *
  * RETURNS:
  * Pointer to allocated memory on success, NULL on failure.
  */
-void * devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
+void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
 {
        struct devres *dr;
 
        /* use raw alloc_dr for kmalloc caller tracing */
-       dr = alloc_dr(devm_kzalloc_release, size, gfp);
+       dr = alloc_dr(devm_kmalloc_release, size, gfp);
        if (unlikely(!dr))
                return NULL;
 
+       /*
+        * This is named devm_kzalloc_release for historical reasons
+        * The initial implementation did not support kmalloc, only kzalloc
+        */
        set_node_dbginfo(&dr->node, "devm_kzalloc_release", size);
        devres_add(dev, dr->data);
        return dr->data;
 }
-EXPORT_SYMBOL_GPL(devm_kzalloc);
+EXPORT_SYMBOL_GPL(devm_kmalloc);
 
 /**
  * devm_kfree - Resource-managed kfree
  * @dev: Device this memory belongs to
  * @p: Memory to free
  *
- * Free memory allocated with devm_kzalloc().
+ * Free memory allocated with devm_kmalloc().
  */
 void devm_kfree(struct device *dev, void *p)
 {
        int rc;
 
-       rc = devres_destroy(dev, devm_kzalloc_release, devm_kzalloc_match, p);
+       rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, p);
        WARN_ON(rc);
 }
 EXPORT_SYMBOL_GPL(devm_kfree);
index 10a4467c63f14b424ea69a8a8c9af3f57c4a85f8..eb8fb94ae2c527b713c21092fcd3b7b0d42e25a0 100644 (file)
@@ -282,31 +282,35 @@ static noinline_for_stack long fw_file_size(struct file *file)
        return st.size;
 }
 
-static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
+static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
 {
        long size;
        char *buf;
+       int rc;
 
        size = fw_file_size(file);
        if (size <= 0)
-               return false;
+               return -EINVAL;
        buf = vmalloc(size);
        if (!buf)
-               return false;
-       if (kernel_read(file, 0, buf, size) != size) {
+               return -ENOMEM;
+       rc = kernel_read(file, 0, buf, size);
+       if (rc != size) {
+               if (rc > 0)
+                       rc = -EIO;
                vfree(buf);
-               return false;
+               return rc;
        }
        fw_buf->data = buf;
        fw_buf->size = size;
-       return true;
+       return 0;
 }
 
-static bool fw_get_filesystem_firmware(struct device *device,
+static int fw_get_filesystem_firmware(struct device *device,
                                       struct firmware_buf *buf)
 {
        int i;
-       bool success = false;
+       int rc = -ENOENT;
        char *path = __getname();
 
        for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
@@ -321,14 +325,17 @@ static bool fw_get_filesystem_firmware(struct device *device,
                file = filp_open(path, O_RDONLY, 0);
                if (IS_ERR(file))
                        continue;
-               success = fw_read_file_contents(file, buf);
+               rc = fw_read_file_contents(file, buf);
                fput(file);
-               if (success)
+               if (rc)
+                       dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n",
+                               path, rc);
+               else
                        break;
        }
        __putname(path);
 
-       if (success) {
+       if (!rc) {
                dev_dbg(device, "firmware: direct-loading firmware %s\n",
                        buf->fw_id);
                mutex_lock(&fw_lock);
@@ -337,7 +344,7 @@ static bool fw_get_filesystem_firmware(struct device *device,
                mutex_unlock(&fw_lock);
        }
 
-       return success;
+       return rc;
 }
 
 /* firmware holds the ownership of pages */
@@ -1086,9 +1093,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
                }
        }
 
-       if (!fw_get_filesystem_firmware(device, fw->priv))
+       ret = fw_get_filesystem_firmware(device, fw->priv);
+       if (ret) {
+               dev_warn(device, "Direct firmware load failed with error %d\n",
+                        ret);
+               dev_warn(device, "Falling back to user helper\n");
                ret = fw_load_from_user_helper(fw, name, device,
                                               uevent, nowait, timeout);
+       }
 
        /* don't cache firmware handled without uevent */
        if (!ret)
index 4f8bef3eb5a8f77b9727b963ea4a5107b8e723e3..47051cd251132ce97752bc8f8f9748be272c0f35 100644 (file)
@@ -488,6 +488,11 @@ static int platform_drv_probe(struct device *_dev)
        if (ret && ACPI_HANDLE(_dev))
                acpi_dev_pm_detach(_dev, true);
 
+       if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
+               dev_warn(_dev, "probe deferral not supported\n");
+               ret = -ENXIO;
+       }
+
        return ret;
 }
 
@@ -553,8 +558,7 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister);
 /**
  * platform_driver_probe - register driver for non-hotpluggable device
  * @drv: platform driver structure
- * @probe: the driver probe routine, probably from an __init section,
- *         must not return -EPROBE_DEFER.
+ * @probe: the driver probe routine, probably from an __init section
  *
  * Use this instead of platform_driver_register() when you know the device
  * is not hotpluggable and has already been registered, and you want to
@@ -565,8 +569,7 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister);
  * into system-on-chip processors, where the controller devices have been
  * configured as part of board setup.
  *
- * This is incompatible with deferred probing so probe() must not
- * return -EPROBE_DEFER.
+ * Note that this is incompatible with deferred probing.
  *
  * Returns zero if the driver registered and bound to a device, else returns
  * a negative error code and with the driver not registered.
@@ -576,6 +579,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
 {
        int retval, code;
 
+       /*
+        * Prevent driver from requesting probe deferral to avoid further
+        * futile probe attempts.
+        */
+       drv->prevent_deferred_probe = true;
+
        /* make sure driver won't have bind/unbind attributes */
        drv->driver.suppress_bind_attrs = true;
 
index 90ee350442a99d243606c97b716af75d909308c9..e15430a82e90e766163c7f5f40e26559b3fabbe1 100644 (file)
@@ -30,28 +30,37 @@ static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, cha
        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
        return sprintf(buf, "0x%03X\n", core->id.manuf);
 }
+static DEVICE_ATTR_RO(manuf);
+
 static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
        return sprintf(buf, "0x%03X\n", core->id.id);
 }
+static DEVICE_ATTR_RO(id);
+
 static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
        return sprintf(buf, "0x%02X\n", core->id.rev);
 }
+static DEVICE_ATTR_RO(rev);
+
 static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
        return sprintf(buf, "0x%X\n", core->id.class);
 }
-static struct device_attribute bcma_device_attrs[] = {
-       __ATTR_RO(manuf),
-       __ATTR_RO(id),
-       __ATTR_RO(rev),
-       __ATTR_RO(class),
-       __ATTR_NULL,
+static DEVICE_ATTR_RO(class);
+
+static struct attribute *bcma_device_attrs[] = {
+       &dev_attr_manuf.attr,
+       &dev_attr_id.attr,
+       &dev_attr_rev.attr,
+       &dev_attr_class.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(bcma_device);
 
 static struct bus_type bcma_bus_type = {
        .name           = "bcma",
@@ -59,7 +68,7 @@ static struct bus_type bcma_bus_type = {
        .probe          = bcma_device_probe,
        .remove         = bcma_device_remove,
        .uevent         = bcma_device_uevent,
-       .dev_attrs      = bcma_device_attrs,
+       .dev_groups     = bcma_device_groups,
 };
 
 static u16 bcma_cc_core_id(struct bcma_bus *bus)
index e07a5fd58ad7463f8775f7334fd692c7e51df2ad..e67fa16e19381573215d44d87e9e19a71698d79e 100644 (file)
@@ -505,7 +505,7 @@ config VIRTIO_BLK
 config BLK_DEV_HD
        bool "Very old hard disk (MFM/RLL/IDE) driver"
        depends on HAVE_IDE
-       depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN
+       depends on !ARM || ARCH_RPC || BROKEN
        help
          This is a very old hard disk driver that lacks the enhanced
          functionality of the newer ones.
index 200926699778e2a0ec2605429362f92282494a56..bb5b90e8e7687a0b71d33aae92f7050f741a6fa9 100644 (file)
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 
 #include <asm/cacheflush.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
 #include <asm/smp_plat.h>
 
+#define DRIVER_NAME            "CCI-400"
+#define DRIVER_NAME_PMU                DRIVER_NAME " PMU"
+#define PMU_NAME               "CCI_400"
+
 #define CCI_PORT_CTRL          0x0
 #define CCI_CTRL_STATUS                0xc
 
@@ -54,6 +64,568 @@ static unsigned int nb_cci_ports;
 static void __iomem *cci_ctrl_base;
 static unsigned long cci_ctrl_phys;
 
+#ifdef CONFIG_HW_PERF_EVENTS
+
+#define CCI_PMCR               0x0100
+#define CCI_PID2               0x0fe8
+
+#define CCI_PMCR_CEN           0x00000001
+#define CCI_PMCR_NCNT_MASK     0x0000f800
+#define CCI_PMCR_NCNT_SHIFT    11
+
+#define CCI_PID2_REV_MASK      0xf0
+#define CCI_PID2_REV_SHIFT     4
+
+/* Port ids */
+#define CCI_PORT_S0    0
+#define CCI_PORT_S1    1
+#define CCI_PORT_S2    2
+#define CCI_PORT_S3    3
+#define CCI_PORT_S4    4
+#define CCI_PORT_M0    5
+#define CCI_PORT_M1    6
+#define CCI_PORT_M2    7
+
+#define CCI_REV_R0             0
+#define CCI_REV_R1             1
+#define CCI_REV_R0_P4          4
+#define CCI_REV_R1_P2          6
+
+#define CCI_PMU_EVT_SEL                0x000
+#define CCI_PMU_CNTR           0x004
+#define CCI_PMU_CNTR_CTRL      0x008
+#define CCI_PMU_OVRFLW         0x00c
+
+#define CCI_PMU_OVRFLW_FLAG    1
+
+#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
+
+/*
+ * Instead of an event id to monitor CCI cycles, a dedicated counter is
+ * provided. Use 0xff to represent CCI cycles and hope that no future revisions
+ * make use of this event in hardware.
+ */
+enum cci400_perf_events {
+       CCI_PMU_CYCLES = 0xff
+};
+
+#define CCI_PMU_EVENT_MASK             0xff
+#define CCI_PMU_EVENT_SOURCE(event)    ((event >> 5) & 0x7)
+#define CCI_PMU_EVENT_CODE(event)      (event & 0x1f)
+
+#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter */
+
+#define CCI_PMU_CYCLE_CNTR_IDX         0
+#define CCI_PMU_CNTR0_IDX              1
+#define CCI_PMU_CNTR_LAST(cci_pmu)     (CCI_PMU_CYCLE_CNTR_IDX + cci_pmu->num_events - 1)
+
+/*
+ * CCI PMU event id is an 8-bit value made of two parts - bits 7:5 for one of 8
+ * ports and bits 4:0 are event codes. There are different event codes
+ * associated with each port type.
+ *
+ * Additionally, the range of events associated with the port types changed
+ * between Rev0 and Rev1.
+ *
+ * The constants below define the range of valid codes for each port type for
+ * the different revisions and are used to validate the event to be monitored.
+ */
+
+#define CCI_REV_R0_SLAVE_PORT_MIN_EV   0x00
+#define CCI_REV_R0_SLAVE_PORT_MAX_EV   0x13
+#define CCI_REV_R0_MASTER_PORT_MIN_EV  0x14
+#define CCI_REV_R0_MASTER_PORT_MAX_EV  0x1a
+
+#define CCI_REV_R1_SLAVE_PORT_MIN_EV   0x00
+#define CCI_REV_R1_SLAVE_PORT_MAX_EV   0x14
+#define CCI_REV_R1_MASTER_PORT_MIN_EV  0x00
+#define CCI_REV_R1_MASTER_PORT_MAX_EV  0x11
+
+struct pmu_port_event_ranges {
+       u8 slave_min;
+       u8 slave_max;
+       u8 master_min;
+       u8 master_max;
+};
+
+static struct pmu_port_event_ranges port_event_range[] = {
+       [CCI_REV_R0] = {
+               .slave_min = CCI_REV_R0_SLAVE_PORT_MIN_EV,
+               .slave_max = CCI_REV_R0_SLAVE_PORT_MAX_EV,
+               .master_min = CCI_REV_R0_MASTER_PORT_MIN_EV,
+               .master_max = CCI_REV_R0_MASTER_PORT_MAX_EV,
+       },
+       [CCI_REV_R1] = {
+               .slave_min = CCI_REV_R1_SLAVE_PORT_MIN_EV,
+               .slave_max = CCI_REV_R1_SLAVE_PORT_MAX_EV,
+               .master_min = CCI_REV_R1_MASTER_PORT_MIN_EV,
+               .master_max = CCI_REV_R1_MASTER_PORT_MAX_EV,
+       },
+};
+
+struct cci_pmu_drv_data {
+       void __iomem *base;
+       struct arm_pmu *cci_pmu;
+       int nr_irqs;
+       int irqs[CCI_PMU_MAX_HW_EVENTS];
+       unsigned long active_irqs;
+       struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
+       unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
+       struct pmu_port_event_ranges *port_ranges;
+       struct pmu_hw_events hw_events;
+};
+static struct cci_pmu_drv_data *pmu;
+
+static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs)
+{
+       int i;
+
+       for (i = 0; i < nr_irqs; i++)
+               if (irq == irqs[i])
+                       return true;
+
+       return false;
+}
+
+static int probe_cci_revision(void)
+{
+       int rev;
+       rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
+       rev >>= CCI_PID2_REV_SHIFT;
+
+       if (rev <= CCI_REV_R0_P4)
+               return CCI_REV_R0;
+       else if (rev <= CCI_REV_R1_P2)
+               return CCI_REV_R1;
+
+       return -ENOENT;
+}
+
+static struct pmu_port_event_ranges *port_range_by_rev(void)
+{
+       int rev = probe_cci_revision();
+
+       if (rev < 0)
+               return NULL;
+
+       return &port_event_range[rev];
+}
+
+static int pmu_is_valid_slave_event(u8 ev_code)
+{
+       return pmu->port_ranges->slave_min <= ev_code &&
+               ev_code <= pmu->port_ranges->slave_max;
+}
+
+static int pmu_is_valid_master_event(u8 ev_code)
+{
+       return pmu->port_ranges->master_min <= ev_code &&
+               ev_code <= pmu->port_ranges->master_max;
+}
+
+static int pmu_validate_hw_event(u8 hw_event)
+{
+       u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
+       u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
+
+       switch (ev_source) {
+       case CCI_PORT_S0:
+       case CCI_PORT_S1:
+       case CCI_PORT_S2:
+       case CCI_PORT_S3:
+       case CCI_PORT_S4:
+               /* Slave Interface */
+               if (pmu_is_valid_slave_event(ev_code))
+                       return hw_event;
+               break;
+       case CCI_PORT_M0:
+       case CCI_PORT_M1:
+       case CCI_PORT_M2:
+               /* Master Interface */
+               if (pmu_is_valid_master_event(ev_code))
+                       return hw_event;
+               break;
+       }
+
+       return -ENOENT;
+}
+
+static int pmu_is_valid_counter(struct arm_pmu *cci_pmu, int idx)
+{
+       return CCI_PMU_CYCLE_CNTR_IDX <= idx &&
+               idx <= CCI_PMU_CNTR_LAST(cci_pmu);
+}
+
+static u32 pmu_read_register(int idx, unsigned int offset)
+{
+       return readl_relaxed(pmu->base + CCI_PMU_CNTR_BASE(idx) + offset);
+}
+
+static void pmu_write_register(u32 value, int idx, unsigned int offset)
+{
+       return writel_relaxed(value, pmu->base + CCI_PMU_CNTR_BASE(idx) + offset);
+}
+
+static void pmu_disable_counter(int idx)
+{
+       pmu_write_register(0, idx, CCI_PMU_CNTR_CTRL);
+}
+
+static void pmu_enable_counter(int idx)
+{
+       pmu_write_register(1, idx, CCI_PMU_CNTR_CTRL);
+}
+
+static void pmu_set_event(int idx, unsigned long event)
+{
+       event &= CCI_PMU_EVENT_MASK;
+       pmu_write_register(event, idx, CCI_PMU_EVT_SEL);
+}
+
+static u32 pmu_get_max_counters(void)
+{
+       u32 n_cnts = (readl_relaxed(cci_ctrl_base + CCI_PMCR) &
+                     CCI_PMCR_NCNT_MASK) >> CCI_PMCR_NCNT_SHIFT;
+
+       /* add 1 for cycle counter */
+       return n_cnts + 1;
+}
+
+static struct pmu_hw_events *pmu_get_hw_events(void)
+{
+       return &pmu->hw_events;
+}
+
+static int pmu_get_event_idx(struct pmu_hw_events *hw, struct perf_event *event)
+{
+       struct arm_pmu *cci_pmu = to_arm_pmu(event->pmu);
+       struct hw_perf_event *hw_event = &event->hw;
+       unsigned long cci_event = hw_event->config_base & CCI_PMU_EVENT_MASK;
+       int idx;
+
+       if (cci_event == CCI_PMU_CYCLES) {
+               if (test_and_set_bit(CCI_PMU_CYCLE_CNTR_IDX, hw->used_mask))
+                       return -EAGAIN;
+
+               return CCI_PMU_CYCLE_CNTR_IDX;
+       }
+
+       for (idx = CCI_PMU_CNTR0_IDX; idx <= CCI_PMU_CNTR_LAST(cci_pmu); ++idx)
+               if (!test_and_set_bit(idx, hw->used_mask))
+                       return idx;
+
+       /* No counters available */
+       return -EAGAIN;
+}
+
+static int pmu_map_event(struct perf_event *event)
+{
+       int mapping;
+       u8 config = event->attr.config & CCI_PMU_EVENT_MASK;
+
+       if (event->attr.type < PERF_TYPE_MAX)
+               return -ENOENT;
+
+       if (config == CCI_PMU_CYCLES)
+               mapping = config;
+       else
+               mapping = pmu_validate_hw_event(config);
+
+       return mapping;
+}
+
+static int pmu_request_irq(struct arm_pmu *cci_pmu, irq_handler_t handler)
+{
+       int i;
+       struct platform_device *pmu_device = cci_pmu->plat_device;
+
+       if (unlikely(!pmu_device))
+               return -ENODEV;
+
+       if (pmu->nr_irqs < 1) {
+               dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n");
+               return -ENODEV;
+       }
+
+       /*
+        * Register all available CCI PMU interrupts. In the interrupt handler
+        * we iterate over the counters checking for interrupt source (the
+        * overflowing counter) and clear it.
+        *
+        * This should allow handling of non-unique interrupt for the counters.
+        */
+       for (i = 0; i < pmu->nr_irqs; i++) {
+               int err = request_irq(pmu->irqs[i], handler, IRQF_SHARED,
+                               "arm-cci-pmu", cci_pmu);
+               if (err) {
+                       dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PMU counters\n",
+                               pmu->irqs[i]);
+                       return err;
+               }
+
+               set_bit(i, &pmu->active_irqs);
+       }
+
+       return 0;
+}
+
+static irqreturn_t pmu_handle_irq(int irq_num, void *dev)
+{
+       unsigned long flags;
+       struct arm_pmu *cci_pmu = (struct arm_pmu *)dev;
+       struct pmu_hw_events *events = cci_pmu->get_hw_events();
+       struct perf_sample_data data;
+       struct pt_regs *regs;
+       int idx, handled = IRQ_NONE;
+
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
+       regs = get_irq_regs();
+       /*
+        * Iterate over counters and update the corresponding perf events.
+        * This should work regardless of whether we have per-counter overflow
+        * interrupt or a combined overflow interrupt.
+        */
+       for (idx = CCI_PMU_CYCLE_CNTR_IDX; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++) {
+               struct perf_event *event = events->events[idx];
+               struct hw_perf_event *hw_counter;
+
+               if (!event)
+                       continue;
+
+               hw_counter = &event->hw;
+
+               /* Did this counter overflow? */
+               if (!pmu_read_register(idx, CCI_PMU_OVRFLW) & CCI_PMU_OVRFLW_FLAG)
+                       continue;
+
+               pmu_write_register(CCI_PMU_OVRFLW_FLAG, idx, CCI_PMU_OVRFLW);
+
+               handled = IRQ_HANDLED;
+
+               armpmu_event_update(event);
+               perf_sample_data_init(&data, 0, hw_counter->last_period);
+               if (!armpmu_event_set_period(event))
+                       continue;
+
+               if (perf_event_overflow(event, &data, regs))
+                       cci_pmu->disable(event);
+       }
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+
+       return IRQ_RETVAL(handled);
+}
+
+static void pmu_free_irq(struct arm_pmu *cci_pmu)
+{
+       int i;
+
+       for (i = 0; i < pmu->nr_irqs; i++) {
+               if (!test_and_clear_bit(i, &pmu->active_irqs))
+                       continue;
+
+               free_irq(pmu->irqs[i], cci_pmu);
+       }
+}
+
+static void pmu_enable_event(struct perf_event *event)
+{
+       unsigned long flags;
+       struct arm_pmu *cci_pmu = to_arm_pmu(event->pmu);
+       struct pmu_hw_events *events = cci_pmu->get_hw_events();
+       struct hw_perf_event *hw_counter = &event->hw;
+       int idx = hw_counter->idx;
+
+       if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
+               dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+               return;
+       }
+
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+       /* Configure the event to count, unless you are counting cycles */
+       if (idx != CCI_PMU_CYCLE_CNTR_IDX)
+               pmu_set_event(idx, hw_counter->config_base);
+
+       pmu_enable_counter(idx);
+
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void pmu_disable_event(struct perf_event *event)
+{
+       struct arm_pmu *cci_pmu = to_arm_pmu(event->pmu);
+       struct hw_perf_event *hw_counter = &event->hw;
+       int idx = hw_counter->idx;
+
+       if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
+               dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+               return;
+       }
+
+       pmu_disable_counter(idx);
+}
+
+static void pmu_start(struct arm_pmu *cci_pmu)
+{
+       u32 val;
+       unsigned long flags;
+       struct pmu_hw_events *events = cci_pmu->get_hw_events();
+
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+       /* Enable all the PMU counters. */
+       val = readl_relaxed(cci_ctrl_base + CCI_PMCR) | CCI_PMCR_CEN;
+       writel(val, cci_ctrl_base + CCI_PMCR);
+
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void pmu_stop(struct arm_pmu *cci_pmu)
+{
+       u32 val;
+       unsigned long flags;
+       struct pmu_hw_events *events = cci_pmu->get_hw_events();
+
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+       /* Disable all the PMU counters. */
+       val = readl_relaxed(cci_ctrl_base + CCI_PMCR) & ~CCI_PMCR_CEN;
+       writel(val, cci_ctrl_base + CCI_PMCR);
+
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static u32 pmu_read_counter(struct perf_event *event)
+{
+       struct arm_pmu *cci_pmu = to_arm_pmu(event->pmu);
+       struct hw_perf_event *hw_counter = &event->hw;
+       int idx = hw_counter->idx;
+       u32 value;
+
+       if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
+               dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+               return 0;
+       }
+       value = pmu_read_register(idx, CCI_PMU_CNTR);
+
+       return value;
+}
+
+static void pmu_write_counter(struct perf_event *event, u32 value)
+{
+       struct arm_pmu *cci_pmu = to_arm_pmu(event->pmu);
+       struct hw_perf_event *hw_counter = &event->hw;
+       int idx = hw_counter->idx;
+
+       if (unlikely(!pmu_is_valid_counter(cci_pmu, idx)))
+               dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+       else
+               pmu_write_register(value, idx, CCI_PMU_CNTR);
+}
+
+static int cci_pmu_init(struct arm_pmu *cci_pmu, struct platform_device *pdev)
+{
+       *cci_pmu = (struct arm_pmu){
+               .name             = PMU_NAME,
+               .max_period       = (1LLU << 32) - 1,
+               .get_hw_events    = pmu_get_hw_events,
+               .get_event_idx    = pmu_get_event_idx,
+               .map_event        = pmu_map_event,
+               .request_irq      = pmu_request_irq,
+               .handle_irq       = pmu_handle_irq,
+               .free_irq         = pmu_free_irq,
+               .enable           = pmu_enable_event,
+               .disable          = pmu_disable_event,
+               .start            = pmu_start,
+               .stop             = pmu_stop,
+               .read_counter     = pmu_read_counter,
+               .write_counter    = pmu_write_counter,
+       };
+
+       cci_pmu->plat_device = pdev;
+       cci_pmu->num_events = pmu_get_max_counters();
+
+       return armpmu_register(cci_pmu, -1);
+}
+
+static const struct of_device_id arm_cci_pmu_matches[] = {
+       {
+               .compatible = "arm,cci-400-pmu",
+       },
+       {},
+};
+
+static int cci_pmu_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int i, ret, irq;
+
+       pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
+       if (!pmu)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       pmu->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(pmu->base))
+               return -ENOMEM;
+
+       /*
+        * CCI PMU has 5 overflow signals - one per counter; but some may be tied
+        * together to a common interrupt.
+        */
+       pmu->nr_irqs = 0;
+       for (i = 0; i < CCI_PMU_MAX_HW_EVENTS; i++) {
+               irq = platform_get_irq(pdev, i);
+               if (irq < 0)
+                       break;
+
+               if (is_duplicate_irq(irq, pmu->irqs, pmu->nr_irqs))
+                       continue;
+
+               pmu->irqs[pmu->nr_irqs++] = irq;
+       }
+
+       /*
+        * Ensure that the device tree has as many interrupts as the number
+        * of counters.
+        */
+       if (i < CCI_PMU_MAX_HW_EVENTS) {
+               dev_warn(&pdev->dev, "In-correct number of interrupts: %d, should be %d\n",
+                       i, CCI_PMU_MAX_HW_EVENTS);
+               return -EINVAL;
+       }
+
+       pmu->port_ranges = port_range_by_rev();
+       if (!pmu->port_ranges) {
+               dev_warn(&pdev->dev, "CCI PMU version not supported\n");
+               return -EINVAL;
+       }
+
+       pmu->cci_pmu = devm_kzalloc(&pdev->dev, sizeof(*(pmu->cci_pmu)), GFP_KERNEL);
+       if (!pmu->cci_pmu)
+               return -ENOMEM;
+
+       pmu->hw_events.events = pmu->events;
+       pmu->hw_events.used_mask = pmu->used_mask;
+       raw_spin_lock_init(&pmu->hw_events.pmu_lock);
+
+       ret = cci_pmu_init(pmu->cci_pmu, pdev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int cci_platform_probe(struct platform_device *pdev)
+{
+       if (!cci_probed())
+               return -ENODEV;
+
+       return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+}
+
+#endif /* CONFIG_HW_PERF_EVENTS */
+
 struct cpu_port {
        u64 mpidr;
        u32 port;
@@ -120,7 +692,7 @@ int cci_ace_get_port(struct device_node *dn)
 }
 EXPORT_SYMBOL_GPL(cci_ace_get_port);
 
-static void __init cci_ace_init_ports(void)
+static void cci_ace_init_ports(void)
 {
        int port, cpu;
        struct device_node *cpun;
@@ -386,7 +958,7 @@ static const struct of_device_id arm_cci_ctrl_if_matches[] = {
        {},
 };
 
-static int __init cci_probe(void)
+static int cci_probe(void)
 {
        struct cci_nb_ports const *cci_config;
        int ret, i, nb_ace = 0, nb_ace_lite = 0;
@@ -490,7 +1062,7 @@ memalloc_err:
 static int cci_init_status = -EAGAIN;
 static DEFINE_MUTEX(cci_probing);
 
-static int __init cci_init(void)
+static int cci_init(void)
 {
        if (cci_init_status != -EAGAIN)
                return cci_init_status;
@@ -502,18 +1074,55 @@ static int __init cci_init(void)
        return cci_init_status;
 }
 
+#ifdef CONFIG_HW_PERF_EVENTS
+static struct platform_driver cci_pmu_driver = {
+       .driver = {
+                  .name = DRIVER_NAME_PMU,
+                  .of_match_table = arm_cci_pmu_matches,
+                 },
+       .probe = cci_pmu_probe,
+};
+
+static struct platform_driver cci_platform_driver = {
+       .driver = {
+                  .name = DRIVER_NAME,
+                  .of_match_table = arm_cci_matches,
+                 },
+       .probe = cci_platform_probe,
+};
+
+static int __init cci_platform_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&cci_pmu_driver);
+       if (ret)
+               return ret;
+
+       return platform_driver_register(&cci_platform_driver);
+}
+
+#else
+
+static int __init cci_platform_init(void)
+{
+       return 0;
+}
+
+#endif
 /*
  * To sort out early init calls ordering a helper function is provided to
  * check if the CCI driver has beed initialized. Function check if the driver
  * has been initialized, if not it calls the init function that probes
  * the driver and updates the return value.
  */
-bool __init cci_probed(void)
+bool cci_probed(void)
 {
        return cci_init() == 0;
 }
 EXPORT_SYMBOL_GPL(cci_probed);
 
 early_initcall(cci_init);
+core_initcall(cci_platform_init);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("ARM CCI support");
index 448ce5e29c561bcf4fb8d1a6d3013fb6339e69be..dca5834685cf93d0cd105e66a7cf656329fc3e2e 100644 (file)
@@ -486,8 +486,7 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
                }
 
                sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
-               irq_flags = devp->hd_flags & HPET_SHARED_IRQ
-                                               ? IRQF_SHARED : IRQF_DISABLED;
+               irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : 0;
                if (request_irq(irq, hpet_interrupt, irq_flags,
                                devp->hd_name, (void *)devp)) {
                        printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
@@ -971,8 +970,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
                struct acpi_resource_fixed_memory32 *fixmem32;
 
                fixmem32 = &res->data.fixed_memory32;
-               if (!fixmem32)
-                       return AE_NO_MEMORY;
 
                hdp->hd_phys_address = fixmem32->address;
                hdp->hd_address = ioremap(fixmem32->address,
index 190d4423653f6b99690967ba3602915eda5463fb..2f685f6eda4868195d9dcc3ac7d317e9cc2fc42a 100644 (file)
@@ -193,8 +193,8 @@ int misc_register(struct miscdevice * misc)
        if (misc->minor == MISC_DYNAMIC_MINOR) {
                int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
                if (i >= DYNAMIC_MINORS) {
-                       mutex_unlock(&misc_mtx);
-                       return -EBUSY;
+                       err = -EBUSY;
+                       goto out;
                }
                misc->minor = DYNAMIC_MINORS - i - 1;
                set_bit(i, misc_minors);
@@ -203,8 +203,8 @@ int misc_register(struct miscdevice * misc)
 
                list_for_each_entry(c, &misc_list, list) {
                        if (c->minor == misc->minor) {
-                               mutex_unlock(&misc_mtx);
-                               return -EBUSY;
+                               err = -EBUSY;
+                               goto out;
                        }
                }
        }
index cfdfe493c6af007a4d2455ab0315ef2611d8ebb3..1fd00dc0689721ae967af86aa2c88dbb903ddef2 100644 (file)
@@ -220,7 +220,7 @@ static int __init nwbutton_init(void)
                return -EBUSY;
        }
 
-       if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, IRQF_DISABLED,
+       if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, 0,
                        "nwbutton", NULL)) {
                printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n",
                                IRQ_NETWINDER_BUTTON);
index c0cbbd429bdc7abcf0d3055404224bff7d367196..35259961cc38f74bbf0f6727dc205f5ec03368da 100644 (file)
@@ -227,7 +227,7 @@ static inline unsigned char rtc_is_updating(void)
 
 #ifdef RTC_IRQ
 /*
- *     A very tiny interrupt handler. It runs with IRQF_DISABLED set,
+ *     A very tiny interrupt handler. It runs with interrupts disabled,
  *     but there is possibility of conflicting with the set_rtc_mmss()
  *     call (the rtc irq and the timer irq can easily run at the same
  *     time in two different CPUs). So we need to serialize
@@ -1040,8 +1040,7 @@ no_irq:
                rtc_int_handler_ptr = rtc_interrupt;
        }
 
-       if (request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED,
-                       "rtc", NULL)) {
+       if (request_irq(RTC_IRQ, rtc_int_handler_ptr, 0, "rtc", NULL)) {
                /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
                rtc_has_irq = 0;
                printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
index 5816b39ff5a9cf43cbba56579d9b0b2d021f8883..8bab59292a0d0a42f2a89914edc36824483160f0 100644 (file)
@@ -108,8 +108,7 @@ scdrv_open(struct inode *inode, struct file *file)
        /* hook this subchannel up to the system controller interrupt */
        mutex_lock(&scdrv_mutex);
        rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
-                        IRQF_SHARED | IRQF_DISABLED,
-                        SYSCTL_BASENAME, sd);
+                        IRQF_SHARED, SYSCTL_BASENAME, sd);
        if (rv) {
                ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
                kfree(sd);
index ee156948b9f810d3cd66fbb3ff303e218f884a53..59bcefd6ec7c8ba86ceacce796af03fdce7e99ad 100644 (file)
@@ -292,8 +292,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
 
        /* hook event subchannel up to the system controller interrupt */
        rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt,
-                        IRQF_SHARED | IRQF_DISABLED,
-                        "system controller events", event_sd);
+                        IRQF_SHARED, "system controller events", event_sd);
        if (rv) {
                printk(KERN_WARNING "%s: irq request failed (%d)\n",
                       __func__, rv);
index e95e0ab0bd870a4c8d679d7dbb092ea2521ee42e..100cd1de9939dc77c5c523b10e15e1bc80908449 100644 (file)
@@ -222,7 +222,7 @@ static int tlclk_open(struct inode *inode, struct file *filp)
        /* This device is wired through the FPGA IO space of the ATCA blade
         * we can't share this IRQ */
        result = request_irq(telclk_interrupt, &tlclk_interrupt,
-                            IRQF_DISABLED, "telco_clock", tlclk_interrupt);
+                            0, "telco_clock", tlclk_interrupt);
        if (result == -EBUSY)
                printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
        else
index 5224da5202d3497589d4d74df171cde3efd7ba67..f6345f932e46c8e841ae2f7e9777da0ed9a905f3 100644 (file)
@@ -721,7 +721,7 @@ static int hwicap_remove(struct device *dev)
 {
        struct hwicap_drvdata *drvdata;
 
-       drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev);
+       drvdata = dev_get_drvdata(dev);
 
        if (!drvdata)
                return 0;
@@ -731,7 +731,6 @@ static int hwicap_remove(struct device *dev)
        iounmap(drvdata->base_address);
        release_mem_region(drvdata->mem_start, drvdata->mem_size);
        kfree(drvdata);
-       dev_set_drvdata(dev, NULL);
 
        mutex_lock(&icap_sem);
        probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
index 5fb4ff53d0887eca089a7a853b29a11df9cab6a5..6b950ca8b71108fdf3f32dd5ea6503eb1e5dc7ed 100644 (file)
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/bcm2835.h>
-#include <linux/clk-provider.h>
 #include <linux/of.h>
 
-static const struct of_device_id clk_match[] __initconst = {
-       { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
-       { }
-};
-
 /*
  * These are fixed clocks. They're probably not all root clocks and it may
  * be possible to turn them on and off but until this is mapped out better
@@ -63,6 +57,4 @@ void __init bcm2835_init_clocks(void)
        ret = clk_register_clkdev(clk, NULL, "20215000.uart");
        if (ret)
                pr_err("uart1_pclk alias not registered\n");
-
-       of_clk_init(clk_match);
 }
index 2e08cb00193685eb80e617c386dcb0b31871c122..2e7e9d9798cb20901cc2dd234c33ef6d306dc966 100644 (file)
@@ -20,8 +20,7 @@
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/of.h>
-
-extern void __iomem *sregs_base;
+#include <linux/of_address.h>
 
 #define HB_PLL_LOCK_500                0x20000000
 #define HB_PLL_LOCK            0x10000000
@@ -280,6 +279,7 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
        const char *clk_name = node->name;
        const char *parent_name;
        struct clk_init_data init;
+       struct device_node *srnp;
        int rc;
 
        rc = of_property_read_u32(node, "reg", &reg);
@@ -290,7 +290,11 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
        if (WARN_ON(!hb_clk))
                return NULL;
 
-       hb_clk->reg = sregs_base + reg;
+       /* Map system registers */
+       srnp = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
+       hb_clk->reg = of_iomap(srnp, 0);
+       BUG_ON(!hb_clk->reg);
+       hb_clk->reg += reg;
 
        of_property_read_string(node, "clock-output-names", &clk_name);
 
index 51410c2ac2cb617b9a98b9c0fd869e1ddd541870..6a934a5296bd4ca2867146dc06272ea1003e238e 100644 (file)
  */
 
 #define SRC_CR                 0x00U
+#define SRC_CR_T0_ENSEL                BIT(15)
+#define SRC_CR_T1_ENSEL                BIT(17)
+#define SRC_CR_T2_ENSEL                BIT(19)
+#define SRC_CR_T3_ENSEL                BIT(21)
+#define SRC_CR_T4_ENSEL                BIT(23)
+#define SRC_CR_T5_ENSEL                BIT(25)
+#define SRC_CR_T6_ENSEL                BIT(27)
+#define SRC_CR_T7_ENSEL                BIT(29)
 #define SRC_XTALCR             0x0CU
 #define SRC_XTALCR_XTALTIMEN   BIT(20)
 #define SRC_XTALCR_SXTALDIS    BIT(19)
@@ -54,6 +62,79 @@ static DEFINE_SPINLOCK(src_lock);
 /* Base address of the SRC */
 static void __iomem *src_base;
 
+static int nomadik_clk_reboot_handler(struct notifier_block *this,
+                               unsigned long code,
+                               void *unused)
+{
+       u32 val;
+
+       /* The main chrystal need to be enabled for reboot to work */
+       val = readl(src_base + SRC_XTALCR);
+       val &= ~SRC_XTALCR_MXTALOVER;
+       val |= SRC_XTALCR_MXTALEN;
+       pr_crit("force-enabling MXTALO\n");
+       writel(val, src_base + SRC_XTALCR);
+       return NOTIFY_OK;
+}
+
+static struct notifier_block nomadik_clk_reboot_notifier = {
+       .notifier_call = nomadik_clk_reboot_handler,
+};
+
+static const struct of_device_id nomadik_src_match[] __initconst = {
+       { .compatible = "stericsson,nomadik-src" },
+       { /* sentinel */ }
+};
+
+static void __init nomadik_src_init(void)
+{
+       struct device_node *np;
+       u32 val;
+
+       np = of_find_matching_node(NULL, nomadik_src_match);
+       if (!np) {
+               pr_crit("no matching node for SRC, aborting clock init\n");
+               return;
+       }
+       src_base = of_iomap(np, 0);
+       if (!src_base) {
+               pr_err("%s: must have src parent node with REGS (%s)\n",
+                      __func__, np->name);
+               return;
+       }
+
+       /* Set all timers to use the 2.4 MHz TIMCLK */
+       val = readl(src_base + SRC_CR);
+       val |= SRC_CR_T0_ENSEL;
+       val |= SRC_CR_T1_ENSEL;
+       val |= SRC_CR_T2_ENSEL;
+       val |= SRC_CR_T3_ENSEL;
+       val |= SRC_CR_T4_ENSEL;
+       val |= SRC_CR_T5_ENSEL;
+       val |= SRC_CR_T6_ENSEL;
+       val |= SRC_CR_T7_ENSEL;
+       writel(val, src_base + SRC_CR);
+
+       val = readl(src_base + SRC_XTALCR);
+       pr_info("SXTALO is %s\n",
+               (val & SRC_XTALCR_SXTALDIS) ? "disabled" : "enabled");
+       pr_info("MXTAL is %s\n",
+               (val & SRC_XTALCR_MXTALSTAT) ? "enabled" : "disabled");
+       if (of_property_read_bool(np, "disable-sxtalo")) {
+               /* The machine uses an external oscillator circuit */
+               val |= SRC_XTALCR_SXTALDIS;
+               pr_info("disabling SXTALO\n");
+       }
+       if (of_property_read_bool(np, "disable-mxtalo")) {
+               /* Disable this too: also run by external oscillator */
+               val |= SRC_XTALCR_MXTALOVER;
+               val &= ~SRC_XTALCR_MXTALEN;
+               pr_info("disabling MXTALO\n");
+       }
+       writel(val, src_base + SRC_XTALCR);
+       register_reboot_notifier(&nomadik_clk_reboot_notifier);
+}
+
 /**
  * struct clk_pll1 - Nomadik PLL1 clock
  * @hw: corresponding clock hardware entry
@@ -431,6 +512,9 @@ static void __init of_nomadik_pll_setup(struct device_node *np)
        const char *parent_name;
        u32 pll_id;
 
+       if (!src_base)
+               nomadik_src_init();
+
        if (of_property_read_u32(np, "pll-id", &pll_id)) {
                pr_err("%s: PLL \"%s\" missing pll-id property\n",
                        __func__, clk_name);
@@ -441,6 +525,8 @@ static void __init of_nomadik_pll_setup(struct device_node *np)
        if (!IS_ERR(clk))
                of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
+CLK_OF_DECLARE(nomadik_pll_clk,
+       "st,nomadik-pll-clock", of_nomadik_pll_setup);
 
 static void __init of_nomadik_hclk_setup(struct device_node *np)
 {
@@ -448,6 +534,9 @@ static void __init of_nomadik_hclk_setup(struct device_node *np)
        const char *clk_name = np->name;
        const char *parent_name;
 
+       if (!src_base)
+               nomadik_src_init();
+
        parent_name = of_clk_get_parent_name(np, 0);
        /*
         * The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
@@ -460,6 +549,8 @@ static void __init of_nomadik_hclk_setup(struct device_node *np)
        if (!IS_ERR(clk))
                of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
+CLK_OF_DECLARE(nomadik_hclk_clk,
+       "st,nomadik-hclk-clock", of_nomadik_hclk_setup);
 
 static void __init of_nomadik_src_clk_setup(struct device_node *np)
 {
@@ -468,6 +559,9 @@ static void __init of_nomadik_src_clk_setup(struct device_node *np)
        const char *parent_name;
        u32 clk_id;
 
+       if (!src_base)
+               nomadik_src_init();
+
        if (of_property_read_u32(np, "clock-id", &clk_id)) {
                pr_err("%s: SRC clock \"%s\" missing clock-id property\n",
                        __func__, clk_name);
@@ -478,89 +572,5 @@ static void __init of_nomadik_src_clk_setup(struct device_node *np)
        if (!IS_ERR(clk))
                of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
-
-static const struct of_device_id nomadik_src_match[] __initconst = {
-       { .compatible = "stericsson,nomadik-src" },
-       { /* sentinel */ }
-};
-
-static const struct of_device_id nomadik_src_clk_match[] __initconst = {
-       {
-               .compatible = "fixed-clock",
-               .data = of_fixed_clk_setup,
-       },
-       {
-               .compatible = "fixed-factor-clock",
-               .data = of_fixed_factor_clk_setup,
-       },
-       {
-               .compatible = "st,nomadik-pll-clock",
-               .data = of_nomadik_pll_setup,
-       },
-       {
-               .compatible = "st,nomadik-hclk-clock",
-               .data = of_nomadik_hclk_setup,
-       },
-       {
-               .compatible = "st,nomadik-src-clock",
-               .data = of_nomadik_src_clk_setup,
-       },
-       { /* sentinel */ }
-};
-
-static int nomadik_clk_reboot_handler(struct notifier_block *this,
-                               unsigned long code,
-                               void *unused)
-{
-       u32 val;
-
-       /* The main chrystal need to be enabled for reboot to work */
-       val = readl(src_base + SRC_XTALCR);
-       val &= ~SRC_XTALCR_MXTALOVER;
-       val |= SRC_XTALCR_MXTALEN;
-       pr_crit("force-enabling MXTALO\n");
-       writel(val, src_base + SRC_XTALCR);
-       return NOTIFY_OK;
-}
-
-static struct notifier_block nomadik_clk_reboot_notifier = {
-       .notifier_call = nomadik_clk_reboot_handler,
-};
-
-void __init nomadik_clk_init(void)
-{
-       struct device_node *np;
-       u32 val;
-
-       np = of_find_matching_node(NULL, nomadik_src_match);
-       if (!np) {
-               pr_crit("no matching node for SRC, aborting clock init\n");
-               return;
-       }
-       src_base = of_iomap(np, 0);
-       if (!src_base) {
-               pr_err("%s: must have src parent node with REGS (%s)\n",
-                      __func__, np->name);
-               return;
-       }
-       val = readl(src_base + SRC_XTALCR);
-       pr_info("SXTALO is %s\n",
-               (val & SRC_XTALCR_SXTALDIS) ? "disabled" : "enabled");
-       pr_info("MXTAL is %s\n",
-               (val & SRC_XTALCR_MXTALSTAT) ? "enabled" : "disabled");
-       if (of_property_read_bool(np, "disable-sxtalo")) {
-               /* The machine uses an external oscillator circuit */
-               val |= SRC_XTALCR_SXTALDIS;
-               pr_info("disabling SXTALO\n");
-       }
-       if (of_property_read_bool(np, "disable-mxtalo")) {
-               /* Disable this too: also run by external oscillator */
-               val |= SRC_XTALCR_MXTALOVER;
-               val &= ~SRC_XTALCR_MXTALEN;
-               pr_info("disabling MXTALO\n");
-       }
-       writel(val, src_base + SRC_XTALCR);
-       register_reboot_notifier(&nomadik_clk_reboot_notifier);
-
-       of_clk_init(nomadik_src_clk_match);
-}
+CLK_OF_DECLARE(nomadik_src_clk,
+       "st,nomadik-src-clock", of_nomadik_src_clk_setup);
index 5ab95f1ad579288c516dc782b14a2b5a871ad7dc..6c15e3316137b87177753f3bd2b04d154d2f3f7a 100644 (file)
@@ -1015,16 +1015,6 @@ static struct clk_std clk_usb1 = {
        },
 };
 
-static struct of_device_id clkc_ids[] = {
-       { .compatible = "sirf,prima2-clkc" },
-       {},
-};
-
-static struct of_device_id rsc_ids[] = {
-       { .compatible = "sirf,prima2-rsc" },
-       {},
-};
-
 enum prima2_clk_index {
        /* 0    1     2      3      4      5      6       7         8      9 */
        rtc,    osc,   pll1,  pll2,  pll3,  mem,   sys,   security, dsp,   gps,
@@ -1082,24 +1072,16 @@ static struct clk_hw *prima2_clk_hw_array[maxclk] __initdata = {
 static struct clk *prima2_clks[maxclk];
 static struct clk_onecell_data clk_data;
 
-void __init sirfsoc_of_clk_init(void)
+static void __init sirfsoc_clk_init(struct device_node *np)
 {
-       struct device_node *np;
+       struct device_node *rscnp;
        int i;
 
-       np = of_find_matching_node(NULL, rsc_ids);
-       if (!np)
-               panic("unable to find compatible rsc node in dtb\n");
-
-       sirfsoc_rsc_vbase = of_iomap(np, 0);
+       rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
+       sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
        if (!sirfsoc_rsc_vbase)
                panic("unable to map rsc registers\n");
-
-       of_node_put(np);
-
-       np = of_find_matching_node(NULL, clkc_ids);
-       if (!np)
-               return;
+       of_node_put(rscnp);
 
        sirfsoc_clk_vbase = of_iomap(np, 0);
        if (!sirfsoc_clk_vbase)
@@ -1124,3 +1106,4 @@ void __init sirfsoc_of_clk_init(void)
 
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 }
+CLK_OF_DECLARE(sirfsoc_clk, "sirf,prima2-clkc", sirfsoc_clk_init);
index 82306f5fb9c2497f82bcfafe403cdbc091b3dc66..7fd5c5e9e25dbbd72a94cd0923ddf9d0a18d1c36 100644 (file)
 
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
 
+#define LEGACY_PMC_BASE                0xD8130000
+
 /* All clocks share the same lock as none can be changed concurrently */
 static DEFINE_SPINLOCK(_lock);
 
@@ -53,6 +56,21 @@ struct clk_pll {
 
 static void __iomem *pmc_base;
 
+static __init void vtwm_set_pmc_base(void)
+{
+       struct device_node *np =
+               of_find_compatible_node(NULL, NULL, "via,vt8500-pmc");
+
+       if (np)
+               pmc_base = of_iomap(np, 0);
+       else
+               pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000);
+       of_node_put(np);
+
+       if (!pmc_base)
+               pr_err("%s:of_iomap(pmc) failed\n", __func__);
+}
+
 #define to_clk_device(_hw) container_of(_hw, struct clk_device, hw)
 
 #define VT8500_PMC_BUSY_MASK           0x18
@@ -222,6 +240,9 @@ static __init void vtwm_device_clk_init(struct device_node *node)
        int rc;
        int clk_init_flags = 0;
 
+       if (!pmc_base)
+               vtwm_set_pmc_base();
+
        dev_clk = kzalloc(sizeof(*dev_clk), GFP_KERNEL);
        if (WARN_ON(!dev_clk))
                return;
@@ -636,6 +657,9 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
        struct clk_init_data init;
        int rc;
 
+       if (!pmc_base)
+               vtwm_set_pmc_base();
+
        rc = of_property_read_u32(node, "reg", &reg);
        if (WARN_ON(rc))
                return;
@@ -694,13 +718,3 @@ static void __init wm8850_pll_init(struct device_node *node)
        vtwm_pll_clk_init(node, PLL_TYPE_WM8850);
 }
 CLK_OF_DECLARE(wm8850_pll, "wm,wm8850-pll-clock", wm8850_pll_init);
-
-void __init vtwm_clk_init(void __iomem *base)
-{
-       if (!base)
-               return;
-
-       pmc_base = base;
-
-       of_clk_init(NULL);
-}
index fc777bdc1886586d2f7e0e253ddc1e78758d4927..81a202d12a7ad89ab56909fce6782baa7fb94ec2 100644 (file)
@@ -39,8 +39,8 @@ static const struct coreclk_ratio a370_coreclk_ratios[] __initconst = {
 };
 
 static const u32 a370_tclk_freqs[] __initconst = {
-       16600000,
-       20000000,
+       166000000,
+       200000000,
 };
 
 static u32 __init a370_get_tclk_freq(void __iomem *sar)
index c396fe3615891501e6f7a21ca6c3bfe88d81acec..9fc9359f51335e60451e9073469f0a6a34ed6730 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clk.h>
 #include <linux/clk/mxs.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -100,16 +101,16 @@ static enum imx23_clk clks_init_on[] __initdata = {
        cpu, hbus, xbus, emi, uart,
 };
 
-int __init mx23_clocks_init(void)
+static void __init mx23_clocks_init(struct device_node *np)
 {
-       struct device_node *np;
+       struct device_node *dcnp;
        u32 i;
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
-       digctrl = of_iomap(np, 0);
+       dcnp = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
+       digctrl = of_iomap(dcnp, 0);
        WARN_ON(!digctrl);
+       of_node_put(dcnp);
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx23-clkctrl");
        clkctrl = of_iomap(np, 0);
        WARN_ON(!clkctrl);
 
@@ -162,7 +163,7 @@ int __init mx23_clocks_init(void)
                if (IS_ERR(clks[i])) {
                        pr_err("i.MX23 clk %d: register failed with %ld\n",
                                i, PTR_ERR(clks[i]));
-                       return PTR_ERR(clks[i]);
+                       return;
                }
 
        clk_data.clks = clks;
@@ -172,5 +173,5 @@ int __init mx23_clocks_init(void)
        for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
                clk_prepare_enable(clks[clks_init_on[i]]);
 
-       return 0;
 }
+CLK_OF_DECLARE(imx23_clkctrl, "fsl,imx23-clkctrl", mx23_clocks_init);
index 4faf0afc44cd5a2ebe0761af3e8d1250ed6c2b77..a6c35010e4e5b1a61f8e802896bc15ad623bc74a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clk.h>
 #include <linux/clk/mxs.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -154,16 +155,16 @@ static enum imx28_clk clks_init_on[] __initdata = {
        cpu, hbus, xbus, emi, uart,
 };
 
-int __init mx28_clocks_init(void)
+static void __init mx28_clocks_init(struct device_node *np)
 {
-       struct device_node *np;
+       struct device_node *dcnp;
        u32 i;
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx28-digctl");
-       digctrl = of_iomap(np, 0);
+       dcnp = of_find_compatible_node(NULL, NULL, "fsl,imx28-digctl");
+       digctrl = of_iomap(dcnp, 0);
        WARN_ON(!digctrl);
+       of_node_put(dcnp);
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx28-clkctrl");
        clkctrl = of_iomap(np, 0);
        WARN_ON(!clkctrl);
 
@@ -239,7 +240,7 @@ int __init mx28_clocks_init(void)
                if (IS_ERR(clks[i])) {
                        pr_err("i.MX28 clk %d: register failed with %ld\n",
                                i, PTR_ERR(clks[i]));
-                       return PTR_ERR(clks[i]);
+                       return;
                }
 
        clk_data.clks = clks;
@@ -250,6 +251,5 @@ int __init mx28_clocks_init(void)
 
        for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
                clk_prepare_enable(clks[clks_init_on[i]]);
-
-       return 0;
 }
+CLK_OF_DECLARE(imx28_clkctrl, "fsl,imx28-clkctrl", mx28_clocks_init);
index 3413380086d5b22f7e9a618231e33af9a1e37b1e..8eb4799237f03d5106cfe52537c587fb7fc648dd 100644 (file)
@@ -8,6 +8,4 @@ obj-$(CONFIG_SOC_EXYNOS5250)    += clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-audss.o
-ifdef CONFIG_COMMON_CLK
 obj-$(CONFIG_ARCH_S3C64XX)     += clk-s3c64xx.o
-endif
index 5bb848cac6ece40ab0e5bceef82d4facafdbd80d..81dd31a686df9e467b7c111f9c808ee568139551 100644 (file)
@@ -49,7 +49,7 @@
 #define SOCFPGA_L4_SP_CLK              "l4_sp_clk"
 #define SOCFPGA_NAND_CLK               "nand_clk"
 #define SOCFPGA_NAND_X_CLK             "nand_x_clk"
-#define SOCFPGA_MMC_CLK                        "mmc_clk"
+#define SOCFPGA_MMC_CLK                        "sdmmc_clk"
 #define SOCFPGA_DB_CLK                 "gpio_db_clk"
 
 #define div_mask(width)        ((1 << (width)) - 1)
index 34ee69f4d50c5bd574ceeed4893b0bb9f67a3686..9bbd035145409b9908ca25fecfd412d5e7345840 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
-#include <linux/clk/sunxi.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 
@@ -617,11 +616,8 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
        }
 }
 
-void __init sunxi_init_clocks(void)
+static void __init sunxi_init_clocks(struct device_node *np)
 {
-       /* Register all the simple and basic clocks on DT */
-       of_clk_init(NULL);
-
        /* Register factor clocks */
        of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
 
@@ -634,3 +630,8 @@ void __init sunxi_init_clocks(void)
        /* Register gate clocks */
        of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
 }
+CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
+CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
+CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sunxi_init_clocks);
+CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sunxi_init_clocks);
+CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sunxi_init_clocks);
index c6a806ed0e8c85439d3c3753bcc133c24ed0cdb7..521483f0ba335f67a5bf7dc96e26adf3ca89fbcf 100644 (file)
@@ -8,6 +8,7 @@ obj-y += clk-prcmu.o
 obj-y += clk-sysctrl.o
 
 # Clock definitions
+obj-y += u8500_of_clk.o
 obj-y += u8500_clk.o
 obj-y += u9540_clk.o
 obj-y += u8540_clk.o
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c
new file mode 100644 (file)
index 0000000..cdeff29
--- /dev/null
@@ -0,0 +1,559 @@
+/*
+ * Clock definitions for u8500 platform.
+ *
+ * Copyright (C) 2012 ST-Ericsson SA
+ * Author: Ulf Hansson <ulf.hansson@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/platform_data/clk-ux500.h>
+#include "clk.h"
+
+#define PRCC_NUM_PERIPH_CLUSTERS 6
+#define PRCC_PERIPHS_PER_CLUSTER 32
+
+static struct clk *prcmu_clk[PRCMU_NUM_CLKS];
+static struct clk *prcc_pclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER];
+static struct clk *prcc_kclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER];
+
+#define PRCC_SHOW(clk, base, bit) \
+       clk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit]
+#define PRCC_PCLK_STORE(clk, base, bit)        \
+       prcc_pclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk
+#define PRCC_KCLK_STORE(clk, base, bit)        \
+       prcc_kclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk
+
+struct clk *ux500_twocell_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct clk **clk_data = data;
+       unsigned int base, bit;
+
+       if (clkspec->args_count != 2)
+               return  ERR_PTR(-EINVAL);
+
+       base = clkspec->args[0];
+       bit = clkspec->args[1];
+
+       if (base != 1 && base != 2 && base != 3 && base != 5 && base != 6) {
+               pr_err("%s: invalid PRCC base %d\n", __func__, base);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return PRCC_SHOW(clk_data, base, bit);
+}
+
+static const struct of_device_id u8500_clk_of_match[] = {
+       { .compatible = "stericsson,u8500-clks", },
+       { },
+};
+
+void u8500_of_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
+                      u32 clkrst5_base, u32 clkrst6_base)
+{
+       struct prcmu_fw_version *fw_version;
+       struct device_node *np = NULL;
+       struct device_node *child = NULL;
+       const char *sgaclk_parent = NULL;
+       struct clk *clk, *rtc_clk, *twd_clk;
+
+       if (of_have_populated_dt())
+               np = of_find_matching_node(NULL, u8500_clk_of_match);
+       if (!np) {
+               pr_err("Either DT or U8500 Clock node not found\n");
+               return;
+       }
+
+       /* Clock sources */
+       clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0,
+                               CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+       prcmu_clk[PRCMU_PLLSOC0] = clk;
+
+       clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1,
+                               CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+       prcmu_clk[PRCMU_PLLSOC1] = clk;
+
+       clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR,
+                               CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+       prcmu_clk[PRCMU_PLLDDR] = clk;
+
+       /* FIXME: Add sys, ulp and int clocks here. */
+
+       rtc_clk = clk_register_fixed_rate(NULL, "rtc32k", "NULL",
+                               CLK_IS_ROOT|CLK_IGNORE_UNUSED,
+                               32768);
+
+       /* PRCMU clocks */
+       fw_version = prcmu_get_fw_version();
+       if (fw_version != NULL) {
+               switch (fw_version->project) {
+               case PRCMU_FW_PROJECT_U8500_C2:
+               case PRCMU_FW_PROJECT_U8520:
+               case PRCMU_FW_PROJECT_U8420:
+                       sgaclk_parent = "soc0_pll";
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (sgaclk_parent)
+               clk = clk_reg_prcmu_gate("sgclk", sgaclk_parent,
+                                       PRCMU_SGACLK, 0);
+       else
+               clk = clk_reg_prcmu_gate("sgclk", NULL,
+                                       PRCMU_SGACLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_SGACLK] = clk;
+
+       clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_UARTCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_MSP02CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_MSP1CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_I2CCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_SLIMCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_PER1CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_PER2CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_PER3CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_PER5CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_PER6CLK] = clk;
+
+       clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_PER7CLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0,
+                               CLK_IS_ROOT|CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_LCDCLK] = clk;
+
+       clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_BMLCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0,
+                               CLK_IS_ROOT|CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_HSITXCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0,
+                               CLK_IS_ROOT|CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_HSIRXCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0,
+                               CLK_IS_ROOT|CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_HDMICLK] = clk;
+
+       clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_APEATCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK,
+                               CLK_IS_ROOT);
+       prcmu_clk[PRCMU_APETRACECLK] = clk;
+
+       clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_MCDECLK] = clk;
+
+       clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK,
+                               CLK_IS_ROOT);
+       prcmu_clk[PRCMU_IPI2CCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK,
+                               CLK_IS_ROOT);
+       prcmu_clk[PRCMU_DSIALTCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_DMACLK] = clk;
+
+       clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_B2R2CLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0,
+                               CLK_IS_ROOT|CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_TVCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_SSPCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_RNGCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_UICCCLK] = clk;
+
+       clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT);
+       prcmu_clk[PRCMU_TIMCLK] = clk;
+
+       clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK,
+                                       100000000,
+                                       CLK_IS_ROOT|CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_SDMMCCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk",
+                               PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_PLLDSI] = clk;
+
+       clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll",
+                               PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_DSI0CLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll",
+                               PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_DSI1CLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk",
+                               PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_DSI0ESCCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk",
+                               PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_DSI1ESCCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk",
+                               PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE);
+       prcmu_clk[PRCMU_DSI2ESCCLK] = clk;
+
+       clk = clk_reg_prcmu_scalable_rate("armss", NULL,
+                               PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+       prcmu_clk[PRCMU_ARMSS] = clk;
+
+       twd_clk = clk_register_fixed_factor(NULL, "smp_twd", "armss",
+                               CLK_IGNORE_UNUSED, 1, 2);
+
+       /*
+        * FIXME: Add special handled PRCMU clocks here:
+        * 1. clkout0yuv, use PRCMU as parent + need regulator + pinctrl.
+        * 2. ab9540_clkout1yuv, see clkout0yuv
+        */
+
+       /* PRCC P-clocks */
+       clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", clkrst1_base,
+                               BIT(0), 0);
+       PRCC_PCLK_STORE(clk, 1, 0);
+
+       clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", clkrst1_base,
+                               BIT(1), 0);
+       PRCC_PCLK_STORE(clk, 1, 1);
+
+       clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", clkrst1_base,
+                               BIT(2), 0);
+       PRCC_PCLK_STORE(clk, 1, 2);
+
+       clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", clkrst1_base,
+                               BIT(3), 0);
+       PRCC_PCLK_STORE(clk, 1, 3);
+
+       clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", clkrst1_base,
+                               BIT(4), 0);
+       PRCC_PCLK_STORE(clk, 1, 4);
+
+       clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", clkrst1_base,
+                               BIT(5), 0);
+       PRCC_PCLK_STORE(clk, 1, 5);
+
+       clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", clkrst1_base,
+                               BIT(6), 0);
+       PRCC_PCLK_STORE(clk, 1, 6);
+
+       clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", clkrst1_base,
+                               BIT(7), 0);
+       PRCC_PCLK_STORE(clk, 1, 7);
+
+       clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", clkrst1_base,
+                               BIT(8), 0);
+       PRCC_PCLK_STORE(clk, 1, 8);
+
+       clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", clkrst1_base,
+                               BIT(9), 0);
+       PRCC_PCLK_STORE(clk, 1, 9);
+
+       clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", clkrst1_base,
+                               BIT(10), 0);
+       PRCC_PCLK_STORE(clk, 1, 10);
+
+       clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", clkrst1_base,
+                               BIT(11), 0);
+       PRCC_PCLK_STORE(clk, 1, 11);
+
+       clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", clkrst2_base,
+                               BIT(0), 0);
+       PRCC_PCLK_STORE(clk, 2, 0);
+
+       clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", clkrst2_base,
+                               BIT(1), 0);
+       PRCC_PCLK_STORE(clk, 2, 1);
+
+       clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", clkrst2_base,
+                               BIT(2), 0);
+       PRCC_PCLK_STORE(clk, 2, 2);
+
+       clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", clkrst2_base,
+                               BIT(3), 0);
+       PRCC_PCLK_STORE(clk, 2, 3);
+
+       clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", clkrst2_base,
+                               BIT(4), 0);
+       PRCC_PCLK_STORE(clk, 2, 4);
+
+       clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", clkrst2_base,
+                               BIT(5), 0);
+       PRCC_PCLK_STORE(clk, 2, 5);
+
+       clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", clkrst2_base,
+                               BIT(6), 0);
+       PRCC_PCLK_STORE(clk, 2, 6);
+
+       clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", clkrst2_base,
+                               BIT(7), 0);
+       PRCC_PCLK_STORE(clk, 2, 7);
+
+       clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", clkrst2_base,
+                               BIT(8), 0);
+       PRCC_PCLK_STORE(clk, 2, 8);
+
+       clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", clkrst2_base,
+                               BIT(9), 0);
+       PRCC_PCLK_STORE(clk, 2, 9);
+
+       clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", clkrst2_base,
+                               BIT(10), 0);
+       PRCC_PCLK_STORE(clk, 2, 10);
+
+       clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", clkrst2_base,
+                               BIT(11), 0);
+       PRCC_PCLK_STORE(clk, 2, 11);
+
+       clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", clkrst2_base,
+                               BIT(12), 0);
+       PRCC_PCLK_STORE(clk, 2, 12);
+
+       clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base,
+                               BIT(0), 0);
+       PRCC_PCLK_STORE(clk, 3, 0);
+
+       clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base,
+                               BIT(1), 0);
+       PRCC_PCLK_STORE(clk, 3, 1);
+
+       clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", clkrst3_base,
+                               BIT(2), 0);
+       PRCC_PCLK_STORE(clk, 3, 2);
+
+       clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", clkrst3_base,
+                               BIT(3), 0);
+       PRCC_PCLK_STORE(clk, 3, 3);
+
+       clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", clkrst3_base,
+                               BIT(4), 0);
+       PRCC_PCLK_STORE(clk, 3, 4);
+
+       clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", clkrst3_base,
+                               BIT(5), 0);
+       PRCC_PCLK_STORE(clk, 3, 5);
+
+       clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", clkrst3_base,
+                               BIT(6), 0);
+       PRCC_PCLK_STORE(clk, 3, 6);
+
+       clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", clkrst3_base,
+                               BIT(7), 0);
+       PRCC_PCLK_STORE(clk, 3, 7);
+
+       clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", clkrst3_base,
+                               BIT(8), 0);
+       PRCC_PCLK_STORE(clk, 3, 8);
+
+       clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", clkrst5_base,
+                               BIT(0), 0);
+       PRCC_PCLK_STORE(clk, 5, 0);
+
+       clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", clkrst5_base,
+                               BIT(1), 0);
+       PRCC_PCLK_STORE(clk, 5, 1);
+
+       clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", clkrst6_base,
+                               BIT(0), 0);
+       PRCC_PCLK_STORE(clk, 6, 0);
+
+       clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", clkrst6_base,
+                               BIT(1), 0);
+       PRCC_PCLK_STORE(clk, 6, 1);
+
+       clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", clkrst6_base,
+                               BIT(2), 0);
+       PRCC_PCLK_STORE(clk, 6, 2);
+
+       clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", clkrst6_base,
+                               BIT(3), 0);
+       PRCC_PCLK_STORE(clk, 6, 3);
+
+       clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", clkrst6_base,
+                               BIT(4), 0);
+       PRCC_PCLK_STORE(clk, 6, 4);
+
+       clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", clkrst6_base,
+                               BIT(5), 0);
+       PRCC_PCLK_STORE(clk, 6, 5);
+
+       clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", clkrst6_base,
+                               BIT(6), 0);
+       PRCC_PCLK_STORE(clk, 6, 6);
+
+       clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", clkrst6_base,
+                               BIT(7), 0);
+       PRCC_PCLK_STORE(clk, 6, 7);
+
+       /* PRCC K-clocks
+        *
+        * FIXME: Some drivers requires PERPIH[n| to be automatically enabled
+        * by enabling just the K-clock, even if it is not a valid parent to
+        * the K-clock. Until drivers get fixed we might need some kind of
+        * "parent muxed join".
+        */
+
+       /* Periph1 */
+       clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk",
+                       clkrst1_base, BIT(0), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 0);
+
+       clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk",
+                       clkrst1_base, BIT(1), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 1);
+
+       clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
+                       clkrst1_base, BIT(2), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 2);
+
+       clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
+                       clkrst1_base, BIT(3), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 3);
+
+       clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
+                       clkrst1_base, BIT(4), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 4);
+
+       clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk",
+                       clkrst1_base, BIT(5), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 5);
+
+       clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
+                       clkrst1_base, BIT(6), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 6);
+
+       clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
+                       clkrst1_base, BIT(8), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 8);
+
+       clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
+                       clkrst1_base, BIT(9), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 9);
+
+       clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
+                       clkrst1_base, BIT(10), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 1, 10);
+
+       /* Periph2 */
+       clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
+                       clkrst2_base, BIT(0), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 2, 0);
+
+       clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk",
+                       clkrst2_base, BIT(2), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 2, 2);
+
+       clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
+                       clkrst2_base, BIT(3), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 2, 3);
+
+       clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk",
+                       clkrst2_base, BIT(4), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 2, 4);
+
+       clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk",
+                       clkrst2_base, BIT(5), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 2, 5);
+
+       /* Note that rate is received from parent. */
+       clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk",
+                       clkrst2_base, BIT(6),
+                       CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
+       PRCC_KCLK_STORE(clk, 2, 6);
+
+       clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk",
+                       clkrst2_base, BIT(7),
+                       CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
+       PRCC_KCLK_STORE(clk, 2, 7);
+
+       /* Periph3 */
+       clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
+                       clkrst3_base, BIT(1), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 1);
+
+       clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
+                       clkrst3_base, BIT(2), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 2);
+
+       clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
+                       clkrst3_base, BIT(3), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 3);
+
+       clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk",
+                       clkrst3_base, BIT(4), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 4);
+
+       clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k",
+                       clkrst3_base, BIT(5), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 5);
+
+       clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk",
+                       clkrst3_base, BIT(6), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 6);
+
+       clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk",
+                       clkrst3_base, BIT(7), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 3, 7);
+
+       /* Periph6 */
+       clk = clk_reg_prcc_kclk("p3_rng_kclk", "rngclk",
+                       clkrst6_base, BIT(0), CLK_SET_RATE_GATE);
+       PRCC_KCLK_STORE(clk, 6, 0);
+
+       for_each_child_of_node(np, child) {
+               static struct clk_onecell_data clk_data;
+
+               if (!of_node_cmp(child->name, "prcmu-clock")) {
+                       clk_data.clks = prcmu_clk;
+                       clk_data.clk_num = ARRAY_SIZE(prcmu_clk);
+                       of_clk_add_provider(child, of_clk_src_onecell_get, &clk_data);
+               }
+               if (!of_node_cmp(child->name, "prcc-periph-clock"))
+                       of_clk_add_provider(child, ux500_twocell_get, prcc_pclk);
+
+               if (!of_node_cmp(child->name, "prcc-kernel-clock"))
+                       of_clk_add_provider(child, ux500_twocell_get, prcc_kclk);
+
+               if (!of_node_cmp(child->name, "rtc32k-clock"))
+                       of_clk_add_provider(child, of_clk_src_simple_get, rtc_clk);
+
+               if (!of_node_cmp(child->name, "smp-twd-clock"))
+                       of_clk_add_provider(child, of_clk_src_simple_get, twd_clk);
+       }
+}
index f26258869deb22d4f2fd760b2139395ae25c9b0f..20c8add90d110db1575e0ccb5695499581853af5 100644 (file)
@@ -83,7 +83,7 @@ void u8540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
        clk_register_clkdev(clk, NULL, "lcd");
        clk_register_clkdev(clk, "lcd", "mcde");
 
-       clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BML8580CLK,
+       clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK,
                                CLK_IS_ROOT);
        clk_register_clkdev(clk, NULL, "bml");
 
index 67ccf4aa72773520baa89708c30737c3ad13c493..f5e4c21b301f6438c32d3552cae4bb9aef9d2a44 100644 (file)
@@ -107,7 +107,7 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
 
        vco = icst_hz_to_vco(icst->params, rate);
        icst->rate = icst_hz(icst->params, vco);
-       vco_set(icst->vcoreg, icst->lockreg, vco);
+       vco_set(icst->lockreg, icst->vcoreg, vco);
        return 0;
 }
 
index f7c99df0880b4d396fee72860b904b5764f943f3..3d79bca474336b16e0cc7810eafae9a28b65b0aa 100644 (file)
 #include <linux/smp.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/icst.h>
 
-static struct cpufreq_driver integrator_driver;
+static void __iomem *cm_base;
+/* The cpufreq driver only use the OSC register */
+#define INTEGRATOR_HDR_OSC_OFFSET       0x08
+#define INTEGRATOR_HDR_LOCK_OFFSET      0x14
 
-#define CM_ID          __io_address(INTEGRATOR_HDR_ID)
-#define CM_OSC __io_address(INTEGRATOR_HDR_OSC)
-#define CM_STAT __io_address(INTEGRATOR_HDR_STAT)
-#define CM_LOCK __io_address(INTEGRATOR_HDR_LOCK)
+static struct cpufreq_driver integrator_driver;
 
 static const struct icst_params lclk_params = {
        .ref            = 24000000,
@@ -100,7 +101,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
        BUG_ON(cpu != smp_processor_id());
 
        /* get current setting */
-       cm_osc = __raw_readl(CM_OSC);
+       cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
        if (machine_is_integrator()) {
                vco.s = (cm_osc >> 8) & 7;
@@ -128,7 +129,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
 
        cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
-       cm_osc = __raw_readl(CM_OSC);
+       cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
        if (machine_is_integrator()) {
                cm_osc &= 0xfffff800;
@@ -138,9 +139,9 @@ static int integrator_set_target(struct cpufreq_policy *policy,
        }
        cm_osc |= vco.v;
 
-       __raw_writel(0xa05f, CM_LOCK);
-       __raw_writel(cm_osc, CM_OSC);
-       __raw_writel(0, CM_LOCK);
+       __raw_writel(0xa05f, cm_base + INTEGRATOR_HDR_LOCK_OFFSET);
+       __raw_writel(cm_osc, cm_base + INTEGRATOR_HDR_OSC_OFFSET);
+       __raw_writel(0, cm_base + INTEGRATOR_HDR_LOCK_OFFSET);
 
        /*
         * Restore the CPUs allowed mask.
@@ -165,7 +166,7 @@ static unsigned int integrator_get(unsigned int cpu)
        BUG_ON(cpu != smp_processor_id());
 
        /* detect memory etc. */
-       cm_osc = __raw_readl(CM_OSC);
+       cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
        if (machine_is_integrator()) {
                vco.s = (cm_osc >> 8) & 7;
@@ -202,19 +203,43 @@ static struct cpufreq_driver integrator_driver = {
        .name           = "integrator",
 };
 
-static int __init integrator_cpu_init(void)
+static int __init integrator_cpufreq_probe(struct platform_device *pdev)
 {
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+        if (!res)
+               return -ENODEV;
+
+       cm_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+       if (!cm_base)
+               return -ENODEV;
+
        return cpufreq_register_driver(&integrator_driver);
 }
 
-static void __exit integrator_cpu_exit(void)
+static void __exit integrator_cpufreq_remove(struct platform_device *pdev)
 {
        cpufreq_unregister_driver(&integrator_driver);
 }
 
+static const struct of_device_id integrator_cpufreq_match[] = {
+       { .compatible = "arm,core-module-integrator"},
+       { },
+};
+
+static struct platform_driver integrator_cpufreq_driver = {
+       .driver = {
+               .name = "integrator-cpufreq",
+               .owner = THIS_MODULE,
+               .of_match_table = integrator_cpufreq_match,
+       },
+       .remove = __exit_p(integrator_cpufreq_remove),
+};
+
+module_platform_driver_probe(integrator_cpufreq_driver,
+                            integrator_cpufreq_probe);
+
 MODULE_AUTHOR ("Russell M. King");
 MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs");
 MODULE_LICENSE ("GPL");
-
-module_init(integrator_cpu_init);
-module_exit(integrator_cpu_exit);
index 8e366032230893dc35c0d03f55138a20e0a33f07..d6f57d5d963181e1125c2aba5f938a48a9afa339 100644 (file)
@@ -4,7 +4,7 @@
 
 config ARM_HIGHBANK_CPUIDLE
        bool "CPU Idle Driver for Calxeda processors"
-       depends on ARCH_HIGHBANK
+       depends on ARM_PSCI
        select ARM_CPU_SUSPEND
        help
          Select this to enable cpuidle on Calxeda processors.
index 34605847957269635b650997d51ac7eb9062416f..36795639df0da2d828c784b61c82a728037f6e1c 100644 (file)
  */
 
 #include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
 #include <linux/init.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/suspend.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
 #include <asm/cpuidle.h>
-#include <asm/proc-fns.h>
-#include <asm/smp_scu.h>
 #include <asm/suspend.h>
-#include <asm/cacheflush.h>
-#include <asm/cp15.h>
-
-extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
-extern void __iomem *scu_base_addr;
-
-static noinline void calxeda_idle_restore(void)
-{
-       set_cr(get_cr() | CR_C);
-       set_auxcr(get_auxcr() | 0x40);
-       scu_power_mode(scu_base_addr, SCU_PM_NORMAL);
-}
+#include <asm/psci.h>
 
 static int calxeda_idle_finish(unsigned long val)
 {
-       /* Already flushed cache, but do it again as the outer cache functions
-        * dirty the cache with spinlocks */
-       flush_cache_all();
-
-       set_auxcr(get_auxcr() & ~0x40);
-       set_cr(get_cr() & ~CR_C);
-
-       scu_power_mode(scu_base_addr, SCU_PM_DORMANT);
-
-       cpu_do_idle();
-
-       /* Restore things if we didn't enter power-gating */
-       calxeda_idle_restore();
-       return 1;
+       const struct psci_power_state ps = {
+               .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
+       };
+       return psci_ops.cpu_suspend(ps, __pa(cpu_resume));
 }
 
 static int calxeda_pwrdown_idle(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv,
                                int index)
 {
-       highbank_set_cpu_jump(smp_processor_id(), cpu_resume);
+       cpu_pm_enter();
        cpu_suspend(0, calxeda_idle_finish);
+       cpu_pm_exit();
+
        return index;
 }
 
@@ -88,11 +65,17 @@ static struct cpuidle_driver calxeda_idle_driver = {
        .state_count = 2,
 };
 
-static int __init calxeda_cpuidle_init(void)
+static int __init calxeda_cpuidle_probe(struct platform_device *pdev)
 {
-       if (!of_machine_is_compatible("calxeda,highbank"))
-               return -ENODEV;
-
        return cpuidle_register(&calxeda_idle_driver, NULL);
 }
-module_init(calxeda_cpuidle_init);
+
+static struct platform_driver calxeda_cpuidle_plat_driver = {
+        .driver = {
+                .name = "cpuidle-calxeda",
+                .owner = THIS_MODULE,
+        },
+        .probe = calxeda_cpuidle_probe,
+};
+
+module_platform_driver(calxeda_cpuidle_plat_driver);
index f238cfd33847ec3c5333158ea39dac72245c8eee..c61a6eccf16958ff2145d1b7971d17da92aa9032 100644 (file)
@@ -154,6 +154,18 @@ config TEGRA20_APB_DMA
          This DMA controller transfers data from memory to peripheral fifo
          or vice versa. It does not support memory to memory data transfer.
 
+config S3C24XX_DMAC
+       tristate "Samsung S3C24XX DMA support"
+       depends on ARCH_S3C24XX && !S3C24XX_DMA
+       select DMA_ENGINE
+       select DMA_VIRTUAL_CHANNELS
+       help
+         Support for the Samsung S3C24XX DMA controller driver. The
+         DMA controller is having multiple DMA channels which can be
+         configured for different peripherals like audio, UART, SPI.
+         The DMA controller can transfer data from memory to peripheral,
+         periphal to memory, periphal to periphal and memory to memory.
+
 source "drivers/dma/sh/Kconfig"
 
 config COH901318
@@ -195,7 +207,7 @@ config SIRF_DMA
 
 config TI_EDMA
        bool "TI EDMA support"
-       depends on ARCH_DAVINCI || ARCH_OMAP
+       depends on ARCH_DAVINCI || ARCH_OMAP || ARCH_KEYSTONE
        select DMA_ENGINE
        select DMA_VIRTUAL_CHANNELS
        select TI_PRIV_EDMA
index db89035b362612304a3334ab5c9834770cab1303..0ce2da97e42972b82a61197a4fe4bb52c35ceac4 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
 obj-$(CONFIG_TI_EDMA) += edma.o
 obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
 obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
+obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
 obj-$(CONFIG_PL330_DMA) += pl330.o
 obj-$(CONFIG_PCH_DMA) += pch_dma.o
 obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c
new file mode 100644 (file)
index 0000000..4cb1279
--- /dev/null
@@ -0,0 +1,1350 @@
+/*
+ * S3C24XX DMA handling
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * based on amba-pl08x.c
+ *
+ * Copyright (c) 2006 ARM Ltd.
+ * Copyright (c) 2010 ST-Ericsson SA
+ *
+ * Author: Peter Pearse <peter.pearse@arm.com>
+ * Author: Linus Walleij <linus.walleij@stericsson.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.
+ *
+ * The DMA controllers in S3C24XX SoCs have a varying number of DMA signals
+ * that can be routed to any of the 4 to 8 hardware-channels.
+ *
+ * Therefore on these DMA controllers the number of channels
+ * and the number of incoming DMA signals are two totally different things.
+ * It is usually not possible to theoretically handle all physical signals,
+ * so a multiplexing scheme with possible denial of use is necessary.
+ *
+ * Open items:
+ * - bursts
+ */
+
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_data/dma-s3c24xx.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define MAX_DMA_CHANNELS       8
+
+#define S3C24XX_DISRC                  0x00
+#define S3C24XX_DISRCC                 0x04
+#define S3C24XX_DISRCC_INC_INCREMENT   0
+#define S3C24XX_DISRCC_INC_FIXED       BIT(0)
+#define S3C24XX_DISRCC_LOC_AHB         0
+#define S3C24XX_DISRCC_LOC_APB         BIT(1)
+
+#define S3C24XX_DIDST                  0x08
+#define S3C24XX_DIDSTC                 0x0c
+#define S3C24XX_DIDSTC_INC_INCREMENT   0
+#define S3C24XX_DIDSTC_INC_FIXED       BIT(0)
+#define S3C24XX_DIDSTC_LOC_AHB         0
+#define S3C24XX_DIDSTC_LOC_APB         BIT(1)
+#define S3C24XX_DIDSTC_INT_TC0         0
+#define S3C24XX_DIDSTC_INT_RELOAD      BIT(2)
+
+#define S3C24XX_DCON                   0x10
+
+#define S3C24XX_DCON_TC_MASK           0xfffff
+#define S3C24XX_DCON_DSZ_BYTE          (0 << 20)
+#define S3C24XX_DCON_DSZ_HALFWORD      (1 << 20)
+#define S3C24XX_DCON_DSZ_WORD          (2 << 20)
+#define S3C24XX_DCON_DSZ_MASK          (3 << 20)
+#define S3C24XX_DCON_DSZ_SHIFT         20
+#define S3C24XX_DCON_AUTORELOAD                0
+#define S3C24XX_DCON_NORELOAD          BIT(22)
+#define S3C24XX_DCON_HWTRIG            BIT(23)
+#define S3C24XX_DCON_HWSRC_SHIFT       24
+#define S3C24XX_DCON_SERV_SINGLE       0
+#define S3C24XX_DCON_SERV_WHOLE                BIT(27)
+#define S3C24XX_DCON_TSZ_UNIT          0
+#define S3C24XX_DCON_TSZ_BURST4                BIT(28)
+#define S3C24XX_DCON_INT               BIT(29)
+#define S3C24XX_DCON_SYNC_PCLK         0
+#define S3C24XX_DCON_SYNC_HCLK         BIT(30)
+#define S3C24XX_DCON_DEMAND            0
+#define S3C24XX_DCON_HANDSHAKE         BIT(31)
+
+#define S3C24XX_DSTAT                  0x14
+#define S3C24XX_DSTAT_STAT_BUSY                BIT(20)
+#define S3C24XX_DSTAT_CURRTC_MASK      0xfffff
+
+#define S3C24XX_DMASKTRIG              0x20
+#define S3C24XX_DMASKTRIG_SWTRIG       BIT(0)
+#define S3C24XX_DMASKTRIG_ON           BIT(1)
+#define S3C24XX_DMASKTRIG_STOP         BIT(2)
+
+#define S3C24XX_DMAREQSEL              0x24
+#define S3C24XX_DMAREQSEL_HW           BIT(0)
+
+/*
+ * S3C2410, S3C2440 and S3C2442 SoCs cannot select any physical channel
+ * for a DMA source. Instead only specific channels are valid.
+ * All of these SoCs have 4 physical channels and the number of request
+ * source bits is 3. Additionally we also need 1 bit to mark the channel
+ * as valid.
+ * Therefore we separate the chansel element of the channel data into 4
+ * parts of 4 bits each, to hold the information if the channel is valid
+ * and the hw request source to use.
+ *
+ * Example:
+ * SDI is valid on channels 0, 2 and 3 - with varying hw request sources.
+ * For it the chansel field would look like
+ *
+ * ((BIT(3) | 1) << 3 * 4) | // channel 3, with request source 1
+ * ((BIT(3) | 2) << 2 * 4) | // channel 2, with request source 2
+ * ((BIT(3) | 2) << 0 * 4)   // channel 0, with request source 2
+ */
+#define S3C24XX_CHANSEL_WIDTH          4
+#define S3C24XX_CHANSEL_VALID          BIT(3)
+#define S3C24XX_CHANSEL_REQ_MASK       7
+
+/*
+ * struct soc_data - vendor-specific config parameters for individual SoCs
+ * @stride: spacing between the registers of each channel
+ * @has_reqsel: does the controller use the newer requestselection mechanism
+ * @has_clocks: are controllable dma-clocks present
+ */
+struct soc_data {
+       int stride;
+       bool has_reqsel;
+       bool has_clocks;
+};
+
+/*
+ * enum s3c24xx_dma_chan_state - holds the virtual channel states
+ * @S3C24XX_DMA_CHAN_IDLE: the channel is idle
+ * @S3C24XX_DMA_CHAN_RUNNING: the channel has allocated a physical transport
+ * channel and is running a transfer on it
+ * @S3C24XX_DMA_CHAN_WAITING: the channel is waiting for a physical transport
+ * channel to become available (only pertains to memcpy channels)
+ */
+enum s3c24xx_dma_chan_state {
+       S3C24XX_DMA_CHAN_IDLE,
+       S3C24XX_DMA_CHAN_RUNNING,
+       S3C24XX_DMA_CHAN_WAITING,
+};
+
+/*
+ * struct s3c24xx_sg - structure containing data per sg
+ * @src_addr: src address of sg
+ * @dst_addr: dst address of sg
+ * @len: transfer len in bytes
+ * @node: node for txd's dsg_list
+ */
+struct s3c24xx_sg {
+       dma_addr_t src_addr;
+       dma_addr_t dst_addr;
+       size_t len;
+       struct list_head node;
+};
+
+/*
+ * struct s3c24xx_txd - wrapper for struct dma_async_tx_descriptor
+ * @vd: virtual DMA descriptor
+ * @dsg_list: list of children sg's
+ * @at: sg currently being transfered
+ * @width: transfer width
+ * @disrcc: value for source control register
+ * @didstc: value for destination control register
+ * @dcon: base value for dcon register
+ */
+struct s3c24xx_txd {
+       struct virt_dma_desc vd;
+       struct list_head dsg_list;
+       struct list_head *at;
+       u8 width;
+       u32 disrcc;
+       u32 didstc;
+       u32 dcon;
+};
+
+struct s3c24xx_dma_chan;
+
+/*
+ * struct s3c24xx_dma_phy - holder for the physical channels
+ * @id: physical index to this channel
+ * @valid: does the channel have all required elements
+ * @base: virtual memory base (remapped) for the this channel
+ * @irq: interrupt for this channel
+ * @clk: clock for this channel
+ * @lock: a lock to use when altering an instance of this struct
+ * @serving: virtual channel currently being served by this physicalchannel
+ * @host: a pointer to the host (internal use)
+ */
+struct s3c24xx_dma_phy {
+       unsigned int                    id;
+       bool                            valid;
+       void __iomem                    *base;
+       unsigned int                    irq;
+       struct clk                      *clk;
+       spinlock_t                      lock;
+       struct s3c24xx_dma_chan         *serving;
+       struct s3c24xx_dma_engine       *host;
+};
+
+/*
+ * struct s3c24xx_dma_chan - this structure wraps a DMA ENGINE channel
+ * @id: the id of the channel
+ * @name: name of the channel
+ * @vc: wrappped virtual channel
+ * @phy: the physical channel utilized by this channel, if there is one
+ * @runtime_addr: address for RX/TX according to the runtime config
+ * @at: active transaction on this channel
+ * @lock: a lock for this channel data
+ * @host: a pointer to the host (internal use)
+ * @state: whether the channel is idle, running etc
+ * @slave: whether this channel is a device (slave) or for memcpy
+ */
+struct s3c24xx_dma_chan {
+       int id;
+       const char *name;
+       struct virt_dma_chan vc;
+       struct s3c24xx_dma_phy *phy;
+       struct dma_slave_config cfg;
+       struct s3c24xx_txd *at;
+       struct s3c24xx_dma_engine *host;
+       enum s3c24xx_dma_chan_state state;
+       bool slave;
+};
+
+/*
+ * struct s3c24xx_dma_engine - the local state holder for the S3C24XX
+ * @pdev: the corresponding platform device
+ * @pdata: platform data passed in from the platform/machine
+ * @base: virtual memory base (remapped)
+ * @slave: slave engine for this instance
+ * @memcpy: memcpy engine for this instance
+ * @phy_chans: array of data for the physical channels
+ */
+struct s3c24xx_dma_engine {
+       struct platform_device                  *pdev;
+       const struct s3c24xx_dma_platdata       *pdata;
+       struct soc_data                         *sdata;
+       void __iomem                            *base;
+       struct dma_device                       slave;
+       struct dma_device                       memcpy;
+       struct s3c24xx_dma_phy                  *phy_chans;
+};
+
+/*
+ * Physical channel handling
+ */
+
+/*
+ * Check whether a certain channel is busy or not.
+ */
+static int s3c24xx_dma_phy_busy(struct s3c24xx_dma_phy *phy)
+{
+       unsigned int val = readl(phy->base + S3C24XX_DSTAT);
+       return val & S3C24XX_DSTAT_STAT_BUSY;
+}
+
+static bool s3c24xx_dma_phy_valid(struct s3c24xx_dma_chan *s3cchan,
+                                 struct s3c24xx_dma_phy *phy)
+{
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       const struct s3c24xx_dma_platdata *pdata = s3cdma->pdata;
+       struct s3c24xx_dma_channel *cdata = &pdata->channels[s3cchan->id];
+       int phyvalid;
+
+       /* every phy is valid for memcopy channels */
+       if (!s3cchan->slave)
+               return true;
+
+       /* On newer variants all phys can be used for all virtual channels */
+       if (s3cdma->sdata->has_reqsel)
+               return true;
+
+       phyvalid = (cdata->chansel >> (phy->id * S3C24XX_CHANSEL_WIDTH));
+       return (phyvalid & S3C24XX_CHANSEL_VALID) ? true : false;
+}
+
+/*
+ * Allocate a physical channel for a virtual channel
+ *
+ * Try to locate a physical channel to be used for this transfer. If all
+ * are taken return NULL and the requester will have to cope by using
+ * some fallback PIO mode or retrying later.
+ */
+static
+struct s3c24xx_dma_phy *s3c24xx_dma_get_phy(struct s3c24xx_dma_chan *s3cchan)
+{
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       const struct s3c24xx_dma_platdata *pdata = s3cdma->pdata;
+       struct s3c24xx_dma_channel *cdata;
+       struct s3c24xx_dma_phy *phy = NULL;
+       unsigned long flags;
+       int i;
+       int ret;
+
+       if (s3cchan->slave)
+               cdata = &pdata->channels[s3cchan->id];
+
+       for (i = 0; i < s3cdma->pdata->num_phy_channels; i++) {
+               phy = &s3cdma->phy_chans[i];
+
+               if (!phy->valid)
+                       continue;
+
+               if (!s3c24xx_dma_phy_valid(s3cchan, phy))
+                       continue;
+
+               spin_lock_irqsave(&phy->lock, flags);
+
+               if (!phy->serving) {
+                       phy->serving = s3cchan;
+                       spin_unlock_irqrestore(&phy->lock, flags);
+                       break;
+               }
+
+               spin_unlock_irqrestore(&phy->lock, flags);
+       }
+
+       /* No physical channel available, cope with it */
+       if (i == s3cdma->pdata->num_phy_channels) {
+               dev_warn(&s3cdma->pdev->dev, "no phy channel available\n");
+               return NULL;
+       }
+
+       /* start the phy clock */
+       if (s3cdma->sdata->has_clocks) {
+               ret = clk_enable(phy->clk);
+               if (ret) {
+                       dev_err(&s3cdma->pdev->dev, "could not enable clock for channel %d, err %d\n",
+                               phy->id, ret);
+                       phy->serving = NULL;
+                       return NULL;
+               }
+       }
+
+       return phy;
+}
+
+/*
+ * Mark the physical channel as free.
+ *
+ * This drops the link between the physical and virtual channel.
+ */
+static inline void s3c24xx_dma_put_phy(struct s3c24xx_dma_phy *phy)
+{
+       struct s3c24xx_dma_engine *s3cdma = phy->host;
+
+       if (s3cdma->sdata->has_clocks)
+               clk_disable(phy->clk);
+
+       phy->serving = NULL;
+}
+
+/*
+ * Stops the channel by writing the stop bit.
+ * This should not be used for an on-going transfer, but as a method of
+ * shutting down a channel (eg, when it's no longer used) or terminating a
+ * transfer.
+ */
+static void s3c24xx_dma_terminate_phy(struct s3c24xx_dma_phy *phy)
+{
+       writel(S3C24XX_DMASKTRIG_STOP, phy->base + S3C24XX_DMASKTRIG);
+}
+
+/*
+ * Virtual channel handling
+ */
+
+static inline
+struct s3c24xx_dma_chan *to_s3c24xx_dma_chan(struct dma_chan *chan)
+{
+       return container_of(chan, struct s3c24xx_dma_chan, vc.chan);
+}
+
+static u32 s3c24xx_dma_getbytes_chan(struct s3c24xx_dma_chan *s3cchan)
+{
+       struct s3c24xx_dma_phy *phy = s3cchan->phy;
+       struct s3c24xx_txd *txd = s3cchan->at;
+       u32 tc = readl(phy->base + S3C24XX_DSTAT) & S3C24XX_DSTAT_CURRTC_MASK;
+
+       return tc * txd->width;
+}
+
+static int s3c24xx_dma_set_runtime_config(struct s3c24xx_dma_chan *s3cchan,
+                                 struct dma_slave_config *config)
+{
+       if (!s3cchan->slave)
+               return -EINVAL;
+
+       /* Reject definitely invalid configurations */
+       if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
+           config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
+               return -EINVAL;
+
+       s3cchan->cfg = *config;
+
+       return 0;
+}
+
+/*
+ * Transfer handling
+ */
+
+static inline
+struct s3c24xx_txd *to_s3c24xx_txd(struct dma_async_tx_descriptor *tx)
+{
+       return container_of(tx, struct s3c24xx_txd, vd.tx);
+}
+
+static struct s3c24xx_txd *s3c24xx_dma_get_txd(void)
+{
+       struct s3c24xx_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
+
+       if (txd) {
+               INIT_LIST_HEAD(&txd->dsg_list);
+               txd->dcon = S3C24XX_DCON_INT | S3C24XX_DCON_NORELOAD;
+       }
+
+       return txd;
+}
+
+static void s3c24xx_dma_free_txd(struct s3c24xx_txd *txd)
+{
+       struct s3c24xx_sg *dsg, *_dsg;
+
+       list_for_each_entry_safe(dsg, _dsg, &txd->dsg_list, node) {
+               list_del(&dsg->node);
+               kfree(dsg);
+       }
+
+       kfree(txd);
+}
+
+static void s3c24xx_dma_start_next_sg(struct s3c24xx_dma_chan *s3cchan,
+                                      struct s3c24xx_txd *txd)
+{
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       struct s3c24xx_dma_phy *phy = s3cchan->phy;
+       const struct s3c24xx_dma_platdata *pdata = s3cdma->pdata;
+       struct s3c24xx_sg *dsg = list_entry(txd->at, struct s3c24xx_sg, node);
+       u32 dcon = txd->dcon;
+       u32 val;
+
+       /* transfer-size and -count from len and width */
+       switch (txd->width) {
+       case 1:
+               dcon |= S3C24XX_DCON_DSZ_BYTE | dsg->len;
+               break;
+       case 2:
+               dcon |= S3C24XX_DCON_DSZ_HALFWORD | (dsg->len / 2);
+               break;
+       case 4:
+               dcon |= S3C24XX_DCON_DSZ_WORD | (dsg->len / 4);
+               break;
+       }
+
+       if (s3cchan->slave) {
+               struct s3c24xx_dma_channel *cdata =
+                                       &pdata->channels[s3cchan->id];
+
+               if (s3cdma->sdata->has_reqsel) {
+                       writel_relaxed((cdata->chansel << 1) |
+                                                       S3C24XX_DMAREQSEL_HW,
+                                       phy->base + S3C24XX_DMAREQSEL);
+               } else {
+                       int csel = cdata->chansel >> (phy->id *
+                                                       S3C24XX_CHANSEL_WIDTH);
+
+                       csel &= S3C24XX_CHANSEL_REQ_MASK;
+                       dcon |= csel << S3C24XX_DCON_HWSRC_SHIFT;
+                       dcon |= S3C24XX_DCON_HWTRIG;
+               }
+       } else {
+               if (s3cdma->sdata->has_reqsel)
+                       writel_relaxed(0, phy->base + S3C24XX_DMAREQSEL);
+       }
+
+       writel_relaxed(dsg->src_addr, phy->base + S3C24XX_DISRC);
+       writel_relaxed(txd->disrcc, phy->base + S3C24XX_DISRCC);
+       writel_relaxed(dsg->dst_addr, phy->base + S3C24XX_DIDST);
+       writel_relaxed(txd->didstc, phy->base + S3C24XX_DIDSTC);
+       writel_relaxed(dcon, phy->base + S3C24XX_DCON);
+
+       val = readl_relaxed(phy->base + S3C24XX_DMASKTRIG);
+       val &= ~S3C24XX_DMASKTRIG_STOP;
+       val |= S3C24XX_DMASKTRIG_ON;
+
+       /* trigger the dma operation for memcpy transfers */
+       if (!s3cchan->slave)
+               val |= S3C24XX_DMASKTRIG_SWTRIG;
+
+       writel(val, phy->base + S3C24XX_DMASKTRIG);
+}
+
+/*
+ * Set the initial DMA register values and start first sg.
+ */
+static void s3c24xx_dma_start_next_txd(struct s3c24xx_dma_chan *s3cchan)
+{
+       struct s3c24xx_dma_phy *phy = s3cchan->phy;
+       struct virt_dma_desc *vd = vchan_next_desc(&s3cchan->vc);
+       struct s3c24xx_txd *txd = to_s3c24xx_txd(&vd->tx);
+
+       list_del(&txd->vd.node);
+
+       s3cchan->at = txd;
+
+       /* Wait for channel inactive */
+       while (s3c24xx_dma_phy_busy(phy))
+               cpu_relax();
+
+       /* point to the first element of the sg list */
+       txd->at = txd->dsg_list.next;
+       s3c24xx_dma_start_next_sg(s3cchan, txd);
+}
+
+static void s3c24xx_dma_free_txd_list(struct s3c24xx_dma_engine *s3cdma,
+                               struct s3c24xx_dma_chan *s3cchan)
+{
+       LIST_HEAD(head);
+
+       vchan_get_all_descriptors(&s3cchan->vc, &head);
+       vchan_dma_desc_free_list(&s3cchan->vc, &head);
+}
+
+/*
+ * Try to allocate a physical channel.  When successful, assign it to
+ * this virtual channel, and initiate the next descriptor.  The
+ * virtual channel lock must be held at this point.
+ */
+static void s3c24xx_dma_phy_alloc_and_start(struct s3c24xx_dma_chan *s3cchan)
+{
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       struct s3c24xx_dma_phy *phy;
+
+       phy = s3c24xx_dma_get_phy(s3cchan);
+       if (!phy) {
+               dev_dbg(&s3cdma->pdev->dev, "no physical channel available for xfer on %s\n",
+                       s3cchan->name);
+               s3cchan->state = S3C24XX_DMA_CHAN_WAITING;
+               return;
+       }
+
+       dev_dbg(&s3cdma->pdev->dev, "allocated physical channel %d for xfer on %s\n",
+               phy->id, s3cchan->name);
+
+       s3cchan->phy = phy;
+       s3cchan->state = S3C24XX_DMA_CHAN_RUNNING;
+
+       s3c24xx_dma_start_next_txd(s3cchan);
+}
+
+static void s3c24xx_dma_phy_reassign_start(struct s3c24xx_dma_phy *phy,
+       struct s3c24xx_dma_chan *s3cchan)
+{
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+
+       dev_dbg(&s3cdma->pdev->dev, "reassigned physical channel %d for xfer on %s\n",
+               phy->id, s3cchan->name);
+
+       /*
+        * We do this without taking the lock; we're really only concerned
+        * about whether this pointer is NULL or not, and we're guaranteed
+        * that this will only be called when it _already_ is non-NULL.
+        */
+       phy->serving = s3cchan;
+       s3cchan->phy = phy;
+       s3cchan->state = S3C24XX_DMA_CHAN_RUNNING;
+       s3c24xx_dma_start_next_txd(s3cchan);
+}
+
+/*
+ * Free a physical DMA channel, potentially reallocating it to another
+ * virtual channel if we have any pending.
+ */
+static void s3c24xx_dma_phy_free(struct s3c24xx_dma_chan *s3cchan)
+{
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       struct s3c24xx_dma_chan *p, *next;
+
+retry:
+       next = NULL;
+
+       /* Find a waiting virtual channel for the next transfer. */
+       list_for_each_entry(p, &s3cdma->memcpy.channels, vc.chan.device_node)
+               if (p->state == S3C24XX_DMA_CHAN_WAITING) {
+                       next = p;
+                       break;
+               }
+
+       if (!next) {
+               list_for_each_entry(p, &s3cdma->slave.channels,
+                                   vc.chan.device_node)
+                       if (p->state == S3C24XX_DMA_CHAN_WAITING &&
+                                     s3c24xx_dma_phy_valid(p, s3cchan->phy)) {
+                               next = p;
+                               break;
+                       }
+       }
+
+       /* Ensure that the physical channel is stopped */
+       s3c24xx_dma_terminate_phy(s3cchan->phy);
+
+       if (next) {
+               bool success;
+
+               /*
+                * Eww.  We know this isn't going to deadlock
+                * but lockdep probably doesn't.
+                */
+               spin_lock(&next->vc.lock);
+               /* Re-check the state now that we have the lock */
+               success = next->state == S3C24XX_DMA_CHAN_WAITING;
+               if (success)
+                       s3c24xx_dma_phy_reassign_start(s3cchan->phy, next);
+               spin_unlock(&next->vc.lock);
+
+               /* If the state changed, try to find another channel */
+               if (!success)
+                       goto retry;
+       } else {
+               /* No more jobs, so free up the physical channel */
+               s3c24xx_dma_put_phy(s3cchan->phy);
+       }
+
+       s3cchan->phy = NULL;
+       s3cchan->state = S3C24XX_DMA_CHAN_IDLE;
+}
+
+static void s3c24xx_dma_unmap_buffers(struct s3c24xx_txd *txd)
+{
+       struct device *dev = txd->vd.tx.chan->device->dev;
+       struct s3c24xx_sg *dsg;
+
+       if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+               if (txd->vd.tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+                       list_for_each_entry(dsg, &txd->dsg_list, node)
+                               dma_unmap_single(dev, dsg->src_addr, dsg->len,
+                                               DMA_TO_DEVICE);
+               else {
+                       list_for_each_entry(dsg, &txd->dsg_list, node)
+                               dma_unmap_page(dev, dsg->src_addr, dsg->len,
+                                               DMA_TO_DEVICE);
+               }
+       }
+
+       if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+               if (txd->vd.tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+                       list_for_each_entry(dsg, &txd->dsg_list, node)
+                               dma_unmap_single(dev, dsg->dst_addr, dsg->len,
+                                               DMA_FROM_DEVICE);
+               else
+                       list_for_each_entry(dsg, &txd->dsg_list, node)
+                               dma_unmap_page(dev, dsg->dst_addr, dsg->len,
+                                               DMA_FROM_DEVICE);
+       }
+}
+
+static void s3c24xx_dma_desc_free(struct virt_dma_desc *vd)
+{
+       struct s3c24xx_txd *txd = to_s3c24xx_txd(&vd->tx);
+       struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(vd->tx.chan);
+
+       if (!s3cchan->slave)
+               s3c24xx_dma_unmap_buffers(txd);
+
+       s3c24xx_dma_free_txd(txd);
+}
+
+static irqreturn_t s3c24xx_dma_irq(int irq, void *data)
+{
+       struct s3c24xx_dma_phy *phy = data;
+       struct s3c24xx_dma_chan *s3cchan = phy->serving;
+       struct s3c24xx_txd *txd;
+
+       dev_dbg(&phy->host->pdev->dev, "interrupt on channel %d\n", phy->id);
+
+       /*
+        * Interrupts happen to notify the completion of a transfer and the
+        * channel should have moved into its stop state already on its own.
+        * Therefore interrupts on channels not bound to a virtual channel
+        * should never happen. Nevertheless send a terminate command to the
+        * channel if the unlikely case happens.
+        */
+       if (unlikely(!s3cchan)) {
+               dev_err(&phy->host->pdev->dev, "interrupt on unused channel %d\n",
+                       phy->id);
+
+               s3c24xx_dma_terminate_phy(phy);
+
+               return IRQ_HANDLED;
+       }
+
+       spin_lock(&s3cchan->vc.lock);
+       txd = s3cchan->at;
+       if (txd) {
+               /* when more sg's are in this txd, start the next one */
+               if (!list_is_last(txd->at, &txd->dsg_list)) {
+                       txd->at = txd->at->next;
+                       s3c24xx_dma_start_next_sg(s3cchan, txd);
+               } else {
+                       s3cchan->at = NULL;
+                       vchan_cookie_complete(&txd->vd);
+
+                       /*
+                        * And start the next descriptor (if any),
+                        * otherwise free this channel.
+                        */
+                       if (vchan_next_desc(&s3cchan->vc))
+                               s3c24xx_dma_start_next_txd(s3cchan);
+                       else
+                               s3c24xx_dma_phy_free(s3cchan);
+               }
+       }
+       spin_unlock(&s3cchan->vc.lock);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * The DMA ENGINE API
+ */
+
+static int s3c24xx_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+                        unsigned long arg)
+{
+       struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&s3cchan->vc.lock, flags);
+
+       switch (cmd) {
+       case DMA_SLAVE_CONFIG:
+               ret = s3c24xx_dma_set_runtime_config(s3cchan,
+                                             (struct dma_slave_config *)arg);
+               break;
+       case DMA_TERMINATE_ALL:
+               if (!s3cchan->phy && !s3cchan->at) {
+                       dev_err(&s3cdma->pdev->dev, "trying to terminate already stopped channel %d\n",
+                               s3cchan->id);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               s3cchan->state = S3C24XX_DMA_CHAN_IDLE;
+
+                /* Mark physical channel as free */
+               if (s3cchan->phy)
+                       s3c24xx_dma_phy_free(s3cchan);
+
+               /* Dequeue current job */
+               if (s3cchan->at) {
+                       s3c24xx_dma_desc_free(&s3cchan->at->vd);
+                       s3cchan->at = NULL;
+               }
+
+               /* Dequeue jobs not yet fired as well */
+               s3c24xx_dma_free_txd_list(s3cdma, s3cchan);
+               break;
+       default:
+               /* Unknown command */
+               ret = -ENXIO;
+               break;
+       }
+
+       spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
+
+       return ret;
+}
+
+static int s3c24xx_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+       return 0;
+}
+
+static void s3c24xx_dma_free_chan_resources(struct dma_chan *chan)
+{
+       /* Ensure all queued descriptors are freed */
+       vchan_free_chan_resources(to_virt_chan(chan));
+}
+
+static enum dma_status s3c24xx_dma_tx_status(struct dma_chan *chan,
+               dma_cookie_t cookie, struct dma_tx_state *txstate)
+{
+       struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
+       struct s3c24xx_txd *txd;
+       struct s3c24xx_sg *dsg;
+       struct virt_dma_desc *vd;
+       unsigned long flags;
+       enum dma_status ret;
+       size_t bytes = 0;
+
+       spin_lock_irqsave(&s3cchan->vc.lock, flags);
+       ret = dma_cookie_status(chan, cookie, txstate);
+       if (ret == DMA_SUCCESS) {
+               spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
+               return ret;
+       }
+
+       /*
+        * There's no point calculating the residue if there's
+        * no txstate to store the value.
+        */
+       if (!txstate) {
+               spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
+               return ret;
+       }
+
+       vd = vchan_find_desc(&s3cchan->vc, cookie);
+       if (vd) {
+               /* On the issued list, so hasn't been processed yet */
+               txd = to_s3c24xx_txd(&vd->tx);
+
+               list_for_each_entry(dsg, &txd->dsg_list, node)
+                       bytes += dsg->len;
+       } else {
+               /*
+                * Currently running, so sum over the pending sg's and
+                * the currently active one.
+                */
+               txd = s3cchan->at;
+
+               dsg = list_entry(txd->at, struct s3c24xx_sg, node);
+               list_for_each_entry_from(dsg, &txd->dsg_list, node)
+                       bytes += dsg->len;
+
+               bytes += s3c24xx_dma_getbytes_chan(s3cchan);
+       }
+       spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
+
+       /*
+        * This cookie not complete yet
+        * Get number of bytes left in the active transactions and queue
+        */
+       dma_set_residue(txstate, bytes);
+
+       /* Whether waiting or running, we're in progress */
+       return ret;
+}
+
+/*
+ * Initialize a descriptor to be used by memcpy submit
+ */
+static struct dma_async_tx_descriptor *s3c24xx_dma_prep_memcpy(
+               struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+               size_t len, unsigned long flags)
+{
+       struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       struct s3c24xx_txd *txd;
+       struct s3c24xx_sg *dsg;
+       int src_mod, dest_mod;
+
+       dev_dbg(&s3cdma->pdev->dev, "prepare memcpy of %d bytes from %s\n",
+                       len, s3cchan->name);
+
+       if ((len & S3C24XX_DCON_TC_MASK) != len) {
+               dev_err(&s3cdma->pdev->dev, "memcpy size %d to large\n", len);
+               return NULL;
+       }
+
+       txd = s3c24xx_dma_get_txd();
+       if (!txd)
+               return NULL;
+
+       dsg = kzalloc(sizeof(*dsg), GFP_NOWAIT);
+       if (!dsg) {
+               s3c24xx_dma_free_txd(txd);
+               return NULL;
+       }
+       list_add_tail(&dsg->node, &txd->dsg_list);
+
+       dsg->src_addr = src;
+       dsg->dst_addr = dest;
+       dsg->len = len;
+
+       /*
+        * Determine a suitable transfer width.
+        * The DMA controller cannot fetch/store information which is not
+        * naturally aligned on the bus, i.e., a 4 byte fetch must start at
+        * an address divisible by 4 - more generally addr % width must be 0.
+        */
+       src_mod = src % 4;
+       dest_mod = dest % 4;
+       switch (len % 4) {
+       case 0:
+               txd->width = (src_mod == 0 && dest_mod == 0) ? 4 : 1;
+               break;
+       case 2:
+               txd->width = ((src_mod == 2 || src_mod == 0) &&
+                             (dest_mod == 2 || dest_mod == 0)) ? 2 : 1;
+               break;
+       default:
+               txd->width = 1;
+               break;
+       }
+
+       txd->disrcc = S3C24XX_DISRCC_LOC_AHB | S3C24XX_DISRCC_INC_INCREMENT;
+       txd->didstc = S3C24XX_DIDSTC_LOC_AHB | S3C24XX_DIDSTC_INC_INCREMENT;
+       txd->dcon |= S3C24XX_DCON_DEMAND | S3C24XX_DCON_SYNC_HCLK |
+                    S3C24XX_DCON_SERV_WHOLE;
+
+       return vchan_tx_prep(&s3cchan->vc, &txd->vd, flags);
+}
+
+static struct dma_async_tx_descriptor *s3c24xx_dma_prep_slave_sg(
+               struct dma_chan *chan, struct scatterlist *sgl,
+               unsigned int sg_len, enum dma_transfer_direction direction,
+               unsigned long flags, void *context)
+{
+       struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
+       struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
+       const struct s3c24xx_dma_platdata *pdata = s3cdma->pdata;
+       struct s3c24xx_dma_channel *cdata = &pdata->channels[s3cchan->id];
+       struct s3c24xx_txd *txd;
+       struct s3c24xx_sg *dsg;
+       struct scatterlist *sg;
+       dma_addr_t slave_addr;
+       u32 hwcfg = 0;
+       int tmp;
+
+       dev_dbg(&s3cdma->pdev->dev, "prepare transaction of %d bytes from %s\n",
+                       sg_dma_len(sgl), s3cchan->name);
+
+       txd = s3c24xx_dma_get_txd();
+       if (!txd)
+               return NULL;
+
+       if (cdata->handshake)
+               txd->dcon |= S3C24XX_DCON_HANDSHAKE;
+
+       switch (cdata->bus) {
+       case S3C24XX_DMA_APB:
+               txd->dcon |= S3C24XX_DCON_SYNC_PCLK;
+               hwcfg |= S3C24XX_DISRCC_LOC_APB;
+               break;
+       case S3C24XX_DMA_AHB:
+               txd->dcon |= S3C24XX_DCON_SYNC_HCLK;
+               hwcfg |= S3C24XX_DISRCC_LOC_AHB;
+               break;
+       }
+
+       /*
+        * Always assume our peripheral desintation is a fixed
+        * address in memory.
+        */
+       hwcfg |= S3C24XX_DISRCC_INC_FIXED;
+
+       /*
+        * Individual dma operations are requested by the slave,
+        * so serve only single atomic operations (S3C24XX_DCON_SERV_SINGLE).
+        */
+       txd->dcon |= S3C24XX_DCON_SERV_SINGLE;
+
+       if (direction == DMA_MEM_TO_DEV) {
+               txd->disrcc = S3C24XX_DISRCC_LOC_AHB |
+                             S3C24XX_DISRCC_INC_INCREMENT;
+               txd->didstc = hwcfg;
+               slave_addr = s3cchan->cfg.dst_addr;
+               txd->width = s3cchan->cfg.dst_addr_width;
+       } else if (direction == DMA_DEV_TO_MEM) {
+               txd->disrcc = hwcfg;
+               txd->didstc = S3C24XX_DIDSTC_LOC_AHB |
+                             S3C24XX_DIDSTC_INC_INCREMENT;
+               slave_addr = s3cchan->cfg.src_addr;
+               txd->width = s3cchan->cfg.src_addr_width;
+       } else {
+               s3c24xx_dma_free_txd(txd);
+               dev_err(&s3cdma->pdev->dev,
+                       "direction %d unsupported\n", direction);
+               return NULL;
+       }
+
+       for_each_sg(sgl, sg, sg_len, tmp) {
+               dsg = kzalloc(sizeof(*dsg), GFP_NOWAIT);
+               if (!dsg) {
+                       s3c24xx_dma_free_txd(txd);
+                       return NULL;
+               }
+               list_add_tail(&dsg->node, &txd->dsg_list);
+
+               dsg->len = sg_dma_len(sg);
+               if (direction == DMA_MEM_TO_DEV) {
+                       dsg->src_addr = sg_dma_address(sg);
+                       dsg->dst_addr = slave_addr;
+               } else { /* DMA_DEV_TO_MEM */
+                       dsg->src_addr = slave_addr;
+                       dsg->dst_addr = sg_dma_address(sg);
+               }
+               break;
+       }
+
+       return vchan_tx_prep(&s3cchan->vc, &txd->vd, flags);
+}
+
+/*
+ * Slave transactions callback to the slave device to allow
+ * synchronization of slave DMA signals with the DMAC enable
+ */
+static void s3c24xx_dma_issue_pending(struct dma_chan *chan)
+{
+       struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
+       unsigned long flags;
+
+       spin_lock_irqsave(&s3cchan->vc.lock, flags);
+       if (vchan_issue_pending(&s3cchan->vc)) {
+               if (!s3cchan->phy && s3cchan->state != S3C24XX_DMA_CHAN_WAITING)
+                       s3c24xx_dma_phy_alloc_and_start(s3cchan);
+       }
+       spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
+}
+
+/*
+ * Bringup and teardown
+ */
+
+/*
+ * Initialise the DMAC memcpy/slave channels.
+ * Make a local wrapper to hold required data
+ */
+static int s3c24xx_dma_init_virtual_channels(struct s3c24xx_dma_engine *s3cdma,
+               struct dma_device *dmadev, unsigned int channels, bool slave)
+{
+       struct s3c24xx_dma_chan *chan;
+       int i;
+
+       INIT_LIST_HEAD(&dmadev->channels);
+
+       /*
+        * Register as many many memcpy as we have physical channels,
+        * we won't always be able to use all but the code will have
+        * to cope with that situation.
+        */
+       for (i = 0; i < channels; i++) {
+               chan = devm_kzalloc(dmadev->dev, sizeof(*chan), GFP_KERNEL);
+               if (!chan) {
+                       dev_err(dmadev->dev,
+                               "%s no memory for channel\n", __func__);
+                       return -ENOMEM;
+               }
+
+               chan->id = i;
+               chan->host = s3cdma;
+               chan->state = S3C24XX_DMA_CHAN_IDLE;
+
+               if (slave) {
+                       chan->slave = true;
+                       chan->name = kasprintf(GFP_KERNEL, "slave%d", i);
+                       if (!chan->name)
+                               return -ENOMEM;
+               } else {
+                       chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i);
+                       if (!chan->name)
+                               return -ENOMEM;
+               }
+               dev_dbg(dmadev->dev,
+                        "initialize virtual channel \"%s\"\n",
+                        chan->name);
+
+               chan->vc.desc_free = s3c24xx_dma_desc_free;
+               vchan_init(&chan->vc, dmadev);
+       }
+       dev_info(dmadev->dev, "initialized %d virtual %s channels\n",
+                i, slave ? "slave" : "memcpy");
+       return i;
+}
+
+static void s3c24xx_dma_free_virtual_channels(struct dma_device *dmadev)
+{
+       struct s3c24xx_dma_chan *chan = NULL;
+       struct s3c24xx_dma_chan *next;
+
+       list_for_each_entry_safe(chan,
+                                next, &dmadev->channels, vc.chan.device_node)
+               list_del(&chan->vc.chan.device_node);
+}
+
+/* s3c2410, s3c2440 and s3c2442 have a 0x40 stride without separate clocks */
+static struct soc_data soc_s3c2410 = {
+       .stride = 0x40,
+       .has_reqsel = false,
+       .has_clocks = false,
+};
+
+/* s3c2412 and s3c2413 have a 0x40 stride and dmareqsel mechanism */
+static struct soc_data soc_s3c2412 = {
+       .stride = 0x40,
+       .has_reqsel = true,
+       .has_clocks = true,
+};
+
+/* s3c2443 and following have a 0x100 stride and dmareqsel mechanism */
+static struct soc_data soc_s3c2443 = {
+       .stride = 0x100,
+       .has_reqsel = true,
+       .has_clocks = true,
+};
+
+static struct platform_device_id s3c24xx_dma_driver_ids[] = {
+       {
+               .name           = "s3c2410-dma",
+               .driver_data    = (kernel_ulong_t)&soc_s3c2410,
+       }, {
+               .name           = "s3c2412-dma",
+               .driver_data    = (kernel_ulong_t)&soc_s3c2412,
+       }, {
+               .name           = "s3c2443-dma",
+               .driver_data    = (kernel_ulong_t)&soc_s3c2443,
+       },
+       { },
+};
+
+static struct soc_data *s3c24xx_dma_get_soc_data(struct platform_device *pdev)
+{
+       return (struct soc_data *)
+                        platform_get_device_id(pdev)->driver_data;
+}
+
+static int s3c24xx_dma_probe(struct platform_device *pdev)
+{
+       const struct s3c24xx_dma_platdata *pdata = dev_get_platdata(&pdev->dev);
+       struct s3c24xx_dma_engine *s3cdma;
+       struct soc_data *sdata;
+       struct resource *res;
+       int ret;
+       int i;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data missing\n");
+               return -ENODEV;
+       }
+
+       /* Basic sanity check */
+       if (pdata->num_phy_channels > MAX_DMA_CHANNELS) {
+               dev_err(&pdev->dev, "to many dma channels %d, max %d\n",
+                       pdata->num_phy_channels, MAX_DMA_CHANNELS);
+               return -EINVAL;
+       }
+
+       sdata = s3c24xx_dma_get_soc_data(pdev);
+       if (!sdata)
+               return -EINVAL;
+
+       s3cdma = devm_kzalloc(&pdev->dev, sizeof(*s3cdma), GFP_KERNEL);
+       if (!s3cdma)
+               return -ENOMEM;
+
+       s3cdma->pdev = pdev;
+       s3cdma->pdata = pdata;
+       s3cdma->sdata = sdata;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       s3cdma->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(s3cdma->base))
+               return PTR_ERR(s3cdma->base);
+
+       s3cdma->phy_chans = devm_kzalloc(&pdev->dev,
+                                             sizeof(struct s3c24xx_dma_phy) *
+                                                       pdata->num_phy_channels,
+                                             GFP_KERNEL);
+       if (!s3cdma->phy_chans)
+               return -ENOMEM;
+
+       /* aquire irqs and clocks for all physical channels */
+       for (i = 0; i < pdata->num_phy_channels; i++) {
+               struct s3c24xx_dma_phy *phy = &s3cdma->phy_chans[i];
+               char clk_name[6];
+
+               phy->id = i;
+               phy->base = s3cdma->base + (i * sdata->stride);
+               phy->host = s3cdma;
+
+               phy->irq = platform_get_irq(pdev, i);
+               if (phy->irq < 0) {
+                       dev_err(&pdev->dev, "failed to get irq %d, err %d\n",
+                               i, phy->irq);
+                       continue;
+               }
+
+               ret = devm_request_irq(&pdev->dev, phy->irq, s3c24xx_dma_irq,
+                                      0, pdev->name, phy);
+               if (ret) {
+                       dev_err(&pdev->dev, "Unable to request irq for channel %d, error %d\n",
+                               i, ret);
+                       continue;
+               }
+
+               if (sdata->has_clocks) {
+                       sprintf(clk_name, "dma.%d", i);
+                       phy->clk = devm_clk_get(&pdev->dev, clk_name);
+                       if (IS_ERR(phy->clk) && sdata->has_clocks) {
+                               dev_err(&pdev->dev, "unable to aquire clock for channel %d, error %lu",
+                                       i, PTR_ERR(phy->clk));
+                               continue;
+                       }
+
+                       ret = clk_prepare(phy->clk);
+                       if (ret) {
+                               dev_err(&pdev->dev, "clock for phy %d failed, error %d\n",
+                                       i, ret);
+                               continue;
+                       }
+               }
+
+               spin_lock_init(&phy->lock);
+               phy->valid = true;
+
+               dev_dbg(&pdev->dev, "physical channel %d is %s\n",
+                       i, s3c24xx_dma_phy_busy(phy) ? "BUSY" : "FREE");
+       }
+
+       /* Initialize memcpy engine */
+       dma_cap_set(DMA_MEMCPY, s3cdma->memcpy.cap_mask);
+       dma_cap_set(DMA_PRIVATE, s3cdma->memcpy.cap_mask);
+       s3cdma->memcpy.dev = &pdev->dev;
+       s3cdma->memcpy.device_alloc_chan_resources =
+                                       s3c24xx_dma_alloc_chan_resources;
+       s3cdma->memcpy.device_free_chan_resources =
+                                       s3c24xx_dma_free_chan_resources;
+       s3cdma->memcpy.device_prep_dma_memcpy = s3c24xx_dma_prep_memcpy;
+       s3cdma->memcpy.device_tx_status = s3c24xx_dma_tx_status;
+       s3cdma->memcpy.device_issue_pending = s3c24xx_dma_issue_pending;
+       s3cdma->memcpy.device_control = s3c24xx_dma_control;
+
+       /* Initialize slave engine for SoC internal dedicated peripherals */
+       dma_cap_set(DMA_SLAVE, s3cdma->slave.cap_mask);
+       dma_cap_set(DMA_PRIVATE, s3cdma->slave.cap_mask);
+       s3cdma->slave.dev = &pdev->dev;
+       s3cdma->slave.device_alloc_chan_resources =
+                                       s3c24xx_dma_alloc_chan_resources;
+       s3cdma->slave.device_free_chan_resources =
+                                       s3c24xx_dma_free_chan_resources;
+       s3cdma->slave.device_tx_status = s3c24xx_dma_tx_status;
+       s3cdma->slave.device_issue_pending = s3c24xx_dma_issue_pending;
+       s3cdma->slave.device_prep_slave_sg = s3c24xx_dma_prep_slave_sg;
+       s3cdma->slave.device_control = s3c24xx_dma_control;
+
+       /* Register as many memcpy channels as there are physical channels */
+       ret = s3c24xx_dma_init_virtual_channels(s3cdma, &s3cdma->memcpy,
+                                               pdata->num_phy_channels, false);
+       if (ret <= 0) {
+               dev_warn(&pdev->dev,
+                        "%s failed to enumerate memcpy channels - %d\n",
+                        __func__, ret);
+               goto err_memcpy;
+       }
+
+       /* Register slave channels */
+       ret = s3c24xx_dma_init_virtual_channels(s3cdma, &s3cdma->slave,
+                               pdata->num_channels, true);
+       if (ret <= 0) {
+               dev_warn(&pdev->dev,
+                       "%s failed to enumerate slave channels - %d\n",
+                               __func__, ret);
+               goto err_slave;
+       }
+
+       ret = dma_async_device_register(&s3cdma->memcpy);
+       if (ret) {
+               dev_warn(&pdev->dev,
+                       "%s failed to register memcpy as an async device - %d\n",
+                       __func__, ret);
+               goto err_memcpy_reg;
+       }
+
+       ret = dma_async_device_register(&s3cdma->slave);
+       if (ret) {
+               dev_warn(&pdev->dev,
+                       "%s failed to register slave as an async device - %d\n",
+                       __func__, ret);
+               goto err_slave_reg;
+       }
+
+       platform_set_drvdata(pdev, s3cdma);
+       dev_info(&pdev->dev, "Loaded dma driver with %d physical channels\n",
+                pdata->num_phy_channels);
+
+       return 0;
+
+err_slave_reg:
+       dma_async_device_unregister(&s3cdma->memcpy);
+err_memcpy_reg:
+       s3c24xx_dma_free_virtual_channels(&s3cdma->slave);
+err_slave:
+       s3c24xx_dma_free_virtual_channels(&s3cdma->memcpy);
+err_memcpy:
+       if (sdata->has_clocks)
+               for (i = 0; i < pdata->num_phy_channels; i++) {
+                       struct s3c24xx_dma_phy *phy = &s3cdma->phy_chans[i];
+                       if (phy->valid)
+                               clk_unprepare(phy->clk);
+               }
+
+       return ret;
+}
+
+static int s3c24xx_dma_remove(struct platform_device *pdev)
+{
+       const struct s3c24xx_dma_platdata *pdata = dev_get_platdata(&pdev->dev);
+       struct s3c24xx_dma_engine *s3cdma = platform_get_drvdata(pdev);
+       struct soc_data *sdata = s3c24xx_dma_get_soc_data(pdev);
+       int i;
+
+       dma_async_device_unregister(&s3cdma->slave);
+       dma_async_device_unregister(&s3cdma->memcpy);
+
+       s3c24xx_dma_free_virtual_channels(&s3cdma->slave);
+       s3c24xx_dma_free_virtual_channels(&s3cdma->memcpy);
+
+       if (sdata->has_clocks)
+               for (i = 0; i < pdata->num_phy_channels; i++) {
+                       struct s3c24xx_dma_phy *phy = &s3cdma->phy_chans[i];
+                       if (phy->valid)
+                               clk_unprepare(phy->clk);
+               }
+
+       return 0;
+}
+
+static struct platform_driver s3c24xx_dma_driver = {
+       .driver         = {
+               .name   = "s3c24xx-dma",
+               .owner  = THIS_MODULE,
+       },
+       .id_table       = s3c24xx_dma_driver_ids,
+       .probe          = s3c24xx_dma_probe,
+       .remove         = s3c24xx_dma_remove,
+};
+
+module_platform_driver(s3c24xx_dma_driver);
+
+bool s3c24xx_dma_filter(struct dma_chan *chan, void *param)
+{
+       struct s3c24xx_dma_chan *s3cchan;
+
+       if (chan->device->dev->driver != &s3c24xx_dma_driver.driver)
+               return false;
+
+       s3cchan = to_s3c24xx_dma_chan(chan);
+
+       return s3cchan->id == (int)param;
+}
+EXPORT_SYMBOL(s3c24xx_dma_filter);
+
+MODULE_DESCRIPTION("S3C24XX DMA Driver");
+MODULE_AUTHOR("Heiko Stuebner");
+MODULE_LICENSE("GPL v2");
index 5985807e52c9439fc1f7587aa2c0645f5e344c57..e23f1c2e505366dd24cb2ff6037f31074f7331ff 100644 (file)
 
 /**
  * struct adc_jack_data - internal data for adc_jack device driver
- * @edev        - extcon device.
- * @cable_names - list of supported cables.
- * @num_cables  - size of cable_names.
- * @adc_conditions       - list of adc value conditions.
- * @num_conditions       - size of adc_conditions.
- * @irq         - irq number of attach/detach event (0 if not exist).
- * @handling_delay      - interrupt handler will schedule extcon event
- *                      handling at handling_delay jiffies.
- * @handler     - extcon event handler called by interrupt handler.
- * @chan       - iio channel being queried.
+ * @edev:              extcon device.
+ * @cable_names:       list of supported cables.
+ * @num_cables:                size of cable_names.
+ * @adc_conditions:    list of adc value conditions.
+ * @num_conditions:    size of adc_conditions.
+ * @irq:               irq number of attach/detach event (0 if not exist).
+ * @handling_delay:    interrupt handler will schedule extcon event
+ *                     handling at handling_delay jiffies.
+ * @handler:           extcon event handler called by interrupt handler.
+ * @chan:              iio channel being queried.
  */
 struct adc_jack_data {
        struct extcon_dev edev;
@@ -64,7 +64,7 @@ static void adc_jack_handler(struct work_struct *work)
 
        ret = iio_read_channel_raw(data->chan, &adc_val);
        if (ret < 0) {
-               dev_err(data->edev.dev, "read channel() error: %d\n", ret);
+               dev_err(&data->edev.dev, "read channel() error: %d\n", ret);
                return;
        }
 
@@ -95,7 +95,7 @@ static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
 static int adc_jack_probe(struct platform_device *pdev)
 {
        struct adc_jack_data *data;
-       struct adc_jack_pdata *pdata = pdev->dev.platform_data;
+       struct adc_jack_pdata *pdata = dev_get_platdata(&pdev->dev);
        int i, err = 0;
 
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
@@ -110,6 +110,7 @@ static int adc_jack_probe(struct platform_device *pdev)
                goto out;
        }
 
+       data->edev.dev.parent = &pdev->dev;
        data->edev.supported_cable = pdata->cable_names;
 
        /* Check the length of array and set num_cables */
@@ -148,7 +149,7 @@ static int adc_jack_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, data);
 
-       err = extcon_dev_register(&data->edev, &pdev->dev);
+       err = extcon_dev_register(&data->edev);
        if (err)
                goto out;
 
index e55713083c7887abe7baa60d24396126446bbf30..3c55ec856e39c714e7b474f081c01180b9aa9e2d 100644 (file)
@@ -86,8 +86,8 @@ struct arizona_extcon_info {
 };
 
 static const struct arizona_micd_config micd_default_modes[] = {
-       { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
-       { 0,                  2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
+       { ARIZONA_ACCDET_SRC, 1, 0 },
+       { 0,                  2, 1 },
 };
 
 static const struct arizona_micd_range micd_default_ranges[] = {
@@ -182,7 +182,8 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
                                        info->micd_modes[mode].gpio);
        regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
                           ARIZONA_MICD_BIAS_SRC_MASK,
-                          info->micd_modes[mode].bias);
+                          info->micd_modes[mode].bias <<
+                          ARIZONA_MICD_BIAS_SRC_SHIFT);
        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
                           ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
 
@@ -193,7 +194,7 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
 
 static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
 {
-       switch (info->micd_modes[0].bias >> ARIZONA_MICD_BIAS_SRC_SHIFT) {
+       switch (info->micd_modes[0].bias) {
        case 1:
                return "MICBIAS1";
        case 2:
@@ -388,7 +389,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
                           >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
 
                if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
-                   (val < 100 || val > 0x3fb)) {
+                   (val < 100 || val >= 0x3fb)) {
                        range++;
                        dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
                                range);
@@ -401,7 +402,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
                }
 
                /* If we go out of range report top of range */
-               if (val < 100 || val > 0x3fb) {
+               if (val < 100 || val >= 0x3fb) {
                        dev_dbg(arizona->dev, "Measurement out of range\n");
                        return ARIZONA_HPDET_MAX;
                }
@@ -514,7 +515,7 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
                }
 
                /*
-                * If we measure the mic as 
+                * If we measure the mic as high impedance
                 */
                if (!id_gpio || info->hpdet_res[1] > 50) {
                        dev_dbg(arizona->dev, "Detected mic\n");
@@ -564,11 +565,10 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
        }
 
        ret = arizona_hpdet_read(info);
-       if (ret == -EAGAIN) {
+       if (ret == -EAGAIN)
                goto out;
-       } else if (ret < 0) {
+       else if (ret < 0)
                goto done;
-       }
        reading = ret;
 
        /* Reset back to starting range */
@@ -578,11 +578,10 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
                           0);
 
        ret = arizona_hpdet_do_id(info, &reading, &mic);
-       if (ret == -EAGAIN) {
+       if (ret == -EAGAIN)
                goto out;
-       } else if (ret < 0) {
+       else if (ret < 0)
                goto done;
-       }
 
        /* Report high impedence cables as line outputs */
        if (reading >= 5000)
@@ -738,8 +737,8 @@ err:
 static void arizona_micd_timeout_work(struct work_struct *work)
 {
        struct arizona_extcon_info *info = container_of(work,
-                                                       struct arizona_extcon_info,
-                                                       micd_timeout_work.work);
+                                               struct arizona_extcon_info,
+                                               micd_timeout_work.work);
 
        mutex_lock(&info->lock);
 
@@ -756,8 +755,8 @@ static void arizona_micd_timeout_work(struct work_struct *work)
 static void arizona_micd_detect(struct work_struct *work)
 {
        struct arizona_extcon_info *info = container_of(work,
-                                                       struct arizona_extcon_info,
-                                                       micd_detect_work.work);
+                                               struct arizona_extcon_info,
+                                               micd_detect_work.work);
        struct arizona *arizona = info->arizona;
        unsigned int val = 0, lvl;
        int ret, i, key;
@@ -769,7 +768,8 @@ static void arizona_micd_detect(struct work_struct *work)
        for (i = 0; i < 10 && !(val & 0x7fc); i++) {
                ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
                if (ret != 0) {
-                       dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
+                       dev_err(arizona->dev,
+                               "Failed to read MICDET: %d\n", ret);
                        mutex_unlock(&info->lock);
                        return;
                }
@@ -777,7 +777,8 @@ static void arizona_micd_detect(struct work_struct *work)
                dev_dbg(arizona->dev, "MICDET: %x\n", val);
 
                if (!(val & ARIZONA_MICD_VALID)) {
-                       dev_warn(arizona->dev, "Microphone detection state invalid\n");
+                       dev_warn(arizona->dev,
+                                "Microphone detection state invalid\n");
                        mutex_unlock(&info->lock);
                        return;
                }
@@ -925,8 +926,8 @@ static irqreturn_t arizona_micdet(int irq, void *data)
 static void arizona_hpdet_work(struct work_struct *work)
 {
        struct arizona_extcon_info *info = container_of(work,
-                                                       struct arizona_extcon_info,
-                                                       hpdet_work.work);
+                                               struct arizona_extcon_info,
+                                               hpdet_work.work);
 
        mutex_lock(&info->lock);
        arizona_start_hpdet_acc_id(info);
@@ -973,10 +974,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
                                           &info->hpdet_work,
                                           msecs_to_jiffies(HPDET_DEBOUNCE));
 
-               if (cancelled_mic)
+               if (cancelled_mic) {
+                       int micd_timeout = info->micd_timeout;
+
                        queue_delayed_work(system_power_efficient_wq,
                                           &info->micd_timeout_work,
-                                          msecs_to_jiffies(info->micd_timeout));
+                                          msecs_to_jiffies(micd_timeout));
+               }
 
                goto out;
        }
@@ -1039,6 +1043,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
        else
                info->micd_timeout = DEFAULT_MICD_TIMEOUT;
 
+out:
        /* Clear trig_sts to make sure DCVDD is not forced up */
        regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
                     ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
@@ -1046,7 +1051,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
                     ARIZONA_JD1_FALL_TRIG_STS |
                     ARIZONA_JD1_RISE_TRIG_STS);
 
-out:
        mutex_unlock(&info->lock);
 
        pm_runtime_mark_last_busy(info->dev);
@@ -1129,9 +1133,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
        }
 
        info->edev.name = "Headset Jack";
+       info->edev.dev.parent = arizona->dev;
        info->edev.supported_cable = arizona_cable;
 
-       ret = extcon_dev_register(&info->edev, arizona->dev);
+       ret = extcon_dev_register(&info->edev);
        if (ret < 0) {
                dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
                        ret);
index 148382faded9f125940ee11ca211bcea38f36290..15443d3b6be18049ddddbb7ec035eb05ce7dc409 100644 (file)
@@ -74,7 +74,7 @@ static DEFINE_MUTEX(extcon_dev_list_lock);
 
 /**
  * check_mutually_exclusive - Check if new_state violates mutually_exclusive
- *                         condition.
+ *                           condition.
  * @edev:      the extcon device
  * @new_state: new cable attach status for @edev
  *
@@ -105,7 +105,7 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
 {
        int i, count = 0;
-       struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev);
+       struct extcon_dev *edev = dev_get_drvdata(dev);
 
        if (edev->print_state) {
                int ret = edev->print_state(edev, buf);
@@ -129,13 +129,12 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-int extcon_set_state(struct extcon_dev *edev, u32 state);
 static ssize_t state_store(struct device *dev, struct device_attribute *attr,
                           const char *buf, size_t count)
 {
        u32 state;
        ssize_t ret = 0;
-       struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev);
+       struct extcon_dev *edev = dev_get_drvdata(dev);
 
        ret = sscanf(buf, "0x%x", &state);
        if (ret == 0)
@@ -153,7 +152,7 @@ static DEVICE_ATTR_RW(state);
 static ssize_t name_show(struct device *dev, struct device_attribute *attr,
                char *buf)
 {
-       struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev);
+       struct extcon_dev *edev = dev_get_drvdata(dev);
 
        /* Optional callback given by the user */
        if (edev->print_name) {
@@ -162,7 +161,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr,
                        return ret;
        }
 
-       return sprintf(buf, "%s\n", dev_name(edev->dev));
+       return sprintf(buf, "%s\n", dev_name(&edev->dev));
 }
 static DEVICE_ATTR_RO(name);
 
@@ -189,7 +188,7 @@ static ssize_t cable_state_show(struct device *dev,
 
 /**
  * extcon_update_state() - Update the cable attach states of the extcon device
- *                     only for the masked bits.
+ *                        only for the masked bits.
  * @edev:      the extcon device
  * @mask:      the bit mask to designate updated bits.
  * @state:     new cable attach status for @edev
@@ -227,11 +226,10 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
                edev->state |= state & mask;
 
                raw_notifier_call_chain(&edev->nh, old_state, edev);
-
                /* This could be in interrupt handler */
                prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
                if (prop_buf) {
-                       length = name_show(edev->dev, NULL, prop_buf);
+                       length = name_show(&edev->dev, NULL, prop_buf);
                        if (length > 0) {
                                if (prop_buf[length - 1] == '\n')
                                        prop_buf[length - 1] = 0;
@@ -239,7 +237,7 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
                                        "NAME=%s", prop_buf);
                                envp[env_offset++] = name_buf;
                        }
-                       length = state_show(edev->dev, NULL, prop_buf);
+                       length = state_show(&edev->dev, NULL, prop_buf);
                        if (length > 0) {
                                if (prop_buf[length - 1] == '\n')
                                        prop_buf[length - 1] = 0;
@@ -251,14 +249,14 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
                        /* Unlock early before uevent */
                        spin_unlock_irqrestore(&edev->lock, flags);
 
-                       kobject_uevent_env(&edev->dev->kobj, KOBJ_CHANGE, envp);
+                       kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp);
                        free_page((unsigned long)prop_buf);
                } else {
                        /* Unlock early before uevent */
                        spin_unlock_irqrestore(&edev->lock, flags);
 
-                       dev_err(edev->dev, "out of memory in extcon_set_state\n");
-                       kobject_uevent(&edev->dev->kobj, KOBJ_CHANGE);
+                       dev_err(&edev->dev, "out of memory in extcon_set_state\n");
+                       kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE);
                }
        } else {
                /* No changes */
@@ -339,8 +337,9 @@ EXPORT_SYMBOL_GPL(extcon_get_cable_state);
 
 /**
  * extcon_set_cable_state_() - Set the status of a specific cable.
- * @edev:      the extcon device that has the cable.
- * @index:     cable index that can be retrieved by extcon_find_cable_index().
+ * @edev:              the extcon device that has the cable.
+ * @index:             cable index that can be retrieved by
+ *                     extcon_find_cable_index().
  * @cable_state:       the new cable status. The default semantics is
  *                     true: attached / false: detached.
  */
@@ -359,8 +358,8 @@ EXPORT_SYMBOL_GPL(extcon_set_cable_state_);
 
 /**
  * extcon_set_cable_state() - Set the status of a specific cable.
- * @edev:      the extcon device that has the cable.
- * @cable_name:        cable name.
+ * @edev:              the extcon device that has the cable.
+ * @cable_name:                cable name.
  * @cable_state:       the new cable status. The default semantics is
  *                     true: attached / false: detached.
  *
@@ -419,14 +418,14 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val,
 
 /**
  * extcon_register_interest() - Register a notifier for a state change of a
- *                           specific cable, not an entier set of cables of a
- *                           extcon device.
- * @obj:       an empty extcon_specific_cable_nb object to be returned.
+ *                             specific cable, not an entier set of cables of a
+ *                             extcon device.
+ * @obj:               an empty extcon_specific_cable_nb object to be returned.
  * @extcon_name:       the name of extcon device.
  *                     if NULL, extcon_register_interest will register
  *                     every cable with the target cable_name given.
  * @cable_name:                the target cable name.
- * @nb:                the notifier block to get notified.
+ * @nb:                        the notifier block to get notified.
  *
  * Provide an empty extcon_specific_cable_nb. extcon_register_interest() sets
  * the struct for you.
@@ -452,7 +451,8 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
                if (!obj->edev)
                        return -ENODEV;
 
-               obj->cable_index = extcon_find_cable_index(obj->edev, cable_name);
+               obj->cable_index = extcon_find_cable_index(obj->edev,
+                                                         cable_name);
                if (obj->cable_index < 0)
                        return obj->cable_index;
 
@@ -460,7 +460,8 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
 
                obj->internal_nb.notifier_call = _call_per_cable;
 
-               return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb);
+               return raw_notifier_chain_register(&obj->edev->nh,
+                                                 &obj->internal_nb);
        } else {
                struct class_dev_iter iter;
                struct extcon_dev *extd;
@@ -470,7 +471,7 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
                        return -ENODEV;
                class_dev_iter_init(&iter, extcon_class, NULL, NULL);
                while ((dev = class_dev_iter_next(&iter))) {
-                       extd = (struct extcon_dev *)dev_get_drvdata(dev);
+                       extd = dev_get_drvdata(dev);
 
                        if (extcon_find_cable_index(extd, cable_name) < 0)
                                continue;
@@ -487,7 +488,7 @@ EXPORT_SYMBOL_GPL(extcon_register_interest);
 
 /**
  * extcon_unregister_interest() - Unregister the notifier registered by
- *                             extcon_register_interest().
+ *                               extcon_register_interest().
  * @obj:       the extcon_specific_cable_nb object returned by
  *             extcon_register_interest().
  */
@@ -502,7 +503,7 @@ EXPORT_SYMBOL_GPL(extcon_unregister_interest);
 
 /**
  * extcon_register_notifier() - Register a notifiee to get notified by
- *                           any attach status changes from the extcon.
+ *                             any attach status changes from the extcon.
  * @edev:      the extcon device.
  * @nb:                a notifier block to be registered.
  *
@@ -556,7 +557,6 @@ static int create_extcon_class(void)
 
 static void extcon_dev_release(struct device *dev)
 {
-       kfree(dev);
 }
 
 static const char *muex_name = "mutually_exclusive";
@@ -567,14 +567,13 @@ static void dummy_sysfs_dev_release(struct device *dev)
 /**
  * extcon_dev_register() - Register a new extcon device
  * @edev       : the new extcon device (should be allocated before calling)
- * @dev                : the parent device for this extcon device.
  *
  * Among the members of edev struct, please set the "user initializing data"
  * in any case and set the "optional callbacks" if required. However, please
  * do not set the values of "internal data", which are initialized by
  * this function.
  */
-int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
+int extcon_dev_register(struct extcon_dev *edev)
 {
        int ret, index = 0;
 
@@ -594,19 +593,20 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
        }
 
        if (index > SUPPORTED_CABLE_MAX) {
-               dev_err(edev->dev, "extcon: maximum number of supported cables exceeded.\n");
+               dev_err(&edev->dev, "extcon: maximum number of supported cables exceeded.\n");
                return -EINVAL;
        }
 
-       edev->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
-       if (!edev->dev)
-               return -ENOMEM;
-       edev->dev->parent = dev;
-       edev->dev->class = extcon_class;
-       edev->dev->release = extcon_dev_release;
+       edev->dev.class = extcon_class;
+       edev->dev.release = extcon_dev_release;
 
-       edev->name = edev->name ? edev->name : dev_name(dev);
-       dev_set_name(edev->dev, "%s", edev->name);
+       edev->name = edev->name ? edev->name : dev_name(edev->dev.parent);
+       if (IS_ERR_OR_NULL(edev->name)) {
+               dev_err(&edev->dev,
+                       "extcon device name is null\n");
+               return -EINVAL;
+       }
+       dev_set_name(&edev->dev, "%s", edev->name);
 
        if (edev->max_supported) {
                char buf[10];
@@ -714,7 +714,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
                        goto err_alloc_groups;
                }
 
-               edev->extcon_dev_type.name = dev_name(edev->dev);
+               edev->extcon_dev_type.name = dev_name(&edev->dev);
                edev->extcon_dev_type.release = dummy_sysfs_dev_release;
 
                for (index = 0; index < edev->max_supported; index++)
@@ -724,25 +724,24 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
                        edev->extcon_dev_type.groups[index] =
                                &edev->attr_g_muex;
 
-               edev->dev->type = &edev->extcon_dev_type;
+               edev->dev.type = &edev->extcon_dev_type;
        }
 
-       ret = device_register(edev->dev);
+       ret = device_register(&edev->dev);
        if (ret) {
-               put_device(edev->dev);
+               put_device(&edev->dev);
                goto err_dev;
        }
 #if defined(CONFIG_ANDROID)
        if (switch_class)
-               ret = class_compat_create_link(switch_class, edev->dev,
-                                              NULL);
+               ret = class_compat_create_link(switch_class, &edev->dev, NULL);
 #endif /* CONFIG_ANDROID */
 
        spin_lock_init(&edev->lock);
 
        RAW_INIT_NOTIFIER_HEAD(&edev->nh);
 
-       dev_set_drvdata(edev->dev, edev);
+       dev_set_drvdata(&edev->dev, edev);
        edev->state = 0;
 
        mutex_lock(&extcon_dev_list_lock);
@@ -768,7 +767,6 @@ err_alloc_cables:
        if (edev->max_supported)
                kfree(edev->cables);
 err_sysfs_alloc:
-       kfree(edev->dev);
        return ret;
 }
 EXPORT_SYMBOL_GPL(extcon_dev_register);
@@ -788,9 +786,9 @@ void extcon_dev_unregister(struct extcon_dev *edev)
        list_del(&edev->entry);
        mutex_unlock(&extcon_dev_list_lock);
 
-       if (IS_ERR_OR_NULL(get_device(edev->dev))) {
-               dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n",
-                               dev_name(edev->dev));
+       if (IS_ERR_OR_NULL(get_device(&edev->dev))) {
+               dev_err(&edev->dev, "Failed to unregister extcon_dev (%s)\n",
+                               dev_name(&edev->dev));
                return;
        }
 
@@ -812,10 +810,10 @@ void extcon_dev_unregister(struct extcon_dev *edev)
 
 #if defined(CONFIG_ANDROID)
        if (switch_class)
-               class_compat_remove_link(switch_class, edev->dev, NULL);
+               class_compat_remove_link(switch_class, &edev->dev, NULL);
 #endif
-       device_unregister(edev->dev);
-       put_device(edev->dev);
+       device_unregister(&edev->dev);
+       put_device(&edev->dev);
 }
 EXPORT_SYMBOL_GPL(extcon_dev_unregister);
 
index f874c30ddbff0a0bb51949d7aa2de90c67c7227b..7e0dff58e4943e8b1b09a44c4adba854898cda9d 100644 (file)
@@ -34,6 +34,7 @@
 struct gpio_extcon_data {
        struct extcon_dev edev;
        unsigned gpio;
+       bool gpio_active_low;
        const char *state_on;
        const char *state_off;
        int irq;
@@ -49,6 +50,8 @@ static void gpio_extcon_work(struct work_struct *work)
                             work);
 
        state = gpio_get_value(data->gpio);
+       if (data->gpio_active_low)
+               state = !state;
        extcon_set_state(&data->edev, state);
 }
 
@@ -78,9 +81,9 @@ static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf)
 
 static int gpio_extcon_probe(struct platform_device *pdev)
 {
-       struct gpio_extcon_platform_data *pdata = pdev->dev.platform_data;
+       struct gpio_extcon_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct gpio_extcon_data *extcon_data;
-       int ret = 0;
+       int ret;
 
        if (!pdata)
                return -EBUSY;
@@ -95,14 +98,22 @@ static int gpio_extcon_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        extcon_data->edev.name = pdata->name;
+       extcon_data->edev.dev.parent = &pdev->dev;
        extcon_data->gpio = pdata->gpio;
+       extcon_data->gpio_active_low = pdata->gpio_active_low;
        extcon_data->state_on = pdata->state_on;
        extcon_data->state_off = pdata->state_off;
        if (pdata->state_on && pdata->state_off)
                extcon_data->edev.print_state = extcon_gpio_print_state;
-       extcon_data->debounce_jiffies = msecs_to_jiffies(pdata->debounce);
+       if (pdata->debounce) {
+               ret = gpio_set_debounce(extcon_data->gpio,
+                                       pdata->debounce * 1000);
+               if (ret < 0)
+                       extcon_data->debounce_jiffies =
+                               msecs_to_jiffies(pdata->debounce);
+       }
 
-       ret = extcon_dev_register(&extcon_data->edev, &pdev->dev);
+       ret = extcon_dev_register(&extcon_data->edev);
        if (ret < 0)
                return ret;
 
index b56bdaa27d4ba15464c645184b2c18ee2df7e530..da268fbc901beae35c56c8da9930f0ddca5dc0dd 100644 (file)
@@ -189,14 +189,17 @@ enum max77693_muic_acc_type {
 
        /* The below accessories have same ADC value so ADCLow and
           ADC1K bit is used to separate specific accessory */
-       MAX77693_MUIC_GND_USB_OTG = 0x100,      /* ADC:0x0, VBVolot:0, ADCLow:0, ADC1K:0 */
-       MAX77693_MUIC_GND_USB_OTG_VB = 0x104,   /* ADC:0x0, VBVolot:1, ADCLow:0, ADC1K:0 */
-       MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* ADC:0x0, VBVolot:0, ADCLow:1, ADC1K:0 */
-       MAX77693_MUIC_GND_MHL = 0x103,          /* ADC:0x0, VBVolot:0, ADCLow:1, ADC1K:1 */
-       MAX77693_MUIC_GND_MHL_VB = 0x107,       /* ADC:0x0, VBVolot:1, ADCLow:1, ADC1K:1 */
+                                               /* ADC|VBVolot|ADCLow|ADC1K| */
+       MAX77693_MUIC_GND_USB_OTG = 0x100,      /* 0x0|      0|     0|    0| */
+       MAX77693_MUIC_GND_USB_OTG_VB = 0x104,   /* 0x0|      1|     0|    0| */
+       MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* 0x0|      0|     1|    0| */
+       MAX77693_MUIC_GND_MHL = 0x103,          /* 0x0|      0|     1|    1| */
+       MAX77693_MUIC_GND_MHL_VB = 0x107,       /* 0x0|      1|     1|    1| */
 };
 
-/* MAX77693 MUIC device support below list of accessories(external connector) */
+/*
+ * MAX77693 MUIC device support below list of accessories(external connector)
+ */
 enum {
        EXTCON_CABLE_USB = 0,
        EXTCON_CABLE_USB_HOST,
@@ -395,12 +398,12 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
                        vbvolt >>= STATUS2_VBVOLT_SHIFT;
 
                        /**
-                        * [0x1][VBVolt][ADCLow][ADC1K]
-                        * [0x1    0       0       0  ] : USB_OTG
-                        * [0x1    1       0       0  ] : USB_OTG_VB
-                        * [0x1    0       1       0  ] : Audio Video Cable with load
-                        * [0x1    0       1       1  ] : MHL without charging connector
-                        * [0x1    1       1       1  ] : MHL with charging connector
+                        * [0x1|VBVolt|ADCLow|ADC1K]
+                        * [0x1|     0|     0|    0] USB_OTG
+                        * [0x1|     1|     0|    0] USB_OTG_VB
+                        * [0x1|     0|     1|    0] Audio Video cable with load
+                        * [0x1|     0|     1|    1] MHL without charging cable
+                        * [0x1|     1|     1|    1] MHL with charging cable
                         */
                        cable_type = ((0x1 << 8)
                                        | (vbvolt << 2)
@@ -723,11 +726,11 @@ static int max77693_muic_adc_handler(struct max77693_muic_info *info)
                if (ret < 0)
                        return ret;
                break;
-       case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON:        /* DOCK_KEY_PREV */
-       case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON:        /* DOCK_KEY_NEXT */
-       case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:        /* DOCK_VOL_DOWN */
-       case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:       /* DOCK_VOL_UP */
-       case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON:       /* DOCK_KEY_PLAY_PAUSE */
+       case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON:      /* DOCK_KEY_PREV */
+       case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON:      /* DOCK_KEY_NEXT */
+       case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:      /* DOCK_VOL_DOWN */
+       case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:     /* DOCK_VOL_UP */
+       case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON:     /* DOCK_KEY_PLAY_PAUSE */
                /*
                 * Button of DOCK device
                 * - the Prev/Next/Volume Up/Volume Down/Play-Pause button
@@ -815,19 +818,21 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
                case MAX77693_MUIC_GND_MHL_VB:
                        /*
                         * MHL cable with MHL_TA(USB/TA) cable
-                        * - MHL cable include two port(HDMI line and separate micro-
-                        * usb port. When the target connect MHL cable, extcon driver
-                        * check whether MHL_TA(USB/TA) cable is connected. If MHL_TA
-                        * cable is connected, extcon driver notify state to notifiee
-                        * for charging battery.
+                        * - MHL cable include two port(HDMI line and separate
+                        * micro-usb port. When the target connect MHL cable,
+                        * extcon driver check whether MHL_TA(USB/TA) cable is
+                        * connected. If MHL_TA cable is connected, extcon
+                        * driver notify state to notifiee for charging battery.
                         *
                         * Features of 'MHL_TA(USB/TA) with MHL cable'
                         * - Support MHL
-                        * - Support charging through micro-usb port without data connection
+                        * - Support charging through micro-usb port without
+                        *   data connection
                         */
                        extcon_set_cable_state(info->edev, "MHL_TA", attached);
                        if (!cable_attached)
-                               extcon_set_cable_state(info->edev, "MHL", cable_attached);
+                               extcon_set_cable_state(info->edev,
+                                                     "MHL", cable_attached);
                        break;
                }
 
@@ -839,47 +844,51 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
                case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:         /* Dock-Audio */
                        /*
                         * Dock-Audio device with USB/TA cable
-                        * - Dock device include two port(Dock-Audio and micro-usb
-                        * port). When the target connect Dock-Audio device, extcon
-                        * driver check whether USB/TA cable is connected. If USB/TA
-                        * cable is connected, extcon driver notify state to notifiee
-                        * for charging battery.
+                        * - Dock device include two port(Dock-Audio and micro-
+                        * usb port). When the target connect Dock-Audio device,
+                        * extcon driver check whether USB/TA cable is connected
+                        * or not. If USB/TA cable is connected, extcon driver
+                        * notify state to notifiee for charging battery.
                         *
                         * Features of 'USB/TA cable with Dock-Audio device'
                         * - Support external output feature of audio.
-                        * - Support charging through micro-usb port without data
-                        *           connection.
+                        * - Support charging through micro-usb port without
+                        *   data connection.
                         */
                        extcon_set_cable_state(info->edev, "USB", attached);
 
                        if (!cable_attached)
-                               extcon_set_cable_state(info->edev, "Dock-Audio", cable_attached);
+                               extcon_set_cable_state(info->edev, "Dock-Audio",
+                                                     cable_attached);
                        break;
                case MAX77693_MUIC_ADC_RESERVED_ACC_3:          /* Dock-Smart */
                        /*
                         * Dock-Smart device with USB/TA cable
                         * - Dock-Desk device include three type of cable which
                         * are HDMI, USB for mouse/keyboard and micro-usb port
-                        * for USB/TA cable. Dock-Smart device need always exteranl
-                        * power supply(USB/TA cable through micro-usb cable). Dock-
-                        * Smart device support screen output of target to separate
-                        * monitor and mouse/keyboard for desktop mode.
+                        * for USB/TA cable. Dock-Smart device need always
+                        * exteranl power supply(USB/TA cable through micro-usb
+                        * cable). Dock-Smart device support screen output of
+                        * target to separate monitor and mouse/keyboard for
+                        * desktop mode.
                         *
                         * Features of 'USB/TA cable with Dock-Smart device'
                         * - Support MHL
                         * - Support external output feature of audio
-                        * - Support charging through micro-usb port without data
-                        *           connection if TA cable is connected to target.
-                        * - Support charging and data connection through micro-usb port
-                        *           if USB cable is connected between target and host
-                        *           device.
+                        * - Support charging through micro-usb port without
+                        *   data connection if TA cable is connected to target.
+                        * - Support charging and data connection through micro-
+                        *   usb port if USB cable is connected between target
+                        *   and host device
                         * - Support OTG device (Mouse/Keyboard)
                         */
-                       ret = max77693_muic_set_path(info, info->path_usb, attached);
+                       ret = max77693_muic_set_path(info, info->path_usb,
+                                                   attached);
                        if (ret < 0)
                                return ret;
 
-                       extcon_set_cable_state(info->edev, "Dock-Smart", attached);
+                       extcon_set_cable_state(info->edev, "Dock-Smart",
+                                             attached);
                        extcon_set_cable_state(info->edev, "MHL", attached);
 
                        break;
@@ -889,25 +898,28 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
                switch (chg_type) {
                case MAX77693_CHARGER_TYPE_NONE:
                        /*
-                        * When MHL(with USB/TA cable) or Dock-Audio with USB/TA cable
-                        * is attached, muic device happen below two interrupt.
-                        * - 'MAX77693_MUIC_IRQ_INT1_ADC' for detecting MHL/Dock-Audio.
-                        * - 'MAX77693_MUIC_IRQ_INT2_CHGTYP' for detecting USB/TA cable
-                        *   connected to MHL or Dock-Audio.
-                        * Always, happen eariler MAX77693_MUIC_IRQ_INT1_ADC interrupt
-                        * than MAX77693_MUIC_IRQ_INT2_CHGTYP interrupt.
+                        * When MHL(with USB/TA cable) or Dock-Audio with USB/TA
+                        * cable is attached, muic device happen below two irq.
+                        * - 'MAX77693_MUIC_IRQ_INT1_ADC' for detecting
+                        *    MHL/Dock-Audio.
+                        * - 'MAX77693_MUIC_IRQ_INT2_CHGTYP' for detecting
+                        *    USB/TA cable connected to MHL or Dock-Audio.
+                        * Always, happen eariler MAX77693_MUIC_IRQ_INT1_ADC
+                        * irq than MAX77693_MUIC_IRQ_INT2_CHGTYP irq.
                         *
-                        * If user attach MHL (with USB/TA cable and immediately detach
-                        * MHL with USB/TA cable before MAX77693_MUIC_IRQ_INT2_CHGTYP
-                        * interrupt is happened, USB/TA cable remain connected state to
-                        * target. But USB/TA cable isn't connected to target. The user
-                        * be face with unusual action. So, driver should check this
-                        * situation in spite of, that previous charger type is N/A.
+                        * If user attach MHL (with USB/TA cable and immediately
+                        * detach MHL with USB/TA cable before MAX77693_MUIC_IRQ
+                        * _INT2_CHGTYP irq is happened, USB/TA cable remain
+                        * connected state to target. But USB/TA cable isn't
+                        * connected to target. The user be face with unusual
+                        * action. So, driver should check this situation in
+                        * spite of, that previous charger type is N/A.
                         */
                        break;
                case MAX77693_CHARGER_TYPE_USB:
                        /* Only USB cable, PATH:AP_USB */
-                       ret = max77693_muic_set_path(info, info->path_usb, attached);
+                       ret = max77693_muic_set_path(info, info->path_usb,
+                                                   attached);
                        if (ret < 0)
                                return ret;
 
@@ -953,7 +965,7 @@ static void max77693_muic_irq_work(struct work_struct *work)
 
        mutex_lock(&info->mutex);
 
-       for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
+       for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
                if (info->irq == muic_irqs[i].virq)
                        irq_type = muic_irqs[i].irq;
 
@@ -1171,8 +1183,9 @@ static int max77693_muic_probe(struct platform_device *pdev)
                goto err_irq;
        }
        info->edev->name = DEV_NAME;
+       info->edev->dev.parent = &pdev->dev;
        info->edev->supported_cable = max77693_extcon_cable;
-       ret = extcon_dev_register(info->edev, NULL);
+       ret = extcon_dev_register(info->edev);
        if (ret) {
                dev_err(&pdev->dev, "failed to register extcon device\n");
                goto err_irq;
@@ -1188,7 +1201,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
                num_init_data = ARRAY_SIZE(default_init_data);
        }
 
-       for (i = 0 ; i < num_init_data ; i++) {
+       for (i = 0; i < num_init_data; i++) {
                enum max77693_irq_source irq_src
                                = MAX77693_IRQ_GROUP_NR;
 
@@ -1214,7 +1227,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
        }
 
        if (pdata->muic_data) {
-               struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
+               struct max77693_muic_platform_data *muic_pdata
+                                                  = pdata->muic_data;
 
                /*
                 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
index 67d6738d85a00d514d3d4c6692e969331663abde..6a00464658c50a6fb1aadecdf8e22467bc7963ca 100644 (file)
@@ -426,7 +426,8 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info)
                break;
        case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF:
        case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON:
-               ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, attached);
+               ret = max8997_muic_handle_usb(info,
+                                            MAX8997_USB_DEVICE, attached);
                if (ret < 0)
                        return ret;
                break;
@@ -504,7 +505,8 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info)
                }
                break;
        case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
-               extcon_set_cable_state(info->edev, "Charge-downstream", attached);
+               extcon_set_cable_state(info->edev,
+                                     "Charge-downstream", attached);
                break;
        case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
                extcon_set_cable_state(info->edev, "TA", attached);
@@ -537,7 +539,7 @@ static void max8997_muic_irq_work(struct work_struct *work)
 
        mutex_lock(&info->mutex);
 
-       for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
+       for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
                if (info->irq == muic_irqs[i].virq)
                        irq_type = muic_irqs[i].irq;
 
@@ -705,8 +707,9 @@ static int max8997_muic_probe(struct platform_device *pdev)
                goto err_irq;
        }
        info->edev->name = DEV_NAME;
+       info->edev->dev.parent = &pdev->dev;
        info->edev->supported_cable = max8997_extcon_cable;
-       ret = extcon_dev_register(info->edev, NULL);
+       ret = extcon_dev_register(info->edev);
        if (ret) {
                dev_err(&pdev->dev, "failed to register extcon device\n");
                goto err_irq;
index 89fdd05c5fd61a39cb75f7c9488f261a9e04412a..6c91976dd82371d63008474cb030aa7e4cfeb507 100644 (file)
@@ -135,7 +135,7 @@ static void palmas_enable_irq(struct palmas_usb *palmas_usb)
 static int palmas_usb_probe(struct platform_device *pdev)
 {
        struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
-       struct palmas_usb_platform_data *pdata = pdev->dev.platform_data;
+       struct palmas_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct device_node *node = pdev->dev.of_node;
        struct palmas_usb *palmas_usb;
        int status;
@@ -178,9 +178,10 @@ static int palmas_usb_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, palmas_usb);
 
        palmas_usb->edev.supported_cable = palmas_extcon_cable;
+       palmas_usb->edev.dev.parent = palmas_usb->dev;
        palmas_usb->edev.mutually_exclusive = mutually_exclusive;
 
-       status = extcon_dev_register(&palmas_usb->edev, palmas_usb->dev);
+       status = extcon_dev_register(&palmas_usb->edev);
        if (status) {
                dev_err(&pdev->dev, "failed to register extcon device\n");
                return status;
index 17df6db5dca7df56729af877b561d99f8892a15e..8847adf392b7ecf823f9f603314c76001367203f 100644 (file)
@@ -15,8 +15,9 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
-
-#include <asm/mach/irq.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 struct davinci_gpio_regs {
        u32     dir;
@@ -31,13 +32,14 @@ struct davinci_gpio_regs {
        u32     intstat;
 };
 
+#define BINTEN 0x8 /* GPIO Interrupt Per-Bank Enable Register */
+
 #define chip2controller(chip)  \
        container_of(chip, struct davinci_gpio_controller, chip)
 
-static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
 static void __iomem *gpio_base;
 
-static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
+static struct davinci_gpio_regs __iomem *gpio2regs(unsigned gpio)
 {
        void __iomem *ptr;
 
@@ -65,7 +67,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
        return g;
 }
 
-static int __init davinci_gpio_irq_setup(void);
+static int davinci_gpio_irq_setup(struct platform_device *pdev);
 
 /*--------------------------------------------------------------------------*/
 
@@ -131,33 +133,53 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
 }
 
-static int __init davinci_gpio_setup(void)
+static int davinci_gpio_probe(struct platform_device *pdev)
 {
        int i, base;
        unsigned ngpio;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-       struct davinci_gpio_regs *regs;
-
-       if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
-               return 0;
+       struct davinci_gpio_controller *chips;
+       struct davinci_gpio_platform_data *pdata;
+       struct davinci_gpio_regs __iomem *regs;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+
+       pdata = dev->platform_data;
+       if (!pdata) {
+               dev_err(dev, "No platform data found\n");
+               return -EINVAL;
+       }
 
        /*
         * The gpio banks conceptually expose a segmented bitmap,
         * and "ngpio" is one more than the largest zero-based
         * bit index that's valid.
         */
-       ngpio = soc_info->gpio_num;
+       ngpio = pdata->ngpio;
        if (ngpio == 0) {
-               pr_err("GPIO setup:  how many GPIOs?\n");
+               dev_err(dev, "How many GPIOs?\n");
                return -EINVAL;
        }
 
        if (WARN_ON(DAVINCI_N_GPIO < ngpio))
                ngpio = DAVINCI_N_GPIO;
 
-       gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
-       if (WARN_ON(!gpio_base))
+       chips = devm_kzalloc(dev,
+                            ngpio * sizeof(struct davinci_gpio_controller),
+                            GFP_KERNEL);
+       if (!chips) {
+               dev_err(dev, "Memory allocation failed\n");
                return -ENOMEM;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(dev, "Invalid memory resource\n");
+               return -EBUSY;
+       }
+
+       gpio_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(gpio_base))
+               return PTR_ERR(gpio_base);
 
        for (i = 0, base = 0; base < ngpio; i++, base += 32) {
                chips[i].chip.label = "DaVinci";
@@ -183,13 +205,10 @@ static int __init davinci_gpio_setup(void)
                gpiochip_add(&chips[i].chip);
        }
 
-       soc_info->gpio_ctlrs = chips;
-       soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
-
-       davinci_gpio_irq_setup();
+       platform_set_drvdata(pdev, chips);
+       davinci_gpio_irq_setup(pdev);
        return 0;
 }
-pure_initcall(davinci_gpio_setup);
 
 /*--------------------------------------------------------------------------*/
 /*
@@ -302,13 +321,14 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
 
 static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
 {
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
+       struct davinci_gpio_controller *d = chip2controller(chip);
 
-       /* NOTE:  we assume for now that only irqs in the first gpio_chip
+       /*
+        * NOTE:  we assume for now that only irqs in the first gpio_chip
         * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
         */
-       if (offset < soc_info->gpio_unbanked)
-               return soc_info->gpio_irq + offset;
+       if (offset < d->irq_base)
+               return d->gpio_irq + offset;
        else
                return -ENODEV;
 }
@@ -317,12 +337,11 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
 {
        struct davinci_gpio_controller *d;
        struct davinci_gpio_regs __iomem *g;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
        u32 mask;
 
        d = (struct davinci_gpio_controller *)data->handler_data;
        g = (struct davinci_gpio_regs __iomem *)d->regs;
-       mask = __gpio_mask(data->irq - soc_info->gpio_irq);
+       mask = __gpio_mask(data->irq - d->gpio_irq);
 
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                return -EINVAL;
@@ -343,24 +362,33 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
  * (dm6446) can be set appropriately for GPIOV33 pins.
  */
 
-static int __init davinci_gpio_irq_setup(void)
+static int davinci_gpio_irq_setup(struct platform_device *pdev)
 {
        unsigned        gpio, irq, bank;
        struct clk      *clk;
        u32             binten = 0;
        unsigned        ngpio, bank_irq;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-       struct davinci_gpio_regs        __iomem *g;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
+       struct davinci_gpio_platform_data *pdata = dev->platform_data;
+       struct davinci_gpio_regs __iomem *g;
 
-       ngpio = soc_info->gpio_num;
+       ngpio = pdata->ngpio;
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res) {
+               dev_err(dev, "Invalid IRQ resource\n");
+               return -EBUSY;
+       }
 
-       bank_irq = soc_info->gpio_irq;
-       if (bank_irq == 0) {
-               printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
-               return -EINVAL;
+       bank_irq = res->start;
+
+       if (!bank_irq) {
+               dev_err(dev, "Invalid IRQ resource\n");
+               return -ENODEV;
        }
 
-       clk = clk_get(NULL, "gpio");
+       clk = devm_clk_get(dev, "gpio");
        if (IS_ERR(clk)) {
                printk(KERN_ERR "Error %ld getting gpio clock?\n",
                       PTR_ERR(clk));
@@ -368,16 +396,17 @@ static int __init davinci_gpio_irq_setup(void)
        }
        clk_prepare_enable(clk);
 
-       /* Arrange gpio_to_irq() support, handling either direct IRQs or
+       /*
+        * Arrange gpio_to_irq() support, handling either direct IRQs or
         * banked IRQs.  Having GPIOs in the first GPIO bank use direct
         * IRQs, while the others use banked IRQs, would need some setup
         * tweaks to recognize hardware which can do that.
         */
        for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
                chips[bank].chip.to_irq = gpio_to_irq_banked;
-               chips[bank].irq_base = soc_info->gpio_unbanked
+               chips[bank].irq_base = pdata->gpio_unbanked
                        ? -EINVAL
-                       : (soc_info->intc_irq_num + gpio);
+                       : (pdata->intc_irq_num + gpio);
        }
 
        /*
@@ -385,7 +414,7 @@ static int __init davinci_gpio_irq_setup(void)
         * controller only handling trigger modes.  We currently assume no
         * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
         */
-       if (soc_info->gpio_unbanked) {
+       if (pdata->gpio_unbanked) {
                static struct irq_chip_type gpio_unbanked;
 
                /* pass "bank 0" GPIO IRQs to AINTC */
@@ -405,7 +434,7 @@ static int __init davinci_gpio_irq_setup(void)
                __raw_writel(~0, &g->set_rising);
 
                /* set the direct IRQs up to use that irqchip */
-               for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
+               for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) {
                        irq_set_chip(irq, &gpio_unbanked.chip);
                        irq_set_handler_data(irq, &chips[gpio / 32]);
                        irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
@@ -450,12 +479,31 @@ static int __init davinci_gpio_irq_setup(void)
        }
 
 done:
-       /* BINTEN -- per-bank interrupt enable. genirq would also let these
+       /*
+        * BINTEN -- per-bank interrupt enable. genirq would also let these
         * bits be set/cleared dynamically.
         */
-       __raw_writel(binten, gpio_base + 0x08);
+       __raw_writel(binten, gpio_base + BINTEN);
 
        printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
 
        return 0;
 }
+
+static struct platform_driver davinci_gpio_driver = {
+       .probe          = davinci_gpio_probe,
+       .driver         = {
+               .name   = "davinci_gpio",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/**
+ * GPIO driver registration needs to be done before machine_init functions
+ * access GPIO. Hence davinci_gpio_drv_reg() is a postcore_initcall.
+ */
+static int __init davinci_gpio_drv_reg(void)
+{
+       return platform_driver_register(&davinci_gpio_driver);
+}
+postcore_initcall(davinci_gpio_drv_reg);
index 358a21c2d811bc6637960ed167ae8e95260ecfca..76e02b9460e63abe14ccbc4aa348929f1e9c2259 100644 (file)
@@ -1033,7 +1033,7 @@ static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
 }
 #endif
 
-#ifdef CONFIG_PLAT_S3C64XX
+#ifdef CONFIG_ARCH_S3C64XX
 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
 {
        return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
@@ -1174,7 +1174,7 @@ struct samsung_gpio_chip s3c24xx_gpios[] = {
  */
 
 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
-#ifdef CONFIG_PLAT_S3C64XX
+#ifdef CONFIG_ARCH_S3C64XX
        {
                .chip   = {
                        .base   = S3C64XX_GPA(0),
@@ -1227,7 +1227,7 @@ static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
 };
 
 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
-#ifdef CONFIG_PLAT_S3C64XX
+#ifdef CONFIG_ARCH_S3C64XX
        {
                .base   = S3C64XX_GPH_BASE + 0x4,
                .chip   = {
@@ -1257,7 +1257,7 @@ static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
 };
 
 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
-#ifdef CONFIG_PLAT_S3C64XX
+#ifdef CONFIG_ARCH_S3C64XX
        {
                .base   = S3C64XX_GPF_BASE,
                .config = &samsung_gpio_cfgs[6],
@@ -2082,34 +2082,14 @@ static __init int samsung_gpiolib_init(void)
        int i, nr_chips;
        int group = 0;
 
-#if defined(CONFIG_PINCTRL_EXYNOS) || defined(CONFIG_PINCTRL_EXYNOS5440)
        /*
-       * This gpio driver includes support for device tree support and there
-       * are platforms using it. In order to maintain compatibility with those
-       * platforms, and to allow non-dt Exynos4210 platforms to use this
-       * gpiolib support, a check is added to find out if there is a active
-       * pin-controller driver support available. If it is available, this
-       * gpiolib support is ignored and the gpiolib support available in
-       * pin-controller driver is used. This is a temporary check and will go
-       * away when all of the Exynos4210 platforms have switched to using
-       * device tree and the pin-ctrl driver.
-       */
-       struct device_node *pctrl_np;
-       static const struct of_device_id exynos_pinctrl_ids[] = {
-               { .compatible = "samsung,s3c2412-pinctrl", },
-               { .compatible = "samsung,s3c2416-pinctrl", },
-               { .compatible = "samsung,s3c2440-pinctrl", },
-               { .compatible = "samsung,s3c2450-pinctrl", },
-               { .compatible = "samsung,exynos4210-pinctrl", },
-               { .compatible = "samsung,exynos4x12-pinctrl", },
-               { .compatible = "samsung,exynos5250-pinctrl", },
-               { .compatible = "samsung,exynos5440-pinctrl", },
-               { }
-       };
-       for_each_matching_node(pctrl_np, exynos_pinctrl_ids)
-               if (pctrl_np && of_device_is_available(pctrl_np))
-                       return -ENODEV;
-#endif
+        * Currently there are two drivers that can provide GPIO support for
+        * Samsung SoCs. For device tree enabled platforms, the new
+        * pinctrl-samsung driver is used, providing both GPIO and pin control
+        * interfaces. For legacy (non-DT) platforms this driver is used.
+        */
+       if (of_have_populated_dt())
+               return -ENODEV;
 
        samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
 
index 3fa3e2867e19b8dfcbd3ca2275b0fbd194cb0693..58445bb69106c71ab648263e731e12151e48c911 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/gpio-davinci.h>
 
 #include <mach/common.h>
 #include <mach/tnetv107x.h>
index 0dee0e0c247ae5fa2f121df234d09979dc00df74..dadbac2772676c842846944c7d21771e175885e2 100644 (file)
@@ -408,7 +408,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
                        IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
 
        if (!value_sd) {
-               value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");
+               value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
                if (!value_sd) {
                        ret = -ENODEV;
                        goto err_out;
index db59bb9fbe23f75b6be9e182937b4ff6588cfafe..10d1de5bce6ff7a35921fa19d1327863b85ab86d 100644 (file)
@@ -107,8 +107,6 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
 static void intel_crt_get_config(struct intel_encoder *encoder,
                                 struct intel_crtc_config *pipe_config)
 {
-       struct drm_device *dev = encoder->base.dev;
-
        pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);
 }
 
index 10e1581022cfdea4acd4e5431ea43155e83898f0..88fc5aefcd964b2f8b6c83476ca7d308066069f1 100644 (file)
@@ -465,6 +465,39 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
        return 1;
 }
 
+int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
+{
+       int ret = 0;
+       struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
+
+       mutex_lock(&data->mutex);
+       if (!hsdev->ref_cnt) {
+               ret = hid_hw_open(hsdev->hdev);
+               if (ret) {
+                       hid_err(hsdev->hdev, "failed to open hid device\n");
+                       mutex_unlock(&data->mutex);
+                       return ret;
+               }
+       }
+       hsdev->ref_cnt++;
+       mutex_unlock(&data->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sensor_hub_device_open);
+
+void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
+{
+       struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
+
+       mutex_lock(&data->mutex);
+       hsdev->ref_cnt--;
+       if (!hsdev->ref_cnt)
+               hid_hw_close(hsdev->hdev);
+       mutex_unlock(&data->mutex);
+}
+EXPORT_SYMBOL_GPL(sensor_hub_device_close);
+
 static int sensor_hub_probe(struct hid_device *hdev,
                                const struct hid_device_id *id)
 {
@@ -506,12 +539,6 @@ static int sensor_hub_probe(struct hid_device *hdev,
                hid_err(hdev, "hw start failed\n");
                return ret;
        }
-       ret = hid_hw_open(hdev);
-       if (ret) {
-               hid_err(hdev, "failed to open input interrupt pipe\n");
-               goto err_stop_hw;
-       }
-
        INIT_LIST_HEAD(&sd->dyn_callback_list);
        sd->hid_sensor_client_cnt = 0;
        report_enum = &hdev->report_enum[HID_INPUT_REPORT];
@@ -520,7 +547,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
        if (dev_cnt > HID_MAX_PHY_DEVICES) {
                hid_err(hdev, "Invalid Physical device count\n");
                ret = -EINVAL;
-               goto err_close;
+               goto err_stop_hw;
        }
        sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt *
                                                sizeof(struct mfd_cell),
@@ -528,7 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
        if (sd->hid_sensor_hub_client_devs == NULL) {
                hid_err(hdev, "Failed to allocate memory for mfd cells\n");
                        ret = -ENOMEM;
-                       goto err_close;
+                       goto err_stop_hw;
        }
        list_for_each_entry(report, &report_enum->report_list, list) {
                hid_dbg(hdev, "Report id:%x\n", report->id);
@@ -565,8 +592,6 @@ err_free_names:
        for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
                kfree(sd->hid_sensor_hub_client_devs[i].name);
        kfree(sd->hid_sensor_hub_client_devs);
-err_close:
-       hid_hw_close(hdev);
 err_stop_hw:
        hid_hw_stop(hdev);
 
index 66d44581e1b1e74a242a8b8cdbf28ac3196325c3..749f7b5c81795e6244c2cdc14abc7683919032c3 100644 (file)
@@ -33,11 +33,13 @@ static ssize_t modalias_show(struct device *dev,
 {
        return sprintf(buf, "hsi:%s\n", dev_name(dev));
 }
+static DEVICE_ATTR_RO(modalias);
 
-static struct device_attribute hsi_bus_dev_attrs[] = {
-       __ATTR_RO(modalias),
-       __ATTR_NULL,
+static struct attribute *hsi_bus_dev_attrs[] = {
+       &dev_attr_modalias.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(hsi_bus_dev);
 
 static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
@@ -53,7 +55,7 @@ static int hsi_bus_match(struct device *dev, struct device_driver *driver)
 
 static struct bus_type hsi_bus_type = {
        .name           = "hsi",
-       .dev_attrs      = hsi_bus_dev_attrs,
+       .dev_groups     = hsi_bus_dev_groups,
        .match          = hsi_bus_match,
        .uevent         = hsi_bus_uevent,
 };
index 6de6c98ce6eb73636d06123024e9f84324947f59..cea623c36ae23cc007138371b14ef05e770fe6d0 100644 (file)
@@ -47,8 +47,8 @@ static void vmbus_setevent(struct vmbus_channel *channel)
                        (unsigned long *) vmbus_connection.send_int_page +
                        (channel->offermsg.child_relid >> 5));
 
-               monitorpage = vmbus_connection.monitor_pages;
-               monitorpage++; /* Get the child to parent monitor page */
+               /* Get the child to parent monitor page */
+               monitorpage = vmbus_connection.monitor_pages[1];
 
                sync_set_bit(channel->monitor_bit,
                        (unsigned long *)&monitorpage->trigger_group
@@ -59,50 +59,6 @@ static void vmbus_setevent(struct vmbus_channel *channel)
        }
 }
 
-/*
- * vmbus_get_debug_info -Retrieve various channel debug info
- */
-void vmbus_get_debug_info(struct vmbus_channel *channel,
-                             struct vmbus_channel_debug_info *debuginfo)
-{
-       struct hv_monitor_page *monitorpage;
-       u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
-       u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
-
-       debuginfo->relid = channel->offermsg.child_relid;
-       debuginfo->state = channel->state;
-       memcpy(&debuginfo->interfacetype,
-              &channel->offermsg.offer.if_type, sizeof(uuid_le));
-       memcpy(&debuginfo->interface_instance,
-              &channel->offermsg.offer.if_instance,
-              sizeof(uuid_le));
-
-       monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
-
-       debuginfo->monitorid = channel->offermsg.monitorid;
-
-       debuginfo->servermonitor_pending =
-                       monitorpage->trigger_group[monitor_group].pending;
-       debuginfo->servermonitor_latency =
-                       monitorpage->latency[monitor_group][monitor_offset];
-       debuginfo->servermonitor_connectionid =
-                       monitorpage->parameter[monitor_group]
-                                       [monitor_offset].connectionid.u.id;
-
-       monitorpage++;
-
-       debuginfo->clientmonitor_pending =
-                       monitorpage->trigger_group[monitor_group].pending;
-       debuginfo->clientmonitor_latency =
-                       monitorpage->latency[monitor_group][monitor_offset];
-       debuginfo->clientmonitor_connectionid =
-                       monitorpage->parameter[monitor_group]
-                                       [monitor_offset].connectionid.u.id;
-
-       hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
-       hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
-}
-
 /*
  * vmbus_open - Open the specified channel.
  */
@@ -855,6 +811,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
        if (signal)
                vmbus_setevent(channel);
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
index bbff5f200bef7a7b070abec6c0f7c202f335159c..fa920469bf104fda2e57d9c2bce2f15f90d5b2a4 100644 (file)
@@ -203,7 +203,8 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
        struct vmbus_channel *primary_channel;
        struct vmbus_channel_relid_released msg;
 
-       vmbus_device_unregister(channel->device_obj);
+       if (channel->device_obj)
+               vmbus_device_unregister(channel->device_obj);
        memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
        msg.child_relid = channel->offermsg.child_relid;
        msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
@@ -216,7 +217,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
        } else {
                primary_channel = channel->primary_channel;
                spin_lock_irqsave(&primary_channel->sc_lock, flags);
-               list_del(&channel->listentry);
+               list_del(&channel->sc_list);
                spin_unlock_irqrestore(&primary_channel->sc_lock, flags);
        }
        free_channel(channel);
index 936093e0271e3c7fffccce7fe0e688c4d6f3ad01..af6edf9b19365a4938ca16f6a913a08cc6a35fa7 100644 (file)
@@ -76,10 +76,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
        msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
        msg->vmbus_version_requested = version;
        msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
-       msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages);
-       msg->monitor_page2 = virt_to_phys(
-                       (void *)((unsigned long)vmbus_connection.monitor_pages +
-                                PAGE_SIZE));
+       msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
+       msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
 
        /*
         * Add to list before we send the request since we may
@@ -169,9 +167,10 @@ int vmbus_connect(void)
         * Setup the monitor notification facility. The 1st page for
         * parent->child and the 2nd page for child->parent
         */
-       vmbus_connection.monitor_pages =
-       (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1);
-       if (vmbus_connection.monitor_pages == NULL) {
+       vmbus_connection.monitor_pages[0] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
+       vmbus_connection.monitor_pages[1] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
+       if ((vmbus_connection.monitor_pages[0] == NULL) ||
+           (vmbus_connection.monitor_pages[1] == NULL)) {
                ret = -ENOMEM;
                goto cleanup;
        }
@@ -229,10 +228,10 @@ cleanup:
                vmbus_connection.int_page = NULL;
        }
 
-       if (vmbus_connection.monitor_pages) {
-               free_pages((unsigned long)vmbus_connection.monitor_pages, 1);
-               vmbus_connection.monitor_pages = NULL;
-       }
+       free_pages((unsigned long)vmbus_connection.monitor_pages[0], 1);
+       free_pages((unsigned long)vmbus_connection.monitor_pages[1], 1);
+       vmbus_connection.monitor_pages[0] = NULL;
+       vmbus_connection.monitor_pages[1] = NULL;
 
        kfree(msginfo);
 
index 88f4096fa078d7f4e2ae1eeee41fd7188ab1a313..f0c5e07c25ec9f88d4bc0cee66a990da77f3636e 100644 (file)
@@ -304,7 +304,7 @@ err:
 void hv_synic_free_cpu(int cpu)
 {
        kfree(hv_context.event_dpc[cpu]);
-       if (hv_context.synic_message_page[cpu])
+       if (hv_context.synic_event_page[cpu])
                free_page((unsigned long)hv_context.synic_event_page[cpu]);
        if (hv_context.synic_message_page[cpu])
                free_page((unsigned long)hv_context.synic_message_page[cpu]);
index 273e3ddb3a20b00c5d1ae03bab6368c5fcfbc26f..62dfd246b94838e622c02bd125650a79a21c3f32 100644 (file)
@@ -97,7 +97,7 @@ static void shutdown_onchannelcallback(void *context)
        struct vmbus_channel *channel = context;
        u32 recvlen;
        u64 requestid;
-       u8  execute_shutdown = false;
+       bool execute_shutdown = false;
        u8  *shut_txf_buf = util_shutdown.recv_buffer;
 
        struct shutdown_msg_data *shutdown_msg;
index d84918fe19ab7023e4189b0cb52d98495340abd1..e05517616a06e549407f422a4713145b0f44e1de 100644 (file)
@@ -514,6 +514,13 @@ struct hv_context {
 
 extern struct hv_context hv_context;
 
+struct hv_ring_buffer_debug_info {
+       u32 current_interrupt_mask;
+       u32 current_read_index;
+       u32 current_write_index;
+       u32 bytes_avail_toread;
+       u32 bytes_avail_towrite;
+};
 
 /* Hv Interface */
 
@@ -612,7 +619,7 @@ struct vmbus_connection {
         * 2 pages - 1st page for parent->child notification and 2nd
         * is child->parent notification
         */
-       void *monitor_pages;
+       struct hv_monitor_page *monitor_pages[2];
        struct list_head chn_msg_list;
        spinlock_t channelmsg_lock;
 
index f9fe46f52cfa35d3d006260ed6a082f41466ef58..48aad4faea068e88cbe61976aa3444d9c8a80a58 100644 (file)
@@ -46,24 +46,6 @@ static struct tasklet_struct msg_dpc;
 static struct completion probe_event;
 static int irq;
 
-struct hv_device_info {
-       u32 chn_id;
-       u32 chn_state;
-       uuid_le chn_type;
-       uuid_le chn_instance;
-
-       u32 monitor_id;
-       u32 server_monitor_pending;
-       u32 server_monitor_latency;
-       u32 server_monitor_conn_id;
-       u32 client_monitor_pending;
-       u32 client_monitor_latency;
-       u32 client_monitor_conn_id;
-
-       struct hv_dev_port_info inbound;
-       struct hv_dev_port_info outbound;
-};
-
 static int vmbus_exists(void)
 {
        if (hv_acpi_dev == NULL)
@@ -72,169 +54,361 @@ static int vmbus_exists(void)
        return 0;
 }
 
+#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
+static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
+{
+       int i;
+       for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
+               sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
+}
 
-static void get_channel_info(struct hv_device *device,
-                            struct hv_device_info *info)
+static u8 channel_monitor_group(struct vmbus_channel *channel)
 {
-       struct vmbus_channel_debug_info debug_info;
+       return (u8)channel->offermsg.monitorid / 32;
+}
 
-       if (!device->channel)
-               return;
+static u8 channel_monitor_offset(struct vmbus_channel *channel)
+{
+       return (u8)channel->offermsg.monitorid % 32;
+}
 
-       vmbus_get_debug_info(device->channel, &debug_info);
+static u32 channel_pending(struct vmbus_channel *channel,
+                          struct hv_monitor_page *monitor_page)
+{
+       u8 monitor_group = channel_monitor_group(channel);
+       return monitor_page->trigger_group[monitor_group].pending;
+}
 
-       info->chn_id = debug_info.relid;
-       info->chn_state = debug_info.state;
-       memcpy(&info->chn_type, &debug_info.interfacetype,
-              sizeof(uuid_le));
-       memcpy(&info->chn_instance, &debug_info.interface_instance,
-              sizeof(uuid_le));
+static u32 channel_latency(struct vmbus_channel *channel,
+                          struct hv_monitor_page *monitor_page)
+{
+       u8 monitor_group = channel_monitor_group(channel);
+       u8 monitor_offset = channel_monitor_offset(channel);
+       return monitor_page->latency[monitor_group][monitor_offset];
+}
 
-       info->monitor_id = debug_info.monitorid;
+static u32 channel_conn_id(struct vmbus_channel *channel,
+                          struct hv_monitor_page *monitor_page)
+{
+       u8 monitor_group = channel_monitor_group(channel);
+       u8 monitor_offset = channel_monitor_offset(channel);
+       return monitor_page->parameter[monitor_group][monitor_offset].connectionid.u.id;
+}
 
-       info->server_monitor_pending = debug_info.servermonitor_pending;
-       info->server_monitor_latency = debug_info.servermonitor_latency;
-       info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
+static ssize_t id_show(struct device *dev, struct device_attribute *dev_attr,
+                      char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
 
-       info->client_monitor_pending = debug_info.clientmonitor_pending;
-       info->client_monitor_latency = debug_info.clientmonitor_latency;
-       info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n", hv_dev->channel->offermsg.child_relid);
+}
+static DEVICE_ATTR_RO(id);
 
-       info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
-       info->inbound.read_idx = debug_info.inbound.current_read_index;
-       info->inbound.write_idx = debug_info.inbound.current_write_index;
-       info->inbound.bytes_avail_toread =
-               debug_info.inbound.bytes_avail_toread;
-       info->inbound.bytes_avail_towrite =
-               debug_info.inbound.bytes_avail_towrite;
+static ssize_t state_show(struct device *dev, struct device_attribute *dev_attr,
+                         char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
 
-       info->outbound.int_mask =
-               debug_info.outbound.current_interrupt_mask;
-       info->outbound.read_idx = debug_info.outbound.current_read_index;
-       info->outbound.write_idx = debug_info.outbound.current_write_index;
-       info->outbound.bytes_avail_toread =
-               debug_info.outbound.bytes_avail_toread;
-       info->outbound.bytes_avail_towrite =
-               debug_info.outbound.bytes_avail_towrite;
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n", hv_dev->channel->state);
 }
+static DEVICE_ATTR_RO(state);
 
-#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
-static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
+static ssize_t monitor_id_show(struct device *dev,
+                              struct device_attribute *dev_attr, char *buf)
 {
-       int i;
-       for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
-               sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n", hv_dev->channel->offermsg.monitorid);
 }
+static DEVICE_ATTR_RO(monitor_id);
 
-/*
- * vmbus_show_device_attr - Show the device attribute in sysfs.
- *
- * This is invoked when user does a
- * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
- */
-static ssize_t vmbus_show_device_attr(struct device *dev,
-                                     struct device_attribute *dev_attr,
-                                     char *buf)
+static ssize_t class_id_show(struct device *dev,
+                              struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "{%pUl}\n",
+                      hv_dev->channel->offermsg.offer.if_type.b);
+}
+static DEVICE_ATTR_RO(class_id);
+
+static ssize_t device_id_show(struct device *dev,
+                             struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "{%pUl}\n",
+                      hv_dev->channel->offermsg.offer.if_instance.b);
+}
+static DEVICE_ATTR_RO(device_id);
+
+static ssize_t modalias_show(struct device *dev,
+                            struct device_attribute *dev_attr, char *buf)
 {
        struct hv_device *hv_dev = device_to_hv_device(dev);
-       struct hv_device_info *device_info;
        char alias_name[VMBUS_ALIAS_LEN + 1];
-       int ret = 0;
 
-       device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL);
-       if (!device_info)
-               return ret;
+       print_alias_name(hv_dev, alias_name);
+       return sprintf(buf, "vmbus:%s\n", alias_name);
+}
+static DEVICE_ATTR_RO(modalias);
 
-       get_channel_info(hv_dev, device_info);
-
-       if (!strcmp(dev_attr->attr.name, "class_id")) {
-               ret = sprintf(buf, "{%pUl}\n", device_info->chn_type.b);
-       } else if (!strcmp(dev_attr->attr.name, "device_id")) {
-               ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);
-       } else if (!strcmp(dev_attr->attr.name, "modalias")) {
-               print_alias_name(hv_dev, alias_name);
-               ret = sprintf(buf, "vmbus:%s\n", alias_name);
-       } else if (!strcmp(dev_attr->attr.name, "state")) {
-               ret = sprintf(buf, "%d\n", device_info->chn_state);
-       } else if (!strcmp(dev_attr->attr.name, "id")) {
-               ret = sprintf(buf, "%d\n", device_info->chn_id);
-       } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
-               ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
-       } else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
-               ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
-       } else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
-               ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
-       } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
-               ret = sprintf(buf, "%d\n",
-                              device_info->outbound.bytes_avail_toread);
-       } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
-               ret = sprintf(buf, "%d\n",
-                              device_info->outbound.bytes_avail_towrite);
-       } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
-               ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
-       } else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
-               ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
-       } else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
-               ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
-       } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
-               ret = sprintf(buf, "%d\n",
-                              device_info->inbound.bytes_avail_toread);
-       } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
-               ret = sprintf(buf, "%d\n",
-                              device_info->inbound.bytes_avail_towrite);
-       } else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
-               ret = sprintf(buf, "%d\n", device_info->monitor_id);
-       } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
-               ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
-       } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
-               ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
-       } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
-               ret = sprintf(buf, "%d\n",
-                              device_info->server_monitor_conn_id);
-       } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
-               ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
-       } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
-               ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
-       } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
-               ret = sprintf(buf, "%d\n",
-                              device_info->client_monitor_conn_id);
-       }
+static ssize_t server_monitor_pending_show(struct device *dev,
+                                          struct device_attribute *dev_attr,
+                                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
 
-       kfree(device_info);
-       return ret;
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n",
+                      channel_pending(hv_dev->channel,
+                                      vmbus_connection.monitor_pages[1]));
+}
+static DEVICE_ATTR_RO(server_monitor_pending);
+
+static ssize_t client_monitor_pending_show(struct device *dev,
+                                          struct device_attribute *dev_attr,
+                                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n",
+                      channel_pending(hv_dev->channel,
+                                      vmbus_connection.monitor_pages[1]));
+}
+static DEVICE_ATTR_RO(client_monitor_pending);
+
+static ssize_t server_monitor_latency_show(struct device *dev,
+                                          struct device_attribute *dev_attr,
+                                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n",
+                      channel_latency(hv_dev->channel,
+                                      vmbus_connection.monitor_pages[0]));
+}
+static DEVICE_ATTR_RO(server_monitor_latency);
+
+static ssize_t client_monitor_latency_show(struct device *dev,
+                                          struct device_attribute *dev_attr,
+                                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n",
+                      channel_latency(hv_dev->channel,
+                                      vmbus_connection.monitor_pages[1]));
+}
+static DEVICE_ATTR_RO(client_monitor_latency);
+
+static ssize_t server_monitor_conn_id_show(struct device *dev,
+                                          struct device_attribute *dev_attr,
+                                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n",
+                      channel_conn_id(hv_dev->channel,
+                                      vmbus_connection.monitor_pages[0]));
+}
+static DEVICE_ATTR_RO(server_monitor_conn_id);
+
+static ssize_t client_monitor_conn_id_show(struct device *dev,
+                                          struct device_attribute *dev_attr,
+                                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       return sprintf(buf, "%d\n",
+                      channel_conn_id(hv_dev->channel,
+                                      vmbus_connection.monitor_pages[1]));
+}
+static DEVICE_ATTR_RO(client_monitor_conn_id);
+
+static ssize_t out_intr_mask_show(struct device *dev,
+                                 struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info outbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+       return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
+}
+static DEVICE_ATTR_RO(out_intr_mask);
+
+static ssize_t out_read_index_show(struct device *dev,
+                                  struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info outbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+       return sprintf(buf, "%d\n", outbound.current_read_index);
+}
+static DEVICE_ATTR_RO(out_read_index);
+
+static ssize_t out_write_index_show(struct device *dev,
+                                   struct device_attribute *dev_attr,
+                                   char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info outbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+       return sprintf(buf, "%d\n", outbound.current_write_index);
+}
+static DEVICE_ATTR_RO(out_write_index);
+
+static ssize_t out_read_bytes_avail_show(struct device *dev,
+                                        struct device_attribute *dev_attr,
+                                        char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info outbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+       return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
 }
+static DEVICE_ATTR_RO(out_read_bytes_avail);
+
+static ssize_t out_write_bytes_avail_show(struct device *dev,
+                                         struct device_attribute *dev_attr,
+                                         char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info outbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+       return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
+}
+static DEVICE_ATTR_RO(out_write_bytes_avail);
+
+static ssize_t in_intr_mask_show(struct device *dev,
+                                struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info inbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+       return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
+}
+static DEVICE_ATTR_RO(in_intr_mask);
+
+static ssize_t in_read_index_show(struct device *dev,
+                                 struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info inbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+       return sprintf(buf, "%d\n", inbound.current_read_index);
+}
+static DEVICE_ATTR_RO(in_read_index);
+
+static ssize_t in_write_index_show(struct device *dev,
+                                  struct device_attribute *dev_attr, char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info inbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+       return sprintf(buf, "%d\n", inbound.current_write_index);
+}
+static DEVICE_ATTR_RO(in_write_index);
+
+static ssize_t in_read_bytes_avail_show(struct device *dev,
+                                       struct device_attribute *dev_attr,
+                                       char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info inbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+       return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
+}
+static DEVICE_ATTR_RO(in_read_bytes_avail);
+
+static ssize_t in_write_bytes_avail_show(struct device *dev,
+                                        struct device_attribute *dev_attr,
+                                        char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       struct hv_ring_buffer_debug_info inbound;
+
+       if (!hv_dev->channel)
+               return -ENODEV;
+       hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+       return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
+}
+static DEVICE_ATTR_RO(in_write_bytes_avail);
 
 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
-static struct device_attribute vmbus_device_attrs[] = {
-       __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL),
-
-       __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
-
-       __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
-
-       __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
-
-       __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
-       __ATTR_NULL
+static struct attribute *vmbus_attrs[] = {
+       &dev_attr_id.attr,
+       &dev_attr_state.attr,
+       &dev_attr_monitor_id.attr,
+       &dev_attr_class_id.attr,
+       &dev_attr_device_id.attr,
+       &dev_attr_modalias.attr,
+       &dev_attr_server_monitor_pending.attr,
+       &dev_attr_client_monitor_pending.attr,
+       &dev_attr_server_monitor_latency.attr,
+       &dev_attr_client_monitor_latency.attr,
+       &dev_attr_server_monitor_conn_id.attr,
+       &dev_attr_client_monitor_conn_id.attr,
+       &dev_attr_out_intr_mask.attr,
+       &dev_attr_out_read_index.attr,
+       &dev_attr_out_write_index.attr,
+       &dev_attr_out_read_bytes_avail.attr,
+       &dev_attr_out_write_bytes_avail.attr,
+       &dev_attr_in_intr_mask.attr,
+       &dev_attr_in_read_index.attr,
+       &dev_attr_in_write_index.attr,
+       &dev_attr_in_read_bytes_avail.attr,
+       &dev_attr_in_write_bytes_avail.attr,
+       NULL,
 };
-
+ATTRIBUTE_GROUPS(vmbus);
 
 /*
  * vmbus_uevent - add uevent for our device
@@ -383,7 +557,7 @@ static struct bus_type  hv_bus = {
        .remove =               vmbus_remove,
        .probe =                vmbus_probe,
        .uevent =               vmbus_uevent,
-       .dev_attrs =    vmbus_device_attrs,
+       .dev_groups =           vmbus_groups,
 };
 
 static const char *driver_name = "hyperv";
index 02906ca99b41c4583ca6c3adb18f309ec88ffad5..3f7f59cc8b5ff36a807a4315eb6469999ea95869 100644 (file)
@@ -197,8 +197,8 @@ comment "IDE chipset support/bugfixes"
 
 config IDE_GENERIC
        tristate "generic/default IDE chipset support"
-       depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
-       default ARM && (ARCH_RPC || ARCH_SHARK)
+       depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC
+       default ARM && ARCH_RPC
        help
          This is the generic IDE driver.  This driver attaches to the
          fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
index 883ffacaf45ac4bbd67ca8fe1f9cf576149665ad..84a6a9e08d64d450ef2828e72d75da8949cf5052 100644 (file)
@@ -25,6 +25,7 @@ static ssize_t media_show(struct device *dev, struct device_attribute *attr,
        ide_drive_t *drive = to_ide_device(dev);
        return sprintf(buf, "%s\n", ide_media_string(drive));
 }
+static DEVICE_ATTR_RO(media);
 
 static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,
                              char *buf)
@@ -32,6 +33,7 @@ static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,
        ide_drive_t *drive = to_ide_device(dev);
        return sprintf(buf, "%s\n", drive->name);
 }
+static DEVICE_ATTR_RO(drivename);
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
@@ -39,6 +41,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
        ide_drive_t *drive = to_ide_device(dev);
        return sprintf(buf, "ide:m-%s\n", ide_media_string(drive));
 }
+static DEVICE_ATTR_RO(modalias);
 
 static ssize_t model_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
@@ -46,6 +49,7 @@ static ssize_t model_show(struct device *dev, struct device_attribute *attr,
        ide_drive_t *drive = to_ide_device(dev);
        return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);
 }
+static DEVICE_ATTR_RO(model);
 
 static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
@@ -53,6 +57,7 @@ static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
        ide_drive_t *drive = to_ide_device(dev);
        return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);
 }
+static DEVICE_ATTR_RO(firmware);
 
 static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
                           char *buf)
@@ -60,16 +65,28 @@ static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
        ide_drive_t *drive = to_ide_device(dev);
        return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);
 }
+static DEVICE_ATTR(serial, 0400, serial_show, NULL);
+
+static DEVICE_ATTR(unload_heads, 0644, ide_park_show, ide_park_store);
+
+static struct attribute *ide_attrs[] = {
+       &dev_attr_media.attr,
+       &dev_attr_drivename.attr,
+       &dev_attr_modalias.attr,
+       &dev_attr_model.attr,
+       &dev_attr_firmware.attr,
+       &dev_attr_serial.attr,
+       &dev_attr_unload_heads.attr,
+       NULL,
+};
+
+static const struct attribute_group ide_attr_group = {
+       .attrs = ide_attrs,
+};
 
-struct device_attribute ide_dev_attrs[] = {
-       __ATTR_RO(media),
-       __ATTR_RO(drivename),
-       __ATTR_RO(modalias),
-       __ATTR_RO(model),
-       __ATTR_RO(firmware),
-       __ATTR(serial, 0400, serial_show, NULL),
-       __ATTR(unload_heads, 0644, ide_park_show, ide_park_store),
-       __ATTR_NULL
+const struct attribute_group *ide_dev_groups[] = {
+       &ide_attr_group,
+       NULL,
 };
 
 static ssize_t store_delete_devices(struct device *portdev,
index fa896210ed7b2af40136dd7784737929fbf80b28..2ce6268a27348c9bfab9910da2ea3f9a364b1a44 100644 (file)
@@ -158,7 +158,7 @@ struct bus_type ide_bus_type = {
        .probe          = generic_ide_probe,
        .remove         = generic_ide_remove,
        .shutdown       = generic_ide_shutdown,
-       .dev_attrs      = ide_dev_attrs,
+       .dev_groups     = ide_dev_groups,
        .suspend        = generic_ide_suspend,
        .resume         = generic_ide_resume,
 };
index 81e3dc260993124981d45cacb9e472e9221d7b8a..28b39283bccffaad1fdd13950aaa62dabd2d7248 100644 (file)
@@ -471,13 +471,10 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct bma180_data *data = iio_priv(indio_dev);
+       int64_t time_ns = iio_get_time_ns();
        int bit, ret, i = 0;
 
        mutex_lock(&data->mutex);
-       if (indio_dev->scan_timestamp) {
-               ret = indio_dev->scan_bytes / sizeof(s64) - 1;
-               ((s64 *)data->buff)[ret] = iio_get_time_ns();
-       }
 
        for_each_set_bit(bit, indio_dev->buffer->scan_mask,
                         indio_dev->masklength) {
@@ -490,7 +487,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
        }
        mutex_unlock(&data->mutex);
 
-       iio_push_to_buffers(indio_dev, (u8 *)data->buff);
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
 err:
        iio_trigger_notify_done(indio_dev->trig);
 
index 46d22f3fb1a9bb0c3fb2259b6399fd1642d107d7..dcda17395c4e68f31f3382cd0c393a5845b025c5 100644 (file)
@@ -182,10 +182,11 @@ static const struct iio_info accel_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -200,7 +201,7 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                accel_state->common_attributes.data_ready);
        if (accel_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)accel_state->accel_val,
+                               accel_state->accel_val,
                                sizeof(accel_state->accel_val));
 
        return 0;
index 709c13259f14e8cab35faee7237794be38c24744..d72118d1189c8648161496919ab17f7ad514df95 100644 (file)
@@ -222,7 +222,6 @@ static int kxsd9_probe(struct spi_device *spi)
 {
        struct iio_dev *indio_dev;
        struct kxsd9_state *st;
-       int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (!indio_dev)
@@ -244,11 +243,7 @@ static int kxsd9_probe(struct spi_device *spi)
        spi_setup(spi);
        kxsd9_power_up(st);
 
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               return ret;
-
-       return 0;
+       return iio_device_register(indio_dev);
 }
 
 static int kxsd9_remove(struct spi_device *spi)
index d9b350756f90f11d1bc77cd88362fe45639d295e..a1e642ee13d6a4f8af5eb0f6a9c92bafe51460d9 100644 (file)
@@ -32,16 +32,7 @@ int st_accel_trig_set_state(struct iio_trigger *trig, bool state)
 
 static int st_accel_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_accel_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_accel_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
index 1458343f6f3fac94f5aa882df1e88d2d9ac37ad1..38caedc76b98f20520f9be751fabc15e90b03793 100644 (file)
@@ -452,8 +452,9 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
 int st_accel_common_probe(struct iio_dev *indio_dev,
                                struct st_sensors_platform_data *plat_data)
 {
-       int err;
        struct st_sensor_data *adata = iio_priv(indio_dev);
+       int irq = adata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &accel_info;
@@ -461,7 +462,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
        err = st_sensors_check_device_support(indio_dev,
                                ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
        if (err < 0)
-               goto st_accel_common_probe_error;
+               return err;
 
        adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
        adata->multiread_bit = adata->sensor->multi_read_bit;
@@ -478,13 +479,13 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
 
        err = st_sensors_init_sensor(indio_dev, plat_data);
        if (err < 0)
-               goto st_accel_common_probe_error;
+               return err;
 
-       if (adata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_accel_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_accel_common_probe_error;
+       err = st_accel_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
 
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev,
                                                 ST_ACCEL_TRIGGER_OPS);
                if (err < 0)
@@ -495,15 +496,14 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
        if (err)
                goto st_accel_device_register_error;
 
-       return err;
+       return 0;
 
 st_accel_device_register_error:
-       if (adata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_accel_probe_trigger_error:
-       if (adata->get_irq_data_ready(indio_dev) > 0)
-               st_accel_deallocate_ring(indio_dev);
-st_accel_common_probe_error:
+       st_accel_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_accel_common_probe);
@@ -513,10 +513,10 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
        struct st_sensor_data *adata = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (adata->get_irq_data_ready(indio_dev) > 0) {
+       if (adata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_accel_deallocate_ring(indio_dev);
-       }
+
+       st_accel_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_accel_common_remove);
 
index 09371cbc9dc123d1a1c929d109202a2a6be68f91..2209f28441e94d013ef435a100c17d6920677e08 100644 (file)
@@ -145,6 +145,16 @@ config MCP320X
          This driver can also be built as a module. If so, the module will be
          called mcp320x.
 
+config MCP3422
+       tristate "Microchip Technology MCP3422/3/4 driver"
+       depends on I2C
+       help
+         Say yes here to build support for Microchip Technology's MCP3422,
+         MCP3423 or MCP3424 analog to digital converters.
+
+         This driver can also be built as a module. If so, the module will be
+         called mcp3422.
+
 config NAU7802
        tristate "Nuvoton NAU7802 ADC driver"
        depends on I2C
@@ -167,6 +177,8 @@ config TI_ADC081C
 config TI_AM335X_ADC
        tristate "TI's AM335X ADC driver"
        depends on MFD_TI_AM335X_TSCADC
+       select IIO_BUFFER
+       select IIO_KFIFO_BUF
        help
          Say yes here to build support for Texas Instruments ADC
          driver which is also a MFD client.
index 33656ef7d1f60fbd8b16c0c4bf5fa61ef2cc2506..ba9a10a24cd03ee4d80f4bc2e0a9fd56b106d908 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
+obj-$(CONFIG_MCP3422) += mcp3422.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
index 371731df1634b97a471f51fd67f1a8fbbddef091..58e945594c7bb7e484588820517c1b067b5c2521 100644 (file)
@@ -27,7 +27,7 @@
 struct ad7266_state {
        struct spi_device       *spi;
        struct regulator        *reg;
-       unsigned long           vref_uv;
+       unsigned long           vref_mv;
 
        struct spi_transfer     single_xfer[3];
        struct spi_message      single_msg;
@@ -61,17 +61,7 @@ static int ad7266_powerdown(struct ad7266_state *st)
 static int ad7266_preenable(struct iio_dev *indio_dev)
 {
        struct ad7266_state *st = iio_priv(indio_dev);
-       int ret;
-
-       ret = ad7266_wakeup(st);
-       if (ret)
-               return ret;
-
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret)
-               ad7266_powerdown(st);
-
-       return ret;
+       return ad7266_wakeup(st);
 }
 
 static int ad7266_postdisable(struct iio_dev *indio_dev)
@@ -96,9 +86,8 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
 
        ret = spi_read(st->spi, st->data, 4);
        if (ret == 0) {
-               if (indio_dev->scan_timestamp)
-                       ((s64 *)st->data)[1] = pf->timestamp;
-               iio_push_to_buffers(indio_dev, (u8 *)st->data);
+               iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+                           pf->timestamp);
        }
 
        iio_trigger_notify_done(indio_dev->trig);
@@ -157,7 +146,7 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long m)
 {
        struct ad7266_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
+       unsigned long scale_mv;
        int ret;
 
        switch (m) {
@@ -175,16 +164,15 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
 
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_uv * 100);
+               scale_mv = st->vref_mv;
                if (st->mode == AD7266_MODE_DIFF)
-                       scale_uv *= 2;
+                       scale_mv *= 2;
                if (st->range == AD7266_RANGE_2VREF)
-                       scale_uv *= 2;
+                       scale_mv *= 2;
 
-               scale_uv >>= chan->scan_type.realbits;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = scale_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                if (st->range == AD7266_RANGE_2VREF &&
                        st->mode != AD7266_MODE_DIFF)
@@ -293,7 +281,7 @@ static const struct iio_info ad7266_info = {
        .driver_module = THIS_MODULE,
 };
 
-static unsigned long ad7266_available_scan_masks[] = {
+static const unsigned long ad7266_available_scan_masks[] = {
        0x003,
        0x00c,
        0x030,
@@ -303,14 +291,14 @@ static unsigned long ad7266_available_scan_masks[] = {
        0x000,
 };
 
-static unsigned long ad7266_available_scan_masks_diff[] = {
+static const unsigned long ad7266_available_scan_masks_diff[] = {
        0x003,
        0x00c,
        0x030,
        0x000,
 };
 
-static unsigned long ad7266_available_scan_masks_fixed[] = {
+static const unsigned long ad7266_available_scan_masks_fixed[] = {
        0x003,
        0x000,
 };
@@ -318,7 +306,7 @@ static unsigned long ad7266_available_scan_masks_fixed[] = {
 struct ad7266_chan_info {
        const struct iio_chan_spec *channels;
        unsigned int num_channels;
-       unsigned long *scan_masks;
+       const unsigned long *scan_masks;
 };
 
 #define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \
@@ -415,10 +403,10 @@ static int ad7266_probe(struct spi_device *spi)
                if (ret < 0)
                        goto error_disable_reg;
 
-               st->vref_uv = ret;
+               st->vref_mv = ret / 1000;
        } else {
                /* Use internal reference */
-               st->vref_uv = 2500000;
+               st->vref_mv = 2500;
        }
 
        if (pdata) {
index 85d1481c312f67b1d84208f9003e04c0a9ee6891..2a3b65c74af9aa32543dc4d248216f31646a1c08 100644 (file)
@@ -159,20 +159,14 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7298_state *st = iio_priv(indio_dev);
-       s64 time_ns = 0;
        int b_sent;
 
        b_sent = spi_sync(st->spi, &st->ring_msg);
        if (b_sent)
                goto done;
 
-       if (indio_dev->scan_timestamp) {
-               time_ns = iio_get_time_ns();
-               memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
-                       &time_ns, sizeof(time_ns));
-       }
-
-       iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+               iio_get_time_ns());
 
 done:
        iio_trigger_notify_done(indio_dev->trig);
index 6d2b1d8d1a1f001dbec29f88633ba90fffe15e90..d141d452c3d1081d4bea64ff01e5b38e855fcd9d 100644 (file)
@@ -64,19 +64,14 @@ static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7476_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        int b_sent;
 
        b_sent = spi_sync(st->spi, &st->msg);
        if (b_sent < 0)
                goto done;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               ((s64 *)st->data)[1] = time_ns;
-
-       iio_push_to_buffers(indio_dev, st->data);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+               iio_get_time_ns());
 done:
        iio_trigger_notify_done(indio_dev->trig);
 
@@ -132,10 +127,9 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
                } else {
                        scale_uv = st->chip_info->int_vref_uv;
                }
-               scale_uv >>= chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = scale_uv / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
index c20203577d2d1e38da820299fba5aca0d10a0c37..c19f8fd1b4b7ac9ba5c2b216d5aa7be362200859 100644 (file)
@@ -202,7 +202,6 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
 {
        struct ad7791_state *st = iio_priv(indio_dev);
        bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR);
-       unsigned long long scale_pv;
 
        switch (info) {
        case IIO_CHAN_INFO_RAW:
@@ -220,23 +219,26 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_SCALE:
                /* The monitor channel uses an internal reference. */
                if (chan->address == AD7791_CH_AVDD_MONITOR) {
-                       scale_pv = 5850000000000ULL;
+                       /*
+                        * The signal is attenuated by a factor of 5 and
+                        * compared against a 1.17V internal reference.
+                        */
+                       *val = 1170 * 5;
                } else {
                        int voltage_uv;
 
                        voltage_uv = regulator_get_voltage(st->reg);
                        if (voltage_uv < 0)
                                return voltage_uv;
-                       scale_pv = (unsigned long long)voltage_uv * 1000000;
+
+                       *val = voltage_uv / 1000;
                }
                if (unipolar)
-                       scale_pv >>= chan->scan_type.realbits;
+                       *val2 = chan->scan_type.realbits;
                else
-                       scale_pv >>= chan->scan_type.realbits - 1;
-               *val2 = do_div(scale_pv, 1000000000);
-               *val = scale_pv;
+                       *val2 = chan->scan_type.realbits - 1;
 
-               return IIO_VAL_INT_PLUS_NANO;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
 
        return -EINVAL;
index 9dd077b78759047ae39fde5a8d0a2b589b487b22..acb7f90359a3460371c9d1e8a00cd15c3a77a26d 100644 (file)
@@ -78,11 +78,6 @@ enum ad7887_supported_device_ids {
 static int ad7887_ring_preenable(struct iio_dev *indio_dev)
 {
        struct ad7887_state *st = iio_priv(indio_dev);
-       int ret;
-
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret < 0)
-               return ret;
 
        /* We know this is a single long so can 'cheat' */
        switch (*indio_dev->active_scan_mask) {
@@ -121,20 +116,14 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7887_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        int b_sent;
 
        b_sent = spi_sync(st->spi, st->ring_msg);
        if (b_sent)
                goto done;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
-                      &time_ns, sizeof(time_ns));
-
-       iio_push_to_buffers(indio_dev, st->data);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+               iio_get_time_ns());
 done:
        iio_trigger_notify_done(indio_dev->trig);
 
index 4108dbb28c3d8edfa1b2e20134cf65e38951d55d..28732c28e8197a688c27d1d665458fae24c8a97f 100644 (file)
@@ -174,20 +174,14 @@ static irqreturn_t ad7923_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7923_state *st = iio_priv(indio_dev);
-       s64 time_ns = 0;
        int b_sent;
 
        b_sent = spi_sync(st->spi, &st->ring_msg);
        if (b_sent)
                goto done;
 
-       if (indio_dev->scan_timestamp) {
-               time_ns = iio_get_time_ns();
-               memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
-                       &time_ns, sizeof(time_ns));
-       }
-
-       iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+               iio_get_time_ns());
 
 done:
        iio_trigger_notify_done(indio_dev->trig);
index f0d6335ae08760d418f56ced0eaec227772fa1ce..e6fbd3e70981fca1a4d93d2c03891fcf1efde6c0 100644 (file)
@@ -368,10 +368,6 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
 
        memset(data, 0x00, 16);
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp)
-               ((s64 *)data)[1] = pf->timestamp;
-
        reg_size = indio_dev->channels[0].scan_type.realbits +
                        indio_dev->channels[0].scan_type.shift;
        reg_size = DIV_ROUND_UP(reg_size, 8);
@@ -391,7 +387,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
                break;
        }
 
-       iio_push_to_buffers(indio_dev, (uint8_t *)data);
+       iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
        sigma_delta->irq_dis = false;
@@ -401,7 +397,6 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
 }
 
 static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
-       .preenable = &iio_sw_buffer_preenable,
        .postenable = &ad_sd_buffer_postenable,
        .predisable = &iio_triggered_buffer_predisable,
        .postdisable = &ad_sd_buffer_postdisable,
index 0f16b553e063f602e4e83104382827bb55cc72b2..17df74908db120a6e33e3f43a51fc4e67784da59 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #define at91_adc_writel(st, reg, val) \
        (writel_relaxed(val, st->reg_base + reg))
 
+#define DRIVER_NAME            "at91_adc"
+#define MAX_POS_BITS           12
+
+#define TOUCH_SAMPLE_PERIOD_US         2000    /* 2ms */
+#define TOUCH_PEN_DETECT_DEBOUNCE_US   200
+
 struct at91_adc_caps {
+       bool    has_ts;         /* Support touch screen */
+       bool    has_tsmr;       /* only at91sam9x5, sama5d3 have TSMR reg */
+       /*
+        * Numbers of sampling data will be averaged. Can be 0~3.
+        * Hardware can average (2 ^ ts_filter_average) sample data.
+        */
+       u8      ts_filter_average;
+       /* Pen Detection input pull-up resistor, can be 0~3 */
+       u8      ts_pen_detect_sensitivity;
+
+       /* startup time calculate function */
+       u32 (*calc_startup_ticks)(u8 startup_time, u32 adc_clk_khz);
+
+       u8      num_channels;
        struct at91_adc_reg_desc registers;
 };
 
+enum atmel_adc_ts_type {
+       ATMEL_ADC_TOUCHSCREEN_NONE = 0,
+       ATMEL_ADC_TOUCHSCREEN_4WIRE = 4,
+       ATMEL_ADC_TOUCHSCREEN_5WIRE = 5,
+};
+
 struct at91_adc_state {
        struct clk              *adc_clk;
        u16                     *buffer;
@@ -67,6 +94,26 @@ struct at91_adc_state {
        bool                    low_res;        /* the resolution corresponds to the lowest one */
        wait_queue_head_t       wq_data_avail;
        struct at91_adc_caps    *caps;
+
+       /*
+        * Following ADC channels are shared by touchscreen:
+        *
+        * CH0 -- Touch screen XP/UL
+        * CH1 -- Touch screen XM/UR
+        * CH2 -- Touch screen YP/LL
+        * CH3 -- Touch screen YM/Sense
+        * CH4 -- Touch screen LR(5-wire only)
+        *
+        * The bitfields below represents the reserved channel in the
+        * touchscreen mode.
+        */
+#define CHAN_MASK_TOUCHSCREEN_4WIRE    (0xf << 0)
+#define CHAN_MASK_TOUCHSCREEN_5WIRE    (0x1f << 0)
+       enum atmel_adc_ts_type  touchscreen_type;
+       struct input_dev        *ts_input;
+
+       u16                     ts_sample_period_val;
+       u32                     ts_pressure_threshold;
 };
 
 static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
@@ -83,13 +130,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
                j++;
        }
 
-       if (idev->scan_timestamp) {
-               s64 *timestamp = (s64 *)((u8 *)st->buffer +
-                                       ALIGN(j, sizeof(s64)));
-               *timestamp = pf->timestamp;
-       }
-
-       iio_push_to_buffers(idev, (u8 *)st->buffer);
+       iio_push_to_buffers_with_timestamp(idev, st->buffer, pf->timestamp);
 
        iio_trigger_notify_done(idev->trig);
 
@@ -101,14 +142,10 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
+/* Handler for classic adc channel eoc trigger */
+void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
 {
-       struct iio_dev *idev = private;
        struct at91_adc_state *st = iio_priv(idev);
-       u32 status = at91_adc_readl(st, st->registers->status_register);
-
-       if (!(status & st->registers->drdy_mask))
-               return IRQ_HANDLED;
 
        if (iio_buffer_enabled(idev)) {
                disable_irq_nosync(irq);
@@ -118,6 +155,115 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
                st->done = true;
                wake_up_interruptible(&st->wq_data_avail);
        }
+}
+
+static int at91_ts_sample(struct at91_adc_state *st)
+{
+       unsigned int xscale, yscale, reg, z1, z2;
+       unsigned int x, y, pres, xpos, ypos;
+       unsigned int rxp = 1;
+       unsigned int factor = 1000;
+       struct iio_dev *idev = iio_priv_to_dev(st);
+
+       unsigned int xyz_mask_bits = st->res;
+       unsigned int xyz_mask = (1 << xyz_mask_bits) - 1;
+
+       /* calculate position */
+       /* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */
+       reg = at91_adc_readl(st, AT91_ADC_TSXPOSR);
+       xpos = reg & xyz_mask;
+       x = (xpos << MAX_POS_BITS) - xpos;
+       xscale = (reg >> 16) & xyz_mask;
+       if (xscale == 0) {
+               dev_err(&idev->dev, "Error: xscale == 0!\n");
+               return -1;
+       }
+       x /= xscale;
+
+       /* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */
+       reg = at91_adc_readl(st, AT91_ADC_TSYPOSR);
+       ypos = reg & xyz_mask;
+       y = (ypos << MAX_POS_BITS) - ypos;
+       yscale = (reg >> 16) & xyz_mask;
+       if (yscale == 0) {
+               dev_err(&idev->dev, "Error: yscale == 0!\n");
+               return -1;
+       }
+       y /= yscale;
+
+       /* calculate the pressure */
+       reg = at91_adc_readl(st, AT91_ADC_TSPRESSR);
+       z1 = reg & xyz_mask;
+       z2 = (reg >> 16) & xyz_mask;
+
+       if (z1 != 0)
+               pres = rxp * (x * factor / 1024) * (z2 * factor / z1 - factor)
+                       / factor;
+       else
+               pres = st->ts_pressure_threshold;       /* no pen contacted */
+
+       dev_dbg(&idev->dev, "xpos = %d, xscale = %d, ypos = %d, yscale = %d, z1 = %d, z2 = %d, press = %d\n",
+                               xpos, xscale, ypos, yscale, z1, z2, pres);
+
+       if (pres < st->ts_pressure_threshold) {
+               dev_dbg(&idev->dev, "x = %d, y = %d, pressure = %d\n",
+                                       x, y, pres / factor);
+               input_report_abs(st->ts_input, ABS_X, x);
+               input_report_abs(st->ts_input, ABS_Y, y);
+               input_report_abs(st->ts_input, ABS_PRESSURE, pres);
+               input_report_key(st->ts_input, BTN_TOUCH, 1);
+               input_sync(st->ts_input);
+       } else {
+               dev_dbg(&idev->dev, "pressure too low: not reporting\n");
+       }
+
+       return 0;
+}
+
+static irqreturn_t at91_adc_interrupt(int irq, void *private)
+{
+       struct iio_dev *idev = private;
+       struct at91_adc_state *st = iio_priv(idev);
+       u32 status = at91_adc_readl(st, st->registers->status_register);
+       const uint32_t ts_data_irq_mask =
+               AT91_ADC_IER_XRDY |
+               AT91_ADC_IER_YRDY |
+               AT91_ADC_IER_PRDY;
+
+       if (status & st->registers->drdy_mask)
+               handle_adc_eoc_trigger(irq, idev);
+
+       if (status & AT91_ADC_IER_PEN) {
+               at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN);
+               at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_NOPEN |
+                       ts_data_irq_mask);
+               /* Set up period trigger for sampling */
+               at91_adc_writel(st, st->registers->trigger_register,
+                       AT91_ADC_TRGR_MOD_PERIOD_TRIG |
+                       AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val));
+       } else if (status & AT91_ADC_IER_NOPEN) {
+               at91_adc_writel(st, st->registers->trigger_register, 0);
+               at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_NOPEN |
+                       ts_data_irq_mask);
+               at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN);
+
+               input_report_key(st->ts_input, BTN_TOUCH, 0);
+               input_sync(st->ts_input);
+       } else if ((status & ts_data_irq_mask) == ts_data_irq_mask) {
+               /* Now all touchscreen data is ready */
+
+               if (status & AT91_ADC_ISR_PENS) {
+                       /* validate data by pen contact */
+                       at91_ts_sample(st);
+               } else {
+                       /* triggered by event that is no pen contact, just read
+                        * them to clean the interrupt and discard all.
+                        */
+                       at91_adc_readl(st, AT91_ADC_TSXPOSR);
+                       at91_adc_readl(st, AT91_ADC_TSYPOSR);
+                       at91_adc_readl(st, AT91_ADC_TSPRESSR);
+               }
+       }
 
        return IRQ_HANDLED;
 }
@@ -127,6 +273,16 @@ static int at91_adc_channel_init(struct iio_dev *idev)
        struct at91_adc_state *st = iio_priv(idev);
        struct iio_chan_spec *chan_array, *timestamp;
        int bit, idx = 0;
+       unsigned long rsvd_mask = 0;
+
+       /* If touchscreen is enable, then reserve the adc channels */
+       if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
+               rsvd_mask = CHAN_MASK_TOUCHSCREEN_4WIRE;
+       else if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_5WIRE)
+               rsvd_mask = CHAN_MASK_TOUCHSCREEN_5WIRE;
+
+       /* set up the channel mask to reserve touchscreen channels */
+       st->channels_mask &= ~rsvd_mask;
 
        idev->num_channels = bitmap_weight(&st->channels_mask,
                                           st->num_channels) + 1;
@@ -279,7 +435,7 @@ static int at91_adc_trigger_init(struct iio_dev *idev)
        int i, ret;
 
        st->trig = devm_kzalloc(&idev->dev,
-                               st->trigger_number * sizeof(st->trig),
+                               st->trigger_number * sizeof(*st->trig),
                                GFP_KERNEL);
 
        if (st->trig == NULL) {
@@ -372,9 +528,9 @@ static int at91_adc_read_raw(struct iio_dev *idev,
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
-               *val = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val2 = 0;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -434,8 +590,80 @@ ret:
        return ret;
 }
 
+static u32 calc_startup_ticks_9260(u8 startup_time, u32 adc_clk_khz)
+{
+       /*
+        * Number of ticks needed to cover the startup time of the ADC
+        * as defined in the electrical characteristics of the board,
+        * divided by 8. The formula thus is :
+        *   Startup Time = (ticks + 1) * 8 / ADC Clock
+        */
+       return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8;
+}
+
+static u32 calc_startup_ticks_9x5(u8 startup_time, u32 adc_clk_khz)
+{
+       /*
+        * For sama5d3x and at91sam9x5, the formula changes to:
+        * Startup Time = <lookup_table_value> / ADC Clock
+        */
+       const int startup_lookup[] = {
+               0  , 8  , 16 , 24 ,
+               64 , 80 , 96 , 112,
+               512, 576, 640, 704,
+               768, 832, 896, 960
+               };
+       int i, size = ARRAY_SIZE(startup_lookup);
+       unsigned int ticks;
+
+       ticks = startup_time * adc_clk_khz / 1000;
+       for (i = 0; i < size; i++)
+               if (ticks < startup_lookup[i])
+                       break;
+
+       ticks = i;
+       if (ticks == size)
+               /* Reach the end of lookup table */
+               ticks = size - 1;
+
+       return ticks;
+}
+
 static const struct of_device_id at91_adc_dt_ids[];
 
+static int at91_adc_probe_dt_ts(struct device_node *node,
+       struct at91_adc_state *st, struct device *dev)
+{
+       int ret;
+       u32 prop;
+
+       ret = of_property_read_u32(node, "atmel,adc-ts-wires", &prop);
+       if (ret) {
+               dev_info(dev, "ADC Touch screen is disabled.\n");
+               return 0;
+       }
+
+       switch (prop) {
+       case 4:
+       case 5:
+               st->touchscreen_type = prop;
+               break;
+       default:
+               dev_err(dev, "Unsupported number of touchscreen wires (%d). Should be 4 or 5.\n", prop);
+               return -EINVAL;
+       }
+
+       prop = 0;
+       of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop);
+       st->ts_pressure_threshold = prop;
+       if (st->ts_pressure_threshold) {
+               return 0;
+       } else {
+               dev_err(dev, "Invalid pressure threshold for the touchscreen\n");
+               return -EINVAL;
+       }
+}
+
 static int at91_adc_probe_dt(struct at91_adc_state *st,
                             struct platform_device *pdev)
 {
@@ -460,13 +688,6 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
        }
        st->channels_mask = prop;
 
-       if (of_property_read_u32(node, "atmel,adc-num-channels", &prop)) {
-               dev_err(&idev->dev, "Missing adc-num-channels property in the DT.\n");
-               ret = -EINVAL;
-               goto error_ret;
-       }
-       st->num_channels = prop;
-
        st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode");
 
        if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) {
@@ -492,6 +713,7 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
                goto error_ret;
 
        st->registers = &st->caps->registers;
+       st->num_channels = st->caps->num_channels;
        st->trigger_number = of_get_child_count(node);
        st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number *
                                        sizeof(struct at91_adc_trigger),
@@ -523,6 +745,12 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
                i++;
        }
 
+       /* Check if touchscreen is supported. */
+       if (st->caps->has_ts)
+               return at91_adc_probe_dt_ts(node, st, &idev->dev);
+       else
+               dev_info(&idev->dev, "not support touchscreen in the adc compatible string.\n");
+
        return 0;
 
 error_ret:
@@ -554,6 +782,114 @@ static const struct iio_info at91_adc_info = {
        .read_raw = &at91_adc_read_raw,
 };
 
+/* Touchscreen related functions */
+static int atmel_ts_open(struct input_dev *dev)
+{
+       struct at91_adc_state *st = input_get_drvdata(dev);
+
+       at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN);
+       return 0;
+}
+
+static void atmel_ts_close(struct input_dev *dev)
+{
+       struct at91_adc_state *st = input_get_drvdata(dev);
+
+       at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN);
+}
+
+static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
+{
+       u32 reg = 0, pendbc;
+       int i = 0;
+
+       if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
+               reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS;
+       else
+               reg = AT91_ADC_TSMR_TSMODE_5WIRE;
+
+       /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
+        * pen detect noise.
+        * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock
+        */
+       pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 1000, 1);
+
+       while (pendbc >> ++i)
+               ;       /* Empty! Find the shift offset */
+       if (abs(pendbc - (1 << i)) < abs(pendbc - (1 << (i - 1))))
+               pendbc = i;
+       else
+               pendbc = i - 1;
+
+       if (st->caps->has_tsmr) {
+               reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average)
+                               & AT91_ADC_TSMR_TSAV;
+               reg |= AT91_ADC_TSMR_PENDBC_(pendbc) & AT91_ADC_TSMR_PENDBC;
+               reg |= AT91_ADC_TSMR_NOTSDMA;
+               reg |= AT91_ADC_TSMR_PENDET_ENA;
+               reg |= 0x03 << 8;       /* TSFREQ, need bigger than TSAV */
+
+               at91_adc_writel(st, AT91_ADC_TSMR, reg);
+       } else {
+               /* TODO: for 9g45 which has no TSMR */
+       }
+
+       /* Change adc internal resistor value for better pen detection,
+        * default value is 100 kOhm.
+        * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm
+        * option only available on ES2 and higher
+        */
+       at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity
+                       & AT91_ADC_ACR_PENDETSENS);
+
+       /* Sample Peroid Time = (TRGPER + 1) / ADCClock */
+       st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US *
+                       adc_clk_khz / 1000) - 1, 1);
+
+       return 0;
+}
+
+static int at91_ts_register(struct at91_adc_state *st,
+               struct platform_device *pdev)
+{
+       struct input_dev *input;
+       struct iio_dev *idev = iio_priv_to_dev(st);
+       int ret;
+
+       input = input_allocate_device();
+       if (!input) {
+               dev_err(&idev->dev, "Failed to allocate TS device!\n");
+               return -ENOMEM;
+       }
+
+       input->name = DRIVER_NAME;
+       input->id.bustype = BUS_HOST;
+       input->dev.parent = &pdev->dev;
+       input->open = atmel_ts_open;
+       input->close = atmel_ts_close;
+
+       __set_bit(EV_ABS, input->evbit);
+       __set_bit(EV_KEY, input->evbit);
+       __set_bit(BTN_TOUCH, input->keybit);
+       input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 0, 0);
+       input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 0, 0);
+       input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0);
+
+       st->ts_input = input;
+       input_set_drvdata(input, st);
+
+       ret = input_register_device(input);
+       if (ret)
+               input_free_device(st->ts_input);
+
+       return ret;
+}
+
+static void at91_ts_unregister(struct at91_adc_state *st)
+{
+       input_unregister_device(st->ts_input);
+}
+
 static int at91_adc_probe(struct platform_device *pdev)
 {
        unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim;
@@ -605,7 +941,7 @@ static int at91_adc_probe(struct platform_device *pdev)
        at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST);
        at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF);
        ret = request_irq(st->irq,
-                         at91_adc_eoc_trigger,
+                         at91_adc_interrupt,
                          0,
                          pdev->dev.driver->name,
                          idev);
@@ -650,6 +986,10 @@ static int at91_adc_probe(struct platform_device *pdev)
        mstrclk = clk_get_rate(st->clk);
        adc_clk = clk_get_rate(st->adc_clk);
        adc_clk_khz = adc_clk / 1000;
+
+       dev_dbg(&pdev->dev, "Master clock is set as: %d Hz, adc_clk should set as: %d Hz\n",
+               mstrclk, adc_clk);
+
        prsc = (mstrclk / (2 * adc_clk)) - 1;
 
        if (!st->startup_time) {
@@ -657,14 +997,8 @@ static int at91_adc_probe(struct platform_device *pdev)
                ret = -EINVAL;
                goto error_disable_adc_clk;
        }
+       ticks = (*st->caps->calc_startup_ticks)(st->startup_time, adc_clk_khz);
 
-       /*
-        * Number of ticks needed to cover the startup time of the ADC as
-        * defined in the electrical characteristics of the board, divided by 8.
-        * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock
-        */
-       ticks = round_up((st->startup_time * adc_clk_khz /
-                         1000) - 1, 8) / 8;
        /*
         * a minimal Sample and Hold Time is necessary for the ADC to guarantee
         * the best converted final value between two channels selection
@@ -692,30 +1026,52 @@ static int at91_adc_probe(struct platform_device *pdev)
        init_waitqueue_head(&st->wq_data_avail);
        mutex_init(&st->lock);
 
-       ret = at91_adc_buffer_init(idev);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Couldn't initialize the buffer.\n");
-               goto error_disable_adc_clk;
-       }
+       /*
+        * Since touch screen will set trigger register as period trigger. So
+        * when touch screen is enabled, then we have to disable hardware
+        * trigger for classic adc.
+        */
+       if (!st->touchscreen_type) {
+               ret = at91_adc_buffer_init(idev);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Couldn't initialize the buffer.\n");
+                       goto error_disable_adc_clk;
+               }
 
-       ret = at91_adc_trigger_init(idev);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Couldn't setup the triggers.\n");
-               goto error_unregister_buffer;
+               ret = at91_adc_trigger_init(idev);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Couldn't setup the triggers.\n");
+                       at91_adc_buffer_remove(idev);
+                       goto error_disable_adc_clk;
+               }
+       } else {
+               if (!st->caps->has_tsmr) {
+                       dev_err(&pdev->dev, "We don't support non-TSMR adc\n");
+                       goto error_disable_adc_clk;
+               }
+
+               ret = at91_ts_register(st, pdev);
+               if (ret)
+                       goto error_disable_adc_clk;
+
+               at91_ts_hw_init(st, adc_clk_khz);
        }
 
        ret = iio_device_register(idev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Couldn't register the device.\n");
-               goto error_remove_triggers;
+               goto error_iio_device_register;
        }
 
        return 0;
 
-error_remove_triggers:
-       at91_adc_trigger_remove(idev);
-error_unregister_buffer:
-       at91_adc_buffer_remove(idev);
+error_iio_device_register:
+       if (!st->touchscreen_type) {
+               at91_adc_trigger_remove(idev);
+               at91_adc_buffer_remove(idev);
+       } else {
+               at91_ts_unregister(st);
+       }
 error_disable_adc_clk:
        clk_disable_unprepare(st->adc_clk);
 error_disable_clk:
@@ -731,8 +1087,12 @@ static int at91_adc_remove(struct platform_device *pdev)
        struct at91_adc_state *st = iio_priv(idev);
 
        iio_device_unregister(idev);
-       at91_adc_trigger_remove(idev);
-       at91_adc_buffer_remove(idev);
+       if (!st->touchscreen_type) {
+               at91_adc_trigger_remove(idev);
+               at91_adc_buffer_remove(idev);
+       } else {
+               at91_ts_unregister(st);
+       }
        clk_disable_unprepare(st->adc_clk);
        clk_disable_unprepare(st->clk);
        free_irq(st->irq, idev);
@@ -742,6 +1102,8 @@ static int at91_adc_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_OF
 static struct at91_adc_caps at91sam9260_caps = {
+       .calc_startup_ticks = calc_startup_ticks_9260,
+       .num_channels = 4,
        .registers = {
                .channel_base = AT91_ADC_CHR(0),
                .drdy_mask = AT91_ADC_DRDY,
@@ -753,6 +1115,9 @@ static struct at91_adc_caps at91sam9260_caps = {
 };
 
 static struct at91_adc_caps at91sam9g45_caps = {
+       .has_ts = true,
+       .calc_startup_ticks = calc_startup_ticks_9260,  /* same as 9260 */
+       .num_channels = 8,
        .registers = {
                .channel_base = AT91_ADC_CHR(0),
                .drdy_mask = AT91_ADC_DRDY,
@@ -764,6 +1129,12 @@ static struct at91_adc_caps at91sam9g45_caps = {
 };
 
 static struct at91_adc_caps at91sam9x5_caps = {
+       .has_ts = true,
+       .has_tsmr = true,
+       .ts_filter_average = 3,
+       .ts_pen_detect_sensitivity = 2,
+       .calc_startup_ticks = calc_startup_ticks_9x5,
+       .num_channels = 12,
        .registers = {
                .channel_base = AT91_ADC_CDR0_9X5,
                .drdy_mask = AT91_ADC_SR_DRDY_9X5,
@@ -788,7 +1159,7 @@ static struct platform_driver at91_adc_driver = {
        .probe = at91_adc_probe,
        .remove = at91_adc_remove,
        .driver = {
-                  .name = "at91_adc",
+                  .name = DRIVER_NAME,
                   .of_match_table = of_match_ptr(at91_adc_dt_ids),
        },
 };
index 4fb35d1d74943b72a77e9a5affe4f8f751382b22..6118dced02b6ee1f0479c71961e686ba8b206cce 100644 (file)
@@ -165,6 +165,8 @@ struct max1363_chip_info {
  * @thresh_low:                low threshold values
  * @vref:              Reference voltage regulator
  * @vref_uv:           Actual (external or internal) reference voltage
+ * @send:              function used to send data to the chip
+ * @recv:              function used to receive data from the chip
  */
 struct max1363_state {
        struct i2c_client               *client;
@@ -186,6 +188,10 @@ struct max1363_state {
        s16                             thresh_low[8];
        struct regulator                *vref;
        u32                             vref_uv;
+       int                             (*send)(const struct i2c_client *client,
+                                               const char *buf, int count);
+       int                             (*recv)(const struct i2c_client *client,
+                                               char *buf, int count);
 };
 
 #define MAX1363_MODE_SINGLE(_num, _mask) {                             \
@@ -311,13 +317,37 @@ static const struct max1363_mode
        return NULL;
 }
 
-static int max1363_write_basic_config(struct i2c_client *client,
-                                     unsigned char d1,
-                                     unsigned char d2)
+static int max1363_smbus_send(const struct i2c_client *client, const char *buf,
+               int count)
 {
-       u8 tx_buf[2] = {d1, d2};
+       int i, err;
 
-       return i2c_master_send(client, tx_buf, 2);
+       for (i = err = 0; err == 0 && i < count; ++i)
+               err = i2c_smbus_write_byte(client, buf[i]);
+
+       return err ? err : count;
+}
+
+static int max1363_smbus_recv(const struct i2c_client *client, char *buf,
+               int count)
+{
+       int i, ret;
+
+       for (i = 0; i < count; ++i) {
+               ret = i2c_smbus_read_byte(client);
+               if (ret < 0)
+                       return ret;
+               buf[i] = ret;
+       }
+
+       return count;
+}
+
+static int max1363_write_basic_config(struct max1363_state *st)
+{
+       u8 tx_buf[2] = { st->setupbyte, st->configbyte };
+
+       return st->send(st->client, tx_buf, 2);
 }
 
 static int max1363_set_scan_mode(struct max1363_state *st)
@@ -327,9 +357,7 @@ static int max1363_set_scan_mode(struct max1363_state *st)
                            | MAX1363_SE_DE_MASK);
        st->configbyte |= st->current_mode->conf;
 
-       return max1363_write_basic_config(st->client,
-                                         st->setupbyte,
-                                         st->configbyte);
+       return max1363_write_basic_config(st);
 }
 
 static int max1363_read_single_chan(struct iio_dev *indio_dev,
@@ -366,7 +394,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
        }
        if (st->chip_info->bits != 8) {
                /* Get reading */
-               data = i2c_master_recv(client, rxbuf, 2);
+               data = st->recv(client, rxbuf, 2);
                if (data < 0) {
                        ret = data;
                        goto error_ret;
@@ -375,7 +403,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
                  ((1 << st->chip_info->bits) - 1);
        } else {
                /* Get reading */
-               data = i2c_master_recv(client, rxbuf, 1);
+               data = st->recv(client, rxbuf, 1);
                if (data < 0) {
                        ret = data;
                        goto error_ret;
@@ -397,7 +425,6 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
 {
        struct max1363_state *st = iio_priv(indio_dev);
        int ret;
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
@@ -406,10 +433,9 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
                        return ret;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = st->vref_uv >> st->chip_info->bits;
-               *val = scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->vref_uv / 1000;
+               *val2 = st->chip_info->bits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                return -EINVAL;
        }
@@ -424,11 +450,21 @@ static const enum max1363_modes max1363_mode_list[] = {
        d0m1to2m3, d1m0to3m2,
 };
 
-#define MAX1363_EV_M                                           \
-       (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)      \
-        | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec max1363_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
 
-#define MAX1363_CHAN_U(num, addr, si, bits, evmask)                    \
+#define MAX1363_CHAN_U(num, addr, si, bits, ev_spec, num_ev_spec)      \
        {                                                               \
                .type = IIO_VOLTAGE,                                    \
                .indexed = 1,                                           \
@@ -444,11 +480,12 @@ static const enum max1363_modes max1363_mode_list[] = {
                        .endianness = IIO_BE,                           \
                },                                                      \
                .scan_index = si,                                       \
-               .event_mask = evmask,                                   \
+               .event_spec = ev_spec,                                  \
+               .num_event_specs = num_ev_spec,                         \
        }
 
 /* bipolar channel */
-#define MAX1363_CHAN_B(num, num2, addr, si, bits, evmask)              \
+#define MAX1363_CHAN_B(num, num2, addr, si, bits, ev_spec, num_ev_spec)        \
        {                                                               \
                .type = IIO_VOLTAGE,                                    \
                .differential = 1,                                      \
@@ -466,28 +503,32 @@ static const enum max1363_modes max1363_mode_list[] = {
                        .endianness = IIO_BE,                           \
                },                                                      \
                .scan_index = si,                                       \
-               .event_mask = evmask,                                   \
+               .event_spec = ev_spec,                                  \
+               .num_event_specs = num_ev_spec,                         \
        }
 
-#define MAX1363_4X_CHANS(bits, em) {                   \
-       MAX1363_CHAN_U(0, _s0, 0, bits, em),            \
-       MAX1363_CHAN_U(1, _s1, 1, bits, em),            \
-       MAX1363_CHAN_U(2, _s2, 2, bits, em),            \
-       MAX1363_CHAN_U(3, _s3, 3, bits, em),            \
-       MAX1363_CHAN_B(0, 1, d0m1, 4, bits, em),        \
-       MAX1363_CHAN_B(2, 3, d2m3, 5, bits, em),        \
-       MAX1363_CHAN_B(1, 0, d1m0, 6, bits, em),        \
-       MAX1363_CHAN_B(3, 2, d3m2, 7, bits, em),        \
-       IIO_CHAN_SOFT_TIMESTAMP(8)                      \
+#define MAX1363_4X_CHANS(bits, ev_spec, num_ev_spec) {                 \
+       MAX1363_CHAN_U(0, _s0, 0, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec),      \
+       MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec),      \
+       MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec),      \
+       MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec),      \
+       IIO_CHAN_SOFT_TIMESTAMP(8)                                      \
        }
 
-static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0);
-static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0);
-static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0);
+static const struct iio_chan_spec max1036_channels[] =
+       MAX1363_4X_CHANS(8, NULL, 0);
+static const struct iio_chan_spec max1136_channels[] =
+       MAX1363_4X_CHANS(10, NULL, 0);
+static const struct iio_chan_spec max1236_channels[] =
+       MAX1363_4X_CHANS(12, NULL, 0);
 static const struct iio_chan_spec max1361_channels[] =
-       MAX1363_4X_CHANS(10, MAX1363_EV_M);
+       MAX1363_4X_CHANS(10, max1363_events, ARRAY_SIZE(max1363_events));
 static const struct iio_chan_spec max1363_channels[] =
-       MAX1363_4X_CHANS(12, MAX1363_EV_M);
+       MAX1363_4X_CHANS(12, max1363_events, ARRAY_SIZE(max1363_events));
 
 /* Applies to max1236, max1237 */
 static const enum max1363_modes max1236_mode_list[] = {
@@ -511,32 +552,32 @@ static const enum max1363_modes max1238_mode_list[] = {
        d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
 };
 
-#define MAX1363_12X_CHANS(bits) {                      \
-       MAX1363_CHAN_U(0, _s0, 0, bits, 0),             \
-       MAX1363_CHAN_U(1, _s1, 1, bits, 0),             \
-       MAX1363_CHAN_U(2, _s2, 2, bits, 0),             \
-       MAX1363_CHAN_U(3, _s3, 3, bits, 0),             \
-       MAX1363_CHAN_U(4, _s4, 4, bits, 0),             \
-       MAX1363_CHAN_U(5, _s5, 5, bits, 0),             \
-       MAX1363_CHAN_U(6, _s6, 6, bits, 0),             \
-       MAX1363_CHAN_U(7, _s7, 7, bits, 0),             \
-       MAX1363_CHAN_U(8, _s8, 8, bits, 0),             \
-       MAX1363_CHAN_U(9, _s9, 9, bits, 0),             \
-       MAX1363_CHAN_U(10, _s10, 10, bits, 0),          \
-       MAX1363_CHAN_U(11, _s11, 11, bits, 0),          \
-       MAX1363_CHAN_B(0, 1, d0m1, 12, bits, 0),        \
-       MAX1363_CHAN_B(2, 3, d2m3, 13, bits, 0),        \
-       MAX1363_CHAN_B(4, 5, d4m5, 14, bits, 0),        \
-       MAX1363_CHAN_B(6, 7, d6m7, 15, bits, 0),        \
-       MAX1363_CHAN_B(8, 9, d8m9, 16, bits, 0),        \
-       MAX1363_CHAN_B(10, 11, d10m11, 17, bits, 0),    \
-       MAX1363_CHAN_B(1, 0, d1m0, 18, bits, 0),        \
-       MAX1363_CHAN_B(3, 2, d3m2, 19, bits, 0),        \
-       MAX1363_CHAN_B(5, 4, d5m4, 20, bits, 0),        \
-       MAX1363_CHAN_B(7, 6, d7m6, 21, bits, 0),        \
-       MAX1363_CHAN_B(9, 8, d9m8, 22, bits, 0),        \
-       MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0),    \
-       IIO_CHAN_SOFT_TIMESTAMP(24)                     \
+#define MAX1363_12X_CHANS(bits) {                              \
+       MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),               \
+       MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),               \
+       MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),               \
+       MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),               \
+       MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),               \
+       MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),               \
+       MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),               \
+       MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),               \
+       MAX1363_CHAN_U(8, _s8, 8, bits, NULL, 0),               \
+       MAX1363_CHAN_U(9, _s9, 9, bits, NULL, 0),               \
+       MAX1363_CHAN_U(10, _s10, 10, bits, NULL, 0),            \
+       MAX1363_CHAN_U(11, _s11, 11, bits, NULL, 0),            \
+       MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0),          \
+       MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0),          \
+       MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0),          \
+       MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0),          \
+       MAX1363_CHAN_B(8, 9, d8m9, 16, bits, NULL, 0),          \
+       MAX1363_CHAN_B(10, 11, d10m11, 17, bits, NULL, 0),      \
+       MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0),          \
+       MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0),          \
+       MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0),          \
+       MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0),          \
+       MAX1363_CHAN_B(9, 8, d9m8, 22, bits, NULL, 0),          \
+       MAX1363_CHAN_B(11, 10, d11m10, 23, bits, NULL, 0),      \
+       IIO_CHAN_SOFT_TIMESTAMP(24)                             \
        }
 static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
 static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
@@ -561,22 +602,22 @@ static const enum max1363_modes max11608_mode_list[] = {
 };
 
 #define MAX1363_8X_CHANS(bits) {                       \
-       MAX1363_CHAN_U(0, _s0, 0, bits, 0),             \
-       MAX1363_CHAN_U(1, _s1, 1, bits, 0),             \
-       MAX1363_CHAN_U(2, _s2, 2, bits, 0),             \
-       MAX1363_CHAN_U(3, _s3, 3, bits, 0),             \
-       MAX1363_CHAN_U(4, _s4, 4, bits, 0),             \
-       MAX1363_CHAN_U(5, _s5, 5, bits, 0),             \
-       MAX1363_CHAN_U(6, _s6, 6, bits, 0),             \
-       MAX1363_CHAN_U(7, _s7, 7, bits, 0),             \
-       MAX1363_CHAN_B(0, 1, d0m1, 8, bits, 0), \
-       MAX1363_CHAN_B(2, 3, d2m3, 9, bits, 0), \
-       MAX1363_CHAN_B(4, 5, d4m5, 10, bits, 0),        \
-       MAX1363_CHAN_B(6, 7, d6m7, 11, bits, 0),        \
-       MAX1363_CHAN_B(1, 0, d1m0, 12, bits, 0),        \
-       MAX1363_CHAN_B(3, 2, d3m2, 13, bits, 0),        \
-       MAX1363_CHAN_B(5, 4, d5m4, 14, bits, 0),        \
-       MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0),        \
+       MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),       \
+       MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),       \
+       MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),       \
+       MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),       \
+       MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),       \
+       MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),       \
+       MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),       \
+       MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),       \
+       MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0),   \
+       MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0),   \
+       MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0),  \
+       MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0),  \
+       MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0),  \
+       MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0),  \
+       MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0),  \
+       MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0),  \
        IIO_CHAN_SOFT_TIMESTAMP(16)                     \
 }
 static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
@@ -588,10 +629,10 @@ static const enum max1363_modes max11644_mode_list[] = {
 };
 
 #define MAX1363_2X_CHANS(bits) {                       \
-       MAX1363_CHAN_U(0, _s0, 0, bits, 0),             \
-       MAX1363_CHAN_U(1, _s1, 1, bits, 0),             \
-       MAX1363_CHAN_B(0, 1, d0m1, 2, bits, 0), \
-       MAX1363_CHAN_B(1, 0, d1m0, 3, bits, 0), \
+       MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),       \
+       MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),       \
+       MAX1363_CHAN_B(0, 1, d0m1, 2, bits, NULL, 0),   \
+       MAX1363_CHAN_B(1, 0, d1m0, 3, bits, NULL, 0),   \
        IIO_CHAN_SOFT_TIMESTAMP(4)                      \
        }
 
@@ -686,20 +727,22 @@ static IIO_CONST_ATTR(sampling_frequency_available,
                "133000 665000 33300 16600 8300 4200 2000 1000");
 
 static int max1363_read_thresh(struct iio_dev *indio_dev,
-                              u64 event_code,
-                              int *val)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, enum iio_event_info info, int *val,
+       int *val2)
 {
        struct max1363_state *st = iio_priv(indio_dev);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
-               *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)];
+       if (dir == IIO_EV_DIR_FALLING)
+               *val = st->thresh_low[chan->channel];
        else
-               *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)];
-       return 0;
+               *val = st->thresh_high[chan->channel];
+       return IIO_VAL_INT;
 }
 
 static int max1363_write_thresh(struct iio_dev *indio_dev,
-                               u64 event_code,
-                               int val)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, enum iio_event_info info, int val,
+       int val2)
 {
        struct max1363_state *st = iio_priv(indio_dev);
        /* make it handle signed correctly as well */
@@ -714,13 +757,15 @@ static int max1363_write_thresh(struct iio_dev *indio_dev,
                break;
        }
 
-       switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       switch (dir) {
        case IIO_EV_DIR_FALLING:
-               st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val;
+               st->thresh_low[chan->channel] = val;
                break;
        case IIO_EV_DIR_RISING:
-               st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val;
+               st->thresh_high[chan->channel] = val;
                break;
+       default:
+               return -EINVAL;
        }
 
        return 0;
@@ -755,24 +800,25 @@ static irqreturn_t max1363_event_handler(int irq, void *private)
        u8 tx[2] = { st->setupbyte,
                     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
 
-       i2c_master_recv(st->client, &rx, 1);
+       st->recv(st->client, &rx, 1);
        mask = rx;
        for_each_set_bit(loc, &mask, 8)
                iio_push_event(indio_dev, max1363_event_codes[loc], timestamp);
-       i2c_master_send(st->client, tx, 2);
+       st->send(st->client, tx, 2);
 
        return IRQ_HANDLED;
 }
 
 static int max1363_read_event_config(struct iio_dev *indio_dev,
-                                    u64 event_code)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        struct max1363_state *st = iio_priv(indio_dev);
        int val;
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+       int number = chan->channel;
 
        mutex_lock(&indio_dev->mlock);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+       if (dir == IIO_EV_DIR_FALLING)
                val = (1 << number) & st->mask_low;
        else
                val = (1 << number) & st->mask_high;
@@ -794,9 +840,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
                st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP;
                st->configbyte &= ~MAX1363_SCAN_MASK;
                st->monitor_on = false;
-               return max1363_write_basic_config(st->client,
-                                               st->setupbyte,
-                                               st->configbyte);
+               return max1363_write_basic_config(st);
        }
 
        /* Ensure we are in the relevant mode */
@@ -858,7 +902,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
                }
 
 
-       ret = i2c_master_send(st->client, tx_buf, len);
+       ret = st->send(st->client, tx_buf, len);
        if (ret < 0)
                goto error_ret;
        if (ret != len) {
@@ -875,7 +919,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
         */
        tx_buf[0] = st->setupbyte;
        tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0;
-       ret = i2c_master_send(st->client, tx_buf, 2);
+       ret = st->send(st->client, tx_buf, 2);
        if (ret < 0)
                goto error_ret;
        if (ret != 2) {
@@ -917,17 +961,17 @@ error_ret:
 }
 
 static int max1363_write_event_config(struct iio_dev *indio_dev,
-                                     u64 event_code,
-                                     int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        int ret = 0;
        struct max1363_state *st = iio_priv(indio_dev);
        u16 unifiedmask;
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+       int number = chan->channel;
 
        mutex_lock(&indio_dev->mlock);
        unifiedmask = st->mask_low | st->mask_high;
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) {
+       if (dir == IIO_EV_DIR_FALLING) {
 
                if (state == 0)
                        st->mask_low &= ~(1 << number);
@@ -995,10 +1039,10 @@ static const struct iio_info max1238_info = {
 };
 
 static const struct iio_info max1363_info = {
-       .read_event_value = &max1363_read_thresh,
-       .write_event_value = &max1363_write_thresh,
-       .read_event_config = &max1363_read_event_config,
-       .write_event_config = &max1363_write_event_config,
+       .read_event_value_new = &max1363_read_thresh,
+       .write_event_value_new = &max1363_write_thresh,
+       .read_event_config_new = &max1363_read_event_config,
+       .write_event_config_new = &max1363_write_event_config,
        .read_raw = &max1363_read_raw,
        .update_scan_mode = &max1363_update_scan_mode,
        .driver_module = THIS_MODULE,
@@ -1436,7 +1480,6 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct max1363_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        __u8 *rxbuf;
        int b_sent;
        size_t d_size;
@@ -1464,17 +1507,13 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
        if (rxbuf == NULL)
                goto done;
        if (st->chip_info->bits != 8)
-               b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
+               b_sent = st->recv(st->client, rxbuf, numvals * 2);
        else
-               b_sent = i2c_master_recv(st->client, rxbuf, numvals);
+               b_sent = st->recv(st->client, rxbuf, numvals);
        if (b_sent < 0)
                goto done_free;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
-       iio_push_to_buffers(indio_dev, rxbuf);
+       iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, iio_get_time_ns());
 
 done_free:
        kfree(rxbuf);
@@ -1484,12 +1523,6 @@ done:
        return IRQ_HANDLED;
 }
 
-static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = {
-       .postenable = &iio_triggered_buffer_postenable,
-       .preenable = &iio_sw_buffer_preenable,
-       .predisable = &iio_triggered_buffer_predisable,
-};
-
 static int max1363_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
@@ -1543,6 +1576,18 @@ static int max1363_probe(struct i2c_client *client,
                st->vref_uv = vref_uv;
        }
 
+       if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               st->send = i2c_master_send;
+               st->recv = i2c_master_recv;
+       } else if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)
+                       && st->chip_info->bits == 8) {
+               st->send = max1363_smbus_send;
+               st->recv = max1363_smbus_recv;
+       } else {
+               ret = -EOPNOTSUPP;
+               goto error_disable_reg;
+       }
+
        ret = max1363_alloc_scan_masks(indio_dev);
        if (ret)
                goto error_disable_reg;
@@ -1559,7 +1604,7 @@ static int max1363_probe(struct i2c_client *client,
                goto error_disable_reg;
 
        ret = iio_triggered_buffer_setup(indio_dev, NULL,
-               &max1363_trigger_handler, &max1363_buffered_setup_ops);
+               &max1363_trigger_handler, NULL);
        if (ret)
                goto error_disable_reg;
 
diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c
new file mode 100644 (file)
index 0000000..1294832
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * mcp3422.c - driver for the Microchip mcp3422/3/4 chip family
+ *
+ * Copyright (C) 2013, Angelo Compagnucci
+ * Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+ *
+ * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
+ *
+ * This driver exports the value of analog input voltage to sysfs, the
+ * voltage unit is nV.
+ *
+ * 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/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/of.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+/* Masks */
+#define MCP3422_CHANNEL_MASK   0x60
+#define MCP3422_PGA_MASK       0x03
+#define MCP3422_SRATE_MASK     0x0C
+#define MCP3422_SRATE_240      0x0
+#define MCP3422_SRATE_60       0x1
+#define MCP3422_SRATE_15       0x2
+#define MCP3422_SRATE_3        0x3
+#define MCP3422_PGA_1  0
+#define MCP3422_PGA_2  1
+#define MCP3422_PGA_4  2
+#define MCP3422_PGA_8  3
+#define MCP3422_CONT_SAMPLING  0x10
+
+#define MCP3422_CHANNEL(config)        (((config) & MCP3422_CHANNEL_MASK) >> 5)
+#define MCP3422_PGA(config)    ((config) & MCP3422_PGA_MASK)
+#define MCP3422_SAMPLE_RATE(config)    (((config) & MCP3422_SRATE_MASK) >> 2)
+
+#define MCP3422_CHANNEL_VALUE(value) (((value) << 5) & MCP3422_CHANNEL_MASK)
+#define MCP3422_PGA_VALUE(value) ((value) & MCP3422_PGA_MASK)
+#define MCP3422_SAMPLE_RATE_VALUE(value) ((value << 2) & MCP3422_SRATE_MASK)
+
+#define MCP3422_CHAN(_index) \
+       { \
+               .type = IIO_VOLTAGE, \
+               .indexed = 1, \
+               .channel = _index, \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
+                               | BIT(IIO_CHAN_INFO_SCALE), \
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+       }
+
+/* LSB is in nV to eliminate floating point */
+static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625};
+
+/*
+ *  scales calculated as:
+ *  rates_to_lsb[sample_rate] / (1 << pga);
+ *  pga is 1 for 0, 2
+ */
+
+static const int mcp3422_scales[4][4] = {
+       { 1000000, 250000, 62500, 15625 },
+       { 500000 , 125000, 31250, 7812 },
+       { 250000 , 62500 , 15625, 3906 },
+       { 125000 , 31250 , 7812 , 1953 } };
+
+/* Constant msleep times for data acquisitions */
+static const int mcp3422_read_times[4] = {
+       [MCP3422_SRATE_240] = 1000 / 240,
+       [MCP3422_SRATE_60] = 1000 / 60,
+       [MCP3422_SRATE_15] = 1000 / 15,
+       [MCP3422_SRATE_3] = 1000 / 3 };
+
+/* sample rates to integer conversion table */
+static const int mcp3422_sample_rates[4] = {
+       [MCP3422_SRATE_240] = 240,
+       [MCP3422_SRATE_60] = 60,
+       [MCP3422_SRATE_15] = 15,
+       [MCP3422_SRATE_3] = 3 };
+
+/* 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 };
+
+/* Client data (each client gets its own) */
+struct mcp3422 {
+       struct i2c_client *i2c;
+       u8 config;
+       u8 pga[4];
+       struct mutex lock;
+};
+
+static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
+{
+       int ret;
+
+       mutex_lock(&adc->lock);
+
+       ret = i2c_master_send(adc->i2c, &newconfig, 1);
+       if (ret > 0) {
+               adc->config = newconfig;
+               ret = 0;
+       }
+
+       mutex_unlock(&adc->lock);
+
+       return ret;
+}
+
+static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config)
+{
+       int ret = 0;
+       u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+       u8 buf[4] = {0, 0, 0, 0};
+       u32 temp;
+
+       if (sample_rate == MCP3422_SRATE_3) {
+               ret = i2c_master_recv(adc->i2c, buf, 4);
+               temp = buf[0] << 16 | buf[1] << 8 | buf[2];
+               *config = buf[3];
+       } else {
+               ret = i2c_master_recv(adc->i2c, buf, 3);
+               temp = buf[0] << 8 | buf[1];
+               *config = buf[2];
+       }
+
+       *value = sign_extend32(temp, mcp3422_sign_extend[sample_rate]);
+
+       return ret;
+}
+
+static int mcp3422_read_channel(struct mcp3422 *adc,
+                               struct iio_chan_spec const *channel, int *value)
+{
+       int ret;
+       u8 config;
+       u8 req_channel = channel->channel;
+
+       if (req_channel != MCP3422_CHANNEL(adc->config)) {
+               config = adc->config;
+               config &= ~MCP3422_CHANNEL_MASK;
+               config |= MCP3422_CHANNEL_VALUE(req_channel);
+               config &= ~MCP3422_PGA_MASK;
+               config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
+               ret = mcp3422_update_config(adc, config);
+               if (ret < 0)
+                       return ret;
+               msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
+       }
+
+       return mcp3422_read(adc, value, &config);
+}
+
+static int mcp3422_read_raw(struct iio_dev *iio,
+                       struct iio_chan_spec const *channel, int *val1,
+                       int *val2, long mask)
+{
+       struct mcp3422 *adc = iio_priv(iio);
+       int err;
+
+       u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+       u8 pga           = MCP3422_PGA(adc->config);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               err = mcp3422_read_channel(adc, channel, val1);
+               if (err < 0)
+                       return -EINVAL;
+               return IIO_VAL_INT;
+
+       case IIO_CHAN_INFO_SCALE:
+
+               *val1 = 0;
+               *val2 = mcp3422_scales[sample_rate][pga];
+               return IIO_VAL_INT_PLUS_NANO;
+
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val1 = mcp3422_sample_rates[MCP3422_SAMPLE_RATE(adc->config)];
+               return IIO_VAL_INT;
+
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int mcp3422_write_raw(struct iio_dev *iio,
+                       struct iio_chan_spec const *channel, int val1,
+                       int val2, long mask)
+{
+       struct mcp3422 *adc = iio_priv(iio);
+       u8 temp;
+       u8 config = adc->config;
+       u8 req_channel = channel->channel;
+       u8 sample_rate = MCP3422_SAMPLE_RATE(config);
+       u8 i;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               if (val1 != 0)
+                       return -EINVAL;
+
+               for (i = 0; i < ARRAY_SIZE(mcp3422_scales[0]); i++) {
+                       if (val2 == mcp3422_scales[sample_rate][i]) {
+                               adc->pga[req_channel] = i;
+
+                               config &= ~MCP3422_CHANNEL_MASK;
+                               config |= MCP3422_CHANNEL_VALUE(req_channel);
+                               config &= ~MCP3422_PGA_MASK;
+                               config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
+
+                               return mcp3422_update_config(adc, config);
+                       }
+               }
+               return -EINVAL;
+
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               switch (val1) {
+               case 240:
+                       temp = MCP3422_SRATE_240;
+                       break;
+               case 60:
+                       temp = MCP3422_SRATE_60;
+                       break;
+               case 15:
+                       temp = MCP3422_SRATE_15;
+                       break;
+               case 3:
+                       temp = MCP3422_SRATE_3;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               config &= ~MCP3422_CHANNEL_MASK;
+               config |= MCP3422_CHANNEL_VALUE(req_channel);
+               config &= ~MCP3422_SRATE_MASK;
+               config |= MCP3422_SAMPLE_RATE_VALUE(temp);
+
+               return mcp3422_update_config(adc, config);
+
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev,
+               struct iio_chan_spec const *chan, long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static ssize_t mcp3422_show_scales(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev));
+       u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+
+       return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n",
+               mcp3422_scales[sample_rate][0],
+               mcp3422_scales[sample_rate][1],
+               mcp3422_scales[sample_rate][2],
+               mcp3422_scales[sample_rate][3]);
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("240 60 15 3");
+static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
+               mcp3422_show_scales, NULL, 0);
+
+static struct attribute *mcp3422_attributes[] = {
+       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+       &iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group mcp3422_attribute_group = {
+       .attrs = mcp3422_attributes,
+};
+
+static const struct iio_chan_spec mcp3422_channels[] = {
+       MCP3422_CHAN(0),
+       MCP3422_CHAN(1),
+};
+
+static const struct iio_chan_spec mcp3424_channels[] = {
+       MCP3422_CHAN(0),
+       MCP3422_CHAN(1),
+       MCP3422_CHAN(2),
+       MCP3422_CHAN(3),
+};
+
+static const struct iio_info mcp3422_info = {
+       .read_raw = mcp3422_read_raw,
+       .write_raw = mcp3422_write_raw,
+       .write_raw_get_fmt = mcp3422_write_raw_get_fmt,
+       .attrs = &mcp3422_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static int mcp3422_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct iio_dev *indio_dev;
+       struct mcp3422 *adc;
+       int err;
+       u8 config;
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+               return -ENODEV;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adc));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       adc = iio_priv(indio_dev);
+       adc->i2c = client;
+
+       mutex_init(&adc->lock);
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->name = dev_name(&client->dev);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->info = &mcp3422_info;
+
+       switch ((unsigned int)(id->driver_data)) {
+       case 2:
+       case 3:
+               indio_dev->channels = mcp3422_channels;
+               indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
+               break;
+       case 4:
+               indio_dev->channels = mcp3424_channels;
+               indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
+               break;
+       }
+
+       /* meaningful default configuration */
+       config = (MCP3422_CONT_SAMPLING
+               | MCP3422_CHANNEL_VALUE(1)
+               | MCP3422_PGA_VALUE(MCP3422_PGA_1)
+               | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240));
+       mcp3422_update_config(adc, config);
+
+       err = iio_device_register(indio_dev);
+       if (err < 0)
+               return err;
+
+       i2c_set_clientdata(client, indio_dev);
+
+       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 },
+       { "mcp3424", 4 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mcp3422_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id mcp3422_of_match[] = {
+       { .compatible = "mcp3422" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mcp3422_of_match);
+#endif
+
+static struct i2c_driver mcp3422_driver = {
+       .driver = {
+               .name = "mcp3422",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(mcp3422_of_match),
+       },
+       .probe = mcp3422_probe,
+       .remove = mcp3422_remove,
+       .id_table = mcp3422_id,
+};
+module_i2c_driver(mcp3422_driver);
+
+MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>");
+MODULE_DESCRIPTION("Microchip mcp3422/3/4 driver");
+MODULE_LICENSE("GPL v2");
index bdf03468f3b8d3e73417c3ad8d841b376d482a33..54c5babe67469bede8e70412470a24dd901e9000 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/wait.h>
 #include <linux/log2.h>
+#include <linux/of.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -569,7 +570,7 @@ static struct i2c_driver nau7802_driver = {
        .id_table = nau7802_i2c_id,
        .driver = {
                   .name = "nau7802",
-                  .of_match_table = of_match_ptr(nau7802_dt_ids),
+                  .of_match_table = nau7802_dt_ids,
        },
 };
 
index ee5f72bffe5a8f993276d480ba5a65e685ada659..b3a82b4d1a7587b586077982f27856dcfdb7dee5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
+#include <linux/of.h>
 
 #include <linux/iio/iio.h>
 #include <linux/regulator/consumer.h>
index a952538a1a8b5be11078744f1463d45067dee567..728411ec764203c371270c390ac77176d788ffd9 100644 (file)
 #include <linux/iio/driver.h>
 
 #include <linux/mfd/ti_am335x_tscadc.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/kfifo_buf.h>
 
 struct tiadc_device {
        struct ti_tscadc_dev *mfd_tscadc;
        int channels;
        u8 channel_line[8];
        u8 channel_step[8];
+       int buffer_en_ch_steps;
+       u16 data[8];
 };
 
 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -56,8 +60,14 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
        return step_en;
 }
 
-static void tiadc_step_config(struct tiadc_device *adc_dev)
+static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
 {
+       return 1 << adc_dev->channel_step[chan];
+}
+
+static void tiadc_step_config(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
        unsigned int stepconfig;
        int i, steps;
 
@@ -72,7 +82,11 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
         */
 
        steps = TOTAL_STEPS - adc_dev->channels;
-       stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
+       if (iio_buffer_enabled(indio_dev))
+               stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
+                                       | STEPCONFIG_MODE_SWCNT;
+       else
+               stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
 
        for (i = 0; i < adc_dev->channels; i++) {
                int chan;
@@ -85,9 +99,175 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
                adc_dev->channel_step[i] = steps;
                steps++;
        }
+}
+
+static irqreturn_t tiadc_irq_h(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       unsigned int status, config;
+       status = tiadc_readl(adc_dev, REG_IRQSTATUS);
+
+       /*
+        * ADC and touchscreen share the IRQ line.
+        * FIFO0 interrupts are used by TSC. Handle FIFO1 IRQs here only
+        */
+       if (status & IRQENB_FIFO1OVRRUN) {
+               /* FIFO Overrun. Clear flag. Disable/Enable ADC to recover */
+               config = tiadc_readl(adc_dev, REG_CTRL);
+               config &= ~(CNTRLREG_TSCSSENB);
+               tiadc_writel(adc_dev, REG_CTRL, config);
+               tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
+                               | IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
+               tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
+               return IRQ_HANDLED;
+       } else if (status & IRQENB_FIFO1THRES) {
+               /* Disable irq and wake worker thread */
+               tiadc_writel(adc_dev, REG_IRQCLR, IRQENB_FIFO1THRES);
+               return IRQ_WAKE_THREAD;
+       }
+
+       return IRQ_NONE;
+}
+
+static irqreturn_t tiadc_worker_h(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       int i, k, fifo1count, read;
+       u16 *data = adc_dev->data;
+
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       for (k = 0; k < fifo1count; k = k + i) {
+               for (i = 0; i < (indio_dev->scan_bytes)/2; i++) {
+                       read = tiadc_readl(adc_dev, REG_FIFO1);
+                       data[i] = read & FIFOREAD_DATA_MASK;
+               }
+               iio_push_to_buffers(indio_dev, (u8 *) data);
+       }
+
+       tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES);
+       tiadc_writel(adc_dev, REG_IRQENABLE, IRQENB_FIFO1THRES);
 
+       return IRQ_HANDLED;
 }
 
+static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       int i, fifo1count, read;
+
+       tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
+                               IRQENB_FIFO1OVRRUN |
+                               IRQENB_FIFO1UNDRFLW));
+
+       /* Flush FIFO. Needed in corner cases in simultaneous tsc/adc use */
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       for (i = 0; i < fifo1count; i++)
+               read = tiadc_readl(adc_dev, REG_FIFO1);
+
+       return 0;
+}
+
+static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       struct iio_buffer *buffer = indio_dev->buffer;
+       unsigned int enb = 0;
+       u8 bit;
+
+       tiadc_step_config(indio_dev);
+       for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels)
+               enb |= (get_adc_step_bit(adc_dev, bit) << 1);
+       adc_dev->buffer_en_ch_steps = enb;
+
+       am335x_tsc_se_set(adc_dev->mfd_tscadc, enb);
+
+       tiadc_writel(adc_dev,  REG_IRQSTATUS, IRQENB_FIFO1THRES
+                               | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
+       tiadc_writel(adc_dev,  REG_IRQENABLE, IRQENB_FIFO1THRES
+                               | IRQENB_FIFO1OVRRUN);
+
+       return 0;
+}
+
+static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       int fifo1count, i, read;
+
+       tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
+                               IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
+       am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
+
+       /* Flush FIFO of leftover data in the time it takes to disable adc */
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       for (i = 0; i < fifo1count; i++)
+               read = tiadc_readl(adc_dev, REG_FIFO1);
+
+       return 0;
+}
+
+static int tiadc_buffer_postdisable(struct iio_dev *indio_dev)
+{
+       tiadc_step_config(indio_dev);
+
+       return 0;
+}
+
+static const struct iio_buffer_setup_ops tiadc_buffer_setup_ops = {
+       .preenable = &tiadc_buffer_preenable,
+       .postenable = &tiadc_buffer_postenable,
+       .predisable = &tiadc_buffer_predisable,
+       .postdisable = &tiadc_buffer_postdisable,
+};
+
+static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
+       irqreturn_t (*pollfunc_bh)(int irq, void *p),
+       irqreturn_t (*pollfunc_th)(int irq, void *p),
+       int irq,
+       unsigned long flags,
+       const struct iio_buffer_setup_ops *setup_ops)
+{
+       int ret;
+
+       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
+       if (!indio_dev->buffer)
+               return -ENOMEM;
+
+       ret = request_threaded_irq(irq, pollfunc_th, pollfunc_bh,
+                               flags, indio_dev->name, indio_dev);
+       if (ret)
+               goto error_kfifo_free;
+
+       indio_dev->setup_ops = setup_ops;
+       indio_dev->modes |= INDIO_BUFFER_HARDWARE;
+
+       ret = iio_buffer_register(indio_dev,
+                                 indio_dev->channels,
+                                 indio_dev->num_channels);
+       if (ret)
+               goto error_free_irq;
+
+       return 0;
+
+error_free_irq:
+       free_irq(irq, indio_dev);
+error_kfifo_free:
+       iio_kfifo_free(indio_dev->buffer);
+       return ret;
+}
+
+static void tiadc_iio_buffered_hardware_remove(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+
+       free_irq(adc_dev->mfd_tscadc->irq, indio_dev);
+       iio_kfifo_free(indio_dev->buffer);
+       iio_buffer_unregister(indio_dev);
+}
+
+
 static const char * const chan_name_ain[] = {
        "AIN0",
        "AIN1",
@@ -120,9 +300,10 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
                chan->channel = adc_dev->channel_line[i];
                chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
                chan->datasheet_name = chan_name_ain[chan->channel];
+               chan->scan_index = i;
                chan->scan_type.sign = 'u';
                chan->scan_type.realbits = 12;
-               chan->scan_type.storagebits = 32;
+               chan->scan_type.storagebits = 16;
        }
 
        indio_dev->channels = chan_array;
@@ -142,11 +323,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
        struct tiadc_device *adc_dev = iio_priv(indio_dev);
        int i, map_val;
        unsigned int fifo1count, read, stepid;
-       u32 step = UINT_MAX;
        bool found = false;
        u32 step_en;
        unsigned long timeout = jiffies + usecs_to_jiffies
                                (IDLE_TIMEOUT * adc_dev->channels);
+
+       if (iio_buffer_enabled(indio_dev))
+               return -EBUSY;
+
        step_en = get_adc_step_mask(adc_dev);
        am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
 
@@ -168,15 +352,6 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
         * Hence we need to flush out this data.
         */
 
-       for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
-               if (chan->channel == adc_dev->channel_line[i]) {
-                       step = adc_dev->channel_step[i];
-                       break;
-               }
-       }
-       if (WARN_ON_ONCE(step == UINT_MAX))
-               return -EINVAL;
-
        fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
        for (i = 0; i < fifo1count; i++) {
                read = tiadc_readl(adc_dev, REG_FIFO1);
@@ -186,7 +361,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
                if (stepid == map_val) {
                        read = read & FIFOREAD_DATA_MASK;
                        found = true;
-                       *val = read;
+                       *val = (u16) read;
                }
        }
 
@@ -237,20 +412,33 @@ static int tiadc_probe(struct platform_device *pdev)
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &tiadc_info;
 
-       tiadc_step_config(adc_dev);
+       tiadc_step_config(indio_dev);
+       tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
 
        err = tiadc_channel_init(indio_dev, adc_dev->channels);
        if (err < 0)
                return err;
 
-       err = iio_device_register(indio_dev);
+       err = tiadc_iio_buffered_hardware_setup(indio_dev,
+               &tiadc_worker_h,
+               &tiadc_irq_h,
+               adc_dev->mfd_tscadc->irq,
+               IRQF_SHARED,
+               &tiadc_buffer_setup_ops);
+
        if (err)
                goto err_free_channels;
 
+       err = iio_device_register(indio_dev);
+       if (err)
+               goto err_buffer_unregister;
+
        platform_set_drvdata(pdev, indio_dev);
 
        return 0;
 
+err_buffer_unregister:
+       tiadc_iio_buffered_hardware_remove(indio_dev);
 err_free_channels:
        tiadc_channels_remove(indio_dev);
        return err;
@@ -263,6 +451,7 @@ static int tiadc_remove(struct platform_device *pdev)
        u32 step_en;
 
        iio_device_unregister(indio_dev);
+       tiadc_iio_buffered_hardware_remove(indio_dev);
        tiadc_channels_remove(indio_dev);
 
        step_en = get_adc_step_mask(adc_dev);
@@ -301,7 +490,7 @@ static int tiadc_resume(struct device *dev)
        restore &= ~(CNTRLREG_POWERDOWN);
        tiadc_writel(adc_dev, REG_CTRL, restore);
 
-       tiadc_step_config(adc_dev);
+       tiadc_step_config(indio_dev);
 
        return 0;
 }
@@ -326,7 +515,7 @@ static struct platform_driver tiadc_driver = {
                .name   = "TI-am335x-adc",
                .owner  = THIS_MODULE,
                .pm     = TIADC_PM_OPS,
-               .of_match_table = of_match_ptr(ti_adc_dt_ids),
+               .of_match_table = ti_adc_dt_ids,
        },
        .probe  = tiadc_probe,
        .remove = tiadc_remove,
index 0ea96c058c0880016de8ec9c1b01b9f20c0cd9b0..53e1c645cee7c3e6ec8fb512cf9aea7ba33a7038 100644 (file)
@@ -887,7 +887,7 @@ static int twl6030_gpadc_probe(struct platform_device *pdev)
        int irq;
        int ret;
 
-       match = of_match_device(of_match_ptr(of_twl6030_match_tbl), dev);
+       match = of_match_device(of_twl6030_match_tbl, dev);
        if (!match)
                return -EINVAL;
 
@@ -948,9 +948,7 @@ static int twl6030_gpadc_probe(struct platform_device *pdev)
        indio_dev->channels = pdata->iio_channels;
        indio_dev->num_channels = pdata->nchannels;
 
-       ret = iio_device_register(indio_dev);
-
-       return ret;
+       return iio_device_register(indio_dev);
 }
 
 static int twl6030_gpadc_remove(struct platform_device *pdev)
index 415f3c6efd7293087cc1d5fa9313e9de308e6245..2d9c6f8c06db999017576e50c6d3e789c0f3f584 100644 (file)
@@ -7,26 +7,36 @@
 
 struct iio_cb_buffer {
        struct iio_buffer buffer;
-       int (*cb)(u8 *data, void *private);
+       int (*cb)(const void *data, void *private);
        void *private;
        struct iio_channel *channels;
 };
 
-static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
+static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer)
 {
-       struct iio_cb_buffer *cb_buff = container_of(buffer,
-                                                    struct iio_cb_buffer,
-                                                    buffer);
+       return container_of(buffer, struct iio_cb_buffer, buffer);
+}
 
+static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)
+{
+       struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
        return cb_buff->cb(data, cb_buff->private);
 }
 
-static struct iio_buffer_access_funcs iio_cb_access = {
+static void iio_buffer_cb_release(struct iio_buffer *buffer)
+{
+       struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
+       kfree(cb_buff->buffer.scan_mask);
+       kfree(cb_buff);
+}
+
+static const struct iio_buffer_access_funcs iio_cb_access = {
        .store_to = &iio_buffer_cb_store_to,
+       .release = &iio_buffer_cb_release,
 };
 
 struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
-                                            int (*cb)(u8 *data,
+                                            int (*cb)(const void *data,
                                                       void *private),
                                             void *private)
 {
@@ -104,9 +114,8 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
 
 void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
 {
-       kfree(cb_buff->buffer.scan_mask);
        iio_channel_release_all(cb_buff->channels);
-       kfree(cb_buff);
+       iio_buffer_put(&cb_buff->buffer);
 }
 EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
 
index 87419c41b991da24d8d284d33502c81f72c1c377..b6e77e0fc420133af7a324de6a0531bfb045f33d 100644 (file)
@@ -34,6 +34,12 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
        struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
        int state_val;
 
+       if (state) {
+               if (sensor_hub_device_open(st->hsdev))
+                       return -EIO;
+       } else
+               sensor_hub_device_close(st->hsdev);
+
        state_val = state ? 1 : 0;
        if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS))
                ++state_val;
index 71a2c5f63b9ced2361c5fb94f255cc3c6430ba23..1665c8e4b62b245c4301a93143b1912ec140466d 100644 (file)
@@ -113,11 +113,8 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
        if (len < 0)
                goto st_sensors_get_buffer_element_error;
 
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)sdata->buffer_data +
-                               ALIGN(len, sizeof(s64))) = pf->timestamp;
-
-       iio_push_to_buffers(indio_dev, sdata->buffer_data);
+       iio_push_to_buffers_with_timestamp(indio_dev, sdata->buffer_data,
+               pf->timestamp);
 
 st_sensors_get_buffer_element_error:
        iio_trigger_notify_done(indio_dev->trig);
index 965ee22d3ac80ef1ae98d26da17d3a44528b43db..7ba1ef27021323ec82ccb8a2cb3242795bfb0116 100644 (file)
@@ -198,21 +198,17 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
 }
 EXPORT_SYMBOL(st_sensors_set_axis_enable);
 
-int st_sensors_init_sensor(struct iio_dev *indio_dev,
-                                       struct st_sensors_platform_data *pdata)
+static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
+                                      struct st_sensors_platform_data *pdata)
 {
-       int err;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
-       mutex_init(&sdata->tb.buf_lock);
-
        switch (pdata->drdy_int_pin) {
        case 1:
                if (sdata->sensor->drdy_irq.mask_int1 == 0) {
                        dev_err(&indio_dev->dev,
                                        "DRDY on INT1 not available.\n");
-                       err = -EINVAL;
-                       goto init_error;
+                       return -EINVAL;
                }
                sdata->drdy_int_pin = 1;
                break;
@@ -220,39 +216,53 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
                if (sdata->sensor->drdy_irq.mask_int2 == 0) {
                        dev_err(&indio_dev->dev,
                                        "DRDY on INT2 not available.\n");
-                       err = -EINVAL;
-                       goto init_error;
+                       return -EINVAL;
                }
                sdata->drdy_int_pin = 2;
                break;
        default:
                dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
-               err = -EINVAL;
-               goto init_error;
+               return -EINVAL;
        }
 
+       return 0;
+}
+
+int st_sensors_init_sensor(struct iio_dev *indio_dev,
+                                       struct st_sensors_platform_data *pdata)
+{
+       struct st_sensor_data *sdata = iio_priv(indio_dev);
+       int err = 0;
+
+       mutex_init(&sdata->tb.buf_lock);
+
+       if (pdata)
+               err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
+
        err = st_sensors_set_enable(indio_dev, false);
        if (err < 0)
-               goto init_error;
+               return err;
 
-       err = st_sensors_set_fullscale(indio_dev,
-                                               sdata->current_fullscale->num);
-       if (err < 0)
-               goto init_error;
+       if (sdata->current_fullscale) {
+               err = st_sensors_set_fullscale(indio_dev,
+                                              sdata->current_fullscale->num);
+               if (err < 0)
+                       return err;
+       } else
+               dev_info(&indio_dev->dev, "Full-scale not possible\n");
 
        err = st_sensors_set_odr(indio_dev, sdata->odr);
        if (err < 0)
-               goto init_error;
+               return err;
 
        /* set BDU */
        err = st_sensors_write_data_with_mask(indio_dev,
                        sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true);
        if (err < 0)
-               goto init_error;
+               return err;
 
        err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
 
-init_error:
        return err;
 }
 EXPORT_SYMBOL(st_sensors_init_sensor);
@@ -263,6 +273,9 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
        u8 drdy_mask;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
+       if (!sdata->sensor->drdy_irq.addr)
+               return 0;
+
        /* Enable/Disable the interrupt generator 1. */
        if (sdata->sensor->drdy_irq.ig1.en_addr > 0) {
                err = st_sensors_write_data_with_mask(indio_dev,
@@ -318,10 +331,8 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
        unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
 
        outdata = kmalloc(byte_for_channel, GFP_KERNEL);
-       if (!outdata) {
-               err = -EINVAL;
-               goto st_sensors_read_axis_data_error;
-       }
+       if (!outdata)
+               return -ENOMEM;
 
        err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
                                ch->address, byte_for_channel,
@@ -336,7 +347,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
 
 st_sensors_free_memory:
        kfree(outdata);
-st_sensors_read_axis_data_error:
+
        return err;
 }
 
@@ -349,28 +360,25 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
                err = -EBUSY;
-               goto read_error;
+               goto out;
        } else {
                err = st_sensors_set_enable(indio_dev, true);
                if (err < 0)
-                       goto read_error;
+                       goto out;
 
                msleep((sdata->sensor->bootime * 1000) / sdata->odr);
                err = st_sensors_read_axis_data(indio_dev, ch, val);
                if (err < 0)
-                       goto read_error;
+                       goto out;
 
                *val = *val >> ch->scan_type.shift;
 
                err = st_sensors_set_enable(indio_dev, false);
        }
+out:
        mutex_unlock(&indio_dev->mlock);
 
        return err;
-
-read_error:
-       mutex_unlock(&indio_dev->mlock);
-       return err;
 }
 EXPORT_SYMBOL(st_sensors_read_info_raw);
 
index 3c6a78a75b78879558ff472c519ab567b01550e9..f378ca8033db699ff0753652cc0d92733119c56a 100644 (file)
@@ -57,7 +57,7 @@ config AD5446
          Say yes here to build support for Analog Devices AD5300, AD5301, AD5310,
          AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453,
          AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612,
-         AD5620, AD5621, AD5622, AD5640, AD5660, AD5662 DACs.
+         AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs.
 
          To compile this driver as a module, choose M here: the
          module will be called ad5446.
index a3a52be4852cb39fb3791b64f53cdbc285e87158..cb9c6366032cd2f8494236c52062e0b6caabdf92 100644 (file)
@@ -239,10 +239,9 @@ static int ad5064_read_raw(struct iio_dev *indio_dev,
                if (scale_uv < 0)
                        return scale_uv;
 
-               scale_uv = (scale_uv * 100) >> chan->scan_type.realbits;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = scale_uv / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -285,8 +284,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
                .name = "powerdown",
                .read = ad5064_read_dac_powerdown,
                .write = ad5064_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5064_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
        { },
 };
index d2da71ece740cbc1b0d62710d0afdbbba725ed91..b968af50db0a1cc2ffdb5565a0121b51d781cd61 100644 (file)
@@ -379,15 +379,14 @@ static int ad5360_read_raw(struct iio_dev *indio_dev,
                *val = ret >> chan->scan_type.shift;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               /* vout = 4 * vref * dac_code */
-               scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
+               scale_uv = ad5360_get_channel_vref(st, chan->channel);
                if (scale_uv < 0)
                        return scale_uv;
 
-               scale_uv >>= (chan->scan_type.realbits);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               /* vout = 4 * vref * dac_code */
+               *val = scale_uv * 4 / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_CALIBBIAS:
                ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
                        chan->address);
index 1c44ae3920e25b463bd907a3057a153fac3ba95f..a59ff0e7b8882139bcbf0e0fd1a55d75670486d1 100644 (file)
@@ -204,7 +204,6 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long info)
 {
        struct ad5380_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        int ret;
 
        switch (info) {
@@ -225,10 +224,9 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
                val -= (1 << chan->scan_type.realbits) / 2;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = ((2 * st->vref) >> chan->scan_type.realbits) * 100;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = 2 * st->vref;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -247,8 +245,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
                .name = "powerdown",
                .read = ad5380_read_dac_powerdown,
                .write = ad5380_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5380_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
        { },
 };
@@ -269,72 +269,72 @@ static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
        [ID_AD5380_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 40,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5380_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 40,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5381_3] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5381_5] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5382_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 32,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5382_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 32,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5383_3] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 32,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5383_5] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 32,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5390_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 16,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5390_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 16,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5391_3] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5391_5] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5392_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 8,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5392_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 8,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
 };
 
@@ -393,7 +393,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
                return ret;
        }
 
-       if (st->chip_info->int_vref == 2500000)
+       if (st->chip_info->int_vref == 2500)
                ctrl |= AD5380_CTRL_INT_VREF_2V5;
 
        st->vref_reg = devm_regulator_get(dev, "vref");
@@ -409,7 +409,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
                if (ret < 0)
                        goto error_disable_reg;
 
-               st->vref = ret;
+               st->vref = ret / 1000;
        } else {
                st->vref = st->chip_info->int_vref;
                ctrl |= AD5380_CTRL_INT_VREF_EN;
index 1f78b14abb7dc684e44e159816376181f591e070..3eeaa82075f7bca0649b5e15afb0c02f21a32458 100644 (file)
@@ -80,6 +80,29 @@ struct ad5421_state {
        } data[2] ____cacheline_aligned;
 };
 
+static const struct iio_event_spec ad5421_current_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
+static const struct iio_event_spec ad5421_temp_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
 static const struct iio_chan_spec ad5421_channels[] = {
        {
                .type = IIO_CURRENT,
@@ -92,13 +115,14 @@ static const struct iio_chan_spec ad5421_channels[] = {
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
                        BIT(IIO_CHAN_INFO_OFFSET),
                .scan_type = IIO_ST('u', 16, 16, 0),
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-                       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
+               .event_spec = ad5421_current_event,
+               .num_event_specs = ARRAY_SIZE(ad5421_current_event),
        },
        {
                .type = IIO_TEMP,
                .channel = -1,
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
+               .event_spec = ad5421_temp_event,
+               .num_event_specs = ARRAY_SIZE(ad5421_temp_event),
        },
 };
 
@@ -281,18 +305,11 @@ static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
        return (min * (1 << 16)) / (max - min);
 }
 
-static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
-{
-       unsigned int min, max;
-
-       ad5421_get_current_min_max(st, &min, &max);
-       return ((max - min) * 1000) / (1 << 16);
-}
-
 static int ad5421_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long m)
 {
        struct ad5421_state *st = iio_priv(indio_dev);
+       unsigned int min, max;
        int ret;
 
        if (chan->type != IIO_CURRENT)
@@ -306,9 +323,10 @@ static int ad5421_read_raw(struct iio_dev *indio_dev,
                *val = ret;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = ad5421_get_scale(st);
-               return IIO_VAL_INT_PLUS_MICRO;
+               ad5421_get_current_min_max(st, &min, &max);
+               *val = max - min;
+               *val2 = (1 << 16) * 1000;
+               return IIO_VAL_FRACTIONAL;
        case IIO_CHAN_INFO_OFFSET:
                *val = ad5421_get_offset(st);
                return IIO_VAL_INT;
@@ -359,15 +377,15 @@ static int ad5421_write_raw(struct iio_dev *indio_dev,
 }
 
 static int ad5421_write_event_config(struct iio_dev *indio_dev,
-       u64 event_code, int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        struct ad5421_state *st = iio_priv(indio_dev);
        unsigned int mask;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_CURRENT:
-               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING)
+               if (dir == IIO_EV_DIR_RISING)
                        mask = AD5421_FAULT_OVER_CURRENT;
                else
                        mask = AD5421_FAULT_UNDER_CURRENT;
@@ -390,15 +408,15 @@ static int ad5421_write_event_config(struct iio_dev *indio_dev,
 }
 
 static int ad5421_read_event_config(struct iio_dev *indio_dev,
-       u64 event_code)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        struct ad5421_state *st = iio_priv(indio_dev);
        unsigned int mask;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_CURRENT:
-               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING)
+               if (dir == IIO_EV_DIR_RISING)
                        mask = AD5421_FAULT_OVER_CURRENT;
                else
                        mask = AD5421_FAULT_UNDER_CURRENT;
@@ -413,12 +431,14 @@ static int ad5421_read_event_config(struct iio_dev *indio_dev,
        return (bool)(st->fault_mask & mask);
 }
 
-static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
-       int *val)
+static int ad5421_read_event_value(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, enum iio_event_info info, int *val,
+       int *val2)
 {
        int ret;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_CURRENT:
                ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
                if (ret < 0)
@@ -432,15 +452,15 @@ static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
                return -EINVAL;
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 static const struct iio_info ad5421_info = {
        .read_raw =             ad5421_read_raw,
        .write_raw =            ad5421_write_raw,
-       .read_event_config =    ad5421_read_event_config,
-       .write_event_config =   ad5421_write_event_config,
-       .read_event_value =     ad5421_read_event_value,
+       .read_event_config_new = ad5421_read_event_config,
+       .write_event_config_new = ad5421_write_event_config,
+       .read_event_value_new = ad5421_read_event_value,
        .driver_module =        THIS_MODULE,
 };
 
@@ -494,13 +514,7 @@ static int ad5421_probe(struct spi_device *spi)
                        return ret;
        }
 
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
+       return iio_device_register(indio_dev);
 }
 
 static int ad5421_remove(struct spi_device *spi)
index 96e9ed4c2d0167f1274ecbc6307a28d4594dbf10..1263b0e5ad84fda9dfdd841bbc23498d19918937 100644 (file)
@@ -132,8 +132,9 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
                .name = "powerdown",
                .read = ad5446_read_dac_powerdown,
                .write = ad5446_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5446_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
        { },
 };
@@ -162,18 +163,15 @@ static int ad5446_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5446_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
                *val = st->cached_val;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -329,6 +327,7 @@ enum ad5446_supported_spi_device_ids {
        ID_AD5601,
        ID_AD5611,
        ID_AD5621,
+       ID_AD5641,
        ID_AD5620_2500,
        ID_AD5620_1250,
        ID_AD5640_2500,
@@ -391,6 +390,10 @@ static const struct ad5446_chip_info ad5446_spi_chip_info[] = {
                .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
                .write = ad5446_write,
        },
+       [ID_AD5641] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
+               .write = ad5446_write,
+       },
        [ID_AD5620_2500] = {
                .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
                .int_vref_mv = 2500,
@@ -445,6 +448,7 @@ static const struct spi_device_id ad5446_spi_ids[] = {
        {"ad5601", ID_AD5601},
        {"ad5611", ID_AD5611},
        {"ad5621", ID_AD5621},
+       {"ad5641", ID_AD5641},
        {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */
        {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */
        {"ad5640-2500", ID_AD5640_2500},
index fff7d0762c0cb10fd4afbc40d9ac6799e10dad31..82e208f6cde2021f8707e1f45d9a3e3c8a528664 100644 (file)
@@ -101,7 +101,6 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
 {
        struct ad5449 *st = iio_priv(indio_dev);
        int ret;
-       struct spi_message msg;
        struct spi_transfer t[] = {
                {
                        .tx_buf = &st->data[0],
@@ -114,15 +113,11 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
                },
        };
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&t[0], &msg);
-       spi_message_add_tail(&t[1], &msg);
-
        mutex_lock(&indio_dev->mlock);
        st->data[0] = cpu_to_be16(addr << 12);
        st->data[1] = cpu_to_be16(AD5449_CMD_NOOP);
 
-       ret = spi_sync(st->spi, &msg);
+       ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
        if (ret < 0)
                goto out_unlock;
 
index caffb16bc05c0ce34b9fa6c65ebfd433ec57bf8f..c0957a918e17128b31bf7c1a4fbf743253b3cca3 100644 (file)
@@ -100,7 +100,6 @@ static int ad5504_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5504_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        int ret;
 
        switch (m) {
@@ -113,11 +112,9 @@ static int ad5504_read_raw(struct iio_dev *indio_dev,
 
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -248,8 +245,10 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
                .name = "powerdown",
                .read = ad5504_read_dac_powerdown,
                .write = ad5504_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5504_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
        { },
 };
index 714af757cd561cc291d88d04c9d00dc2cab8ed1a..774dd968145bd0515bad4799b805b4741f7fdb9e 100644 (file)
@@ -50,15 +50,12 @@ static int ad5624r_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5624r_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -163,8 +160,10 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
                .name = "powerdown",
                .read = ad5624r_read_dac_powerdown,
                .write = ad5624r_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5624r_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
        { },
 };
index 57825ead7db2eec071cf7d593bfbcb642bfa9784..30e506e37dd26adb6ad0510f8be0f1ca298b786d 100644 (file)
@@ -201,7 +201,6 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5686_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        int ret;
 
        switch (m) {
@@ -213,14 +212,10 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
                        return ret;
                *val = ret;
                return IIO_VAL_INT;
-               break;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 100000)
-                       >> (chan->scan_type.realbits);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -265,8 +260,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
                .name = "powerdown",
                .read = ad5686_read_dac_powerdown,
                .write = ad5686_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
        { },
 };
index 36a4361aece12b771169a541e993eead076c602a..9a78d5abb2f6646579fe6ffea21acd51dce91ca7 100644 (file)
@@ -253,15 +253,6 @@ static inline int ad5755_get_offset(struct ad5755_state *st,
        return (min * (1 << chan->scan_type.realbits)) / (max - min);
 }
 
-static inline int ad5755_get_scale(struct ad5755_state *st,
-       struct iio_chan_spec const *chan)
-{
-       int min, max;
-
-       ad5755_get_min_max(st, chan, &min, &max);
-       return ((max - min) * 1000000000ULL) >> chan->scan_type.realbits;
-}
-
 static int ad5755_chan_reg_info(struct ad5755_state *st,
        struct iio_chan_spec const *chan, long info, bool write,
        unsigned int *reg, unsigned int *shift, unsigned int *offset)
@@ -303,13 +294,15 @@ static int ad5755_read_raw(struct iio_dev *indio_dev,
 {
        struct ad5755_state *st = iio_priv(indio_dev);
        unsigned int reg, shift, offset;
+       int min, max;
        int ret;
 
        switch (info) {
        case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = ad5755_get_scale(st, chan);
-               return IIO_VAL_INT_PLUS_NANO;
+               ad5755_get_min_max(st, chan, &min, &max);
+               *val = max - min;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                *val = ad5755_get_offset(st, chan);
                return IIO_VAL_INT;
@@ -386,6 +379,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
                .name = "powerdown",
                .read = ad5755_read_powerdown,
                .write = ad5755_write_powerdown,
+               .shared = IIO_SEPARATE,
        },
        { },
 };
@@ -595,13 +589,7 @@ static int ad5755_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
+       return iio_device_register(indio_dev);
 }
 
 static int ad5755_remove(struct spi_device *spi)
index df7e028d9db5ef618549e5c08ca82158be58abef..a8ff5b2ed13ef396440b93cddc74d5f0a2397303 100644 (file)
@@ -217,7 +217,6 @@ static int ad5764_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long info)
 {
        struct ad5764_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        unsigned int reg;
        int vref;
        int ret;
@@ -245,15 +244,14 @@ static int ad5764_read_raw(struct iio_dev *indio_dev,
                *val = sign_extend32(*val, 5);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               /* vout = 4 * vref + ((dac_code / 65535) - 0.5) */
+               /* vout = 4 * vref + ((dac_code / 65536) - 0.5) */
                vref = ad5764_get_channel_vref(st, chan->channel);
                if (vref < 0)
                        return vref;
 
-               scale_uv = (vref * 4 * 100) >> chan->scan_type.realbits;
-               *val = scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = vref * 4 / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                *val = -(1 << chan->scan_type.realbits) / 2;
                return IIO_VAL_INT;
index ce7458963309aa4fd08a82c8d9274d02090d2174..d64acbd89482b82308601d88cb742446b865856a 100644 (file)
@@ -270,9 +270,9 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
                *val >>= chan->scan_type.shift;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->vref_mv;
+               *val2 = (1 << chan->scan_type.realbits) - 1;
+               return IIO_VAL_FRACTIONAL;
        case IIO_CHAN_INFO_OFFSET:
                val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
                do_div(val64, st->vref_mv);
@@ -287,11 +287,12 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
 static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
        {
                .name = "powerdown",
-               .shared = true,
+               .shared = IIO_SHARED_BY_TYPE,
                .read = ad5791_read_dac_powerdown,
                .write = ad5791_write_dac_powerdown,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5791_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
        { },
 };
index ed2d276477bd9970aeede225b93b7cc56c8ab40e..d0505fd22ef46c467d99f6b7e9dca18b9a4a688d 100644 (file)
@@ -169,6 +169,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
                .name = "powerdown",
                .read = ad7303_read_dac_powerdown,
                .write = ad7303_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
        { },
 };
index 83adcbf1a205e73f173763258c08b5cac2f9ad06..6e1903537950d966ac1ed385497c1ae6b795d6b0 100644 (file)
@@ -82,15 +82,13 @@ static int max517_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct max517_data *data = iio_priv(indio_dev);
-       unsigned int scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_SCALE:
                /* Corresponds to Vref / 2^(bits) */
-               scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8;
-               *val =  scale_uv / 1000000;
-               *val2 = scale_uv % 1000000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = data->vref_mv[chan->channel];
+               *val2 = 8;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -162,7 +160,6 @@ static int max517_probe(struct i2c_client *client,
        struct max517_data *data;
        struct iio_dev *indio_dev;
        struct max517_platform_data *platform_data = client->dev.platform_data;
-       int err;
 
        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
        if (!indio_dev)
@@ -194,13 +191,7 @@ static int max517_probe(struct i2c_client *client,
                data->vref_mv[1] = platform_data->vref_mv[1];
        }
 
-       err = iio_device_register(indio_dev);
-       if (err)
-               return err;
-
-       dev_info(&client->dev, "DAC registered\n");
-
-       return 0;
+       return iio_device_register(indio_dev);
 }
 
 static int max517_remove(struct i2c_client *client)
index 1397b6e0e414c25835aebd829dc2bede15dedee3..9f57ae84ab89c6aa89bb2aa23d634ceed242fcc2 100644 (file)
@@ -195,8 +195,9 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
                .name = "powerdown",
                .read = mcp4725_read_powerdown,
                .write = mcp4725_write_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
        { },
 };
@@ -238,17 +239,15 @@ static int mcp4725_read_raw(struct iio_dev *indio_dev,
                           int *val, int *val2, long mask)
 {
        struct mcp4725_data *data = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
                *val = data->dac_value;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (data->vref_mv * 1000) >> 12;
-               *val =  scale_uv / 1000000;
-               *val2 = scale_uv % 1000000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = data->vref_mv;
+               *val2 = 12;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -321,13 +320,7 @@ static int mcp4725_probe(struct i2c_client *client,
        data->powerdown_mode = pd ? pd-1 : 2; /* 500kohm_to_gnd */
        data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
 
-       err = iio_device_register(indio_dev);
-       if (err)
-               return err;
-
-       dev_info(&client->dev, "MCP4725 DAC registered\n");
-
-       return 0;
+       return iio_device_register(indio_dev);
 }
 
 static int mcp4725_remove(struct i2c_client *client)
index 52605c0ea3a69fce7c1d312d4fa1610de43174fd..63a25d9e120486db1dd1c023b0b0456f32da68a1 100644 (file)
@@ -351,6 +351,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
        .read = adf4350_read, \
        .write = adf4350_write, \
        .private = _ident, \
+       .shared = IIO_SEPARATE, \
 }
 
 static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
index e9ec022ae2250c62f6400ae1a9ee5dbdf06a9c30..add509837269ba8868f717950256fa9670174a17 100644 (file)
@@ -51,7 +51,6 @@ static int adis16080_read_sample(struct iio_dev *indio_dev,
                u16 addr, int *val)
 {
        struct adis16080_state *st = iio_priv(indio_dev);
-       struct spi_message m;
        int ret;
        struct spi_transfer     t[] = {
                {
@@ -66,11 +65,7 @@ static int adis16080_read_sample(struct iio_dev *indio_dev,
 
        st->buf = cpu_to_be16(addr | ADIS16080_DIN_WRITE);
 
-       spi_message_init(&m);
-       spi_message_add_tail(&t[0], &m);
-       spi_message_add_tail(&t[1], &m);
-
-       ret = spi_sync(st->us, &m);
+       ret = spi_sync_transfer(st->us, t, ARRAY_SIZE(t));
        if (ret == 0)
                *val = sign_extend32(be16_to_cpu(st->buf), 11);
 
index ac66fc184042e4aa7e23545555321521a032df31..445c2aecfadde205921049a1e0b42d64342318d5 100644 (file)
@@ -47,7 +47,6 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
 {
        int ret;
        struct adis16130_state *st = iio_priv(indio_dev);
-       struct spi_message msg;
        struct spi_transfer xfer = {
                .tx_buf = st->buf,
                .rx_buf = st->buf,
@@ -59,10 +58,7 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
        st->buf[0] = ADIS16130_CON_RD | reg_addr;
        st->buf[1] = st->buf[2] = st->buf[3] = 0;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->us, &msg);
-
+       ret = spi_sync_transfer(st->us, &xfer, 1);
        if (ret == 0)
                *val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3];
        mutex_unlock(&st->buf_lock);
@@ -103,7 +99,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        case IIO_CHAN_INFO_OFFSET:
                switch (chan->type) {
                case IIO_ANGL_VEL:
@@ -115,7 +110,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        }
 
        return -EINVAL;
index 06541162fc0213676467d3028f9ae1dde70cb848..22b6fb80fa1a7a99d3003d15e44fd63ac07f10b2 100644 (file)
@@ -239,7 +239,6 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        case IIO_CHAN_INFO_OFFSET:
                *val = 250000 / 1453; /* 25 C = 0x00 */
                return IIO_VAL_INT;
index 6dab2995f0f26ebc5111b75281722ea029ee3c8c..1e546ba7ba45e1c92acf9ae926b9c29c386785ef 100644 (file)
@@ -90,7 +90,6 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
                                    u8 reg_address,
                                    u16 *val)
 {
-       struct spi_message msg;
        struct adxrs450_state *st = iio_priv(indio_dev);
        u32 tx;
        int ret;
@@ -114,10 +113,7 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
                tx |= ADXRS450_P;
 
        st->tx = cpu_to_be32(tx);
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(st->us, &msg);
+       ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
        if (ret) {
                dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
                                reg_address);
@@ -169,7 +165,6 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
  **/
 static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
 {
-       struct spi_message msg;
        struct adxrs450_state *st = iio_priv(indio_dev);
        int ret;
        struct spi_transfer xfers[] = {
@@ -188,10 +183,7 @@ static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
        mutex_lock(&st->buf_lock);
        st->tx = cpu_to_be32(ADXRS450_SENSOR_DATA);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(st->us, &msg);
+       ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
        if (ret) {
                dev_err(&st->us->dev, "Problem while reading sensor data\n");
                goto error_ret;
@@ -354,7 +346,6 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
                ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
                if (ret)
index c688d974d3e3ec3d858a4f07e6dabf592866a395..ea01c6bcfb56825979efc7bfc588eeb9e429e059 100644 (file)
@@ -182,10 +182,11 @@ static const struct iio_info gyro_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -200,7 +201,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                gyro_state->common_attributes.data_ready);
        if (gyro_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)gyro_state->gyro_val,
+                               gyro_state->gyro_val,
                                sizeof(gyro_state->gyro_val));
 
        return 0;
index 6c43af9bb0a4474097f2def7ec15d973a7238b47..e3b3c5084070d808ca88939e3f13257472ba3e55 100644 (file)
@@ -55,11 +55,8 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
        if (ret < 0)
                goto error_ret;
 
-       if (indio_dev->scan_timestamp)
-               memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
-                               &pf->timestamp, sizeof(pf->timestamp));
+       iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
 
-       iio_push_to_buffers(indio_dev, (u8 *)buf);
        iio_trigger_notify_done(indio_dev->trig);
 
 error_ret:
index 69017c7ec302a785ffd86afca90ff3b2ae1e9d3e..d67b17b6a7aab1abd0077e297c5e0f9769eee893 100644 (file)
@@ -32,16 +32,7 @@ int st_gyro_trig_set_state(struct iio_trigger *trig, bool state)
 
 static int st_gyro_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_gyro_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_gyro_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_gyro_buffer_postenable(struct iio_dev *indio_dev)
index e13c2b0bf3d1ae27de590555d349b6b31632f112..d53d91adfb557b0e575a17030221c6e01b2b7d38 100644 (file)
@@ -305,8 +305,9 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
 int st_gyro_common_probe(struct iio_dev *indio_dev,
                                        struct st_sensors_platform_data *pdata)
 {
-       int err;
        struct st_sensor_data *gdata = iio_priv(indio_dev);
+       int irq = gdata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &gyro_info;
@@ -314,7 +315,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
        err = st_sensors_check_device_support(indio_dev,
                                ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
        if (err < 0)
-               goto st_gyro_common_probe_error;
+               return err;
 
        gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
        gdata->multiread_bit = gdata->sensor->multi_read_bit;
@@ -327,13 +328,13 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
 
        err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
-               goto st_gyro_common_probe_error;
+               return err;
 
-       if (gdata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_gyro_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_gyro_common_probe_error;
+       err = st_gyro_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
 
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev,
                                                  ST_GYRO_TRIGGER_OPS);
                if (err < 0)
@@ -344,15 +345,14 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
        if (err)
                goto st_gyro_device_register_error;
 
-       return err;
+       return 0;
 
 st_gyro_device_register_error:
-       if (gdata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_gyro_probe_trigger_error:
-       if (gdata->get_irq_data_ready(indio_dev) > 0)
-               st_gyro_deallocate_ring(indio_dev);
-st_gyro_common_probe_error:
+       st_gyro_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_gyro_common_probe);
@@ -362,10 +362,10 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
        struct st_sensor_data *gdata = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (gdata->get_irq_data_ready(indio_dev) > 0) {
+       if (gdata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_gyro_deallocate_ring(indio_dev);
-       }
+
+       st_gyro_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_gyro_common_remove);
 
index 9b32253b824be454bf2f6c46bf02acb022b3be46..f6db6af36ba6de20ceb2cf9dc159dff9f53a1987 100644 (file)
@@ -30,9 +30,12 @@ int __iio_add_chan_devattr(const char *postfix,
                                                const char *buf,
                                                size_t len),
                           u64 mask,
-                          bool generic,
+                          enum iio_shared_by shared_by,
                           struct device *dev,
                           struct list_head *attr_list);
+void iio_free_chan_devattr_list(struct list_head *attr_list);
+
+ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2);
 
 /* Event interface flags */
 #define IIO_BUSY_BIT_POS 1
@@ -50,6 +53,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 #define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
 
 void iio_disable_all_buffers(struct iio_dev *indio_dev);
+void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
 
 #else
 
@@ -57,11 +61,13 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev);
 #define iio_buffer_read_first_n_outer_addr NULL
 
 static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
+static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {}
 
 #endif
 
 int iio_device_register_eventset(struct iio_dev *indio_dev);
 void iio_device_unregister_eventset(struct iio_dev *indio_dev);
+void iio_device_wakeup_eventset(struct iio_dev *indio_dev);
 int iio_event_getfd(struct iio_dev *indio_dev);
 
 #endif
index 054c01d6e73cf147845ea3da748fcb05068a3505..f2cf829e5df104ea35b64a0493c4975493826bcb 100644 (file)
@@ -82,13 +82,8 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
                spi_setup(st->adis.spi);
        }
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp) {
-               void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
-               *(s64 *)b = pf->timestamp;
-       }
-
-       iio_push_to_buffers(indio_dev, adis->buffer);
+       iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
+               pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
 
index 99d8e0b0dd34243168a750794df130ee77d8fe37..cb32b593f1c55c023046d97cfc41263ea3818d89 100644 (file)
@@ -102,13 +102,8 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
                mutex_unlock(&adis->txrx_lock);
        }
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp) {
-               void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
-               *(s64 *)b = pf->timestamp;
-       }
-
-       iio_push_to_buffers(indio_dev, adis->buffer);
+       iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
+               pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
 
index 7da0832f187b8d320cd8618eb3379b2015bee927..429517117eff43d92b86238a284635c8b3b4b8f9 100644 (file)
@@ -124,7 +124,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
        u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
        u16 fifo_count;
        s64 timestamp;
-       u64 *tmp;
 
        mutex_lock(&indio_dev->mlock);
        if (!(st->chip_config.accl_fifo_enable |
@@ -170,9 +169,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
                if (0 == result)
                        timestamp = 0;
 
-               tmp = (u64 *)data;
-               tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
-               result = iio_push_to_buffers(indio_dev, data);
+               result = iio_push_to_buffers_with_timestamp(indio_dev, data,
+                       timestamp);
                if (result)
                        goto flush_fifo;
                fifo_count -= bytes_per_datum;
index 2db7dcd826b9db6500e354498b385cbb3ebd9f7d..7f9152c3c4d3dafa61f2cac1126b1cbd50306a6e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/cdev.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 
 #include <linux/iio/iio.h>
 #include "iio_core.h"
@@ -31,16 +32,9 @@ static const char * const iio_endian_prefix[] = {
        [IIO_LE] = "le",
 };
 
-static bool iio_buffer_is_active(struct iio_dev *indio_dev,
-                                struct iio_buffer *buf)
+static bool iio_buffer_is_active(struct iio_buffer *buf)
 {
-       struct list_head *p;
-
-       list_for_each(p, &indio_dev->buffer_list)
-               if (p == &buf->buffer_list)
-                       return true;
-
-       return false;
+       return !list_empty(&buf->buffer_list);
 }
 
 /**
@@ -55,6 +49,9 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        if (!rb || !rb->access->read_first_n)
                return -EINVAL;
        return rb->access->read_first_n(rb, n, buf);
@@ -69,6 +66,9 @@ unsigned int iio_buffer_poll(struct file *filp,
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        poll_wait(filp, &rb->pollq, wait);
        if (rb->stufftoread)
                return POLLIN | POLLRDNORM;
@@ -76,10 +76,27 @@ unsigned int iio_buffer_poll(struct file *filp,
        return 0;
 }
 
+/**
+ * iio_buffer_wakeup_poll - Wakes up the buffer waitqueue
+ * @indio_dev: The IIO device
+ *
+ * Wakes up the event waitqueue used for poll(). Should usually
+ * be called when the device is unregistered.
+ */
+void iio_buffer_wakeup_poll(struct iio_dev *indio_dev)
+{
+       if (!indio_dev->buffer)
+               return;
+
+       wake_up(&indio_dev->buffer->pollq);
+}
+
 void iio_buffer_init(struct iio_buffer *buffer)
 {
        INIT_LIST_HEAD(&buffer->demux_list);
+       INIT_LIST_HEAD(&buffer->buffer_list);
        init_waitqueue_head(&buffer->pollq);
+       kref_init(&buffer->ref);
 }
 EXPORT_SYMBOL(iio_buffer_init);
 
@@ -146,7 +163,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
        if (ret < 0)
                return ret;
        mutex_lock(&indio_dev->mlock);
-       if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
+       if (iio_buffer_is_active(indio_dev->buffer)) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -192,7 +209,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
                return ret;
 
        mutex_lock(&indio_dev->mlock);
-       if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
+       if (iio_buffer_is_active(indio_dev->buffer)) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -214,7 +231,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
                                     &iio_show_scan_index,
                                     NULL,
                                     0,
-                                    0,
+                                    IIO_SEPARATE,
                                     &indio_dev->dev,
                                     &buffer->scan_el_dev_attr_list);
        if (ret)
@@ -249,29 +266,14 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
                                             0,
                                             &indio_dev->dev,
                                             &buffer->scan_el_dev_attr_list);
+       if (ret)
+               goto error_ret;
        attrcount++;
        ret = attrcount;
 error_ret:
        return ret;
 }
 
-static void iio_buffer_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev,
-                                                    struct iio_dev_attr *p)
-{
-       kfree(p->dev_attr.attr.name);
-       kfree(p);
-}
-
-static void __iio_buffer_attr_cleanup(struct iio_dev *indio_dev)
-{
-       struct iio_dev_attr *p, *n;
-       struct iio_buffer *buffer = indio_dev->buffer;
-
-       list_for_each_entry_safe(p, n,
-                                &buffer->scan_el_dev_attr_list, l)
-               iio_buffer_remove_and_free_scan_dev_attr(indio_dev, p);
-}
-
 static const char * const iio_scan_elements_group_name = "scan_elements";
 
 int iio_buffer_register(struct iio_dev *indio_dev,
@@ -348,7 +350,7 @@ int iio_buffer_register(struct iio_dev *indio_dev,
 error_free_scan_mask:
        kfree(buffer->scan_mask);
 error_cleanup_dynamic:
-       __iio_buffer_attr_cleanup(indio_dev);
+       iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
 
        return ret;
 }
@@ -358,7 +360,7 @@ void iio_buffer_unregister(struct iio_dev *indio_dev)
 {
        kfree(indio_dev->buffer->scan_mask);
        kfree(indio_dev->buffer->scan_el_group.attrs);
-       __iio_buffer_attr_cleanup(indio_dev);
+       iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list);
 }
 EXPORT_SYMBOL(iio_buffer_unregister);
 
@@ -396,7 +398,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
                        return len;
 
        mutex_lock(&indio_dev->mlock);
-       if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
+       if (iio_buffer_is_active(indio_dev->buffer)) {
                ret = -EBUSY;
        } else {
                if (buffer->access->set_length)
@@ -414,13 +416,11 @@ ssize_t iio_buffer_show_enable(struct device *dev,
                               char *buf)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       return sprintf(buf, "%d\n",
-                      iio_buffer_is_active(indio_dev,
-                                           indio_dev->buffer));
+       return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer));
 }
 EXPORT_SYMBOL(iio_buffer_show_enable);
 
-/* note NULL used as error indicator as it doesn't make sense. */
+/* Note NULL used as error indicator as it doesn't make sense. */
 static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
                                          unsigned int masklength,
                                          const unsigned long *mask)
@@ -435,8 +435,8 @@ static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
        return NULL;
 }
 
-static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
-                                 bool timestamp)
+static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
+                               const unsigned long *mask, bool timestamp)
 {
        const struct iio_chan_spec *ch;
        unsigned bytes = 0;
@@ -460,6 +460,19 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
        return bytes;
 }
 
+static void iio_buffer_activate(struct iio_dev *indio_dev,
+       struct iio_buffer *buffer)
+{
+       iio_buffer_get(buffer);
+       list_add(&buffer->buffer_list, &indio_dev->buffer_list);
+}
+
+static void iio_buffer_deactivate(struct iio_buffer *buffer)
+{
+       list_del_init(&buffer->buffer_list);
+       iio_buffer_put(buffer);
+}
+
 void iio_disable_all_buffers(struct iio_dev *indio_dev)
 {
        struct iio_buffer *buffer, *_buffer;
@@ -472,7 +485,7 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev)
 
        list_for_each_entry_safe(buffer, _buffer,
                        &indio_dev->buffer_list, buffer_list)
-               list_del_init(&buffer->buffer_list);
+               iio_buffer_deactivate(buffer);
 
        indio_dev->currentmode = INDIO_DIRECT_MODE;
        if (indio_dev->setup_ops->postdisable)
@@ -482,7 +495,21 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev)
                kfree(indio_dev->active_scan_mask);
 }
 
-int iio_update_buffers(struct iio_dev *indio_dev,
+static void iio_buffer_update_bytes_per_datum(struct iio_dev *indio_dev,
+       struct iio_buffer *buffer)
+{
+       unsigned int bytes;
+
+       if (!buffer->access->set_bytes_per_datum)
+               return;
+
+       bytes = iio_compute_scan_bytes(indio_dev, buffer->scan_mask,
+               buffer->scan_timestamp);
+
+       buffer->access->set_bytes_per_datum(buffer, bytes);
+}
+
+static int __iio_update_buffers(struct iio_dev *indio_dev,
                       struct iio_buffer *insert_buffer,
                       struct iio_buffer *remove_buffer)
 {
@@ -512,9 +539,9 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                indio_dev->active_scan_mask = NULL;
 
        if (remove_buffer)
-               list_del(&remove_buffer->buffer_list);
+               iio_buffer_deactivate(remove_buffer);
        if (insert_buffer)
-               list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
+               iio_buffer_activate(indio_dev, insert_buffer);
 
        /* If no buffers in list, we are done */
        if (list_empty(&indio_dev->buffer_list)) {
@@ -524,7 +551,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                return 0;
        }
 
-       /* What scan mask do we actually have ?*/
+       /* What scan mask do we actually have*/
        compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
                                sizeof(long), GFP_KERNEL);
        if (compound_mask == NULL) {
@@ -549,7 +576,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                         * Roll back.
                         * Note can only occur when adding a buffer.
                         */
-                       list_del(&insert_buffer->buffer_list);
+                       iio_buffer_deactivate(insert_buffer);
                        if (old_mask) {
                                indio_dev->active_scan_mask = old_mask;
                                success = -EINVAL;
@@ -579,7 +606,8 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                iio_compute_scan_bytes(indio_dev,
                                       indio_dev->active_scan_mask,
                                       indio_dev->scan_timestamp);
-       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
+       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+               iio_buffer_update_bytes_per_datum(indio_dev, buffer);
                if (buffer->access->request_update) {
                        ret = buffer->access->request_update(buffer);
                        if (ret) {
@@ -588,6 +616,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                                goto error_run_postdisable;
                        }
                }
+       }
        if (indio_dev->info->update_scan_mode) {
                ret = indio_dev->info
                        ->update_scan_mode(indio_dev,
@@ -597,7 +626,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                        goto error_run_postdisable;
                }
        }
-       /* Definitely possible for devices to support both of these.*/
+       /* Definitely possible for devices to support both of these. */
        if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
                if (!indio_dev->trig) {
                        printk(KERN_INFO "Buffer not started: no trigger\n");
@@ -608,7 +637,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
        } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
                indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
-       } else { /* should never be reached */
+       } else { /* Should never be reached */
                ret = -EINVAL;
                goto error_run_postdisable;
        }
@@ -640,13 +669,50 @@ error_run_postdisable:
 error_remove_inserted:
 
        if (insert_buffer)
-               list_del(&insert_buffer->buffer_list);
+               iio_buffer_deactivate(insert_buffer);
        indio_dev->active_scan_mask = old_mask;
        kfree(compound_mask);
 error_ret:
 
        return ret;
 }
+
+int iio_update_buffers(struct iio_dev *indio_dev,
+                      struct iio_buffer *insert_buffer,
+                      struct iio_buffer *remove_buffer)
+{
+       int ret;
+
+       if (insert_buffer == remove_buffer)
+               return 0;
+
+       mutex_lock(&indio_dev->info_exist_lock);
+       mutex_lock(&indio_dev->mlock);
+
+       if (insert_buffer && iio_buffer_is_active(insert_buffer))
+               insert_buffer = NULL;
+
+       if (remove_buffer && !iio_buffer_is_active(remove_buffer))
+               remove_buffer = NULL;
+
+       if (!insert_buffer && !remove_buffer) {
+               ret = 0;
+               goto out_unlock;
+       }
+
+       if (indio_dev->info == NULL) {
+               ret = -ENODEV;
+               goto out_unlock;
+       }
+
+       ret = __iio_update_buffers(indio_dev, insert_buffer, remove_buffer);
+
+out_unlock:
+       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&indio_dev->info_exist_lock);
+
+       return ret;
+}
 EXPORT_SYMBOL_GPL(iio_update_buffers);
 
 ssize_t iio_buffer_store_enable(struct device *dev,
@@ -657,7 +723,6 @@ ssize_t iio_buffer_store_enable(struct device *dev,
        int ret;
        bool requested_state;
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct iio_buffer *pbuf = indio_dev->buffer;
        bool inlist;
 
        ret = strtobool(buf, &requested_state);
@@ -667,16 +732,16 @@ ssize_t iio_buffer_store_enable(struct device *dev,
        mutex_lock(&indio_dev->mlock);
 
        /* Find out if it is in the list */
-       inlist = iio_buffer_is_active(indio_dev, pbuf);
+       inlist = iio_buffer_is_active(indio_dev->buffer);
        /* Already in desired state */
        if (inlist == requested_state)
                goto done;
 
        if (requested_state)
-               ret = iio_update_buffers(indio_dev,
+               ret = __iio_update_buffers(indio_dev,
                                         indio_dev->buffer, NULL);
        else
-               ret = iio_update_buffers(indio_dev,
+               ret = __iio_update_buffers(indio_dev,
                                         NULL, indio_dev->buffer);
 
        if (ret < 0)
@@ -687,24 +752,6 @@ done:
 }
 EXPORT_SYMBOL(iio_buffer_store_enable);
 
-int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
-{
-       struct iio_buffer *buffer;
-       unsigned bytes;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-
-       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
-               if (buffer->access->set_bytes_per_datum) {
-                       bytes = iio_compute_scan_bytes(indio_dev,
-                                                      buffer->scan_mask,
-                                                      buffer->scan_timestamp);
-
-                       buffer->access->set_bytes_per_datum(buffer, bytes);
-               }
-       return 0;
-}
-EXPORT_SYMBOL(iio_sw_buffer_preenable);
-
 /**
  * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected
  * @indio_dev: the iio device
@@ -732,6 +779,7 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
 
 /**
  * iio_scan_mask_set() - set particular bit in the scan mask
+ * @indio_dev: the iio device
  * @buffer: the buffer whose scan mask we are interested in
  * @bit: the bit to be set.
  *
@@ -752,7 +800,7 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
        if (trialmask == NULL)
                return -ENOMEM;
        if (!indio_dev->masklength) {
-               WARN_ON("trying to set scanmask prior to registering buffer\n");
+               WARN_ON("Trying to set scanmask prior to registering buffer\n");
                goto err_invalid_mask;
        }
        bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
@@ -807,8 +855,8 @@ struct iio_demux_table {
        struct list_head l;
 };
 
-static unsigned char *iio_demux(struct iio_buffer *buffer,
-                                unsigned char *datain)
+static const void *iio_demux(struct iio_buffer *buffer,
+                                const void *datain)
 {
        struct iio_demux_table *t;
 
@@ -821,9 +869,9 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
        return buffer->demux_bounce;
 }
 
-static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
+static int iio_push_to_buffer(struct iio_buffer *buffer, const void *data)
 {
-       unsigned char *dataout = iio_demux(buffer, data);
+       const void *dataout = iio_demux(buffer, data);
 
        return buffer->access->store_to(buffer, dataout);
 }
@@ -838,7 +886,7 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
 }
 
 
-int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
+int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
 {
        int ret;
        struct iio_buffer *buf;
@@ -961,3 +1009,45 @@ error_clear_mux_table:
        return ret;
 }
 EXPORT_SYMBOL_GPL(iio_update_demux);
+
+/**
+ * iio_buffer_release() - Free a buffer's resources
+ * @ref: Pointer to the kref embedded in the iio_buffer struct
+ *
+ * This function is called when the last reference to the buffer has been
+ * dropped. It will typically free all resources allocated by the buffer. Do not
+ * call this function manually, always use iio_buffer_put() when done using a
+ * buffer.
+ */
+static void iio_buffer_release(struct kref *ref)
+{
+       struct iio_buffer *buffer = container_of(ref, struct iio_buffer, ref);
+
+       buffer->access->release(buffer);
+}
+
+/**
+ * iio_buffer_get() - Grab a reference to the buffer
+ * @buffer: The buffer to grab a reference for, may be NULL
+ *
+ * Returns the pointer to the buffer that was passed into the function.
+ */
+struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer)
+{
+       if (buffer)
+               kref_get(&buffer->ref);
+
+       return buffer;
+}
+EXPORT_SYMBOL_GPL(iio_buffer_get);
+
+/**
+ * iio_buffer_put() - Release the reference to the buffer
+ * @buffer: The buffer to release the reference for, may be NULL
+ */
+void iio_buffer_put(struct iio_buffer *buffer)
+{
+       if (buffer)
+               kref_put(&buffer->ref, iio_buffer_release);
+}
+EXPORT_SYMBOL_GPL(iio_buffer_put);
index f95c6979efd8f58fdf42e2a6d11a645b4191c17d..18f72e3d0ed6e6c8e9bb73ec8616124a2422aed4 100644 (file)
@@ -9,6 +9,8 @@
  * Based on elements of hwmon and input subsystems.
  */
 
+#define pr_fmt(fmt) "iio-core: " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/idr.h>
@@ -28,6 +30,7 @@
 #include "iio_core_trigger.h"
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
+#include <linux/iio/buffer.h>
 
 /* IDA to assign each registered device a unique id */
 static DEFINE_IDA(iio_ida);
@@ -101,6 +104,7 @@ static const char * const iio_chan_info_postfix[] = {
        [IIO_CHAN_INFO_PHASE] = "phase",
        [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
        [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
+       [IIO_CHAN_INFO_INT_TIME] = "integration_time",
 };
 
 const struct iio_chan_spec
@@ -130,16 +134,13 @@ static int __init iio_init(void)
        /* Register sysfs bus */
        ret  = bus_register(&iio_bus_type);
        if (ret < 0) {
-               printk(KERN_ERR
-                      "%s could not register bus type\n",
-                       __FILE__);
+               pr_err("could not register bus type\n");
                goto error_nothing;
        }
 
        ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio");
        if (ret < 0) {
-               printk(KERN_ERR "%s: failed to allocate char dev region\n",
-                      __FILE__);
+               pr_err("failed to allocate char dev region\n");
                goto error_unregister_bus_type;
        }
 
@@ -361,22 +362,20 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
 }
 EXPORT_SYMBOL_GPL(iio_enum_write);
 
-static ssize_t iio_read_channel_info(struct device *dev,
-                                    struct device_attribute *attr,
-                                    char *buf)
+/**
+ * iio_format_value() - Formats a IIO value into its string representation
+ * @buf: The buffer to which the formated value gets written
+ * @type: One of the IIO_VAL_... constants. This decides how the val and val2
+ *        parameters are formatted.
+ * @val: First part of the value, exact meaning depends on the type parameter.
+ * @val2: Second part of the value, exact meaning depends on the type parameter.
+ */
+ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        unsigned long long tmp;
-       int val, val2;
        bool scale_db = false;
-       int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
-                                           &val, &val2, this_attr->address);
-
-       if (ret < 0)
-               return ret;
 
-       switch (ret) {
+       switch (type) {
        case IIO_VAL_INT:
                return sprintf(buf, "%d\n", val);
        case IIO_VAL_INT_PLUS_MICRO_DB:
@@ -408,6 +407,22 @@ static ssize_t iio_read_channel_info(struct device *dev,
        }
 }
 
+static ssize_t iio_read_channel_info(struct device *dev,
+                                    struct device_attribute *attr,
+                                    char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       int val, val2;
+       int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
+                                           &val, &val2, this_attr->address);
+
+       if (ret < 0)
+               return ret;
+
+       return iio_format_value(buf, ret, val, val2);
+}
+
 /**
  * iio_str_to_fixpoint() - Parse a fixed-point number from a string
  * @str: The string to parse
@@ -516,14 +531,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                                                struct device_attribute *attr,
                                                const char *buf,
                                                size_t len),
-                          bool generic)
+                          enum iio_shared_by shared_by)
 {
-       int ret;
-       char *name_format, *full_postfix;
+       int ret = 0;
+       char *name_format = NULL;
+       char *full_postfix;
        sysfs_attr_init(&dev_attr->attr);
 
        /* Build up postfix of <extend_name>_<modifier>_postfix */
-       if (chan->modified && !generic) {
+       if (chan->modified && (shared_by == IIO_SEPARATE)) {
                if (chan->extend_name)
                        full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
                                                 iio_modifier_names[chan
@@ -544,53 +560,78 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                                                 chan->extend_name,
                                                 postfix);
        }
-       if (full_postfix == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       if (full_postfix == NULL)
+               return -ENOMEM;
 
        if (chan->differential) { /* Differential can not have modifier */
-               if (generic)
+               switch (shared_by) {
+               case IIO_SHARED_BY_ALL:
+                       name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
+                       break;
+               case IIO_SHARED_BY_DIR:
+                       name_format = kasprintf(GFP_KERNEL, "%s_%s",
+                                               iio_direction[chan->output],
+                                               full_postfix);
+                       break;
+               case IIO_SHARED_BY_TYPE:
                        name_format
                                = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            iio_chan_type_name_spec[chan->type],
                                            full_postfix);
-               else if (chan->indexed)
+                       break;
+               case IIO_SEPARATE:
+                       if (!chan->indexed) {
+                               WARN_ON("Differential channels must be indexed\n");
+                               ret = -EINVAL;
+                               goto error_free_full_postfix;
+                       }
                        name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
+                               = kasprintf(GFP_KERNEL,
+                                           "%s_%s%d-%s%d_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            chan->channel,
                                            iio_chan_type_name_spec[chan->type],
                                            chan->channel2,
                                            full_postfix);
-               else {
-                       WARN_ON("Differential channels must be indexed\n");
-                       ret = -EINVAL;
-                       goto error_free_full_postfix;
+                       break;
                }
        } else { /* Single ended */
-               if (generic)
-                       name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s_%s",
-                                           iio_direction[chan->output],
-                                           iio_chan_type_name_spec[chan->type],
-                                           full_postfix);
-               else if (chan->indexed)
-                       name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
-                                           iio_direction[chan->output],
-                                           iio_chan_type_name_spec[chan->type],
-                                           chan->channel,
-                                           full_postfix);
-               else
+               switch (shared_by) {
+               case IIO_SHARED_BY_ALL:
+                       name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
+                       break;
+               case IIO_SHARED_BY_DIR:
+                       name_format = kasprintf(GFP_KERNEL, "%s_%s",
+                                               iio_direction[chan->output],
+                                               full_postfix);
+                       break;
+               case IIO_SHARED_BY_TYPE:
                        name_format
                                = kasprintf(GFP_KERNEL, "%s_%s_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            full_postfix);
+                       break;
+
+               case IIO_SEPARATE:
+                       if (chan->indexed)
+                               name_format
+                                       = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
+                                                   iio_direction[chan->output],
+                                                   iio_chan_type_name_spec[chan->type],
+                                                   chan->channel,
+                                                   full_postfix);
+                       else
+                               name_format
+                                       = kasprintf(GFP_KERNEL, "%s_%s_%s",
+                                                   iio_direction[chan->output],
+                                                   iio_chan_type_name_spec[chan->type],
+                                                   full_postfix);
+                       break;
+               }
        }
        if (name_format == NULL) {
                ret = -ENOMEM;
@@ -614,16 +655,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                dev_attr->attr.mode |= S_IWUSR;
                dev_attr->store = writefunc;
        }
-       kfree(name_format);
-       kfree(full_postfix);
-
-       return 0;
-
 error_free_name_format:
        kfree(name_format);
 error_free_full_postfix:
        kfree(full_postfix);
-error_ret:
+
        return ret;
 }
 
@@ -642,21 +678,21 @@ int __iio_add_chan_devattr(const char *postfix,
                                                const char *buf,
                                                size_t len),
                           u64 mask,
-                          bool generic,
+                          enum iio_shared_by shared_by,
                           struct device *dev,
                           struct list_head *attr_list)
 {
        int ret;
        struct iio_dev_attr *iio_attr, *t;
 
-       iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL);
+       iio_attr = kzalloc(sizeof(*iio_attr), GFP_KERNEL);
        if (iio_attr == NULL) {
                ret = -ENOMEM;
                goto error_ret;
        }
        ret = __iio_device_attr_init(&iio_attr->dev_attr,
                                     postfix, chan,
-                                    readfunc, writefunc, generic);
+                                    readfunc, writefunc, shared_by);
        if (ret)
                goto error_iio_dev_attr_free;
        iio_attr->c = chan;
@@ -664,7 +700,7 @@ int __iio_add_chan_devattr(const char *postfix,
        list_for_each_entry(t, attr_list, l)
                if (strcmp(t->dev_attr.attr.name,
                           iio_attr->dev_attr.attr.name) == 0) {
-                       if (!generic)
+                       if (shared_by == IIO_SEPARATE)
                                dev_err(dev, "tried to double register : %s\n",
                                        t->dev_attr.attr.name);
                        ret = -EBUSY;
@@ -682,46 +718,68 @@ error_ret:
        return ret;
 }
 
-static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
-                                       struct iio_chan_spec const *chan)
+static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
+                                        struct iio_chan_spec const *chan,
+                                        enum iio_shared_by shared_by,
+                                        const long *infomask)
 {
-       int ret, attrcount = 0;
-       int i;
-       const struct iio_chan_spec_ext_info *ext_info;
+       int i, ret, attrcount = 0;
 
-       if (chan->channel < 0)
-               return 0;
-       for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
+       for_each_set_bit(i, infomask, sizeof(infomask)*8) {
                ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
                                             chan,
                                             &iio_read_channel_info,
                                             &iio_write_channel_info,
                                             i,
-                                            0,
+                                            shared_by,
                                             &indio_dev->dev,
                                             &indio_dev->channel_attr_list);
-               if (ret < 0)
-                       goto error_ret;
-               attrcount++;
-       }
-       for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
-               ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
-                                            chan,
-                                            &iio_read_channel_info,
-                                            &iio_write_channel_info,
-                                            i,
-                                            1,
-                                            &indio_dev->dev,
-                                            &indio_dev->channel_attr_list);
-               if (ret == -EBUSY) {
-                       ret = 0;
+               if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
                        continue;
-               } else if (ret < 0) {
-                       goto error_ret;
-               }
+               else if (ret < 0)
+                       return ret;
                attrcount++;
        }
 
+       return attrcount;
+}
+
+static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
+                                       struct iio_chan_spec const *chan)
+{
+       int ret, attrcount = 0;
+       const struct iio_chan_spec_ext_info *ext_info;
+
+       if (chan->channel < 0)
+               return 0;
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SEPARATE,
+                                           &chan->info_mask_separate);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_TYPE,
+                                           &chan->info_mask_shared_by_type);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_DIR,
+                                           &chan->info_mask_shared_by_dir);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_ALL,
+                                           &chan->info_mask_shared_by_all);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
        if (chan->ext_info) {
                unsigned int i = 0;
                for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
@@ -740,22 +798,31 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
                                continue;
 
                        if (ret)
-                               goto error_ret;
+                               return ret;
 
                        attrcount++;
                }
        }
 
-       ret = attrcount;
-error_ret:
-       return ret;
+       return attrcount;
 }
 
-static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
-                                                struct iio_dev_attr *p)
+/**
+ * iio_free_chan_devattr_list() - Free a list of IIO device attributes
+ * @attr_list: List of IIO device attributes
+ *
+ * This function frees the memory allocated for each of the IIO device
+ * attributes in the list. Note: if you want to reuse the list after calling
+ * this function you have to reinitialize it using INIT_LIST_HEAD().
+ */
+void iio_free_chan_devattr_list(struct list_head *attr_list)
 {
-       kfree(p->dev_attr.attr.name);
-       kfree(p);
+       struct iio_dev_attr *p, *n;
+
+       list_for_each_entry_safe(p, n, attr_list, l) {
+               kfree(p->dev_attr.attr.name);
+               kfree(p);
+       }
 }
 
 static ssize_t iio_show_dev_name(struct device *dev,
@@ -771,7 +838,7 @@ static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
 static int iio_device_register_sysfs(struct iio_dev *indio_dev)
 {
        int i, ret = 0, attrcount, attrn, attrcount_orig = 0;
-       struct iio_dev_attr *p, *n;
+       struct iio_dev_attr *p;
        struct attribute **attr;
 
        /* First count elements in any existing group */
@@ -824,11 +891,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
        return 0;
 
 error_clear_attrs:
-       list_for_each_entry_safe(p, n,
-                                &indio_dev->channel_attr_list, l) {
-               list_del(&p->l);
-               iio_device_remove_and_free_read_attr(indio_dev, p);
-       }
+       iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
 
        return ret;
 }
@@ -836,12 +899,7 @@ error_clear_attrs:
 static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
 {
 
-       struct iio_dev_attr *p, *n;
-
-       list_for_each_entry_safe(p, n, &indio_dev->channel_attr_list, l) {
-               list_del(&p->l);
-               iio_device_remove_and_free_read_attr(indio_dev, p);
-       }
+       iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
        kfree(indio_dev->chan_attr_group.attrs);
 }
 
@@ -853,6 +911,8 @@ static void iio_dev_release(struct device *device)
        iio_device_unregister_eventset(indio_dev);
        iio_device_unregister_sysfs(indio_dev);
 
+       iio_buffer_put(indio_dev->buffer);
+
        ida_simple_remove(&iio_ida, indio_dev->id);
        kfree(indio_dev);
 }
@@ -890,7 +950,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
                dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL);
                if (dev->id < 0) {
                        /* cannot use a dev_err as the name isn't available */
-                       printk(KERN_ERR "Failed to get id\n");
+                       pr_err("failed to get device id\n");
                        kfree(dev);
                        return NULL;
                }
@@ -995,6 +1055,9 @@ static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        int __user *ip = (int __user *)arg;
        int fd;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        if (cmd == IIO_GET_EVENT_FD_IOCTL) {
                fd = iio_event_getfd(indio_dev);
                if (copy_to_user(ip, &fd, sizeof(fd)))
@@ -1091,6 +1154,10 @@ void iio_device_unregister(struct iio_dev *indio_dev)
        iio_disable_all_buffers(indio_dev);
 
        indio_dev->info = NULL;
+
+       iio_device_wakeup_eventset(indio_dev);
+       iio_buffer_wakeup_poll(indio_dev);
+
        mutex_unlock(&indio_dev->info_exist_lock);
 }
 EXPORT_SYMBOL(iio_device_unregister);
index 6be65ef5faa9b6e46716857af7ed67d8eb7ea004..dac15b9f9df8db9bf42518d1394875347b5fb0c6 100644 (file)
@@ -76,6 +76,9 @@ static unsigned int iio_event_poll(struct file *filep,
        struct iio_event_interface *ev_int = indio_dev->event_interface;
        unsigned int events = 0;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        poll_wait(filep, &ev_int->wait, wait);
 
        spin_lock_irq(&ev_int->wait.lock);
@@ -96,6 +99,9 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
        unsigned int copied;
        int ret;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        if (count < sizeof(struct iio_event_data))
                return -EINVAL;
 
@@ -107,9 +113,14 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
                }
                /* Blocking on device; waiting for something to be there */
                ret = wait_event_interruptible_locked_irq(ev_int->wait,
-                                       !kfifo_is_empty(&ev_int->det_events));
+                                       !kfifo_is_empty(&ev_int->det_events) ||
+                                       indio_dev->info == NULL);
                if (ret)
                        goto error_unlock;
+               if (indio_dev->info == NULL) {
+                       ret = -ENODEV;
+                       goto error_unlock;
+               }
                /* Single access device so no one else can get the data */
        }
 
@@ -166,7 +177,7 @@ int iio_event_getfd(struct iio_dev *indio_dev)
        iio_device_get(indio_dev);
 
        fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
-                               indio_dev, O_RDONLY);
+                               indio_dev, O_RDONLY | O_CLOEXEC);
        if (fd < 0) {
                spin_lock_irq(&ev_int->wait.lock);
                __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
@@ -190,6 +201,27 @@ static const char * const iio_ev_dir_text[] = {
        [IIO_EV_DIR_FALLING] = "falling"
 };
 
+static const char * const iio_ev_info_text[] = {
+       [IIO_EV_INFO_ENABLE] = "en",
+       [IIO_EV_INFO_VALUE] = "value",
+       [IIO_EV_INFO_HYSTERESIS] = "hysteresis",
+};
+
+static enum iio_event_direction iio_ev_attr_dir(struct iio_dev_attr *attr)
+{
+       return attr->c->event_spec[attr->address & 0xffff].dir;
+}
+
+static enum iio_event_type iio_ev_attr_type(struct iio_dev_attr *attr)
+{
+       return attr->c->event_spec[attr->address & 0xffff].type;
+}
+
+static enum iio_event_info iio_ev_attr_info(struct iio_dev_attr *attr)
+{
+       return (attr->address >> 16) & 0xffff;
+}
+
 static ssize_t iio_ev_state_store(struct device *dev,
                                  struct device_attribute *attr,
                                  const char *buf,
@@ -204,9 +236,14 @@ static ssize_t iio_ev_state_store(struct device *dev,
        if (ret < 0)
                return ret;
 
-       ret = indio_dev->info->write_event_config(indio_dev,
-                                                 this_attr->address,
-                                                 val);
+       if (indio_dev->info->write_event_config)
+               ret = indio_dev->info->write_event_config(indio_dev,
+                       this_attr->address, val);
+       else
+               ret = indio_dev->info->write_event_config_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr), val);
+
        return (ret < 0) ? ret : len;
 }
 
@@ -216,9 +253,15 @@ static ssize_t iio_ev_state_show(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       int val = indio_dev->info->read_event_config(indio_dev,
-                                                    this_attr->address);
+       int val;
 
+       if (indio_dev->info->read_event_config)
+               val = indio_dev->info->read_event_config(indio_dev,
+                       this_attr->address);
+       else
+               val = indio_dev->info->read_event_config_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr));
        if (val < 0)
                return val;
        else
@@ -231,14 +274,24 @@ static ssize_t iio_ev_value_show(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       int val, ret;
-
-       ret = indio_dev->info->read_event_value(indio_dev,
-                                               this_attr->address, &val);
-       if (ret < 0)
-               return ret;
+       int val, val2;
+       int ret;
 
-       return sprintf(buf, "%d\n", val);
+       if (indio_dev->info->read_event_value) {
+               ret = indio_dev->info->read_event_value(indio_dev,
+                       this_attr->address, &val);
+               if (ret < 0)
+                       return ret;
+               return sprintf(buf, "%d\n", val);
+       } else {
+               ret = indio_dev->info->read_event_value_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
+                       &val, &val2);
+               if (ret < 0)
+                       return ret;
+               return iio_format_value(buf, ret, val, val2);
+       }
 }
 
 static ssize_t iio_ev_value_store(struct device *dev,
@@ -248,25 +301,120 @@ static ssize_t iio_ev_value_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       int val;
+       int val, val2;
        int ret;
 
-       if (!indio_dev->info->write_event_value)
+       if (!indio_dev->info->write_event_value &&
+               !indio_dev->info->write_event_value_new)
                return -EINVAL;
 
-       ret = kstrtoint(buf, 10, &val);
-       if (ret)
-               return ret;
-
-       ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
-                                                val);
+       if (indio_dev->info->write_event_value) {
+               ret = kstrtoint(buf, 10, &val);
+               if (ret)
+                       return ret;
+               ret = indio_dev->info->write_event_value(indio_dev,
+                       this_attr->address, val);
+       } else {
+               ret = iio_str_to_fixpoint(buf, 100000, &val, &val2);
+               if (ret)
+                       return ret;
+               ret = indio_dev->info->write_event_value_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
+                       val, val2);
+       }
        if (ret < 0)
                return ret;
 
        return len;
 }
 
-static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
+static int iio_device_add_event(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int spec_index,
+       enum iio_event_type type, enum iio_event_direction dir,
+       enum iio_shared_by shared_by, const unsigned long *mask)
+{
+       ssize_t (*show)(struct device *, struct device_attribute *, char *);
+       ssize_t (*store)(struct device *, struct device_attribute *,
+               const char *, size_t);
+       unsigned int attrcount = 0;
+       unsigned int i;
+       char *postfix;
+       int ret;
+
+       for_each_set_bit(i, mask, sizeof(*mask)) {
+               postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
+                               iio_ev_type_text[type], iio_ev_dir_text[dir],
+                               iio_ev_info_text[i]);
+               if (postfix == NULL)
+                       return -ENOMEM;
+
+               if (i == IIO_EV_INFO_ENABLE) {
+                       show = iio_ev_state_show;
+                       store = iio_ev_state_store;
+               } else {
+                       show = iio_ev_value_show;
+                       store = iio_ev_value_store;
+               }
+
+               ret = __iio_add_chan_devattr(postfix, chan, show, store,
+                        (i << 16) | spec_index, shared_by, &indio_dev->dev,
+                       &indio_dev->event_interface->dev_attr_list);
+               kfree(postfix);
+
+               if (ret)
+                       return ret;
+
+               attrcount++;
+       }
+
+       return attrcount;
+}
+
+static int iio_device_add_event_sysfs_new(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan)
+{
+       int ret = 0, i, attrcount = 0;
+       enum iio_event_direction dir;
+       enum iio_event_type type;
+
+       for (i = 0; i < chan->num_event_specs; i++) {
+               type = chan->event_spec[i].type;
+               dir = chan->event_spec[i].dir;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SEPARATE, &chan->event_spec[i].mask_separate);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SHARED_BY_TYPE,
+                       &chan->event_spec[i].mask_shared_by_type);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SHARED_BY_DIR,
+                       &chan->event_spec[i].mask_shared_by_dir);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SHARED_BY_ALL,
+                       &chan->event_spec[i].mask_shared_by_all);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+       }
+       ret = attrcount;
+error_ret:
+       return ret;
+}
+
+static int iio_device_add_event_sysfs_old(struct iio_dev *indio_dev,
                                      struct iio_chan_spec const *chan)
 {
        int ret = 0, i, attrcount = 0;
@@ -339,15 +487,14 @@ error_ret:
        return ret;
 }
 
-static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev)
+
+static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
+                                     struct iio_chan_spec const *chan)
 {
-       struct iio_dev_attr *p, *n;
-       list_for_each_entry_safe(p, n,
-                                &indio_dev->event_interface->
-                                dev_attr_list, l) {
-               kfree(p->dev_attr.attr.name);
-               kfree(p);
-       }
+       if (chan->event_mask)
+               return iio_device_add_event_sysfs_old(indio_dev, chan);
+       else
+               return iio_device_add_event_sysfs_new(indio_dev, chan);
 }
 
 static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
@@ -369,9 +516,12 @@ static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)
 {
        int j;
 
-       for (j = 0; j < indio_dev->num_channels; j++)
+       for (j = 0; j < indio_dev->num_channels; j++) {
                if (indio_dev->channels[j].event_mask != 0)
                        return true;
+               if (indio_dev->channels[j].num_event_specs != 0)
+                       return true;
+       }
        return false;
 }
 
@@ -441,18 +591,32 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
        return 0;
 
 error_free_setup_event_lines:
-       __iio_remove_event_config_attrs(indio_dev);
+       iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
        kfree(indio_dev->event_interface);
 error_ret:
 
        return ret;
 }
 
+/**
+ * iio_device_wakeup_eventset - Wakes up the event waitqueue
+ * @indio_dev: The IIO device
+ *
+ * Wakes up the event waitqueue used for poll() and blocking read().
+ * Should usually be called when the device is unregistered.
+ */
+void iio_device_wakeup_eventset(struct iio_dev *indio_dev)
+{
+       if (indio_dev->event_interface == NULL)
+               return;
+       wake_up(&indio_dev->event_interface->wait);
+}
+
 void iio_device_unregister_eventset(struct iio_dev *indio_dev)
 {
        if (indio_dev->event_interface == NULL)
                return;
-       __iio_remove_event_config_attrs(indio_dev);
+       iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
        kfree(indio_dev->event_interface->group.attrs);
        kfree(indio_dev->event_interface);
 }
index 46c619b0d8c51141b6ee23aaf0a76d1facf525e7..d6f54930b34af49185f6fa76dd41372a5214bc35 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/trigger_consumer.h>
 
 static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
-       .preenable = &iio_sw_buffer_preenable,
        .postenable = &iio_triggered_buffer_postenable,
        .predisable = &iio_triggered_buffer_predisable,
 };
@@ -47,14 +46,17 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
        irqreturn_t (*pollfunc_th)(int irq, void *p),
        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) {
                ret = -ENOMEM;
                goto error_ret;
        }
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh,
                                                 pollfunc_th,
                                                 IRQF_ONESHOT,
index a923c78d5cb48f40b2b661933b329f4ddb420c64..95c6fc81c2c78f2d57598995753e342302c3cb3a 100644 (file)
@@ -7,10 +7,12 @@
 #include <linux/mutex.h>
 #include <linux/iio/kfifo_buf.h>
 #include <linux/sched.h>
+#include <linux/poll.h>
 
 struct iio_kfifo {
        struct iio_buffer buffer;
        struct kfifo kf;
+       struct mutex user_lock;
        int update_needed;
 };
 
@@ -31,13 +33,18 @@ static int iio_request_update_kfifo(struct iio_buffer *r)
        int ret = 0;
        struct iio_kfifo *buf = iio_to_kfifo(r);
 
-       if (!buf->update_needed)
-               goto error_ret;
-       kfifo_free(&buf->kf);
-       ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
+       mutex_lock(&buf->user_lock);
+       if (buf->update_needed) {
+               kfifo_free(&buf->kf);
+               ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
                                   buf->buffer.length);
+               buf->update_needed = false;
+       } else {
+               kfifo_reset_out(&buf->kf);
+       }
        r->stufftoread = false;
-error_ret:
+       mutex_unlock(&buf->user_lock);
+
        return ret;
 }
 
@@ -94,7 +101,7 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length)
 }
 
 static int iio_store_to_kfifo(struct iio_buffer *r,
-                             u8 *data)
+                             const void *data)
 {
        int ret;
        struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -102,7 +109,7 @@ static int iio_store_to_kfifo(struct iio_buffer *r,
        if (ret != 1)
                return -EBUSY;
        r->stufftoread = true;
-       wake_up_interruptible(&r->pollq);
+       wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM);
 
        return 0;
 }
@@ -113,12 +120,13 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r,
        int ret, copied;
        struct iio_kfifo *kf = iio_to_kfifo(r);
 
-       if (n < r->bytes_per_datum || r->bytes_per_datum == 0)
-               return -EINVAL;
+       if (mutex_lock_interruptible(&kf->user_lock))
+               return -ERESTARTSYS;
 
-       ret = kfifo_to_user(&kf->kf, buf, n, &copied);
-       if (ret < 0)
-               return ret;
+       if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
+               ret = -EINVAL;
+       else
+               ret = kfifo_to_user(&kf->kf, buf, n, &copied);
 
        if (kfifo_is_empty(&kf->kf))
                r->stufftoread = false;
@@ -126,9 +134,22 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r,
        if (!kfifo_is_empty(&kf->kf))
                r->stufftoread = true;
 
+       mutex_unlock(&kf->user_lock);
+       if (ret < 0)
+               return ret;
+
        return copied;
 }
 
+static void iio_kfifo_buffer_release(struct iio_buffer *buffer)
+{
+       struct iio_kfifo *kf = iio_to_kfifo(buffer);
+
+       mutex_destroy(&kf->user_lock);
+       kfifo_free(&kf->kf);
+       kfree(kf);
+}
+
 static const struct iio_buffer_access_funcs kfifo_access_funcs = {
        .store_to = &iio_store_to_kfifo,
        .read_first_n = &iio_read_first_n_kfifo,
@@ -137,6 +158,7 @@ static const struct iio_buffer_access_funcs kfifo_access_funcs = {
        .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
        .get_length = &iio_get_length_kfifo,
        .set_length = &iio_set_length_kfifo,
+       .release = &iio_kfifo_buffer_release,
 };
 
 struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
@@ -151,13 +173,14 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
        kf->buffer.attrs = &iio_kfifo_attribute_group;
        kf->buffer.access = &kfifo_access_funcs;
        kf->buffer.length = 2;
+       mutex_init(&kf->user_lock);
        return &kf->buffer;
 }
 EXPORT_SYMBOL(iio_kfifo_allocate);
 
 void iio_kfifo_free(struct iio_buffer *r)
 {
-       kfree(iio_to_kfifo(r));
+       iio_buffer_put(r);
 }
 EXPORT_SYMBOL(iio_kfifo_free);
 
index bf9fa0d7aff9c26d0b4caf22bf25881de868c93d..f98c2b509254e2b8fdce8cd77db408f11b244495 100644 (file)
@@ -27,6 +27,29 @@ config APDS9300
         To compile this driver as a module, choose M here: the
         module will be called apds9300.
 
+config CM36651
+       depends on I2C
+       tristate "CM36651 driver"
+       help
+        Say Y here if you use cm36651.
+        This option enables proximity & RGB sensor using
+        Capella cm36651 device driver.
+
+        To compile this driver as a module, choose M here:
+        the module will be called cm36651.
+
+config GP2AP020A00F
+       tristate "Sharp GP2AP020A00F Proximity/ALS sensor"
+       depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say Y here if you have a Sharp GP2AP020A00F proximity/ALS combo-chip
+         hooked to an I2C bus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gp2ap020a00f.
+
 config HID_SENSOR_ALS
        depends on HID_SENSOR_HUB
        select IIO_BUFFER
@@ -55,6 +78,16 @@ config SENSORS_LM3533
          changes. The ALS-control output values can be set per zone for the
          three current output channels.
 
+config TCS3472
+       tristate "TAOS TCS3472 color light-to-digital converter"
+       depends on I2C
+       help
+        If you say yes here you get support for the TAOS TCS3472
+        family of color light-to-digital converters with IR filter.
+
+        This driver can also be built as a module.  If so, the module
+        will be called tcs3472.
+
 config SENSORS_TSL2563
        tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
        depends on I2C
@@ -65,6 +98,16 @@ config SENSORS_TSL2563
         This driver can also be built as a module.  If so, the module
         will be called tsl2563.
 
+config TSL4531
+       tristate "TAOS TSL4531 ambient light sensors"
+       depends on I2C
+       help
+        Say Y here if you want to build a driver for the TAOS TSL4531 family
+        of ambient light sensors with direct lux output.
+
+        To compile this driver as a module, choose M here: the
+        module will be called tsl4531.
+
 config VCNL4000
        tristate "VCNL4000 combined ALS and proximity sensor"
        depends on I2C
index 354ee9ab2379a92ba73a486d399e0b243c594ea1..daa327f39e04e71923e514320e081bab337633d2 100644 (file)
@@ -5,7 +5,11 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADJD_S311)                += adjd_s311.o
 obj-$(CONFIG_APDS9300)         += apds9300.o
+obj-$(CONFIG_CM36651)          += cm36651.o
+obj-$(CONFIG_GP2AP020A00F)     += gp2ap020a00f.o
 obj-$(CONFIG_HID_SENSOR_ALS)   += hid-sensor-als.o
 obj-$(CONFIG_SENSORS_LM3533)   += lm3533-als.o
 obj-$(CONFIG_SENSORS_TSL2563)  += tsl2563.o
+obj-$(CONFIG_TCS3472)          += tcs3472.o
+obj-$(CONFIG_TSL4531)          += tsl4531.o
 obj-$(CONFIG_VCNL4000)         += vcnl4000.o
index 23cff798598aad0cf0f3078de05804d6a07541b5..83d15c5baf646cd61de0ecf4b87fa054b1df0f49 100644 (file)
@@ -114,43 +114,6 @@ static int adjd_s311_read_data(struct iio_dev *indio_dev, u8 reg, int *val)
        return 0;
 }
 
-static ssize_t adjd_s311_read_int_time(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct adjd_s311_data *data = iio_priv(indio_dev);
-       s32 ret;
-
-       ret = i2c_smbus_read_word_data(data->client,
-               ADJD_S311_INT_REG(chan->address));
-       if (ret < 0)
-               return ret;
-
-       return sprintf(buf, "%d\n", ret & ADJD_S311_INT_MASK);
-}
-
-static ssize_t adjd_s311_write_int_time(struct iio_dev *indio_dev,
-        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-        size_t len)
-{
-       struct adjd_s311_data *data = iio_priv(indio_dev);
-       unsigned long int_time;
-       int ret;
-
-       ret = kstrtoul(buf, 10, &int_time);
-       if (ret)
-               return ret;
-
-       if (int_time > ADJD_S311_INT_MASK)
-               return -EINVAL;
-
-       ret = i2c_smbus_write_word_data(data->client,
-               ADJD_S311_INT_REG(chan->address), int_time);
-       if (ret < 0)
-               return ret;
-
-       return len;
-}
-
 static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
 {
        struct iio_poll_func *pf = p;
@@ -175,10 +138,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
                len += 2;
        }
 
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
-                       = time_ns;
-       iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, time_ns);
 
 done:
        iio_trigger_notify_done(indio_dev->trig);
@@ -186,25 +146,16 @@ done:
        return IRQ_HANDLED;
 }
 
-static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = {
-       {
-               .name = "integration_time",
-               .read = adjd_s311_read_int_time,
-               .write = adjd_s311_write_int_time,
-       },
-       { }
-};
-
 #define ADJD_S311_CHANNEL(_color, _scan_idx) { \
        .type = IIO_INTENSITY, \
        .modified = 1, \
        .address = (IDX_##_color), \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
-               BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
+               BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
+               BIT(IIO_CHAN_INFO_INT_TIME), \
        .channel2 = (IIO_MOD_LIGHT_##_color), \
        .scan_index = (_scan_idx), \
        .scan_type = IIO_ST('u', 10, 16, 0), \
-       .ext_info = adjd_s311_ext_info, \
 }
 
 static const struct iio_chan_spec adjd_s311_channels[] = {
@@ -236,6 +187,18 @@ static int adjd_s311_read_raw(struct iio_dev *indio_dev,
                        return ret;
                *val = ret & ADJD_S311_CAP_MASK;
                return IIO_VAL_INT;
+       case IIO_CHAN_INFO_INT_TIME:
+               ret = i2c_smbus_read_word_data(data->client,
+                       ADJD_S311_INT_REG(chan->address));
+               if (ret < 0)
+                       return ret;
+               *val = 0;
+               /*
+                * not documented, based on measurement:
+                * 4095 LSBs correspond to roughly 4 ms
+                */
+               *val2 = ret & ADJD_S311_INT_MASK;
+               return IIO_VAL_INT_PLUS_MICRO;
        }
        return -EINVAL;
 }
@@ -245,16 +208,20 @@ static int adjd_s311_write_raw(struct iio_dev *indio_dev,
                               int val, int val2, long mask)
 {
        struct adjd_s311_data *data = iio_priv(indio_dev);
-       int ret;
 
        switch (mask) {
        case IIO_CHAN_INFO_HARDWAREGAIN:
                if (val < 0 || val > ADJD_S311_CAP_MASK)
                        return -EINVAL;
 
-               ret = i2c_smbus_write_byte_data(data->client,
+               return i2c_smbus_write_byte_data(data->client,
                        ADJD_S311_CAP_REG(chan->address), val);
-               return ret;
+       case IIO_CHAN_INFO_INT_TIME:
+               if (val != 0 || val2 < 0 || val2 > ADJD_S311_INT_MASK)
+                       return -EINVAL;
+
+               return i2c_smbus_write_word_data(data->client,
+                       ADJD_S311_INT_REG(chan->address), val2);
        }
        return -EINVAL;
 }
index 66a58bda6dc893b96efb106be82296c275419c37..51097bbd59c94a584ed4ab060f0fda2729df80f6 100644 (file)
@@ -273,12 +273,14 @@ static int apds9300_read_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
-static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
-               int *val)
+static int apds9300_read_thresh(struct iio_dev *indio_dev,
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, enum iio_event_info info,
+               int *val, int *val2)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
 
-       switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       switch (dir) {
        case IIO_EV_DIR_RISING:
                *val = data->thresh_hi;
                break;
@@ -289,17 +291,19 @@ static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
                return -EINVAL;
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
-static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
-               int val)
+static int apds9300_write_thresh(struct iio_dev *indio_dev,
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, enum iio_event_info info, int val,
+               int val2)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
        int ret;
 
        mutex_lock(&data->mutex);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+       if (dir == IIO_EV_DIR_RISING)
                ret = apds9300_set_thresh_hi(data, val);
        else
                ret = apds9300_set_thresh_low(data, val);
@@ -309,7 +313,9 @@ static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
 }
 
 static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
-               u64 event_code)
+               const struct iio_chan_spec *chan,
+               enum iio_event_type type,
+               enum iio_event_direction dir)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
 
@@ -317,7 +323,8 @@ static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
 }
 
 static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
-               u64 event_code, int state)
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, int state)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
        int ret;
@@ -337,10 +344,24 @@ static const struct iio_info apds9300_info_no_irq = {
 static const struct iio_info apds9300_info = {
        .driver_module          = THIS_MODULE,
        .read_raw               = apds9300_read_raw,
-       .read_event_value       = apds9300_read_thresh,
-       .write_event_value      = apds9300_write_thresh,
-       .read_event_config      = apds9300_read_interrupt_config,
-       .write_event_config     = apds9300_write_interrupt_config,
+       .read_event_value_new   = apds9300_read_thresh,
+       .write_event_value_new  = apds9300_write_thresh,
+       .read_event_config_new  = apds9300_read_interrupt_config,
+       .write_event_config_new = apds9300_write_interrupt_config,
+};
+
+static const struct iio_event_spec apds9300_event_spec[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
 };
 
 static const struct iio_chan_spec apds9300_channels[] = {
@@ -355,10 +376,8 @@ static const struct iio_chan_spec apds9300_channels[] = {
                .channel2 = IIO_MOD_LIGHT_BOTH,
                .indexed = true,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-               .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_RISING) |
-                              IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_FALLING)),
+               .event_spec = apds9300_event_spec,
+               .num_event_specs = ARRAY_SIZE(apds9300_event_spec),
        }, {
                .type = IIO_INTENSITY,
                .channel = 1,
diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c
new file mode 100644 (file)
index 0000000..21df571
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.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.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+
+/* Slave address 0x19 for PS of 7 bit addressing protocol for I2C */
+#define CM36651_I2C_ADDR_PS            0x19
+/* Alert Response Address */
+#define CM36651_ARA                    0x0C
+
+/* Ambient light sensor */
+#define CM36651_CS_CONF1               0x00
+#define CM36651_CS_CONF2               0x01
+#define CM36651_ALS_WH_M               0x02
+#define CM36651_ALS_WH_L               0x03
+#define CM36651_ALS_WL_M               0x04
+#define CM36651_ALS_WL_L               0x05
+#define CM36651_CS_CONF3               0x06
+#define CM36651_CS_CONF_REG_NUM                0x02
+
+/* Proximity sensor */
+#define CM36651_PS_CONF1               0x00
+#define CM36651_PS_THD                 0x01
+#define CM36651_PS_CANC                        0x02
+#define CM36651_PS_CONF2               0x03
+#define CM36651_PS_REG_NUM             0x04
+
+/* CS_CONF1 command code */
+#define CM36651_ALS_ENABLE             0x00
+#define CM36651_ALS_DISABLE            0x01
+#define CM36651_ALS_INT_EN             0x02
+#define CM36651_ALS_THRES              0x04
+
+/* CS_CONF2 command code */
+#define CM36651_CS_CONF2_DEFAULT_BIT   0x08
+
+/* CS_CONF3 channel integration time */
+#define CM36651_CS_IT1                 0x00 /* Integration time 80000 usec */
+#define CM36651_CS_IT2                 0x40 /* Integration time 160000 usec */
+#define CM36651_CS_IT3                 0x80 /* Integration time 320000 usec */
+#define CM36651_CS_IT4                 0xC0 /* Integration time 640000 usec */
+
+/* PS_CONF1 command code */
+#define CM36651_PS_ENABLE              0x00
+#define CM36651_PS_DISABLE             0x01
+#define CM36651_PS_INT_EN              0x02
+#define CM36651_PS_PERS2               0x04
+#define CM36651_PS_PERS3               0x08
+#define CM36651_PS_PERS4               0x0C
+
+/* PS_CONF1 command code: integration time */
+#define CM36651_PS_IT1                 0x00 /* Integration time 320 usec */
+#define CM36651_PS_IT2                 0x10 /* Integration time 420 usec */
+#define CM36651_PS_IT3                 0x20 /* Integration time 520 usec */
+#define CM36651_PS_IT4                 0x30 /* Integration time 640 usec */
+
+/* PS_CONF1 command code: duty ratio */
+#define CM36651_PS_DR1                 0x00 /* Duty ratio 1/80 */
+#define CM36651_PS_DR2                 0x40 /* Duty ratio 1/160 */
+#define CM36651_PS_DR3                 0x80 /* Duty ratio 1/320 */
+#define CM36651_PS_DR4                 0xC0 /* Duty ratio 1/640 */
+
+/* PS_THD command code */
+#define CM36651_PS_INITIAL_THD         0x05
+
+/* PS_CANC command code */
+#define CM36651_PS_CANC_DEFAULT                0x00
+
+/* PS_CONF2 command code */
+#define CM36651_PS_HYS1                        0x00
+#define CM36651_PS_HYS2                        0x01
+#define CM36651_PS_SMART_PERS_EN       0x02
+#define CM36651_PS_DIR_INT             0x04
+#define CM36651_PS_MS                  0x10
+
+#define CM36651_CS_COLOR_NUM           4
+
+#define CM36651_CLOSE_PROXIMITY                0x32
+#define CM36651_FAR_PROXIMITY                  0x33
+
+#define CM36651_CS_INT_TIME_AVAIL      "80000 160000 320000 640000"
+#define CM36651_PS_INT_TIME_AVAIL      "320 420 520 640"
+
+enum cm36651_operation_mode {
+       CM36651_LIGHT_EN,
+       CM36651_PROXIMITY_EN,
+       CM36651_PROXIMITY_EV_EN,
+};
+
+enum cm36651_light_channel_idx {
+       CM36651_LIGHT_CHANNEL_IDX_RED,
+       CM36651_LIGHT_CHANNEL_IDX_GREEN,
+       CM36651_LIGHT_CHANNEL_IDX_BLUE,
+       CM36651_LIGHT_CHANNEL_IDX_CLEAR,
+};
+
+enum cm36651_command {
+       CM36651_CMD_READ_RAW_LIGHT,
+       CM36651_CMD_READ_RAW_PROXIMITY,
+       CM36651_CMD_PROX_EV_EN,
+       CM36651_CMD_PROX_EV_DIS,
+};
+
+static const u8 cm36651_cs_reg[CM36651_CS_CONF_REG_NUM] = {
+       CM36651_CS_CONF1,
+       CM36651_CS_CONF2,
+};
+
+static const u8 cm36651_ps_reg[CM36651_PS_REG_NUM] = {
+       CM36651_PS_CONF1,
+       CM36651_PS_THD,
+       CM36651_PS_CANC,
+       CM36651_PS_CONF2,
+};
+
+struct cm36651_data {
+       const struct cm36651_platform_data *pdata;
+       struct i2c_client *client;
+       struct i2c_client *ps_client;
+       struct i2c_client *ara_client;
+       struct mutex lock;
+       struct regulator *vled_reg;
+       unsigned long flags;
+       int cs_int_time[CM36651_CS_COLOR_NUM];
+       int ps_int_time;
+       u8 cs_ctrl_regs[CM36651_CS_CONF_REG_NUM];
+       u8 ps_ctrl_regs[CM36651_PS_REG_NUM];
+       u16 color[CM36651_CS_COLOR_NUM];
+};
+
+static int cm36651_setup_reg(struct cm36651_data *cm36651)
+{
+       struct i2c_client *client = cm36651->client;
+       struct i2c_client *ps_client = cm36651->ps_client;
+       int i, ret;
+
+       /* CS initialization */
+       cm36651->cs_ctrl_regs[CM36651_CS_CONF1] = CM36651_ALS_ENABLE |
+                                                            CM36651_ALS_THRES;
+       cm36651->cs_ctrl_regs[CM36651_CS_CONF2] = CM36651_CS_CONF2_DEFAULT_BIT;
+
+       for (i = 0; i < CM36651_CS_CONF_REG_NUM; i++) {
+               ret = i2c_smbus_write_byte_data(client, cm36651_cs_reg[i],
+                                                    cm36651->cs_ctrl_regs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       /* PS initialization */
+       cm36651->ps_ctrl_regs[CM36651_PS_CONF1] = CM36651_PS_ENABLE |
+                                                               CM36651_PS_IT2;
+       cm36651->ps_ctrl_regs[CM36651_PS_THD] = CM36651_PS_INITIAL_THD;
+       cm36651->ps_ctrl_regs[CM36651_PS_CANC] = CM36651_PS_CANC_DEFAULT;
+       cm36651->ps_ctrl_regs[CM36651_PS_CONF2] = CM36651_PS_HYS2 |
+                               CM36651_PS_DIR_INT | CM36651_PS_SMART_PERS_EN;
+
+       for (i = 0; i < CM36651_PS_REG_NUM; i++) {
+               ret = i2c_smbus_write_byte_data(ps_client, cm36651_ps_reg[i],
+                                                    cm36651->ps_ctrl_regs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       /* Set shutdown mode */
+       ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
+                                                         CM36651_ALS_DISABLE);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(cm36651->ps_client,
+                                        CM36651_PS_CONF1, CM36651_PS_DISABLE);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int cm36651_read_output(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       struct i2c_client *client = cm36651->client;
+       int ret = -EINVAL;
+
+       switch (chan->type) {
+       case IIO_LIGHT:
+               *val = i2c_smbus_read_word_data(client, chan->address);
+               if (*val < 0)
+                       return ret;
+
+               ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
+                                                       CM36651_ALS_DISABLE);
+               if (ret < 0)
+                       return ret;
+
+               ret = IIO_VAL_INT;
+               break;
+       case IIO_PROXIMITY:
+               *val = i2c_smbus_read_byte(cm36651->ps_client);
+               if (*val < 0)
+                       return ret;
+
+               if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
+                       ret = i2c_smbus_write_byte_data(cm36651->ps_client,
+                                       CM36651_PS_CONF1, CM36651_PS_DISABLE);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               ret = IIO_VAL_INT;
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+static irqreturn_t cm36651_irq_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+       int ev_dir, ret;
+       u64 ev_code;
+
+       /*
+        * The PS INT pin is an active low signal that PS INT move logic low
+        * when the object is detect. Once the MCU host received the PS INT
+        * "LOW" signal, the Host needs to read the data at Alert Response
+        * Address(ARA) to clear the PS INT signal. After clearing the PS
+        * INT pin, the PS INT signal toggles from low to high.
+        */
+       ret = i2c_smbus_read_byte(cm36651->ara_client);
+       if (ret < 0) {
+               dev_err(&client->dev,
+                               "%s: Data read failed: %d\n", __func__, ret);
+               return IRQ_HANDLED;
+       }
+       switch (ret) {
+       case CM36651_CLOSE_PROXIMITY:
+               ev_dir = IIO_EV_DIR_RISING;
+               break;
+       case CM36651_FAR_PROXIMITY:
+               ev_dir = IIO_EV_DIR_FALLING;
+               break;
+       default:
+               dev_err(&client->dev,
+                       "%s: Data read wrong: %d\n", __func__, ret);
+               return IRQ_HANDLED;
+       }
+
+       ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
+                               CM36651_CMD_READ_RAW_PROXIMITY,
+                               IIO_EV_TYPE_THRESH, ev_dir);
+
+       iio_push_event(indio_dev, ev_code, iio_get_time_ns());
+
+       return IRQ_HANDLED;
+}
+
+static int cm36651_set_operation_mode(struct cm36651_data *cm36651, int cmd)
+{
+       struct i2c_client *client = cm36651->client;
+       struct i2c_client *ps_client = cm36651->ps_client;
+       int ret = -EINVAL;
+
+       switch (cmd) {
+       case CM36651_CMD_READ_RAW_LIGHT:
+               ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
+                               cm36651->cs_ctrl_regs[CM36651_CS_CONF1]);
+               break;
+       case CM36651_CMD_READ_RAW_PROXIMITY:
+               if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags))
+                       return CM36651_PROXIMITY_EV_EN;
+
+               ret = i2c_smbus_write_byte_data(ps_client, CM36651_PS_CONF1,
+                               cm36651->ps_ctrl_regs[CM36651_PS_CONF1]);
+               break;
+       case CM36651_CMD_PROX_EV_EN:
+               if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
+                       dev_err(&client->dev,
+                               "Already proximity event enable state\n");
+                       return ret;
+               }
+               set_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+
+               ret = i2c_smbus_write_byte_data(ps_client,
+                       cm36651_ps_reg[CM36651_PS_CONF1],
+                       CM36651_PS_INT_EN | CM36651_PS_PERS2 | CM36651_PS_IT2);
+
+               if (ret < 0) {
+                       dev_err(&client->dev, "Proximity enable event failed\n");
+                       return ret;
+               }
+               break;
+       case CM36651_CMD_PROX_EV_DIS:
+               if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
+                       dev_err(&client->dev,
+                               "Already proximity event disable state\n");
+                       return ret;
+               }
+               clear_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+               ret = i2c_smbus_write_byte_data(ps_client,
+                                       CM36651_PS_CONF1, CM36651_PS_DISABLE);
+               break;
+       }
+
+       if (ret < 0)
+               dev_err(&client->dev, "Write register failed\n");
+
+       return ret;
+}
+
+static int cm36651_read_channel(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       struct i2c_client *client = cm36651->client;
+       int cmd, ret;
+
+       if (chan->type == IIO_LIGHT)
+               cmd = CM36651_CMD_READ_RAW_LIGHT;
+       else if (chan->type == IIO_PROXIMITY)
+               cmd = CM36651_CMD_READ_RAW_PROXIMITY;
+       else
+               return -EINVAL;
+
+       ret = cm36651_set_operation_mode(cm36651, cmd);
+       if (ret < 0) {
+               dev_err(&client->dev, "CM36651 set operation mode failed\n");
+               return ret;
+       }
+       /* Delay for work after enable operation */
+       msleep(50);
+       ret = cm36651_read_output(cm36651, chan, val);
+       if (ret < 0) {
+               dev_err(&client->dev, "CM36651 read output failed\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static int cm36651_read_int_time(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       switch (chan->type) {
+       case IIO_LIGHT:
+               if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1)
+                       *val = 80000;
+               else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2)
+                       *val = 160000;
+               else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3)
+                       *val = 320000;
+               else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4)
+                       *val = 640000;
+               else
+                       return -EINVAL;
+               break;
+       case IIO_PROXIMITY:
+               if (cm36651->ps_int_time == CM36651_PS_IT1)
+                       *val = 320;
+               else if (cm36651->ps_int_time == CM36651_PS_IT2)
+                       *val = 420;
+               else if (cm36651->ps_int_time == CM36651_PS_IT3)
+                       *val = 520;
+               else if (cm36651->ps_int_time == CM36651_PS_IT4)
+                       *val = 640;
+               else
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int cm36651_write_int_time(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int val)
+{
+       struct i2c_client *client = cm36651->client;
+       struct i2c_client *ps_client = cm36651->ps_client;
+       int int_time, ret;
+
+       switch (chan->type) {
+       case IIO_LIGHT:
+               if (val == 80000)
+                       int_time = CM36651_CS_IT1;
+               else if (val == 160000)
+                       int_time = CM36651_CS_IT2;
+               else if (val == 320000)
+                       int_time = CM36651_CS_IT3;
+               else if (val == 640000)
+                       int_time = CM36651_CS_IT4;
+               else
+                       return -EINVAL;
+
+               ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF3,
+                                          int_time >> 2 * (chan->address));
+               if (ret < 0) {
+                       dev_err(&client->dev, "CS integration time write failed\n");
+                       return ret;
+               }
+               cm36651->cs_int_time[chan->address] = int_time;
+               break;
+       case IIO_PROXIMITY:
+               if (val == 320)
+                       int_time = CM36651_PS_IT1;
+               else if (val == 420)
+                       int_time = CM36651_PS_IT2;
+               else if (val == 520)
+                       int_time = CM36651_PS_IT3;
+               else if (val == 640)
+                       int_time = CM36651_PS_IT4;
+               else
+                       return -EINVAL;
+
+               ret = i2c_smbus_write_byte_data(ps_client,
+                                               CM36651_PS_CONF1, int_time);
+               if (ret < 0) {
+                       dev_err(&client->dev, "PS integration time write failed\n");
+                       return ret;
+               }
+               cm36651->ps_int_time = int_time;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int cm36651_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long mask)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&cm36651->lock);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = cm36651_read_channel(cm36651, chan, val);
+               break;
+       case IIO_CHAN_INFO_INT_TIME:
+               ret = cm36651_read_int_time(cm36651, chan, val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       mutex_unlock(&cm36651->lock);
+
+       return ret;
+}
+
+static int cm36651_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+       int ret = -EINVAL;
+
+       if (mask == IIO_CHAN_INFO_INT_TIME) {
+               ret = cm36651_write_int_time(cm36651, chan, val);
+               if (ret < 0)
+                       dev_err(&client->dev, "Integration time write failed\n");
+       }
+
+       return ret;
+}
+
+static int cm36651_read_prox_thresh(struct iio_dev *indio_dev,
+                                       u64 event_code, int *val)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+
+       *val = cm36651->ps_ctrl_regs[CM36651_PS_THD];
+
+       return 0;
+}
+
+static int cm36651_write_prox_thresh(struct iio_dev *indio_dev,
+                                       u64 event_code, int val)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+       int ret;
+
+       if (val < 3 || val > 255)
+               return -EINVAL;
+
+       cm36651->ps_ctrl_regs[CM36651_PS_THD] = val;
+       ret = i2c_smbus_write_byte_data(cm36651->ps_client, CM36651_PS_THD,
+                                       cm36651->ps_ctrl_regs[CM36651_PS_THD]);
+
+       if (ret < 0) {
+               dev_err(&client->dev, "PS threshold write failed: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int cm36651_write_prox_event_config(struct iio_dev *indio_dev,
+                                       u64 event_code, int state)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       int cmd, ret = -EINVAL;
+
+       mutex_lock(&cm36651->lock);
+
+       cmd = state ? CM36651_CMD_PROX_EV_EN : CM36651_CMD_PROX_EV_DIS;
+       ret = cm36651_set_operation_mode(cm36651, cmd);
+
+       mutex_unlock(&cm36651->lock);
+
+       return ret;
+}
+
+static int cm36651_read_prox_event_config(struct iio_dev *indio_dev,
+                                                       u64 event_code)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       int event_en;
+
+       mutex_lock(&cm36651->lock);
+
+       event_en = test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+
+       mutex_unlock(&cm36651->lock);
+
+       return event_en;
+}
+
+#define CM36651_LIGHT_CHANNEL(_color, _idx) {          \
+       .type = IIO_LIGHT,                              \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
+                       BIT(IIO_CHAN_INFO_INT_TIME),    \
+       .address = _idx,                                \
+       .modified = 1,                                  \
+       .channel2 = IIO_MOD_LIGHT_##_color,             \
+}                                                      \
+
+static const struct iio_chan_spec cm36651_channels[] = {
+       {
+               .type = IIO_PROXIMITY,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                               BIT(IIO_CHAN_INFO_INT_TIME),
+               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER)
+       },
+       CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED),
+       CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN),
+       CM36651_LIGHT_CHANNEL(BLUE, CM36651_LIGHT_CHANNEL_IDX_BLUE),
+       CM36651_LIGHT_CHANNEL(CLEAR, CM36651_LIGHT_CHANNEL_IDX_CLEAR),
+};
+
+static IIO_CONST_ATTR(in_illuminance_integration_time_available,
+                                       CM36651_CS_INT_TIME_AVAIL);
+static IIO_CONST_ATTR(in_proximity_integration_time_available,
+                                       CM36651_PS_INT_TIME_AVAIL);
+
+static struct attribute *cm36651_attributes[] = {
+       &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr,
+       &iio_const_attr_in_proximity_integration_time_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group cm36651_attribute_group = {
+       .attrs = cm36651_attributes
+};
+
+static const struct iio_info cm36651_info = {
+       .driver_module          = THIS_MODULE,
+       .read_raw               = &cm36651_read_raw,
+       .write_raw              = &cm36651_write_raw,
+       .read_event_value       = &cm36651_read_prox_thresh,
+       .write_event_value      = &cm36651_write_prox_thresh,
+       .read_event_config      = &cm36651_read_prox_event_config,
+       .write_event_config     = &cm36651_write_prox_event_config,
+       .attrs                  = &cm36651_attribute_group,
+};
+
+static int cm36651_probe(struct i2c_client *client,
+                            const struct i2c_device_id *id)
+{
+       struct cm36651_data *cm36651;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm36651));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       cm36651 = iio_priv(indio_dev);
+
+       cm36651->vled_reg = devm_regulator_get(&client->dev, "vled");
+       if (IS_ERR(cm36651->vled_reg)) {
+               dev_err(&client->dev, "get regulator vled failed\n");
+               return PTR_ERR(cm36651->vled_reg);
+       }
+
+       ret = regulator_enable(cm36651->vled_reg);
+       if (ret) {
+               dev_err(&client->dev, "enable regulator vled failed\n");
+               return ret;
+       }
+
+       i2c_set_clientdata(client, indio_dev);
+
+       cm36651->client = client;
+       cm36651->ps_client = i2c_new_dummy(client->adapter,
+                                                    CM36651_I2C_ADDR_PS);
+       cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA);
+       mutex_init(&cm36651->lock);
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->channels = cm36651_channels;
+       indio_dev->num_channels = ARRAY_SIZE(cm36651_channels);
+       indio_dev->info = &cm36651_info;
+       indio_dev->name = id->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = cm36651_setup_reg(cm36651);
+       if (ret) {
+               dev_err(&client->dev, "%s: register setup failed\n", __func__);
+               goto error_disable_reg;
+       }
+
+       ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler,
+                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                                       "cm36651", indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "%s: request irq failed\n", __func__);
+               goto error_disable_reg;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "%s: regist device failed\n", __func__);
+               goto error_free_irq;
+       }
+
+       return 0;
+
+error_free_irq:
+       free_irq(client->irq, indio_dev);
+error_disable_reg:
+       regulator_disable(cm36651->vled_reg);
+       return ret;
+}
+
+static int cm36651_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       regulator_disable(cm36651->vled_reg);
+       free_irq(client->irq, indio_dev);
+
+       return 0;
+}
+
+static const struct i2c_device_id cm36651_id[] = {
+       { "cm36651", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, cm36651_id);
+
+static const struct of_device_id cm36651_of_match[] = {
+       { .compatible = "capella,cm36651" },
+       { }
+};
+
+static struct i2c_driver cm36651_driver = {
+       .driver = {
+               .name   = "cm36651",
+               .of_match_table = of_match_ptr(cm36651_of_match),
+               .owner  = THIS_MODULE,
+       },
+       .probe          = cm36651_probe,
+       .remove         = cm36651_remove,
+       .id_table       = cm36651_id,
+};
+
+module_i2c_driver(cm36651_driver);
+
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_DESCRIPTION("CM36651 proximity/ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
new file mode 100644 (file)
index 0000000..dc79835
--- /dev/null
@@ -0,0 +1,1654 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
+ *
+ * IIO features supported by the driver:
+ *
+ * Read-only raw channels:
+ *   - illiminance_clear [lux]
+ *   - illiminance_ir
+ *   - proximity
+ *
+ * Triggered buffer:
+ *   - illiminance_clear
+ *   - illiminance_ir
+ *   - proximity
+ *
+ * Events:
+ *   - illuminance_clear (rising and falling)
+ *   - proximity (rising and falling)
+ *     - both falling and rising thresholds for the proximity events
+ *       must be set to the values greater than 0.
+ *
+ * The driver supports triggered buffers for all the three
+ * channels as well as high and low threshold events for the
+ * illuminance_clear and proxmimity channels. Triggers
+ * can be enabled simultaneously with both illuminance_clear
+ * events. Proximity events cannot be enabled simultaneously
+ * with any triggers or illuminance events. Enabling/disabling
+ * one of the proximity events automatically enables/disables
+ * the other one.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irq_work.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define GP2A_I2C_NAME "gp2ap020a00f"
+
+/* Registers */
+#define GP2AP020A00F_OP_REG    0x00 /* Basic operations */
+#define GP2AP020A00F_ALS_REG   0x01 /* ALS related settings */
+#define GP2AP020A00F_PS_REG    0x02 /* PS related settings */
+#define GP2AP020A00F_LED_REG   0x03 /* LED reg */
+#define GP2AP020A00F_TL_L_REG  0x04 /* ALS: Threshold low LSB */
+#define GP2AP020A00F_TL_H_REG  0x05 /* ALS: Threshold low MSB */
+#define GP2AP020A00F_TH_L_REG  0x06 /* ALS: Threshold high LSB */
+#define GP2AP020A00F_TH_H_REG  0x07 /* ALS: Threshold high MSB */
+#define GP2AP020A00F_PL_L_REG  0x08 /* PS: Threshold low LSB */
+#define GP2AP020A00F_PL_H_REG  0x09 /* PS: Threshold low MSB */
+#define GP2AP020A00F_PH_L_REG  0x0a /* PS: Threshold high LSB */
+#define GP2AP020A00F_PH_H_REG  0x0b /* PS: Threshold high MSB */
+#define GP2AP020A00F_D0_L_REG  0x0c /* ALS result: Clear/Illuminance LSB */
+#define GP2AP020A00F_D0_H_REG  0x0d /* ALS result: Clear/Illuminance MSB */
+#define GP2AP020A00F_D1_L_REG  0x0e /* ALS result: IR LSB */
+#define GP2AP020A00F_D1_H_REG  0x0f /* ALS result: IR LSB */
+#define GP2AP020A00F_D2_L_REG  0x10 /* PS result LSB */
+#define GP2AP020A00F_D2_H_REG  0x11 /* PS result MSB */
+#define GP2AP020A00F_NUM_REGS  0x12 /* Number of registers */
+
+/* OP_REG bits */
+#define GP2AP020A00F_OP3_MASK          0x80 /* Software shutdown */
+#define GP2AP020A00F_OP3_SHUTDOWN      0x00
+#define GP2AP020A00F_OP3_OPERATION     0x80
+#define GP2AP020A00F_OP2_MASK          0x40 /* Auto shutdown/Continuous mode */
+#define GP2AP020A00F_OP2_AUTO_SHUTDOWN 0x00
+#define GP2AP020A00F_OP2_CONT_OPERATION        0x40
+#define GP2AP020A00F_OP_MASK           0x30 /* Operating mode selection  */
+#define GP2AP020A00F_OP_ALS_AND_PS     0x00
+#define GP2AP020A00F_OP_ALS            0x10
+#define GP2AP020A00F_OP_PS             0x20
+#define GP2AP020A00F_OP_DEBUG          0x30
+#define GP2AP020A00F_PROX_MASK         0x08 /* PS: detection/non-detection */
+#define GP2AP020A00F_PROX_NON_DETECT   0x00
+#define GP2AP020A00F_PROX_DETECT       0x08
+#define GP2AP020A00F_FLAG_P            0x04 /* PS: interrupt result  */
+#define GP2AP020A00F_FLAG_A            0x02 /* ALS: interrupt result  */
+#define GP2AP020A00F_TYPE_MASK         0x01 /* Output data type selection */
+#define GP2AP020A00F_TYPE_MANUAL_CALC  0x00
+#define GP2AP020A00F_TYPE_AUTO_CALC    0x01
+
+/* ALS_REG bits */
+#define GP2AP020A00F_PRST_MASK         0xc0 /* Number of measurement cycles */
+#define GP2AP020A00F_PRST_ONCE         0x00
+#define GP2AP020A00F_PRST_4_CYCLES     0x40
+#define GP2AP020A00F_PRST_8_CYCLES     0x80
+#define GP2AP020A00F_PRST_16_CYCLES    0xc0
+#define GP2AP020A00F_RES_A_MASK                0x38 /* ALS: Resolution */
+#define GP2AP020A00F_RES_A_800ms       0x00
+#define GP2AP020A00F_RES_A_400ms       0x08
+#define GP2AP020A00F_RES_A_200ms       0x10
+#define GP2AP020A00F_RES_A_100ms       0x18
+#define GP2AP020A00F_RES_A_25ms                0x20
+#define GP2AP020A00F_RES_A_6_25ms      0x28
+#define GP2AP020A00F_RES_A_1_56ms      0x30
+#define GP2AP020A00F_RES_A_0_39ms      0x38
+#define GP2AP020A00F_RANGE_A_MASK      0x07 /* ALS: Max measurable range */
+#define GP2AP020A00F_RANGE_A_x1                0x00
+#define GP2AP020A00F_RANGE_A_x2                0x01
+#define GP2AP020A00F_RANGE_A_x4                0x02
+#define GP2AP020A00F_RANGE_A_x8                0x03
+#define GP2AP020A00F_RANGE_A_x16       0x04
+#define GP2AP020A00F_RANGE_A_x32       0x05
+#define GP2AP020A00F_RANGE_A_x64       0x06
+#define GP2AP020A00F_RANGE_A_x128      0x07
+
+/* PS_REG bits */
+#define GP2AP020A00F_ALC_MASK          0x80 /* Auto light cancel */
+#define GP2AP020A00F_ALC_ON            0x80
+#define GP2AP020A00F_ALC_OFF           0x00
+#define GP2AP020A00F_INTTYPE_MASK      0x40 /* Interrupt type setting */
+#define GP2AP020A00F_INTTYPE_LEVEL     0x00
+#define GP2AP020A00F_INTTYPE_PULSE     0x40
+#define GP2AP020A00F_RES_P_MASK                0x38 /* PS: Resolution */
+#define GP2AP020A00F_RES_P_800ms_x2    0x00
+#define GP2AP020A00F_RES_P_400ms_x2    0x08
+#define GP2AP020A00F_RES_P_200ms_x2    0x10
+#define GP2AP020A00F_RES_P_100ms_x2    0x18
+#define GP2AP020A00F_RES_P_25ms_x2     0x20
+#define GP2AP020A00F_RES_P_6_25ms_x2   0x28
+#define GP2AP020A00F_RES_P_1_56ms_x2   0x30
+#define GP2AP020A00F_RES_P_0_39ms_x2   0x38
+#define GP2AP020A00F_RANGE_P_MASK      0x07 /* PS: Max measurable range */
+#define GP2AP020A00F_RANGE_P_x1                0x00
+#define GP2AP020A00F_RANGE_P_x2                0x01
+#define GP2AP020A00F_RANGE_P_x4                0x02
+#define GP2AP020A00F_RANGE_P_x8                0x03
+#define GP2AP020A00F_RANGE_P_x16       0x04
+#define GP2AP020A00F_RANGE_P_x32       0x05
+#define GP2AP020A00F_RANGE_P_x64       0x06
+#define GP2AP020A00F_RANGE_P_x128      0x07
+
+/* LED reg bits */
+#define GP2AP020A00F_INTVAL_MASK       0xc0 /* Intermittent operating */
+#define GP2AP020A00F_INTVAL_0          0x00
+#define GP2AP020A00F_INTVAL_4          0x40
+#define GP2AP020A00F_INTVAL_8          0x80
+#define GP2AP020A00F_INTVAL_16         0xc0
+#define GP2AP020A00F_IS_MASK           0x30 /* ILED drive peak current */
+#define GP2AP020A00F_IS_13_8mA         0x00
+#define GP2AP020A00F_IS_27_5mA         0x10
+#define GP2AP020A00F_IS_55mA           0x20
+#define GP2AP020A00F_IS_110mA          0x30
+#define GP2AP020A00F_PIN_MASK          0x0c /* INT terminal setting */
+#define GP2AP020A00F_PIN_ALS_OR_PS     0x00
+#define GP2AP020A00F_PIN_ALS           0x04
+#define GP2AP020A00F_PIN_PS            0x08
+#define GP2AP020A00F_PIN_PS_DETECT     0x0c
+#define GP2AP020A00F_FREQ_MASK         0x02 /* LED modulation frequency */
+#define GP2AP020A00F_FREQ_327_5kHz     0x00
+#define GP2AP020A00F_FREQ_81_8kHz      0x02
+#define GP2AP020A00F_RST               0x01 /* Software reset */
+
+#define GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR     0
+#define GP2AP020A00F_SCAN_MODE_LIGHT_IR                1
+#define GP2AP020A00F_SCAN_MODE_PROXIMITY       2
+#define GP2AP020A00F_CHAN_TIMESTAMP            3
+
+#define GP2AP020A00F_DATA_READY_TIMEOUT                msecs_to_jiffies(1000)
+#define GP2AP020A00F_DATA_REG(chan)            (GP2AP020A00F_D0_L_REG + \
+                                                       (chan) * 2)
+#define GP2AP020A00F_THRESH_REG(th_val_id)     (GP2AP020A00F_TL_L_REG + \
+                                                       (th_val_id) * 2)
+#define GP2AP020A00F_THRESH_VAL_ID(reg_addr)   ((reg_addr - 4) / 2)
+
+#define GP2AP020A00F_SUBTRACT_MODE     0
+#define GP2AP020A00F_ADD_MODE          1
+
+#define GP2AP020A00F_MAX_CHANNELS      3
+
+enum gp2ap020a00f_opmode {
+       GP2AP020A00F_OPMODE_READ_RAW_CLEAR,
+       GP2AP020A00F_OPMODE_READ_RAW_IR,
+       GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY,
+       GP2AP020A00F_OPMODE_ALS,
+       GP2AP020A00F_OPMODE_PS,
+       GP2AP020A00F_OPMODE_ALS_AND_PS,
+       GP2AP020A00F_OPMODE_PROX_DETECT,
+       GP2AP020A00F_OPMODE_SHUTDOWN,
+       GP2AP020A00F_NUM_OPMODES,
+};
+
+enum gp2ap020a00f_cmd {
+       GP2AP020A00F_CMD_READ_RAW_CLEAR,
+       GP2AP020A00F_CMD_READ_RAW_IR,
+       GP2AP020A00F_CMD_READ_RAW_PROXIMITY,
+       GP2AP020A00F_CMD_TRIGGER_CLEAR_EN,
+       GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS,
+       GP2AP020A00F_CMD_TRIGGER_IR_EN,
+       GP2AP020A00F_CMD_TRIGGER_IR_DIS,
+       GP2AP020A00F_CMD_TRIGGER_PROX_EN,
+       GP2AP020A00F_CMD_TRIGGER_PROX_DIS,
+       GP2AP020A00F_CMD_ALS_HIGH_EV_EN,
+       GP2AP020A00F_CMD_ALS_HIGH_EV_DIS,
+       GP2AP020A00F_CMD_ALS_LOW_EV_EN,
+       GP2AP020A00F_CMD_ALS_LOW_EV_DIS,
+       GP2AP020A00F_CMD_PROX_HIGH_EV_EN,
+       GP2AP020A00F_CMD_PROX_HIGH_EV_DIS,
+       GP2AP020A00F_CMD_PROX_LOW_EV_EN,
+       GP2AP020A00F_CMD_PROX_LOW_EV_DIS,
+};
+
+enum gp2ap020a00f_flags {
+       GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER,
+       GP2AP020A00F_FLAG_ALS_IR_TRIGGER,
+       GP2AP020A00F_FLAG_PROX_TRIGGER,
+       GP2AP020A00F_FLAG_PROX_RISING_EV,
+       GP2AP020A00F_FLAG_PROX_FALLING_EV,
+       GP2AP020A00F_FLAG_ALS_RISING_EV,
+       GP2AP020A00F_FLAG_ALS_FALLING_EV,
+       GP2AP020A00F_FLAG_LUX_MODE_HI,
+       GP2AP020A00F_FLAG_DATA_READY,
+};
+
+enum gp2ap020a00f_thresh_val_id {
+       GP2AP020A00F_THRESH_TL,
+       GP2AP020A00F_THRESH_TH,
+       GP2AP020A00F_THRESH_PL,
+       GP2AP020A00F_THRESH_PH,
+};
+
+struct gp2ap020a00f_data {
+       const struct gp2ap020a00f_platform_data *pdata;
+       struct i2c_client *client;
+       struct mutex lock;
+       char *buffer;
+       struct regulator *vled_reg;
+       unsigned long flags;
+       enum gp2ap020a00f_opmode cur_opmode;
+       struct iio_trigger *trig;
+       struct regmap *regmap;
+       unsigned int thresh_val[4];
+       u8 debug_reg_addr;
+       struct irq_work work;
+       wait_queue_head_t data_ready_queue;
+};
+
+static const u8 gp2ap020a00f_reg_init_tab[] = {
+       [GP2AP020A00F_OP_REG] = GP2AP020A00F_OP3_SHUTDOWN,
+       [GP2AP020A00F_ALS_REG] = GP2AP020A00F_RES_A_25ms |
+                                GP2AP020A00F_RANGE_A_x8,
+       [GP2AP020A00F_PS_REG] = GP2AP020A00F_ALC_ON |
+                               GP2AP020A00F_RES_P_1_56ms_x2 |
+                               GP2AP020A00F_RANGE_P_x4,
+       [GP2AP020A00F_LED_REG] = GP2AP020A00F_INTVAL_0 |
+                                GP2AP020A00F_IS_110mA |
+                                GP2AP020A00F_FREQ_327_5kHz,
+       [GP2AP020A00F_TL_L_REG] = 0,
+       [GP2AP020A00F_TL_H_REG] = 0,
+       [GP2AP020A00F_TH_L_REG] = 0,
+       [GP2AP020A00F_TH_H_REG] = 0,
+       [GP2AP020A00F_PL_L_REG] = 0,
+       [GP2AP020A00F_PL_H_REG] = 0,
+       [GP2AP020A00F_PH_L_REG] = 0,
+       [GP2AP020A00F_PH_H_REG] = 0,
+};
+
+static bool gp2ap020a00f_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case GP2AP020A00F_OP_REG:
+       case GP2AP020A00F_D0_L_REG:
+       case GP2AP020A00F_D0_H_REG:
+       case GP2AP020A00F_D1_L_REG:
+       case GP2AP020A00F_D1_H_REG:
+       case GP2AP020A00F_D2_L_REG:
+       case GP2AP020A00F_D2_H_REG:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const struct regmap_config gp2ap020a00f_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = GP2AP020A00F_D2_H_REG,
+       .cache_type = REGCACHE_RBTREE,
+
+       .volatile_reg = gp2ap020a00f_is_volatile_reg,
+};
+
+static const struct gp2ap020a00f_mutable_config_regs {
+       u8 op_reg;
+       u8 als_reg;
+       u8 ps_reg;
+       u8 led_reg;
+} opmode_regs_settings[GP2AP020A00F_NUM_OPMODES] = {
+       [GP2AP020A00F_OPMODE_READ_RAW_CLEAR] = {
+               GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_AUTO_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS
+       },
+       [GP2AP020A00F_OPMODE_READ_RAW_IR] = {
+               GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS
+       },
+       [GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY] = {
+               GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_PS
+       },
+       [GP2AP020A00F_OPMODE_PROX_DETECT] = {
+               GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_4_CYCLES,
+               GP2AP020A00F_INTTYPE_PULSE,
+               GP2AP020A00F_PIN_PS_DETECT
+       },
+       [GP2AP020A00F_OPMODE_ALS] = {
+               GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_AUTO_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS
+       },
+       [GP2AP020A00F_OPMODE_PS] = {
+               GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_4_CYCLES,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_PS
+       },
+       [GP2AP020A00F_OPMODE_ALS_AND_PS] = {
+               GP2AP020A00F_OP_ALS_AND_PS
+               | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_AUTO_CALC,
+               GP2AP020A00F_PRST_4_CYCLES,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS_OR_PS
+       },
+       [GP2AP020A00F_OPMODE_SHUTDOWN] = { GP2AP020A00F_OP3_SHUTDOWN, },
+};
+
+static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data,
+                                       enum gp2ap020a00f_opmode op)
+{
+       unsigned int op_reg_val;
+       int err;
+
+       if (op != GP2AP020A00F_OPMODE_SHUTDOWN) {
+               err = regmap_read(data->regmap, GP2AP020A00F_OP_REG,
+                                       &op_reg_val);
+               if (err < 0)
+                       return err;
+               /*
+                * Shutdown the device if the operation being executed entails
+                * mode transition.
+                */
+               if ((opmode_regs_settings[op].op_reg & GP2AP020A00F_OP_MASK) !=
+                   (op_reg_val & GP2AP020A00F_OP_MASK)) {
+                       /* set shutdown mode */
+                       err = regmap_update_bits(data->regmap,
+                               GP2AP020A00F_OP_REG, GP2AP020A00F_OP3_MASK,
+                               GP2AP020A00F_OP3_SHUTDOWN);
+                       if (err < 0)
+                               return err;
+               }
+
+               err = regmap_update_bits(data->regmap, GP2AP020A00F_ALS_REG,
+                       GP2AP020A00F_PRST_MASK, opmode_regs_settings[op]
+                                                               .als_reg);
+               if (err < 0)
+                       return err;
+
+               err = regmap_update_bits(data->regmap, GP2AP020A00F_PS_REG,
+                       GP2AP020A00F_INTTYPE_MASK, opmode_regs_settings[op]
+                                                               .ps_reg);
+               if (err < 0)
+                       return err;
+
+               err = regmap_update_bits(data->regmap, GP2AP020A00F_LED_REG,
+                       GP2AP020A00F_PIN_MASK, opmode_regs_settings[op]
+                                                               .led_reg);
+               if (err < 0)
+                       return err;
+       }
+
+       /* Set OP_REG and apply operation mode (power on / off) */
+       err = regmap_update_bits(data->regmap,
+                                GP2AP020A00F_OP_REG,
+                                GP2AP020A00F_OP_MASK | GP2AP020A00F_OP2_MASK |
+                                GP2AP020A00F_OP3_MASK | GP2AP020A00F_TYPE_MASK,
+                                opmode_regs_settings[op].op_reg);
+       if (err < 0)
+               return err;
+
+       data->cur_opmode = op;
+
+       return 0;
+}
+
+static bool gp2ap020a00f_als_enabled(struct gp2ap020a00f_data *data)
+{
+       return test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
+}
+
+static bool gp2ap020a00f_prox_detect_enabled(struct gp2ap020a00f_data *data)
+{
+       return test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
+}
+
+static int gp2ap020a00f_write_event_threshold(struct gp2ap020a00f_data *data,
+                               enum gp2ap020a00f_thresh_val_id th_val_id,
+                               bool enable)
+{
+       __le16 thresh_buf = 0;
+       unsigned int thresh_reg_val;
+
+       if (!enable)
+               thresh_reg_val = 0;
+       else if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags) &&
+                th_val_id != GP2AP020A00F_THRESH_PL &&
+                th_val_id != GP2AP020A00F_THRESH_PH)
+               /*
+                * For the high lux mode ALS threshold has to be scaled down
+                * to allow for proper comparison with the output value.
+                */
+               thresh_reg_val = data->thresh_val[th_val_id] / 16;
+       else
+               thresh_reg_val = data->thresh_val[th_val_id] > 16000 ?
+                                       16000 :
+                                       data->thresh_val[th_val_id];
+
+       thresh_buf = cpu_to_le16(thresh_reg_val);
+
+       return regmap_bulk_write(data->regmap,
+                                GP2AP020A00F_THRESH_REG(th_val_id),
+                                (u8 *)&thresh_buf, 2);
+}
+
+static int gp2ap020a00f_alter_opmode(struct gp2ap020a00f_data *data,
+                       enum gp2ap020a00f_opmode diff_mode, int add_sub)
+{
+       enum gp2ap020a00f_opmode new_mode;
+
+       if (diff_mode != GP2AP020A00F_OPMODE_ALS &&
+           diff_mode != GP2AP020A00F_OPMODE_PS)
+               return -EINVAL;
+
+       if (add_sub == GP2AP020A00F_ADD_MODE) {
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_SHUTDOWN)
+                       new_mode =  diff_mode;
+               else
+                       new_mode = GP2AP020A00F_OPMODE_ALS_AND_PS;
+       } else {
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_ALS_AND_PS)
+                       new_mode = (diff_mode == GP2AP020A00F_OPMODE_ALS) ?
+                                       GP2AP020A00F_OPMODE_PS :
+                                       GP2AP020A00F_OPMODE_ALS;
+               else
+                       new_mode = GP2AP020A00F_OPMODE_SHUTDOWN;
+       }
+
+       return gp2ap020a00f_set_operation_mode(data, new_mode);
+}
+
+static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
+                                       enum gp2ap020a00f_cmd cmd)
+{
+       int err = 0;
+
+       switch (cmd) {
+       case GP2AP020A00F_CMD_READ_RAW_CLEAR:
+               if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
+                       return -EBUSY;
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_READ_RAW_CLEAR);
+               break;
+       case GP2AP020A00F_CMD_READ_RAW_IR:
+               if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
+                       return -EBUSY;
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_READ_RAW_IR);
+               break;
+       case GP2AP020A00F_CMD_READ_RAW_PROXIMITY:
+               if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
+                       return -EBUSY;
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_CLEAR_EN:
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data))
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+               set_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS:
+               clear_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
+               if (gp2ap020a00f_als_enabled(data))
+                       break;
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_IR_EN:
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data))
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+               set_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_IR_DIS:
+               clear_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
+               if (gp2ap020a00f_als_enabled(data))
+                       break;
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_PROX_EN:
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_PS,
+                                               GP2AP020A00F_ADD_MODE);
+               set_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_PROX_DIS:
+               clear_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_PS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+               break;
+       case GP2AP020A00F_CMD_ALS_HIGH_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
+                       return 0;
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, true);
+               break;
+       case GP2AP020A00F_CMD_ALS_HIGH_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, false);
+               break;
+       case GP2AP020A00F_CMD_ALS_LOW_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
+                       return 0;
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, true);
+               break;
+       case GP2AP020A00F_CMD_ALS_LOW_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, false);
+               break;
+       case GP2AP020A00F_CMD_PROX_HIGH_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
+                       return 0;
+               if (gp2ap020a00f_als_enabled(data) ||
+                   data->cur_opmode == GP2AP020A00F_OPMODE_PS)
+                       return -EBUSY;
+               if (!gp2ap020a00f_prox_detect_enabled(data)) {
+                       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_PROX_DETECT);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PH, true);
+               break;
+       case GP2AP020A00F_CMD_PROX_HIGH_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+               if (err < 0)
+                       return err;
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PH, false);
+               break;
+       case GP2AP020A00F_CMD_PROX_LOW_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
+                       return 0;
+               if (gp2ap020a00f_als_enabled(data) ||
+                   data->cur_opmode == GP2AP020A00F_OPMODE_PS)
+                       return -EBUSY;
+               if (!gp2ap020a00f_prox_detect_enabled(data)) {
+                       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_PROX_DETECT);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PL, true);
+               break;
+       case GP2AP020A00F_CMD_PROX_LOW_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+               if (err < 0)
+                       return err;
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PL, false);
+               break;
+       }
+
+       return err;
+}
+
+static int wait_conversion_complete_irq(struct gp2ap020a00f_data *data)
+{
+       int ret;
+
+       ret = wait_event_timeout(data->data_ready_queue,
+                                test_bit(GP2AP020A00F_FLAG_DATA_READY,
+                                         &data->flags),
+                                GP2AP020A00F_DATA_READY_TIMEOUT);
+       clear_bit(GP2AP020A00F_FLAG_DATA_READY, &data->flags);
+
+       return ret > 0 ? 0 : -ETIME;
+}
+
+static int gp2ap020a00f_read_output(struct gp2ap020a00f_data *data,
+                                       unsigned int output_reg, int *val)
+{
+       u8 reg_buf[2];
+       int err;
+
+       err = wait_conversion_complete_irq(data);
+       if (err < 0)
+               dev_dbg(&data->client->dev, "data ready timeout\n");
+
+       err = regmap_bulk_read(data->regmap, output_reg, reg_buf, 2);
+       if (err < 0)
+               return err;
+
+       *val = le16_to_cpup((__le16 *)reg_buf);
+
+       return err;
+}
+
+static bool gp2ap020a00f_adjust_lux_mode(struct gp2ap020a00f_data *data,
+                                int output_val)
+{
+       u8 new_range = 0xff;
+       int err;
+
+       if (!test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags)) {
+               if (output_val > 16000) {
+                       set_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags);
+                       new_range = GP2AP020A00F_RANGE_A_x128;
+               }
+       } else {
+               if (output_val < 1000) {
+                       clear_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags);
+                       new_range = GP2AP020A00F_RANGE_A_x8;
+               }
+       }
+
+       if (new_range != 0xff) {
+               /* Clear als threshold registers to avoid spurious
+                * events caused by lux mode transition.
+                */
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, false);
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Clearing als threshold register failed.\n");
+                       return false;
+               }
+
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, false);
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Clearing als threshold register failed.\n");
+                       return false;
+               }
+
+               /* Change lux mode */
+               err = regmap_update_bits(data->regmap,
+                       GP2AP020A00F_OP_REG,
+                       GP2AP020A00F_OP3_MASK,
+                       GP2AP020A00F_OP3_SHUTDOWN);
+
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Shutting down the device failed.\n");
+                       return false;
+               }
+
+               err = regmap_update_bits(data->regmap,
+                       GP2AP020A00F_ALS_REG,
+                       GP2AP020A00F_RANGE_A_MASK,
+                       new_range);
+
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Adjusting device lux mode failed.\n");
+                       return false;
+               }
+
+               err = regmap_update_bits(data->regmap,
+                       GP2AP020A00F_OP_REG,
+                       GP2AP020A00F_OP3_MASK,
+                       GP2AP020A00F_OP3_OPERATION);
+
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Powering up the device failed.\n");
+                       return false;
+               }
+
+               /* Adjust als threshold register values to the new lux mode */
+               if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags)) {
+                       err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, true);
+                       if (err < 0) {
+                               dev_err(&data->client->dev,
+                               "Adjusting als threshold value failed.\n");
+                               return false;
+                       }
+               }
+
+               if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags)) {
+                       err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, true);
+                       if (err < 0) {
+                               dev_err(&data->client->dev,
+                               "Adjusting als threshold value failed.\n");
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+
+       return false;
+}
+
+static void gp2ap020a00f_output_to_lux(struct gp2ap020a00f_data *data,
+                                               int *output_val)
+{
+       if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags))
+               *output_val *= 16;
+}
+
+static void gp2ap020a00f_iio_trigger_work(struct irq_work *work)
+{
+       struct gp2ap020a00f_data *data =
+               container_of(work, struct gp2ap020a00f_data, work);
+
+       iio_trigger_poll(data->trig, 0);
+}
+
+static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
+       unsigned int op_reg_val;
+       int ret;
+
+       /* Read interrupt flags */
+       ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG, &op_reg_val);
+       if (ret < 0)
+               return IRQ_HANDLED;
+
+       if (gp2ap020a00f_prox_detect_enabled(priv)) {
+               if (op_reg_val & GP2AP020A00F_PROX_DETECT) {
+                       iio_push_event(indio_dev,
+                              IIO_UNMOD_EVENT_CODE(
+                                   IIO_PROXIMITY,
+                                   GP2AP020A00F_SCAN_MODE_PROXIMITY,
+                                   IIO_EV_TYPE_ROC,
+                                   IIO_EV_DIR_RISING),
+                              iio_get_time_ns());
+               } else {
+                       iio_push_event(indio_dev,
+                              IIO_UNMOD_EVENT_CODE(
+                                   IIO_PROXIMITY,
+                                   GP2AP020A00F_SCAN_MODE_PROXIMITY,
+                                   IIO_EV_TYPE_ROC,
+                                   IIO_EV_DIR_FALLING),
+                              iio_get_time_ns());
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
+       u8 op_reg_flags, d0_reg_buf[2];
+       unsigned int output_val, op_reg_val;
+       int thresh_val_id, ret;
+
+       /* Read interrupt flags */
+       ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG,
+                                                       &op_reg_val);
+       if (ret < 0)
+               goto done;
+
+       op_reg_flags = op_reg_val & (GP2AP020A00F_FLAG_A | GP2AP020A00F_FLAG_P
+                                       | GP2AP020A00F_PROX_DETECT);
+
+       op_reg_val &= (~GP2AP020A00F_FLAG_A & ~GP2AP020A00F_FLAG_P
+                                       & ~GP2AP020A00F_PROX_DETECT);
+
+       /* Clear interrupt flags (if not in INTTYPE_PULSE mode) */
+       if (priv->cur_opmode != GP2AP020A00F_OPMODE_PROX_DETECT) {
+               ret = regmap_write(priv->regmap, GP2AP020A00F_OP_REG,
+                                                               op_reg_val);
+               if (ret < 0)
+                       goto done;
+       }
+
+       if (op_reg_flags & GP2AP020A00F_FLAG_A) {
+               /* Check D0 register to assess if the lux mode
+                * transition is required.
+                */
+               ret = regmap_bulk_read(priv->regmap, GP2AP020A00F_D0_L_REG,
+                                                       d0_reg_buf, 2);
+               if (ret < 0)
+                       goto done;
+
+               output_val = le16_to_cpup((__le16 *)d0_reg_buf);
+
+               if (gp2ap020a00f_adjust_lux_mode(priv, output_val))
+                       goto done;
+
+               gp2ap020a00f_output_to_lux(priv, &output_val);
+
+               /*
+                * We need to check output value to distinguish
+                * between high and low ambient light threshold event.
+                */
+               if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &priv->flags)) {
+                       thresh_val_id =
+                           GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TH_L_REG);
+                       if (output_val > priv->thresh_val[thresh_val_id])
+                               iio_push_event(indio_dev,
+                                      IIO_MOD_EVENT_CODE(
+                                           IIO_LIGHT,
+                                           GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
+                                           IIO_MOD_LIGHT_CLEAR,
+                                           IIO_EV_TYPE_THRESH,
+                                           IIO_EV_DIR_RISING),
+                                      iio_get_time_ns());
+               }
+
+               if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &priv->flags)) {
+                       thresh_val_id =
+                           GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TL_L_REG);
+                       if (output_val < priv->thresh_val[thresh_val_id])
+                               iio_push_event(indio_dev,
+                                      IIO_MOD_EVENT_CODE(
+                                           IIO_LIGHT,
+                                           GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
+                                           IIO_MOD_LIGHT_CLEAR,
+                                           IIO_EV_TYPE_THRESH,
+                                           IIO_EV_DIR_FALLING),
+                                      iio_get_time_ns());
+               }
+       }
+
+       if (priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_CLEAR ||
+           priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_IR ||
+           priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY) {
+               set_bit(GP2AP020A00F_FLAG_DATA_READY, &priv->flags);
+               wake_up(&priv->data_ready_queue);
+               goto done;
+       }
+
+       if (test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &priv->flags) ||
+           test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &priv->flags) ||
+           test_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &priv->flags))
+               /* This fires off the trigger. */
+               irq_work_queue(&priv->work);
+
+done:
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
+{
+       struct iio_poll_func *pf = data;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
+       size_t d_size = 0;
+       __le32 light_lux;
+       int i, out_val, ret;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               ret = regmap_bulk_read(priv->regmap,
+                               GP2AP020A00F_DATA_REG(i),
+                               &priv->buffer[d_size], 2);
+               if (ret < 0)
+                       goto done;
+
+               if (i == GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR ||
+                   i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) {
+                       out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]);
+                       gp2ap020a00f_output_to_lux(priv, &out_val);
+                       light_lux = cpu_to_le32(out_val);
+                       memcpy(&priv->buffer[d_size], (u8 *)&light_lux, 4);
+                       d_size += 4;
+               } else {
+                       d_size += 2;
+               }
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer,
+               pf->timestamp);
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan,
+                                            enum iio_event_direction event_dir)
+{
+       switch (chan->type) {
+       case IIO_PROXIMITY:
+               if (event_dir == IIO_EV_DIR_RISING)
+                       return GP2AP020A00F_PH_L_REG;
+               else
+                       return GP2AP020A00F_PL_L_REG;
+       case IIO_LIGHT:
+               if (event_dir == IIO_EV_DIR_RISING)
+                       return GP2AP020A00F_TH_L_REG;
+               else
+                       return GP2AP020A00F_TL_L_REG;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
+                                       enum iio_event_info info,
+                                       int val, int val2)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       bool event_en = false;
+       u8 thresh_val_id;
+       u8 thresh_reg_l;
+       int err = 0;
+
+       mutex_lock(&data->lock);
+
+       thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir);
+       thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l);
+
+       if (thresh_val_id > GP2AP020A00F_THRESH_PH) {
+               err = -EINVAL;
+               goto error_unlock;
+       }
+
+       switch (thresh_reg_l) {
+       case GP2AP020A00F_TH_L_REG:
+               event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV,
+                                                       &data->flags);
+               break;
+       case GP2AP020A00F_TL_L_REG:
+               event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV,
+                                                       &data->flags);
+               break;
+       case GP2AP020A00F_PH_L_REG:
+               if (val == 0) {
+                       err = -EINVAL;
+                       goto error_unlock;
+               }
+               event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV,
+                                                       &data->flags);
+               break;
+       case GP2AP020A00F_PL_L_REG:
+               if (val == 0) {
+                       err = -EINVAL;
+                       goto error_unlock;
+               }
+               event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV,
+                                                       &data->flags);
+               break;
+       }
+
+       data->thresh_val[thresh_val_id] = val;
+       err =  gp2ap020a00f_write_event_threshold(data, thresh_val_id,
+                                                       event_en);
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev,
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir,
+                                      enum iio_event_info info,
+                                      int *val, int *val2)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       u8 thresh_reg_l;
+       int err = IIO_VAL_INT;
+
+       mutex_lock(&data->lock);
+
+       thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir);
+
+       if (thresh_reg_l > GP2AP020A00F_PH_L_REG) {
+               err = -EINVAL;
+               goto error_unlock;
+       }
+
+       *val = data->thresh_val[GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l)];
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev,
+                                               int state)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       enum gp2ap020a00f_cmd cmd_high_ev, cmd_low_ev;
+       int err;
+
+       cmd_high_ev = state ? GP2AP020A00F_CMD_PROX_HIGH_EV_EN :
+                             GP2AP020A00F_CMD_PROX_HIGH_EV_DIS;
+       cmd_low_ev = state ? GP2AP020A00F_CMD_PROX_LOW_EV_EN :
+                            GP2AP020A00F_CMD_PROX_LOW_EV_DIS;
+
+       /*
+        * In order to enable proximity detection feature in the device
+        * both high and low threshold registers have to be written
+        * with different values, greater than zero.
+        */
+       if (state) {
+               if (data->thresh_val[GP2AP020A00F_THRESH_PL] == 0)
+                       return -EINVAL;
+
+               if (data->thresh_val[GP2AP020A00F_THRESH_PH] == 0)
+                       return -EINVAL;
+       }
+
+       err = gp2ap020a00f_exec_cmd(data, cmd_high_ev);
+       if (err < 0)
+               return err;
+
+       err = gp2ap020a00f_exec_cmd(data, cmd_low_ev);
+       if (err < 0)
+               return err;
+
+       free_irq(data->client->irq, indio_dev);
+
+       if (state)
+               err = request_threaded_irq(data->client->irq, NULL,
+                                          &gp2ap020a00f_prox_sensing_handler,
+                                          IRQF_TRIGGER_RISING |
+                                          IRQF_TRIGGER_FALLING |
+                                          IRQF_ONESHOT,
+                                          "gp2ap020a00f_prox_sensing",
+                                          indio_dev);
+       else {
+               err = request_threaded_irq(data->client->irq, NULL,
+                                          &gp2ap020a00f_thresh_event_handler,
+                                          IRQF_TRIGGER_FALLING |
+                                          IRQF_ONESHOT,
+                                          "gp2ap020a00f_thresh_event",
+                                          indio_dev);
+       }
+
+       return err;
+}
+
+static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev,
+                                          const struct iio_chan_spec *chan,
+                                          enum iio_event_type type,
+                                          enum iio_event_direction dir,
+                                          int state)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       enum gp2ap020a00f_cmd cmd;
+       int err;
+
+       mutex_lock(&data->lock);
+
+       switch (chan->type) {
+       case IIO_PROXIMITY:
+               err = gp2ap020a00f_write_prox_event_config(indio_dev, state);
+               break;
+       case IIO_LIGHT:
+               if (dir == IIO_EV_DIR_RISING) {
+                       cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN :
+                                     GP2AP020A00F_CMD_ALS_HIGH_EV_DIS;
+                       err = gp2ap020a00f_exec_cmd(data, cmd);
+               } else {
+                       cmd = state ? GP2AP020A00F_CMD_ALS_LOW_EV_EN :
+                                     GP2AP020A00F_CMD_ALS_LOW_EV_DIS;
+                       err = gp2ap020a00f_exec_cmd(data, cmd);
+               }
+               break;
+       default:
+               err = -EINVAL;
+       }
+
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev,
+                                          const struct iio_chan_spec *chan,
+                                          enum iio_event_type type,
+                                          enum iio_event_direction dir)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int event_en = 0;
+
+       mutex_lock(&data->lock);
+
+       switch (chan->type) {
+       case IIO_PROXIMITY:
+               if (dir == IIO_EV_DIR_RISING)
+                       event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV,
+                                                               &data->flags);
+               else
+                       event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV,
+                                                               &data->flags);
+               break;
+       case IIO_LIGHT:
+               if (dir == IIO_EV_DIR_RISING)
+                       event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV,
+                                                               &data->flags);
+               else
+                       event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV,
+                                                               &data->flags);
+               break;
+       default:
+               event_en = -EINVAL;
+               break;
+       }
+
+       mutex_unlock(&data->lock);
+
+       return event_en;
+}
+
+static int gp2ap020a00f_read_channel(struct gp2ap020a00f_data *data,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       enum gp2ap020a00f_cmd cmd;
+       int err;
+
+       switch (chan->scan_index) {
+       case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
+               cmd = GP2AP020A00F_CMD_READ_RAW_CLEAR;
+               break;
+       case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
+               cmd = GP2AP020A00F_CMD_READ_RAW_IR;
+               break;
+       case GP2AP020A00F_SCAN_MODE_PROXIMITY:
+               cmd = GP2AP020A00F_CMD_READ_RAW_PROXIMITY;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       err = gp2ap020a00f_exec_cmd(data, cmd);
+       if (err < 0) {
+               dev_err(&data->client->dev,
+                       "gp2ap020a00f_exec_cmd failed\n");
+               goto error_ret;
+       }
+
+       err = gp2ap020a00f_read_output(data, chan->address, val);
+       if (err < 0)
+               dev_err(&data->client->dev,
+                       "gp2ap020a00f_read_output failed\n");
+
+       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+       if (err < 0)
+               dev_err(&data->client->dev,
+                       "Failed to shut down the device.\n");
+
+       if (cmd == GP2AP020A00F_CMD_READ_RAW_CLEAR ||
+           cmd == GP2AP020A00F_CMD_READ_RAW_IR)
+               gp2ap020a00f_output_to_lux(data, val);
+
+error_ret:
+       return err;
+}
+
+static int gp2ap020a00f_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val, int *val2,
+                          long mask)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int err = -EINVAL;
+
+       mutex_lock(&data->lock);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (iio_buffer_enabled(indio_dev)) {
+                       err = -EBUSY;
+                       goto error_unlock;
+               }
+
+               err = gp2ap020a00f_read_channel(data, chan, val);
+               break;
+       }
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err < 0 ? err : IIO_VAL_INT;
+}
+
+static const struct iio_event_spec gp2ap020a00f_event_spec_light[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
+static const struct iio_event_spec gp2ap020a00f_event_spec_prox[] = {
+       {
+               .type = IIO_EV_TYPE_ROC,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_ROC,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
+static const struct iio_chan_spec gp2ap020a00f_channels[] = {
+       {
+               .type = IIO_LIGHT,
+               .channel2 = IIO_MOD_LIGHT_CLEAR,
+               .modified = 1,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 24,
+                       .shift = 0,
+                       .storagebits = 32,
+                       .endianness = IIO_LE,
+               },
+               .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
+               .address = GP2AP020A00F_D0_L_REG,
+               .event_spec = gp2ap020a00f_event_spec_light,
+               .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_light),
+       },
+       {
+               .type = IIO_LIGHT,
+               .channel2 = IIO_MOD_LIGHT_IR,
+               .modified = 1,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 24,
+                       .shift = 0,
+                       .storagebits = 32,
+                       .endianness = IIO_LE,
+               },
+               .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_IR,
+               .address = GP2AP020A00F_D1_L_REG,
+       },
+       {
+               .type = IIO_PROXIMITY,
+               .modified = 0,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .shift = 0,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .scan_index = GP2AP020A00F_SCAN_MODE_PROXIMITY,
+               .address = GP2AP020A00F_D2_L_REG,
+               .event_spec = gp2ap020a00f_event_spec_prox,
+               .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_prox),
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(GP2AP020A00F_CHAN_TIMESTAMP),
+};
+
+static const struct iio_info gp2ap020a00f_info = {
+       .read_raw = &gp2ap020a00f_read_raw,
+       .read_event_value_new = &gp2ap020a00f_read_event_val,
+       .read_event_config_new = &gp2ap020a00f_read_event_config,
+       .write_event_value_new = &gp2ap020a00f_write_event_val,
+       .write_event_config_new = &gp2ap020a00f_write_event_config,
+       .driver_module = THIS_MODULE,
+};
+
+static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int i, err = 0;
+
+       mutex_lock(&data->lock);
+
+       /*
+        * Enable triggers according to the scan_mask. Enabling either
+        * LIGHT_CLEAR or LIGHT_IR scan mode results in enabling ALS
+        * module in the device, which generates samples in both D0 (clear)
+        * and D1 (ir) registers. As the two registers are bound to the
+        * two separate IIO channels they are treated in the driver logic
+        * as if they were controlled independently.
+        */
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               switch (i) {
+               case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_CLEAR_EN);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_IR_EN);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_PROXIMITY:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_PROX_EN);
+                       break;
+               }
+       }
+
+       if (err < 0)
+               goto error_unlock;
+
+       data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+       if (!data->buffer) {
+               err = -ENOMEM;
+               goto error_unlock;
+       }
+
+       err = iio_triggered_buffer_postenable(indio_dev);
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int i, err;
+
+       mutex_lock(&data->lock);
+
+       err = iio_triggered_buffer_predisable(indio_dev);
+       if (err < 0)
+               goto error_unlock;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               switch (i) {
+               case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_IR_DIS);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_PROXIMITY:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_PROX_DIS);
+                       break;
+               }
+       }
+
+       if (err == 0)
+               kfree(data->buffer);
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = {
+       .postenable = &gp2ap020a00f_buffer_postenable,
+       .predisable = &gp2ap020a00f_buffer_predisable,
+};
+
+static const struct iio_trigger_ops gp2ap020a00f_trigger_ops = {
+       .owner = THIS_MODULE,
+};
+
+static int gp2ap020a00f_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+{
+       struct gp2ap020a00f_data *data;
+       struct iio_dev *indio_dev;
+       struct regmap *regmap;
+       int err;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+
+       data->vled_reg = devm_regulator_get(&client->dev, "vled");
+       if (IS_ERR(data->vled_reg))
+               return PTR_ERR(data->vled_reg);
+
+       err = regulator_enable(data->vled_reg);
+       if (err)
+               return err;
+
+       regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(&client->dev, "Regmap initialization failed.\n");
+               err = PTR_ERR(regmap);
+               goto error_regulator_disable;
+       }
+
+       /* Initialize device registers */
+       err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG,
+                       gp2ap020a00f_reg_init_tab,
+                       ARRAY_SIZE(gp2ap020a00f_reg_init_tab));
+
+       if (err < 0) {
+               dev_err(&client->dev, "Device initialization failed.\n");
+               goto error_regulator_disable;
+       }
+
+       i2c_set_clientdata(client, indio_dev);
+
+       data->client = client;
+       data->cur_opmode = GP2AP020A00F_OPMODE_SHUTDOWN;
+       data->regmap = regmap;
+       init_waitqueue_head(&data->data_ready_queue);
+
+       mutex_init(&data->lock);
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->channels = gp2ap020a00f_channels;
+       indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels);
+       indio_dev->info = &gp2ap020a00f_info;
+       indio_dev->name = id->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       /* Allocate buffer */
+       err = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+               &gp2ap020a00f_trigger_handler, &gp2ap020a00f_buffer_setup_ops);
+       if (err < 0)
+               goto error_regulator_disable;
+
+       /* Allocate trigger */
+       data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger",
+                                                       indio_dev->name);
+       if (data->trig == NULL) {
+               err = -ENOMEM;
+               dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n");
+               goto error_uninit_buffer;
+       }
+
+       /* This needs to be requested here for read_raw calls to work. */
+       err = request_threaded_irq(client->irq, NULL,
+                                  &gp2ap020a00f_thresh_event_handler,
+                                  IRQF_TRIGGER_FALLING |
+                                  IRQF_ONESHOT,
+                                  "gp2ap020a00f_als_event",
+                                  indio_dev);
+       if (err < 0) {
+               dev_err(&client->dev, "Irq request failed.\n");
+               goto error_uninit_buffer;
+       }
+
+       data->trig->ops = &gp2ap020a00f_trigger_ops;
+       data->trig->dev.parent = &data->client->dev;
+
+       init_irq_work(&data->work, gp2ap020a00f_iio_trigger_work);
+
+       err = iio_trigger_register(data->trig);
+       if (err < 0) {
+               dev_err(&client->dev, "Failed to register iio trigger.\n");
+               goto error_free_irq;
+       }
+
+       err = iio_device_register(indio_dev);
+       if (err < 0)
+               goto error_trigger_unregister;
+
+       return 0;
+
+error_trigger_unregister:
+       iio_trigger_unregister(data->trig);
+error_free_irq:
+       free_irq(client->irq, indio_dev);
+error_uninit_buffer:
+       iio_triggered_buffer_cleanup(indio_dev);
+error_regulator_disable:
+       regulator_disable(data->vled_reg);
+
+       return err;
+}
+
+static int gp2ap020a00f_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int err;
+
+       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+       if (err < 0)
+               dev_err(&indio_dev->dev, "Failed to power off the device.\n");
+
+       iio_device_unregister(indio_dev);
+       iio_trigger_unregister(data->trig);
+       free_irq(client->irq, indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+       regulator_disable(data->vled_reg);
+
+       return 0;
+}
+
+static const struct i2c_device_id gp2ap020a00f_id[] = {
+       { GP2A_I2C_NAME, 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gp2ap020a00f_of_match[] = {
+       { .compatible = "sharp,gp2ap020a00f" },
+       { }
+};
+#endif
+
+static struct i2c_driver gp2ap020a00f_driver = {
+       .driver = {
+               .name   = GP2A_I2C_NAME,
+               .of_match_table = of_match_ptr(gp2ap020a00f_of_match),
+               .owner  = THIS_MODULE,
+       },
+       .probe          = gp2ap020a00f_probe,
+       .remove         = gp2ap020a00f_remove,
+       .id_table       = gp2ap020a00f_id,
+};
+
+module_i2c_driver(gp2ap020a00f_driver);
+
+MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
+MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver");
+MODULE_LICENSE("GPL v2");
index e59d00c3139c00c15f44e4ab14c844341d9663e5..fa6ae8cf89eaa9edfdfffe379939bc7cc8a491f0 100644 (file)
@@ -161,10 +161,11 @@ static const struct iio_info als_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+                                       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -179,7 +180,7 @@ static int als_proc_event(struct hid_sensor_hub_device *hsdev,
                                als_state->common_attributes.data_ready);
        if (als_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)&als_state->illum,
+                               &als_state->illum,
                                sizeof(als_state->illum));
 
        return 0;
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
new file mode 100644 (file)
index 0000000..45df220
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * tcs3472.c - Support for TAOS TCS3472 color light-to-digital converter
+ *
+ * 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.
+ *
+ * Color light sensor with 16-bit channels for red, green, blue, clear);
+ * 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725,
+ * TCS34727)
+ *
+ * TODO: interrupt support, thresholds, wait time
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/pm.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>
+
+#define TCS3472_DRV_NAME "tcs3472"
+
+#define TCS3472_COMMAND BIT(7)
+#define TCS3472_AUTO_INCR BIT(5)
+
+#define TCS3472_ENABLE (TCS3472_COMMAND | 0x00)
+#define TCS3472_ATIME (TCS3472_COMMAND | 0x01)
+#define TCS3472_WTIME (TCS3472_COMMAND | 0x03)
+#define TCS3472_AILT (TCS3472_COMMAND | 0x04)
+#define TCS3472_AIHT (TCS3472_COMMAND | 0x06)
+#define TCS3472_PERS (TCS3472_COMMAND | 0x0c)
+#define TCS3472_CONFIG (TCS3472_COMMAND | 0x0d)
+#define TCS3472_CONTROL (TCS3472_COMMAND | 0x0f)
+#define TCS3472_ID (TCS3472_COMMAND | 0x12)
+#define TCS3472_STATUS (TCS3472_COMMAND | 0x13)
+#define TCS3472_CDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x14)
+#define TCS3472_RDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x16)
+#define TCS3472_GDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x18)
+#define TCS3472_BDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x1a)
+
+#define TCS3472_STATUS_AVALID BIT(0)
+#define TCS3472_ENABLE_AEN BIT(1)
+#define TCS3472_ENABLE_PON BIT(0)
+#define TCS3472_CONTROL_AGAIN_MASK (BIT(0) | BIT(1))
+
+struct tcs3472_data {
+       struct i2c_client *client;
+       u8 enable;
+       u8 control;
+       u8 atime;
+       u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */
+};
+
+#define TCS3472_CHANNEL(_color, _si, _addr) { \
+       .type = IIO_INTENSITY, \
+       .modified = 1, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBSCALE) | \
+               BIT(IIO_CHAN_INFO_INT_TIME), \
+       .channel2 = IIO_MOD_LIGHT_##_color, \
+       .address = _addr, \
+       .scan_index = _si, \
+       .scan_type = IIO_ST('u', 16, 16, 0), \
+}
+
+static const int tcs3472_agains[] = { 1, 4, 16, 60 };
+
+static const struct iio_chan_spec tcs3472_channels[] = {
+       TCS3472_CHANNEL(CLEAR, 0, TCS3472_CDATA),
+       TCS3472_CHANNEL(RED, 1, TCS3472_RDATA),
+       TCS3472_CHANNEL(GREEN, 2, TCS3472_GDATA),
+       TCS3472_CHANNEL(BLUE, 3, TCS3472_BDATA),
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static int tcs3472_req_data(struct tcs3472_data *data)
+{
+       int tries = 50;
+       int ret;
+
+       while (tries--) {
+               ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS);
+               if (ret < 0)
+                       return ret;
+               if (ret & TCS3472_STATUS_AVALID)
+                       break;
+               msleep(20);
+       }
+
+       if (tries < 0) {
+               dev_err(&data->client->dev, "data not ready\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int tcs3472_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val, int *val2, long mask)
+{
+       struct tcs3472_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = tcs3472_req_data(data);
+               if (ret < 0)
+                       return ret;
+               ret = i2c_smbus_read_word_data(data->client, chan->address);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               *val = tcs3472_agains[data->control &
+                       TCS3472_CONTROL_AGAIN_MASK];
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_INT_TIME:
+               *val = 0;
+               *val2 = (256 - data->atime) * 2400;
+               return IIO_VAL_INT_PLUS_MICRO;
+       }
+       return -EINVAL;
+}
+
+static int tcs3472_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val, int val2, long mask)
+{
+       struct tcs3472_data *data = iio_priv(indio_dev);
+       int i;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_CALIBSCALE:
+               if (val2 != 0)
+                       return -EINVAL;
+               for (i = 0; i < ARRAY_SIZE(tcs3472_agains); i++) {
+                       if (val == tcs3472_agains[i]) {
+                               data->control &= ~TCS3472_CONTROL_AGAIN_MASK;
+                               data->control |= i;
+                               return i2c_smbus_write_byte_data(
+                                       data->client, TCS3472_CONTROL,
+                                       data->control);
+                       }
+               }
+               return -EINVAL;
+       case IIO_CHAN_INFO_INT_TIME:
+               if (val != 0)
+                       return -EINVAL;
+               for (i = 0; i < 256; i++) {
+                       if (val2 == (256 - i) * 2400) {
+                               data->atime = i;
+                               return i2c_smbus_write_word_data(
+                                       data->client, TCS3472_ATIME,
+                                       data->atime);
+                       }
+
+               }
+               return -EINVAL;
+       }
+       return -EINVAL;
+}
+
+static irqreturn_t tcs3472_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct tcs3472_data *data = iio_priv(indio_dev);
+       int len = 0;
+       int i, j = 0;
+
+       int ret = tcs3472_req_data(data);
+       if (ret < 0)
+               goto done;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               ret = i2c_smbus_read_word_data(data->client,
+                       TCS3472_CDATA + 2*i);
+               if (ret < 0)
+                       goto done;
+
+               data->buffer[j++] = ret;
+               len += 2;
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+               iio_get_time_ns());
+
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static ssize_t tcs3472_show_int_time_available(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       size_t len = 0;
+       int i;
+
+       for (i = 1; i <= 256; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
+                       2400 * i);
+
+       /* replace trailing space by newline */
+       buf[len - 1] = '\n';
+
+       return len;
+}
+
+static IIO_CONST_ATTR(calibscale_available, "1 4 16 60");
+static IIO_DEV_ATTR_INT_TIME_AVAIL(tcs3472_show_int_time_available);
+
+static struct attribute *tcs3472_attributes[] = {
+       &iio_const_attr_calibscale_available.dev_attr.attr,
+       &iio_dev_attr_integration_time_available.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group tcs3472_attribute_group = {
+       .attrs = tcs3472_attributes,
+};
+
+static const struct iio_info tcs3472_info = {
+       .read_raw = tcs3472_read_raw,
+       .write_raw = tcs3472_write_raw,
+       .attrs = &tcs3472_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static int tcs3472_probe(struct i2c_client *client,
+                          const struct i2c_device_id *id)
+{
+       struct tcs3472_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (indio_dev == NULL)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
+       data->client = client;
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->info = &tcs3472_info;
+       indio_dev->name = TCS3472_DRV_NAME;
+       indio_dev->channels = tcs3472_channels;
+       indio_dev->num_channels = ARRAY_SIZE(tcs3472_channels);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_ID);
+       if (ret < 0)
+               return ret;
+
+       if (ret == 0x44)
+               dev_info(&client->dev, "TCS34721/34725 found\n");
+       else if (ret == 0x4d)
+               dev_info(&client->dev, "TCS34723/34727 found\n");
+       else
+               return -ENODEV;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_CONTROL);
+       if (ret < 0)
+               return ret;
+       data->control = ret;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_ATIME);
+       if (ret < 0)
+               return ret;
+       data->atime = ret;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_ENABLE);
+       if (ret < 0)
+               return ret;
+
+       /* enable device */
+       data->enable = ret | TCS3472_ENABLE_PON | TCS3472_ENABLE_AEN;
+       ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
+               data->enable);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_triggered_buffer_setup(indio_dev, NULL,
+               tcs3472_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 tcs3472_powerdown(struct tcs3472_data *data)
+{
+       return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
+               data->enable & ~(TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
+}
+
+static int tcs3472_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);
+       tcs3472_powerdown(iio_priv(indio_dev));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tcs3472_suspend(struct device *dev)
+{
+       struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+       return tcs3472_powerdown(data);
+}
+
+static int tcs3472_resume(struct device *dev)
+{
+       struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+       return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
+               data->enable | (TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume);
+
+static const struct i2c_device_id tcs3472_id[] = {
+       { "tcs3472", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tcs3472_id);
+
+static struct i2c_driver tcs3472_driver = {
+       .driver = {
+               .name   = TCS3472_DRV_NAME,
+               .pm     = &tcs3472_pm_ops,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = tcs3472_probe,
+       .remove         = tcs3472_remove,
+       .id_table       = tcs3472_id,
+};
+module_i2c_driver(tcs3472_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("TCS3472 color light sensors driver");
+MODULE_LICENSE("GPL");
index ebb962c5c323a025f9c9e1ef8cfb27f40f2ba8d5..5e5d9dea22c598016c225848333c1e31595c811f 100644 (file)
@@ -526,6 +526,20 @@ error_ret:
        return ret;
 }
 
+static const struct iio_event_spec tsl2563_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                               BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                               BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
 static const struct iio_chan_spec tsl2563_channels[] = {
        {
                .type = IIO_LIGHT,
@@ -538,10 +552,8 @@ static const struct iio_chan_spec tsl2563_channels[] = {
                .channel2 = IIO_MOD_LIGHT_BOTH,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                BIT(IIO_CHAN_INFO_CALIBSCALE),
-               .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_RISING) |
-                              IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_FALLING)),
+               .event_spec = tsl2563_events,
+               .num_event_specs = ARRAY_SIZE(tsl2563_events),
        }, {
                .type = IIO_INTENSITY,
                .modified = 1,
@@ -552,12 +564,13 @@ static const struct iio_chan_spec tsl2563_channels[] = {
 };
 
 static int tsl2563_read_thresh(struct iio_dev *indio_dev,
-                              u64 event_code,
-                              int *val)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, enum iio_event_info info, int *val,
+       int *val2)
 {
        struct tsl2563_chip *chip = iio_priv(indio_dev);
 
-       switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       switch (dir) {
        case IIO_EV_DIR_RISING:
                *val = chip->high_thres;
                break;
@@ -568,18 +581,19 @@ static int tsl2563_read_thresh(struct iio_dev *indio_dev,
                return -EINVAL;
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 static int tsl2563_write_thresh(struct iio_dev *indio_dev,
-                                 u64 event_code,
-                                 int val)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, enum iio_event_info info, int val,
+       int val2)
 {
        struct tsl2563_chip *chip = iio_priv(indio_dev);
        int ret;
        u8 address;
 
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+       if (dir == IIO_EV_DIR_RISING)
                address = TSL2563_REG_HIGHLOW;
        else
                address = TSL2563_REG_LOWLOW;
@@ -591,7 +605,7 @@ static int tsl2563_write_thresh(struct iio_dev *indio_dev,
        ret = i2c_smbus_write_byte_data(chip->client,
                                        TSL2563_CMD | (address + 1),
                                        (val >> 8) & 0xFF);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+       if (dir == IIO_EV_DIR_RISING)
                chip->high_thres = val;
        else
                chip->low_thres = val;
@@ -620,8 +634,8 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
 }
 
 static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
-                                         u64 event_code,
-                                         int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        struct tsl2563_chip *chip = iio_priv(indio_dev);
        int ret = 0;
@@ -662,7 +676,8 @@ out:
 }
 
 static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
-                                        u64 event_code)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        struct tsl2563_chip *chip = iio_priv(indio_dev);
        int ret;
@@ -687,10 +702,10 @@ static const struct iio_info tsl2563_info = {
        .driver_module = THIS_MODULE,
        .read_raw = &tsl2563_read_raw,
        .write_raw = &tsl2563_write_raw,
-       .read_event_value = &tsl2563_read_thresh,
-       .write_event_value = &tsl2563_write_thresh,
-       .read_event_config = &tsl2563_read_interrupt_config,
-       .write_event_config = &tsl2563_write_interrupt_config,
+       .read_event_value_new = &tsl2563_read_thresh,
+       .write_event_value_new = &tsl2563_write_thresh,
+       .read_event_config_new = &tsl2563_read_interrupt_config,
+       .write_event_config_new = &tsl2563_write_interrupt_config,
 };
 
 static int tsl2563_probe(struct i2c_client *client,
diff --git a/drivers/iio/light/tsl4531.c b/drivers/iio/light/tsl4531.c
new file mode 100644 (file)
index 0000000..a15006e
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * tsl4531.c - Support for TAOS TSL4531 ambient light sensor
+ *
+ * Copyright 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.
+ *
+ * IIO driver for the TSL4531x family
+ *   TSL45311/TSL45313: 7-bit I2C slave address 0x39
+ *   TSL45315/TSL45317: 7-bit I2C slave address 0x29
+ *
+ * TODO: single cycle measurement
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define TSL4531_DRV_NAME "tsl4531"
+
+#define TCS3472_COMMAND BIT(7)
+
+#define TSL4531_CONTROL (TCS3472_COMMAND | 0x00)
+#define TSL4531_CONFIG (TCS3472_COMMAND | 0x01)
+#define TSL4531_DATA (TCS3472_COMMAND | 0x04)
+#define TSL4531_ID (TCS3472_COMMAND | 0x0a)
+
+/* operating modes in control register */
+#define TSL4531_MODE_POWERDOWN 0x00
+#define TSL4531_MODE_SINGLE_ADC 0x02
+#define TSL4531_MODE_NORMAL 0x03
+
+/* integration time control in config register */
+#define TSL4531_TCNTRL_400MS 0x00
+#define TSL4531_TCNTRL_200MS 0x01
+#define TSL4531_TCNTRL_100MS 0x02
+
+/* part number in id register */
+#define TSL45311_ID 0x8
+#define TSL45313_ID 0x9
+#define TSL45315_ID 0xa
+#define TSL45317_ID 0xb
+#define TSL4531_ID_SHIFT 4
+
+struct tsl4531_data {
+       struct i2c_client *client;
+       struct mutex lock;
+       int int_time;
+};
+
+static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.2 0.4");
+
+static struct attribute *tsl4531_attributes[] = {
+       &iio_const_attr_integration_time_available.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group tsl4531_attribute_group = {
+       .attrs = tsl4531_attributes,
+};
+
+static const struct iio_chan_spec tsl4531_channels[] = {
+       {
+               .type = IIO_LIGHT,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_INT_TIME)
+       }
+};
+
+static int tsl4531_read_raw(struct iio_dev *indio_dev,
+                               struct iio_chan_spec const *chan,
+                               int *val, int *val2, long mask)
+{
+       struct tsl4531_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = i2c_smbus_read_word_data(data->client,
+                       TSL4531_DATA);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /* 0.. 1x, 1 .. 2x, 2 .. 4x */
+               *val = 1 << data->int_time;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_INT_TIME:
+               if (data->int_time == 0)
+                       *val2 = 400000;
+               else if (data->int_time == 1)
+                       *val2 = 200000;
+               else if (data->int_time == 2)
+                       *val2 = 100000;
+               else
+                       return -EINVAL;
+               *val = 0;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int tsl4531_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct tsl4531_data *data = iio_priv(indio_dev);
+       int int_time, ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_INT_TIME:
+               if (val != 0)
+                       return -EINVAL;
+               if (val2 == 400000)
+                       int_time = 0;
+               else if (val2 == 200000)
+                       int_time = 1;
+               else if (val2 == 100000)
+                       int_time = 2;
+               else
+                       return -EINVAL;
+               mutex_lock(&data->lock);
+               ret = i2c_smbus_write_byte_data(data->client,
+                       TSL4531_CONFIG, int_time);
+               if (ret >= 0)
+                       data->int_time = int_time;
+               mutex_unlock(&data->lock);
+               return ret;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info tsl4531_info = {
+       .read_raw = tsl4531_read_raw,
+       .write_raw = tsl4531_write_raw,
+       .attrs = &tsl4531_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static int tsl4531_check_id(struct i2c_client *client)
+{
+       int ret = i2c_smbus_read_byte_data(client, TSL4531_ID);
+       if (ret < 0)
+               return ret;
+
+       switch (ret >> TSL4531_ID_SHIFT) {
+       case TSL45311_ID:
+       case TSL45313_ID:
+       case TSL45315_ID:
+       case TSL45317_ID:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int tsl4531_probe(struct i2c_client *client,
+                         const struct i2c_device_id *id)
+{
+       struct tsl4531_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
+       data->client = client;
+       mutex_init(&data->lock);
+
+       if (!tsl4531_check_id(client)) {
+               dev_err(&client->dev, "no TSL4531 sensor\n");
+               return -ENODEV;
+       }
+
+       ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONTROL,
+               TSL4531_MODE_NORMAL);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONFIG,
+               TSL4531_TCNTRL_400MS);
+       if (ret < 0)
+               return ret;
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->info = &tsl4531_info;
+       indio_dev->channels = tsl4531_channels;
+       indio_dev->num_channels = ARRAY_SIZE(tsl4531_channels);
+       indio_dev->name = TSL4531_DRV_NAME;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       return iio_device_register(indio_dev);
+}
+
+static int tsl4531_powerdown(struct i2c_client *client)
+{
+       return i2c_smbus_write_byte_data(client, TSL4531_CONTROL,
+               TSL4531_MODE_POWERDOWN);
+}
+
+static int tsl4531_remove(struct i2c_client *client)
+{
+       iio_device_unregister(i2c_get_clientdata(client));
+       tsl4531_powerdown(client);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tsl4531_suspend(struct device *dev)
+{
+       return tsl4531_powerdown(to_i2c_client(dev));
+}
+
+static int tsl4531_resume(struct device *dev)
+{
+       return i2c_smbus_write_byte_data(to_i2c_client(dev), TSL4531_CONTROL,
+               TSL4531_MODE_NORMAL);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tsl4531_pm_ops, tsl4531_suspend, tsl4531_resume);
+
+static const struct i2c_device_id tsl4531_id[] = {
+       { "tsl4531", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tsl4531_id);
+
+static struct i2c_driver tsl4531_driver = {
+       .driver = {
+               .name   = TSL4531_DRV_NAME,
+               .pm     = &tsl4531_pm_ops,
+               .owner  = THIS_MODULE,
+       },
+       .probe  = tsl4531_probe,
+       .remove = tsl4531_remove,
+       .id_table = tsl4531_id,
+};
+
+module_i2c_driver(tsl4531_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("TAOS TSL4531 ambient light sensors driver");
+MODULE_LICENSE("GPL");
index 2bb304215b1d88e2c19189215806ec7311f41739..ecb3341ef9c07a8e56ddaf1de8d76d31456e6d2a 100644 (file)
@@ -179,11 +179,7 @@ static int vcnl4000_probe(struct i2c_client *client,
        indio_dev->name = VCNL4000_DRV_NAME;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       ret = iio_device_register(indio_dev);
-       if (ret < 0)
-               return ret;
-
-       return 0;
+       return iio_device_register(indio_dev);
 }
 
 static int vcnl4000_remove(struct i2c_client *client)
index 4fa923f37b971e51a92942ccd0884b07a5fe8195..0cf09637b35b64f16a37c3adece1416cc453fee1 100644 (file)
@@ -16,6 +16,16 @@ config AK8975
          To compile this driver as a module, choose M here: the module
          will be called ak8975.
 
+config MAG3110
+       tristate "Freescale MAG3110 3-Axis Magnetometer"
+       depends on I2C
+       help
+         Say yes here to build support for the Freescale MAG3110 3-Axis
+         magnetometer.
+
+         To compile this driver as a module, choose M here: the module
+         will be called mag3110.
+
 config HID_SENSOR_MAGNETOMETER_3D
        depends on HID_SENSOR_HUB
        select IIO_BUFFER
index f91b1b68d3924cb925e34710be91f1144bdca844..0f5d3c9857992425efee09de2a95ef0acb972dc1 100644 (file)
@@ -4,6 +4,7 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AK8975)   += ak8975.o
+obj-$(CONFIG_MAG3110)  += mag3110.o
 obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
 
 obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o
index 7105f22d6cd7f36890148327acc83f9584ef28ab..ff284e5afd9587c4e8a14bc9633b018098ce983c 100644 (file)
@@ -263,7 +263,7 @@ static int ak8975_setup(struct i2c_client *client)
  *
  * HuT = H * 1229/4096, or roughly, 3/10.
  *
- * Since 1uT = 100 gauss, our final scale factor becomes:
+ * Since 1uT = 0.01 gauss, our final scale factor becomes:
  *
  * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
  * Hadj = H * ((ASA + 128) * 30 / 256
index a98460b15e4b63fc791494c32b1594993a12b6d1..2634920562fb7263bad4ac9d8c6c75fe7a434b49 100644 (file)
@@ -183,10 +183,11 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -201,7 +202,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                magn_state->common_attributes.data_ready);
        if (magn_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)magn_state->magn_val,
+                               magn_state->magn_val,
                                sizeof(magn_state->magn_val));
 
        return 0;
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c
new file mode 100644 (file)
index 0000000..783c5b4
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * mag3110.c - Support for Freescale MAG3110 magnetometer 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 0x0e)
+ *
+ * TODO: irq, user offset, oversampling, continuous 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 MAG3110_STATUS 0x00
+#define MAG3110_OUT_X 0x01 /* MSB first */
+#define MAG3110_OUT_Y 0x03
+#define MAG3110_OUT_Z 0x05
+#define MAG3110_WHO_AM_I 0x07
+#define MAG3110_OFF_X 0x09 /* MSB first */
+#define MAG3110_OFF_Y 0x0b
+#define MAG3110_OFF_Z 0x0d
+#define MAG3110_DIE_TEMP 0x0f
+#define MAG3110_CTRL_REG1 0x10
+#define MAG3110_CTRL_REG2 0x11
+
+#define MAG3110_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
+
+#define MAG3110_CTRL_DR_MASK (BIT(7) | BIT(6) | BIT(5))
+#define MAG3110_CTRL_DR_SHIFT 5
+#define MAG3110_CTRL_DR_DEFAULT 0
+
+#define MAG3110_CTRL_TM BIT(1) /* trigger single measurement */
+#define MAG3110_CTRL_AC BIT(0) /* continuous measurements */
+
+#define MAG3110_CTRL_AUTO_MRST_EN BIT(7) /* magnetic auto-reset */
+#define MAG3110_CTRL_RAW BIT(5) /* measurements not user-offset corrected */
+
+#define MAG3110_DEVICE_ID 0xc4
+
+/* Each client has this additional data */
+struct mag3110_data {
+       struct i2c_client *client;
+       struct mutex lock;
+       u8 ctrl_reg1;
+};
+
+static int mag3110_request(struct mag3110_data *data)
+{
+       int ret, tries = 150;
+
+       /* trigger measurement */
+       ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
+               data->ctrl_reg1 | MAG3110_CTRL_TM);
+       if (ret < 0)
+               return ret;
+
+       while (tries-- > 0) {
+               ret = i2c_smbus_read_byte_data(data->client, MAG3110_STATUS);
+               if (ret < 0)
+                       return ret;
+               /* wait for data ready */
+               if ((ret & MAG3110_STATUS_DRDY) == MAG3110_STATUS_DRDY)
+                       break;
+               msleep(20);
+       }
+
+       if (tries < 0) {
+               dev_err(&data->client->dev, "data not ready\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int mag3110_read(struct mag3110_data *data, __be16 buf[3])
+{
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = mag3110_request(data);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               return ret;
+       }
+       ret = i2c_smbus_read_i2c_block_data(data->client,
+               MAG3110_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
+       mutex_unlock(&data->lock);
+
+       return ret;
+}
+
+static ssize_t mag3110_show_int_plus_micros(char *buf,
+       const int (*vals)[2], int n)
+{
+       size_t len = 0;
+
+       while (n-- > 0)
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                       "%d.%d ", vals[n][0], vals[n][1]);
+
+       /* replace trailing space by newline */
+       buf[len - 1] = '\n';
+
+       return len;
+}
+
+static int mag3110_get_int_plus_micros_index(const int (*vals)[2], int n,
+                                       int val, int val2)
+{
+       while (n-- > 0)
+               if (val == vals[n][0] && val2 == vals[n][1])
+                       return n;
+
+       return -EINVAL;
+}
+
+static const int mag3110_samp_freq[8][2] = {
+       {80, 0}, {40, 0}, {20, 0}, {10, 0}, {5, 0}, {2, 500000},
+       {1, 250000}, {0, 625000}
+};
+
+static ssize_t mag3110_show_samp_freq_avail(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       return mag3110_show_int_plus_micros(buf, mag3110_samp_freq, 8);
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mag3110_show_samp_freq_avail);
+
+static int mag3110_get_samp_freq_index(struct mag3110_data *data,
+       int val, int val2)
+{
+       return mag3110_get_int_plus_micros_index(mag3110_samp_freq, 8, val,
+               val2);
+}
+
+static int mag3110_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long mask)
+{
+       struct mag3110_data *data = iio_priv(indio_dev);
+       __be16 buffer[3];
+       int i, ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               switch (chan->type) {
+               case IIO_MAGN: /* in 0.1 uT / LSB */
+                       ret = mag3110_read(data, buffer);
+                       if (ret < 0)
+                               return ret;
+                       *val = sign_extend32(
+                               be16_to_cpu(buffer[chan->scan_index]), 15);
+                       return IIO_VAL_INT;
+               case IIO_TEMP: /* in 1 C / LSB */
+                       mutex_lock(&data->lock);
+                       ret = mag3110_request(data);
+                       if (ret < 0) {
+                               mutex_unlock(&data->lock);
+                               return ret;
+                       }
+                       ret = i2c_smbus_read_byte_data(data->client,
+                               MAG3110_DIE_TEMP);
+                       mutex_unlock(&data->lock);
+                       if (ret < 0)
+                               return ret;
+                       *val = sign_extend32(ret, 7);
+                       return IIO_VAL_INT;
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = 1000;
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT;
+               *val = mag3110_samp_freq[i][0];
+               *val2 = mag3110_samp_freq[i][1];
+               return IIO_VAL_INT_PLUS_MICRO;
+       }
+       return -EINVAL;
+}
+
+static int mag3110_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct mag3110_data *data = iio_priv(indio_dev);
+       int rate;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               rate = mag3110_get_samp_freq_index(data, val, val2);
+               if (rate < 0)
+                       return -EINVAL;
+
+               data->ctrl_reg1 &= ~MAG3110_CTRL_DR_MASK;
+               data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT;
+               return i2c_smbus_write_byte_data(data->client,
+                       MAG3110_CTRL_REG1, data->ctrl_reg1);
+       default:
+               return -EINVAL;
+       }
+}
+
+static irqreturn_t mag3110_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct mag3110_data *data = iio_priv(indio_dev);
+       u8 buffer[16]; /* 3 16-bit channels + 1 byte temp + padding + ts */
+       int ret;
+
+       ret = mag3110_read(data, (__be16 *) buffer);
+       if (ret < 0)
+               goto done;
+
+       if (test_bit(3, indio_dev->active_scan_mask)) {
+               ret = i2c_smbus_read_byte_data(data->client,
+                       MAG3110_DIE_TEMP);
+               if (ret < 0)
+                       goto done;
+               buffer[6] = ret;
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, buffer,
+               iio_get_time_ns());
+
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+       return IRQ_HANDLED;
+}
+
+#define MAG3110_CHANNEL(axis, idx) { \
+       .type = IIO_MAGN, \
+       .modified = 1, \
+       .channel2 = IIO_MOD_##axis, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .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), \
+}
+
+static const struct iio_chan_spec mag3110_channels[] = {
+       MAG3110_CHANNEL(X, 0),
+       MAG3110_CHANNEL(Y, 1),
+       MAG3110_CHANNEL(Z, 2),
+       {
+               .type = IIO_TEMP,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_index = 3,
+               .scan_type = IIO_ST('s', 8, 8, 0),
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static struct attribute *mag3110_attributes[] = {
+       &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group mag3110_group = {
+       .attrs = mag3110_attributes,
+};
+
+static const struct iio_info mag3110_info = {
+       .attrs = &mag3110_group,
+       .read_raw = &mag3110_read_raw,
+       .write_raw = &mag3110_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0};
+
+static int mag3110_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct mag3110_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       ret = i2c_smbus_read_byte_data(client, MAG3110_WHO_AM_I);
+       if (ret < 0)
+               return ret;
+       if (ret != MAG3110_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 = &mag3110_info;
+       indio_dev->name = id->name;
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = mag3110_channels;
+       indio_dev->num_channels = ARRAY_SIZE(mag3110_channels);
+       indio_dev->available_scan_masks = mag3110_scan_masks;
+
+       data->ctrl_reg1 = MAG3110_CTRL_DR_DEFAULT;
+       ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG1,
+               data->ctrl_reg1);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG2,
+               MAG3110_CTRL_AUTO_MRST_EN | MAG3110_CTRL_RAW);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_triggered_buffer_setup(indio_dev, NULL,
+               mag3110_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 mag3110_standby(struct mag3110_data *data)
+{
+       return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
+               data->ctrl_reg1 & ~MAG3110_CTRL_AC);
+}
+
+static int mag3110_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);
+       mag3110_standby(iio_priv(indio_dev));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mag3110_suspend(struct device *dev)
+{
+       return mag3110_standby(iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev))));
+}
+
+static int mag3110_resume(struct device *dev)
+{
+       struct mag3110_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+
+       return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
+               data->ctrl_reg1);
+}
+
+static SIMPLE_DEV_PM_OPS(mag3110_pm_ops, mag3110_suspend, mag3110_resume);
+#define MAG3110_PM_OPS (&mag3110_pm_ops)
+#else
+#define MAG3110_PM_OPS NULL
+#endif
+
+static const struct i2c_device_id mag3110_id[] = {
+       { "mag3110", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mag3110_id);
+
+static struct i2c_driver mag3110_driver = {
+       .driver = {
+               .name   = "mag3110",
+               .pm     = MAG3110_PM_OPS,
+       },
+       .probe = mag3110_probe,
+       .remove = mag3110_remove,
+       .id_table = mag3110_id,
+};
+module_i2c_driver(mag3110_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Freescale MAG3110 magnetometer driver");
+MODULE_LICENSE("GPL");
index 708857bdb47d3d4ba69a0fc65d1512defe4881c9..bf427dc0d226c40de9adc92257ece78ab6b14de6 100644 (file)
 
 static int st_magn_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_magn_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_magn_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_magn_buffer_postenable(struct iio_dev *indio_dev)
index cab3bc7494a2260214a85874310ac80deca87c0a..52bbcfa1e07795208b45633ced62de0015772b74 100644 (file)
@@ -348,8 +348,9 @@ static const struct iio_info magn_info = {
 int st_magn_common_probe(struct iio_dev *indio_dev,
                                        struct st_sensors_platform_data *pdata)
 {
-       int err;
        struct st_sensor_data *mdata = iio_priv(indio_dev);
+       int irq = mdata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &magn_info;
@@ -357,7 +358,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
        err = st_sensors_check_device_support(indio_dev,
                                ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
        if (err < 0)
-               goto st_magn_common_probe_error;
+               return err;
 
        mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
        mdata->multiread_bit = mdata->sensor->multi_read_bit;
@@ -370,12 +371,13 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
 
        err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
-               goto st_magn_common_probe_error;
+               return err;
 
-       if (mdata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_magn_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_magn_common_probe_error;
+       err = st_magn_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
+
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev, NULL);
                if (err < 0)
                        goto st_magn_probe_trigger_error;
@@ -385,15 +387,14 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
        if (err)
                goto st_magn_device_register_error;
 
-       return err;
+       return 0;
 
 st_magn_device_register_error:
-       if (mdata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_magn_probe_trigger_error:
-       if (mdata->get_irq_data_ready(indio_dev) > 0)
-               st_magn_deallocate_ring(indio_dev);
-st_magn_common_probe_error:
+       st_magn_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_magn_common_probe);
@@ -403,10 +404,10 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
        struct st_sensor_data *mdata = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (mdata->get_irq_data_ready(indio_dev) > 0) {
+       if (mdata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_magn_deallocate_ring(indio_dev);
-       }
+
+       st_magn_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_magn_common_remove);
 
index 26fdc0bdb99d59d8f8a956252d5d927f6b553551..4f2e0f9bad8c100d89a43265daa0af8bb3b7450b 100644 (file)
@@ -14,7 +14,7 @@ config IIO_ST_PRESS
        select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
        help
          Say yes here to build support for STMicroelectronics pressure
-         sensors: LPS331AP.
+         sensors: LPS001WP, LPS331AP.
 
          This driver can also be built as a module. If so, these modules
          will be created:
index b0b630688da665138a97e3afbf33c1f387dda323..049c21acf1f051bfea9067c45ad7eb543b6361b2 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/iio/common/st_sensors.h>
 
+#define LPS001WP_PRESS_DEV_NAME                "lps001wp"
 #define LPS331AP_PRESS_DEV_NAME                "lps331ap"
 
 /**
index f877ef8af5201dfbabd03bc06b79db061111a12f..b37b1c9ac93210dc755ac95830fc956e428333ce 100644 (file)
@@ -32,16 +32,7 @@ int st_press_trig_set_state(struct iio_trigger *trig, bool state)
 
 static int st_press_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_press_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_press_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_press_buffer_postenable(struct iio_dev *indio_dev)
index ceebd3c27892b183f6f276b1dbdb4d7a6a5a9a74..58083f9d51c56691281891e4afbbe368d92697ab 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
+#include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
 
 #include <linux/iio/common/st_sensors.h>
                                                 ST_PRESS_LSB_PER_CELSIUS)
 #define ST_PRESS_NUMBER_DATA_CHANNELS          1
 
-/* DEFAULT VALUE FOR SENSORS */
-#define ST_PRESS_DEFAULT_OUT_XL_ADDR           0x28
-#define ST_TEMP_DEFAULT_OUT_L_ADDR             0x2b
-
 /* FULLSCALE */
 #define ST_PRESS_FS_AVL_1260MB                 1260
 
-/* CUSTOM VALUES FOR SENSOR 1 */
-#define ST_PRESS_1_WAI_EXP                     0xbb
-#define ST_PRESS_1_ODR_ADDR                    0x20
-#define ST_PRESS_1_ODR_MASK                    0x70
-#define ST_PRESS_1_ODR_AVL_1HZ_VAL             0x01
-#define ST_PRESS_1_ODR_AVL_7HZ_VAL             0x05
-#define ST_PRESS_1_ODR_AVL_13HZ_VAL            0x06
-#define ST_PRESS_1_ODR_AVL_25HZ_VAL            0x07
-#define ST_PRESS_1_PW_ADDR                     0x20
-#define ST_PRESS_1_PW_MASK                     0x80
-#define ST_PRESS_1_FS_ADDR                     0x23
-#define ST_PRESS_1_FS_MASK                     0x30
-#define ST_PRESS_1_FS_AVL_1260_VAL             0x00
-#define ST_PRESS_1_FS_AVL_1260_GAIN            ST_PRESS_KPASCAL_NANO_SCALE
-#define ST_PRESS_1_FS_AVL_TEMP_GAIN            ST_PRESS_CELSIUS_NANO_SCALE
-#define ST_PRESS_1_BDU_ADDR                    0x20
-#define ST_PRESS_1_BDU_MASK                    0x04
-#define ST_PRESS_1_DRDY_IRQ_ADDR               0x22
-#define ST_PRESS_1_DRDY_IRQ_INT1_MASK          0x04
-#define ST_PRESS_1_DRDY_IRQ_INT2_MASK          0x20
-#define ST_PRESS_1_MULTIREAD_BIT               true
-#define ST_PRESS_1_TEMP_OFFSET                 42500
-
-static const struct iio_chan_spec st_press_channels[] = {
-       ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
+/* CUSTOM VALUES FOR LPS331AP SENSOR */
+#define ST_PRESS_LPS331AP_WAI_EXP              0xbb
+#define ST_PRESS_LPS331AP_ODR_ADDR             0x20
+#define ST_PRESS_LPS331AP_ODR_MASK             0x70
+#define ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL      0x01
+#define ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL      0x05
+#define ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL     0x06
+#define ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL     0x07
+#define ST_PRESS_LPS331AP_PW_ADDR              0x20
+#define ST_PRESS_LPS331AP_PW_MASK              0x80
+#define ST_PRESS_LPS331AP_FS_ADDR              0x23
+#define ST_PRESS_LPS331AP_FS_MASK              0x30
+#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL      0x00
+#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN     ST_PRESS_KPASCAL_NANO_SCALE
+#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN     ST_PRESS_CELSIUS_NANO_SCALE
+#define ST_PRESS_LPS331AP_BDU_ADDR             0x20
+#define ST_PRESS_LPS331AP_BDU_MASK             0x04
+#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR                0x22
+#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK   0x04
+#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK   0x20
+#define ST_PRESS_LPS331AP_MULTIREAD_BIT                true
+#define ST_PRESS_LPS331AP_TEMP_OFFSET          42500
+#define ST_PRESS_LPS331AP_OUT_XL_ADDR          0x28
+#define ST_TEMP_LPS331AP_OUT_L_ADDR            0x2b
+
+/* CUSTOM VALUES FOR LPS001WP SENSOR */
+#define ST_PRESS_LPS001WP_WAI_EXP              0xba
+#define ST_PRESS_LPS001WP_ODR_ADDR             0x20
+#define ST_PRESS_LPS001WP_ODR_MASK             0x30
+#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL      0x01
+#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL      0x02
+#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL     0x03
+#define ST_PRESS_LPS001WP_PW_ADDR              0x20
+#define ST_PRESS_LPS001WP_PW_MASK              0x40
+#define ST_PRESS_LPS001WP_BDU_ADDR             0x20
+#define ST_PRESS_LPS001WP_BDU_MASK             0x04
+#define ST_PRESS_LPS001WP_MULTIREAD_BIT                true
+#define ST_PRESS_LPS001WP_OUT_L_ADDR           0x28
+#define ST_TEMP_LPS001WP_OUT_L_ADDR            0x2a
+
+static const struct iio_chan_spec st_press_lps331ap_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_PRESS_LPS331AP_OUT_XL_ADDR,
+               .scan_index = ST_SENSORS_SCAN_X,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 24,
+                       .storagebits = 24,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate =
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-                       ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
-                       ST_PRESS_DEFAULT_OUT_XL_ADDR),
-       ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
-                                               BIT(IIO_CHAN_INFO_OFFSET),
-                       -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
-                       ST_TEMP_DEFAULT_OUT_L_ADDR),
+               .modified = 0,
+       },
+       {
+               .type = IIO_TEMP,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_TEMP_LPS331AP_OUT_L_ADDR,
+               .scan_index = -1,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_OFFSET),
+               .modified = 0,
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(1)
+};
+
+static const struct iio_chan_spec st_press_lps001wp_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
+               .scan_index = ST_SENSORS_SCAN_X,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .modified = 0,
+       },
+       {
+               .type = IIO_TEMP,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
+               .scan_index = -1,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_OFFSET),
+               .modified = 0,
+       },
        IIO_CHAN_SOFT_TIMESTAMP(1)
 };
 
 static const struct st_sensors st_press_sensors[] = {
        {
-               .wai = ST_PRESS_1_WAI_EXP,
+               .wai = ST_PRESS_LPS331AP_WAI_EXP,
                .sensors_supported = {
                        [0] = LPS331AP_PRESS_DEV_NAME,
                },
-               .ch = (struct iio_chan_spec *)st_press_channels,
+               .ch = (struct iio_chan_spec *)st_press_lps331ap_channels,
+               .num_ch = ARRAY_SIZE(st_press_lps331ap_channels),
                .odr = {
-                       .addr = ST_PRESS_1_ODR_ADDR,
-                       .mask = ST_PRESS_1_ODR_MASK,
+                       .addr = ST_PRESS_LPS331AP_ODR_ADDR,
+                       .mask = ST_PRESS_LPS331AP_ODR_MASK,
                        .odr_avl = {
-                               { 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, },
-                               { 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, },
-                               { 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, },
-                               { 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, },
+                               { 1, ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL, },
+                               { 7, ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL, },
+                               { 13, ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL, },
+                               { 25, ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL, },
                        },
                },
                .pw = {
-                       .addr = ST_PRESS_1_PW_ADDR,
-                       .mask = ST_PRESS_1_PW_MASK,
+                       .addr = ST_PRESS_LPS331AP_PW_ADDR,
+                       .mask = ST_PRESS_LPS331AP_PW_MASK,
                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
                },
                .fs = {
-                       .addr = ST_PRESS_1_FS_ADDR,
-                       .mask = ST_PRESS_1_FS_MASK,
+                       .addr = ST_PRESS_LPS331AP_FS_ADDR,
+                       .mask = ST_PRESS_LPS331AP_FS_MASK,
                        .fs_avl = {
                                [0] = {
                                        .num = ST_PRESS_FS_AVL_1260MB,
-                                       .value = ST_PRESS_1_FS_AVL_1260_VAL,
-                                       .gain = ST_PRESS_1_FS_AVL_1260_GAIN,
-                                       .gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN,
+                                       .value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
+                                       .gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
+                                       .gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
                                },
                        },
                },
                .bdu = {
-                       .addr = ST_PRESS_1_BDU_ADDR,
-                       .mask = ST_PRESS_1_BDU_MASK,
+                       .addr = ST_PRESS_LPS331AP_BDU_ADDR,
+                       .mask = ST_PRESS_LPS331AP_BDU_MASK,
                },
                .drdy_irq = {
-                       .addr = ST_PRESS_1_DRDY_IRQ_ADDR,
-                       .mask_int1 = ST_PRESS_1_DRDY_IRQ_INT1_MASK,
-                       .mask_int2 = ST_PRESS_1_DRDY_IRQ_INT2_MASK,
+                       .addr = ST_PRESS_LPS331AP_DRDY_IRQ_ADDR,
+                       .mask_int1 = ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK,
+                       .mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK,
                },
-               .multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
+               .multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
+               .bootime = 2,
+       },
+       {
+               .wai = ST_PRESS_LPS001WP_WAI_EXP,
+               .sensors_supported = {
+                       [0] = LPS001WP_PRESS_DEV_NAME,
+               },
+               .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
+               .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
+               .odr = {
+                       .addr = ST_PRESS_LPS001WP_ODR_ADDR,
+                       .mask = ST_PRESS_LPS001WP_ODR_MASK,
+                       .odr_avl = {
+                               { 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, },
+                               { 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, },
+                               { 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, },
+                       },
+               },
+               .pw = {
+                       .addr = ST_PRESS_LPS001WP_PW_ADDR,
+                       .mask = ST_PRESS_LPS001WP_PW_MASK,
+                       .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+                       .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+               },
+               .fs = {
+                       .addr = 0,
+               },
+               .bdu = {
+                       .addr = ST_PRESS_LPS001WP_BDU_ADDR,
+                       .mask = ST_PRESS_LPS001WP_BDU_MASK,
+               },
+               .drdy_irq = {
+                       .addr = 0,
+               },
+               .multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT,
                .bootime = 2,
        },
 };
@@ -207,44 +314,85 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
 #define ST_PRESS_TRIGGER_OPS NULL
 #endif
 
+static void st_press_power_enable(struct iio_dev *indio_dev)
+{
+       struct st_sensor_data *pdata = iio_priv(indio_dev);
+       int err;
+
+       /* Regulators not mandatory, but if requested we should enable them. */
+       pdata->vdd = devm_regulator_get_optional(&indio_dev->dev, "vdd");
+       if (!IS_ERR(pdata->vdd)) {
+               err = regulator_enable(pdata->vdd);
+               if (err != 0)
+                       dev_warn(&indio_dev->dev,
+                                "Failed to enable specified Vdd supply\n");
+       }
+
+       pdata->vdd_io = devm_regulator_get_optional(&indio_dev->dev, "vddio");
+       if (!IS_ERR(pdata->vdd_io)) {
+               err = regulator_enable(pdata->vdd_io);
+               if (err != 0)
+                       dev_warn(&indio_dev->dev,
+                                "Failed to enable specified Vdd_IO supply\n");
+       }
+}
+
+static void st_press_power_disable(struct iio_dev *indio_dev)
+{
+       struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+       if (!IS_ERR(pdata->vdd))
+               regulator_disable(pdata->vdd);
+
+       if (!IS_ERR(pdata->vdd_io))
+               regulator_disable(pdata->vdd_io);
+}
+
 int st_press_common_probe(struct iio_dev *indio_dev,
                                struct st_sensors_platform_data *plat_data)
 {
-       int err;
        struct st_sensor_data *pdata = iio_priv(indio_dev);
+       int irq = pdata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &press_info;
 
+       st_press_power_enable(indio_dev);
+
        err = st_sensors_check_device_support(indio_dev,
-                               ARRAY_SIZE(st_press_sensors), st_press_sensors);
+                                             ARRAY_SIZE(st_press_sensors),
+                                             st_press_sensors);
        if (err < 0)
-               goto st_press_common_probe_error;
+               return err;
 
        pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
-       pdata->multiread_bit = pdata->sensor->multi_read_bit;
-       indio_dev->channels = pdata->sensor->ch;
-       indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
+       pdata->multiread_bit     = pdata->sensor->multi_read_bit;
+       indio_dev->channels      = pdata->sensor->ch;
+       indio_dev->num_channels  = pdata->sensor->num_ch;
+
+       if (pdata->sensor->fs.addr != 0)
+               pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
+                       &pdata->sensor->fs.fs_avl[0];
 
-       pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
-                                               &pdata->sensor->fs.fs_avl[0];
        pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
 
-       if (!plat_data)
+       /* Some devices don't support a data ready pin. */
+       if (!plat_data && pdata->sensor->drdy_irq.addr)
                plat_data =
                        (struct st_sensors_platform_data *)&default_press_pdata;
 
        err = st_sensors_init_sensor(indio_dev, plat_data);
        if (err < 0)
-               goto st_press_common_probe_error;
+               return err;
 
-       if (pdata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_press_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_press_common_probe_error;
+       err = st_press_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
 
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev,
-                                                       ST_PRESS_TRIGGER_OPS);
+                                                 ST_PRESS_TRIGGER_OPS);
                if (err < 0)
                        goto st_press_probe_trigger_error;
        }
@@ -256,12 +404,11 @@ int st_press_common_probe(struct iio_dev *indio_dev,
        return err;
 
 st_press_device_register_error:
-       if (pdata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_press_probe_trigger_error:
-       if (pdata->get_irq_data_ready(indio_dev) > 0)
-               st_press_deallocate_ring(indio_dev);
-st_press_common_probe_error:
+       st_press_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_press_common_probe);
@@ -270,11 +417,13 @@ void st_press_common_remove(struct iio_dev *indio_dev)
 {
        struct st_sensor_data *pdata = iio_priv(indio_dev);
 
+       st_press_power_disable(indio_dev);
+
        iio_device_unregister(indio_dev);
-       if (pdata->get_irq_data_ready(indio_dev) > 0) {
+       if (pdata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_press_deallocate_ring(indio_dev);
-       }
+
+       st_press_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_press_common_remove);
 
index 08aac5e6251dd11c770c240a81c38fd82773bc03..51eab7fcb1949894913048980895966792a5c4c9 100644 (file)
@@ -49,6 +49,7 @@ static int st_press_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id st_press_id_table[] = {
+       { LPS001WP_PRESS_DEV_NAME },
        { LPS331AP_PRESS_DEV_NAME },
        {},
 };
index 399a29b6017b25336e9f9bf052d4488b941f28f1..27322af6d665857a52435f139beca6a7689995f0 100644 (file)
@@ -48,6 +48,7 @@ static int st_press_spi_remove(struct spi_device *spi)
 }
 
 static const struct spi_device_id st_press_id_table[] = {
+       { LPS001WP_PRESS_DEV_NAME },
        { LPS331AP_PRESS_DEV_NAME },
        {},
 };
index 6d63883da1ab0e56be798538e1d965b1032eacb7..84a0789c3d96882de6db6c161e62c2feee444bc0 100644 (file)
@@ -70,12 +70,16 @@ static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)
        return i2c_smbus_read_word_swapped(data->client, reg);
 }
 
+static const int tmp006_freqs[5][2] = { {4, 0}, {2, 0}, {1, 0},
+                                       {0, 500000}, {0, 250000} };
+
 static int tmp006_read_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *channel, int *val,
                            int *val2, long mask)
 {
        struct tmp006_data *data = iio_priv(indio_dev);
        s32 ret;
+       int cr;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
@@ -106,6 +110,12 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,
                        break;
                }
                return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               cr = (data->config & TMP006_CONFIG_CR_MASK)
+                       >> TMP006_CONFIG_CR_SHIFT;
+               *val = tmp006_freqs[cr][0];
+               *val2 = tmp006_freqs[cr][1];
+               return IIO_VAL_INT_PLUS_MICRO;
        default:
                break;
        }
@@ -113,48 +123,32 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,
        return -EINVAL;
 }
 
-static const char * const tmp006_freqs[] = { "4", "2", "1", "0.5", "0.25" };
-
-static ssize_t tmp006_show_freq(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       struct tmp006_data *data = iio_priv(dev_to_iio_dev(dev));
-       int cr = (data->config & TMP006_CONFIG_CR_MASK)
-               >> TMP006_CONFIG_CR_SHIFT;
-       return sprintf(buf, "%s\n", tmp006_freqs[cr]);
-}
-
-static ssize_t tmp006_store_freq(struct device *dev,
-                                struct device_attribute *attr,
-                                const char *buf, size_t len)
+static int tmp006_write_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int val,
+                           int val2,
+                           long mask)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tmp006_data *data = iio_priv(indio_dev);
        int i;
-       bool found = false;
 
        for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
-               if (sysfs_streq(buf, tmp006_freqs[i])) {
-                       found = true;
-                       break;
-               }
-       if (!found)
-               return -EINVAL;
+               if ((val == tmp006_freqs[i][0]) &&
+                   (val2 == tmp006_freqs[i][1])) {
+                       data->config &= ~TMP006_CONFIG_CR_MASK;
+                       data->config |= i << TMP006_CONFIG_CR_SHIFT;
 
-       data->config &= ~TMP006_CONFIG_CR_MASK;
-       data->config |= i << TMP006_CONFIG_CR_SHIFT;
+                       return i2c_smbus_write_word_swapped(data->client,
+                                                           TMP006_CONFIG,
+                                                           data->config);
 
-       return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
-               data->config);
+               }
+       return -EINVAL;
 }
 
-static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
-                       tmp006_show_freq, tmp006_store_freq);
-
 static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
 
 static struct attribute *tmp006_attributes[] = {
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        NULL
 };
@@ -168,16 +162,19 @@ static const struct iio_chan_spec tmp006_channels[] = {
                .type = IIO_VOLTAGE,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                        BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
        },
        {
                .type = IIO_TEMP,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                        BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
        }
 };
 
 static const struct iio_info tmp006_info = {
        .read_raw = tmp006_read_raw,
+       .write_raw = tmp006_write_raw,
        .attrs = &tmp006_attribute_group,
        .driver_module = THIS_MODULE,
 };
index effcd0ac98d84021c3ba439555342d660a025ef0..15e3b850f513e9158318bf5ff3ae420cf8a14500 100644 (file)
@@ -23,7 +23,7 @@ struct iio_sysfs_trig {
 };
 
 static LIST_HEAD(iio_sysfs_trig_list);
-static DEFINE_MUTEX(iio_syfs_trig_list_mut);
+static DEFINE_MUTEX(iio_sysfs_trig_list_mut);
 
 static int iio_sysfs_trigger_probe(int id);
 static ssize_t iio_sysfs_trig_add(struct device *dev,
@@ -135,7 +135,7 @@ static int iio_sysfs_trigger_probe(int id)
        struct iio_sysfs_trig *t;
        int ret;
        bool foundit = false;
-       mutex_lock(&iio_syfs_trig_list_mut);
+       mutex_lock(&iio_sysfs_trig_list_mut);
        list_for_each_entry(t, &iio_sysfs_trig_list, l)
                if (id == t->id) {
                        foundit = true;
@@ -169,7 +169,7 @@ static int iio_sysfs_trigger_probe(int id)
                goto out2;
        list_add(&t->l, &iio_sysfs_trig_list);
        __module_get(THIS_MODULE);
-       mutex_unlock(&iio_syfs_trig_list_mut);
+       mutex_unlock(&iio_sysfs_trig_list_mut);
        return 0;
 
 out2:
@@ -177,7 +177,7 @@ out2:
 free_t:
        kfree(t);
 out1:
-       mutex_unlock(&iio_syfs_trig_list_mut);
+       mutex_unlock(&iio_sysfs_trig_list_mut);
        return ret;
 }
 
@@ -185,14 +185,14 @@ static int iio_sysfs_trigger_remove(int id)
 {
        bool foundit = false;
        struct iio_sysfs_trig *t;
-       mutex_lock(&iio_syfs_trig_list_mut);
+       mutex_lock(&iio_sysfs_trig_list_mut);
        list_for_each_entry(t, &iio_sysfs_trig_list, l)
                if (id == t->id) {
                        foundit = true;
                        break;
                }
        if (!foundit) {
-               mutex_unlock(&iio_syfs_trig_list_mut);
+               mutex_unlock(&iio_sysfs_trig_list_mut);
                return -EINVAL;
        }
 
@@ -202,7 +202,7 @@ static int iio_sysfs_trigger_remove(int id)
        list_del(&t->l);
        kfree(t);
        module_put(THIS_MODULE);
-       mutex_unlock(&iio_syfs_trig_list_mut);
+       mutex_unlock(&iio_sysfs_trig_list_mut);
        return 0;
 }
 
index 922a7fea2ce6758f39d5945a74d2953efcc672f5..24c41ba7d4e01dcf852050d3f1d8ef27b5f0a22f 100644 (file)
@@ -422,14 +422,15 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
  * Gameport port operations
  */
 
-static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t gameport_description_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct gameport *gameport = to_gameport_port(dev);
 
        return sprintf(buf, "%s\n", gameport->name);
 }
+static DEVICE_ATTR(description, S_IRUGO, gameport_description_show, NULL);
 
-static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t drvctl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct gameport *gameport = to_gameport_port(dev);
        struct device_driver *drv;
@@ -457,12 +458,14 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut
 
        return error ? error : count;
 }
+static DEVICE_ATTR_WO(drvctl);
 
-static struct device_attribute gameport_device_attrs[] = {
-       __ATTR(description, S_IRUGO, gameport_show_description, NULL),
-       __ATTR(drvctl, S_IWUSR, NULL, gameport_rebind_driver),
-       __ATTR_NULL
+static struct attribute *gameport_device_attrs[] = {
+       &dev_attr_description.attr,
+       &dev_attr_drvctl.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(gameport_device);
 
 static void gameport_release_port(struct device *dev)
 {
@@ -750,7 +753,7 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv)
 
 static struct bus_type gameport_bus = {
        .name           = "gameport",
-       .dev_attrs      = gameport_device_attrs,
+       .dev_groups     = gameport_device_groups,
        .drv_groups     = gameport_driver_groups,
        .match          = gameport_bus_match,
        .probe          = gameport_driver_probe,
index 33b3e88fe4a2312f0047a4a700a2733c9ef81ee4..1de1e5f8f7956dad40a745a08c7d4026f1370e28 100644 (file)
@@ -21,7 +21,7 @@ if SERIO
 config SERIO_I8042
        tristate "i8042 PC Keyboard controller" if EXPERT || !X86
        default y
-       depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \
+       depends on !PARISC && (!ARM || FOOTBRIDGE_HOST) && \
                   (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \
                   !ARC
        help
index 2b56855c2c773d2f47ec0ab57e147a761092b39b..98707fb2cb5d672b6b5bcdc8b787bb37c90c9989 100644 (file)
@@ -365,7 +365,7 @@ static ssize_t serio_show_description(struct device *dev, struct device_attribut
        return sprintf(buf, "%s\n", serio->name);
 }
 
-static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct serio *serio = to_serio_port(dev);
 
@@ -373,54 +373,31 @@ static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *
                        serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
 }
 
-static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct serio *serio = to_serio_port(dev);
        return sprintf(buf, "%02x\n", serio->id.type);
 }
 
-static ssize_t serio_show_id_proto(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t proto_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct serio *serio = to_serio_port(dev);
        return sprintf(buf, "%02x\n", serio->id.proto);
 }
 
-static ssize_t serio_show_id_id(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct serio *serio = to_serio_port(dev);
        return sprintf(buf, "%02x\n", serio->id.id);
 }
 
-static ssize_t serio_show_id_extra(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t extra_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct serio *serio = to_serio_port(dev);
        return sprintf(buf, "%02x\n", serio->id.extra);
 }
 
-static DEVICE_ATTR(type, S_IRUGO, serio_show_id_type, NULL);
-static DEVICE_ATTR(proto, S_IRUGO, serio_show_id_proto, NULL);
-static DEVICE_ATTR(id, S_IRUGO, serio_show_id_id, NULL);
-static DEVICE_ATTR(extra, S_IRUGO, serio_show_id_extra, NULL);
-
-static struct attribute *serio_device_id_attrs[] = {
-       &dev_attr_type.attr,
-       &dev_attr_proto.attr,
-       &dev_attr_id.attr,
-       &dev_attr_extra.attr,
-       NULL
-};
-
-static struct attribute_group serio_id_attr_group = {
-       .name   = "id",
-       .attrs  = serio_device_id_attrs,
-};
-
-static const struct attribute_group *serio_device_attr_groups[] = {
-       &serio_id_attr_group,
-       NULL
-};
-
-static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t drvctl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct serio *serio = to_serio_port(dev);
        struct device_driver *drv;
@@ -474,14 +451,36 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *
        return retval;
 }
 
-static struct device_attribute serio_device_attrs[] = {
-       __ATTR(description, S_IRUGO, serio_show_description, NULL),
-       __ATTR(modalias, S_IRUGO, serio_show_modalias, NULL),
-       __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
-       __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
-       __ATTR_NULL
+static DEVICE_ATTR_RO(type);
+static DEVICE_ATTR_RO(proto);
+static DEVICE_ATTR_RO(id);
+static DEVICE_ATTR_RO(extra);
+static DEVICE_ATTR_RO(modalias);
+static DEVICE_ATTR_WO(drvctl);
+static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
+static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode);
+
+static struct attribute *serio_device_id_attrs[] = {
+       &dev_attr_type.attr,
+       &dev_attr_proto.attr,
+       &dev_attr_id.attr,
+       &dev_attr_extra.attr,
+       &dev_attr_modalias.attr,
+       &dev_attr_description.attr,
+       &dev_attr_drvctl.attr,
+       &dev_attr_bind_mode.attr,
+       NULL
 };
 
+static struct attribute_group serio_id_attr_group = {
+       .name   = "id",
+       .attrs  = serio_device_id_attrs,
+};
+
+static const struct attribute_group *serio_device_attr_groups[] = {
+       &serio_id_attr_group,
+       NULL
+};
 
 static void serio_release_port(struct device *dev)
 {
@@ -996,7 +995,6 @@ EXPORT_SYMBOL(serio_interrupt);
 
 static struct bus_type serio_bus = {
        .name           = "serio",
-       .dev_attrs      = serio_device_attrs,
        .drv_groups     = serio_driver_groups,
        .match          = serio_bus_match,
        .uevent         = serio_uevent,
index e1c5300cacfc2044f83175dccffd864a8bd01fbc..24e625c0b5314217accaee7886f2d05e2652901d 100644 (file)
@@ -52,6 +52,7 @@ struct titsc {
        u32                     config_inp[4];
        u32                     bit_xp, bit_xn, bit_yp, bit_yn;
        u32                     inp_xp, inp_xn, inp_yp, inp_yn;
+       u32                     step_mask;
 };
 
 static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
@@ -196,7 +197,8 @@ static void titsc_step_config(struct titsc *ts_dev)
 
        /* The steps1 â€¦ end and bit 0 for TS_Charge */
        stepenable = (1 << (end_step + 2)) - 1;
-       am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
+       ts_dev->step_mask = stepenable;
+       am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
 }
 
 static void titsc_read_coordinates(struct titsc *ts_dev,
@@ -260,6 +262,10 @@ static irqreturn_t titsc_irq(int irq, void *dev)
        unsigned int fsm;
 
        status = titsc_readl(ts_dev, REG_IRQSTATUS);
+       /*
+        * ADC and touchscreen share the IRQ line.
+        * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only
+        */
        if (status & IRQENB_FIFO0THRES) {
 
                titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
@@ -316,7 +322,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
 
        if (irqclr) {
                titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
-               am335x_tsc_se_update(ts_dev->mfd_tscadc);
+               am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
                return IRQ_HANDLED;
        }
        return IRQ_NONE;
@@ -389,7 +395,7 @@ static int titsc_probe(struct platform_device *pdev)
        }
 
        err = request_irq(ts_dev->irq, titsc_irq,
-                         0, pdev->dev.driver->name, ts_dev);
+                         IRQF_SHARED, pdev->dev.driver->name, ts_dev);
        if (err) {
                dev_err(&pdev->dev, "failed to allocate irq.\n");
                goto err_free_mem;
index 6e066c53acce7fcd0fc5f36193f8b4c05a25ebb5..d0016ba469edeed10c58fd1ce93c5615dc2735c4 100644 (file)
@@ -180,20 +180,28 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 
 ipack_device_attr(id_format, "0x%hhu\n");
 
-static struct device_attribute ipack_dev_attrs[] = {
-       __ATTR_RO(id),
-       __ATTR_RO(id_device),
-       __ATTR_RO(id_format),
-       __ATTR_RO(id_vendor),
-       __ATTR_RO(modalias),
+static DEVICE_ATTR_RO(id);
+static DEVICE_ATTR_RO(id_device);
+static DEVICE_ATTR_RO(id_format);
+static DEVICE_ATTR_RO(id_vendor);
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *ipack_attrs[] = {
+       &dev_attr_id.attr,
+       &dev_attr_id_device.attr,
+       &dev_attr_id_format.attr,
+       &dev_attr_id_vendor.attr,
+       &dev_attr_modalias.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(ipack);
 
 static struct bus_type ipack_bus_type = {
        .name      = "ipack",
        .probe     = ipack_bus_probe,
        .match     = ipack_bus_match,
        .remove    = ipack_bus_remove,
-       .dev_attrs = ipack_dev_attrs,
+       .dev_groups = ipack_groups,
        .uevent    = ipack_uevent,
 };
 
index bb328a366122851b0d28308e13079dfb3ad146d2..433cc8568dec803c78957d12e9bb9b15d7e4ff00 100644 (file)
 #include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/of_pci.h>
 #include <linux/irqdomain.h>
+#include <linux/slab.h>
+#include <linux/msi.h>
 #include <asm/mach/arch.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
 #define IPI_DOORBELL_START                      (0)
 #define IPI_DOORBELL_END                        (8)
 #define IPI_DOORBELL_MASK                       0xFF
+#define PCI_MSI_DOORBELL_START                  (16)
+#define PCI_MSI_DOORBELL_NR                     (16)
+#define PCI_MSI_DOORBELL_END                    (32)
+#define PCI_MSI_DOORBELL_MASK                   0xFFFF0000
 
 static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 
 static void __iomem *per_cpu_int_base;
 static void __iomem *main_int_base;
 static struct irq_domain *armada_370_xp_mpic_domain;
+#ifdef CONFIG_PCI_MSI
+static struct irq_domain *armada_370_xp_msi_domain;
+static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
+static DEFINE_MUTEX(msi_used_lock);
+static phys_addr_t msi_doorbell_addr;
+#endif
 
 /*
  * In SMP mode:
@@ -87,6 +100,144 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
                                ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
 }
 
+#ifdef CONFIG_PCI_MSI
+
+static int armada_370_xp_alloc_msi(void)
+{
+       int hwirq;
+
+       mutex_lock(&msi_used_lock);
+       hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR);
+       if (hwirq >= PCI_MSI_DOORBELL_NR)
+               hwirq = -ENOSPC;
+       else
+               set_bit(hwirq, msi_used);
+       mutex_unlock(&msi_used_lock);
+
+       return hwirq;
+}
+
+static void armada_370_xp_free_msi(int hwirq)
+{
+       mutex_lock(&msi_used_lock);
+       if (!test_bit(hwirq, msi_used))
+               pr_err("trying to free unused MSI#%d\n", hwirq);
+       else
+               clear_bit(hwirq, msi_used);
+       mutex_unlock(&msi_used_lock);
+}
+
+static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
+                                      struct pci_dev *pdev,
+                                      struct msi_desc *desc)
+{
+       struct msi_msg msg;
+       irq_hw_number_t hwirq;
+       int virq;
+
+       hwirq = armada_370_xp_alloc_msi();
+       if (hwirq < 0)
+               return hwirq;
+
+       virq = irq_create_mapping(armada_370_xp_msi_domain, hwirq);
+       if (!virq) {
+               armada_370_xp_free_msi(hwirq);
+               return -EINVAL;
+       }
+
+       irq_set_msi_desc(virq, desc);
+
+       msg.address_lo = msi_doorbell_addr;
+       msg.address_hi = 0;
+       msg.data = 0xf00 | (hwirq + 16);
+
+       write_msi_msg(virq, &msg);
+       return 0;
+}
+
+static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
+                                          unsigned int irq)
+{
+       struct irq_data *d = irq_get_irq_data(irq);
+       irq_dispose_mapping(irq);
+       armada_370_xp_free_msi(d->hwirq);
+}
+
+static struct irq_chip armada_370_xp_msi_irq_chip = {
+       .name = "armada_370_xp_msi_irq",
+       .irq_enable = unmask_msi_irq,
+       .irq_disable = mask_msi_irq,
+       .irq_mask = mask_msi_irq,
+       .irq_unmask = unmask_msi_irq,
+};
+
+static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
+                                irq_hw_number_t hw)
+{
+       irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip,
+                                handle_simple_irq);
+       set_irq_flags(virq, IRQF_VALID);
+
+       return 0;
+}
+
+static const struct irq_domain_ops armada_370_xp_msi_irq_ops = {
+       .map = armada_370_xp_msi_map,
+};
+
+static int armada_370_xp_msi_init(struct device_node *node,
+                                 phys_addr_t main_int_phys_base)
+{
+       struct msi_chip *msi_chip;
+       u32 reg;
+       int ret;
+
+       msi_doorbell_addr = main_int_phys_base +
+               ARMADA_370_XP_SW_TRIG_INT_OFFS;
+
+       msi_chip = kzalloc(sizeof(*msi_chip), GFP_KERNEL);
+       if (!msi_chip)
+               return -ENOMEM;
+
+       msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
+       msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
+       msi_chip->of_node = node;
+
+       armada_370_xp_msi_domain =
+               irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR,
+                                     &armada_370_xp_msi_irq_ops,
+                                     NULL);
+       if (!armada_370_xp_msi_domain) {
+               kfree(msi_chip);
+               return -ENOMEM;
+       }
+
+       ret = of_pci_msi_chip_add(msi_chip);
+       if (ret < 0) {
+               irq_domain_remove(armada_370_xp_msi_domain);
+               kfree(msi_chip);
+               return ret;
+       }
+
+       reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS)
+               | PCI_MSI_DOORBELL_MASK;
+
+       writel(reg, per_cpu_int_base +
+              ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
+
+       /* Unmask IPI interrupt */
+       writel(1, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
+
+       return 0;
+}
+#else
+static inline int armada_370_xp_msi_init(struct device_node *node,
+                                        phys_addr_t main_int_phys_base)
+{
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_SMP
 static int armada_xp_set_affinity(struct irq_data *d,
                                  const struct cpumask *mask_val, bool force)
@@ -214,12 +365,39 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
                if (irqnr > 1022)
                        break;
 
-               if (irqnr > 0) {
+               if (irqnr > 1) {
                        irqnr = irq_find_mapping(armada_370_xp_mpic_domain,
                                        irqnr);
                        handle_IRQ(irqnr, regs);
                        continue;
                }
+
+#ifdef CONFIG_PCI_MSI
+               /* MSI handling */
+               if (irqnr == 1) {
+                       u32 msimask, msinr;
+
+                       msimask = readl_relaxed(per_cpu_int_base +
+                                               ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
+                               & PCI_MSI_DOORBELL_MASK;
+
+                       writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base +
+                              ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
+
+                       for (msinr = PCI_MSI_DOORBELL_START;
+                            msinr < PCI_MSI_DOORBELL_END; msinr++) {
+                               int irq;
+
+                               if (!(msimask & BIT(msinr)))
+                                       continue;
+
+                               irq = irq_find_mapping(armada_370_xp_msi_domain,
+                                                      msinr - 16);
+                               handle_IRQ(irq, regs);
+                       }
+               }
+#endif
+
 #ifdef CONFIG_SMP
                /* IPI Handling */
                if (irqnr == 0) {
@@ -248,12 +426,25 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
 static int __init armada_370_xp_mpic_of_init(struct device_node *node,
                                             struct device_node *parent)
 {
+       struct resource main_int_res, per_cpu_int_res;
        u32 control;
 
-       main_int_base = of_iomap(node, 0);
-       per_cpu_int_base = of_iomap(node, 1);
+       BUG_ON(of_address_to_resource(node, 0, &main_int_res));
+       BUG_ON(of_address_to_resource(node, 1, &per_cpu_int_res));
+
+       BUG_ON(!request_mem_region(main_int_res.start,
+                                  resource_size(&main_int_res),
+                                  node->full_name));
+       BUG_ON(!request_mem_region(per_cpu_int_res.start,
+                                  resource_size(&per_cpu_int_res),
+                                  node->full_name));
 
+       main_int_base = ioremap(main_int_res.start,
+                               resource_size(&main_int_res));
        BUG_ON(!main_int_base);
+
+       per_cpu_int_base = ioremap(per_cpu_int_res.start,
+                                  resource_size(&per_cpu_int_res));
        BUG_ON(!per_cpu_int_base);
 
        control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
@@ -262,8 +453,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
                irq_domain_add_linear(node, (control >> 2) & 0x3ff,
                                &armada_370_xp_mpic_irq_ops, NULL);
 
-       if (!armada_370_xp_mpic_domain)
-               panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
+       BUG_ON(!armada_370_xp_mpic_domain);
 
        irq_set_default_host(armada_370_xp_mpic_domain);
 
@@ -280,6 +470,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
 
 #endif
 
+       armada_370_xp_msi_init(node, main_int_res.start);
+
        set_handle_irq(armada_370_xp_handle_irq);
 
        return 0;
index 16c78f1c5ef25ad4121b1ee7e2b7fab30cedce95..1693b8e7f26ad83c9686af3af7273e41c5e4af04 100644 (file)
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/irqdomain.h>
-#include <linux/irqchip/bcm2835.h>
 
 #include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#include "irqchip.h"
 
 /* Put the bank and irq (32 bits) into the hwirq */
 #define MAKE_HWIRQ(b, n)       ((b << 5) | (n))
@@ -93,6 +95,8 @@ struct armctrl_ic {
 };
 
 static struct armctrl_ic intc __read_mostly;
+static asmlinkage void __exception_irq_entry bcm2835_handle_irq(
+       struct pt_regs *regs);
 
 static void armctrl_mask_irq(struct irq_data *d)
 {
@@ -164,17 +168,9 @@ static int __init armctrl_of_init(struct device_node *node,
                        set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
                }
        }
-       return 0;
-}
-
-static struct of_device_id irq_of_match[] __initconst = {
-       { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init },
-       { }
-};
 
-void __init bcm2835_init_irq(void)
-{
-       of_irq_init(irq_of_match);
+       set_handle_irq(bcm2835_handle_irq);
+       return 0;
 }
 
 /*
@@ -200,7 +196,7 @@ static void armctrl_handle_shortcut(int bank, struct pt_regs *regs,
        handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
 }
 
-asmlinkage void __exception_irq_entry bcm2835_handle_irq(
+static asmlinkage void __exception_irq_entry bcm2835_handle_irq(
        struct pt_regs *regs)
 {
        u32 stat, irq;
@@ -222,3 +218,5 @@ asmlinkage void __exception_irq_entry bcm2835_handle_irq(
                }
        }
 }
+
+IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic", armctrl_of_init);
index 2bbb00404cf5001df2c6f8654de6d467d58f3b6d..8e21ae0bab4658a2ee2beb15a07a7a396411261f 100644 (file)
@@ -469,6 +469,8 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
 int __init vic_of_init(struct device_node *node, struct device_node *parent)
 {
        void __iomem *regs;
+       u32 interrupt_mask = ~0;
+       u32 wakeup_mask = ~0;
 
        if (WARN(parent, "non-root VICs are not supported"))
                return -EINVAL;
@@ -477,10 +479,13 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
        if (WARN_ON(!regs))
                return -EIO;
 
+       of_property_read_u32(node, "valid-mask", &interrupt_mask);
+       of_property_read_u32(node, "valid-wakeup-mask", &wakeup_mask);
+
        /*
         * Passing 0 as first IRQ makes the simple domain allocate descriptors
         */
-       __vic_init(regs, 0, ~0, ~0, node);
+       __vic_init(regs, 0, interrupt_mask, wakeup_mask, node);
 
        return 0;
 }
index a7fd82133b12b18139e57c50d382b094d88951c4..12dc29ba7399c8188da2b0ddffcf659eb46115f7 100644 (file)
@@ -1654,9 +1654,9 @@ int bitmap_create(struct mddev *mddev)
        bitmap->mddev = mddev;
 
        if (mddev->kobj.sd)
-               bm = sysfs_get_dirent(mddev->kobj.sd, NULL, "bitmap");
+               bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap");
        if (bm) {
-               bitmap->sysfs_can_clear = sysfs_get_dirent(bm, NULL, "can_clear");
+               bitmap->sysfs_can_clear = sysfs_get_dirent(bm, "can_clear");
                sysfs_put(bm);
        } else
                bitmap->sysfs_can_clear = NULL;
index 561a65f82e26af05c8210f94b49367b6fa51e55b..2445fece926339bf7a4566ffefd40a9d792eba07 100644 (file)
@@ -3555,7 +3555,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
                        printk(KERN_WARNING
                               "md: cannot register extra attributes for %s\n",
                               mdname(mddev));
-               mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, NULL, "sync_action");
+               mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action");
        }               
        if (mddev->pers->sync_request != NULL &&
            pers->sync_request == NULL) {
index 608050c43f17e9d7688a9b3d1b749b7971d47c33..b0051f2fbc0c84b735a711679c9835fc15d3b27b 100644 (file)
@@ -501,7 +501,7 @@ extern struct attribute_group md_bitmap_group;
 static inline struct sysfs_dirent *sysfs_get_dirent_safe(struct sysfs_dirent *sd, char *name)
 {
        if (sd)
-               return sysfs_get_dirent(sd, NULL, name);
+               return sysfs_get_dirent(sd, name);
        return sd;
 }
 static inline void sysfs_notify_dirent_safe(struct sysfs_dirent *sd)
index c7caf94621b418b351f19c040267c98754e4a924..eb70dda8cbf362c83ab53503eec1948ea5f36004 100644 (file)
@@ -112,7 +112,7 @@ config VIDEO_OMAP3_DEBUG
 config VIDEO_S3C_CAMIF
        tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver"
        depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
-       depends on (PLAT_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME
+       depends on (ARCH_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME
        select VIDEOBUF2_DMA_CONTIG
        ---help---
          This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera
index 53ad0f080179721dd97c333a051ce034d948e857..d2d3b4b614359e239a540198451fd55b81339353 100644 (file)
@@ -29,7 +29,7 @@ config VIDEO_S5P_FIMC
 config VIDEO_S5P_MIPI_CSIS
        tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
        depends on REGULATOR
-       select S5P_SETUP_MIPIPHY
+       select GENERIC_PHY
        help
          This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
          receiver (MIPI-CSIS) devices.
index 0914230b42de55ea531d63cc10bce844d1282ed3..9fc2af6a04466b402c6f931097e28dbdec2ad29c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/memory.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_data/mipi-csis.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -180,6 +181,7 @@ struct csis_drvdata {
  * @sd: v4l2_subdev associated with CSIS device instance
  * @index: the hardware instance index
  * @pdev: CSIS platform device
+ * @phy: pointer to the CSIS generic PHY
  * @regs: mmaped I/O registers memory
  * @supplies: CSIS regulator supplies
  * @clock: CSIS clocks
@@ -203,6 +205,7 @@ struct csis_state {
        struct v4l2_subdev sd;
        u8 index;
        struct platform_device *pdev;
+       struct phy *phy;
        void __iomem *regs;
        struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
        struct clk *clock[NUM_CSIS_CLOCKS];
@@ -779,8 +782,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
                                        "samsung,csis-wclk");
 
        state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
-
        of_node_put(node);
+
        return 0;
 }
 #else
@@ -829,6 +832,10 @@ static int s5pcsis_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       state->phy = devm_phy_get(dev, "csis");
+       if (IS_ERR(state->phy))
+               return PTR_ERR(state->phy);
+
        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        state->regs = devm_ioremap_resource(dev, mem_res);
        if (IS_ERR(state->regs))
@@ -922,7 +929,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
        mutex_lock(&state->lock);
        if (state->flags & ST_POWERED) {
                s5pcsis_stop_stream(state);
-               ret = s5p_csis_phy_enable(state->index, false);
+               ret = phy_power_off(state->phy);
                if (ret)
                        goto unlock;
                ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
@@ -958,7 +965,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
                                            state->supplies);
                if (ret)
                        goto unlock;
-               ret = s5p_csis_phy_enable(state->index, true);
+               ret = phy_power_on(state->phy);
                if (!ret) {
                        state->flags |= ST_POWERED;
                } else {
index ffcb10ac434156adc89e4e9237d30e4ade530830..bbf4aea1627d389339526a5451b3ac1fc7e4815a 100644 (file)
@@ -153,24 +153,24 @@ static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
        struct memstick_dev *card = container_of(dev, struct memstick_dev,    \
                                                 dev);                        \
        return sprintf(buf, format, card->id.name);                           \
-}
+}                                                                             \
+static DEVICE_ATTR_RO(name);
 
 MEMSTICK_ATTR(type, "%02X");
 MEMSTICK_ATTR(category, "%02X");
 MEMSTICK_ATTR(class, "%02X");
 
-#define MEMSTICK_ATTR_RO(name) __ATTR(name, S_IRUGO, name##_show, NULL)
-
-static struct device_attribute memstick_dev_attrs[] = {
-       MEMSTICK_ATTR_RO(type),
-       MEMSTICK_ATTR_RO(category),
-       MEMSTICK_ATTR_RO(class),
-       __ATTR_NULL
+static struct attribute *memstick_dev_attrs[] = {
+       &dev_attr_type.attr,
+       &dev_attr_category.attr,
+       &dev_attr_class.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(memstick_dev);
 
 static struct bus_type memstick_bus_type = {
        .name           = "memstick",
-       .dev_attrs      = memstick_dev_attrs,
+       .dev_groups     = memstick_dev_groups,
        .match          = memstick_bus_match,
        .uevent         = memstick_uevent,
        .probe          = memstick_device_probe,
index cbe384fb848c97078d609a751d34a8d0f627cfa7..91614f11f89a38d719b6091b9c7b8654557df3bc 100644 (file)
@@ -33,7 +33,7 @@ extern int __init i2o_pci_init(void);
 extern void __exit i2o_pci_exit(void);
 
 /* device */
-extern struct device_attribute i2o_device_attrs[];
+extern const struct attribute_group *i2o_device_groups[];
 
 extern void i2o_device_remove(struct i2o_device *);
 extern int i2o_device_parse_lct(struct i2o_controller *);
index 4547db99f7da7d6e321894419a15f5ec3c6413b8..98348f420b52b9aae3dee2c274122739fc5ef931 100644 (file)
@@ -138,45 +138,55 @@ static void i2o_device_release(struct device *dev)
 }
 
 /**
- *     i2o_device_show_class_id - Displays class id of I2O device
+ *     class_id_show - Displays class id of I2O device
  *     @dev: device of which the class id should be displayed
  *     @attr: pointer to device attribute
  *     @buf: buffer into which the class id should be printed
  *
  *     Returns the number of bytes which are printed into the buffer.
  */
-static ssize_t i2o_device_show_class_id(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
+static ssize_t class_id_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
 {
        struct i2o_device *i2o_dev = to_i2o_device(dev);
 
        sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
        return strlen(buf) + 1;
 }
+static DEVICE_ATTR_RO(class_id);
 
 /**
- *     i2o_device_show_tid - Displays TID of I2O device
+ *     tid_show - Displays TID of I2O device
  *     @dev: device of which the TID should be displayed
  *     @attr: pointer to device attribute
  *     @buf: buffer into which the TID should be printed
  *
  *     Returns the number of bytes which are printed into the buffer.
  */
-static ssize_t i2o_device_show_tid(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
+static ssize_t tid_show(struct device *dev, struct device_attribute *attr,
+                       char *buf)
 {
        struct i2o_device *i2o_dev = to_i2o_device(dev);
 
        sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
        return strlen(buf) + 1;
 }
+static DEVICE_ATTR_RO(tid);
 
 /* I2O device attributes */
-struct device_attribute i2o_device_attrs[] = {
-       __ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
-       __ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
-       __ATTR_NULL
+static struct attribute *i2o_device_attrs[] = {
+       &dev_attr_class_id.attr,
+       &dev_attr_tid.attr,
+       NULL,
+};
+
+static const struct attribute_group i2o_device_group = {
+       .attrs = i2o_device_attrs,
+};
+
+const struct attribute_group *i2o_device_groups[] = {
+       &i2o_device_group,
+       NULL,
 };
 
 /**
index 813eaa33fa1431af96a2c2f3ac40b1000dd9ed7b..b6b92d760510be0f5cd92009a616fbccc9ce088d 100644 (file)
@@ -62,7 +62,7 @@ static int i2o_bus_match(struct device *dev, struct device_driver *drv)
 struct bus_type i2o_bus_type = {
        .name = "i2o",
        .match = i2o_bus_match,
-       .dev_attrs = i2o_device_attrs
+       .dev_groups = i2o_device_groups,
 };
 
 /**
index 53f371dcbb6e96550537b108fffbba1c00af3015..b9ce60c301de026bba38daf276e83773c44379ec 100644 (file)
@@ -480,7 +480,6 @@ static struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
        CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true),
        CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true),
        CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true),
-       CLK_MGT_ENTRY(BML8580CLK, PLL_DIV, true),
        CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true),
        CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true),
        CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true),
index 4f6f0fa5d3b7768d4265b632f4e1620be22c347b..7cc32a8ff01c01b06e8d29ae44134253d81828ba 100644 (file)
@@ -32,7 +32,6 @@
 #define PRCM_PER7CLK_MGT       (0x040)
 #define PRCM_LCDCLK_MGT                (0x044)
 #define PRCM_BMLCLK_MGT                (0x04C)
-#define PRCM_BML8580CLK_MGT    (0x108)
 #define PRCM_HSITXCLK_MGT      (0x050)
 #define PRCM_HSIRXCLK_MGT      (0x054)
 #define PRCM_HDMICLK_MGT       (0x058)
index 8dacd4c9ee8745f6449aaff8f6e9c03a4dd20341..e760715bd9cbd30c01c6c16da430c06931fb04c1 100644 (file)
@@ -537,4 +537,5 @@ source "drivers/misc/carma/Kconfig"
 source "drivers/misc/altera-stapl/Kconfig"
 source "drivers/misc/mei/Kconfig"
 source "drivers/misc/vmw_vmci/Kconfig"
+source "drivers/misc/mic/Kconfig"
 endmenu
index c235d5b683111534a39996b75d8832f063ea0ae9..0b7ea3ea8bb86cc3971c7af15258c285100bd8e1 100644 (file)
@@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI)               += mei/
 obj-$(CONFIG_VMWARE_VMCI)      += vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)      += lattice-ecp3-config.o
 obj-$(CONFIG_SRAM)             += sram.o
+obj-y                          += mic/
index 1256a4bf1c04aca6465bcdde05158ade90c7881e..b7ebf8021d99d8c392d6f58961a7e3524f2d71ba 100644 (file)
@@ -297,7 +297,7 @@ static int __init charlcd_probe(struct platform_device *pdev)
        lcd->irq = platform_get_irq(pdev, 0);
        /* If no IRQ is supplied, we'll survive without it */
        if (lcd->irq >= 0) {
-               if (request_irq(lcd->irq, charlcd_interrupt, IRQF_DISABLED,
+               if (request_irq(lcd->irq, charlcd_interrupt, 0,
                                DRIVERNAME, lcd)) {
                        ret = -EIO;
                        goto out_no_irq;
index 494d0500bda6483a9f3d93f6287075d5f0825448..a6dc56e1bc58e70566bd6321bca1ae1191519b3b 100644 (file)
@@ -90,8 +90,10 @@ int pwm_channel_alloc(int index, struct pwm_channel *ch)
        unsigned long   flags;
        int             status = 0;
 
-       /* insist on PWM init, with this signal pinned out */
-       if (!pwm || !(pwm->mask & 1 << index))
+       if (!pwm)
+               return -EPROBE_DEFER;
+
+       if (!(pwm->mask & 1 << index))
                return -ENODEV;
 
        if (index < 0 || index >= PWM_NCHAN || !ch)
index 057580e026c056f7b6ff576d51fbe225db0efd47..48ea33d15a79eca71bce4c7f3c986d7609880304 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/of.h>
 
 #define BH1780_REG_CONTROL     0x80
 #define BH1780_REG_PARTID      0x8A
@@ -244,6 +245,15 @@ static const struct i2c_device_id bh1780_id[] = {
        { },
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_bh1780_match[] = {
+       { .compatible = "rohm,bh1780gli", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, of_bh1780_match);
+#endif
+
 static struct i2c_driver bh1780_driver = {
        .probe          = bh1780_probe,
        .remove         = bh1780_remove,
@@ -251,6 +261,7 @@ static struct i2c_driver bh1780_driver = {
        .driver = {
                .name = "bh1780",
                .pm     = &bh1780_pm,
+               .of_match_table = of_match_ptr(of_bh1780_match),
        },
 };
 
index 849e2fed4da2841310ee9a5cd80430cb29f6d950..2704d885a9b30517cea14c91fda89d5e6748a64e 100644 (file)
@@ -374,7 +374,7 @@ int bmp085_detect(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(bmp085_detect);
 
-static void __init bmp085_get_of_properties(struct bmp085_data *data)
+static void bmp085_get_of_properties(struct bmp085_data *data)
 {
 #ifdef CONFIG_OF
        struct device_node *np = data->dev->of_node;
index 2e50f811ff599205aade6f1b877bc7877e3917bb..fb397e7d1cce8a17ab2583c2bedc49438d72b03b 100644 (file)
@@ -176,7 +176,7 @@ static int cb710_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct cb710_chip *chip = pci_get_drvdata(pdev);
 
-       free_irq(pdev->irq, chip);
+       devm_free_irq(&pdev->dev, pdev->irq, chip);
        pci_save_state(pdev);
        pci_disable_device(pdev);
        if (state.event & PM_EVENT_SLEEP)
index 04f2e1fa9dd15b10871919a788c81aff782178f8..9536852fd4c68e28673b6325737fdf1cd82df5c1 100644 (file)
@@ -96,4 +96,17 @@ config EEPROM_DIGSY_MTC_CFG
 
          If unsure, say N.
 
+config EEPROM_SUNXI_SID
+       tristate "Allwinner sunxi security ID support"
+       depends on ARCH_SUNXI && SYSFS
+       help
+         This is a driver for the 'security ID' available on various Allwinner
+         devices.
+
+         Due to the potential risks involved with changing e-fuses,
+         this driver is read-only.
+
+         This driver can also be built as a module. If so, the module
+         will be called sunxi_sid.
+
 endmenu
index fc1e81d292673b14732e9268b7cb9cdca9d921fb..9507aec95e948f88f31579585e60b8632c0b3782 100644 (file)
@@ -4,4 +4,5 @@ obj-$(CONFIG_EEPROM_LEGACY)     += eeprom.o
 obj-$(CONFIG_EEPROM_MAX6875)   += max6875.o
 obj-$(CONFIG_EEPROM_93CX6)     += eeprom_93cx6.o
 obj-$(CONFIG_EEPROM_93XX46)    += eeprom_93xx46.o
+obj-$(CONFIG_EEPROM_SUNXI_SID) += sunxi_sid.o
 obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o
index 5d4fd69d04ca05f1b189e458fdbacd4e54e3a0b7..94b8a33243192d4217c54442424bc91e1dbd936c 100644 (file)
@@ -428,6 +428,9 @@ static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj,
 {
        struct at24_data *at24;
 
+       if (unlikely(off >= attr->size))
+               return -EFBIG;
+
        at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
        return at24_write(at24, buf, off, count);
 }
index 840b3594a5ae3c852b1e643a9f4b7e167033ad4f..4f3bca1003a175d2eb0ea7fdf423cd8dfa70e14d 100644 (file)
@@ -462,10 +462,17 @@ static int at25_remove(struct spi_device *spi)
 
 /*-------------------------------------------------------------------------*/
 
+static const struct of_device_id at25_of_match[] = {
+       { .compatible = "atmel,at25", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, at25_of_match);
+
 static struct spi_driver at25_driver = {
        .driver = {
                .name           = "at25",
                .owner          = THIS_MODULE,
+               .of_match_table = at25_of_match,
        },
        .probe          = at25_probe,
        .remove         = at25_remove,
index 94cfc121257710459b98a5088d1820d618080e10..3a015abb444a826baecef6c6596f6a5c58adb648 100644 (file)
@@ -202,7 +202,7 @@ eeprom_93xx46_bin_write(struct file *filp, struct kobject *kobj,
        edev = dev_get_drvdata(dev);
 
        if (unlikely(off >= edev->bin.size))
-               return 0;
+               return -EFBIG;
        if ((off + count) > edev->bin.size)
                count = edev->bin.size - off;
        if (unlikely(!count))
diff --git a/drivers/misc/eeprom/sunxi_sid.c b/drivers/misc/eeprom/sunxi_sid.c
new file mode 100644 (file)
index 0000000..9c34e57
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://www.linux-sunxi.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.
+ *
+ * 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 exposes the Allwinner security ID, efuses exported in byte-
+ * sized chunks.
+ */
+
+#include <linux/compiler.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#define DRV_NAME "sunxi-sid"
+
+struct sunxi_sid_data {
+       void __iomem *reg_base;
+       unsigned int keysize;
+};
+
+/* We read the entire key, due to a 32 bit read alignment requirement. Since we
+ * want to return the requested byte, this results in somewhat slower code and
+ * uses 4 times more reads as needed but keeps code simpler. Since the SID is
+ * only very rarely probed, this is not really an issue.
+ */
+static u8 sunxi_sid_read_byte(const struct sunxi_sid_data *sid_data,
+                             const unsigned int offset)
+{
+       u32 sid_key;
+
+       if (offset >= sid_data->keysize)
+               return 0;
+
+       sid_key = ioread32be(sid_data->reg_base + round_down(offset, 4));
+       sid_key >>= (offset % 4) * 8;
+
+       return sid_key; /* Only return the last byte */
+}
+
+static ssize_t sid_read(struct file *fd, struct kobject *kobj,
+                       struct bin_attribute *attr, char *buf,
+                       loff_t pos, size_t size)
+{
+       struct platform_device *pdev;
+       struct sunxi_sid_data *sid_data;
+       int i;
+
+       pdev = to_platform_device(kobj_to_dev(kobj));
+       sid_data = platform_get_drvdata(pdev);
+
+       if (pos < 0 || pos >= sid_data->keysize)
+               return 0;
+       if (size > sid_data->keysize - pos)
+               size = sid_data->keysize - pos;
+
+       for (i = 0; i < size; i++)
+               buf[i] = sunxi_sid_read_byte(sid_data, pos + i);
+
+       return i;
+}
+
+static struct bin_attribute sid_bin_attr = {
+       .attr = { .name = "eeprom", .mode = S_IRUGO, },
+       .read = sid_read,
+};
+
+static int sunxi_sid_remove(struct platform_device *pdev)
+{
+       device_remove_bin_file(&pdev->dev, &sid_bin_attr);
+       dev_dbg(&pdev->dev, "driver unloaded\n");
+
+       return 0;
+}
+
+static const struct of_device_id sunxi_sid_of_match[] = {
+       { .compatible = "allwinner,sun4i-sid", .data = (void *)16},
+       { .compatible = "allwinner,sun7i-a20-sid", .data = (void *)512},
+       {/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
+
+static int sunxi_sid_probe(struct platform_device *pdev)
+{
+       struct sunxi_sid_data *sid_data;
+       struct resource *res;
+       const struct of_device_id *of_dev_id;
+       u8 *entropy;
+       unsigned int i;
+
+       sid_data = devm_kzalloc(&pdev->dev, sizeof(struct sunxi_sid_data),
+                               GFP_KERNEL);
+       if (!sid_data)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       sid_data->reg_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(sid_data->reg_base))
+               return PTR_ERR(sid_data->reg_base);
+
+       of_dev_id = of_match_device(sunxi_sid_of_match, &pdev->dev);
+       if (!of_dev_id)
+               return -ENODEV;
+       sid_data->keysize = (int)of_dev_id->data;
+
+       platform_set_drvdata(pdev, sid_data);
+
+       sid_bin_attr.size = sid_data->keysize;
+       if (device_create_bin_file(&pdev->dev, &sid_bin_attr))
+               return -ENODEV;
+
+       entropy = kzalloc(sizeof(u8) * sid_data->keysize, GFP_KERNEL);
+       for (i = 0; i < sid_data->keysize; i++)
+               entropy[i] = sunxi_sid_read_byte(sid_data, i);
+       add_device_randomness(entropy, sid_data->keysize);
+       kfree(entropy);
+
+       dev_dbg(&pdev->dev, "loaded\n");
+
+       return 0;
+}
+
+static struct platform_driver sunxi_sid_driver = {
+       .probe = sunxi_sid_probe,
+       .remove = sunxi_sid_remove,
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = sunxi_sid_of_match,
+       },
+};
+module_platform_driver(sunxi_sid_driver);
+
+MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>");
+MODULE_DESCRIPTION("Allwinner sunxi security id driver");
+MODULE_LICENSE("GPL");
index 0346d87c5fed9f20fffa622269b4102bbdeb516f..6b3bf9ab051db1e5e0c1ef15dec4bbd50906da42 100644 (file)
@@ -153,7 +153,6 @@ error_ioremap:
 error_heartbeat:
        ibmasm_event_buffer_exit(sp);
 error_eventbuffer:
-       pci_set_drvdata(pdev, NULL);
        kfree(sp);
 error_kmalloc:
         pci_release_regions(pdev);
@@ -165,7 +164,7 @@ error_resources:
 
 static void ibmasm_remove_one(struct pci_dev *pdev)
 {
-       struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
+       struct service_processor *sp = pci_get_drvdata(pdev);
 
        dbg("Unregistering UART\n");
        ibmasm_unregister_uart(sp);
@@ -182,7 +181,6 @@ static void ibmasm_remove_one(struct pci_dev *pdev)
        ibmasm_free_remote_input_dev(sp);
        iounmap(sp->base_address);
        ibmasm_event_buffer_exit(sp);
-       pci_set_drvdata(pdev, NULL);
        kfree(sp);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
index 2fc0586ce3bb772b7f3100e983ecdd21b43f08bd..a2edb2ee0921657e188b89311673793bb2aa5fff 100644 (file)
 #include <scsi/scsi_cmnd.h>
 #include <linux/debugfs.h>
 #include <linux/vmalloc.h>
+#include <linux/mman.h>
 
 #ifdef CONFIG_IDE
 #include <linux/ide.h>
 #endif
 
+/*
+ * Make sure our attempts to over run the kernel stack doesn't trigger
+ * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
+ * recurse past the end of THREAD_SIZE by default.
+ */
+#if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0)
+#define REC_STACK_SIZE (CONFIG_FRAME_WARN / 2)
+#else
+#define REC_STACK_SIZE (THREAD_SIZE / 8)
+#endif
+#define REC_NUM_DEFAULT ((THREAD_SIZE / REC_STACK_SIZE) * 2)
+
 #define DEFAULT_COUNT 10
-#define REC_NUM_DEFAULT 10
 #define EXEC_SIZE 64
 
 enum cname {
@@ -86,6 +98,9 @@ enum ctype {
        CT_EXEC_STACK,
        CT_EXEC_KMALLOC,
        CT_EXEC_VMALLOC,
+       CT_EXEC_USERSPACE,
+       CT_ACCESS_USERSPACE,
+       CT_WRITE_RO,
 };
 
 static char* cp_name[] = {
@@ -119,6 +134,9 @@ static char* cp_type[] = {
        "EXEC_STACK",
        "EXEC_KMALLOC",
        "EXEC_VMALLOC",
+       "EXEC_USERSPACE",
+       "ACCESS_USERSPACE",
+       "WRITE_RO",
 };
 
 static struct jprobe lkdtm;
@@ -139,9 +157,10 @@ static DEFINE_SPINLOCK(lock_me_up);
 
 static u8 data_area[EXEC_SIZE];
 
+static const unsigned long rodata = 0xAA55AA55;
+
 module_param(recur_count, int, 0644);
-MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
-                                "default is 10");
+MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test");
 module_param(cpoint_name, charp, 0444);
 MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
 module_param(cpoint_type, charp, 0444);
@@ -280,16 +299,16 @@ static int lkdtm_parse_commandline(void)
        return -EINVAL;
 }
 
-static int recursive_loop(int a)
+static int recursive_loop(int remaining)
 {
-       char buf[1024];
+       char buf[REC_STACK_SIZE];
 
-       memset(buf,0xFF,1024);
-       recur_count--;
-       if (!recur_count)
+       /* Make sure compiler does not optimize this away. */
+       memset(buf, (remaining & 0xff) | 0x1, REC_STACK_SIZE);
+       if (!remaining)
                return 0;
        else
-               return recursive_loop(a);
+               return recursive_loop(remaining - 1);
 }
 
 static void do_nothing(void)
@@ -297,6 +316,14 @@ static void do_nothing(void)
        return;
 }
 
+static noinline void corrupt_stack(void)
+{
+       /* Use default char array length that triggers stack protection. */
+       char data[8];
+
+       memset((void *)data, 0, 64);
+}
+
 static void execute_location(void *dst)
 {
        void (*func)(void) = dst;
@@ -305,6 +332,15 @@ static void execute_location(void *dst)
        func();
 }
 
+static void execute_user_location(void *dst)
+{
+       void (*func)(void) = dst;
+
+       if (copy_to_user(dst, do_nothing, EXEC_SIZE))
+               return;
+       func();
+}
+
 static void lkdtm_do_action(enum ctype which)
 {
        switch (which) {
@@ -325,15 +361,11 @@ static void lkdtm_do_action(enum ctype which)
                        ;
                break;
        case CT_OVERFLOW:
-               (void) recursive_loop(0);
+               (void) recursive_loop(recur_count);
                break;
-       case CT_CORRUPT_STACK: {
-               /* Make sure the compiler creates and uses an 8 char array. */
-               volatile char data[8];
-
-               memset((void *)data, 0, 64);
+       case CT_CORRUPT_STACK:
+               corrupt_stack();
                break;
-       }
        case CT_UNALIGNED_LOAD_STORE_WRITE: {
                static u8 data[5] __attribute__((aligned(4))) = {1, 2,
                                3, 4, 5};
@@ -401,6 +433,49 @@ static void lkdtm_do_action(enum ctype which)
                vfree(vmalloc_area);
                break;
        }
+       case CT_EXEC_USERSPACE: {
+               unsigned long user_addr;
+
+               user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
+                                   PROT_READ | PROT_WRITE | PROT_EXEC,
+                                   MAP_ANONYMOUS | MAP_PRIVATE, 0);
+               if (user_addr >= TASK_SIZE) {
+                       pr_warn("Failed to allocate user memory\n");
+                       return;
+               }
+               execute_user_location((void *)user_addr);
+               vm_munmap(user_addr, PAGE_SIZE);
+               break;
+       }
+       case CT_ACCESS_USERSPACE: {
+               unsigned long user_addr, tmp;
+               unsigned long *ptr;
+
+               user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
+                                   PROT_READ | PROT_WRITE | PROT_EXEC,
+                                   MAP_ANONYMOUS | MAP_PRIVATE, 0);
+               if (user_addr >= TASK_SIZE) {
+                       pr_warn("Failed to allocate user memory\n");
+                       return;
+               }
+
+               ptr = (unsigned long *)user_addr;
+               tmp = *ptr;
+               tmp += 0xc0dec0de;
+               *ptr = tmp;
+
+               vm_munmap(user_addr, PAGE_SIZE);
+
+               break;
+       }
+       case CT_WRITE_RO: {
+               unsigned long *ptr;
+
+               ptr = (unsigned long *)&rodata;
+               *ptr ^= 0xabcd1234;
+
+               break;
+       }
        case CT_NONE:
        default:
                break;
index f6ff711aa5bbbaa4a177dbd416ccdab53017bb23..d22c6864508b2de3505f56fa7c0a44b97dbe90fb 100644 (file)
@@ -58,6 +58,7 @@ void mei_amthif_reset_params(struct mei_device *dev)
        dev->iamthif_state = MEI_IAMTHIF_IDLE;
        dev->iamthif_timer = 0;
        dev->iamthif_stall_timer = 0;
+       dev->iamthif_open_count = 0;
 }
 
 /**
@@ -78,8 +79,10 @@ int mei_amthif_host_init(struct mei_device *dev)
 
        i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
        if (i < 0) {
-               dev_info(&dev->pdev->dev, "amthif: failed to find the client\n");
-               return -ENOENT;
+               ret = i;
+               dev_info(&dev->pdev->dev,
+                       "amthif: failed to find the client %d\n", ret);
+               return ret;
        }
 
        cl->me_client_id = dev->me_clients[i].client_id;
@@ -106,8 +109,9 @@ int mei_amthif_host_init(struct mei_device *dev)
        ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
 
        if (ret < 0) {
-               dev_err(&dev->pdev->dev, "amthif: failed link client\n");
-               return -ENOENT;
+               dev_err(&dev->pdev->dev,
+                       "amthif: failed link client %d\n", ret);
+               return ret;
        }
 
        cl->state = MEI_FILE_CONNECTING;
@@ -313,13 +317,13 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
                mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
                mei_hdr.reserved = 0;
                dev->iamthif_msg_buf_index += mei_hdr.length;
-               if (mei_write_message(dev, &mei_hdr,
-                                       (unsigned char *)dev->iamthif_msg_buf))
-                       return -ENODEV;
+               ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf);
+               if (ret)
+                       return ret;
 
                if (mei_hdr.msg_complete) {
                        if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
-                               return -ENODEV;
+                               return -EIO;
                        dev->iamthif_flow_control_pending = true;
                        dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
                        dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
@@ -459,6 +463,16 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
        struct mei_msg_hdr mei_hdr;
        size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
        u32 msg_slots = mei_data2slots(len);
+       int rets;
+
+       rets = mei_cl_flow_ctrl_creds(cl);
+       if (rets < 0)
+               return rets;
+
+       if (rets == 0) {
+               cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
+               return 0;
+       }
 
        mei_hdr.host_addr = cl->host_client_id;
        mei_hdr.me_addr = cl->me_client_id;
@@ -481,16 +495,17 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
        dev_dbg(&dev->pdev->dev, MEI_HDR_FMT,  MEI_HDR_PRM(&mei_hdr));
 
        *slots -=  msg_slots;
-       if (mei_write_message(dev, &mei_hdr,
-               dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) {
-                       dev->iamthif_state = MEI_IAMTHIF_IDLE;
-                       cl->status = -ENODEV;
-                       list_del(&cb->list);
-                       return -ENODEV;
+       rets = mei_write_message(dev, &mei_hdr,
+                       dev->iamthif_msg_buf + dev->iamthif_msg_buf_index);
+       if (rets) {
+               dev->iamthif_state = MEI_IAMTHIF_IDLE;
+               cl->status = rets;
+               list_del(&cb->list);
+               return rets;
        }
 
        if (mei_cl_flow_ctrl_reduce(cl))
-               return -ENODEV;
+               return -EIO;
 
        dev->iamthif_msg_buf_index += mei_hdr.length;
        cl->status = 0;
@@ -720,8 +735,8 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file)
 */
 int mei_amthif_release(struct mei_device *dev, struct file *file)
 {
-       if (dev->open_handle_count > 0)
-               dev->open_handle_count--;
+       if (dev->iamthif_open_count > 0)
+               dev->iamthif_open_count--;
 
        if (dev->iamthif_file_object == file &&
            dev->iamthif_state != MEI_IAMTHIF_IDLE) {
index cd2033cd7120d7631fa8d345409ed9ea86259799..4bc7d620d695f05c26a558cfe70992a4dae83963 100644 (file)
@@ -245,7 +245,7 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
        /* Check if we have an ME client device */
        id = mei_me_cl_by_id(dev, cl->me_client_id);
        if (id < 0)
-               return -ENODEV;
+               return id;
 
        if (length > dev->me_clients[id].props.max_msg_length)
                return -EINVAL;
index e0684b4d9a08aebd26453de23c5b88fb69b6b7d7..87c96e4669e2c50fd9bb5889c813f3a35ce64b1f 100644 (file)
@@ -187,10 +187,14 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
  */
 int mei_cl_flush_queues(struct mei_cl *cl)
 {
+       struct mei_device *dev;
+
        if (WARN_ON(!cl || !cl->dev))
                return -EINVAL;
 
-       dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
+       dev = cl->dev;
+
+       cl_dbg(dev, cl, "remove list entry belonging to cl\n");
        mei_io_list_flush(&cl->dev->read_list, cl);
        mei_io_list_flush(&cl->dev->write_list, cl);
        mei_io_list_flush(&cl->dev->write_waiting_list, cl);
@@ -271,6 +275,7 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
 int mei_cl_link(struct mei_cl *cl, int id)
 {
        struct mei_device *dev;
+       long open_handle_count;
 
        if (WARN_ON(!cl || !cl->dev))
                return -EINVAL;
@@ -284,7 +289,14 @@ int mei_cl_link(struct mei_cl *cl, int id)
 
        if (id >= MEI_CLIENTS_MAX) {
                dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ;
-               return -ENOENT;
+               return -EMFILE;
+       }
+
+       open_handle_count = dev->open_handle_count + dev->iamthif_open_count;
+       if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
+               dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
+                       MEI_MAX_OPEN_HANDLE_COUNT);
+               return -EMFILE;
        }
 
        dev->open_handle_count++;
@@ -296,7 +308,7 @@ int mei_cl_link(struct mei_cl *cl, int id)
 
        cl->state = MEI_FILE_INITIALIZING;
 
-       dev_dbg(&dev->pdev->dev, "link cl host id = %d\n", cl->host_client_id);
+       cl_dbg(dev, cl, "link cl\n");
        return 0;
 }
 
@@ -308,7 +320,6 @@ int mei_cl_link(struct mei_cl *cl, int id)
 int mei_cl_unlink(struct mei_cl *cl)
 {
        struct mei_device *dev;
-       struct mei_cl *pos, *next;
 
        /* don't shout on error exit path */
        if (!cl)
@@ -320,14 +331,21 @@ int mei_cl_unlink(struct mei_cl *cl)
 
        dev = cl->dev;
 
-       list_for_each_entry_safe(pos, next, &dev->file_list, link) {
-               if (cl->host_client_id == pos->host_client_id) {
-                       dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
-                               pos->host_client_id, pos->me_client_id);
-                       list_del_init(&pos->link);
-                       break;
-               }
-       }
+       cl_dbg(dev, cl, "unlink client");
+
+       if (dev->open_handle_count > 0)
+               dev->open_handle_count--;
+
+       /* never clear the 0 bit */
+       if (cl->host_client_id)
+               clear_bit(cl->host_client_id, dev->host_clients_map);
+
+       list_del_init(&cl->link);
+
+       cl->state = MEI_FILE_INITIALIZING;
+
+       list_del_init(&cl->link);
+
        return 0;
 }
 
@@ -341,17 +359,6 @@ void mei_host_client_init(struct work_struct *work)
 
        mutex_lock(&dev->device_lock);
 
-       bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
-       dev->open_handle_count = 0;
-
-       /*
-        * Reserving the first three client IDs
-        * 0: Reserved for MEI Bus Message communications
-        * 1: Reserved for Watchdog
-        * 2: Reserved for AMTHI
-        */
-       bitmap_set(dev->host_clients_map, 0, 3);
-
        for (i = 0; i < dev->me_clients_num; i++) {
                client_props = &dev->me_clients[i].props;
 
@@ -390,6 +397,8 @@ int mei_cl_disconnect(struct mei_cl *cl)
 
        dev = cl->dev;
 
+       cl_dbg(dev, cl, "disconnecting");
+
        if (cl->state != MEI_FILE_DISCONNECTING)
                return 0;
 
@@ -402,13 +411,13 @@ int mei_cl_disconnect(struct mei_cl *cl)
                dev->hbuf_is_ready = false;
                if (mei_hbm_cl_disconnect_req(dev, cl)) {
                        rets = -ENODEV;
-                       dev_err(&dev->pdev->dev, "failed to disconnect.\n");
+                       cl_err(dev, cl, "failed to disconnect.\n");
                        goto free;
                }
                mdelay(10); /* Wait for hardware disconnection ready */
                list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
        } else {
-               dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
+               cl_dbg(dev, cl, "add disconnect cb to control write list\n");
                list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 
        }
@@ -421,18 +430,17 @@ int mei_cl_disconnect(struct mei_cl *cl)
        mutex_lock(&dev->device_lock);
        if (MEI_FILE_DISCONNECTED == cl->state) {
                rets = 0;
-               dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
+               cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
        } else {
                rets = -ENODEV;
                if (MEI_FILE_DISCONNECTED != cl->state)
-                       dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
+                       cl_err(dev, cl, "wrong status client disconnect.\n");
 
                if (err)
-                       dev_dbg(&dev->pdev->dev,
-                                       "wait failed disconnect err=%08x\n",
+                       cl_dbg(dev, cl, "wait failed disconnect err=%08x\n",
                                        err);
 
-               dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
+               cl_err(dev, cl, "failed to disconnect from FW client.\n");
        }
 
        mei_io_list_flush(&dev->ctrl_rd_list, cl);
@@ -639,13 +647,12 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
                return -ENODEV;
 
        if (cl->read_cb) {
-               dev_dbg(&dev->pdev->dev, "read is pending.\n");
+               cl_dbg(dev, cl, "read is pending.\n");
                return -EBUSY;
        }
        i = mei_me_cl_by_id(dev, cl->me_client_id);
        if (i < 0) {
-               dev_err(&dev->pdev->dev, "no such me client %d\n",
-                       cl->me_client_id);
+               cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
                return  -ENODEV;
        }
 
@@ -664,6 +671,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
        if (dev->hbuf_is_ready) {
                dev->hbuf_is_ready = false;
                if (mei_hbm_cl_flow_control_req(dev, cl)) {
+                       cl_err(dev, cl, "flow control send failed\n");
                        rets = -ENODEV;
                        goto err;
                }
@@ -691,10 +699,32 @@ err:
 int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
                                     s32 *slots, struct mei_cl_cb *cmpl_list)
 {
-       struct mei_device *dev = cl->dev;
+       struct mei_device *dev;
+       struct mei_msg_data *buf;
        struct mei_msg_hdr mei_hdr;
-       size_t len = cb->request_buffer.size - cb->buf_idx;
-       u32 msg_slots = mei_data2slots(len);
+       size_t len;
+       u32 msg_slots;
+       int rets;
+
+
+       if (WARN_ON(!cl || !cl->dev))
+               return -ENODEV;
+
+       dev = cl->dev;
+
+       buf = &cb->request_buffer;
+
+       rets = mei_cl_flow_ctrl_creds(cl);
+       if (rets < 0)
+               return rets;
+
+       if (rets == 0) {
+               cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
+               return 0;
+       }
+
+       len = buf->size - cb->buf_idx;
+       msg_slots = mei_data2slots(len);
 
        mei_hdr.host_addr = cl->host_client_id;
        mei_hdr.me_addr = cl->me_client_id;
@@ -714,16 +744,15 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
                return 0;
        }
 
-       dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
+       cl_dbg(dev, cl, "buf: size = %d idx = %lu\n",
                        cb->request_buffer.size, cb->buf_idx);
-       dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
 
        *slots -=  msg_slots;
-       if (mei_write_message(dev, &mei_hdr,
-                       cb->request_buffer.data + cb->buf_idx)) {
-               cl->status = -ENODEV;
+       rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
+       if (rets) {
+               cl->status = rets;
                list_move_tail(&cb->list, &cmpl_list->list);
-               return -ENODEV;
+               return rets;
        }
 
        cl->status = 0;
@@ -732,7 +761,7 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
 
        if (mei_hdr.msg_complete) {
                if (mei_cl_flow_ctrl_reduce(cl))
-                       return -ENODEV;
+                       return -EIO;
                list_move_tail(&cb->list, &dev->write_waiting_list.list);
        }
 
@@ -767,7 +796,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
 
        buf = &cb->request_buffer;
 
-       dev_dbg(&dev->pdev->dev, "mei_cl_write %d\n", buf->size);
+       cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size);
 
 
        cb->fop_type = MEI_FOP_WRITE;
@@ -800,14 +829,10 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
        mei_hdr.me_addr = cl->me_client_id;
        mei_hdr.reserved = 0;
 
-       dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
-               MEI_HDR_PRM(&mei_hdr));
-
 
-       if (mei_write_message(dev, &mei_hdr, buf->data)) {
-               rets = -EIO;
+       rets = mei_write_message(dev, &mei_hdr, buf->data);
+       if (rets)
                goto err;
-       }
 
        cl->writing_state = MEI_WRITING;
        cb->buf_idx = mei_hdr.length;
@@ -898,11 +923,11 @@ void mei_cl_all_wakeup(struct mei_device *dev)
        struct mei_cl *cl, *next;
        list_for_each_entry_safe(cl, next, &dev->file_list, link) {
                if (waitqueue_active(&cl->rx_wait)) {
-                       dev_dbg(&dev->pdev->dev, "Waking up reading client!\n");
+                       cl_dbg(dev, cl, "Waking up reading client!\n");
                        wake_up_interruptible(&cl->rx_wait);
                }
                if (waitqueue_active(&cl->tx_wait)) {
-                       dev_dbg(&dev->pdev->dev, "Waking up writing client!\n");
+                       cl_dbg(dev, cl, "Waking up writing client!\n");
                        wake_up_interruptible(&cl->tx_wait);
                }
        }
index 892cc4207fa202629e27698c0ae536f0b81880b0..c8396e582f1c697d296834cb62f19442998b59be 100644 (file)
@@ -115,4 +115,13 @@ void mei_cl_all_disconnect(struct mei_device *dev);
 void mei_cl_all_wakeup(struct mei_device *dev);
 void mei_cl_all_write_clear(struct mei_device *dev);
 
+#define MEI_CL_FMT "cl:host=%02d me=%02d "
+#define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id
+
+#define cl_dbg(dev, cl, format, arg...) \
+       dev_dbg(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
+
+#define cl_err(dev, cl, format, arg...) \
+       dev_err(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
+
 #endif /* _MEI_CLIENT_H_ */
index 0a0448326e9d583f951932b220d90186c59f92b7..9b3a0fb7f265861bc23e42797281e5d2423bc5fc 100644 (file)
@@ -49,7 +49,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
        kfree(dev->me_clients);
        dev->me_clients = NULL;
 
-       dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
+       dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
                dev->me_clients_num * sizeof(struct mei_me_client));
        /* allocate storage for ME clients representation */
        clients = kcalloc(dev->me_clients_num,
@@ -174,7 +174,7 @@ int mei_hbm_start_req(struct mei_device *dev)
                dev_err(&dev->pdev->dev, "version message write failed\n");
                dev->dev_state = MEI_DEV_RESETTING;
                mei_reset(dev, 1);
-               return -ENODEV;
+               return -EIO;
        }
        dev->hbm_state = MEI_HBM_START;
        dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
@@ -677,7 +677,10 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
        case HOST_ENUM_RES_CMD:
                enum_res = (struct hbm_host_enum_response *) mei_msg;
-               memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
+               BUILD_BUG_ON(sizeof(dev->me_clients_map)
+                               < sizeof(enum_res->valid_addresses));
+               memcpy(dev->me_clients_map, enum_res->valid_addresses,
+                       sizeof(enum_res->valid_addresses));
                if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
                    dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
                                dev->init_clients_timer = 0;
index 6a203b6e83463e6252cdb6123780b1c5de63c8f0..6c0fde55270d3681c6048c1516b6915c291e4c45 100644 (file)
 #define MEI_DEV_ID_PPT_3      0x1DBA  /* Panther Point */
 
 #define MEI_DEV_ID_LPT        0x8C3A  /* Lynx Point */
+#define MEI_DEV_ID_LPT_W      0x8D3A  /* Lynx Point - Wellsburg */
 #define MEI_DEV_ID_LPT_LP     0x9C3A  /* Lynx Point LP */
 /*
  * MEI HW Section
index 6197018e2f16a24296619442fe6c8744c7c55b88..f7f3abbe12b6e2a8cc7058397ce77dc0c3cc7029 100644 (file)
@@ -68,6 +68,14 @@ void mei_device_init(struct mei_device *dev)
        mei_io_list_init(&dev->amthif_cmd_list);
        mei_io_list_init(&dev->amthif_rd_complete_list);
 
+       bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
+       dev->open_handle_count = 0;
+
+       /*
+        * Reserving the first client ID
+        * 0: Reserved for MEI Bus Message communications
+        */
+       bitmap_set(dev->host_clients_map, 0, 1);
 }
 EXPORT_SYMBOL_GPL(mei_device_init);
 
@@ -139,6 +147,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
                        dev->dev_state != MEI_DEV_POWER_DOWN &&
                        dev->dev_state != MEI_DEV_POWER_UP);
 
+       if (unexpected)
+               dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
+                        mei_dev_state_str(dev->dev_state));
+
        ret = mei_hw_reset(dev, interrupts_enabled);
        if (ret) {
                dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
@@ -165,12 +177,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
                /* remove entry if already in list */
                dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
                mei_cl_unlink(&dev->wd_cl);
-               if (dev->open_handle_count > 0)
-                       dev->open_handle_count--;
                mei_cl_unlink(&dev->iamthif_cl);
-               if (dev->open_handle_count > 0)
-                       dev->open_handle_count--;
-
                mei_amthif_reset_params(dev);
                memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
        }
@@ -182,10 +189,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
        dev->rd_msg_hdr = 0;
        dev->wd_pending = false;
 
-       if (unexpected)
-               dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
-                        mei_dev_state_str(dev->dev_state));
-
        if (!interrupts_enabled) {
                dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n");
                return;
index 4b59cb742dee9bac451b4cbf5d268083c8534ea7..7a95c07e59a6d675a4cc37a41c70fbd3e95961d7 100644 (file)
@@ -113,13 +113,13 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
 
                if (cb->response_buffer.size == 0 ||
                    cb->response_buffer.data == NULL) {
-                       dev_err(&dev->pdev->dev, "response buffer is not allocated.\n");
+                       cl_err(dev, cl, "response buffer is not allocated.\n");
                        list_del(&cb->list);
                        return -ENOMEM;
                }
 
                if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) {
-                       dev_dbg(&dev->pdev->dev, "message overflow. size %d len %d idx %ld\n",
+                       cl_dbg(dev, cl, "message overflow. size %d len %d idx %ld\n",
                                cb->response_buffer.size,
                                mei_hdr->length, cb->buf_idx);
                        buffer = krealloc(cb->response_buffer.data,
@@ -127,7 +127,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
                                          GFP_KERNEL);
 
                        if (!buffer) {
-                               dev_err(&dev->pdev->dev, "allocation failed.\n");
+                               cl_err(dev, cl, "allocation failed.\n");
                                list_del(&cb->list);
                                return -ENOMEM;
                        }
@@ -143,9 +143,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
                if (mei_hdr->msg_complete) {
                        cl->status = 0;
                        list_del(&cb->list);
-                       dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n",
-                               cl->host_client_id,
-                               cl->me_client_id,
+                       cl_dbg(dev, cl, "completed read length = %lu\n",
                                cb->buf_idx);
                        list_add_tail(&cb->list, &complete_list->list);
                }
@@ -218,9 +216,11 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
                           s32 *slots, struct mei_cl_cb *cmpl_list)
 {
        struct mei_device *dev = cl->dev;
-
        u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
 
+       int ret;
+
+
        if (*slots < msg_slots) {
                /* return the cancel routine */
                list_del(&cb->list);
@@ -229,12 +229,14 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
 
        *slots -= msg_slots;
 
-       if (mei_hbm_cl_flow_control_req(dev, cl)) {
-               cl->status = -ENODEV;
+       ret = mei_hbm_cl_flow_control_req(dev, cl);
+       if (ret) {
+               cl->status = ret;
                cb->buf_idx = 0;
                list_move_tail(&cb->list, &cmpl_list->list);
-               return -ENODEV;
+               return ret;
        }
+
        list_move_tail(&cb->list, &dev->read_list.list);
 
        return 0;
@@ -256,6 +258,7 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
                           s32 *slots, struct mei_cl_cb *cmpl_list)
 {
        struct mei_device *dev = cl->dev;
+       int ret;
 
        u32 msg_slots =
                mei_data2slots(sizeof(struct hbm_client_connect_request));
@@ -270,11 +273,12 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
 
        cl->state = MEI_FILE_CONNECTING;
 
-       if (mei_hbm_cl_connect_req(dev, cl)) {
-               cl->status = -ENODEV;
+       ret = mei_hbm_cl_connect_req(dev, cl);
+       if (ret) {
+               cl->status = ret;
                cb->buf_idx = 0;
                list_del(&cb->list);
-               return -ENODEV;
+               return ret;
        }
 
        list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
@@ -345,14 +349,14 @@ int mei_irq_read_handler(struct mei_device *dev,
 
        /* decide where to read the message too */
        if (!mei_hdr->host_addr) {
-               dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
+               dev_dbg(&dev->pdev->dev, "call mei_hbm_dispatch.\n");
                mei_hbm_dispatch(dev, mei_hdr);
-               dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
+               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)) {
 
-               dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
+               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));
 
                ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list);
@@ -423,12 +427,12 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
                if (MEI_WRITING == cl->writing_state &&
                    cb->fop_type == MEI_FOP_WRITE &&
                    cl != &dev->iamthif_cl) {
-                       dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
+                       cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
                        cl->writing_state = MEI_WRITE_COMPLETE;
                        list_add_tail(&cb->list, &cmpl_list->list);
                }
                if (cl == &dev->iamthif_cl) {
-                       dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
+                       cl_dbg(dev, cl, "check iamthif flow control.\n");
                        if (dev->iamthif_flow_control_pending) {
                                ret = mei_amthif_irq_read(dev, &slots);
                                if (ret)
@@ -509,13 +513,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
                cl = cb->cl;
                if (cl == NULL)
                        continue;
-               if (mei_cl_flow_ctrl_creds(cl) <= 0) {
-                       dev_dbg(&dev->pdev->dev,
-                               "No flow control credentials for client %d, not sending.\n",
-                               cl->host_client_id);
-                       continue;
-               }
-
                if (cl == &dev->iamthif_cl)
                        ret = mei_amthif_irq_write_complete(cl, cb,
                                                &slots, cmpl_list);
index cabeddd66c1f406f73f7e5bed2a56b7e52cd7621..9661a812f55045d2cd522a7877ed8d4759f49b38 100644 (file)
@@ -60,48 +60,45 @@ static int mei_open(struct inode *inode, struct file *file)
 
        int err;
 
-       err = -ENODEV;
        if (!misc->parent)
-               goto out;
+               return -ENODEV;
 
        pdev = container_of(misc->parent, struct pci_dev, dev);
 
        dev = pci_get_drvdata(pdev);
        if (!dev)
-               goto out;
+               return -ENODEV;
 
        mutex_lock(&dev->device_lock);
-       err = -ENOMEM;
-       cl = mei_cl_allocate(dev);
-       if (!cl)
-               goto out_unlock;
+
+       cl = NULL;
 
        err = -ENODEV;
        if (dev->dev_state != MEI_DEV_ENABLED) {
                dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED  dev_state = %s\n",
                    mei_dev_state_str(dev->dev_state));
-               goto out_unlock;
-       }
-       err = -EMFILE;
-       if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
-               dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
-                       MEI_MAX_OPEN_HANDLE_COUNT);
-               goto out_unlock;
+               goto err_unlock;
        }
 
+       err = -ENOMEM;
+       cl = mei_cl_allocate(dev);
+       if (!cl)
+               goto err_unlock;
+
+       /* open_handle_count check is handled in the mei_cl_link */
        err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
        if (err)
-               goto out_unlock;
+               goto err_unlock;
 
        file->private_data = cl;
+
        mutex_unlock(&dev->device_lock);
 
        return nonseekable_open(inode, file);
 
-out_unlock:
+err_unlock:
        mutex_unlock(&dev->device_lock);
        kfree(cl);
-out:
        return err;
 }
 
@@ -144,10 +141,6 @@ static int mei_release(struct inode *inode, struct file *file)
            cl->host_client_id,
            cl->me_client_id);
 
-       if (dev->open_handle_count > 0) {
-               clear_bit(cl->host_client_id, dev->host_clients_map);
-               dev->open_handle_count--;
-       }
        mei_cl_unlink(cl);
 
 
@@ -165,10 +158,7 @@ static int mei_release(struct inode *inode, struct file *file)
 
        file->private_data = NULL;
 
-       if (cb) {
-               mei_io_cb_free(cb);
-               cb = NULL;
-       }
+       mei_io_cb_free(cb);
 
        kfree(cl);
 out:
@@ -203,12 +193,18 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
 
        dev = cl->dev;
 
+
        mutex_lock(&dev->device_lock);
        if (dev->dev_state != MEI_DEV_ENABLED) {
                rets = -ENODEV;
                goto out;
        }
 
+       if (length == 0) {
+               rets = 0;
+               goto out;
+       }
+
        if (cl == &dev->iamthif_cl) {
                rets = mei_amthif_read(dev, file, ubuf, length, offset);
                goto out;
@@ -347,8 +343,14 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
                rets = -ENODEV;
                goto out;
        }
-       if (length > dev->me_clients[id].props.max_msg_length || length <= 0) {
-               rets = -EMSGSIZE;
+
+       if (length == 0) {
+               rets = 0;
+               goto out;
+       }
+
+       if (length > dev->me_clients[id].props.max_msg_length) {
+               rets = -EFBIG;
                goto out;
        }
 
@@ -401,8 +403,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
                goto out;
 
        rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
-       if (rets)
+       if (rets) {
+               dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
+               rets = -EFAULT;
                goto out;
+       }
 
        if (cl == &dev->iamthif_cl) {
                rets = mei_amthif_write(dev, write_cb);
@@ -489,11 +494,11 @@ static int mei_ioctl_connect_client(struct file *file,
                        rets = -ENODEV;
                        goto end;
                }
-               clear_bit(cl->host_client_id, dev->host_clients_map);
                mei_cl_unlink(cl);
 
                kfree(cl);
                cl = NULL;
+               dev->iamthif_open_count++;
                file->private_data = &dev->iamthif_cl;
 
                client = &data->out_client_properties;
@@ -564,7 +569,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
        dev_dbg(&dev->pdev->dev, "copy connect data from user\n");
        if (copy_from_user(connect_data, (char __user *)data,
                                sizeof(struct mei_connect_client_data))) {
-               dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n");
+               dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
                rets = -EFAULT;
                goto out;
        }
index 456b322013e269fc61f911d6f5761768c2863d4f..406f68e05b4ed4ccdbc6d9f886386a5d110e307b 100644 (file)
@@ -414,6 +414,7 @@ struct mei_device {
        struct file *iamthif_file_object;
        struct mei_cl iamthif_cl;
        struct mei_cl_cb *iamthif_current_cb;
+       long iamthif_open_count;
        int iamthif_mtu;
        unsigned long iamthif_timer;
        u32 iamthif_stall_timer;
index d0c6907dfd926809620e5ca459781042e32ba093..994ca4aff1a37ecf1b6fc53a2b44e1f446b710dd 100644 (file)
@@ -485,8 +485,11 @@ int mei_nfc_host_init(struct mei_device *dev)
        if (ndev->cl_info)
                return 0;
 
-       cl_info = mei_cl_allocate(dev);
-       cl = mei_cl_allocate(dev);
+       ndev->cl_info = mei_cl_allocate(dev);
+       ndev->cl = mei_cl_allocate(dev);
+
+       cl = ndev->cl;
+       cl_info = ndev->cl_info;
 
        if (!cl || !cl_info) {
                ret = -ENOMEM;
@@ -527,10 +530,9 @@ int mei_nfc_host_init(struct mei_device *dev)
 
        cl->device_uuid = mei_nfc_guid;
 
+
        list_add_tail(&cl->device_link, &dev->device_list);
 
-       ndev->cl_info = cl_info;
-       ndev->cl = cl;
        ndev->req_id = 1;
 
        INIT_WORK(&ndev->init_work, mei_nfc_init);
index 1b3844e823792a0893ee9b200cbc7a681ee7025f..b96205aece0c781d267ef9c2ac198cc154145080 100644 (file)
@@ -77,6 +77,7 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
 
        /* required last entry */
@@ -189,7 +190,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        schedule_delayed_work(&dev->timer_work, HZ);
 
-       pr_debug("initialization successful.\n");
+       dev_dbg(&pdev->dev, "initialization successful.\n");
 
        return 0;
 
@@ -231,7 +232,7 @@ static void mei_me_remove(struct pci_dev *pdev)
        hw = to_me_hw(dev);
 
 
-       dev_err(&pdev->dev, "stop\n");
+       dev_dbg(&pdev->dev, "stop\n");
        mei_stop(dev);
 
        /* disable interrupts */
@@ -239,7 +240,6 @@ static void mei_me_remove(struct pci_dev *pdev)
 
        free_irq(pdev->irq, dev);
        pci_disable_msi(pdev);
-       pci_set_drvdata(pdev, NULL);
 
        if (hw->mem_addr)
                pci_iounmap(pdev, hw->mem_addr);
@@ -262,7 +262,7 @@ static int mei_me_pci_suspend(struct device *device)
        if (!dev)
                return -ENODEV;
 
-       dev_err(&pdev->dev, "suspend\n");
+       dev_dbg(&pdev->dev, "suspend\n");
 
        mei_stop(dev);
 
index b8921432e89de3a350431b607f0daf1eeefb4757..9e354216c163d43d7ebe2f11241b2783d7f0a707 100644 (file)
@@ -60,7 +60,7 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
 int mei_wd_host_init(struct mei_device *dev)
 {
        struct mei_cl *cl = &dev->wd_cl;
-       int i;
+       int id;
        int ret;
 
        mei_cl_init(cl, dev);
@@ -70,19 +70,19 @@ int mei_wd_host_init(struct mei_device *dev)
 
 
        /* check for valid client id */
-       i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
-       if (i < 0) {
+       id = mei_me_cl_by_uuid(dev, &mei_wd_guid);
+       if (id < 0) {
                dev_info(&dev->pdev->dev, "wd: failed to find the client\n");
-               return -ENOENT;
+               return id;
        }
 
-       cl->me_client_id = dev->me_clients[i].client_id;
+       cl->me_client_id = dev->me_clients[id].client_id;
 
        ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID);
 
        if (ret < 0) {
                dev_info(&dev->pdev->dev, "wd: failed link client\n");
-               return -ENOENT;
+               return ret;
        }
 
        cl->state = MEI_FILE_CONNECTING;
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
new file mode 100644 (file)
index 0000000..e42b331
--- /dev/null
@@ -0,0 +1,39 @@
+comment "Intel MIC Host Driver"
+
+config INTEL_MIC_HOST
+       tristate "Intel MIC Host Driver"
+       depends on 64BIT && PCI && X86
+       select VHOST_RING
+       default N
+       help
+         This enables Host Driver support for the Intel Many Integrated
+         Core (MIC) family of PCIe form factor coprocessor devices that
+         run a 64 bit Linux OS. The driver manages card OS state and
+         enables communication between host and card. Intel MIC X100
+         devices are currently supported.
+
+         If you are building a host kernel with an Intel MIC device then
+         say M (recommended) or Y, else say N. If unsure say N.
+
+         More information about the Intel MIC family as well as the Linux
+         OS and tools for MIC to use with this driver are available from
+         <http://software.intel.com/en-us/mic-developer>.
+
+comment "Intel MIC Card Driver"
+
+config INTEL_MIC_CARD
+       tristate "Intel MIC Card Driver"
+       depends on 64BIT && X86
+       select VIRTIO
+       default N
+       help
+         This enables card driver support for the Intel Many Integrated
+         Core (MIC) device family. The card driver communicates shutdown/
+         crash events to the host and allows registration/configuration of
+         virtio devices. Intel MIC X100 devices are currently supported.
+
+         If you are building a card kernel for an Intel MIC device then
+         say M (recommended) or Y, else say N. If unsure say N.
+
+         For more information see
+         <http://software.intel.com/en-us/mic-developer>.
diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile
new file mode 100644 (file)
index 0000000..05b34d6
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile - Intel MIC Linux driver.
+# Copyright(c) 2013, Intel Corporation.
+#
+obj-$(CONFIG_INTEL_MIC_HOST) += host/
+obj-$(CONFIG_INTEL_MIC_CARD) += card/
diff --git a/drivers/misc/mic/card/Makefile b/drivers/misc/mic/card/Makefile
new file mode 100644 (file)
index 0000000..69d58be
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile - Intel MIC Linux driver.
+# Copyright(c) 2013, Intel Corporation.
+#
+ccflags-y += -DINTEL_MIC_CARD
+
+obj-$(CONFIG_INTEL_MIC_CARD) += mic_card.o
+mic_card-y += mic_x100.o
+mic_card-y += mic_device.o
+mic_card-y += mic_debugfs.o
+mic_card-y += mic_virtio.o
diff --git a/drivers/misc/mic/card/mic_debugfs.c b/drivers/misc/mic/card/mic_debugfs.c
new file mode 100644 (file)
index 0000000..421b3d7
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+
+/* Debugfs parent dir */
+static struct dentry *mic_dbg;
+
+/**
+ * mic_intr_test - Send interrupts to host.
+ */
+static int mic_intr_test(struct seq_file *s, void *unused)
+{
+       struct mic_driver *mdrv = s->private;
+       struct mic_device *mdev = &mdrv->mdev;
+
+       mic_send_intr(mdev, 0);
+       msleep(1000);
+       mic_send_intr(mdev, 1);
+       msleep(1000);
+       mic_send_intr(mdev, 2);
+       msleep(1000);
+       mic_send_intr(mdev, 3);
+       msleep(1000);
+
+       return 0;
+}
+
+static int mic_intr_test_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_intr_test, inode->i_private);
+}
+
+static int mic_intr_test_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations intr_test_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_intr_test_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_intr_test_release
+};
+
+/**
+ * mic_create_card_debug_dir - Initialize MIC debugfs entries.
+ */
+void __init mic_create_card_debug_dir(struct mic_driver *mdrv)
+{
+       struct dentry *d;
+
+       if (!mic_dbg)
+               return;
+
+       mdrv->dbg_dir = debugfs_create_dir(mdrv->name, mic_dbg);
+       if (!mdrv->dbg_dir) {
+               dev_err(mdrv->dev, "Cant create dbg_dir %s\n", mdrv->name);
+               return;
+       }
+
+       d = debugfs_create_file("intr_test", 0444, mdrv->dbg_dir,
+               mdrv, &intr_test_ops);
+
+       if (!d) {
+               dev_err(mdrv->dev,
+                       "Cant create dbg intr_test %s\n", mdrv->name);
+               return;
+       }
+}
+
+/**
+ * mic_delete_card_debug_dir - Uninitialize MIC debugfs entries.
+ */
+void mic_delete_card_debug_dir(struct mic_driver *mdrv)
+{
+       if (!mdrv->dbg_dir)
+               return;
+
+       debugfs_remove_recursive(mdrv->dbg_dir);
+}
+
+/**
+ * mic_init_card_debugfs - Initialize global debugfs entry.
+ */
+void __init mic_init_card_debugfs(void)
+{
+       mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       if (!mic_dbg)
+               pr_err("can't create debugfs dir\n");
+}
+
+/**
+ * mic_exit_card_debugfs - Uninitialize global debugfs entry
+ */
+void mic_exit_card_debugfs(void)
+{
+       debugfs_remove(mic_dbg);
+}
diff --git a/drivers/misc/mic/card/mic_device.c b/drivers/misc/mic/card/mic_device.c
new file mode 100644 (file)
index 0000000..d0980ff
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_virtio.h"
+
+static struct mic_driver *g_drv;
+static struct mic_irq *shutdown_cookie;
+
+static void mic_notify_host(u8 state)
+{
+       struct mic_driver *mdrv = g_drv;
+       struct mic_bootparam __iomem *bootparam = mdrv->dp;
+
+       iowrite8(state, &bootparam->shutdown_status);
+       dev_dbg(mdrv->dev, "%s %d system_state %d\n",
+               __func__, __LINE__, state);
+       mic_send_intr(&mdrv->mdev, ioread8(&bootparam->c2h_shutdown_db));
+}
+
+static int mic_panic_event(struct notifier_block *this, unsigned long event,
+               void *ptr)
+{
+       struct mic_driver *mdrv = g_drv;
+       struct mic_bootparam __iomem *bootparam = mdrv->dp;
+
+       iowrite8(-1, &bootparam->h2c_config_db);
+       iowrite8(-1, &bootparam->h2c_shutdown_db);
+       mic_notify_host(MIC_CRASHED);
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block mic_panic = {
+       .notifier_call  = mic_panic_event,
+};
+
+static irqreturn_t mic_shutdown_isr(int irq, void *data)
+{
+       struct mic_driver *mdrv = g_drv;
+       struct mic_bootparam __iomem *bootparam = mdrv->dp;
+
+       mic_ack_interrupt(&g_drv->mdev);
+       if (ioread8(&bootparam->shutdown_card))
+               orderly_poweroff(true);
+       return IRQ_HANDLED;
+}
+
+static int mic_shutdown_init(void)
+{
+       int rc = 0;
+       struct mic_driver *mdrv = g_drv;
+       struct mic_bootparam __iomem *bootparam = mdrv->dp;
+       int shutdown_db;
+
+       shutdown_db = mic_next_card_db();
+       shutdown_cookie = mic_request_card_irq(mic_shutdown_isr,
+                       "Shutdown", mdrv, shutdown_db);
+       if (IS_ERR(shutdown_cookie))
+               rc = PTR_ERR(shutdown_cookie);
+       else
+               iowrite8(shutdown_db, &bootparam->h2c_shutdown_db);
+       return rc;
+}
+
+static void mic_shutdown_uninit(void)
+{
+       struct mic_driver *mdrv = g_drv;
+       struct mic_bootparam __iomem *bootparam = mdrv->dp;
+
+       iowrite8(-1, &bootparam->h2c_shutdown_db);
+       mic_free_card_irq(shutdown_cookie, mdrv);
+}
+
+static int __init mic_dp_init(void)
+{
+       struct mic_driver *mdrv = g_drv;
+       struct mic_device *mdev = &mdrv->mdev;
+       struct mic_bootparam __iomem *bootparam;
+       u64 lo, hi, dp_dma_addr;
+       u32 magic;
+
+       lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD);
+       hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD);
+
+       dp_dma_addr = lo | (hi << 32);
+       mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE);
+       if (!mdrv->dp) {
+               dev_err(mdrv->dev, "Cannot remap Aperture BAR\n");
+               return -ENOMEM;
+       }
+       bootparam = mdrv->dp;
+       magic = ioread32(&bootparam->magic);
+       if (MIC_MAGIC != magic) {
+               dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic);
+               return -EIO;
+       }
+       return 0;
+}
+
+/* Uninitialize the device page */
+static void mic_dp_uninit(void)
+{
+       mic_card_unmap(&g_drv->mdev, g_drv->dp);
+}
+
+/**
+ * mic_request_card_irq - request an irq.
+ *
+ * @func: The callback function that handles the interrupt.
+ * @name: The ASCII name of the callee requesting the irq.
+ * @data: private data that is returned back when calling the
+ * function handler.
+ * @index: The doorbell index of the requester.
+ *
+ * returns: The cookie that is transparent to the caller. Passed
+ * back when calling mic_free_irq. An appropriate error code
+ * is returned on failure. Caller needs to use IS_ERR(return_val)
+ * to check for failure and PTR_ERR(return_val) to obtained the
+ * error code.
+ *
+ */
+struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
+       const char *name, void *data, int index)
+{
+       int rc = 0;
+       unsigned long cookie;
+       struct mic_driver *mdrv = g_drv;
+
+       rc  = request_irq(mic_db_to_irq(mdrv, index), func,
+               0, name, data);
+       if (rc) {
+               dev_err(mdrv->dev, "request_irq failed rc = %d\n", rc);
+               goto err;
+       }
+       mdrv->irq_info.irq_usage_count[index]++;
+       cookie = index;
+       return (struct mic_irq *)cookie;
+err:
+       return ERR_PTR(rc);
+}
+
+/**
+ * mic_free_card_irq - free irq.
+ *
+ * @cookie: cookie obtained during a successful call to mic_request_irq
+ * @data: private data specified by the calling function during the
+ * mic_request_irq
+ *
+ * returns: none.
+ */
+void mic_free_card_irq(struct mic_irq *cookie, void *data)
+{
+       int index;
+       struct mic_driver *mdrv = g_drv;
+
+       index = (unsigned long)cookie & 0xFFFFU;
+       free_irq(mic_db_to_irq(mdrv, index), data);
+       mdrv->irq_info.irq_usage_count[index]--;
+}
+
+/**
+ * mic_next_card_db - Get the doorbell with minimum usage count.
+ *
+ * Returns the irq index.
+ */
+int mic_next_card_db(void)
+{
+       int i;
+       int index = 0;
+       struct mic_driver *mdrv = g_drv;
+
+       for (i = 0; i < mdrv->intr_info.num_intr; i++) {
+               if (mdrv->irq_info.irq_usage_count[i] <
+                       mdrv->irq_info.irq_usage_count[index])
+                       index = i;
+       }
+
+       return index;
+}
+
+/**
+ * mic_init_irq - Initialize irq information.
+ *
+ * Returns 0 in success. Appropriate error code on failure.
+ */
+static int mic_init_irq(void)
+{
+       struct mic_driver *mdrv = g_drv;
+
+       mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) *
+                       mdrv->intr_info.num_intr),
+                       GFP_KERNEL);
+       if (!mdrv->irq_info.irq_usage_count)
+               return -ENOMEM;
+       return 0;
+}
+
+/**
+ * mic_uninit_irq - Uninitialize irq information.
+ *
+ * None.
+ */
+static void mic_uninit_irq(void)
+{
+       struct mic_driver *mdrv = g_drv;
+
+       kfree(mdrv->irq_info.irq_usage_count);
+}
+
+/*
+ * mic_driver_init - MIC driver initialization tasks.
+ *
+ * Returns 0 in success. Appropriate error code on failure.
+ */
+int __init mic_driver_init(struct mic_driver *mdrv)
+{
+       int rc;
+
+       g_drv = mdrv;
+       /*
+        * Unloading the card module is not supported. The MIC card module
+        * handles fundamental operations like host/card initiated shutdowns
+        * and informing the host about card crashes and cannot be unloaded.
+        */
+       if (!try_module_get(mdrv->dev->driver->owner)) {
+               rc = -ENODEV;
+               goto done;
+       }
+       rc = mic_dp_init();
+       if (rc)
+               goto put;
+       rc = mic_init_irq();
+       if (rc)
+               goto dp_uninit;
+       rc = mic_shutdown_init();
+       if (rc)
+               goto irq_uninit;
+       rc = mic_devices_init(mdrv);
+       if (rc)
+               goto shutdown_uninit;
+       mic_create_card_debug_dir(mdrv);
+       atomic_notifier_chain_register(&panic_notifier_list, &mic_panic);
+done:
+       return rc;
+shutdown_uninit:
+       mic_shutdown_uninit();
+irq_uninit:
+       mic_uninit_irq();
+dp_uninit:
+       mic_dp_uninit();
+put:
+       module_put(mdrv->dev->driver->owner);
+       return rc;
+}
+
+/*
+ * mic_driver_uninit - MIC driver uninitialization tasks.
+ *
+ * Returns None
+ */
+void mic_driver_uninit(struct mic_driver *mdrv)
+{
+       mic_delete_card_debug_dir(mdrv);
+       mic_devices_uninit(mdrv);
+       /*
+        * Inform the host about the shutdown status i.e. poweroff/restart etc.
+        * The module cannot be unloaded so the only code path to call
+        * mic_devices_uninit(..) is the shutdown callback.
+        */
+       mic_notify_host(system_state);
+       mic_shutdown_uninit();
+       mic_uninit_irq();
+       mic_dp_uninit();
+       module_put(mdrv->dev->driver->owner);
+}
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h
new file mode 100644 (file)
index 0000000..347b9b3
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#ifndef _MIC_CARD_DEVICE_H_
+#define _MIC_CARD_DEVICE_H_
+
+#include <linux/workqueue.h>
+#include <linux/io.h>
+
+/**
+ * struct mic_intr_info - Contains h/w specific interrupt sources info
+ *
+ * @num_intr: The number of irqs available
+ */
+struct mic_intr_info {
+       u32 num_intr;
+};
+
+/**
+ * struct mic_irq_info - OS specific irq information
+ *
+ * @irq_usage_count: usage count array tracking the number of sources
+ * assigned for each irq.
+ */
+struct mic_irq_info {
+       int *irq_usage_count;
+};
+
+/**
+ * struct mic_device -  MIC device information.
+ *
+ * @mmio: MMIO bar information.
+ */
+struct mic_device {
+       struct mic_mw mmio;
+};
+
+/**
+ * struct mic_driver - MIC card driver information.
+ *
+ * @name: Name for MIC driver.
+ * @dbg_dir: debugfs directory of this MIC device.
+ * @dev: The device backing this MIC.
+ * @dp: The pointer to the virtio device page.
+ * @mdev: MIC device information for the host.
+ * @hotplug_work: Hot plug work for adding/removing virtio devices.
+ * @irq_info: The OS specific irq information
+ * @intr_info: H/W specific interrupt information.
+ */
+struct mic_driver {
+       char name[20];
+       struct dentry *dbg_dir;
+       struct device *dev;
+       void __iomem *dp;
+       struct mic_device mdev;
+       struct work_struct hotplug_work;
+       struct mic_irq_info irq_info;
+       struct mic_intr_info intr_info;
+};
+
+/**
+ * struct mic_irq - opaque pointer used as cookie
+ */
+struct mic_irq;
+
+/**
+ * mic_mmio_read - read from an MMIO register.
+ * @mw: MMIO register base virtual address.
+ * @offset: register offset.
+ *
+ * RETURNS: register value.
+ */
+static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset)
+{
+       return ioread32(mw->va + offset);
+}
+
+/**
+ * mic_mmio_write - write to an MMIO register.
+ * @mw: MMIO register base virtual address.
+ * @val: the data value to put into the register
+ * @offset: register offset.
+ *
+ * RETURNS: none.
+ */
+static inline void
+mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
+{
+       iowrite32(val, mw->va + offset);
+}
+
+int mic_driver_init(struct mic_driver *mdrv);
+void mic_driver_uninit(struct mic_driver *mdrv);
+int mic_next_card_db(void);
+struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
+       const char *name, void *data, int intr_src);
+void mic_free_card_irq(struct mic_irq *cookie, void *data);
+u32 mic_read_spad(struct mic_device *mdev, unsigned int idx);
+void mic_send_intr(struct mic_device *mdev, int doorbell);
+int mic_db_to_irq(struct mic_driver *mdrv, int db);
+u32 mic_ack_interrupt(struct mic_device *mdev);
+void mic_hw_intr_init(struct mic_driver *mdrv);
+void __iomem *
+mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size);
+void mic_card_unmap(struct mic_device *mdev, void __iomem *addr);
+void __init mic_create_card_debug_dir(struct mic_driver *mdrv);
+void mic_delete_card_debug_dir(struct mic_driver *mdrv);
+void __init mic_init_card_debugfs(void);
+void mic_exit_card_debugfs(void);
+#endif
diff --git a/drivers/misc/mic/card/mic_virtio.c b/drivers/misc/mic/card/mic_virtio.c
new file mode 100644 (file)
index 0000000..914cc9b
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Adapted from:
+ *
+ * virtio for kvm on s390
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * 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.
+ *
+ *    Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/virtio_config.h>
+
+#include "../common/mic_dev.h"
+#include "mic_virtio.h"
+
+#define VIRTIO_SUBCODE_64 0x0D00
+
+#define MIC_MAX_VRINGS                4
+struct mic_vdev {
+       struct virtio_device vdev;
+       struct mic_device_desc __iomem *desc;
+       struct mic_device_ctrl __iomem *dc;
+       struct mic_device *mdev;
+       void __iomem *vr[MIC_MAX_VRINGS];
+       int used_size[MIC_MAX_VRINGS];
+       struct completion reset_done;
+       struct mic_irq *virtio_cookie;
+       int c2h_vdev_db;
+};
+
+static struct mic_irq *virtio_config_cookie;
+#define to_micvdev(vd) container_of(vd, struct mic_vdev, vdev)
+
+/* Helper API to obtain the parent of the virtio device */
+static inline struct device *mic_dev(struct mic_vdev *mvdev)
+{
+       return mvdev->vdev.dev.parent;
+}
+
+/* This gets the device's feature bits. */
+static u32 mic_get_features(struct virtio_device *vdev)
+{
+       unsigned int i, bits;
+       u32 features = 0;
+       struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
+       u8 __iomem *in_features = mic_vq_features(desc);
+       int feature_len = ioread8(&desc->feature_len);
+
+       bits = min_t(unsigned, feature_len,
+               sizeof(vdev->features)) * 8;
+       for (i = 0; i < bits; i++)
+               if (ioread8(&in_features[i / 8]) & (BIT(i % 8)))
+                       features |= BIT(i);
+
+       return features;
+}
+
+static void mic_finalize_features(struct virtio_device *vdev)
+{
+       unsigned int i, bits;
+       struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
+       u8 feature_len = ioread8(&desc->feature_len);
+       /* Second half of bitmap is features we accept. */
+       u8 __iomem *out_features =
+               mic_vq_features(desc) + feature_len;
+
+       /* Give virtio_ring a chance to accept features. */
+       vring_transport_features(vdev);
+
+       memset_io(out_features, 0, feature_len);
+       bits = min_t(unsigned, feature_len,
+               sizeof(vdev->features)) * 8;
+       for (i = 0; i < bits; i++) {
+               if (test_bit(i, vdev->features))
+                       iowrite8(ioread8(&out_features[i / 8]) | (1 << (i % 8)),
+                                &out_features[i / 8]);
+       }
+}
+
+/*
+ * Reading and writing elements in config space
+ */
+static void mic_get(struct virtio_device *vdev, unsigned int offset,
+                  void *buf, unsigned len)
+{
+       struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
+
+       if (offset + len > ioread8(&desc->config_len))
+               return;
+       memcpy_fromio(buf, mic_vq_configspace(desc) + offset, len);
+}
+
+static void mic_set(struct virtio_device *vdev, unsigned int offset,
+                  const void *buf, unsigned len)
+{
+       struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
+
+       if (offset + len > ioread8(&desc->config_len))
+               return;
+       memcpy_toio(mic_vq_configspace(desc) + offset, buf, len);
+}
+
+/*
+ * The operations to get and set the status word just access the status
+ * field of the device descriptor. set_status also interrupts the host
+ * to tell about status changes.
+ */
+static u8 mic_get_status(struct virtio_device *vdev)
+{
+       return ioread8(&to_micvdev(vdev)->desc->status);
+}
+
+static void mic_set_status(struct virtio_device *vdev, u8 status)
+{
+       struct mic_vdev *mvdev = to_micvdev(vdev);
+       if (!status)
+               return;
+       iowrite8(status, &mvdev->desc->status);
+       mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
+}
+
+/* Inform host on a virtio device reset and wait for ack from host */
+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;
+
+       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--;) {
+               if (ioread8(&dc->host_ack))
+                       break;
+               msleep(100);
+       };
+
+       dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
+
+       /* Reset status to 0 in case we timed out */
+       iowrite8(0, &mvdev->desc->status);
+}
+
+static void mic_reset(struct virtio_device *vdev)
+{
+       struct mic_vdev *mvdev = to_micvdev(vdev);
+
+       dev_dbg(mic_dev(mvdev), "%s: virtio id %d\n",
+               __func__, vdev->id.device);
+
+       mic_reset_inform_host(vdev);
+       complete_all(&mvdev->reset_done);
+}
+
+/*
+ * The virtio_ring code calls this API when it wants to notify the Host.
+ */
+static void mic_notify(struct virtqueue *vq)
+{
+       struct mic_vdev *mvdev = vq->priv;
+
+       mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
+}
+
+static void mic_del_vq(struct virtqueue *vq, int n)
+{
+       struct mic_vdev *mvdev = to_micvdev(vq->vdev);
+       struct vring *vr = (struct vring *)(vq + 1);
+
+       free_pages((unsigned long) vr->used, get_order(mvdev->used_size[n]));
+       vring_del_virtqueue(vq);
+       mic_card_unmap(mvdev->mdev, mvdev->vr[n]);
+       mvdev->vr[n] = NULL;
+}
+
+static void mic_del_vqs(struct virtio_device *vdev)
+{
+       struct mic_vdev *mvdev = to_micvdev(vdev);
+       struct virtqueue *vq, *n;
+       int idx = 0;
+
+       dev_dbg(mic_dev(mvdev), "%s\n", __func__);
+
+       list_for_each_entry_safe(vq, n, &vdev->vqs, list)
+               mic_del_vq(vq, idx++);
+}
+
+/*
+ * This routine will assign vring's allocated in host/io memory. Code in
+ * virtio_ring.c however continues to access this io memory as if it were local
+ * memory without io accessors.
+ */
+static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
+                                    unsigned index,
+                                    void (*callback)(struct virtqueue *vq),
+                                    const char *name)
+{
+       struct mic_vdev *mvdev = to_micvdev(vdev);
+       struct mic_vqconfig __iomem *vqconfig;
+       struct mic_vqconfig config;
+       struct virtqueue *vq;
+       void __iomem *va;
+       struct _mic_vring_info __iomem *info;
+       void *used;
+       int vr_size, _vr_size, err, magic;
+       struct vring *vr;
+       u8 type = ioread8(&mvdev->desc->type);
+
+       if (index >= ioread8(&mvdev->desc->num_vq))
+               return ERR_PTR(-ENOENT);
+
+       if (!name)
+               return ERR_PTR(-ENOENT);
+
+       /* 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 = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
+       va = mic_card_map(mvdev->mdev, 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);
+       if (!vq) {
+               err = -ENOMEM;
+               goto unmap;
+       }
+       info = va + _vr_size;
+       magic = ioread32(&info->magic);
+
+       if (WARN(magic != MIC_MAGIC + type + index, "magic mismatch")) {
+               err = -EIO;
+               goto unmap;
+       }
+
+       /* Allocate and reassign used ring now */
+       mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
+                       sizeof(struct vring_used_elem) * config.num);
+       used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+                                       get_order(mvdev->used_size[index]));
+       if (!used) {
+               err = -ENOMEM;
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, err);
+               goto del_vq;
+       }
+       iowrite64(virt_to_phys(used), &vqconfig->used_address);
+
+       /*
+        * To reassign the used ring here we are directly accessing
+        * struct vring_virtqueue which is a private data structure
+        * in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
+        * vring_new_virtqueue() would ensure that
+        *  (&vq->vring == (struct vring *) (&vq->vq + 1));
+        */
+       vr = (struct vring *)(vq + 1);
+       vr->used = used;
+
+       vq->priv = mvdev;
+       return vq;
+del_vq:
+       vring_del_virtqueue(vq);
+unmap:
+       mic_card_unmap(mvdev->mdev, mvdev->vr[index]);
+       return ERR_PTR(err);
+}
+
+static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+                       struct virtqueue *vqs[],
+                       vq_callback_t *callbacks[],
+                       const char *names[])
+{
+       struct mic_vdev *mvdev = to_micvdev(vdev);
+       struct mic_device_ctrl __iomem *dc = mvdev->dc;
+       int i, err, retry = 100;
+
+       /* We must have this many virtqueues. */
+       if (nvqs > ioread8(&mvdev->desc->num_vq))
+               return -ENOENT;
+
+       for (i = 0; i < nvqs; ++i) {
+               dev_dbg(mic_dev(mvdev), "%s: %d: %s\n",
+                       __func__, i, names[i]);
+               vqs[i] = mic_find_vq(vdev, i, callbacks[i], names[i]);
+               if (IS_ERR(vqs[i])) {
+                       err = PTR_ERR(vqs[i]);
+                       goto error;
+               }
+       }
+
+       iowrite8(1, &dc->used_address_updated);
+       /*
+        * Send an interrupt to the host to inform it that used
+        * rings have been re-assigned.
+        */
+       mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
+       for (i = retry; i--;) {
+               if (!ioread8(&dc->used_address_updated))
+                       break;
+               msleep(100);
+       };
+
+       dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
+       if (!retry) {
+               err = -ENODEV;
+               goto error;
+       }
+
+       return 0;
+error:
+       mic_del_vqs(vdev);
+       return err;
+}
+
+/*
+ * The config ops structure as defined by virtio config
+ */
+static struct virtio_config_ops mic_vq_config_ops = {
+       .get_features = mic_get_features,
+       .finalize_features = mic_finalize_features,
+       .get = mic_get,
+       .set = mic_set,
+       .get_status = mic_get_status,
+       .set_status = mic_set_status,
+       .reset = mic_reset,
+       .find_vqs = mic_find_vqs,
+       .del_vqs = mic_del_vqs,
+};
+
+static irqreturn_t
+mic_virtio_intr_handler(int irq, void *data)
+{
+       struct mic_vdev *mvdev = data;
+       struct virtqueue *vq;
+
+       mic_ack_interrupt(mvdev->mdev);
+       list_for_each_entry(vq, &mvdev->vdev.vqs, list)
+               vring_interrupt(0, vq);
+
+       return IRQ_HANDLED;
+}
+
+static void mic_virtio_release_dev(struct device *_d)
+{
+       /*
+        * No need for a release method similar to virtio PCI.
+        * Provide an empty one to avoid getting a warning from core.
+        */
+}
+
+/*
+ * adds a new device and register it with virtio
+ * appropriate drivers are loaded by the device model
+ */
+static int mic_add_device(struct mic_device_desc __iomem *d,
+       unsigned int offset, struct mic_driver *mdrv)
+{
+       struct mic_vdev *mvdev;
+       int ret;
+       int virtio_db;
+       u8 type = ioread8(&d->type);
+
+       mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
+       if (!mvdev) {
+               dev_err(mdrv->dev, "Cannot allocate mic dev %u type %u\n",
+                       offset, type);
+               return -ENOMEM;
+       }
+
+       mvdev->mdev = &mdrv->mdev;
+       mvdev->vdev.dev.parent = mdrv->dev;
+       mvdev->vdev.dev.release = mic_virtio_release_dev;
+       mvdev->vdev.id.device = type;
+       mvdev->vdev.config = &mic_vq_config_ops;
+       mvdev->desc = d;
+       mvdev->dc = (void __iomem *)d + mic_aligned_desc_size(d);
+       init_completion(&mvdev->reset_done);
+
+       virtio_db = mic_next_card_db();
+       mvdev->virtio_cookie = mic_request_card_irq(mic_virtio_intr_handler,
+                       "virtio intr", mvdev, virtio_db);
+       if (IS_ERR(mvdev->virtio_cookie)) {
+               ret = PTR_ERR(mvdev->virtio_cookie);
+               goto kfree;
+       }
+       iowrite8((u8)virtio_db, &mvdev->dc->h2c_vdev_db);
+       mvdev->c2h_vdev_db = ioread8(&mvdev->dc->c2h_vdev_db);
+
+       ret = register_virtio_device(&mvdev->vdev);
+       if (ret) {
+               dev_err(mic_dev(mvdev),
+                       "Failed to register mic device %u type %u\n",
+                       offset, type);
+               goto free_irq;
+       }
+       iowrite64((u64)mvdev, &mvdev->dc->vdev);
+       dev_dbg(mic_dev(mvdev), "%s: registered mic device %u type %u mvdev %p\n",
+               __func__, offset, type, mvdev);
+
+       return 0;
+
+free_irq:
+       mic_free_card_irq(mvdev->virtio_cookie, mvdev);
+kfree:
+       kfree(mvdev);
+       return ret;
+}
+
+/*
+ * match for a mic device with a specific desc pointer
+ */
+static int mic_match_desc(struct device *dev, void *data)
+{
+       struct virtio_device *vdev = dev_to_virtio(dev);
+       struct mic_vdev *mvdev = to_micvdev(vdev);
+
+       return mvdev->desc == (void __iomem *)data;
+}
+
+static void mic_handle_config_change(struct mic_device_desc __iomem *d,
+       unsigned int offset, struct mic_driver *mdrv)
+{
+       struct mic_device_ctrl __iomem *dc
+               = (void __iomem *)d + mic_aligned_desc_size(d);
+       struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
+       struct virtio_driver *drv;
+
+       if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED)
+               return;
+
+       dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__);
+       drv = container_of(mvdev->vdev.dev.driver,
+                               struct virtio_driver, driver);
+       if (drv->config_changed)
+               drv->config_changed(&mvdev->vdev);
+       iowrite8(1, &dc->guest_ack);
+}
+
+/*
+ * removes a virtio device if a hot remove event has been
+ * requested by the host.
+ */
+static int mic_remove_device(struct mic_device_desc __iomem *d,
+       unsigned int offset, struct mic_driver *mdrv)
+{
+       struct mic_device_ctrl __iomem *dc
+               = (void __iomem *)d + mic_aligned_desc_size(d);
+       struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
+       u8 status;
+       int ret = -1;
+
+       if (ioread8(&dc->config_change) == MIC_VIRTIO_PARAM_DEV_REMOVE) {
+               dev_dbg(mdrv->dev,
+                       "%s %d config_change %d type %d mvdev %p\n",
+                       __func__, __LINE__,
+                       ioread8(&dc->config_change), ioread8(&d->type), mvdev);
+
+               status = ioread8(&d->status);
+               INIT_COMPLETION(mvdev->reset_done);
+               unregister_virtio_device(&mvdev->vdev);
+               mic_free_card_irq(mvdev->virtio_cookie, mvdev);
+               if (status & VIRTIO_CONFIG_S_DRIVER_OK)
+                       wait_for_completion(&mvdev->reset_done);
+               kfree(mvdev);
+               iowrite8(1, &dc->guest_ack);
+               dev_dbg(mdrv->dev, "%s %d guest_ack %d\n",
+                       __func__, __LINE__, ioread8(&dc->guest_ack));
+               ret = 0;
+       }
+
+       return ret;
+}
+
+#define REMOVE_DEVICES true
+
+static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
+{
+       s8 type;
+       unsigned int i;
+       struct mic_device_desc __iomem *d;
+       struct mic_device_ctrl __iomem *dc;
+       struct device *dev;
+       int ret;
+
+       for (i = mic_aligned_size(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);
+               /*
+                * This read barrier is paired with the corresponding write
+                * barrier on the host which is inserted before adding or
+                * removing a virtio device descriptor, by updating the type.
+                */
+               rmb();
+               type = ioread8(&d->type);
+
+               /* end of list */
+               if (type == 0)
+                       break;
+
+               if (type == -1)
+                       continue;
+
+               /* device already exists */
+               dev = device_find_child(mdrv->dev, d, mic_match_desc);
+               if (dev) {
+                       if (remove)
+                               iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
+                                        &dc->config_change);
+                       put_device(dev);
+                       mic_handle_config_change(d, i, mdrv);
+                       ret = mic_remove_device(d, i, mdrv);
+                       if (!ret && !remove)
+                               iowrite8(-1, &d->type);
+                       if (remove) {
+                               iowrite8(0, &dc->config_change);
+                               iowrite8(0, &dc->guest_ack);
+                       }
+                       continue;
+               }
+
+               /* new device */
+               dev_dbg(mdrv->dev, "%s %d Adding new virtio device %p\n",
+                       __func__, __LINE__, d);
+               if (!remove)
+                       mic_add_device(d, i, mdrv);
+       }
+}
+
+/*
+ * mic_hotplug_device tries to find changes in the device page.
+ */
+static void mic_hotplug_devices(struct work_struct *work)
+{
+       struct mic_driver *mdrv = container_of(work,
+               struct mic_driver, hotplug_work);
+
+       mic_scan_devices(mdrv, !REMOVE_DEVICES);
+}
+
+/*
+ * Interrupt handler for hot plug/config changes etc.
+ */
+static irqreturn_t
+mic_extint_handler(int irq, void *data)
+{
+       struct mic_driver *mdrv = (struct mic_driver *)data;
+
+       dev_dbg(mdrv->dev, "%s %d hotplug work\n",
+               __func__, __LINE__);
+       mic_ack_interrupt(&mdrv->mdev);
+       schedule_work(&mdrv->hotplug_work);
+       return IRQ_HANDLED;
+}
+
+/*
+ * Init function for virtio
+ */
+int mic_devices_init(struct mic_driver *mdrv)
+{
+       int rc;
+       struct mic_bootparam __iomem *bootparam;
+       int config_db;
+
+       INIT_WORK(&mdrv->hotplug_work, mic_hotplug_devices);
+       mic_scan_devices(mdrv, !REMOVE_DEVICES);
+
+       config_db = mic_next_card_db();
+       virtio_config_cookie = mic_request_card_irq(mic_extint_handler,
+                       "virtio_config_intr", mdrv, config_db);
+       if (IS_ERR(virtio_config_cookie)) {
+               rc = PTR_ERR(virtio_config_cookie);
+               goto exit;
+       }
+
+       bootparam = mdrv->dp;
+       iowrite8(config_db, &bootparam->h2c_config_db);
+       return 0;
+exit:
+       return rc;
+}
+
+/*
+ * Uninit function for virtio
+ */
+void mic_devices_uninit(struct mic_driver *mdrv)
+{
+       struct mic_bootparam __iomem *bootparam = mdrv->dp;
+       iowrite8(-1, &bootparam->h2c_config_db);
+       mic_free_card_irq(virtio_config_cookie, mdrv);
+       flush_work(&mdrv->hotplug_work);
+       mic_scan_devices(mdrv, REMOVE_DEVICES);
+}
diff --git a/drivers/misc/mic/card/mic_virtio.h b/drivers/misc/mic/card/mic_virtio.h
new file mode 100644 (file)
index 0000000..2c5c22c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#ifndef __MIC_CARD_VIRTIO_H
+#define __MIC_CARD_VIRTIO_H
+
+#include <linux/mic_common.h>
+#include "mic_device.h"
+
+/*
+ * 64 bit I/O access
+ */
+#ifndef ioread64
+#define ioread64 readq
+#endif
+#ifndef iowrite64
+#define iowrite64 writeq
+#endif
+
+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)
+               + ioread8(&desc->feature_len) * 2
+               + ioread8(&desc->config_len);
+}
+
+static inline struct mic_vqconfig __iomem *
+mic_vq_config(struct mic_device_desc __iomem *desc)
+{
+       return (struct mic_vqconfig __iomem *)(desc + 1);
+}
+
+static inline __u8 __iomem *
+mic_vq_features(struct mic_device_desc __iomem *desc)
+{
+       return (__u8 __iomem *)(mic_vq_config(desc) + ioread8(&desc->num_vq));
+}
+
+static inline __u8 __iomem *
+mic_vq_configspace(struct mic_device_desc __iomem *desc)
+{
+       return mic_vq_features(desc) + ioread8(&desc->feature_len) * 2;
+}
+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);
+}
+
+int mic_devices_init(struct mic_driver *mdrv);
+void mic_devices_uninit(struct mic_driver *mdrv);
+
+#endif
diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c
new file mode 100644 (file)
index 0000000..2868945
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_x100.h"
+
+static const char mic_driver_name[] = "mic";
+
+static struct mic_driver g_drv;
+
+/**
+ * mic_read_spad - read from the scratchpad register
+ * @mdev: pointer to mic_device instance
+ * @idx: index to scratchpad register, 0 based
+ *
+ * This function allows reading of the 32bit scratchpad register.
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+u32 mic_read_spad(struct mic_device *mdev, unsigned int idx)
+{
+       return mic_mmio_read(&mdev->mmio,
+               MIC_X100_SBOX_BASE_ADDRESS +
+               MIC_X100_SBOX_SPAD0 + idx * 4);
+}
+
+/**
+ * __mic_send_intr - Send interrupt to Host.
+ * @mdev: pointer to mic_device instance
+ * @doorbell: Doorbell number.
+ */
+void mic_send_intr(struct mic_device *mdev, int doorbell)
+{
+       struct mic_mw *mw = &mdev->mmio;
+
+       if (doorbell > MIC_X100_MAX_DOORBELL_IDX)
+               return;
+       /* Ensure that the interrupt is ordered w.r.t previous stores. */
+       wmb();
+       mic_mmio_write(mw, MIC_X100_SBOX_SDBIC0_DBREQ_BIT,
+                      MIC_X100_SBOX_BASE_ADDRESS +
+                      (MIC_X100_SBOX_SDBIC0 + (4 * doorbell)));
+}
+
+/**
+ * mic_ack_interrupt - Device specific interrupt handling.
+ * @mdev: pointer to mic_device instance
+ *
+ * Returns: bitmask of doorbell events triggered.
+ */
+u32 mic_ack_interrupt(struct mic_device *mdev)
+{
+       return 0;
+}
+
+static inline int mic_get_sbox_irq(int db)
+{
+       return MIC_X100_IRQ_BASE + db;
+}
+
+static inline int mic_get_rdmasr_irq(int index)
+{
+       return  MIC_X100_RDMASR_IRQ_BASE + index;
+}
+
+/**
+ * mic_hw_intr_init - Initialize h/w specific interrupt
+ * information.
+ * @mdrv: pointer to mic_driver
+ */
+void mic_hw_intr_init(struct mic_driver *mdrv)
+{
+       mdrv->intr_info.num_intr = MIC_X100_NUM_SBOX_IRQ +
+                               MIC_X100_NUM_RDMASR_IRQ;
+}
+
+/**
+ * mic_db_to_irq - Retrieve irq number corresponding to a doorbell.
+ * @mdrv: pointer to mic_driver
+ * @db: The doorbell obtained for which the irq is needed. Doorbell
+ * may correspond to an sbox doorbell or an rdmasr index.
+ *
+ * Returns the irq corresponding to the doorbell.
+ */
+int mic_db_to_irq(struct mic_driver *mdrv, int db)
+{
+       int rdmasr_index;
+       if (db < MIC_X100_NUM_SBOX_IRQ) {
+               return mic_get_sbox_irq(db);
+       } else {
+               rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ +
+                       MIC_X100_RDMASR_IRQ_BASE;
+               return mic_get_rdmasr_irq(rdmasr_index);
+       }
+}
+
+/*
+ * mic_card_map - Allocate virtual address for a remote memory region.
+ * @mdev: pointer to mic_device instance.
+ * @addr: Remote DMA address.
+ * @size: Size of the region.
+ *
+ * Returns: Virtual address backing the remote memory region.
+ */
+void __iomem *
+mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size)
+{
+       return ioremap(addr, size);
+}
+
+/*
+ * mic_card_unmap - Unmap the virtual address for a remote memory region.
+ * @mdev: pointer to mic_device instance.
+ * @addr: Virtual address for remote memory region.
+ *
+ * Returns: None.
+ */
+void mic_card_unmap(struct mic_device *mdev, void __iomem *addr)
+{
+       iounmap(addr);
+}
+
+static int __init mic_probe(struct platform_device *pdev)
+{
+       struct mic_driver *mdrv = &g_drv;
+       struct mic_device *mdev = &mdrv->mdev;
+       int rc = 0;
+
+       mdrv->dev = &pdev->dev;
+       snprintf(mdrv->name, sizeof(mic_driver_name), mic_driver_name);
+
+       mdev->mmio.pa = MIC_X100_MMIO_BASE;
+       mdev->mmio.len = MIC_X100_MMIO_LEN;
+       mdev->mmio.va = ioremap(MIC_X100_MMIO_BASE, MIC_X100_MMIO_LEN);
+       if (!mdev->mmio.va) {
+               dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
+               rc = -EIO;
+               goto done;
+       }
+       mic_hw_intr_init(mdrv);
+       rc = mic_driver_init(mdrv);
+       if (rc) {
+               dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc);
+               goto iounmap;
+       }
+done:
+       return rc;
+iounmap:
+       iounmap(mdev->mmio.va);
+       return rc;
+}
+
+static int mic_remove(struct platform_device *pdev)
+{
+       struct mic_driver *mdrv = &g_drv;
+       struct mic_device *mdev = &mdrv->mdev;
+
+       mic_driver_uninit(mdrv);
+       iounmap(mdev->mmio.va);
+       return 0;
+}
+
+static void mic_platform_shutdown(struct platform_device *pdev)
+{
+       mic_remove(pdev);
+}
+
+static struct platform_device mic_platform_dev = {
+       .name = mic_driver_name,
+       .id   = 0,
+       .num_resources = 0,
+};
+
+static struct platform_driver __refdata mic_platform_driver = {
+       .probe = mic_probe,
+       .remove = mic_remove,
+       .shutdown = mic_platform_shutdown,
+       .driver         = {
+               .name   = mic_driver_name,
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init mic_init(void)
+{
+       int ret;
+       struct cpuinfo_x86 *c = &cpu_data(0);
+
+       if (!(c->x86 == 11 && c->x86_model == 1)) {
+               ret = -ENODEV;
+               pr_err("%s not running on X100 ret %d\n", __func__, ret);
+               goto done;
+       }
+
+       mic_init_card_debugfs();
+       ret = platform_device_register(&mic_platform_dev);
+       if (ret) {
+               pr_err("platform_device_register ret %d\n", ret);
+               goto cleanup_debugfs;
+       }
+       ret = platform_driver_register(&mic_platform_driver);
+       if (ret) {
+               pr_err("platform_driver_register ret %d\n", ret);
+               goto device_unregister;
+       }
+       return ret;
+
+device_unregister:
+       platform_device_unregister(&mic_platform_dev);
+cleanup_debugfs:
+       mic_exit_card_debugfs();
+done:
+       return ret;
+}
+
+static void __exit mic_exit(void)
+{
+       platform_driver_unregister(&mic_platform_driver);
+       platform_device_unregister(&mic_platform_dev);
+       mic_exit_card_debugfs();
+}
+
+module_init(mic_init);
+module_exit(mic_exit);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) MIC X100 Card driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/card/mic_x100.h b/drivers/misc/mic/card/mic_x100.h
new file mode 100644 (file)
index 0000000..d66ea55
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Disclaimer: The codes contained in these modules may be specific to
+ * the Intel Software Development Platform codenamed: Knights Ferry, and
+ * the Intel product codenamed: Knights Corner, and are not backward
+ * compatible with other Intel products. Additionally, Intel will NOT
+ * support the codes or instruction set in future products.
+ *
+ * Intel MIC Card driver.
+ *
+ */
+#ifndef _MIC_X100_CARD_H_
+#define _MIC_X100_CARD_H_
+
+#define MIC_X100_MMIO_BASE 0x08007C0000ULL
+#define MIC_X100_MMIO_LEN 0x00020000ULL
+#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000ULL
+
+#define MIC_X100_SBOX_SPAD0 0x0000AB20
+#define MIC_X100_SBOX_SDBIC0 0x0000CC90
+#define MIC_X100_SBOX_SDBIC0_DBREQ_BIT 0x80000000
+#define MIC_X100_SBOX_RDMASR0  0x0000B180
+
+#define MIC_X100_MAX_DOORBELL_IDX 8
+
+#define MIC_X100_NUM_SBOX_IRQ 8
+#define MIC_X100_NUM_RDMASR_IRQ 8
+#define MIC_X100_SBOX_IRQ_BASE 0
+#define MIC_X100_RDMASR_IRQ_BASE 17
+
+#define MIC_X100_IRQ_BASE 26
+
+#endif
diff --git a/drivers/misc/mic/common/mic_dev.h b/drivers/misc/mic/common/mic_dev.h
new file mode 100644 (file)
index 0000000..92999c2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC driver.
+ *
+ */
+#ifndef __MIC_DEV_H__
+#define __MIC_DEV_H__
+
+/**
+ * struct mic_mw - MIC memory window
+ *
+ * @pa: Base physical address.
+ * @va: Base ioremap'd virtual address.
+ * @len: Size of the memory window.
+ */
+struct mic_mw {
+       phys_addr_t pa;
+       void __iomem *va;
+       resource_size_t len;
+};
+
+/*
+ * Scratch pad register offsets used by the host to communicate
+ * device page DMA address to the card.
+ */
+#define MIC_DPLO_SPAD 14
+#define MIC_DPHI_SPAD 15
+
+/*
+ * These values are supposed to be in the config_change field of the
+ * device page when the host sends a config change interrupt to the card.
+ */
+#define MIC_VIRTIO_PARAM_DEV_REMOVE 0x1
+#define MIC_VIRTIO_PARAM_CONFIG_CHANGED 0x2
+
+#endif
diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile
new file mode 100644 (file)
index 0000000..c2197f9
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile - Intel MIC Linux driver.
+# Copyright(c) 2013, Intel Corporation.
+#
+obj-$(CONFIG_INTEL_MIC_HOST) += mic_host.o
+mic_host-objs := mic_main.o
+mic_host-objs += mic_x100.o
+mic_host-objs += mic_sysfs.o
+mic_host-objs += mic_smpt.o
+mic_host-objs += mic_intr.o
+mic_host-objs += mic_boot.o
+mic_host-objs += mic_debugfs.o
+mic_host-objs += mic_fops.o
+mic_host-objs += mic_virtio.o
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c
new file mode 100644 (file)
index 0000000..b079c65
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/pci.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_smpt.h"
+#include "mic_virtio.h"
+
+/**
+ * mic_reset - Reset the MIC device.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_reset(struct mic_device *mdev)
+{
+       int i;
+
+#define MIC_RESET_TO (45)
+
+       INIT_COMPLETION(mdev->reset_wait);
+       mdev->ops->reset_fw_ready(mdev);
+       mdev->ops->reset(mdev);
+
+       for (i = 0; i < MIC_RESET_TO; i++) {
+               if (mdev->ops->is_fw_ready(mdev))
+                       goto done;
+               /*
+                * Resets typically take 10s of seconds to complete.
+                * Since an MMIO read is required to check if the
+                * firmware is ready or not, a 1 second delay works nicely.
+                */
+               msleep(1000);
+       }
+       mic_set_state(mdev, MIC_RESET_FAILED);
+done:
+       complete_all(&mdev->reset_wait);
+}
+
+/* Initialize the MIC bootparams */
+void mic_bootparam_init(struct mic_device *mdev)
+{
+       struct mic_bootparam *bootparam = mdev->dp;
+
+       bootparam->magic = MIC_MAGIC;
+       bootparam->c2h_shutdown_db = mdev->shutdown_db;
+       bootparam->h2c_shutdown_db = -1;
+       bootparam->h2c_config_db = -1;
+       bootparam->shutdown_status = 0;
+       bootparam->shutdown_card = 0;
+}
+
+/**
+ * mic_start - Start the MIC.
+ * @mdev: pointer to mic_device instance
+ * @buf: buffer containing boot string including firmware/ramdisk path.
+ *
+ * This function prepares an MIC for boot and initiates boot.
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+int mic_start(struct mic_device *mdev, const char *buf)
+{
+       int rc;
+       mutex_lock(&mdev->mic_mutex);
+retry:
+       if (MIC_OFFLINE != mdev->state) {
+               rc = -EINVAL;
+               goto unlock_ret;
+       }
+       if (!mdev->ops->is_fw_ready(mdev)) {
+               mic_reset(mdev);
+               /*
+                * The state will either be MIC_OFFLINE if the reset succeeded
+                * or MIC_RESET_FAILED if the firmware reset failed.
+                */
+               goto retry;
+       }
+       rc = mdev->ops->load_mic_fw(mdev, buf);
+       if (rc)
+               goto unlock_ret;
+       mic_smpt_restore(mdev);
+       mic_intr_restore(mdev);
+       mdev->intr_ops->enable_interrupts(mdev);
+       mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
+       mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
+       mdev->ops->send_firmware_intr(mdev);
+       mic_set_state(mdev, MIC_ONLINE);
+unlock_ret:
+       mutex_unlock(&mdev->mic_mutex);
+       return rc;
+}
+
+/**
+ * mic_stop - Prepare the MIC for reset and trigger reset.
+ * @mdev: pointer to mic_device instance
+ * @force: force a MIC to reset even if it is already offline.
+ *
+ * RETURNS: None.
+ */
+void mic_stop(struct mic_device *mdev, bool force)
+{
+       mutex_lock(&mdev->mic_mutex);
+       if (MIC_OFFLINE != mdev->state || force) {
+               mic_virtio_reset_devices(mdev);
+               mic_bootparam_init(mdev);
+               mic_reset(mdev);
+               if (MIC_RESET_FAILED == mdev->state)
+                       goto unlock;
+               mic_set_shutdown_status(mdev, MIC_NOP);
+               if (MIC_SUSPENDED != mdev->state)
+                       mic_set_state(mdev, MIC_OFFLINE);
+       }
+unlock:
+       mutex_unlock(&mdev->mic_mutex);
+}
+
+/**
+ * mic_shutdown - Initiate MIC shutdown.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: None.
+ */
+void mic_shutdown(struct mic_device *mdev)
+{
+       struct mic_bootparam *bootparam = mdev->dp;
+       s8 db = bootparam->h2c_shutdown_db;
+
+       mutex_lock(&mdev->mic_mutex);
+       if (MIC_ONLINE == mdev->state && db != -1) {
+               bootparam->shutdown_card = 1;
+               mdev->ops->send_intr(mdev, db);
+               mic_set_state(mdev, MIC_SHUTTING_DOWN);
+       }
+       mutex_unlock(&mdev->mic_mutex);
+}
+
+/**
+ * mic_shutdown_work - Handle shutdown interrupt from MIC.
+ * @work: The work structure.
+ *
+ * This work is scheduled whenever the host has received a shutdown
+ * interrupt from the MIC.
+ */
+void mic_shutdown_work(struct work_struct *work)
+{
+       struct mic_device *mdev = container_of(work, struct mic_device,
+                       shutdown_work);
+       struct mic_bootparam *bootparam = mdev->dp;
+
+       mutex_lock(&mdev->mic_mutex);
+       mic_set_shutdown_status(mdev, bootparam->shutdown_status);
+       bootparam->shutdown_status = 0;
+
+       /*
+        * if state is MIC_SUSPENDED, OSPM suspend is in progress. We do not
+        * change the state here so as to prevent users from booting the card
+        * during and after the suspend operation.
+        */
+       if (MIC_SHUTTING_DOWN != mdev->state &&
+           MIC_SUSPENDED != mdev->state)
+               mic_set_state(mdev, MIC_SHUTTING_DOWN);
+       mutex_unlock(&mdev->mic_mutex);
+}
+
+/**
+ * mic_reset_trigger_work - Trigger MIC reset.
+ * @work: The work structure.
+ *
+ * This work is scheduled whenever the host wants to reset the MIC.
+ */
+void mic_reset_trigger_work(struct work_struct *work)
+{
+       struct mic_device *mdev = container_of(work, struct mic_device,
+                       reset_trigger_work);
+
+       mic_stop(mdev, false);
+}
+
+/**
+ * mic_complete_resume - Complete MIC Resume after an OSPM suspend/hibernate
+ * event.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: None.
+ */
+void mic_complete_resume(struct mic_device *mdev)
+{
+       if (mdev->state != MIC_SUSPENDED) {
+               dev_warn(mdev->sdev->parent, "state %d should be %d\n",
+                        mdev->state, MIC_SUSPENDED);
+               return;
+       }
+
+       /* Make sure firmware is ready */
+       if (!mdev->ops->is_fw_ready(mdev))
+               mic_stop(mdev, true);
+
+       mutex_lock(&mdev->mic_mutex);
+       mic_set_state(mdev, MIC_OFFLINE);
+       mutex_unlock(&mdev->mic_mutex);
+}
+
+/**
+ * mic_prepare_suspend - Handle suspend notification for the MIC device.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: None.
+ */
+void mic_prepare_suspend(struct mic_device *mdev)
+{
+       int rc;
+
+#define MIC_SUSPEND_TIMEOUT (60 * HZ)
+
+       mutex_lock(&mdev->mic_mutex);
+       switch (mdev->state) {
+       case MIC_OFFLINE:
+               /*
+                * Card is already offline. Set state to MIC_SUSPENDED
+                * to prevent users from booting the card.
+                */
+               mic_set_state(mdev, MIC_SUSPENDED);
+               mutex_unlock(&mdev->mic_mutex);
+               break;
+       case MIC_ONLINE:
+               /*
+                * Card is online. Set state to MIC_SUSPENDING and notify
+                * MIC user space daemon which will issue card
+                * shutdown and reset.
+                */
+               mic_set_state(mdev, MIC_SUSPENDING);
+               mutex_unlock(&mdev->mic_mutex);
+               rc = wait_for_completion_timeout(&mdev->reset_wait,
+                                               MIC_SUSPEND_TIMEOUT);
+               /* Force reset the card if the shutdown completion timed out */
+               if (!rc) {
+                       mutex_lock(&mdev->mic_mutex);
+                       mic_set_state(mdev, MIC_SUSPENDED);
+                       mutex_unlock(&mdev->mic_mutex);
+                       mic_stop(mdev, true);
+               }
+               break;
+       case MIC_SHUTTING_DOWN:
+               /*
+                * Card is shutting down. Set state to MIC_SUSPENDED
+                * to prevent further boot of the card.
+                */
+               mic_set_state(mdev, MIC_SUSPENDED);
+               mutex_unlock(&mdev->mic_mutex);
+               rc = wait_for_completion_timeout(&mdev->reset_wait,
+                                               MIC_SUSPEND_TIMEOUT);
+               /* Force reset the card if the shutdown completion timed out */
+               if (!rc)
+                       mic_stop(mdev, true);
+               break;
+       default:
+               mutex_unlock(&mdev->mic_mutex);
+               break;
+       }
+}
+
+/**
+ * mic_suspend - Initiate MIC suspend. Suspend merely issues card shutdown.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: None.
+ */
+void mic_suspend(struct mic_device *mdev)
+{
+       struct mic_bootparam *bootparam = mdev->dp;
+       s8 db = bootparam->h2c_shutdown_db;
+
+       mutex_lock(&mdev->mic_mutex);
+       if (MIC_SUSPENDING == mdev->state && db != -1) {
+               bootparam->shutdown_card = 1;
+               mdev->ops->send_intr(mdev, db);
+               mic_set_state(mdev, MIC_SUSPENDED);
+       }
+       mutex_unlock(&mdev->mic_mutex);
+}
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c
new file mode 100644 (file)
index 0000000..028ba5d
--- /dev/null
@@ -0,0 +1,491 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/debugfs.h>
+#include <linux/pci.h>
+#include <linux/seq_file.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_smpt.h"
+#include "mic_virtio.h"
+
+/* Debugfs parent dir */
+static struct dentry *mic_dbg;
+
+/**
+ * mic_log_buf_show - Display MIC kernel log buffer.
+ *
+ * log_buf addr/len is read from System.map by user space
+ * and populated in sysfs entries.
+ */
+static int mic_log_buf_show(struct seq_file *s, void *unused)
+{
+       void __iomem *log_buf_va;
+       int __iomem *log_buf_len_va;
+       struct mic_device *mdev = s->private;
+       void *kva;
+       int size;
+       unsigned long aper_offset;
+
+       if (!mdev || !mdev->log_buf_addr || !mdev->log_buf_len)
+               goto done;
+       /*
+        * Card kernel will never be relocated and any kernel text/data mapping
+        * can be translated to phys address by subtracting __START_KERNEL_map.
+        */
+       aper_offset = (unsigned long)mdev->log_buf_len - __START_KERNEL_map;
+       log_buf_len_va = mdev->aper.va + aper_offset;
+       aper_offset = (unsigned long)mdev->log_buf_addr - __START_KERNEL_map;
+       log_buf_va = mdev->aper.va + aper_offset;
+       size = ioread32(log_buf_len_va);
+
+       kva = kmalloc(size, GFP_KERNEL);
+       if (!kva)
+               goto done;
+       mutex_lock(&mdev->mic_mutex);
+       memcpy_fromio(kva, log_buf_va, size);
+       switch (mdev->state) {
+       case MIC_ONLINE:
+               /* Fall through */
+       case MIC_SHUTTING_DOWN:
+               seq_write(s, kva, size);
+               break;
+       default:
+               break;
+       }
+       mutex_unlock(&mdev->mic_mutex);
+       kfree(kva);
+done:
+       return 0;
+}
+
+static int mic_log_buf_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_log_buf_show, inode->i_private);
+}
+
+static int mic_log_buf_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations log_buf_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_log_buf_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_log_buf_release
+};
+
+static int mic_smpt_show(struct seq_file *s, void *pos)
+{
+       int i;
+       struct mic_device *mdev = s->private;
+       unsigned long flags;
+
+       seq_printf(s, "MIC %-2d |%-10s| %-14s %-10s\n",
+                  mdev->id, "SMPT entry", "SW DMA addr", "RefCount");
+       seq_puts(s, "====================================================\n");
+
+       if (mdev->smpt) {
+               struct mic_smpt_info *smpt_info = mdev->smpt;
+               spin_lock_irqsave(&smpt_info->smpt_lock, flags);
+               for (i = 0; i < smpt_info->info.num_reg; i++) {
+                       seq_printf(s, "%9s|%-10d| %-#14llx %-10lld\n",
+                                  " ",  i, smpt_info->entry[i].dma_addr,
+                                  smpt_info->entry[i].ref_count);
+               }
+               spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
+       }
+       seq_puts(s, "====================================================\n");
+       return 0;
+}
+
+static int mic_smpt_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_smpt_show, inode->i_private);
+}
+
+static int mic_smpt_debug_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations smpt_file_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_smpt_debug_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_smpt_debug_release
+};
+
+static int mic_soft_reset_show(struct seq_file *s, void *pos)
+{
+       struct mic_device *mdev = s->private;
+
+       mic_stop(mdev, true);
+       return 0;
+}
+
+static int mic_soft_reset_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_soft_reset_show, inode->i_private);
+}
+
+static int mic_soft_reset_debug_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations soft_reset_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_soft_reset_debug_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_soft_reset_debug_release
+};
+
+static int mic_post_code_show(struct seq_file *s, void *pos)
+{
+       struct mic_device *mdev = s->private;
+       u32 reg = mdev->ops->get_postcode(mdev);
+
+       seq_printf(s, "%c%c", reg & 0xff, (reg >> 8) & 0xff);
+       return 0;
+}
+
+static int mic_post_code_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_post_code_show, inode->i_private);
+}
+
+static int mic_post_code_debug_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations post_code_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_post_code_debug_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_post_code_debug_release
+};
+
+static int mic_dp_show(struct seq_file *s, void *pos)
+{
+       struct mic_device *mdev = s->private;
+       struct mic_device_desc *d;
+       struct mic_device_ctrl *dc;
+       struct mic_vqconfig *vqconfig;
+       __u32 *features;
+       __u8 *config;
+       struct mic_bootparam *bootparam = mdev->dp;
+       int i, j;
+
+       seq_printf(s, "Bootparam: magic 0x%x\n",
+                  bootparam->magic);
+       seq_printf(s, "Bootparam: h2c_shutdown_db %d\n",
+                  bootparam->h2c_shutdown_db);
+       seq_printf(s, "Bootparam: h2c_config_db %d\n",
+                  bootparam->h2c_config_db);
+       seq_printf(s, "Bootparam: c2h_shutdown_db %d\n",
+                  bootparam->c2h_shutdown_db);
+       seq_printf(s, "Bootparam: shutdown_status %d\n",
+                  bootparam->shutdown_status);
+       seq_printf(s, "Bootparam: shutdown_card %d\n",
+                  bootparam->shutdown_card);
+
+       for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
+            i += mic_total_desc_size(d)) {
+               d = mdev->dp + i;
+               dc = (void *)d + mic_aligned_desc_size(d);
+
+               /* end of list */
+               if (d->type == 0)
+                       break;
+
+               if (d->type == -1)
+                       continue;
+
+               seq_printf(s, "Type %d ", d->type);
+               seq_printf(s, "Num VQ %d ", d->num_vq);
+               seq_printf(s, "Feature Len %d\n", d->feature_len);
+               seq_printf(s, "Config Len %d ", d->config_len);
+               seq_printf(s, "Shutdown Status %d\n", d->status);
+
+               for (j = 0; j < d->num_vq; j++) {
+                       vqconfig = mic_vq_config(d) + j;
+                       seq_printf(s, "vqconfig[%d]: ", j);
+                       seq_printf(s, "address 0x%llx ", vqconfig->address);
+                       seq_printf(s, "num %d ", vqconfig->num);
+                       seq_printf(s, "used address 0x%llx\n",
+                                  vqconfig->used_address);
+               }
+
+               features = (__u32 *)mic_vq_features(d);
+               seq_printf(s, "Features: Host 0x%x ", features[0]);
+               seq_printf(s, "Guest 0x%x\n", features[1]);
+
+               config = mic_vq_configspace(d);
+               for (j = 0; j < d->config_len; j++)
+                       seq_printf(s, "config[%d]=%d\n", j, config[j]);
+
+               seq_puts(s, "Device control:\n");
+               seq_printf(s, "Config Change %d ", dc->config_change);
+               seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
+               seq_printf(s, "Guest Ack %d ", dc->guest_ack);
+               seq_printf(s, "Host ack %d\n", dc->host_ack);
+               seq_printf(s, "Used address updated %d ",
+                          dc->used_address_updated);
+               seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
+               seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
+               seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
+       }
+
+       return 0;
+}
+
+static int mic_dp_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_dp_show, inode->i_private);
+}
+
+static int mic_dp_debug_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations dp_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_dp_debug_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_dp_debug_release
+};
+
+static int mic_vdev_info_show(struct seq_file *s, void *unused)
+{
+       struct mic_device *mdev = s->private;
+       struct list_head *pos, *tmp;
+       struct mic_vdev *mvdev;
+       int i, j;
+
+       mutex_lock(&mdev->mic_mutex);
+       list_for_each_safe(pos, tmp, &mdev->vdev_list) {
+               mvdev = list_entry(pos, struct mic_vdev, list);
+               seq_printf(s, "VDEV type %d state %s in %ld out %ld\n",
+                          mvdev->virtio_id,
+                          mic_vdevup(mvdev) ? "UP" : "DOWN",
+                          mvdev->in_bytes,
+                          mvdev->out_bytes);
+               for (i = 0; i < MIC_MAX_VRINGS; i++) {
+                       struct vring_desc *desc;
+                       struct vring_avail *avail;
+                       struct vring_used *used;
+                       struct mic_vringh *mvr = &mvdev->mvr[i];
+                       struct vringh *vrh = &mvr->vrh;
+                       int num = vrh->vring.num;
+                       if (!num)
+                               continue;
+                       desc = vrh->vring.desc;
+                       seq_printf(s, "vring i %d avail_idx %d",
+                                  i, mvr->vring.info->avail_idx & (num - 1));
+                       seq_printf(s, " vring i %d avail_idx %d\n",
+                                  i, mvr->vring.info->avail_idx);
+                       seq_printf(s, "vrh i %d weak_barriers %d",
+                                  i, vrh->weak_barriers);
+                       seq_printf(s, " last_avail_idx %d last_used_idx %d",
+                                  vrh->last_avail_idx, vrh->last_used_idx);
+                       seq_printf(s, " completed %d\n", vrh->completed);
+                       for (j = 0; j < num; j++) {
+                               seq_printf(s, "desc[%d] addr 0x%llx len %d",
+                                          j, desc->addr, desc->len);
+                               seq_printf(s, " flags 0x%x next %d\n",
+                                          desc->flags, desc->next);
+                               desc++;
+                       }
+                       avail = vrh->vring.avail;
+                       seq_printf(s, "avail flags 0x%x idx %d\n",
+                                  avail->flags, avail->idx & (num - 1));
+                       seq_printf(s, "avail flags 0x%x idx %d\n",
+                                  avail->flags, avail->idx);
+                       for (j = 0; j < num; j++)
+                               seq_printf(s, "avail ring[%d] %d\n",
+                                          j, avail->ring[j]);
+                       used = vrh->vring.used;
+                       seq_printf(s, "used flags 0x%x idx %d\n",
+                                  used->flags, used->idx & (num - 1));
+                       seq_printf(s, "used flags 0x%x idx %d\n",
+                                  used->flags, used->idx);
+                       for (j = 0; j < num; j++)
+                               seq_printf(s, "used ring[%d] id %d len %d\n",
+                                          j, used->ring[j].id,
+                                          used->ring[j].len);
+               }
+       }
+       mutex_unlock(&mdev->mic_mutex);
+
+       return 0;
+}
+
+static int mic_vdev_info_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_vdev_info_show, inode->i_private);
+}
+
+static int mic_vdev_info_debug_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations vdev_info_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_vdev_info_debug_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_vdev_info_debug_release
+};
+
+static int mic_msi_irq_info_show(struct seq_file *s, void *pos)
+{
+       struct mic_device *mdev  = s->private;
+       int reg;
+       int i, j;
+       u16 entry;
+       u16 vector;
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+
+       if (pci_dev_msi_enabled(pdev)) {
+               for (i = 0; i < mdev->irq_info.num_vectors; i++) {
+                       if (pdev->msix_enabled) {
+                               entry = mdev->irq_info.msix_entries[i].entry;
+                               vector = mdev->irq_info.msix_entries[i].vector;
+                       } else {
+                               entry = 0;
+                               vector = pdev->irq;
+                       }
+
+                       reg = mdev->intr_ops->read_msi_to_src_map(mdev, entry);
+
+                       seq_printf(s, "%s %-10d %s %-10d MXAR[%d]: %08X\n",
+                                  "IRQ:", vector, "Entry:", entry, i, reg);
+
+                       seq_printf(s, "%-10s", "offset:");
+                       for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
+                               seq_printf(s, "%4d ", j);
+                       seq_puts(s, "\n");
+
+
+                       seq_printf(s, "%-10s", "count:");
+                       for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
+                               seq_printf(s, "%4d ",
+                                          (mdev->irq_info.mic_msi_map[i] &
+                                          BIT(j)) ? 1 : 0);
+                       seq_puts(s, "\n\n");
+               }
+       } else {
+               seq_puts(s, "MSI/MSIx interrupts not enabled\n");
+       }
+
+       return 0;
+}
+
+static int mic_msi_irq_info_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mic_msi_irq_info_show, inode->i_private);
+}
+
+static int
+mic_msi_irq_info_debug_release(struct inode *inode, struct file *file)
+{
+       return single_release(inode, file);
+}
+
+static const struct file_operations msi_irq_info_ops = {
+       .owner   = THIS_MODULE,
+       .open    = mic_msi_irq_info_debug_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = mic_msi_irq_info_debug_release
+};
+
+/**
+ * mic_create_debug_dir - Initialize MIC debugfs entries.
+ */
+void mic_create_debug_dir(struct mic_device *mdev)
+{
+       if (!mic_dbg)
+               return;
+
+       mdev->dbg_dir = debugfs_create_dir(dev_name(mdev->sdev), mic_dbg);
+       if (!mdev->dbg_dir)
+               return;
+
+       debugfs_create_file("log_buf", 0444, mdev->dbg_dir, mdev, &log_buf_ops);
+
+       debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, &smpt_file_ops);
+
+       debugfs_create_file("soft_reset", 0444, mdev->dbg_dir, mdev,
+                           &soft_reset_ops);
+
+       debugfs_create_file("post_code", 0444, mdev->dbg_dir, mdev,
+                           &post_code_ops);
+
+       debugfs_create_file("dp", 0444, mdev->dbg_dir, mdev, &dp_ops);
+
+       debugfs_create_file("vdev_info", 0444, mdev->dbg_dir, mdev,
+                           &vdev_info_ops);
+
+       debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir, mdev,
+                           &msi_irq_info_ops);
+}
+
+/**
+ * mic_delete_debug_dir - Uninitialize MIC debugfs entries.
+ */
+void mic_delete_debug_dir(struct mic_device *mdev)
+{
+       if (!mdev->dbg_dir)
+               return;
+
+       debugfs_remove_recursive(mdev->dbg_dir);
+}
+
+/**
+ * mic_init_debugfs - Initialize global debugfs entry.
+ */
+void __init mic_init_debugfs(void)
+{
+       mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       if (!mic_dbg)
+               pr_err("can't create debugfs dir\n");
+}
+
+/**
+ * mic_exit_debugfs - Uninitialize global debugfs entry
+ */
+void mic_exit_debugfs(void)
+{
+       debugfs_remove(mic_dbg);
+}
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h
new file mode 100644 (file)
index 0000000..3574cc3
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef _MIC_DEVICE_H_
+#define _MIC_DEVICE_H_
+
+#include <linux/cdev.h>
+#include <linux/idr.h>
+#include <linux/notifier.h>
+
+#include "mic_intr.h"
+
+/* The maximum number of MIC devices supported in a single host system. */
+#define MIC_MAX_NUM_DEVS 256
+
+/**
+ * enum mic_hw_family - The hardware family to which a device belongs.
+ */
+enum mic_hw_family {
+       MIC_FAMILY_X100 = 0,
+       MIC_FAMILY_UNKNOWN
+};
+
+/**
+ * enum mic_stepping - MIC stepping ids.
+ */
+enum mic_stepping {
+       MIC_A0_STEP = 0x0,
+       MIC_B0_STEP = 0x10,
+       MIC_B1_STEP = 0x11,
+       MIC_C0_STEP = 0x20,
+};
+
+/**
+ * struct mic_device -  MIC device information for each card.
+ *
+ * @mmio: MMIO bar information.
+ * @aper: Aperture bar information.
+ * @family: The MIC family to which this device belongs.
+ * @ops: MIC HW specific operations.
+ * @id: The unique device id for this MIC device.
+ * @stepping: Stepping ID.
+ * @attr_group: Pointer to list of sysfs attribute groups.
+ * @sdev: Device for sysfs entries.
+ * @mic_mutex: Mutex for synchronizing access to mic_device.
+ * @intr_ops: HW specific interrupt operations.
+ * @smpt_ops: Hardware specific SMPT operations.
+ * @smpt: MIC SMPT information.
+ * @intr_info: H/W specific interrupt information.
+ * @irq_info: The OS specific irq information
+ * @dbg_dir: debugfs directory of this MIC device.
+ * @cmdline: Kernel command line.
+ * @firmware: Firmware file name.
+ * @ramdisk: Ramdisk file name.
+ * @bootmode: Boot mode i.e. "linux" or "elf" for flash updates.
+ * @bootaddr: MIC boot address.
+ * @reset_trigger_work: Work for triggering reset requests.
+ * @shutdown_work: Work for handling shutdown interrupts.
+ * @state: MIC state.
+ * @shutdown_status: MIC status reported by card for shutdown/crashes.
+ * @state_sysfs: Sysfs dirent for notifying ring 3 about MIC state changes.
+ * @reset_wait: Waitqueue for sleeping while reset completes.
+ * @log_buf_addr: Log buffer address for MIC.
+ * @log_buf_len: Log buffer length address for MIC.
+ * @dp: virtio device page
+ * @dp_dma_addr: virtio device page DMA address.
+ * @shutdown_db: shutdown doorbell.
+ * @shutdown_cookie: shutdown cookie.
+ * @cdev: Character device for MIC.
+ * @vdev_list: list of virtio devices.
+ * @pm_notifier: Handles PM notifications from the OS.
+ */
+struct mic_device {
+       struct mic_mw mmio;
+       struct mic_mw aper;
+       enum mic_hw_family family;
+       struct mic_hw_ops *ops;
+       int id;
+       enum mic_stepping stepping;
+       const struct attribute_group **attr_group;
+       struct device *sdev;
+       struct mutex mic_mutex;
+       struct mic_hw_intr_ops *intr_ops;
+       struct mic_smpt_ops *smpt_ops;
+       struct mic_smpt_info *smpt;
+       struct mic_intr_info *intr_info;
+       struct mic_irq_info irq_info;
+       struct dentry *dbg_dir;
+       char *cmdline;
+       char *firmware;
+       char *ramdisk;
+       char *bootmode;
+       u32 bootaddr;
+       struct work_struct reset_trigger_work;
+       struct work_struct shutdown_work;
+       u8 state;
+       u8 shutdown_status;
+       struct sysfs_dirent *state_sysfs;
+       struct completion reset_wait;
+       void *log_buf_addr;
+       int *log_buf_len;
+       void *dp;
+       dma_addr_t dp_dma_addr;
+       int shutdown_db;
+       struct mic_irq *shutdown_cookie;
+       struct cdev cdev;
+       struct list_head vdev_list;
+       struct notifier_block pm_notifier;
+};
+
+/**
+ * struct mic_hw_ops - MIC HW specific operations.
+ * @aper_bar: Aperture bar resource number.
+ * @mmio_bar: MMIO bar resource number.
+ * @read_spad: Read from scratch pad register.
+ * @write_spad: Write to scratch pad register.
+ * @send_intr: Send an interrupt for a particular doorbell on the card.
+ * @ack_interrupt: Hardware specific operations to ack the h/w on
+ * receipt of an interrupt.
+ * @reset: Reset the remote processor.
+ * @reset_fw_ready: Reset firmware ready field.
+ * @is_fw_ready: Check if firmware is ready for OS download.
+ * @send_firmware_intr: Send an interrupt to the card firmware.
+ * @load_mic_fw: Load firmware segments required to boot the card
+ * into card memory. This includes the kernel, command line, ramdisk etc.
+ * @get_postcode: Get post code status from firmware.
+ */
+struct mic_hw_ops {
+       u8 aper_bar;
+       u8 mmio_bar;
+       u32 (*read_spad)(struct mic_device *mdev, unsigned int idx);
+       void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val);
+       void (*send_intr)(struct mic_device *mdev, int doorbell);
+       u32 (*ack_interrupt)(struct mic_device *mdev);
+       void (*reset)(struct mic_device *mdev);
+       void (*reset_fw_ready)(struct mic_device *mdev);
+       bool (*is_fw_ready)(struct mic_device *mdev);
+       void (*send_firmware_intr)(struct mic_device *mdev);
+       int (*load_mic_fw)(struct mic_device *mdev, const char *buf);
+       u32 (*get_postcode)(struct mic_device *mdev);
+};
+
+/**
+ * mic_mmio_read - read from an MMIO register.
+ * @mw: MMIO register base virtual address.
+ * @offset: register offset.
+ *
+ * RETURNS: register value.
+ */
+static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset)
+{
+       return ioread32(mw->va + offset);
+}
+
+/**
+ * mic_mmio_write - write to an MMIO register.
+ * @mw: MMIO register base virtual address.
+ * @val: the data value to put into the register
+ * @offset: register offset.
+ *
+ * RETURNS: none.
+ */
+static inline void
+mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
+{
+       iowrite32(val, mw->va + offset);
+}
+
+void mic_sysfs_init(struct mic_device *mdev);
+int mic_start(struct mic_device *mdev, const char *buf);
+void mic_stop(struct mic_device *mdev, bool force);
+void mic_shutdown(struct mic_device *mdev);
+void mic_reset_delayed_work(struct work_struct *work);
+void mic_reset_trigger_work(struct work_struct *work);
+void mic_shutdown_work(struct work_struct *work);
+void mic_bootparam_init(struct mic_device *mdev);
+void mic_set_state(struct mic_device *mdev, u8 state);
+void mic_set_shutdown_status(struct mic_device *mdev, u8 status);
+void mic_create_debug_dir(struct mic_device *dev);
+void mic_delete_debug_dir(struct mic_device *dev);
+void __init mic_init_debugfs(void);
+void mic_exit_debugfs(void);
+void mic_prepare_suspend(struct mic_device *mdev);
+void mic_complete_resume(struct mic_device *mdev);
+void mic_suspend(struct mic_device *mdev);
+#endif
diff --git a/drivers/misc/mic/host/mic_fops.c b/drivers/misc/mic/host/mic_fops.c
new file mode 100644 (file)
index 0000000..85776d7
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/poll.h>
+#include <linux/pci.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_fops.h"
+#include "mic_virtio.h"
+
+int mic_open(struct inode *inode, struct file *f)
+{
+       struct mic_vdev *mvdev;
+       struct mic_device *mdev = container_of(inode->i_cdev,
+               struct mic_device, cdev);
+
+       mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
+       if (!mvdev)
+               return -ENOMEM;
+
+       init_waitqueue_head(&mvdev->waitq);
+       INIT_LIST_HEAD(&mvdev->list);
+       mvdev->mdev = mdev;
+       mvdev->virtio_id = -1;
+
+       f->private_data = mvdev;
+       return 0;
+}
+
+int mic_release(struct inode *inode, struct file *f)
+{
+       struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
+
+       if (-1 != mvdev->virtio_id)
+               mic_virtio_del_device(mvdev);
+       f->private_data = NULL;
+       kfree(mvdev);
+       return 0;
+}
+
+long mic_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+       struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
+       void __user *argp = (void __user *)arg;
+       int ret;
+
+       switch (cmd) {
+       case MIC_VIRTIO_ADD_DEVICE:
+       {
+               ret = mic_virtio_add_device(mvdev, argp);
+               if (ret < 0) {
+                       dev_err(mic_dev(mvdev),
+                               "%s %d errno ret %d\n",
+                               __func__, __LINE__, ret);
+                       return ret;
+               }
+               break;
+       }
+       case MIC_VIRTIO_COPY_DESC:
+       {
+               struct mic_copy_desc copy;
+
+               ret = mic_vdev_inited(mvdev);
+               if (ret)
+                       return ret;
+
+               if (copy_from_user(&copy, argp, sizeof(copy)))
+                       return -EFAULT;
+
+               dev_dbg(mic_dev(mvdev),
+                       "%s %d === iovcnt 0x%x vr_idx 0x%x update_used %d\n",
+                       __func__, __LINE__, copy.iovcnt, copy.vr_idx,
+                       copy.update_used);
+
+               ret = mic_virtio_copy_desc(mvdev, &copy);
+               if (ret < 0) {
+                       dev_err(mic_dev(mvdev),
+                               "%s %d errno ret %d\n",
+                               __func__, __LINE__, ret);
+                       return ret;
+               }
+               if (copy_to_user(
+                       &((struct mic_copy_desc __user *)argp)->out_len,
+                       &copy.out_len, sizeof(copy.out_len))) {
+                       dev_err(mic_dev(mvdev), "%s %d errno ret %d\n",
+                               __func__, __LINE__, -EFAULT);
+                       return -EFAULT;
+               }
+               break;
+       }
+       case MIC_VIRTIO_CONFIG_CHANGE:
+       {
+               ret = mic_vdev_inited(mvdev);
+               if (ret)
+                       return ret;
+
+               ret = mic_virtio_config_change(mvdev, argp);
+               if (ret < 0) {
+                       dev_err(mic_dev(mvdev),
+                               "%s %d errno ret %d\n",
+                               __func__, __LINE__, ret);
+                       return ret;
+               }
+               break;
+       }
+       default:
+               return -ENOIOCTLCMD;
+       };
+       return 0;
+}
+
+/*
+ * We return POLLIN | POLLOUT from poll when new buffers are enqueued, and
+ * not when previously enqueued buffers may be available. This means that
+ * in the card->host (TX) path, when userspace is unblocked by poll it
+ * must drain all available descriptors or it can stall.
+ */
+unsigned int mic_poll(struct file *f, poll_table *wait)
+{
+       struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
+       int mask = 0;
+
+       poll_wait(f, &mvdev->waitq, wait);
+
+       if (mic_vdev_inited(mvdev)) {
+               mask = POLLERR;
+       } else if (mvdev->poll_wake) {
+               mvdev->poll_wake = 0;
+               mask = POLLIN | POLLOUT;
+       }
+
+       return mask;
+}
+
+static inline int
+mic_query_offset(struct mic_vdev *mvdev, unsigned long offset,
+                unsigned long *size, unsigned long *pa)
+{
+       struct mic_device *mdev = mvdev->mdev;
+       unsigned long start = MIC_DP_SIZE;
+       int i;
+
+       /*
+        * MMAP interface is as follows:
+        * offset                               region
+        * 0x0                                  virtio device_page
+        * 0x1000                               first vring
+        * 0x1000 + size of 1st vring           second vring
+        * ....
+        */
+       if (!offset) {
+               *pa = virt_to_phys(mdev->dp);
+               *size = MIC_DP_SIZE;
+               return 0;
+       }
+
+       for (i = 0; i < mvdev->dd->num_vq; i++) {
+               struct mic_vringh *mvr = &mvdev->mvr[i];
+               if (offset == start) {
+                       *pa = virt_to_phys(mvr->vring.va);
+                       *size = mvr->vring.len;
+                       return 0;
+               }
+               start += mvr->vring.len;
+       }
+       return -1;
+}
+
+/*
+ * Maps the device page and virtio rings to user space for readonly access.
+ */
+int
+mic_mmap(struct file *f, struct vm_area_struct *vma)
+{
+       struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long pa, size = vma->vm_end - vma->vm_start, size_rem = size;
+       int i, err;
+
+       err = mic_vdev_inited(mvdev);
+       if (err)
+               return err;
+
+       if (vma->vm_flags & VM_WRITE)
+               return -EACCES;
+
+       while (size_rem) {
+               i = mic_query_offset(mvdev, offset, &size, &pa);
+               if (i < 0)
+                       return -EINVAL;
+               err = remap_pfn_range(vma, vma->vm_start + offset,
+                       pa >> PAGE_SHIFT, size, vma->vm_page_prot);
+               if (err)
+                       return err;
+               dev_dbg(mic_dev(mvdev),
+                       "%s %d type %d size 0x%lx off 0x%lx pa 0x%lx vma 0x%lx\n",
+                       __func__, __LINE__, mvdev->virtio_id, size, offset,
+                       pa, vma->vm_start + offset);
+               size_rem -= size;
+               offset += size;
+       }
+       return 0;
+}
diff --git a/drivers/misc/mic/host/mic_fops.h b/drivers/misc/mic/host/mic_fops.h
new file mode 100644 (file)
index 0000000..dc3893d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef _MIC_FOPS_H_
+#define _MIC_FOPS_H_
+
+int mic_open(struct inode *inode, struct file *filp);
+int mic_release(struct inode *inode, struct file *filp);
+ssize_t mic_read(struct file *filp, char __user *buf,
+                       size_t count, loff_t *pos);
+long mic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+int mic_mmap(struct file *f, struct vm_area_struct *vma);
+unsigned int mic_poll(struct file *f, poll_table *wait);
+
+#endif
diff --git a/drivers/misc/mic/host/mic_intr.c b/drivers/misc/mic/host/mic_intr.c
new file mode 100644 (file)
index 0000000..f9c29bc
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+
+/*
+ * mic_invoke_callback - Invoke callback functions registered for
+ * the corresponding source id.
+ *
+ * @mdev: pointer to the mic_device instance
+ * @idx: The interrupt source id.
+ *
+ * Returns none.
+ */
+static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
+{
+       struct mic_intr_cb *intr_cb;
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+
+       spin_lock(&mdev->irq_info.mic_intr_lock);
+       list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list)
+               if (intr_cb->func)
+                       intr_cb->func(pdev->irq, intr_cb->data);
+       spin_unlock(&mdev->irq_info.mic_intr_lock);
+}
+
+/**
+ * mic_interrupt - Generic interrupt handler for
+ * MSI and INTx based interrupts.
+ */
+static irqreturn_t mic_interrupt(int irq, void *dev)
+{
+       struct mic_device *mdev = dev;
+       struct mic_intr_info *info = mdev->intr_info;
+       u32 mask;
+       int i;
+
+       mask = mdev->ops->ack_interrupt(mdev);
+       if (!mask)
+               return IRQ_NONE;
+
+       for (i = info->intr_start_idx[MIC_INTR_DB];
+                       i < info->intr_len[MIC_INTR_DB]; i++)
+               if (mask & BIT(i))
+                       mic_invoke_callback(mdev, i);
+
+       return IRQ_HANDLED;
+}
+
+/* Return the interrupt offset from the index. Index is 0 based. */
+static u16 mic_map_src_to_offset(struct mic_device *mdev,
+               int intr_src, enum mic_intr_type type)
+{
+       if (type >= MIC_NUM_INTR_TYPES)
+               return MIC_NUM_OFFSETS;
+       if (intr_src >= mdev->intr_info->intr_len[type])
+               return MIC_NUM_OFFSETS;
+
+       return mdev->intr_info->intr_start_idx[type] + intr_src;
+}
+
+/* Return next available msix_entry. */
+static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
+{
+       int i;
+       struct mic_irq_info *info = &mdev->irq_info;
+
+       for (i = 0; i < info->num_vectors; i++)
+               if (!info->mic_msi_map[i])
+                       return &info->msix_entries[i];
+       return NULL;
+}
+
+/**
+ * mic_register_intr_callback - Register a callback handler for the
+ * given source id.
+ *
+ * @mdev: pointer to the mic_device instance
+ * @idx: The source id to be registered.
+ * @func: The function to be called when the source id receives
+ * the interrupt.
+ * @data: Private data of the requester.
+ * Return the callback structure that was registered or an
+ * appropriate error on failure.
+ */
+static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
+                       u8 idx, irqreturn_t (*func) (int irq, void *dev),
+                       void *data)
+{
+       struct mic_intr_cb *intr_cb;
+       unsigned long flags;
+       int rc;
+       intr_cb = kmalloc(sizeof(*intr_cb), GFP_KERNEL);
+
+       if (!intr_cb)
+               return ERR_PTR(-ENOMEM);
+
+       intr_cb->func = func;
+       intr_cb->data = data;
+       intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
+               0, 0, GFP_KERNEL);
+       if (intr_cb->cb_id < 0) {
+               rc = intr_cb->cb_id;
+               goto ida_fail;
+       }
+
+       spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
+       list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
+       spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
+
+       return intr_cb;
+ida_fail:
+       kfree(intr_cb);
+       return ERR_PTR(rc);
+}
+
+/**
+ * mic_unregister_intr_callback - Unregister the callback handler
+ * identified by its callback id.
+ *
+ * @mdev: pointer to the mic_device instance
+ * @idx: The callback structure id to be unregistered.
+ * Return the source id that was unregistered or MIC_NUM_OFFSETS if no
+ * such callback handler was found.
+ */
+static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
+{
+       struct list_head *pos, *tmp;
+       struct mic_intr_cb *intr_cb;
+       unsigned long flags;
+       int i;
+
+       for (i = 0;  i < MIC_NUM_OFFSETS; i++) {
+               spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
+               list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
+                       intr_cb = list_entry(pos, struct mic_intr_cb, list);
+                       if (intr_cb->cb_id == idx) {
+                               list_del(pos);
+                               ida_simple_remove(&mdev->irq_info.cb_ida,
+                                                 intr_cb->cb_id);
+                               kfree(intr_cb);
+                               spin_unlock_irqrestore(
+                                       &mdev->irq_info.mic_intr_lock, flags);
+                               return i;
+                       }
+               }
+               spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
+       }
+       return MIC_NUM_OFFSETS;
+}
+
+/**
+ * mic_setup_msix - Initializes MSIx interrupts.
+ *
+ * @mdev: pointer to mic_device instance
+ *
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev)
+{
+       int rc, i;
+       int entry_size = sizeof(*mdev->irq_info.msix_entries);
+
+       mdev->irq_info.msix_entries = kmalloc_array(MIC_MIN_MSIX,
+                                                   entry_size, GFP_KERNEL);
+       if (!mdev->irq_info.msix_entries) {
+               rc = -ENOMEM;
+               goto err_nomem1;
+       }
+
+       for (i = 0; i < MIC_MIN_MSIX; i++)
+               mdev->irq_info.msix_entries[i].entry = i;
+
+       rc = pci_enable_msix(pdev, mdev->irq_info.msix_entries,
+               MIC_MIN_MSIX);
+       if (rc) {
+               dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
+               goto err_enable_msix;
+       }
+
+       mdev->irq_info.num_vectors = MIC_MIN_MSIX;
+       mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
+               mdev->irq_info.num_vectors), GFP_KERNEL);
+
+       if (!mdev->irq_info.mic_msi_map) {
+               rc = -ENOMEM;
+               goto err_nomem2;
+       }
+
+       dev_dbg(mdev->sdev->parent,
+               "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
+       return 0;
+err_nomem2:
+       pci_disable_msix(pdev);
+err_enable_msix:
+       kfree(mdev->irq_info.msix_entries);
+err_nomem1:
+       mdev->irq_info.num_vectors = 0;
+       return rc;
+}
+
+/**
+ * mic_setup_callbacks - Initialize data structures needed
+ * to handle callbacks.
+ *
+ * @mdev: pointer to mic_device instance
+ */
+static int mic_setup_callbacks(struct mic_device *mdev)
+{
+       int i;
+
+       mdev->irq_info.cb_list = kmalloc_array(MIC_NUM_OFFSETS,
+                                              sizeof(*mdev->irq_info.cb_list),
+                                              GFP_KERNEL);
+       if (!mdev->irq_info.cb_list)
+               return -ENOMEM;
+
+       for (i = 0; i < MIC_NUM_OFFSETS; i++)
+               INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
+       ida_init(&mdev->irq_info.cb_ida);
+       spin_lock_init(&mdev->irq_info.mic_intr_lock);
+       return 0;
+}
+
+/**
+ * mic_release_callbacks - Uninitialize data structures needed
+ * to handle callbacks.
+ *
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_release_callbacks(struct mic_device *mdev)
+{
+       unsigned long flags;
+       struct list_head *pos, *tmp;
+       struct mic_intr_cb *intr_cb;
+       int i;
+
+       for (i = 0; i < MIC_NUM_OFFSETS; i++) {
+               spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
+
+               if (list_empty(&mdev->irq_info.cb_list[i])) {
+                       spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
+                                              flags);
+                       break;
+               }
+
+               list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
+                       intr_cb = list_entry(pos, struct mic_intr_cb, list);
+                       list_del(pos);
+                       ida_simple_remove(&mdev->irq_info.cb_ida,
+                                         intr_cb->cb_id);
+                       kfree(intr_cb);
+               }
+               spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
+       }
+       ida_destroy(&mdev->irq_info.cb_ida);
+       kfree(mdev->irq_info.cb_list);
+}
+
+/**
+ * mic_setup_msi - Initializes MSI interrupts.
+ *
+ * @mdev: pointer to mic_device instance
+ * @pdev: PCI device structure
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
+{
+       int rc;
+
+       rc = pci_enable_msi(pdev);
+       if (rc) {
+               dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
+               return rc;
+       }
+
+       mdev->irq_info.num_vectors = 1;
+       mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
+               mdev->irq_info.num_vectors), GFP_KERNEL);
+
+       if (!mdev->irq_info.mic_msi_map) {
+               rc = -ENOMEM;
+               goto err_nomem1;
+       }
+
+       rc = mic_setup_callbacks(mdev);
+       if (rc) {
+               dev_err(&pdev->dev, "Error setting up callbacks\n");
+               goto err_nomem2;
+       }
+
+       rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
+       if (rc) {
+               dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
+               goto err_irq_req_fail;
+       }
+
+       dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
+       return 0;
+err_irq_req_fail:
+       mic_release_callbacks(mdev);
+err_nomem2:
+       kfree(mdev->irq_info.mic_msi_map);
+err_nomem1:
+       pci_disable_msi(pdev);
+       mdev->irq_info.num_vectors = 0;
+       return rc;
+}
+
+/**
+ * mic_setup_intx - Initializes legacy interrupts.
+ *
+ * @mdev: pointer to mic_device instance
+ * @pdev: PCI device structure
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
+{
+       int rc;
+
+       pci_msi_off(pdev);
+
+       /* Enable intx */
+       pci_intx(pdev, 1);
+       rc = mic_setup_callbacks(mdev);
+       if (rc) {
+               dev_err(&pdev->dev, "Error setting up callbacks\n");
+               goto err_nomem;
+       }
+
+       rc = request_irq(pdev->irq, mic_interrupt,
+               IRQF_SHARED, "mic-intx", mdev);
+       if (rc)
+               goto err;
+
+       dev_dbg(&pdev->dev, "intx irq setup\n");
+       return 0;
+err:
+       mic_release_callbacks(mdev);
+err_nomem:
+       return rc;
+}
+
+/**
+ * mic_next_db - Retrieve the next doorbell interrupt source id.
+ * The id is picked sequentially from the available pool of
+ * doorlbell ids.
+ *
+ * @mdev: pointer to the mic_device instance.
+ *
+ * Returns the next doorbell interrupt source.
+ */
+int mic_next_db(struct mic_device *mdev)
+{
+       int next_db;
+
+       next_db = mdev->irq_info.next_avail_src %
+               mdev->intr_info->intr_len[MIC_INTR_DB];
+       mdev->irq_info.next_avail_src++;
+       return next_db;
+}
+
+#define COOKIE_ID_SHIFT 16
+#define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
+#define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
+#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
+
+/**
+ * mic_request_irq - request an irq. mic_mutex needs
+ * to be held before calling this function.
+ *
+ * @mdev: pointer to mic_device instance
+ * @func: The callback function that handles the interrupt.
+ * The function needs to call ack_interrupts
+ * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
+ * @name: The ASCII name of the callee requesting the irq.
+ * @data: private data that is returned back when calling the
+ * function handler.
+ * @intr_src: The source id of the requester. Its the doorbell id
+ * for Doorbell interrupts and DMA channel id for DMA interrupts.
+ * @type: The type of interrupt. Values defined in mic_intr_type
+ *
+ * returns: The cookie that is transparent to the caller. Passed
+ * back when calling mic_free_irq. An appropriate error code
+ * is returned on failure. Caller needs to use IS_ERR(return_val)
+ * to check for failure and PTR_ERR(return_val) to obtained the
+ * error code.
+ *
+ */
+struct mic_irq *mic_request_irq(struct mic_device *mdev,
+       irqreturn_t (*func)(int irq, void *dev),
+       const char *name, void *data, int intr_src,
+       enum mic_intr_type type)
+{
+       u16 offset;
+       int rc = 0;
+       struct msix_entry *msix = NULL;
+       unsigned long cookie = 0;
+       u16 entry;
+       struct mic_intr_cb *intr_cb;
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+
+       offset = mic_map_src_to_offset(mdev, intr_src, type);
+       if (offset >= MIC_NUM_OFFSETS) {
+               dev_err(mdev->sdev->parent,
+                       "Error mapping index %d to a valid source id.\n",
+                       intr_src);
+               rc = -EINVAL;
+               goto err;
+       }
+
+       if (mdev->irq_info.num_vectors > 1) {
+               msix = mic_get_available_vector(mdev);
+               if (!msix) {
+                       dev_err(mdev->sdev->parent,
+                               "No MSIx vectors available for use.\n");
+                       rc = -ENOSPC;
+                       goto err;
+               }
+
+               rc = request_irq(msix->vector, func, 0, name, data);
+               if (rc) {
+                       dev_dbg(mdev->sdev->parent,
+                               "request irq failed rc = %d\n", rc);
+                       goto err;
+               }
+               entry = msix->entry;
+               mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
+               mdev->intr_ops->program_msi_to_src_map(mdev,
+                               entry, offset, true);
+               cookie = MK_COOKIE(entry, offset);
+               dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
+                       msix->vector, intr_src);
+       } else {
+               intr_cb = mic_register_intr_callback(mdev,
+                               offset, func, data);
+               if (IS_ERR(intr_cb)) {
+                       dev_err(mdev->sdev->parent,
+                               "No available callback entries for use\n");
+                       rc = PTR_ERR(intr_cb);
+                       goto err;
+               }
+
+               entry = 0;
+               if (pci_dev_msi_enabled(pdev)) {
+                       mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
+                       mdev->intr_ops->program_msi_to_src_map(mdev,
+                               entry, offset, true);
+               }
+               cookie = MK_COOKIE(entry, intr_cb->cb_id);
+               dev_dbg(mdev->sdev->parent, "callback %d registered for src: %d\n",
+                       intr_cb->cb_id, intr_src);
+       }
+       return (struct mic_irq *)cookie;
+err:
+       return ERR_PTR(rc);
+}
+
+/**
+ * mic_free_irq - free irq. mic_mutex
+ *  needs to be held before calling this function.
+ *
+ * @mdev: pointer to mic_device instance
+ * @cookie: cookie obtained during a successful call to mic_request_irq
+ * @data: private data specified by the calling function during the
+ * mic_request_irq
+ *
+ * returns: none.
+ */
+void mic_free_irq(struct mic_device *mdev,
+       struct mic_irq *cookie, void *data)
+{
+       u32 offset;
+       u32 entry;
+       u8 src_id;
+       unsigned int irq;
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+
+       entry = GET_ENTRY((unsigned long)cookie);
+       offset = GET_OFFSET((unsigned long)cookie);
+       if (mdev->irq_info.num_vectors > 1) {
+               if (entry >= mdev->irq_info.num_vectors) {
+                       dev_warn(mdev->sdev->parent,
+                                "entry %d should be < num_irq %d\n",
+                               entry, mdev->irq_info.num_vectors);
+                       return;
+               }
+               irq = mdev->irq_info.msix_entries[entry].vector;
+               free_irq(irq, data);
+               mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
+               mdev->intr_ops->program_msi_to_src_map(mdev,
+                       entry, offset, false);
+
+               dev_dbg(mdev->sdev->parent, "irq: %d freed\n", irq);
+       } else {
+               irq = pdev->irq;
+               src_id = mic_unregister_intr_callback(mdev, offset);
+               if (src_id >= MIC_NUM_OFFSETS) {
+                       dev_warn(mdev->sdev->parent, "Error unregistering callback\n");
+                       return;
+               }
+               if (pci_dev_msi_enabled(pdev)) {
+                       mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
+                       mdev->intr_ops->program_msi_to_src_map(mdev,
+                               entry, src_id, false);
+               }
+               dev_dbg(mdev->sdev->parent, "callback %d unregistered for src: %d\n",
+                       offset, src_id);
+       }
+}
+
+/**
+ * mic_setup_interrupts - Initializes interrupts.
+ *
+ * @mdev: pointer to mic_device instance
+ * @pdev: PCI device structure
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
+{
+       int rc;
+
+       rc = mic_setup_msix(mdev, pdev);
+       if (!rc)
+               goto done;
+
+       rc = mic_setup_msi(mdev, pdev);
+       if (!rc)
+               goto done;
+
+       rc = mic_setup_intx(mdev, pdev);
+       if (rc) {
+               dev_err(mdev->sdev->parent, "no usable interrupts\n");
+               return rc;
+       }
+done:
+       mdev->intr_ops->enable_interrupts(mdev);
+       return 0;
+}
+
+/**
+ * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
+ *
+ * @mdev: pointer to mic_device instance
+ * @pdev: PCI device structure
+ *
+ * returns none.
+ */
+void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
+{
+       int i;
+
+       mdev->intr_ops->disable_interrupts(mdev);
+       if (mdev->irq_info.num_vectors > 1) {
+               for (i = 0; i < mdev->irq_info.num_vectors; i++) {
+                       if (mdev->irq_info.mic_msi_map[i])
+                               dev_warn(&pdev->dev, "irq %d may still be in use.\n",
+                                        mdev->irq_info.msix_entries[i].vector);
+               }
+               kfree(mdev->irq_info.mic_msi_map);
+               kfree(mdev->irq_info.msix_entries);
+               pci_disable_msix(pdev);
+       } else {
+               if (pci_dev_msi_enabled(pdev)) {
+                       free_irq(pdev->irq, mdev);
+                       kfree(mdev->irq_info.mic_msi_map);
+                       pci_disable_msi(pdev);
+               } else {
+                       free_irq(pdev->irq, mdev);
+               }
+               mic_release_callbacks(mdev);
+       }
+}
+
+/**
+ * mic_intr_restore - Restore MIC interrupt registers.
+ *
+ * @mdev: pointer to mic_device instance.
+ *
+ * Restore the interrupt registers to values previously
+ * stored in the SW data structures. mic_mutex needs to
+ * be held before calling this function.
+ *
+ * returns None.
+ */
+void mic_intr_restore(struct mic_device *mdev)
+{
+       int entry, offset;
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+
+       if (!pci_dev_msi_enabled(pdev))
+               return;
+
+       for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
+               for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
+                       if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
+                               mdev->intr_ops->program_msi_to_src_map(mdev,
+                                       entry, offset, true);
+               }
+       }
+}
diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h
new file mode 100644 (file)
index 0000000..6091aa9
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef _MIC_INTR_H_
+#define _MIC_INTR_H_
+
+/*
+ * The minimum number of msix vectors required for normal operation.
+ * 3 for virtio network, console and block devices.
+ * 1 for card shutdown notifications.
+ */
+#define MIC_MIN_MSIX 4
+#define MIC_NUM_OFFSETS 32
+
+/**
+ * mic_intr_source - The type of source that will generate
+ * the interrupt.The number of types needs to be in sync with
+ * MIC_NUM_INTR_TYPES
+ *
+ * MIC_INTR_DB: The source is a doorbell
+ * MIC_INTR_DMA: The source is a DMA channel
+ * MIC_INTR_ERR: The source is an error interrupt e.g. SBOX ERR
+ * MIC_NUM_INTR_TYPES: Total number of interrupt sources.
+ */
+enum mic_intr_type {
+       MIC_INTR_DB = 0,
+       MIC_INTR_DMA,
+       MIC_INTR_ERR,
+       MIC_NUM_INTR_TYPES
+};
+
+/**
+ * struct mic_intr_info - Contains h/w specific interrupt sources
+ * information.
+ *
+ * @intr_start_idx: Contains the starting indexes of the
+ * interrupt types.
+ * @intr_len: Contains the length of the interrupt types.
+ */
+struct mic_intr_info {
+       u16 intr_start_idx[MIC_NUM_INTR_TYPES];
+       u16 intr_len[MIC_NUM_INTR_TYPES];
+};
+
+/**
+ * struct mic_irq_info - OS specific irq information
+ *
+ * @next_avail_src: next available doorbell that can be assigned.
+ * @msix_entries: msix entries allocated while setting up MSI-x
+ * @mic_msi_map: The MSI/MSI-x mapping information.
+ * @num_vectors: The number of MSI/MSI-x vectors that have been allocated.
+ * @cb_ida: callback ID allocator to track the callbacks registered.
+ * @mic_intr_lock: spinlock to protect the interrupt callback list.
+ * @cb_list: Array of callback lists one for each source.
+ */
+struct mic_irq_info {
+       int next_avail_src;
+       struct msix_entry *msix_entries;
+       u32 *mic_msi_map;
+       u16 num_vectors;
+       struct ida cb_ida;
+       spinlock_t mic_intr_lock;
+       struct list_head *cb_list;
+};
+
+/**
+ * struct mic_intr_cb - Interrupt callback structure.
+ *
+ * @func: The callback function
+ * @data: Private data of the requester.
+ * @cb_id: The callback id. Identifies this callback.
+ * @list: list head pointing to the next callback structure.
+ */
+struct mic_intr_cb {
+       irqreturn_t (*func) (int irq, void *data);
+       void *data;
+       int cb_id;
+       struct list_head list;
+};
+
+/**
+ * struct mic_irq - opaque pointer used as cookie
+ */
+struct mic_irq;
+
+/* Forward declaration */
+struct mic_device;
+
+/**
+ * struct mic_hw_intr_ops: MIC HW specific interrupt operations
+ * @intr_init: Initialize H/W specific interrupt information.
+ * @enable_interrupts: Enable interrupts from the hardware.
+ * @disable_interrupts: Disable interrupts from the hardware.
+ * @program_msi_to_src_map: Update MSI mapping registers with
+ * irq information.
+ * @read_msi_to_src_map: Read MSI mapping registers containing
+ * irq information.
+ */
+struct mic_hw_intr_ops {
+       void (*intr_init)(struct mic_device *mdev);
+       void (*enable_interrupts)(struct mic_device *mdev);
+       void (*disable_interrupts)(struct mic_device *mdev);
+       void (*program_msi_to_src_map) (struct mic_device *mdev,
+                       int idx, int intr_src, bool set);
+       u32 (*read_msi_to_src_map) (struct mic_device *mdev,
+                       int idx);
+};
+
+int mic_next_db(struct mic_device *mdev);
+struct mic_irq *mic_request_irq(struct mic_device *mdev,
+       irqreturn_t (*func)(int irq, void *data),
+       const char *name, void *data, int intr_src,
+       enum mic_intr_type type);
+
+void mic_free_irq(struct mic_device *mdev,
+               struct mic_irq *cookie, void *data);
+int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
+void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
+void mic_intr_restore(struct mic_device *mdev);
+#endif
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c
new file mode 100644 (file)
index 0000000..ad838c7
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ * Global TODO's across the driver to be added after initial base
+ * patches are accepted upstream:
+ * 1) Enable DMA support.
+ * 2) Enable per vring interrupt support.
+ */
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/suspend.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_x100.h"
+#include "mic_smpt.h"
+#include "mic_fops.h"
+#include "mic_virtio.h"
+
+static const char mic_driver_name[] = "mic";
+
+static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)},
+
+       /* required last entry */
+       { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, mic_pci_tbl);
+
+/* ID allocator for MIC devices */
+static struct ida g_mic_ida;
+/* Class of MIC devices for sysfs accessibility. */
+static struct class *g_mic_class;
+/* Base device node number for MIC devices */
+static dev_t g_mic_devno;
+
+static const struct file_operations mic_fops = {
+       .open = mic_open,
+       .release = mic_release,
+       .unlocked_ioctl = mic_ioctl,
+       .poll = mic_poll,
+       .mmap = mic_mmap,
+       .owner = THIS_MODULE,
+};
+
+/* Initialize the device page */
+static int mic_dp_init(struct mic_device *mdev)
+{
+       mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL);
+       if (!mdev->dp) {
+               dev_err(mdev->sdev->parent, "%s %d err %d\n",
+                       __func__, __LINE__, -ENOMEM);
+               return -ENOMEM;
+       }
+
+       mdev->dp_dma_addr = mic_map_single(mdev,
+               mdev->dp, MIC_DP_SIZE);
+       if (mic_map_error(mdev->dp_dma_addr)) {
+               kfree(mdev->dp);
+               dev_err(mdev->sdev->parent, "%s %d err %d\n",
+                       __func__, __LINE__, -ENOMEM);
+               return -ENOMEM;
+       }
+       mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
+       mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
+       return 0;
+}
+
+/* Uninitialize the device page */
+static void mic_dp_uninit(struct mic_device *mdev)
+{
+       mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE);
+       kfree(mdev->dp);
+}
+
+/**
+ * mic_shutdown_db - Shutdown doorbell interrupt handler.
+ */
+static irqreturn_t mic_shutdown_db(int irq, void *data)
+{
+       struct mic_device *mdev = data;
+       struct mic_bootparam *bootparam = mdev->dp;
+
+       mdev->ops->ack_interrupt(mdev);
+
+       switch (bootparam->shutdown_status) {
+       case MIC_HALTED:
+       case MIC_POWER_OFF:
+       case MIC_RESTART:
+               /* Fall through */
+       case MIC_CRASHED:
+               schedule_work(&mdev->shutdown_work);
+               break;
+       default:
+               break;
+       };
+       return IRQ_HANDLED;
+}
+
+/**
+ * mic_ops_init: Initialize HW specific operation tables.
+ *
+ * @mdev: pointer to mic_device instance
+ *
+ * returns none.
+ */
+static void mic_ops_init(struct mic_device *mdev)
+{
+       switch (mdev->family) {
+       case MIC_FAMILY_X100:
+               mdev->ops = &mic_x100_ops;
+               mdev->intr_ops = &mic_x100_intr_ops;
+               mdev->smpt_ops = &mic_x100_smpt_ops;
+               break;
+       default:
+               break;
+       }
+}
+
+/**
+ * mic_get_family - Determine hardware family to which this MIC belongs.
+ *
+ * @pdev: The pci device structure
+ *
+ * returns family.
+ */
+static enum mic_hw_family mic_get_family(struct pci_dev *pdev)
+{
+       enum mic_hw_family family;
+
+       switch (pdev->device) {
+       case MIC_X100_PCI_DEVICE_2250:
+       case MIC_X100_PCI_DEVICE_2251:
+       case MIC_X100_PCI_DEVICE_2252:
+       case MIC_X100_PCI_DEVICE_2253:
+       case MIC_X100_PCI_DEVICE_2254:
+       case MIC_X100_PCI_DEVICE_2255:
+       case MIC_X100_PCI_DEVICE_2256:
+       case MIC_X100_PCI_DEVICE_2257:
+       case MIC_X100_PCI_DEVICE_2258:
+       case MIC_X100_PCI_DEVICE_2259:
+       case MIC_X100_PCI_DEVICE_225a:
+       case MIC_X100_PCI_DEVICE_225b:
+       case MIC_X100_PCI_DEVICE_225c:
+       case MIC_X100_PCI_DEVICE_225d:
+       case MIC_X100_PCI_DEVICE_225e:
+               family = MIC_FAMILY_X100;
+               break;
+       default:
+               family = MIC_FAMILY_UNKNOWN;
+               break;
+       }
+       return family;
+}
+
+/**
+* mic_pm_notifier: Notifier callback function that handles
+* PM notifications.
+*
+* @notifier_block: The notifier structure.
+* @pm_event: The event for which the driver was notified.
+* @unused: Meaningless. Always NULL.
+*
+* returns NOTIFY_DONE
+*/
+static int mic_pm_notifier(struct notifier_block *notifier,
+               unsigned long pm_event, void *unused)
+{
+       struct mic_device *mdev = container_of(notifier,
+               struct mic_device, pm_notifier);
+
+       switch (pm_event) {
+       case PM_HIBERNATION_PREPARE:
+               /* Fall through */
+       case PM_SUSPEND_PREPARE:
+               mic_prepare_suspend(mdev);
+               break;
+       case PM_POST_HIBERNATION:
+               /* Fall through */
+       case PM_POST_SUSPEND:
+               /* Fall through */
+       case PM_POST_RESTORE:
+               mic_complete_resume(mdev);
+               break;
+       case PM_RESTORE_PREPARE:
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_DONE;
+}
+
+/**
+ * mic_device_init - Allocates and initializes the MIC device structure
+ *
+ * @mdev: pointer to mic_device instance
+ * @pdev: The pci device structure
+ *
+ * returns none.
+ */
+static int
+mic_device_init(struct mic_device *mdev, struct pci_dev *pdev)
+{
+       int rc;
+
+       mdev->family = mic_get_family(pdev);
+       mdev->stepping = pdev->revision;
+       mic_ops_init(mdev);
+       mic_sysfs_init(mdev);
+       mutex_init(&mdev->mic_mutex);
+       mdev->irq_info.next_avail_src = 0;
+       INIT_WORK(&mdev->reset_trigger_work, mic_reset_trigger_work);
+       INIT_WORK(&mdev->shutdown_work, mic_shutdown_work);
+       init_completion(&mdev->reset_wait);
+       INIT_LIST_HEAD(&mdev->vdev_list);
+       mdev->pm_notifier.notifier_call = mic_pm_notifier;
+       rc = register_pm_notifier(&mdev->pm_notifier);
+       if (rc) {
+               dev_err(&pdev->dev, "register_pm_notifier failed rc %d\n",
+                       rc);
+               goto register_pm_notifier_fail;
+       }
+       return 0;
+register_pm_notifier_fail:
+       flush_work(&mdev->shutdown_work);
+       flush_work(&mdev->reset_trigger_work);
+       return rc;
+}
+
+/**
+ * mic_device_uninit - Frees resources allocated during mic_device_init(..)
+ *
+ * @mdev: pointer to mic_device instance
+ *
+ * returns none
+ */
+static void mic_device_uninit(struct mic_device *mdev)
+{
+       /* The cmdline sysfs entry might have allocated cmdline */
+       kfree(mdev->cmdline);
+       kfree(mdev->firmware);
+       kfree(mdev->ramdisk);
+       kfree(mdev->bootmode);
+       flush_work(&mdev->reset_trigger_work);
+       flush_work(&mdev->shutdown_work);
+       unregister_pm_notifier(&mdev->pm_notifier);
+}
+
+/**
+ * mic_probe - Device Initialization Routine
+ *
+ * @pdev: PCI device structure
+ * @ent: entry in mic_pci_tbl
+ *
+ * returns 0 on success, < 0 on failure.
+ */
+static int mic_probe(struct pci_dev *pdev,
+               const struct pci_device_id *ent)
+{
+       int rc;
+       struct mic_device *mdev;
+
+       mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+       if (!mdev) {
+               rc = -ENOMEM;
+               dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc);
+               goto mdev_alloc_fail;
+       }
+       mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL);
+       if (mdev->id < 0) {
+               rc = mdev->id;
+               dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc);
+               goto ida_fail;
+       }
+
+       rc = mic_device_init(mdev, pdev);
+       if (rc) {
+               dev_err(&pdev->dev, "mic_device_init failed rc %d\n", rc);
+               goto device_init_fail;
+       }
+
+       rc = pci_enable_device(pdev);
+       if (rc) {
+               dev_err(&pdev->dev, "failed to enable pci device.\n");
+               goto uninit_device;
+       }
+
+       pci_set_master(pdev);
+
+       rc = pci_request_regions(pdev, mic_driver_name);
+       if (rc) {
+               dev_err(&pdev->dev, "failed to get pci regions.\n");
+               goto disable_device;
+       }
+
+       rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+       if (rc) {
+               dev_err(&pdev->dev, "Cannot set DMA mask\n");
+               goto release_regions;
+       }
+
+       mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar);
+       mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar);
+       mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar);
+       if (!mdev->mmio.va) {
+               dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
+               rc = -EIO;
+               goto release_regions;
+       }
+
+       mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar);
+       mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar);
+       mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len);
+       if (!mdev->aper.va) {
+               dev_err(&pdev->dev, "Cannot remap Aperture BAR\n");
+               rc = -EIO;
+               goto unmap_mmio;
+       }
+
+       mdev->intr_ops->intr_init(mdev);
+       rc = mic_setup_interrupts(mdev, pdev);
+       if (rc) {
+               dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc);
+               goto unmap_aper;
+       }
+       rc = mic_smpt_init(mdev);
+       if (rc) {
+               dev_err(&pdev->dev, "smpt_init failed %d\n", rc);
+               goto free_interrupts;
+       }
+
+       pci_set_drvdata(pdev, mdev);
+
+       mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev,
+               MKDEV(MAJOR(g_mic_devno), mdev->id), NULL,
+               mdev->attr_group, "mic%d", mdev->id);
+       if (IS_ERR(mdev->sdev)) {
+               rc = PTR_ERR(mdev->sdev);
+               dev_err(&pdev->dev,
+                       "device_create_with_groups failed rc %d\n", rc);
+               goto smpt_uninit;
+       }
+       mdev->state_sysfs = sysfs_get_dirent(mdev->sdev->kobj.sd, "state");
+       if (!mdev->state_sysfs) {
+               rc = -ENODEV;
+               dev_err(&pdev->dev, "sysfs_get_dirent failed rc %d\n", rc);
+               goto destroy_device;
+       }
+
+       rc = mic_dp_init(mdev);
+       if (rc) {
+               dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc);
+               goto sysfs_put;
+       }
+       mutex_lock(&mdev->mic_mutex);
+
+       mdev->shutdown_db = mic_next_db(mdev);
+       mdev->shutdown_cookie = mic_request_irq(mdev, mic_shutdown_db,
+               "shutdown-interrupt", mdev, mdev->shutdown_db, MIC_INTR_DB);
+       if (IS_ERR(mdev->shutdown_cookie)) {
+               rc = PTR_ERR(mdev->shutdown_cookie);
+               mutex_unlock(&mdev->mic_mutex);
+               goto dp_uninit;
+       }
+       mutex_unlock(&mdev->mic_mutex);
+       mic_bootparam_init(mdev);
+
+       mic_create_debug_dir(mdev);
+       cdev_init(&mdev->cdev, &mic_fops);
+       mdev->cdev.owner = THIS_MODULE;
+       rc = cdev_add(&mdev->cdev, MKDEV(MAJOR(g_mic_devno), mdev->id), 1);
+       if (rc) {
+               dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc);
+               goto cleanup_debug_dir;
+       }
+       return 0;
+cleanup_debug_dir:
+       mic_delete_debug_dir(mdev);
+       mutex_lock(&mdev->mic_mutex);
+       mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
+       mutex_unlock(&mdev->mic_mutex);
+dp_uninit:
+       mic_dp_uninit(mdev);
+sysfs_put:
+       sysfs_put(mdev->state_sysfs);
+destroy_device:
+       device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
+smpt_uninit:
+       mic_smpt_uninit(mdev);
+free_interrupts:
+       mic_free_interrupts(mdev, pdev);
+unmap_aper:
+       iounmap(mdev->aper.va);
+unmap_mmio:
+       iounmap(mdev->mmio.va);
+release_regions:
+       pci_release_regions(pdev);
+disable_device:
+       pci_disable_device(pdev);
+uninit_device:
+       mic_device_uninit(mdev);
+device_init_fail:
+       ida_simple_remove(&g_mic_ida, mdev->id);
+ida_fail:
+       kfree(mdev);
+mdev_alloc_fail:
+       dev_err(&pdev->dev, "Probe failed rc %d\n", rc);
+       return rc;
+}
+
+/**
+ * mic_remove - Device Removal Routine
+ * mic_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ *
+ * @pdev: PCI device structure
+ */
+static void mic_remove(struct pci_dev *pdev)
+{
+       struct mic_device *mdev;
+
+       mdev = pci_get_drvdata(pdev);
+       if (!mdev)
+               return;
+
+       mic_stop(mdev, false);
+       cdev_del(&mdev->cdev);
+       mic_delete_debug_dir(mdev);
+       mutex_lock(&mdev->mic_mutex);
+       mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
+       mutex_unlock(&mdev->mic_mutex);
+       flush_work(&mdev->shutdown_work);
+       mic_dp_uninit(mdev);
+       sysfs_put(mdev->state_sysfs);
+       device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
+       mic_smpt_uninit(mdev);
+       mic_free_interrupts(mdev, pdev);
+       iounmap(mdev->mmio.va);
+       iounmap(mdev->aper.va);
+       mic_device_uninit(mdev);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       ida_simple_remove(&g_mic_ida, mdev->id);
+       kfree(mdev);
+}
+static struct pci_driver mic_driver = {
+       .name = mic_driver_name,
+       .id_table = mic_pci_tbl,
+       .probe = mic_probe,
+       .remove = mic_remove
+};
+
+static int __init mic_init(void)
+{
+       int ret;
+
+       ret = alloc_chrdev_region(&g_mic_devno, 0,
+               MIC_MAX_NUM_DEVS, mic_driver_name);
+       if (ret) {
+               pr_err("alloc_chrdev_region failed ret %d\n", ret);
+               goto error;
+       }
+
+       g_mic_class = class_create(THIS_MODULE, mic_driver_name);
+       if (IS_ERR(g_mic_class)) {
+               ret = PTR_ERR(g_mic_class);
+               pr_err("class_create failed ret %d\n", ret);
+               goto cleanup_chrdev;
+       }
+
+       mic_init_debugfs();
+       ida_init(&g_mic_ida);
+       ret = pci_register_driver(&mic_driver);
+       if (ret) {
+               pr_err("pci_register_driver failed ret %d\n", ret);
+               goto cleanup_debugfs;
+       }
+       return ret;
+cleanup_debugfs:
+       mic_exit_debugfs();
+       class_destroy(g_mic_class);
+cleanup_chrdev:
+       unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
+error:
+       return ret;
+}
+
+static void __exit mic_exit(void)
+{
+       pci_unregister_driver(&mic_driver);
+       ida_destroy(&g_mic_ida);
+       mic_exit_debugfs();
+       class_destroy(g_mic_class);
+       unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
+}
+
+module_init(mic_init);
+module_exit(mic_exit);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/host/mic_smpt.c b/drivers/misc/mic/host/mic_smpt.c
new file mode 100644 (file)
index 0000000..fae474c
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/pci.h>
+
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_smpt.h"
+
+static inline u64 mic_system_page_mask(struct mic_device *mdev)
+{
+       return (1ULL << mdev->smpt->info.page_shift) - 1ULL;
+}
+
+static inline u8 mic_sys_addr_to_smpt(struct mic_device *mdev, dma_addr_t pa)
+{
+       return (pa - mdev->smpt->info.base) >> mdev->smpt->info.page_shift;
+}
+
+static inline u64 mic_smpt_to_pa(struct mic_device *mdev, u8 index)
+{
+       return mdev->smpt->info.base + (index * mdev->smpt->info.page_size);
+}
+
+static inline u64 mic_smpt_offset(struct mic_device *mdev, dma_addr_t pa)
+{
+       return pa & mic_system_page_mask(mdev);
+}
+
+static inline u64 mic_smpt_align_low(struct mic_device *mdev, dma_addr_t pa)
+{
+       return ALIGN(pa - mic_system_page_mask(mdev),
+               mdev->smpt->info.page_size);
+}
+
+static inline u64 mic_smpt_align_high(struct mic_device *mdev, dma_addr_t pa)
+{
+       return ALIGN(pa, mdev->smpt->info.page_size);
+}
+
+/* Total Cumulative system memory accessible by MIC across all SMPT entries */
+static inline u64 mic_max_system_memory(struct mic_device *mdev)
+{
+       return mdev->smpt->info.num_reg * mdev->smpt->info.page_size;
+}
+
+/* Maximum system memory address accessible by MIC */
+static inline u64 mic_max_system_addr(struct mic_device *mdev)
+{
+       return mdev->smpt->info.base + mic_max_system_memory(mdev) - 1ULL;
+}
+
+/* Check if the DMA address is a MIC system memory address */
+static inline bool
+mic_is_system_addr(struct mic_device *mdev, dma_addr_t pa)
+{
+       return pa >= mdev->smpt->info.base && pa <= mic_max_system_addr(mdev);
+}
+
+/* Populate an SMPT entry and update the reference counts. */
+static void mic_add_smpt_entry(int spt, s64 *ref, u64 addr,
+               int entries, struct mic_device *mdev)
+{
+       struct mic_smpt_info *smpt_info = mdev->smpt;
+       int i;
+
+       for (i = spt; i < spt + entries; i++,
+               addr += smpt_info->info.page_size) {
+               if (!smpt_info->entry[i].ref_count &&
+                   (smpt_info->entry[i].dma_addr != addr)) {
+                       mdev->smpt_ops->set(mdev, addr, i);
+                       smpt_info->entry[i].dma_addr = addr;
+               }
+               smpt_info->entry[i].ref_count += ref[i - spt];
+       }
+}
+
+/*
+ * Find an available MIC address in MIC SMPT address space
+ * for a given DMA address and size.
+ */
+static dma_addr_t mic_smpt_op(struct mic_device *mdev, u64 dma_addr,
+                               int entries, s64 *ref, size_t size)
+{
+       int spt;
+       int ae = 0;
+       int i;
+       unsigned long flags;
+       dma_addr_t mic_addr = 0;
+       dma_addr_t addr = dma_addr;
+       struct mic_smpt_info *smpt_info = mdev->smpt;
+
+       spin_lock_irqsave(&smpt_info->smpt_lock, flags);
+
+       /* find existing entries */
+       for (i = 0; i < smpt_info->info.num_reg; i++) {
+               if (smpt_info->entry[i].dma_addr == addr) {
+                       ae++;
+                       addr += smpt_info->info.page_size;
+               } else if (ae) /* cannot find contiguous entries */
+                       goto not_found;
+
+               if (ae == entries)
+                       goto found;
+       }
+
+       /* find free entry */
+       for (ae = 0, i = 0; i < smpt_info->info.num_reg; i++) {
+               ae = (smpt_info->entry[i].ref_count == 0) ? ae + 1 : 0;
+               if (ae == entries)
+                       goto found;
+       }
+
+not_found:
+       spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
+       return mic_addr;
+
+found:
+       spt = i - entries + 1;
+       mic_addr = mic_smpt_to_pa(mdev, spt);
+       mic_add_smpt_entry(spt, ref, dma_addr, entries, mdev);
+       smpt_info->map_count++;
+       smpt_info->ref_count += (s64)size;
+       spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
+       return mic_addr;
+}
+
+/*
+ * Returns number of smpt entries needed for dma_addr to dma_addr + size
+ * also returns the reference count array for each of those entries
+ * and the starting smpt address
+ */
+static int mic_get_smpt_ref_count(struct mic_device *mdev, dma_addr_t dma_addr,
+                               size_t size, s64 *ref,  u64 *smpt_start)
+{
+       u64 start =  dma_addr;
+       u64 end = dma_addr + size;
+       int i = 0;
+
+       while (start < end) {
+               ref[i++] = min(mic_smpt_align_high(mdev, start + 1),
+                       end) - start;
+               start = mic_smpt_align_high(mdev, start + 1);
+       }
+
+       if (smpt_start)
+               *smpt_start = mic_smpt_align_low(mdev, dma_addr);
+
+       return i;
+}
+
+/*
+ * mic_to_dma_addr - Converts a MIC address to a DMA address.
+ *
+ * @mdev: pointer to mic_device instance.
+ * @mic_addr: MIC address.
+ *
+ * returns a DMA address.
+ */
+static dma_addr_t
+mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr)
+{
+       struct mic_smpt_info *smpt_info = mdev->smpt;
+       int spt;
+       dma_addr_t dma_addr;
+
+       if (!mic_is_system_addr(mdev, mic_addr)) {
+               dev_err(mdev->sdev->parent,
+                       "mic_addr is invalid. mic_addr = 0x%llx\n", mic_addr);
+               return -EINVAL;
+       }
+       spt = mic_sys_addr_to_smpt(mdev, mic_addr);
+       dma_addr = smpt_info->entry[spt].dma_addr +
+               mic_smpt_offset(mdev, mic_addr);
+       return dma_addr;
+}
+
+/**
+ * mic_map - Maps a DMA address to a MIC physical address.
+ *
+ * @mdev: pointer to mic_device instance.
+ * @dma_addr: DMA address.
+ * @size: Size of the region to be mapped.
+ *
+ * This API converts the DMA address provided to a DMA address understood
+ * by MIC. Caller should check for errors by calling mic_map_error(..).
+ *
+ * returns DMA address as required by MIC.
+ */
+dma_addr_t mic_map(struct mic_device *mdev, dma_addr_t dma_addr, size_t size)
+{
+       dma_addr_t mic_addr = 0;
+       int num_entries;
+       s64 *ref;
+       u64 smpt_start;
+
+       if (!size || size > mic_max_system_memory(mdev))
+               return mic_addr;
+
+       ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL);
+       if (!ref)
+               return mic_addr;
+
+       num_entries = mic_get_smpt_ref_count(mdev, dma_addr, size,
+               ref, &smpt_start);
+
+       /* Set the smpt table appropriately and get 16G aligned mic address */
+       mic_addr = mic_smpt_op(mdev, smpt_start, num_entries, ref, size);
+
+       kfree(ref);
+
+       /*
+        * If mic_addr is zero then its an error case
+        * since mic_addr can never be zero.
+        * else generate mic_addr by adding the 16G offset in dma_addr
+        */
+       if (!mic_addr && MIC_FAMILY_X100 == mdev->family) {
+               dev_err(mdev->sdev->parent,
+                       "mic_map failed dma_addr 0x%llx size 0x%lx\n",
+                       dma_addr, size);
+               return mic_addr;
+       } else {
+               return mic_addr + mic_smpt_offset(mdev, dma_addr);
+       }
+}
+
+/**
+ * mic_unmap - Unmaps a MIC physical address.
+ *
+ * @mdev: pointer to mic_device instance.
+ * @mic_addr: MIC physical address.
+ * @size: Size of the region to be unmapped.
+ *
+ * This API unmaps the mappings created by mic_map(..).
+ *
+ * returns None.
+ */
+void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size)
+{
+       struct mic_smpt_info *smpt_info = mdev->smpt;
+       s64 *ref;
+       int num_smpt;
+       int spt;
+       int i;
+       unsigned long flags;
+
+       if (!size)
+               return;
+
+       if (!mic_is_system_addr(mdev, mic_addr)) {
+               dev_err(mdev->sdev->parent,
+                       "invalid address: 0x%llx\n", mic_addr);
+               return;
+       }
+
+       spt = mic_sys_addr_to_smpt(mdev, mic_addr);
+       ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL);
+       if (!ref)
+               return;
+
+       /* Get number of smpt entries to be mapped, ref count array */
+       num_smpt = mic_get_smpt_ref_count(mdev, mic_addr, size, ref, NULL);
+
+       spin_lock_irqsave(&smpt_info->smpt_lock, flags);
+       smpt_info->unmap_count++;
+       smpt_info->ref_count -= (s64)size;
+
+       for (i = spt; i < spt + num_smpt; i++) {
+               smpt_info->entry[i].ref_count -= ref[i - spt];
+               if (smpt_info->entry[i].ref_count < 0)
+                       dev_warn(mdev->sdev->parent,
+                                "ref count for entry %d is negative\n", i);
+       }
+       spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
+       kfree(ref);
+}
+
+/**
+ * mic_map_single - Maps a virtual address to a MIC physical address.
+ *
+ * @mdev: pointer to mic_device instance.
+ * @va: Kernel direct mapped virtual address.
+ * @size: Size of the region to be mapped.
+ *
+ * This API calls pci_map_single(..) for the direct mapped virtual address
+ * and then converts the DMA address provided to a DMA address understood
+ * by MIC. Caller should check for errors by calling mic_map_error(..).
+ *
+ * returns DMA address as required by MIC.
+ */
+dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size)
+{
+       dma_addr_t mic_addr = 0;
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+       dma_addr_t dma_addr =
+               pci_map_single(pdev, va, size, PCI_DMA_BIDIRECTIONAL);
+
+       if (!pci_dma_mapping_error(pdev, dma_addr)) {
+               mic_addr = mic_map(mdev, dma_addr, size);
+               if (!mic_addr) {
+                       dev_err(mdev->sdev->parent,
+                               "mic_map failed dma_addr 0x%llx size 0x%lx\n",
+                               dma_addr, size);
+                       pci_unmap_single(pdev, dma_addr,
+                                        size, PCI_DMA_BIDIRECTIONAL);
+               }
+       }
+       return mic_addr;
+}
+
+/**
+ * mic_unmap_single - Unmaps a MIC physical address.
+ *
+ * @mdev: pointer to mic_device instance.
+ * @mic_addr: MIC physical address.
+ * @size: Size of the region to be unmapped.
+ *
+ * This API unmaps the mappings created by mic_map_single(..).
+ *
+ * returns None.
+ */
+void
+mic_unmap_single(struct mic_device *mdev, dma_addr_t mic_addr, size_t size)
+{
+       struct pci_dev *pdev = container_of(mdev->sdev->parent,
+               struct pci_dev, dev);
+       dma_addr_t dma_addr = mic_to_dma_addr(mdev, mic_addr);
+       mic_unmap(mdev, mic_addr, size);
+       pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
+}
+
+/**
+ * mic_smpt_init - Initialize MIC System Memory Page Tables.
+ *
+ * @mdev: pointer to mic_device instance.
+ *
+ * returns 0 for success and -errno for error.
+ */
+int mic_smpt_init(struct mic_device *mdev)
+{
+       int i, err = 0;
+       dma_addr_t dma_addr;
+       struct mic_smpt_info *smpt_info;
+
+       mdev->smpt = kmalloc(sizeof(*mdev->smpt), GFP_KERNEL);
+       if (!mdev->smpt)
+               return -ENOMEM;
+
+       smpt_info = mdev->smpt;
+       mdev->smpt_ops->init(mdev);
+       smpt_info->entry = kmalloc_array(smpt_info->info.num_reg,
+                                        sizeof(*smpt_info->entry), GFP_KERNEL);
+       if (!smpt_info->entry) {
+               err = -ENOMEM;
+               goto free_smpt;
+       }
+       spin_lock_init(&smpt_info->smpt_lock);
+       for (i = 0; i < smpt_info->info.num_reg; i++) {
+               dma_addr = i * smpt_info->info.page_size;
+               smpt_info->entry[i].dma_addr = dma_addr;
+               smpt_info->entry[i].ref_count = 0;
+               mdev->smpt_ops->set(mdev, dma_addr, i);
+       }
+       smpt_info->ref_count = 0;
+       smpt_info->map_count = 0;
+       smpt_info->unmap_count = 0;
+       return 0;
+free_smpt:
+       kfree(smpt_info);
+       return err;
+}
+
+/**
+ * mic_smpt_uninit - UnInitialize MIC System Memory Page Tables.
+ *
+ * @mdev: pointer to mic_device instance.
+ *
+ * returns None.
+ */
+void mic_smpt_uninit(struct mic_device *mdev)
+{
+       struct mic_smpt_info *smpt_info = mdev->smpt;
+       int i;
+
+       dev_dbg(mdev->sdev->parent,
+               "nodeid %d SMPT ref count %lld map %lld unmap %lld\n",
+               mdev->id, smpt_info->ref_count,
+               smpt_info->map_count, smpt_info->unmap_count);
+
+       for (i = 0; i < smpt_info->info.num_reg; i++) {
+               dev_dbg(mdev->sdev->parent,
+                       "SMPT entry[%d] dma_addr = 0x%llx ref_count = %lld\n",
+                       i, smpt_info->entry[i].dma_addr,
+                       smpt_info->entry[i].ref_count);
+               if (smpt_info->entry[i].ref_count)
+                       dev_warn(mdev->sdev->parent,
+                                "ref count for entry %d is not zero\n", i);
+       }
+       kfree(smpt_info->entry);
+       kfree(smpt_info);
+}
+
+/**
+ * mic_smpt_restore - Restore MIC System Memory Page Tables.
+ *
+ * @mdev: pointer to mic_device instance.
+ *
+ * Restore the SMPT registers to values previously stored in the
+ * SW data structures. Some MIC steppings lose register state
+ * across resets and this API should be called for performing
+ * a restore operation if required.
+ *
+ * returns None.
+ */
+void mic_smpt_restore(struct mic_device *mdev)
+{
+       int i;
+       dma_addr_t dma_addr;
+
+       for (i = 0; i < mdev->smpt->info.num_reg; i++) {
+               dma_addr = mdev->smpt->entry[i].dma_addr;
+               mdev->smpt_ops->set(mdev, dma_addr, i);
+       }
+}
diff --git a/drivers/misc/mic/host/mic_smpt.h b/drivers/misc/mic/host/mic_smpt.h
new file mode 100644 (file)
index 0000000..51970ab
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef MIC_SMPT_H
+#define MIC_SMPT_H
+/**
+ * struct mic_smpt_ops - MIC HW specific SMPT operations.
+ * @init: Initialize hardware specific SMPT information in mic_smpt_hw_info.
+ * @set: Set the value for a particular SMPT entry.
+ */
+struct mic_smpt_ops {
+       void (*init)(struct mic_device *mdev);
+       void (*set)(struct mic_device *mdev, dma_addr_t dma_addr, u8 index);
+};
+
+/**
+ * struct mic_smpt - MIC SMPT entry information.
+ * @dma_addr: Base DMA address for this SMPT entry.
+ * @ref_count: Number of active mappings for this SMPT entry in bytes.
+ */
+struct mic_smpt {
+       dma_addr_t dma_addr;
+       s64 ref_count;
+};
+
+/**
+ * struct mic_smpt_hw_info - MIC SMPT hardware specific information.
+ * @num_reg: Number of SMPT registers.
+ * @page_shift: System memory page shift.
+ * @page_size: System memory page size.
+ * @base: System address base.
+ */
+struct mic_smpt_hw_info {
+       u8 num_reg;
+       u8 page_shift;
+       u64 page_size;
+       u64 base;
+};
+
+/**
+ * struct mic_smpt_info - MIC SMPT information.
+ * @entry: Array of SMPT entries.
+ * @smpt_lock: Spin lock protecting access to SMPT data structures.
+ * @info: Hardware specific SMPT information.
+ * @ref_count: Number of active SMPT mappings (for debug).
+ * @map_count: Number of SMPT mappings created (for debug).
+ * @unmap_count: Number of SMPT mappings destroyed (for debug).
+ */
+struct mic_smpt_info {
+       struct mic_smpt *entry;
+       spinlock_t smpt_lock;
+       struct mic_smpt_hw_info info;
+       s64 ref_count;
+       s64 map_count;
+       s64 unmap_count;
+};
+
+dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size);
+void mic_unmap_single(struct mic_device *mdev,
+       dma_addr_t mic_addr, size_t size);
+dma_addr_t mic_map(struct mic_device *mdev,
+       dma_addr_t dma_addr, size_t size);
+void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size);
+
+/**
+ * mic_map_error - Check a MIC address for errors.
+ *
+ * @mdev: pointer to mic_device instance.
+ *
+ * returns Whether there was an error during mic_map..(..) APIs.
+ */
+static inline bool mic_map_error(dma_addr_t mic_addr)
+{
+       return !mic_addr;
+}
+
+int mic_smpt_init(struct mic_device *mdev);
+void mic_smpt_uninit(struct mic_device *mdev);
+void mic_smpt_restore(struct mic_device *mdev);
+
+#endif
diff --git a/drivers/misc/mic/host/mic_sysfs.c b/drivers/misc/mic/host/mic_sysfs.c
new file mode 100644 (file)
index 0000000..6dd864e
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/pci.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+
+/*
+ * A state-to-string lookup table, for exposing a human readable state
+ * via sysfs. Always keep in sync with enum mic_states
+ */
+static const char * const mic_state_string[] = {
+       [MIC_OFFLINE] = "offline",
+       [MIC_ONLINE] = "online",
+       [MIC_SHUTTING_DOWN] = "shutting_down",
+       [MIC_RESET_FAILED] = "reset_failed",
+       [MIC_SUSPENDING] = "suspending",
+       [MIC_SUSPENDED] = "suspended",
+};
+
+/*
+ * A shutdown-status-to-string lookup table, for exposing a human
+ * readable state via sysfs. Always keep in sync with enum mic_shutdown_status
+ */
+static const char * const mic_shutdown_status_string[] = {
+       [MIC_NOP] = "nop",
+       [MIC_CRASHED] = "crashed",
+       [MIC_HALTED] = "halted",
+       [MIC_POWER_OFF] = "poweroff",
+       [MIC_RESTART] = "restart",
+};
+
+void mic_set_shutdown_status(struct mic_device *mdev, u8 shutdown_status)
+{
+       dev_dbg(mdev->sdev->parent, "Shutdown Status %s -> %s\n",
+               mic_shutdown_status_string[mdev->shutdown_status],
+               mic_shutdown_status_string[shutdown_status]);
+       mdev->shutdown_status = shutdown_status;
+}
+
+void mic_set_state(struct mic_device *mdev, u8 state)
+{
+       dev_dbg(mdev->sdev->parent, "State %s -> %s\n",
+               mic_state_string[mdev->state],
+               mic_state_string[state]);
+       mdev->state = state;
+       sysfs_notify_dirent(mdev->state_sysfs);
+}
+
+static ssize_t
+family_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       static const char x100[] = "x100";
+       static const char unknown[] = "Unknown";
+       const char *card = NULL;
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       switch (mdev->family) {
+       case MIC_FAMILY_X100:
+               card = x100;
+               break;
+       default:
+               card = unknown;
+               break;
+       }
+       return scnprintf(buf, PAGE_SIZE, "%s\n", card);
+}
+static DEVICE_ATTR_RO(family);
+
+static ssize_t
+stepping_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       char *string = "??";
+
+       if (!mdev)
+               return -EINVAL;
+
+       switch (mdev->stepping) {
+       case MIC_A0_STEP:
+               string = "A0";
+               break;
+       case MIC_B0_STEP:
+               string = "B0";
+               break;
+       case MIC_B1_STEP:
+               string = "B1";
+               break;
+       case MIC_C0_STEP:
+               string = "C0";
+               break;
+       default:
+               break;
+       }
+       return scnprintf(buf, PAGE_SIZE, "%s\n", string);
+}
+static DEVICE_ATTR_RO(stepping);
+
+static ssize_t
+state_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev || mdev->state >= MIC_LAST)
+               return -EINVAL;
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n",
+               mic_state_string[mdev->state]);
+}
+
+static ssize_t
+state_store(struct device *dev, struct device_attribute *attr,
+           const char *buf, size_t count)
+{
+       int rc = 0;
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       if (!mdev)
+               return -EINVAL;
+       if (sysfs_streq(buf, "boot")) {
+               rc = mic_start(mdev, buf);
+               if (rc) {
+                       dev_err(mdev->sdev->parent,
+                               "mic_boot failed rc %d\n", rc);
+                       count = rc;
+               }
+               goto done;
+       }
+
+       if (sysfs_streq(buf, "reset")) {
+               schedule_work(&mdev->reset_trigger_work);
+               goto done;
+       }
+
+       if (sysfs_streq(buf, "shutdown")) {
+               mic_shutdown(mdev);
+               goto done;
+       }
+
+       if (sysfs_streq(buf, "suspend")) {
+               mic_suspend(mdev);
+               goto done;
+       }
+
+       count = -EINVAL;
+done:
+       return count;
+}
+static DEVICE_ATTR_RW(state);
+
+static ssize_t shutdown_status_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev || mdev->shutdown_status >= MIC_STATUS_LAST)
+               return -EINVAL;
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n",
+               mic_shutdown_status_string[mdev->shutdown_status]);
+}
+static DEVICE_ATTR_RO(shutdown_status);
+
+static ssize_t
+cmdline_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       char *cmdline;
+
+       if (!mdev)
+               return -EINVAL;
+
+       cmdline = mdev->cmdline;
+
+       if (cmdline)
+               return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline);
+       return 0;
+}
+
+static ssize_t
+cmdline_store(struct device *dev, struct device_attribute *attr,
+             const char *buf, size_t count)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       mutex_lock(&mdev->mic_mutex);
+       kfree(mdev->cmdline);
+
+       mdev->cmdline = kmalloc(count + 1, GFP_KERNEL);
+       if (!mdev->cmdline) {
+               count = -ENOMEM;
+               goto unlock;
+       }
+
+       strncpy(mdev->cmdline, buf, count);
+
+       if (mdev->cmdline[count - 1] == '\n')
+               mdev->cmdline[count - 1] = '\0';
+       else
+               mdev->cmdline[count] = '\0';
+unlock:
+       mutex_unlock(&mdev->mic_mutex);
+       return count;
+}
+static DEVICE_ATTR_RW(cmdline);
+
+static ssize_t
+firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       char *firmware;
+
+       if (!mdev)
+               return -EINVAL;
+
+       firmware = mdev->firmware;
+
+       if (firmware)
+               return scnprintf(buf, PAGE_SIZE, "%s\n", firmware);
+       return 0;
+}
+
+static ssize_t
+firmware_store(struct device *dev, struct device_attribute *attr,
+              const char *buf, size_t count)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       mutex_lock(&mdev->mic_mutex);
+       kfree(mdev->firmware);
+
+       mdev->firmware = kmalloc(count + 1, GFP_KERNEL);
+       if (!mdev->firmware) {
+               count = -ENOMEM;
+               goto unlock;
+       }
+       strncpy(mdev->firmware, buf, count);
+
+       if (mdev->firmware[count - 1] == '\n')
+               mdev->firmware[count - 1] = '\0';
+       else
+               mdev->firmware[count] = '\0';
+unlock:
+       mutex_unlock(&mdev->mic_mutex);
+       return count;
+}
+static DEVICE_ATTR_RW(firmware);
+
+static ssize_t
+ramdisk_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       char *ramdisk;
+
+       if (!mdev)
+               return -EINVAL;
+
+       ramdisk = mdev->ramdisk;
+
+       if (ramdisk)
+               return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk);
+       return 0;
+}
+
+static ssize_t
+ramdisk_store(struct device *dev, struct device_attribute *attr,
+             const char *buf, size_t count)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       mutex_lock(&mdev->mic_mutex);
+       kfree(mdev->ramdisk);
+
+       mdev->ramdisk = kmalloc(count + 1, GFP_KERNEL);
+       if (!mdev->ramdisk) {
+               count = -ENOMEM;
+               goto unlock;
+       }
+
+       strncpy(mdev->ramdisk, buf, count);
+
+       if (mdev->ramdisk[count - 1] == '\n')
+               mdev->ramdisk[count - 1] = '\0';
+       else
+               mdev->ramdisk[count] = '\0';
+unlock:
+       mutex_unlock(&mdev->mic_mutex);
+       return count;
+}
+static DEVICE_ATTR_RW(ramdisk);
+
+static ssize_t
+bootmode_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       char *bootmode;
+
+       if (!mdev)
+               return -EINVAL;
+
+       bootmode = mdev->bootmode;
+
+       if (bootmode)
+               return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode);
+       return 0;
+}
+
+static ssize_t
+bootmode_store(struct device *dev, struct device_attribute *attr,
+              const char *buf, size_t count)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "elf"))
+               return -EINVAL;
+
+       mutex_lock(&mdev->mic_mutex);
+       kfree(mdev->bootmode);
+
+       mdev->bootmode = kmalloc(count + 1, GFP_KERNEL);
+       if (!mdev->bootmode) {
+               count = -ENOMEM;
+               goto unlock;
+       }
+
+       strncpy(mdev->bootmode, buf, count);
+
+       if (mdev->bootmode[count - 1] == '\n')
+               mdev->bootmode[count - 1] = '\0';
+       else
+               mdev->bootmode[count] = '\0';
+unlock:
+       mutex_unlock(&mdev->mic_mutex);
+       return count;
+}
+static DEVICE_ATTR_RW(bootmode);
+
+static ssize_t
+log_buf_addr_show(struct device *dev, struct device_attribute *attr,
+                 char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_addr);
+}
+
+static ssize_t
+log_buf_addr_store(struct device *dev, struct device_attribute *attr,
+                  const char *buf, size_t count)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       int ret;
+       unsigned long addr;
+
+       if (!mdev)
+               return -EINVAL;
+
+       ret = kstrtoul(buf, 16, &addr);
+       if (ret)
+               goto exit;
+
+       mdev->log_buf_addr = (void *)addr;
+       ret = count;
+exit:
+       return ret;
+}
+static DEVICE_ATTR_RW(log_buf_addr);
+
+static ssize_t
+log_buf_len_show(struct device *dev, struct device_attribute *attr,
+                char *buf)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+       if (!mdev)
+               return -EINVAL;
+
+       return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_len);
+}
+
+static ssize_t
+log_buf_len_store(struct device *dev, struct device_attribute *attr,
+                 const char *buf, size_t count)
+{
+       struct mic_device *mdev = dev_get_drvdata(dev->parent);
+       int ret;
+       unsigned long addr;
+
+       if (!mdev)
+               return -EINVAL;
+
+       ret = kstrtoul(buf, 16, &addr);
+       if (ret)
+               goto exit;
+
+       mdev->log_buf_len = (int *)addr;
+       ret = count;
+exit:
+       return ret;
+}
+static DEVICE_ATTR_RW(log_buf_len);
+
+static struct attribute *mic_default_attrs[] = {
+       &dev_attr_family.attr,
+       &dev_attr_stepping.attr,
+       &dev_attr_state.attr,
+       &dev_attr_shutdown_status.attr,
+       &dev_attr_cmdline.attr,
+       &dev_attr_firmware.attr,
+       &dev_attr_ramdisk.attr,
+       &dev_attr_bootmode.attr,
+       &dev_attr_log_buf_addr.attr,
+       &dev_attr_log_buf_len.attr,
+
+       NULL
+};
+
+ATTRIBUTE_GROUPS(mic_default);
+
+void mic_sysfs_init(struct mic_device *mdev)
+{
+       mdev->attr_group = mic_default_groups;
+}
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
new file mode 100644 (file)
index 0000000..5b8494b
--- /dev/null
@@ -0,0 +1,700 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_smpt.h"
+#include "mic_virtio.h"
+
+/*
+ * Initiates the copies across the PCIe bus from card memory to
+ * a user space buffer.
+ */
+static int mic_virtio_copy_to_user(struct mic_vdev *mvdev,
+               void __user *ubuf, size_t len, u64 addr)
+{
+       int err;
+       void __iomem *dbuf = mvdev->mdev->aper.va + addr;
+       /*
+        * 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)) {
+               err = -EFAULT;
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, err);
+               goto err;
+       }
+       mvdev->in_bytes += len;
+       err = 0;
+err:
+       return err;
+}
+
+/*
+ * Initiates copies across the PCIe bus from a user space
+ * buffer to card memory.
+ */
+static int mic_virtio_copy_from_user(struct mic_vdev *mvdev,
+               void __user *ubuf, size_t len, u64 addr)
+{
+       int err;
+       void __iomem *dbuf = mvdev->mdev->aper.va + addr;
+       /*
+        * 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)) {
+               err = -EFAULT;
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, err);
+               goto err;
+       }
+       mvdev->out_bytes += len;
+       err = 0;
+err:
+       return err;
+}
+
+#define MIC_VRINGH_READ true
+
+/* The function to call to notify the card about added buffers */
+static void mic_notify(struct vringh *vrh)
+{
+       struct mic_vringh *mvrh = container_of(vrh, struct mic_vringh, vrh);
+       struct mic_vdev *mvdev = mvrh->mvdev;
+       s8 db = mvdev->dc->h2c_vdev_db;
+
+       if (db != -1)
+               mvdev->mdev->ops->send_intr(mvdev->mdev, db);
+}
+
+/* Determine the total number of bytes consumed in a VRINGH KIOV */
+static inline u32 mic_vringh_iov_consumed(struct vringh_kiov *iov)
+{
+       int i;
+       u32 total = iov->consumed;
+
+       for (i = 0; i < iov->i; i++)
+               total += iov->iov[i].iov_len;
+       return total;
+}
+
+/*
+ * Traverse the VRINGH KIOV and issue the APIs to trigger the copies.
+ * This API is heavily based on the vringh_iov_xfer(..) implementation
+ * in vringh.c. The reason we cannot reuse vringh_iov_pull_kern(..)
+ * and vringh_iov_push_kern(..) directly is because there is no
+ * way to override the VRINGH xfer(..) routines as of v3.10.
+ */
+static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
+       void __user *ubuf, size_t len, bool read, size_t *out_len)
+{
+       int ret = 0;
+       size_t partlen, tot_len = 0;
+
+       while (len && iov->i < iov->used) {
+               partlen = min(iov->iov[iov->i].iov_len, len);
+               if (read)
+                       ret = mic_virtio_copy_to_user(mvdev,
+                               ubuf, partlen,
+                               (u64)iov->iov[iov->i].iov_base);
+               else
+                       ret = mic_virtio_copy_from_user(mvdev,
+                               ubuf, partlen,
+                               (u64)iov->iov[iov->i].iov_base);
+               if (ret) {
+                       dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                               __func__, __LINE__, ret);
+                       break;
+               }
+               len -= partlen;
+               ubuf += partlen;
+               tot_len += partlen;
+               iov->consumed += partlen;
+               iov->iov[iov->i].iov_len -= partlen;
+               iov->iov[iov->i].iov_base += partlen;
+               if (!iov->iov[iov->i].iov_len) {
+                       /* Fix up old iov element then increment. */
+                       iov->iov[iov->i].iov_len = iov->consumed;
+                       iov->iov[iov->i].iov_base -= iov->consumed;
+
+                       iov->consumed = 0;
+                       iov->i++;
+               }
+       }
+       *out_len = tot_len;
+       return ret;
+}
+
+/*
+ * Use the standard VRINGH infrastructure in the kernel to fetch new
+ * descriptors, initiate the copies and update the used ring.
+ */
+static int _mic_virtio_copy(struct mic_vdev *mvdev,
+       struct mic_copy_desc *copy)
+{
+       int ret = 0, iovcnt = copy->iovcnt;
+       struct iovec iov;
+       struct iovec __user *u_iov = copy->iov;
+       void __user *ubuf = NULL;
+       struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
+       struct vringh_kiov *riov = &mvr->riov;
+       struct vringh_kiov *wiov = &mvr->wiov;
+       struct vringh *vrh = &mvr->vrh;
+       u16 *head = &mvr->head;
+       struct mic_vring *vr = &mvr->vring;
+       size_t len = 0, out_len;
+
+       copy->out_len = 0;
+       /* Fetch a new IOVEC if all previous elements have been processed */
+       if (riov->i == riov->used && wiov->i == wiov->used) {
+               ret = vringh_getdesc_kern(vrh, riov, wiov,
+                               head, GFP_KERNEL);
+               /* Check if there are available descriptors */
+               if (ret <= 0)
+                       return ret;
+       }
+       while (iovcnt) {
+               if (!len) {
+                       /* Copy over a new iovec from user space. */
+                       ret = copy_from_user(&iov, u_iov, sizeof(*u_iov));
+                       if (ret) {
+                               ret = -EINVAL;
+                               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                                       __func__, __LINE__, ret);
+                               break;
+                       }
+                       len = iov.iov_len;
+                       ubuf = iov.iov_base;
+               }
+               /* Issue all the read descriptors first */
+               ret = mic_vringh_copy(mvdev, riov, ubuf, len,
+                       MIC_VRINGH_READ, &out_len);
+               if (ret) {
+                       dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                               __func__, __LINE__, ret);
+                       break;
+               }
+               len -= out_len;
+               ubuf += out_len;
+               copy->out_len += out_len;
+               /* Issue the write descriptors next */
+               ret = mic_vringh_copy(mvdev, wiov, ubuf, len,
+                       !MIC_VRINGH_READ, &out_len);
+               if (ret) {
+                       dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                               __func__, __LINE__, ret);
+                       break;
+               }
+               len -= out_len;
+               ubuf += out_len;
+               copy->out_len += out_len;
+               if (!len) {
+                       /* One user space iovec is now completed */
+                       iovcnt--;
+                       u_iov++;
+               }
+               /* Exit loop if all elements in KIOVs have been processed. */
+               if (riov->i == riov->used && wiov->i == wiov->used)
+                       break;
+       }
+       /*
+        * Update the used ring if a descriptor was available and some data was
+        * copied in/out and the user asked for a used ring update.
+        */
+       if (*head != USHRT_MAX && copy->out_len && copy->update_used) {
+               u32 total = 0;
+
+               /* Determine the total data consumed */
+               total += mic_vringh_iov_consumed(riov);
+               total += mic_vringh_iov_consumed(wiov);
+               vringh_complete_kern(vrh, *head, total);
+               *head = USHRT_MAX;
+               if (vringh_need_notify_kern(vrh) > 0)
+                       vringh_notify(vrh);
+               vringh_kiov_cleanup(riov);
+               vringh_kiov_cleanup(wiov);
+               /* Update avail idx for user space */
+               vr->info->avail_idx = vrh->last_avail_idx;
+       }
+       return ret;
+}
+
+static inline int mic_verify_copy_args(struct mic_vdev *mvdev,
+               struct mic_copy_desc *copy)
+{
+       if (copy->vr_idx >= mvdev->dd->num_vq) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -EINVAL);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/* Copy a specified number of virtio descriptors in a chain */
+int mic_virtio_copy_desc(struct mic_vdev *mvdev,
+               struct mic_copy_desc *copy)
+{
+       int err;
+       struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
+
+       err = mic_verify_copy_args(mvdev, copy);
+       if (err)
+               return err;
+
+       mutex_lock(&mvr->vr_mutex);
+       if (!mic_vdevup(mvdev)) {
+               err = -ENODEV;
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, err);
+               goto err;
+       }
+       err = _mic_virtio_copy(mvdev, copy);
+       if (err) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, err);
+       }
+err:
+       mutex_unlock(&mvr->vr_mutex);
+       return err;
+}
+
+static void mic_virtio_init_post(struct mic_vdev *mvdev)
+{
+       struct mic_vqconfig *vqconfig = mic_vq_config(mvdev->dd);
+       int i;
+
+       for (i = 0; i < mvdev->dd->num_vq; i++) {
+               if (!le64_to_cpu(vqconfig[i].used_address)) {
+                       dev_warn(mic_dev(mvdev), "used_address zero??\n");
+                       continue;
+               }
+               mvdev->mvr[i].vrh.vring.used =
+                       mvdev->mdev->aper.va +
+                       le64_to_cpu(vqconfig[i].used_address);
+       }
+
+       mvdev->dc->used_address_updated = 0;
+
+       dev_dbg(mic_dev(mvdev), "%s: device type %d LINKUP\n",
+               __func__, mvdev->virtio_id);
+}
+
+static inline void mic_virtio_device_reset(struct mic_vdev *mvdev)
+{
+       int i;
+
+       dev_dbg(mic_dev(mvdev), "%s: status %d device type %d RESET\n",
+               __func__, mvdev->dd->status, mvdev->virtio_id);
+
+       for (i = 0; i < mvdev->dd->num_vq; i++)
+               /*
+                * Avoid lockdep false positive. The + 1 is for the mic
+                * mutex which is held in the reset devices code path.
+                */
+               mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
+
+       /* 0 status means "reset" */
+       mvdev->dd->status = 0;
+       mvdev->dc->vdev_reset = 0;
+       mvdev->dc->host_ack = 1;
+
+       for (i = 0; i < mvdev->dd->num_vq; i++) {
+               struct vringh *vrh = &mvdev->mvr[i].vrh;
+               mvdev->mvr[i].vring.info->avail_idx = 0;
+               vrh->completed = 0;
+               vrh->last_avail_idx = 0;
+               vrh->last_used_idx = 0;
+       }
+
+       for (i = 0; i < mvdev->dd->num_vq; i++)
+               mutex_unlock(&mvdev->mvr[i].vr_mutex);
+}
+
+void mic_virtio_reset_devices(struct mic_device *mdev)
+{
+       struct list_head *pos, *tmp;
+       struct mic_vdev *mvdev;
+
+       dev_dbg(mdev->sdev->parent, "%s\n",  __func__);
+
+       list_for_each_safe(pos, tmp, &mdev->vdev_list) {
+               mvdev = list_entry(pos, struct mic_vdev, list);
+               mic_virtio_device_reset(mvdev);
+               mvdev->poll_wake = 1;
+               wake_up(&mvdev->waitq);
+       }
+}
+
+void mic_bh_handler(struct work_struct *work)
+{
+       struct mic_vdev *mvdev = container_of(work, struct mic_vdev,
+                       virtio_bh_work);
+
+       if (mvdev->dc->used_address_updated)
+               mic_virtio_init_post(mvdev);
+
+       if (mvdev->dc->vdev_reset)
+               mic_virtio_device_reset(mvdev);
+
+       mvdev->poll_wake = 1;
+       wake_up(&mvdev->waitq);
+}
+
+static irqreturn_t mic_virtio_intr_handler(int irq, void *data)
+{
+       struct mic_vdev *mvdev = data;
+       struct mic_device *mdev = mvdev->mdev;
+
+       mdev->ops->ack_interrupt(mdev);
+       schedule_work(&mvdev->virtio_bh_work);
+       return IRQ_HANDLED;
+}
+
+int mic_virtio_config_change(struct mic_vdev *mvdev,
+                       void __user *argp)
+{
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+       int ret = 0, retry = 100, i;
+       struct mic_bootparam *bootparam = mvdev->mdev->dp;
+       s8 db = bootparam->h2c_config_db;
+
+       mutex_lock(&mvdev->mdev->mic_mutex);
+       for (i = 0; i < mvdev->dd->num_vq; i++)
+               mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
+
+       if (db == -1 || mvdev->dd->type == -1) {
+               ret = -EIO;
+               goto exit;
+       }
+
+       if (copy_from_user(mic_vq_configspace(mvdev->dd),
+                          argp, mvdev->dd->config_len)) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -EFAULT);
+               ret = -EFAULT;
+               goto exit;
+       }
+       mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
+       mvdev->mdev->ops->send_intr(mvdev->mdev, db);
+
+       for (i = retry; i--;) {
+               ret = wait_event_timeout(wake,
+                       mvdev->dc->guest_ack, msecs_to_jiffies(100));
+               if (ret)
+                       break;
+       }
+
+       dev_dbg(mic_dev(mvdev),
+               "%s %d retry: %d\n", __func__, __LINE__, retry);
+       mvdev->dc->config_change = 0;
+       mvdev->dc->guest_ack = 0;
+exit:
+       for (i = 0; i < mvdev->dd->num_vq; i++)
+               mutex_unlock(&mvdev->mvr[i].vr_mutex);
+       mutex_unlock(&mvdev->mdev->mic_mutex);
+       return ret;
+}
+
+static int mic_copy_dp_entry(struct mic_vdev *mvdev,
+                                       void __user *argp,
+                                       __u8 *type,
+                                       struct mic_device_desc **devpage)
+{
+       struct mic_device *mdev = mvdev->mdev;
+       struct mic_device_desc dd, *dd_config, *devp;
+       struct mic_vqconfig *vqconfig;
+       int ret = 0, i;
+       bool slot_found = false;
+
+       if (copy_from_user(&dd, argp, sizeof(dd))) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -EFAULT);
+               return -EFAULT;
+       }
+
+       if (mic_aligned_desc_size(&dd) > MIC_MAX_DESC_BLK_SIZE ||
+           dd.num_vq > MIC_MAX_VRINGS) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -EINVAL);
+               return -EINVAL;
+       }
+
+       dd_config = kmalloc(mic_desc_size(&dd), GFP_KERNEL);
+       if (dd_config == NULL) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -ENOMEM);
+               return -ENOMEM;
+       }
+       if (copy_from_user(dd_config, argp, mic_desc_size(&dd))) {
+               ret = -EFAULT;
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, ret);
+               goto exit;
+       }
+
+       vqconfig = mic_vq_config(dd_config);
+       for (i = 0; i < dd.num_vq; i++) {
+               if (le16_to_cpu(vqconfig[i].num) > MIC_MAX_VRING_ENTRIES) {
+                       ret =  -EINVAL;
+                       dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                               __func__, __LINE__, ret);
+                       goto exit;
+               }
+       }
+
+       /* Find the first free device page entry */
+       for (i = mic_aligned_size(struct mic_bootparam);
+               i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
+               i += mic_total_desc_size(devp)) {
+               devp = mdev->dp + i;
+               if (devp->type == 0 || devp->type == -1) {
+                       slot_found = true;
+                       break;
+               }
+       }
+       if (!slot_found) {
+               ret =  -EINVAL;
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, ret);
+               goto exit;
+       }
+       /*
+        * Save off the type before doing the memcpy. Type will be set in the
+        * end after completing all initialization for the new device.
+        */
+       *type = dd_config->type;
+       dd_config->type = 0;
+       memcpy(devp, dd_config, mic_desc_size(dd_config));
+
+       *devpage = devp;
+exit:
+       kfree(dd_config);
+       return ret;
+}
+
+static void mic_init_device_ctrl(struct mic_vdev *mvdev,
+                               struct mic_device_desc *devpage)
+{
+       struct mic_device_ctrl *dc;
+
+       dc = (void *)devpage + mic_aligned_desc_size(devpage);
+
+       dc->config_change = 0;
+       dc->guest_ack = 0;
+       dc->vdev_reset = 0;
+       dc->host_ack = 0;
+       dc->used_address_updated = 0;
+       dc->c2h_vdev_db = -1;
+       dc->h2c_vdev_db = -1;
+       mvdev->dc = dc;
+}
+
+int mic_virtio_add_device(struct mic_vdev *mvdev,
+                       void __user *argp)
+{
+       struct mic_device *mdev = mvdev->mdev;
+       struct mic_device_desc *dd = NULL;
+       struct mic_vqconfig *vqconfig;
+       int vr_size, i, j, ret;
+       u8 type = 0;
+       s8 db;
+       char irqname[10];
+       struct mic_bootparam *bootparam = mdev->dp;
+       u16 num;
+
+       mutex_lock(&mdev->mic_mutex);
+
+       ret = mic_copy_dp_entry(mvdev, argp, &type, &dd);
+       if (ret) {
+               mutex_unlock(&mdev->mic_mutex);
+               return ret;
+       }
+
+       mic_init_device_ctrl(mvdev, dd);
+
+       mvdev->dd = dd;
+       mvdev->virtio_id = type;
+       vqconfig = mic_vq_config(dd);
+       INIT_WORK(&mvdev->virtio_bh_work, mic_bh_handler);
+
+       for (i = 0; i < dd->num_vq; i++) {
+               struct mic_vringh *mvr = &mvdev->mvr[i];
+               struct mic_vring *vr = &mvdev->mvr[i].vring;
+               num = le16_to_cpu(vqconfig[i].num);
+               mutex_init(&mvr->vr_mutex);
+               vr_size = PAGE_ALIGN(vring_size(num, MIC_VIRTIO_RING_ALIGN) +
+                       sizeof(struct _mic_vring_info));
+               vr->va = (void *)
+                       __get_free_pages(GFP_KERNEL | __GFP_ZERO,
+                                        get_order(vr_size));
+               if (!vr->va) {
+                       ret = -ENOMEM;
+                       dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                               __func__, __LINE__, ret);
+                       goto err;
+               }
+               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)) {
+                       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);
+
+               vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN);
+               ret = vringh_init_kern(&mvr->vrh,
+                       *(u32 *)mic_vq_features(mvdev->dd), num, false,
+                       vr->vr.desc, vr->vr.avail, vr->vr.used);
+               if (ret) {
+                       dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                               __func__, __LINE__, ret);
+                       goto err;
+               }
+               vringh_kiov_init(&mvr->riov, NULL, 0);
+               vringh_kiov_init(&mvr->wiov, NULL, 0);
+               mvr->head = USHRT_MAX;
+               mvr->mvdev = mvdev;
+               mvr->vrh.notify = mic_notify;
+               dev_dbg(mdev->sdev->parent,
+                       "%s %d index %d va %p info %p vr_size 0x%x\n",
+                       __func__, __LINE__, i, vr->va, vr->info, vr_size);
+       }
+
+       snprintf(irqname, sizeof(irqname), "mic%dvirtio%d", mdev->id,
+                mvdev->virtio_id);
+       mvdev->virtio_db = mic_next_db(mdev);
+       mvdev->virtio_cookie = mic_request_irq(mdev, mic_virtio_intr_handler,
+                       irqname, mvdev, mvdev->virtio_db, MIC_INTR_DB);
+       if (IS_ERR(mvdev->virtio_cookie)) {
+               ret = PTR_ERR(mvdev->virtio_cookie);
+               dev_dbg(mdev->sdev->parent, "request irq failed\n");
+               goto err;
+       }
+
+       mvdev->dc->c2h_vdev_db = mvdev->virtio_db;
+
+       list_add_tail(&mvdev->list, &mdev->vdev_list);
+       /*
+        * Order the type update with previous stores. This write barrier
+        * is paired with the corresponding read barrier before the uncached
+        * system memory read of the type, on the card while scanning the
+        * device page.
+        */
+       smp_wmb();
+       dd->type = type;
+
+       dev_dbg(mdev->sdev->parent, "Added virtio device id %d\n", dd->type);
+
+       db = bootparam->h2c_config_db;
+       if (db != -1)
+               mdev->ops->send_intr(mdev, db);
+       mutex_unlock(&mdev->mic_mutex);
+       return 0;
+err:
+       vqconfig = mic_vq_config(dd);
+       for (j = 0; j < i; j++) {
+               struct mic_vringh *mvr = &mvdev->mvr[j];
+               mic_unmap_single(mdev, le64_to_cpu(vqconfig[j].address),
+                                mvr->vring.len);
+               free_pages((unsigned long)mvr->vring.va,
+                          get_order(mvr->vring.len));
+       }
+       mutex_unlock(&mdev->mic_mutex);
+       return ret;
+}
+
+void mic_virtio_del_device(struct mic_vdev *mvdev)
+{
+       struct list_head *pos, *tmp;
+       struct mic_vdev *tmp_mvdev;
+       struct mic_device *mdev = mvdev->mdev;
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+       int i, ret, retry = 100;
+       struct mic_vqconfig *vqconfig;
+       struct mic_bootparam *bootparam = mdev->dp;
+       s8 db;
+
+       mutex_lock(&mdev->mic_mutex);
+       db = bootparam->h2c_config_db;
+       if (db == -1)
+               goto skip_hot_remove;
+       dev_dbg(mdev->sdev->parent,
+               "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--;) {
+               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",
+               mvdev->virtio_id, mvdev->dc->config_change,
+               mvdev->dc->guest_ack);
+       mvdev->dc->config_change = 0;
+       mvdev->dc->guest_ack = 0;
+skip_hot_remove:
+       mic_free_irq(mdev, mvdev->virtio_cookie, mvdev);
+       flush_work(&mvdev->virtio_bh_work);
+       vqconfig = mic_vq_config(mvdev->dd);
+       for (i = 0; i < mvdev->dd->num_vq; i++) {
+               struct mic_vringh *mvr = &mvdev->mvr[i];
+               vringh_kiov_cleanup(&mvr->riov);
+               vringh_kiov_cleanup(&mvr->wiov);
+               mic_unmap_single(mdev, le64_to_cpu(vqconfig[i].address),
+                                mvr->vring.len);
+               free_pages((unsigned long)mvr->vring.va,
+                          get_order(mvr->vring.len));
+       }
+
+       list_for_each_safe(pos, tmp, &mdev->vdev_list) {
+               tmp_mvdev = list_entry(pos, struct mic_vdev, list);
+               if (tmp_mvdev == mvdev) {
+                       list_del(pos);
+                       dev_dbg(mdev->sdev->parent,
+                               "Removing virtio device id %d\n",
+                               mvdev->virtio_id);
+                       break;
+               }
+       }
+       /*
+        * Order the type update with previous stores. This write barrier
+        * is paired with the corresponding read barrier before the uncached
+        * system memory read of the type, on the card while scanning the
+        * device page.
+        */
+       smp_wmb();
+       mvdev->dd->type = -1;
+       mutex_unlock(&mdev->mic_mutex);
+}
diff --git a/drivers/misc/mic/host/mic_virtio.h b/drivers/misc/mic/host/mic_virtio.h
new file mode 100644 (file)
index 0000000..184f3c8
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef MIC_VIRTIO_H
+#define MIC_VIRTIO_H
+
+#include <linux/virtio_config.h>
+#include <linux/mic_ioctl.h>
+
+/*
+ * Note on endianness.
+ * 1. Host can be both BE or LE
+ * 2. Guest/card is LE. Host uses le_to_cpu to access desc/avail
+ *    rings and ioreadXX/iowriteXX to access used ring.
+ * 3. Device page exposed by host to guest contains LE values. Guest
+ *    accesses these using ioreadXX/iowriteXX etc. This way in general we
+ *    obey the virtio spec according to which guest works with native
+ *    endianness and host is aware of guest endianness and does all
+ *    required endianness conversion.
+ * 4. Data provided from user space to guest (in ADD_DEVICE and
+ *    CONFIG_CHANGE ioctl's) is not interpreted by the driver and should be
+ *    in guest endianness.
+ */
+
+/**
+ * struct mic_vringh - Virtio ring host information.
+ *
+ * @vring: The MIC vring used for setting up user space mappings.
+ * @vrh: The host VRINGH used for accessing the card vrings.
+ * @riov: The VRINGH read kernel IOV.
+ * @wiov: The VRINGH write kernel IOV.
+ * @head: The VRINGH head index address passed to vringh_getdesc_kern(..).
+ * @vr_mutex: Mutex for synchronizing access to the VRING.
+ * @mvdev: Back pointer to MIC virtio device for vringh_notify(..).
+ */
+struct mic_vringh {
+       struct mic_vring vring;
+       struct vringh vrh;
+       struct vringh_kiov riov;
+       struct vringh_kiov wiov;
+       u16 head;
+       struct mutex vr_mutex;
+       struct mic_vdev *mvdev;
+};
+
+/**
+ * struct mic_vdev - Host information for a card Virtio device.
+ *
+ * @virtio_id - Virtio device id.
+ * @waitq - Waitqueue to allow ring3 apps to poll.
+ * @mdev - Back pointer to host MIC device.
+ * @poll_wake - Used for waking up threads blocked in poll.
+ * @out_bytes - Debug stats for number of bytes copied from host to card.
+ * @in_bytes - Debug stats for number of bytes copied from card to host.
+ * @mvr - Store per VRING data structures.
+ * @virtio_bh_work - Work struct used to schedule virtio bottom half handling.
+ * @dd - Virtio device descriptor.
+ * @dc - Virtio device control fields.
+ * @list - List of Virtio devices.
+ * @virtio_db - The doorbell used by the card to interrupt the host.
+ * @virtio_cookie - The cookie returned while requesting interrupts.
+ */
+struct mic_vdev {
+       int virtio_id;
+       wait_queue_head_t waitq;
+       struct mic_device *mdev;
+       int poll_wake;
+       unsigned long out_bytes;
+       unsigned long in_bytes;
+       struct mic_vringh mvr[MIC_MAX_VRINGS];
+       struct work_struct virtio_bh_work;
+       struct mic_device_desc *dd;
+       struct mic_device_ctrl *dc;
+       struct list_head list;
+       int virtio_db;
+       struct mic_irq *virtio_cookie;
+};
+
+void mic_virtio_uninit(struct mic_device *mdev);
+int mic_virtio_add_device(struct mic_vdev *mvdev,
+                       void __user *argp);
+void mic_virtio_del_device(struct mic_vdev *mvdev);
+int mic_virtio_config_change(struct mic_vdev *mvdev,
+                       void __user *argp);
+int mic_virtio_copy_desc(struct mic_vdev *mvdev,
+       struct mic_copy_desc *request);
+void mic_virtio_reset_devices(struct mic_device *mdev);
+void mic_bh_handler(struct work_struct *work);
+
+/* Helper API to obtain the MIC PCIe device */
+static inline struct device *mic_dev(struct mic_vdev *mvdev)
+{
+       return mvdev->mdev->sdev->parent;
+}
+
+/* Helper API to check if a virtio device is initialized */
+static inline int mic_vdev_inited(struct mic_vdev *mvdev)
+{
+       /* Device has not been created yet */
+       if (!mvdev->dd || !mvdev->dd->type) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -EINVAL);
+               return -EINVAL;
+       }
+
+       /* Device has been removed/deleted */
+       if (mvdev->dd->type == -1) {
+               dev_err(mic_dev(mvdev), "%s %d err %d\n",
+                       __func__, __LINE__, -ENODEV);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/* Helper API to check if a virtio device is running */
+static inline bool mic_vdevup(struct mic_vdev *mvdev)
+{
+       return !!mvdev->dd->status;
+}
+#endif
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c
new file mode 100644 (file)
index 0000000..81e9541
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#include <linux/fs.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+
+#include "../common/mic_dev.h"
+#include "mic_device.h"
+#include "mic_x100.h"
+#include "mic_smpt.h"
+
+/**
+ * mic_x100_write_spad - write to the scratchpad register
+ * @mdev: pointer to mic_device instance
+ * @idx: index to the scratchpad register, 0 based
+ * @val: the data value to put into the register
+ *
+ * This function allows writing of a 32bit value to the indexed scratchpad
+ * register.
+ *
+ * RETURNS: none.
+ */
+static void
+mic_x100_write_spad(struct mic_device *mdev, unsigned int idx, u32 val)
+{
+       dev_dbg(mdev->sdev->parent, "Writing 0x%x to scratch pad index %d\n",
+               val, idx);
+       mic_mmio_write(&mdev->mmio, val,
+                      MIC_X100_SBOX_BASE_ADDRESS +
+                      MIC_X100_SBOX_SPAD0 + idx * 4);
+}
+
+/**
+ * mic_x100_read_spad - read from the scratchpad register
+ * @mdev: pointer to mic_device instance
+ * @idx: index to scratchpad register, 0 based
+ *
+ * This function allows reading of the 32bit scratchpad register.
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static u32
+mic_x100_read_spad(struct mic_device *mdev, unsigned int idx)
+{
+       u32 val = mic_mmio_read(&mdev->mmio,
+               MIC_X100_SBOX_BASE_ADDRESS +
+               MIC_X100_SBOX_SPAD0 + idx * 4);
+
+       dev_dbg(mdev->sdev->parent,
+               "Reading 0x%x from scratch pad index %d\n", val, idx);
+       return val;
+}
+
+/**
+ * mic_x100_enable_interrupts - Enable interrupts.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_enable_interrupts(struct mic_device *mdev)
+{
+       u32 reg;
+       struct mic_mw *mw = &mdev->mmio;
+       u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0;
+       u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0;
+
+       reg = mic_mmio_read(mw, sice0);
+       reg |= MIC_X100_SBOX_DBR_BITS(0xf) | MIC_X100_SBOX_DMA_BITS(0xff);
+       mic_mmio_write(mw, reg, sice0);
+
+       /*
+        * Enable auto-clear when enabling interrupts. Applicable only for
+        * MSI-x. Legacy and MSI mode cannot have auto-clear enabled.
+        */
+       if (mdev->irq_info.num_vectors > 1) {
+               reg = mic_mmio_read(mw, siac0);
+               reg |= MIC_X100_SBOX_DBR_BITS(0xf) |
+                       MIC_X100_SBOX_DMA_BITS(0xff);
+               mic_mmio_write(mw, reg, siac0);
+       }
+}
+
+/**
+ * mic_x100_disable_interrupts - Disable interrupts.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_disable_interrupts(struct mic_device *mdev)
+{
+       u32 reg;
+       struct mic_mw *mw = &mdev->mmio;
+       u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0;
+       u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0;
+       u32 sicc0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICC0;
+
+       reg = mic_mmio_read(mw, sice0);
+       mic_mmio_write(mw, reg, sicc0);
+
+       if (mdev->irq_info.num_vectors > 1) {
+               reg = mic_mmio_read(mw, siac0);
+               reg &= ~(MIC_X100_SBOX_DBR_BITS(0xf) |
+                       MIC_X100_SBOX_DMA_BITS(0xff));
+               mic_mmio_write(mw, reg, siac0);
+       }
+}
+
+/**
+ * mic_x100_send_sbox_intr - Send an MIC_X100_SBOX interrupt to MIC.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_send_sbox_intr(struct mic_device *mdev,
+                       int doorbell)
+{
+       struct mic_mw *mw = &mdev->mmio;
+       u64 apic_icr_offset = MIC_X100_SBOX_APICICR0 + doorbell * 8;
+       u32 apicicr_low = mic_mmio_read(mw, MIC_X100_SBOX_BASE_ADDRESS +
+                                       apic_icr_offset);
+
+       /* for MIC we need to make sure we "hit" the send_icr bit (13) */
+       apicicr_low = (apicicr_low | (1 << 13));
+
+       /* Ensure that the interrupt is ordered w.r.t. previous stores. */
+       wmb();
+       mic_mmio_write(mw, apicicr_low,
+                      MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
+}
+
+/**
+ * mic_x100_send_rdmasr_intr - Send an RDMASR interrupt to MIC.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_send_rdmasr_intr(struct mic_device *mdev,
+                       int doorbell)
+{
+       int rdmasr_offset = MIC_X100_SBOX_RDMASR0 + (doorbell << 2);
+       /* Ensure that the interrupt is ordered w.r.t. previous stores. */
+       wmb();
+       mic_mmio_write(&mdev->mmio, 0,
+                      MIC_X100_SBOX_BASE_ADDRESS + rdmasr_offset);
+}
+
+/**
+ * __mic_x100_send_intr - Send interrupt to MIC.
+ * @mdev: pointer to mic_device instance
+ * @doorbell: doorbell number.
+ */
+static void mic_x100_send_intr(struct mic_device *mdev, int doorbell)
+{
+       int rdmasr_db;
+       if (doorbell < MIC_X100_NUM_SBOX_IRQ) {
+               mic_x100_send_sbox_intr(mdev, doorbell);
+       } else {
+               rdmasr_db = doorbell - MIC_X100_NUM_SBOX_IRQ +
+                       MIC_X100_RDMASR_IRQ_BASE;
+               mic_x100_send_rdmasr_intr(mdev, rdmasr_db);
+       }
+}
+
+/**
+ * mic_ack_interrupt - Device specific interrupt handling.
+ * @mdev: pointer to mic_device instance
+ *
+ * Returns: bitmask of doorbell events triggered.
+ */
+static u32 mic_x100_ack_interrupt(struct mic_device *mdev)
+{
+       u32 reg = 0;
+       struct mic_mw *mw = &mdev->mmio;
+       u32 sicr0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICR0;
+
+       /* Clear pending bit array. */
+       if (MIC_A0_STEP == mdev->stepping)
+               mic_mmio_write(mw, 1, MIC_X100_SBOX_BASE_ADDRESS +
+                       MIC_X100_SBOX_MSIXPBACR);
+
+       if (mdev->irq_info.num_vectors <= 1) {
+               reg = mic_mmio_read(mw, sicr0);
+
+               if (unlikely(!reg))
+                       goto done;
+
+               mic_mmio_write(mw, reg, sicr0);
+       }
+
+       if (mdev->stepping >= MIC_B0_STEP)
+               mdev->intr_ops->enable_interrupts(mdev);
+done:
+       return reg;
+}
+
+/**
+ * mic_x100_hw_intr_init - Initialize h/w specific interrupt
+ * information.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_hw_intr_init(struct mic_device *mdev)
+{
+       mdev->intr_info = (struct mic_intr_info *)mic_x100_intr_init;
+}
+
+/**
+ * mic_x100_read_msi_to_src_map - read from the MSI mapping registers
+ * @mdev: pointer to mic_device instance
+ * @idx: index to the mapping register, 0 based
+ *
+ * This function allows reading of the 32bit MSI mapping register.
+ *
+ * RETURNS: The value in the register.
+ */
+static u32
+mic_x100_read_msi_to_src_map(struct mic_device *mdev, int idx)
+{
+       return mic_mmio_read(&mdev->mmio,
+               MIC_X100_SBOX_BASE_ADDRESS +
+               MIC_X100_SBOX_MXAR0 + idx * 4);
+}
+
+/**
+ * mic_x100_program_msi_to_src_map - program the MSI mapping registers
+ * @mdev: pointer to mic_device instance
+ * @idx: index to the mapping register, 0 based
+ * @offset: The bit offset in the register that needs to be updated.
+ * @set: boolean specifying if the bit in the specified offset needs
+ * to be set or cleared.
+ *
+ * RETURNS: None.
+ */
+static void
+mic_x100_program_msi_to_src_map(struct mic_device *mdev,
+                               int idx, int offset, bool set)
+{
+       unsigned long reg;
+       struct mic_mw *mw = &mdev->mmio;
+       u32 mxar = MIC_X100_SBOX_BASE_ADDRESS +
+               MIC_X100_SBOX_MXAR0 + idx * 4;
+
+       reg = mic_mmio_read(mw, mxar);
+       if (set)
+               __set_bit(offset, &reg);
+       else
+               __clear_bit(offset, &reg);
+       mic_mmio_write(mw, reg, mxar);
+}
+
+/*
+ * mic_x100_reset_fw_ready - Reset Firmware ready status field.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_reset_fw_ready(struct mic_device *mdev)
+{
+       mdev->ops->write_spad(mdev, MIC_X100_DOWNLOAD_INFO, 0);
+}
+
+/*
+ * mic_x100_is_fw_ready - Check if firmware is ready.
+ * @mdev: pointer to mic_device instance
+ */
+static bool mic_x100_is_fw_ready(struct mic_device *mdev)
+{
+       u32 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
+       return MIC_X100_SPAD2_DOWNLOAD_STATUS(scratch2) ? true : false;
+}
+
+/**
+ * mic_x100_get_apic_id - Get bootstrap APIC ID.
+ * @mdev: pointer to mic_device instance
+ */
+static u32 mic_x100_get_apic_id(struct mic_device *mdev)
+{
+       u32 scratch2 = 0;
+
+       scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
+       return MIC_X100_SPAD2_APIC_ID(scratch2);
+}
+
+/**
+ * mic_x100_send_firmware_intr - Send an interrupt to the firmware on MIC.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_send_firmware_intr(struct mic_device *mdev)
+{
+       u32 apicicr_low;
+       u64 apic_icr_offset = MIC_X100_SBOX_APICICR7;
+       int vector = MIC_X100_BSP_INTERRUPT_VECTOR;
+       struct mic_mw *mw = &mdev->mmio;
+
+       /*
+        * For MIC we need to make sure we "hit"
+        * the send_icr bit (13).
+        */
+       apicicr_low = (vector | (1 << 13));
+
+       mic_mmio_write(mw, mic_x100_get_apic_id(mdev),
+                      MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset + 4);
+
+       /* Ensure that the interrupt is ordered w.r.t. previous stores. */
+       wmb();
+       mic_mmio_write(mw, apicicr_low,
+                      MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
+}
+
+/**
+ * mic_x100_hw_reset - Reset the MIC device.
+ * @mdev: pointer to mic_device instance
+ */
+static void mic_x100_hw_reset(struct mic_device *mdev)
+{
+       u32 reset_reg;
+       u32 rgcr = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_RGCR;
+       struct mic_mw *mw = &mdev->mmio;
+
+       /* Ensure that the reset is ordered w.r.t. previous loads and stores */
+       mb();
+       /* Trigger reset */
+       reset_reg = mic_mmio_read(mw, rgcr);
+       reset_reg |= 0x1;
+       mic_mmio_write(mw, reset_reg, rgcr);
+       /*
+        * It seems we really want to delay at least 1 second
+        * after touching reset to prevent a lot of problems.
+        */
+       msleep(1000);
+}
+
+/**
+ * mic_x100_load_command_line - Load command line to MIC.
+ * @mdev: pointer to mic_device instance
+ * @fw: the firmware image
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int
+mic_x100_load_command_line(struct mic_device *mdev, const struct firmware *fw)
+{
+       u32 len = 0;
+       u32 boot_mem;
+       char *buf;
+       void __iomem *cmd_line_va = mdev->aper.va + mdev->bootaddr + fw->size;
+#define CMDLINE_SIZE 2048
+
+       boot_mem = mdev->aper.len >> 20;
+       buf = kzalloc(CMDLINE_SIZE, GFP_KERNEL);
+       if (!buf) {
+               dev_err(mdev->sdev->parent,
+                       "%s %d allocation failed\n", __func__, __LINE__);
+               return -ENOMEM;
+       }
+       len += snprintf(buf, CMDLINE_SIZE - len,
+               " mem=%dM", boot_mem);
+       if (mdev->cmdline)
+               snprintf(buf + len, CMDLINE_SIZE - len, " %s", mdev->cmdline);
+       memcpy_toio(cmd_line_va, buf, strlen(buf) + 1);
+       kfree(buf);
+       return 0;
+}
+
+/**
+ * mic_x100_load_ramdisk - Load ramdisk to MIC.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int
+mic_x100_load_ramdisk(struct mic_device *mdev)
+{
+       const struct firmware *fw;
+       int rc;
+       struct boot_params __iomem *bp = mdev->aper.va + mdev->bootaddr;
+
+       rc = request_firmware(&fw,
+                       mdev->ramdisk, mdev->sdev->parent);
+       if (rc < 0) {
+               dev_err(mdev->sdev->parent,
+                       "ramdisk request_firmware failed: %d %s\n",
+                       rc, mdev->ramdisk);
+               goto error;
+       }
+       /*
+        * Typically the bootaddr for card OS is 64M
+        * 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);
+       release_firmware(fw);
+error:
+       return rc;
+}
+
+/**
+ * mic_x100_get_boot_addr - Get MIC boot address.
+ * @mdev: pointer to mic_device instance
+ *
+ * This function is called during firmware load to determine
+ * the address at which the OS should be downloaded in card
+ * memory i.e. GDDR.
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int
+mic_x100_get_boot_addr(struct mic_device *mdev)
+{
+       u32 scratch2, boot_addr;
+       int rc = 0;
+
+       scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
+       boot_addr = MIC_X100_SPAD2_DOWNLOAD_ADDR(scratch2);
+       dev_dbg(mdev->sdev->parent, "%s %d boot_addr 0x%x\n",
+               __func__, __LINE__, boot_addr);
+       if (boot_addr > (1 << 31)) {
+               dev_err(mdev->sdev->parent,
+                       "incorrect bootaddr 0x%x\n",
+                       boot_addr);
+               rc = -EINVAL;
+               goto error;
+       }
+       mdev->bootaddr = boot_addr;
+error:
+       return rc;
+}
+
+/**
+ * mic_x100_load_firmware - Load firmware to MIC.
+ * @mdev: pointer to mic_device instance
+ * @buf: buffer containing boot string including firmware/ramdisk path.
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+static int
+mic_x100_load_firmware(struct mic_device *mdev, const char *buf)
+{
+       int rc;
+       const struct firmware *fw;
+
+       rc = mic_x100_get_boot_addr(mdev);
+       if (rc)
+               goto error;
+       /* load OS */
+       rc = request_firmware(&fw, mdev->firmware, mdev->sdev->parent);
+       if (rc < 0) {
+               dev_err(mdev->sdev->parent,
+                       "ramdisk request_firmware failed: %d %s\n",
+                       rc, mdev->firmware);
+               goto error;
+       }
+       if (mdev->bootaddr > mdev->aper.len - fw->size) {
+               rc = -EINVAL;
+               dev_err(mdev->sdev->parent, "%s %d rc %d bootaddr 0x%x\n",
+                       __func__, __LINE__, rc, mdev->bootaddr);
+               release_firmware(fw);
+               goto error;
+       }
+       memcpy_toio(mdev->aper.va + mdev->bootaddr, fw->data, fw->size);
+       mdev->ops->write_spad(mdev, MIC_X100_FW_SIZE, fw->size);
+       if (!strcmp(mdev->bootmode, "elf"))
+               goto done;
+       /* load command line */
+       rc = mic_x100_load_command_line(mdev, fw);
+       if (rc) {
+               dev_err(mdev->sdev->parent, "%s %d rc %d\n",
+                       __func__, __LINE__, rc);
+               goto error;
+       }
+       release_firmware(fw);
+       /* load ramdisk */
+       if (mdev->ramdisk)
+               rc = mic_x100_load_ramdisk(mdev);
+error:
+       dev_dbg(mdev->sdev->parent, "%s %d rc %d\n", __func__, __LINE__, rc);
+done:
+       return rc;
+}
+
+/**
+ * mic_x100_get_postcode - Get postcode status from firmware.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: postcode.
+ */
+static u32 mic_x100_get_postcode(struct mic_device *mdev)
+{
+       return mic_mmio_read(&mdev->mmio, MIC_X100_POSTCODE);
+}
+
+/**
+ * mic_x100_smpt_set - Update an SMPT entry with a DMA address.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: none.
+ */
+static void
+mic_x100_smpt_set(struct mic_device *mdev, dma_addr_t dma_addr, u8 index)
+{
+#define SNOOP_ON       (0 << 0)
+#define SNOOP_OFF      (1 << 0)
+/*
+ * Sbox Smpt Reg Bits:
+ * Bits        31:2    Host address
+ * Bits        1       RSVD
+ * Bits        0       No snoop
+ */
+#define BUILD_SMPT(NO_SNOOP, HOST_ADDR)  \
+       (u32)(((HOST_ADDR) << 2) | ((NO_SNOOP) & 0x01))
+
+       uint32_t smpt_reg_val = BUILD_SMPT(SNOOP_ON,
+                       dma_addr >> mdev->smpt->info.page_shift);
+       mic_mmio_write(&mdev->mmio, smpt_reg_val,
+                      MIC_X100_SBOX_BASE_ADDRESS +
+                      MIC_X100_SBOX_SMPT00 + (4 * index));
+}
+
+/**
+ * mic_x100_smpt_hw_init - Initialize SMPT X100 specific fields.
+ * @mdev: pointer to mic_device instance
+ *
+ * RETURNS: none.
+ */
+static void mic_x100_smpt_hw_init(struct mic_device *mdev)
+{
+       struct mic_smpt_hw_info *info = &mdev->smpt->info;
+
+       info->num_reg = 32;
+       info->page_shift = 34;
+       info->page_size = (1ULL << info->page_shift);
+       info->base = 0x8000000000ULL;
+}
+
+struct mic_smpt_ops mic_x100_smpt_ops = {
+       .init = mic_x100_smpt_hw_init,
+       .set = mic_x100_smpt_set,
+};
+
+struct mic_hw_ops mic_x100_ops = {
+       .aper_bar = MIC_X100_APER_BAR,
+       .mmio_bar = MIC_X100_MMIO_BAR,
+       .read_spad = mic_x100_read_spad,
+       .write_spad = mic_x100_write_spad,
+       .send_intr = mic_x100_send_intr,
+       .ack_interrupt = mic_x100_ack_interrupt,
+       .reset = mic_x100_hw_reset,
+       .reset_fw_ready = mic_x100_reset_fw_ready,
+       .is_fw_ready = mic_x100_is_fw_ready,
+       .send_firmware_intr = mic_x100_send_firmware_intr,
+       .load_mic_fw = mic_x100_load_firmware,
+       .get_postcode = mic_x100_get_postcode,
+};
+
+struct mic_hw_intr_ops mic_x100_intr_ops = {
+       .intr_init = mic_x100_hw_intr_init,
+       .enable_interrupts = mic_x100_enable_interrupts,
+       .disable_interrupts = mic_x100_disable_interrupts,
+       .program_msi_to_src_map = mic_x100_program_msi_to_src_map,
+       .read_msi_to_src_map = mic_x100_read_msi_to_src_map,
+};
diff --git a/drivers/misc/mic/host/mic_x100.h b/drivers/misc/mic/host/mic_x100.h
new file mode 100644 (file)
index 0000000..8b7daa1
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef _MIC_X100_HW_H_
+#define _MIC_X100_HW_H_
+
+#define MIC_X100_PCI_DEVICE_2250 0x2250
+#define MIC_X100_PCI_DEVICE_2251 0x2251
+#define MIC_X100_PCI_DEVICE_2252 0x2252
+#define MIC_X100_PCI_DEVICE_2253 0x2253
+#define MIC_X100_PCI_DEVICE_2254 0x2254
+#define MIC_X100_PCI_DEVICE_2255 0x2255
+#define MIC_X100_PCI_DEVICE_2256 0x2256
+#define MIC_X100_PCI_DEVICE_2257 0x2257
+#define MIC_X100_PCI_DEVICE_2258 0x2258
+#define MIC_X100_PCI_DEVICE_2259 0x2259
+#define MIC_X100_PCI_DEVICE_225a 0x225a
+#define MIC_X100_PCI_DEVICE_225b 0x225b
+#define MIC_X100_PCI_DEVICE_225c 0x225c
+#define MIC_X100_PCI_DEVICE_225d 0x225d
+#define MIC_X100_PCI_DEVICE_225e 0x225e
+
+#define MIC_X100_APER_BAR 0
+#define MIC_X100_MMIO_BAR 4
+
+#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000
+#define MIC_X100_SBOX_SPAD0 0x0000AB20
+#define MIC_X100_SBOX_SICR0_DBR(x) ((x) & 0xf)
+#define MIC_X100_SBOX_SICR0_DMA(x) (((x) >> 8) & 0xff)
+#define MIC_X100_SBOX_SICE0_DBR(x) ((x) & 0xf)
+#define MIC_X100_SBOX_DBR_BITS(x) ((x) & 0xf)
+#define MIC_X100_SBOX_SICE0_DMA(x) (((x) >> 8) & 0xff)
+#define MIC_X100_SBOX_DMA_BITS(x) (((x) & 0xff) << 8)
+
+#define MIC_X100_SBOX_APICICR0 0x0000A9D0
+#define MIC_X100_SBOX_SICR0 0x00009004
+#define MIC_X100_SBOX_SICE0 0x0000900C
+#define MIC_X100_SBOX_SICC0 0x00009010
+#define MIC_X100_SBOX_SIAC0 0x00009014
+#define MIC_X100_SBOX_MSIXPBACR 0x00009084
+#define MIC_X100_SBOX_MXAR0 0x00009044
+#define MIC_X100_SBOX_SMPT00 0x00003100
+#define MIC_X100_SBOX_RDMASR0 0x0000B180
+
+#define MIC_X100_DOORBELL_IDX_START 0
+#define MIC_X100_NUM_DOORBELL 4
+#define MIC_X100_DMA_IDX_START 8
+#define MIC_X100_NUM_DMA 8
+#define MIC_X100_ERR_IDX_START 30
+#define MIC_X100_NUM_ERR 1
+
+#define MIC_X100_NUM_SBOX_IRQ 8
+#define MIC_X100_NUM_RDMASR_IRQ 8
+#define MIC_X100_RDMASR_IRQ_BASE 17
+#define MIC_X100_SPAD2_DOWNLOAD_STATUS(x) ((x) & 0x1)
+#define MIC_X100_SPAD2_APIC_ID(x)      (((x) >> 1) & 0x1ff)
+#define MIC_X100_SPAD2_DOWNLOAD_ADDR(x) ((x) & 0xfffff000)
+#define MIC_X100_SBOX_APICICR7 0x0000AA08
+#define MIC_X100_SBOX_RGCR 0x00004010
+#define MIC_X100_SBOX_SDBIC0 0x0000CC90
+#define MIC_X100_DOWNLOAD_INFO 2
+#define MIC_X100_FW_SIZE 5
+#define MIC_X100_POSTCODE 0x242c
+
+static const u16 mic_x100_intr_init[] = {
+               MIC_X100_DOORBELL_IDX_START,
+               MIC_X100_DMA_IDX_START,
+               MIC_X100_ERR_IDX_START,
+               MIC_X100_NUM_DOORBELL,
+               MIC_X100_NUM_DMA,
+               MIC_X100_NUM_ERR,
+};
+
+/* Host->Card(bootstrap) Interrupt Vector */
+#define MIC_X100_BSP_INTERRUPT_VECTOR 229
+
+extern struct mic_hw_ops mic_x100_ops;
+extern struct mic_smpt_ops mic_x100_smpt_ops;
+extern struct mic_hw_intr_ops mic_x100_intr_ops;
+
+#endif
index 68b7c773d2cf472e23395ec563a7ed3abfbb9c9c..30754927fd80d584881b3ce5475ddef874bb353c 100644 (file)
@@ -395,7 +395,7 @@ static int phantom_probe(struct pci_dev *pdev,
        iowrite32(0, pht->caddr + PHN_IRQCTL);
        ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
        retval = request_irq(pdev->irq, phantom_isr,
-                       IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
+                       IRQF_SHARED, "phantom", pht);
        if (retval) {
                dev_err(&pdev->dev, "can't establish ISR\n");
                goto err_unmo;
index f84ff0c060358d2d4e2fa6e78d070fd385f0eaa4..eda38cbe85307edd67863122e24451d269d66866 100644 (file)
@@ -892,7 +892,6 @@ static void pti_pci_remove(struct pci_dev *pdev)
        }
 
        iounmap(drv_data->pti_ioaddr);
-       pci_set_drvdata(pdev, NULL);
        kfree(drv_data);
        pci_release_region(pdev, 1);
        pci_disable_device(pdev);
index 9b237221bc4e8abf19391886ee6465065db2e16a..83da711ce9f13688660192f55fac62571961ec93 100644 (file)
@@ -22,9 +22,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/spi/spi.h>
-
-#define DAC7512_DRV_NAME       "dac7512"
-#define DRIVER_VERSION         "1.0"
+#include <linux/of.h>
 
 static ssize_t dac7512_store_val(struct device *dev,
                                 struct device_attribute *attr,
@@ -75,13 +73,29 @@ static int dac7512_remove(struct spi_device *spi)
        return 0;
 }
 
+static const struct spi_device_id dac7512_id_table[] = {
+       { "dac7512", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(spi, dac7512_id_table);
+
+#ifdef CONFIG_OF
+static const struct of_device_id dac7512_of_match[] = {
+       { .compatible = "ti,dac7512", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, dac7512_of_match);
+#endif
+
 static struct spi_driver dac7512_driver = {
        .driver = {
-               .name   = DAC7512_DRV_NAME,
+               .name   = "dac7512",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(dac7512_of_match),
        },
        .probe  = dac7512_probe,
        .remove = dac7512_remove,
+       .id_table = dac7512_id_table,
 };
 
 module_spi_driver(dac7512_driver);
@@ -89,4 +103,3 @@ module_spi_driver(dac7512_driver);
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("DAC7512 16-bit DAC");
 MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRIVER_VERSION);
index f8d6654391e5df35f13ec7b7e825baf3710baee6..a606c8901e1859099bf387e8a7d1f8b07b0f3cd0 100644 (file)
@@ -356,8 +356,10 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
        pci_set_drvdata(dev, fm);
 
        fm->addr = pci_ioremap_bar(dev, 0);
-       if (!fm->addr)
+       if (!fm->addr) {
+               rc = -ENODEV;
                goto err_out_free;
+       }
 
        rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm);
        if (rc)
@@ -378,7 +380,6 @@ err_out_irq:
 err_out_unmap:
        iounmap(fm->addr);
 err_out_free:
-       pci_set_drvdata(dev, NULL);
        tifm_free_adapter(fm);
 err_out_int:
        pci_intx(dev, 0);
@@ -405,8 +406,6 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
        for (cnt = 0; cnt < fm->num_sockets; cnt++)
                tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));
 
-       pci_set_drvdata(dev, NULL);
-
        iounmap(fm->addr);
        pci_intx(dev, 0);
        pci_release_regions(dev);
index 0ab7c922212cd860703d78a85621bfe68a067825..a511b2a713b33b9b6dce502c6cbb46cc930b8d58 100644 (file)
@@ -145,15 +145,17 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr,
        struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
        return sprintf(buf, "%x", sock->type);
 }
+static DEVICE_ATTR_RO(type);
 
-static struct device_attribute tifm_dev_attrs[] = {
-       __ATTR(type, S_IRUGO, type_show, NULL),
-       __ATTR_NULL
+static struct attribute *tifm_dev_attrs[] = {
+       &dev_attr_type.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(tifm_dev);
 
 static struct bus_type tifm_bus_type = {
        .name      = "tifm",
-       .dev_attrs = tifm_dev_attrs,
+       .dev_groups = tifm_dev_groups,
        .match     = tifm_bus_match,
        .uevent    = tifm_uevent,
        .probe     = tifm_device_probe,
index b3a2b763ecf25bd792b762c8f30778012398320a..c98b03b993537aa62ff1e38242b6ad9dbc59b96d 100644 (file)
@@ -649,7 +649,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
        return 0;
 
 err_free_irq:
-       free_irq(vmci_dev->irq, &vmci_dev);
+       free_irq(vmci_dev->irq, vmci_dev);
        tasklet_kill(&vmci_dev->datagram_tasklet);
        tasklet_kill(&vmci_dev->bm_tasklet);
 
index d4722b3dc8ec762987f18d25268727ea9954b32c..1723a6e4f2e8ea97b70e3d151f0bc0e29dc29c15 100644 (file)
@@ -243,11 +243,7 @@ static int vmci_host_setup_notify(struct vmci_ctx *context,
        /*
         * Lock physical page backing a given user VA.
         */
-       down_read(&current->mm->mmap_sem);
-       retval = get_user_pages(current, current->mm,
-                               PAGE_ALIGN(uva),
-                               1, 1, 0, &page, NULL);
-       up_read(&current->mm->mmap_sem);
+       retval = get_user_pages_fast(PAGE_ALIGN(uva), 1, 1, &page);
        if (retval != 1)
                return VMCI_ERROR_GENERIC;
 
index a0515a6d6ebdbcf1438e4e8c544d879fc478e08a..1b7b303085d28d459c2595776fd82b15cf9a0dc5 100644 (file)
@@ -732,13 +732,9 @@ static int qp_host_get_user_memory(u64 produce_uva,
        int retval;
        int err = VMCI_SUCCESS;
 
-       down_write(&current->mm->mmap_sem);
-       retval = get_user_pages(current,
-                               current->mm,
-                               (uintptr_t) produce_uva,
-                               produce_q->kernel_if->num_pages,
-                               1, 0,
-                               produce_q->kernel_if->u.h.header_page, NULL);
+       retval = get_user_pages_fast((uintptr_t) produce_uva,
+                                    produce_q->kernel_if->num_pages, 1,
+                                    produce_q->kernel_if->u.h.header_page);
        if (retval < produce_q->kernel_if->num_pages) {
                pr_warn("get_user_pages(produce) failed (retval=%d)", retval);
                qp_release_pages(produce_q->kernel_if->u.h.header_page,
@@ -747,12 +743,9 @@ static int qp_host_get_user_memory(u64 produce_uva,
                goto out;
        }
 
-       retval = get_user_pages(current,
-                               current->mm,
-                               (uintptr_t) consume_uva,
-                               consume_q->kernel_if->num_pages,
-                               1, 0,
-                               consume_q->kernel_if->u.h.header_page, NULL);
+       retval = get_user_pages_fast((uintptr_t) consume_uva,
+                                    consume_q->kernel_if->num_pages, 1,
+                                    consume_q->kernel_if->u.h.header_page);
        if (retval < consume_q->kernel_if->num_pages) {
                pr_warn("get_user_pages(consume) failed (retval=%d)", retval);
                qp_release_pages(consume_q->kernel_if->u.h.header_page,
@@ -763,8 +756,6 @@ static int qp_host_get_user_memory(u64 produce_uva,
        }
 
  out:
-       up_write(&current->mm->mmap_sem);
-
        return err;
 }
 
index 704bf66f58733a036bf79bfc4ef585f29acb7626..3e227bd91e81935eaf3f4ffce830de99b3e1321d 100644 (file)
@@ -27,7 +27,7 @@
 
 #define to_mmc_driver(d)       container_of(d, struct mmc_driver, drv)
 
-static ssize_t mmc_type_show(struct device *dev,
+static ssize_t type_show(struct device *dev,
        struct device_attribute *attr, char *buf)
 {
        struct mmc_card *card = mmc_dev_to_card(dev);
@@ -45,11 +45,13 @@ static ssize_t mmc_type_show(struct device *dev,
                return -EFAULT;
        }
 }
+static DEVICE_ATTR_RO(type);
 
-static struct device_attribute mmc_dev_attrs[] = {
-       __ATTR(type, S_IRUGO, mmc_type_show, NULL),
-       __ATTR_NULL,
+static struct attribute *mmc_dev_attrs[] = {
+       &dev_attr_type.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(mmc_dev);
 
 /*
  * This currently matches any MMC driver to any MMC card - drivers
@@ -218,7 +220,7 @@ static const struct dev_pm_ops mmc_bus_pm_ops = {
 
 static struct bus_type mmc_bus_type = {
        .name           = "mmc",
-       .dev_attrs      = mmc_dev_attrs,
+       .dev_groups     = mmc_dev_groups,
        .match          = mmc_bus_match,
        .uevent         = mmc_bus_uevent,
        .probe          = mmc_bus_probe,
index 6d67492a9247b14f0ed07c2c2f9373bf0be7cdcd..ef8956568c3a2978b90cab02a9dc0ed56c76254f 100644 (file)
@@ -34,7 +34,8 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf)                            \
                                                                        \
        func = dev_to_sdio_func (dev);                                  \
        return sprintf (buf, format_string, func->field);               \
-}
+}                                                                      \
+static DEVICE_ATTR_RO(field)
 
 sdio_config_attr(class, "0x%02x\n");
 sdio_config_attr(vendor, "0x%04x\n");
@@ -47,14 +48,16 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
        return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
                        func->class, func->vendor, func->device);
 }
-
-static struct device_attribute sdio_dev_attrs[] = {
-       __ATTR_RO(class),
-       __ATTR_RO(vendor),
-       __ATTR_RO(device),
-       __ATTR_RO(modalias),
-       __ATTR_NULL,
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *sdio_dev_attrs[] = {
+       &dev_attr_class.attr,
+       &dev_attr_vendor.attr,
+       &dev_attr_device.attr,
+       &dev_attr_modalias.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(sdio_dev);
 
 static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
        const struct sdio_device_id *id)
@@ -225,7 +228,7 @@ static const struct dev_pm_ops sdio_bus_pm_ops = {
 
 static struct bus_type sdio_bus_type = {
        .name           = "sdio",
-       .dev_attrs      = sdio_dev_attrs,
+       .dev_groups     = sdio_dev_groups,
        .match          = sdio_bus_match,
        .uevent         = sdio_bus_uevent,
        .probe          = sdio_bus_probe,
index 06c5b0b28ebc99f547b88fb9be47a43196872ff8..deecee08c2881d0ee6ad34a9d049368e5d05ceec 100644 (file)
@@ -655,7 +655,7 @@ static const struct mmc_host_ops mvsd_ops = {
        .enable_sdio_irq        = mvsd_enable_sdio_irq,
 };
 
-static void __init
+static void
 mv_conf_mbus_windows(struct mvsd_host *host,
                     const struct mbus_dram_target_info *dram)
 {
@@ -677,7 +677,7 @@ mv_conf_mbus_windows(struct mvsd_host *host,
        }
 }
 
-static int __init mvsd_probe(struct platform_device *pdev)
+static int mvsd_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct mmc_host *mmc = NULL;
@@ -819,7 +819,7 @@ out:
        return ret;
 }
 
-static int __exit mvsd_remove(struct platform_device *pdev)
+static int mvsd_remove(struct platform_device *pdev)
 {
        struct mmc_host *mmc = platform_get_drvdata(pdev);
 
@@ -872,7 +872,8 @@ static const struct of_device_id mvsdio_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, mvsdio_dt_ids);
 
 static struct platform_driver mvsd_driver = {
-       .remove         = __exit_p(mvsd_remove),
+       .probe          = mvsd_probe,
+       .remove         = mvsd_remove,
        .suspend        = mvsd_suspend,
        .resume         = mvsd_resume,
        .driver         = {
@@ -881,7 +882,7 @@ static struct platform_driver mvsd_driver = {
        },
 };
 
-module_platform_driver_probe(mvsd_driver, mvsd_probe);
+module_platform_driver(mvsd_driver);
 
 /* maximum card clock frequency (default 50MHz) */
 module_param(maxfreq, int, 0);
index 060feeaf6b3e5554328904a1ac870a97cbc5685b..bd1ce7d137023fed1f42bc606166a111946466c1 100644 (file)
@@ -1139,7 +1139,7 @@ static int pmecc_choose_ecc(struct atmel_nand_host *host,
        return 0;
 }
 
-static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
+static int atmel_pmecc_nand_init_params(struct platform_device *pdev,
                                         struct atmel_nand_host *host)
 {
        struct mtd_info *mtd = &host->mtd;
@@ -1548,7 +1548,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host,
 }
 #endif
 
-static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
+static int atmel_hw_nand_init_params(struct platform_device *pdev,
                                         struct atmel_nand_host *host)
 {
        struct mtd_info *mtd = &host->mtd;
@@ -1987,7 +1987,7 @@ static struct platform_driver atmel_nand_nfc_driver;
 /*
  * Probe for the NAND device.
  */
-static int __init atmel_nand_probe(struct platform_device *pdev)
+static int atmel_nand_probe(struct platform_device *pdev)
 {
        struct atmel_nand_host *host;
        struct mtd_info *mtd;
@@ -2184,7 +2184,7 @@ err_nand_ioremap:
 /*
  * Remove a NAND device.
  */
-static int __exit atmel_nand_remove(struct platform_device *pdev)
+static int atmel_nand_remove(struct platform_device *pdev)
 {
        struct atmel_nand_host *host = platform_get_drvdata(pdev);
        struct mtd_info *mtd = &host->mtd;
@@ -2270,7 +2270,8 @@ static struct platform_driver atmel_nand_nfc_driver = {
 };
 
 static struct platform_driver atmel_nand_driver = {
-       .remove         = __exit_p(atmel_nand_remove),
+       .probe          = atmel_nand_probe,
+       .remove         = atmel_nand_remove,
        .driver         = {
                .name   = "atmel_nand",
                .owner  = THIS_MODULE,
@@ -2278,7 +2279,7 @@ static struct platform_driver atmel_nand_driver = {
        },
 };
 
-module_platform_driver_probe(atmel_nand_driver, atmel_nand_probe);
+module_platform_driver(atmel_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Rick Bronson");
index c29b836749b6323fe86c35e7762b25a3c8596978..ec9b6460a38dd0549b5b69f281b36f6cce0a3e7d 100644 (file)
@@ -149,14 +149,6 @@ err_no_cmd:
        return -EPERM;
 }
 
-static const void *bonding_namespace(struct class *cls,
-                                    const struct class_attribute *attr)
-{
-       const struct bond_net *bn =
-               container_of(attr, struct bond_net, class_attr_bonding_masters);
-       return bn->net;
-}
-
 /* class attribute for bond_masters file.  This ends up in /sys/class/net */
 static const struct class_attribute class_attr_bonding_masters = {
        .attr = {
@@ -165,7 +157,6 @@ static const struct class_attribute class_attr_bonding_masters = {
        },
        .show = bonding_show_bonds,
        .store = bonding_store_bonds,
-       .namespace = bonding_namespace,
 };
 
 int bond_create_slave_symlinks(struct net_device *master,
@@ -1787,7 +1778,8 @@ int bond_create_sysfs(struct bond_net *bn)
        bn->class_attr_bonding_masters = class_attr_bonding_masters;
        sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
 
-       ret = netdev_class_create_file(&bn->class_attr_bonding_masters);
+       ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
+                                         bn->net);
        /*
         * Permit multiple loads of the module by ignoring failures to
         * create the bonding_masters sysfs file.  Bonding devices
@@ -1817,7 +1809,7 @@ int bond_create_sysfs(struct bond_net *bn)
  */
 void bond_destroy_sysfs(struct bond_net *bn)
 {
-       netdev_class_remove_file(&bn->class_attr_bonding_masters);
+       netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
 }
 
 /*
index a668cd491cb3ae427e38db535df7a8c9dc1109e1..e3fc07cf2f6269e5ccf0ca5dbf42897c191cecd4 100644 (file)
@@ -814,9 +814,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota)
                        msg_ctrl_save = priv->read_reg(priv,
                                        C_CAN_IFACE(MSGCTRL_REG, 0));
 
-                       if (msg_ctrl_save & IF_MCONT_EOB)
-                               return num_rx_pkts;
-
                        if (msg_ctrl_save & IF_MCONT_MSGLST) {
                                c_can_handle_lost_msg_obj(dev, 0, msg_obj);
                                num_rx_pkts++;
@@ -824,6 +821,9 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota)
                                continue;
                        }
 
+                       if (msg_ctrl_save & IF_MCONT_EOB)
+                               return num_rx_pkts;
+
                        if (!(msg_ctrl_save & IF_MCONT_NEWDAT))
                                continue;
 
index 3b95465882401fc556c647071b8c27f5724a8dbf..4b2d5ed62b119197ef5f25f23412247878cba36a 100644 (file)
@@ -1544,9 +1544,9 @@ static int kvaser_usb_init_one(struct usb_interface *intf,
        return 0;
 }
 
-static void kvaser_usb_get_endpoints(const struct usb_interface *intf,
-                                    struct usb_endpoint_descriptor **in,
-                                    struct usb_endpoint_descriptor **out)
+static int kvaser_usb_get_endpoints(const struct usb_interface *intf,
+                                   struct usb_endpoint_descriptor **in,
+                                   struct usb_endpoint_descriptor **out)
 {
        const struct usb_host_interface *iface_desc;
        struct usb_endpoint_descriptor *endpoint;
@@ -1557,12 +1557,18 @@ static void kvaser_usb_get_endpoints(const struct usb_interface *intf,
        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
                endpoint = &iface_desc->endpoint[i].desc;
 
-               if (usb_endpoint_is_bulk_in(endpoint))
+               if (!*in && usb_endpoint_is_bulk_in(endpoint))
                        *in = endpoint;
 
-               if (usb_endpoint_is_bulk_out(endpoint))
+               if (!*out && usb_endpoint_is_bulk_out(endpoint))
                        *out = endpoint;
+
+               /* use first bulk endpoint for in and out */
+               if (*in && *out)
+                       return 0;
        }
+
+       return -ENODEV;
 }
 
 static int kvaser_usb_probe(struct usb_interface *intf,
@@ -1576,8 +1582,8 @@ static int kvaser_usb_probe(struct usb_interface *intf,
        if (!dev)
                return -ENOMEM;
 
-       kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out);
-       if (!dev->bulk_in || !dev->bulk_out) {
+       err = kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out);
+       if (err) {
                dev_err(&intf->dev, "Cannot get usb endpoint(s)");
                return err;
        }
index 94edc9c6fbbf317765d41d8d4ba9cfc6b817ec20..1b89f1a9127eb42a845822d724ea4fc520a9fb1e 100644 (file)
@@ -725,7 +725,6 @@ static irqreturn_t lance_dma_merr_int(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
-       clear_ioasic_dma_irq(irq);
        printk(KERN_ERR "%s: DMA error\n", dev->name);
        return IRQ_HANDLED;
 }
@@ -812,7 +811,7 @@ static int lance_open(struct net_device *dev)
        if (lp->dma_irq >= 0) {
                unsigned long flags;
 
-               if (request_irq(lp->dma_irq, lance_dma_merr_int, 0,
+               if (request_irq(lp->dma_irq, lance_dma_merr_int, IRQF_ONESHOT,
                                "lance error", dev)) {
                        free_irq(dev->irq, dev);
                        printk("%s: Can't get DMA IRQ %d\n", dev->name,
index 249468f953651480a5e0b897d582dd09743c6c3b..9e8a3e024e0150e71b77057c83c6aa3bdf1aabcf 100644 (file)
@@ -244,25 +244,33 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
                                     struct bgmac_slot_info *slot)
 {
        struct device *dma_dev = bgmac->core->dma_dev;
+       struct sk_buff *skb;
+       dma_addr_t dma_addr;
        struct bgmac_rx_header *rx;
 
        /* Alloc skb */
-       slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
-       if (!slot->skb)
+       skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
+       if (!skb)
                return -ENOMEM;
 
        /* Poison - if everything goes fine, hardware will overwrite it */
-       rx = (struct bgmac_rx_header *)slot->skb->data;
+       rx = (struct bgmac_rx_header *)skb->data;
        rx->len = cpu_to_le16(0xdead);
        rx->flags = cpu_to_le16(0xbeef);
 
        /* Map skb for the DMA */
-       slot->dma_addr = dma_map_single(dma_dev, slot->skb->data,
-                                       BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
-       if (dma_mapping_error(dma_dev, slot->dma_addr)) {
+       dma_addr = dma_map_single(dma_dev, skb->data,
+                                 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
+       if (dma_mapping_error(dma_dev, dma_addr)) {
                bgmac_err(bgmac, "DMA mapping error\n");
+               dev_kfree_skb(skb);
                return -ENOMEM;
        }
+
+       /* Update the slot */
+       slot->skb = skb;
+       slot->dma_addr = dma_addr;
+
        if (slot->dma_addr & 0xC0000000)
                bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
 
index 4ab4c89c60cd1eeca873fad127d2702ab2a1a0d1..74d6486fccfde2cba3128410a9d8b59c79a98918 100644 (file)
@@ -2545,10 +2545,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
                }
        }
 
-       /* Allocated memory for FW statistics  */
-       if (bnx2x_alloc_fw_stats_mem(bp))
-               LOAD_ERROR_EXIT(bp, load_error0);
-
        /* need to be done after alloc mem, since it's self adjusting to amount
         * of memory available for RSS queues
         */
@@ -2558,6 +2554,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
                LOAD_ERROR_EXIT(bp, load_error0);
        }
 
+       /* Allocated memory for FW statistics  */
+       if (bnx2x_alloc_fw_stats_mem(bp))
+               LOAD_ERROR_EXIT(bp, load_error0);
+
        /* request pf to initialize status blocks */
        if (IS_VF(bp)) {
                rc = bnx2x_vfpf_init(bp);
@@ -2812,8 +2812,8 @@ load_error1:
        if (IS_PF(bp))
                bnx2x_clear_pf_load(bp);
 load_error0:
-       bnx2x_free_fp_mem(bp);
        bnx2x_free_fw_stats_mem(bp);
+       bnx2x_free_fp_mem(bp);
        bnx2x_free_mem(bp);
 
        return rc;
index bf08ad68b4052374552e376739a101af0a652cf6..5e07efb6ec1366bcef6b020d228a9b408e9b2000 100644 (file)
@@ -2018,6 +2018,8 @@ failed:
 
 void bnx2x_iov_remove_one(struct bnx2x *bp)
 {
+       int vf_idx;
+
        /* if SRIOV is not enabled there's nothing to do */
        if (!IS_SRIOV(bp))
                return;
@@ -2026,6 +2028,18 @@ void bnx2x_iov_remove_one(struct bnx2x *bp)
        pci_disable_sriov(bp->pdev);
        DP(BNX2X_MSG_IOV, "sriov disabled\n");
 
+       /* disable access to all VFs */
+       for (vf_idx = 0; vf_idx < bp->vfdb->sriov.total; vf_idx++) {
+               bnx2x_pretend_func(bp,
+                                  HW_VF_HANDLE(bp,
+                                               bp->vfdb->sriov.first_vf_in_pf +
+                                               vf_idx));
+               DP(BNX2X_MSG_IOV, "disabling internal access for vf %d\n",
+                  bp->vfdb->sriov.first_vf_in_pf + vf_idx);
+               bnx2x_vf_enable_internal(bp, 0);
+               bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
+       }
+
        /* free vf database */
        __bnx2x_iov_free_vfdb(bp);
 }
@@ -3197,7 +3211,7 @@ int bnx2x_enable_sriov(struct bnx2x *bp)
         * the "acquire" messages to appear on the VF PF channel.
         */
        DP(BNX2X_MSG_IOV, "about to call enable sriov\n");
-       pci_disable_sriov(bp->pdev);
+       bnx2x_disable_sriov(bp);
        rc = pci_enable_sriov(bp->pdev, req_vfs);
        if (rc) {
                BNX2X_ERR("pci_enable_sriov failed with %d\n", rc);
index 9c89dc8fe1057dc1c410728bd252f135f9a80879..632b318eb38a5852a77e94cb86f19e3a094ae774 100644 (file)
@@ -1599,7 +1599,8 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
        flits = skb_transport_offset(skb) / 8;
        sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
        sgl_flits = make_sgl(skb, sgp, skb_transport_header(skb),
-                            skb->tail - skb->transport_header,
+                            skb_tail_pointer(skb) -
+                            skb_transport_header(skb),
                             adap->pdev);
        if (need_skb_unmap()) {
                setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
index db020230bd0bba5ec72186bed9539357ec315abc..c99dac6a9ddf22131ed9f68e1fe22e018a0c8fcc 100644 (file)
@@ -696,6 +696,15 @@ static inline int qnq_async_evt_rcvd(struct be_adapter *adapter)
        return adapter->flags & BE_FLAGS_QNQ_ASYNC_EVT_RCVD;
 }
 
+static inline int fw_major_num(const char *fw_ver)
+{
+       int fw_major = 0;
+
+       sscanf(fw_ver, "%d.", &fw_major);
+
+       return fw_major;
+}
+
 extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
                u16 num_popped);
 extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
index 2c38cc402119c763021ea77461455fd0fa8ac035..53ed58b492c8fb5a7372e68e64eeee5eaaee0e09 100644 (file)
@@ -3247,6 +3247,12 @@ static int be_setup(struct be_adapter *adapter)
 
        be_cmd_get_fw_ver(adapter, adapter->fw_ver, adapter->fw_on_flash);
 
+       if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) {
+               dev_err(dev, "Firmware on card is old(%s), IRQs may not work.",
+                       adapter->fw_ver);
+               dev_err(dev, "Please upgrade firmware to version >= 4.0\n");
+       }
+
        if (adapter->vlans_added)
                be_vid_config(adapter);
 
index dac564c25440cbb5c222a02a8488f8ad6c676e16..e7847510eda26368d5b4f290d83bb8aa7baf179b 100644 (file)
@@ -263,7 +263,9 @@ static inline void mal_schedule_poll(struct mal_instance *mal)
 {
        if (likely(napi_schedule_prep(&mal->napi))) {
                MAL_DBG2(mal, "schedule_poll" NL);
+               spin_lock(&mal->lock);
                mal_disable_eob_irq(mal);
+               spin_unlock(&mal->lock);
                __napi_schedule(&mal->napi);
        } else
                MAL_DBG2(mal, "already in poll" NL);
@@ -442,15 +444,13 @@ static int mal_poll(struct napi_struct *napi, int budget)
                if (unlikely(mc->ops->peek_rx(mc->dev) ||
                             test_bit(MAL_COMMAC_RX_STOPPED, &mc->flags))) {
                        MAL_DBG2(mal, "rotting packet" NL);
-                       if (napi_reschedule(napi))
-                               mal_disable_eob_irq(mal);
-                       else
-                               MAL_DBG2(mal, "already in poll list" NL);
-
-                       if (budget > 0)
-                               goto again;
-                       else
+                       if (!napi_reschedule(napi))
                                goto more_work;
+
+                       spin_lock_irqsave(&mal->lock, flags);
+                       mal_disable_eob_irq(mal);
+                       spin_unlock_irqrestore(&mal->lock, flags);
+                       goto again;
                }
                mc->ops->poll_tx(mc->dev);
        }
index ea20182c6969245e53a3a9da563c76461555f7f5..bb11624a1f3948bb81c38238b89422389b43c61b 100644 (file)
@@ -1691,7 +1691,7 @@ static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave
                        vp_oper->vlan_idx = NO_INDX;
                }
                if (NO_INDX != vp_oper->mac_idx) {
-                       __mlx4_unregister_mac(&priv->dev, port, vp_oper->mac_idx);
+                       __mlx4_unregister_mac(&priv->dev, port, vp_oper->state.mac);
                        vp_oper->mac_idx = NO_INDX;
                }
        }
index 3ca00e05f23d2ade287d6c1d9047410eeac43114..ace217c447ddd182d0143bb2977b2e62b23ba883 100644 (file)
@@ -2276,9 +2276,9 @@ int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
                temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
                npar_info->max_linkspeed_reg_offset = temp;
        }
-       if (npar_info->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS)
-               memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
-                      sizeof(ahw->extra_capability));
+
+       memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
+              sizeof(ahw->extra_capability));
 
 out:
        qlcnic_free_mbx_args(&cmd);
index f8adc7b01f1f5ef9e62899a9c68c5eea9d2e2cba..b64e2bef94287cea63a5f452a7e97add7ee73986 100644 (file)
@@ -785,8 +785,6 @@ void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter)
 
 #define QLCNIC_ENABLE_IPV4_LRO         1
 #define QLCNIC_ENABLE_IPV6_LRO         2
-#define QLCNIC_NO_DEST_IPV4_CHECK      (1 << 8)
-#define QLCNIC_NO_DEST_IPV6_CHECK      (2 << 8)
 
 int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
 {
@@ -806,11 +804,10 @@ int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
 
        word = 0;
        if (enable) {
-               word = QLCNIC_ENABLE_IPV4_LRO | QLCNIC_NO_DEST_IPV4_CHECK;
+               word = QLCNIC_ENABLE_IPV4_LRO;
                if (adapter->ahw->extra_capability[0] &
                    QLCNIC_FW_CAP2_HW_LRO_IPV6)
-                       word |= QLCNIC_ENABLE_IPV6_LRO |
-                               QLCNIC_NO_DEST_IPV6_CHECK;
+                       word |= QLCNIC_ENABLE_IPV6_LRO;
        }
 
        req.words[0] = cpu_to_le64(word);
index 9e61eb8674524575481d0f1158d75353ea4ef724..d8f4897e9e820ebef4469c2c744e75910f6ebf2c 100644 (file)
@@ -1131,7 +1131,10 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
                if (err == -EIO)
                        return err;
                adapter->ahw->extra_capability[0] = temp;
+       } else {
+               adapter->ahw->extra_capability[0] = 0;
        }
+
        adapter->ahw->max_mac_filters = nic_info.max_mac_filters;
        adapter->ahw->max_mtu = nic_info.max_mtu;
 
@@ -2159,8 +2162,7 @@ void qlcnic_set_drv_version(struct qlcnic_adapter *adapter)
        else if (qlcnic_83xx_check(adapter))
                fw_cmd = QLCNIC_CMD_83XX_SET_DRV_VER;
 
-       if ((ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) &&
-           (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_SET_DRV_VER))
+       if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_SET_DRV_VER)
                qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
 }
 
index adeee615dd19f4e0d7c6288466798781a1f8bda7..c9a15925a1f757bf1da6ceef594389df15315f24 100644 (file)
@@ -310,6 +310,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,
                             const char *buf,
                             size_t count)
 {
+       unsigned long flags;
        int enabled;
        int err;
 
@@ -324,9 +325,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,
                return -EINVAL;
        }
 
-       mutex_lock(&nt->mutex);
        if (enabled) {  /* 1 */
-
                /*
                 * Skip netpoll_parse_options() -- all the attributes are
                 * already configured via configfs. Just print them out.
@@ -334,19 +333,22 @@ static ssize_t store_enabled(struct netconsole_target *nt,
                netpoll_print_options(&nt->np);
 
                err = netpoll_setup(&nt->np);
-               if (err) {
-                       mutex_unlock(&nt->mutex);
+               if (err)
                        return err;
-               }
 
                printk(KERN_INFO "netconsole: network logging started\n");
-
        } else {        /* 0 */
+               /* We need to disable the netconsole before cleaning it up
+                * otherwise we might end up in write_msg() with
+                * nt->np.dev == NULL and nt->enabled == 1
+                */
+               spin_lock_irqsave(&target_list_lock, flags);
+               nt->enabled = 0;
+               spin_unlock_irqrestore(&target_list_lock, flags);
                netpoll_cleanup(&nt->np);
        }
 
        nt->enabled = enabled;
-       mutex_unlock(&nt->mutex);
 
        return strnlen(buf, count);
 }
@@ -563,8 +565,10 @@ static ssize_t netconsole_target_attr_store(struct config_item *item,
        struct netconsole_target_attr *na =
                container_of(attr, struct netconsole_target_attr, attr);
 
+       mutex_lock(&nt->mutex);
        if (na->store)
                ret = na->store(nt, buf, count);
+       mutex_unlock(&nt->mutex);
 
        return ret;
 }
index dc920974204e6426610ac5f2fad3a7ba4bd1dd9c..56178761ce930750a0d035a9593dcf0464d10d6d 100644 (file)
@@ -438,17 +438,19 @@ phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
 
        return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
 }
+static DEVICE_ATTR_RO(phy_id);
 
-static struct device_attribute mdio_dev_attrs[] = {
-       __ATTR_RO(phy_id),
-       __ATTR_NULL
+static struct attribute *mdio_dev_attrs[] = {
+       &dev_attr_phy_id.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(mdio_dev);
 
 struct bus_type mdio_bus_type = {
        .name           = "mdio_bus",
        .match          = mdio_bus_match,
        .pm             = MDIO_BUS_PM_OPS,
-       .dev_attrs      = mdio_dev_attrs,
+       .dev_groups     = mdio_dev_groups,
 };
 EXPORT_SYMBOL(mdio_bus_type);
 
index 846cc19c04f23f2f5a15adf65d8098cc36513eb6..8e8d0fcd4979f10c71ff1e37140313d255429847 100644 (file)
@@ -78,7 +78,6 @@
 #define AX_MEDIUM_STATUS_MODE                  0x22
        #define AX_MEDIUM_GIGAMODE      0x01
        #define AX_MEDIUM_FULL_DUPLEX   0x02
-       #define AX_MEDIUM_ALWAYS_ONE    0x04
        #define AX_MEDIUM_EN_125MHZ     0x08
        #define AX_MEDIUM_RXFLOW_CTRLEN 0x10
        #define AX_MEDIUM_TXFLOW_CTRLEN 0x20
@@ -1065,8 +1064,8 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
 
        /* Configure default medium type => giga */
        *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
-                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
-                AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
+                AX_MEDIUM_GIGAMODE;
        ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
                          2, 2, tmp16);
 
@@ -1225,7 +1224,7 @@ static int ax88179_link_reset(struct usbnet *dev)
        }
 
        mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
-              AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE;
+              AX_MEDIUM_RXFLOW_CTRLEN;
 
        ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
                         1, 1, &link_sts);
@@ -1339,8 +1338,8 @@ static int ax88179_reset(struct usbnet *dev)
 
        /* Configure default medium type => giga */
        *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
-                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
-                AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
+                AX_MEDIUM_GIGAMODE;
        ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
                          2, 2, tmp16);
 
index 9fbdfcd1e1a0693e96edd908928953097b99742d..bbc9cb84ec1fe4f857bc5df63a0ecb3f80659b1b 100644 (file)
@@ -1118,11 +1118,6 @@ static int virtnet_cpu_callback(struct notifier_block *nfb,
 {
        struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
 
-       mutex_lock(&vi->config_lock);
-
-       if (!vi->config_enable)
-               goto done;
-
        switch(action & ~CPU_TASKS_FROZEN) {
        case CPU_ONLINE:
        case CPU_DOWN_FAILED:
@@ -1136,8 +1131,6 @@ static int virtnet_cpu_callback(struct notifier_block *nfb,
                break;
        }
 
-done:
-       mutex_unlock(&vi->config_lock);
        return NOTIFY_OK;
 }
 
@@ -1699,6 +1692,8 @@ static int virtnet_freeze(struct virtio_device *vdev)
        struct virtnet_info *vi = vdev->priv;
        int i;
 
+       unregister_hotcpu_notifier(&vi->nb);
+
        /* Prevent config work handler from accessing the device */
        mutex_lock(&vi->config_lock);
        vi->config_enable = false;
@@ -1747,6 +1742,10 @@ static int virtnet_restore(struct virtio_device *vdev)
        virtnet_set_queues(vi, vi->curr_queue_pairs);
        rtnl_unlock();
 
+       err = register_hotcpu_notifier(&vi->nb);
+       if (err)
+               return err;
+
        return 0;
 }
 #endif
index 5bbcb5e3ee0c0cf5e9fefff42fb6892541e14548..388ddf60a66d492f0df7ea2c6f008b51a7778252 100644 (file)
@@ -148,10 +148,6 @@ static int  enslave( struct net_device *, struct net_device * );
 static int  emancipate( struct net_device * );
 #endif
 
-#ifdef __i386__
-#define ASM_CRC 1
-#endif
-
 static const char  version[] =
        "Granch SBNI12 driver ver 5.0.1  Jun 22 2001  Denis I.Timofeev.\n";
 
@@ -1551,88 +1547,6 @@ __setup( "sbni=", sbni_setup );
 
 /* -------------------------------------------------------------------------- */
 
-#ifdef ASM_CRC
-
-static u32
-calc_crc32( u32  crc,  u8  *p,  u32  len )
-{
-       register u32  _crc;
-       _crc = crc;
-       
-       __asm__ __volatile__ (
-               "xorl   %%ebx, %%ebx\n"
-               "movl   %2, %%esi\n" 
-               "movl   %3, %%ecx\n" 
-               "movl   $crc32tab, %%edi\n"
-               "shrl   $2, %%ecx\n"
-               "jz     1f\n"
-
-               ".align 4\n"
-       "0:\n"
-               "movb   %%al, %%bl\n"
-               "movl   (%%esi), %%edx\n"
-               "shrl   $8, %%eax\n"
-               "xorb   %%dl, %%bl\n"
-               "shrl   $8, %%edx\n"
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-
-               "movb   %%al, %%bl\n"
-               "shrl   $8, %%eax\n"
-               "xorb   %%dl, %%bl\n"
-               "shrl   $8, %%edx\n"
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-
-               "movb   %%al, %%bl\n"
-               "shrl   $8, %%eax\n"
-               "xorb   %%dl, %%bl\n"
-               "movb   %%dh, %%dl\n" 
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-
-               "movb   %%al, %%bl\n"
-               "shrl   $8, %%eax\n"
-               "xorb   %%dl, %%bl\n"
-               "addl   $4, %%esi\n"
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-
-               "decl   %%ecx\n"
-               "jnz    0b\n"
-
-       "1:\n"
-               "movl   %3, %%ecx\n"
-               "andl   $3, %%ecx\n"
-               "jz     2f\n"
-
-               "movb   %%al, %%bl\n"
-               "shrl   $8, %%eax\n"
-               "xorb   (%%esi), %%bl\n"
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-
-               "decl   %%ecx\n"
-               "jz     2f\n"
-
-               "movb   %%al, %%bl\n"
-               "shrl   $8, %%eax\n"
-               "xorb   1(%%esi), %%bl\n"
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-
-               "decl   %%ecx\n"
-               "jz     2f\n"
-
-               "movb   %%al, %%bl\n"
-               "shrl   $8, %%eax\n"
-               "xorb   2(%%esi), %%bl\n"
-               "xorl   (%%edi,%%ebx,4), %%eax\n"
-       "2:\n"
-               : "=a" (_crc)
-               : "0" (_crc), "g" (p), "g" (len)
-               : "bx", "cx", "dx", "si", "di"
-       );
-
-       return  _crc;
-}
-
-#else  /* ASM_CRC */
-
 static u32
 calc_crc32( u32  crc,  u8  *p,  u32  len )
 {
@@ -1642,9 +1556,6 @@ calc_crc32( u32  crc,  u8  *p,  u32  len )
        return  crc;
 }
 
-#endif /* ASM_CRC */
-
-
 static u32  crc32tab[] __attribute__ ((aligned(8))) = {
        0xD202EF8D,  0xA505DF1B,  0x3C0C8EA1,  0x4B0BBE37,
        0xD56F2B94,  0xA2681B02,  0x3B614AB8,  0x4C667A2E,
index 5715318d6bab3b4c7905c7c69ee549e39636c6cc..400fea1de080c163f18fbe8efa3048a47abe6ec1 100644 (file)
@@ -163,6 +163,7 @@ struct xenvif {
        unsigned long   credit_usec;
        unsigned long   remaining_credit;
        struct timer_list credit_timeout;
+       u64 credit_window_start;
 
        /* Statistics */
        unsigned long rx_gso_checksum_fixup;
index 01bb854c7f62bfc281dfdc0081829237f2f843d6..459935a6bfae3ab31c634feff974e64f8f93cf3d 100644 (file)
@@ -312,8 +312,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
        vif->credit_bytes = vif->remaining_credit = ~0UL;
        vif->credit_usec  = 0UL;
        init_timer(&vif->credit_timeout);
-       /* Initialize 'expires' now: it's used to track the credit window. */
-       vif->credit_timeout.expires = jiffies;
+       vif->credit_window_start = get_jiffies_64();
 
        dev->netdev_ops = &xenvif_netdev_ops;
        dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
index f3e591c611ded744ec0b6ea2cefe9b7dd3d568c7..900da4b243ad7a0a4eb21ae992d52912650f4c5c 100644 (file)
@@ -1185,9 +1185,8 @@ out:
 
 static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
 {
-       unsigned long now = jiffies;
-       unsigned long next_credit =
-               vif->credit_timeout.expires +
+       u64 now = get_jiffies_64();
+       u64 next_credit = vif->credit_window_start +
                msecs_to_jiffies(vif->credit_usec / 1000);
 
        /* Timer could already be pending in rare cases. */
@@ -1195,8 +1194,8 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
                return true;
 
        /* Passed the point where we can replenish credit? */
-       if (time_after_eq(now, next_credit)) {
-               vif->credit_timeout.expires = now;
+       if (time_after_eq64(now, next_credit)) {
+               vif->credit_window_start = now;
                tx_add_credit(vif);
        }
 
@@ -1208,6 +1207,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
                        tx_credit_callback;
                mod_timer(&vif->credit_timeout,
                          next_credit);
+               vif->credit_window_start = next_credit;
 
                return true;
        }
index 3d950481112634fc847d61fef187efc86503a189..43186feb4294598b570727e5382263fbffbb1d0d 100644 (file)
@@ -3,7 +3,7 @@ menu "PCI host controller drivers"
 
 config PCI_MVEBU
        bool "Marvell EBU PCIe controller"
-       depends on ARCH_MVEBU || ARCH_KIRKWOOD
+       depends on ARCH_MVEBU || ARCH_DOVE || ARCH_KIRKWOOD
        depends on OF
 
 config PCIE_DW
index 729d5a101d621ece6d36b425ad213a48a57a859f..80b2250ea19a6f892e3645e8736216c7dd96aafd 100644 (file)
@@ -9,13 +9,17 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/mbus.h>
+#include <linux/msi.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/of_address.h>
-#include <linux/of_pci.h>
 #include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of_pci.h>
 #include <linux/of_platform.h>
 
 /*
@@ -103,6 +107,7 @@ struct mvebu_pcie_port;
 struct mvebu_pcie {
        struct platform_device *pdev;
        struct mvebu_pcie_port *ports;
+       struct msi_chip *msi;
        struct resource io;
        struct resource realio;
        struct resource mem;
@@ -115,7 +120,6 @@ struct mvebu_pcie_port {
        char *name;
        void __iomem *base;
        spinlock_t conf_lock;
-       int haslink;
        u32 port;
        u32 lane;
        int devfn;
@@ -124,6 +128,9 @@ struct mvebu_pcie_port {
        unsigned int io_target;
        unsigned int io_attr;
        struct clk *clk;
+       int reset_gpio;
+       int reset_active_low;
+       char *reset_name;
        struct mvebu_sw_pci_bridge bridge;
        struct device_node *dn;
        struct mvebu_pcie *pcie;
@@ -133,29 +140,39 @@ struct mvebu_pcie_port {
        size_t iowin_size;
 };
 
+static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
+{
+       writel(val, port->base + reg);
+}
+
+static inline u32 mvebu_readl(struct mvebu_pcie_port *port, u32 reg)
+{
+       return readl(port->base + reg);
+}
+
 static bool mvebu_pcie_link_up(struct mvebu_pcie_port *port)
 {
-       return !(readl(port->base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
+       return !(mvebu_readl(port, PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
 }
 
 static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie_port *port, int nr)
 {
        u32 stat;
 
-       stat = readl(port->base + PCIE_STAT_OFF);
+       stat = mvebu_readl(port, PCIE_STAT_OFF);
        stat &= ~PCIE_STAT_BUS;
        stat |= nr << 8;
-       writel(stat, port->base + PCIE_STAT_OFF);
+       mvebu_writel(port, stat, PCIE_STAT_OFF);
 }
 
 static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
 {
        u32 stat;
 
-       stat = readl(port->base + PCIE_STAT_OFF);
+       stat = mvebu_readl(port, PCIE_STAT_OFF);
        stat &= ~PCIE_STAT_DEV;
        stat |= nr << 16;
-       writel(stat, port->base + PCIE_STAT_OFF);
+       mvebu_writel(port, stat, PCIE_STAT_OFF);
 }
 
 /*
@@ -163,7 +180,7 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
  * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
  * WIN[0-3] -> DRAM bank[0-3]
  */
-static void __init mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
+static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 {
        const struct mbus_dram_target_info *dram;
        u32 size;
@@ -173,33 +190,34 @@ static void __init mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
        /* First, disable and clear BARs and windows. */
        for (i = 1; i < 3; i++) {
-               writel(0, port->base + PCIE_BAR_CTRL_OFF(i));
-               writel(0, port->base + PCIE_BAR_LO_OFF(i));
-               writel(0, port->base + PCIE_BAR_HI_OFF(i));
+               mvebu_writel(port, 0, PCIE_BAR_CTRL_OFF(i));
+               mvebu_writel(port, 0, PCIE_BAR_LO_OFF(i));
+               mvebu_writel(port, 0, PCIE_BAR_HI_OFF(i));
        }
 
        for (i = 0; i < 5; i++) {
-               writel(0, port->base + PCIE_WIN04_CTRL_OFF(i));
-               writel(0, port->base + PCIE_WIN04_BASE_OFF(i));
-               writel(0, port->base + PCIE_WIN04_REMAP_OFF(i));
+               mvebu_writel(port, 0, PCIE_WIN04_CTRL_OFF(i));
+               mvebu_writel(port, 0, PCIE_WIN04_BASE_OFF(i));
+               mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i));
        }
 
-       writel(0, port->base + PCIE_WIN5_CTRL_OFF);
-       writel(0, port->base + PCIE_WIN5_BASE_OFF);
-       writel(0, port->base + PCIE_WIN5_REMAP_OFF);
+       mvebu_writel(port, 0, PCIE_WIN5_CTRL_OFF);
+       mvebu_writel(port, 0, PCIE_WIN5_BASE_OFF);
+       mvebu_writel(port, 0, PCIE_WIN5_REMAP_OFF);
 
        /* Setup windows for DDR banks.  Count total DDR size on the fly. */
        size = 0;
        for (i = 0; i < dram->num_cs; i++) {
                const struct mbus_dram_window *cs = dram->cs + i;
 
-               writel(cs->base & 0xffff0000,
-                      port->base + PCIE_WIN04_BASE_OFF(i));
-               writel(0, port->base + PCIE_WIN04_REMAP_OFF(i));
-               writel(((cs->size - 1) & 0xffff0000) |
-                       (cs->mbus_attr << 8) |
-                       (dram->mbus_dram_target_id << 4) | 1,
-                      port->base + PCIE_WIN04_CTRL_OFF(i));
+               mvebu_writel(port, cs->base & 0xffff0000,
+                            PCIE_WIN04_BASE_OFF(i));
+               mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i));
+               mvebu_writel(port,
+                            ((cs->size - 1) & 0xffff0000) |
+                            (cs->mbus_attr << 8) |
+                            (dram->mbus_dram_target_id << 4) | 1,
+                            PCIE_WIN04_CTRL_OFF(i));
 
                size += cs->size;
        }
@@ -209,41 +227,40 @@ static void __init mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
                size = 1 << fls(size);
 
        /* Setup BAR[1] to all DRAM banks. */
-       writel(dram->cs[0].base, port->base + PCIE_BAR_LO_OFF(1));
-       writel(0, port->base + PCIE_BAR_HI_OFF(1));
-       writel(((size - 1) & 0xffff0000) | 1,
-              port->base + PCIE_BAR_CTRL_OFF(1));
+       mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
+       mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
+       mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
+                    PCIE_BAR_CTRL_OFF(1));
 }
 
-static void __init mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
+static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-       u16 cmd;
-       u32 mask;
+       u32 cmd, mask;
 
        /* Point PCIe unit MBUS decode windows to DRAM space. */
        mvebu_pcie_setup_wins(port);
 
        /* Master + slave enable. */
-       cmd = readw(port->base + PCIE_CMD_OFF);
+       cmd = mvebu_readl(port, PCIE_CMD_OFF);
        cmd |= PCI_COMMAND_IO;
        cmd |= PCI_COMMAND_MEMORY;
        cmd |= PCI_COMMAND_MASTER;
-       writew(cmd, port->base + PCIE_CMD_OFF);
+       mvebu_writel(port, cmd, PCIE_CMD_OFF);
 
        /* Enable interrupt lines A-D. */
-       mask = readl(port->base + PCIE_MASK_OFF);
+       mask = mvebu_readl(port, PCIE_MASK_OFF);
        mask |= PCIE_MASK_ENABLE_INTS;
-       writel(mask, port->base + PCIE_MASK_OFF);
+       mvebu_writel(port, mask, PCIE_MASK_OFF);
 }
 
 static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
                                 struct pci_bus *bus,
                                 u32 devfn, int where, int size, u32 *val)
 {
-       writel(PCIE_CONF_ADDR(bus->number, devfn, where),
-              port->base + PCIE_CONF_ADDR_OFF);
+       mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
+                    PCIE_CONF_ADDR_OFF);
 
-       *val = readl(port->base + PCIE_CONF_DATA_OFF);
+       *val = mvebu_readl(port, PCIE_CONF_DATA_OFF);
 
        if (size == 1)
                *val = (*val >> (8 * (where & 3))) & 0xff;
@@ -257,21 +274,24 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
                                 struct pci_bus *bus,
                                 u32 devfn, int where, int size, u32 val)
 {
-       int ret = PCIBIOS_SUCCESSFUL;
+       u32 _val, shift = 8 * (where & 3);
 
-       writel(PCIE_CONF_ADDR(bus->number, devfn, where),
-              port->base + PCIE_CONF_ADDR_OFF);
+       mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
+                    PCIE_CONF_ADDR_OFF);
+       _val = mvebu_readl(port, PCIE_CONF_DATA_OFF);
 
        if (size == 4)
-               writel(val, port->base + PCIE_CONF_DATA_OFF);
+               _val = val;
        else if (size == 2)
-               writew(val, port->base + PCIE_CONF_DATA_OFF + (where & 3));
+               _val = (_val & ~(0xffff << shift)) | ((val & 0xffff) << shift);
        else if (size == 1)
-               writeb(val, port->base + PCIE_CONF_DATA_OFF + (where & 3));
+               _val = (_val & ~(0xff << shift)) | ((val & 0xff) << shift);
        else
-               ret = PCIBIOS_BAD_REGISTER_NUMBER;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
 
-       return ret;
+       mvebu_writel(port, _val, PCIE_CONF_DATA_OFF);
+
+       return PCIBIOS_SUCCESSFUL;
 }
 
 static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
@@ -552,7 +572,7 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
        if (bus->number == 0)
                return mvebu_sw_pci_bridge_write(port, where, size, val);
 
-       if (!port->haslink)
+       if (!mvebu_pcie_link_up(port))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        /*
@@ -594,7 +614,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
        if (bus->number == 0)
                return mvebu_sw_pci_bridge_read(port, where, size, val);
 
-       if (!port->haslink) {
+       if (!mvebu_pcie_link_up(port)) {
                *val = 0xffffffff;
                return PCIBIOS_DEVICE_NOT_FOUND;
        }
@@ -626,7 +646,7 @@ static struct pci_ops mvebu_pcie_ops = {
        .write = mvebu_pcie_wr_conf,
 };
 
-static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
+static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
 {
        struct mvebu_pcie *pcie = sys_to_pcie(sys);
        int i;
@@ -645,7 +665,7 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
        return 1;
 }
 
-static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct of_irq oirq;
        int ret;
@@ -673,11 +693,17 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
        return bus;
 }
 
-resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
-                                         const struct resource *res,
-                                         resource_size_t start,
-                                         resource_size_t size,
-                                         resource_size_t align)
+static void mvebu_pcie_add_bus(struct pci_bus *bus)
+{
+       struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
+       bus->msi = pcie->msi;
+}
+
+static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
+                                               const struct resource *res,
+                                               resource_size_t start,
+                                               resource_size_t size,
+                                               resource_size_t align)
 {
        if (dev->bus->number != 0)
                return start;
@@ -696,7 +722,7 @@ resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
                return start;
 }
 
-static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
+static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
 {
        struct hw_pci hw;
 
@@ -709,6 +735,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
        hw.map_irq        = mvebu_pcie_map_irq;
        hw.ops            = &mvebu_pcie_ops;
        hw.align_resource = mvebu_pcie_align_resource;
+       hw.add_bus        = mvebu_pcie_add_bus;
 
        pci_common_init(&hw);
 }
@@ -718,10 +745,8 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
  * <...> property for one that matches the given port/lane. Once
  * found, maps it.
  */
-static void __iomem * __init
-mvebu_pcie_map_registers(struct platform_device *pdev,
-                        struct device_node *np,
-                        struct mvebu_pcie_port *port)
+static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev,
+                     struct device_node *np, struct mvebu_pcie_port *port)
 {
        struct resource regs;
        int ret = 0;
@@ -777,7 +802,22 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
        return -ENOENT;
 }
 
-static int __init mvebu_pcie_probe(struct platform_device *pdev)
+static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
+{
+       struct device_node *msi_node;
+
+       msi_node = of_parse_phandle(pcie->pdev->dev.of_node,
+                                   "msi-parent", 0);
+       if (!msi_node)
+               return;
+
+       pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
+
+       if (pcie->msi)
+               pcie->msi->dev = &pcie->pdev->dev;
+}
+
+static int mvebu_pcie_probe(struct platform_device *pdev)
 {
        struct mvebu_pcie *pcie;
        struct device_node *np = pdev->dev.of_node;
@@ -790,6 +830,7 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        pcie->pdev = pdev;
+       platform_set_drvdata(pdev, pcie);
 
        /* Get the PCIe memory and I/O aperture */
        mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
@@ -818,13 +859,14 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
                return ret;
        }
 
+       i = 0;
        for_each_child_of_node(pdev->dev.of_node, child) {
                if (!of_device_is_available(child))
                        continue;
-               pcie->nports++;
+               i++;
        }
 
-       pcie->ports = devm_kzalloc(&pdev->dev, pcie->nports *
+       pcie->ports = devm_kzalloc(&pdev->dev, i *
                                   sizeof(struct mvebu_pcie_port),
                                   GFP_KERNEL);
        if (!pcie->ports)
@@ -833,6 +875,7 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
        i = 0;
        for_each_child_of_node(pdev->dev.of_node, child) {
                struct mvebu_pcie_port *port = &pcie->ports[i];
+               enum of_gpio_flags flags;
 
                if (!of_device_is_available(child))
                        continue;
@@ -873,45 +916,68 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
                        continue;
                }
 
+               port->reset_gpio = of_get_named_gpio_flags(child,
+                                                  "reset-gpios", 0, &flags);
+               if (gpio_is_valid(port->reset_gpio)) {
+                       u32 reset_udelay = 20000;
+
+                       port->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
+                       port->reset_name = kasprintf(GFP_KERNEL,
+                                    "pcie%d.%d-reset", port->port, port->lane);
+                       of_property_read_u32(child, "reset-delay-us",
+                                            &reset_udelay);
+
+                       ret = devm_gpio_request_one(&pdev->dev,
+                           port->reset_gpio, GPIOF_DIR_OUT, port->reset_name);
+                       if (ret) {
+                               if (ret == -EPROBE_DEFER)
+                                       return ret;
+                               continue;
+                       }
+
+                       gpio_set_value(port->reset_gpio,
+                                      (port->reset_active_low) ? 1 : 0);
+                       msleep(reset_udelay/1000);
+               }
+
+               port->clk = of_clk_get_by_name(child, NULL);
+               if (IS_ERR(port->clk)) {
+                       dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
+                              port->port, port->lane);
+                       continue;
+               }
+
+               ret = clk_prepare_enable(port->clk);
+               if (ret)
+                       continue;
+
                port->base = mvebu_pcie_map_registers(pdev, child, port);
                if (IS_ERR(port->base)) {
                        dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
                                port->port, port->lane);
                        port->base = NULL;
+                       clk_disable_unprepare(port->clk);
                        continue;
                }
 
                mvebu_pcie_set_local_dev_nr(port, 1);
 
-               if (mvebu_pcie_link_up(port)) {
-                       port->haslink = 1;
-                       dev_info(&pdev->dev, "PCIe%d.%d: link up\n",
-                                port->port, port->lane);
-               } else {
-                       port->haslink = 0;
-                       dev_info(&pdev->dev, "PCIe%d.%d: link down\n",
-                                port->port, port->lane);
-               }
-
                port->clk = of_clk_get_by_name(child, NULL);
                if (IS_ERR(port->clk)) {
                        dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
                               port->port, port->lane);
                        iounmap(port->base);
-                       port->haslink = 0;
                        continue;
                }
 
                port->dn = child;
-
-               clk_prepare_enable(port->clk);
                spin_lock_init(&port->conf_lock);
-
                mvebu_sw_pci_bridge_init(port);
-
                i++;
        }
 
+       pcie->nports = i;
+       mvebu_pcie_msi_enable(pcie);
        mvebu_pcie_enable(pcie);
 
        return 0;
@@ -920,6 +986,7 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
 static const struct of_device_id mvebu_pcie_of_match_table[] = {
        { .compatible = "marvell,armada-xp-pcie", },
        { .compatible = "marvell,armada-370-pcie", },
+       { .compatible = "marvell,dove-pcie", },
        { .compatible = "marvell,kirkwood-pcie", },
        {},
 };
@@ -931,16 +998,12 @@ static struct platform_driver mvebu_pcie_driver = {
                .name = "mvebu-pcie",
                .of_match_table =
                   of_match_ptr(mvebu_pcie_of_match_table),
+               /* driver unloading/unbinding currently not supported */
+               .suppress_bind_attrs = true,
        },
+       .probe = mvebu_pcie_probe,
 };
-
-static int __init mvebu_pcie_init(void)
-{
-       return platform_driver_probe(&mvebu_pcie_driver,
-                                    mvebu_pcie_probe);
-}
-
-subsys_initcall(mvebu_pcie_init);
+module_platform_driver(mvebu_pcie_driver);
 
 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
 MODULE_DESCRIPTION("Marvell EBU PCIe driver");
index 66e505ca24ef418a250219789faeb8bd1de8a9be..3c7eb5dd91c636c17e7dadd374022096455d24b1 100644 (file)
@@ -133,7 +133,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       pr_debug("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot));
        kfree(slot->hotplug_slot->info);
        kfree(slot->hotplug_slot);
        kfree(slot);
@@ -183,10 +182,9 @@ int zpci_init_slot(struct zpci_dev *zdev)
        snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
        rc = pci_hp_register(slot->hotplug_slot, zdev->bus,
                             ZPCI_DEVFN, name);
-       if (rc) {
-               pr_err("pci_hp_register failed with error %d\n", rc);
+       if (rc)
                goto error_reg;
-       }
+
        list_add(&slot->slot_list, &s390_hotplug_slot_list);
        return 0;
 
index 98f7b9b89507e05a331cceacc8defad13e7d9534..38f3c0140dfb6f411cdb4f1ba72133bc8303e48e 100644 (file)
@@ -135,6 +135,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
                return retval;
        return count;
 }
+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
 
 /**
  * store_remove_id - remove a PCI device ID from this driver
@@ -180,12 +181,14 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count)
                return retval;
        return count;
 }
+static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
 
-static struct driver_attribute pci_drv_attrs[] = {
-       __ATTR(new_id, S_IWUSR, NULL, store_new_id),
-       __ATTR(remove_id, S_IWUSR, NULL, store_remove_id),
-       __ATTR_NULL,
+static struct attribute *pci_drv_attrs[] = {
+       &driver_attr_new_id.attr,
+       &driver_attr_remove_id.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(pci_drv);
 
 /**
  * pci_match_id - See if a pci device matches a given pci_id table
@@ -1317,8 +1320,8 @@ struct bus_type pci_bus_type = {
        .remove         = pci_device_remove,
        .shutdown       = pci_device_shutdown,
        .dev_attrs      = pci_dev_attrs,
-       .bus_attrs      = pci_bus_attrs,
-       .drv_attrs      = pci_drv_attrs,
+       .bus_groups     = pci_bus_groups,
+       .drv_groups     = pci_drv_groups,
        .pm             = PCI_PM_OPS_PTR,
 };
 
index 7128cfdd64aa9d31c8628be30e7c65b33396dbfb..d8eb880bd1fce5971774a03719eb3be14e83f690 100644 (file)
@@ -302,10 +302,20 @@ static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
        }
        return count;
 }
+static BUS_ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store);
 
-struct bus_attribute pci_bus_attrs[] = {
-       __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store),
-       __ATTR_NULL
+struct attribute *pci_bus_attrs[] = {
+       &bus_attr_rescan.attr,
+       NULL,
+};
+
+static const struct attribute_group pci_bus_group = {
+       .attrs = pci_bus_attrs,
+};
+
+const struct attribute_group *pci_bus_groups[] = {
+       &pci_bus_group,
+       NULL,
 };
 
 static ssize_t
index 8a00c063d7bc67af7a3256fdd4a81c3d4d87f80b..607be58dd72859ab40384c49d0de8a84f49c24a7 100644 (file)
@@ -156,7 +156,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
 extern struct device_attribute pci_dev_attrs[];
 extern const struct attribute_group *pcibus_groups[];
 extern struct device_type pci_dev_type;
-extern struct bus_attribute pci_bus_attrs[];
+extern const struct attribute_group *pci_bus_groups[];
 
 
 /**
index b8f5acf02261ca6708b26692d420f9164d2ac046..de24232c5191040fa0aa3607d12a7d3fd2a0d4ae 100644 (file)
@@ -245,7 +245,7 @@ static int at91_cf_dt_init(struct platform_device *pdev)
 }
 #endif
 
-static int __init at91_cf_probe(struct platform_device *pdev)
+static int at91_cf_probe(struct platform_device *pdev)
 {
        struct at91_cf_socket   *cf;
        struct at91_cf_data     *board = pdev->dev.platform_data;
@@ -354,7 +354,7 @@ fail0a:
        return status;
 }
 
-static int __exit at91_cf_remove(struct platform_device *pdev)
+static int at91_cf_remove(struct platform_device *pdev)
 {
        struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
 
@@ -404,14 +404,13 @@ static struct platform_driver at91_cf_driver = {
                .owner          = THIS_MODULE,
                .of_match_table = of_match_ptr(at91_cf_dt_ids),
        },
-       .remove         = __exit_p(at91_cf_remove),
+       .probe          = at91_cf_probe,
+       .remove         = at91_cf_remove,
        .suspend        = at91_cf_suspend,
        .resume         = at91_cf_resume,
 };
 
-/*--------------------------------------------------------------------------*/
-
-module_platform_driver_probe(at91_cf_driver, at91_cf_probe);
+module_platform_driver(at91_cf_driver);
 
 MODULE_DESCRIPTION("AT91 Compact Flash Driver");
 MODULE_AUTHOR("David Brownell");
index 2deacbb2ffdc4d325b9dea851d8d2dc56a44191a..757119b87146cbc5219527c8e7c584795c34174e 100644 (file)
@@ -992,16 +992,17 @@ static ssize_t field##_show (struct device *dev, struct device_attribute *attr,
 {                                                                      \
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);               \
        return p_dev->test ? sprintf(buf, format, p_dev->field) : -ENODEV; \
-}
+}                                                                      \
+static DEVICE_ATTR_RO(field);
 
 #define pcmcia_device_stringattr(name, field)                                  \
 static ssize_t name##_show (struct device *dev, struct device_attribute *attr, char *buf)              \
 {                                                                      \
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);               \
        return p_dev->field ? sprintf(buf, "%s\n", p_dev->field) : -ENODEV; \
-}
+}                                                                      \
+static DEVICE_ATTR_RO(name);
 
-pcmcia_device_attr(func, socket, "0x%02x\n");
 pcmcia_device_attr(func_id, has_func_id, "0x%02x\n");
 pcmcia_device_attr(manf_id, has_manf_id, "0x%04x\n");
 pcmcia_device_attr(card_id, has_card_id, "0x%04x\n");
@@ -1010,8 +1011,16 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]);
 pcmcia_device_stringattr(prod_id3, prod_id[2]);
 pcmcia_device_stringattr(prod_id4, prod_id[3]);
 
-static ssize_t pcmcia_show_resources(struct device *dev,
-                                    struct device_attribute *attr, char *buf)
+static ssize_t function_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+       return p_dev->socket ? sprintf(buf, "0x%02x\n", p_dev->func) : -ENODEV;
+}
+static DEVICE_ATTR_RO(function);
+
+static ssize_t resources_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
        char *str = buf;
@@ -1022,8 +1031,9 @@ static ssize_t pcmcia_show_resources(struct device *dev,
 
        return str - buf;
 }
+static DEVICE_ATTR_RO(resources);
 
-static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t pm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 
@@ -1033,8 +1043,8 @@ static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute
                return sprintf(buf, "on\n");
 }
 
-static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute *attr,
-                                    const char *buf, size_t count)
+static ssize_t pm_state_store(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
        int ret = 0;
@@ -1049,7 +1059,7 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute
 
        return ret ? ret : count;
 }
-
+static DEVICE_ATTR_RW(pm_state);
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1072,8 +1082,9 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
                                p_dev->func, p_dev->device_no,
                                hash[0], hash[1], hash[2], hash[3]);
 }
+static DEVICE_ATTR_RO(modalias);
 
-static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
+static ssize_t allow_func_id_match_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
@@ -1088,22 +1099,24 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
 
        return count;
 }
-
-static struct device_attribute pcmcia_dev_attrs[] = {
-       __ATTR(function, 0444, func_show, NULL),
-       __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state),
-       __ATTR(resources, 0444, pcmcia_show_resources, NULL),
-       __ATTR_RO(func_id),
-       __ATTR_RO(manf_id),
-       __ATTR_RO(card_id),
-       __ATTR_RO(prod_id1),
-       __ATTR_RO(prod_id2),
-       __ATTR_RO(prod_id3),
-       __ATTR_RO(prod_id4),
-       __ATTR_RO(modalias),
-       __ATTR(allow_func_id_match, 0200, NULL, pcmcia_store_allow_func_id_match),
-       __ATTR_NULL,
+static DEVICE_ATTR_WO(allow_func_id_match);
+
+static struct attribute *pcmcia_dev_attrs[] = {
+       &dev_attr_resources.attr,
+       &dev_attr_pm_state.attr,
+       &dev_attr_function.attr,
+       &dev_attr_func_id.attr,
+       &dev_attr_manf_id.attr,
+       &dev_attr_card_id.attr,
+       &dev_attr_prod_id1.attr,
+       &dev_attr_prod_id2.attr,
+       &dev_attr_prod_id3.attr,
+       &dev_attr_prod_id4.attr,
+       &dev_attr_modalias.attr,
+       &dev_attr_allow_func_id_match.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(pcmcia_dev);
 
 /* PM support, also needed for reset */
 
@@ -1389,7 +1402,7 @@ struct bus_type pcmcia_bus_type = {
        .name = "pcmcia",
        .uevent = pcmcia_bus_uevent,
        .match = pcmcia_bus_match,
-       .dev_attrs = pcmcia_dev_attrs,
+       .dev_groups = pcmcia_dev_groups,
        .probe = pcmcia_device_probe,
        .remove = pcmcia_device_remove,
        .suspend = pcmcia_dev_suspend,
index a4c16ee5c7188d24bce41f834851f61f5e56d9ea..622dd6fe7347c7e3aec8fb3d337347ec8bd03537 100644 (file)
@@ -777,15 +777,4 @@ static struct pci_driver pd6729_pci_driver = {
        .remove         = pd6729_pci_remove,
 };
 
-static int pd6729_module_init(void)
-{
-       return pci_register_driver(&pd6729_pci_driver);
-}
-
-static void pd6729_module_exit(void)
-{
-       pci_unregister_driver(&pd6729_pci_driver);
-}
-
-module_init(pd6729_module_init);
-module_exit(pd6729_module_exit);
+module_pci_driver(pd6729_pci_driver);
index 6b4ff099fb13c8de403f20e1920c002787c8a81d..dc18a3a5e010479756545400a3c84f7dc0409685 100644 (file)
@@ -1439,20 +1439,6 @@ static struct pci_driver yenta_cardbus_driver = {
        .driver.pm      = YENTA_PM_OPS,
 };
 
-
-static int __init yenta_socket_init(void)
-{
-       return pci_register_driver(&yenta_cardbus_driver);
-}
-
-
-static void __exit yenta_socket_exit(void)
-{
-       pci_unregister_driver(&yenta_cardbus_driver);
-}
-
-
-module_init(yenta_socket_init);
-module_exit(yenta_socket_exit);
+module_pci_driver(yenta_cardbus_driver);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
new file mode 100644 (file)
index 0000000..a344f3d
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# PHY
+#
+
+menu "PHY Subsystem"
+
+config GENERIC_PHY
+       tristate "PHY Core"
+       help
+         Generic PHY support.
+
+         This framework is designed to provide a generic interface for PHY
+         devices present in the kernel. This layer will have the generic
+         API by which phy drivers can create PHY using the phy framework and
+         phy users can obtain reference to the PHY. All the users of this
+         framework should select this config.
+
+config PHY_EXYNOS_MIPI_VIDEO
+       tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
+       help
+         Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
+         and EXYNOS SoCs.
+
+config OMAP_USB2
+       tristate "OMAP USB2 PHY Driver"
+       depends on ARCH_OMAP2PLUS
+       select GENERIC_PHY
+       select USB_PHY
+       select OMAP_CONTROL_USB
+       help
+         Enable this to support the transceiver that is part of SOC. This
+         driver takes care of all the PHY functionality apart from comparator.
+         The USB OTG controller communicates with the comparator using this
+         driver.
+
+config TWL4030_USB
+       tristate "TWL4030 USB Transceiver Driver"
+       depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
+       select GENERIC_PHY
+       select USB_PHY
+       help
+         Enable this to support the USB OTG transceiver on TWL4030
+         family chips (including the TWL5030 and TPS659x0 devices).
+         This transceiver supports high and full speed devices plus,
+         in host mode, low speed.
+
+config PHY_EXYNOS_DP_VIDEO
+       tristate "EXYNOS SoC series Display Port PHY driver"
+       depends on OF
+       select GENERIC_PHY
+       help
+         Support for Display Port PHY found on Samsung EXYNOS SoCs.
+
+endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
new file mode 100644 (file)
index 0000000..d0caae9
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for the phy drivers.
+#
+
+obj-$(CONFIG_GENERIC_PHY)              += phy-core.o
+obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)      += phy-exynos-dp-video.o
+obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)    += phy-exynos-mipi-video.o
+obj-$(CONFIG_OMAP_USB2)                        += phy-omap-usb2.o
+obj-$(CONFIG_TWL4030_USB)              += phy-twl4030-usb.o
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
new file mode 100644 (file)
index 0000000..03cf8fb
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * phy-core.c  --  Generic Phy framework.
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/idr.h>
+#include <linux/pm_runtime.h>
+
+static struct class *phy_class;
+static DEFINE_MUTEX(phy_provider_mutex);
+static LIST_HEAD(phy_provider_list);
+static DEFINE_IDA(phy_ida);
+
+static void devm_phy_release(struct device *dev, void *res)
+{
+       struct phy *phy = *(struct phy **)res;
+
+       phy_put(phy);
+}
+
+static void devm_phy_provider_release(struct device *dev, void *res)
+{
+       struct phy_provider *phy_provider = *(struct phy_provider **)res;
+
+       of_phy_provider_unregister(phy_provider);
+}
+
+static void devm_phy_consume(struct device *dev, void *res)
+{
+       struct phy *phy = *(struct phy **)res;
+
+       phy_destroy(phy);
+}
+
+static int devm_phy_match(struct device *dev, void *res, void *match_data)
+{
+       return res == match_data;
+}
+
+static struct phy *phy_lookup(struct device *device, const char *port)
+{
+       unsigned int count;
+       struct phy *phy;
+       struct device *dev;
+       struct phy_consumer *consumers;
+       struct class_dev_iter iter;
+
+       class_dev_iter_init(&iter, phy_class, NULL, NULL);
+       while ((dev = class_dev_iter_next(&iter))) {
+               phy = to_phy(dev);
+               count = phy->init_data->num_consumers;
+               consumers = phy->init_data->consumers;
+               while (count--) {
+                       if (!strcmp(consumers->dev_name, dev_name(device)) &&
+                                       !strcmp(consumers->port, port)) {
+                               class_dev_iter_exit(&iter);
+                               return phy;
+                       }
+                       consumers++;
+               }
+       }
+
+       class_dev_iter_exit(&iter);
+       return ERR_PTR(-ENODEV);
+}
+
+static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
+{
+       struct phy_provider *phy_provider;
+
+       list_for_each_entry(phy_provider, &phy_provider_list, list) {
+               if (phy_provider->dev->of_node == node)
+                       return phy_provider;
+       }
+
+       return ERR_PTR(-EPROBE_DEFER);
+}
+
+int phy_pm_runtime_get(struct phy *phy)
+{
+       if (!pm_runtime_enabled(&phy->dev))
+               return -ENOTSUPP;
+
+       return pm_runtime_get(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_pm_runtime_get);
+
+int phy_pm_runtime_get_sync(struct phy *phy)
+{
+       if (!pm_runtime_enabled(&phy->dev))
+               return -ENOTSUPP;
+
+       return pm_runtime_get_sync(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync);
+
+int phy_pm_runtime_put(struct phy *phy)
+{
+       if (!pm_runtime_enabled(&phy->dev))
+               return -ENOTSUPP;
+
+       return pm_runtime_put(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_pm_runtime_put);
+
+int phy_pm_runtime_put_sync(struct phy *phy)
+{
+       if (!pm_runtime_enabled(&phy->dev))
+               return -ENOTSUPP;
+
+       return pm_runtime_put_sync(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_pm_runtime_put_sync);
+
+void phy_pm_runtime_allow(struct phy *phy)
+{
+       if (!pm_runtime_enabled(&phy->dev))
+               return;
+
+       pm_runtime_allow(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_pm_runtime_allow);
+
+void phy_pm_runtime_forbid(struct phy *phy)
+{
+       if (!pm_runtime_enabled(&phy->dev))
+               return;
+
+       pm_runtime_forbid(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_pm_runtime_forbid);
+
+int phy_init(struct phy *phy)
+{
+       int ret;
+
+       ret = phy_pm_runtime_get_sync(phy);
+       if (ret < 0 && ret != -ENOTSUPP)
+               return ret;
+
+       mutex_lock(&phy->mutex);
+       if (phy->init_count++ == 0 && phy->ops->init) {
+               ret = phy->ops->init(phy);
+               if (ret < 0) {
+                       dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+                       goto out;
+               }
+       }
+
+out:
+       mutex_unlock(&phy->mutex);
+       phy_pm_runtime_put(phy);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_init);
+
+int phy_exit(struct phy *phy)
+{
+       int ret;
+
+       ret = phy_pm_runtime_get_sync(phy);
+       if (ret < 0 && ret != -ENOTSUPP)
+               return ret;
+
+       mutex_lock(&phy->mutex);
+       if (--phy->init_count == 0 && phy->ops->exit) {
+               ret = phy->ops->exit(phy);
+               if (ret < 0) {
+                       dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+                       goto out;
+               }
+       }
+
+out:
+       mutex_unlock(&phy->mutex);
+       phy_pm_runtime_put(phy);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_exit);
+
+int phy_power_on(struct phy *phy)
+{
+       int ret = -ENOTSUPP;
+
+       ret = phy_pm_runtime_get_sync(phy);
+       if (ret < 0 && ret != -ENOTSUPP)
+               return ret;
+
+       mutex_lock(&phy->mutex);
+       if (phy->power_count++ == 0 && phy->ops->power_on) {
+               ret = phy->ops->power_on(phy);
+               if (ret < 0) {
+                       dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+                       goto out;
+               }
+       }
+
+out:
+       mutex_unlock(&phy->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_power_on);
+
+int phy_power_off(struct phy *phy)
+{
+       int ret = -ENOTSUPP;
+
+       mutex_lock(&phy->mutex);
+       if (--phy->power_count == 0 && phy->ops->power_off) {
+               ret =  phy->ops->power_off(phy);
+               if (ret < 0) {
+                       dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
+                       goto out;
+               }
+       }
+
+out:
+       mutex_unlock(&phy->mutex);
+       phy_pm_runtime_put(phy);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_power_off);
+
+/**
+ * of_phy_get() - lookup and obtain a reference to a phy by phandle
+ * @dev: device that requests this phy
+ * @index: the index of the phy
+ *
+ * Returns the phy associated with the given phandle value,
+ * after getting a refcount to it or -ENODEV if there is no such phy or
+ * -EPROBE_DEFER if there is a phandle to the phy, but the device is
+ * not yet loaded. This function uses of_xlate call back function provided
+ * while registering the phy_provider to find the phy instance.
+ */
+static struct phy *of_phy_get(struct device *dev, int index)
+{
+       int ret;
+       struct phy_provider *phy_provider;
+       struct phy *phy = NULL;
+       struct of_phandle_args args;
+
+       ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells",
+               index, &args);
+       if (ret) {
+               dev_dbg(dev, "failed to get phy in %s node\n",
+                       dev->of_node->full_name);
+               return ERR_PTR(-ENODEV);
+       }
+
+       mutex_lock(&phy_provider_mutex);
+       phy_provider = of_phy_provider_lookup(args.np);
+       if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
+               phy = ERR_PTR(-EPROBE_DEFER);
+               goto err0;
+       }
+
+       phy = phy_provider->of_xlate(phy_provider->dev, &args);
+       module_put(phy_provider->owner);
+
+err0:
+       mutex_unlock(&phy_provider_mutex);
+       of_node_put(args.np);
+
+       return phy;
+}
+
+/**
+ * phy_put() - release the PHY
+ * @phy: the phy returned by phy_get()
+ *
+ * Releases a refcount the caller received from phy_get().
+ */
+void phy_put(struct phy *phy)
+{
+       if (IS_ERR(phy))
+               return;
+
+       module_put(phy->ops->owner);
+       put_device(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_put);
+
+/**
+ * devm_phy_put() - release the PHY
+ * @dev: device that wants to release this phy
+ * @phy: the phy returned by devm_phy_get()
+ *
+ * destroys the devres associated with this phy and invokes phy_put
+ * to release the phy.
+ */
+void devm_phy_put(struct device *dev, struct phy *phy)
+{
+       int r;
+
+       r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
+       dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+}
+EXPORT_SYMBOL_GPL(devm_phy_put);
+
+/**
+ * of_phy_simple_xlate() - returns the phy instance from phy provider
+ * @dev: the PHY provider device
+ * @args: of_phandle_args (not used here)
+ *
+ * Intended to be used by phy provider for the common case where #phy-cells is
+ * 0. For other cases where #phy-cells is greater than '0', the phy provider
+ * should provide a custom of_xlate function that reads the *args* and returns
+ * the appropriate phy.
+ */
+struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
+       *args)
+{
+       struct phy *phy;
+       struct class_dev_iter iter;
+       struct device_node *node = dev->of_node;
+
+       class_dev_iter_init(&iter, phy_class, NULL, NULL);
+       while ((dev = class_dev_iter_next(&iter))) {
+               phy = to_phy(dev);
+               if (node != phy->dev.of_node)
+                       continue;
+
+               class_dev_iter_exit(&iter);
+               return phy;
+       }
+
+       class_dev_iter_exit(&iter);
+       return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(of_phy_simple_xlate);
+
+/**
+ * phy_get() - lookup and obtain a reference to a phy.
+ * @dev: device that requests this phy
+ * @string: the phy name as given in the dt data or the name of the controller
+ * port for non-dt case
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy.  The caller is responsible for
+ * calling phy_put() to release that count.
+ */
+struct phy *phy_get(struct device *dev, const char *string)
+{
+       int index = 0;
+       struct phy *phy = NULL;
+
+       if (string == NULL) {
+               dev_WARN(dev, "missing string\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       if (dev->of_node) {
+               index = of_property_match_string(dev->of_node, "phy-names",
+                       string);
+               phy = of_phy_get(dev, index);
+               if (IS_ERR(phy)) {
+                       dev_err(dev, "unable to find phy\n");
+                       return phy;
+               }
+       } else {
+               phy = phy_lookup(dev, string);
+               if (IS_ERR(phy)) {
+                       dev_err(dev, "unable to find phy\n");
+                       return phy;
+               }
+       }
+
+       if (!try_module_get(phy->ops->owner))
+               return ERR_PTR(-EPROBE_DEFER);
+
+       get_device(&phy->dev);
+
+       return phy;
+}
+EXPORT_SYMBOL_GPL(phy_get);
+
+/**
+ * devm_phy_get() - lookup and obtain a reference to a phy.
+ * @dev: device that requests this phy
+ * @string: the phy name as given in the dt data or phy device name
+ * for non-dt case
+ *
+ * Gets the phy using phy_get(), and associates a device with it using
+ * devres. On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
+ */
+struct phy *devm_phy_get(struct device *dev, const char *string)
+{
+       struct phy **ptr, *phy;
+
+       ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       phy = phy_get(dev, string);
+       if (!IS_ERR(phy)) {
+               *ptr = phy;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return phy;
+}
+EXPORT_SYMBOL_GPL(devm_phy_get);
+
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @ops: function pointers for performing phy operations
+ * @init_data: contains the list of PHY consumers or NULL
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
+       struct phy_init_data *init_data)
+{
+       int ret;
+       int id;
+       struct phy *phy;
+
+       if (!dev) {
+               dev_WARN(dev, "no device provided for PHY\n");
+               ret = -EINVAL;
+               goto err0;
+       }
+
+       phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+       if (!phy) {
+               ret = -ENOMEM;
+               goto err0;
+       }
+
+       id = ida_simple_get(&phy_ida, 0, 0, GFP_KERNEL);
+       if (id < 0) {
+               dev_err(dev, "unable to get id\n");
+               ret = id;
+               goto err0;
+       }
+
+       device_initialize(&phy->dev);
+       mutex_init(&phy->mutex);
+
+       phy->dev.class = phy_class;
+       phy->dev.parent = dev;
+       phy->dev.of_node = dev->of_node;
+       phy->id = id;
+       phy->ops = ops;
+       phy->init_data = init_data;
+
+       ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id);
+       if (ret)
+               goto err1;
+
+       ret = device_add(&phy->dev);
+       if (ret)
+               goto err1;
+
+       if (pm_runtime_enabled(dev)) {
+               pm_runtime_enable(&phy->dev);
+               pm_runtime_no_callbacks(&phy->dev);
+       }
+
+       return phy;
+
+err1:
+       ida_remove(&phy_ida, phy->id);
+       put_device(&phy->dev);
+       kfree(phy);
+
+err0:
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(phy_create);
+
+/**
+ * devm_phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @ops: function pointers for performing phy operations
+ * @init_data: contains the list of PHY consumers or NULL
+ *
+ * Creates a new PHY device adding it to the PHY class.
+ * While at that, it also associates the device with the phy using devres.
+ * On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
+ */
+struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
+       struct phy_init_data *init_data)
+{
+       struct phy **ptr, *phy;
+
+       ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       phy = phy_create(dev, ops, init_data);
+       if (!IS_ERR(phy)) {
+               *ptr = phy;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return phy;
+}
+EXPORT_SYMBOL_GPL(devm_phy_create);
+
+/**
+ * phy_destroy() - destroy the phy
+ * @phy: the phy to be destroyed
+ *
+ * Called to destroy the phy.
+ */
+void phy_destroy(struct phy *phy)
+{
+       pm_runtime_disable(&phy->dev);
+       device_unregister(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_destroy);
+
+/**
+ * devm_phy_destroy() - destroy the PHY
+ * @dev: device that wants to release this phy
+ * @phy: the phy returned by devm_phy_get()
+ *
+ * destroys the devres associated with this phy and invokes phy_destroy
+ * to destroy the phy.
+ */
+void devm_phy_destroy(struct device *dev, struct phy *phy)
+{
+       int r;
+
+       r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy);
+       dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+}
+EXPORT_SYMBOL_GPL(devm_phy_destroy);
+
+/**
+ * __of_phy_provider_register() - create/register phy provider with the framework
+ * @dev: struct device of the phy provider
+ * @owner: the module owner containing of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy provider
+ *
+ * Creates struct phy_provider from dev and of_xlate function pointer.
+ * This is used in the case of dt boot for finding the phy instance from
+ * phy provider.
+ */
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+       struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+       struct of_phandle_args *args))
+{
+       struct phy_provider *phy_provider;
+
+       phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
+       if (!phy_provider)
+               return ERR_PTR(-ENOMEM);
+
+       phy_provider->dev = dev;
+       phy_provider->owner = owner;
+       phy_provider->of_xlate = of_xlate;
+
+       mutex_lock(&phy_provider_mutex);
+       list_add_tail(&phy_provider->list, &phy_provider_list);
+       mutex_unlock(&phy_provider_mutex);
+
+       return phy_provider;
+}
+EXPORT_SYMBOL_GPL(__of_phy_provider_register);
+
+/**
+ * __devm_of_phy_provider_register() - create/register phy provider with the
+ * framework
+ * @dev: struct device of the phy provider
+ * @owner: the module owner containing of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy provider
+ *
+ * Creates struct phy_provider from dev and of_xlate function pointer.
+ * This is used in the case of dt boot for finding the phy instance from
+ * phy provider. While at that, it also associates the device with the
+ * phy provider using devres. On driver detach, release function is invoked
+ * on the devres data, then, devres data is freed.
+ */
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+       struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+       struct of_phandle_args *args))
+{
+       struct phy_provider **ptr, *phy_provider;
+
+       ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
+       if (!IS_ERR(phy_provider)) {
+               *ptr = phy_provider;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return phy_provider;
+}
+EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register);
+
+/**
+ * of_phy_provider_unregister() - unregister phy provider from the framework
+ * @phy_provider: phy provider returned by of_phy_provider_register()
+ *
+ * Removes the phy_provider created using of_phy_provider_register().
+ */
+void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+       if (IS_ERR(phy_provider))
+               return;
+
+       mutex_lock(&phy_provider_mutex);
+       list_del(&phy_provider->list);
+       kfree(phy_provider);
+       mutex_unlock(&phy_provider_mutex);
+}
+EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
+
+/**
+ * devm_of_phy_provider_unregister() - remove phy provider from the framework
+ * @dev: struct device of the phy provider
+ *
+ * destroys the devres associated with this phy provider and invokes
+ * of_phy_provider_unregister to unregister the phy provider.
+ */
+void devm_of_phy_provider_unregister(struct device *dev,
+       struct phy_provider *phy_provider) {
+       int r;
+
+       r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
+               phy_provider);
+       dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
+}
+EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
+
+/**
+ * phy_release() - release the phy
+ * @dev: the dev member within phy
+ *
+ * When the last reference to the device is removed, it is called
+ * from the embedded kobject as release method.
+ */
+static void phy_release(struct device *dev)
+{
+       struct phy *phy;
+
+       phy = to_phy(dev);
+       dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
+       ida_remove(&phy_ida, phy->id);
+       kfree(phy);
+}
+
+static int __init phy_core_init(void)
+{
+       phy_class = class_create(THIS_MODULE, "phy");
+       if (IS_ERR(phy_class)) {
+               pr_err("failed to create phy class --> %ld\n",
+                       PTR_ERR(phy_class));
+               return PTR_ERR(phy_class);
+       }
+
+       phy_class->dev_release = phy_release;
+
+       return 0;
+}
+module_init(phy_core_init);
+
+static void __exit phy_core_exit(void)
+{
+       class_destroy(phy_class);
+}
+module_exit(phy_core_exit);
+
+MODULE_DESCRIPTION("Generic PHY Framework");
+MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c
new file mode 100644 (file)
index 0000000..1dbe6ce
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Samsung EXYNOS SoC series Display Port PHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.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.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* DPTX_PHY_CONTROL register */
+#define EXYNOS_DPTX_PHY_ENABLE         (1 << 0)
+
+struct exynos_dp_video_phy {
+       void __iomem *regs;
+};
+
+static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on)
+{
+       u32 reg;
+
+       reg = readl(state->regs);
+       if (on)
+               reg |= EXYNOS_DPTX_PHY_ENABLE;
+       else
+               reg &= ~EXYNOS_DPTX_PHY_ENABLE;
+       writel(reg, state->regs);
+
+       return 0;
+}
+
+static int exynos_dp_video_phy_power_on(struct phy *phy)
+{
+       struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
+
+       return __set_phy_state(state, 1);
+}
+
+static int exynos_dp_video_phy_power_off(struct phy *phy)
+{
+       struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
+
+       return __set_phy_state(state, 0);
+}
+
+static struct phy_ops exynos_dp_video_phy_ops = {
+       .power_on       = exynos_dp_video_phy_power_on,
+       .power_off      = exynos_dp_video_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static int exynos_dp_video_phy_probe(struct platform_device *pdev)
+{
+       struct exynos_dp_video_phy *state;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct phy_provider *phy_provider;
+       struct phy *phy;
+
+       state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       state->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(state->regs))
+               return PTR_ERR(state->regs);
+
+       phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
+       phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL);
+       if (IS_ERR(phy)) {
+               dev_err(dev, "failed to create Display Port PHY\n");
+               return PTR_ERR(phy);
+       }
+       phy_set_drvdata(phy, state);
+
+       return 0;
+}
+
+static const struct of_device_id exynos_dp_video_phy_of_match[] = {
+       { .compatible = "samsung,exynos5250-dp-video-phy" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match);
+
+static struct platform_driver exynos_dp_video_phy_driver = {
+       .probe  = exynos_dp_video_phy_probe,
+       .driver = {
+               .name   = "exynos-dp-video-phy",
+               .owner  = THIS_MODULE,
+               .of_match_table = exynos_dp_video_phy_of_match,
+       }
+};
+module_platform_driver(exynos_dp_video_phy_driver);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("Samsung EXYNOS SoC DP PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
new file mode 100644 (file)
index 0000000..0c5efab
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
+#define EXYNOS_MIPI_PHY_CONTROL(n)     ((n) * 4)
+#define EXYNOS_MIPI_PHY_ENABLE         (1 << 0)
+#define EXYNOS_MIPI_PHY_SRESETN                (1 << 1)
+#define EXYNOS_MIPI_PHY_MRESETN                (1 << 2)
+#define EXYNOS_MIPI_PHY_RESET_MASK     (3 << 1)
+
+enum exynos_mipi_phy_id {
+       EXYNOS_MIPI_PHY_ID_CSIS0,
+       EXYNOS_MIPI_PHY_ID_DSIM0,
+       EXYNOS_MIPI_PHY_ID_CSIS1,
+       EXYNOS_MIPI_PHY_ID_DSIM1,
+       EXYNOS_MIPI_PHYS_NUM
+};
+
+#define is_mipi_dsim_phy_id(id) \
+       ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1)
+
+struct exynos_mipi_video_phy {
+       spinlock_t slock;
+       struct video_phy_desc {
+               struct phy *phy;
+               unsigned int index;
+       } phys[EXYNOS_MIPI_PHYS_NUM];
+       void __iomem *regs;
+};
+
+static int __set_phy_state(struct exynos_mipi_video_phy *state,
+                       enum exynos_mipi_phy_id id, unsigned int on)
+{
+       void __iomem *addr;
+       u32 reg, reset;
+
+       addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
+
+       if (is_mipi_dsim_phy_id(id))
+               reset = EXYNOS_MIPI_PHY_MRESETN;
+       else
+               reset = EXYNOS_MIPI_PHY_SRESETN;
+
+       spin_lock(&state->slock);
+       reg = readl(addr);
+       if (on)
+               reg |= reset;
+       else
+               reg &= ~reset;
+       writel(reg, addr);
+
+       /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */
+       if (on)
+               reg |= EXYNOS_MIPI_PHY_ENABLE;
+       else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
+               reg &= ~EXYNOS_MIPI_PHY_ENABLE;
+
+       writel(reg, addr);
+       spin_unlock(&state->slock);
+       return 0;
+}
+
+#define to_mipi_video_phy(desc) \
+       container_of((desc), struct exynos_mipi_video_phy, phys[(desc)->index]);
+
+static int exynos_mipi_video_phy_power_on(struct phy *phy)
+{
+       struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
+       struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
+
+       return __set_phy_state(state, phy_desc->index, 1);
+}
+
+static int exynos_mipi_video_phy_power_off(struct phy *phy)
+{
+       struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
+       struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
+
+       return __set_phy_state(state, phy_desc->index, 0);
+}
+
+static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
+                                       struct of_phandle_args *args)
+{
+       struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
+
+       if (WARN_ON(args->args[0] > EXYNOS_MIPI_PHYS_NUM))
+               return ERR_PTR(-ENODEV);
+
+       return state->phys[args->args[0]].phy;
+}
+
+static struct phy_ops exynos_mipi_video_phy_ops = {
+       .power_on       = exynos_mipi_video_phy_power_on,
+       .power_off      = exynos_mipi_video_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
+{
+       struct exynos_mipi_video_phy *state;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct phy_provider *phy_provider;
+       unsigned int i;
+
+       state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       state->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(state->regs))
+               return PTR_ERR(state->regs);
+
+       dev_set_drvdata(dev, state);
+       spin_lock_init(&state->slock);
+
+       phy_provider = devm_of_phy_provider_register(dev,
+                                       exynos_mipi_video_phy_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
+       for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
+               struct phy *phy = devm_phy_create(dev,
+                                       &exynos_mipi_video_phy_ops, NULL);
+               if (IS_ERR(phy)) {
+                       dev_err(dev, "failed to create PHY %d\n", i);
+                       return PTR_ERR(phy);
+               }
+
+               state->phys[i].phy = phy;
+               state->phys[i].index = i;
+               phy_set_drvdata(phy, &state->phys[i]);
+       }
+
+       return 0;
+}
+
+static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
+       { .compatible = "samsung,s5pv210-mipi-video-phy" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
+
+static struct platform_driver exynos_mipi_video_phy_driver = {
+       .probe  = exynos_mipi_video_phy_probe,
+       .driver = {
+               .of_match_table = exynos_mipi_video_phy_of_match,
+               .name  = "exynos-mipi-video-phy",
+               .owner = THIS_MODULE,
+       }
+};
+module_platform_driver(exynos_mipi_video_phy_driver);
+
+MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
new file mode 100644 (file)
index 0000000..bfc5c33
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * omap-usb2.c - USB PHY, talking to musb controller in OMAP.
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/usb/omap_usb.h>
+#include <linux/usb/phy_companion.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
+#include <linux/usb/omap_control_usb.h>
+#include <linux/phy/phy.h>
+#include <linux/of_platform.h>
+
+/**
+ * omap_usb2_set_comparator - links the comparator present in the sytem with
+ *     this phy
+ * @comparator - the companion phy(comparator) for this phy
+ *
+ * The phy companion driver should call this API passing the phy_companion
+ * filled with set_vbus and start_srp to be used by usb phy.
+ *
+ * For use by phy companion driver
+ */
+int omap_usb2_set_comparator(struct phy_companion *comparator)
+{
+       struct omap_usb *phy;
+       struct usb_phy  *x = usb_get_phy(USB_PHY_TYPE_USB2);
+
+       if (IS_ERR(x))
+               return -ENODEV;
+
+       phy = phy_to_omapusb(x);
+       phy->comparator = comparator;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
+
+static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
+{
+       struct omap_usb *phy = phy_to_omapusb(otg->phy);
+
+       if (!phy->comparator)
+               return -ENODEV;
+
+       return phy->comparator->set_vbus(phy->comparator, enabled);
+}
+
+static int omap_usb_start_srp(struct usb_otg *otg)
+{
+       struct omap_usb *phy = phy_to_omapusb(otg->phy);
+
+       if (!phy->comparator)
+               return -ENODEV;
+
+       return phy->comparator->start_srp(phy->comparator);
+}
+
+static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+       struct usb_phy  *phy = otg->phy;
+
+       otg->host = host;
+       if (!host)
+               phy->state = OTG_STATE_UNDEFINED;
+
+       return 0;
+}
+
+static int omap_usb_set_peripheral(struct usb_otg *otg,
+               struct usb_gadget *gadget)
+{
+       struct usb_phy  *phy = otg->phy;
+
+       otg->gadget = gadget;
+       if (!gadget)
+               phy->state = OTG_STATE_UNDEFINED;
+
+       return 0;
+}
+
+static int omap_usb2_suspend(struct usb_phy *x, int suspend)
+{
+       struct omap_usb *phy = phy_to_omapusb(x);
+       int ret;
+
+       if (suspend && !phy->is_suspended) {
+               omap_control_usb_phy_power(phy->control_dev, 0);
+               pm_runtime_put_sync(phy->dev);
+               phy->is_suspended = 1;
+       } else if (!suspend && phy->is_suspended) {
+               ret = pm_runtime_get_sync(phy->dev);
+               if (ret < 0) {
+                       dev_err(phy->dev, "get_sync failed with err %d\n", ret);
+                       return ret;
+               }
+               omap_control_usb_phy_power(phy->control_dev, 1);
+               phy->is_suspended = 0;
+       }
+
+       return 0;
+}
+
+static int omap_usb_power_off(struct phy *x)
+{
+       struct omap_usb *phy = phy_get_drvdata(x);
+
+       omap_control_usb_phy_power(phy->control_dev, 0);
+
+       return 0;
+}
+
+static int omap_usb_power_on(struct phy *x)
+{
+       struct omap_usb *phy = phy_get_drvdata(x);
+
+       omap_control_usb_phy_power(phy->control_dev, 1);
+
+       return 0;
+}
+
+static struct phy_ops ops = {
+       .power_on       = omap_usb_power_on,
+       .power_off      = omap_usb_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static int omap_usb2_probe(struct platform_device *pdev)
+{
+       struct omap_usb *phy;
+       struct phy *generic_phy;
+       struct phy_provider *phy_provider;
+       struct usb_otg *otg;
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *control_node;
+       struct platform_device *control_pdev;
+
+       if (!node)
+               return -EINVAL;
+
+       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy) {
+               dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
+               return -ENOMEM;
+       }
+
+       otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
+       if (!otg) {
+               dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
+               return -ENOMEM;
+       }
+
+       phy->dev                = &pdev->dev;
+
+       phy->phy.dev            = phy->dev;
+       phy->phy.label          = "omap-usb2";
+       phy->phy.set_suspend    = omap_usb2_suspend;
+       phy->phy.otg            = otg;
+       phy->phy.type           = USB_PHY_TYPE_USB2;
+
+       phy_provider = devm_of_phy_provider_register(phy->dev,
+                       of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
+       control_node = of_parse_phandle(node, "ctrl-module", 0);
+       if (!control_node) {
+               dev_err(&pdev->dev, "Failed to get control device phandle\n");
+               return -EINVAL;
+       }
+
+       control_pdev = of_find_device_by_node(control_node);
+       if (!control_pdev) {
+               dev_err(&pdev->dev, "Failed to get control device\n");
+               return -EINVAL;
+       }
+
+       phy->control_dev = &control_pdev->dev;
+
+       phy->is_suspended       = 1;
+       omap_control_usb_phy_power(phy->control_dev, 0);
+
+       otg->set_host           = omap_usb_set_host;
+       otg->set_peripheral     = omap_usb_set_peripheral;
+       otg->set_vbus           = omap_usb_set_vbus;
+       otg->start_srp          = omap_usb_start_srp;
+       otg->phy                = &phy->phy;
+
+       platform_set_drvdata(pdev, phy);
+       pm_runtime_enable(phy->dev);
+
+       generic_phy = devm_phy_create(phy->dev, &ops, NULL);
+       if (IS_ERR(generic_phy))
+               return PTR_ERR(generic_phy);
+
+       phy_set_drvdata(generic_phy, phy);
+
+       phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
+       if (IS_ERR(phy->wkupclk)) {
+               dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
+               return PTR_ERR(phy->wkupclk);
+       }
+       clk_prepare(phy->wkupclk);
+
+       phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m");
+       if (IS_ERR(phy->optclk))
+               dev_vdbg(&pdev->dev, "unable to get refclk960m\n");
+       else
+               clk_prepare(phy->optclk);
+
+       usb_add_phy_dev(&phy->phy);
+
+       return 0;
+}
+
+static int omap_usb2_remove(struct platform_device *pdev)
+{
+       struct omap_usb *phy = platform_get_drvdata(pdev);
+
+       clk_unprepare(phy->wkupclk);
+       if (!IS_ERR(phy->optclk))
+               clk_unprepare(phy->optclk);
+       usb_remove_phy(&phy->phy);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int omap_usb2_runtime_suspend(struct device *dev)
+{
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct omap_usb *phy = platform_get_drvdata(pdev);
+
+       clk_disable(phy->wkupclk);
+       if (!IS_ERR(phy->optclk))
+               clk_disable(phy->optclk);
+
+       return 0;
+}
+
+static int omap_usb2_runtime_resume(struct device *dev)
+{
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct omap_usb *phy = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = clk_enable(phy->wkupclk);
+       if (ret < 0) {
+               dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
+               goto err0;
+       }
+
+       if (!IS_ERR(phy->optclk)) {
+               ret = clk_enable(phy->optclk);
+               if (ret < 0) {
+                       dev_err(phy->dev, "Failed to enable optclk %d\n", ret);
+                       goto err1;
+               }
+       }
+
+       return 0;
+
+err1:
+       clk_disable(phy->wkupclk);
+
+err0:
+       return ret;
+}
+
+static const struct dev_pm_ops omap_usb2_pm_ops = {
+       SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume,
+               NULL)
+};
+
+#define DEV_PM_OPS     (&omap_usb2_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id omap_usb2_id_table[] = {
+       { .compatible = "ti,omap-usb2" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
+#endif
+
+static struct platform_driver omap_usb2_driver = {
+       .probe          = omap_usb2_probe,
+       .remove         = omap_usb2_remove,
+       .driver         = {
+               .name   = "omap-usb2",
+               .owner  = THIS_MODULE,
+               .pm     = DEV_PM_OPS,
+               .of_match_table = of_match_ptr(omap_usb2_id_table),
+       },
+};
+
+module_platform_driver(omap_usb2_driver);
+
+MODULE_ALIAS("platform: omap_usb2");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("OMAP USB2 phy driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
new file mode 100644 (file)
index 0000000..daf65e6
--- /dev/null
@@ -0,0 +1,815 @@
+/*
+ * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller
+ *
+ * Copyright (C) 2004-2007 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Current status:
+ *     - HS USB ULPI mode works.
+ *     - 3-pin mode support may be added in future.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/usb/otg.h>
+#include <linux/phy/phy.h>
+#include <linux/usb/musb-omap.h>
+#include <linux/usb/ulpi.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+/* Register defines */
+
+#define MCPC_CTRL                      0x30
+#define MCPC_CTRL_RTSOL                        (1 << 7)
+#define MCPC_CTRL_EXTSWR               (1 << 6)
+#define MCPC_CTRL_EXTSWC               (1 << 5)
+#define MCPC_CTRL_VOICESW              (1 << 4)
+#define MCPC_CTRL_OUT64K               (1 << 3)
+#define MCPC_CTRL_RTSCTSSW             (1 << 2)
+#define MCPC_CTRL_HS_UART              (1 << 0)
+
+#define MCPC_IO_CTRL                   0x33
+#define MCPC_IO_CTRL_MICBIASEN         (1 << 5)
+#define MCPC_IO_CTRL_CTS_NPU           (1 << 4)
+#define MCPC_IO_CTRL_RXD_PU            (1 << 3)
+#define MCPC_IO_CTRL_TXDTYP            (1 << 2)
+#define MCPC_IO_CTRL_CTSTYP            (1 << 1)
+#define MCPC_IO_CTRL_RTSTYP            (1 << 0)
+
+#define MCPC_CTRL2                     0x36
+#define MCPC_CTRL2_MCPC_CK_EN          (1 << 0)
+
+#define OTHER_FUNC_CTRL                        0x80
+#define OTHER_FUNC_CTRL_BDIS_ACON_EN   (1 << 4)
+#define OTHER_FUNC_CTRL_FIVEWIRE_MODE  (1 << 2)
+
+#define OTHER_IFC_CTRL                 0x83
+#define OTHER_IFC_CTRL_OE_INT_EN       (1 << 6)
+#define OTHER_IFC_CTRL_CEA2011_MODE    (1 << 5)
+#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN     (1 << 4)
+#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT      (1 << 3)
+#define OTHER_IFC_CTRL_HIZ_ULPI                (1 << 2)
+#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0)
+
+#define OTHER_INT_EN_RISE              0x86
+#define OTHER_INT_EN_FALL              0x89
+#define OTHER_INT_STS                  0x8C
+#define OTHER_INT_LATCH                        0x8D
+#define OTHER_INT_VB_SESS_VLD          (1 << 7)
+#define OTHER_INT_DM_HI                        (1 << 6) /* not valid for "latch" reg */
+#define OTHER_INT_DP_HI                        (1 << 5) /* not valid for "latch" reg */
+#define OTHER_INT_BDIS_ACON            (1 << 3) /* not valid for "fall" regs */
+#define OTHER_INT_MANU                 (1 << 1)
+#define OTHER_INT_ABNORMAL_STRESS      (1 << 0)
+
+#define ID_STATUS                      0x96
+#define ID_RES_FLOAT                   (1 << 4)
+#define ID_RES_440K                    (1 << 3)
+#define ID_RES_200K                    (1 << 2)
+#define ID_RES_102K                    (1 << 1)
+#define ID_RES_GND                     (1 << 0)
+
+#define POWER_CTRL                     0xAC
+#define POWER_CTRL_OTG_ENAB            (1 << 5)
+
+#define OTHER_IFC_CTRL2                        0xAF
+#define OTHER_IFC_CTRL2_ULPI_STP_LOW   (1 << 4)
+#define OTHER_IFC_CTRL2_ULPI_TXEN_POL  (1 << 3)
+#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2)
+#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK    (3 << 0) /* bits 0 and 1 */
+#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N   (0 << 0)
+#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N   (1 << 0)
+
+#define REG_CTRL_EN                    0xB2
+#define REG_CTRL_ERROR                 0xB5
+#define ULPI_I2C_CONFLICT_INTEN                (1 << 0)
+
+#define OTHER_FUNC_CTRL2               0xB8
+#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0)
+
+/* following registers do not have separate _clr and _set registers */
+#define VBUS_DEBOUNCE                  0xC0
+#define ID_DEBOUNCE                    0xC1
+#define VBAT_TIMER                     0xD3
+#define PHY_PWR_CTRL                   0xFD
+#define PHY_PWR_PHYPWD                 (1 << 0)
+#define PHY_CLK_CTRL                   0xFE
+#define PHY_CLK_CTRL_CLOCKGATING_EN    (1 << 2)
+#define PHY_CLK_CTRL_CLK32K_EN         (1 << 1)
+#define REQ_PHY_DPLL_CLK               (1 << 0)
+#define PHY_CLK_CTRL_STS               0xFF
+#define PHY_DPLL_CLK                   (1 << 0)
+
+/* In module TWL_MODULE_PM_MASTER */
+#define STS_HW_CONDITIONS              0x0F
+
+/* In module TWL_MODULE_PM_RECEIVER */
+#define VUSB_DEDICATED1                        0x7D
+#define VUSB_DEDICATED2                        0x7E
+#define VUSB1V5_DEV_GRP                        0x71
+#define VUSB1V5_TYPE                   0x72
+#define VUSB1V5_REMAP                  0x73
+#define VUSB1V8_DEV_GRP                        0x74
+#define VUSB1V8_TYPE                   0x75
+#define VUSB1V8_REMAP                  0x76
+#define VUSB3V1_DEV_GRP                        0x77
+#define VUSB3V1_TYPE                   0x78
+#define VUSB3V1_REMAP                  0x79
+
+/* In module TWL4030_MODULE_INTBR */
+#define PMBR1                          0x0D
+#define GPIO_USB_4PIN_ULPI_2430C       (3 << 0)
+
+struct twl4030_usb {
+       struct usb_phy          phy;
+       struct device           *dev;
+
+       /* TWL4030 internal USB regulator supplies */
+       struct regulator        *usb1v5;
+       struct regulator        *usb1v8;
+       struct regulator        *usb3v1;
+
+       /* for vbus reporting with irqs disabled */
+       spinlock_t              lock;
+
+       /* pin configuration */
+       enum twl4030_usb_mode   usb_mode;
+
+       int                     irq;
+       enum omap_musb_vbus_id_status linkstat;
+       bool                    vbus_supplied;
+       u8                      asleep;
+       bool                    irq_enabled;
+
+       struct delayed_work     id_workaround_work;
+};
+
+/* internal define on top of container_of */
+#define phy_to_twl(x)          container_of((x), struct twl4030_usb, phy)
+
+/*-------------------------------------------------------------------------*/
+
+static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl,
+               u8 module, u8 data, u8 address)
+{
+       u8 check;
+
+       if ((twl_i2c_write_u8(module, data, address) >= 0) &&
+           (twl_i2c_read_u8(module, &check, address) >= 0) &&
+                                               (check == data))
+               return 0;
+       dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n",
+                       1, module, address, check, data);
+
+       /* Failed once: Try again */
+       if ((twl_i2c_write_u8(module, data, address) >= 0) &&
+           (twl_i2c_read_u8(module, &check, address) >= 0) &&
+                                               (check == data))
+               return 0;
+       dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n",
+                       2, module, address, check, data);
+
+       /* Failed again: Return error */
+       return -EBUSY;
+}
+
+#define twl4030_usb_write_verify(twl, address, data)   \
+       twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address))
+
+static inline int twl4030_usb_write(struct twl4030_usb *twl,
+               u8 address, u8 data)
+{
+       int ret = 0;
+
+       ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address);
+       if (ret < 0)
+               dev_dbg(twl->dev,
+                       "TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
+       return ret;
+}
+
+static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address)
+{
+       u8 data;
+       int ret = 0;
+
+       ret = twl_i2c_read_u8(module, &data, address);
+       if (ret >= 0)
+               ret = data;
+       else
+               dev_dbg(twl->dev,
+                       "TWL4030:readb[0x%x,0x%x] Error %d\n",
+                                       module, address, ret);
+
+       return ret;
+}
+
+static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address)
+{
+       return twl4030_readb(twl, TWL_MODULE_USB, address);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static inline int
+twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
+{
+       return twl4030_usb_write(twl, ULPI_SET(reg), bits);
+}
+
+static inline int
+twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
+{
+       return twl4030_usb_write(twl, ULPI_CLR(reg), bits);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static bool twl4030_is_driving_vbus(struct twl4030_usb *twl)
+{
+       int ret;
+
+       ret = twl4030_usb_read(twl, PHY_CLK_CTRL_STS);
+       if (ret < 0 || !(ret & PHY_DPLL_CLK))
+               /*
+                * if clocks are off, registers are not updated,
+                * but we can assume we don't drive VBUS in this case
+                */
+               return false;
+
+       ret = twl4030_usb_read(twl, ULPI_OTG_CTRL);
+       if (ret < 0)
+               return false;
+
+       return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false;
+}
+
+static enum omap_musb_vbus_id_status
+       twl4030_usb_linkstat(struct twl4030_usb *twl)
+{
+       int     status;
+       enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN;
+
+       twl->vbus_supplied = false;
+
+       /*
+        * For ID/VBUS sensing, see manual section 15.4.8 ...
+        * except when using only battery backup power, two
+        * comparators produce VBUS_PRES and ID_PRES signals,
+        * which don't match docs elsewhere.  But ... BIT(7)
+        * and BIT(2) of STS_HW_CONDITIONS, respectively, do
+        * seem to match up.  If either is true the USB_PRES
+        * signal is active, the OTG module is activated, and
+        * its interrupt may be raised (may wake the system).
+        */
+       status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS);
+       if (status < 0)
+               dev_err(twl->dev, "USB link status err %d\n", status);
+       else if (status & (BIT(7) | BIT(2))) {
+               if (status & BIT(7)) {
+                       if (twl4030_is_driving_vbus(twl))
+                               status &= ~BIT(7);
+                       else
+                               twl->vbus_supplied = true;
+               }
+
+               if (status & BIT(2))
+                       linkstat = OMAP_MUSB_ID_GROUND;
+               else if (status & BIT(7))
+                       linkstat = OMAP_MUSB_VBUS_VALID;
+               else
+                       linkstat = OMAP_MUSB_VBUS_OFF;
+       } else {
+               if (twl->linkstat != OMAP_MUSB_UNKNOWN)
+                       linkstat = OMAP_MUSB_VBUS_OFF;
+       }
+
+       dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
+                       status, status, linkstat);
+
+       /* REVISIT this assumes host and peripheral controllers
+        * are registered, and that both are active...
+        */
+
+       return linkstat;
+}
+
+static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode)
+{
+       twl->usb_mode = mode;
+
+       switch (mode) {
+       case T2_USB_MODE_ULPI:
+               twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL,
+                                       ULPI_IFC_CTRL_CARKITMODE);
+               twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
+               twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL,
+                                       ULPI_FUNC_CTRL_XCVRSEL_MASK |
+                                       ULPI_FUNC_CTRL_OPMODE_MASK);
+               break;
+       case -1:
+               /* FIXME: power on defaults */
+               break;
+       default:
+               dev_err(twl->dev, "unsupported T2 transceiver mode %d\n",
+                               mode);
+               break;
+       };
+}
+
+static void twl4030_i2c_access(struct twl4030_usb *twl, int on)
+{
+       unsigned long timeout;
+       int val = twl4030_usb_read(twl, PHY_CLK_CTRL);
+
+       if (val >= 0) {
+               if (on) {
+                       /* enable DPLL to access PHY registers over I2C */
+                       val |= REQ_PHY_DPLL_CLK;
+                       WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL,
+                                               (u8)val) < 0);
+
+                       timeout = jiffies + HZ;
+                       while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) &
+                                                       PHY_DPLL_CLK)
+                               && time_before(jiffies, timeout))
+                                       udelay(10);
+                       if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) &
+                                                       PHY_DPLL_CLK))
+                               dev_err(twl->dev, "Timeout setting T2 HSUSB "
+                                               "PHY DPLL clock\n");
+               } else {
+                       /* let ULPI control the DPLL clock */
+                       val &= ~REQ_PHY_DPLL_CLK;
+                       WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL,
+                                               (u8)val) < 0);
+               }
+       }
+}
+
+static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
+{
+       u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
+
+       if (on)
+               pwr &= ~PHY_PWR_PHYPWD;
+       else
+               pwr |= PHY_PWR_PHYPWD;
+
+       WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+}
+
+static void twl4030_phy_power(struct twl4030_usb *twl, int on)
+{
+       int ret;
+
+       if (on) {
+               ret = regulator_enable(twl->usb3v1);
+               if (ret)
+                       dev_err(twl->dev, "Failed to enable usb3v1\n");
+
+               ret = regulator_enable(twl->usb1v8);
+               if (ret)
+                       dev_err(twl->dev, "Failed to enable usb1v8\n");
+
+               /*
+                * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
+                * in twl4030) resets the VUSB_DEDICATED2 register. This reset
+                * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
+                * SLEEP. We work around this by clearing the bit after usv3v1
+                * is re-activated. This ensures that VUSB3V1 is really active.
+                */
+               twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
+
+               ret = regulator_enable(twl->usb1v5);
+               if (ret)
+                       dev_err(twl->dev, "Failed to enable usb1v5\n");
+
+               __twl4030_phy_power(twl, 1);
+               twl4030_usb_write(twl, PHY_CLK_CTRL,
+                                 twl4030_usb_read(twl, PHY_CLK_CTRL) |
+                                       (PHY_CLK_CTRL_CLOCKGATING_EN |
+                                               PHY_CLK_CTRL_CLK32K_EN));
+       } else {
+               __twl4030_phy_power(twl, 0);
+               regulator_disable(twl->usb1v5);
+               regulator_disable(twl->usb1v8);
+               regulator_disable(twl->usb3v1);
+       }
+}
+
+static int twl4030_phy_power_off(struct phy *phy)
+{
+       struct twl4030_usb *twl = phy_get_drvdata(phy);
+
+       if (twl->asleep)
+               return 0;
+
+       twl4030_phy_power(twl, 0);
+       twl->asleep = 1;
+       dev_dbg(twl->dev, "%s\n", __func__);
+       return 0;
+}
+
+static void __twl4030_phy_power_on(struct twl4030_usb *twl)
+{
+       twl4030_phy_power(twl, 1);
+       twl4030_i2c_access(twl, 1);
+       twl4030_usb_set_mode(twl, twl->usb_mode);
+       if (twl->usb_mode == T2_USB_MODE_ULPI)
+               twl4030_i2c_access(twl, 0);
+}
+
+static int twl4030_phy_power_on(struct phy *phy)
+{
+       struct twl4030_usb *twl = phy_get_drvdata(phy);
+
+       if (!twl->asleep)
+               return 0;
+       __twl4030_phy_power_on(twl);
+       twl->asleep = 0;
+       dev_dbg(twl->dev, "%s\n", __func__);
+
+       /*
+        * XXX When VBUS gets driven after musb goes to A mode,
+        * ID_PRES related interrupts no longer arrive, why?
+        * Register itself is updated fine though, so we must poll.
+        */
+       if (twl->linkstat == OMAP_MUSB_ID_GROUND) {
+               cancel_delayed_work(&twl->id_workaround_work);
+               schedule_delayed_work(&twl->id_workaround_work, HZ);
+       }
+       return 0;
+}
+
+static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
+{
+       /* Enable writing to power configuration registers */
+       twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
+                        TWL4030_PM_MASTER_PROTECT_KEY);
+
+       twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
+                        TWL4030_PM_MASTER_PROTECT_KEY);
+
+       /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/
+       /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/
+
+       /* input to VUSB3V1 LDO is from VBAT, not VBUS */
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
+
+       /* Initialize 3.1V regulator */
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
+
+       twl->usb3v1 = devm_regulator_get(twl->dev, "usb3v1");
+       if (IS_ERR(twl->usb3v1))
+               return -ENODEV;
+
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
+
+       /* Initialize 1.5V regulator */
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
+
+       twl->usb1v5 = devm_regulator_get(twl->dev, "usb1v5");
+       if (IS_ERR(twl->usb1v5))
+               return -ENODEV;
+
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
+
+       /* Initialize 1.8V regulator */
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
+
+       twl->usb1v8 = devm_regulator_get(twl->dev, "usb1v8");
+       if (IS_ERR(twl->usb1v8))
+               return -ENODEV;
+
+       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
+
+       /* disable access to power configuration registers */
+       twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
+                        TWL4030_PM_MASTER_PROTECT_KEY);
+
+       return 0;
+}
+
+static ssize_t twl4030_usb_vbus_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct twl4030_usb *twl = dev_get_drvdata(dev);
+       unsigned long flags;
+       int ret = -EINVAL;
+
+       spin_lock_irqsave(&twl->lock, flags);
+       ret = sprintf(buf, "%s\n",
+                       twl->vbus_supplied ? "on" : "off");
+       spin_unlock_irqrestore(&twl->lock, flags);
+
+       return ret;
+}
+static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
+
+static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
+{
+       struct twl4030_usb *twl = _twl;
+       enum omap_musb_vbus_id_status status;
+       bool status_changed = false;
+
+       status = twl4030_usb_linkstat(twl);
+
+       spin_lock_irq(&twl->lock);
+       if (status >= 0 && status != twl->linkstat) {
+               twl->linkstat = status;
+               status_changed = true;
+       }
+       spin_unlock_irq(&twl->lock);
+
+       if (status_changed) {
+               /* FIXME add a set_power() method so that B-devices can
+                * configure the charger appropriately.  It's not always
+                * correct to consume VBUS power, and how much current to
+                * consume is a function of the USB configuration chosen
+                * by the host.
+                *
+                * REVISIT usb_gadget_vbus_connect(...) as needed, ditto
+                * its disconnect() sibling, when changing to/from the
+                * USB_LINK_VBUS state.  musb_hdrc won't care until it
+                * starts to handle softconnect right.
+                */
+               omap_musb_mailbox(status);
+       }
+       sysfs_notify(&twl->dev->kobj, NULL, "vbus");
+
+       return IRQ_HANDLED;
+}
+
+static void twl4030_id_workaround_work(struct work_struct *work)
+{
+       struct twl4030_usb *twl = container_of(work, struct twl4030_usb,
+               id_workaround_work.work);
+       enum omap_musb_vbus_id_status status;
+       bool status_changed = false;
+
+       status = twl4030_usb_linkstat(twl);
+
+       spin_lock_irq(&twl->lock);
+       if (status >= 0 && status != twl->linkstat) {
+               twl->linkstat = status;
+               status_changed = true;
+       }
+       spin_unlock_irq(&twl->lock);
+
+       if (status_changed) {
+               dev_dbg(twl->dev, "handle missing status change to %d\n",
+                               status);
+               omap_musb_mailbox(status);
+       }
+
+       /* don't schedule during sleep - irq works right then */
+       if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
+               cancel_delayed_work(&twl->id_workaround_work);
+               schedule_delayed_work(&twl->id_workaround_work, HZ);
+       }
+}
+
+static int twl4030_phy_init(struct phy *phy)
+{
+       struct twl4030_usb *twl = phy_get_drvdata(phy);
+       enum omap_musb_vbus_id_status status;
+
+       /*
+        * Start in sleep state, we'll get called through set_suspend()
+        * callback when musb is runtime resumed and it's time to start.
+        */
+       __twl4030_phy_power(twl, 0);
+       twl->asleep = 1;
+
+       status = twl4030_usb_linkstat(twl);
+       twl->linkstat = status;
+
+       if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) {
+               omap_musb_mailbox(twl->linkstat);
+               twl4030_phy_power_on(phy);
+       }
+
+       sysfs_notify(&twl->dev->kobj, NULL, "vbus");
+       return 0;
+}
+
+static int twl4030_set_peripheral(struct usb_otg *otg,
+                                       struct usb_gadget *gadget)
+{
+       if (!otg)
+               return -ENODEV;
+
+       otg->gadget = gadget;
+       if (!gadget)
+               otg->phy->state = OTG_STATE_UNDEFINED;
+
+       return 0;
+}
+
+static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+       if (!otg)
+               return -ENODEV;
+
+       otg->host = host;
+       if (!host)
+               otg->phy->state = OTG_STATE_UNDEFINED;
+
+       return 0;
+}
+
+static const struct phy_ops ops = {
+       .init           = twl4030_phy_init,
+       .power_on       = twl4030_phy_power_on,
+       .power_off      = twl4030_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static int twl4030_usb_probe(struct platform_device *pdev)
+{
+       struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
+       struct twl4030_usb      *twl;
+       struct phy              *phy;
+       int                     status, err;
+       struct usb_otg          *otg;
+       struct device_node      *np = pdev->dev.of_node;
+       struct phy_provider     *phy_provider;
+       struct phy_init_data    *init_data = NULL;
+
+       twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
+       if (!twl)
+               return -ENOMEM;
+
+       if (np)
+               of_property_read_u32(np, "usb_mode",
+                               (enum twl4030_usb_mode *)&twl->usb_mode);
+       else if (pdata) {
+               twl->usb_mode = pdata->usb_mode;
+               init_data = pdata->init_data;
+       } else {
+               dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
+               return -EINVAL;
+       }
+
+       otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL);
+       if (!otg)
+               return -ENOMEM;
+
+       twl->dev                = &pdev->dev;
+       twl->irq                = platform_get_irq(pdev, 0);
+       twl->vbus_supplied      = false;
+       twl->asleep             = 1;
+       twl->linkstat           = OMAP_MUSB_UNKNOWN;
+
+       twl->phy.dev            = twl->dev;
+       twl->phy.label          = "twl4030";
+       twl->phy.otg            = otg;
+       twl->phy.type           = USB_PHY_TYPE_USB2;
+
+       otg->phy                = &twl->phy;
+       otg->set_host           = twl4030_set_host;
+       otg->set_peripheral     = twl4030_set_peripheral;
+
+       phy_provider = devm_of_phy_provider_register(twl->dev,
+               of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
+       phy = devm_phy_create(twl->dev, &ops, init_data);
+       if (IS_ERR(phy)) {
+               dev_dbg(&pdev->dev, "Failed to create PHY\n");
+               return PTR_ERR(phy);
+       }
+
+       phy_set_drvdata(phy, twl);
+
+       /* init spinlock for workqueue */
+       spin_lock_init(&twl->lock);
+
+       INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work);
+
+       err = twl4030_usb_ldo_init(twl);
+       if (err) {
+               dev_err(&pdev->dev, "ldo init failed\n");
+               return err;
+       }
+       usb_add_phy_dev(&twl->phy);
+
+       platform_set_drvdata(pdev, twl);
+       if (device_create_file(&pdev->dev, &dev_attr_vbus))
+               dev_warn(&pdev->dev, "could not create sysfs file\n");
+
+       ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
+
+       /* Our job is to use irqs and status from the power module
+        * to keep the transceiver disabled when nothing's connected.
+        *
+        * FIXME we actually shouldn't start enabling it until the
+        * USB controller drivers have said they're ready, by calling
+        * set_host() and/or set_peripheral() ... OTG_capable boards
+        * need both handles, otherwise just one suffices.
+        */
+       twl->irq_enabled = true;
+       status = devm_request_threaded_irq(twl->dev, twl->irq, NULL,
+                       twl4030_usb_irq, IRQF_TRIGGER_FALLING |
+                       IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl);
+       if (status < 0) {
+               dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
+                       twl->irq, status);
+               return status;
+       }
+
+       dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
+       return 0;
+}
+
+static int twl4030_usb_remove(struct platform_device *pdev)
+{
+       struct twl4030_usb *twl = platform_get_drvdata(pdev);
+       int val;
+
+       cancel_delayed_work(&twl->id_workaround_work);
+       device_remove_file(twl->dev, &dev_attr_vbus);
+
+       /* set transceiver mode to power on defaults */
+       twl4030_usb_set_mode(twl, -1);
+
+       /* autogate 60MHz ULPI clock,
+        * clear dpll clock request for i2c access,
+        * disable 32KHz
+        */
+       val = twl4030_usb_read(twl, PHY_CLK_CTRL);
+       if (val >= 0) {
+               val |= PHY_CLK_CTRL_CLOCKGATING_EN;
+               val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK);
+               twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val);
+       }
+
+       /* disable complete OTG block */
+       twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
+
+       if (!twl->asleep)
+               twl4030_phy_power(twl, 0);
+
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id twl4030_usb_id_table[] = {
+       { .compatible = "ti,twl4030-usb" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, twl4030_usb_id_table);
+#endif
+
+static struct platform_driver twl4030_usb_driver = {
+       .probe          = twl4030_usb_probe,
+       .remove         = twl4030_usb_remove,
+       .driver         = {
+               .name   = "twl4030_usb",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(twl4030_usb_id_table),
+       },
+};
+
+static int __init twl4030_usb_init(void)
+{
+       return platform_driver_register(&twl4030_usb_driver);
+}
+subsys_initcall(twl4030_usb_init);
+
+static void __exit twl4030_usb_exit(void)
+{
+       platform_driver_unregister(&twl4030_usb_driver);
+}
+module_exit(twl4030_usb_exit);
+
+MODULE_ALIAS("platform:twl4030_usb");
+MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation");
+MODULE_DESCRIPTION("TWL4030 USB transceiver driver");
+MODULE_LICENSE("GPL");
index a82ace4d9a20975ee7ddc44fd7632191316c3eb9..0846922b2316d0774e4f154aee45256c6019a41a 100644 (file)
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/list.h>
+#include <linux/interrupt.h>
+
+#include <linux/irqchip/chained_irq.h>
 
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/pinconf-generic.h>
 
+#include <linux/platform_data/pinctrl-single.h>
+
 #include "core.h"
 #include "pinconf.h"
 
@@ -149,6 +155,22 @@ struct pcs_name {
        char name[PCS_REG_NAME_LEN];
 };
 
+/**
+ * struct pcs_soc_data - SoC specific settings
+ * @flags:     initial SoC specific PCS_FEAT_xxx values
+ * @irq:       optional interrupt for the controller
+ * @irq_enable_mask:   optional SoC specific interrupt enable mask
+ * @irq_status_mask:   optional SoC specific interrupt status mask
+ * @rearm:     optional SoC specific wake-up rearm function
+ */
+struct pcs_soc_data {
+       unsigned flags;
+       int irq;
+       unsigned irq_enable_mask;
+       unsigned irq_status_mask;
+       void (*rearm)(void);
+};
+
 /**
  * struct pcs_device - pinctrl device instance
  * @res:       resources
@@ -156,13 +178,14 @@ struct pcs_name {
  * @size:      size of the ioremapped area
  * @dev:       device entry
  * @pctl:      pin controller device
+ * @flags:     mask of PCS_FEAT_xxx values
+ * @lock:      spinlock for register access
  * @mutex:     mutex protecting the lists
  * @width:     bits per mux register
  * @fmask:     function register mask
  * @fshift:    function register shift
  * @foff:      value to turn mux off
  * @fmax:      max number of functions in fmask
- * @is_pinconf:        whether supports pinconf
  * @bits_per_pin:number of bits per pin
  * @names:     array of register names for pins
  * @pins:      physical pins on the SoC
@@ -171,6 +194,9 @@ struct pcs_name {
  * @pingroups: list of pingroups
  * @functions: list of functions
  * @gpiofuncs: list of gpio functions
+ * @irqs:      list of interrupt registers
+ * @chip:      chip container for this instance
+ * @domain:    IRQ domain for this instance
  * @ngroups:   number of pingroups
  * @nfuncs:    number of functions
  * @desc:      pin controller descriptor
@@ -183,6 +209,12 @@ struct pcs_device {
        unsigned size;
        struct device *dev;
        struct pinctrl_dev *pctl;
+       unsigned flags;
+#define PCS_QUIRK_SHARED_IRQ   (1 << 2)
+#define PCS_FEAT_IRQ           (1 << 1)
+#define PCS_FEAT_PINCONF       (1 << 0)
+       struct pcs_soc_data socdata;
+       raw_spinlock_t lock;
        struct mutex mutex;
        unsigned width;
        unsigned fmask;
@@ -190,7 +222,6 @@ struct pcs_device {
        unsigned foff;
        unsigned fmax;
        bool bits_per_mux;
-       bool is_pinconf;
        unsigned bits_per_pin;
        struct pcs_name *names;
        struct pcs_data pins;
@@ -199,6 +230,9 @@ struct pcs_device {
        struct list_head pingroups;
        struct list_head functions;
        struct list_head gpiofuncs;
+       struct list_head irqs;
+       struct irq_chip chip;
+       struct irq_domain *domain;
        unsigned ngroups;
        unsigned nfuncs;
        struct pinctrl_desc desc;
@@ -206,6 +240,10 @@ struct pcs_device {
        void (*write)(unsigned val, void __iomem *reg);
 };
 
+#define PCS_QUIRK_HAS_SHARED_IRQ       (pcs->flags & PCS_QUIRK_SHARED_IRQ)
+#define PCS_HAS_IRQ            (pcs->flags & PCS_FEAT_IRQ)
+#define PCS_HAS_PINCONF                (pcs->flags & PCS_FEAT_PINCONF)
+
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
                           unsigned long *config);
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
@@ -429,9 +467,11 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
 
        for (i = 0; i < func->nvals; i++) {
                struct pcs_func_vals *vals;
+               unsigned long flags;
                unsigned val, mask;
 
                vals = &func->vals[i];
+               raw_spin_lock_irqsave(&pcs->lock, flags);
                val = pcs->read(vals->reg);
 
                if (pcs->bits_per_mux)
@@ -442,6 +482,7 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
                val &= ~mask;
                val |= (vals->val & mask);
                pcs->write(val, vals->reg);
+               raw_spin_unlock_irqrestore(&pcs->lock, flags);
        }
 
        return 0;
@@ -483,13 +524,16 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
 
        for (i = 0; i < func->nvals; i++) {
                struct pcs_func_vals *vals;
+               unsigned long flags;
                unsigned val;
 
                vals = &func->vals[i];
+               raw_spin_lock_irqsave(&pcs->lock, flags);
                val = pcs->read(vals->reg);
                val &= ~pcs->fmask;
                val |= pcs->foff << pcs->fshift;
                pcs->write(val, vals->reg);
+               raw_spin_unlock_irqrestore(&pcs->lock, flags);
        }
 }
 
@@ -1060,7 +1104,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
        };
 
        /* If pinconf isn't supported, don't parse properties in below. */
-       if (!pcs->is_pinconf)
+       if (!PCS_HAS_PINCONF)
                return 0;
 
        /* cacluate how much properties are supported in current node */
@@ -1184,7 +1228,7 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
        (*map)->data.mux.group = np->name;
        (*map)->data.mux.function = np->name;
 
-       if (pcs->is_pinconf) {
+       if (PCS_HAS_PINCONF) {
                res = pcs_parse_pinconf(pcs, np, function, map);
                if (res)
                        goto free_pingroups;
@@ -1305,7 +1349,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
        (*map)->data.mux.group = np->name;
        (*map)->data.mux.function = np->name;
 
-       if (pcs->is_pinconf) {
+       if (PCS_HAS_PINCONF) {
                dev_err(pcs->dev, "pinconf not supported\n");
                goto free_pingroups;
        }
@@ -1439,12 +1483,34 @@ static void pcs_free_pingroups(struct pcs_device *pcs)
        mutex_unlock(&pcs->mutex);
 }
 
+/**
+ * pcs_irq_free() - free interrupt
+ * @pcs: pcs driver instance
+ */
+static void pcs_irq_free(struct pcs_device *pcs)
+{
+       struct pcs_soc_data *pcs_soc = &pcs->socdata;
+
+       if (pcs_soc->irq < 0)
+               return;
+
+       if (pcs->domain)
+               irq_domain_remove(pcs->domain);
+
+       if (PCS_QUIRK_HAS_SHARED_IRQ)
+               free_irq(pcs_soc->irq, pcs_soc);
+       else
+               irq_set_chained_handler(pcs_soc->irq, NULL);
+}
+
 /**
  * pcs_free_resources() - free memory used by this driver
  * @pcs: pcs driver instance
  */
 static void pcs_free_resources(struct pcs_device *pcs)
 {
+       pcs_irq_free(pcs);
+
        if (pcs->pctl)
                pinctrl_unregister(pcs->pctl);
 
@@ -1493,6 +1559,268 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
        }
        return ret;
 }
+/**
+ * @reg:       virtual address of interrupt register
+ * @hwirq:     hardware irq number
+ * @irq:       virtual irq number
+ * @node:      list node
+ */
+struct pcs_interrupt {
+       void __iomem *reg;
+       irq_hw_number_t hwirq;
+       unsigned int irq;
+       struct list_head node;
+};
+
+/**
+ * pcs_irq_set() - enables or disables an interrupt
+ *
+ * Note that this currently assumes one interrupt per pinctrl
+ * register that is typically used for wake-up events.
+ */
+static inline void pcs_irq_set(struct pcs_soc_data *pcs_soc,
+                              int irq, const bool enable)
+{
+       struct pcs_device *pcs;
+       struct list_head *pos;
+       unsigned mask;
+
+       pcs = container_of(pcs_soc, struct pcs_device, socdata);
+       list_for_each(pos, &pcs->irqs) {
+               struct pcs_interrupt *pcswi;
+               unsigned soc_mask;
+
+               pcswi = list_entry(pos, struct pcs_interrupt, node);
+               if (irq != pcswi->irq)
+                       continue;
+
+               soc_mask = pcs_soc->irq_enable_mask;
+               raw_spin_lock(&pcs->lock);
+               mask = pcs->read(pcswi->reg);
+               if (enable)
+                       mask |= soc_mask;
+               else
+                       mask &= ~soc_mask;
+               pcs->write(mask, pcswi->reg);
+               raw_spin_unlock(&pcs->lock);
+       }
+}
+
+/**
+ * pcs_irq_mask() - mask pinctrl interrupt
+ * @d: interrupt data
+ */
+static void pcs_irq_mask(struct irq_data *d)
+{
+       struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d);
+
+       pcs_irq_set(pcs_soc, d->irq, false);
+}
+
+/**
+ * pcs_irq_unmask() - unmask pinctrl interrupt
+ * @d: interrupt data
+ */
+static void pcs_irq_unmask(struct irq_data *d)
+{
+       struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d);
+
+       pcs_irq_set(pcs_soc, d->irq, true);
+       if (pcs_soc->rearm)
+               pcs_soc->rearm();
+}
+
+/**
+ * pcs_irq_set_wake() - toggle the suspend and resume wake up
+ * @d: interrupt data
+ * @state: wake-up state
+ *
+ * Note that this should be called only for suspend and resume.
+ * For runtime PM, the wake-up events should be enabled by default.
+ */
+static int pcs_irq_set_wake(struct irq_data *d, unsigned int state)
+{
+       if (state)
+               pcs_irq_unmask(d);
+       else
+               pcs_irq_mask(d);
+
+       return 0;
+}
+
+/**
+ * pcs_irq_handle() - common interrupt handler
+ * @pcs_irq: interrupt data
+ *
+ * Note that this currently assumes we have one interrupt bit per
+ * mux register. This interrupt is typically used for wake-up events.
+ * For more complex interrupts different handlers can be specified.
+ */
+static int pcs_irq_handle(struct pcs_soc_data *pcs_soc)
+{
+       struct pcs_device *pcs;
+       struct list_head *pos;
+       int count = 0;
+
+       pcs = container_of(pcs_soc, struct pcs_device, socdata);
+       list_for_each(pos, &pcs->irqs) {
+               struct pcs_interrupt *pcswi;
+               unsigned mask;
+
+               pcswi = list_entry(pos, struct pcs_interrupt, node);
+               raw_spin_lock(&pcs->lock);
+               mask = pcs->read(pcswi->reg);
+               raw_spin_unlock(&pcs->lock);
+               if (mask & pcs_soc->irq_status_mask) {
+                       generic_handle_irq(irq_find_mapping(pcs->domain,
+                                                           pcswi->hwirq));
+                       count++;
+               }
+       }
+
+       /*
+        * For debugging on omaps, you may want to call pcs_soc->rearm()
+        * here to see wake-up interrupts during runtime also.
+        */
+
+       return count;
+}
+
+/**
+ * pcs_irq_handler() - handler for the shared interrupt case
+ * @irq: interrupt
+ * @d: data
+ *
+ * Use this for cases where multiple instances of
+ * pinctrl-single share a single interrupt like on omaps.
+ */
+static irqreturn_t pcs_irq_handler(int irq, void *d)
+{
+       struct pcs_soc_data *pcs_soc = d;
+
+       return pcs_irq_handle(pcs_soc) ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/**
+ * pcs_irq_handle() - handler for the dedicated chained interrupt case
+ * @irq: interrupt
+ * @desc: interrupt descriptor
+ *
+ * Use this if you have a separate interrupt for each
+ * pinctrl-single instance.
+ */
+static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc);
+       struct irq_chip *chip;
+       int res;
+
+       chip = irq_get_chip(irq);
+       chained_irq_enter(chip, desc);
+       res = pcs_irq_handle(pcs_soc);
+       /* REVISIT: export and add handle_bad_irq(irq, desc)? */
+       chained_irq_exit(chip, desc);
+
+       return;
+}
+
+static int pcs_irqdomain_map(struct irq_domain *d, unsigned int irq,
+                            irq_hw_number_t hwirq)
+{
+       struct pcs_soc_data *pcs_soc = d->host_data;
+       struct pcs_device *pcs;
+       struct pcs_interrupt *pcswi;
+
+       pcs = container_of(pcs_soc, struct pcs_device, socdata);
+       pcswi = devm_kzalloc(pcs->dev, sizeof(*pcswi), GFP_KERNEL);
+       if (!pcswi)
+               return -ENOMEM;
+
+       pcswi->reg = pcs->base + hwirq;
+       pcswi->hwirq = hwirq;
+       pcswi->irq = irq;
+
+       mutex_lock(&pcs->mutex);
+       list_add_tail(&pcswi->node, &pcs->irqs);
+       mutex_unlock(&pcs->mutex);
+
+       irq_set_chip_data(irq, pcs_soc);
+       irq_set_chip_and_handler(irq, &pcs->chip,
+                                handle_level_irq);
+
+#ifdef CONFIG_ARM
+       set_irq_flags(irq, IRQF_VALID);
+#else
+       irq_set_noprobe(irq);
+#endif
+
+       return 0;
+}
+
+static struct irq_domain_ops pcs_irqdomain_ops = {
+       .map = pcs_irqdomain_map,
+       .xlate = irq_domain_xlate_onecell,
+};
+
+/**
+ * pcs_irq_init_chained_handler() - set up a chained interrupt handler
+ * @pcs: pcs driver instance
+ * @np: device node pointer
+ */
+static int pcs_irq_init_chained_handler(struct pcs_device *pcs,
+                                       struct device_node *np)
+{
+       struct pcs_soc_data *pcs_soc = &pcs->socdata;
+       const char *name = "pinctrl";
+       int num_irqs;
+
+       if (!pcs_soc->irq_enable_mask ||
+           !pcs_soc->irq_status_mask) {
+               pcs_soc->irq = -1;
+               return -EINVAL;
+       }
+
+       INIT_LIST_HEAD(&pcs->irqs);
+       pcs->chip.name = name;
+       pcs->chip.irq_ack = pcs_irq_mask;
+       pcs->chip.irq_mask = pcs_irq_mask;
+       pcs->chip.irq_unmask = pcs_irq_unmask;
+       pcs->chip.irq_set_wake = pcs_irq_set_wake;
+
+       if (PCS_QUIRK_HAS_SHARED_IRQ) {
+               int res;
+
+               res = request_irq(pcs_soc->irq, pcs_irq_handler,
+                                 IRQF_SHARED | IRQF_NO_SUSPEND,
+                                 name, pcs_soc);
+               if (res) {
+                       pcs_soc->irq = -1;
+                       return res;
+               }
+       } else {
+               irq_set_handler_data(pcs_soc->irq, pcs_soc);
+               irq_set_chained_handler(pcs_soc->irq,
+                                       pcs_irq_chain_handler);
+       }
+
+       /*
+        * We can use the register offset as the hardirq
+        * number as irq_domain_add_simple maps them lazily.
+        * This way we can easily support more than one
+        * interrupt per function if needed.
+        */
+       num_irqs = pcs->size;
+
+       pcs->domain = irq_domain_add_simple(np, num_irqs, 0,
+                                           &pcs_irqdomain_ops,
+                                           pcs_soc);
+       if (!pcs->domain) {
+               irq_set_chained_handler(pcs_soc->irq, NULL);
+               return -EINVAL;
+       }
+
+       return 0;
+}
 
 #ifdef CONFIG_PM
 static int pinctrl_single_suspend(struct platform_device *pdev,
@@ -1523,8 +1851,10 @@ static int pcs_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *match;
+       struct pcs_pdata *pdata;
        struct resource *res;
        struct pcs_device *pcs;
+       const struct pcs_soc_data *soc;
        int ret;
 
        match = of_match_device(pcs_of_match, &pdev->dev);
@@ -1537,11 +1867,14 @@ static int pcs_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        pcs->dev = &pdev->dev;
+       raw_spin_lock_init(&pcs->lock);
        mutex_init(&pcs->mutex);
        INIT_LIST_HEAD(&pcs->pingroups);
        INIT_LIST_HEAD(&pcs->functions);
        INIT_LIST_HEAD(&pcs->gpiofuncs);
-       pcs->is_pinconf = match->data;
+       soc = match->data;
+       pcs->flags = soc->flags;
+       memcpy(&pcs->socdata, soc, sizeof(*soc));
 
        PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
                         "register width not specified\n");
@@ -1610,7 +1943,7 @@ static int pcs_probe(struct platform_device *pdev)
        pcs->desc.name = DRIVER_NAME;
        pcs->desc.pctlops = &pcs_pinctrl_ops;
        pcs->desc.pmxops = &pcs_pinmux_ops;
-       if (pcs->is_pinconf)
+       if (PCS_HAS_PINCONF)
                pcs->desc.confops = &pcs_pinconf_ops;
        pcs->desc.owner = THIS_MODULE;
 
@@ -1629,6 +1962,27 @@ static int pcs_probe(struct platform_device *pdev)
        if (ret < 0)
                goto free;
 
+       pcs->socdata.irq = irq_of_parse_and_map(np, 0);
+       if (pcs->socdata.irq)
+               pcs->flags |= PCS_FEAT_IRQ;
+
+       /* We still need auxdata for some omaps for PRM interrupts */
+       pdata = dev_get_platdata(&pdev->dev);
+       if (pdata) {
+               if (pdata->rearm)
+                       pcs->socdata.rearm = pdata->rearm;
+               if (pdata->irq) {
+                       pcs->socdata.irq = pdata->irq;
+                       pcs->flags |= PCS_FEAT_IRQ;
+               }
+       }
+
+       if (PCS_HAS_IRQ) {
+               ret = pcs_irq_init_chained_handler(pcs, np);
+               if (ret < 0)
+                       dev_warn(pcs->dev, "initialized with no interrupts\n");
+       }
+
        dev_info(pcs->dev, "%i pins at pa %p size %u\n",
                 pcs->desc.npins, pcs->base, pcs->size);
 
@@ -1652,9 +2006,25 @@ static int pcs_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct pcs_soc_data pinctrl_single_omap_wkup = {
+       .flags = PCS_QUIRK_SHARED_IRQ,
+       .irq_enable_mask = (1 << 14),   /* OMAP_WAKEUP_EN */
+       .irq_status_mask = (1 << 15),   /* OMAP_WAKEUP_EVENT */
+};
+
+static const struct pcs_soc_data pinctrl_single = {
+};
+
+static const struct pcs_soc_data pinconf_single = {
+       .flags = PCS_FEAT_PINCONF,
+};
+
 static struct of_device_id pcs_of_match[] = {
-       { .compatible = "pinctrl-single", .data = (void *)false },
-       { .compatible = "pinconf-single", .data = (void *)true },
+       { .compatible = "ti,omap3-padconf", .data = &pinctrl_single_omap_wkup },
+       { .compatible = "ti,omap4-padconf", .data = &pinctrl_single_omap_wkup },
+       { .compatible = "ti,omap5-padconf", .data = &pinctrl_single_omap_wkup },
+       { .compatible = "pinctrl-single", .data = &pinctrl_single },
+       { .compatible = "pinconf-single", .data = &pinconf_single },
        { },
 };
 MODULE_DEVICE_TABLE(of, pcs_of_match);
index ffd53e3eb92f1191116c84f5e85a3723988879f5..c8873b0ca551d9fc93add48ae212e7bbf3ef7662 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 extern spinlock_t pnp_lock;
-extern struct device_attribute pnp_interface_attrs[];
+extern const struct attribute_group *pnp_dev_groups[];
 void *pnp_alloc(long size);
 
 int pnp_register_protocol(struct pnp_protocol *protocol);
index a39ee38a9414cece2b0742e05f2cf5260a0fc842..6936e0acedcd6bfce4b8166bb4b8da6a922e0f47 100644 (file)
@@ -246,7 +246,7 @@ struct bus_type pnp_bus_type = {
        .remove  = pnp_device_remove,
        .shutdown = pnp_device_shutdown,
        .pm      = &pnp_bus_dev_pm_ops,
-       .dev_attrs = pnp_interface_attrs,
+       .dev_groups = pnp_dev_groups,
 };
 
 int pnp_register_driver(struct pnp_driver *drv)
index 0c201317284b40e93014d0a574b3ef0ab9d81b9b..e6c403be09a924b7fe795e973dafb227a089affe 100644 (file)
@@ -203,8 +203,8 @@ static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
        }
 }
 
-static ssize_t pnp_show_options(struct device *dmdev,
-                               struct device_attribute *attr, char *buf)
+static ssize_t options_show(struct device *dmdev, struct device_attribute *attr,
+                           char *buf)
 {
        struct pnp_dev *dev = to_pnp_dev(dmdev);
        pnp_info_buffer_t *buffer;
@@ -241,10 +241,10 @@ static ssize_t pnp_show_options(struct device *dmdev,
        kfree(buffer);
        return ret;
 }
+static DEVICE_ATTR_RO(options);
 
-static ssize_t pnp_show_current_resources(struct device *dmdev,
-                                         struct device_attribute *attr,
-                                         char *buf)
+static ssize_t resources_show(struct device *dmdev,
+                             struct device_attribute *attr, char *buf)
 {
        struct pnp_dev *dev = to_pnp_dev(dmdev);
        pnp_info_buffer_t *buffer;
@@ -331,9 +331,9 @@ static char *pnp_get_resource_value(char *buf,
        return buf;
 }
 
-static ssize_t pnp_set_current_resources(struct device *dmdev,
-                                        struct device_attribute *attr,
-                                        const char *ubuf, size_t count)
+static ssize_t resources_store(struct device *dmdev,
+                              struct device_attribute *attr, const char *ubuf,
+                              size_t count)
 {
        struct pnp_dev *dev = to_pnp_dev(dmdev);
        char *buf = (void *)ubuf;
@@ -434,9 +434,10 @@ done:
                return retval;
        return count;
 }
+static DEVICE_ATTR_RW(resources);
 
-static ssize_t pnp_show_current_ids(struct device *dmdev,
-                                   struct device_attribute *attr, char *buf)
+static ssize_t id_show(struct device *dmdev, struct device_attribute *attr,
+                      char *buf)
 {
        char *str = buf;
        struct pnp_dev *dev = to_pnp_dev(dmdev);
@@ -448,12 +449,20 @@ static ssize_t pnp_show_current_ids(struct device *dmdev,
        }
        return (str - buf);
 }
+static DEVICE_ATTR_RO(id);
 
-struct device_attribute pnp_interface_attrs[] = {
-       __ATTR(resources, S_IRUGO | S_IWUSR,
-                  pnp_show_current_resources,
-                  pnp_set_current_resources),
-       __ATTR(options, S_IRUGO, pnp_show_options, NULL),
-       __ATTR(id, S_IRUGO, pnp_show_current_ids, NULL),
-       __ATTR_NULL,
+static struct attribute *pnp_dev_attrs[] = {
+       &dev_attr_resources.attr,
+       &dev_attr_options.attr,
+       &dev_attr_id.attr,
+       NULL,
+};
+
+static const struct attribute_group pnp_dev_group = {
+       .attrs = pnp_dev_attrs,
+};
+
+const struct attribute_group *pnp_dev_groups[] = {
+       &pnp_dev_group,
+       NULL,
 };
index 3e9b6a78ad18a4dcff861886d0828b5622aad267..c9ae692d34518c97485114cae2c685e6da81e11a 100644 (file)
@@ -223,8 +223,8 @@ struct device rio_bus = {
 struct bus_type rio_bus_type = {
        .name = "rapidio",
        .match = rio_match_bus,
-       .dev_attrs = rio_dev_attrs,
-       .bus_attrs = rio_bus_attrs,
+       .dev_groups = rio_dev_groups,
+       .bus_groups = rio_bus_groups,
        .probe = rio_device_probe,
        .remove = rio_device_remove,
        .uevent = rio_uevent,
index 9331be646dc34d4075df3b6512975efe3eec8c1a..e0221c6d0cc238543cc84557a9ffb176a64c23f3 100644 (file)
@@ -27,6 +27,7 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf)                    \
                                                                        \
        return sprintf(buf, format_string, rdev->field);                \
 }                                                                      \
+static DEVICE_ATTR_RO(field);
 
 rio_config_attr(did, "0x%04x\n");
 rio_config_attr(vid, "0x%04x\n");
@@ -54,6 +55,7 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch
 
        return (str - buf);
 }
+static DEVICE_ATTR_RO(routes);
 
 static ssize_t lprev_show(struct device *dev,
                          struct device_attribute *attr, char *buf)
@@ -63,6 +65,7 @@ static ssize_t lprev_show(struct device *dev,
        return sprintf(buf, "%s\n",
                        (rdev->prev) ? rio_name(rdev->prev) : "root");
 }
+static DEVICE_ATTR_RO(lprev);
 
 static ssize_t lnext_show(struct device *dev,
                          struct device_attribute *attr, char *buf)
@@ -83,6 +86,7 @@ static ssize_t lnext_show(struct device *dev,
 
        return str - buf;
 }
+static DEVICE_ATTR_RO(lnext);
 
 static ssize_t modalias_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
@@ -92,23 +96,29 @@ static ssize_t modalias_show(struct device *dev,
        return sprintf(buf, "rapidio:v%04Xd%04Xav%04Xad%04X\n",
                       rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did);
 }
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *rio_dev_attrs[] = {
+       &dev_attr_did.attr,
+       &dev_attr_vid.attr,
+       &dev_attr_device_rev.attr,
+       &dev_attr_asm_did.attr,
+       &dev_attr_asm_vid.attr,
+       &dev_attr_asm_rev.attr,
+       &dev_attr_lprev.attr,
+       &dev_attr_destid.attr,
+       &dev_attr_modalias.attr,
+       NULL,
+};
 
-struct device_attribute rio_dev_attrs[] = {
-       __ATTR_RO(did),
-       __ATTR_RO(vid),
-       __ATTR_RO(device_rev),
-       __ATTR_RO(asm_did),
-       __ATTR_RO(asm_vid),
-       __ATTR_RO(asm_rev),
-       __ATTR_RO(lprev),
-       __ATTR_RO(destid),
-       __ATTR_RO(modalias),
-       __ATTR_NULL,
+static const struct attribute_group rio_dev_group = {
+       .attrs = rio_dev_attrs,
 };
 
-static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
-static DEVICE_ATTR(lnext, S_IRUGO, lnext_show, NULL);
-static DEVICE_ATTR(hopcount, S_IRUGO, hopcount_show, NULL);
+const struct attribute_group *rio_dev_groups[] = {
+       &rio_dev_group,
+       NULL,
+};
 
 static ssize_t
 rio_read_config(struct file *filp, struct kobject *kobj,
@@ -316,8 +326,18 @@ exit:
 
        return rc;
 }
+static BUS_ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store);
+
+static struct attribute *rio_bus_attrs[] = {
+       &bus_attr_scan.attr,
+       NULL,
+};
+
+static const struct attribute_group rio_bus_group = {
+       .attrs = rio_bus_attrs,
+};
 
-struct bus_attribute rio_bus_attrs[] = {
-       __ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store),
-       __ATTR_NULL
+const struct attribute_group *rio_bus_groups[] = {
+       &rio_bus_group,
+       NULL,
 };
index 085215cd8502f5b12ca93787a267eef1d173759a..5f99d22ad0b04534440ba1d17d247c9b127caba2 100644 (file)
@@ -48,8 +48,8 @@ extern struct rio_mport *rio_find_mport(int mport_id);
 extern int rio_mport_scan(int mport_id);
 
 /* Structures internal to the RIO core code */
-extern struct device_attribute rio_dev_attrs[];
-extern struct bus_attribute rio_bus_attrs[];
+extern const struct attribute_group *rio_dev_groups[];
+extern const struct attribute_group *rio_bus_groups[];
 
 #define RIO_GET_DID(size, x)   (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
 #define RIO_SET_DID(size, x)   (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
index 4e2a81854f517cac05b775dd57d234e5d871e15e..45560ffb038d21e5ca5e7cf98afad3fdde634b29 100644 (file)
@@ -275,6 +275,12 @@ static int hid_time_probe(struct platform_device *pdev)
                return ret;
        }
 
+       ret = sensor_hub_device_open(hsdev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to open sensor hub device!\n");
+               goto err_open;
+       }
+
        time_state->rtc = devm_rtc_device_register(&pdev->dev,
                                        "hid-sensor-time", &hid_time_rtc_ops,
                                        THIS_MODULE);
@@ -282,17 +288,24 @@ static int hid_time_probe(struct platform_device *pdev)
        if (IS_ERR_OR_NULL(time_state->rtc)) {
                ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
                time_state->rtc = NULL;
-               sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
                dev_err(&pdev->dev, "rtc device register failed!\n");
+               goto err_rtc;
        }
 
        return ret;
+
+err_rtc:
+       sensor_hub_device_close(hsdev);
+err_open:
+       sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
+       return ret;
 }
 
 static int hid_time_remove(struct platform_device *pdev)
 {
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 
+       sensor_hub_device_close(hsdev);
        sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
 
        return 0;
index 451bf99582ff09948c04e6634ca2d381c0d6a45a..244f77f844f020afec60f072694f7c70bcaadb8a 100644 (file)
@@ -698,10 +698,11 @@ static void dasd_profile_start(struct dasd_block *block,
        }
 
        spin_lock(&block->profile.lock);
-       if (block->profile.data)
+       if (block->profile.data) {
                block->profile.data->dasd_io_nr_req[counter]++;
                if (rq_data_dir(req) == READ)
                        block->profile.data->dasd_read_nr_req[counter]++;
+       }
        spin_unlock(&block->profile.lock);
 
        /*
index 5d73e6e49af6c96cb9e97b60163485b1ba5dbb8b..548209a9c43c58ae687809d5da605f7b8e97184b 100644 (file)
@@ -223,8 +223,12 @@ static void scm_blk_request(struct request_queue *rq)
        int ret;
 
        while ((req = blk_peek_request(rq))) {
-               if (req->cmd_type != REQ_TYPE_FS)
+               if (req->cmd_type != REQ_TYPE_FS) {
+                       blk_start_request(req);
+                       blk_dump_rq_flags(req, KMSG_COMPONENT " bad request");
+                       blk_end_request_all(req, -EIO);
                        continue;
+               }
 
                if (!scm_permit_request(bdev, req)) {
                        scm_ensure_queue_restart(bdev);
index 8b387b32fd622b981a19e951eca1b3fd30c783bf..e59331e6c2e5ef682dae02f7f5fbebe1bae1b5c8 100644 (file)
@@ -107,7 +107,7 @@ extern debug_info_t *scm_debug;
 
 static inline void SCM_LOG_HEX(int level, void *data, int length)
 {
-       if (level > scm_debug->level)
+       if (!debug_level_enabled(scm_debug, level))
                return;
        while (length > 0) {
                debug_event(scm_debug, level, data, length);
index 4600aa10a1c6c5824f36168fb83b414d2e4e915b..668b32b0dc1dc39317ebbc682f55bedbc86537c3 100644 (file)
@@ -60,7 +60,7 @@ static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn)
        struct appldata_product_id id;
        int rc;
 
-       strcpy(id.prod_nr, "LNXAPPL");
+       strncpy(id.prod_nr, "LNXAPPL", 7);
        id.prod_fn = myhdr->applid;
        id.record_nr = myhdr->record_num;
        id.version_nr = myhdr->version;
index 24a08e8f19e1b9ed3366b5f035d4a0fd214bf97e..2cdec21e8924ea7b0403aafd1b0bae172a76416e 100644 (file)
@@ -615,10 +615,10 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
 
        if (rp->state != RAW3270_STATE_RESET)
                return;
-       if (rq && rq->rc) {
+       if (rq->rc) {
                /* Reset command failed. */
                rp->state = RAW3270_STATE_INIT;
-       } else if (0 && MACHINE_IS_VM) {
+       } else if (MACHINE_IS_VM) {
                raw3270_size_device_vm(rp);
                raw3270_size_device_done(rp);
        } else
index 794820a123d0c83c07b1b2e546efc84c25daa14a..ffb1fcf0bf5bed9928f53e1205f8b6b01635f6b6 100644 (file)
@@ -151,7 +151,7 @@ static int __init init_cpu_info(enum arch_id arch)
 
        /* get info for boot cpu from lowcore, stored in the HSA */
 
-       sa = kmalloc(sizeof(*sa), GFP_KERNEL);
+       sa = dump_save_area_create(0);
        if (!sa)
                return -ENOMEM;
        if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
@@ -159,7 +159,6 @@ static int __init init_cpu_info(enum arch_id arch)
                kfree(sa);
                return -EIO;
        }
-       zfcpdump_save_areas[0] = sa;
        return 0;
 }
 
@@ -246,24 +245,25 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len)
 static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
 {
        unsigned long end;
-       int i = 0;
+       int i;
 
        if (count == 0)
                return 0;
 
        end = start + count;
-       while (zfcpdump_save_areas[i]) {
+       for (i = 0; i < dump_save_areas.count; i++) {
                unsigned long cp_start, cp_end; /* copy range */
                unsigned long sa_start, sa_end; /* save area range */
                unsigned long prefix;
                unsigned long sa_off, len, buf_off;
+               struct save_area *save_area = dump_save_areas.areas[i];
 
-               prefix = zfcpdump_save_areas[i]->pref_reg;
+               prefix = save_area->pref_reg;
                sa_start = prefix + sys_info.sa_base;
                sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
 
                if ((end < sa_start) || (start > sa_end))
-                       goto next;
+                       continue;
                cp_start = max(start, sa_start);
                cp_end = min(end, sa_end);
 
@@ -272,10 +272,8 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
                len = cp_end - cp_start;
 
                TRACE("copy_lc for: %lx\n", start);
-               if (copy_lc(buf + buf_off, zfcpdump_save_areas[i], sa_off, len))
+               if (copy_lc(buf + buf_off, save_area, sa_off, len))
                        return -EFAULT;
-next:
-               i++;
        }
        return 0;
 }
@@ -637,8 +635,8 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr,
        hdr->num_pages = mem_size / PAGE_SIZE;
        hdr->tod = get_tod_clock();
        get_cpu_id(&hdr->cpu_id);
-       for (i = 0; zfcpdump_save_areas[i]; i++) {
-               prefix = zfcpdump_save_areas[i]->pref_reg;
+       for (i = 0; i < dump_save_areas.count; i++) {
+               prefix = dump_save_areas.areas[i]->pref_reg;
                hdr->real_cpu_cnt++;
                if (!prefix)
                        continue;
index d028fd800c9c6afd7f5b5627475c4bfe6552f04b..f055df0b167fc83e1f2f6f17e0aef47e129007b4 100644 (file)
@@ -194,15 +194,14 @@ EXPORT_SYMBOL(airq_iv_release);
  */
 unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
 {
-       const unsigned long be_to_le = BITS_PER_LONG - 1;
        unsigned long bit;
 
        if (!iv->avail)
                return -1UL;
        spin_lock(&iv->lock);
-       bit = find_first_bit_left(iv->avail, iv->bits);
+       bit = find_first_bit_inv(iv->avail, iv->bits);
        if (bit < iv->bits) {
-               clear_bit(bit ^ be_to_le, iv->avail);
+               clear_bit_inv(bit, iv->avail);
                if (bit >= iv->end)
                        iv->end = bit + 1;
        } else
@@ -220,19 +219,17 @@ EXPORT_SYMBOL(airq_iv_alloc_bit);
  */
 void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
 {
-       const unsigned long be_to_le = BITS_PER_LONG - 1;
-
        if (!iv->avail)
                return;
        spin_lock(&iv->lock);
        /* Clear (possibly left over) interrupt bit */
-       clear_bit(bit ^ be_to_le, iv->vector);
+       clear_bit_inv(bit, iv->vector);
        /* Make the bit position available again */
-       set_bit(bit ^ be_to_le, iv->avail);
+       set_bit_inv(bit, iv->avail);
        if (bit == iv->end - 1) {
                /* Find new end of bit-field */
                while (--iv->end > 0)
-                       if (!test_bit((iv->end - 1) ^ be_to_le, iv->avail))
+                       if (!test_bit_inv(iv->end - 1, iv->avail))
                                break;
        }
        spin_unlock(&iv->lock);
@@ -251,15 +248,13 @@ EXPORT_SYMBOL(airq_iv_free_bit);
 unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
                           unsigned long end)
 {
-       const unsigned long be_to_le = BITS_PER_LONG - 1;
        unsigned long bit;
 
        /* Find non-zero bit starting from 'ivs->next'. */
-       bit = find_next_bit_left(iv->vector, end, start);
+       bit = find_next_bit_inv(iv->vector, end, start);
        if (bit >= end)
                return -1UL;
-       /* Clear interrupt bit (find left uses big-endian bit numbers) */
-       clear_bit(bit ^ be_to_le, iv->vector);
+       clear_bit_inv(bit, iv->vector);
        return bit;
 }
 EXPORT_SYMBOL(airq_iv_scan);
index d9eddcba7e884d788a9d8c1f3dad14bc3d71cf77..aca7bfc113aaeb4067043cd10bdc0662dd8ec286 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/kernel_stat.h>
+#include <linux/completion.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
@@ -42,7 +43,7 @@ static debug_info_t *eadm_debug;
 
 static void EADM_LOG_HEX(int level, void *data, int length)
 {
-       if (level > eadm_debug->level)
+       if (!debug_level_enabled(eadm_debug, level))
                return;
        while (length > 0) {
                debug_event(eadm_debug, level, data, length);
@@ -159,6 +160,9 @@ static void eadm_subchannel_irq(struct subchannel *sch)
        }
        scm_irq_handler((struct aob *)(unsigned long)scsw->aob, error);
        private->state = EADM_IDLE;
+
+       if (private->completion)
+               complete(private->completion);
 }
 
 static struct subchannel *eadm_get_idle_sch(void)
@@ -255,13 +259,32 @@ out:
 
 static void eadm_quiesce(struct subchannel *sch)
 {
+       struct eadm_private *private = get_eadm_private(sch);
+       DECLARE_COMPLETION_ONSTACK(completion);
        int ret;
 
+       spin_lock_irq(sch->lock);
+       if (private->state != EADM_BUSY)
+               goto disable;
+
+       if (eadm_subchannel_clear(sch))
+               goto disable;
+
+       private->completion = &completion;
+       spin_unlock_irq(sch->lock);
+
+       wait_for_completion_io(&completion);
+
+       spin_lock_irq(sch->lock);
+       private->completion = NULL;
+
+disable:
+       eadm_subchannel_set_timeout(sch, 0);
        do {
-               spin_lock_irq(sch->lock);
                ret = cio_disable_subchannel(sch);
-               spin_unlock_irq(sch->lock);
        } while (ret == -EBUSY);
+
+       spin_unlock_irq(sch->lock);
 }
 
 static int eadm_subchannel_remove(struct subchannel *sch)
index 2779be093982ee1c219f4c9c6c24ab8edebe8ce3..9664e4653f9861416a78f4193cbe57d8d3105864 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef EADM_SCH_H
 #define EADM_SCH_H
 
+#include <linux/completion.h>
 #include <linux/device.h>
 #include <linux/timer.h>
 #include <linux/list.h>
@@ -9,9 +10,10 @@
 struct eadm_private {
        union orb orb;
        enum {EADM_IDLE, EADM_BUSY, EADM_NOT_OPER} state;
+       struct completion *completion;
+       struct subchannel *sch;
        struct timer_list timer;
        struct list_head head;
-       struct subchannel *sch;
 } __aligned(8);
 
 #define get_eadm_private(n) ((struct eadm_private *)dev_get_drvdata(&n->dev))
index 647b422bb22a594b760d0a5590c962a7683192b6..dfac9bfefea3f11a9f61069006281a750551f39c 100644 (file)
 extern debug_info_t *qdio_dbf_setup;
 extern debug_info_t *qdio_dbf_error;
 
-/* sort out low debug levels early to avoid wasted sprints */
-static inline int qdio_dbf_passes(debug_info_t *dbf_grp, int level)
-{
-       return (level <= dbf_grp->level);
-}
-
 #define DBF_ERR                3       /* error conditions     */
 #define DBF_WARN       4       /* warning conditions   */
 #define DBF_INFO       6       /* informational        */
@@ -65,7 +59,7 @@ static inline void DBF_ERROR_HEX(void *addr, int len)
 #define DBF_DEV_EVENT(level, device, text...) \
        do { \
                char debug_buffer[QDIO_DBF_LEN]; \
-               if (qdio_dbf_passes(device->debug_area, level)) { \
+               if (debug_level_enabled(device->debug_area, level)) { \
                        snprintf(debug_buffer, QDIO_DBF_LEN, text); \
                        debug_text_event(device->debug_area, level, debug_buffer); \
                } \
index bbd3e511c771addebda2639675d85664b3191494..3e602e8affa78cba97282e41c5f9e3a18315e45b 100644 (file)
@@ -528,7 +528,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
        case SLSB_P_INPUT_PRIMED:
                inbound_primed(q, count);
                q->first_to_check = add_buf(q->first_to_check, count);
-               if (atomic_sub(count, &q->nr_buf_used) == 0)
+               if (atomic_sub_return(count, &q->nr_buf_used) == 0)
                        qperf_inc(q, inbound_queue_full);
                if (q->irq_ptr->perf_stat_enabled)
                        account_sbals(q, count);
index 841ea72e4a4e93a12d397070530191d4b02adb5d..28d9349de1adf77cf20dbe5f938d6a27afd3eaeb 100644 (file)
 /* that gives us 15 characters in the text event views */
 #define ZCRYPT_DBF_LEN 16
 
-/* sort out low debug levels early to avoid wasted sprints */
-static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
-{
-       return (level <= dbf_grp->level);
-}
-
 #define DBF_ERR                3       /* error conditions     */
 #define DBF_WARN       4       /* warning conditions   */
 #define DBF_INFO       6       /* informational        */
@@ -25,7 +19,7 @@ static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
 
 #define ZCRYPT_DBF_COMMON(level, text...) \
        do { \
-               if (zcrypt_dbf_passes(zcrypt_dbf_common, level)) { \
+               if (debug_level_enabled(zcrypt_dbf_common, level)) { \
                        char debug_buffer[ZCRYPT_DBF_LEN]; \
                        snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
                        debug_text_event(zcrypt_dbf_common, level, \
@@ -35,7 +29,7 @@ static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
 
 #define ZCRYPT_DBF_DEVICES(level, text...) \
        do { \
-               if (zcrypt_dbf_passes(zcrypt_dbf_devices, level)) { \
+               if (debug_level_enabled(zcrypt_dbf_devices, level)) { \
                        char debug_buffer[ZCRYPT_DBF_LEN]; \
                        snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
                        debug_text_event(zcrypt_dbf_devices, level, \
@@ -45,7 +39,7 @@ static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
 
 #define ZCRYPT_DBF_DEV(level, device, text...) \
        do { \
-               if (zcrypt_dbf_passes(device->dbf_area, level)) { \
+               if (debug_level_enabled(device->dbf_area, level)) { \
                        char debug_buffer[ZCRYPT_DBF_LEN]; \
                        snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
                        debug_text_event(device->dbf_area, level, \
index 1bc5904df19ff550d3094ed939faab28f5cac44c..3339b9b607b3aa6ca5ad5ba60c20cd5c3144df55 100644 (file)
@@ -114,15 +114,9 @@ do { \
        debug_event(claw_dbf_##name,level,(void*)(addr),len); \
 } while (0)
 
-/* Allow to sort out low debug levels early to avoid wasted sprints */
-static inline int claw_dbf_passes(debug_info_t *dbf_grp, int level)
-{
-       return (level <= dbf_grp->level);
-}
-
 #define CLAW_DBF_TEXT_(level,name,text...) \
        do { \
-               if (claw_dbf_passes(claw_dbf_##name, level)) { \
+               if (debug_level_enabled(claw_dbf_##name, level)) { \
                        sprintf(debug_buffer, text); \
                        debug_text_event(claw_dbf_##name, level, \
                                                debug_buffer); \
index 6514e1cb3f1cf1b21cc7bd2d4422ca48fe2b7d47..8363f1c966ef7e5a2e55d6f2a861ae011f9601d7 100644 (file)
@@ -66,7 +66,7 @@ void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *fmt, ...)
        char dbf_txt_buf[64];
        va_list args;
 
-       if (level > (ctcm_dbf[dbf_nix].id)->level)
+       if (!debug_level_enabled(ctcm_dbf[dbf_nix].id, level))
                return;
        va_start(args, fmt);
        vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
index 8c03392ac833f2a284c7f422f296b52fc610e285..150fcb4cebc3510e5a4e45dfb61f63728cd5ed7d 100644 (file)
@@ -16,15 +16,9 @@ do { \
        debug_event(lcs_dbf_##name,level,(void*)(addr),len); \
 } while (0)
 
-/* Allow to sort out low debug levels early to avoid wasted sprints */
-static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level)
-{
-       return (level <= dbf_grp->level);
-}
-
 #define LCS_DBF_TEXT_(level,name,text...) \
        do { \
-               if (lcs_dbf_passes(lcs_dbf_##name, level)) { \
+               if (debug_level_enabled(lcs_dbf_##name, level)) { \
                        sprintf(debug_buffer, text); \
                        debug_text_event(lcs_dbf_##name, level, debug_buffer); \
                } \
index 279ad504ec3c85e3e410d231fac82e812a75b5d2..9b333fcf1a4c38ea45d352f253aaa47838d78c91 100644 (file)
@@ -105,15 +105,9 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
 
 DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
 
-/* Allow to sort out low debug levels early to avoid wasted sprints */
-static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level)
-{
-       return (level <= dbf_grp->level);
-}
-
 #define IUCV_DBF_TEXT_(name, level, text...) \
        do { \
-               if (iucv_dbf_passes(iucv_dbf_##name, level)) { \
+               if (debug_level_enabled(iucv_dbf_##name, level)) { \
                        char* __buf = get_cpu_var(iucv_dbf_txt_buf); \
                        sprintf(__buf, text); \
                        debug_text_event(iucv_dbf_##name, level, __buf); \
index 0a328d0d11bebaac40ccbaf2239ca999dd736373..d7b66a28fe75577dd6ccaef41619eb19b327df34 100644 (file)
@@ -5096,7 +5096,7 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *fmt, ...)
        char dbf_txt_buf[32];
        va_list args;
 
-       if (level > id->level)
+       if (!debug_level_enabled(id, level))
                return;
        va_start(args, fmt);
        vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
index 3ac7a4b30dd910ef6f59c4ada70966d66694c90e..0be3d48681aead94466a71ab7b34c6ae7ca098ff 100644 (file)
@@ -278,7 +278,7 @@ struct zfcp_dbf {
 static inline
 void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
 {
-       if (level <= req->adapter->dbf->hba->level)
+       if (debug_level_enabled(req->adapter->dbf->hba, level))
                zfcp_dbf_hba_fsf_res(tag, req);
 }
 
@@ -317,7 +317,7 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
        struct zfcp_adapter *adapter = (struct zfcp_adapter *)
                                        scmd->device->host->hostdata[0];
 
-       if (level <= adapter->dbf->scsi->level)
+       if (debug_level_enabled(adapter->dbf->scsi, level))
                zfcp_dbf_scsi(tag, scmd, req);
 }
 
index c9382d6eee7861bf4a8bd1399cfb6180a1fb7273..1f4f22fe82812170db684cbdd406c23c4cb32f82 100644 (file)
@@ -553,16 +553,20 @@ static struct device_type fcoe_fcf_device_type = {
        .release = fcoe_fcf_device_release,
 };
 
-static struct bus_attribute fcoe_bus_attr_group[] = {
-       __ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
-       __ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
-       __ATTR_NULL
+static BUS_ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store);
+static BUS_ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store);
+
+static struct attribute *fcoe_bus_attrs[] = {
+       &bus_attr_ctlr_create.attr,
+       &bus_attr_ctlr_destroy.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(fcoe_bus);
 
 static struct bus_type fcoe_bus_type = {
        .name = "fcoe",
        .match = &fcoe_bus_match,
-       .bus_attrs = fcoe_bus_attr_group,
+       .bus_groups = fcoe_bus_groups,
 };
 
 /**
index e55ddf7cd7c2c42274145051c16760da800ad5ee..32a811d11c25cc419fc11878a9b2d3ff7c74c4bb 100644 (file)
@@ -374,7 +374,8 @@ static ssize_t \
 attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
 { \
        return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
-}
+} \
+static DEVICE_ATTR_RO(attrib);
 
 ssb_config_attr(core_num, core_index, "%u\n")
 ssb_config_attr(coreid, id.coreid, "0x%04x\n")
@@ -387,16 +388,18 @@ name_show(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%s\n",
                       ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
 }
-
-static struct device_attribute ssb_device_attrs[] = {
-       __ATTR_RO(name),
-       __ATTR_RO(core_num),
-       __ATTR_RO(coreid),
-       __ATTR_RO(vendor),
-       __ATTR_RO(revision),
-       __ATTR_RO(irq),
-       __ATTR_NULL,
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *ssb_device_attrs[] = {
+       &dev_attr_name.attr,
+       &dev_attr_core_num.attr,
+       &dev_attr_coreid.attr,
+       &dev_attr_vendor.attr,
+       &dev_attr_revision.attr,
+       &dev_attr_irq.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(ssb_device);
 
 static struct bus_type ssb_bustype = {
        .name           = "ssb",
@@ -407,7 +410,7 @@ static struct bus_type ssb_bustype = {
        .suspend        = ssb_device_suspend,
        .resume         = ssb_device_resume,
        .uevent         = ssb_device_uevent,
-       .dev_attrs      = ssb_device_attrs,
+       .dev_groups     = ssb_device_groups,
 };
 
 static void ssb_buses_lock(void)
index 3626dbc8eb0bba5134f89aa19178fedb3e504e98..3bfdaa8d80a9ccb9b299d6bd4fde693ed4d03652 100644 (file)
@@ -136,6 +136,8 @@ source "drivers/staging/goldfish/Kconfig"
 
 source "drivers/staging/netlogic/Kconfig"
 
+source "drivers/staging/mt29f_spinand/Kconfig"
+
 source "drivers/staging/dwc2/Kconfig"
 
 source "drivers/staging/lustre/Kconfig"
index d1b4b8003c2d4de3898796e74d973cb2aa25f888..b0d3303b46808f224578c3757006aef96099e4cd 100644 (file)
@@ -66,3 +66,4 @@ obj-$(CONFIG_USB_BTMTK)               += btmtk_usb/
 obj-$(CONFIG_XILLYBUS)         += xillybus/
 obj-$(CONFIG_DGNC)                     += dgnc/
 obj-$(CONFIG_DGAP)                     += dgap/
+obj-$(CONFIG_MTD_SPINAND_MT29F)        += mt29f_spinand/
index c0c95be0f969de825119ce2a6ee535fd6668a63b..1e9ab6dfc90d446f84fdec75891a30683bb13927 100644 (file)
@@ -10,6 +10,7 @@ if ANDROID
 
 config ANDROID_BINDER_IPC
        bool "Android Binder IPC Driver"
+       depends on MMU
        default n
        ---help---
          Binder is used in Android for both communication between processes,
@@ -76,7 +77,7 @@ config SYNC
        bool "Synchronization framework"
        default n
        select ANON_INODES
-       help
+       ---help---
          This option enables the framework for synchronization between multiple
          drivers.  Sync implementations can take advantage of hardware
          synchronization built into devices like GPUs.
@@ -85,7 +86,7 @@ config SW_SYNC
        bool "Software synchronization objects"
        default n
        depends on SYNC
-       help
+       ---help---
          A sync object driver that uses a 32bit counter to coordinate
          syncrhronization.  Useful when there is no hardware primitive backing
          the synchronization.
@@ -94,7 +95,7 @@ config SW_SYNC_USER
        bool "Userspace API for SW_SYNC"
        default n
        depends on SW_SYNC
-       help
+       ---help---
          Provides a user space API to the sw sync object.
          *WARNING* improper use of this can result in deadlocking kernel
          drivers from userspace.
index 6dc27dac679d9133052b7aca2ad2ea06cf1d3486..647694f43dcf12fe9c30c300674f128569f79780 100644 (file)
@@ -60,7 +60,12 @@ struct devalarm {
 
 static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
 
-
+/**
+ * is_wakeup() - Checks to see if this alarm can wake the device
+ * @type:       The type of alarm being checked
+ *
+ * Return: 1 if this is a wakeup alarm, otherwise 0
+ */
 static int is_wakeup(enum android_alarm_type type)
 {
        return (type == ANDROID_ALARM_RTC_WAKEUP ||
@@ -76,7 +81,6 @@ static void devalarm_start(struct devalarm *alrm, ktime_t exp)
                hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
 }
 
-
 static int devalarm_try_to_cancel(struct devalarm *alrm)
 {
        if (is_wakeup(alrm->type))
index 8e76ddca0999dd29e50d68f61d4f78c0ba6fbac3..23948f16701206926ec9a76ce347641316d692c5 100644 (file)
 #define ASHMEM_NAME_PREFIX_LEN (sizeof(ASHMEM_NAME_PREFIX) - 1)
 #define ASHMEM_FULL_NAME_LEN (ASHMEM_NAME_LEN + ASHMEM_NAME_PREFIX_LEN)
 
-/*
- * ashmem_area - anonymous shared memory area
- * Lifecycle: From our parent file's open() until its release()
- * Locking: Protected by `ashmem_mutex'
- * Big Note: Mappings do NOT pin this structure; it dies on close()
+/**
+ * struct ashmem_area - The anonymous shared memory area
+ * @name:              The optional name in /proc/pid/maps
+ * @unpinned_list:     The list of all ashmem areas
+ * @file:              The shmem-based backing file
+ * @size:              The size of the mapping, in bytes
+ * @prot_masks:                The allowed protection bits, as vm_flags
+ *
+ * The lifecycle of this structure is from our parent file's open() until
+ * its release(). It is also protected by 'ashmem_mutex'
+ *
+ * Warning: Mappings do NOT pin this structure; It dies on close()
  */
 struct ashmem_area {
-       char name[ASHMEM_FULL_NAME_LEN]; /* optional name in /proc/pid/maps */
-       struct list_head unpinned_list;  /* list of all ashmem areas */
-       struct file *file;               /* the shmem-based backing file */
-       size_t size;                     /* size of the mapping, in bytes */
-       unsigned long prot_mask;         /* allowed prot bits, as vm_flags */
+       char name[ASHMEM_FULL_NAME_LEN];
+       struct list_head unpinned_list;
+       struct file *file;
+       size_t size;
+       unsigned long prot_mask;
 };
 
-/*
- * ashmem_range - represents an interval of unpinned (evictable) pages
- * Lifecycle: From unpin to pin
- * Locking: Protected by `ashmem_mutex'
+/**
+ * struct ashmem_range - A range of unpinned/evictable pages
+ * @lru:                The entry in the LRU list
+ * @unpinned:           The entry in its area's unpinned list
+ * @asma:               The associated anonymous shared memory area.
+ * @pgstart:            The starting page (inclusive)
+ * @pgend:              The ending page (inclusive)
+ * @purged:             The purge status (ASHMEM_NOT or ASHMEM_WAS_PURGED)
+ *
+ * The lifecycle of this structure is from unpin to pin.
+ * It is protected by 'ashmem_mutex'
  */
 struct ashmem_range {
-       struct list_head lru;           /* entry in LRU list */
-       struct list_head unpinned;      /* entry in its area's unpinned list */
-       struct ashmem_area *asma;       /* associated area */
-       size_t pgstart;                 /* starting page, inclusive */
-       size_t pgend;                   /* ending page, inclusive */
-       unsigned int purged;            /* ASHMEM_NOT or ASHMEM_WAS_PURGED */
+       struct list_head lru;
+       struct list_head unpinned;
+       struct ashmem_area *asma;
+       size_t pgstart;
+       size_t pgend;
+       unsigned int purged;
 };
 
 /* LRU list of unpinned pages, protected by ashmem_mutex */
 static LIST_HEAD(ashmem_lru_list);
 
-/* Count of pages on our LRU list, protected by ashmem_mutex */
+/**
+ * long lru_count - The count of pages on our LRU list.
+ *
+ * This is protected by ashmem_mutex.
+ */
 static unsigned long lru_count;
 
-/*
+/**
  * ashmem_mutex - protects the list of and each individual ashmem_area
  *
  * Lock Ordering: ashmex_mutex -> i_mutex -> i_alloc_sem
@@ -105,28 +123,43 @@ static struct kmem_cache *ashmem_range_cachep __read_mostly;
 
 #define PROT_MASK              (PROT_EXEC | PROT_READ | PROT_WRITE)
 
+/**
+ * lru_add() - Adds a range of memory to the LRU list
+ * @range:     The memory range being added.
+ *
+ * The range is first added to the end (tail) of the LRU list.
+ * After this, the size of the range is added to @lru_count
+ */
 static inline void lru_add(struct ashmem_range *range)
 {
        list_add_tail(&range->lru, &ashmem_lru_list);
        lru_count += range_size(range);
 }
 
+/**
+ * lru_del() - Removes a range of memory from the LRU list
+ * @range:     The memory range being removed
+ *
+ * The range is first deleted from the LRU list.
+ * After this, the size of the range is removed from @lru_count
+ */
 static inline void lru_del(struct ashmem_range *range)
 {
        list_del(&range->lru);
        lru_count -= range_size(range);
 }
 
-/*
- * range_alloc - allocate and initialize a new ashmem_range structure
+/**
+ * range_alloc() - Allocates and initializes a new ashmem_range structure
+ * @asma:         The associated ashmem_area
+ * @prev_range:           The previous ashmem_range in the sorted asma->unpinned list
+ * @purged:       Initial purge status (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED)
+ * @start:        The starting page (inclusive)
+ * @end:          The ending page (inclusive)
  *
- * 'asma' - associated ashmem_area
- * 'prev_range' - the previous ashmem_range in the sorted asma->unpinned list
- * 'purged' - initial purge value (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED)
- * 'start' - starting page, inclusive
- * 'end' - ending page, inclusive
+ * This function is protected by ashmem_mutex.
  *
- * Caller must hold ashmem_mutex.
+ * Return: 0 if successful, or -ENOMEM if there is an error
  */
 static int range_alloc(struct ashmem_area *asma,
                       struct ashmem_range *prev_range, unsigned int purged,
@@ -151,6 +184,10 @@ static int range_alloc(struct ashmem_area *asma,
        return 0;
 }
 
+/**
+ * range_del() - Deletes and dealloctes an ashmem_range structure
+ * @range:      The associated ashmem_range that has previously been allocated
+ */
 static void range_del(struct ashmem_range *range)
 {
        list_del(&range->unpinned);
@@ -159,10 +196,17 @@ static void range_del(struct ashmem_range *range)
        kmem_cache_free(ashmem_range_cachep, range);
 }
 
-/*
- * range_shrink - shrinks a range
+/**
+ * range_shrink() - Shrinks an ashmem_range
+ * @range:         The associated ashmem_range being shrunk
+ * @start:         The starting byte of the new range
+ * @end:           The ending byte of the new range
  *
- * Caller must hold ashmem_mutex.
+ * This does not modify the data inside the existing range in any way - It
+ * simply shrinks the boundaries of the range.
+ *
+ * Theoretically, with a little tweaking, this could eventually be changed
+ * to range_resize, and expand the lru_count if the new range is larger.
  */
 static inline void range_shrink(struct ashmem_range *range,
                                size_t start, size_t end)
@@ -176,6 +220,16 @@ static inline void range_shrink(struct ashmem_range *range,
                lru_count -= pre - range_size(range);
 }
 
+/**
+ * ashmem_open() - Opens an Anonymous Shared Memory structure
+ * @inode:        The backing file's index node(?)
+ * @file:         The backing file
+ *
+ * Please note that the ashmem_area is not returned by this function - It is
+ * instead written to "file->private_data".
+ *
+ * Return: 0 if successful, or another code if unsuccessful.
+ */
 static int ashmem_open(struct inode *inode, struct file *file)
 {
        struct ashmem_area *asma;
@@ -197,6 +251,14 @@ static int ashmem_open(struct inode *inode, struct file *file)
        return 0;
 }
 
+/**
+ * ashmem_release() - Releases an Anonymous Shared Memory structure
+ * @ignored:         The backing file's Index Node(?) - It is ignored here.
+ * @file:            The backing file
+ *
+ * Return: 0 if successful. If it is anything else, go have a coffee and
+ * try again.
+ */
 static int ashmem_release(struct inode *ignored, struct file *file)
 {
        struct ashmem_area *asma = file->private_data;
@@ -214,6 +276,15 @@ static int ashmem_release(struct inode *ignored, struct file *file)
        return 0;
 }
 
+/**
+ * ashmem_read() - Reads a set of bytes from an Ashmem-enabled file
+ * @file:         The associated backing file.
+ * @buf:          The buffer of data being written to
+ * @len:          The number of bytes being read
+ * @pos:          The position of the first byte to read.
+ *
+ * Return: 0 if successful, or another return code if not.
+ */
 static ssize_t ashmem_read(struct file *file, char __user *buf,
                           size_t len, loff_t *pos)
 {
@@ -706,7 +777,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                .gfp_mask = GFP_KERNEL,
                                .nr_to_scan = LONG_MAX,
                        };
-
+                       ret = ashmem_shrink_count(&ashmem_shrinker, &sc);
                        nodes_setall(sc.nodes_to_scan);
                        ashmem_shrink_scan(&ashmem_shrinker, &sc);
                }
index 98ac020bf912fb8efd11872c3e992265734f510b..eaec1dab7fe489fbbc9d171a4acdf5f78d765df6 100644 (file)
@@ -1700,7 +1700,8 @@ err_no_context_mgr_node:
                thread->return_error = return_error;
 }
 
-int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
+static int binder_thread_write(struct binder_proc *proc,
+                       struct binder_thread *thread,
                        void __user *buffer, size_t size, size_t *consumed)
 {
        uint32_t cmd;
@@ -1773,7 +1774,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
                case BC_INCREFS_DONE:
                case BC_ACQUIRE_DONE: {
                        void __user *node_ptr;
-                       void *cookie;
+                       void __user *cookie;
                        struct binder_node *node;
 
                        if (get_user(node_ptr, (void * __user *)ptr))
@@ -2055,8 +2056,8 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
        return 0;
 }
 
-void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread,
-                   uint32_t cmd)
+static void binder_stat_br(struct binder_proc *proc,
+                          struct binder_thread *thread, uint32_t cmd)
 {
        trace_binder_return(cmd);
        if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) {
index ec907ab2ff5484fdfb87168b9f87ae9937582d3c..905c7cc9588e85998e6c918c09fb9f2a7884662d 100644 (file)
@@ -31,7 +31,7 @@ struct timed_output_dev {
        int             state;
 };
 
-extern int timed_output_dev_register(struct timed_output_dev *dev);
-extern void timed_output_dev_unregister(struct timed_output_dev *dev);
+int timed_output_dev_register(struct timed_output_dev *dev);
+void timed_output_dev_unregister(struct timed_output_dev *dev);
 
 #endif
index 1d8bf08b5bfd4e946a892ddc358dfd18387e2aab..9cd59871adb2af112520b873dc5eeedf6e65975e 100644 (file)
@@ -35,7 +35,7 @@ struct bcm_link_request {
 #define MAX_PROTOCOL_LENGTH   32
 #define IPV6_ADDRESS_SIZEINBYTES 0x10
 
-typedef union _U_IP_ADDRESS {
+union u_ip_address {
        struct {
                ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH]; /* Source Ip Address Range */
                ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH]; /* Source Ip Mask Address Range */
@@ -52,7 +52,7 @@ typedef union _U_IP_ADDRESS {
                UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES];
                UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES];
        };
-} U_IP_ADDRESS;
+};
 
 struct bcm_hdr_suppression_contextinfo {
        UCHAR ucaHdrSuppressionInBuf[MAX_PHS_LENGTHS]; /* Intermediate buffer to accumulate pkt Header for PHS */
@@ -63,13 +63,13 @@ struct bcm_classifier_rule {
        ULONG           ulSFID;
        UCHAR           ucReserved[2];
        B_UINT16        uiClassifierRuleIndex;
-       BOOLEAN         bUsed;
+       bool            bUsed;
        USHORT          usVCID_Value;
        B_UINT8         u8ClassifierRulePriority; /* This field detemines the Classifier Priority */
-       U_IP_ADDRESS    stSrcIpAddress;
+       union u_ip_address      stSrcIpAddress;
        UCHAR           ucIPSourceAddressLength; /* Ip Source Address Length */
 
-       U_IP_ADDRESS    stDestIpAddress;
+       union u_ip_address      stDestIpAddress;
        UCHAR           ucIPDestinationAddressLength; /* Ip Destination Address Length */
        UCHAR           ucIPTypeOfServiceLength; /* Type of service Length */
        UCHAR           ucTosLow; /* Tos Low */
@@ -86,14 +86,14 @@ struct bcm_classifier_rule {
        USHORT          usDestPortRangeHi[MAX_PORT_RANGE];
        UCHAR           ucDestPortRangeLength;
 
-       BOOLEAN         bProtocolValid;
-       BOOLEAN         bTOSValid;
-       BOOLEAN         bDestIpValid;
-       BOOLEAN         bSrcIpValid;
+       bool            bProtocolValid;
+       bool            bTOSValid;
+       bool            bDestIpValid;
+       bool            bSrcIpValid;
 
        /* For IPv6 Addressing */
        UCHAR           ucDirection;
-       BOOLEAN         bIpv6Protocol;
+       bool            bIpv6Protocol;
        UINT32          u32PHSRuleID;
        struct bcm_phs_rule sPhsRule;
        UCHAR           u8AssociatedPHSI;
@@ -113,11 +113,11 @@ struct bcm_classifier_rule {
 };
 
 struct bcm_fragmented_packet_info {
-       BOOLEAN                 bUsed;
+       bool                    bUsed;
        ULONG                   ulSrcIpAddress;
        USHORT                  usIpIdentification;
        struct bcm_classifier_rule *pstMatchedClassifierEntry;
-       BOOLEAN                 bOutOfOrderFragment;
+       bool                    bOutOfOrderFragment;
 };
 
 struct bcm_packet_info {
@@ -128,9 +128,9 @@ struct bcm_packet_info {
        /* This field determines the priority of the SF Queues */
        B_UINT8         u8TrafficPriority;
 
-       BOOLEAN         bValid;
-       BOOLEAN         bActive;
-       BOOLEAN         bActivateRequestSent;
+       bool            bValid;
+       bool            bActive;
+       bool            bActivateRequestSent;
 
        B_UINT8         u8QueueType; /* BE or rtPS */
 
@@ -170,17 +170,17 @@ struct bcm_packet_info {
                };
        };
 
-       BOOLEAN         bProtocolValid;
-       BOOLEAN         bTOSValid;
-       BOOLEAN         bDestIpValid;
-       BOOLEAN         bSrcIpValid;
+       bool            bProtocolValid;
+       bool            bTOSValid;
+       bool            bDestIpValid;
+       bool            bSrcIpValid;
 
-       BOOLEAN         bActiveSet;
-       BOOLEAN         bAdmittedSet;
-       BOOLEAN         bAuthorizedSet;
-       BOOLEAN         bClassifierPriority;
+       bool            bActiveSet;
+       bool            bAdmittedSet;
+       bool            bAuthorizedSet;
+       bool            bClassifierPriority;
        UCHAR           ucServiceClassName[MAX_CLASS_NAME_LENGTH];
-       BOOLEAN         bHeaderSuppressionEnabled;
+       bool            bHeaderSuppressionEnabled;
        spinlock_t      SFQueueLock;
        void            *pstSFIndication;
        struct timeval  stLastUpdateTokenAt;
@@ -196,8 +196,8 @@ struct bcm_tarang_data {
        struct sk_buff          *RxAppControlHead;
        struct sk_buff          *RxAppControlTail;
        int                     AppCtrlQueueLen;
-       BOOLEAN                 MacTracingEnabled;
-       BOOLEAN                 bApplicationToExit;
+       bool                    MacTracingEnabled;
+       bool                    bApplicationToExit;
        struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs;
        ULONG                   RxCntrlMsgBitMask;
 };
@@ -205,7 +205,7 @@ struct bcm_tarang_data {
 struct bcm_targetdsx_buffer {
        ULONG           ulTargetDsxBuffer;
        B_UINT16        tid;
-       BOOLEAN         valid;
+       bool            valid;
 };
 
 typedef int (*FP_FLASH_WRITE)(struct bcm_mini_adapter *, UINT, PVOID);
@@ -221,11 +221,11 @@ struct bcm_mini_adapter {
        u32                     msg_enable;
        CHAR                    *caDsxReqResp;
        atomic_t                ApplicationRunning;
-       BOOLEAN                 AppCtrlQueueOverFlow;
+       bool                    AppCtrlQueueOverFlow;
        atomic_t                CurrentApplicationCount;
        atomic_t                RegisteredApplicationCount;
-       BOOLEAN                 LinkUpStatus;
-       BOOLEAN                 TimerActive;
+       bool                    LinkUpStatus;
+       bool                    TimerActive;
        u32                     StatisticsPointer;
        struct sk_buff          *RxControlHead;
        struct sk_buff          *RxControlTail;
@@ -249,25 +249,25 @@ struct bcm_mini_adapter {
        UINT                    u32TotalDSD;
        struct bcm_packet_info  PackInfo[NO_OF_QUEUES];
        struct bcm_classifier_rule astClassifierTable[MAX_CLASSIFIERS];
-       BOOLEAN                 TransferMode;
+       bool                    TransferMode;
 
        /*************** qos ******************/
-       BOOLEAN                 bETHCSEnabled;
+       bool                    bETHCSEnabled;
        ULONG                   BEBucketSize;
        ULONG                   rtPSBucketSize;
        UCHAR                   LinkStatus;
-       BOOLEAN                 AutoLinkUp;
-       BOOLEAN                 AutoSyncup;
+       bool                    AutoLinkUp;
+       bool                    AutoSyncup;
 
        int                     major;
        int                     minor;
        wait_queue_head_t       tx_packet_wait_queue;
        wait_queue_head_t       process_rx_cntrlpkt;
        atomic_t                process_waiting;
-       BOOLEAN                 fw_download_done;
+       bool                    fw_download_done;
 
        char                    *txctlpacket[MAX_CNTRL_PKTS];
-       atomic_t                cntrlpktCnt ;
+       atomic_t                cntrlpktCnt;
        atomic_t                index_app_read_cntrlpkt;
        atomic_t                index_wr_txcntrlpkt;
        atomic_t                index_rd_txcntrlpkt;
@@ -280,19 +280,19 @@ struct bcm_mini_adapter {
        ULONG                   ulTotalTargetBuffersAvailable;
        unsigned long           chip_id;
        wait_queue_head_t       lowpower_mode_wait_queue;
-       BOOLEAN                 bFlashBoot;
-       BOOLEAN                 bBinDownloaded;
-       BOOLEAN                 bCfgDownloaded;
-       BOOLEAN                 bSyncUpRequestSent;
+       bool                    bFlashBoot;
+       bool                    bBinDownloaded;
+       bool                    bCfgDownloaded;
+       bool                    bSyncUpRequestSent;
        USHORT                  usBestEffortQueueIndex;
        wait_queue_head_t       ioctl_fw_dnld_wait_queue;
-       BOOLEAN                 waiting_to_fw_download_done;
+       bool                    waiting_to_fw_download_done;
        pid_t                   fw_download_process_pid;
        struct bcm_target_params *pstargetparams;
-       BOOLEAN                 device_removed;
-       BOOLEAN                 DeviceAccess;
-       BOOLEAN                 bIsAutoCorrectEnabled;
-       BOOLEAN                 bDDRInitDone;
+       bool                    device_removed;
+       bool                    DeviceAccess;
+       bool                    bIsAutoCorrectEnabled;
+       bool                    bDDRInitDone;
        int                     DDRSetting;
        ULONG                   ulPowerSaveMode;
        spinlock_t              txtransmitlock;
@@ -324,22 +324,22 @@ struct bcm_mini_adapter {
                        PVOID,
                        int);
        int (*interface_transmit)(PVOID, PVOID , UINT);
-       BOOLEAN                 IdleMode;
-       BOOLEAN                 bDregRequestSentInIdleMode;
-       BOOLEAN                 bTriedToWakeUpFromlowPowerMode;
-       BOOLEAN                 bShutStatus;
-       BOOLEAN                 bWakeUpDevice;
+       bool                    IdleMode;
+       bool                    bDregRequestSentInIdleMode;
+       bool                    bTriedToWakeUpFromlowPowerMode;
+       bool                    bShutStatus;
+       bool                    bWakeUpDevice;
        unsigned int            usIdleModePattern;
        /* BOOLEAN                      bTriedToWakeUpFromShutdown; */
-       BOOLEAN                 bLinkDownRequested;
+       bool                    bLinkDownRequested;
        int                     downloadDDR;
        struct bcm_phs_extension stBCMPhsContext;
        struct bcm_hdr_suppression_contextinfo stPhsTxContextInfo;
        uint8_t                 ucaPHSPktRestoreBuf[2048];
        uint8_t                 bPHSEnabled;
-       BOOLEAN                 AutoFirmDld;
-       BOOLEAN                 bMipsConfig;
-       BOOLEAN                 bDPLLConfig;
+       bool                    AutoFirmDld;
+       bool                    bMipsConfig;
+       bool                    bDPLLConfig;
        UINT32                  aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
        UINT32                  aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
        struct bcm_fragmented_packet_info astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES];
@@ -348,8 +348,8 @@ struct bcm_mini_adapter {
        enum bcm_nvm_type       eNVMType;
        UINT                    uiSectorSize;
        UINT                    uiSectorSizeInCFG;
-       BOOLEAN                 bSectorSizeOverride;
-       BOOLEAN                 bStatusWrite;
+       bool                    bSectorSizeOverride;
+       bool                    bStatusWrite;
        UINT                    uiNVMDSDSize;
        UINT                    uiVendorExtnFlag;
        /* it will always represent chosen DSD at any point of time.
@@ -376,18 +376,18 @@ struct bcm_mini_adapter {
        UINT                    uiActiveDSDOffsetAtFwDld;  /* For accessing Active DSD chosen before f/w download */
        UINT                    uiFlashLayoutMajorVersion;
        UINT                    uiFlashLayoutMinorVersion;
-       BOOLEAN                 bAllDSDWriteAllow;
-       BOOLEAN                 bSigCorrupted;
+       bool                    bAllDSDWriteAllow;
+       bool                    bSigCorrupted;
        /* this should be set who so ever want to change the Headers. after Wrtie it should be reset immediately. */
-       BOOLEAN                 bHeaderChangeAllowed;
+       bool                    bHeaderChangeAllowed;
        int                     SelectedChip;
-       BOOLEAN                 bEndPointHalted;
+       bool                    bEndPointHalted;
        /* while bFlashRawRead will be true, Driver  ignore map lay out and consider flash as of without any map. */
-       BOOLEAN                 bFlashRawRead;
-       BOOLEAN                 bPreparingForLowPowerMode;
-       BOOLEAN                 bDoSuspend;
+       bool                    bFlashRawRead;
+       bool                    bPreparingForLowPowerMode;
+       bool                    bDoSuspend;
        UINT                    syscfgBefFwDld;
-       BOOLEAN                 StopAllXaction;
+       bool                    StopAllXaction;
        UINT32                  liTimeSinceLastNetEntry; /* Used to Support extended CAPI requirements from */
        struct semaphore        LowPowerModeSync;
        ULONG                   liDrainCalculated;
index 639ba96adb36b58e1c21b6ae037f084be512cdfc..87b74ca84c42154eac8c8715deea37f5b20aa5ce 100644 (file)
@@ -49,11 +49,8 @@ static int bcm_char_release(struct inode *inode, struct file *filp)
 
        pTarang = (struct bcm_tarang_data *)filp->private_data;
 
-       if (pTarang == NULL) {
-               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-                               "ptarang is null\n");
+       if (pTarang == NULL)
                return 0;
-       }
 
        Adapter = pTarang->Adapter;
 
@@ -119,7 +116,7 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size,
                return -ENODEV;
        }
 
-       if (FALSE == Adapter->fw_download_done)
+       if (false == Adapter->fw_download_done)
                return -EACCES;
 
        down(&Adapter->RxAppControlQueuelock);
@@ -180,7 +177,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
        if (Adapter->device_removed)
                return -EFAULT;
 
-       if (FALSE == Adapter->fw_download_done) {
+       if (false == Adapter->fw_download_done) {
                switch (cmd) {
                case IOCTL_MAC_ADDR_REQ:
                case IOCTL_LINK_REQ:
@@ -425,7 +422,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                uiOperation = gpio_info.uiGpioValue;
                value = (1<<uiBit);
 
-               if (IsReqGpioIsLedInNVM(Adapter, value) == FALSE) {
+               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);
                        Status = -EINVAL;
                        break;
@@ -572,7 +569,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
                        return -EFAULT;
 
-               if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == FALSE) {
+               if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
                        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);
@@ -665,7 +662,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                }
 
                /* Validating the request */
-               if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == FALSE) {
+               if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == false) {
                        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_mode[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap);
@@ -768,10 +765,10 @@ cntrlEnd:
                if (down_trylock(&Adapter->fw_download_sema))
                        return -EBUSY;
 
-               Adapter->bBinDownloaded = FALSE;
+               Adapter->bBinDownloaded = false;
                Adapter->fw_download_process_pid = current->pid;
-               Adapter->bCfgDownloaded = FALSE;
-               Adapter->fw_download_done = FALSE;
+               Adapter->bCfgDownloaded = false;
+               Adapter->fw_download_done = false;
                netif_carrier_off(Adapter->dev);
                netif_stop_queue(Adapter->dev);
                Status = reset_card_proc(Adapter);
@@ -848,7 +845,7 @@ cntrlEnd:
 
                        if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
                                Adapter->DriverState = DRIVER_INIT;
-                               Adapter->LEDInfo.bLedInitDone = FALSE;
+                               Adapter->LEDInfo.bLedInitDone = false;
                                wake_up(&Adapter->LEDInfo.notify_led_event);
                        }
                }
@@ -900,7 +897,7 @@ cntrlEnd:
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
 
                timeout = 5*HZ;
-               Adapter->waiting_to_fw_download_done = FALSE;
+               Adapter->waiting_to_fw_download_done = false;
                wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
                                Adapter->waiting_to_fw_download_done, timeout);
                Adapter->fw_download_process_pid = INVALID_PID;
@@ -1052,7 +1049,7 @@ cntrlEnd:
                if (tracing_flag)
                        Adapter->pTarangs->MacTracingEnabled = TRUE;
                else
-                       Adapter->pTarangs->MacTracingEnabled = FALSE;
+                       Adapter->pTarangs->MacTracingEnabled = false;
                break;
        }
 
@@ -1109,7 +1106,7 @@ cntrlEnd:
        }
 
        case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
-               if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE == Adapter->IdleMode)) {
+               if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE == Adapter->IdleMode)) {
                        Adapter->usIdleModePattern = ABORT_IDLE_MODE;
                        Adapter->bWakeUpDevice = TRUE;
                        wake_up(&Adapter->process_rx_cntrlpkt);
@@ -1168,7 +1165,7 @@ cntrlEnd:
                        break;
                }
 
-               if (pBulkBuffer->SwapEndian == FALSE)
+               if (pBulkBuffer->SwapEndian == false)
                        Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
                else
                        Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
@@ -1387,7 +1384,7 @@ cntrlEnd:
                        if (IsFlash2x(Adapter))
                                BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);
 
-                       Adapter->bHeaderChangeAllowed = FALSE;
+                       Adapter->bHeaderChangeAllowed = false;
 
                        up(&Adapter->NVMRdmWrmLock);
 
@@ -1432,7 +1429,7 @@ cntrlEnd:
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify);
 
                /* This was internal to driver for raw read. now it has ben exposed to user space app. */
-               if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == FALSE)
+               if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == false)
                        return STATUS_FAILURE;
 
                NOB = sFlash2xRead.numOfBytes;
@@ -1510,7 +1507,7 @@ cntrlEnd:
                }
 
                /* First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite */
-               Adapter->bAllDSDWriteAllow = FALSE;
+               Adapter->bAllDSDWriteAllow = false;
 
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
 
@@ -1531,7 +1528,7 @@ cntrlEnd:
                        return -EINVAL;
                }
 
-               if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == FALSE)
+               if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == false)
                        return STATUS_FAILURE;
 
                InputAddr = sFlash2xWrite.pDataBuff;
@@ -1686,7 +1683,7 @@ cntrlEnd:
 
        case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION: {
                /* Right Now we are taking care of only DSD */
-               Adapter->bAllDSDWriteAllow = FALSE;
+               Adapter->bAllDSDWriteAllow = false;
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
                Status = STATUS_SUCCESS;
        }
@@ -1697,7 +1694,7 @@ cntrlEnd:
                Status = STATUS_SUCCESS;
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION  Called");
 
-               Adapter->bAllDSDWriteAllow = FALSE;
+               Adapter->bAllDSDWriteAllow = false;
                if (IsFlash2x(Adapter) != TRUE) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map");
                        return -EINVAL;
@@ -1720,12 +1717,12 @@ cntrlEnd:
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset);
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes);
 
-               if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == FALSE) {
+               if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == false) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection);
                        return -EINVAL;
                }
 
-               if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == FALSE) {
+               if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == false) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection);
                        return -EINVAL;
                }
@@ -1924,7 +1921,7 @@ cntrlEnd:
                                OutPutBuff = OutPutBuff + ReadBytes;
                        }
                }
-               Adapter->bFlashRawRead = FALSE;
+               Adapter->bFlashRawRead = false;
                up(&Adapter->NVMRdmWrmLock);
                kfree(pReadBuff);
                break;
index 4e470d4bb4e8f297c15ab40825f66e0ab7c9c239..53fee2f9a498866c6a19d3d6c3ca1d078fd7206e 100644 (file)
@@ -6,7 +6,7 @@ static INT bcm_open(struct net_device *dev)
 {
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
 
-       if (Adapter->fw_download_done == FALSE) {
+       if (Adapter->fw_download_done == false) {
                pr_notice(PFX "%s: link up failed (download in progress)\n",
                          dev->name);
                return -EBUSY;
@@ -142,7 +142,8 @@ static void bcm_get_drvinfo(struct net_device *dev,
                            struct ethtool_drvinfo *info)
 {
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
-       struct bcm_interface_adapter *psIntfAdapter = Adapter->pvInterfaceAdapter;
+       struct bcm_interface_adapter *psIntfAdapter =
+                                               Adapter->pvInterfaceAdapter;
        struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
 
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
index 976514502927a116466ca5cc5ec3181148a20b4b..cc91b5e934aa0f73e4aa43a5a7ded9333e9ffd28 100644 (file)
@@ -113,7 +113,7 @@ static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIn
 static inline VOID
 CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry,
                B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc,
-               BOOLEAN bIpVersion6, enum bcm_ipaddr_context eIpAddrContext)
+               bool bIpVersion6, enum bcm_ipaddr_context eIpAddrContext)
 {
        int i = 0;
        UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS;
@@ -213,7 +213,7 @@ CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry,
        }
 }
 
-void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, BOOLEAN bFreeAll)
+void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, bool bFreeAll)
 {
        int i;
 
@@ -256,7 +256,7 @@ static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, stru
        pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
        if (pstClassifierEntry) {
                /* Store if Ipv6 */
-               pstClassifierEntry->bIpv6Protocol = (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : FALSE;
+               pstClassifierEntry->bIpv6Protocol = (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : false;
 
                /* Destinaiton Port */
                pstClassifierEntry->ucDestPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength / 4;
@@ -301,7 +301,7 @@ static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, stru
                                psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength,
                                psfCSType->cCPacketClassificationRule.u8IPDestinationAddress,
                                (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ?
-                       TRUE : FALSE, eDestIpAddress);
+                       TRUE : false, eDestIpAddress);
 
                /* Source Ip Address and Mask */
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Source Parameters : ");
@@ -309,7 +309,7 @@ static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, stru
                CopyIpAddrToClassifier(pstClassifierEntry,
                                psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength,
                                psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress,
-                               (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : FALSE,
+                               (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : false,
                                eSrcIpAddress);
 
                /* TOS */
@@ -383,7 +383,7 @@ static inline VOID DeleteClassifierRuleFromSF(struct bcm_mini_adapter *Adapter,
        u16PacketClassificationRuleIndex = Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex;
        pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
        if (pstClassifierEntry) {
-               pstClassifierEntry->bUsed = FALSE;
+               pstClassifierEntry->bUsed = false;
                pstClassifierEntry->uiClassifierRuleIndex = 0;
                memset(pstClassifierEntry, 0, sizeof(struct bcm_classifier_rule));
 
@@ -685,7 +685,7 @@ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer
                                                        memcpy(sPhsRule.u8PHSF, psfCSType->cPhsRule.u8PHSF, MAX_PHS_LENGTHS);
                                                        memcpy(sPhsRule.u8PHSM, psfCSType->cPhsRule.u8PHSM, MAX_PHS_LENGTHS);
                                                        sPhsRule.u8RefCnt = 0;
-                                                       sPhsRule.bUnclassifiedPHSRule = FALSE;
+                                                       sPhsRule.bUnclassifiedPHSRule = false;
                                                        sPhsRule.PHSModifiedBytes = 0;
                                                        sPhsRule.PHSModifiedNumPackets = 0;
                                                        sPhsRule.PHSErrorNumPackets = 0;
@@ -837,7 +837,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
        UINT nCurClassifierCnt;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
 
-       pstAddIndication = (struct bcm_add_indication_alt *)pvBuffer;
+       pstAddIndication = pvBuffer;
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>");
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type);
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction);
@@ -1339,14 +1339,14 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu
        UINT uiSearchRuleIndex;
        ULONG ulSFID;
 
-       pstAddIndicationAlt = (struct bcm_add_indication_alt *)(pvBuffer);
+       pstAddIndicationAlt = pvBuffer;
 
        /*
         * In case of DSD Req By MS, we should immediately delete this SF so that
         * we can stop the further classifying the pkt for this SF.
         */
        if (pstAddIndicationAlt->u8Type == DSD_REQ) {
-               pstDeletionRequest = (struct bcm_del_request *)pvBuffer;
+               pstDeletionRequest = pvBuffer;
 
                ulSFID = ntohl(pstDeletionRequest->u32SFID);
                uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);
@@ -1452,12 +1452,12 @@ static inline struct bcm_add_indication_alt
        struct bcm_add_indication *pstAddIndication = NULL;
        struct bcm_add_indication_alt *pstAddIndicationDest = NULL;
 
-       pstAddIndication = (struct bcm_add_indication *)(pvBuffer);
+       pstAddIndication = pvBuffer;
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>");
        if ((pstAddIndication->u8Type == DSD_REQ) ||
                (pstAddIndication->u8Type == DSD_RSP) ||
                (pstAddIndication->u8Type == DSD_ACK))
-               return (struct bcm_add_indication_alt *)pvBuffer;
+               return pvBuffer;
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage ");
        /*
@@ -1577,7 +1577,7 @@ static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UIN
        ULONG idx, max_try;
 
        if ((Adapter->ulTotalTargetBuffersAvailable == 0) || (Adapter->ulFreeTargetBufferCnt == 0)) {
-               ClearTargetDSXBuffer(Adapter, tid, FALSE);
+               ClearTargetDSXBuffer(Adapter, tid, false);
                return 0;
        }
 
@@ -1590,7 +1590,7 @@ static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UIN
 
        if (max_try == 0) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", Adapter->ulFreeTargetBufferCnt);
-               ClearTargetDSXBuffer(Adapter, tid, FALSE);
+               ClearTargetDSXBuffer(Adapter, tid, false);
                return 0;
        }
 
@@ -1630,7 +1630,7 @@ int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter)
  * for the Connection Management.
  * @return - Queue index for the free SFID else returns Invalid Index.
  */
-BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer to the Adapter structure */
+bool CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer to the Adapter structure */
                                PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */)
 {
        struct bcm_connect_mgr_params *psfLocalSet = NULL;
@@ -1644,9 +1644,9 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
         */
        pstAddIndication = RestoreCmControlResponseMessage(Adapter, pvBuffer);
        if (pstAddIndication == NULL) {
-               ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication *)pvBuffer)->u16TID, FALSE);
+               ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication *)pvBuffer)->u16TID, false);
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message");
-               return FALSE;
+               return false;
        }
 
        DumpCmControlPacket(pstAddIndication);
@@ -1656,7 +1656,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
        pLeader->Status = CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ;
        pLeader->Vcid = 0;
 
-       ClearTargetDSXBuffer(Adapter, pstAddIndication->u16TID, FALSE);
+       ClearTargetDSXBuffer(Adapter, pstAddIndication->u16TID, false);
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n", pstAddIndication->u16TID);
        switch (pstAddIndication->u8Type) {
        case DSA_REQ:
@@ -1708,9 +1708,9 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
                        if (pstAddIndication->sfAdmittedSet.bValid == TRUE)
                                Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE;
 
-                       if (pstAddIndication->sfActiveSet.bValid == FALSE) {
-                               Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-                               Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
+                       if (pstAddIndication->sfActiveSet.bValid == false) {
+                               Adapter->PackInfo[uiSearchRuleIndex].bActive = false;
+                               Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = false;
                                if (pstAddIndication->sfAdmittedSet.bValid)
                                        psfLocalSet = &pstAddIndication->sfAdmittedSet;
                                else if (pstAddIndication->sfAuthorizedSet.bValid)
@@ -1722,8 +1722,8 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
 
                        if (!psfLocalSet) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n");
-                               Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-                               Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE;
+                               Adapter->PackInfo[uiSearchRuleIndex].bActive = false;
+                               Adapter->PackInfo[uiSearchRuleIndex].bValid = false;
                                Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0;
                                kfree(pstAddIndication);
                        } else if (psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) {
@@ -1759,15 +1759,15 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
                                        }
                                }
                        } else {
-                               Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-                               Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE;
+                               Adapter->PackInfo[uiSearchRuleIndex].bActive = false;
+                               Adapter->PackInfo[uiSearchRuleIndex].bValid = false;
                                Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0;
                                kfree(pstAddIndication);
                        }
                } else {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
                        kfree(pstAddIndication);
-                       return FALSE;
+                       return false;
                }
        }
        break;
@@ -1812,9 +1812,9 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
                        if (pstChangeIndication->sfAdmittedSet.bValid == TRUE)
                                Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE;
 
-                       if (pstChangeIndication->sfActiveSet.bValid == FALSE) {
-                               Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-                               Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
+                       if (pstChangeIndication->sfActiveSet.bValid == false) {
+                               Adapter->PackInfo[uiSearchRuleIndex].bActive = false;
+                               Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = false;
 
                                if (pstChangeIndication->sfAdmittedSet.bValid)
                                        psfLocalSet = &pstChangeIndication->sfAdmittedSet;
@@ -1827,8 +1827,8 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
 
                        if (!psfLocalSet) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n");
-                               Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-                               Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE;
+                               Adapter->PackInfo[uiSearchRuleIndex].bActive = false;
+                               Adapter->PackInfo[uiSearchRuleIndex].bValid = false;
                                Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0;
                                kfree(pstAddIndication);
                        } else if (psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) {
@@ -1847,7 +1847,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
                } else {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
                        kfree(pstAddIndication);
-                       return FALSE;
+                       return false;
                }
        }
        break;
@@ -1883,7 +1883,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter,  /* <Pointer
                break;
        default:
                kfree(pstAddIndication);
-               return FALSE;
+               return false;
        }
        return TRUE;
 }
@@ -1934,13 +1934,13 @@ VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer
                        continue;
                }
 
-               if (pHostInfo->RetainSF == FALSE) {
+               if (pHostInfo->RetainSF == false) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Going to Delete SF");
                        deleteSFBySfid(Adapter, uiSearchRuleIndex);
                } else {
                        Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pHostInfo->VCID);
                        Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pHostInfo->newCID);
-                       Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+                       Adapter->PackInfo[uiSearchRuleIndex].bActive = false;
 
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "pHostInfo->QoSParamSet: 0x%x\n", pHostInfo->QoSParamSet);
 
index 4ddfc3d45bc0145d9be4bb4d1efe936d3c5500e8..0887d3f49e2f5e219bdf2bbfb37e9ac8139cfde7 100644 (file)
@@ -55,7 +55,7 @@ unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, vo
 int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
 int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
 unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter);
-BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer);
+bool CmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer);
 
 #pragma pack(pop)
 
index f5eda96f0f83786d3bb58603db7add394a0e06c5..9f7e30f637eaff41d0f0128fd315cd5f5ce3960f 100644 (file)
@@ -1106,7 +1106,7 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
        unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY;
        UINT  value = 0;
        int retval = STATUS_SUCCESS;
-       BOOLEAN bOverrideSelfRefresh = FALSE;
+       bool bOverrideSelfRefresh = false;
 
        switch (Adapter->chip_id)
        {
index 1bb53e247a6254bcea91c2d83a62cdf5653b5677..495fe3dc514874b5b57f2773f2516a62d3046bff 100644 (file)
 static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
 {
        struct bcm_tarang_data *pTarang = NULL;
-       BOOLEAN HighPriorityMessage = FALSE;
+       bool HighPriorityMessage = false;
        struct sk_buff *newPacket = NULL;
        CHAR cntrl_msg_mask_bit = 0;
-       BOOLEAN drop_pkt_flag = TRUE;
+       bool drop_pkt_flag = TRUE;
        USHORT usStatus = *(PUSHORT)(skb->data);
 
        if (netif_msg_pktdata(Adapter))
@@ -91,13 +91,13 @@ static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk
                 *      cntrl_msg_mask_bit);
                 */
                if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit))
-                       drop_pkt_flag = FALSE;
+                       drop_pkt_flag = false;
 
                if ((drop_pkt_flag == TRUE) ||
                                (pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN)
                                || ((pTarang->AppCtrlQueueLen >
                                        MAX_APP_QUEUE_LEN / 2) &&
-                                   (HighPriorityMessage == FALSE))) {
+                                   (HighPriorityMessage == false))) {
                        /*
                         * Assumption:-
                         * 1. every tarang manages it own dropped pkt
@@ -175,8 +175,8 @@ int control_packet_handler(struct bcm_mini_adapter *Adapter /* pointer to adapte
                        return 0;
                }
                if (TRUE == Adapter->bWakeUpDevice) {
-                       Adapter->bWakeUpDevice = FALSE;
-                       if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode)
+                       Adapter->bWakeUpDevice = false;
+                       if ((false == Adapter->bTriedToWakeUpFromlowPowerMode)
                                        && ((TRUE == Adapter->IdleMode) ||
                                            (TRUE == Adapter->bShutStatus))) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
index 6d803e7b094a819a8d76efe0879d15da4e48eec9..cd160670e028e6bc465edc4b84c4ff43a89506aa 100644 (file)
@@ -1,13 +1,13 @@
 #include "headers.h"
 
-static BOOLEAN MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
+static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
        struct bcm_ipv6_hdr *pstIpv6Header);
-static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
+static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
        struct bcm_ipv6_hdr *pstIpv6Header);
 static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header);
 
 static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
-       UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength)
+       UCHAR *pucNextHeader, bool *bParseDone, USHORT *pusPayloadLength)
 {
        UCHAR *pucRetHeaderPtr = NULL;
        UCHAR *pucPayloadPtr = NULL;
@@ -29,7 +29,7 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
        }
 
        /* Get the Nextt Header Type */
-       *bParseDone = FALSE;
+       *bParseDone = false;
 
 
        switch (*pucNextHeader) {
@@ -124,7 +124,7 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
 
        }
 
-       if (*bParseDone == FALSE) {
+       if (*bParseDone == false) {
                if (*pusPayloadLength <= usNextHeaderOffset) {
                        *bParseDone = TRUE;
                } else {
@@ -144,7 +144,7 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort,
        USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader)
 {
        UCHAR *pIpv6HdrScanContext = pucPayload;
-       BOOLEAN bDone = FALSE;
+       bool bDone = false;
        UCHAR ucHeaderType = 0;
        UCHAR *pucNextHeader = NULL;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -187,12 +187,12 @@ USHORT    IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
        USHORT  ushSrcPort = 0;
        UCHAR   ucNextProtocolAboveIP = 0;
        struct bcm_ipv6_hdr *pstIpv6Header = NULL;
-       BOOLEAN bClassificationSucceed = FALSE;
+       bool bClassificationSucceed = false;
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
                        DBG_LVL_ALL, "IpVersion6 ==========>\n");
 
-       pstIpv6Header = (struct bcm_ipv6_hdr *)pcIpHeader;
+       pstIpv6Header = pcIpHeader;
 
        DumpIpv6Header(pstIpv6Header);
 
@@ -277,10 +277,10 @@ USHORT    IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
                INT iMatchedSFQueueIndex = 0;
                iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
                if (iMatchedSFQueueIndex >= NO_OF_QUEUES) {
-                       bClassificationSucceed = FALSE;
+                       bClassificationSucceed = false;
                } else {
-                       if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == FALSE)
-                               bClassificationSucceed = FALSE;
+                       if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false)
+                               bClassificationSucceed = false;
                }
        }
 
@@ -288,7 +288,7 @@ USHORT      IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
 }
 
 
-static BOOLEAN MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
+static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
        struct bcm_ipv6_hdr *pstIpv6Header)
 {
        UINT uiLoopIndex = 0;
@@ -341,10 +341,10 @@ static BOOLEAN MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule
                        }
                }
        }
-       return FALSE;
+       return false;
 }
 
-static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
+static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
        struct bcm_ipv6_hdr *pstIpv6Header)
 {
        UINT uiLoopIndex = 0;
@@ -398,7 +398,7 @@ static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRul
                        }
                }
        }
-       return FALSE;
+       return false;
 
 }
 
index 348ad75b340dddcda08338d1c2f90a1a5e900001..463bdee9dfcafb02f97f2bfecfb90fe153a070cb 100644 (file)
@@ -6,7 +6,7 @@ int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
        mm_segment_t oldfs = {0};
        int errno = 0, len = 0; /* ,is_config_file = 0 */
        loff_t pos = 0;
-       struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
+       struct bcm_interface_adapter *psIntfAdapter = arg;
        /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
        char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
 
@@ -61,7 +61,7 @@ int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_c
        loff_t pos = 0;
        static int fw_down;
        INT Status = STATUS_SUCCESS;
-       struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
+       struct bcm_interface_adapter *psIntfAdapter = arg;
        int bytes;
 
        buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
@@ -166,7 +166,7 @@ static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm
        }
 
        if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
-               Adapter->LEDInfo.bLedInitDone = FALSE;
+               Adapter->LEDInfo.bLedInitDone = false;
                Adapter->DriverState = DRIVER_INIT;
                wake_up(&Adapter->LEDInfo.notify_led_event);
        }
@@ -214,7 +214,7 @@ int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_
         * Firmware. Check for the Config file to be first to be sent from the
         * Application
         */
-       atomic_set(&Adapter->uiMBupdate, FALSE);
+       atomic_set(&Adapter->uiMBupdate, false);
        if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
                /* Can't Download Firmware. */
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n");
index 5347828660429917b1946f31391d52552a935fd4..5959fbdcd1bef322bbc6b823cb8e5d4a20b31413 100644 (file)
@@ -89,8 +89,8 @@ int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *pui
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode");
 
                        /* Set Idle Mode Flag to False and Clear IdleMode reg. */
-                       Adapter->IdleMode = FALSE;
-                       Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
+                       Adapter->IdleMode = false;
+                       Adapter->bTriedToWakeUpFromlowPowerMode = false;
 
                        wake_up(&Adapter->lowpower_mode_wait_queue);
 
index 79058ce5b332b00cd344c33d8cba05e3a5f6a134..3acdb58a10f58d7637f7702a70aae1cc3c73f0f2 100644 (file)
@@ -332,7 +332,7 @@ static int device_run(struct bcm_interface_adapter *psIntfAdapter)
                 * now register the cntrl interface.
                 * after downloading the f/w waiting for 5 sec to get the mailbox interrupt.
                 */
-               psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE;
+               psIntfAdapter->psAdapter->waiting_to_fw_download_done = false;
                value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
                                        psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ);
 
@@ -430,7 +430,7 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
        unsigned long value;
        int retval = 0;
        int usedIntOutForBulkTransfer = 0 ;
-       BOOLEAN bBcm16 = FALSE;
+       bool bBcm16 = false;
        UINT uiData = 0;
        int bytes;
 
@@ -472,7 +472,7 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
                                retval = usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1);
                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
                                "BCM16 is applicable on this dongle\n");
-                       if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) {
+                       if (retval || (psIntfAdapter->bHighSpeedDevice == false)) {
                                usedIntOutForBulkTransfer = EP2 ;
                                endpoint = &iface_desc->endpoint[EP2].desc;
                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
@@ -481,8 +481,8 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
                                 * If Modem is high speed device EP2 should be INT OUT End point
                                 * If Mode is FS then EP2 should be bulk end point
                                 */
-                               if (((psIntfAdapter->bHighSpeedDevice == TRUE) && (bcm_usb_endpoint_is_int_out(endpoint) == FALSE))
-                                       || ((psIntfAdapter->bHighSpeedDevice == FALSE) && (bcm_usb_endpoint_is_bulk_out(endpoint) == FALSE))) {
+                               if (((psIntfAdapter->bHighSpeedDevice == TRUE) && (bcm_usb_endpoint_is_int_out(endpoint) == false))
+                                       || ((psIntfAdapter->bHighSpeedDevice == false) && (bcm_usb_endpoint_is_bulk_out(endpoint) == false))) {
                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
                                                "Configuring the EEPROM\n");
                                        /* change the EP2, EP4 to INT OUT end point */
@@ -501,7 +501,7 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
                                        }
 
                                }
-                               if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) {
+                               if ((psIntfAdapter->bHighSpeedDevice == false) && bcm_usb_endpoint_is_bulk_out(endpoint)) {
                                        /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
                                        UINT _uiData = ntohl(EP2_CFG_INT);
                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
@@ -513,7 +513,7 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
                                endpoint = &iface_desc->endpoint[EP4].desc;
                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
                                        "Choosing AltSetting as a default setting.\n");
-                               if (bcm_usb_endpoint_is_int_out(endpoint) == FALSE) {
+                               if (bcm_usb_endpoint_is_int_out(endpoint) == false) {
                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
                                                "Dongle does not have BCM16 Fix.\n");
                                        /* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */
@@ -619,7 +619,7 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
        psIntfAdapter->bSuspended = TRUE;
 
        if (TRUE == psIntfAdapter->bPreparingForBusSuspend) {
-               psIntfAdapter->bPreparingForBusSuspend = FALSE;
+               psIntfAdapter->bPreparingForBusSuspend = false;
 
                if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) {
                        psIntfAdapter->psAdapter->IdleMode = TRUE ;
@@ -631,7 +631,7 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
                                "Host Entered in PMU Shutdown Mode.\n");
                }
        }
-       psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE;
+       psIntfAdapter->psAdapter->bPreparingForLowPowerMode = false;
 
        /* Signaling the control pkt path */
        wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue);
@@ -644,7 +644,7 @@ static int InterfaceResume(struct usb_interface *intf)
        struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
 
        mdelay(100);
-       psIntfAdapter->bSuspended = FALSE;
+       psIntfAdapter->bSuspended = false;
 
        StartInterruptUrb(psIntfAdapter);
        InterfaceRx(psIntfAdapter);
index 8322f1b76e2ab9698482730a8073612ccf445335..7b39f4f5f1ab46aa2412b94766338ef47d883e0c 100644 (file)
@@ -60,7 +60,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
                                psIntfAdapter->psAdapter->downloadDDR +=1;
                                wake_up(&Adapter->tx_packet_wait_queue);
                        }
-                       if(FALSE == Adapter->waiting_to_fw_download_done)
+                       if(false == Adapter->waiting_to_fw_download_done)
                        {
                                Adapter->waiting_to_fw_download_done = TRUE;
                                wake_up(&Adapter->ioctl_fw_dnld_wait_queue);
@@ -147,11 +147,11 @@ INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
 {
        INT status = 0;
 
-       if( FALSE == psIntfAdapter->psAdapter->device_removed &&
-               FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
-               FALSE == psIntfAdapter->bSuspended &&
-               FALSE == psIntfAdapter->bPreparingForBusSuspend &&
-               FALSE == psIntfAdapter->psAdapter->StopAllXaction)
+       if( false == psIntfAdapter->psAdapter->device_removed &&
+               false == psIntfAdapter->psAdapter->bEndPointHalted &&
+               false == psIntfAdapter->bSuspended &&
+               false == psIntfAdapter->bPreparingForBusSuspend &&
+               false == psIntfAdapter->psAdapter->StopAllXaction)
        {
                status = usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
                if (status)
index afca010f9db59b0ccc48820cedfabfa2163f2f31..4173fd7d671c3fac2d3841b7443c0bf1407c1da0 100644 (file)
@@ -44,7 +44,7 @@ int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
        else
                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes);
 
-       psIntfAdapter->psAdapter->DeviceAccess = FALSE;
+       psIntfAdapter->psAdapter->DeviceAccess = false;
        return bytes;
 }
 
@@ -90,10 +90,10 @@ int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
 
        if (retval < 0) {
                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d", retval);
-               psIntfAdapter->psAdapter->DeviceAccess = FALSE;
+               psIntfAdapter->psAdapter->DeviceAccess = false;
                return retval;
        } else {
-               psIntfAdapter->psAdapter->DeviceAccess = FALSE;
+               psIntfAdapter->psAdapter->DeviceAccess = false;
                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
                return STATUS_SUCCESS;
        }
@@ -104,7 +104,7 @@ int BcmRDM(void *arg,
        void *buff,
        int len)
 {
-       return InterfaceRDM((struct bcm_interface_adapter*)arg, addr, buff, len);
+       return InterfaceRDM((struct bcm_interface_adapter *)arg, addr, buff, len);
 }
 
 int BcmWRM(void *arg,
@@ -211,7 +211,7 @@ void putUsbSuspend(struct work_struct *work)
        psIntfAdapter = container_of(work, struct bcm_interface_adapter, usbSuspendWork);
        intf = psIntfAdapter->interface;
 
-       if (psIntfAdapter->bSuspended == FALSE)
+       if (psIntfAdapter->bSuspended == false)
                usb_autopm_put_interface(intf);
 }
 
index 26f5bc76111c59574d41870d384fd82f039e423a..f2973f5e503a45d7c5d71b7a4004f0964ec3e308 100644 (file)
@@ -19,7 +19,7 @@ GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter)
        UINT index = 0;
 
        if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
-               (psIntfAdapter->psAdapter->StopAllXaction == FALSE))
+               (psIntfAdapter->psAdapter->StopAllXaction == false))
        {
                index = atomic_read(&psIntfAdapter->uCurrRcb);
                pRcb = &psIntfAdapter->asUsbRcb[index];
@@ -38,7 +38,7 @@ GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter)
 static void read_bulk_callback(struct urb *urb)
 {
        struct sk_buff *skb = NULL;
-       BOOLEAN bHeaderSupressionEnabled = FALSE;
+       bool bHeaderSupressionEnabled = false;
        int QueueIndex = NO_OF_QUEUES + 1;
        UINT uiIndex=0;
        int process_done = 1;
@@ -57,7 +57,7 @@ static void read_bulk_callback(struct urb *urb)
                (0 == urb->actual_length)
                )
        {
-               pRcb->bUsed = FALSE;
+               pRcb->bUsed = false;
                atomic_dec(&psIntfAdapter->uNumRcbUsed);
                return;
        }
@@ -73,7 +73,7 @@ static void read_bulk_callback(struct urb *urb)
                {
                        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status);
                }
-               pRcb->bUsed = FALSE;
+               pRcb->bUsed = false;
                atomic_dec(&psIntfAdapter->uNumRcbUsed);
                urb->status = STATUS_SUCCESS ;
                return ;
@@ -192,7 +192,7 @@ static void read_bulk_callback(struct urb *urb)
                }
        }
        Adapter->PrevNumRecvDescs++;
-       pRcb->bUsed = FALSE;
+       pRcb->bUsed = false;
        atomic_dec(&psIntfAdapter->uNumRcbUsed);
 }
 
@@ -205,10 +205,10 @@ static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_us
                        psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
                        urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback,
                        pRcb);
-       if(FALSE == psIntfAdapter->psAdapter->device_removed &&
-          FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
-          FALSE == psIntfAdapter->bSuspended &&
-          FALSE == psIntfAdapter->bPreparingForBusSuspend)
+       if(false == psIntfAdapter->psAdapter->device_removed &&
+          false == psIntfAdapter->psAdapter->bEndPointHalted &&
+          false == psIntfAdapter->bSuspended &&
+          false == psIntfAdapter->bPreparingForBusSuspend)
        {
                retval = usb_submit_urb(urb, GFP_ATOMIC);
                if (retval)
@@ -240,7 +240,7 @@ Return:                             TRUE  - If Rx was successful.
                                        Other - If an error occurred.
 */
 
-BOOLEAN InterfaceRx (struct bcm_interface_adapter *psIntfAdapter)
+bool InterfaceRx (struct bcm_interface_adapter *psIntfAdapter)
 {
        USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
        struct bcm_usb_rcb *pRcb = NULL;
@@ -253,7 +253,7 @@ BOOLEAN InterfaceRx (struct bcm_interface_adapter *psIntfAdapter)
                if(pRcb == NULL)
                {
                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer");
-                       return FALSE;
+                       return false;
                }
                //atomic_inc(&psIntfAdapter->uNumRcbUsed);
                ReceiveRcb(psIntfAdapter, pRcb);
index 424645e9e47656ae4794cd68e0cba3948b606f4c..b4e858bcda3435e7f9382dbe4fa733f2681dff0d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _INTERFACE_RX_H
 #define _INTERFACE_RX_H
 
-BOOLEAN InterfaceRx(struct bcm_interface_adapter *Adapter);
+bool InterfaceRx(struct bcm_interface_adapter *Adapter);
 
 #endif
 
index b8c785556dda8c9f2ce797f1f8402c1a99a38d8e..b9c2784e9811bb7f2f7852eded26c333ce42cab2 100644 (file)
@@ -7,7 +7,7 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
        struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter;
        struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer;
        struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ;
-       BOOLEAN bpowerDownMsg = FALSE ;
+       bool bpowerDownMsg = false ;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
 
     if (unlikely(netif_msg_tx_done(Adapter)))
@@ -26,7 +26,7 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
                }
        }
 
-       pTcb->bUsed = FALSE;
+       pTcb->bUsed = false;
        atomic_dec(&psIntfAdapter->uNumTcbUsed);
 
 
@@ -42,7 +42,7 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
                        //This covers the bus err while Idle Request msg sent down.
                        if(urb->status != STATUS_SUCCESS)
                        {
-                               psAdapter->bPreparingForLowPowerMode = FALSE ;
+                               psAdapter->bPreparingForLowPowerMode = false ;
                                BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem");
                                //Signalling the cntrl pkt path in Ioctl
                                wake_up(&psAdapter->lowpower_mode_wait_queue);
@@ -50,11 +50,11 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
                                goto err_exit;
                        }
 
-                       if(psAdapter->bDoSuspend == FALSE)
+                       if(psAdapter->bDoSuspend == false)
                        {
                                psAdapter->IdleMode = TRUE;
                                //since going in Idle mode completed hence making this var false;
-                               psAdapter->bPreparingForLowPowerMode = FALSE ;
+                               psAdapter->bPreparingForLowPowerMode = false ;
 
                                BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State...");
                                //Signalling the cntrl pkt path in Ioctl
@@ -70,7 +70,7 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
                        //This covers the bus err while shutdown Request msg sent down.
                        if(urb->status != STATUS_SUCCESS)
                        {
-                               psAdapter->bPreparingForLowPowerMode = FALSE ;
+                               psAdapter->bPreparingForLowPowerMode = false ;
                                BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem");
                                //Signalling the cntrl pkt path in Ioctl
                                wake_up(&psAdapter->lowpower_mode_wait_queue);
@@ -79,11 +79,11 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
                        }
 
                        bpowerDownMsg = TRUE ;
-                       if(psAdapter->bDoSuspend == FALSE)
+                       if(psAdapter->bDoSuspend == false)
                        {
                                psAdapter->bShutStatus = TRUE;
                                //since going in shutdown mode completed hence making this var false;
-                               psAdapter->bPreparingForLowPowerMode = FALSE ;
+                               psAdapter->bPreparingForLowPowerMode = false ;
                                BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State...");
                                //Signalling the cntrl pkt path in Ioctl
                                wake_up(&psAdapter->lowpower_mode_wait_queue);
@@ -113,7 +113,7 @@ static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAda
        UINT index = 0;
 
        if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
-               (psIntfAdapter->psAdapter->StopAllXaction ==FALSE))
+               (psIntfAdapter->psAdapter->StopAllXaction ==false))
        {
                index = atomic_read(&psIntfAdapter->uCurrTcb);
                pTcb = &psIntfAdapter->asUsbTcb[index];
@@ -161,10 +161,10 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_u
        }
        urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */
 
-       if(FALSE == psIntfAdapter->psAdapter->device_removed &&
-          FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
-          FALSE == psIntfAdapter->bSuspended &&
-          FALSE == psIntfAdapter->bPreparingForBusSuspend)
+       if(false == psIntfAdapter->psAdapter->device_removed &&
+          false == psIntfAdapter->psAdapter->bEndPointHalted &&
+          false == psIntfAdapter->bSuspended &&
+          false == psIntfAdapter->bPreparingForBusSuspend)
        {
                retval = usb_submit_urb(urb, GFP_ATOMIC);
                if (retval)
@@ -184,7 +184,7 @@ int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
 {
        struct bcm_usb_tcb *pTcb= NULL;
 
-       struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
+       struct bcm_interface_adapter *psIntfAdapter = arg;
        pTcb= GetBulkOutTcb(psIntfAdapter);
        if(pTcb == NULL)
        {
index bc486163332d909a54c15dcaf937d2afca4eaabb..f95b06713a284d90101c4e5d261ab2b77069ee3b 100644 (file)
@@ -82,7 +82,7 @@ static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet
                return 0;
        }
 
-       if (FALSE != psSF->bValid && psSF->ucDirection) {
+       if (false != psSF->bValid && psSF->ucDirection) {
                if (0 != psSF->uiCurrentTokenCount) {
                                return psSF->uiCurrentTokenCount;
                } else {
@@ -188,7 +188,7 @@ static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter, struct
                                spin_unlock_bh(&psSF->SFQueueLock);
 
                                Status = SendPacketFromQueue(Adapter, psSF, QueuePacket);
-                               psSF->uiPendedLast = FALSE;
+                               psSF->uiPendedLast = false;
                        } else {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo);
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
@@ -250,7 +250,7 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
        UINT uiPrevTotalCount = 0;
        int iIndex = 0;
 
-       BOOLEAN exit_flag = TRUE;
+       bool exit_flag = TRUE;
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>");
 
@@ -299,7 +299,7 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
                                CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
                                uiPrevTotalCount--;
-                               exit_flag = FALSE;
+                               exit_flag = false;
                        }
                }
 
index 4cfc2c33c6966a1e2b3d560205aac87548c422bc..7b2fa0f4a2e48485dc53b1b8cb90abe6d6c12aac 100644 (file)
@@ -53,7 +53,7 @@ int InitAdapter(struct bcm_mini_adapter *psAdapter)
        init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue);
        init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue);
        psAdapter->waiting_to_fw_download_done = TRUE;
-       psAdapter->fw_download_done = FALSE;
+       psAdapter->fw_download_done = false;
 
        default_wimax_protocol_initialize(psAdapter);
        for (i = 0; i < MAX_CNTRL_PKTS; i++) {
@@ -255,7 +255,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
 
                if (Adapter->bShutStatus == TRUE) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n");
-                       if (Adapter->bTriedToWakeUpFromlowPowerMode == FALSE) {
+                       if (Adapter->bTriedToWakeUpFromlowPowerMode == false) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n");
                                Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; /* change it to 1 for current support. */
                                Adapter->bWakeUpDevice = TRUE;
@@ -346,7 +346,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
                        pktlen = pLeader->PLength;
                        Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen);
                        if (Status != 1) {
-                               ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, FALSE);
+                               ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, false);
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly ");
                                return STATUS_FAILURE;
                        }
@@ -499,7 +499,7 @@ void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuff
                        Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK;
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x\n", Adapter->bPHSEnabled);
 
-                       if ((FALSE == Adapter->bShutStatus) && (FALSE == Adapter->IdleMode)) {
+                       if ((false == Adapter->bShutStatus) && (false == Adapter->IdleMode)) {
                                if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
                                        Adapter->DriverState = NORMAL_OPERATION;
                                        wake_up(&Adapter->LEDInfo.notify_led_event);
@@ -517,8 +517,8 @@ void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuff
                        Adapter->LinkUpStatus = 0;
                        Adapter->LinkStatus = 0;
                        Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX;
-                       Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
-                       Adapter->IdleMode = FALSE;
+                       Adapter->bTriedToWakeUpFromlowPowerMode = false;
+                       Adapter->IdleMode = false;
                        beceem_protocol_reset(Adapter);
 
                        break;
@@ -578,7 +578,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
 
                stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!");
-               Adapter->bPreparingForLowPowerMode = FALSE;
+               Adapter->bPreparingForLowPowerMode = false;
        } else {
                stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; /* 2; Idle ACK */
                Adapter->StatisticsPointer = 0;
@@ -613,7 +613,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
                        if (Adapter->bDoSuspend == TRUE)
                                Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
                } else {
-                       Adapter->bPreparingForLowPowerMode = FALSE;
+                       Adapter->bPreparingForLowPowerMode = false;
                }
 
                if (!NVMAccess)
@@ -626,7 +626,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
        status = CopyBufferToControlPacket(Adapter, &stIdleResponse);
        if ((status != STATUS_SUCCESS)) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n");
-               Adapter->bPreparingForLowPowerMode = FALSE;
+               Adapter->bPreparingForLowPowerMode = false;
                StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
        }
        do_gettimeofday(&tv);
@@ -651,8 +651,8 @@ void DumpPackInfo(struct bcm_mini_adapter *Adapter)
 
        for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "*********** Showing Details Of Queue %d***** ******", uiLoopIndex);
-               if (FALSE == Adapter->PackInfo[uiLoopIndex].bValid) {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid is FALSE for %X index\n", uiLoopIndex);
+               if (false == Adapter->PackInfo[uiLoopIndex].bValid) {
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid is false for %X index\n", uiLoopIndex);
                        continue;
                }
 
@@ -783,7 +783,7 @@ int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
        int bytes;
 
        psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter));
-       ps_adapter->bDDRInitDone = FALSE;
+       ps_adapter->bDDRInitDone = false;
 
        if (ps_adapter->chip_id >= T3LPB) {
                /* SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before */
@@ -803,7 +803,7 @@ int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
        if (ps_adapter->chip_id >= T3LPB) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Resetting UMA-B\n");
                retval = usb_reset_device(psIntfAdapter->udev);
-               psIntfAdapter->psAdapter->StopAllXaction = FALSE;
+               psIntfAdapter->psAdapter->StopAllXaction = false;
 
                if (retval != STATUS_SUCCESS) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval);
@@ -888,7 +888,7 @@ int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
        wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue));
 
 err_exit:
-       psIntfAdapter->psAdapter->StopAllXaction = FALSE;
+       psIntfAdapter->psAdapter->StopAllXaction = false;
        return retval;
 }
 
@@ -968,7 +968,7 @@ int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter)
                return -EIO;
        }
 
-       if (FALSE == ps_adapter->AutoFirmDld) {
+       if (false == ps_adapter->AutoFirmDld) {
                BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n");
                /* If Auto f/w download is disable, register the control interface, */
                /* register the control interface after the mailbox. */
@@ -1094,7 +1094,7 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
 
        if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) {
                pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
-               Adapter->AutoSyncup = FALSE;
+               Adapter->AutoSyncup = false;
        } else {
                pr_info(DRV_NAME ": AutoSyncup is Enabled\n");
                Adapter->AutoSyncup = TRUE;
@@ -1105,7 +1105,7 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
                Adapter->AutoLinkUp = TRUE;
        } else {
                pr_info(DRV_NAME ": Disabling autolink up");
-               Adapter->AutoLinkUp = FALSE;
+               Adapter->AutoLinkUp = false;
        }
        /* Setting the DDR Setting.. */
        Adapter->DDRSetting = (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >> 8)&0x0F;
@@ -1117,7 +1117,7 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
                Adapter->AutoFirmDld = TRUE;
        } else {
                pr_info(DRV_NAME ": Disabling Auto Firmware Download\n");
-               Adapter->AutoFirmDld = FALSE;
+               Adapter->AutoFirmDld = false;
        }
        uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
        Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
@@ -1155,21 +1155,21 @@ static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
 
        if (reporting_mode == TRUE) {
                BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "can't do suspen/resume as reporting mode is enable");
-               psAdapter->bDoSuspend = FALSE;
+               psAdapter->bDoSuspend = false;
        }
 
        if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) {
                /* If reporting mode is enable, switch PMU to PMC */
                {
                        psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
-                       psAdapter->bDoSuspend = FALSE;
+                       psAdapter->bDoSuspend = false;
                }
 
                /* clearing space bit[15..12] */
                psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12)));
                /* placing the power save mode option */
                psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12));
-       } else if (psAdapter->bIsAutoCorrectEnabled == FALSE) {
+       } else if (psAdapter->bIsAutoCorrectEnabled == false) {
                /* remove the autocorrect disable bit set before dumping. */
                psAdapter->ulPowerSaveMode &= ~(1 << 3);
                psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15));
@@ -1302,8 +1302,8 @@ static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
                wake_up(&Adapter->LEDInfo.notify_led_event);
        }
 
-       Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
-       Adapter->bShutStatus = FALSE;
+       Adapter->bTriedToWakeUpFromlowPowerMode = false;
+       Adapter->bShutStatus = false;
        wake_up(&Adapter->lowpower_mode_wait_queue);
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
 }
@@ -1341,7 +1341,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
 
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n");
                stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */
-               Adapter->bPreparingForLowPowerMode = FALSE;
+               Adapter->bPreparingForLowPowerMode = false;
        } else {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n");
                stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER; /* ShutDown ACK */
@@ -1374,7 +1374,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
                        if (Adapter->bDoSuspend == TRUE)
                                Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
                } else {
-                       Adapter->bPreparingForLowPowerMode = FALSE;
+                       Adapter->bPreparingForLowPowerMode = false;
                }
 
                if (!NVMAccess)
@@ -1387,7 +1387,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
        Status = CopyBufferToControlPacket(Adapter, &stShutdownResponse);
        if ((Status != STATUS_SUCCESS)) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n");
-               Adapter->bPreparingForLowPowerMode = FALSE;
+               Adapter->bPreparingForLowPowerMode = false;
                StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
        }
 }
@@ -1430,11 +1430,11 @@ void ResetCounters(struct bcm_mini_adapter *Adapter)
        Adapter->LinkStatus = 0;
        atomic_set(&Adapter->cntrlpktCnt, 0);
        atomic_set(&Adapter->TotalPacketCount, 0);
-       Adapter->fw_download_done = FALSE;
+       Adapter->fw_download_done = false;
        Adapter->LinkStatus = 0;
-       Adapter->AutoLinkUp = FALSE;
-       Adapter->IdleMode = FALSE;
-       Adapter->bShutStatus = FALSE;
+       Adapter->AutoLinkUp = false;
+       Adapter->IdleMode = false;
+       Adapter->bShutStatus = false;
 }
 
 struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP)
@@ -1521,7 +1521,7 @@ void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter)
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x\n", Adapter->PackInfo[iIndex].usVCID_Value);
                }
        }
-       atomic_set(&Adapter->uiMBupdate, FALSE);
+       atomic_set(&Adapter->uiMBupdate, false);
 }
 
 void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex)
@@ -1557,8 +1557,8 @@ static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter)
        netif_carrier_off(Adapter->dev);
        netif_stop_queue(Adapter->dev);
 
-       Adapter->IdleMode = FALSE;
-       Adapter->LinkUpStatus = FALSE;
+       Adapter->IdleMode = false;
+       Adapter->LinkUpStatus = false;
        ClearTargetDSXBuffer(Adapter, 0, TRUE);
        /* Delete All Classifier Rules */
 
@@ -1568,7 +1568,7 @@ static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter)
        flush_all_queues(Adapter);
 
        if (Adapter->TimerActive == TRUE)
-               Adapter->TimerActive = FALSE;
+               Adapter->TimerActive = false;
 
        memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(struct bcm_fragmented_packet_info) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
 
index af5d22faa7f03c5a787d0cb054d8f5c50f2143a8..892ebc65cdd3964de42a2688368a259718753cab 100644 (file)
@@ -8,9 +8,9 @@ static UINT CreateClassifierPHSRule(B_UINT16  uiClsId, struct bcm_phs_classifier
 
 static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_entry *pstClassifierEntry, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
 
-static BOOLEAN ValidatePHSRuleComplete(struct bcm_phs_rule *psPhsRule);
+static bool ValidatePHSRuleComplete(struct bcm_phs_rule *psPhsRule);
 
-static BOOLEAN DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule);
+static bool DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule);
 
 static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_classifier_entry **ppstClassifierEntry);
 
@@ -67,7 +67,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
                struct sk_buff **pPacket,
                USHORT Vcid,
                B_UINT16 uiClassifierRuleID,
-               BOOLEAN bHeaderSuppressionEnabled,
+               bool bHeaderSuppressionEnabled,
                UINT *PacketLen,
                UCHAR bEthCSSupport)
 {
@@ -81,7 +81,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
        PUCHAR pucPHSPktHdrOutBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
        UINT usPacketType;
        UINT BytesToRemove = 0;
-       BOOLEAN bPHSI = 0;
+       bool bPHSI = 0;
        LONG ulPhsStatus = 0;
        UINT numBytesCompressed = 0;
        struct sk_buff *newPacket = NULL;
@@ -569,7 +569,7 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
                                memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
                        }
                }
-               pstServiceFlowEntry->bUsed = FALSE;
+               pstServiceFlowEntry->bUsed = false;
                pstServiceFlowEntry->uiVcid = 0;
        }
 
@@ -596,7 +596,7 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
  * 0 if successful,
  * >0 Error.
  */
-ULONG PhsCompress(IN void *pvContext,
+static ULONG PhsCompress(IN void *pvContext,
                IN B_UINT16 uiVcid,
                IN B_UINT16 uiClsId,
                IN void *pvInputBuffer,
@@ -677,7 +677,7 @@ ULONG PhsCompress(IN void *pvContext,
  * 0 if successful,
  * >0 Error.
  */
-ULONG PhsDeCompress(IN void *pvContext,
+static ULONG PhsDeCompress(IN void *pvContext,
                IN B_UINT16 uiVcid,
                IN void *pvInputBuffer,
                OUT void *pvOutputBuffer,
@@ -788,26 +788,26 @@ static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesT
        psServiceFlowRulesTable = NULL;
 }
 
-static BOOLEAN ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule)
+static bool ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule)
 {
        if (psPhsRule) {
                if (!psPhsRule->u8PHSI) {
                        /* PHSI is not valid */
-                       return FALSE;
+                       return false;
                }
 
                if (!psPhsRule->u8PHSS) {
                        /* PHSS Is Undefined */
-                       return FALSE;
+                       return false;
                }
 
                /* Check if PHSF is defines for the PHS Rule */
                if (!psPhsRule->u8PHSFLength) /* If any part of PHSF is valid then Rule contains valid PHSF */
-                       return FALSE;
+                       return false;
 
                return TRUE;
        } else
-               return FALSE;
+               return false;
 }
 
 UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
@@ -829,7 +829,7 @@ UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
        return PHS_INVALID_TABLE_INDEX;
 }
 
-UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
+static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
                        IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext,
                        OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
 {
@@ -880,7 +880,7 @@ static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTab
        return PHS_INVALID_TABLE_INDEX;
 }
 
-UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
+static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
                                IN struct bcm_phs_table *psServiceFlowTable,
                                struct bcm_phs_rule *psPhsRule,
                                B_UINT8 u8AssociatedPHSI)
@@ -888,7 +888,7 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
        struct bcm_phs_classifier_table *psaClassifiertable = NULL;
        UINT uiStatus = 0;
        int iSfIndex;
-       BOOLEAN bFreeEntryFound = FALSE;
+       bool bFreeEntryFound = false;
 
        /* Check for a free entry in SFID table */
        for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) {
@@ -913,7 +913,7 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
        return uiStatus;
 }
 
-UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
+static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
                                IN B_UINT16 uiClsId,
                                IN struct bcm_phs_entry *pstServiceFlowEntry,
                                struct bcm_phs_rule *psPhsRule,
@@ -1009,7 +1009,7 @@ static UINT CreateClassifierPHSRule(IN B_UINT16  uiClsId,
                                B_UINT8 u8AssociatedPHSI)
 {
        UINT iClassifierIndex = 0;
-       BOOLEAN bFreeEntryFound = FALSE;
+       bool bFreeEntryFound = false;
        struct bcm_phs_classifier_entry *psClassifierRules = NULL;
        UINT nStatus = PHS_SUCCESS;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -1102,7 +1102,7 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16  uiClsId,
 {
        struct bcm_phs_rule *pstAddPhsRule = NULL;
        UINT nPhsRuleIndex = 0;
-       BOOLEAN bPHSRuleOrphaned = FALSE;
+       bool bPHSRuleOrphaned = false;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
 
        psPhsRule->u8RefCnt = 0;
@@ -1124,7 +1124,7 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16  uiClsId,
                }
 
                /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId */
-               if (FALSE == bPHSRuleOrphaned) {
+               if (false == bPHSRuleOrphaned) {
 
                        pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
                        if (NULL == pstClassifierEntry->pstPhsRule)
@@ -1150,10 +1150,10 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16  uiClsId,
        return PHS_SUCCESS;
 }
 
-static BOOLEAN DerefPhsRule(IN B_UINT16  uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule)
+static bool DerefPhsRule(IN B_UINT16  uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule)
 {
        if (pstPhsRule == NULL)
-               return FALSE;
+               return false;
 
        if (pstPhsRule->u8RefCnt)
                pstPhsRule->u8RefCnt--;
@@ -1166,7 +1166,7 @@ static BOOLEAN DerefPhsRule(IN B_UINT16  uiClsId, struct bcm_phs_classifier_tabl
                 */
                return TRUE;
        } else
-               return FALSE;
+               return false;
 }
 
 void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
@@ -1239,7 +1239,7 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
  *                     header.
  *     0       -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
  */
-int phs_decompress(unsigned char *in_buf,
+static int phs_decompress(unsigned char *in_buf,
                unsigned char *out_buf,
                struct bcm_phs_rule *decomp_phs_rules,
                UINT *header_size)
index 82d8682841809d17858e4f8f43f7db66e9a0383e..d697f9c860cff03457ab182ce950a2d7f14157ff 100644 (file)
@@ -5,7 +5,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
                                        struct sk_buff **pPacket,
                                         USHORT Vcid,
                                         B_UINT16 uiClassifierRuleID,
-                                        BOOLEAN bHeaderSuppressionEnabled,
+                                        bool bHeaderSuppressionEnabled,
                                         PUINT PacketLen,
                                         UCHAR bEthCSSupport);
 
@@ -39,7 +39,7 @@ ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16  uiClsI
 ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ;
 
 
-BOOLEAN ValidatePHSRule(struct bcm_phs_rule *psPhsRule);
+bool ValidatePHSRule(struct bcm_phs_rule *psPhsRule);
 
 UINT GetServiceFlowEntry(struct bcm_phs_table *psServiceFlowTable,B_UINT16 uiVcid, struct bcm_phs_entry **ppstServiceFlowEntry);
 
index 2a673b125f008e83f5f8a82b64b176a2f928ea16..fb53a00591ebaaef9b272985e40760c9e27b4dce 100644 (file)
@@ -111,7 +111,7 @@ void update_per_cid_rx (struct bcm_mini_adapter *Adapter);
 
 void update_per_sf_desc_cnts( struct bcm_mini_adapter *Adapter);
 
-void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter,B_UINT16 TID,BOOLEAN bFreeAll);
+void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter,B_UINT16 TID,bool bFreeAll);
 
 
 void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex);
@@ -138,7 +138,7 @@ INT BeceemEEPROMBulkWrite(
        PUCHAR pBuffer,
        UINT uiOffset,
        UINT uiNumBytes,
-       BOOLEAN bVerify);
+       bool bVerify);
 
 
 INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,UINT dwAddress, UINT *pdwData);
@@ -155,13 +155,13 @@ INT BeceemNVMWrite(
        PUINT pBuffer,
        UINT uiOffset,
        UINT uiNumBytes,
-       BOOLEAN bVerify);
+       bool bVerify);
 
 
 INT BcmInitNVM(struct bcm_mini_adapter *Adapter);
 
 INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize);
-BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
+bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
 
 INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap);
 
@@ -198,7 +198,7 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter,
                                                UINT numOfBytes);
 
 
-BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter);
+bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter);
 
 
 VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter,PUINT puiBuffer);
@@ -212,7 +212,7 @@ INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer
 
 
 VOID putUsbSuspend(struct work_struct *work);
-BOOLEAN IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios);
+bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios);
 
 
 #endif
index 2d4a77cca9150b76137d1d84d93cac930b433fda..1609a2bdc522a8a8117f6a23bac5c63a7f0c6269 100644 (file)
@@ -5,7 +5,7 @@ This file contains the routines related to Quality of Service.
 #include "headers.h"
 
 static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, PVOID pvEthPayload, struct bcm_eth_packet_info *pstEthCsPktInfo);
-static BOOLEAN EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo, struct bcm_classifier_rule *pstClassifierRule, B_UINT8 EthCSCupport);
+static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo, struct bcm_classifier_rule *pstClassifierRule, B_UINT8 EthCSCupport);
 
 static USHORT  IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd,
                           struct bcm_classifier_rule *pstClassifierRule);
@@ -24,7 +24,7 @@ static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex);
 *
 * Returns     - TRUE(If address matches) else FAIL .
 *********************************************************************/
-BOOLEAN MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulSrcIP)
+bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulSrcIP)
 {
        UCHAR ucLoopIndex = 0;
 
@@ -43,7 +43,7 @@ BOOLEAN MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG u
                }
        }
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched");
-       return FALSE;
+       return false;
 }
 
 
@@ -58,7 +58,7 @@ BOOLEAN MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG u
 *
 * Returns     - TRUE(If address matches) else FAIL .
 *********************************************************************/
-BOOLEAN MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP)
+bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP)
 {
        UCHAR ucLoopIndex = 0;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -77,7 +77,7 @@ BOOLEAN MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG
                }
        }
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched");
-       return FALSE;
+       return false;
 }
 
 
@@ -91,7 +91,7 @@ BOOLEAN MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG
 *
 * Returns     - TRUE(If address matches) else FAIL.
 **************************************************************************/
-BOOLEAN MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucTypeOfService)
+bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucTypeOfService)
 {
 
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -103,7 +103,7 @@ BOOLEAN MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucTypeOfSe
                return TRUE;
        }
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched");
-       return FALSE;
+       return false;
 }
 
 
@@ -132,7 +132,7 @@ bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucProtoc
                }
        }
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched");
-       return FALSE;
+       return false;
 }
 
 
@@ -164,7 +164,7 @@ bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPo
                }
        }
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ", ushSrcPort);
-       return FALSE;
+       return false;
 }
 
 
@@ -197,7 +197,7 @@ bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushDest
                }
        }
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched", ushDestPort);
-       return FALSE;
+       return false;
 }
 /**
 @ingroup tx_functions
@@ -209,7 +209,7 @@ static USHORT       IpVersion4(struct bcm_mini_adapter *Adapter,
                           struct bcm_classifier_rule *pstClassifierRule)
 {
        struct bcm_transport_header *xprt_hdr = NULL;
-       BOOLEAN bClassificationSucceed = FALSE;
+       bool    bClassificationSucceed = false;
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "========>");
 
@@ -223,7 +223,7 @@ static USHORT       IpVersion4(struct bcm_mini_adapter *Adapter,
                //Checking classifier validity
                if (!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR)
                {
-                       bClassificationSucceed = FALSE;
+                       bClassificationSucceed = false;
                        break;
                }
 
@@ -233,17 +233,17 @@ static USHORT     IpVersion4(struct bcm_mini_adapter *Adapter,
 
                //**************Checking IP header parameter**************************//
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to match Source IP Address");
-               if (FALSE == (bClassificationSucceed =
+               if (false == (bClassificationSucceed =
                        MatchSrcIpAddress(pstClassifierRule, iphd->saddr)))
                        break;
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched");
 
-               if (FALSE == (bClassificationSucceed =
+               if (false == (bClassificationSucceed =
                        MatchDestIpAddress(pstClassifierRule, iphd->daddr)))
                        break;
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched");
 
-               if (FALSE == (bClassificationSucceed =
+               if (false == (bClassificationSucceed =
                        MatchTos(pstClassifierRule, iphd->tos)))
                {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n");
@@ -251,7 +251,7 @@ static USHORT       IpVersion4(struct bcm_mini_adapter *Adapter,
                }
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched");
 
-               if (FALSE == (bClassificationSucceed =
+               if (false == (bClassificationSucceed =
                        MatchProtocol(pstClassifierRule, iphd->protocol)))
                        break;
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched");
@@ -263,7 +263,7 @@ static USHORT       IpVersion4(struct bcm_mini_adapter *Adapter,
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
                        (iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source);
 
-               if (FALSE == (bClassificationSucceed =
+               if (false == (bClassificationSucceed =
                        MatchSrcPort(pstClassifierRule,
                                ntohs((iphd->protocol == UDP) ?
                                xprt_hdr->uhdr.source : xprt_hdr->thdr.source))))
@@ -273,7 +273,7 @@ static USHORT       IpVersion4(struct bcm_mini_adapter *Adapter,
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Port %04x",
                        (iphd->protocol == UDP) ? xprt_hdr->uhdr.dest :
                        xprt_hdr->thdr.dest);
-               if (FALSE == (bClassificationSucceed =
+               if (false == (bClassificationSucceed =
                        MatchDestPort(pstClassifierRule,
                        ntohs((iphd->protocol == UDP) ?
                        xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest))))
@@ -286,13 +286,13 @@ static USHORT     IpVersion4(struct bcm_mini_adapter *Adapter,
                iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
                if (iMatchedSFQueueIndex >= NO_OF_QUEUES)
                {
-                       bClassificationSucceed = FALSE;
+                       bClassificationSucceed = false;
                }
                else
                {
-                       if (FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
+                       if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
                        {
-                               bClassificationSucceed = FALSE;
+                               bClassificationSucceed = false;
                        }
                }
        }
@@ -451,7 +451,7 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
        struct iphdr *pIpHeader = NULL;
        INT       uiSfIndex = 0;
        USHORT  usIndex = Adapter->usBestEffortQueueIndex;
-       BOOLEAN bFragmentedPkt = FALSE, bClassificationSucceed = FALSE;
+       bool    bFragmentedPkt = false, bClassificationSucceed = false;
        USHORT  usCurrFragment = 0;
 
        struct bcm_tcp_header *pTcpHeader;
@@ -529,16 +529,16 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
                //to classify the packet until match found
                do
                {
-                       if (FALSE == Adapter->astClassifierTable[uiLoopIndex].bUsed)
+                       if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed)
                        {
-                               bClassificationSucceed = FALSE;
+                               bClassificationSucceed = false;
                                break;
                        }
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "Adapter->PackInfo[%d].bvalid=True\n", uiLoopIndex);
 
                        if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection)
                        {
-                               bClassificationSucceed = FALSE;//cannot be processed for classification.
+                               bClassificationSucceed = false;//cannot be processed for classification.
                                break;                                          // it is a down link connection
                        }
 
@@ -556,7 +556,7 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
                                if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType)
                                {
                                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
-                                       bClassificationSucceed = FALSE;
+                                       bClassificationSucceed = false;
                                        break;
                                }
 
@@ -577,7 +577,7 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
                                if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType)
                                {
                                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
-                                       bClassificationSucceed = FALSE;
+                                       bClassificationSucceed = false;
                                        break;
                                }
                        }
@@ -590,7 +590,7 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
                                if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket)
                                {
                                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet\n");
-                                       bClassificationSucceed = FALSE;
+                                       bClassificationSucceed = false;
                                        break;
                                }
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dump IP Header :\n");
@@ -636,7 +636,7 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
                        stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr;
                        stFragPktInfo.usIpIdentification = pIpHeader->id;
                        stFragPktInfo.pstMatchedClassifierEntry = pstClassifierRule;
-                       stFragPktInfo.bOutOfOrderFragment = FALSE;
+                       stFragPktInfo.bOutOfOrderFragment = false;
                        AddFragIPClsEntry(Adapter, &stFragPktInfo);
                }
 
@@ -649,7 +649,7 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
                return INVALID_QUEUE_INDEX;
 }
 
-static BOOLEAN EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule, PUCHAR Mac)
+static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule, PUCHAR Mac)
 {
        UINT i = 0;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -661,12 +661,12 @@ static BOOLEAN EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifier
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", i, Mac[i], pstClassifierRule->au8EThCSSrcMAC[i], pstClassifierRule->au8EThCSSrcMACMask[i]);
                if ((pstClassifierRule->au8EThCSSrcMAC[i] & pstClassifierRule->au8EThCSSrcMACMask[i]) !=
                        (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
-                       return FALSE;
+                       return false;
        }
        return TRUE;
 }
 
-static BOOLEAN EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule, PUCHAR Mac)
+static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule, PUCHAR Mac)
 {
        UINT i = 0;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -678,12 +678,12 @@ static BOOLEAN EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifie
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", i, Mac[i], pstClassifierRule->au8EThCSDestMAC[i], pstClassifierRule->au8EThCSDestMACMask[i]);
                if ((pstClassifierRule->au8EThCSDestMAC[i] & pstClassifierRule->au8EThCSDestMACMask[i]) !=
                        (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
-                       return FALSE;
+                       return false;
        }
        return TRUE;
 }
 
-static BOOLEAN EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo)
+static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo)
 {
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
        if ((pstClassifierRule->ucEtherTypeLen == 0) ||
@@ -698,29 +698,29 @@ static BOOLEAN EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRul
                if (memcmp(&pstEthCsPktInfo->usEtherType, &pstClassifierRule->au8EthCSEtherType[1], 2) == 0)
                        return TRUE;
                else
-                       return FALSE;
+                       return false;
        }
 
        if (pstClassifierRule->au8EthCSEtherType[0] == 2)
        {
                if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
-                       return FALSE;
+                       return false;
 
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "%s  EthCS DSAP:%x EtherType[2]:%x\n", __FUNCTION__, pstEthCsPktInfo->ucDSAP, pstClassifierRule->au8EthCSEtherType[2]);
                if (pstEthCsPktInfo->ucDSAP == pstClassifierRule->au8EthCSEtherType[2])
                        return TRUE;
                else
-                       return FALSE;
+                       return false;
 
        }
 
-       return FALSE;
+       return false;
 
 }
 
-static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo)
+static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo)
 {
-       BOOLEAN bClassificationSucceed = FALSE;
+       bool bClassificationSucceed = false;
        USHORT usVLANID;
        B_UINT8 uPriority = 0;
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -731,7 +731,7 @@ static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule
        if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID))
        {
                if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
-                               return FALSE;
+                               return false;
 
                uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(struct bcm_eth_header))) & 0xF000) >> 13;
 
@@ -739,17 +739,17 @@ static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule
                                bClassificationSucceed = TRUE;
 
                if (!bClassificationSucceed)
-                       return FALSE;
+                       return false;
        }
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "ETH CS 802.1 D  User Priority Rule Matched\n");
 
-       bClassificationSucceed = FALSE;
+       bClassificationSucceed = false;
 
        if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID))
        {
                if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
-                               return FALSE;
+                               return false;
 
                usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(struct bcm_eth_header))) & 0xFFF;
 
@@ -759,7 +759,7 @@ static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule
                        bClassificationSucceed = TRUE;
 
                if (!bClassificationSucceed)
-                       return FALSE;
+                       return false;
        }
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "ETH CS 802.1 Q VLAN ID Rule Matched\n");
@@ -768,26 +768,26 @@ static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule
 }
 
 
-static BOOLEAN EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff* skb,
+static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff* skb,
                                struct bcm_eth_packet_info *pstEthCsPktInfo,
                                struct bcm_classifier_rule *pstClassifierRule,
                                B_UINT8 EthCSCupport)
 {
-       BOOLEAN bClassificationSucceed = FALSE;
+       bool bClassificationSucceed = false;
        bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule, ((struct bcm_eth_header *)(skb->data))->au8SourceAddress);
        if (!bClassificationSucceed)
-               return FALSE;
+               return false;
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "ETH CS SrcMAC Matched\n");
 
        bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule, ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress);
        if (!bClassificationSucceed)
-               return FALSE;
+               return false;
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "ETH CS DestMAC Matched\n");
 
        //classify on ETHType/802.2SAP TLV
        bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule, skb, pstEthCsPktInfo);
        if (!bClassificationSucceed)
-               return FALSE;
+               return false;
 
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "ETH CS EthType/802.2SAP Matched\n");
 
@@ -795,7 +795,7 @@ static BOOLEAN EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff
 
        bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule, skb, pstEthCsPktInfo);
        if (!bClassificationSucceed)
-               return FALSE;
+               return false;
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "ETH CS 802.1 VLAN Rules Matched\n");
 
        return bClassificationSucceed;
index f8dc3e20b47590d4174d01705bf8d0bd29539e63..2ed4836b965410a2ef556fb9d76e06206d6f6781 100644 (file)
@@ -84,7 +84,7 @@ int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket)
 int SetupNextSend(struct bcm_mini_adapter *Adapter,  struct sk_buff *Packet, USHORT Vcid)
 {
        int     status = 0;
-       BOOLEAN bHeaderSupressionEnabled = FALSE;
+       bool    bHeaderSupressionEnabled = false;
        B_UINT16 uiClassifierRuleID;
        u16     QueueIndex = skb_get_queue_mapping(Packet);
        struct bcm_leader Leader = {0};
@@ -204,7 +204,7 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje
                /* Check end point for halt/stall. */
                if (Adapter->bEndPointHalted == TRUE) {
                        Bcm_clear_halt_of_endpoints(Adapter);
-                       Adapter->bEndPointHalted = FALSE;
+                       Adapter->bEndPointHalted = false;
                        StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
                }
 
index a985abf194fd4f63749a4130aba536683a3b0466..832adcfd1e3a31230e3b0cb01527aa455931ac56 100644 (file)
@@ -6,10 +6,10 @@
 #define  STATUS_SUCCESS        0
 #define  STATUS_FAILURE -1
 
-#define         FALSE          0
+
 #define         TRUE           1
 
-typedef char BOOLEAN;
+
 typedef char CHAR;
 typedef int INT;
 typedef short SHORT;
index 05a948a3698cb15eabdd8b25418ca26e96b79366..eee4f4795a7195e9496edbe1c0170e627e896cea 100644 (file)
@@ -13,12 +13,12 @@ static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
        return u16CheckSum;
 }
 
-BOOLEAN IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
+bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
 {
        INT Status;
        Status = (Adapter->gpioBitMap & gpios) ^ gpios;
        if (Status)
-               return FALSE;
+               return false;
        else
                return TRUE;
 }
@@ -27,7 +27,7 @@ static INT LED_Blink(struct bcm_mini_adapter *Adapter, UINT GPIO_Num, UCHAR uiLe
                ULONG timeout, INT num_of_time, enum bcm_led_events currdriverstate)
 {
        int Status = STATUS_SUCCESS;
-       BOOLEAN bInfinite = FALSE;
+       bool bInfinite = false;
 
        /* Check if num_of_time is -ve. If yes, blink led in infinite loop */
        if (num_of_time < 0) {
@@ -67,7 +67,7 @@ static INT LED_Blink(struct bcm_mini_adapter *Adapter, UINT GPIO_Num, UCHAR uiLe
                                currdriverstate != Adapter->DriverState ||
                                        kthread_should_stop(),
                                msecs_to_jiffies(timeout));
-               if (bInfinite == FALSE)
+               if (bInfinite == false)
                        num_of_time--;
        }
        return Status;
@@ -108,7 +108,7 @@ static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_N
        int Status = STATUS_SUCCESS;
        INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
        UINT remDelay = 0;
-       BOOLEAN bBlinkBothLED = TRUE;
+       bool bBlinkBothLED = TRUE;
        /* UINT GPIO_num = DISABLE_GPIO_NUM; */
        ulong timeout = 0;
 
@@ -120,7 +120,7 @@ static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_N
        num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
        num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
 
-       while ((Adapter->device_removed == FALSE)) {
+       while ((Adapter->device_removed == false)) {
                timeout = 50;
                /*
                 * Blink Tx and Rx LED when both Tx and Rx is
@@ -478,7 +478,7 @@ static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
 
 
 static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
-                                       BOOLEAN *bEnableThread)
+                                       bool *bEnableThread)
 {
        int Status = STATUS_SUCCESS;
        /* Array to store GPIO numbers from EEPROM */
@@ -499,10 +499,10 @@ static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
        /* Read the GPIO numbers from EEPROM */
        Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
        if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) {
-               *bEnableThread = FALSE;
+               *bEnableThread = false;
                return STATUS_SUCCESS;
        } else if (Status) {
-               *bEnableThread = FALSE;
+               *bEnableThread = false;
                return Status;
        }
 
@@ -561,7 +561,7 @@ static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
                        uiNum_of_LED_Type++;
        }
        if (uiNum_of_LED_Type >= NUM_OF_LEDS)
-               *bEnableThread = FALSE;
+               *bEnableThread = false;
 
        return Status;
 }
@@ -602,7 +602,7 @@ static VOID LedGpioInit(struct bcm_mini_adapter *Adapter)
                BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
                        DBG_LVL_ALL, "LED Thread: WRM Failed\n");
 
-       Adapter->LEDInfo.bIdle_led_off = FALSE;
+       Adapter->LEDInfo.bIdle_led_off = false;
 }
 
 static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter, UCHAR *GPIO_num_tx,
@@ -660,7 +660,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
        UCHAR dummyIndex = 0;
 
        /* currdriverstate = Adapter->DriverState; */
-       Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE;
+       Adapter->LEDInfo.bIdleMode_tx_from_host = false;
 
        /*
         * Wait till event is triggered
@@ -698,7 +698,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
                if (GPIO_num != DISABLE_GPIO_NUM)
                        TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
 
-               if (Adapter->LEDInfo.bLedInitDone == FALSE) {
+               if (Adapter->LEDInfo.bLedInitDone == false) {
                        LedGpioInit(Adapter);
                        Adapter->LEDInfo.bLedInitDone = TRUE;
                }
@@ -757,7 +757,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
                                UCHAR uiLEDTx = 0;
                                UCHAR uiLEDRx = 0;
                                currdriverstate = NORMAL_OPERATION;
-                               Adapter->LEDInfo.bIdle_led_off = FALSE;
+                               Adapter->LEDInfo.bIdle_led_off = false;
 
                                BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx,
                                        &GPIO_num_rx, &uiLEDTx, &uiLEDRx,
@@ -803,7 +803,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
 
                        }
                        /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
-                       Adapter->LEDInfo.bLedInitDone = FALSE;
+                       Adapter->LEDInfo.bLedInitDone = false;
                        Adapter->LEDInfo.bIdle_led_off = TRUE;
                        wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
                        GPIO_num = DISABLE_GPIO_NUM;
@@ -830,7 +830,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
                        currdriverstate = LED_THREAD_INACTIVE;
                        Adapter->LEDInfo.led_thread_running =
                                        BCM_LED_THREAD_RUNNING_INACTIVELY;
-                       Adapter->LEDInfo.bLedInitDone = FALSE;
+                       Adapter->LEDInfo.bLedInitDone = false;
                        /* disable ALL LED */
                        for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
                                if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
@@ -841,7 +841,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
                case LED_THREAD_ACTIVE:
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
                                DBG_LVL_ALL, "Activating LED thread again...");
-                       if (Adapter->LinkUpStatus == FALSE)
+                       if (Adapter->LinkUpStatus == false)
                                Adapter->DriverState = NO_NETWORK_ENTRY;
                        else
                                Adapter->DriverState = NORMAL_OPERATION;
@@ -860,7 +860,7 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
 int InitLedSettings(struct bcm_mini_adapter *Adapter)
 {
        int Status = STATUS_SUCCESS;
-       BOOLEAN bEnableThread = TRUE;
+       bool bEnableThread = TRUE;
        UCHAR uiIndex = 0;
 
        /*
@@ -899,7 +899,7 @@ int InitLedSettings(struct bcm_mini_adapter *Adapter)
                init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
                Adapter->LEDInfo.led_thread_running =
                                        BCM_LED_THREAD_RUNNING_ACTIVELY;
-               Adapter->LEDInfo.bIdle_led_off = FALSE;
+               Adapter->LEDInfo.bIdle_led_off = false;
                Adapter->LEDInfo.led_cntrl_threadid =
                        kthread_run((int (*)(void *)) LEDControlThread,
                        Adapter, "led_control_thread");
index 91a5715964b93727a61ad263bd6745ed5e54ad32..9e5f955a1a08520683a476959f968399c855402e 100644 (file)
@@ -45,7 +45,7 @@ static int BeceemFlashBulkWrite(
        PUINT pBuffer,
        unsigned int uiOffset,
        unsigned int uiNumBytes,
-       BOOLEAN bVerify);
+       bool bVerify);
 
 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter);
 
@@ -103,7 +103,7 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
                }
                if (!(dwRetries%RETRIES_PER_DELAY))
                        udelay(1000);
-               uiStatus = 0 ;
+               uiStatus = 0;
        }
        return uiData;
 } /* ReadEEPROMStatusRegister */
@@ -1034,7 +1034,7 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
                                PUINT pBuffer,
                                unsigned int uiOffset,
                                unsigned int uiNumBytes,
-                               BOOLEAN bVerify)
+                               bool bVerify)
 {
        PCHAR pTempBuff                 = NULL;
        PUCHAR pcBuffer                 = (PUCHAR)pBuffer;
@@ -1084,18 +1084,18 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
         * for DSD calibration, allow it without checking of sector permission
         */
 
-       if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) {
+       if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) {
                index = 0;
                uiTemp = uiNumSectTobeRead;
                while (uiTemp) {
-                       if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) {
+                       if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable",
                                                (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
                                Status = SECTOR_IS_NOT_WRITABLE;
                                goto BeceemFlashBulkWrite_EXIT;
                        }
                        uiTemp = uiTemp - 1;
-                       index = index + 1 ;
+                       index = index + 1;
                }
        }
        Adapter->SelectedChip = RESET_CHIP_SELECT;
@@ -1222,7 +1222,7 @@ static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
                                PUINT pBuffer,
                                unsigned int uiOffset,
                                unsigned int uiNumBytes,
-                               BOOLEAN bVerify)
+                               bool bVerify)
 {
        PCHAR pTempBuff                 = NULL;
        PUCHAR pcBuffer                 = (PUCHAR)pBuffer;
@@ -1265,18 +1265,18 @@ static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
                        uiNumSectTobeRead++;
        }
 
-       if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) {
+       if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) {
                index = 0;
                uiTemp = uiNumSectTobeRead;
                while (uiTemp) {
-                       if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) {
+                       if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable",
                                                (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
                                Status = SECTOR_IS_NOT_WRITABLE;
                                goto BeceemFlashBulkWriteStatus_EXIT;
                        }
                        uiTemp = uiTemp - 1;
-                       index = index + 1 ;
+                       index = index + 1;
                }
        }
 
@@ -1525,7 +1525,7 @@ static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
 
                        if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) {
                                /* re-write */
-                               BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE);
+                               BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, false);
                                mdelay(3);
                                BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
 
@@ -1539,7 +1539,7 @@ static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
                        BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
                        if (uiData != pBuffer[uiIndex]) {
                                /* re-write */
-                               BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE);
+                               BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, false);
                                mdelay(3);
                                BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
                                if (uiData != pBuffer[uiIndex])
@@ -1724,7 +1724,7 @@ int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter,
                        PUCHAR pBuffer,
                        unsigned int uiOffset,
                        unsigned int uiNumBytes,
-                       BOOLEAN bVerify)
+                       bool bVerify)
 {
        unsigned int uiBytesToCopy      = uiNumBytes;
        /* unsigned int uiRdbk          = 0; */
@@ -1819,7 +1819,7 @@ int BeceemNVMRead(struct bcm_mini_adapter *Adapter,
        #endif
 
        if (Adapter->eNVMType == NVM_FLASH) {
-               if (Adapter->bFlashRawRead == FALSE) {
+               if (Adapter->bFlashRawRead == false) {
                        if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
                                return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes);
 
@@ -1870,7 +1870,7 @@ int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
                PUINT pBuffer,
                unsigned int uiOffset,
                unsigned int uiNumBytes,
-               BOOLEAN bVerify)
+               bool bVerify)
 {
        int Status = 0;
        unsigned int uiTemp = 0;
@@ -2425,7 +2425,7 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter)
        B_UINT32 i = 0;
        unsigned int uiSizeSection = 0;
 
-       Adapter->uiVendorExtnFlag = FALSE;
+       Adapter->uiVendorExtnFlag = false;
 
        for (i = 0; i < TOTAL_SECTIONS; i++)
                Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
@@ -2685,12 +2685,12 @@ int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash
        switch (eFlashSectionVal) {
        case ISO_IMAGE1:
                if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
-                       (IsNonCDLessDevice(Adapter) == FALSE))
+                       (IsNonCDLessDevice(Adapter) == false))
                        SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
                break;
        case ISO_IMAGE2:
                if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
-                       (IsNonCDLessDevice(Adapter) == FALSE))
+                       (IsNonCDLessDevice(Adapter) == false))
                        SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
                break;
        case DSD0:
@@ -2770,12 +2770,12 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x
        switch (eFlash2xSectionVal) {
        case ISO_IMAGE1:
                if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) &&
-                       (IsNonCDLessDevice(Adapter) == FALSE))
+                       (IsNonCDLessDevice(Adapter) == false))
                        SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
                break;
        case ISO_IMAGE2:
                if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) &&
-                       (IsNonCDLessDevice(Adapter) == FALSE))
+                       (IsNonCDLessDevice(Adapter) == false))
                        SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
                break;
        case DSD0:
@@ -2831,7 +2831,7 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x
                SectEndOffset = INVALID_OFFSET;
        }
 
-       return SectEndOffset ;
+       return SectEndOffset;
 }
 
 /*
@@ -3037,7 +3037,7 @@ static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
  *
  * Return Value:-
  * Success:-TRUE ,  offset is writable
- * Failure:-FALSE, offset is RO
+ * Failure:-false, offset is RO
  *
  */
 
@@ -3062,7 +3062,7 @@ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset
        if (permissionBits == SECTOR_READWRITE_PERMISSION)
                return TRUE;
        else
-               return FALSE;
+               return false;
 }
 
 static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
@@ -3105,13 +3105,13 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
        struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
        enum bcm_flash2x_section_val uiHighestPriDSD = 0;
        enum bcm_flash2x_section_val uiHighestPriISO = 0;
-       BOOLEAN SetActiveDSDDone = FALSE;
-       BOOLEAN SetActiveISODone = FALSE;
+       bool SetActiveDSDDone = false;
+       bool SetActiveISODone = false;
 
        /* For 1.x map all the section except DSD0 will be shown as not present
         * This part will be used by calibration tool to detect the number of DSD present in Flash.
         */
-       if (IsFlash2x(Adapter) == FALSE) {
+       if (IsFlash2x(Adapter) == false) {
                psFlash2xBitMap->ISO_IMAGE2 = 0;
                psFlash2xBitMap->ISO_IMAGE1 = 0;
                psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */
@@ -3143,10 +3143,10 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                        psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
 
                /* Calculation for extrating the Access permission */
-               if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
+               if (IsSectionWritable(Adapter, ISO_IMAGE2) == false)
                        psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
 
-               if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) {
+               if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE2) {
                        psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
                        SetActiveISODone = TRUE;
                }
@@ -3163,10 +3163,10 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                        psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
 
                /* Calculation for extrating the Access permission */
-               if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
+               if (IsSectionWritable(Adapter, ISO_IMAGE1) == false)
                        psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
 
-               if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) {
+               if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE1) {
                        psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
                        SetActiveISODone = TRUE;
                }
@@ -3183,11 +3183,11 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                        psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
 
                /* Calculation for extrating the Access permission */
-               if (IsSectionWritable(Adapter, DSD2) == FALSE) {
+               if (IsSectionWritable(Adapter, DSD2) == false) {
                        psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
                } else {
                        /* Means section is writable */
-                       if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) {
+                       if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD2)) {
                                psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
                                SetActiveDSDDone = TRUE;
                        }
@@ -3205,11 +3205,11 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                        psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
 
                /* Calculation for extrating the Access permission */
-               if (IsSectionWritable(Adapter, DSD1) == FALSE) {
+               if (IsSectionWritable(Adapter, DSD1) == false) {
                        psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
                } else {
                        /* Means section is writable */
-                       if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) {
+                       if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD1)) {
                                psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
                                SetActiveDSDDone = TRUE;
                        }
@@ -3227,11 +3227,11 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                        psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
 
                /* Setting Access permission */
-               if (IsSectionWritable(Adapter, DSD0) == FALSE) {
+               if (IsSectionWritable(Adapter, DSD0) == false) {
                        psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
                } else {
                        /* Means section is writable */
-                       if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) {
+                       if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD0)) {
                                psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
                                SetActiveDSDDone = TRUE;
                        }
@@ -3249,7 +3249,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
 
                /* Calculation for extrating the Access permission */
-               if (IsSectionWritable(Adapter, VSA0) == FALSE)
+               if (IsSectionWritable(Adapter, VSA0) == false)
                        psFlash2xBitMap->VSA0 |=  FLASH2X_SECTION_RO;
 
                /* By Default section is Active */
@@ -3267,7 +3267,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
 
                /* Checking For Access permission */
-               if (IsSectionWritable(Adapter, VSA1) == FALSE)
+               if (IsSectionWritable(Adapter, VSA1) == false)
                        psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
 
                /* By Default section is Active */
@@ -3285,7 +3285,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
 
                /* Checking For Access permission */
-               if (IsSectionWritable(Adapter, VSA2) == FALSE)
+               if (IsSectionWritable(Adapter, VSA2) == false)
                        psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
 
                /* By Default section is Active */
@@ -3303,7 +3303,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
 
                /* Checking For Access permission */
-               if (IsSectionWritable(Adapter, SCSI) == FALSE)
+               if (IsSectionWritable(Adapter, SCSI) == false)
                        psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
 
                /* By Default section is Active */
@@ -3321,7 +3321,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_fl
                psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
 
                /* Checking For Access permission */
-               if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
+               if (IsSectionWritable(Adapter, CONTROL_SECTION) == false)
                        psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
 
                /* By Default section is Active */
@@ -3358,7 +3358,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti
        /* struct bcm_dsd_header sDSD = {0};
         * struct bcm_iso_header sISO = {0};
         */
-       int HighestPriDSD = 0 ;
+       int HighestPriDSD = 0;
        int HighestPriISO = 0;
 
        Status = IsSectionWritable(Adapter, eFlash2xSectVal);
@@ -3517,7 +3517,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti
                break;
        }
 
-       Adapter->bHeaderChangeAllowed = FALSE;
+       Adapter->bHeaderChangeAllowed = false;
        return Status;
 }
 
@@ -3536,7 +3536,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
        enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
        unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
        unsigned int uiTotalDataToCopy = 0;
-       BOOLEAN IsThisHeaderSector = FALSE;
+       bool IsThisHeaderSector = false;
        unsigned int sigOffset = 0;
        unsigned int ISOLength = 0;
        unsigned int Status = STATUS_SUCCESS;
@@ -3669,14 +3669,14 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
                                break;
                        }
 
-                       Adapter->bHeaderChangeAllowed = FALSE;
+                       Adapter->bHeaderChangeAllowed = false;
                        if (IsThisHeaderSector == TRUE) {
                                WriteToFlashWithoutSectorErase(Adapter,
                                                        SigBuff,
                                                        eISOWritePart,
                                                        sigOffset,
                                                        MAX_RW_SIZE);
-                               IsThisHeaderSector = FALSE;
+                               IsThisHeaderSector = false;
                        }
                        /* subtracting the written Data */
                        uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
@@ -3782,7 +3782,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
                                break;
                        }
 
-                       Adapter->bHeaderChangeAllowed = FALSE;
+                       Adapter->bHeaderChangeAllowed = false;
                        if (IsThisHeaderSector == TRUE) {
                                WriteToFlashWithoutSectorErase(Adapter,
                                                        SigBuff,
@@ -3790,7 +3790,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
                                                        sigOffset,
                                                        MAX_RW_SIZE);
 
-                               IsThisHeaderSector = FALSE;
+                               IsThisHeaderSector = false;
                        }
 
                        /* subtracting the written Data */
@@ -3848,13 +3848,13 @@ int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sectio
        unsigned int uiOffset = 0;
 
        /* struct bcm_dsd_header dsdHeader = {0}; */
-       if (Adapter->bSigCorrupted == FALSE) {
+       if (Adapter->bSigCorrupted == false) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
                return STATUS_SUCCESS;
        }
 
-       if (Adapter->bAllDSDWriteAllow == FALSE) {
-               if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) {
+       if (Adapter->bAllDSDWriteAllow == false) {
+               if (IsSectionWritable(Adapter, eFlashSectionVal) == false) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
                        return SECTOR_IS_NOT_WRITABLE;
                }
@@ -3886,9 +3886,9 @@ int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sectio
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
 
        Adapter->bHeaderChangeAllowed = TRUE;
-       Adapter->bSigCorrupted = FALSE;
+       Adapter->bSigCorrupted = false;
        BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
-       Adapter->bHeaderChangeAllowed = FALSE;
+       Adapter->bHeaderChangeAllowed = false;
 
        return STATUS_SUCCESS;
 }
@@ -3899,7 +3899,7 @@ int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sectio
  * @Adapater :- Bcm Driver Private Data Structure
  * @psFlash2xReadWrite :-Flash2x Read/write structure pointer
  *
- * Return values:-Return TRUE is request is valid else FALSE.
+ * Return values:-Return TRUE is request is valid else false.
  */
 
 int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
@@ -3912,7 +3912,7 @@ int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2
 
        if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section);
-               return FALSE;
+               return false;
        }
        uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section);
        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section);
@@ -3949,7 +3949,7 @@ int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2
                return TRUE;
        else {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
-               return FALSE;
+               return false;
        }
 }
 
@@ -3966,7 +3966,7 @@ int IsFlash2x(struct bcm_mini_adapter *Adapter)
        if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
                return TRUE;
        else
-               return FALSE;
+               return false;
 }
 
 /*
@@ -3986,7 +3986,7 @@ static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
                 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
                 * In case of Raw Read... use the default value
                 */
-               if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
+               if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
                        !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
                        uiBaseAddr = Adapter->uiFlashBaseAdd;
                else
@@ -3996,7 +3996,7 @@ static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
                 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
                 * In case of Raw Read... use the default value
                 */
-               if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
+               if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
                        !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
                        uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
                else
@@ -4094,7 +4094,7 @@ int BcmCopySection(struct bcm_mini_adapter *Adapter,
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
                        break;
                }
-               Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE);
+               Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, false);
                if (Status) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
                        break;
@@ -4110,7 +4110,7 @@ int BcmCopySection(struct bcm_mini_adapter *Adapter,
        } while (numOfBytes > 0);
 
        kfree(pBuff);
-       Adapter->bHeaderChangeAllowed = FALSE;
+       Adapter->bHeaderChangeAllowed = false;
 
        return Status;
 }
@@ -4129,7 +4129,7 @@ int BcmCopySection(struct bcm_mini_adapter *Adapter,
 int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
 {
        unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
-       BOOLEAN bHasHeader = FALSE;
+       bool bHasHeader = false;
        PUCHAR pTempBuff = NULL;
        unsigned int uiSectAlignAddr = 0;
        unsigned int sig = 0;
@@ -4153,7 +4153,7 @@ int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned
                bHasHeader = TRUE;
        }
        /* If Header is present overwrite passed buffer with this */
-       if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) {
+       if (bHasHeader && (Adapter->bHeaderChangeAllowed == false)) {
                pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL);
                if (!pTempBuff) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
@@ -4172,13 +4172,13 @@ int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned
                sig = ntohl(sig);
                if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
-                       Adapter->bSigCorrupted = FALSE;
+                       Adapter->bSigCorrupted = false;
                        return STATUS_SUCCESS;
                }
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig);
                *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER);
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only");
-               Adapter->bSigCorrupted = FALSE;
+               Adapter->bSigCorrupted = false;
        }
 
        return STATUS_SUCCESS;
@@ -4450,7 +4450,7 @@ int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
                BcmDoChipSelect(Adapter, uiOffset);
                uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
 
-               for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
+               for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
                        if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
                                Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
                        else
@@ -4469,19 +4469,19 @@ int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
        return Status;
 }
 
-BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
+bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
 {
-       BOOLEAN SectionPresent = FALSE;
+       bool SectionPresent = false;
 
        switch (section) {
        case ISO_IMAGE1:
                if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
-                       (IsNonCDLessDevice(Adapter) == FALSE))
+                       (IsNonCDLessDevice(Adapter) == false))
                        SectionPresent = TRUE;
                break;
        case ISO_IMAGE2:
                if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
-                       (IsNonCDLessDevice(Adapter) == FALSE))
+                       (IsNonCDLessDevice(Adapter) == false))
                        SectionPresent = TRUE;
                break;
        case DSD0:
@@ -4518,7 +4518,7 @@ BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x
                break;
        default:
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
-               SectionPresent =  FALSE;
+               SectionPresent =  false;
        }
 
        return SectionPresent;
@@ -4527,17 +4527,17 @@ BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x
 int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
 {
        int offset = STATUS_FAILURE;
-       int Status = FALSE;
+       int Status = false;
 
-       if (IsSectionExistInFlash(Adapter, Section) == FALSE) {
+       if (IsSectionExistInFlash(Adapter, Section) == false) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section);
-               return FALSE;
+               return false;
        }
 
        offset = BcmGetSectionValStartOffset(Adapter, Section);
        if (offset == INVALID_OFFSET) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section);
-               return FALSE;
+               return false;
        }
 
        if (IsSectionExistInVendorInfo(Adapter, Section))
@@ -4555,8 +4555,8 @@ static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sect
        unsigned int BlockStatus = 0;
        unsigned int uiSectAlignAddr = 0;
 
-       Adapter->bSigCorrupted = FALSE;
-       if (Adapter->bAllDSDWriteAllow == FALSE) {
+       Adapter->bSigCorrupted = false;
+       if (Adapter->bAllDSDWriteAllow == false) {
                if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
                        return SECTOR_IS_NOT_WRITABLE;
@@ -4615,7 +4615,7 @@ static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sect
        unsigned int sig = 0;
        unsigned int uiOffset = 0;
 
-       Adapter->bSigCorrupted = FALSE;
+       Adapter->bSigCorrupted = false;
 
        if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
@@ -4656,10 +4656,10 @@ static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sect
        return STATUS_SUCCESS;
 }
 
-BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
+bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
 {
        if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
                return TRUE;
        else
-               return FALSE;
+               return false;
 }
index d38a06f762df19765d014498dfbe736e9fb46e77..2c57a16788c0d6eb82488fa0a814d4a80de9a6b5 100644 (file)
@@ -113,7 +113,7 @@ INT vendorextnReadSection(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_sect
  *             STATUS_SUCCESS/STATUS_FAILURE
  */
 INT vendorextnWriteSection(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
-                       UINT offset, UINT numOfBytes, BOOLEAN bVerify)
+                       UINT offset, UINT numOfBytes, bool bVerify)
 {
        return STATUS_FAILURE;
 }
index 52890d216edf3b9828e7ad040c6df4d0e6195a25..ff57f05704511b259035c06d6e05e64eb6c51add 100644 (file)
@@ -11,7 +11,7 @@ INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg);
 INT vendorextnReadSection(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
                        UINT offset, UINT numOfBytes);
 INT vendorextnWriteSection(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
-                       UINT offset, UINT numOfBytes, BOOLEAN bVerify);
+                       UINT offset, UINT numOfBytes, bool bVerify);
 INT vendorextnWriteSectionWithoutErase(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
                        UINT offset, UINT numOfBytes);
 
index 0e783e8d71ca3e8691b1a1c00cfd54cd0d1c4691..7a9bf3b578104bf57939ce032c96dc17c88840be 100644 (file)
@@ -16,7 +16,8 @@
  *  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
- *  or on the worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *  or on the worldwide web at
+ *  http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  *
  */
 
@@ -72,8 +73,9 @@ static int btmtk_usb_reset(struct usb_device *udev)
 
        BT_DBG("%s\n", __func__);
 
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, DEVICE_VENDOR_REQUEST_OUT,
-                                                 0x01, 0x00, NULL, 0x00, CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
+                       DEVICE_VENDOR_REQUEST_OUT, 0x01, 0x00,
+                       NULL, 0x00, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
                BT_ERR("%s error(%d)\n", __func__, ret);
@@ -91,20 +93,22 @@ static int btmtk_usb_io_read32(struct btmtk_usb_data *data, u32 reg, u32 *val)
        u8 request = data->r_request;
        struct usb_device *udev = data->udev;
        int ret;
+       __le32 val_le;
 
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request, DEVICE_VENDOR_REQUEST_IN,
-                                                 0x0, reg, data->io_buf, 4,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request,
+                       DEVICE_VENDOR_REQUEST_IN, 0x0, reg, data->io_buf,
+                       4, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
                *val = 0xffffffff;
-               BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, *val);
+               BT_ERR("%s error(%d), reg=%x, value=%x\n",
+                               __func__, ret, reg, *val);
                return ret;
        }
 
-       memmove(val, data->io_buf, 4);
+       memmove(&val_le, data->io_buf, 4);
 
-       *val = le32_to_cpu(*val);
+       *val = le32_to_cpu(val_le);
 
        if (ret > 0)
                ret = 0;
@@ -122,12 +126,13 @@ static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val)
        index = (u16)reg;
        value = val & 0x0000ffff;
 
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, DEVICE_VENDOR_REQUEST_OUT,
-                                                 value, index, NULL, 0,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request,
+                       DEVICE_VENDOR_REQUEST_OUT, value, index,
+                       NULL, 0, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
-               BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, val);
+               BT_ERR("%s error(%d), reg=%x, value=%x\n",
+                               __func__, ret, reg, val);
                return ret;
        }
 
@@ -139,7 +144,8 @@ static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val)
                                value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
-               BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, val);
+               BT_ERR("%s error(%d), reg=%x, value=%x\n",
+                               __func__, ret, reg, val);
                return ret;
        }
 
@@ -186,13 +192,15 @@ static void btmtk_usb_cap_init(struct btmtk_usb_data *data)
                ret = request_firmware(&firmware, MT7650_FIRMWARE, &udev->dev);
                if (ret < 0) {
                        if (ret == -ENOENT) {
-                               BT_ERR("Firmware file \"%s\" not found \n", MT7650_FIRMWARE);
+                               BT_ERR("Firmware file \"%s\" not found\n",
+                                               MT7650_FIRMWARE);
                        } else {
-                               BT_ERR("Firmware file \"%s\" request failed (err=%d) \n",
+                               BT_ERR("Firmware file \"%s\" request failed (err=%d)\n",
                                        MT7650_FIRMWARE, ret);
                        }
                } else {
-                       BT_DBG("Firmware file \"%s\" Found \n", MT7650_FIRMWARE);
+                       BT_DBG("Firmware file \"%s\" Found\n",
+                                       MT7650_FIRMWARE);
                        /* load firmware here */
                        data->firmware = firmware;
                        btmtk_usb_load_fw(data);
@@ -205,7 +213,8 @@ static void btmtk_usb_cap_init(struct btmtk_usb_data *data)
                ret = request_firmware(&firmware, MT7662_FIRMWARE, &udev->dev);
                if (ret < 0) {
                        if (ret == -ENOENT) {
-                               BT_ERR("Firmware file \"%s\" not found\n", MT7662_FIRMWARE);
+                               BT_ERR("Firmware file \"%s\" not found\n",
+                                               MT7662_FIRMWARE);
                        } else {
                                BT_ERR("Firmware file \"%s\" request failed (err=%d)\n",
                                        MT7662_FIRMWARE, ret);
@@ -241,9 +250,8 @@ static u16 checksume16(u8 *pData, int len)
        if (len)
                sum += *((u8 *)pData);
 
-       while (sum >> 16) {
+       while (sum >> 16)
                sum = (sum & 0xFFFF) + (sum >> 16);
-       }
 
        return ~sum;
 }
@@ -258,13 +266,12 @@ static int btmtk_usb_chk_crc(struct btmtk_usb_data *data, u32 checksum_len)
        memmove(data->io_buf, &data->rom_patch_offset, 4);
        memmove(&data->io_buf[4], &checksum_len, 4);
 
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, DEVICE_VENDOR_REQUEST_IN,
-                                                 0x20, 0x00, data->io_buf, 8,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1,
+                       DEVICE_VENDOR_REQUEST_IN, 0x20, 0x00, data->io_buf,
+                       8, CONTROL_TIMEOUT_JIFFIES);
 
-       if (ret < 0) {
+       if (ret < 0)
                BT_ERR("%s error(%d)\n", __func__, ret);
-       }
 
        return ret;
 }
@@ -274,6 +281,7 @@ static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data)
        int ret = 0;
        struct usb_device *udev = data->udev;
        u16 crc, count = 0;
+       __le16 crc_le;
 
        BT_DBG("%s\n", __func__);
 
@@ -288,9 +296,9 @@ static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data)
                        BT_ERR("%s error(%d)\n", __func__, ret);
                }
 
-               memmove(&crc, data->io_buf, 2);
+               memmove(&crc_le, data->io_buf, 2);
 
-               crc = le16_to_cpu(crc);
+               crc = le16_to_cpu(crc_le);
 
                if (crc != 0xFFFF)
                        break;
@@ -318,8 +326,8 @@ static int btmtk_usb_reset_wmt(struct btmtk_usb_data *data)
        BT_DBG("%s\n", __func__);
 
        ret = usb_control_msg(data->udev, usb_sndctrlpipe(data->udev, 0), 0x01,
-                               DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00, data->io_buf,
-                               8, CONTROL_TIMEOUT_JIFFIES);
+                               DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00,
+                               data->io_buf, 8, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret)
                BT_ERR("%s:(%d)\n", __func__, ret);
@@ -350,7 +358,8 @@ static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *data)
        unsigned char phase;
        void *buf;
        char *pos;
-       unsigned int pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
+       unsigned int pipe;
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
 
        if (!data->firmware) {
                BT_ERR("%s:please assign a rom patch\n", __func__);
@@ -391,7 +400,8 @@ load_patch_protect:
                goto error0;
        }
 
-       buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT, GFP_ATOMIC, &data_dma);
+       buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT,
+                       GFP_ATOMIC, &data_dma);
 
        if (!buf) {
                ret = -ENOMEM;
@@ -409,78 +419,82 @@ load_patch_protect:
        /* loading rom patch */
        while (1) {
                s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE;
-               sent_len = (patch_len - cur_len) >= sent_len_max ? sent_len_max : (patch_len - cur_len);
+               sent_len = min_t(s32, (patch_len - cur_len), sent_len_max);
 
                BT_DBG("patch_len = %d\n", patch_len);
                BT_DBG("cur_len = %d\n", cur_len);
                BT_DBG("sent_len = %d\n", sent_len);
 
-               if (sent_len > 0) {
-                       if (first_block == 1) {
-                               if (sent_len < sent_len_max)
-                                       phase = PATCH_PHASE3;
-                               else
-                                       phase = PATCH_PHASE1;
-                               first_block = 0;
-                       } else if (sent_len == sent_len_max) {
-                               phase = PATCH_PHASE2;
-                       } else {
+               if (sent_len <= 0)
+                       break;
+
+               if (first_block == 1) {
+                       if (sent_len < sent_len_max)
                                phase = PATCH_PHASE3;
-                       }
+                       else
+                               phase = PATCH_PHASE1;
+                       first_block = 0;
+               } else if (sent_len == sent_len_max) {
+                       phase = PATCH_PHASE2;
+               } else {
+                       phase = PATCH_PHASE3;
+               }
 
-                       /* prepare HCI header */
-                       pos[0] = 0x6F;
-                       pos[1] = 0xFC;
-                       pos[2] = (sent_len + 5) & 0xFF;
-                       pos[3] = ((sent_len + 5) >> 8) & 0xFF;
+               /* prepare HCI header */
+               pos[0] = 0x6F;
+               pos[1] = 0xFC;
+               pos[2] = (sent_len + 5) & 0xFF;
+               pos[3] = ((sent_len + 5) >> 8) & 0xFF;
 
-                       /* prepare WMT header */
-                       pos[4] = 0x01;
-                       pos[5] = 0x01;
-                       pos[6] = (sent_len + 1) & 0xFF;
-                       pos[7] = ((sent_len + 1) >> 8) & 0xFF;
+               /* prepare WMT header */
+               pos[4] = 0x01;
+               pos[5] = 0x01;
+               pos[6] = (sent_len + 1) & 0xFF;
+               pos[7] = ((sent_len + 1) >> 8) & 0xFF;
 
-                       pos[8] = phase;
+               pos[8] = phase;
 
-                       memcpy(&pos[9], data->firmware->data + PATCH_INFO_SIZE + cur_len, sent_len);
+               memcpy(&pos[9],
+                       data->firmware->data + PATCH_INFO_SIZE + cur_len,
+                       sent_len);
 
-                       BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n",
-                                       sent_len + PATCH_HEADER_SIZE, phase);
+               BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n",
+                               sent_len + PATCH_HEADER_SIZE, phase);
 
-                       usb_fill_bulk_urb(urb,
-                                       data->udev,
-                                       pipe,
-                                       buf,
-                                       sent_len + PATCH_HEADER_SIZE,
-                                       load_rom_patch_complete,
-                                       &sent_to_mcu_done);
+               usb_fill_bulk_urb(urb,
+                               data->udev,
+                               pipe,
+                               buf,
+                               sent_len + PATCH_HEADER_SIZE,
+                               load_rom_patch_complete,
+                               &sent_to_mcu_done);
 
-                       urb->transfer_dma = data_dma;
-                       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               urb->transfer_dma = data_dma;
+               urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-                       ret = usb_submit_urb(urb, GFP_ATOMIC);
+               ret = usb_submit_urb(urb, GFP_ATOMIC);
 
-                       if (ret)
-                               goto error2;
+               if (ret)
+                       goto error2;
 
-                       if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
-                               usb_kill_urb(urb);
-                               BT_ERR("upload rom_patch timeout\n");
-                               goto error2;
-                       }
+               if (!wait_for_completion_timeout(&sent_to_mcu_done,
+                                       msecs_to_jiffies(1000))) {
+                       usb_kill_urb(urb);
+                       BT_ERR("upload rom_patch timeout\n");
+                       goto error2;
+               }
 
-                       BT_DBG(".");
+               BT_DBG(".");
 
-                       mdelay(200);
+               mdelay(200);
 
-                       cur_len += sent_len;
+               cur_len += sent_len;
 
-               } else {
-                       break;
-               }
        }
 
-       total_checksum = checksume16((u8 *)data->firmware->data + PATCH_INFO_SIZE, patch_len);
+       total_checksum = checksume16(
+                       (u8 *)data->firmware->data + PATCH_INFO_SIZE,
+                       patch_len);
 
        BT_DBG("Send checksum req..\n");
 
@@ -520,8 +534,8 @@ static int load_fw_iv(struct btmtk_usb_data *data)
        memmove(buf, data->firmware->data + 32, 64);
 
        ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
-                                                 DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+                       DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64,
+                       CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
                BT_ERR("%s error(%d) step4\n", __func__, ret);
@@ -552,6 +566,7 @@ static int btmtk_usb_load_fw(struct btmtk_usb_data *data)
        void *buf;
        u32 cur_len = 0;
        u32 packet_header = 0;
+       __le32 packet_header_le;
        u32 value;
        u32 ilm_len = 0, dlm_len = 0;
        u16 fw_ver, build_ver;
@@ -559,7 +574,8 @@ static int btmtk_usb_load_fw(struct btmtk_usb_data *data)
        dma_addr_t data_dma;
        int ret = 0, sent_len;
        struct completion sent_to_mcu_done;
-       unsigned int pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
+       unsigned int pipe;
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
 
        if (!data->firmware) {
                BT_ERR("%s:please assign a fw\n", __func__);
@@ -598,9 +614,11 @@ loadfw_protect:
                        | (*(data->firmware->data + 5) << 8)
                        | (*(data->firmware->data + 4));
 
-       fw_ver = (*(data->firmware->data + 11) << 8) | (*(data->firmware->data + 10));
+       fw_ver = (*(data->firmware->data + 11) << 8) |
+             (*(data->firmware->data + 10));
 
-       build_ver = (*(data->firmware->data + 9) << 8) | (*(data->firmware->data + 8));
+       build_ver = (*(data->firmware->data + 9) << 8) |
+                (*(data->firmware->data + 8));
 
        BT_DBG("fw version:%d.%d.%02d ",
                        (fw_ver & 0xf000) >> 8,
@@ -657,22 +675,22 @@ loadfw_protect:
 
        /* Loading ILM */
        while (1) {
-               sent_len = (ilm_len - cur_len) >= 14336 ? 14336 : (ilm_len - cur_len);
+               sent_len = min_t(s32, (ilm_len - cur_len), 14336);
 
                if (sent_len > 0) {
                        packet_header &= ~(0xffffffff);
                        packet_header |= (sent_len << 16);
-                       packet_header = cpu_to_le32(packet_header);
+                       packet_header_le = cpu_to_le32(packet_header);
 
-                       memmove(buf, &packet_header, 4);
-                       memmove(buf + 4, data->firmware->data + 32 + cur_len, sent_len);
+                       memmove(buf, &packet_header_le, 4);
+                       memmove(buf + 4, data->firmware->data + 32 + cur_len,
+                                       sent_len);
 
                        /* U2M_PDMA descriptor */
                        btmtk_usb_io_write32(data, 0x230, cur_len);
 
-                       while ((sent_len % 4) != 0) {
+                       while ((sent_len % 4) != 0)
                                sent_len++;
-                       }
 
                        /* U2M_PDMA length */
                        btmtk_usb_io_write32(data, 0x234, sent_len << 16);
@@ -693,7 +711,8 @@ loadfw_protect:
                        if (ret)
                                goto error3;
 
-                       if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
+                       if (!wait_for_completion_timeout(&sent_to_mcu_done,
+                                               msecs_to_jiffies(1000))) {
                                usb_kill_urb(urb);
                                BT_ERR("upload ilm fw timeout\n");
                                goto error3;
@@ -714,58 +733,60 @@ loadfw_protect:
 
        /* Loading DLM */
        while (1) {
-               sent_len = (dlm_len - cur_len) >= 14336 ? 14336 : (dlm_len - cur_len);
+               sent_len = min_t(s32, (dlm_len - cur_len), 14336);
 
-               if (sent_len > 0) {
-                       packet_header &= ~(0xffffffff);
-                       packet_header |= (sent_len << 16);
-                       packet_header = cpu_to_le32(packet_header);
+               if (sent_len <= 0)
+                       break;
 
-                       memmove(buf, &packet_header, 4);
-                       memmove(buf + 4, data->firmware->data + 32 + ilm_len + cur_len, sent_len);
+               packet_header &= ~(0xffffffff);
+               packet_header |= (sent_len << 16);
+               packet_header_le = cpu_to_le32(packet_header);
 
-                       /* U2M_PDMA descriptor */
-                       btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len);
+               memmove(buf, &packet_header_le, 4);
+               memmove(buf + 4,
+                       data->firmware->data + 32 + ilm_len + cur_len,
+                       sent_len);
 
-                       while ((sent_len % 4) != 0) {
-                               BT_DBG("sent_len is not divided by 4\n");
-                               sent_len++;
-                       }
+               /* U2M_PDMA descriptor */
+               btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len);
 
-                       /* U2M_PDMA length */
-                       btmtk_usb_io_write32(data, 0x234, sent_len << 16);
+               while ((sent_len % 4) != 0) {
+                       BT_DBG("sent_len is not divided by 4\n");
+                       sent_len++;
+               }
 
-                       usb_fill_bulk_urb(urb,
-                                       udev,
-                                       pipe,
-                                       buf,
-                                       sent_len + 4,
-                                       load_fw_complete,
-                                       &sent_to_mcu_done);
+               /* U2M_PDMA length */
+               btmtk_usb_io_write32(data, 0x234, sent_len << 16);
 
-                       urb->transfer_dma = data_dma;
-                       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               usb_fill_bulk_urb(urb,
+                               udev,
+                               pipe,
+                               buf,
+                               sent_len + 4,
+                               load_fw_complete,
+                               &sent_to_mcu_done);
 
-                       ret = usb_submit_urb(urb, GFP_ATOMIC);
+               urb->transfer_dma = data_dma;
+               urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-                       if (ret)
-                               goto error3;
+               ret = usb_submit_urb(urb, GFP_ATOMIC);
 
-                       if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
-                               usb_kill_urb(urb);
-                               BT_ERR("upload dlm fw timeout\n");
-                               goto error3;
-                       }
+               if (ret)
+                       goto error3;
 
-                       BT_DBG(".");
+               if (!wait_for_completion_timeout(&sent_to_mcu_done,
+                                       msecs_to_jiffies(1000))) {
+                       usb_kill_urb(urb);
+                       BT_ERR("upload dlm fw timeout\n");
+                       goto error3;
+               }
 
-                       mdelay(500);
+               BT_DBG(".");
 
-                       cur_len += sent_len;
+               mdelay(500);
+
+               cur_len += sent_len;
 
-               } else {
-                       break;
-               }
        }
 
        /* upload 64bytes interrupt vector */
@@ -921,9 +942,8 @@ static void btmtk_usb_bulk_in_complete(struct urb *urb)
        BT_DBG("%s:%s urb %p status %d count %d", __func__, hdev->name,
                                        urb, urb->status, urb->actual_length);
 
-       if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
                return;
-       }
 
        if (urb->status == 0) {
                hdev->stat.byte_rx += urb->actual_length;
@@ -978,8 +998,8 @@ static int btmtk_usb_submit_bulk_in_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
        pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
 
-       usb_fill_bulk_urb(urb, data->udev, pipe,
-                                       buf, size, btmtk_usb_bulk_in_complete, hdev);
+       usb_fill_bulk_urb(urb, data->udev, pipe, buf, size,
+                       btmtk_usb_bulk_in_complete, hdev);
 
        urb->transfer_flags |= URB_FREE_BUFFER;
 
@@ -1015,7 +1035,8 @@ static void btmtk_usb_isoc_in_complete(struct urb *urb)
        if (urb->status == 0) {
                for (i = 0; i < urb->number_of_packets; i++) {
                        unsigned int offset = urb->iso_frame_desc[i].offset;
-                       unsigned int length = urb->iso_frame_desc[i].actual_length;
+                       unsigned int length;
+                       length = urb->iso_frame_desc[i].actual_length;
 
                        if (urb->iso_frame_desc[i].status)
                                continue;
@@ -1096,8 +1117,9 @@ static int btmtk_usb_submit_isoc_in_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
        pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
 
-       usb_fill_int_urb(urb, data->udev, pipe, buf, size, btmtk_usb_isoc_in_complete,
-                               hdev, data->isoc_rx_ep->bInterval);
+       usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+                       btmtk_usb_isoc_in_complete, hdev,
+                       data->isoc_rx_ep->bInterval);
 
        urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
 
@@ -1306,7 +1328,8 @@ static int btmtk_usb_send_frame(struct sk_buff *skb)
                }
 
                usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
-                               skb->data, skb->len, btmtk_usb_tx_complete, skb);
+                               skb->data, skb->len,
+                               btmtk_usb_tx_complete, skb);
 
                hdev->stat.cmd_tx++;
                break;
@@ -1322,8 +1345,8 @@ static int btmtk_usb_send_frame(struct sk_buff *skb)
                pipe = usb_sndbulkpipe(data->udev,
                                        data->bulk_tx_ep->bEndpointAddress);
 
-               usb_fill_bulk_urb(urb, data->udev, pipe,
-                               skb->data, skb->len, btmtk_usb_tx_complete, skb);
+               usb_fill_bulk_urb(urb, data->udev, pipe, skb->data,
+                               skb->len, btmtk_usb_tx_complete, skb);
 
                hdev->stat.acl_tx++;
                BT_DBG("HCI_ACLDATA_PKT:\n");
@@ -1442,7 +1465,8 @@ static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
 
 static void btmtk_usb_work(struct work_struct *work)
 {
-       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, work);
+       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data,
+                       work);
        struct hci_dev *hdev = data->hdev;
        int new_alts;
        int err;
@@ -1451,7 +1475,8 @@ static void btmtk_usb_work(struct work_struct *work)
 
        if (hdev->conn_hash.sco_num > 0) {
                if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
-                       err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
+                       err = usb_autopm_get_interface(data->isoc ?
+                                       data->isoc : data->intf);
                        if (err < 0) {
                                clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
                                usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -1489,13 +1514,15 @@ static void btmtk_usb_work(struct work_struct *work)
                __set_isoc_interface(hdev, 0);
 
                if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
-                        usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
+                       usb_autopm_put_interface(data->isoc ?
+                                        data->isoc : data->intf);
        }
 }
 
 static void btmtk_usb_waker(struct work_struct *work)
 {
-       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, waker);
+       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data,
+                       waker);
        int err;
 
        err = usb_autopm_get_interface(data->intf);
index 2dbaf39e2fc296b0b5acfc6b32fd0f9bb67d80e3..62efd74b8c04746da6cb1ccfa425139fa67e89bf 100644 (file)
@@ -692,10 +692,7 @@ static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
                __func__, puBuf, dwLength, bCircular);
 
        /*  To pin down user pages we must first acquire the mapping semaphore. */
-       down_read(&current->mm->mmap_sem);      /*  get memory map semaphore */
-       nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0,
-                               pPages, NULL);
-       up_read(&current->mm->mmap_sem);        /*  release the semaphore */
+       nPages = get_user_pages_fast(ulStart, len, 1, pPages);
        dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages);
 
        if (nPages > 0) {               /*  if we succeeded */
index f73287eab373a92b7f1a9876c3e53eb7f2cee327..bfa27e7fc0169feb81a0dc631c7a85f565dea107 100644 (file)
@@ -485,6 +485,7 @@ config COMEDI_NI_ATMIO
        tristate "NI AT-MIO E series ISA-PNP card support"
        select COMEDI_8255
        select COMEDI_NI_TIO
+       select COMEDI_FC
        ---help---
          Enable support for National Instruments AT-MIO E series cards
          National Instruments AT-MIO-16E-1 (ni_atmio),
@@ -990,8 +991,6 @@ config COMEDI_ME_DAQ
 
 config COMEDI_NI_6527
        tristate "NI 6527 support"
-       depends on HAS_DMA
-       select COMEDI_MITE
        ---help---
          Enable support for the National Instruments 6527 PCI card
 
index 94b2385fb0af29afc1812f0029ee28d47ff64608..4e26bd7fc84f3560135296aea5cadd736df7797d 100644 (file)
@@ -344,7 +344,7 @@ unsigned int comedi_buf_read_free(struct comedi_async *async,
 }
 EXPORT_SYMBOL_GPL(comedi_buf_read_free);
 
-int comedi_buf_put(struct comedi_async *async, short x)
+int comedi_buf_put(struct comedi_async *async, unsigned short x)
 {
        unsigned int n = __comedi_buf_write_alloc(async, sizeof(short), 1);
 
@@ -352,20 +352,20 @@ int comedi_buf_put(struct comedi_async *async, short x)
                async->events |= COMEDI_CB_ERROR;
                return 0;
        }
-       *(short *)(async->prealloc_buf + async->buf_write_ptr) = x;
+       *(unsigned short *)(async->prealloc_buf + async->buf_write_ptr) = x;
        comedi_buf_write_free(async, sizeof(short));
        return 1;
 }
 EXPORT_SYMBOL_GPL(comedi_buf_put);
 
-int comedi_buf_get(struct comedi_async *async, short *x)
+int comedi_buf_get(struct comedi_async *async, unsigned short *x)
 {
        unsigned int n = comedi_buf_read_n_available(async);
 
        if (n < sizeof(short))
                return 0;
        comedi_buf_read_alloc(async, sizeof(short));
-       *x = *(short *)(async->prealloc_buf + async->buf_read_ptr);
+       *x = *(unsigned short *)(async->prealloc_buf + async->buf_read_ptr);
        comedi_buf_read_free(async, sizeof(short));
        return 1;
 }
index 1636c7ca57e237fcd516141933c5047ee12131da..f3d59e2a1152b5626caa9c7e7e0ebd9f50f587b6 100644 (file)
@@ -543,7 +543,7 @@ void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
 {
        s->private = kzalloc(size, GFP_KERNEL);
        if (s->private)
-               comedi_set_subdevice_runflags(s, ~0, SRF_FREE_SPRIV);
+               s->runflags |= SRF_FREE_SPRIV;
        return s->private;
 }
 EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
@@ -806,7 +806,6 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
                } else {
                        us->range_type = 0;     /* XXX */
                }
-               us->flags = s->flags;
 
                if (s->busy)
                        us->subd_flags |= SDF_BUSY;
@@ -818,8 +817,6 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
                        us->subd_flags |= SDF_LOCK_OWNER;
                if (!s->maxdata && s->maxdata_list)
                        us->subd_flags |= SDF_MAXDATA;
-               if (s->flaglist)
-                       us->subd_flags |= SDF_FLAGS;
                if (s->range_table_list)
                        us->subd_flags |= SDF_RANGETYPE;
                if (s->do_cmd)
@@ -829,8 +826,6 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
                        us->insn_bits_support = COMEDI_SUPPORTED;
                else
                        us->insn_bits_support = COMEDI_UNSUPPORTED;
-
-               us->settling_time_0 = s->settling_time_0;
        }
 
        ret = copy_to_user(arg, tmp, dev->n_subdevices * sizeof(*tmp));
@@ -875,13 +870,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
                        return -EFAULT;
        }
 
-       if (it.flaglist) {
-               if (!s->flaglist)
-                       return -EINVAL;
-               if (copy_to_user(it.flaglist, s->flaglist,
-                                s->n_chan * sizeof(unsigned int)))
-                       return -EFAULT;
-       }
+       if (it.flaglist)
+               return -EINVAL; /* flaglist not supported */
 
        if (it.rangelist) {
                int i;
@@ -1431,17 +1421,11 @@ static int do_cmd_ioctl(struct comedi_device *dev,
        async->cmd = cmd;
        async->cmd.data = NULL;
        /* load channel/gain list */
-       async->cmd.chanlist =
-           kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL);
-       if (!async->cmd.chanlist) {
-               DPRINTK("allocation failed\n");
-               return -ENOMEM;
-       }
-
-       if (copy_from_user(async->cmd.chanlist, user_chanlist,
-                          async->cmd.chanlist_len * sizeof(int))) {
-               DPRINTK("fault reading chanlist\n");
-               ret = -EFAULT;
+       async->cmd.chanlist = memdup_user(user_chanlist,
+                                         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);
                goto cleanup;
        }
 
@@ -1485,7 +1469,8 @@ 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, ~0, SRF_USER | SRF_RUNNING);
+       comedi_set_subdevice_runflags(s, SRF_USER | SRF_ERROR | SRF_RUNNING,
+                                     SRF_USER | SRF_RUNNING);
 
        /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
         * comedi_read() or comedi_write() */
@@ -1558,18 +1543,11 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
 
        /* load channel/gain list */
        if (cmd.chanlist) {
-               chanlist =
-                   kmalloc(cmd.chanlist_len * sizeof(int), GFP_KERNEL);
-               if (!chanlist) {
-                       DPRINTK("allocation failed\n");
-                       ret = -ENOMEM;
-                       goto cleanup;
-               }
-
-               if (copy_from_user(chanlist, user_chanlist,
-                                  cmd.chanlist_len * sizeof(int))) {
-                       DPRINTK("fault reading chanlist\n");
-                       ret = -EFAULT;
+               chanlist = memdup_user(user_chanlist,
+                                      cmd.chanlist_len * sizeof(int));
+               if (IS_ERR(chanlist)) {
+                       ret = PTR_ERR(chanlist);
+                       DPRINTK("memdup_user exited with code %d", ret);
                        goto cleanup;
                }
 
index 2e19f659cd22ff828ceb056dc82bc644156e0913..143be8076a2e72361d11f88a2b64db8c4b89855b 100644 (file)
@@ -57,11 +57,6 @@ struct comedi_subdevice {
        unsigned int maxdata;   /* if maxdata==0, use list */
        const unsigned int *maxdata_list;       /* list is channel specific */
 
-       unsigned int flags;
-       const unsigned int *flaglist;
-
-       unsigned int settling_time_0;
-
        const struct comedi_lrange *range_table;
        const struct comedi_lrange *const *range_table_list;
 
@@ -307,7 +302,26 @@ static inline bool comedi_range_is_unipolar(struct comedi_subdevice *s,
        return s->range_table->range[range].min >= 0;
 }
 
-/* some silly little inline functions */
+static inline bool comedi_chan_range_is_bipolar(struct comedi_subdevice *s,
+                                               unsigned int chan,
+                                               unsigned int range)
+{
+       return s->range_table_list[chan]->range[range].min < 0;
+}
+
+static inline bool comedi_chan_range_is_unipolar(struct comedi_subdevice *s,
+                                                unsigned int chan,
+                                                unsigned int range)
+{
+       return s->range_table_list[chan]->range[range].min >= 0;
+}
+
+/* munge between offset binary and two's complement values */
+static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s,
+                                              unsigned int val)
+{
+       return val ^ s->maxdata ^ (s->maxdata >> 1);
+}
 
 static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
 {
@@ -332,8 +346,8 @@ unsigned int comedi_buf_read_n_available(struct comedi_async *);
 unsigned int comedi_buf_read_alloc(struct comedi_async *, unsigned int);
 unsigned int comedi_buf_read_free(struct comedi_async *, unsigned int);
 
-int comedi_buf_put(struct comedi_async *, short);
-int comedi_buf_get(struct comedi_async *, short *);
+int comedi_buf_put(struct comedi_async *, unsigned short);
+int comedi_buf_get(struct comedi_async *, unsigned short *);
 
 void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
                          const void *source, unsigned int num_bytes);
@@ -345,6 +359,8 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
 int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *,
                           struct comedi_insn *, unsigned int *data,
                           unsigned int mask);
+unsigned int comedi_dio_update_state(struct comedi_subdevice *,
+                                    unsigned int *data);
 
 void *comedi_alloc_devpriv(struct comedi_device *, size_t);
 int comedi_alloc_subdevices(struct comedi_device *, int);
index 317a821b7906409a5fef8edd6a40b3360945300e..8f02bf66e20b2002b3b52655919a89f95c0fcad9 100644 (file)
@@ -190,6 +190,28 @@ int comedi_dio_insn_config(struct comedi_device *dev,
 }
 EXPORT_SYMBOL_GPL(comedi_dio_insn_config);
 
+/**
+ * comedi_dio_update_state() - update the internal state of DIO subdevices.
+ * @s: comedi_subdevice struct
+ * @data: the channel mask and bits to update
+ */
+unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
+                                    unsigned int *data)
+{
+       unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1)
+                                                : 0xffffffff;
+       unsigned int mask = data[0] & chanmask;
+       unsigned int bits = data[1];
+
+       if (mask) {
+               s->state &= ~mask;
+               s->state |= (bits & mask);
+       }
+
+       return mask;
+}
+EXPORT_SYMBOL_GPL(comedi_dio_update_state);
+
 static int insn_rw_emulate_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
@@ -285,6 +307,13 @@ static int __comedi_device_postconfig(struct comedi_device *dev)
                if (s->type == COMEDI_SUBD_UNUSED)
                        continue;
 
+               if (s->type == COMEDI_SUBD_DO) {
+                       if (s->n_chan < 32)
+                               s->io_bits = (1 << s->n_chan) - 1;
+                       else
+                               s->io_bits = 0xffffffff;
+               }
+
                if (s->len_chanlist == 0)
                        s->len_chanlist = 1;
 
index 3abedcd2527bbb2aade465b75f0fe23f4918afdf..e3d737cf73029070248ff603b13ce89a6abf0c49 100644 (file)
 
 #include "../comedi.h"
 
+/*
+ * Common oscillator base values in nanoseconds
+ */
+#define I8254_OSC_BASE_10MHZ           100
+#define I8254_OSC_BASE_5MHZ            200
+#define I8254_OSC_BASE_4MHZ            250
+#define I8254_OSC_BASE_2MHZ            500
+#define I8254_OSC_BASE_1MHZ            1000
+
 #define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
 
 static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
index 2f070fdbbb1d3b206b6e17f5f10bea0ec6e3a02a..b4009e863414ed87be35f2168921cf02e20caa67 100644 (file)
@@ -112,7 +112,7 @@ void subdev_8255_interrupt(struct comedi_device *dev,
 {
        struct subdev_8255_private *spriv = s->private;
        unsigned long iobase = spriv->iobase;
-       short d;
+       unsigned short d;
 
        d = spriv->io(0, _8255_DATA, 0, iobase);
        d |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8);
@@ -126,30 +126,24 @@ EXPORT_SYMBOL_GPL(subdev_8255_interrupt);
 
 static int subdev_8255_insn(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        struct subdev_8255_private *spriv = s->private;
        unsigned long iobase = spriv->iobase;
        unsigned int mask;
-       unsigned int bits;
        unsigned int v;
 
-       mask = data[0];
-       bits = data[1];
-
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               v = s->state;
-               v &= ~mask;
-               v |= (bits & mask);
-
                if (mask & 0xff)
-                       spriv->io(1, _8255_DATA, v & 0xff, iobase);
+                       spriv->io(1, _8255_DATA, s->state & 0xff, iobase);
                if (mask & 0xff00)
-                       spriv->io(1, _8255_DATA + 1, (v >> 8) & 0xff, iobase);
+                       spriv->io(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
+                                 iobase);
                if (mask & 0xff0000)
-                       spriv->io(1, _8255_DATA + 2, (v >> 16) & 0xff, iobase);
-
-               s->state = v;
+                       spriv->io(1, _8255_DATA + 2, (s->state >> 16) & 0xff,
+                                 iobase);
        }
 
        v = spriv->io(0, _8255_DATA, 0, iobase);
@@ -288,9 +282,6 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
        s->insn_bits    = subdev_8255_insn;
        s->insn_config  = subdev_8255_insn_config;
 
-       s->state        = 0;
-       s->io_bits      = 0;
-
        subdev_8255_do_config(dev, s);
 
        return 0;
index 63dff7729ea893e8e76ce2fdcad61ca50ebb9d45..dc87df032203746418fa7274b36be42c38617d3a 100644 (file)
@@ -204,7 +204,6 @@ static int addi_auto_attach(struct comedi_device *dev,
                s->len_chanlist =
                        devpriv->s_EeParameters.i_NbrDiChannel;
                s->range_table = &range_digital;
-               s->io_bits = 0; /* all bits input */
                s->insn_config = this_board->di_config;
                s->insn_read = this_board->di_read;
                s->insn_write = this_board->di_write;
@@ -223,7 +222,6 @@ static int addi_auto_attach(struct comedi_device *dev,
                s->len_chanlist =
                        devpriv->s_EeParameters.i_NbrDoChannel;
                s->range_table = &range_digital;
-               s->io_bits = 0xf;       /* all bits output */
 
                /* insn_config - for digital output memory */
                s->insn_config = this_board->do_config;
index dfd1e666cc18864191cab0536ddf99c0ee82f3b8..2ed2da3499f44a3c012c6b9bda78019bba1680a5 100644 (file)
@@ -133,7 +133,7 @@ struct addi_private {
        unsigned short us_UseDma;       /*  To use Dma or not */
        unsigned char b_DmaDoubleBuffer;        /*  we can use double buffering */
        unsigned int ui_DmaActualBuffer;        /*  which buffer is used now */
-       short *ul_DmaBufferVirtual[2];  /*  pointers to begin of DMA buffer */
+       unsigned short *ul_DmaBufferVirtual[2]; /*  pointers to DMA buffer */
        unsigned int ul_DmaBufferHw[2]; /*  hw address of DMA buff */
        unsigned int ui_DmaBufferSize[2];       /*  size of dma buffer in bytes */
        unsigned int ui_DmaBufferUsesize[2];    /*  which size we may now used for transfer */
index e3cc429403c08c35df09f02286a1079df039f0c9..84668544f52d79927fa0b664fad3aca6313bd361 100644 (file)
@@ -260,18 +260,13 @@ static int apci1564_do_insn_bits(struct comedi_device *dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
                        APCI1564_DIGITAL_OP_RW);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
                        APCI1564_DIGITAL_OP_RW);
-       }
 
        data[1] = s->state;
 
index 1449b92403e249ff2e1198dfdcc2dece751105ee..3c9eec84f0eb557c25a5ea4bd82fdca4a15f515d 100644 (file)
@@ -1391,7 +1391,7 @@ static int i_APCI3120_CommandAnalogInput(struct comedi_device *dev,
  */
 static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
                                                  struct comedi_subdevice *s,
-                                                 short *dma_buffer,
+                                                 unsigned short *dma_buffer,
                                                  unsigned int num_samples)
 {
        struct addi_private *devpriv = dev->private;
@@ -2175,21 +2175,16 @@ static int apci3120_do_insn_bits(struct comedi_device *dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-       unsigned int val;
 
-       /* The do channels are bits 7:4 of the do register */
-       val = devpriv->b_DigitalOutputRegister >> 4;
-       if (mask) {
-               val &= ~mask;
-               val |= (bits & mask);
-               devpriv->b_DigitalOutputRegister = val << 4;
+       if (comedi_dio_update_state(s, data)) {
+               /* The do channels are bits 7:4 of the do register */
+               devpriv->b_DigitalOutputRegister = s->state << 4;
 
-               outb(val << 4, devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+               outb(devpriv->b_DigitalOutputRegister,
+                    devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
        }
 
-       data[1] = val;
+       data[1] = s->state;
 
        return insn->n;
 }
index 32dce0329fd5a1ab10d8a0c64ff162c538858812..dc73d4d348ed4fa9eb94635e2614e18102939de5 100644 (file)
@@ -623,16 +623,11 @@ static int apci3200_do_insn_bits(struct comedi_device *dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        s->state = inl(devpriv->i_IobaseAddon) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, devpriv->i_IobaseAddon);
-       }
 
        data[1] = s->state;
 
index 08674c18cf429052648b932c59ea7792bd44a47d..9d1b1425c60b7c8ec41f574df4f733687820c688 100644 (file)
@@ -90,16 +90,10 @@ static int apci1516_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inw(dev->iobase + APCI1516_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + APCI1516_DO_REG);
-       }
 
        data[1] = s->state;
 
index 96523744b8de57cc5203d7c7667b60f67f4b647c..5ee204bcbeef3a5577547c34d04c24f378b87464 100644 (file)
@@ -87,17 +87,8 @@ static int apci16xx_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       /* Only update the channels configured as outputs */
-       mask &= s->io_bits;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + APCI16XX_OUT_REG(s->index));
-       }
 
        data[1] = inl(dev->iobase + APCI16XX_IN_REG(s->index));
 
index 6b0ea16ff5467eeb3da5c76a9c8a9f2c9c705faa..c77ee8732d38fe158f974a29ff5f0f2921afc609 100644 (file)
@@ -57,16 +57,10 @@ static int apci2032_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + APCI2032_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + APCI2032_DO_REG);
-       }
 
        data[1] = s->state;
 
index 92ac8ece8494b1e1998ed545ea62f89fb9d793c5..7fb32e778d8ba5742565c3aaf508557dca385807 100644 (file)
@@ -50,16 +50,10 @@ static int apci2200_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inw(dev->iobase + APCI2200_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + APCI2200_DO_REG);
-       }
 
        data[1] = s->state;
 
index d804957018aba8db2c0e95bd4f9d29a33ce8dfa0..67d09e8afb2efdbcf8c21677f884a135c59a5e8b 100644 (file)
@@ -164,7 +164,6 @@ static int apci3120_auto_attach(struct comedi_device *dev,
        s->maxdata = 1;
        s->len_chanlist = this_board->i_NbrDiChannel;
        s->range_table = &range_digital;
-       s->io_bits = 0; /* all bits input */
        s->insn_bits = apci3120_di_insn_bits;
 
        /*  Allocate and Initialise DO Subdevice Structures */
@@ -176,7 +175,6 @@ static int apci3120_auto_attach(struct comedi_device *dev,
        s->maxdata = this_board->i_DoMaxdata;
        s->len_chanlist = this_board->i_NbrDoChannel;
        s->range_table = &range_digital;
-       s->io_bits = 0xf;       /* all bits output */
        s->insn_bits = apci3120_do_insn_bits;
 
        /*  Allocate and Initialise Timer Subdevice Structures */
index d9650ffb7d2f3e99603535b1cf091df0db8b8b54..6138440b919e86dc94ea6c80f06c6573c079bb0b 100644 (file)
@@ -161,16 +161,10 @@ static int apci3501_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + APCI3501_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + APCI3501_DO_REG);
-       }
 
        data[1] = s->state;
 
index cf5dd10eaf91daa71cb75ced4270c450d49d31de..761cbf8f964b3c69b96c84baab5d9c21d7829454 100644 (file)
@@ -664,16 +664,10 @@ static int apci3xxx_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + 48) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + 48);
-       }
 
        data[1] = s->state;
 
@@ -717,16 +711,11 @@ static int apci3xxx_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
+       unsigned int mask;
        unsigned int val;
 
-       /* only update output channels */
-       mask &= s->io_bits;
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0xff)
                        outl(s->state & 0xff, dev->iobase + 80);
                if (mask & 0xff0000)
index a67ad57cefcb906c108f044cd2c3c069bc788418..dd092c7954a9ef88e209b0f5392c6683b4618344 100644 (file)
@@ -1,44 +1,35 @@
 /*
-    comedi/drivers/adl_pci6208.c
-
-    Hardware driver for ADLink 6208 series cards:
-       card         | voltage output    | current output
-       -------------+-------------------+---------------
-       PCI-6208V    |  8 channels       | -
-       PCI-6216V    | 16 channels       | -
-       PCI-6208A    |  8 channels       | 8 channels
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
-
-    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.
-*/
+ * adl_pci6208.c
+ * Comedi driver for ADLink 6208 series cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+ *
+ * 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.
+ */
+
 /*
-Driver: adl_pci6208
-Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
-Devices: (ADLink) PCI-6208 [adl_pci6208]
-        (ADLink) PCI-6216 [adl_pci6216]
-Author: nsyeow <nsyeow@pd.jaring.my>
-Updated: Fri, 30 Jan 2004 14:44:27 +0800
-Status: untested
-
-Configuration Options: not applicable, uses PCI auto config
-
-References:
-       - ni_660x.c
-       - adl_pci9111.c         copied the entire pci setup section
-       - adl_pci9118.c
-*/
+ * Driver: adl_pci6208
+ * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
+ * Devices: (ADLink) PCI-6208 [adl_pci6208]
+ *         (ADLink) PCI-6216 [adl_pci6216]
+ * Author: nsyeow <nsyeow@pd.jaring.my>
+ * Updated: Fri, 30 Jan 2004 14:44:27 +0800
+ * Status: untested
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ */
 
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
 
 #include "../comedidev.h"
@@ -82,37 +73,56 @@ struct pci6208_private {
        unsigned int ao_readback[PCI6208_MAX_AO_CHANNELS];
 };
 
-static int pci6208_ao_winsn(struct comedi_device *dev,
-                           struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+static int pci6208_ao_wait_for_data_send(struct comedi_device *dev,
+                                        unsigned int timeout)
+{
+       unsigned int status;
+
+       while (timeout--) {
+               status = inw(dev->iobase + PCI6208_AO_STATUS);
+               if ((status & PCI6208_AO_STATUS_DATA_SEND) == 0)
+                       return 0;
+               udelay(1);
+       }
+
+       return -ETIME;
+}
+
+static int pci6208_ao_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct pci6208_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
-       unsigned long invert = 1 << (16 - 1);
-       unsigned long value = 0;
-       unsigned short status;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val = devpriv->ao_readback[chan];
+       int ret;
        int i;
 
        for (i = 0; i < insn->n; i++) {
-               value = data[i] ^ invert;
+               val = data[i];
 
-               do {
-                       status = inw(dev->iobase + PCI6208_AO_STATUS);
-               } while (status & PCI6208_AO_STATUS_DATA_SEND);
+               /* D/A transfer rate is 2.2us, wait up to 10us */
+               ret = pci6208_ao_wait_for_data_send(dev, 10);
+               if (ret)
+                       return ret;
 
-               outw(value, dev->iobase + PCI6208_AO_CONTROL(chan));
+               /* the hardware expects two's complement values */
+               outw(comedi_offset_munge(s, val),
+                    dev->iobase + PCI6208_AO_CONTROL(chan));
        }
-       devpriv->ao_readback[chan] = value;
+       devpriv->ao_readback[chan] = val;
 
        return insn->n;
 }
 
-static int pci6208_ao_rinsn(struct comedi_device *dev,
-                           struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+static int pci6208_ao_insn_read(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
        struct pci6208_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
 
        for (i = 0; i < insn->n; i++)
@@ -141,15 +151,8 @@ static int pci6208_do_insn_bits(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI6208_DIO);
-       }
 
        data[1] = s->state;
 
@@ -193,8 +196,8 @@ static int pci6208_auto_attach(struct comedi_device *dev,
        s->n_chan       = boardinfo->ao_chans;
        s->maxdata      = 0xffff;
        s->range_table  = &range_bipolar10;
-       s->insn_write   = pci6208_ao_winsn;
-       s->insn_read    = pci6208_ao_rinsn;
+       s->insn_write   = pci6208_ao_insn_write;
+       s->insn_read    = pci6208_ao_insn_read;
 
        s = &dev->subdevices[1];
        /* digital input subdevice */
@@ -221,10 +224,6 @@ static int pci6208_auto_attach(struct comedi_device *dev,
        val = inw(dev->iobase + PCI6208_DIO);
        val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT;
        s->state        = val;
-       s->io_bits      = 0x0f;
-
-       dev_info(dev->class_dev, "%s: %s, I/O base=0x%04lx\n",
-               dev->driver->driver_name, dev->board_name, dev->iobase);
 
        return 0;
 }
@@ -259,5 +258,5 @@ static struct pci_driver adl_pci6208_pci_driver = {
 module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for ADLink 6208 series cards");
 MODULE_LICENSE("GPL");
index 81b7203f824f15e7947b1f5783184171cdf10fc3..5617f5ca384a0bd8fd463c85dca28357bb025a2a 100644 (file)
@@ -112,21 +112,10 @@ static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev,
                                    unsigned int *data)
 {
        unsigned long reg = (unsigned long)s->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + reg);
-       }
 
-       /*
-        * NOTE: The output register is not readable.
-        * This returned state will not be correct until all the
-        * outputs have been updated.
-        */
        data[1] = s->state;
 
        return insn->n;
index 78cea193504f3e772413298b25dca9bacb45a39b..eab8da2c3d66910b23ef26cc5fceac488843a114 100644 (file)
@@ -86,8 +86,6 @@ TODO:
 #define PCI9111_AI_INSTANT_READ_UDELAY_US      2
 #define PCI9111_AI_INSTANT_READ_TIMEOUT                100
 
-#define PCI9111_8254_CLOCK_PERIOD_NS           500
-
 /*
  * IO address map and bit defines
  */
@@ -153,7 +151,7 @@ struct pci9111_private_data {
        unsigned int div1;
        unsigned int div2;
 
-       short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
+       unsigned short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
 };
 
 static void plx9050_interrupt_control(unsigned long io_base,
@@ -393,11 +391,10 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
-                                              &dev_private->div1,
-                                              &dev_private->div2,
-                                              &cmd->convert_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &dev_private->div1,
+                                         &dev_private->div2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        error++;
        }
@@ -570,7 +567,7 @@ static void pci9111_ai_munge(struct comedi_device *dev,
                             unsigned int num_bytes,
                             unsigned int start_chan_index)
 {
-       short *array = data;
+       unsigned short *array = data;
        unsigned int maxdata = s->maxdata;
        unsigned int invert = (maxdata + 1) >> 1;
        unsigned int shift = (maxdata == 0xffff) ? 0 : 4;
@@ -813,15 +810,8 @@ static int pci9111_do_insn_bits(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI9111_DIO_REG);
-       }
 
        data[1] = s->state;
 
index 22196ada0362200b12f83d89e9bed0dfa208e83d..986489641ed774a5c7d79380288339ea0be5dd33 100644 (file)
@@ -352,12 +352,11 @@ struct pci9118_private {
                                                 * on external start
                                                 */
        unsigned int ai_data_len;
-       short *ai_data;
-       short ao_data[2];                       /* data output buffer */
+       unsigned short ao_data[2];              /* data output buffer */
        unsigned int ai_scans;                  /* number of scans to do */
        char dma_doublebuf;                     /* we can use double buffering */
        unsigned int dma_actbuf;                /* which buffer is used now */
-       short *dmabuf_virt[2];                  /*
+       unsigned short *dmabuf_virt[2];         /*
                                                 * pointers to begin of
                                                 * DMA buffer
                                                 */
@@ -671,13 +670,12 @@ static int pci9118_insn_bits_di(struct comedi_device *dev,
 
 static int pci9118_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
-       }
+
        data[1] = s->state;
 
        return insn->n;
@@ -701,7 +699,7 @@ static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
 
 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
                                          struct comedi_subdevice *s,
-                                         short *dma_buffer,
+                                         unsigned short *dma_buffer,
                                          unsigned int num_samples)
 {
        struct pci9118_private *devpriv = dev->private;
@@ -725,7 +723,7 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev,
 
 static int move_block_from_dma(struct comedi_device *dev,
                                        struct comedi_subdevice *s,
-                                       short *dma_buffer,
+                                       unsigned short *dma_buffer,
                                        unsigned int num_samples)
 {
        struct pci9118_private *devpriv = dev->private;
@@ -793,7 +791,8 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
        case 4:
                if (*tim2 < this_board->ai_ns_min)
                        *tim2 = this_board->ai_ns_min;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         div1, div2,
                                          tim2, flags & TRIG_ROUND_NEAREST);
                break;
        case 2:
@@ -925,7 +924,7 @@ static void pci9118_ai_munge(struct comedi_device *dev,
 {
        struct pci9118_private *devpriv = dev->private;
        unsigned int i, num_samples = num_bytes / sizeof(short);
-       short *array = data;
+       unsigned short *array = data;
 
        for (i = 0; i < num_samples; i++) {
                if (devpriv->usedma)
@@ -945,7 +944,7 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
                                           unsigned short int_daq)
 {
        struct pci9118_private *devpriv = dev->private;
-       register short sampl;
+       unsigned short sampl;
 
        s->async->events = 0;
 
@@ -1278,9 +1277,9 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->scan_begin_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (cmd->scan_begin_arg < this_board->ai_ns_min)
                        cmd->scan_begin_arg = this_board->ai_ns_min;
                if (tmp != cmd->scan_begin_arg)
@@ -1289,9 +1288,9 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < this_board->ai_ns_min)
                        cmd->convert_arg = this_board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -1613,7 +1612,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_n_chan = cmd->chanlist_len;
        devpriv->ai_n_scanlen = cmd->scan_end_arg;
        devpriv->ai_chanlist = cmd->chanlist;
-       devpriv->ai_data = s->async->prealloc_buf;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
        devpriv->ai_timer1 = 0;
        devpriv->ai_timer2 = 0;
@@ -1987,8 +1985,8 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
                for (i = 0; i < 2; i++) {
                        for (pages = 4; pages >= 0; pages--) {
                                devpriv->dmabuf_virt[i] =
-                                   (short *)__get_free_pages(GFP_KERNEL,
-                                                             pages);
+                                   (unsigned short *)
+                                   __get_free_pages(GFP_KERNEL, pages);
                                if (devpriv->dmabuf_virt[i])
                                        break;
                        }
@@ -2075,7 +2073,6 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
        s->maxdata = 1;
        s->len_chanlist = 4;
        s->range_table = &range_digital;
-       s->io_bits = 0;         /* all bits input */
        s->insn_bits = pci9118_insn_bits_di;
 
        s = &dev->subdevices[3];
@@ -2085,11 +2082,10 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
        s->maxdata = 1;
        s->len_chanlist = 4;
        s->range_table = &range_digital;
-       s->io_bits = 0xf;       /* all bits output */
        s->insn_bits = pci9118_insn_bits_do;
 
        devpriv->valid = 1;
-       devpriv->i8254_osc_base = 250;  /* 250ns=4MHz */
+       devpriv->i8254_osc_base = I8254_OSC_BASE_4MHZ;
        devpriv->ai_maskharderr = 0x10a;
                                        /* default measure crash condition */
        if (hw_err_mask)                /* disable some requested */
index cdf5ba26c5904fdd93db071dc59c51addca83f7a..8150a67cd1fbf99927db2220dbb40bb0847c46b1 100644 (file)
@@ -119,7 +119,6 @@ struct adq12b_private {
        int differential;       /* option 3 of comedi_config */
        int last_channel;
        int last_range;
-       unsigned int digital_state;
 };
 
 /*
@@ -186,23 +185,25 @@ static int adq12b_di_insn_bits(struct comedi_device *dev,
 
 static int adq12b_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       struct adq12b_private *devpriv = dev->private;
-       int channel;
-
-       for (channel = 0; channel < 8; channel++)
-               if (((data[0] >> channel) & 0x01) != 0)
-                       outb((((data[1] >> channel) & 0x01) << 3) | channel,
-                            dev->iobase + ADQ12B_OUTBR);
-
-       /* store information to retrieve when asked for reading */
-       if (data[0]) {
-               devpriv->digital_state &= ~data[0];
-               devpriv->digital_state |= (data[0] & data[1]);
+       unsigned int mask;
+       unsigned int chan;
+       unsigned int val;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               for (chan = 0; chan < 8; chan++) {
+                       if ((mask >> chan) & 0x01) {
+                               val = (s->state >> chan) & 0x01;
+                               outb((val << 3) | chan,
+                                    dev->iobase + ADQ12B_OUTBR);
+                       }
+               }
        }
 
-       data[1] = devpriv->digital_state;
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -223,7 +224,6 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        devpriv->unipolar = it->options[1];
        devpriv->differential = it->options[2];
-       devpriv->digital_state = 0;
        /*
         * initialize channel and range to -1 so we make sure we
         * always write at least once to the CTREG in the instruction
index f84df46d326aeededa20d574bdcb8ae5b749a53f..c3fdcabe9aec6ac77626e0cecee123dc9d7c597e 100644 (file)
@@ -314,10 +314,9 @@ struct pci1710_private {
        unsigned int *ai_chanlist;      /*  actaul chanlist */
        unsigned int ai_flags;  /*  flaglist */
        unsigned int ai_data_len;       /*  len of data buffer */
-       short *ai_data;         /*  data buffer */
        unsigned int ai_timer1; /*  timers */
        unsigned int ai_timer2;
-       short ao_data[4];       /*  data output buffer */
+       unsigned short ao_data[4];      /*  data output buffer */
        unsigned int cnt0_write_wait;   /* after a write, wait for update of the
                                         * internal state */
 };
@@ -544,18 +543,14 @@ static int pci171x_insn_bits_di(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci171x_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI171x_DO);
-       }
+
        data[1] = s->state;
 
        return insn->n;
@@ -740,7 +735,7 @@ static void interrupt_pci1710_every_sample(void *d)
        int m;
 #ifdef PCI171x_PARANOIDCHECK
        const struct boardtype *this_board = comedi_board(dev);
-       short sampl;
+       unsigned short sampl;
 #endif
 
        m = inw(dev->iobase + PCI171x_STATUS);
@@ -821,7 +816,7 @@ static int move_block_from_fifo(struct comedi_device *dev,
        int i, j;
 #ifdef PCI171x_PARANOIDCHECK
        const struct boardtype *this_board = comedi_board(dev);
-       int sampl;
+       unsigned short sampl;
 #endif
 
        j = s->async->cur_chan;
@@ -1009,9 +1004,10 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
                } else {
                        devpriv->ai_et = 0;
                }
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &devpriv->ai_timer1,
-                                         devpriv->ai_flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &devpriv->ai_timer1,
+                                         devpriv->ai_flags);
                outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
                if (mode != 2) {
                        /*  start pacer */
@@ -1090,9 +1086,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < this_board->ai_ns_min)
                        cmd->convert_arg = this_board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -1125,7 +1121,6 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_chanlist = cmd->chanlist;
        devpriv->ai_flags = cmd->flags;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
-       devpriv->ai_data = s->async->prealloc_buf;
        devpriv->ai_timer1 = 0;
        devpriv->ai_timer2 = 0;
 
@@ -1288,7 +1283,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
                        s->do_cmdtest = pci171x_ai_cmdtest;
                        s->do_cmd = pci171x_ai_cmd;
                }
-               devpriv->i8254_osc_base = 100;  /*  100ns=10MHz */
+               devpriv->i8254_osc_base = I8254_OSC_BASE_10MHZ;
                subdev++;
        }
 
@@ -1320,7 +1315,6 @@ static int pci1710_auto_attach(struct comedi_device *dev,
                s->maxdata = 1;
                s->len_chanlist = this_board->n_dichan;
                s->range_table = &range_digital;
-               s->io_bits = 0; /* all bits input */
                s->insn_bits = pci171x_insn_bits_di;
                subdev++;
        }
@@ -1333,9 +1327,6 @@ static int pci1710_auto_attach(struct comedi_device *dev,
                s->maxdata = 1;
                s->len_chanlist = this_board->n_dochan;
                s->range_table = &range_digital;
-               /* all bits output */
-               s->io_bits = (1 << this_board->n_dochan) - 1;
-               s->state = 0;
                s->insn_bits = pci171x_insn_bits_do;
                subdev++;
        }
index b793d6987b843366654ac9935b0546ade9230f10..bd4f781b4b24a0ac66896c05f15b2c102f69f555 100644 (file)
@@ -105,7 +105,7 @@ TODO:
 
 struct pci1723_private {
        unsigned char da_range[8];      /* D/A output range for each channel */
-       short ao_data[8];       /* data output buffer */
+       unsigned short ao_data[8];      /* data output buffer */
 };
 
 /*
@@ -205,19 +205,16 @@ static int pci1723_dio_insn_config(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-  digital i/o bits read/write
-*/
 static int pci1723_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD);
-       }
+
        data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+
        return insn->n;
 }
 
index f091fa0d304df6d54da515db639804faeb125a43..6bac665261f847c750299a9979bb140d7c83784c 100644 (file)
@@ -448,45 +448,39 @@ static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        const struct diosubd_data *d = (const struct diosubd_data *)s->private;
        int i;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                for (i = 0; i < d->regs; i++)
                        outb((s->state >> (8 * i)) & 0xff,
                             dev->iobase + d->addr + i);
        }
+
        data[1] = s->state;
 
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        const struct diosubd_data *d = (const struct diosubd_data *)s->private;
        int i;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                for (i = 0; i < d->regs; i++)
                        outw((s->state >> (16 * i)) & 0xffff,
                             dev->iobase + d->addr + 2 * i);
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -641,12 +635,10 @@ static int pci1760_insn_bits_di(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci1760_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
        int ret;
        unsigned char omb[4] = {
@@ -657,14 +649,13 @@ static int pci1760_insn_bits_do(struct comedi_device *dev,
        };
        unsigned char imb[4];
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                omb[0] = s->state;
                ret = pci1760_mbxrequest(dev, omb, imb);
                if (!ret)
                        return ret;
        }
+
        data[1] = s->state;
 
        return insn->n;
index afe87cc897612c0508f0924088b65452533ad052..22b3dda135ff23a9b7ff351bba8c578227e90353 100644 (file)
@@ -45,9 +45,7 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
                                           struct comedi_insn *insn,
                                           unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_update_state(s, data)) {
                outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
                outb((s->state >> 8) & 0xff,
                     dev->iobase + AIO_IIRO_16_RELAY_8_15);
index c1f723e8614613826d9753e07ec6af5044f925a7..2e4bf284d52c08e5edc7fbd6221563b01cd92e70 100644 (file)
@@ -941,31 +941,34 @@ static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
        dio200_write8(dev, subpriv->ofs + 3, config);
 }
 
-/*
- * Handle 'insn_bits' for an '8255' DIO subdevice.
- */
 static int dio200_subdev_8255_bits(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
 {
        struct dio200_subdev_8255 *subpriv = s->private;
+       unsigned int mask;
+       unsigned int val;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-               if (data[0] & 0xff)
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0xff)
                        dio200_write8(dev, subpriv->ofs, s->state & 0xff);
-               if (data[0] & 0xff00)
+               if (mask & 0xff00)
                        dio200_write8(dev, subpriv->ofs + 1,
                                      (s->state >> 8) & 0xff);
-               if (data[0] & 0xff0000)
+               if (mask & 0xff0000)
                        dio200_write8(dev, subpriv->ofs + 2,
                                      (s->state >> 16) & 0xff);
        }
-       data[1] = dio200_read8(dev, subpriv->ofs);
-       data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
-       data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
-       return 2;
+
+       val = dio200_read8(dev, subpriv->ofs);
+       val |= dio200_read8(dev, subpriv->ofs + 1) << 8;
+       val |= dio200_read8(dev, subpriv->ofs + 2) << 16;
+
+       data[1] = val;
+
+       return insn->n;
 }
 
 /*
@@ -1022,8 +1025,6 @@ static int dio200_subdev_8255_init(struct comedi_device *dev,
        s->maxdata = 1;
        s->insn_bits = dio200_subdev_8255_bits;
        s->insn_config = dio200_subdev_8255_config;
-       s->state = 0;
-       s->io_bits = 0;
        dio200_subdev_8255_set_dir(dev, s);
        return 0;
 }
index e7108045f5535969a695622697060a46c47a7e8b..5b4b5ab34e2e930869b854f0f7b4b2056b2dc526 100644 (file)
@@ -57,17 +57,16 @@ static const struct pc263_board pc263_boards[] = {
 
 static int pc263_do_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outb(s->state & 0xFF, dev->iobase);
-               outb(s->state >> 8, dev->iobase + 1);
+       if (comedi_dio_update_state(s, data)) {
+               outb(s->state & 0xff, dev->iobase);
+               outb((s->state >> 8) & 0xff, dev->iobase + 1);
        }
+
+       data[1] = s->state;
+
        return insn->n;
 }
 
index 179de53a86f009cc69df7bb9be00067ac735e7d0..810e397d8fd7009a25f93c49cc0a076283af7fa7 100644 (file)
@@ -215,12 +215,6 @@ Caveats:
 #define CLK_EXT                7       /* external clock */
 /* Macro to construct clock input configuration register value. */
 #define CLK_CONFIG(chan, src)  ((((chan) & 3) << 3) | ((src) & 7))
-/* Timebases in ns. */
-#define TIMEBASE_10MHZ         100
-#define TIMEBASE_1MHZ          1000
-#define TIMEBASE_100KHZ                10000
-#define TIMEBASE_10KHZ         100000
-#define TIMEBASE_1KHZ          1000000
 
 /*
  * Counter/timer gate input configuration sources.
@@ -379,7 +373,7 @@ struct pci224_private {
        unsigned long state;
        spinlock_t ao_spinlock;
        unsigned int *ao_readback;
-       short *ao_scan_vals;
+       unsigned short *ao_scan_vals;
        unsigned char *ao_scan_order;
        int intr_cpuid;
        short intr_running;
@@ -843,26 +837,26 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                switch (round_mode) {
                case TRIG_ROUND_NEAREST:
                default:
-                       round = TIMEBASE_10MHZ / 2;
+                       round = I8254_OSC_BASE_10MHZ / 2;
                        break;
                case TRIG_ROUND_DOWN:
                        round = 0;
                        break;
                case TRIG_ROUND_UP:
-                       round = TIMEBASE_10MHZ - 1;
+                       round = I8254_OSC_BASE_10MHZ - 1;
                        break;
                }
                /* Be careful to avoid overflow! */
-               div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
-               div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
-                   TIMEBASE_10MHZ;
+               div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
+               div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
+                       I8254_OSC_BASE_10MHZ;
                if (div2 <= 0x10000) {
                        /* A single timer will suffice. */
                        if (div2 < 2)
                                div2 = 2;
-                       cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
+                       cmd->scan_begin_arg = div2 * I8254_OSC_BASE_10MHZ;
                        if (cmd->scan_begin_arg < div2 ||
-                           cmd->scan_begin_arg < TIMEBASE_10MHZ) {
+                           cmd->scan_begin_arg < I8254_OSC_BASE_10MHZ) {
                                /* Overflow! */
                                cmd->scan_begin_arg = MAX_SCAN_PERIOD;
                        }
@@ -870,7 +864,8 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                        /* Use two timers. */
                        div1 = devpriv->cached_div1;
                        div2 = devpriv->cached_div2;
-                       pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+                       pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                                  &div1, &div2,
                                                   &cmd->scan_begin_arg,
                                                   round_mode);
                        devpriv->cached_div1 = div1;
@@ -1002,19 +997,19 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                switch (round_mode) {
                case TRIG_ROUND_NEAREST:
                default:
-                       round = TIMEBASE_10MHZ / 2;
+                       round = I8254_OSC_BASE_10MHZ / 2;
                        break;
                case TRIG_ROUND_DOWN:
                        round = 0;
                        break;
                case TRIG_ROUND_UP:
-                       round = TIMEBASE_10MHZ - 1;
+                       round = I8254_OSC_BASE_10MHZ - 1;
                        break;
                }
                /* Be careful to avoid overflow! */
-               div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
-               div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
-                   TIMEBASE_10MHZ;
+               div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
+               div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
+                       I8254_OSC_BASE_10MHZ;
                if (div2 <= 0x10000) {
                        /* A single timer will suffice. */
                        if (div2 < 2)
@@ -1025,7 +1020,8 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                        /* Use two timers. */
                        div1 = devpriv->cached_div1;
                        div2 = devpriv->cached_div2;
-                       pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+                       pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                                  &div1, &div2,
                                                   &ns, round_mode);
                }
 
@@ -1116,7 +1112,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
        const struct pci224_board *thisboard = comedi_board(dev);
        struct pci224_private *devpriv = dev->private;
        struct comedi_async *async = s->async;
-       short *array = data;
+       unsigned short *array = data;
        unsigned int length = num_bytes / sizeof(*array);
        unsigned int offset;
        unsigned int shift;
index 43059c25d5ea1ac8f89d1b0dbe30d35126a7dc36..a97bbd6ca3db5a5a3b6945c5157c25082ac62165 100644 (file)
@@ -573,14 +573,14 @@ static const struct comedi_lrange pci230_ao_range = { 2, {
 /* PCI230 daccon bipolar flag for each analogue output range. */
 static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
 
-static short pci230_ai_read(struct comedi_device *dev)
+static unsigned short pci230_ai_read(struct comedi_device *dev)
 {
        const struct pci230_board *thisboard = comedi_board(dev);
        struct pci230_private *devpriv = dev->private;
-       short data;
+       unsigned short data;
 
        /* Read sample. */
-       data = (short)inw(dev->iobase + PCI230_ADCDATA);
+       data = inw(dev->iobase + PCI230_ADCDATA);
        /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
         * four bits reserved for expansion). */
        /* PCI230+ is 16 bit AI. */
@@ -595,7 +595,7 @@ static short pci230_ai_read(struct comedi_device *dev)
 }
 
 static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
-                                                   short datum)
+                                                   unsigned short datum)
 {
        const struct pci230_board *thisboard = comedi_board(dev);
        struct pci230_private *devpriv = dev->private;
@@ -609,11 +609,12 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
         * four bits reserved for expansion). */
        /* PCI230+ is also 12 bit AO. */
        datum <<= (16 - thisboard->ao_bits);
-       return (unsigned short)datum;
+       return datum;
 }
 
 static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
-                                         short datum, unsigned int chan)
+                                         unsigned short datum,
+                                         unsigned int chan)
 {
        struct pci230_private *devpriv = dev->private;
 
@@ -627,8 +628,8 @@ static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
                                                                PCI230_DACOUT2));
 }
 
-static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum,
-                                       unsigned int chan)
+static inline void pci230_ao_write_fifo(struct comedi_device *dev,
+                                       unsigned short datum, unsigned int chan)
 {
        struct pci230_private *devpriv = dev->private;
 
@@ -1165,7 +1166,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev,
                                    struct comedi_subdevice *s)
 {
        struct pci230_private *devpriv = dev->private;
-       short data;
+       unsigned short data;
        int i, ret;
        struct comedi_async *async = s->async;
        struct comedi_cmd *cmd = &async->cmd;
@@ -1258,7 +1259,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
                /* Process scans. */
                for (n = 0; n < num_scans; n++) {
                        for (i = 0; i < cmd->chanlist_len; i++) {
-                               short datum;
+                               unsigned short datum;
 
                                comedi_buf_get(async, &datum);
                                pci230_ao_write_fifo(dev, datum,
index 145bb48f618e9ab1516a8881f2c0f13c4bb795c2..4bd4ef8e88cd05dbf6453fb88f988196c5eb5174 100644 (file)
@@ -44,17 +44,16 @@ The state of the outputs can be read.
 
 static int pci263_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outb(s->state & 0xFF, dev->iobase);
-               outb(s->state >> 8, dev->iobase + 1);
+       if (comedi_dio_update_state(s, data)) {
+               outb(s->state & 0xff, dev->iobase);
+               outb((s->state >> 8) & 0xff, dev->iobase + 1);
        }
+
+       data[1] = s->state;
+
        return insn->n;
 }
 
index 0ce93da70847c566fd328ae21ae80f258fade0f1..64d5f291553fb46a04f94154a6c20973c8af812f 100644 (file)
@@ -234,9 +234,9 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev,
                unsigned int div1 = 0, div2 = 0;
 
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer(100, &div1, &div2,
-                                         &cmd->scan_begin_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &div1, &div2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
@@ -244,9 +244,9 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev,
                unsigned int div1 = 0, div2 = 0;
 
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(100, &div1, &div2,
-                                         &cmd->scan_begin_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &div1, &div2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
                if (cmd->scan_begin_src == TRIG_TIMER &&
@@ -325,14 +325,11 @@ static int das16cs_ao_rinsn(struct comedi_device *dev,
 
 static int das16cs_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + DAS16CS_DIO);
-       }
 
        data[1] = inw(dev->iobase + DAS16CS_DIO);
 
index 41d89ee7fa33078e53203ea52739211c89646e6d..e72a403db17ca8e0f0d7715791ef1ff8d27223b0 100644 (file)
@@ -73,7 +73,6 @@ analog triggering on 1602 series
 #include "amcc_s5933.h"
 #include "comedi_fc.h"
 
-#define TIMER_BASE             100     /* 10MHz master clock */
 #define AI_BUFFER_SIZE         1024    /* max ai fifo size */
 #define AO_BUFFER_SIZE         1024    /* max ao fifo size */
 #define NUM_CHANNELS_8800      8
@@ -358,15 +357,15 @@ struct cb_pcidas_private {
        unsigned int s5933_intcsr_bits;
        unsigned int ao_control_bits;
        /* fifo buffers */
-       short ai_buffer[AI_BUFFER_SIZE];
-       short ao_buffer[AO_BUFFER_SIZE];
+       unsigned short ai_buffer[AI_BUFFER_SIZE];
+       unsigned short ao_buffer[AO_BUFFER_SIZE];
        /* divisors of master clock for analog output pacing */
        unsigned int ao_divisor1;
        unsigned int ao_divisor2;
        /* number of analog output samples remaining */
        unsigned int ao_count;
        /* cached values for readback */
-       int ao_value[2];
+       unsigned short ao_value[2];
        unsigned int caldac_value[NUM_CHANNELS_8800];
        unsigned int trimpot_value[NUM_CHANNELS_8402];
        unsigned int dac08_value;
@@ -880,21 +879,19 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd->scan_begin_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd->convert_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
        }
@@ -932,9 +929,9 @@ static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
 {
        struct cb_pcidas_private *devpriv = dev->private;
 
-       i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
-                                      &(devpriv->divisor2), ns,
-                                      rounding_flags & TRIG_ROUND_MASK);
+       i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                 &devpriv->divisor1, &devpriv->divisor2,
+                                 ns, rounding_flags);
 
        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
        i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
@@ -1084,11 +1081,10 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->ao_divisor1),
-                                              &(devpriv->ao_divisor2),
-                                              &(cmd->scan_begin_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->ao_divisor1,
+                                         &devpriv->ao_divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
@@ -1209,11 +1205,10 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
 
        /*  load counters */
        if (cmd->scan_begin_src == TRIG_TIMER) {
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->ao_divisor1),
-                                              &(devpriv->ao_divisor2),
-                                              &(cmd->scan_begin_arg),
-                                              cmd->flags);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->ao_divisor1,
+                                         &devpriv->ao_divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
 
                /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
                i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
index 388dbd7a5d27f2fa1c93b24f4f2342558f4b0b8c..ff5206536be36c3c4013efce6ca5fd9081f32ae0 100644 (file)
@@ -1137,7 +1137,7 @@ struct pcidas64_private {
        volatile short ai_cmd_running;
        unsigned int ai_fifo_segment_length;
        struct ext_clock_info ext_clock;
-       short ao_bounce_buffer[DAC_FIFO_SIZE];
+       unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
 };
 
 static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
@@ -3490,18 +3490,15 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
        return insn->n;
 }
 
-static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-                   struct comedi_insn *insn, unsigned int *data)
+static int do_wbits(struct comedi_device *dev,
+                   struct comedi_subdevice *s,
+                   struct comedi_insn *insn,
+                   unsigned int *data)
 {
        struct pcidas64_private *devpriv = dev->private;
 
-       data[0] &= 0xf;
-       /*  zero bits we are going to change */
-       s->state &= ~data[0];
-       /*  set new bits */
-       s->state |= data[0] & data[1];
-
-       writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
+       if (comedi_dio_update_state(s, data))
+               writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
 
        data[1] = s->state;
 
@@ -3526,14 +3523,14 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
        return insn->n;
 }
 
-static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int dio_60xx_wbits(struct comedi_device *dev,
+                         struct comedi_subdevice *s,
+                         struct comedi_insn *insn,
+                         unsigned int *data)
 {
        struct pcidas64_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                writeb(s->state,
                       devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
        }
index a4dea7cb86bef30294574aa42299793b70eb0308..8558b07f8df3a0bd07267fcfdc7eb0e8d40e4fb2 100644 (file)
@@ -30,7 +30,7 @@ extern unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
                                              unsigned int num_bytes);
 
 static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
-                                              short data)
+                                              unsigned short data)
 {
        return cfc_write_array_to_buffer(subd, &data, sizeof(data));
 };
index f28a15f0274e44819040d7322d046f43aab03c05..9de81c7712fb9103ae9054f54b37abf4dfa2c0b8 100644 (file)
 /*
-    comedi/drivers/comedi_parport.c
-    hardware driver for standard parallel port
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1998,2001 David A. Schleef <ds@schleef.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.
-
-    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.
-*/
-/*
-Driver: comedi_parport
-Description: Standard PC parallel port
-Author: ds
-Status: works in immediate mode
-Devices: [standard] parallel port (comedi_parport)
-Updated: Tue, 30 Apr 2002 21:11:45 -0700
-
-A cheap and easy way to get a few more digital I/O lines.  Steal
-additional parallel ports from old computers or your neighbors'
-computers.
-
-Option list:
- 0: I/O port base for the parallel port.
- 1: IRQ
-
-Parallel Port Lines:
-
-pin     subdev  chan    aka
----     ------  ----    ---
-1       2       0       strobe
-2       0       0       data 0
-3       0       1       data 1
-4       0       2       data 2
-5       0       3       data 3
-6       0       4       data 4
-7       0       5       data 5
-8       0       6       data 6
-9       0       7       data 7
-10      1       3       acknowledge
-11      1       4       busy
-12      1       2       output
-13      1       1       printer selected
-14      2       1       auto LF
-15      1       0       error
-16      2       2       init
-17      2       3       select printer
-18-25   ground
-
-Notes:
-
-Subdevices 0 is digital I/O, subdevice 1 is digital input, and
-subdevice 2 is digital output.  Unlike other Comedi devices,
-subdevice 0 defaults to output.
-
-Pins 13 and 14 are inverted once by Comedi and once by the
-hardware, thus cancelling the effect.
-
-Pin 1 is a strobe, thus acts like one.  There's no way in software
-to change this, at least on a standard parallel port.
-
-Subdevice 3 pretends to be a digital input subdevice, but it always
-returns 0 when read.  However, if you run a command with
-scan_begin_src=TRIG_EXT, it uses pin 10 as a external triggering
-pin, which can be used to wake up tasks.
-*/
+ * comedi_parport.c
+ * Comedi driver for standard parallel port
+ *
+ * For more information see:
+ *     http://retired.beyondlogic.org/spp/parallel.htm
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998,2001 David A. Schleef <ds@schleef.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.
+ *
+ * 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.
+ */
+
 /*
-   see http://www.beyondlogic.org/ for information.
-   or http://www.linux-magazin.de/ausgabe/1999/10/IO/io.html
+ * Driver: comedi_parport
+ * Description: Standard PC parallel port
+ * Author: ds
+ * Status: works in immediate mode
+ * Devices: (standard) parallel port [comedi_parport]
+ * Updated: Tue, 30 Apr 2002 21:11:45 -0700
+ *
+ * A cheap and easy way to get a few more digital I/O lines. Steal
+ * additional parallel ports from old computers or your neighbors'
+ * computers.
+ *
+ * Option list:
+ *   0: I/O port base for the parallel port.
+ *   1: IRQ (optional)
+ *
+ * Parallel Port Lines:
+ *
+ *      pin   subdev  chan  type  name
+ *     -----  ------  ----  ----  --------------
+ *       1      2       0    DO   strobe
+ *       2      0       0    DIO  data 0
+ *       3      0       1    DIO  data 1
+ *       4      0       2    DIO  data 2
+ *       5      0       3    DIO  data 3
+ *       6      0       4    DIO  data 4
+ *       7      0       5    DIO  data 5
+ *       8      0       6    DIO  data 6
+ *       9      0       7    DIO  data 7
+ *      10      1       3    DI   ack
+ *      11      1       4    DI   busy
+ *      12      1       2    DI   paper out
+ *      13      1       1    DI   select in
+ *      14      2       1    DO   auto LF
+ *      15      1       0    DI   error
+ *      16      2       2    DO   init
+ *      17      2       3    DO   select printer
+ *     18-25                      ground
+ *
+ * When an IRQ is configured subdevice 3 pretends to be a digital
+ * input subdevice, but it always returns 0 when read. However, if
+ * you run a command with scan_begin_src=TRIG_EXT, it uses pin 10
+ * as a external trigger, which can be used to wake up tasks.
  */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 #include <linux/interrupt.h>
 
-#include "comedi_fc.h"
-
-#define PARPORT_SIZE 3
-
-#define PARPORT_A 0
-#define PARPORT_B 1
-#define PARPORT_C 2
+#include "../comedidev.h"
 
-struct parport_private {
-       unsigned int a_data;
-       unsigned int c_data;
-       int enable_irq;
-};
+#include "comedi_fc.h"
 
-static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+/*
+ * Register map
+ */
+#define PARPORT_DATA_REG       0x00
+#define PARPORT_STATUS_REG     0x01
+#define PARPORT_CTRL_REG       0x02
+#define PARPORT_CTRL_IRQ_ENA   (1 << 4)
+#define PARPORT_CTRL_BIDIR_ENA (1 << 5)
+
+static int parport_data_reg_insn_bits(struct comedi_device *dev,
+                                     struct comedi_subdevice *s,
+                                     struct comedi_insn *insn,
+                                     unsigned int *data)
 {
-       struct parport_private *devpriv = dev->private;
-
-       if (data[0]) {
-               devpriv->a_data &= ~data[0];
-               devpriv->a_data |= (data[0] & data[1]);
-
-               outb(devpriv->a_data, dev->iobase + PARPORT_A);
-       }
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + PARPORT_DATA_REG);
 
-       data[1] = inb(dev->iobase + PARPORT_A);
+       data[1] = inb(dev->iobase + PARPORT_DATA_REG);
 
        return insn->n;
 }
 
-static int parport_insn_config_a(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+static int parport_data_reg_insn_config(struct comedi_device *dev,
+                                       struct comedi_subdevice *s,
+                                       struct comedi_insn *insn,
+                                       unsigned int *data)
 {
-       struct parport_private *devpriv = dev->private;
-
-       if (data[0]) {
-               s->io_bits = 0xff;
-               devpriv->c_data &= ~(1 << 5);
-       } else {
-               s->io_bits = 0;
-               devpriv->c_data |= (1 << 5);
-       }
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       unsigned int ctrl;
+       int ret;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
+       if (ret)
+               return ret;
+
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       if (s->io_bits)
+               ctrl &= ~PARPORT_CTRL_BIDIR_ENA;
+       else
+               ctrl |= PARPORT_CTRL_BIDIR_ENA;
+       outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
 
-       return 1;
+       return insn->n;
 }
 
-static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int parport_status_reg_insn_bits(struct comedi_device *dev,
+                                       struct comedi_subdevice *s,
+                                       struct comedi_insn *insn,
+                                       unsigned int *data)
 {
-       if (data[0]) {
-               /* should writes be ignored? */
-               /* anyone??? */
-       }
-
-       data[1] = (inb(dev->iobase + PARPORT_B) >> 3);
+       data[1] = inb(dev->iobase + PARPORT_STATUS_REG) >> 3;
 
        return insn->n;
 }
 
-static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int parport_ctrl_reg_insn_bits(struct comedi_device *dev,
+                                     struct comedi_subdevice *s,
+                                     struct comedi_insn *insn,
+                                     unsigned int *data)
 {
-       struct parport_private *devpriv = dev->private;
-
-       data[0] &= 0x0f;
-       if (data[0]) {
-               devpriv->c_data &= ~data[0];
-               devpriv->c_data |= (data[0] & data[1]);
+       unsigned int ctrl;
 
-               outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       if (comedi_dio_update_state(s, data)) {
+               ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+               ctrl &= (PARPORT_CTRL_IRQ_ENA | PARPORT_CTRL_BIDIR_ENA);
+               ctrl |= s->state;
+               outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
        }
 
-       data[1] = devpriv->c_data & 0xf;
+       data[1] = s->state;
 
        return insn->n;
 }
 
-static int parport_intr_insn(struct comedi_device *dev,
-                            struct comedi_subdevice *s,
-                            struct comedi_insn *insn, unsigned int *data)
+static int parport_intr_insn_bits(struct comedi_device *dev,
+                                 struct comedi_subdevice *s,
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        data[1] = 0;
        return insn->n;
@@ -213,12 +198,11 @@ static int parport_intr_cmdtest(struct comedi_device *dev,
 static int parport_intr_cmd(struct comedi_device *dev,
                            struct comedi_subdevice *s)
 {
-       struct parport_private *devpriv = dev->private;
+       unsigned int ctrl;
 
-       devpriv->c_data |= 0x10;
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
-
-       devpriv->enable_irq = 1;
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       ctrl |= PARPORT_CTRL_IRQ_ENA;
+       outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
 
        return 0;
 }
@@ -226,12 +210,11 @@ static int parport_intr_cmd(struct comedi_device *dev,
 static int parport_intr_cancel(struct comedi_device *dev,
                               struct comedi_subdevice *s)
 {
-       struct parport_private *devpriv = dev->private;
-
-       devpriv->c_data &= ~0x10;
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       unsigned int ctrl;
 
-       devpriv->enable_irq = 0;
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       ctrl &= ~PARPORT_CTRL_IRQ_ENA;
+       outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
 
        return 0;
 }
@@ -239,10 +222,11 @@ static int parport_intr_cancel(struct comedi_device *dev,
 static irqreturn_t parport_interrupt(int irq, void *d)
 {
        struct comedi_device *dev = d;
-       struct parport_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[3];
+       struct comedi_subdevice *s = dev->read_subdev;
+       unsigned int ctrl;
 
-       if (!devpriv->enable_irq)
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       if (!(ctrl & PARPORT_CTRL_IRQ_ENA))
                return IRQ_NONE;
 
        comedi_buf_put(s->async, 0);
@@ -255,79 +239,69 @@ static irqreturn_t parport_interrupt(int irq, void *d)
 static int parport_attach(struct comedi_device *dev,
                          struct comedi_devconfig *it)
 {
-       struct parport_private *devpriv;
        struct comedi_subdevice *s;
-       unsigned int irq;
        int ret;
 
-       ret = comedi_request_region(dev, it->options[0], PARPORT_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x03);
        if (ret)
                return ret;
 
-       irq = it->options[1];
-       if (irq) {
-               ret = request_irq(irq, parport_interrupt, 0, dev->board_name,
-                                 dev);
-               if (ret < 0) {
-                       dev_err(dev->class_dev, "irq not available\n");
-                       return -EINVAL;
-               }
-               dev->irq = irq;
+       if (it->options[1]) {
+               ret = request_irq(it->options[1], parport_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0)
+                       dev->irq = it->options[1];
        }
 
-       ret = comedi_alloc_subdevices(dev, 4);
+       ret = comedi_alloc_subdevices(dev, dev->irq ? 4 : 3);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
-               return -ENOMEM;
-
+       /* Digial I/O subdevice - Parallel port DATA register */
        s = &dev->subdevices[0];
-       s->type = COMEDI_SUBD_DIO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 8;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = parport_insn_a;
-       s->insn_config = parport_insn_config_a;
-
+       s->type         = COMEDI_SUBD_DIO;
+       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+       s->n_chan       = 8;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = parport_data_reg_insn_bits;
+       s->insn_config  = parport_data_reg_insn_config;
+
+       /* Digial Input subdevice - Parallel port STATUS register */
        s = &dev->subdevices[1];
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 5;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = parport_insn_b;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 5;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = parport_status_reg_insn_bits;
+
+       /* Digial Output subdevice - Parallel port CONTROL register */
        s = &dev->subdevices[2];
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = 4;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = parport_insn_c;
-
-       s = &dev->subdevices[3];
-       if (irq) {
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 4;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = parport_ctrl_reg_insn_bits;
+
+       if (dev->irq) {
+               /* Digial Input subdevice - Interrupt support */
+               s = &dev->subdevices[3];
                dev->read_subdev = s;
-               s->type = COMEDI_SUBD_DI;
-               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
-               s->n_chan = 1;
-               s->maxdata = 1;
-               s->range_table = &range_digital;
-               s->insn_bits = parport_intr_insn;
-               s->do_cmdtest = parport_intr_cmdtest;
-               s->do_cmd = parport_intr_cmd;
-               s->cancel = parport_intr_cancel;
-       } else {
-               s->type = COMEDI_SUBD_UNUSED;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_bits    = parport_intr_insn_bits;
+               s->do_cmdtest   = parport_intr_cmdtest;
+               s->do_cmd       = parport_intr_cmd;
+               s->cancel       = parport_intr_cancel;
        }
 
-       devpriv->a_data = 0;
-       outb(devpriv->a_data, dev->iobase + PARPORT_A);
-       devpriv->c_data = 0;
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       outb(0, dev->iobase + PARPORT_DATA_REG);
+       outb(0, dev->iobase + PARPORT_CTRL_REG);
 
        return 0;
 }
@@ -341,5 +315,5 @@ static struct comedi_driver parport_driver = {
 module_comedi_driver(parport_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi: Standard parallel port driver");
 MODULE_LICENSE("GPL");
index e781716bf3555e9a93b3af8e7bb5a11ac12c35da..89836c0828d9cb08a8626cecbe9fd266bf38f9d2 100644 (file)
@@ -40,17 +40,11 @@ Configuration Options: not applicable, uses comedi PCI auto config
 
 static int contec_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PIO1616L_DO_REG);
-       }
 
        data[1] = s->state;
 
index 5f669709501f90376afe046e84bda819f1544f2d..15dd33e3e1c796c12f2f409a77da22395c4c6c48 100644 (file)
@@ -279,27 +279,23 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
        return insn->n;
 }
 
-static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int das08_do_wbits(struct comedi_device *dev,
+                         struct comedi_subdevice *s,
+                         struct comedi_insn *insn,
+                         unsigned int *data)
 {
        struct das08_private_struct *devpriv = dev->private;
-       int wbits;
-
-       /*  get current settings of digital output lines */
-       wbits = (devpriv->do_mux_bits >> 4) & 0xf;
-       /*  null bits we are going to set */
-       wbits &= ~data[0];
-       /*  set new bit values */
-       wbits |= data[0] & data[1];
-       /*  remember digital output bits */
-       /*  prevent race with setting of analog input mux */
-       spin_lock(&dev->spinlock);
-       devpriv->do_mux_bits &= ~DAS08_DO_MASK;
-       devpriv->do_mux_bits |= DAS08_OP(wbits);
-       outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
-       spin_unlock(&dev->spinlock);
 
-       data[1] = wbits;
+       if (comedi_dio_update_state(s, data)) {
+               /* prevent race with setting of analog input mux */
+               spin_lock(&dev->spinlock);
+               devpriv->do_mux_bits &= ~DAS08_DO_MASK;
+               devpriv->do_mux_bits |= DAS08_OP(s->state);
+               outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+               spin_unlock(&dev->spinlock);
+       }
+
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -316,17 +312,13 @@ static int das08jr_di_rbits(struct comedi_device *dev,
 
 static int das08jr_do_wbits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
-       struct das08_private_struct *devpriv = dev->private;
-
-       /*  null bits we are going to set */
-       devpriv->do_bits &= ~data[0];
-       /*  set new bit values */
-       devpriv->do_bits |= data[0] & data[1];
-       outb(devpriv->do_bits, dev->iobase + DAS08JR_DIO);
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DAS08JR_DIO);
 
-       data[1] = devpriv->do_bits;
+       data[1] = s->state;
 
        return insn->n;
 }
index cce1b584200a82acbf1036af85fa91c103b2d3e8..46a314c5113e56c5699ae242b66db2e4b19c79a0 100644 (file)
@@ -41,7 +41,6 @@ struct das08_board_struct {
 
 struct das08_private_struct {
        unsigned int do_mux_bits;       /*  bits for do/mux register on boards without separate do register */
-       unsigned int do_bits;   /*  bits for do register on boards with register dedicated to digital out only */
        const unsigned int *pg_gainlist;
        unsigned int ao_readback[2];    /* assume 2 AO channels */
 };
index 1b0793f33b9f12742453d18ca5801601f87413b4..a8446ca041106b8987ea16daa9b39e09d8ed590b 100644 (file)
@@ -675,21 +675,19 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
        if (cmd->scan_begin_src == TRIG_TIMER) {
                unsigned int tmp = cmd->scan_begin_arg;
                /*  set divisors, correct timing arguments */
-               i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->scan_begin_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->clockbase,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                err += (tmp != cmd->scan_begin_arg);
        }
        if (cmd->convert_src == TRIG_TIMER) {
                unsigned int tmp = cmd->convert_arg;
                /*  set divisors, correct timing arguments */
-               i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->convert_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->clockbase,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                err += (tmp != cmd->convert_arg);
        }
        if (err)
@@ -725,11 +723,9 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
        struct das16_private_struct *devpriv = dev->private;
        unsigned long timer_base = dev->iobase + DAS16_TIMER_BASE_REG;
 
-       i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
-                                      &devpriv->divisor1,
-                                      &devpriv->divisor2,
-                                      &ns,
-                                      rounding_flags & TRIG_ROUND_MASK);
+       i8253_cascade_ns_to_timer(devpriv->clockbase,
+                                 &devpriv->divisor1, &devpriv->divisor2,
+                                 &ns, rounding_flags);
 
        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
        i8254_load(timer_base, 0, 1, devpriv->divisor1, 2);
@@ -850,7 +846,7 @@ static void das16_ai_munge(struct comedi_device *dev,
                           unsigned int start_chan_index)
 {
        unsigned int i, num_samples = num_bytes / sizeof(short);
-       short *data = array;
+       unsigned short *data = array;
 
        for (i = 0; i < num_samples; i++) {
                data[i] = le16_to_cpu(data[i]);
@@ -952,15 +948,8 @@ static int das16_do_insn_bits(struct comedi_device *dev,
                              struct comedi_insn *insn,
                              unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outb(s->state, dev->iobase + DAS16_DIO_REG);
-       }
 
        data[1] = s->state;
 
@@ -1043,14 +1032,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                status = inb(dev->iobase + DAS1600_STATUS_REG);
 
                if (status & DAS1600_STATUS_CLK_10MHZ)
-                       devpriv->clockbase = 100;
+                       devpriv->clockbase = I8254_OSC_BASE_10MHZ;
                else
-                       devpriv->clockbase = 1000;
+                       devpriv->clockbase = I8254_OSC_BASE_1MHZ;
        } else {
                if (it->options[3])
-                       devpriv->clockbase = 1000 / it->options[3];
+                       devpriv->clockbase = I8254_OSC_BASE_1MHZ /
+                                            it->options[3];
                else
-                       devpriv->clockbase = 1000;      /*  1 MHz default */
+                       devpriv->clockbase = I8254_OSC_BASE_1MHZ;
        }
 
        /* initialize dma */
index b943c449b69198ef9782137d65c5c0a0cd5524a1..fce9acfe8084596d8c6f9b5c522c276a9ac0dd24 100644 (file)
@@ -63,8 +63,6 @@ irq can be omitted, although the cmd interface will not work without it.
 #define DAS16M1_SIZE 16
 #define DAS16M1_SIZE2 8
 
-#define DAS16M1_XTAL 100       /* 10 MHz master clock */
-
 #define FIFO_SIZE 1024         /*  1024 sample fifo */
 
 /*
@@ -133,19 +131,18 @@ struct das16m1_private_struct {
         * needed to keep track of whether new count has been loaded into
         * counter yet (loaded by first sample conversion) */
        u16 initial_hw_count;
-       short ai_buffer[FIFO_SIZE];
-       unsigned int do_bits;   /*  saves status of digital output bits */
+       unsigned short ai_buffer[FIFO_SIZE];
        unsigned int divisor1;  /*  divides master clock to obtain conversion speed */
        unsigned int divisor2;  /*  divides master clock to obtain conversion speed */
        unsigned long extra_iobase;
 };
 
-static inline short munge_sample(short data)
+static inline unsigned short munge_sample(unsigned short data)
 {
        return (data >> 4) & 0xfff;
 }
 
-static void munge_sample_array(short *array, unsigned int num_elements)
+static void munge_sample_array(unsigned short *array, unsigned int num_elements)
 {
        unsigned int i;
 
@@ -208,11 +205,10 @@ static int das16m1_cmd_test(struct comedi_device *dev,
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
                /* calculate counter values that give desired timing */
-               i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL,
-                                              &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd->convert_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
        }
@@ -251,9 +247,10 @@ static unsigned int das16m1_set_pacer(struct comedi_device *dev,
 {
        struct das16m1_private_struct *devpriv = dev->private;
 
-       i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1),
-                                      &(devpriv->divisor2), &ns,
-                                      rounding_flags & TRIG_ROUND_MASK);
+       i8253_cascade_ns_to_timer_2div(I8254_OSC_BASE_10MHZ,
+                                      &devpriv->divisor1,
+                                      &devpriv->divisor2,
+                                      &ns, rounding_flags);
 
        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
        i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
@@ -393,22 +390,13 @@ static int das16m1_di_rbits(struct comedi_device *dev,
 
 static int das16m1_do_wbits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
-       struct das16m1_private_struct *devpriv = dev->private;
-       unsigned int wbits;
-
-       /*  only set bits that have been masked */
-       data[0] &= 0xf;
-       wbits = devpriv->do_bits;
-       /*  zero bits that have been masked */
-       wbits &= ~data[0];
-       /*  set masked bits */
-       wbits |= data[0] & data[1];
-       devpriv->do_bits = wbits;
-       data[1] = wbits;
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DAS16M1_DIO);
 
-       outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -649,7 +637,7 @@ static int das16m1_attach(struct comedi_device *dev,
        outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
 
        /*  initialize digital output lines */
-       outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+       outb(0, dev->iobase + DAS16M1_DIO);
 
        /* set the interrupt level */
        if (dev->irq)
index 5b300294d3229171d2212d962bdc626a57810f09..1880038956d05dcd6234ac7e18af4326380769f6 100644 (file)
@@ -108,7 +108,6 @@ TODO:
 /* misc. defines */
 #define DAS1800_SIZE           16      /* uses 16 io addresses */
 #define FIFO_SIZE              1024    /*  1024 sample fifo */
-#define TIMER_BASE             200     /*  5 Mhz master clock */
 #define UNIPOLAR               0x4     /*  bit that determines whether input range is uni/bipolar */
 #define DMA_BUF_SIZE           0x1ff00 /*  size in bytes of dma buffers */
 
@@ -427,7 +426,6 @@ struct das1800_private {
        volatile unsigned int count;    /* number of data points left to be taken */
        unsigned int divisor1;  /* value to load into board's counter 1 for timed conversions */
        unsigned int divisor2;  /* value to load into board's counter 2 for timed conversions */
-       int do_bits;            /* digital output bits */
        int irq_dma_bits;       /* bits for control register b */
        /* dma bits for control register b, stored so that dma can be
         * turned on and off */
@@ -440,7 +438,8 @@ struct das1800_private {
        uint16_t *dma_current_buf;      /* pointer to dma buffer currently being used */
        unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
        unsigned long iobase2;  /* secondary io address used for analog out on 'ao' boards */
-       short ao_update_bits;   /* remembers the last write to the 'update' dac */
+       unsigned short ao_update_bits;  /* remembers the last write to the
+                                        * 'update' dac */
 };
 
 /* analog out range for 'ao' boards */
@@ -503,7 +502,7 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
                                          struct comedi_subdevice *s)
 {
        struct das1800_private *devpriv = dev->private;
-       short dpnt;
+       unsigned short dpnt;
        int unipolar;
        struct comedi_cmd *cmd = &s->async->cmd;
 
@@ -840,12 +839,11 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
                if (cmd->scan_begin_src == TRIG_FOLLOW) {
                        tmp_arg = cmd->convert_arg;
                        /* calculate counter values that give desired timing */
-                       i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                      &(devpriv->divisor1),
-                                                      &(devpriv->divisor2),
-                                                      &(cmd->convert_arg),
-                                                      cmd->
-                                                      flags & TRIG_ROUND_MASK);
+                       i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                                 &devpriv->divisor1,
+                                                 &devpriv->divisor2,
+                                                 &cmd->convert_arg,
+                                                 cmd->flags);
                        if (tmp_arg != cmd->convert_arg)
                                err++;
                }
@@ -870,16 +868,11 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
                                }
                                tmp_arg = cmd->scan_begin_arg;
                                /* calculate counter values that give desired timing */
-                               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                              &(devpriv->
-                                                                divisor1),
-                                                              &(devpriv->
-                                                                divisor2),
-                                                              &(cmd->
-                                                                scan_begin_arg),
-                                                              cmd->
-                                                              flags &
-                                                              TRIG_ROUND_MASK);
+                               i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                                         &devpriv->divisor1,
+                                                         &devpriv->divisor2,
+                                                         &cmd->scan_begin_arg,
+                                                         cmd->flags);
                                if (tmp_arg != cmd->scan_begin_arg)
                                        err++;
                        }
@@ -1011,12 +1004,10 @@ static int setup_counters(struct comedi_device *dev,
                if (cmd->convert_src == TRIG_TIMER) {
                        /* set conversion frequency */
                        period = cmd->convert_arg;
-                       i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                      &devpriv->divisor1,
-                                                      &devpriv->divisor2,
-                                                      &period,
-                                                      cmd->flags &
-                                                       TRIG_ROUND_MASK);
+                       i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                                 &devpriv->divisor1,
+                                                 &devpriv->divisor2,
+                                                 &period, cmd->flags);
                        if (das1800_set_frequency(dev) < 0)
                                return -1;
                }
@@ -1024,9 +1015,10 @@ static int setup_counters(struct comedi_device *dev,
        case TRIG_TIMER:        /*  in burst mode */
                /* set scan frequency */
                period = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
-                                              &devpriv->divisor2, &period,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &period, cmd->flags);
                if (das1800_set_frequency(dev) < 0)
                        return -1;
                break;
@@ -1220,7 +1212,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
        int i, n;
        int chan, range, aref, chan_range;
        int timeout = 1000;
-       short dpnt;
+       unsigned short dpnt;
        int conv_flags = 0;
        unsigned long irq_flags;
 
@@ -1285,7 +1277,7 @@ static int das1800_ao_winsn(struct comedi_device *dev,
        int chan = CR_CHAN(insn->chanspec);
 /* int range = CR_RANGE(insn->chanspec); */
        int update_chan = thisboard->ao_n_chan - 1;
-       short output;
+       unsigned short output;
        unsigned long irq_flags;
 
        /*   card expects two's complement data */
@@ -1319,24 +1311,15 @@ static int das1800_di_rbits(struct comedi_device *dev,
        return insn->n;
 }
 
-/* writes to digital output channels */
 static int das1800_do_wbits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
-       struct das1800_private *devpriv = dev->private;
-       unsigned int wbits;
-
-       /*  only set bits that have been masked */
-       data[0] &= (1 << s->n_chan) - 1;
-       wbits = devpriv->do_bits;
-       wbits &= ~data[0];
-       wbits |= data[0] & data[1];
-       devpriv->do_bits = wbits;
-
-       outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DAS1800_DIGITAL);
 
-       data[1] = devpriv->do_bits;
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -1644,7 +1627,7 @@ static int das1800_attach(struct comedi_device *dev,
        das1800_cancel(dev, dev->read_subdev);
 
        /*  initialize digital out channels */
-       outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+       outb(0, dev->iobase + DAS1800_DIGITAL);
 
        /*  initialize analog out channels */
        if (thisboard->ao_ability == 1) {
index 11e16114e4e3150ccca1763f44107ee6e2238dad..5af0a5764a8c77c728998558025c0289605d0512 100644 (file)
@@ -66,7 +66,6 @@ cmd triggers supported:
 #include "comedi_fc.h"
 
 #define DAS800_SIZE           8
-#define TIMER_BASE            1000
 #define N_CHAN_AI             8        /*  number of analog input channels */
 
 /* Registers for the das800 */
@@ -356,11 +355,10 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
                int tmp = cmd->convert_arg;
 
                /* calculate counter values that give desired timing */
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->convert_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_1MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
        }
@@ -630,13 +628,9 @@ static int das800_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        struct das800_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        unsigned long irq_flags;
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
+       if (comedi_dio_update_state(s, data)) {
                devpriv->do_bits = s->state << 4;
 
                spin_lock_irqsave(&dev->spinlock, irq_flags);
index 118a4fd129f903ee3481c392644e115a8ef56188..b04a5633f754ef3c286ca0ef7615ba67152482d4 100644 (file)
@@ -596,52 +596,40 @@ static int dmm32at_ao_rinsn(struct comedi_device *dev,
 
 static int dmm32at_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct dmm32at_private *devpriv = dev->private;
-       unsigned char diobits;
-
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               /* outw(s->state,dev->iobase + DMM32AT_DIO); */
+       unsigned int mask;
+       unsigned int val;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               /* get access to the DIO regs */
+               outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
+
+               /* if either part of dio is set for output */
+               if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
+                   ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+                       val = (s->state & 0x00ff0000) >> 16;
+                       outb(val, dev->iobase + DMM32AT_DIOC);
+               }
+               if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
+                       val = (s->state & 0x0000ff00) >> 8;
+                       outb(val, dev->iobase + DMM32AT_DIOB);
+               }
+               if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
+                       val = (s->state & 0x000000ff);
+                       outb(val, dev->iobase + DMM32AT_DIOA);
+               }
        }
 
-       /* get access to the DIO regs */
-       outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
-
-       /* if either part of dio is set for output */
-       if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
-           ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
-               diobits = (s->state & 0x00ff0000) >> 16;
-               outb(diobits, dev->iobase + DMM32AT_DIOC);
-       }
-       if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
-               diobits = (s->state & 0x0000ff00) >> 8;
-               outb(diobits, dev->iobase + DMM32AT_DIOB);
-       }
-       if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
-               diobits = (s->state & 0x000000ff);
-               outb(diobits, dev->iobase + DMM32AT_DIOA);
-       }
+       val = inb(dev->iobase + DMM32AT_DIOA);
+       val |= inb(dev->iobase + DMM32AT_DIOB) << 8;
+       val |= inb(dev->iobase + DMM32AT_DIOC) << 16;
+       s->state = val;
 
-       /* now read the state back in */
-       s->state = inb(dev->iobase + DMM32AT_DIOC);
-       s->state <<= 8;
-       s->state |= inb(dev->iobase + DMM32AT_DIOB);
-       s->state <<= 8;
-       s->state |= inb(dev->iobase + DMM32AT_DIOA);
-       data[1] = s->state;
-
-       /* on return, data[1] contains the value of the digital
-        * input and output lines. */
-       /* data[1]=inw(dev->iobase + DMM32AT_DIO); */
-       /* or we could just return the software copy of the output values if
-        * it was a purely digital output subdevice */
-       /* data[1]=s->state; */
+       data[1] = val;
 
        return insn->n;
 }
index 38918a1198aa83cfbcc717f69be05c074b9bd7aa..811c8c59c01761f87ef8a9936cd3b648d8ea3751 100644 (file)
@@ -260,7 +260,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data)
 
 static int dt2801_readdata2(struct comedi_device *dev, int *data)
 {
-       int lb, hb;
+       int lb = 0;
+       int hb = 0;
        int ret;
 
        ret = dt2801_readdata(dev, &lb);
@@ -528,23 +529,23 @@ static int dt2801_ao_insn_write(struct comedi_device *dev,
 
 static int dt2801_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       int which = 0;
-
-       if (s == &dev->subdevices[3])
-               which = 1;
+       int which = (s == &dev->subdevices[3]) ? 1 : 0;
+       unsigned int val = 0;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                dt2801_writecmd(dev, DT_C_WRITE_DIG);
                dt2801_writedata(dev, which);
                dt2801_writedata(dev, s->state);
        }
+
        dt2801_writecmd(dev, DT_C_READ_DIG);
        dt2801_writedata(dev, which);
-       dt2801_readdata(dev, data + 1);
+       dt2801_readdata(dev, &val);
+
+       data[1] = val;
 
        return insn->n;
 }
index a41a5716f3584fdbb488203b1c87b055fe5ae84f..0ca02fa7ba1b96e1a92edd97a81ca92a623bc711 100644 (file)
@@ -353,11 +353,11 @@ static int dt2811_di_insn_bits(struct comedi_device *dev,
 
 static int dt2811_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= data[0] & data[1];
-       outb(s->state, dev->iobase + DT2811_DIO);
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DT2811_DIO);
 
        data[1] = s->state;
 
index f4a8529239b5448b5fe5c9a317b0dfaf1146bc46..bf589936e5465f7822d47cc7e31c4d2162fa5fa9 100644 (file)
@@ -80,36 +80,31 @@ static int dt2817_dio_insn_config(struct comedi_device *dev,
 
 static int dt2817_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       unsigned int changed;
-
-       /* It's questionable whether it is more important in
-        * a driver like this to be deterministic or fast.
-        * We choose fast. */
-
-       if (data[0]) {
-               changed = s->state;
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-               changed ^= s->state;
-               changed &= s->io_bits;
-               if (changed & 0x000000ff)
-                       outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
-               if (changed & 0x0000ff00)
-                       outb((s->state >> 8) & 0xff,
-                            dev->iobase + DT2817_DATA + 1);
-               if (changed & 0x00ff0000)
-                       outb((s->state >> 16) & 0xff,
-                            dev->iobase + DT2817_DATA + 2);
-               if (changed & 0xff000000)
-                       outb((s->state >> 24) & 0xff,
-                            dev->iobase + DT2817_DATA + 3);
+       unsigned long iobase = dev->iobase + DT2817_DATA;
+       unsigned int mask;
+       unsigned int val;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0x000000ff)
+                       outb(s->state & 0xff, iobase + 0);
+               if (mask & 0x0000ff00)
+                       outb((s->state >> 8) & 0xff, iobase + 1);
+               if (mask & 0x00ff0000)
+                       outb((s->state >> 16) & 0xff, iobase + 2);
+               if (mask & 0xff000000)
+                       outb((s->state >> 24) & 0xff, iobase + 3);
        }
-       data[1] = inb(dev->iobase + DT2817_DATA + 0);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+       val = inb(iobase + 0);
+       val |= (inb(iobase + 1) << 8);
+       val |= (inb(iobase + 2) << 16);
+       val |= (inb(iobase + 3) << 24);
+
+       data[1] = val;
 
        return insn->n;
 }
index da3ee859bdbcedd025708fa0af0ac434df241b26..a01e6b553887ab23480d8de187ef0079a662715e 100644 (file)
@@ -226,7 +226,7 @@ struct dt282x_private {
 
        const struct comedi_lrange *darangelist[2];
 
-       short ao[2];
+       unsigned short ao[2];
 
        volatile int dacsr;     /* software copies of registers */
        volatile int adcsr;
@@ -237,7 +237,7 @@ struct dt282x_private {
 
        struct {
                int chan;
-               short *buf;     /* DMA buffer */
+               unsigned short *buf;    /* DMA buffer */
                volatile int size;      /* size of current transfer */
        } dma[2];
        int dma_maxsize;        /* max size of DMA transfer (in bytes) */
@@ -283,7 +283,7 @@ static void dt282x_disable_dma(struct comedi_device *dev);
 
 static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
 
-static void dt282x_munge(struct comedi_device *dev, short *buf,
+static void dt282x_munge(struct comedi_device *dev, unsigned short *buf,
                         unsigned int nbytes)
 {
        const struct dt282x_board *board = comedi_board(dev);
@@ -496,9 +496,9 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
 #if 0
        if (adcsr & DT2821_ADDONE) {
                int ret;
-               short data;
+               unsigned short data;
 
-               data = (short)inw(dev->iobase + DT2821_ADDAT);
+               data = inw(dev->iobase + DT2821_ADDAT);
                data &= (1 << board->adbits) - 1;
 
                if (devpriv->ad_2scomp)
@@ -796,7 +796,7 @@ static int dt282x_ao_insn_write(struct comedi_device *dev,
 {
        const struct dt282x_board *board = comedi_board(dev);
        struct dt282x_private *devpriv = dev->private;
-       short d;
+       unsigned short d;
        unsigned int chan;
 
        chan = CR_CHAN(insn->chanspec);
@@ -967,14 +967,12 @@ static int dt282x_ao_cancel(struct comedi_device *dev,
 
 static int dt282x_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + DT2821_DIODAT);
-       }
+
        data[1] = inw(dev->iobase + DT2821_DIODAT);
 
        return insn->n;
index 64ef87598b607deffe7b9a11999c753defbce126..292226eeff924dd6c7b9dccda948d6bbce476016 100644 (file)
@@ -331,7 +331,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
        int rear;
        int count;
        int i;
-       short data;
+       unsigned short data;
 
        front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
        count = front - devpriv->ai_front;
@@ -665,13 +665,12 @@ static int dt3k_dio_insn_config(struct comedi_device *dev,
 
 static int dt3k_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[1] & data[0];
+       if (comedi_dio_update_state(s, data))
                dt3k_writesingle(dev, SUBS_DOUT, 0, s->state);
-       }
+
        data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0);
 
        return insn->n;
index b5e6f33dc217c4493f595ddedc82e86a3b5b2ee1..73af600c172532d05ac634b83c094fa983a20a49 100644 (file)
@@ -85,13 +85,9 @@ for my needs.
 #define F020_MASK_DACxCN_DACxEN                0x80
 
 enum {
-       /* A/D  D/A  DI  DO  CT */
-       DT9812_DEVID_DT9812_10, /*  8    2   8   8   1  +/- 10V */
-       DT9812_DEVID_DT9812_2PT5,       /* 8    2   8   8   1  0-2.44V */
-#if 0
-       DT9812_DEVID_DT9813,    /*  16   2   4   4   1  +/- 10V */
-       DT9812_DEVID_DT9814     /*  24   2   0   0   1  +/- 10V */
-#endif
+                                       /* A/D  D/A  DI  DO  CT */
+       DT9812_DEVID_DT9812_10,         /*  8    2   8   8   1  +/- 10V */
+       DT9812_DEVID_DT9812_2PT5,       /*  8    2   8   8   1  0-2.44V */
 };
 
 enum dt9812_gain {
@@ -580,15 +576,8 @@ static int dt9812_do_insn_bits(struct comedi_device *dev,
                               struct comedi_insn *insn,
                               unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                dt9812_digital_out(dev, s->state);
-       }
 
        data[1] = s->state;
 
index fd525f499f2a2db47d16eef9a9f07b780cc00690..f2a9f1c2f3b6dfe2ffa563a53c466ac7bd7fd987 100644 (file)
@@ -147,33 +147,23 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/* digital output bit interface */
 static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev,
-                             struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                                    struct comedi_subdevice *s,
+                                    struct comedi_insn *insn,
+                                    unsigned int *data)
 {
        struct dyna_pci10xx_private *devpriv = dev->private;
 
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit.
-        * s->state contains the previous write data
-        */
        mutex_lock(&devpriv->mutex);
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                smp_mb();
                outw_p(s->state, devpriv->BADR3);
                udelay(10);
        }
 
-       /*
-        * On return, data[1] contains the value of the digital
-        * input and output lines. We just return the software copy of the
-        * output values if it was a purely digital output subdevice.
-        */
        data[1] = s->state;
        mutex_unlock(&devpriv->mutex);
+
        return insn->n;
 }
 
index 8d70f64b157478b43c79eb32ad2952962e7316e3..e3ff4c43897978ef7caf355215358bf2595e3a12 100644 (file)
@@ -25,8 +25,7 @@ Configuration options:
 
 #define FL512_SIZE 16          /* the size of the used memory */
 struct fl512_private {
-
-       short ao_readback[2];
+       unsigned short ao_readback[2];
 };
 
 static const struct comedi_lrange range_fl512 = { 4, {
index 3889d23292d04d322dcba5d37dbf6d14c0a8aab0..1e16641ec52d6991bce167d633a03f475f73a936 100644 (file)
@@ -118,9 +118,7 @@ struct icp_multi_private {
        unsigned char act_chanlist_len; /*  len of scanlist */
        unsigned char act_chanlist_pos; /*  actual position in MUX list */
        unsigned int *ai_chanlist;      /*  actaul chanlist */
-       short *ai_data;         /*  data buffer */
-       short ao_data[4];       /*  data output buffer */
-       short di_data;          /*  Digital input data */
+       unsigned short ao_data[4];      /*  data output buffer */
        unsigned int do_data;   /*  Remember digital output data */
 };
 
@@ -348,18 +346,13 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev,
 
 static int icp_multi_insn_bits_do(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        struct icp_multi_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
-               printk(KERN_DEBUG "Digital outputs = %4x \n", s->state);
-
+       if (comedi_dio_update_state(s, data))
                writew(s->state, devpriv->io_addr + ICP_MULTI_DO);
-       }
 
        data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
 
@@ -548,7 +541,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
        s->maxdata = 1;
        s->len_chanlist = 16;
        s->range_table = &range_digital;
-       s->io_bits = 0;
        s->insn_bits = icp_multi_insn_bits_di;
 
        s = &dev->subdevices[3];
@@ -558,8 +550,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
        s->maxdata = 1;
        s->len_chanlist = 8;
        s->range_table = &range_digital;
-       s->io_bits = 0xff;
-       s->state = 0;
        s->insn_bits = icp_multi_insn_bits_do;
 
        s = &dev->subdevices[4];
index 5c3a318b464012bff1f5a44c2788e20008399ed7..8577778441fa8cfa1f5af64f40f82e4cc7d0ee15 100644 (file)
@@ -378,13 +378,10 @@ static int ii20k_dio_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        struct ii20k_private *devpriv = dev->private;
-       unsigned int mask = data[0] & s->io_bits;       /* outputs only */
-       unsigned int bits = data[1];
+       unsigned int mask;
 
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0x000000ff)
                        writeb((s->state >> 0) & 0xff,
                               devpriv->ioaddr + II20K_DIO0_REG);
index 8f4afadab76a617a526da821d3ac029562eadf3c..3d12e913592649f3eb4c1dc999058695f27b8a86 100644 (file)
@@ -427,7 +427,7 @@ static int xilinx_download(struct comedi_device *dev)
 static void me4000_reset(struct comedi_device *dev)
 {
        struct me4000_info *info = dev->private;
-       unsigned long val;
+       unsigned int val;
        int chan;
 
        /* Make a hardware reset */
@@ -480,9 +480,9 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
        int rang = CR_RANGE(insn->chanspec);
        int aref = CR_AREF(insn->chanspec);
 
-       unsigned long entry = 0;
-       unsigned long tmp;
-       long lval;
+       unsigned int entry = 0;
+       unsigned int tmp;
+       unsigned int lval;
 
        if (insn->n == 0) {
                return 0;
@@ -586,7 +586,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 static int me4000_ai_cancel(struct comedi_device *dev,
                            struct comedi_subdevice *s)
 {
-       unsigned long tmp;
+       unsigned int tmp;
 
        /* Stop any running conversion */
        tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
@@ -783,7 +783,7 @@ static int ai_prepare(struct comedi_device *dev,
                      unsigned int scan_ticks, unsigned int chan_ticks)
 {
 
-       unsigned long tmp = 0;
+       unsigned int tmp = 0;
 
        /* Write timer arguments */
        ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
@@ -1108,7 +1108,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
        struct comedi_subdevice *s = &dev->subdevices[0];
        int i;
        int c = 0;
-       long lval;
+       unsigned int lval;
 
        if (!dev->attached)
                return IRQ_NONE;
@@ -1252,7 +1252,7 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
        int chan = CR_CHAN(insn->chanspec);
        int rang = CR_RANGE(insn->chanspec);
        int aref = CR_AREF(insn->chanspec);
-       unsigned long tmp;
+       unsigned int tmp;
 
        if (insn->n == 0) {
                return 0;
@@ -1313,29 +1313,12 @@ static int me4000_ao_insn_read(struct comedi_device *dev,
        return 1;
 }
 
-/*=============================================================================
-  Digital I/O section
-  ===========================================================================*/
-
 static int me4000_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       /*
-        * The insn data consists of a mask in data[0] and the new data
-        * in data[1]. The mask defines which bits we are concerning about.
-        * The new data must be anded with the mask.
-        * Each channel corresponds to a bit.
-        */
-       if (data[0]) {
-               /* Check if requested ports are configured for output */
-               if ((s->io_bits & data[0]) != data[0])
-                       return -EIO;
-
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
-               /* Write out the new digital output lines */
+       if (comedi_dio_update_state(s, data)) {
                outl((s->state >> 0) & 0xFF,
                            dev->iobase + ME4000_DIO_PORT_0_REG);
                outl((s->state >> 8) & 0xFF,
@@ -1346,8 +1329,6 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
                            dev->iobase + ME4000_DIO_PORT_3_REG);
        }
 
-       /* On return, data[1] contains the value of
-          the digital input and output lines. */
        data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
                  ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
                  ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
index a6f6d4a46587f06d1b84ba53a45df3ebcf150821..24ec9ef9b1a0fc326ac560aa74a5b57105fd2647 100644 (file)
@@ -222,15 +222,11 @@ static int me_dio_insn_bits(struct comedi_device *dev,
        struct me_private_data *dev_private = dev->private;
        void __iomem *mmio_porta = dev_private->me_regbase + ME_DIO_PORT_A;
        void __iomem *mmio_portb = dev_private->me_regbase + ME_DIO_PORT_B;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
+       unsigned int mask;
        unsigned int val;
 
-       mask &= s->io_bits;     /* only update the COMEDI_OUTPUT channels */
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0x0000ffff)
                        writew((s->state & 0xffff), mmio_porta);
                if (mask & 0xffff0000)
@@ -545,7 +541,6 @@ static int me_auto_attach(struct comedi_device *dev,
        s->range_table  = &range_digital;
        s->insn_bits    = me_dio_insn_bits;
        s->insn_config  = me_dio_insn_config;
-       s->io_bits      = 0;
 
        dev_info(dev->class_dev, "%s: %s attached\n",
                dev->driver->driver_name, dev->board_name);
index 9d75ea4e201bcb553cc5cb75b38b759d0fe87e65..3ca755eca285dd129741640c7153f7a0413dcfe8 100644 (file)
@@ -163,11 +163,11 @@ static int multiq3_di_insn_bits(struct comedi_device *dev,
 
 static int multiq3_do_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= (data[0] & data[1]);
-       outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
+       if (comedi_dio_update_state(s, data))
+               outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
 
        data[1] = s->state;
 
index c2745f201f2c19cb713b812630c0d0774fb3c5d8..85aa9609d6a280994bffaa8ad72f0eac5c3c3861 100644 (file)
@@ -1,41 +1,33 @@
 /*
-    comedi/drivers/ni_6527.c
-    driver for National Instruments PCI-6527
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.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.
-
-    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.
-*/
-/*
-Driver: ni_6527
-Description: National Instruments 6527
-Author: ds
-Status: works
-Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
-Updated: Sat, 25 Jan 2003 13:24:40 -0800
-
-
-*/
+ * ni_6527.c
+ * Comedi driver for National Instruments PCI-6527
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.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.
+ *
+ * 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.
+ */
 
 /*
-   Manuals (available from ftp://ftp.natinst.com/support/manuals)
-
-       370106b.pdf     6527 Register Level Programmer Manual
-
+ * Driver: ni_6527
+ * Description: National Instruments 6527
+ * Devices: (National Instruments) PCI-6527 [pci-6527]
+ *          (National Instruments) PXI-6527 [pxi-6527]
+ * Author: David A. Schleef <ds@schleef.org>
+ * Updated: Sat, 25 Jan 2003 13:24:40 -0800
+ * Status: works
+ *
+ * Configuration Options: not applicable, uses PCI auto config
  */
 
-#define DEBUG 1
-#define DEBUG_FLAGS
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -43,39 +35,41 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
 #include "../comedidev.h"
 
 #include "comedi_fc.h"
-#include "mite.h"
-
-#define DRIVER_NAME "ni_6527"
-
-#define NI6527_DIO_SIZE 4096
-#define NI6527_MITE_SIZE 4096
-
-#define Port_Register(x)                       (0x00+(x))
-#define ID_Register                            0x06
-
-#define Clear_Register                         0x07
-#define ClrEdge                                0x08
-#define ClrOverflow                    0x04
-#define ClrFilter                      0x02
-#define ClrInterval                    0x01
 
-#define Filter_Interval(x)                     (0x08+(x))
-#define Filter_Enable(x)                       (0x0c+(x))
-
-#define Change_Status                          0x14
-#define MasterInterruptStatus          0x04
-#define Overflow                       0x02
-#define EdgeStatus                     0x01
-
-#define Master_Interrupt_Control               0x15
-#define FallingEdgeIntEnable           0x10
-#define RisingEdgeIntEnable            0x08
-#define MasterInterruptEnable          0x04
-#define OverflowIntEnable              0x02
-#define EdgeIntEnable                  0x01
-
-#define Rising_Edge_Detection_Enable(x)                (0x018+(x))
-#define Falling_Edge_Detection_Enable(x)       (0x020+(x))
+/*
+ * PCI BAR1 - Register memory map
+ *
+ * Manuals (available from ftp://ftp.natinst.com/support/manuals)
+ *     370106b.pdf     6527 Register Level Programmer Manual
+ */
+#define NI6527_DI_REG(x)               (0x00 + (x))
+#define NI6527_DO_REG(x)               (0x03 + (x))
+#define NI6527_ID_REG                  0x06
+#define NI6527_CLR_REG                 0x07
+#define NI6527_CLR_EDGE                        (1 << 3)
+#define NI6527_CLR_OVERFLOW            (1 << 2)
+#define NI6527_CLR_FILT                        (1 << 1)
+#define NI6527_CLR_INTERVAL            (1 << 0)
+#define NI6527_CLR_IRQS                        (NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW)
+#define NI6527_CLR_RESET_FILT          (NI6527_CLR_FILT | NI6527_CLR_INTERVAL)
+#define NI6527_FILT_INTERVAL_REG(x)    (0x08 + (x))
+#define NI6527_FILT_ENA_REG(x)         (0x0c + (x))
+#define NI6527_STATUS_REG              0x14
+#define NI6527_STATUS_IRQ              (1 << 2)
+#define NI6527_STATUS_OVERFLOW         (1 << 1)
+#define NI6527_STATUS_EDGE             (1 << 0)
+#define NI6527_CTRL_REG                        0x15
+#define NI6527_CTRL_FALLING            (1 << 4)
+#define NI6527_CTRL_RISING             (1 << 3)
+#define NI6527_CTRL_IRQ                        (1 << 2)
+#define NI6527_CTRL_OVERFLOW           (1 << 1)
+#define NI6527_CTRL_EDGE               (1 << 0)
+#define NI6527_CTRL_DISABLE_IRQS       0
+#define NI6527_CTRL_ENABLE_IRQS                (NI6527_CTRL_FALLING | \
+                                        NI6527_CTRL_RISING | \
+                                        NI6527_CTRL_IRQ | NI6527_CTRL_EDGE)
+#define NI6527_RISING_EDGE_REG(x)      (0x18 + (x))
+#define NI6527_FALLING_EDGE_REG(x)     (0x20 + (x))
 
 enum ni6527_boardid {
        BOARD_PCI6527,
@@ -96,96 +90,113 @@ static const struct ni6527_board ni6527_boards[] = {
 };
 
 struct ni6527_private {
-       struct mite_struct *mite;
+       void __iomem *mmio_base;
        unsigned int filter_interval;
        unsigned int filter_enable;
 };
 
+static void ni6527_set_filter_interval(struct comedi_device *dev,
+                                      unsigned int val)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       if (val != devpriv->filter_interval) {
+               writeb(val & 0xff, mmio + NI6527_FILT_INTERVAL_REG(0));
+               writeb((val >> 8) & 0xff, mmio + NI6527_FILT_INTERVAL_REG(1));
+               writeb((val >> 16) & 0x0f, mmio + NI6527_FILT_INTERVAL_REG(2));
+
+               writeb(NI6527_CLR_INTERVAL, mmio + NI6527_CLR_REG);
+
+               devpriv->filter_interval = val;
+       }
+}
+
+static void ni6527_set_filter_enable(struct comedi_device *dev,
+                                    unsigned int val)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       writeb(val & 0xff, mmio + NI6527_FILT_ENA_REG(0));
+       writeb((val >> 8) & 0xff, mmio + NI6527_FILT_ENA_REG(1));
+       writeb((val >> 16) & 0xff, mmio + NI6527_FILT_ENA_REG(2));
+}
+
 static int ni6527_di_insn_config(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int interval;
 
-       if (insn->n != 2)
-               return -EINVAL;
-
-       if (data[0] != INSN_CONFIG_FILTER)
-               return -EINVAL;
-
-       if (data[1]) {
+       switch (data[0]) {
+       case INSN_CONFIG_FILTER:
+               /*
+                * The deglitch filter interval is specified in nanoseconds.
+                * The hardware supports intervals in 200ns increments. Round
+                * the user values up and return the actual interval.
+                */
                interval = (data[1] + 100) / 200;
                data[1] = interval * 200;
 
-               if (interval != devpriv->filter_interval) {
-                       writeb(interval & 0xff,
-                              devpriv->mite->daq_io_addr + Filter_Interval(0));
-                       writeb((interval >> 8) & 0xff,
-                              devpriv->mite->daq_io_addr + Filter_Interval(1));
-                       writeb((interval >> 16) & 0x0f,
-                              devpriv->mite->daq_io_addr + Filter_Interval(2));
-
-                       writeb(ClrInterval,
-                              devpriv->mite->daq_io_addr + Clear_Register);
-
-                       devpriv->filter_interval = interval;
+               if (interval) {
+                       ni6527_set_filter_interval(dev, interval);
+                       devpriv->filter_enable |= 1 << chan;
+               } else {
+                       devpriv->filter_enable &= ~(1 << chan);
                }
-
-               devpriv->filter_enable |= 1 << chan;
-       } else {
-               devpriv->filter_enable &= ~(1 << chan);
+               ni6527_set_filter_enable(dev, devpriv->filter_enable);
+               break;
+       default:
+               return -EINVAL;
        }
 
-       writeb(devpriv->filter_enable,
-              devpriv->mite->daq_io_addr + Filter_Enable(0));
-       writeb(devpriv->filter_enable >> 8,
-              devpriv->mite->daq_io_addr + Filter_Enable(1));
-       writeb(devpriv->filter_enable >> 16,
-              devpriv->mite->daq_io_addr + Filter_Enable(2));
-
-       return 2;
+       return insn->n;
 }
 
 static int ni6527_di_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+       unsigned int val;
 
-       data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
-       data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
-       data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
+       val = readb(mmio + NI6527_DI_REG(0));
+       val |= (readb(mmio + NI6527_DI_REG(1)) << 8);
+       val |= (readb(mmio + NI6527_DI_REG(2)) << 16);
+
+       data[1] = val;
 
        return insn->n;
 }
 
 static int ni6527_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
-
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
-               /* The open relay state on the board cooresponds to 1,
-                * but in Comedi, it is represented by 0. */
-               if (data[0] & 0x0000ff) {
-                       writeb((s->state ^ 0xff),
-                              devpriv->mite->daq_io_addr + Port_Register(3));
-               }
-               if (data[0] & 0x00ff00) {
-                       writeb((s->state >> 8) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(4));
-               }
-               if (data[0] & 0xff0000) {
-                       writeb((s->state >> 16) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(5));
-               }
+       void __iomem *mmio = devpriv->mmio_base;
+       unsigned int mask;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               /* Outputs are inverted */
+               unsigned int val = s->state ^ 0xffffff;
+
+               if (mask & 0x0000ff)
+                       writeb(val & 0xff, mmio + NI6527_DO_REG(0));
+               if (mask & 0x00ff00)
+                       writeb((val >> 8) & 0xff, mmio + NI6527_DO_REG(1));
+               if (mask & 0xff0000)
+                       writeb((val >> 16) & 0xff, mmio + NI6527_DO_REG(2));
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -195,21 +206,22 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
 {
        struct comedi_device *dev = d;
        struct ni6527_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[2];
+       struct comedi_subdevice *s = dev->read_subdev;
+       void __iomem *mmio = devpriv->mmio_base;
        unsigned int status;
 
-       status = readb(devpriv->mite->daq_io_addr + Change_Status);
-       if ((status & MasterInterruptStatus) == 0)
-               return IRQ_NONE;
-       if ((status & EdgeStatus) == 0)
+       status = readb(mmio + NI6527_STATUS_REG);
+       if (!(status & NI6527_STATUS_IRQ))
                return IRQ_NONE;
 
-       writeb(ClrEdge | ClrOverflow,
-              devpriv->mite->daq_io_addr + Clear_Register);
+       if (status & NI6527_STATUS_EDGE) {
+               comedi_buf_put(s->async, 0);
+               s->async->events |= COMEDI_CB_EOS;
+               comedi_event(dev, s);
+       }
+
+       writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
 
-       comedi_buf_put(s->async, 0);
-       s->async->events |= COMEDI_CB_EOS;
-       comedi_event(dev, s);
        return IRQ_HANDLED;
 }
 
@@ -259,13 +271,10 @@ static int ni6527_intr_cmd(struct comedi_device *dev,
                           struct comedi_subdevice *s)
 {
        struct ni6527_private *devpriv = dev->private;
-       /* struct comedi_cmd *cmd = &s->async->cmd; */
+       void __iomem *mmio = devpriv->mmio_base;
 
-       writeb(ClrEdge | ClrOverflow,
-              devpriv->mite->daq_io_addr + Clear_Register);
-       writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
-              MasterInterruptEnable | EdgeIntEnable,
-              devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
+       writeb(NI6527_CTRL_ENABLE_IRQS, mmio + NI6527_CTRL_REG);
 
        return 0;
 }
@@ -274,8 +283,9 @@ static int ni6527_intr_cancel(struct comedi_device *dev,
                              struct comedi_subdevice *s)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
 
-       writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
 
        return 0;
 }
@@ -288,32 +298,54 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
+static void ni6527_set_edge_detection(struct comedi_device *dev,
+                                     unsigned int rising,
+                                     unsigned int falling)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       /* enable rising-edge detection channels */
+       writeb(rising & 0xff, mmio + NI6527_RISING_EDGE_REG(0));
+       writeb((rising >> 8) & 0xff, mmio + NI6527_RISING_EDGE_REG(1));
+       writeb((rising >> 16) & 0xff, mmio + NI6527_RISING_EDGE_REG(2));
+
+       /* enable falling-edge detection channels */
+       writeb(falling & 0xff, mmio + NI6527_FALLING_EDGE_REG(0));
+       writeb((falling >> 8) & 0xff, mmio + NI6527_FALLING_EDGE_REG(1));
+       writeb((falling >> 16) & 0xff, mmio + NI6527_FALLING_EDGE_REG(2));
+}
+
 static int ni6527_intr_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
+{
+       switch (data[0]) {
+       case INSN_CONFIG_CHANGE_NOTIFY:
+               /* check_insn_config_length() does not check this instruction */
+               if (insn->n != 3)
+                       return -EINVAL;
+               ni6527_set_edge_detection(dev, data[1], data[2]);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return insn->n;
+}
+
+static void ni6527_reset(struct comedi_device *dev)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
 
-       if (insn->n < 1)
-               return -EINVAL;
-       if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
-               return -EINVAL;
+       /* disable deglitch filters on all channels */
+       ni6527_set_filter_enable(dev, 0);
 
-       writeb(data[1],
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
-       writeb(data[1] >> 8,
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
-       writeb(data[1] >> 16,
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
-
-       writeb(data[2],
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
-       writeb(data[2] >> 8,
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
-       writeb(data[2] >> 16,
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
-
-       return 2;
+       writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
+              mmio + NI6527_CLR_REG);
+       writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
 }
 
 static int ni6527_auto_attach(struct comedi_device *dev,
@@ -332,75 +364,69 @@ static int ni6527_auto_attach(struct comedi_device *dev,
        dev->board_ptr = board;
        dev->board_name = board->name;
 
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
+
        ret = comedi_pci_enable(dev);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
+       devpriv->mmio_base = pci_ioremap_bar(pcidev, 1);
+       if (!devpriv->mmio_base)
                return -ENOMEM;
 
-       devpriv->mite = mite_alloc(pcidev);
-       if (!devpriv->mite)
-               return -ENOMEM;
+       /* make sure this is actually a 6527 device */
+       if (readb(devpriv->mmio_base + NI6527_ID_REG) != 0x27)
+               return -ENODEV;
 
-       ret = mite_setup(devpriv->mite);
-       if (ret < 0) {
-               dev_err(dev->class_dev, "error setting up mite\n");
-               return ret;
-       }
+       ni6527_reset(dev);
 
-       dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name,
-                readb(devpriv->mite->daq_io_addr + ID_Register));
+       ret = request_irq(pcidev->irq, ni6527_interrupt, IRQF_SHARED,
+                         dev->board_name, dev);
+       if (ret == 0)
+               dev->irq = pcidev->irq;
 
        ret = comedi_alloc_subdevices(dev, 3);
        if (ret)
                return ret;
 
+       /* Digital Input subdevice */
        s = &dev->subdevices[0];
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 24;
-       s->range_table = &range_digital;
-       s->maxdata = 1;
-       s->insn_config = ni6527_di_insn_config;
-       s->insn_bits = ni6527_di_insn_bits;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 24;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_config  = ni6527_di_insn_config;
+       s->insn_bits    = ni6527_di_insn_bits;
+
+       /* Digital Output subdevice */
        s = &dev->subdevices[1];
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 24;
-       s->range_table = &range_unknown;  /* FIXME: actually conductance */
-       s->maxdata = 1;
-       s->insn_bits = ni6527_do_insn_bits;
-
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 24;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = ni6527_do_insn_bits;
+
+       /* Edge detection interrupt subdevice */
        s = &dev->subdevices[2];
-       dev->read_subdev = s;
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
-       s->n_chan = 1;
-       s->range_table = &range_unknown;
-       s->maxdata = 1;
-       s->do_cmdtest = ni6527_intr_cmdtest;
-       s->do_cmd = ni6527_intr_cmd;
-       s->cancel = ni6527_intr_cancel;
-       s->insn_bits = ni6527_intr_insn_bits;
-       s->insn_config = ni6527_intr_insn_config;
-
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
-
-       writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
-              devpriv->mite->daq_io_addr + Clear_Register);
-       writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
-
-       ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
-                         IRQF_SHARED, DRIVER_NAME, dev);
-       if (ret < 0)
-               dev_warn(dev->class_dev, "irq not available\n");
-       else
-               dev->irq = mite_irq(devpriv->mite);
+       if (dev->irq) {
+               dev->read_subdev = s;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_config  = ni6527_intr_insn_config;
+               s->insn_bits    = ni6527_intr_insn_bits;
+               s->do_cmdtest   = ni6527_intr_cmdtest;
+               s->do_cmd       = ni6527_intr_cmd;
+               s->cancel       = ni6527_intr_cancel;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
 
        return 0;
 }
@@ -409,23 +435,18 @@ static void ni6527_detach(struct comedi_device *dev)
 {
        struct ni6527_private *devpriv = dev->private;
 
-       if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr)
-               writeb(0x00,
-                      devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       if (devpriv && devpriv->mmio_base)
+               ni6527_reset(dev);
        if (dev->irq)
                free_irq(dev->irq, dev);
-       if (devpriv && devpriv->mite) {
-               mite_unsetup(devpriv->mite);
-               mite_free(devpriv->mite);
-       }
        comedi_pci_disable(dev);
 }
 
 static struct comedi_driver ni6527_driver = {
-       .driver_name = DRIVER_NAME,
-       .module = THIS_MODULE,
-       .auto_attach = ni6527_auto_attach,
-       .detach = ni6527_detach,
+       .driver_name    = "ni_6527",
+       .module         = THIS_MODULE,
+       .auto_attach    = ni6527_auto_attach,
+       .detach         = ni6527_detach,
 };
 
 static int ni6527_pci_probe(struct pci_dev *dev,
@@ -442,7 +463,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
 MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
 
 static struct pci_driver ni6527_pci_driver = {
-       .name           = DRIVER_NAME,
+       .name           = "ni_6527",
        .id_table       = ni6527_pci_table,
        .probe          = ni6527_pci_probe,
        .remove         = comedi_pci_auto_unconfig,
@@ -450,5 +471,5 @@ static struct pci_driver ni6527_pci_driver = {
 module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for National Instruments PCI-6527");
 MODULE_LICENSE("GPL");
index 3607336dafe297968395871e00bd0a14fa700bd5..8a991dcab24a9b5a08cdcaf480979292337db555 100644 (file)
@@ -1213,7 +1213,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
        s->range_table = &range_digital;
        s->insn_bits = ni_660x_dio_insn_bits;
        s->insn_config = ni_660x_dio_insn_config;
-       s->io_bits = 0;         /* all bits default to input */
        /*  we use the ioconfig registers to control dio direction, so zero
        output enables in stc dio control reg */
        ni_660x_write_register(dev, 0, 0, STCDIOControl);
index e2926ce3fb24be9799e1ce2fe949992dfacc17c3..e4414cf110e7e3a72e049d48d0c00c32a7e7d6c6 100644 (file)
@@ -136,20 +136,15 @@ static int ni_670x_ao_rinsn(struct comedi_device *dev,
 
 static int ni_670x_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct ni_670x_private *devpriv = dev->private;
        void __iomem *io_addr = devpriv->mite->daq_io_addr +
                                        DIO_PORT0_DATA_OFFSET;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                writel(s->state, io_addr);
-       }
 
        data[1] = readl(io_addr);
 
index 2512ce8dfcaa7bd2a830fc29aaf307555b115d28..63c847932eb88983fbe082c969cfb94787293e95 100644 (file)
@@ -154,7 +154,7 @@ struct a2150_private {
 
        volatile unsigned int count;    /* number of data points left to be taken */
        unsigned int dma;       /*  dma channel */
-       s16 *dma_buffer;        /*  dma buffer */
+       uint16_t *dma_buffer;   /*  dma buffer */
        unsigned int dma_transfer_size; /*  size in bytes of dma transfers */
        int irq_dma_bits;       /*  irq/dma register bits */
        int config_bits;        /*  config register bits */
@@ -192,7 +192,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
        struct comedi_async *async;
        struct comedi_cmd *cmd;
        unsigned int max_points, num_points, residue, leftover;
-       short dpnt;
+       unsigned short dpnt;
        static const int sample_size = sizeof(devpriv->dma_buffer[0]);
 
        if (!dev->attached) {
@@ -684,13 +684,12 @@ static int a2150_set_chanlist(struct comedi_device *dev,
                devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
                break;
        case 2:
-               if (start_channel == 0) {
+               if (start_channel == 0)
                        devpriv->config_bits |= CHANNEL_BITS(0x2);
-               } else if (start_channel == 2) {
+               else if (start_channel == 2)
                        devpriv->config_bits |= CHANNEL_BITS(0x3);
-               } else {
+               else
                        return -1;
-               }
                break;
        case 4:
                devpriv->config_bits |= CHANNEL_BITS(0x1);
index b9122fd835e1e714cec811c43d2c6c1a51675e9e..10e3e9475ee2c544336ea3075755df30972240e1 100644 (file)
 /*
-    comedi/drivers/ni_at_ao.c
-    Driver for NI AT-AO-6/10 boards
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000,2002 David A. Schleef <ds@schleef.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.
-
-    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.
-*/
-/*
-Driver: ni_at_ao
-Description: National Instruments AT-AO-6/10
-Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
-Status: should work
-Author: ds
-Updated: Sun Dec 26 12:26:28 EST 2004
-
-Configuration options:
-  [0] - I/O port base address
-  [1] - IRQ (unused)
-  [2] - DMA (unused)
-  [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V
-       bipolar, 1 for 0V to 10V unipolar)
-
-*/
+ * ni_at_ao.c
+ * Driver for NI AT-AO-6/10 boards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000,2002 David A. Schleef <ds@schleef.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.
+ *
+ * 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.
+ */
+
 /*
- * Register-level programming information can be found in NI
- * document 320379.pdf.
+ * Driver: ni_at_ao
+ * Description: National Instruments AT-AO-6/10
+ * Devices: (National Instruments) AT-AO-6 [at-ao-6]
+ *          (National Instruments) AT-AO-10 [at-ao-10]
+ * Status: should work
+ * Author: David A. Schleef <ds@schleef.org>
+ * Updated: Sun Dec 26 12:26:28 EST 2004
+ *
+ * Configuration options:
+ *   [0] - I/O port base address
+ *   [1] - IRQ (unused)
+ *   [2] - DMA (unused)
+ *   [3] - analog output range, set by jumpers on hardware
+ *         0 for -10 to 10V bipolar
+ *         1 for 0V to 10V unipolar
  */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 
-/* board egisters */
-/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+#include "../comedidev.h"
 
-#define ATAO_SIZE 0x20
-
-#define ATAO_2_DMATCCLR                0x00    /* W 16 */
-#define ATAO_DIN               0x00    /* R 16 */
-#define ATAO_DOUT              0x00    /* W 16 */
-
-#define ATAO_CFG2              0x02    /* W 16 */
-#define CALLD1 0x8000
-#define CALLD0 0x4000
-#define FFRTEN 0x2000
-#define DAC2S8 0x1000
-#define DAC2S6 0x0800
-#define DAC2S4 0x0400
-#define DAC2S2 0x0200
-#define DAC2S0 0x0100
-#define LDAC8          0x0080
-#define LDAC6          0x0040
-#define LDAC4          0x0020
-#define LDAC2          0x0010
-#define LDAC0          0x0008
-#define PROMEN 0x0004
-#define SCLK           0x0002
-#define SDATA          0x0001
-
-#define ATAO_2_INT1CLR         0x02    /* W 16 */
-
-#define ATAO_CFG3              0x04    /* W 16 */
-#define DMAMODE        0x0040
-#define CLKOUT 0x0020
-#define RCLKEN 0x0010
-#define DOUTEN2        0x0008
-#define DOUTEN1        0x0004
-#define EN2_5V 0x0002
-#define SCANEN 0x0001
-
-#define ATAO_2_INT2CLR         0x04    /* W 16 */
-
-#define ATAO_82C53_BASE                0x06    /* RW 8 */
-
-#define ATAO_82C53_CNTR1       0x06    /* RW 8 */
-#define ATAO_82C53_CNTR2       0x07    /* RW 8 */
-#define ATAO_82C53_CNTR3       0x08    /* RW 8 */
-#define ATAO_82C53_CNTRCMD     0x09    /* W 8 */
-#define CNTRSEL1       0x80
-#define CNTRSEL0       0x40
-#define RWSEL1 0x20
-#define RWSEL0 0x10
-#define MODESEL2       0x08
-#define MODESEL1       0x04
-#define MODESEL0       0x02
-#define BCDSEL 0x01
-  /* read-back command */
-#define COUNT          0x20
-#define STATUS 0x10
-#define CNTR3          0x08
-#define CNTR2          0x04
-#define CNTR1          0x02
-  /* status */
-#define OUT            0x80
-#define _NULL          0x40
-#define RW1            0x20
-#define RW0            0x10
-#define MODE2          0x08
-#define MODE1          0x04
-#define MODE0          0x02
-#define BCD            0x01
-
-#define ATAO_2_RTSISHFT                0x06    /* W 8 */
-#define RSI            0x01
-
-#define ATAO_2_RTSISTRB                0x07    /* W 8 */
-
-#define ATAO_CFG1              0x0a    /* W 16 */
-#define EXTINT2EN      0x8000
-#define EXTINT1EN      0x4000
-#define CNTINT2EN      0x2000
-#define CNTINT1EN      0x1000
-#define TCINTEN        0x0800
-#define CNT1SRC        0x0400
-#define CNT2SRC        0x0200
-#define FIFOEN 0x0100
-#define GRP2WR 0x0080
-#define EXTUPDEN       0x0040
-#define DMARQ          0x0020
-#define DMAEN          0x0010
-#define CH_mask        0x000f
-#define ATAO_STATUS            0x0a    /* R 16 */
-#define FH             0x0040
-#define FE             0x0020
-#define FF             0x0010
-#define INT2           0x0008
-#define INT1           0x0004
-#define TCINT          0x0002
-#define PROMOUT        0x0001
-
-#define ATAO_FIFO_WRITE                0x0c    /* W 16 */
-#define ATAO_FIFO_CLEAR                0x0c    /* R 16 */
-#define ATAO_DACn(x)           (0x0c + 2*(x))  /* W */
+#include "8253.h"
 
 /*
- * Board descriptions for two imaginary boards.  Describing the
- * boards in this way is optional, and completely driver-dependent.
- * Some drivers use arrays such as this, other do not.
+ * Register map
+ *
+ * Register-level programming information can be found in NI
+ * document 320379.pdf.
  */
+#define ATAO_DIO_REG           0x00
+#define ATAO_CFG2_REG          0x02
+#define ATAO_CFG2_CALLD_NOP    (0 << 14)
+#define ATAO_CFG2_CALLD(x)     ((((x) >> 3) + 1) << 14)
+#define ATAO_CFG2_FFRTEN       (1 << 13)
+#define ATAO_CFG2_DACS(x)      (1 << (((x) / 2) + 8))
+#define ATAO_CFG2_LDAC(x)      (1 << (((x) / 2) + 3))
+#define ATAO_CFG2_PROMEN       (1 << 2)
+#define ATAO_CFG2_SCLK         (1 << 1)
+#define ATAO_CFG2_SDATA                (1 << 0)
+#define ATAO_CFG3_REG          0x04
+#define ATAO_CFG3_DMAMODE      (1 << 6)
+#define ATAO_CFG3_CLKOUT       (1 << 5)
+#define ATAO_CFG3_RCLKEN       (1 << 4)
+#define ATAO_CFG3_DOUTEN2      (1 << 3)
+#define ATAO_CFG3_DOUTEN1      (1 << 2)
+#define ATAO_CFG3_EN2_5V       (1 << 1)
+#define ATAO_CFG3_SCANEN       (1 << 0)
+#define ATAO_82C53_BASE                0x06
+#define ATAO_CFG1_REG          0x0a
+#define ATAO_CFG1_EXTINT2EN    (1 << 15)
+#define ATAO_CFG1_EXTINT1EN    (1 << 14)
+#define ATAO_CFG1_CNTINT2EN    (1 << 13)
+#define ATAO_CFG1_CNTINT1EN    (1 << 12)
+#define ATAO_CFG1_TCINTEN      (1 << 11)
+#define ATAO_CFG1_CNT1SRC      (1 << 10)
+#define ATAO_CFG1_CNT2SRC      (1 << 9)
+#define ATAO_CFG1_FIFOEN       (1 << 8)
+#define ATAO_CFG1_GRP2WR       (1 << 7)
+#define ATAO_CFG1_EXTUPDEN     (1 << 6)
+#define ATAO_CFG1_DMARQ                (1 << 5)
+#define ATAO_CFG1_DMAEN                (1 << 4)
+#define ATAO_CFG1_CH(x)                (((x) & 0xf) << 0)
+#define ATAO_STATUS_REG                0x0a
+#define ATAO_STATUS_FH         (1 << 6)
+#define ATAO_STATUS_FE         (1 << 5)
+#define ATAO_STATUS_FF         (1 << 4)
+#define ATAO_STATUS_INT2       (1 << 3)
+#define ATAO_STATUS_INT1       (1 << 2)
+#define ATAO_STATUS_TCINT      (1 << 1)
+#define ATAO_STATUS_PROMOUT    (1 << 0)
+#define ATAO_FIFO_WRITE_REG    0x0c
+#define ATAO_FIFO_CLEAR_REG    0x0c
+#define ATAO_AO_REG(x)         (0x0c + ((x) * 2))
+
+/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+#define ATAO_2_DMATCCLR_REG    0x00
+#define ATAO_2_INT1CLR_REG     0x02
+#define ATAO_2_INT2CLR_REG     0x04
+#define ATAO_2_RTSISHFT_REG    0x06
+#define ATAO_2_RTSISHFT_RSI    (1 << 0)
+#define ATAO_2_RTSISTRB_REG    0x07
+
 struct atao_board {
        const char *name;
        int n_ao_chans;
 };
 
-struct atao_private {
+static const struct atao_board atao_boards[] = {
+       {
+               .name           = "at-ao-6",
+               .n_ao_chans     = 6,
+       }, {
+               .name           = "at-ao-10",
+               .n_ao_chans     = 10,
+       },
+};
 
+struct atao_private {
        unsigned short cfg1;
-       unsigned short cfg2;
        unsigned short cfg3;
 
        /* Used for AO readback */
        unsigned int ao_readback[10];
+
+       /* Used for caldac readback */
+       unsigned char caldac[21];
 };
 
-static void atao_reset(struct comedi_device *dev)
+static void atao_select_reg_group(struct comedi_device *dev, int group)
 {
        struct atao_private *devpriv = dev->private;
 
-       /* This is the reset sequence described in the manual */
-
-       devpriv->cfg1 = 0;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-
-       outb(RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
-       outb(0x03, dev->iobase + ATAO_82C53_CNTR1);
-       outb(CNTRSEL0 | RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
-
-       devpriv->cfg2 = 0;
-       outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
-
-       devpriv->cfg3 = 0;
-       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
-
-       inw(dev->iobase + ATAO_FIFO_CLEAR);
-
-       devpriv->cfg1 |= GRP2WR;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-
-       outw(0, dev->iobase + ATAO_2_INT1CLR);
-       outw(0, dev->iobase + ATAO_2_INT2CLR);
-       outw(0, dev->iobase + ATAO_2_DMATCCLR);
-
-       devpriv->cfg1 &= ~GRP2WR;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+       if (group)
+               devpriv->cfg1 |= ATAO_CFG1_GRP2WR;
+       else
+               devpriv->cfg1 &= ~ATAO_CFG1_GRP2WR;
+       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
 }
 
-static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-                        struct comedi_insn *insn, unsigned int *data)
+static int atao_ao_insn_write(struct comedi_device *dev,
+                             struct comedi_subdevice *s,
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
        struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val;
        int i;
-       int chan = CR_CHAN(insn->chanspec);
-       short bits;
+
+       if (chan == 0)
+               atao_select_reg_group(dev, 1);
 
        for (i = 0; i < insn->n; i++) {
-               bits = data[i] - 0x800;
-               if (chan == 0) {
-                       devpriv->cfg1 |= GRP2WR;
-                       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-               }
-               outw(bits, dev->iobase + ATAO_DACn(chan));
-               if (chan == 0) {
-                       devpriv->cfg1 &= ~GRP2WR;
-                       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-               }
-               devpriv->ao_readback[chan] = data[i];
+               val = data[i];
+               devpriv->ao_readback[chan] = val;
+
+               /* munge offset binary (unsigned) to two's complement */
+               val = comedi_offset_munge(s, val);
+               outw(val, dev->iobase + ATAO_AO_REG(chan));
        }
 
-       return i;
+       if (chan == 0)
+               atao_select_reg_group(dev, 0);
+
+       return insn->n;
 }
 
-static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-                        struct comedi_insn *insn, unsigned int *data)
+static int atao_ao_insn_read(struct comedi_device *dev,
+                            struct comedi_subdevice *s,
+                            struct comedi_insn *insn,
+                            unsigned int *data)
 {
        struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
-       int chan = CR_CHAN(insn->chanspec);
 
        for (i = 0; i < insn->n; i++)
                data[i] = devpriv->ao_readback[chan];
 
-       return i;
+       return insn->n;
 }
 
 static int atao_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               outw(s->state, dev->iobase + ATAO_DOUT);
-       }
+       if (comedi_dio_update_state(s, data))
+               outw(s->state, dev->iobase + ATAO_DIO_REG);
 
-       data[1] = inw(dev->iobase + ATAO_DIN);
+       data[1] = inw(dev->iobase + ATAO_DIO_REG);
 
        return insn->n;
 }
@@ -266,57 +212,128 @@ static int atao_dio_insn_config(struct comedi_device *dev,
                return ret;
 
        if (s->io_bits & 0x0f)
-               devpriv->cfg3 |= DOUTEN1;
+               devpriv->cfg3 |= ATAO_CFG3_DOUTEN1;
        else
-               devpriv->cfg3 &= ~DOUTEN1;
+               devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN1;
        if (s->io_bits & 0xf0)
-               devpriv->cfg3 |= DOUTEN2;
+               devpriv->cfg3 |= ATAO_CFG3_DOUTEN2;
        else
-               devpriv->cfg3 &= ~DOUTEN2;
+               devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN2;
 
-       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
 
        return insn->n;
 }
 
 /*
- * Figure 2-1 in the manual shows 3 chips labeled DAC8800, which
- * are 8-channel 8-bit DACs.  These are most likely the calibration
- * DACs.  It is not explicitly stated in the manual how to access
- * the caldacs, but we can guess.
+ * There are three DAC8800 TrimDACs on the board. These are 8-channel,
+ * 8-bit DACs that are used to calibrate the Analog Output channels.
+ * The factory default calibration values are stored in the EEPROM.
+ * The TrimDACs, and EEPROM addresses, are mapped as:
+ *
+ *        Channel       EEPROM  Description
+ *   -----------------  ------  -----------------------------------
+ *    0 - DAC0 Chan 0    0x30   AO Channel 0 Offset
+ *    1 - DAC0 Chan 1    0x31   AO Channel 0 Gain
+ *    2 - DAC0 Chan 2    0x32   AO Channel 1 Offset
+ *    3 - DAC0 Chan 3    0x33   AO Channel 1 Gain
+ *    4 - DAC0 Chan 4    0x34   AO Channel 2 Offset
+ *    5 - DAC0 Chan 5    0x35   AO Channel 2 Gain
+ *    6 - DAC0 Chan 6    0x36   AO Channel 3 Offset
+ *    7 - DAC0 Chan 7    0x37   AO Channel 3 Gain
+ *    8 - DAC1 Chan 0    0x38   AO Channel 4 Offset
+ *    9 - DAC1 Chan 1    0x39   AO Channel 4 Gain
+ *   10 - DAC1 Chan 2    0x3a   AO Channel 5 Offset
+ *   11 - DAC1 Chan 3    0x3b   AO Channel 5 Gain
+ *   12 - DAC1 Chan 4    0x3c   2.5V Offset
+ *   13 - DAC1 Chan 5    0x3d   AO Channel 6 Offset (at-ao-10 only)
+ *   14 - DAC1 Chan 6    0x3e   AO Channel 6 Gain   (at-ao-10 only)
+ *   15 - DAC1 Chan 7    0x3f   AO Channel 7 Offset (at-ao-10 only)
+ *   16 - DAC2 Chan 0    0x40   AO Channel 7 Gain   (at-ao-10 only)
+ *   17 - DAC2 Chan 1    0x41   AO Channel 8 Offset (at-ao-10 only)
+ *   18 - DAC2 Chan 2    0x42   AO Channel 8 Gain   (at-ao-10 only)
+ *   19 - DAC2 Chan 3    0x43   AO Channel 9 Offset (at-ao-10 only)
+ *   20 - DAC2 Chan 4    0x44   AO Channel 9 Gain   (at-ao-10 only)
+ *        DAC2 Chan 5    0x45   Reserved
+ *        DAC2 Chan 6    0x46   Reserved
+ *        DAC2 Chan 7    0x47   Reserved
  */
+static int atao_calib_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int bitstring;
+       unsigned int val;
+       int bit;
+
+       if (insn->n == 0)
+               return 0;
+
+       devpriv->caldac[chan] = data[insn->n - 1] & s->maxdata;
+
+       /* write the channel and last data value to the caldac */
+       bitstring = ((chan & 0x7) << 8) | devpriv->caldac[chan];
+
+       /* clock the bitstring to the caldac; MSB -> LSB */
+       for (bit = 1 << 10; bit; bit >>= 1) {
+               val = (bit & bitstring) ? ATAO_CFG2_SDATA : 0;
+
+               outw(val, dev->iobase + ATAO_CFG2_REG);
+               outw(val | ATAO_CFG2_SCLK, dev->iobase + ATAO_CFG2_REG);
+       }
+
+       /* strobe the caldac to load the value */
+       outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG);
+       outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
+
+       return insn->n;
+}
+
 static int atao_calib_insn_read(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
+       struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
+
        for (i = 0; i < insn->n; i++)
-               data[i] = 0;    /* XXX */
+               data[i] = devpriv->caldac[chan];
+
        return insn->n;
 }
 
-static int atao_calib_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+static void atao_reset(struct comedi_device *dev)
 {
        struct atao_private *devpriv = dev->private;
-       unsigned int bitstring, bit;
-       unsigned int chan = CR_CHAN(insn->chanspec);
 
-       bitstring = ((chan & 0x7) << 8) | (data[insn->n - 1] & 0xff);
+       /* This is the reset sequence described in the manual */
 
-       for (bit = 1 << (11 - 1); bit; bit >>= 1) {
-               outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
-                    dev->iobase + ATAO_CFG2);
-               outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
-                    dev->iobase + ATAO_CFG2);
-       }
-       /* strobe the appropriate caldac */
-       outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
-            dev->iobase + ATAO_CFG2);
-       outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+       devpriv->cfg1 = 0;
+       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
 
-       return insn->n;
+       /* Put outputs of counter 1 and counter 2 in a high state */
+       i8254_load(dev->iobase + ATAO_82C53_BASE, 0,
+                  0, 0x0003, I8254_MODE4 | I8254_BINARY);
+       i8254_set_mode(dev->iobase + ATAO_82C53_BASE, 0,
+                  1, I8254_MODE4 | I8254_BINARY);
+
+       outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
+
+       devpriv->cfg3 = 0;
+       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
+
+       inw(dev->iobase + ATAO_FIFO_CLEAR_REG);
+
+       atao_select_reg_group(dev, 1);
+       outw(0, dev->iobase + ATAO_2_INT1CLR_REG);
+       outw(0, dev->iobase + ATAO_2_INT2CLR_REG);
+       outw(0, dev->iobase + ATAO_2_DMATCCLR_REG);
+       atao_select_reg_group(dev, 0);
 }
 
 static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -324,12 +341,9 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        const struct atao_board *board = comedi_board(dev);
        struct atao_private *devpriv;
        struct comedi_subdevice *s;
-       int ao_unipolar;
        int ret;
 
-       ao_unipolar = it->options[3];
-
-       ret = comedi_request_region(dev, it->options[0], ATAO_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x20);
        if (ret)
                return ret;
 
@@ -341,60 +355,44 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (ret)
                return ret;
 
+       /* Analog Output subdevice */
        s = &dev->subdevices[0];
-       /* analog output subdevice */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = board->n_ao_chans;
-       s->maxdata = (1 << 12) - 1;
-       if (ao_unipolar)
-               s->range_table = &range_unipolar10;
-       else
-               s->range_table = &range_bipolar10;
-       s->insn_write = &atao_ao_winsn;
-       s->insn_read = &atao_ao_rinsn;
-
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = board->n_ao_chans;
+       s->maxdata      = 0x0fff;
+       s->range_table  = it->options[3] ? &range_unipolar10 : &range_bipolar10;
+       s->insn_write   = atao_ao_insn_write;
+       s->insn_read    = atao_ao_insn_read;
+
+       /* Digital I/O subdevice */
        s = &dev->subdevices[1];
-       /* digital i/o subdevice */
-       s->type = COMEDI_SUBD_DIO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 8;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = atao_dio_insn_bits;
-       s->insn_config = atao_dio_insn_config;
+       s->type         = COMEDI_SUBD_DIO;
+       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+       s->n_chan       = 8;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = atao_dio_insn_bits;
+       s->insn_config  = atao_dio_insn_config;
 
-       s = &dev->subdevices[2];
        /* caldac subdevice */
-       s->type = COMEDI_SUBD_CALIB;
-       s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
-       s->n_chan = 21;
-       s->maxdata = 0xff;
-       s->insn_read = atao_calib_insn_read;
-       s->insn_write = atao_calib_insn_write;
-
+       s = &dev->subdevices[2];
+       s->type         = COMEDI_SUBD_CALIB;
+       s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+       s->n_chan       = (board->n_ao_chans * 2) + 1;
+       s->maxdata      = 0xff;
+       s->insn_read    = atao_calib_insn_read;
+       s->insn_write   = atao_calib_insn_write;
+
+       /* EEPROM subdevice */
        s = &dev->subdevices[3];
-       /* eeprom subdevice */
-       /* s->type=COMEDI_SUBD_EEPROM; */
-       s->type = COMEDI_SUBD_UNUSED;
+       s->type         = COMEDI_SUBD_UNUSED;
 
        atao_reset(dev);
 
-       printk(KERN_INFO "\n");
-
        return 0;
 }
 
-static const struct atao_board atao_boards[] = {
-       {
-               .name           = "ai-ao-6",
-               .n_ao_chans     = 6,
-       }, {
-               .name           = "ai-ao-10",
-               .n_ao_chans     = 10,
-       },
-};
-
 static struct comedi_driver ni_at_ao_driver = {
        .driver_name    = "ni_at_ao",
        .module         = THIS_MODULE,
@@ -407,5 +405,5 @@ static struct comedi_driver ni_at_ao_driver = {
 module_comedi_driver(ni_at_ao_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for NI AT-AO-6/10 boards");
 MODULE_LICENSE("GPL");
index bb3491f5ad21c993c916ab827cfe74dffa05ad41..a9f7d40d6db24ed32f8efcd07bef5e4ce94160f6 100644 (file)
@@ -558,13 +558,12 @@ static int atmio16d_ao_insn_write(struct comedi_device *dev,
 
 static int atmio16d_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] | data[1]);
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
-       }
+
        data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
 
        return insn->n;
index 404f83de276da21bd00cb4d17c7b87eb9fd9743d..e4cdca349157f89ab12ccf543c849769c9785dfd 100644 (file)
@@ -72,18 +72,22 @@ Manuals:    Register level: http://www.ni.com/pdf/manuals/340698.pdf
 
 static int daq700_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       unsigned int mask;
+       unsigned int val;
 
-               if (data[0] & 0xff)
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0xff)
                        outb(s->state & 0xff, dev->iobase + DIO_W);
        }
 
-       data[1] = s->state & 0xff;
-       data[1] |= inb(dev->iobase + DIO_R) << 8;
+       val = s->state & 0xff;
+       val |= inb(dev->iobase + DIO_R) << 8;
+
+       data[1] = val;
 
        return insn->n;
 }
@@ -212,7 +216,6 @@ static int daq700_auto_attach(struct comedi_device *dev,
        s->maxdata      = 1;
        s->insn_bits    = daq700_dio_insn_bits;
        s->insn_config  = daq700_dio_insn_config;
-       s->state        = 0;
        s->io_bits      = 0x00ff;
 
        /* DAQCard-700 ai */
index 1add114dc0bc9d5b490d169a88e69c63f86106e6..0512445df08eb0d601bbb9f49a0f959aa2033bf5 100644 (file)
@@ -73,7 +73,6 @@
 #include "ni_labpc_isadma.h"
 
 #define LABPC_SIZE             0x20    /* size of ISA io region */
-#define LABPC_TIMER_BASE       500     /* 2 MHz master clock */
 #define LABPC_ADC_TIMEOUT      1000
 
 enum scan_mode {
@@ -201,12 +200,6 @@ static int labpc_counter_set_mode(struct comedi_device *dev,
                return i8254_set_mode(base_address, 0, counter_number, mode);
 }
 
-static bool labpc_range_is_unipolar(struct comedi_subdevice *s,
-                                   unsigned int range)
-{
-       return s->range_table->range[range].min >= 0;
-}
-
 static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct labpc_private *devpriv = dev->private;
@@ -272,7 +265,7 @@ static void labpc_setup_cmd6_reg(struct comedi_device *dev,
                devpriv->cmd6 &= ~CMD6_NRSE;
 
        /* bipolar or unipolar range? */
-       if (labpc_range_is_unipolar(s, range))
+       if (comedi_range_is_unipolar(s, range))
                devpriv->cmd6 |= CMD6_ADCUNI;
        else
                devpriv->cmd6 &= ~CMD6_ADCUNI;
@@ -465,13 +458,13 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
                 * clock speed on convert and scan counters)
                 */
                devpriv->divisor_b0 = (scan_period - 1) /
-                   (LABPC_TIMER_BASE * max_counter_value) + 1;
+                   (I8254_OSC_BASE_2MHZ * max_counter_value) + 1;
                if (devpriv->divisor_b0 < min_counter_value)
                        devpriv->divisor_b0 = min_counter_value;
                if (devpriv->divisor_b0 > max_counter_value)
                        devpriv->divisor_b0 = max_counter_value;
 
-               base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
+               base_period = I8254_OSC_BASE_2MHZ * devpriv->divisor_b0;
 
                /*  set a0 for conversion frequency and b1 for scan frequency */
                switch (cmd->flags & TRIG_ROUND_MASK) {
@@ -516,22 +509,20 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
                 * calculate cascaded counter values
                 * that give desired scan timing
                 */
-               i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
-                                              &(devpriv->divisor_b1),
-                                              &(devpriv->divisor_b0),
-                                              &scan_period,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &devpriv->divisor_b1,
+                                         &devpriv->divisor_b0,
+                                         &scan_period, cmd->flags);
                labpc_set_ai_scan_period(cmd, mode, scan_period);
        } else if (convert_period) {
                /*
                 * calculate cascaded counter values
                 * that give desired conversion timing
                 */
-               i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
-                                              &(devpriv->divisor_a0),
-                                              &(devpriv->divisor_b0),
-                                              &convert_period,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &devpriv->divisor_a0,
+                                         &devpriv->divisor_b0,
+                                         &convert_period, cmd->flags);
                labpc_set_ai_convert_period(cmd, mode, convert_period);
        }
 }
@@ -902,7 +893,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 static int labpc_drain_fifo(struct comedi_device *dev)
 {
        struct labpc_private *devpriv = dev->private;
-       short data;
+       unsigned short data;
        struct comedi_async *async = dev->read_subdev->async;
        const int timeout = 10000;
        unsigned int i;
@@ -1046,7 +1037,7 @@ static int labpc_ao_insn_write(struct comedi_device *dev,
        /* set range */
        if (board->is_labpc1200) {
                range = CR_RANGE(insn->chanspec);
-               if (labpc_range_is_unipolar(s, range))
+               if (comedi_range_is_unipolar(s, range))
                        devpriv->cmd6 |= CMD6_DACUNI(channel);
                else
                        devpriv->cmd6 &= ~CMD6_DACUNI(channel);
index 4e02770e834bd7df20e8f015c92750ba4efb05a1..5113397bfecf4c864a48aeca9ccd7cd7f718b60c 100644 (file)
@@ -1292,7 +1292,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
        struct comedi_cmd *cmd = &async->cmd;
        int chan;
        int i;
-       short d;
+       unsigned short d;
        u32 packed_data;
        int range;
        int err = 1;
@@ -1403,7 +1403,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
        int i;
 
        if (board->reg_type == ni_reg_611x) {
-               short data[2];
+               unsigned short data[2];
                u32 dl;
 
                for (i = 0; i < n / 2; i++) {
@@ -1420,7 +1420,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
                        cfc_write_to_buffer(s, data[0]);
                }
        } else if (board->reg_type == ni_reg_6143) {
-               short data[2];
+               unsigned short data[2];
                u32 dl;
 
                /*  This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */
@@ -1511,9 +1511,9 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-       short data[2];
+       unsigned short data[2];
        u32 dl;
-       short fifo_empty;
+       unsigned short fifo_empty;
        int i;
 
        if (board->reg_type == ni_reg_611x) {
@@ -1577,7 +1577,7 @@ static void get_last_sample_611x(struct comedi_device *dev)
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv __maybe_unused = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-       short data;
+       unsigned short data;
        u32 dl;
 
        if (board->reg_type != ni_reg_611x)
@@ -1596,7 +1596,7 @@ static void get_last_sample_6143(struct comedi_device *dev)
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv __maybe_unused = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-       short data;
+       unsigned short data;
        u32 dl;
 
        if (board->reg_type != ni_reg_6143)
@@ -1621,7 +1621,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
        struct comedi_async *async = s->async;
        unsigned int i;
        unsigned int length = num_bytes / bytes_per_sample(s);
-       short *array = data;
+       unsigned short *array = data;
        unsigned int *larray = data;
 
        for (i = 0; i < length; i++) {
@@ -2873,7 +2873,7 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
        unsigned int i;
        unsigned int offset;
        unsigned int length = num_bytes / sizeof(short);
-       short *array = data;
+       unsigned short *array = data;
 
        offset = 1 << (board->aobits - 1);
        for (i = 0; i < length; i++) {
@@ -3547,28 +3547,22 @@ static int ni_dio_insn_config(struct comedi_device *dev,
 
 static int ni_dio_insn_bits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        struct ni_private *devpriv = dev->private;
 
-#ifdef DEBUG_DIO
-       printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
-#endif
-
-       if (data[0]) {
-               /* Perform check to make sure we're not using the
-                  serial part of the dio */
-               if ((data[0] & (DIO_SDIN | DIO_SDOUT))
-                   && devpriv->serial_interval_ns)
-                       return -EBUSY;
+       /* Make sure we're not using the serial part of the dio */
+       if ((data[0] & (DIO_SDIN | DIO_SDOUT)) && devpriv->serial_interval_ns)
+               return -EBUSY;
 
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
                devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
                devpriv->stc_writew(dev, devpriv->dio_output,
                                    DIO_Output_Register);
        }
+
        data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
 
        return insn->n;
@@ -3598,16 +3592,9 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
 {
        struct ni_private *devpriv __maybe_unused = dev->private;
 
-#ifdef DEBUG_DIO
-       printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
-              data[1]);
-#endif
-
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                ni_writel(s->state, M_Offset_Static_Digital_Output);
-       }
+
        data[1] = ni_readl(M_Offset_Static_Digital_Input);
 
        return insn->n;
@@ -5355,20 +5342,20 @@ static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
 
 static int ni_pfi_insn_bits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv __maybe_unused = dev->private;
 
-       if ((board->reg_type & ni_reg_m_series_mask) == 0) {
+       if (!(board->reg_type & ni_reg_m_series_mask))
                return -ENOTSUPP;
-       }
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+
+       if (comedi_dio_update_state(s, data))
                ni_writew(s->state, M_Offset_PFI_DO);
-       }
+
        data[1] = ni_readw(M_Offset_PFI_DI);
+
        return insn->n;
 }
 
index fad81bc97b6e090d87b1391349bf4c8ad3a4dcd9..e3a8fa96d9b398fa13c8e8f564967393d20e1d5c 100644 (file)
@@ -406,9 +406,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
        struct mite_struct *mite = devpriv->mite;
 
        /* int i, j; */
-       long int AuxData = 0;
-       short data1 = 0;
-       short data2 = 0;
+       unsigned int auxdata = 0;
+       unsigned short data1 = 0;
+       unsigned short data2 = 0;
        int flags;
        int status;
        int work = 0;
@@ -481,11 +481,11 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                                              );
                                        goto out;
                                }
-                               AuxData =
+                               auxdata =
                                    readl(devpriv->mite->daq_io_addr +
                                          Group_1_FIFO);
-                               data1 = AuxData & 0xffff;
-                               data2 = (AuxData & 0xffff0000) >> 16;
+                               data1 = auxdata & 0xffff;
+                               data2 = (auxdata & 0xffff0000) >> 16;
                                comedi_buf_put(async, data1);
                                comedi_buf_put(async, data2);
                                /* DPRINTK("read:%d, %d\n",data1,data2); */
@@ -657,15 +657,14 @@ static int ni_pcidio_insn_config(struct comedi_device *dev,
 
 static int ni_pcidio_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct nidio96_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
-       }
+
        data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
 
        return insn->n;
index 11bf0aab82ea98528f26d436e4a4c6bf4472ec4e..f0630b7897b507171cb56d1ea09f7645521ca5e4 100644 (file)
@@ -1491,7 +1491,7 @@ struct ni_board_struct {
        unsigned short pwm_up_count;    \
        unsigned short pwm_down_count;  \
        \
-       short ai_fifo_buffer[0x2000];                           \
+       unsigned short ai_fifo_buffer[0x2000];                  \
        uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
        uint32_t serial_number; \
        \
index e859f85a8e17c1b39ac7300f7ded90f250da1d22..f0fc123ef56603994e8338e67884283388cc80e4 100644 (file)
 /*
  comedi/drivers/pcl711.c
-   hardware driver for PC-LabCard PCL-711 and AdSys ACL-8112
-   and compatibles
-
-   COMEDI - Linux Control and Measurement Device Interface
-   Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-   Janne Jalkanen <jalkanen@cs.hut.fi>
  Eric Bunn <ebu@cs.hut.fi>
-
  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.
pcl711.c
+ * Comedi driver for PC-LabCard PCL-711 and AdSys ACL-8112 and compatibles
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *                   Janne Jalkanen <jalkanen@cs.hut.fi>
+ *                   Eric Bunn <ebu@cs.hut.fi>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+ *
* 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.
  */
-/*
-Driver: pcl711
-Description: Advantech PCL-711 and 711b, ADLink ACL-8112
-Author: ds, Janne Jalkanen <jalkanen@cs.hut.fi>, Eric Bunn <ebu@cs.hut.fi>
-Status: mostly complete
-Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
-  [AdLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
-
-Since these boards do not have DMA or FIFOs, only immediate mode is
-supported.
-
-*/
 
 /*
-   Dave Andruczyk <dave@tech.buffalostate.edu> also wrote a
-   driver for the PCL-711.  I used a few ideas from his driver
-   here.  His driver also has more comments, if you are
-   interested in understanding how this driver works.
-   http://tech.buffalostate.edu/~dave/driver/
-
-   The ACL-8112 driver was hacked from the sources of the PCL-711
-   driver (the 744 chip used on the 8112 is almost the same as
-   the 711b chip, but it has more I/O channels) by
-   Janne Jalkanen (jalkanen@cs.hut.fi) and
-   Erik Bunn (ebu@cs.hut.fi).  Remerged with the PCL-711 driver
-   by ds.
-
-   [acl-8112]
-   This driver supports both TRIGNOW and TRIGCLK,
-   but does not yet support DMA transfers.  It also supports
-   both high (HG) and low (DG) versions of the card, though
-   the HG version has been untested.
-
+ * Driver: pcl711
+ * Description: Advantech PCL-711 and 711b, ADLink ACL-8112
+ * Devices: (Advantech) PCL-711 [pcl711]
+ *         (Advantech) PCL-711B [pcl711b]
+ *         (AdLink) ACL-8112HG [acl8112hg]
+ *         (AdLink) ACL-8112DG [acl8112dg]
+ * Author: David A. Schleef <ds@schleef.org>
+ *        Janne Jalkanen <jalkanen@cs.hut.fi>
+ *        Eric Bunn <ebu@cs.hut.fi>
+ * Updated:
+ * Status: mostly complete
+ *
+ * Configuration Options:
+ *   [0] - I/O port base
+ *   [1] - IRQ, optional
  */
 
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include "../comedidev.h"
 
-#include <linux/delay.h>
+#include "../comedidev.h"
 
 #include "comedi_fc.h"
 #include "8253.h"
 
-#define PCL711_SIZE 16
-
-#define PCL711_CTR0 0
-#define PCL711_CTR1 1
-#define PCL711_CTR2 2
-#define PCL711_CTRCTL 3
-#define PCL711_AD_LO 4
-#define PCL711_DA0_LO 4
-#define PCL711_AD_HI 5
-#define PCL711_DA0_HI 5
-#define PCL711_DI_LO 6
-#define PCL711_DA1_LO 6
-#define PCL711_DI_HI 7
-#define PCL711_DA1_HI 7
-#define PCL711_CLRINTR 8
-#define PCL711_GAIN 9
-#define PCL711_MUX 10
-#define PCL711_MODE 11
-#define PCL711_SOFTTRIG 12
-#define PCL711_DO_LO 13
-#define PCL711_DO_HI 14
-
-static const struct comedi_lrange range_pcl711b_ai = { 5, {
-                                                          BIP_RANGE(5),
-                                                          BIP_RANGE(2.5),
-                                                          BIP_RANGE(1.25),
-                                                          BIP_RANGE(0.625),
-                                                          BIP_RANGE(0.3125)
-                                                          }
+/*
+ * I/O port register map
+ */
+#define PCL711_TIMER_BASE      0x00
+#define PCL711_AI_LSB_REG      0x04
+#define PCL711_AI_MSB_REG      0x05
+#define PCL711_AI_MSB_DRDY     (1 << 4)
+#define PCL711_AO_LSB_REG(x)   (0x04 + ((x) * 2))
+#define PCL711_AO_MSB_REG(x)   (0x05 + ((x) * 2))
+#define PCL711_DI_LSB_REG      0x06
+#define PCL711_DI_MSB_REG      0x07
+#define PCL711_INT_STAT_REG    0x08
+#define PCL711_INT_STAT_CLR    (0 << 0)  /* any value will work */
+#define PCL711_AI_GAIN_REG     0x09
+#define PCL711_AI_GAIN(x)      (((x) & 0xf) << 0)
+#define PCL711_MUX_REG         0x0a
+#define PCL711_MUX_CHAN(x)     (((x) & 0xf) << 0)
+#define PCL711_MUX_CS0         (1 << 4)
+#define PCL711_MUX_CS1         (1 << 5)
+#define PCL711_MUX_DIFF                (PCL711_MUX_CS0 | PCL711_MUX_CS1)
+#define PCL711_MODE_REG                0x0b
+#define PCL711_MODE_DEFAULT    (0 << 0)
+#define PCL711_MODE_SOFTTRIG   (1 << 0)
+#define PCL711_MODE_EXT                (2 << 0)
+#define PCL711_MODE_EXT_IRQ    (3 << 0)
+#define PCL711_MODE_PACER      (4 << 0)
+#define PCL711_MODE_PACER_IRQ  (6 << 0)
+#define PCL711_MODE_IRQ(x)     (((x) & 0x7) << 4)
+#define PCL711_SOFTTRIG_REG    0x0c
+#define PCL711_SOFTTRIG                (0 << 0)  /* any value will work */
+#define PCL711_DO_LSB_REG      0x0d
+#define PCL711_DO_MSB_REG      0x0e
+
+static const struct comedi_lrange range_pcl711b_ai = {
+       5, {
+               BIP_RANGE(5),
+               BIP_RANGE(2.5),
+               BIP_RANGE(1.25),
+               BIP_RANGE(0.625),
+               BIP_RANGE(0.3125)
+       }
 };
 
-static const struct comedi_lrange range_acl8112hg_ai = { 12, {
-                                                             BIP_RANGE(5),
-                                                             BIP_RANGE(0.5),
-                                                             BIP_RANGE(0.05),
-                                                             BIP_RANGE(0.005),
-                                                             UNI_RANGE(10),
-                                                             UNI_RANGE(1),
-                                                             UNI_RANGE(0.1),
-                                                             UNI_RANGE(0.01),
-                                                             BIP_RANGE(10),
-                                                             BIP_RANGE(1),
-                                                             BIP_RANGE(0.1),
-                                                             BIP_RANGE(0.01)
-                                                             }
+static const struct comedi_lrange range_acl8112hg_ai = {
+       12, {
+               BIP_RANGE(5),
+               BIP_RANGE(0.5),
+               BIP_RANGE(0.05),
+               BIP_RANGE(0.005),
+               UNI_RANGE(10),
+               UNI_RANGE(1),
+               UNI_RANGE(0.1),
+               UNI_RANGE(0.01),
+               BIP_RANGE(10),
+               BIP_RANGE(1),
+               BIP_RANGE(0.1),
+               BIP_RANGE(0.01)
+       }
 };
 
-static const struct comedi_lrange range_acl8112dg_ai = { 9, {
-                                                            BIP_RANGE(5),
-                                                            BIP_RANGE(2.5),
-                                                            BIP_RANGE(1.25),
-                                                            BIP_RANGE(0.625),
-                                                            UNI_RANGE(10),
-                                                            UNI_RANGE(5),
-                                                            UNI_RANGE(2.5),
-                                                            UNI_RANGE(1.25),
-                                                            BIP_RANGE(10)
-                                                            }
+static const struct comedi_lrange range_acl8112dg_ai = {
+       9, {
+               BIP_RANGE(5),
+               BIP_RANGE(2.5),
+               BIP_RANGE(1.25),
+               BIP_RANGE(0.625),
+               UNI_RANGE(10),
+               UNI_RANGE(5),
+               UNI_RANGE(2.5),
+               UNI_RANGE(1.25),
+               BIP_RANGE(10)
+       }
 };
 
-/*
- * flags
- */
-
-#define PCL711_TIMEOUT 100
-#define PCL711_DRDY 0x10
-
-static const int i8253_osc_base = 500; /* 2 Mhz */
-
 struct pcl711_board {
-
        const char *name;
-       int is_pcl711b;
-       int is_8112;
-       int is_dg;
-       int n_ranges;
        int n_aichan;
        int n_aochan;
        int maxirq;
        const struct comedi_lrange *ai_range_type;
 };
 
-struct pcl711_private {
+static const struct pcl711_board boardtypes[] = {
+       {
+               .name           = "pcl711",
+               .n_aichan       = 8,
+               .n_aochan       = 1,
+               .ai_range_type  = &range_bipolar5,
+       }, {
+               .name           = "pcl711b",
+               .n_aichan       = 8,
+               .n_aochan       = 1,
+               .maxirq         = 7,
+               .ai_range_type  = &range_pcl711b_ai,
+       }, {
+               .name           = "acl8112hg",
+               .n_aichan       = 16,
+               .n_aochan       = 2,
+               .maxirq         = 15,
+               .ai_range_type  = &range_acl8112hg_ai,
+       }, {
+               .name           = "acl8112dg",
+               .n_aichan       = 16,
+               .n_aochan       = 2,
+               .maxirq         = 15,
+               .ai_range_type  = &range_acl8112dg_ai,
+       },
+};
 
-       int board;
-       int adchan;
-       int ntrig;
-       int aip[8];
-       int mode;
+struct pcl711_private {
+       unsigned int ntrig;
        unsigned int ao_readback[2];
        unsigned int divisor1;
        unsigned int divisor2;
 };
 
+static void pcl711_ai_set_mode(struct comedi_device *dev, unsigned int mode)
+{
+       /*
+        * The pcl711b board uses bits in the mode register to select the
+        * interrupt. The other boards supported by this driver all use
+        * jumpers on the board.
+        *
+        * Enables the interrupt when needed on the pcl711b board. These
+        * bits do nothing on the other boards.
+        */
+       if (mode == PCL711_MODE_EXT_IRQ || mode == PCL711_MODE_PACER_IRQ)
+               mode |= PCL711_MODE_IRQ(dev->irq);
+
+       outb(mode, dev->iobase + PCL711_MODE_REG);
+}
+
+static unsigned int pcl711_ai_get_sample(struct comedi_device *dev,
+                                        struct comedi_subdevice *s)
+{
+       unsigned int val;
+
+       val = inb(dev->iobase + PCL711_AI_MSB_REG) << 8;
+       val |= inb(dev->iobase + PCL711_AI_LSB_REG);
+
+       return val & s->maxdata;
+}
+
+static int pcl711_ai_cancel(struct comedi_device *dev,
+                           struct comedi_subdevice *s)
+{
+       outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
+       pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
+       return 0;
+}
+
 static irqreturn_t pcl711_interrupt(int irq, void *d)
 {
-       int lo, hi;
-       int data;
        struct comedi_device *dev = d;
-       const struct pcl711_board *board = comedi_board(dev);
        struct pcl711_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[0];
+       struct comedi_subdevice *s = dev->read_subdev;
+       unsigned int data;
 
        if (!dev->attached) {
                comedi_error(dev, "spurious interrupt");
                return IRQ_HANDLED;
        }
 
-       hi = inb(dev->iobase + PCL711_AD_HI);
-       lo = inb(dev->iobase + PCL711_AD_LO);
-       outb(0, dev->iobase + PCL711_CLRINTR);
-
-       data = (hi << 8) | lo;
+       data = pcl711_ai_get_sample(dev, s);
 
-       /* FIXME! Nothing else sets ntrig! */
-       if (!(--devpriv->ntrig)) {
-               if (board->is_8112)
-                       outb(1, dev->iobase + PCL711_MODE);
-               else
-                       outb(0, dev->iobase + PCL711_MODE);
+       outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
 
-               s->async->events |= COMEDI_CB_EOA;
+       if (comedi_buf_put(s->async, data) == 0) {
+               s->async->events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+       } else {
+               s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+               if (s->async->cmd.stop_src == TRIG_COUNT &&
+                   !(--devpriv->ntrig)) {
+                       pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
+                       s->async->events |= COMEDI_CB_EOA;
+               }
        }
        comedi_event(dev, s);
        return IRQ_HANDLED;
 }
 
-static void pcl711_set_changain(struct comedi_device *dev, int chan)
+static void pcl711_set_changain(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               unsigned int chanspec)
 {
-       const struct pcl711_board *board = comedi_board(dev);
-       int chan_register;
-
-       outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN);
-
-       chan_register = CR_CHAN(chan);
-
-       if (board->is_8112) {
+       unsigned int chan = CR_CHAN(chanspec);
+       unsigned int range = CR_RANGE(chanspec);
+       unsigned int aref = CR_AREF(chanspec);
+       unsigned int mux = 0;
+
+       outb(PCL711_AI_GAIN(range), dev->iobase + PCL711_AI_GAIN_REG);
+
+       if (s->n_chan > 8) {
+               /* Select the correct MPC508A chip */
+               if (aref == AREF_DIFF) {
+                       chan &= 0x7;
+                       mux |= PCL711_MUX_DIFF;
+               } else {
+                       if (chan < 8)
+                               mux |= PCL711_MUX_CS0;
+                       else
+                               mux |= PCL711_MUX_CS1;
+               }
+       }
+       outb(mux | PCL711_MUX_CHAN(chan), dev->iobase + PCL711_MUX_REG);
+}
 
-               /*
-                *  Set the correct channel.  The two channel banks are switched
-                *  using the mask value.
-                *  NB: To use differential channels, you should use
-                *  mask = 0x30, but I haven't written the support for this
-                *  yet. /JJ
-                */
+static int pcl711_ai_wait_for_eoc(struct comedi_device *dev,
+                                 unsigned int timeout)
+{
+       unsigned int msb;
 
-               if (chan_register >= 8)
-                       chan_register = 0x20 | (chan_register & 0x7);
-               else
-                       chan_register |= 0x10;
-       } else {
-               outb(chan_register, dev->iobase + PCL711_MUX);
+       while (timeout--) {
+               msb = inb(dev->iobase + PCL711_AI_MSB_REG);
+               if ((msb & PCL711_AI_MSB_DRDY) == 0)
+                       return 0;
+               udelay(1);
        }
+       return -ETIME;
 }
 
-static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int pcl711_ai_insn_read(struct comedi_device *dev,
+                              struct comedi_subdevice *s,
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       const struct pcl711_board *board = comedi_board(dev);
-       int i, n;
-       int hi, lo;
-
-       pcl711_set_changain(dev, insn->chanspec);
-
-       for (n = 0; n < insn->n; n++) {
-               /*
-                *  Write the correct mode (software polling) and start polling
-                *  by writing to the trigger register
-                */
-               outb(1, dev->iobase + PCL711_MODE);
-
-               if (!board->is_8112)
-                       outb(0, dev->iobase + PCL711_SOFTTRIG);
-
-               i = PCL711_TIMEOUT;
-               while (--i) {
-                       hi = inb(dev->iobase + PCL711_AD_HI);
-                       if (!(hi & PCL711_DRDY))
-                               goto ok;
-                       udelay(1);
-               }
-               printk(KERN_ERR "comedi%d: pcl711: A/D timeout\n", dev->minor);
-               return -ETIME;
+       int ret;
+       int i;
+
+       pcl711_set_changain(dev, s, insn->chanspec);
 
-ok:
-               lo = inb(dev->iobase + PCL711_AD_LO);
+       pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
 
-               data[n] = ((hi & 0xf) << 8) | lo;
+       for (i = 0; i < insn->n; i++) {
+               outb(PCL711_SOFTTRIG, dev->iobase + PCL711_SOFTTRIG_REG);
+
+               ret = pcl711_ai_wait_for_eoc(dev, 100);
+               if (ret)
+                       return ret;
+
+               data[i] = pcl711_ai_get_sample(dev, s);
        }
 
-       return n;
+       return insn->n;
 }
 
 static int pcl711_ai_cmdtest(struct comedi_device *dev,
@@ -292,7 +329,6 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
                err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        } else {
 #define MAX_SPEED 1000
-#define TIMER_BASE 100
                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
                                                 MAX_SPEED);
        }
@@ -313,11 +349,11 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->scan_begin_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->scan_begin_arg,
+                                         cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
@@ -331,110 +367,106 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
 static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct pcl711_private *devpriv = dev->private;
-       int timer1, timer2;
        struct comedi_cmd *cmd = &s->async->cmd;
 
-       pcl711_set_changain(dev, cmd->chanlist[0]);
+       pcl711_set_changain(dev, s, cmd->chanlist[0]);
+
+       if (cmd->stop_src == TRIG_COUNT) {
+               if (cmd->stop_arg == 0) {
+                       /* an empty acquisition */
+                       s->async->events |= COMEDI_CB_EOA;
+                       comedi_event(dev, s);
+                       return 0;
+               }
+               devpriv->ntrig = cmd->stop_arg;
+       }
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
-               /*
-                *  Set timers
-                *      timer chip is an 8253, with timers 1 and 2
-                *      cascaded
-                *  0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
-                *        Mode 2 = Rate generator
-                *
-                *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
-                */
-
-               timer1 = timer2 = 0;
-               i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
-                                         &cmd->scan_begin_arg,
-                                         TRIG_ROUND_NEAREST);
-
-               outb(0x74, dev->iobase + PCL711_CTRCTL);
-               outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
-               outb((timer1 >> 8) & 0xff, dev->iobase + PCL711_CTR1);
-               outb(0xb4, dev->iobase + PCL711_CTRCTL);
-               outb(timer2 & 0xff, dev->iobase + PCL711_CTR2);
-               outb((timer2 >> 8) & 0xff, dev->iobase + PCL711_CTR2);
-
-               /* clear pending interrupts (just in case) */
-               outb(0, dev->iobase + PCL711_CLRINTR);
-
-               /*
-                *  Set mode to IRQ transfer
-                */
-               outb(devpriv->mode | 6, dev->iobase + PCL711_MODE);
+               i8254_load(dev->iobase + PCL711_TIMER_BASE, 0,
+                          1, devpriv->divisor1, I8254_MODE2 | I8254_BINARY);
+               i8254_load(dev->iobase + PCL711_TIMER_BASE, 0,
+                          2, devpriv->divisor2, I8254_MODE2 | I8254_BINARY);
+
+               outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
+
+               pcl711_ai_set_mode(dev, PCL711_MODE_PACER_IRQ);
        } else {
-               /* external trigger */
-               outb(devpriv->mode | 3, dev->iobase + PCL711_MODE);
+               pcl711_ai_set_mode(dev, PCL711_MODE_EXT_IRQ);
        }
 
        return 0;
 }
 
-/*
-   analog output
-*/
-static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static void pcl711_ao_write(struct comedi_device *dev,
+                           unsigned int chan, unsigned int val)
 {
-       struct pcl711_private *devpriv = dev->private;
-       int n;
-       int chan = CR_CHAN(insn->chanspec);
+       outb(val & 0xff, dev->iobase + PCL711_AO_LSB_REG(chan));
+       outb((val >> 8) & 0xff, dev->iobase + PCL711_AO_MSB_REG(chan));
+}
 
-       for (n = 0; n < insn->n; n++) {
-               outb((data[n] & 0xff),
-                    dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO));
-               outb((data[n] >> 8),
-                    dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
+static int pcl711_ao_insn_write(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       struct pcl711_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val = devpriv->ao_readback[chan];
+       int i;
 
-               devpriv->ao_readback[chan] = data[n];
+       for (i = 0; i < insn->n; i++) {
+               val = data[i];
+               pcl711_ao_write(dev, chan, val);
        }
+       devpriv->ao_readback[chan] = val;
 
-       return n;
+       return insn->n;
 }
 
 static int pcl711_ao_insn_read(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct pcl711_private *devpriv = dev->private;
-       int n;
-       int chan = CR_CHAN(insn->chanspec);
-
-       for (n = 0; n < insn->n; n++)
-               data[n] = devpriv->ao_readback[chan];
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int i;
 
-       return n;
+       for (i = 0; i < insn->n; i++)
+               data[i] = devpriv->ao_readback[chan];
 
+       return insn->n;
 }
 
-/* Digital port read - Untested on 8112 */
 static int pcl711_di_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       data[1] = inb(dev->iobase + PCL711_DI_LO) |
-           (inb(dev->iobase + PCL711_DI_HI) << 8);
+       unsigned int val;
+
+       val = inb(dev->iobase + PCL711_DI_LSB_REG);
+       val |= (inb(dev->iobase + PCL711_DI_MSB_REG) << 8);
+
+       data[1] = val;
 
        return insn->n;
 }
 
-/* Digital port write - Untested on 8112 */
 static int pcl711_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       unsigned int mask;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0x00ff)
+                       outb(s->state & 0xff, dev->iobase + PCL711_DO_LSB_REG);
+               if (mask & 0xff00)
+                       outb((s->state >> 8), dev->iobase + PCL711_DO_MSB_REG);
        }
-       if (data[0] & 0x00ff)
-               outb(s->state & 0xff, dev->iobase + PCL711_DO_LO);
-       if (data[0] & 0xff00)
-               outb((s->state >> 8), dev->iobase + PCL711_DO_HI);
 
        data[1] = s->state;
 
@@ -445,112 +477,82 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
        const struct pcl711_board *board = comedi_board(dev);
        struct pcl711_private *devpriv;
-       int ret;
-       unsigned int irq;
        struct comedi_subdevice *s;
+       int ret;
+
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
 
-       ret = comedi_request_region(dev, it->options[0], PCL711_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x10);
        if (ret)
                return ret;
 
-       /* grab our IRQ */
-       irq = it->options[1];
-       if (irq > board->maxirq) {
-               printk(KERN_ERR "irq out of range\n");
-               return -EINVAL;
-       }
-       if (irq) {
-               if (request_irq(irq, pcl711_interrupt, 0, dev->board_name,
-                               dev)) {
-                       printk(KERN_ERR "unable to allocate irq %u\n", irq);
-                       return -EINVAL;
-               } else {
-                       printk(KERN_INFO "( irq = %u )\n", irq);
-               }
+       if (it->options[1] && it->options[1] <= board->maxirq) {
+               ret = request_irq(it->options[1], pcl711_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0)
+                       dev->irq = it->options[1];
        }
-       dev->irq = irq;
 
        ret = comedi_alloc_subdevices(dev, 4);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
-               return -ENOMEM;
-
+       /* Analog Input subdevice */
        s = &dev->subdevices[0];
-       /* AI subdevice */
-       s->type = COMEDI_SUBD_AI;
-       s->subdev_flags = SDF_READABLE | SDF_GROUND;
-       s->n_chan = board->n_aichan;
-       s->maxdata = 0xfff;
-       s->len_chanlist = 1;
-       s->range_table = board->ai_range_type;
-       s->insn_read = pcl711_ai_insn;
-       if (irq) {
+       s->type         = COMEDI_SUBD_AI;
+       s->subdev_flags = SDF_READABLE | SDF_GROUND;
+       if (board->n_aichan > 8)
+               s->subdev_flags |= SDF_DIFF;
+       s->n_chan       = board->n_aichan;
+       s->maxdata      = 0xfff;
+       s->range_table  = board->ai_range_type;
+       s->insn_read    = pcl711_ai_insn_read;
+       if (dev->irq) {
                dev->read_subdev = s;
-               s->subdev_flags |= SDF_CMD_READ;
-               s->do_cmdtest = pcl711_ai_cmdtest;
-               s->do_cmd = pcl711_ai_cmd;
+               s->subdev_flags |= SDF_CMD_READ;
+               s->len_chanlist = 1;
+               s->do_cmdtest   = pcl711_ai_cmdtest;
+               s->do_cmd       = pcl711_ai_cmd;
+               s->cancel       = pcl711_ai_cancel;
        }
 
+       /* Analog Output subdevice */
        s = &dev->subdevices[1];
-       /* AO subdevice */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = board->n_aochan;
-       s->maxdata = 0xfff;
-       s->len_chanlist = 1;
-       s->range_table = &range_bipolar5;
-       s->insn_write = pcl711_ao_insn;
-       s->insn_read = pcl711_ao_insn_read;
-
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = board->n_aochan;
+       s->maxdata      = 0xfff;
+       s->range_table  = &range_bipolar5;
+       s->insn_write   = pcl711_ao_insn_write;
+       s->insn_read    = pcl711_ao_insn_read;
+
+       /* Digital Input subdevice */
        s = &dev->subdevices[2];
-       /* 16-bit digital input */
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 16;
-       s->maxdata = 1;
-       s->len_chanlist = 16;
-       s->range_table = &range_digital;
-       s->insn_bits = pcl711_di_insn_bits;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 16;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = pcl711_di_insn_bits;
+
+       /* Digital Output subdevice */
        s = &dev->subdevices[3];
-       /* 16-bit digital out */
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = 16;
-       s->maxdata = 1;
-       s->len_chanlist = 16;
-       s->range_table = &range_digital;
-       s->state = 0;
-       s->insn_bits = pcl711_do_insn_bits;
-
-       /*
-          this is the "base value" for the mode register, which is
-          used for the irq on the PCL711
-        */
-       if (board->is_pcl711b)
-               devpriv->mode = (dev->irq << 4);
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 16;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = pcl711_do_insn_bits;
 
        /* clear DAC */
-       outb(0, dev->iobase + PCL711_DA0_LO);
-       outb(0, dev->iobase + PCL711_DA0_HI);
-       outb(0, dev->iobase + PCL711_DA1_LO);
-       outb(0, dev->iobase + PCL711_DA1_HI);
-
-       printk(KERN_INFO "\n");
+       pcl711_ao_write(dev, 0, 0x0);
+       pcl711_ao_write(dev, 1, 0x0);
 
        return 0;
 }
 
-static const struct pcl711_board boardtypes[] = {
-       { "pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5 },
-       { "pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai },
-       { "acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai },
-       { "acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai },
-};
-
 static struct comedi_driver pcl711_driver = {
        .driver_name    = "pcl711",
        .module         = THIS_MODULE,
@@ -563,5 +565,5 @@ static struct comedi_driver pcl711_driver = {
 module_comedi_driver(pcl711_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for PCL-711 compatible boards");
 MODULE_LICENSE("GPL");
index a4d0bcc31e52df22290fbfb174f08eac5f89f3c5..cf9568ee46e46f2bcb064c5339baebb3c007aa8e 100644 (file)
 /*
-    comedi/drivers/pcl726.c
-
-    hardware driver for Advantech cards:
-     card:   PCL-726, PCL-727, PCL-728
-     driver: pcl726,  pcl727,  pcl728
-    and for ADLink cards:
-     card:   ACL-6126, ACL-6128
-     driver: acl6126,  acl6128
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
-
-    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.
-*/
-/*
-Driver: pcl726
-Description: Advantech PCL-726 & compatibles
-Author: ds
-Status: untested
-Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
-  [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
-
-Interrupts are not supported.
-
-    Options for PCL-726:
-     [0] - IO Base
-     [2]...[7] - D/A output range for channel 1-6:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-               4: 4-20mA, 5: unknown (external reference)
-
-    Options for PCL-727:
-     [0] - IO Base
-     [2]...[13] - D/A output range for channel 1-12:
-               0: 0-5V, 1: 0-10V, 2: +/-5V,
-               3: 4-20mA
-
-    Options for PCL-728 and ACL-6128:
-     [0] - IO Base
-     [2], [3] - D/A output range for channel 1 and 2:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-               4: 4-20mA, 5: 0-20mA
-
-    Options for ACL-6126:
-     [0] - IO Base
-     [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
-     [2]...[7] - D/A output range for channel 1-6:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-               4: 4-20mA
-*/
+ * pcl726.c
+ * Comedi driver for 6/12-Channel D/A Output and DIO cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+ *
+ * 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.
+ */
 
 /*
-    Thanks to Circuit Specialists for having programming info (!) on
-    their web page.  (http://www.cir.com/)
-*/
+ * Driver: pcl726
+ * Description: Advantech PCL-726 & compatibles
+ * Author: David A. Schleef <ds@schleef.org>
+ * Status: untested
+ * Devices: (Advantech) PCL-726 [pcl726]
+ *         (Advantech) PCL-727 [pcl727]
+ *         (Advantech) PCL-728 [pcl728]
+ *         (ADLink) ACL-6126 [acl6126]
+ *         (ADLink) ACL-6128 [acl6128]
+ *
+ * Configuration Options:
+ *   [0]  - IO Base
+ *   [1]  - IRQ (ACL-6126 only)
+ *   [2]  - D/A output range for channel 0
+ *   [3]  - D/A output range for channel 1
+ *
+ * Boards with > 2 analog output channels:
+ *   [4]  - D/A output range for channel 2
+ *   [5]  - D/A output range for channel 3
+ *   [6]  - D/A output range for channel 4
+ *   [7]  - D/A output range for channel 5
+ *
+ * Boards with > 6 analog output channels:
+ *   [8]  - D/A output range for channel 6
+ *   [9]  - D/A output range for channel 7
+ *   [10] - D/A output range for channel 8
+ *   [11] - D/A output range for channel 9
+ *   [12] - D/A output range for channel 10
+ *   [13] - D/A output range for channel 11
+ *
+ * For PCL-726 the D/A output ranges are:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA, 5: unknown
+ *
+ * For PCL-727:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: 4-20mA
+ *
+ * For PCL-728 and ACL-6128:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA, 5: 0-20mA
+ *
+ * For ACL-6126:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA
+ */
 
 #include <linux/module.h>
-#include "../comedidev.h"
-
-#undef ACL6126_IRQ             /* no interrupt support (yet) */
+#include <linux/interrupt.h>
 
-#define PCL726_SIZE 16
-#define PCL727_SIZE 32
-#define PCL728_SIZE 8
+#include "../comedidev.h"
 
-#define PCL726_DAC0_HI 0
-#define PCL726_DAC0_LO 1
+#include "comedi_fc.h"
 
-#define PCL726_DO_HI 12
-#define PCL726_DO_LO 13
-#define PCL726_DI_HI 14
-#define PCL726_DI_LO 15
+#define PCL726_AO_MSB_REG(x)   (0x00 + ((x) * 2))
+#define PCL726_AO_LSB_REG(x)   (0x01 + ((x) * 2))
+#define PCL726_DO_MSB_REG      0x0c
+#define PCL726_DO_LSB_REG      0x0d
+#define PCL726_DI_MSB_REG      0x0e
+#define PCL726_DI_LSB_REG      0x0f
 
-#define PCL727_DO_HI 24
-#define PCL727_DO_LO 25
-#define PCL727_DI_HI  0
-#define PCL727_DI_LO  1
+#define PCL727_DI_MSB_REG      0x00
+#define PCL727_DI_LSB_REG      0x01
+#define PCL727_DO_MSB_REG      0x18
+#define PCL727_DO_LSB_REG      0x19
 
 static const struct comedi_lrange *const rangelist_726[] = {
-       &range_unipolar5, &range_unipolar10,
-       &range_bipolar5, &range_bipolar10,
-       &range_4_20mA, &range_unknown
+       &range_unipolar5,
+       &range_unipolar10,
+       &range_bipolar5,
+       &range_bipolar10,
+       &range_4_20mA,
+       &range_unknown
 };
 
 static const struct comedi_lrange *const rangelist_727[] = {
-       &range_unipolar5, &range_unipolar10,
+       &range_unipolar5,
+       &range_unipolar10,
        &range_bipolar5,
        &range_4_20mA
 };
 
 static const struct comedi_lrange *const rangelist_728[] = {
-       &range_unipolar5, &range_unipolar10,
-       &range_bipolar5, &range_bipolar10,
-       &range_4_20mA, &range_0_20mA
+       &range_unipolar5,
+       &range_unipolar10,
+       &range_bipolar5,
+       &range_bipolar10,
+       &range_4_20mA,
+       &range_0_20mA
 };
 
 struct pcl726_board {
-
-       const char *name;       /*  driver name */
-       int n_aochan;           /*  num of D/A chans */
-       int num_of_ranges;      /*  num of ranges */
-       unsigned int IRQbits;   /*  allowed interrupts */
-       unsigned int io_range;  /*  len of IO space */
-       char have_dio;          /*  1=card have DI/DO ports */
-       int di_hi;              /*  ports for DI/DO operations */
-       int di_lo;
-       int do_hi;
-       int do_lo;
-       const struct comedi_lrange *const *range_type_list;
-       /*  list of supported ranges */
+       const char *name;
+       unsigned long io_len;
+       unsigned int irq_mask;
+       const struct comedi_lrange *const *ao_ranges;
+       int ao_num_ranges;
+       int ao_nchan;
+       unsigned int have_dio:1;
+       unsigned int is_pcl727:1;
 };
 
-static const struct pcl726_board boardtypes[] = {
-       {"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
-        PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
-        &rangelist_726[0],},
-       {"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
-        PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
-        &rangelist_727[0],},
-       {"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
-        0, 0, 0, 0,
-        &rangelist_728[0],},
-       {"acl6126", 6, 5, 0x96e8, PCL726_SIZE, 1,
-        PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
-        &rangelist_726[0],},
-       {"acl6128", 2, 6, 0x0000, PCL728_SIZE, 0,
-        0, 0, 0, 0,
-        &rangelist_728[0],},
+static const struct pcl726_board pcl726_boards[] = {
+       {
+               .name           = "pcl726",
+               .io_len         = 0x10,
+               .ao_ranges      = &rangelist_726[0],
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_726),
+               .ao_nchan       = 6,
+               .have_dio       = 1,
+       }, {
+               .name           = "pcl727",
+               .io_len         = 0x20,
+               .ao_ranges      = &rangelist_727[0],
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_727),
+               .ao_nchan       = 12,
+               .have_dio       = 1,
+               .is_pcl727      = 1,
+       }, {
+               .name           = "pcl728",
+               .io_len         = 0x08,
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_728),
+               .ao_ranges      = &rangelist_728[0],
+               .ao_nchan       = 2,
+       }, {
+               .name           = "acl6126",
+               .io_len         = 0x10,
+               .irq_mask       = 0x96e8,
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_726),
+               .ao_ranges      = &rangelist_726[0],
+               .ao_nchan       = 6,
+               .have_dio       = 1,
+       }, {
+               .name           = "acl6128",
+               .io_len         = 0x08,
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_728),
+               .ao_ranges      = &rangelist_728[0],
+               .ao_nchan       = 2,
+       },
 };
 
 struct pcl726_private {
-
-       int bipolar[12];
        const struct comedi_lrange *rangelist[12];
        unsigned int ao_readback[12];
+       unsigned int cmd_running:1;
 };
 
-static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int pcl726_intr_insn_bits(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       data[1] = 0;
+       return insn->n;
+}
+
+static int pcl726_intr_cmdtest(struct comedi_device *dev,
+                              struct comedi_subdevice *s,
+                              struct comedi_cmd *cmd)
+{
+       int err = 0;
+
+       /* Step 1 : check if triggers are trivially valid */
+
+       err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+       err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+       err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+       err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+       err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+       if (err)
+               return 1;
+
+       /* Step 2a : make sure trigger sources are unique */
+       /* Step 2b : and mutually compatible */
+
+       if (err)
+               return 2;
+
+       /* Step 3: check if arguments are trivially valid */
+
+       err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+       err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+       if (err)
+               return 3;
+
+       /* step 4: ignored */
+
+       if (err)
+               return 4;
+
+       return 0;
+}
+
+static int pcl726_intr_cmd(struct comedi_device *dev,
+                          struct comedi_subdevice *s)
+{
+       struct pcl726_private *devpriv = dev->private;
+
+       devpriv->cmd_running = 1;
+
+       return 0;
+}
+
+static int pcl726_intr_cancel(struct comedi_device *dev,
+                             struct comedi_subdevice *s)
 {
        struct pcl726_private *devpriv = dev->private;
-       int hi, lo;
-       int n;
-       int chan = CR_CHAN(insn->chanspec);
-
-       for (n = 0; n < insn->n; n++) {
-               lo = data[n] & 0xff;
-               hi = (data[n] >> 8) & 0xf;
-               if (devpriv->bipolar[chan])
-                       hi ^= 0x8;
-               /*
-                * the programming info did not say which order
-                * to write bytes.  switch the order of the next
-                * two lines if you get glitches.
-                */
-               outb(hi, dev->iobase + PCL726_DAC0_HI + 2 * chan);
-               outb(lo, dev->iobase + PCL726_DAC0_LO + 2 * chan);
-               devpriv->ao_readback[chan] = data[n];
+
+       devpriv->cmd_running = 0;
+
+       return 0;
+}
+
+static irqreturn_t pcl726_interrupt(int irq, void *d)
+{
+       struct comedi_device *dev = d;
+       struct comedi_subdevice *s = dev->read_subdev;
+       struct pcl726_private *devpriv = dev->private;
+
+       if (devpriv->cmd_running) {
+               pcl726_intr_cancel(dev, s);
+
+               comedi_buf_put(s->async, 0);
+               s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+               comedi_event(dev, s);
        }
 
-       return n;
+       return IRQ_HANDLED;
+}
+
+static int pcl726_ao_insn_write(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       struct pcl726_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int range = CR_RANGE(insn->chanspec);
+       unsigned int val;
+       int i;
+
+       for (i = 0; i < insn->n; i++) {
+               val = data[i];
+               devpriv->ao_readback[chan] = val;
+
+               /* bipolar data to the DAC is two's complement */
+               if (comedi_chan_range_is_bipolar(s, chan, range))
+                       val = comedi_offset_munge(s, val);
+
+               /* order is important, MSB then LSB */
+               outb((val >> 8) & 0xff, dev->iobase + PCL726_AO_MSB_REG(chan));
+               outb(val & 0xff, dev->iobase + PCL726_AO_LSB_REG(chan));
+       }
+
+       return insn->n;
 }
 
 static int pcl726_ao_insn_read(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct pcl726_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
-       int n;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int i;
+
+       for (i = 0; i < insn->n; i++)
+               data[i] = devpriv->ao_readback[chan];
 
-       for (n = 0; n < insn->n; n++)
-               data[n] = devpriv->ao_readback[chan];
-       return n;
+       return insn->n;
 }
 
 static int pcl726_di_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        const struct pcl726_board *board = comedi_board(dev);
+       unsigned int val;
 
-       data[1] = inb(dev->iobase + board->di_lo) |
-           (inb(dev->iobase + board->di_hi) << 8);
+       if (board->is_pcl727) {
+               val = inb(dev->iobase + PCL727_DI_LSB_REG);
+               val |= (inb(dev->iobase + PCL727_DI_MSB_REG) << 8);
+       } else {
+               val = inb(dev->iobase + PCL726_DI_LSB_REG);
+               val |= (inb(dev->iobase + PCL726_DI_MSB_REG) << 8);
+       }
+
+       data[1] = val;
 
        return insn->n;
 }
 
 static int pcl726_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        const struct pcl726_board *board = comedi_board(dev);
-
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       unsigned long io = dev->iobase;
+       unsigned int mask;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (board->is_pcl727) {
+                       if (mask & 0x00ff)
+                               outb(s->state & 0xff, io + PCL727_DO_LSB_REG);
+                       if (mask & 0xff00)
+                               outb((s->state >> 8), io + PCL727_DO_MSB_REG);
+               } else {
+                       if (mask & 0x00ff)
+                               outb(s->state & 0xff, io + PCL726_DO_LSB_REG);
+                       if (mask & 0xff00)
+                               outb((s->state >> 8), io + PCL726_DO_MSB_REG);
+               }
        }
-       if (data[1] & 0x00ff)
-               outb(s->state & 0xff, dev->iobase + board->do_lo);
-       if (data[1] & 0xff00)
-               outb((s->state >> 8), dev->iobase + board->do_hi);
 
        data[1] = s->state;
 
        return insn->n;
 }
 
-static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pcl726_attach(struct comedi_device *dev,
+                        struct comedi_devconfig *it)
 {
        const struct pcl726_board *board = comedi_board(dev);
        struct pcl726_private *devpriv;
        struct comedi_subdevice *s;
-       int ret, i;
-#ifdef ACL6126_IRQ
-       unsigned int irq;
-#endif
+       int subdev;
+       int ret;
+       int i;
 
-       ret = comedi_request_region(dev, it->options[0], board->io_range);
+       ret = comedi_request_region(dev, it->options[0], board->io_len);
        if (ret)
                return ret;
 
@@ -232,97 +358,81 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (!devpriv)
                return -ENOMEM;
 
-       for (i = 0; i < 12; i++) {
-               devpriv->bipolar[i] = 0;
-               devpriv->rangelist[i] = &range_unknown;
-       }
-
-#ifdef ACL6126_IRQ
-       irq = 0;
-       if (boardtypes[board].IRQbits != 0) {   /* board support IRQ */
-               irq = it->options[1];
-               devpriv->first_chan = 2;
-               if (irq) {      /* we want to use IRQ */
-                       if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
-                               printk(KERN_WARNING
-                                       ", IRQ %d is out of allowed range,"
-                                       " DISABLING IT", irq);
-                               irq = 0;        /* Bad IRQ */
-                       } else {
-                               if (request_irq(irq, interrupt_pcl818, 0,
-                                               dev->board_name, dev)) {
-                                       printk(KERN_WARNING
-                                               ", unable to allocate IRQ %d,"
-                                               " DISABLING IT", irq);
-                                       irq = 0;        /* Can't use IRQ */
-                               } else {
-                                       printk(", irq=%d", irq);
-                               }
-                       }
+       /*
+        * Hook up the external trigger source interrupt only if the
+        * user config option is valid and the board supports interrupts.
+        */
+       if (it->options[1] && (board->irq_mask & (1 << it->options[1]))) {
+               ret = request_irq(it->options[1], pcl726_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0) {
+                       /* External trigger source is from Pin-17 of CN3 */
+                       dev->irq = it->options[1];
                }
        }
 
-       dev->irq = irq;
-#endif
+       /* setup the per-channel analog output range_table_list */
+       for (i = 0; i < 12; i++) {
+               unsigned int opt = it->options[2 + i];
 
-       printk("\n");
+               if (opt < board->ao_num_ranges && i < board->ao_nchan)
+                       devpriv->rangelist[i] = board->ao_ranges[opt];
+               else
+                       devpriv->rangelist[i] = &range_unknown;
+       }
 
-       ret = comedi_alloc_subdevices(dev, 3);
+       subdev = board->have_dio ? 3 : 1;
+       if (dev->irq)
+               subdev++;
+       ret = comedi_alloc_subdevices(dev, subdev);
        if (ret)
                return ret;
 
-       s = &dev->subdevices[0];
-       /* ao */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
-       s->n_chan = board->n_aochan;
-       s->maxdata = 0xfff;
-       s->len_chanlist = 1;
-       s->insn_write = pcl726_ao_insn;
-       s->insn_read = pcl726_ao_insn_read;
-       s->range_table_list = devpriv->rangelist;
-       for (i = 0; i < board->n_aochan; i++) {
-               int j;
-
-               j = it->options[2 + 1];
-               if ((j < 0) || (j >= board->num_of_ranges)) {
-                       printk
-                           ("Invalid range for channel %d! Must be 0<=%d<%d\n",
-                            i, j, board->num_of_ranges - 1);
-                       j = 0;
-               }
-               devpriv->rangelist[i] = board->range_type_list[j];
-               if (devpriv->rangelist[i]->range[0].min ==
-                   -devpriv->rangelist[i]->range[0].max)
-                       devpriv->bipolar[i] = 1;        /* bipolar range */
-       }
+       subdev = 0;
 
-       s = &dev->subdevices[1];
-       /* di */
-       if (!board->have_dio) {
-               s->type = COMEDI_SUBD_UNUSED;
-       } else {
-               s->type = COMEDI_SUBD_DI;
-               s->subdev_flags = SDF_READABLE | SDF_GROUND;
-               s->n_chan = 16;
-               s->maxdata = 1;
-               s->len_chanlist = 1;
-               s->insn_bits = pcl726_di_insn_bits;
-               s->range_table = &range_digital;
+       /* Analog Output subdevice */
+       s = &dev->subdevices[subdev++];
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+       s->n_chan       = board->ao_nchan;
+       s->maxdata      = 0x0fff;
+       s->range_table_list = devpriv->rangelist;
+       s->insn_write   = pcl726_ao_insn_write;
+       s->insn_read    = pcl726_ao_insn_read;
+
+       if (board->have_dio) {
+               /* Digital Input subdevice */
+               s = &dev->subdevices[subdev++];
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE;
+               s->n_chan       = 16;
+               s->maxdata      = 1;
+               s->insn_bits    = pcl726_di_insn_bits;
+               s->range_table  = &range_digital;
+
+               /* Digital Output subdevice */
+               s = &dev->subdevices[subdev++];
+               s->type         = COMEDI_SUBD_DO;
+               s->subdev_flags = SDF_WRITABLE;
+               s->n_chan       = 16;
+               s->maxdata      = 1;
+               s->insn_bits    = pcl726_do_insn_bits;
+               s->range_table  = &range_digital;
        }
 
-       s = &dev->subdevices[2];
-       /* do */
-       if (!board->have_dio) {
-               s->type = COMEDI_SUBD_UNUSED;
-       } else {
-               s->type = COMEDI_SUBD_DO;
-               s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
-               s->n_chan = 16;
-               s->maxdata = 1;
-               s->len_chanlist = 1;
-               s->insn_bits = pcl726_do_insn_bits;
-               s->range_table = &range_digital;
+       if (dev->irq) {
+               /* Digial Input subdevice - Interrupt support */
+               s = &dev->subdevices[subdev++];
+               dev->read_subdev = s;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_bits    = pcl726_intr_insn_bits;
+               s->do_cmdtest   = pcl726_intr_cmdtest;
+               s->do_cmd       = pcl726_intr_cmd;
+               s->cancel       = pcl726_intr_cancel;
        }
 
        return 0;
@@ -333,12 +443,12 @@ static struct comedi_driver pcl726_driver = {
        .module         = THIS_MODULE,
        .attach         = pcl726_attach,
        .detach         = comedi_legacy_detach,
-       .board_name     = &boardtypes[0].name,
-       .num_names      = ARRAY_SIZE(boardtypes),
+       .board_name     = &pcl726_boards[0].name,
+       .num_names      = ARRAY_SIZE(pcl726_boards),
        .offset         = sizeof(struct pcl726_board),
 };
 module_comedi_driver(pcl726_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Advantech PCL-726 & compatibles");
 MODULE_LICENSE("GPL");
index 2a659f23ecda78be31cbb369c735c543c8218616..d041b714db29732f91e8739db8dcf1122f55d55b 100644 (file)
@@ -167,20 +167,17 @@ static int pcl730_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        unsigned long reg = (unsigned long)s->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
+       unsigned int mask;
 
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & 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 03a098900d34eca1acdda953983c3004f8f59cca..03315abcca1918ab8887caf2ac6739ec4fd76376 100644 (file)
@@ -355,7 +355,6 @@ struct pcl812_private {
        unsigned int ai_n_chan; /*  how many channels is measured */
        unsigned int ai_flags;  /*  flaglist */
        unsigned int ai_data_len;       /*  len of data buffer */
-       short *ai_data;         /*  data buffer */
        unsigned int ai_is16b;  /*  =1 we have 16 bit card */
        unsigned long dmabuf[2];        /*  PTR to DMA buf */
        unsigned int dmapages[2];       /*  how many pages we have allocated */
@@ -509,19 +508,16 @@ static int pcl812_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pcl812_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_update_state(s, data)) {
                outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
                outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -592,9 +588,9 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(board->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < board->ai_ns_min)
                        cmd->convert_arg = board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -640,8 +636,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                        cmd->convert_arg = board->ai_ns_min;
                i8253_cascade_ns_to_timer(board->i8254_osc_base,
                                          &divisor1, &divisor2,
-                                         &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+                                         &cmd->convert_arg, cmd->flags);
        }
 
        start_pacer(dev, -1, 0, 0);     /*  stop pacer */
@@ -665,7 +660,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
        devpriv->ai_flags = cmd->flags;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
-       devpriv->ai_data = s->async->prealloc_buf;
        if (cmd->stop_src == TRIG_COUNT) {
                devpriv->ai_scans = cmd->stop_arg;
                devpriv->ai_neverending = 0;
@@ -835,7 +829,8 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
 ==============================================================================
 */
 static void transfer_from_dma_buf(struct comedi_device *dev,
-                                 struct comedi_subdevice *s, short *ptr,
+                                 struct comedi_subdevice *s,
+                                 unsigned short *ptr,
                                  unsigned int bufptr, unsigned int len)
 {
        struct pcl812_private *devpriv = dev->private;
@@ -873,9 +868,9 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
        struct comedi_subdevice *s = &dev->subdevices[0];
        unsigned long dma_flags;
        int len, bufptr;
-       short *ptr;
+       unsigned short *ptr;
 
-       ptr = (short *)devpriv->dmabuf[devpriv->next_dma_buf];
+       ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf];
        len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
            devpriv->ai_poll_ptr;
 
@@ -1443,40 +1438,40 @@ static void pcl812_detach(struct comedi_device *dev)
 
 static const struct pcl812_board boardtypes[] = {
        {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff,
-        33000, 500, &range_bipolar10, &range_unipolar5,
+        33000, I8254_OSC_BASE_2MHZ, &range_bipolar10, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
-        33000, 500, &range_pcl812pg_ai, &range_unipolar5,
+        33000, I8254_OSC_BASE_2MHZ, &range_pcl812pg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
-        10000, 500, &range_pcl812pg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl812pg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112dg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
        {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112hg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
        {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff,
-        10000, 500, &range_pcl813b_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b_ai, &range_unipolar5,
         0x000c, 0x00, PCLx1x_IORANGE, 0},
        {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff,
-        10000, 500, &range_pcl813b_ai, NULL,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b_ai, NULL,
         0x000c, 0x00, PCLx1x_IORANGE, 0},
        {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff,
-        10000, 500, &range_a821pgh_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_a821pgh_ai, &range_unipolar5,
         0x000c, 0x00, PCLx1x_IORANGE, 0},
        {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112dg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112hg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        8000, 500, &range_acl8112dg_ai, &range_unipolar5,
+        8000, I8254_OSC_BASE_2MHZ, &range_acl8112dg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        8000, 500, &range_acl8112hg_ai, &range_unipolar5,
+        8000, I8254_OSC_BASE_2MHZ, &range_acl8112hg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff,
         0, 0, &range_pcl813b_ai, NULL,
@@ -1491,10 +1486,10 @@ static const struct pcl812_board boardtypes[] = {
         0, 0, &range_iso813_1_ai, NULL,
         0x0000, 0x00, PCLx1x_IORANGE, 0},
        {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
-        10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b2_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
        {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
-        10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b2_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
 };
 
index f03134962596ccbe2254edaa7ab4eb04c688acaf..ab9d2bd26a207b11ff463f0952cf66f8d95cd456 100644 (file)
@@ -229,7 +229,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl816_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[0];
-       int low, hi;
+       unsigned char low, hi;
        int timeout = 50;       /* wait max 50us */
 
        while (timeout--) {
@@ -281,7 +281,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
    analog input dma mode 1 & 3, 816 cards
 */
 static void transfer_from_dma_buf(struct comedi_device *dev,
-                                 struct comedi_subdevice *s, short *ptr,
+                                 struct comedi_subdevice *s,
+                                 unsigned short *ptr,
                                  unsigned int bufptr, unsigned int len)
 {
        struct pcl816_private *devpriv = dev->private;
@@ -324,7 +325,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
        struct comedi_subdevice *s = &dev->subdevices[0];
        int len, bufptr, this_dma_buf;
        unsigned long dma_flags;
-       short *ptr;
+       unsigned short *ptr;
 
        disable_dma(devpriv->dma);
        this_dma_buf = devpriv->next_dma_buf;
@@ -352,7 +353,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
        devpriv->dma_runs_to_end--;
        outb(0, dev->iobase + PCL816_CLRINT);   /* clear INT request */
 
-       ptr = (short *)devpriv->dmabuf[this_dma_buf];
+       ptr = (unsigned short *)devpriv->dmabuf[this_dma_buf];
 
        len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
        bufptr = devpriv->ai_poll_ptr;
@@ -481,8 +482,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
                tmp = cmd->convert_arg;
                i8253_cascade_ns_to_timer(board->i8254_osc_base,
                                          &divisor1, &divisor2,
-                                         &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < board->ai_ns_min)
                        cmd->convert_arg = board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -528,9 +528,9 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                if (cmd->convert_arg < board->ai_ns_min)
                        cmd->convert_arg = board->ai_ns_min;
 
-               i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(board->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
 
                /*  PCL816 crash if any divisor is set to 1 */
                if (divisor1 == 1) {
@@ -666,7 +666,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
        }
 
        transfer_from_dma_buf(dev, s,
-                             (short *)devpriv->dmabuf[devpriv->next_dma_buf],
+                             (unsigned short *)devpriv->dmabuf[devpriv->
+                                                               next_dma_buf],
                              devpriv->ai_poll_ptr, top2);
 
        devpriv->ai_poll_ptr = top1;    /*  new buffer position */
@@ -1105,7 +1106,7 @@ static const struct pcl816_board boardtypes[] = {
         0xffff,                /*  D/A maxdata */
         1024,
         1,                     /*  ao chan list */
-        100},
+        I8254_OSC_BASE_10MHZ},
        {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
         &range_pcl816, PCLx1x_RANGE,
         0x00fc,
@@ -1114,7 +1115,7 @@ static const struct pcl816_board boardtypes[] = {
         0x3fff,
         1024,
         1,
-        100},
+        I8254_OSC_BASE_10MHZ},
 };
 
 static struct comedi_driver pcl816_driver = {
index a52ba82ff0e4a10adbdebf1508b73b1d7967c132..9e4d7e8605097bff47e0dedb3e605b90b170da06 100644 (file)
@@ -289,7 +289,6 @@ struct pcl818_private {
        unsigned int *ai_chanlist;      /*  actaul chanlist */
        unsigned int ai_flags;  /*  flaglist */
        unsigned int ai_data_len;       /*  len of data buffer */
-       short *ai_data;         /*  data buffer */
        unsigned int ai_timer1; /*  timers */
        unsigned int ai_timer2;
        struct comedi_subdevice *sub_ai;        /*  ptr to AI subdevice */
@@ -418,21 +417,15 @@ static int pcl818_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-   DIGITAL OUTPUT MODE0, 818 cards
-
-   only one sample per call is supported
-*/
 static int pcl818_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= (data[0] & data[1]);
-
-       outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
-       outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+       if (comedi_dio_update_state(s, data)) {
+               outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
+               outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+       }
 
        data[1] = s->state;
 
@@ -449,7 +442,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl818_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[0];
-       int low;
+       unsigned char low;
        int timeout = 50;       /* wait max 50us */
 
        while (timeout--) {
@@ -511,7 +504,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
        struct comedi_subdevice *s = &dev->subdevices[0];
        int i, len, bufptr;
        unsigned long flags;
-       short *ptr;
+       unsigned short *ptr;
 
        disable_dma(devpriv->dma);
        devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
@@ -534,7 +527,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
 
        devpriv->dma_runs_to_end--;
        outb(0, dev->iobase + PCL818_CLRINT);   /* clear INT request */
-       ptr = (short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
+       ptr = (unsigned short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
 
        len = devpriv->hwdmasize[0] >> 1;
        bufptr = 0;
@@ -588,7 +581,8 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl818_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[0];
-       int i, len, lo;
+       int i, len;
+       unsigned char lo;
 
        outb(0, dev->iobase + PCL818_FI_INTCLR);        /*  clear fifo int request */
 
@@ -806,8 +800,9 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
                devpriv->neverending_ai = 1;    /* well, user want neverending */
 
        if (mode == 1) {
-               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
+               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg,
                                          TRIG_ROUND_NEAREST);
                if (divisor1 == 1) {    /* PCL718/818 crash if any divisor is set to 1 */
                        divisor1 = 2;
@@ -1040,9 +1035,9 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < board->ns_min)
                        cmd->convert_arg = board->ns_min;
                if (tmp != cmd->convert_arg)
@@ -1077,7 +1072,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_chanlist = cmd->chanlist;
        devpriv->ai_flags = cmd->flags;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
-       devpriv->ai_data = s->async->prealloc_buf;
        devpriv->ai_timer1 = 0;
        devpriv->ai_timer2 = 0;
 
@@ -1438,9 +1432,9 @@ no_dma:
 
        /* select 1/10MHz oscilator */
        if ((it->options[3] == 0) || (it->options[3] == 10))
-               devpriv->i8253_osc_base = 100;
+               devpriv->i8253_osc_base = I8254_OSC_BASE_10MHZ;
        else
-               devpriv->i8253_osc_base = 1000;
+               devpriv->i8253_osc_base = I8254_OSC_BASE_1MHZ;
 
        /* max sampling speed */
        devpriv->ns_min = board->ns_min;
index 423f23676d26cc1df6b8d91bf81a4691c9d0150d..fe482fdd512ed32f94af0987b236b2da28d62a57 100644 (file)
@@ -75,12 +75,6 @@ static int pcmad_ai_wait_for_eoc(struct comedi_device *dev,
        return -ETIME;
 }
 
-static bool pcmad_range_is_bipolar(struct comedi_subdevice *s,
-                                  unsigned int range)
-{
-       return s->range_table->range[range].min < 0;
-}
-
 static int pcmad_ai_insn_read(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn,
@@ -106,7 +100,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
                if (s->maxdata == 0x0fff)
                        val >>= 4;
 
-               if (pcmad_range_is_bipolar(s, range)) {
+               if (comedi_range_is_bipolar(s, range)) {
                        /* munge the two's complement value */
                        val ^= ((s->maxdata + 1) >> 1);
                }
index 574443df42dab212d5083e7aee5affd3493ffcd9..14cee3ac92c52f67fadd05b4b3cec4d92efaec7a 100644 (file)
@@ -553,12 +553,11 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
                                                                                val |= (1U << n);
                                                                }
                                                                /* Write the scan to the buffer. */
-                                                               if (comedi_buf_put(s->async, ((short *)&val)[0])
+                                                               if (comedi_buf_put(s->async, val)
                                                                    &&
                                                                    comedi_buf_put
                                                                    (s->async,
-                                                                    ((short *)
-                                                                     &val)[1])) {
+                                                                    val >> 16)) {
                                                                        s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
                                                                } else {
                                                                        /* Overflow! Stop acquisition!! */
@@ -846,7 +845,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                    CR_RANGE(insn->chanspec), aref = CR_AREF(insn->chanspec);
                unsigned char command_byte = 0;
                unsigned iooffset = 0;
-               short sample, adc_adjust = 0;
+               unsigned short sample, adc_adjust = 0;
 
                if (chan > 7)
                        chan -= 8, iooffset = 4;        /*
index 67e2bb1d66f00c61357780d7e95fa86d8275530d..954fa96a50ac766df3ed8d257704e46442302293 100644 (file)
@@ -315,8 +315,8 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
        }
 
        /* Write the scan to the buffer. */
-       if (comedi_buf_put(s->async, ((short *)&val)[0]) &&
-           comedi_buf_put(s->async, ((short *)&val)[1])) {
+       if (comedi_buf_put(s->async, val) &&
+           comedi_buf_put(s->async, val >> 16)) {
                s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
        } else {
                /* Overflow! Stop acquisition!! */
index 9775d3622a6266a51da709d951dbb6ae60e415d1..96a46954b3c09819184474a82615962a9120146d 100644 (file)
@@ -208,8 +208,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
        case buffer:
                while (!((status = inb(dev->iobase + DAQP_STATUS))
                         & DAQP_STATUS_FIFO_EMPTY)) {
-
-                       short data;
+                       unsigned short data;
 
                        if (status & DAQP_STATUS_DATA_LOST) {
                                s->async->events |=
@@ -690,18 +689,12 @@ static int daqp_do_insn_bits(struct comedi_device *dev,
                             unsigned int *data)
 {
        struct daqp_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        if (devpriv->stop)
                return -EIO;
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outb(s->state, dev->iobase + DAQP_DIGITAL_IO);
-       }
 
        data[1] = s->state;
 
index 93c980c62a23a96ded07673231cf216e85055f2e..44c8712ed9e05ddf939f1792dd452b94d2e7044f 100644 (file)
@@ -394,11 +394,8 @@ struct rtd_private {
        long ai_count;          /* total transfer size (samples) */
        int xfer_count;         /* # to transfer data. 0->1/2FIFO */
        int flags;              /* flag event modes */
-
-       unsigned char chan_is_bipolar[RTD_MAX_CHANLIST / 8];    /* bit array */
-
+       DECLARE_BITMAP(chan_is_bipolar, RTD_MAX_CHANLIST);
        unsigned int ao_readback[2];
-
        unsigned fifosz;
 };
 
@@ -407,14 +404,6 @@ struct rtd_private {
 #define DMA0_ACTIVE    0x02    /* DMA0 is active */
 #define DMA1_ACTIVE    0x04    /* DMA1 is active */
 
-/* Macros for accessing channel list bit array */
-#define CHAN_ARRAY_TEST(array, index) \
-       (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
-#define CHAN_ARRAY_SET(array, index) \
-       (((array)[(index)/8] |= 1 << ((index) & 0x7)))
-#define CHAN_ARRAY_CLEAR(array, index) \
-       (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
-
 /*
   Given a desired period and the clock period (both in ns),
   return the proper counter value (divider-1).
@@ -478,17 +467,17 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
                /* +-5 range */
                r |= 0x000;
                r |= (range & 0x7) << 4;
-               CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
+               __set_bit(index, devpriv->chan_is_bipolar);
        } else if (range < board->range_uni10) {
                /* +-10 range */
                r |= 0x100;
                r |= ((range - board->range_bip10) & 0x7) << 4;
-               CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
+               __set_bit(index, devpriv->chan_is_bipolar);
        } else {
                /* +10 range */
                r |= 0x200;
                r |= ((range - board->range_uni10) & 0x7) << 4;
-               CHAN_ARRAY_CLEAR(devpriv->chan_is_bipolar, index);
+               __clear_bit(index, devpriv->chan_is_bipolar);
        }
 
        switch (aref) {
@@ -602,7 +591,7 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
 
        /* convert n samples */
        for (n = 0; n < insn->n; n++) {
-               s16 d;
+               unsigned short d;
                /* trigger conversion */
                writew(0, devpriv->las0 + LAS0_ADC);
 
@@ -619,11 +608,10 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
                /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
                d = d >> 3;     /* low 3 bits are marker lines */
-               if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar, 0))
+               if (test_bit(0, devpriv->chan_is_bipolar))
                        /* convert to comedi unsigned data */
-                       data[n] = d + 2048;
-               else
-                       data[n] = d;
+                       d = comedi_offset_munge(s, d);
+               data[n] = d & s->maxdata;
        }
 
        /* return the number of samples read/written */
@@ -643,8 +631,7 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
        int ii;
 
        for (ii = 0; ii < count; ii++) {
-               short sample;
-               s16 d;
+               unsigned short d;
 
                if (0 == devpriv->ai_count) {   /* done */
                        d = readw(devpriv->las1 + LAS1_ADC_FIFO);
@@ -653,14 +640,12 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
 
                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
                d = d >> 3;     /* low 3 bits are marker lines */
-               if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
-                                   s->async->cur_chan)) {
+               if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar))
                        /* convert to comedi unsigned data */
-                       sample = d + 2048;
-               } else
-                       sample = d;
+                       d = comedi_offset_munge(s, d);
+               d &= s->maxdata;
 
-               if (!comedi_buf_put(s->async, sample))
+               if (!comedi_buf_put(s->async, d))
                        return -1;
 
                if (devpriv->ai_count > 0)      /* < 0, means read forever */
@@ -677,22 +662,19 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
        struct rtd_private *devpriv = dev->private;
 
        while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
-               short sample;
-               s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
+               unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 
                if (0 == devpriv->ai_count) {   /* done */
                        continue;       /* read rest */
                }
 
                d = d >> 3;     /* low 3 bits are marker lines */
-               if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
-                                   s->async->cur_chan)) {
+               if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar))
                        /* convert to comedi unsigned data */
-                       sample = d + 2048;
-               } else
-                       sample = d;
+                       d = comedi_offset_munge(s, d);
+               d &= s->maxdata;
 
-               if (!comedi_buf_put(s->async, sample))
+               if (!comedi_buf_put(s->async, d))
                        return -1;
 
                if (devpriv->ai_count > 0)      /* < 0, means read forever */
@@ -1217,15 +1199,9 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
                             unsigned int *data)
 {
        struct rtd_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
-       }
 
        data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
 
index cbb4ba5b852a1fdf43b44a0c2b7dacd2092f8c60..e1f3671ac056095982922ff3697832f9ded54dbf 100644 (file)
@@ -267,13 +267,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
                               struct comedi_insn *insn,
                               unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data)) {
                /* Outputs are inverted... */
                outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
        }
index d629463b85a2ae38ba7c97d8329633ce606b7c1c..9950f59b1192c99dc471265027dbb2a9fd26fc4a 100644 (file)
@@ -499,14 +499,11 @@ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
 static int s526_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + REG_DIO);
-       }
 
        data[1] = inw(dev->iobase + REG_DIO) & 0xff;
 
index d22b95dcb9bdff2ae4e064513ac7295f16b7fbbf..6815cfe2664e42e632114b3e87ca140b349008f3 100644 (file)
@@ -1,63 +1,63 @@
 /*
-  comedi/drivers/s626.c
-  Sensoray s626 Comedi driver
-
-  COMEDI - Linux Control and Measurement Device Interface
-  Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-  Based on Sensoray Model 626 Linux driver Version 0.2
-  Copyright (C) 2002-2004 Sensoray Co., 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; 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.
-*/
* comedi/drivers/s626.c
* Sensoray s626 Comedi driver
+ *
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
* Based on Sensoray Model 626 Linux driver Version 0.2
* Copyright (C) 2002-2004 Sensoray Co., 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; 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.
+ */
 
 /*
-Driver: s626
-Description: Sensoray 626 driver
-Devices: [Sensoray] 626 (s626)
-Authors: Gianluca Palli <gpalli@deis.unibo.it>,
-Updated: Fri, 15 Feb 2008 10:28:42 +0000
-Status: experimental
-
-Configuration options: not applicable, uses PCI auto config
-
-INSN_CONFIG instructions:
-  analog input:
-   none
-
-  analog output:
-   none
-
-  digital channel:
-   s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
-   supported configuration options:
-   INSN_CONFIG_DIO_QUERY
-   COMEDI_INPUT
-   COMEDI_OUTPUT
-
-  encoder:
-   Every channel must be configured before reading.
-
-   Example code
-
-   insn.insn=INSN_CONFIG;   //configuration instruction
-   insn.n=1;                //number of operation (must be 1)
-   insn.data=&initialvalue; //initial value loaded into encoder
                              //during configuration
-   insn.subdev=5;           //encoder subdevice
-   insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
-                                                       //to configure
-
-   comedi_do_insn(cf,&insn); //executing configuration
-*/
+ * Driver: s626
+ * Description: Sensoray 626 driver
+ * Devices: [Sensoray] 626 (s626)
+ * Authors: Gianluca Palli <gpalli@deis.unibo.it>,
+ * Updated: Fri, 15 Feb 2008 10:28:42 +0000
+ * Status: experimental
+
+ * Configuration options: not applicable, uses PCI auto config
+
+ * INSN_CONFIG instructions:
*   analog input:
*    none
+ *
*   analog output:
*    none
+ *
*   digital channel:
*    s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
*    supported configuration options:
*    INSN_CONFIG_DIO_QUERY
*    COMEDI_INPUT
*    COMEDI_OUTPUT
+ *
*   encoder:
*    Every channel must be configured before reading.
+ *
  Example code
+ *
*    insn.insn=INSN_CONFIG;   //configuration instruction
*    insn.n=1;                //number of operation (must be 1)
*    insn.data=&initialvalue; //initial value loaded into encoder
*                             //during configuration
*    insn.subdev=5;           //encoder subdevice
*    insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
*                                                         //to configure
+ *
*    comedi_do_insn(cf,&insn); //executing configuration
+ */
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -71,68 +71,91 @@ INSN_CONFIG instructions:
 #include "comedi_fc.h"
 #include "s626.h"
 
-#define PCI_VENDOR_ID_S626 0x1131
-#define PCI_DEVICE_ID_S626 0x7146
-#define PCI_SUBVENDOR_ID_S626 0x6000
-#define PCI_SUBDEVICE_ID_S626 0x0272
+struct s626_buffer_dma {
+       dma_addr_t physical_base;
+       void *logical_base;
+};
 
 struct s626_private {
        void __iomem *mmio;
-       uint8_t ai_cmd_running; /*  ai_cmd is running */
-       uint8_t ai_continous;   /*  continous acquisition */
-       int ai_sample_count;    /*  number of samples to acquire */
-       unsigned int ai_sample_timer;
-       /*  time between samples in  units of the timer */
-       int ai_convert_count;   /*  conversion counter */
-       unsigned int ai_convert_timer;
-       /*  time between conversion in  units of the timer */
-       uint16_t CounterIntEnabs;
-       /* Counter interrupt enable  mask for MISC2 register. */
-       uint8_t AdcItems;       /* Number of items in ADC poll  list. */
-       struct bufferDMA RPSBuf;        /* DMA buffer used to hold ADC (RPS1) program. */
-       struct bufferDMA ANABuf;
-       /* DMA buffer used to receive ADC data and hold DAC data. */
-       uint32_t *pDacWBuf;
-       /* Pointer to logical adrs of DMA buffer used to hold DAC  data. */
-       uint16_t Dacpol;        /* Image of DAC polarity register. */
-       uint8_t TrimSetpoint[12];       /* Images of TrimDAC setpoints */
-       /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */
-       uint32_t I2CAdrs;
-       /* I2C device address for onboard EEPROM (board rev dependent). */
-       /*   short         I2Cards; */
+       uint8_t ai_cmd_running;         /* ai_cmd is running */
+       uint8_t ai_continuous;          /* continuous acquisition */
+       int ai_sample_count;            /* number of samples to acquire */
+       unsigned int ai_sample_timer;   /* time between samples in
+                                        * units of the timer */
+       int ai_convert_count;           /* conversion counter */
+       unsigned int ai_convert_timer;  /* time between conversion in
+                                        * units of the timer */
+       uint16_t counter_int_enabs;     /* counter interrupt enable mask
+                                        * for MISC2 register */
+       uint8_t adc_items;              /* number of items in ADC poll list */
+       struct s626_buffer_dma rps_buf; /* DMA buffer used to hold ADC (RPS1)
+                                        * program */
+       struct s626_buffer_dma ana_buf; /* DMA buffer used to receive ADC data
+                                        * and hold DAC data */
+       uint32_t *dac_wbuf;             /* pointer to logical adrs of DMA buffer
+                                        * used to hold DAC data */
+       uint16_t dacpol;                /* image of DAC polarity register */
+       uint8_t trim_setpoint[12];      /* images of TrimDAC setpoints */
+       uint32_t i2c_adrs;              /* I2C device address for onboard EEPROM
+                                        * (board rev dependent) */
        unsigned int ao_readback[S626_DAC_CHANNELS];
 };
 
-/*  COUNTER OBJECT ------------------------------------------------ */
-struct enc_private {
-       /*  Pointers to functions that differ for A and B counters: */
-       uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *); /* Return clock enable. */
-       uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *); /* Return interrupt source. */
-       uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *);       /* Return preload trigger source. */
-       uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *);   /* Return standardized operating mode. */
-       void (*PulseIndex) (struct comedi_device *dev, struct enc_private *);   /* Generate soft index strobe. */
-       void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab);     /* Program clock enable. */
-       void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource);        /* Program interrupt source. */
-       void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig);   /* Program preload trigger source. */
-       void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);      /* Program standardized operating mode. */
-       void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *);        /* Reset event capture flags. */
-
-       uint16_t MyCRA;         /*    Address of CRA register. */
-       uint16_t MyCRB;         /*    Address of CRB register. */
-       uint16_t MyLatchLsw;    /*    Address of Latch least-significant-word */
-       /*    register. */
-       uint16_t MyEventBits[4];        /*    Bit translations for IntSrc -->RDMISC2. */
+/* COUNTER OBJECT ------------------------------------------------ */
+struct s626_enc_info {
+       /* Pointers to functions that differ for A and B counters: */
+       /* Return clock enable. */
+       uint16_t(*get_enable)(struct comedi_device *dev,
+                             const struct s626_enc_info *k);
+       /* Return interrupt source. */
+       uint16_t(*get_int_src)(struct comedi_device *dev,
+                              const struct s626_enc_info *k);
+       /* Return preload trigger source. */
+       uint16_t(*get_load_trig)(struct comedi_device *dev,
+                                const struct s626_enc_info *k);
+       /* Return standardized operating mode. */
+       uint16_t(*get_mode)(struct comedi_device *dev,
+                           const struct s626_enc_info *k);
+       /* Generate soft index strobe. */
+       void (*pulse_index)(struct comedi_device *dev,
+                           const struct s626_enc_info *k);
+       /* Program clock enable. */
+       void (*set_enable)(struct comedi_device *dev,
+                          const struct s626_enc_info *k, uint16_t enab);
+       /* Program interrupt source. */
+       void (*set_int_src)(struct comedi_device *dev,
+                           const struct s626_enc_info *k, uint16_t int_source);
+       /* Program preload trigger source. */
+       void (*set_load_trig)(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t trig);
+       /* Program standardized operating mode. */
+       void (*set_mode)(struct comedi_device *dev,
+                        const struct s626_enc_info *k, uint16_t setup,
+                        uint16_t disable_int_src);
+       /* Reset event capture flags. */
+       void (*reset_cap_flags)(struct comedi_device *dev,
+                               const struct s626_enc_info *k);
+
+       uint16_t my_cra;        /* address of CRA register */
+       uint16_t my_crb;        /* address of CRB register */
+       uint16_t my_latch_lsw;  /* address of Latch least-significant-word
+                                * register */
+       uint16_t my_event_bits[4]; /* bit translations for IntSrc -->RDMISC2 */
 };
 
-#define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
-
-/*  Counter overflow/index event flag masks for RDMISC2. */
-#define INDXMASK(C)            (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 +  4)))
-#define OVERMASK(C)            (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
-#define EVBITS(C)              { 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
+/* Counter overflow/index event flag masks for RDMISC2. */
+#define S626_INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 +  4)))
+#define S626_OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
+#define S626_EVBITS(C) { 0, S626_OVERMASK(C), S626_INDXMASK(C), \
+                         S626_OVERMASK(C) | S626_INDXMASK(C) }
 
-/*  Translation table to map IntSrc into equivalent RDMISC2 event flag  bits. */
-/* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
+/*
+ * Translation table to map IntSrc into equivalent RDMISC2 event flag  bits.
+ * static const uint16_t s626_event_bits[][4] =
+ *     { S626_EVBITS(0), S626_EVBITS(1), S626_EVBITS(2), S626_EVBITS(3),
+ *       S626_EVBITS(4), S626_EVBITS(5) };
+ */
 
 /*
  * Enable/disable a function or test status bit(s) that are accessed
@@ -144,6 +167,7 @@ static void s626_mc_enable(struct comedi_device *dev,
        struct s626_private *devpriv = dev->private;
        unsigned int val = (cmd << 16) | cmd;
 
+       mmiowb();
        writel(val, devpriv->mmio + reg);
 }
 
@@ -153,6 +177,7 @@ static void s626_mc_disable(struct comedi_device *dev,
        struct s626_private *devpriv = dev->private;
 
        writel(cmd << 16 , devpriv->mmio + reg);
+       mmiowb();
 }
 
 static bool s626_mc_test(struct comedi_device *dev,
@@ -166,15 +191,10 @@ static bool s626_mc_test(struct comedi_device *dev,
        return (val & cmd) ? true : false;
 }
 
-#define BUGFIX_STREG(REGADRS)   (REGADRS - 4)
+#define S626_BUGFIX_STREG(REGADRS)   ((REGADRS) - 4)
 
-/*  Write a time slot control record to TSL2. */
-#define VECTPORT(VECTNUM)              (P_TSL2 + ((VECTNUM) << 2))
-
-/*  Code macros used for constructing I2C command bytes. */
-#define I2C_B2(ATTR, VAL)      (((ATTR) << 6) | ((VAL) << 24))
-#define I2C_B1(ATTR, VAL)      (((ATTR) << 4) | ((VAL) << 16))
-#define I2C_B0(ATTR, VAL)      (((ATTR) << 2) | ((VAL) <<  8))
+/* Write a time slot control record to TSL2. */
+#define S626_VECTPORT(VECTNUM)         (S626_P_TSL2 + ((VECTNUM) << 2))
 
 static const struct comedi_lrange s626_range_table = {
        2, {
@@ -183,178 +203,182 @@ static const struct comedi_lrange s626_range_table = {
        }
 };
 
-/*  Execute a DEBI transfer.  This must be called from within a */
-/*  critical section. */
-static void DEBItransfer(struct comedi_device *dev)
+/*
+ * Execute a DEBI transfer.  This must be called from within a critical section.
+ */
+static void s626_debi_transfer(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
 
        /* Initiate upload of shadow RAM to DEBI control register */
-       s626_mc_enable(dev, MC2_UPLD_DEBI, P_MC2);
+       s626_mc_enable(dev, S626_MC2_UPLD_DEBI, S626_P_MC2);
 
        /*
         * Wait for completion of upload from shadow RAM to
         * DEBI control register.
         */
-       while (!s626_mc_test(dev, MC2_UPLD_DEBI, P_MC2))
+       while (!s626_mc_test(dev, S626_MC2_UPLD_DEBI, S626_P_MC2))
                ;
 
        /* Wait until DEBI transfer is done */
-       while (readl(devpriv->mmio + P_PSR) & PSR_DEBI_S)
+       while (readl(devpriv->mmio + S626_P_PSR) & S626_PSR_DEBI_S)
                ;
 }
 
-/*  Initialize the DEBI interface for all transfers. */
-
-static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
+/*
+ * Read a value from a gate array register.
+ */
+static uint16_t s626_debi_read(struct comedi_device *dev, uint16_t addr)
 {
        struct s626_private *devpriv = dev->private;
 
        /* Set up DEBI control register value in shadow RAM */
-       writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD);
+       writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
 
        /*  Execute the DEBI transfer. */
-       DEBItransfer(dev);
+       s626_debi_transfer(dev);
 
-       return readl(devpriv->mmio + P_DEBIAD);
+       return readl(devpriv->mmio + S626_P_DEBIAD);
 }
 
-/*  Write a value to a gate array register. */
-static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
+/*
+ * Write a value to a gate array register.
+ */
+static void s626_debi_write(struct comedi_device *dev, uint16_t addr,
+                           uint16_t wdata)
 {
        struct s626_private *devpriv = dev->private;
 
        /* Set up DEBI control register value in shadow RAM */
-       writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD);
-       writel(wdata, devpriv->mmio + P_DEBIAD);
+       writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+       writel(wdata, devpriv->mmio + S626_P_DEBIAD);
 
        /*  Execute the DEBI transfer. */
-       DEBItransfer(dev);
+       s626_debi_transfer(dev);
 }
 
-/* Replace the specified bits in a gate array register.  Imports: mask
+/*
+ * Replace the specified bits in a gate array register.  Imports: mask
  * specifies bits that are to be preserved, wdata is new value to be
  * or'd with the masked original.
  */
-static void DEBIreplace(struct comedi_device *dev, unsigned int addr,
-                       unsigned int mask, unsigned int wdata)
+static void s626_debi_replace(struct comedi_device *dev, unsigned int addr,
+                             unsigned int mask, unsigned int wdata)
 {
        struct s626_private *devpriv = dev->private;
        unsigned int val;
 
        addr &= 0xffff;
-       writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD);
-       DEBItransfer(dev);
+       writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+       s626_debi_transfer(dev);
 
-       writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD);
-       val = readl(devpriv->mmio + P_DEBIAD);
+       writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+       val = readl(devpriv->mmio + S626_P_DEBIAD);
        val &= mask;
        val |= wdata;
-       writel(val & 0xffff, devpriv->mmio + P_DEBIAD);
-       DEBItransfer(dev);
+       writel(val & 0xffff, devpriv->mmio + S626_P_DEBIAD);
+       s626_debi_transfer(dev);
 }
 
 /* **************  EEPROM ACCESS FUNCTIONS  ************** */
 
-static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
+static uint32_t s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
 {
        struct s626_private *devpriv = dev->private;
        unsigned int ctrl;
 
        /* Write I2C command to I2C Transfer Control shadow register */
-       writel(val, devpriv->mmio + P_I2CCTRL);
+       writel(val, devpriv->mmio + S626_P_I2CCTRL);
 
        /*
         * Upload I2C shadow registers into working registers and
         * wait for upload confirmation.
         */
-       s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
-       while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2))
+       s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+       while (!s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2))
                ;
 
        /* Wait until I2C bus transfer is finished or an error occurs */
        do {
-               ctrl = readl(devpriv->mmio + P_I2CCTRL);
-       } while ((ctrl & (I2C_BUSY | I2C_ERR)) == I2C_BUSY);
+               ctrl = readl(devpriv->mmio + S626_P_I2CCTRL);
+       } while ((ctrl & (S626_I2C_BUSY | S626_I2C_ERR)) == S626_I2C_BUSY);
 
        /* Return non-zero if I2C error occurred */
-       return ctrl & I2C_ERR;
+       return ctrl & S626_I2C_ERR;
 }
 
-/*  Read uint8_t from EEPROM. */
-static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
+/* Read uint8_t from EEPROM. */
+static uint8_t s626_i2c_read(struct comedi_device *dev, uint8_t addr)
 {
        struct s626_private *devpriv = dev->private;
 
-       /*  Send EEPROM target address. */
-       if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
-                        /* Byte2 = I2C command: write to I2C EEPROM  device. */
-                        | I2C_B1(I2C_ATTRSTOP, addr)
-                        /* Byte1 = EEPROM internal target address. */
-                        | I2C_B0(I2C_ATTRNOP, 0))) {   /*  Byte0 = Not sent. */
-               /*  Abort function and declare error if handshake failed. */
+       /*
+        * Send EEPROM target address:
+        *  Byte2 = I2C command: write to I2C EEPROM device.
+        *  Byte1 = EEPROM internal target address.
+        *  Byte0 = Not sent.
+        */
+       if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART,
+                                               devpriv->i2c_adrs) |
+                                   S626_I2C_B1(S626_I2C_ATTRSTOP, addr) |
+                                   S626_I2C_B0(S626_I2C_ATTRNOP, 0)))
+               /* Abort function and declare error if handshake failed. */
                return 0;
-       }
-       /*  Execute EEPROM read. */
-       if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR)
-
-                        /*  Byte2 = I2C */
-                        /*  command: read */
-                        /*  from I2C EEPROM */
-                        /*  device. */
-                        |I2C_B1(I2C_ATTRSTOP, 0)
 
-                        /*  Byte1 receives */
-                        /*  uint8_t from */
-                        /*  EEPROM. */
-                        |I2C_B0(I2C_ATTRNOP, 0))) {    /*  Byte0 = Not  sent. */
-
-               /*  Abort function and declare error if handshake failed. */
+       /*
+        * Execute EEPROM read:
+        *  Byte2 = I2C command: read from I2C EEPROM device.
+        *  Byte1 receives uint8_t from EEPROM.
+        *  Byte0 = Not sent.
+        */
+       if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART,
+                                          (devpriv->i2c_adrs | 1)) |
+                                   S626_I2C_B1(S626_I2C_ATTRSTOP, 0) |
+                                   S626_I2C_B0(S626_I2C_ATTRNOP, 0)))
+               /* Abort function and declare error if handshake failed. */
                return 0;
-       }
 
-       return (readl(devpriv->mmio + P_I2CCTRL) >> 16) & 0xff;
+       return (readl(devpriv->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
 }
 
 /* ***********  DAC FUNCTIONS *********** */
 
-/*  Slot 0 base settings. */
-#define VECT0  (XSD2 | RSD3 | SIB_A2)
-/*  Slot 0 always shifts in  0xFF and store it to  FB_BUFFER2. */
+/* TrimDac LogicalChan-to-PhysicalChan mapping table. */
+static const uint8_t s626_trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
 
-/*  TrimDac LogicalChan-to-PhysicalChan mapping table. */
-static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
-
-/*  TrimDac LogicalChan-to-EepromAdrs mapping table. */
-static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
+/* TrimDac LogicalChan-to-EepromAdrs mapping table. */
+static const uint8_t s626_trimadrs[] = {
+       0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63
+};
 
-/* Private helper function: Transmit serial data to DAC via Audio
+/*
+ * Private helper function: Transmit serial data to DAC via Audio
  * channel 2.  Assumes: (1) TSL2 slot records initialized, and (2)
- * Dacpol contains valid target image.
+ * dacpol contains valid target image.
  */
-static void SendDAC(struct comedi_device *dev, uint32_t val)
+static void s626_send_dac(struct comedi_device *dev, uint32_t val)
 {
        struct s626_private *devpriv = dev->private;
 
        /* START THE SERIAL CLOCK RUNNING ------------- */
 
-       /* Assert DAC polarity control and enable gating of DAC serial clock
+       /*
+        * Assert DAC polarity control and enable gating of DAC serial clock
         * and audio bit stream signals.  At this point in time we must be
         * assured of being in time slot 0.  If we are not in slot 0, the
         * serial clock and audio stream signals will be disabled; this is
-        * because the following DEBIwrite statement (which enables signals
-        * to be passed through the gate array) would execute before the
-        * trailing edge of WS1/WS3 (which turns off the signals), thus
+        * because the following s626_debi_write statement (which enables
+        * signals to be passed through the gate array) would execute before
+        * the trailing edge of WS1/WS3 (which turns off the signals), thus
         * causing the signals to be inactive during the DAC write.
         */
-       DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
+       s626_debi_write(dev, S626_LP_DACPOL, devpriv->dacpol);
 
        /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
 
        /* Copy DAC setpoint value to DAC's output DMA buffer. */
-
-       /* writel(val, devpriv->mmio + (uint32_t)devpriv->pDacWBuf); */
-       *devpriv->pDacWBuf = val;
+       /* writel(val, devpriv->mmio + (uint32_t)devpriv->dac_wbuf); */
+       *devpriv->dac_wbuf = val;
 
        /*
         * Enable the output DMA transfer. This will cause the DMAC to copy
@@ -362,56 +386,62 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * then immediately terminate because the protection address is
         * reached upon transfer of the first DWORD value.
         */
-       s626_mc_enable(dev, MC1_A2OUT, P_MC1);
+       s626_mc_enable(dev, S626_MC1_A2OUT, S626_P_MC1);
 
-       /*  While the DMA transfer is executing ... */
+       /* While the DMA transfer is executing ... */
 
        /*
         * Reset Audio2 output FIFO's underflow flag (along with any
         * other FIFO underflow/overflow flags). When set, this flag
         * will indicate that we have emerged from slot 0.
         */
-       writel(ISR_AFOU, devpriv->mmio + P_ISR);
+       writel(S626_ISR_AFOU, devpriv->mmio + S626_P_ISR);
 
-       /* Wait for the DMA transfer to finish so that there will be data
+       /*
+        * Wait for the DMA transfer to finish so that there will be data
         * available in the FIFO when time slot 1 tries to transfer a DWORD
         * from the FIFO to the output buffer register.  We test for DMA
         * Done by polling the DMAC enable flag; this flag is automatically
         * cleared when the transfer has finished.
         */
-       while (readl(devpriv->mmio + P_MC1) & MC1_A2OUT)
+       while (readl(devpriv->mmio + S626_P_MC1) & S626_MC1_A2OUT)
                ;
 
        /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
 
-       /* FIFO data is now available, so we enable execution of time slots
+       /*
+        * FIFO data is now available, so we enable execution of time slots
         * 1 and higher by clearing the EOS flag in slot 0.  Note that SD3
         * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
         * detection.
         */
-       writel(XSD2 | RSD3 | SIB_A2, devpriv->mmio + VECTPORT(0));
+       writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2,
+              devpriv->mmio + S626_VECTPORT(0));
 
-       /* Wait for slot 1 to execute to ensure that the Packet will be
+       /*
+        * Wait for slot 1 to execute to ensure that the Packet will be
         * transmitted.  This is detected by polling the Audio2 output FIFO
         * underflow flag, which will be set when slot 1 execution has
         * finished transferring the DAC's data DWORD from the output FIFO
         * to the output buffer register.
         */
-       while (!(readl(devpriv->mmio + P_SSR) & SSR_AF2_OUT))
+       while (!(readl(devpriv->mmio + S626_P_SSR) & S626_SSR_AF2_OUT))
                ;
 
-       /* Set up to trap execution at slot 0 when the TSL sequencer cycles
+       /*
+        * Set up to trap execution at slot 0 when the TSL sequencer cycles
         * back to slot 0 after executing the EOS in slot 5.  Also,
         * simultaneously shift out and in the 0x00 that is ALWAYS the value
         * stored in the last byte to be shifted out of the FIFO's DWORD
         * buffer register.
         */
-       writel(XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS,
-              devpriv->mmio + VECTPORT(0));
+       writel(S626_XSD2 | S626_XFIFO_2 | S626_RSD2 | S626_SIB_A2 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(0));
 
        /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
 
-       /* Wait for the TSL to finish executing all time slots before
+       /*
+        * Wait for the TSL to finish executing all time slots before
         * exiting this function.  We must do this so that the next DAC
         * write doesn't start, thereby enabling clock/chip select signals:
         *
@@ -428,17 +458,19 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         *    we test for the FB_BUFFER2 MSB contents to be equal to 0xFF.  If
         *    the TSL has not yet finished executing slot 5 ...
         */
-       if (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000) {
-               /* The trap was set on time and we are still executing somewhere
+       if (readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000) {
+               /*
+                * The trap was set on time and we are still executing somewhere
                 * in slots 2-5, so we now wait for slot 0 to execute and trap
                 * TSL execution.  This is detected when FB_BUFFER2 MSB changes
                 * from 0xFF to 0x00, which slot 0 causes to happen by shifting
                 * out/in on SD2 the 0x00 that is always referenced by slot 5.
                 */
-               while (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000)
+               while (readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000)
                        ;
        }
-       /* Either (1) we were too late setting the slot 0 trap; the TSL
+       /*
+        * Either (1) we were too late setting the slot 0 trap; the TSL
         * sequencer restarted slot 0 before we could set the EOS trap flag,
         * or (2) we were not late and execution is now trapped at slot 0.
         * In either case, we must now change slot 0 so that it will store
@@ -446,37 +478,46 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * In order to do this, we reprogram slot 0 so that it will shift in
         * SD3, which is driven only by a pull-up resistor.
         */
-       writel(RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0));
+       writel(S626_RSD3 | S626_SIB_A2 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(0));
 
-       /* Wait for slot 0 to execute, at which time the TSL is setup for
+       /*
+        * Wait for slot 0 to execute, at which time the TSL is setup for
         * the next DAC write.  This is detected when FB_BUFFER2 MSB changes
         * from 0x00 to 0xFF.
         */
-       while (!(readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000))
+       while (!(readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000))
                ;
 }
 
-/*  Private helper function: Write setpoint to an application DAC channel. */
-static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
+/*
+ * 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)
 {
        struct s626_private *devpriv = dev->private;
-       register uint16_t signmask;
-       register uint32_t WSImage;
+       uint16_t signmask;
+       uint32_t ws_image;
+       uint32_t val;
 
-       /*  Adjust DAC data polarity and set up Polarity Control Register */
-       /*  image. */
+       /*
+        * Adjust DAC data polarity and set up Polarity Control Register image.
+        */
        signmask = 1 << chan;
        if (dacdata < 0) {
                dacdata = -dacdata;
-               devpriv->Dacpol |= signmask;
-       } else
-               devpriv->Dacpol &= ~signmask;
+               devpriv->dacpol |= signmask;
+       } else {
+               devpriv->dacpol &= ~signmask;
+       }
 
-       /*  Limit DAC setpoint value to valid range. */
-       if ((uint16_t) dacdata > 0x1FFF)
+       /* Limit DAC setpoint value to valid range. */
+       if ((uint16_t)dacdata > 0x1FFF)
                dacdata = 0x1FFF;
 
-       /* Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
+       /*
+        * Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
         * and V3 transmit the setpoint to the target DAC.  V4 and V5 send
         * data to a non-existent TrimDac channel just to keep the clock
         * running after sending data to the target DAC.  This is necessary
@@ -487,140 +528,792 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
         */
 
        /* Choose DAC chip select to be asserted */
-       WSImage = (chan & 2) ? WS1 : WS2;
+       ws_image = (chan & 2) ? S626_WS1 : S626_WS2;
        /* Slot 2: Transmit high data byte to target DAC */
-       writel(XSD2 | XFIFO_1 | WSImage, devpriv->mmio + VECTPORT(2));
+       writel(S626_XSD2 | S626_XFIFO_1 | ws_image,
+              devpriv->mmio + S626_VECTPORT(2));
        /* Slot 3: Transmit low data byte to target DAC */
-       writel(XSD2 | XFIFO_0 | WSImage, devpriv->mmio + VECTPORT(3));
+       writel(S626_XSD2 | S626_XFIFO_0 | ws_image,
+              devpriv->mmio + S626_VECTPORT(3));
        /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
-       writel(XSD2 | XFIFO_3 | WS3, devpriv->mmio + VECTPORT(4));
+       writel(S626_XSD2 | S626_XFIFO_3 | S626_WS3,
+              devpriv->mmio + S626_VECTPORT(4));
        /* Slot 5: running after writing target DAC's low data byte */
-       writel(XSD2 | XFIFO_2 | WS3 | EOS, devpriv->mmio + VECTPORT(5));
+       writel(S626_XSD2 | S626_XFIFO_2 | S626_WS3 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(5));
 
-       /*  Construct and transmit target DAC's serial packet:
-        * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
+       /*
+        * Construct and transmit target DAC's serial packet:
+        * (A10D DDDD), (DDDD DDDD), (0x0F), (0x00) where A is chan<0>,
         * and D<12:0> is the DAC setpoint.  Append a WORD value (that writes
         * to a  non-existent TrimDac channel) that serves to keep the clock
         * running after the packet has been sent to the target DAC.
         */
-       SendDAC(dev, 0x0F000000
-               /* Continue clock after target DAC data (write to non-existent trimdac). */
-               | 0x00004000
-               /* Address the two main dual-DAC devices (TSL's chip select enables
-                * target device). */
-               | ((uint32_t) (chan & 1) << 15)
-               /*  Address the DAC channel within the  device. */
-               | (uint32_t) dacdata);  /*  Include DAC setpoint data. */
-
+       val = 0x0F000000;       /* Continue clock after target DAC data
+                                * (write to non-existent trimdac). */
+       val |= 0x00004000;      /* Address the two main dual-DAC devices
+                                * (TSL's chip select enables target device). */
+       val |= ((uint32_t)(chan & 1) << 15);    /* Address the DAC channel
+                                                * within the device. */
+       val |= (uint32_t)dacdata;       /* Include DAC setpoint data. */
+       s626_send_dac(dev, val);
 }
 
-static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
-                        uint8_t DacData)
+static void s626_write_trim_dac(struct comedi_device *dev, uint8_t logical_chan,
+                               uint8_t dac_data)
 {
        struct s626_private *devpriv = dev->private;
        uint32_t chan;
 
-       /*  Save the new setpoint in case the application needs to read it back later. */
-       devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
+       /*
+        * Save the new setpoint in case the application needs to read it back
+        * later.
+        */
+       devpriv->trim_setpoint[logical_chan] = (uint8_t)dac_data;
 
-       /*  Map logical channel number to physical channel number. */
-       chan = (uint32_t) trimchan[LogicalChan];
+       /* Map logical channel number to physical channel number. */
+       chan = s626_trimchan[logical_chan];
 
-       /* Set up TSL2 records for TrimDac write operation.  All slots shift
+       /*
+        * Set up TSL2 records for TrimDac write operation.  All slots shift
         * 0xFF in from pulled-up SD3 so that the end of the slot sequence
         * can be detected.
         */
 
        /* Slot 2: Send high uint8_t to target TrimDac */
-       writel(XSD2 | XFIFO_1 | WS3, devpriv->mmio + VECTPORT(2));
+       writel(S626_XSD2 | S626_XFIFO_1 | S626_WS3,
+              devpriv->mmio + S626_VECTPORT(2));
        /* Slot 3: Send low uint8_t to target TrimDac */
-       writel(XSD2 | XFIFO_0 | WS3, devpriv->mmio + VECTPORT(3));
+       writel(S626_XSD2 | S626_XFIFO_0 | S626_WS3,
+              devpriv->mmio + S626_VECTPORT(3));
        /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */
-       writel(XSD2 | XFIFO_3 | WS1, devpriv->mmio + VECTPORT(4));
+       writel(S626_XSD2 | S626_XFIFO_3 | S626_WS1,
+              devpriv->mmio + S626_VECTPORT(4));
        /* Slot 5: Send NOP low  uint8_t to DAC0 */
-       writel(XSD2 | XFIFO_2 | WS1 | EOS, devpriv->mmio + VECTPORT(5));
+       writel(S626_XSD2 | S626_XFIFO_2 | S626_WS1 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(5));
 
-       /* Construct and transmit target DAC's serial packet:
-        * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
+       /*
+        * Construct and transmit target DAC's serial packet:
+        * (0000 AAAA), (DDDD DDDD), (0x00), (0x00) where A<3:0> is the
         * DAC channel's address, and D<7:0> is the DAC setpoint.  Append a
         * WORD value (that writes a channel 0 NOP command to a non-existent
         * main DAC channel) that serves to keep the clock running after the
         * packet has been sent to the target DAC.
         */
 
-       /*  Address the DAC channel within the trimdac device. */
-       SendDAC(dev, ((uint32_t) chan << 8)
-               | (uint32_t) DacData);  /*  Include DAC setpoint data. */
+       /*
+        * Address the DAC channel within the trimdac device.
+        * Include DAC setpoint data.
+        */
+       s626_send_dac(dev, (chan << 8) | dac_data);
 }
 
-static void LoadTrimDACs(struct comedi_device *dev)
+static void s626_load_trim_dacs(struct comedi_device *dev)
 {
-       register uint8_t i;
+       uint8_t i;
 
-       /*  Copy TrimDac setpoint values from EEPROM to TrimDacs. */
-       for (i = 0; i < ARRAY_SIZE(trimchan); i++)
-               WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
+       /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */
+       for (i = 0; i < ARRAY_SIZE(s626_trimchan); i++)
+               s626_write_trim_dac(dev, i,
+                                   s626_i2c_read(dev, s626_trimadrs[i]));
 }
 
 /* ******  COUNTER FUNCTIONS  ******* */
-/* All counter functions address a specific counter by means of the
+
+/*
+ * All counter functions address a specific counter by means of the
  * "Counter" argument, which is a logical counter number.  The Counter
  * argument may have any of the following legal values: 0=0A, 1=1A,
  * 2=2A, 3=0B, 4=1B, 5=2B.
  */
 
-/*  Read a counter's output latch. */
-static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
+/*
+ * Read a counter's output latch.
+ */
+static uint32_t s626_read_latch(struct comedi_device *dev,
+                               const struct s626_enc_info *k)
 {
-       register uint32_t value;
+       uint32_t value;
 
-       /*  Latch counts and fetch LSW of latched counts value. */
-       value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
+       /* Latch counts and fetch LSW of latched counts value. */
+       value = s626_debi_read(dev, k->my_latch_lsw);
 
-       /*  Fetch MSW of latched counts and combine with LSW. */
-       value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
+       /* Fetch MSW of latched counts and combine with LSW. */
+       value |= ((uint32_t)s626_debi_read(dev, k->my_latch_lsw + 2) << 16);
 
-       /*  Return latched counts. */
+       /* Return latched counts. */
        return value;
 }
 
-/* Return/set a counter pair's latch trigger source.  0: On read
+/*
+ * Return/set a counter pair's latch trigger source.  0: On read
  * access, 1: A index latches A, 2: B index latches B, 3: A overflow
  * latches B.
  */
-static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
-                          uint16_t value)
+static void s626_set_latch_source(struct comedi_device *dev,
+                                 const struct s626_enc_info *k, uint16_t value)
 {
-       DEBIreplace(dev, k->MyCRB,
-                   ~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC),
-                   value << CRBBIT_LATCHSRC);
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_LATCHSRC),
+                         S626_SET_CRB_LATCHSRC(value));
 }
 
-/*  Write value into counter preload register. */
-static void Preload(struct comedi_device *dev, struct enc_private *k,
-                   uint32_t value)
+/*
+ * Write value into counter preload register.
+ */
+static void s626_preload(struct comedi_device *dev,
+                        const struct s626_enc_info *k, uint32_t value)
 {
-       DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value);
-       DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
-                 (uint16_t) (value >> 16));
+       s626_debi_write(dev, k->my_latch_lsw, value);
+       s626_debi_write(dev, k->my_latch_lsw + 2, value >> 16);
 }
 
-static unsigned int s626_ai_reg_to_uint(int data)
+/* ******  PRIVATE COUNTER FUNCTIONS ****** */
+
+/*
+ * Reset a counter's index and overflow event capture flags.
+ */
+static void s626_reset_cap_flags_a(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
 {
-       unsigned int tempdata;
+       s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
+                         (S626_SET_CRB_INTRESETCMD(1) |
+                          S626_SET_CRB_INTRESET_A(1)));
+}
 
-       tempdata = (data >> 18);
-       if (tempdata & 0x2000)
-               tempdata &= 0x1fff;
-       else
-               tempdata += (1 << 13);
+static void s626_reset_cap_flags_b(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
+                         (S626_SET_CRB_INTRESETCMD(1) |
+                          S626_SET_CRB_INTRESET_B(1)));
+}
+
+/*
+ * Return counter setup in a format (COUNTER_SETUP) that is consistent
+ * for both A and B counters.
+ */
+static uint16_t s626_get_mode_a(struct comedi_device *dev,
+                               const struct s626_enc_info *k)
+{
+       uint16_t cra;
+       uint16_t crb;
+       uint16_t setup;
+       unsigned cntsrc, clkmult, clkpol, encmode;
+
+       /* Fetch CRA and CRB register images. */
+       cra = s626_debi_read(dev, k->my_cra);
+       crb = s626_debi_read(dev, k->my_crb);
+
+       /*
+        * Populate the standardized counter setup bit fields.
+        */
+       setup =
+               /* LoadSrc  = LoadSrcA. */
+               S626_SET_STD_LOADSRC(S626_GET_CRA_LOADSRC_A(cra)) |
+               /* LatchSrc = LatchSrcA. */
+               S626_SET_STD_LATCHSRC(S626_GET_CRB_LATCHSRC(crb)) |
+               /* IntSrc   = IntSrcA. */
+               S626_SET_STD_INTSRC(S626_GET_CRA_INTSRC_A(cra)) |
+               /* IndxSrc  = IndxSrcA. */
+               S626_SET_STD_INDXSRC(S626_GET_CRA_INDXSRC_A(cra)) |
+               /* IndxPol  = IndxPolA. */
+               S626_SET_STD_INDXPOL(S626_GET_CRA_INDXPOL_A(cra)) |
+               /* ClkEnab  = ClkEnabA. */
+               S626_SET_STD_CLKENAB(S626_GET_CRB_CLKENAB_A(crb));
+
+       /* Adjust mode-dependent parameters. */
+       cntsrc = S626_GET_CRA_CNTSRC_A(cra);
+       if (cntsrc & S626_CNTSRC_SYSCLK) {
+               /* Timer mode (CntSrcA<1> == 1): */
+               encmode = S626_ENCMODE_TIMER;
+               /* Set ClkPol to indicate count direction (CntSrcA<0>). */
+               clkpol = cntsrc & 1;
+               /* ClkMult must be 1x in Timer mode. */
+               clkmult = S626_CLKMULT_1X;
+       } else {
+               /* Counter mode (CntSrcA<1> == 0): */
+               encmode = S626_ENCMODE_COUNTER;
+               /* Pass through ClkPol. */
+               clkpol = S626_GET_CRA_CLKPOL_A(cra);
+               /* Force ClkMult to 1x if not legal, else pass through. */
+               clkmult = S626_GET_CRA_CLKMULT_A(cra);
+               if (clkmult == S626_CLKMULT_SPECIAL)
+                       clkmult = S626_CLKMULT_1X;
+       }
+       setup |= S626_SET_STD_ENCMODE(encmode) | S626_SET_STD_CLKMULT(clkmult) |
+                S626_SET_STD_CLKPOL(clkpol);
+
+       /* Return adjusted counter setup. */
+       return setup;
+}
+
+static uint16_t s626_get_mode_b(struct comedi_device *dev,
+                               const struct s626_enc_info *k)
+{
+       uint16_t cra;
+       uint16_t crb;
+       uint16_t setup;
+       unsigned cntsrc, clkmult, clkpol, encmode;
 
-       return tempdata;
+       /* Fetch CRA and CRB register images. */
+       cra = s626_debi_read(dev, k->my_cra);
+       crb = s626_debi_read(dev, k->my_crb);
+
+       /*
+        * Populate the standardized counter setup bit fields.
+        */
+       setup =
+               /* IntSrc   = IntSrcB. */
+               S626_SET_STD_INTSRC(S626_GET_CRB_INTSRC_B(crb)) |
+               /* LatchSrc = LatchSrcB. */
+               S626_SET_STD_LATCHSRC(S626_GET_CRB_LATCHSRC(crb)) |
+               /* LoadSrc  = LoadSrcB. */
+               S626_SET_STD_LOADSRC(S626_GET_CRB_LOADSRC_B(crb)) |
+               /* IndxPol  = IndxPolB. */
+               S626_SET_STD_INDXPOL(S626_GET_CRB_INDXPOL_B(crb)) |
+               /* ClkEnab  = ClkEnabB. */
+               S626_SET_STD_CLKENAB(S626_GET_CRB_CLKENAB_B(crb)) |
+               /* IndxSrc  = IndxSrcB. */
+               S626_SET_STD_INDXSRC(S626_GET_CRA_INDXSRC_B(cra));
+
+       /* Adjust mode-dependent parameters. */
+       cntsrc = S626_GET_CRA_CNTSRC_B(cra);
+       clkmult = S626_GET_CRB_CLKMULT_B(crb);
+       if (clkmult == S626_CLKMULT_SPECIAL) {
+               /* Extender mode (ClkMultB == S626_CLKMULT_SPECIAL): */
+               encmode = S626_ENCMODE_EXTENDER;
+               /* Indicate multiplier is 1x. */
+               clkmult = S626_CLKMULT_1X;
+               /* Set ClkPol equal to Timer count direction (CntSrcB<0>). */
+               clkpol = cntsrc & 1;
+       } else if (cntsrc & S626_CNTSRC_SYSCLK) {
+               /* Timer mode (CntSrcB<1> == 1): */
+               encmode = S626_ENCMODE_TIMER;
+               /* Indicate multiplier is 1x. */
+               clkmult = S626_CLKMULT_1X;
+               /* Set ClkPol equal to Timer count direction (CntSrcB<0>). */
+               clkpol = cntsrc & 1;
+       } else {
+               /* If Counter mode (CntSrcB<1> == 0): */
+               encmode = S626_ENCMODE_COUNTER;
+               /* Clock multiplier is passed through. */
+               /* Clock polarity is passed through. */
+               clkpol = S626_GET_CRB_CLKPOL_B(crb);
+       }
+       setup |= S626_SET_STD_ENCMODE(encmode) | S626_SET_STD_CLKMULT(clkmult) |
+                S626_SET_STD_CLKPOL(clkpol);
+
+       /* Return adjusted counter setup. */
+       return setup;
 }
 
-/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */
-/*   return 0; */
-/* } */
+/*
+ * Set the operating mode for the specified counter.  The setup
+ * parameter is treated as a COUNTER_SETUP data type.  The following
+ * parameters are programmable (all other parms are ignored): ClkMult,
+ * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+ */
+static void s626_set_mode_a(struct comedi_device *dev,
+                           const struct s626_enc_info *k, uint16_t setup,
+                           uint16_t disable_int_src)
+{
+       struct s626_private *devpriv = dev->private;
+       uint16_t cra;
+       uint16_t crb;
+       unsigned cntsrc, clkmult, clkpol;
+
+       /* Initialize CRA and CRB images. */
+       /* Preload trigger is passed through. */
+       cra = S626_SET_CRA_LOADSRC_A(S626_GET_STD_LOADSRC(setup));
+       /* IndexSrc is passed through. */
+       cra |= S626_SET_CRA_INDXSRC_A(S626_GET_STD_INDXSRC(setup));
+
+       /* Reset any pending CounterA event captures. */
+       crb = S626_SET_CRB_INTRESETCMD(1) | S626_SET_CRB_INTRESET_A(1);
+       /* Clock enable is passed through. */
+       crb |= S626_SET_CRB_CLKENAB_A(S626_GET_STD_CLKENAB(setup));
+
+       /* Force IntSrc to Disabled if disable_int_src is asserted. */
+       if (!disable_int_src)
+               cra |= S626_SET_CRA_INTSRC_A(S626_GET_STD_INTSRC(setup));
+
+       /* Populate all mode-dependent attributes of CRA & CRB images. */
+       clkpol = S626_GET_STD_CLKPOL(setup);
+       switch (S626_GET_STD_ENCMODE(setup)) {
+       case S626_ENCMODE_EXTENDER: /* Extender Mode: */
+               /* Force to Timer mode (Extender valid only for B counters). */
+               /* Fall through to case S626_ENCMODE_TIMER: */
+       case S626_ENCMODE_TIMER:        /* Timer Mode: */
+               /* CntSrcA<1> selects system clock */
+               cntsrc = S626_CNTSRC_SYSCLK;
+               /* Count direction (CntSrcA<0>) obtained from ClkPol. */
+               cntsrc |= clkpol;
+               /* ClkPolA behaves as always-on clock enable. */
+               clkpol = 1;
+               /* ClkMult must be 1x. */
+               clkmult = S626_CLKMULT_1X;
+               break;
+       default:                /* Counter Mode: */
+               /* Select ENC_C and ENC_D as clock/direction inputs. */
+               cntsrc = S626_CNTSRC_ENCODER;
+               /* Clock polarity is passed through. */
+               /* Force multiplier to x1 if not legal, else pass through. */
+               clkmult = S626_GET_STD_CLKMULT(setup);
+               if (clkmult == S626_CLKMULT_SPECIAL)
+                       clkmult = S626_CLKMULT_1X;
+               break;
+       }
+       cra |= S626_SET_CRA_CNTSRC_A(cntsrc) | S626_SET_CRA_CLKPOL_A(clkpol) |
+              S626_SET_CRA_CLKMULT_A(clkmult);
+
+       /*
+        * Force positive index polarity if IndxSrc is software-driven only,
+        * otherwise pass it through.
+        */
+       if (S626_GET_STD_INDXSRC(setup) != S626_INDXSRC_SOFT)
+               cra |= S626_SET_CRA_INDXPOL_A(S626_GET_STD_INDXPOL(setup));
+
+       /*
+        * If IntSrc has been forced to Disabled, update the MISC2 interrupt
+        * enable mask to indicate the counter interrupt is disabled.
+        */
+       if (disable_int_src)
+               devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+
+       /*
+        * While retaining CounterB and LatchSrc configurations, program the
+        * new counter operating mode.
+        */
+       s626_debi_replace(dev, k->my_cra,
+                         S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B, cra);
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A), crb);
+}
+
+static void s626_set_mode_b(struct comedi_device *dev,
+                           const struct s626_enc_info *k, uint16_t setup,
+                           uint16_t disable_int_src)
+{
+       struct s626_private *devpriv = dev->private;
+       uint16_t cra;
+       uint16_t crb;
+       unsigned cntsrc, clkmult, clkpol;
+
+       /* Initialize CRA and CRB images. */
+       /* IndexSrc is passed through. */
+       cra = S626_SET_CRA_INDXSRC_B(S626_GET_STD_INDXSRC(setup));
+
+       /* Reset event captures and disable interrupts. */
+       crb = S626_SET_CRB_INTRESETCMD(1) | S626_SET_CRB_INTRESET_B(1);
+       /* Clock enable is passed through. */
+       crb |= S626_SET_CRB_CLKENAB_B(S626_GET_STD_CLKENAB(setup));
+       /* Preload trigger source is passed through. */
+       crb |= S626_SET_CRB_LOADSRC_B(S626_GET_STD_LOADSRC(setup));
+
+       /* Force IntSrc to Disabled if disable_int_src is asserted. */
+       if (!disable_int_src)
+               crb |= S626_SET_CRB_INTSRC_B(S626_GET_STD_INTSRC(setup));
+
+       /* Populate all mode-dependent attributes of CRA & CRB images. */
+       clkpol = S626_GET_STD_CLKPOL(setup);
+       switch (S626_GET_STD_ENCMODE(setup)) {
+       case S626_ENCMODE_TIMER:        /* Timer Mode: */
+               /* CntSrcB<1> selects system clock */
+               cntsrc = S626_CNTSRC_SYSCLK;
+               /* with direction (CntSrcB<0>) obtained from ClkPol. */
+               cntsrc |= clkpol;
+               /* ClkPolB behaves as always-on clock enable. */
+               clkpol = 1;
+               /* ClkMultB must be 1x. */
+               clkmult = S626_CLKMULT_1X;
+               break;
+       case S626_ENCMODE_EXTENDER:     /* Extender Mode: */
+               /* CntSrcB source is OverflowA (same as "timer") */
+               cntsrc = S626_CNTSRC_SYSCLK;
+               /* with direction obtained from ClkPol. */
+               cntsrc |= clkpol;
+               /* ClkPolB controls IndexB -- always set to active. */
+               clkpol = 1;
+               /* ClkMultB selects OverflowA as the clock source. */
+               clkmult = S626_CLKMULT_SPECIAL;
+               break;
+       default:                /* Counter Mode: */
+               /* Select ENC_C and ENC_D as clock/direction inputs. */
+               cntsrc = S626_CNTSRC_ENCODER;
+               /* ClkPol is passed through. */
+               /* Force ClkMult to x1 if not legal, otherwise pass through. */
+               clkmult = S626_GET_STD_CLKMULT(setup);
+               if (clkmult == S626_CLKMULT_SPECIAL)
+                       clkmult = S626_CLKMULT_1X;
+               break;
+       }
+       cra |= S626_SET_CRA_CNTSRC_B(cntsrc);
+       crb |= S626_SET_CRB_CLKPOL_B(clkpol) | S626_SET_CRB_CLKMULT_B(clkmult);
+
+       /*
+        * Force positive index polarity if IndxSrc is software-driven only,
+        * otherwise pass it through.
+        */
+       if (S626_GET_STD_INDXSRC(setup) != S626_INDXSRC_SOFT)
+               crb |= S626_SET_CRB_INDXPOL_B(S626_GET_STD_INDXPOL(setup));
+
+       /*
+        * If IntSrc has been forced to Disabled, update the MISC2 interrupt
+        * enable mask to indicate the counter interrupt is disabled.
+        */
+       if (disable_int_src)
+               devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+
+       /*
+        * While retaining CounterA and LatchSrc configurations, program the
+        * new counter operating mode.
+        */
+       s626_debi_replace(dev, k->my_cra,
+                         ~(S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B), cra);
+       s626_debi_replace(dev, k->my_crb,
+                         S626_CRBMSK_CLKENAB_A | S626_CRBMSK_LATCHSRC, crb);
+}
+
+/*
+ * Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index.
+ */
+static void s626_set_enable_a(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t enab)
+{
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A),
+                         S626_SET_CRB_CLKENAB_A(enab));
+}
+
+static void s626_set_enable_b(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t enab)
+{
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_B),
+                         S626_SET_CRB_CLKENAB_B(enab));
+}
+
+static uint16_t s626_get_enable_a(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return S626_GET_CRB_CLKENAB_A(s626_debi_read(dev, k->my_crb));
+}
+
+static uint16_t s626_get_enable_b(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return S626_GET_CRB_CLKENAB_B(s626_debi_read(dev, k->my_crb));
+}
+
+#ifdef unused
+static uint16_t s626_get_latch_source(struct comedi_device *dev,
+                                     const struct s626_enc_info *k)
+{
+       return S626_GET_CRB_LATCHSRC(s626_debi_read(dev, k->my_crb));
+}
+#endif
+
+/*
+ * Return/set the event that will trigger transfer of the preload
+ * register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
+ * 2=OverflowA (B counters only), 3=disabled.
+ */
+static void s626_set_load_trig_a(struct comedi_device *dev,
+                                const struct s626_enc_info *k, uint16_t trig)
+{
+       s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_LOADSRC_A,
+                         S626_SET_CRA_LOADSRC_A(trig));
+}
+
+static void s626_set_load_trig_b(struct comedi_device *dev,
+                                const struct s626_enc_info *k, uint16_t trig)
+{
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL),
+                         S626_SET_CRB_LOADSRC_B(trig));
+}
+
+static uint16_t s626_get_load_trig_a(struct comedi_device *dev,
+                                    const struct s626_enc_info *k)
+{
+       return S626_GET_CRA_LOADSRC_A(s626_debi_read(dev, k->my_cra));
+}
+
+static uint16_t s626_get_load_trig_b(struct comedi_device *dev,
+                                    const struct s626_enc_info *k)
+{
+       return S626_GET_CRB_LOADSRC_B(s626_debi_read(dev, k->my_crb));
+}
+
+/*
+ * Return/set counter interrupt source and clear any captured
+ * index/overflow events.  int_source: 0=Disabled, 1=OverflowOnly,
+ * 2=IndexOnly, 3=IndexAndOverflow.
+ */
+static void s626_set_int_src_a(struct comedi_device *dev,
+                              const struct s626_enc_info *k,
+                              uint16_t int_source)
+{
+       struct s626_private *devpriv = dev->private;
+
+       /* Reset any pending counter overflow or index captures. */
+       s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
+                         (S626_SET_CRB_INTRESETCMD(1) |
+                          S626_SET_CRB_INTRESET_A(1)));
+
+       /* Program counter interrupt source. */
+       s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_INTSRC_A,
+                         S626_SET_CRA_INTSRC_A(int_source));
+
+       /* Update MISC2 interrupt enable mask. */
+       devpriv->counter_int_enabs =
+           (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
+           k->my_event_bits[int_source];
+}
+
+static void s626_set_int_src_b(struct comedi_device *dev,
+                              const struct s626_enc_info *k,
+                              uint16_t int_source)
+{
+       struct s626_private *devpriv = dev->private;
+       uint16_t crb;
+
+       /* Cache writeable CRB register image. */
+       crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
+
+       /* Reset any pending counter overflow or index captures. */
+       s626_debi_write(dev, k->my_crb, (crb | S626_SET_CRB_INTRESETCMD(1) |
+                                        S626_SET_CRB_INTRESET_B(1)));
+
+       /* Program counter interrupt source. */
+       s626_debi_write(dev, k->my_crb, ((crb & ~S626_CRBMSK_INTSRC_B) |
+                                        S626_SET_CRB_INTSRC_B(int_source)));
+
+       /* Update MISC2 interrupt enable mask. */
+       devpriv->counter_int_enabs =
+               (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
+               k->my_event_bits[int_source];
+}
+
+static uint16_t s626_get_int_src_a(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return S626_GET_CRA_INTSRC_A(s626_debi_read(dev, k->my_cra));
+}
+
+static uint16_t s626_get_int_src_b(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return S626_GET_CRB_INTSRC_B(s626_debi_read(dev, k->my_crb));
+}
+
+#ifdef unused
+/*
+ * Return/set the clock multiplier.
+ */
+static void s626_set_clk_mult(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKMULT) |
+                            S626_SET_STD_CLKMULT(value)), false);
+}
+
+static uint16_t s626_get_clk_mult(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return S626_GET_STD_CLKMULT(k->get_mode(dev, k));
+}
+
+/*
+ * Return/set the clock polarity.
+ */
+static void s626_set_clk_pol(struct comedi_device *dev,
+                            const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKPOL) |
+                            S626_SET_STD_CLKPOL(value)), false);
+}
+
+static uint16_t s626_get_clk_pol(struct comedi_device *dev,
+                                const struct s626_enc_info *k)
+{
+       return S626_GET_STD_CLKPOL(k->get_mode(dev, k));
+}
+
+/*
+ * Return/set the encoder mode.
+ */
+static void s626_set_enc_mode(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_ENCMODE) |
+                            S626_SET_STD_ENCMODE(value)), false);
+}
+
+static uint16_t s626_get_enc_mode(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return S626_GET_STD_ENCMODE(k->get_mode(dev, k));
+}
+
+/*
+ * Return/set the index polarity.
+ */
+static void s626_set_index_pol(struct comedi_device *dev,
+                              const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXPOL) |
+                            S626_SET_STD_INDXPOL(value != 0)), false);
+}
+
+static uint16_t s626_get_index_pol(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return S626_GET_STD_INDXPOL(k->get_mode(dev, k));
+}
+
+/*
+ * Return/set the index source.
+ */
+static void s626_set_index_src(struct comedi_device *dev,
+                              const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXSRC) |
+                            S626_SET_STD_INDXSRC(value != 0)), false);
+}
+
+static uint16_t s626_get_index_src(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return S626_GET_STD_INDXSRC(k->get_mode(dev, k));
+}
+#endif
+
+/*
+ * Generate an index pulse.
+ */
+static void s626_pulse_index_a(struct comedi_device *dev,
+                              const struct s626_enc_info *k)
+{
+       uint16_t cra;
+
+       cra = s626_debi_read(dev, k->my_cra);
+       /* Pulse index. */
+       s626_debi_write(dev, k->my_cra, (cra ^ S626_CRAMSK_INDXPOL_A));
+       s626_debi_write(dev, k->my_cra, cra);
+}
+
+static void s626_pulse_index_b(struct comedi_device *dev,
+                              const struct s626_enc_info *k)
+{
+       uint16_t crb;
+
+       crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
+       /* Pulse index. */
+       s626_debi_write(dev, k->my_crb, (crb ^ S626_CRBMSK_INDXPOL_B));
+       s626_debi_write(dev, k->my_crb, crb);
+}
+
+static const struct s626_enc_info s626_enc_chan_info[] = {
+       {
+               .get_enable             = s626_get_enable_a,
+               .get_int_src            = s626_get_int_src_a,
+               .get_load_trig          = s626_get_load_trig_a,
+               .get_mode               = s626_get_mode_a,
+               .pulse_index            = s626_pulse_index_a,
+               .set_enable             = s626_set_enable_a,
+               .set_int_src            = s626_set_int_src_a,
+               .set_load_trig          = s626_set_load_trig_a,
+               .set_mode               = s626_set_mode_a,
+               .reset_cap_flags        = s626_reset_cap_flags_a,
+               .my_cra                 = S626_LP_CR0A,
+               .my_crb                 = S626_LP_CR0B,
+               .my_latch_lsw           = S626_LP_CNTR0ALSW,
+               .my_event_bits          = S626_EVBITS(0),
+       }, {
+               .get_enable             = s626_get_enable_a,
+               .get_int_src            = s626_get_int_src_a,
+               .get_load_trig          = s626_get_load_trig_a,
+               .get_mode               = s626_get_mode_a,
+               .pulse_index            = s626_pulse_index_a,
+               .set_enable             = s626_set_enable_a,
+               .set_int_src            = s626_set_int_src_a,
+               .set_load_trig          = s626_set_load_trig_a,
+               .set_mode               = s626_set_mode_a,
+               .reset_cap_flags        = s626_reset_cap_flags_a,
+               .my_cra                 = S626_LP_CR1A,
+               .my_crb                 = S626_LP_CR1B,
+               .my_latch_lsw           = S626_LP_CNTR1ALSW,
+               .my_event_bits          = S626_EVBITS(1),
+       }, {
+               .get_enable             = s626_get_enable_a,
+               .get_int_src            = s626_get_int_src_a,
+               .get_load_trig          = s626_get_load_trig_a,
+               .get_mode               = s626_get_mode_a,
+               .pulse_index            = s626_pulse_index_a,
+               .set_enable             = s626_set_enable_a,
+               .set_int_src            = s626_set_int_src_a,
+               .set_load_trig          = s626_set_load_trig_a,
+               .set_mode               = s626_set_mode_a,
+               .reset_cap_flags        = s626_reset_cap_flags_a,
+               .my_cra                 = S626_LP_CR2A,
+               .my_crb                 = S626_LP_CR2B,
+               .my_latch_lsw           = S626_LP_CNTR2ALSW,
+               .my_event_bits          = S626_EVBITS(2),
+       }, {
+               .get_enable             = s626_get_enable_b,
+               .get_int_src            = s626_get_int_src_b,
+               .get_load_trig          = s626_get_load_trig_b,
+               .get_mode               = s626_get_mode_b,
+               .pulse_index            = s626_pulse_index_b,
+               .set_enable             = s626_set_enable_b,
+               .set_int_src            = s626_set_int_src_b,
+               .set_load_trig          = s626_set_load_trig_b,
+               .set_mode               = s626_set_mode_b,
+               .reset_cap_flags        = s626_reset_cap_flags_b,
+               .my_cra                 = S626_LP_CR0A,
+               .my_crb                 = S626_LP_CR0B,
+               .my_latch_lsw           = S626_LP_CNTR0BLSW,
+               .my_event_bits          = S626_EVBITS(3),
+       }, {
+               .get_enable             = s626_get_enable_b,
+               .get_int_src            = s626_get_int_src_b,
+               .get_load_trig          = s626_get_load_trig_b,
+               .get_mode               = s626_get_mode_b,
+               .pulse_index            = s626_pulse_index_b,
+               .set_enable             = s626_set_enable_b,
+               .set_int_src            = s626_set_int_src_b,
+               .set_load_trig          = s626_set_load_trig_b,
+               .set_mode               = s626_set_mode_b,
+               .reset_cap_flags        = s626_reset_cap_flags_b,
+               .my_cra                 = S626_LP_CR1A,
+               .my_crb                 = S626_LP_CR1B,
+               .my_latch_lsw           = S626_LP_CNTR1BLSW,
+               .my_event_bits          = S626_EVBITS(4),
+       }, {
+               .get_enable             = s626_get_enable_b,
+               .get_int_src            = s626_get_int_src_b,
+               .get_load_trig          = s626_get_load_trig_b,
+               .get_mode               = s626_get_mode_b,
+               .pulse_index            = s626_pulse_index_b,
+               .set_enable             = s626_set_enable_b,
+               .set_int_src            = s626_set_int_src_b,
+               .set_load_trig          = s626_set_load_trig_b,
+               .set_mode               = s626_set_mode_b,
+               .reset_cap_flags        = s626_reset_cap_flags_b,
+               .my_cra                 = S626_LP_CR2A,
+               .my_crb                 = S626_LP_CR2B,
+               .my_latch_lsw           = S626_LP_CNTR2BLSW,
+               .my_event_bits          = S626_EVBITS(5),
+       },
+};
+
+static unsigned int s626_ai_reg_to_uint(unsigned int data)
+{
+       return ((data >> 18) & 0x3fff) ^ 0x2000;
+}
 
 static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
 {
@@ -629,19 +1322,19 @@ static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
        unsigned int status;
 
        /* set channel to capture positive edge */
-       status = DEBIread(dev, LP_RDEDGSEL(group));
-       DEBIwrite(dev, LP_WREDGSEL(group), mask | status);
+       status = s626_debi_read(dev, S626_LP_RDEDGSEL(group));
+       s626_debi_write(dev, S626_LP_WREDGSEL(group), mask | status);
 
        /* enable interrupt on selected channel */
-       status = DEBIread(dev, LP_RDINTSEL(group));
-       DEBIwrite(dev, LP_WRINTSEL(group), mask | status);
+       status = s626_debi_read(dev, S626_LP_RDINTSEL(group));
+       s626_debi_write(dev, S626_LP_WRINTSEL(group), mask | status);
 
        /* enable edge capture write command */
-       DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_EDCAP);
 
        /* enable edge capture on selected channel */
-       status = DEBIread(dev, LP_RDCAPSEL(group));
-       DEBIwrite(dev, LP_WRCAPSEL(group), mask | status);
+       status = s626_debi_read(dev, S626_LP_RDCAPSEL(group));
+       s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask | status);
 
        return 0;
 }
@@ -650,10 +1343,10 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
                              unsigned int mask)
 {
        /* disable edge capture write command */
-       DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
 
        /* enable edge capture on selected channel */
-       DEBIwrite(dev, LP_WRCAPSEL(group), mask);
+       s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask);
 
        return 0;
 }
@@ -663,17 +1356,17 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
        unsigned int group;
 
        /* disable edge capture write command */
-       DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
 
        /* clear all dio pending events and interrupt */
        for (group = 0; group < S626_DIO_BANKS; group++)
-               DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
+               s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff);
 
        return 0;
 }
 
-static void handle_dio_interrupt(struct comedi_device *dev,
-                                uint16_t irqbit, uint8_t group)
+static void s626_handle_dio_interrupt(struct comedi_device *dev,
+                                     uint16_t irqbit, uint8_t group)
 {
        struct s626_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
@@ -686,7 +1379,7 @@ static void handle_dio_interrupt(struct comedi_device *dev,
                if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 &&
                    cmd->start_src == TRIG_EXT) {
                        /* Start executing the RPS program */
-                       s626_mc_enable(dev, MC1_ERPS1, P_MC1);
+                       s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
                        if (cmd->scan_begin_src == TRIG_EXT)
                                s626_dio_set_irq(dev, cmd->scan_begin_arg);
@@ -694,7 +1387,7 @@ static void handle_dio_interrupt(struct comedi_device *dev,
                if ((irqbit >> (cmd->scan_begin_arg - (16 * group))) == 1 &&
                    cmd->scan_begin_src == TRIG_EXT) {
                        /* Trigger ADC scan loop start */
-                       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
 
                        if (cmd->convert_src == TRIG_EXT) {
                                devpriv->ai_convert_count = cmd->chanlist_len;
@@ -703,16 +1396,17 @@ static void handle_dio_interrupt(struct comedi_device *dev,
                        }
 
                        if (cmd->convert_src == TRIG_TIMER) {
-                               struct enc_private *k = &encpriv[5];
+                               const struct s626_enc_info *k =
+                                       &s626_enc_chan_info[5];
 
                                devpriv->ai_convert_count = cmd->chanlist_len;
-                               k->SetEnable(dev, k, CLKENAB_ALWAYS);
+                               k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
                        }
                }
                if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 &&
                    cmd->convert_src == TRIG_EXT) {
                        /* Trigger ADC scan loop start */
-                       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
 
                        devpriv->ai_convert_count--;
                        if (devpriv->ai_convert_count > 0)
@@ -721,7 +1415,7 @@ static void handle_dio_interrupt(struct comedi_device *dev,
        }
 }
 
-static void check_dio_interrupts(struct comedi_device *dev)
+static void s626_check_dio_interrupts(struct comedi_device *dev)
 {
        uint16_t irqbit;
        uint8_t group;
@@ -729,90 +1423,91 @@ static void check_dio_interrupts(struct comedi_device *dev)
        for (group = 0; group < S626_DIO_BANKS; group++) {
                irqbit = 0;
                /* read interrupt type */
-               irqbit = DEBIread(dev, LP_RDCAPFLG(group));
+               irqbit = s626_debi_read(dev, S626_LP_RDCAPFLG(group));
 
                /* check if interrupt is generated from dio channels */
                if (irqbit) {
-                       handle_dio_interrupt(dev, irqbit, group);
+                       s626_handle_dio_interrupt(dev, irqbit, group);
                        return;
                }
        }
 }
 
-static void check_counter_interrupts(struct comedi_device *dev)
+static void s626_check_counter_interrupts(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
        struct comedi_async *async = s->async;
        struct comedi_cmd *cmd = &async->cmd;
-       struct enc_private *k;
+       const struct s626_enc_info *k;
        uint16_t irqbit;
 
        /* read interrupt type */
-       irqbit = DEBIread(dev, LP_RDMISC2);
+       irqbit = s626_debi_read(dev, S626_LP_RDMISC2);
 
        /* check interrupt on counters */
-       if (irqbit & IRQ_COINT1A) {
-               k = &encpriv[0];
+       if (irqbit & S626_IRQ_COINT1A) {
+               k = &s626_enc_chan_info[0];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT2A) {
-               k = &encpriv[1];
+       if (irqbit & S626_IRQ_COINT2A) {
+               k = &s626_enc_chan_info[1];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT3A) {
-               k = &encpriv[2];
+       if (irqbit & S626_IRQ_COINT3A) {
+               k = &s626_enc_chan_info[2];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT1B) {
-               k = &encpriv[3];
+       if (irqbit & S626_IRQ_COINT1B) {
+               k = &s626_enc_chan_info[3];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT2B) {
-               k = &encpriv[4];
+       if (irqbit & S626_IRQ_COINT2B) {
+               k = &s626_enc_chan_info[4];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
 
                if (devpriv->ai_convert_count > 0) {
                        devpriv->ai_convert_count--;
                        if (devpriv->ai_convert_count == 0)
-                               k->SetEnable(dev, k, CLKENAB_INDEX);
+                               k->set_enable(dev, k, S626_CLKENAB_INDEX);
 
                        if (cmd->convert_src == TRIG_TIMER) {
                                /* Trigger ADC scan loop start */
-                               s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                               s626_mc_enable(dev, S626_MC2_ADC_RPS,
+                                              S626_P_MC2);
                        }
                }
        }
-       if (irqbit & IRQ_COINT3B) {
-               k = &encpriv[5];
+       if (irqbit & S626_IRQ_COINT3B) {
+               k = &s626_enc_chan_info[5];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
 
                if (cmd->scan_begin_src == TRIG_TIMER) {
                        /* Trigger ADC scan loop start */
-                       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
                }
 
                if (cmd->convert_src == TRIG_TIMER) {
-                       k = &encpriv[4];
+                       k = &s626_enc_chan_info[4];
                        devpriv->ai_convert_count = cmd->chanlist_len;
-                       k->SetEnable(dev, k, CLKENAB_ALWAYS);
+                       k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
                }
        }
 }
 
-static bool handle_eos_interrupt(struct comedi_device *dev)
+static bool s626_handle_eos_interrupt(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
@@ -823,19 +1518,19 @@ static bool handle_eos_interrupt(struct comedi_device *dev)
         * first uint16_t in the buffer because it contains junk data
         * from the final ADC of the previous poll list scan.
         */
-       int32_t *readaddr = (int32_t *)devpriv->ANABuf.LogicalBase + 1;
+       uint32_t *readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1;
        bool finished = false;
        int i;
 
        /* get the data and hand it over to comedi */
        for (i = 0; i < cmd->chanlist_len; i++) {
-               short tempdata;
+               unsigned short tempdata;
 
                /*
                 * Convert ADC data to 16-bit integer values and copy
                 * to application buffer.
                 */
-               tempdata = s626_ai_reg_to_uint((int)*readaddr);
+               tempdata = s626_ai_reg_to_uint(*readaddr);
                readaddr++;
 
                /* put data into read buffer */
@@ -846,13 +1541,13 @@ static bool handle_eos_interrupt(struct comedi_device *dev)
        /* end of scan occurs */
        async->events |= COMEDI_CB_EOS;
 
-       if (!devpriv->ai_continous)
+       if (!devpriv->ai_continuous)
                devpriv->ai_sample_count--;
        if (devpriv->ai_sample_count <= 0) {
                devpriv->ai_cmd_running = 0;
 
                /* Stop RPS program */
-               s626_mc_disable(dev, MC1_ERPS1, P_MC1);
+               s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
                /* send end of acquisition */
                async->events |= COMEDI_CB_EOA;
@@ -879,229 +1574,238 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 
        if (!dev->attached)
                return IRQ_NONE;
-       /*  lock to avoid race with comedi_poll */
+       /* lock to avoid race with comedi_poll */
        spin_lock_irqsave(&dev->spinlock, flags);
 
        /* save interrupt enable register state */
-       irqstatus = readl(devpriv->mmio + P_IER);
+       irqstatus = readl(devpriv->mmio + S626_P_IER);
 
        /* read interrupt type */
-       irqtype = readl(devpriv->mmio + P_ISR);
+       irqtype = readl(devpriv->mmio + S626_P_ISR);
 
        /* disable master interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        /* clear interrupt */
-       writel(irqtype, devpriv->mmio + P_ISR);
+       writel(irqtype, devpriv->mmio + S626_P_ISR);
 
        switch (irqtype) {
-       case IRQ_RPS1:          /*  end_of_scan occurs */
-               if (handle_eos_interrupt(dev))
+       case S626_IRQ_RPS1:     /* end_of_scan occurs */
+               if (s626_handle_eos_interrupt(dev))
                        irqstatus = 0;
                break;
-       case IRQ_GPIO3: /* check dio and conter interrupt */
+       case S626_IRQ_GPIO3:    /* check dio and counter interrupt */
                /* s626_dio_clear_irq(dev); */
-               check_dio_interrupts(dev);
-               check_counter_interrupts(dev);
+               s626_check_dio_interrupts(dev);
+               s626_check_counter_interrupts(dev);
                break;
        }
 
        /* enable interrupt */
-       writel(irqstatus, devpriv->mmio + P_IER);
+       writel(irqstatus, devpriv->mmio + S626_P_IER);
 
        spin_unlock_irqrestore(&dev->spinlock, flags);
        return IRQ_HANDLED;
 }
 
 /*
- * this functions build the RPS program for hardware driven acquistion
+ * This function builds the RPS program for hardware driven acquisition.
  */
-static void ResetADC(struct comedi_device *dev, uint8_t *ppl)
+static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl)
 {
        struct s626_private *devpriv = dev->private;
-       register uint32_t *pRPS;
-       uint32_t JmpAdrs;
+       uint32_t *rps;
+       uint32_t jmp_adrs;
        uint16_t i;
        uint16_t n;
-       uint32_t LocalPPL;
-       struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
+       uint32_t local_ppl;
+       struct comedi_cmd *cmd = &dev->subdevices->async->cmd;
 
        /* Stop RPS program in case it is currently running */
-       s626_mc_disable(dev, MC1_ERPS1, P_MC1);
+       s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
-       /*  Set starting logical address to write RPS commands. */
-       pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
+       /* Set starting logical address to write RPS commands. */
+       rps = (uint32_t *)devpriv->rps_buf.logical_base;
 
        /* Initialize RPS instruction pointer */
-       writel((uint32_t)devpriv->RPSBuf.PhysicalBase,
-              devpriv->mmio + P_RPSADDR1);
-
-       /*  Construct RPS program in RPSBuf DMA buffer */
+       writel((uint32_t)devpriv->rps_buf.physical_base,
+              devpriv->mmio + S626_P_RPSADDR1);
 
+       /* Construct RPS program in rps_buf DMA buffer */
        if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
-               /*  Wait for Start trigger. */
-               *pRPS++ = RPS_PAUSE | RPS_SIGADC;
-               *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
+               /* Wait for Start trigger. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC;
+               *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC;
        }
 
-       /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
+       /*
+        * SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
         * because the first RPS DEBI Write following a non-RPS DEBI write
         * seems to always fail.  If we don't do this dummy write, the ADC
         * gain might not be set to the value required for the first slot in
         * the poll list; the ADC gain would instead remain unchanged from
         * the previously programmed value.
         */
-       *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
        /* Write DEBI Write command and address to shadow RAM. */
+       *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
+       *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_GSEL;
+       *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
+       /* Write DEBI immediate data  to shadow RAM: */
+       *rps++ = S626_GSEL_BIPOLAR5V;   /* arbitrary immediate data  value. */
+       *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
+       /* Reset "shadow RAM  uploaded" flag. */
+       /* Invoke shadow RAM upload. */
+       *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
+       /* Wait for shadow upload to finish. */
+       *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
 
-       *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
-       *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
-       /*  Write DEBI immediate data  to shadow RAM: */
-
-       *pRPS++ = GSEL_BIPOLAR5V;
-       /*  arbitrary immediate data  value. */
-
-       *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
-       /*  Reset "shadow RAM  uploaded" flag. */
-       *pRPS++ = RPS_UPLOAD | RPS_DEBI;        /*  Invoke shadow RAM upload. */
-       *pRPS++ = RPS_PAUSE | RPS_DEBI; /*  Wait for shadow upload to finish. */
-
-       /* Digitize all slots in the poll list. This is implemented as a
+       /*
+        * Digitize all slots in the poll list. This is implemented as a
         * for loop to limit the slot count to 16 in case the application
-        * forgot to set the EOPL flag in the final slot.
+        * forgot to set the S626_EOPL flag in the final slot.
         */
-       for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
-               /* Convert application's poll list item to private board class
+       for (devpriv->adc_items = 0; devpriv->adc_items < 16;
+            devpriv->adc_items++) {
+               /*
+                * Convert application's poll list item to private board class
                 * format.  Each app poll list item is an uint8_t with form
                 * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
                 * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
                 */
-               LocalPPL =
-                   (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
-                                  GSEL_BIPOLAR10V);
-
-               /*  Switch ADC analog gain. */
-               *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /*  Write DEBI command */
-               /*  and address to */
-               /*  shadow RAM. */
-               *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
-               *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);  /*  Write DEBI */
-               /*  immediate data to */
-               /*  shadow RAM. */
-               *pRPS++ = LocalPPL;
-               *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;     /*  Reset "shadow RAM uploaded" */
-               /*  flag. */
-               *pRPS++ = RPS_UPLOAD | RPS_DEBI;        /*  Invoke shadow RAM upload. */
-               *pRPS++ = RPS_PAUSE | RPS_DEBI; /*  Wait for shadow upload to */
-               /*  finish. */
-
-               /*  Select ADC analog input channel. */
-               *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
-               /*  Write DEBI command and address to  shadow RAM. */
-               *pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
-               *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
-               /*  Write DEBI immediate data to shadow RAM. */
-               *pRPS++ = LocalPPL;
-               *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
-               /*  Reset "shadow RAM uploaded"  flag. */
-
-               *pRPS++ = RPS_UPLOAD | RPS_DEBI;
-               /*  Invoke shadow RAM upload. */
-
-               *pRPS++ = RPS_PAUSE | RPS_DEBI;
-               /*  Wait for shadow upload to finish. */
-
-               /* Delay at least 10 microseconds for analog input settling.
-                * Instead of padding with NOPs, we use RPS_JUMP instructions
-                * here; this allows us to produce a longer delay than is
-                * possible with NOPs because each RPS_JUMP flushes the RPS'
-                * instruction prefetch pipeline.
+               local_ppl = (*ppl << 8) | (*ppl & 0x10 ? S626_GSEL_BIPOLAR5V :
+                                          S626_GSEL_BIPOLAR10V);
+
+               /* Switch ADC analog gain. */
+               /* Write DEBI command and address to shadow RAM. */
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
+               *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_GSEL;
+               /* Write DEBI immediate data to shadow RAM. */
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
+               *rps++ = local_ppl;
+               /* Reset "shadow RAM uploaded" flag. */
+               *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
+               /* Invoke shadow RAM upload. */
+               *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
+               /* Wait for shadow upload to finish. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
+               /* Select ADC analog input channel. */
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
+               /* Write DEBI command and address to shadow RAM. */
+               *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_ISEL;
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
+               /* Write DEBI immediate data to shadow RAM. */
+               *rps++ = local_ppl;
+               /* Reset "shadow RAM uploaded" flag. */
+               *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
+               /* Invoke shadow RAM upload. */
+               *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
+               /* Wait for shadow upload to finish. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
+
+               /*
+                * Delay at least 10 microseconds for analog input settling.
+                * Instead of padding with NOPs, we use S626_RPS_JUMP
+                * instructions here; this allows us to produce a longer delay
+                * than is possible with NOPs because each S626_RPS_JUMP
+                * flushes the RPS' instruction prefetch pipeline.
                 */
-               JmpAdrs =
-                   (uint32_t) devpriv->RPSBuf.PhysicalBase +
-                   (uint32_t) ((unsigned long)pRPS -
-                               (unsigned long)devpriv->RPSBuf.LogicalBase);
-               for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
-                       JmpAdrs += 8;   /*  Repeat to implement time delay: */
-                       *pRPS++ = RPS_JUMP;     /*  Jump to next RPS instruction. */
-                       *pRPS++ = JmpAdrs;
+               jmp_adrs =
+                       (uint32_t)devpriv->rps_buf.physical_base +
+                       (uint32_t)((unsigned long)rps -
+                                  (unsigned long)devpriv->
+                                                 rps_buf.logical_base);
+               for (i = 0; i < (10 * S626_RPSCLK_PER_US / 2); i++) {
+                       jmp_adrs += 8;  /* Repeat to implement time delay: */
+                       /* Jump to next RPS instruction. */
+                       *rps++ = S626_RPS_JUMP;
+                       *rps++ = jmp_adrs;
                }
 
                if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
-                       /*  Wait for Start trigger. */
-                       *pRPS++ = RPS_PAUSE | RPS_SIGADC;
-                       *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
+                       /* Wait for Start trigger. */
+                       *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC;
+                       *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC;
                }
-               /*  Start ADC by pulsing GPIO1. */
-               *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  Begin ADC Start pulse. */
-               *pRPS++ = GPIO_BASE | GPIO1_LO;
-               *pRPS++ = RPS_NOP;
-               /*  VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
-               *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  End ADC Start pulse. */
-               *pRPS++ = GPIO_BASE | GPIO1_HI;
-
-               /* Wait for ADC to complete (GPIO2 is asserted high when ADC not
+               /* Start ADC by pulsing GPIO1. */
+               /* Begin ADC Start pulse. */
+               *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
+               *rps++ = S626_GPIO_BASE | S626_GPIO1_LO;
+               *rps++ = S626_RPS_NOP;
+               /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+               /* End ADC Start pulse. */
+               *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
+               *rps++ = S626_GPIO_BASE | S626_GPIO1_HI;
+               /*
+                * Wait for ADC to complete (GPIO2 is asserted high when ADC not
                 * busy) and for data from previous conversion to shift into FB
                 * BUFFER 1 register.
                 */
-               *pRPS++ = RPS_PAUSE | RPS_GPIO2;        /*  Wait for ADC done. */
-
-               /*  Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
-               *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
-               *pRPS++ =
-                   (uint32_t) devpriv->ANABuf.PhysicalBase +
-                   (devpriv->AdcItems << 2);
-
-               /*  If this slot's EndOfPollList flag is set, all channels have */
-               /*  now been processed. */
-               if (*ppl++ & EOPL) {
-                       devpriv->AdcItems++;    /*  Adjust poll list item count. */
-                       break;  /*  Exit poll list processing loop. */
+               /* Wait for ADC done. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_GPIO2;
+
+               /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
+               *rps++ = S626_RPS_STREG |
+                        (S626_BUGFIX_STREG(S626_P_FB_BUFFER1) >> 2);
+               *rps++ = (uint32_t)devpriv->ana_buf.physical_base +
+                        (devpriv->adc_items << 2);
+
+               /*
+                * If this slot's EndOfPollList flag is set, all channels have
+                * now been processed.
+                */
+               if (*ppl++ & S626_EOPL) {
+                       devpriv->adc_items++; /* Adjust poll list item count. */
+                       break;  /* Exit poll list processing loop. */
                }
        }
 
-       /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
+       /*
+        * VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
         * ADC to stabilize for 2 microseconds before starting the final
         * (dummy) conversion.  This delay is necessary to allow sufficient
         * time between last conversion finished and the start of the dummy
         * conversion.  Without this delay, the last conversion's data value
         * is sometimes set to the previous conversion's data value.
         */
-       for (n = 0; n < (2 * RPSCLK_PER_US); n++)
-               *pRPS++ = RPS_NOP;
+       for (n = 0; n < (2 * S626_RPSCLK_PER_US); n++)
+               *rps++ = S626_RPS_NOP;
 
-       /* Start a dummy conversion to cause the data from the last
+       /*
+        * Start a dummy conversion to cause the data from the last
         * conversion of interest to be shifted in.
         */
-       *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  Begin ADC Start pulse. */
-       *pRPS++ = GPIO_BASE | GPIO1_LO;
-       *pRPS++ = RPS_NOP;
+       /* Begin ADC Start pulse. */
+       *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
+       *rps++ = S626_GPIO_BASE | S626_GPIO1_LO;
+       *rps++ = S626_RPS_NOP;
        /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
-       *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  End ADC Start pulse. */
-       *pRPS++ = GPIO_BASE | GPIO1_HI;
+       *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2); /* End ADC Start pulse. */
+       *rps++ = S626_GPIO_BASE | S626_GPIO1_HI;
 
-       /* Wait for the data from the last conversion of interest to arrive
+       /*
+        * Wait for the data from the last conversion of interest to arrive
         * in FB BUFFER 1 register.
         */
-       *pRPS++ = RPS_PAUSE | RPS_GPIO2;        /*  Wait for ADC done. */
+       *rps++ = S626_RPS_PAUSE | S626_RPS_GPIO2;       /* Wait for ADC done. */
 
-       /*  Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
-       *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);        /*  */
-       *pRPS++ =
-           (uint32_t) devpriv->ANABuf.PhysicalBase + (devpriv->AdcItems << 2);
+       /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
+       *rps++ = S626_RPS_STREG | (S626_BUGFIX_STREG(S626_P_FB_BUFFER1) >> 2);
+       *rps++ = (uint32_t)devpriv->ana_buf.physical_base +
+                (devpriv->adc_items << 2);
 
-       /*  Indicate ADC scan loop is finished. */
-       /*  *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ;  // Signal ReadADC() that scan is done. */
+       /* Indicate ADC scan loop is finished. */
+       /* Signal ReadADC() that scan is done. */
+       /* *rps++= S626_RPS_CLRSIGNAL | S626_RPS_SIGADC; */
 
        /* invoke interrupt */
-       if (devpriv->ai_cmd_running == 1) {
-               *pRPS++ = RPS_IRQ;
-       }
-       /*  Restart RPS program at its beginning. */
-       *pRPS++ = RPS_JUMP;     /*  Branch to start of RPS program. */
-       *pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
+       if (devpriv->ai_cmd_running == 1)
+               *rps++ = S626_RPS_IRQ;
+
+       /* Restart RPS program at its beginning. */
+       *rps++ = S626_RPS_JUMP; /* Branch to start of RPS program. */
+       *rps++ = (uint32_t)devpriv->rps_buf.physical_base;
 
-       /*  End of RPS program build */
+       /* End of RPS program build */
 }
 
 #ifdef unused_code
@@ -1111,14 +1815,14 @@ static int s626_ai_rinsn(struct comedi_device *dev,
                         unsigned int *data)
 {
        struct s626_private *devpriv = dev->private;
-       register uint8_t i;
-       register int32_t *readaddr;
+       uint8_t i;
+       int32_t *readaddr;
 
        /* Trigger ADC scan loop start */
-       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
 
        /* Wait until ADC scan loop is finished (RPS Signal 0 reset) */
-       while (s626_mc_test(dev, MC2_ADC_RPS, P_MC2))
+       while (s626_mc_test(dev, S626_MC2_ADC_RPS, S626_P_MC2))
                ;
 
        /*
@@ -1126,13 +1830,13 @@ static int s626_ai_rinsn(struct comedi_device *dev,
         * first uint16_t in the buffer because it contains junk data from
         * the final ADC of the previous poll list scan.
         */
-       readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1;
+       readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1;
 
        /*
         * Convert ADC data to 16-bit integer values and
         * copy to application buffer.
         */
-       for (i = 0; i < devpriv->AdcItems; i++) {
+       for (i = 0; i < devpriv->adc_items; i++) {
                *data = s626_ai_reg_to_uint(*readaddr++);
                data++;
        }
@@ -1148,55 +1852,61 @@ static int s626_ai_insn_read(struct comedi_device *dev,
        struct s626_private *devpriv = dev->private;
        uint16_t chan = CR_CHAN(insn->chanspec);
        uint16_t range = CR_RANGE(insn->chanspec);
-       uint16_t AdcSpec = 0;
-       uint32_t GpioImage;
-       int tmp;
+       uint16_t adc_spec = 0;
+       uint32_t gpio_image;
+       uint32_t tmp;
        int n;
 
-       /* Convert application's ADC specification into form
+       /*
+        * Convert application's ADC specification into form
         *  appropriate for register programming.
         */
        if (range == 0)
-               AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
+               adc_spec = (chan << 8) | (S626_GSEL_BIPOLAR5V);
        else
-               AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
+               adc_spec = (chan << 8) | (S626_GSEL_BIPOLAR10V);
 
-       /*  Switch ADC analog gain. */
-       DEBIwrite(dev, LP_GSEL, AdcSpec);       /*  Set gain. */
+       /* Switch ADC analog gain. */
+       s626_debi_write(dev, S626_LP_GSEL, adc_spec);   /* Set gain. */
 
-       /*  Select ADC analog input channel. */
-       DEBIwrite(dev, LP_ISEL, AdcSpec);       /*  Select channel. */
+       /* Select ADC analog input channel. */
+       s626_debi_write(dev, S626_LP_ISEL, adc_spec);   /* Select channel. */
 
        for (n = 0; n < insn->n; n++) {
-
-               /*  Delay 10 microseconds for analog input settling. */
+               /* Delay 10 microseconds for analog input settling. */
                udelay(10);
 
                /* Start ADC by pulsing GPIO1 low */
-               GpioImage = readl(devpriv->mmio + P_GPIO);
+               gpio_image = readl(devpriv->mmio + S626_P_GPIO);
                /* Assert ADC Start command */
-               writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+               writel(gpio_image & ~S626_GPIO1_HI,
+                      devpriv->mmio + S626_P_GPIO);
                /* and stretch it out */
-               writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
-               writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+               writel(gpio_image & ~S626_GPIO1_HI,
+                      devpriv->mmio + S626_P_GPIO);
+               writel(gpio_image & ~S626_GPIO1_HI,
+                      devpriv->mmio + S626_P_GPIO);
                /* Negate ADC Start command */
-               writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO);
+               writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
 
-               /*  Wait for ADC to complete (GPIO2 is asserted high when */
-               /*  ADC not busy) and for data from previous conversion to */
-               /*  shift into FB BUFFER 1 register. */
+               /*
+                * Wait for ADC to complete (GPIO2 is asserted high when
+                * ADC not busy) and for data from previous conversion to
+                * shift into FB BUFFER 1 register.
+                */
 
                /* Wait for ADC done */
-               while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2))
+               while (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_GPIO2))
                        ;
 
                /* Fetch ADC data */
                if (n != 0) {
-                       tmp = readl(devpriv->mmio + P_FB_BUFFER1);
+                       tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
                        data[n - 1] = s626_ai_reg_to_uint(tmp);
                }
 
-               /* Allow the ADC to stabilize for 4 microseconds before
+               /*
+                * Allow the ADC to stabilize for 4 microseconds before
                 * starting the next (final) conversion.  This delay is
                 * necessary to allow sufficient time between last
                 * conversion finished and the start of the next
@@ -1207,28 +1917,30 @@ static int s626_ai_insn_read(struct comedi_device *dev,
                udelay(4);
        }
 
-       /* Start a dummy conversion to cause the data from the
-        * previous conversion to be shifted in. */
-       GpioImage = readl(devpriv->mmio + P_GPIO);
+       /*
+        * Start a dummy conversion to cause the data from the
+        * previous conversion to be shifted in.
+        */
+       gpio_image = readl(devpriv->mmio + S626_P_GPIO);
        /* Assert ADC Start command */
-       writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
        /* and stretch it out */
-       writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
-       writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+       writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
        /* Negate ADC Start command */
-       writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
 
-       /*  Wait for the data to arrive in FB BUFFER 1 register. */
+       /* Wait for the data to arrive in FB BUFFER 1 register. */
 
        /* Wait for ADC done */
-       while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2))
+       while (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_GPIO2))
                ;
 
-       /*  Fetch ADC data from audio interface's input shift register. */
+       /* Fetch ADC data from audio interface's input shift register. */
 
        /* Fetch ADC data */
        if (n != 0) {
-               tmp = readl(devpriv->mmio + P_FB_BUFFER1);
+               tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
                data[n - 1] = s626_ai_reg_to_uint(tmp);
        }
 
@@ -1237,17 +1949,16 @@ static int s626_ai_insn_read(struct comedi_device *dev,
 
 static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
 {
-
        int n;
 
        for (n = 0; n < cmd->chanlist_len; n++) {
-               if (CR_RANGE((cmd->chanlist)[n]) == 0)
-                       ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V);
+               if (CR_RANGE(cmd->chanlist[n]) == 0)
+                       ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_5V;
                else
-                       ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V);
+                       ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_10V;
        }
        if (n != 0)
-               ppl[n - 1] |= EOPL;
+               ppl[n - 1] |= S626_EOPL;
 
        return n;
 }
@@ -1259,18 +1970,20 @@ static int s626_ai_inttrig(struct comedi_device *dev,
                return -EINVAL;
 
        /* Start executing the RPS program */
-       s626_mc_enable(dev, MC1_ERPS1, P_MC1);
+       s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
        s->async->inttrig = NULL;
 
        return 1;
 }
 
-/* This function doesn't require a particular form, this is just what
+/*
+ * This function doesn't require a particular form, this is just what
  * happens to be used in some of the drivers.  It should convert ns
  * nanoseconds to a counter value suitable for programming the device.
  * Also, it should adjust ns so that it cooresponds to the actual time
- * that the device will use. */
+ * that the device will use.
+ */
 static int s626_ns_to_timer(int *nanosec, int round_mode)
 {
        int divider, base;
@@ -1294,68 +2007,75 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
        return divider - 1;
 }
 
-static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
-                           int tick)
+static void s626_timer_load(struct comedi_device *dev,
+                           const struct s626_enc_info *k, int tick)
 {
-       uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
-           /*  index. */
-           (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
-           (CLKSRC_TIMER << BF_CLKSRC) |       /*  Operating mode is Timer. */
-           (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
-           (CNTDIR_DOWN << BF_CLKPOL) |        /*  Count direction is Down. */
-           (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
-           (CLKENAB_INDEX << BF_CLKENAB);
-       uint16_t valueSrclatch = LATCHSRC_A_INDXA;
-       /*   uint16_t enab=CLKENAB_ALWAYS; */
+       uint16_t setup =
+               /* Preload upon index. */
+               S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
+               /* Disable hardware index. */
+               S626_SET_STD_INDXSRC(S626_INDXSRC_SOFT) |
+               /* Operating mode is Timer. */
+               S626_SET_STD_ENCMODE(S626_ENCMODE_TIMER) |
+               /* Count direction is Down. */
+               S626_SET_STD_CLKPOL(S626_CNTDIR_DOWN) |
+               /* Clock multiplier is 1x. */
+               S626_SET_STD_CLKMULT(S626_CLKMULT_1X) |
+               /* Enabled by index */
+               S626_SET_STD_CLKENAB(S626_CLKENAB_INDEX);
+       uint16_t value_latchsrc = S626_LATCHSRC_A_INDXA;
+       /* uint16_t enab = S626_CLKENAB_ALWAYS; */
 
-       k->SetMode(dev, k, Setup, FALSE);
+       k->set_mode(dev, k, setup, false);
 
-       /*  Set the preload register */
-       Preload(dev, k, tick);
+       /* Set the preload register */
+       s626_preload(dev, k, tick);
 
-       /*  Software index pulse forces the preload register to load */
-       /*  into the counter */
-       k->SetLoadTrig(dev, k, 0);
-       k->PulseIndex(dev, k);
+       /*
+        * Software index pulse forces the preload register to load
+        * into the counter
+        */
+       k->set_load_trig(dev, k, 0);
+       k->pulse_index(dev, k);
 
        /* set reload on counter overflow */
-       k->SetLoadTrig(dev, k, 1);
+       k->set_load_trig(dev, k, 1);
 
        /* set interrupt on overflow */
-       k->SetIntSrc(dev, k, INTSRC_OVER);
+       k->set_int_src(dev, k, S626_INTSRC_OVER);
 
-       SetLatchSource(dev, k, valueSrclatch);
-       /*   k->SetEnable(dev,k,(uint16_t)(enab != 0)); */
+       s626_set_latch_source(dev, k, value_latchsrc);
+       /* k->set_enable(dev, k, (uint16_t)(enab != 0)); */
 }
 
-/*  TO COMPLETE  */
+/* TO COMPLETE  */
 static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct s626_private *devpriv = dev->private;
        uint8_t ppl[16];
        struct comedi_cmd *cmd = &s->async->cmd;
-       struct enc_private *k;
+       const struct s626_enc_info *k;
        int tick;
 
        if (devpriv->ai_cmd_running) {
-               printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n",
-                      dev->minor);
+               dev_err(dev->class_dev,
+                       "s626_ai_cmd: Another ai_cmd is running\n");
                return -EBUSY;
        }
        /* disable interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        /* clear interrupt request */
-       writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->mmio + P_ISR);
+       writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, devpriv->mmio + S626_P_ISR);
 
        /* clear any pending interrupt */
        s626_dio_clear_irq(dev);
-       /*   s626_enc_clear_irq(dev); */
+       /* s626_enc_clear_irq(dev); */
 
        /* reset ai_cmd_running flag */
        devpriv->ai_cmd_running = 0;
 
-       /*  test if cmd is valid */
+       /* test if cmd is valid */
        if (cmd == NULL)
                return -EINVAL;
 
@@ -1373,17 +2093,20 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        case TRIG_FOLLOW:
                break;
        case TRIG_TIMER:
-               /*  set a conter to generate adc trigger at scan_begin_arg interval */
-               k = &encpriv[5];
+               /*
+                * set a counter to generate adc trigger at scan_begin_arg
+                * interval
+                */
+               k = &s626_enc_chan_info[5];
                tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
                                        cmd->flags & TRIG_ROUND_MASK);
 
                /* load timer value and enable interrupt */
                s626_timer_load(dev, k, tick);
-               k->SetEnable(dev, k, CLKENAB_ALWAYS);
+               k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
                break;
        case TRIG_EXT:
-               /*  set the digital line and interrupt for scan trigger */
+               /* set the digital line and interrupt for scan trigger */
                if (cmd->start_src != TRIG_EXT)
                        s626_dio_set_irq(dev, cmd->scan_begin_arg);
                break;
@@ -1393,52 +2116,53 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        case TRIG_NOW:
                break;
        case TRIG_TIMER:
-               /*  set a conter to generate adc trigger at convert_arg interval */
-               k = &encpriv[4];
+               /*
+                * set a counter to generate adc trigger at convert_arg
+                * interval
+                */
+               k = &s626_enc_chan_info[4];
                tick = s626_ns_to_timer((int *)&cmd->convert_arg,
                                        cmd->flags & TRIG_ROUND_MASK);
 
                /* load timer value and enable interrupt */
                s626_timer_load(dev, k, tick);
-               k->SetEnable(dev, k, CLKENAB_INDEX);
+               k->set_enable(dev, k, S626_CLKENAB_INDEX);
                break;
        case TRIG_EXT:
-               /*  set the digital line and interrupt for convert trigger */
-               if (cmd->scan_begin_src != TRIG_EXT
-                   && cmd->start_src == TRIG_EXT)
+               /* set the digital line and interrupt for convert trigger */
+               if (cmd->scan_begin_src != TRIG_EXT &&
+                   cmd->start_src == TRIG_EXT)
                        s626_dio_set_irq(dev, cmd->convert_arg);
                break;
        }
 
        switch (cmd->stop_src) {
        case TRIG_COUNT:
-               /*  data arrives as one packet */
+               /* data arrives as one packet */
                devpriv->ai_sample_count = cmd->stop_arg;
-               devpriv->ai_continous = 0;
+               devpriv->ai_continuous = 0;
                break;
        case TRIG_NONE:
-               /*  continous acquisition */
-               devpriv->ai_continous = 1;
+               /* continuous acquisition */
+               devpriv->ai_continuous = 1;
                devpriv->ai_sample_count = 1;
                break;
        }
 
-       ResetADC(dev, ppl);
+       s626_reset_adc(dev, ppl);
 
        switch (cmd->start_src) {
        case TRIG_NOW:
                /* Trigger ADC scan loop start */
-               /* s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); */
+               /* s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2); */
 
                /* Start executing the RPS program */
-               s626_mc_enable(dev, MC1_ERPS1, P_MC1);
-
+               s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
                s->async->inttrig = NULL;
                break;
        case TRIG_EXT:
                /* configure DIO channel for acquisition trigger */
                s626_dio_set_irq(dev, cmd->start_arg);
-
                s->async->inttrig = NULL;
                break;
        case TRIG_INT:
@@ -1447,7 +2171,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        }
 
        /* enable interrupt */
-       writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->mmio + P_IER);
+       writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, devpriv->mmio + S626_P_IER);
 
        return 0;
 }
@@ -1461,11 +2185,11 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
        /* Step 1 : check if triggers are trivially valid */
 
        err |= cfc_check_trigger_src(&cmd->start_src,
-                                       TRIG_NOW | TRIG_INT | TRIG_EXT);
+                                    TRIG_NOW | TRIG_INT | TRIG_EXT);
        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
-                                       TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW);
+                                    TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW);
        err |= cfc_check_trigger_src(&cmd->convert_src,
-                                       TRIG_TIMER | TRIG_EXT | TRIG_NOW);
+                                    TRIG_TIMER | TRIG_EXT | TRIG_NOW);
        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 
@@ -1490,34 +2214,34 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
                err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        if (cmd->start_src == TRIG_EXT)
                err |= cfc_check_trigger_arg_max(&cmd->start_arg, 39);
-
        if (cmd->scan_begin_src == TRIG_EXT)
                err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 39);
-
        if (cmd->convert_src == TRIG_EXT)
                err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 39);
 
-#define MAX_SPEED      200000  /* in nanoseconds */
-#define MIN_SPEED      2000000000      /* in nanoseconds */
+#define S626_MAX_SPEED 200000  /* in nanoseconds */
+#define S626_MIN_SPEED 2000000000      /* in nanoseconds */
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
-                                                MAX_SPEED);
+                                                S626_MAX_SPEED);
                err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
-                                                MIN_SPEED);
+                                                S626_MIN_SPEED);
        } else {
                /* external trigger */
                /* should be level/edge, hi/lo specification here */
                /* should specify multiple external triggers */
-/*             err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
+               /* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
        }
        if (cmd->convert_src == TRIG_TIMER) {
-               err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
-               err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED);
+               err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+                                                S626_MAX_SPEED);
+               err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
+                                                S626_MIN_SPEED);
        } else {
                /* external trigger */
                /* see above */
-/*             err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
+               /* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
        }
 
        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
@@ -1546,10 +2270,10 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
                if (tmp != cmd->convert_arg)
                        err++;
                if (cmd->scan_begin_src == TRIG_TIMER &&
-                   cmd->scan_begin_arg <
-                   cmd->convert_arg * cmd->scan_end_arg) {
-                       cmd->scan_begin_arg =
-                           cmd->convert_arg * cmd->scan_end_arg;
+                   cmd->scan_begin_arg < cmd->convert_arg *
+                                         cmd->scan_end_arg) {
+                       cmd->scan_begin_arg = cmd->convert_arg *
+                                             cmd->scan_end_arg;
                        err++;
                }
        }
@@ -1565,10 +2289,10 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
        struct s626_private *devpriv = dev->private;
 
        /* Stop RPS program in case it is currently running */
-       s626_mc_disable(dev, MC1_ERPS1, P_MC1);
+       s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
        /* disable master interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        devpriv->ai_cmd_running = 0;
 
@@ -1588,7 +2312,7 @@ static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
                devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[i];
                dacdata -= (0x1fff);
 
-               SetDAC(dev, chan, dacdata);
+               s626_set_dac(dev, chan, dacdata);
        }
 
        return i;
@@ -1606,7 +2330,9 @@ static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
        return i;
 }
 
-/* *************** DIGITAL I/O FUNCTIONS ***************
+/* *************** DIGITAL I/O FUNCTIONS *************** */
+
+/*
  * All DIO functions address a group of DIO channels by means of
  * "group" argument.  group may be 0, 1 or 2, which correspond to DIO
  * ports A, B and C, respectively.
@@ -1616,19 +2342,19 @@ static void s626_dio_init(struct comedi_device *dev)
 {
        uint16_t group;
 
-       /*  Prepare to treat writes to WRCapSel as capture disables. */
-       DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
+       /* Prepare to treat writes to WRCapSel as capture disables. */
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
 
-       /*  For each group of sixteen channels ... */
+       /* For each group of sixteen channels ... */
        for (group = 0; group < S626_DIO_BANKS; group++) {
                /* Disable all interrupts */
-               DEBIwrite(dev, LP_WRINTSEL(group), 0);
+               s626_debi_write(dev, S626_LP_WRINTSEL(group), 0);
                /* Disable all event captures */
-               DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
+               s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff);
                /* Init all DIOs to default edge polarity */
-               DEBIwrite(dev, LP_WREDGSEL(group), 0);
+               s626_debi_write(dev, S626_LP_WREDGSEL(group), 0);
                /* Program all outputs to inactive state */
-               DEBIwrite(dev, LP_WRDOUT(group), 0);
+               s626_debi_write(dev, S626_LP_WRDOUT(group), 0);
        }
 }
 
@@ -1638,20 +2364,11 @@ static int s626_dio_insn_bits(struct comedi_device *dev,
                              unsigned int *data)
 {
        unsigned long group = (unsigned long)s->private;
-       unsigned long mask = data[0];
-       unsigned long bits = data[1];
 
-       if (mask) {
-               /* Check if requested channels are configured for output */
-               if ((s->io_bits & mask) != mask)
-                       return -EIO;
+       if (comedi_dio_update_state(s, data))
+               s626_debi_write(dev, S626_LP_WRDOUT(group), s->state);
 
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
-               DEBIwrite(dev, LP_WRDOUT(group), s->state);
-       }
-       data[1] = DEBIread(dev, LP_RDDIN(group));
+       data[1] = s626_debi_read(dev, S626_LP_RDDIN(group));
 
        return insn->n;
 }
@@ -1668,42 +2385,51 @@ static int s626_dio_insn_config(struct comedi_device *dev,
        if (ret)
                return ret;
 
-       DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
+       s626_debi_write(dev, S626_LP_WRDOUT(group), s->io_bits);
 
        return insn->n;
 }
 
-/* Now this function initializes the value of the counter (data[0])
-   and set the subdevice. To complete with trigger and interrupt
-   configuration */
-/* FIXME: data[0] is supposed to be an INSN_CONFIG_xxx constant indicating
+/*
+ * Now this function initializes the value of the counter (data[0])
+ * and set the subdevice. To complete with trigger and interrupt
+ * configuration.
+ *
+ * FIXME: data[0] is supposed to be an INSN_CONFIG_xxx constant indicating
  * what is being configured, but this function appears to be using data[0]
- * as a variable. */
+ * as a variable.
+ */
 static int s626_enc_insn_config(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
 {
-       uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
-           /*  index. */
-           (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
-           (CLKSRC_COUNTER << BF_CLKSRC) |     /*  Operating mode is Counter. */
-           (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
-           /* ( CNTDIR_UP << BF_CLKPOL ) |      // Count direction is Down. */
-           (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
-           (CLKENAB_INDEX << BF_CLKENAB);
-       /*   uint16_t DisableIntSrc=TRUE; */
-       /*  uint32_t Preloadvalue;              //Counter initial value */
-       uint16_t valueSrclatch = LATCHSRC_AB_READ;
-       uint16_t enab = CLKENAB_ALWAYS;
-       struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
-
-       /*   (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
-
-       k->SetMode(dev, k, Setup, TRUE);
-       Preload(dev, k, data[0]);
-       k->PulseIndex(dev, k);
-       SetLatchSource(dev, k, valueSrclatch);
-       k->SetEnable(dev, k, (uint16_t) (enab != 0));
+       uint16_t setup =
+               /* Preload upon index. */
+               S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
+               /* Disable hardware index. */
+               S626_SET_STD_INDXSRC(S626_INDXSRC_SOFT) |
+               /* Operating mode is Counter. */
+               S626_SET_STD_ENCMODE(S626_ENCMODE_COUNTER) |
+               /* Active high clock. */
+               S626_SET_STD_CLKPOL(S626_CLKPOL_POS) |
+               /* Clock multiplier is 1x. */
+               S626_SET_STD_CLKMULT(S626_CLKMULT_1X) |
+               /* Enabled by index */
+               S626_SET_STD_CLKENAB(S626_CLKENAB_INDEX);
+       /* uint16_t disable_int_src = true; */
+       /* uint32_t Preloadvalue;              //Counter initial value */
+       uint16_t value_latchsrc = S626_LATCHSRC_AB_READ;
+       uint16_t enab = S626_CLKENAB_ALWAYS;
+       const struct s626_enc_info *k =
+               &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
+
+       /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
+
+       k->set_mode(dev, k, setup, true);
+       s626_preload(dev, k, data[0]);
+       k->pulse_index(dev, k);
+       s626_set_latch_source(dev, k, value_latchsrc);
+       k->set_enable(dev, k, (enab != 0));
 
        return insn->n;
 }
@@ -1712,12 +2438,12 @@ static int s626_enc_insn_read(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn, unsigned int *data)
 {
-
        int n;
-       struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+       const struct s626_enc_info *k =
+               &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
 
        for (n = 0; n < insn->n; n++)
-               data[n] = ReadLatch(dev, k);
+               data[n] = s626_read_latch(dev, k);
 
        return n;
 }
@@ -1726,31 +2452,32 @@ static int s626_enc_insn_write(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data)
 {
+       const struct s626_enc_info *k =
+               &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
 
-       struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+       /* Set the preload register */
+       s626_preload(dev, k, data[0]);
 
-       /*  Set the preload register */
-       Preload(dev, k, data[0]);
-
-       /*  Software index pulse forces the preload register to load */
-       /*  into the counter */
-       k->SetLoadTrig(dev, k, 0);
-       k->PulseIndex(dev, k);
-       k->SetLoadTrig(dev, k, 2);
+       /*
+        * Software index pulse forces the preload register to load
+        * into the counter
+        */
+       k->set_load_trig(dev, k, 0);
+       k->pulse_index(dev, k);
+       k->set_load_trig(dev, k, 2);
 
        return 1;
 }
 
-static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
+static void s626_write_misc2(struct comedi_device *dev, uint16_t new_image)
 {
-       DEBIwrite(dev, LP_MISC1, MISC1_WENABLE);        /*  enab writes to */
-       /*  MISC2 register. */
-       DEBIwrite(dev, LP_WRMISC2, NewImage);   /*  Write new image to MISC2. */
-       DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE);       /*  Disable writes to MISC2. */
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_WENABLE);
+       s626_debi_write(dev, S626_LP_WRMISC2, new_image);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_WDISABLE);
 }
 
-static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
-                     size_t bsize)
+static void s626_close_dma_b(struct comedi_device *dev,
+                            struct s626_buffer_dma *pdma, size_t bsize)
 {
        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
        void *vbptr;
@@ -1758,554 +2485,44 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
 
        if (pdma == NULL)
                return;
-       /* find the matching allocation from the board struct */
 
-       vbptr = pdma->LogicalBase;
-       vpptr = pdma->PhysicalBase;
+       /* find the matching allocation from the board struct */
+       vbptr = pdma->logical_base;
+       vpptr = pdma->physical_base;
        if (vbptr) {
                pci_free_consistent(pcidev, bsize, vbptr, vpptr);
-               pdma->LogicalBase = NULL;
-               pdma->PhysicalBase = 0;
-       }
-}
-
-/* ******  PRIVATE COUNTER FUNCTIONS ****** */
-
-/*  Reset a counter's index and overflow event capture flags. */
-
-static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
-{
-       DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
-                   CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
-}
-
-static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
-{
-       DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
-                   CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
-}
-
-/*  Return counter setup in a format (COUNTER_SETUP) that is consistent */
-/*  for both A and B counters. */
-
-static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup;
-
-       /*  Fetch CRA and CRB register images. */
-       cra = DEBIread(dev, k->MyCRA);
-       crb = DEBIread(dev, k->MyCRB);
-
-       /*  Populate the standardized counter setup bit fields.  Note: */
-       /*  IndexSrc is restricted to ENC_X or IndxPol. */
-       setup = ((cra & STDMSK_LOADSRC) /*  LoadSrc  = LoadSrcA. */
-                |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)      /*  LatchSrc = LatchSrcA. */
-                |((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC)  /*  IntSrc   = IntSrcA. */
-                |((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /*  IndxSrc  = IndxSrcA<1>. */
-                |((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL)       /*  IndxPol  = IndxPolA. */
-                |((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB));     /*  ClkEnab  = ClkEnabA. */
-
-       /*  Adjust mode-dependent parameters. */
-       if (cra & (2 << CRABIT_CLKSRC_A))       /*  If Timer mode (ClkSrcA<1> == 1): */
-               setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)       /*    Indicate Timer mode. */
-                         |((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /*    Set ClkPol to indicate count direction (ClkSrcA<0>). */
-                         |(MULT_X1 << STDBIT_CLKMULT));        /*    ClkMult must be 1x in Timer mode. */
-
-       else                    /*  If Counter mode (ClkSrcA<1> == 0): */
-               setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)     /*    Indicate Counter mode. */
-                         |((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /*    Pass through ClkPol. */
-                         |(((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ?       /*    Force ClkMult to 1x if not legal, else pass through. */
-                           (MULT_X1 << STDBIT_CLKMULT) :
-                           ((cra >> (CRABIT_CLKMULT_A -
-                                     STDBIT_CLKMULT)) & STDMSK_CLKMULT)));
-
-       /*  Return adjusted counter setup. */
-       return setup;
-}
-
-static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup;
-
-       /*  Fetch CRA and CRB register images. */
-       cra = DEBIread(dev, k->MyCRA);
-       crb = DEBIread(dev, k->MyCRB);
-
-       /*  Populate the standardized counter setup bit fields.  Note: */
-       /*  IndexSrc is restricted to ENC_X or IndxPol. */
-       setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC)   /*  IntSrc   = IntSrcB. */
-                |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)      /*  LatchSrc = LatchSrcB. */
-                |((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC)       /*  LoadSrc  = LoadSrcB. */
-                |((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL)       /*  IndxPol  = IndxPolB. */
-                |((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB)       /*  ClkEnab  = ClkEnabB. */
-                |((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC));       /*  IndxSrc  = IndxSrcB<1>. */
-
-       /*  Adjust mode-dependent parameters. */
-       if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B))  /*  If Extender mode (ClkMultB == MULT_X0): */
-               setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC)    /*    Indicate Extender mode. */
-                         |(MULT_X1 << STDBIT_CLKMULT)  /*    Indicate multiplier is 1x. */
-                         |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));       /*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
-
-       else if (cra & (2 << CRABIT_CLKSRC_B))  /*  If Timer mode (ClkSrcB<1> == 1): */
-               setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)       /*    Indicate Timer mode. */
-                         |(MULT_X1 << STDBIT_CLKMULT)  /*    Indicate multiplier is 1x. */
-                         |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));       /*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
-
-       else                    /*  If Counter mode (ClkSrcB<1> == 0): */
-               setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)     /*    Indicate Timer mode. */
-                         |((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT)      /*    Clock multiplier is passed through. */
-                         |((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL));       /*    Clock polarity is passed through. */
-
-       /*  Return adjusted counter setup. */
-       return setup;
-}
-
-/*
- * Set the operating mode for the specified counter.  The setup
- * parameter is treated as a COUNTER_SETUP data type.  The following
- * parameters are programmable (all other parms are ignored): ClkMult,
- * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
- */
-
-static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
-                     uint16_t Setup, uint16_t DisableIntSrc)
-{
-       struct s626_private *devpriv = dev->private;
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup = Setup;        /*  Cache the Standard Setup. */
-
-       /*  Initialize CRA and CRB images. */
-       cra = ((setup & CRAMSK_LOADSRC_A)       /*  Preload trigger is passed through. */
-              |((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))));       /*  IndexSrc is restricted to ENC_X or IndxPol. */
-
-       crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A   /*  Reset any pending CounterA event captures. */
-              | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));    /*  Clock enable is passed through. */
-
-       /*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
-       if (!DisableIntSrc)
-               cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
-                                                   CRABIT_INTSRC_A));
-
-       /*  Populate all mode-dependent attributes of CRA & CRB images. */
-       switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
-       case CLKSRC_EXTENDER:   /*  Extender Mode: Force to Timer mode */
-               /*  (Extender valid only for B counters). */
-
-       case CLKSRC_TIMER:      /*  Timer Mode: */
-               cra |= ((2 << CRABIT_CLKSRC_A)  /*    ClkSrcA<1> selects system clock */
-                       |((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /*      with count direction (ClkSrcA<0>) obtained from ClkPol. */
-                       |(1 << CRABIT_CLKPOL_A) /*    ClkPolA behaves as always-on clock enable. */
-                       |(MULT_X1 << CRABIT_CLKMULT_A));        /*    ClkMult must be 1x. */
-               break;
-
-       default:                /*  Counter Mode: */
-               cra |= (CLKSRC_COUNTER  /*    Select ENC_C and ENC_D as clock/direction inputs. */
-                       | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL))        /*    Clock polarity is passed through. */
-                       |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?   /*    Force multiplier to x1 if not legal, otherwise pass through. */
-                         (MULT_X1 << CRABIT_CLKMULT_A) :
-                         ((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
-                                                       STDBIT_CLKMULT))));
+               pdma->logical_base = NULL;
+               pdma->physical_base = 0;
        }
-
-       /*  Force positive index polarity if IndxSrc is software-driven only, */
-       /*  otherwise pass it through. */
-       if (~setup & STDMSK_INDXSRC)
-               cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
-                                                    STDBIT_INDXPOL));
-
-       /*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
-       /*  enable mask to indicate the counter interrupt is disabled. */
-       if (DisableIntSrc)
-               devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
-
-       /*  While retaining CounterB and LatchSrc configurations, program the */
-       /*  new counter operating mode. */
-       DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A), crb);
-}
-
-static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
-                     uint16_t Setup, uint16_t DisableIntSrc)
-{
-       struct s626_private *devpriv = dev->private;
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup = Setup;        /*  Cache the Standard Setup. */
-
-       /*  Initialize CRA and CRB images. */
-       cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC));  /*  IndexSrc field is restricted to ENC_X or IndxPol. */
-
-       crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B   /*  Reset event captures and disable interrupts. */
-              | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB))      /*  Clock enable is passed through. */
-              |((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)));     /*  Preload trigger source is passed through. */
-
-       /*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
-       if (!DisableIntSrc)
-               crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
-                                                   CRBBIT_INTSRC_B));
-
-       /*  Populate all mode-dependent attributes of CRA & CRB images. */
-       switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
-       case CLKSRC_TIMER:      /*  Timer Mode: */
-               cra |= ((2 << CRABIT_CLKSRC_B)  /*    ClkSrcB<1> selects system clock */
-                       |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));       /*      with direction (ClkSrcB<0>) obtained from ClkPol. */
-               crb |= ((1 << CRBBIT_CLKPOL_B)  /*    ClkPolB behaves as always-on clock enable. */
-                       |(MULT_X1 << CRBBIT_CLKMULT_B));        /*    ClkMultB must be 1x. */
-               break;
-
-       case CLKSRC_EXTENDER:   /*  Extender Mode: */
-               cra |= ((2 << CRABIT_CLKSRC_B)  /*    ClkSrcB source is OverflowA (same as "timer") */
-                       |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));       /*      with direction obtained from ClkPol. */
-               crb |= ((1 << CRBBIT_CLKPOL_B)  /*    ClkPolB controls IndexB -- always set to active. */
-                       |(MULT_X0 << CRBBIT_CLKMULT_B));        /*    ClkMultB selects OverflowA as the clock source. */
-               break;
-
-       default:                /*  Counter Mode: */
-               cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B);     /*    Select ENC_C and ENC_D as clock/direction inputs. */
-               crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B))  /*    ClkPol is passed through. */
-                       |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?   /*    Force ClkMult to x1 if not legal, otherwise pass through. */
-                         (MULT_X1 << CRBBIT_CLKMULT_B) :
-                         ((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
-                                                       STDBIT_CLKMULT))));
-       }
-
-       /*  Force positive index polarity if IndxSrc is software-driven only, */
-       /*  otherwise pass it through. */
-       if (~setup & STDMSK_INDXSRC)
-               crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
-                                                    CRBBIT_INDXPOL_B));
-
-       /*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
-       /*  enable mask to indicate the counter interrupt is disabled. */
-       if (DisableIntSrc)
-               devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
-
-       /*  While retaining CounterA and LatchSrc configurations, program the */
-       /*  new counter operating mode. */
-       DEBIreplace(dev, k->MyCRA, ~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B), cra);
-       DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
-}
-
-/*  Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index. */
-
-static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t enab)
-{
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A),
-                   enab << CRBBIT_CLKENAB_A);
-}
-
-static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t enab)
-{
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B),
-                   enab << CRBBIT_CLKENAB_B);
-}
-
-static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
-}
-
-static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
-}
-
-/*
- * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
- * {
- *     return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
- * }
- */
-
-/*
- * Return/set the event that will trigger transfer of the preload
- * register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
- * 2=OverflowA (B counters only), 3=disabled.
- */
-
-static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
-                         uint16_t Trig)
-{
-       DEBIreplace(dev, k->MyCRA, ~CRAMSK_LOADSRC_A,
-                   Trig << CRABIT_LOADSRC_A);
-}
-
-static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
-                         uint16_t Trig)
-{
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL),
-                   Trig << CRBBIT_LOADSRC_B);
-}
-
-static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
-}
-
-static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
-}
-
-/* Return/set counter interrupt source and clear any captured
- * index/overflow events.  IntSource: 0=Disabled, 1=OverflowOnly,
- * 2=IndexOnly, 3=IndexAndOverflow.
- */
-
-static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t IntSource)
-{
-       struct s626_private *devpriv = dev->private;
-
-       /*  Reset any pending counter overflow or index captures. */
-       DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
-                   CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
-
-       /*  Program counter interrupt source. */
-       DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
-                   IntSource << CRABIT_INTSRC_A);
-
-       /*  Update MISC2 interrupt enable mask. */
-       devpriv->CounterIntEnabs =
-           (devpriv->CounterIntEnabs & ~k->
-            MyEventBits[3]) | k->MyEventBits[IntSource];
-}
-
-static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t IntSource)
-{
-       struct s626_private *devpriv = dev->private;
-       uint16_t crb;
-
-       /*  Cache writeable CRB register image. */
-       crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
-
-       /*  Reset any pending counter overflow or index captures. */
-       DEBIwrite(dev, k->MyCRB,
-                 (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
-
-       /*  Program counter interrupt source. */
-       DEBIwrite(dev, k->MyCRB,
-                 (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
-                                                         CRBBIT_INTSRC_B)));
-
-       /*  Update MISC2 interrupt enable mask. */
-       devpriv->CounterIntEnabs =
-           (devpriv->CounterIntEnabs & ~k->
-            MyEventBits[3]) | k->MyEventBits[IntSource];
-}
-
-static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
-}
-
-static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
-}
-
-/*  Return/set the clock multiplier. */
-
-/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */
-/* } */
-
-/* Return/set the clock polarity. */
-
-/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */
-/* } */
-
-/* Return/set the clock source.  */
-
-/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */
-/* } */
-
-/* Return/set the index polarity. */
-
-/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */
-/* } */
-
-/*  Return/set the index source. */
-
-/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */
-/* } */
-
-/*  Generate an index pulse. */
-
-static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t cra;
-
-       cra = DEBIread(dev, k->MyCRA);  /*  Pulse index. */
-       DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
-       DEBIwrite(dev, k->MyCRA, cra);
-}
-
-static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t crb;
-
-       crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;        /*  Pulse index. */
-       DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
-       DEBIwrite(dev, k->MyCRB, crb);
 }
 
-static struct enc_private enc_private_data[] = {
-       {
-               .GetEnable      = GetEnable_A,
-               .GetIntSrc      = GetIntSrc_A,
-               .GetLoadTrig    = GetLoadTrig_A,
-               .GetMode        = GetMode_A,
-               .PulseIndex     = PulseIndex_A,
-               .SetEnable      = SetEnable_A,
-               .SetIntSrc      = SetIntSrc_A,
-               .SetLoadTrig    = SetLoadTrig_A,
-               .SetMode        = SetMode_A,
-               .ResetCapFlags  = ResetCapFlags_A,
-               .MyCRA          = LP_CR0A,
-               .MyCRB          = LP_CR0B,
-               .MyLatchLsw     = LP_CNTR0ALSW,
-               .MyEventBits    = EVBITS(0),
-       }, {
-               .GetEnable      = GetEnable_A,
-               .GetIntSrc      = GetIntSrc_A,
-               .GetLoadTrig    = GetLoadTrig_A,
-               .GetMode        = GetMode_A,
-               .PulseIndex     = PulseIndex_A,
-               .SetEnable      = SetEnable_A,
-               .SetIntSrc      = SetIntSrc_A,
-               .SetLoadTrig    = SetLoadTrig_A,
-               .SetMode        = SetMode_A,
-               .ResetCapFlags  = ResetCapFlags_A,
-               .MyCRA          = LP_CR1A,
-               .MyCRB          = LP_CR1B,
-               .MyLatchLsw     = LP_CNTR1ALSW,
-               .MyEventBits    = EVBITS(1),
-       }, {
-               .GetEnable      = GetEnable_A,
-               .GetIntSrc      = GetIntSrc_A,
-               .GetLoadTrig    = GetLoadTrig_A,
-               .GetMode        = GetMode_A,
-               .PulseIndex     = PulseIndex_A,
-               .SetEnable      = SetEnable_A,
-               .SetIntSrc      = SetIntSrc_A,
-               .SetLoadTrig    = SetLoadTrig_A,
-               .SetMode        = SetMode_A,
-               .ResetCapFlags  = ResetCapFlags_A,
-               .MyCRA          = LP_CR2A,
-               .MyCRB          = LP_CR2B,
-               .MyLatchLsw     = LP_CNTR2ALSW,
-               .MyEventBits    = EVBITS(2),
-       }, {
-               .GetEnable      = GetEnable_B,
-               .GetIntSrc      = GetIntSrc_B,
-               .GetLoadTrig    = GetLoadTrig_B,
-               .GetMode        = GetMode_B,
-               .PulseIndex     = PulseIndex_B,
-               .SetEnable      = SetEnable_B,
-               .SetIntSrc      = SetIntSrc_B,
-               .SetLoadTrig    = SetLoadTrig_B,
-               .SetMode        = SetMode_B,
-               .ResetCapFlags  = ResetCapFlags_B,
-               .MyCRA          = LP_CR0A,
-               .MyCRB          = LP_CR0B,
-               .MyLatchLsw     = LP_CNTR0BLSW,
-               .MyEventBits    = EVBITS(3),
-       }, {
-               .GetEnable      = GetEnable_B,
-               .GetIntSrc      = GetIntSrc_B,
-               .GetLoadTrig    = GetLoadTrig_B,
-               .GetMode        = GetMode_B,
-               .PulseIndex     = PulseIndex_B,
-               .SetEnable      = SetEnable_B,
-               .SetIntSrc      = SetIntSrc_B,
-               .SetLoadTrig    = SetLoadTrig_B,
-               .SetMode        = SetMode_B,
-               .ResetCapFlags  = ResetCapFlags_B,
-               .MyCRA          = LP_CR1A,
-               .MyCRB          = LP_CR1B,
-               .MyLatchLsw     = LP_CNTR1BLSW,
-               .MyEventBits    = EVBITS(4),
-       }, {
-               .GetEnable      = GetEnable_B,
-               .GetIntSrc      = GetIntSrc_B,
-               .GetLoadTrig    = GetLoadTrig_B,
-               .GetMode        = GetMode_B,
-               .PulseIndex     = PulseIndex_B,
-               .SetEnable      = SetEnable_B,
-               .SetIntSrc      = SetIntSrc_B,
-               .SetLoadTrig    = SetLoadTrig_B,
-               .SetMode        = SetMode_B,
-               .ResetCapFlags  = ResetCapFlags_B,
-               .MyCRA          = LP_CR2A,
-               .MyCRB          = LP_CR2B,
-               .MyLatchLsw     = LP_CNTR2BLSW,
-               .MyEventBits    = EVBITS(5),
-       },
-};
-
-static void CountersInit(struct comedi_device *dev)
+static void s626_counters_init(struct comedi_device *dev)
 {
        int chan;
-       struct enc_private *k;
-       uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
-           /*  index. */
-           (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
-           (CLKSRC_COUNTER << BF_CLKSRC) |     /*  Operating mode is counter. */
-           (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
-           (CNTDIR_UP << BF_CLKPOL) |  /*  Count direction is up. */
-           (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
-           (CLKENAB_INDEX << BF_CLKENAB);      /*  Enabled by index */
-
-       /*  Disable all counter interrupts and clear any captured counter events. */
+       const struct s626_enc_info *k;
+       uint16_t setup =
+               /* Preload upon index. */
+               S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
+               /* Disable hardware index. */
+               S626_SET_STD_INDXSRC(S626_INDXSRC_SOFT) |
+               /* Operating mode is counter. */
+               S626_SET_STD_ENCMODE(S626_ENCMODE_COUNTER) |
+               /* Active high clock. */
+               S626_SET_STD_CLKPOL(S626_CLKPOL_POS) |
+               /* Clock multiplier is 1x. */
+               S626_SET_STD_CLKMULT(S626_CLKMULT_1X) |
+               /* Enabled by index */
+               S626_SET_STD_CLKENAB(S626_CLKENAB_INDEX);
+
+       /*
+        * Disable all counter interrupts and clear any captured counter events.
+        */
        for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
-               k = &encpriv[chan];
-               k->SetMode(dev, k, Setup, TRUE);
-               k->SetIntSrc(dev, k, 0);
-               k->ResetCapFlags(dev, k);
-               k->SetEnable(dev, k, CLKENAB_ALWAYS);
+               k = &s626_enc_chan_info[chan];
+               k->set_mode(dev, k, setup, true);
+               k->set_int_src(dev, k, 0);
+               k->reset_cap_flags(dev, k);
+               k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
        }
 }
 
@@ -2316,17 +2533,17 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev)
        void *addr;
        dma_addr_t appdma;
 
-       addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma);
+       addr = pci_alloc_consistent(pcidev, S626_DMABUF_SIZE, &appdma);
        if (!addr)
                return -ENOMEM;
-       devpriv->ANABuf.LogicalBase = addr;
-       devpriv->ANABuf.PhysicalBase = appdma;
+       devpriv->ana_buf.logical_base = addr;
+       devpriv->ana_buf.physical_base = appdma;
 
-       addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma);
+       addr = pci_alloc_consistent(pcidev, S626_DMABUF_SIZE, &appdma);
        if (!addr)
                return -ENOMEM;
-       devpriv->RPSBuf.LogicalBase = addr;
-       devpriv->RPSBuf.PhysicalBase = appdma;
+       devpriv->rps_buf.logical_base = addr;
+       devpriv->rps_buf.physical_base = appdma;
 
        return 0;
 }
@@ -2334,42 +2551,43 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev)
 static void s626_initialize(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
-       dma_addr_t pPhysBuf;
+       dma_addr_t phys_buf;
        uint16_t chan;
        int i;
 
        /* Enable DEBI and audio pins, enable I2C interface */
-       s626_mc_enable(dev, MC1_DEBI | MC1_AUDIO | MC1_I2C, P_MC1);
+       s626_mc_enable(dev, S626_MC1_DEBI | S626_MC1_AUDIO | S626_MC1_I2C,
+                      S626_P_MC1);
 
        /*
-        *  Configure DEBI operating mode
+        * Configure DEBI operating mode
         *
-        *   Local bus is 16 bits wide
-        *   Declare DEBI transfer timeout interval
-        *   Set up byte lane steering
-        *   Intel-compatible local bus (DEBI never times out)
+        *  Local bus is 16 bits wide
+        *  Declare DEBI transfer timeout interval
+        *  Set up byte lane steering
+        *  Intel-compatible local bus (DEBI never times out)
         */
-       writel(DEBI_CFG_SLAVE16 |
-              (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
-              DEBI_SWAP | DEBI_CFG_INTEL,
-              devpriv->mmio + P_DEBICFG);
+       writel(S626_DEBI_CFG_SLAVE16 |
+              (S626_DEBI_TOUT << S626_DEBI_CFG_TOUT_BIT) | S626_DEBI_SWAP |
+              S626_DEBI_CFG_INTEL, devpriv->mmio + S626_P_DEBICFG);
 
        /* Disable MMU paging */
-       writel(DEBI_PAGE_DISABLE, devpriv->mmio + P_DEBIPAGE);
+       writel(S626_DEBI_PAGE_DISABLE, devpriv->mmio + S626_P_DEBIPAGE);
 
        /* Init GPIO so that ADC Start* is negated */
-       writel(GPIO_BASE | GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(S626_GPIO_BASE | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
 
        /* I2C device address for onboard eeprom (revb) */
-       devpriv->I2CAdrs = 0xA0;
+       devpriv->i2c_adrs = 0xA0;
 
        /*
         * Issue an I2C ABORT command to halt any I2C
         * operation in progress and reset BUSY flag.
         */
-       writel(I2C_CLKSEL | I2C_ABORT, devpriv->mmio + P_I2CSTAT);
-       s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
-       while (!(readl(devpriv->mmio + P_MC2) & MC2_UPLD_IIC))
+       writel(S626_I2C_CLKSEL | S626_I2C_ABORT,
+              devpriv->mmio + S626_P_I2CSTAT);
+       s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+       while (!(readl(devpriv->mmio + S626_P_MC2) & S626_MC2_UPLD_IIC))
                ;
 
        /*
@@ -2377,9 +2595,9 @@ static void s626_initialize(struct comedi_device *dev)
         * reg twice to reset all  I2C error flags.
         */
        for (i = 0; i < 2; i++) {
-               writel(I2C_CLKSEL, devpriv->mmio + P_I2CSTAT);
-               s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
-               while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2))
+               writel(S626_I2C_CLKSEL, devpriv->mmio + S626_P_I2CSTAT);
+               s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+               while (!s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2))
                        ;
        }
 
@@ -2389,31 +2607,32 @@ static void s626_initialize(struct comedi_device *dev)
         * DAC data setup times are satisfied, enable DAC serial
         * clock out.
         */
-       writel(ACON2_INIT, devpriv->mmio + P_ACON2);
+       writel(S626_ACON2_INIT, devpriv->mmio + S626_P_ACON2);
 
        /*
         * Set up TSL1 slot list, which is used to control the
-        * accumulation of ADC data: RSD1 = shift data in on SD1.
-        * SIB_A1  = store data uint8_t at next available location
+        * accumulation of ADC data: S626_RSD1 = shift data in on SD1.
+        * S626_SIB_A1  = store data uint8_t at next available location
         * in FB BUFFER1 register.
         */
-       writel(RSD1 | SIB_A1, devpriv->mmio + P_TSL1);
-       writel(RSD1 | SIB_A1 | EOS, devpriv->mmio + P_TSL1 + 4);
+       writel(S626_RSD1 | S626_SIB_A1, devpriv->mmio + S626_P_TSL1);
+       writel(S626_RSD1 | S626_SIB_A1 | S626_EOS,
+              devpriv->mmio + S626_P_TSL1 + 4);
 
        /* Enable TSL1 slot list so that it executes all the time */
-       writel(ACON1_ADCSTART, devpriv->mmio + P_ACON1);
+       writel(S626_ACON1_ADCSTART, devpriv->mmio + S626_P_ACON1);
 
        /*
         * Initialize RPS registers used for ADC
         */
 
        /* Physical start of RPS program */
-       writel((uint32_t)devpriv->RPSBuf.PhysicalBase,
-              devpriv->mmio + P_RPSADDR1);
+       writel((uint32_t)devpriv->rps_buf.physical_base,
+              devpriv->mmio + S626_P_RPSADDR1);
        /* RPS program performs no explicit mem writes */
-       writel(0, devpriv->mmio + P_RPSPAGE1);
+       writel(0, devpriv->mmio + S626_P_RPSPAGE1);
        /* Disable RPS timeouts */
-       writel(0, devpriv->mmio + P_RPS1_TOUT);
+       writel(0, devpriv->mmio + S626_P_RPS1_TOUT);
 
 #if 0
        /*
@@ -2425,38 +2644,37 @@ static void s626_initialize(struct comedi_device *dev)
         * because the SAA7146 ADC interface does not start up in
         * a defined state after a PCI reset.
         */
-
        {
-       uint8_t PollList;
-       uint16_t AdcData;
-       uint16_t StartVal;
-       uint16_t index;
-       unsigned int data[16];
+               uint8_t poll_list;
+               uint16_t adc_data;
+               uint16_t start_val;
+               uint16_t index;
+               unsigned int data[16];
 
-       /* Create a simple polling list for analog input channel 0 */
-       PollList = EOPL;
-       ResetADC(dev, &PollList);
+               /* Create a simple polling list for analog input channel 0 */
+               poll_list = S626_EOPL;
+               s626_reset_adc(dev, &poll_list);
 
-       /* Get initial ADC value */
-       s626_ai_rinsn(dev, dev->subdevices, NULL, data);
-       StartVal = data[0];
-
-       /*
-        * VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION.
-        *
-        * Invoke ADCs until the new ADC value differs from the initial
-        * value or a timeout occurs.  The timeout protects against the
-        * possibility that the driver is restarting and the ADC data is a
-        * fixed value resulting from the applied ADC analog input being
-        * unusually quiet or at the rail.
-        */
-       for (index = 0; index < 500; index++) {
+               /* Get initial ADC value */
                s626_ai_rinsn(dev, dev->subdevices, NULL, data);
-               AdcData = data[0];
-               if (AdcData != StartVal)
-                       break;
-       }
+               start_val = data[0];
 
+               /*
+                * VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED
+                * EXECUTION.
+                *
+                * Invoke ADCs until the new ADC value differs from the initial
+                * value or a timeout occurs.  The timeout protects against the
+                * possibility that the driver is restarting and the ADC data is
+                * a fixed value resulting from the applied ADC analog input
+                * being unusually quiet or at the rail.
+                */
+               for (index = 0; index < 500; index++) {
+                       s626_ai_rinsn(dev, dev->subdevices, NULL, data);
+                       adc_data = data[0];
+                       if (adc_data != start_val)
+                               break;
+               }
        }
 #endif /* SAA7146 BUG WORKAROUND */
 
@@ -2469,7 +2687,7 @@ static void s626_initialize(struct comedi_device *dev)
         *   burst length = 1 DWORD
         *   threshold = 1 DWORD.
         */
-       writel(0, devpriv->mmio + P_PCI_BT_A);
+       writel(0, devpriv->mmio + S626_P_PCI_BT_A);
 
        /*
         * Init Audio2's output DMA physical addresses.  The protection
@@ -2477,18 +2695,18 @@ static void s626_initialize(struct comedi_device *dev)
         * single DWORD will be transferred each time a DMA transfer is
         * enabled.
         */
-       pPhysBuf = devpriv->ANABuf.PhysicalBase +
-                  (DAC_WDMABUF_OS * sizeof(uint32_t));
-       writel((uint32_t)pPhysBuf, devpriv->mmio + P_BASEA2_OUT);
-       writel((uint32_t)(pPhysBuf + sizeof(uint32_t)),
-              devpriv->mmio + P_PROTA2_OUT);
+       phys_buf = devpriv->ana_buf.physical_base +
+                  (S626_DAC_WDMABUF_OS * sizeof(uint32_t));
+       writel((uint32_t)phys_buf, devpriv->mmio + S626_P_BASEA2_OUT);
+       writel((uint32_t)(phys_buf + sizeof(uint32_t)),
+              devpriv->mmio + S626_P_PROTA2_OUT);
 
        /*
         * Cache Audio2's output DMA buffer logical address.  This is
         * where DAC data is buffered for A2 output DMA transfers.
         */
-       devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase +
-                           DAC_WDMABUF_OS;
+       devpriv->dac_wbuf = (uint32_t *)devpriv->ana_buf.logical_base +
+                           S626_DAC_WDMABUF_OS;
 
        /*
         * Audio2's output channels does not use paging.  The
@@ -2496,7 +2714,7 @@ static void s626_initialize(struct comedi_device *dev)
         * DMAC will automatically halt and its PCI address pointer
         * will be reset when the protection address is reached.
         */
-       writel(8, devpriv->mmio + P_PAGEA2_OUT);
+       writel(8, devpriv->mmio + S626_P_PAGEA2_OUT);
 
        /*
         * Initialize time slot list 2 (TSL2), which is used to control
@@ -2511,7 +2729,8 @@ static void s626_initialize(struct comedi_device *dev)
         */
 
        /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */
-       writel(XSD2 | RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0));
+       writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(0));
 
        /*
         * Initialize slot 1, which is constant.  Slot 1 causes a
@@ -2523,18 +2742,18 @@ static void s626_initialize(struct comedi_device *dev)
         */
 
        /* Slot 1: Fetch DWORD from Audio2's output FIFO */
-       writel(LF_A2, devpriv->mmio + VECTPORT(1));
+       writel(S626_LF_A2, devpriv->mmio + S626_VECTPORT(1));
 
        /* Start DAC's audio interface (TSL2) running */
-       writel(ACON1_DACSTART, devpriv->mmio + P_ACON1);
+       writel(S626_ACON1_DACSTART, devpriv->mmio + S626_P_ACON1);
 
        /*
         * Init Trim DACs to calibrated values.  Do it twice because the
         * SAA7146 audio channel does not always reset properly and
         * sometimes causes the first few TrimDAC writes to malfunction.
         */
-       LoadTrimDACs(dev);
-       LoadTrimDACs(dev);
+       s626_load_trim_dacs(dev);
+       s626_load_trim_dacs(dev);
 
        /*
         * Manually init all gate array hardware in case this is a soft
@@ -2549,10 +2768,10 @@ static void s626_initialize(struct comedi_device *dev)
         * polarity images.
         */
        for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
-               SetDAC(dev, chan, 0);
+               s626_set_dac(dev, chan, 0);
 
        /* Init counters */
-       CountersInit(dev);
+       s626_counters_init(dev);
 
        /*
         * Without modifying the state of the Battery Backup enab, disable
@@ -2560,8 +2779,8 @@ static void s626_initialize(struct comedi_device *dev)
         * standard DIO (vs. counter overflow) mode, disable the battery
         * charger, and reset the watchdog interval selector to zero.
         */
-       WriteMISC2(dev, (uint16_t)(DEBIread(dev, LP_RDMISC2) &
-                                  MISC2_BATT_ENABLE));
+       s626_write_misc2(dev, (s626_debi_read(dev, S626_LP_RDMISC2) &
+                              S626_MISC2_BATT_ENABLE));
 
        /* Initialize the digital I/O subsystem */
        s626_dio_init(dev);
@@ -2588,10 +2807,10 @@ static int s626_auto_attach(struct comedi_device *dev,
                return -ENOMEM;
 
        /* disable master interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        /* soft reset */
-       writel(MC1_SOFT_RESET, devpriv->mmio + P_MC1);
+       writel(S626_MC1_SOFT_RESET, devpriv->mmio + S626_P_MC1);
 
        /* DMA FIXME DMA// */
 
@@ -2670,7 +2889,7 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->io_bits      = 0xffff;
        s->private      = (void *)2;    /* DIO group 2 */
        s->range_table  = &range_digital;
-       s->insn_config  = s626_dio_insn_config;
+       s->insn_config  = s626_dio_insn_config;
        s->insn_bits    = s626_dio_insn_bits;
 
        s = &dev->subdevices[5];
@@ -2679,7 +2898,6 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
        s->n_chan       = S626_ENCODER_CHANNELS;
        s->maxdata      = 0xffffff;
-       s->private      = enc_private_data;
        s->range_table  = &range_unknown;
        s->insn_config  = s626_enc_insn_config;
        s->insn_read    = s626_enc_insn_read;
@@ -2703,20 +2921,22 @@ static void s626_detach(struct comedi_device *dev)
                if (devpriv->mmio) {
                        /* interrupt mask */
                        /* Disable master interrupt */
-                       writel(0, devpriv->mmio + P_IER);
+                       writel(0, devpriv->mmio + S626_P_IER);
                        /* Clear board's IRQ status flag */
-                       writel(IRQ_GPIO3 | IRQ_RPS1,
-                              devpriv->mmio + P_ISR);
+                       writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1,
+                              devpriv->mmio + S626_P_ISR);
 
-                       /*  Disable the watchdog timer and battery charger. */
-                       WriteMISC2(dev, 0);
+                       /* Disable the watchdog timer and battery charger. */
+                       s626_write_misc2(dev, 0);
 
                        /* Close all interfaces on 7146 device */
-                       writel(MC1_SHUTDOWN, devpriv->mmio + P_MC1);
-                       writel(ACON1_BASE, devpriv->mmio + P_ACON1);
+                       writel(S626_MC1_SHUTDOWN, devpriv->mmio + S626_P_MC1);
+                       writel(S626_ACON1_BASE, devpriv->mmio + S626_P_ACON1);
 
-                       CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE);
-                       CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
+                       s626_close_dma_b(dev, &devpriv->rps_buf,
+                                        S626_DMABUF_SIZE);
+                       s626_close_dma_b(dev, &devpriv->ana_buf,
+                                        S626_DMABUF_SIZE);
                }
 
                if (dev->irq)
@@ -2746,8 +2966,8 @@ static int s626_pci_probe(struct pci_dev *dev,
  * Philips SAA7146 media/dvb based cards.
  */
 static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
-       { PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
-               PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0 },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146,
+                        0x6000, 0x0272) },
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, s626_pci_table);
index a85e6bdcad0750905f32c1078b4310e9d364db50..33b72739c1cbdf4c6887971fa12b1408ff8d247d 100644 (file)
 /*
-  comedi/drivers/s626.h
-  Sensoray s626 Comedi driver, header file
-
-  COMEDI - Linux Control and Measurement Device Interface
-  Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-  Based on Sensoray Model 626 Linux driver Version 0.2
-  Copyright (C) 2002-2004 Sensoray Co., 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; 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.
-*/
-
-/*
-  Driver: s626.o (s626.ko)
-  Description: Sensoray 626 driver
-  Devices: Sensoray s626
-  Authors: Gianluca Palli <gpalli@deis.unibo.it>,
-  Updated: Thu, 12 Jul 2005
-  Status: experimental
-
-  Configuration Options:
-  analog input:
-   none
-
-  analog output:
-   none
-
-  digital channel:
-   s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
-   supported configuration options:
-   INSN_CONFIG_DIO_QUERY
-   COMEDI_INPUT
-   COMEDI_OUTPUT
-
-  encoder:
-   Every channel must be configured before reading.
-
-   Example code
-
-   insn.insn=INSN_CONFIG;   // configuration instruction
-   insn.n=1;                // number of operation (must be 1)
-   insn.data=&initialvalue; // initial value loaded into encoder
-                            // during configuration
-   insn.subdev=5;           // encoder subdevice
-   insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); // encoder_channel
-                                                        // to configure
-
-   comedi_do_insn(cf,&insn); // executing configuration
-*/
-
-#if !defined(TRUE)
-#define TRUE    (1)
-#endif
-
-#if !defined(FALSE)
-#define FALSE   (0)
-#endif
-
-#define S626_SIZE 0x0200
-#define DMABUF_SIZE                    4096    /*  4k pages */
+ * comedi/drivers/s626.h
+ * Sensoray s626 Comedi driver, header file
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * Based on Sensoray Model 626 Linux driver Version 0.2
+ * Copyright (C) 2002-2004 Sensoray Co., 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; 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 S626_H_INCLUDED
+#define S626_H_INCLUDED
+
+#define S626_DMABUF_SIZE       4096    /* 4k pages */
 
 #define S626_ADC_CHANNELS       16
 #define S626_DAC_CHANNELS       4
 #define S626_ENCODER_CHANNELS   6
 #define S626_DIO_CHANNELS       48
-#define S626_DIO_BANKS         3       /*  Number of DIO groups. */
-#define S626_DIO_EXTCHANS      40      /*  Number of */
-                                       /*  extended-capability */
-                                       /*  DIO channels. */
-
-#define NUM_TRIMDACS   12      /*  Number of valid TrimDAC channels. */
-
-/*  PCI bus interface types. */
-#define INTEL                          1       /*  Intel bus type. */
-#define MOTOROLA                       2       /*  Motorola bus type. */
+#define S626_DIO_BANKS         3       /* Number of DIO groups. */
+#define S626_DIO_EXTCHANS      40      /* Number of extended-capability
+                                        * DIO channels. */
 
-#define PLATFORM               INTEL   /*  *** SELECT PLATFORM TYPE *** */
+#define S626_NUM_TRIMDACS      12      /* Number of valid TrimDAC channels. */
 
-#define RANGE_5V                0x10   /*  +/-5V range */
-#define RANGE_10V               0x00   /*  +/-10V range */
+/* PCI bus interface types. */
+#define S626_INTEL             1       /* Intel bus type. */
+#define S626_MOTOROLA          2       /* Motorola bus type. */
 
-#define EOPL                   0x80    /*  End of ADC poll list marker. */
-#define GSEL_BIPOLAR5V         0x00F0  /*  LP_GSEL setting for 5V bipolar range. */
-#define GSEL_BIPOLAR10V                0x00A0  /*  LP_GSEL setting for 10V bipolar range. */
+#define S626_PLATFORM          S626_INTEL /* *** SELECT PLATFORM TYPE *** */
 
-/*  Error codes that must be visible to this base class. */
-#define ERR_ILLEGAL_PARM       0x00010000      /*  Illegal function parameter value was specified. */
-#define ERR_I2C                        0x00020000      /*  I2C error. */
-#define ERR_COUNTERSETUP       0x00200000      /*  Illegal setup specified for counter channel. */
-#define ERR_DEBI_TIMEOUT       0x00400000      /*  DEBI transfer timed out. */
+#define S626_RANGE_5V          0x10    /* +/-5V range */
+#define S626_RANGE_10V         0x00    /* +/-10V range */
 
-/*  Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF. */
-#define ADC_DMABUF_DWORDS      40      /*  ADC DMA buffer must hold 16 samples, plus pre/post garbage samples. */
-#define DAC_WDMABUF_DWORDS     1       /*  DAC output DMA buffer holds a single sample. */
+#define S626_EOPL              0x80    /* End of ADC poll list marker. */
+#define S626_GSEL_BIPOLAR5V    0x00F0  /* S626_LP_GSEL setting 5V bipolar. */
+#define S626_GSEL_BIPOLAR10V   0x00A0  /* S626_LP_GSEL setting 10V bipolar. */
 
-/*  All remaining space in 4KB DMA buffer is available for the RPS1 program. */
+/* Error codes that must be visible to this base class. */
+#define S626_ERR_ILLEGAL_PARM  0x00010000      /* Illegal function parameter
+                                                * value was specified. */
+#define S626_ERR_I2C           0x00020000      /* I2C error. */
+#define S626_ERR_COUNTERSETUP  0x00200000      /* Illegal setup specified for
+                                                * counter channel. */
+#define S626_ERR_DEBI_TIMEOUT  0x00400000      /* DEBI transfer timed out. */
 
-/*  Address offsets, in DWORDS, from base of DMA buffer. */
-#define DAC_WDMABUF_OS         ADC_DMABUF_DWORDS
-
-/*  Interrupt enab bit in ISR and IER. */
-#define IRQ_GPIO3              0x00000040      /*  IRQ enable for GPIO3. */
-#define IRQ_RPS1                0x10000000
-#define ISR_AFOU               0x00000800
+/*
+ * Organization (physical order) and size (in DWORDs) of logical DMA buffers
+ * contained by ANA_DMABUF.
+ */
+#define S626_ADC_DMABUF_DWORDS 40      /* ADC DMA buffer must hold 16 samples,
+                                        * plus pre/post garbage samples. */
+#define S626_DAC_WDMABUF_DWORDS        1       /* DAC output DMA buffer holds a single
+                                        * sample. */
+
+/* All remaining space in 4KB DMA buffer is available for the RPS1 program. */
+
+/* Address offsets, in DWORDS, from base of DMA buffer. */
+#define S626_DAC_WDMABUF_OS    S626_ADC_DMABUF_DWORDS
+
+/*  Interrupt enable bit in ISR and IER. */
+#define S626_IRQ_GPIO3         0x00000040      /* IRQ enable for GPIO3. */
+#define S626_IRQ_RPS1          0x10000000
+#define S626_ISR_AFOU          0x00000800
 /* Audio fifo under/overflow  detected. */
 
-#define IRQ_COINT1A             0x0400 /* conter 1A overflow interrupt mask */
-#define IRQ_COINT1B             0x0800 /* conter 1B overflow interrupt mask */
-#define IRQ_COINT2A             0x1000 /* conter 2A overflow interrupt mask */
-#define IRQ_COINT2B             0x2000 /* conter 2B overflow interrupt mask */
-#define IRQ_COINT3A             0x4000 /* conter 3A overflow interrupt mask */
-#define IRQ_COINT3B             0x8000 /* conter 3B overflow interrupt mask */
-
-/*  RPS command codes. */
-#define RPS_CLRSIGNAL          0x00000000      /*  CLEAR SIGNAL */
-#define RPS_SETSIGNAL          0x10000000      /*  SET SIGNAL */
-#define RPS_NOP                        0x00000000      /*  NOP */
-#define RPS_PAUSE              0x20000000      /*  PAUSE */
-#define RPS_UPLOAD             0x40000000      /*  UPLOAD */
-#define RPS_JUMP               0x80000000      /*  JUMP */
-#define RPS_LDREG              0x90000100      /*  LDREG (1 uint32_t only) */
-#define RPS_STREG              0xA0000100      /*  STREG (1 uint32_t only) */
-#define RPS_STOP               0x50000000      /*  STOP */
-#define RPS_IRQ                 0x60000000     /*  IRQ */
-
-#define RPS_LOGICAL_OR         0x08000000      /*  Logical OR conditionals. */
-#define RPS_INVERT             0x04000000      /*  Test for negated semaphores. */
-#define RPS_DEBI               0x00000002      /*  DEBI done */
-
-#define RPS_SIG0               0x00200000      /*  RPS semaphore 0 (used by ADC). */
-#define RPS_SIG1               0x00400000      /*  RPS semaphore 1 (used by DAC). */
-#define RPS_SIG2               0x00800000      /*  RPS semaphore 2 (not used). */
-#define RPS_GPIO2              0x00080000      /*  RPS GPIO2 */
-#define RPS_GPIO3              0x00100000      /*  RPS GPIO3 */
-
-#define RPS_SIGADC             RPS_SIG0        /*  Trigger/status for ADC's RPS program. */
-#define RPS_SIGDAC             RPS_SIG1        /*  Trigger/status for DAC's RPS program. */
-
-/*  RPS clock parameters. */
-#define RPSCLK_SCALAR          8       /*  This is apparent ratio of PCI/RPS clks (undocumented!!). */
-#define RPSCLK_PER_US          (33 / RPSCLK_SCALAR)    /*  Number of RPS clocks in one microsecond. */
-
-/*  Event counter source addresses. */
-#define SBA_RPS_A0             0x27    /*  Time of RPS0 busy, in PCI clocks. */
-
-/*  GPIO constants. */
-#define GPIO_BASE              0x10004000      /*  GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out. */
-#define GPIO1_LO               0x00000000      /*  GPIO1 set to LOW. */
-#define GPIO1_HI               0x00001000      /*  GPIO1 set to HIGH. */
-
-/*  Primary Status Register (PSR) constants. */
-#define PSR_DEBI_E             0x00040000      /*  DEBI event flag. */
-#define PSR_DEBI_S             0x00080000      /*  DEBI status flag. */
-#define PSR_A2_IN              0x00008000      /*  Audio output DMA2 protection address reached. */
-#define PSR_AFOU               0x00000800      /*  Audio FIFO under/overflow detected. */
-#define PSR_GPIO2              0x00000020      /*  GPIO2 input pin: 0=AdcBusy, 1=AdcIdle. */
-#define PSR_EC0S               0x00000001      /*  Event counter 0 threshold reached. */
-
-/*  Secondary Status Register (SSR) constants. */
-#define SSR_AF2_OUT            0x00000200      /*  Audio 2 output FIFO under/overflow detected. */
-
-/*  Master Control Register 1 (MC1) constants. */
-#define MC1_SOFT_RESET         0x80000000      /*  Invoke 7146 soft reset. */
-#define MC1_SHUTDOWN           0x3FFF0000      /*  Shut down all MC1-controlled enables. */
-
-#define MC1_ERPS1              0x2000  /*  enab/disable RPS task 1. */
-#define MC1_ERPS0              0x1000  /*  enab/disable RPS task 0. */
-#define MC1_DEBI               0x0800  /*  enab/disable DEBI pins. */
-#define MC1_AUDIO              0x0200  /*  enab/disable audio port pins. */
-#define MC1_I2C                        0x0100  /*  enab/disable I2C interface. */
-#define MC1_A2OUT              0x0008  /*  enab/disable transfer on A2 out. */
-#define MC1_A2IN               0x0004  /*  enab/disable transfer on A2 in. */
-#define MC1_A1IN               0x0001  /*  enab/disable transfer on A1 in. */
-
-/*  Master Control Register 2 (MC2) constants. */
-#define MC2_UPLD_DEBIq         0x00020002      /*  Upload DEBI registers. */
-#define MC2_UPLD_IICq          0x00010001      /*  Upload I2C registers. */
-#define MC2_RPSSIG2_ONq                0x20002000      /*  Assert RPS_SIG2. */
-#define MC2_RPSSIG1_ONq                0x10001000      /*  Assert RPS_SIG1. */
-#define MC2_RPSSIG0_ONq                0x08000800      /*  Assert RPS_SIG0. */
-#define MC2_UPLD_DEBI_MASKq    0x00000002      /*  Upload DEBI mask. */
-#define MC2_UPLD_IIC_MASKq     0x00000001      /*  Upload I2C mask. */
-#define MC2_RPSSIG2_MASKq      0x00002000      /*  RPS_SIG2 bit mask. */
-#define MC2_RPSSIG1_MASKq      0x00001000      /*  RPS_SIG1 bit mask. */
-#define MC2_RPSSIG0_MASKq      0x00000800      /*  RPS_SIG0 bit mask. */
-
-#define MC2_DELAYTRIG_4USq     MC2_RPSSIG1_ON
-#define MC2_DELAYBUSY_4USq     MC2_RPSSIG1_MASK
-
-#define        MC2_DELAYTRIG_6USq      MC2_RPSSIG2_ON
-#define MC2_DELAYBUSY_6USq     MC2_RPSSIG2_MASK
-
-#define MC2_UPLD_DEBI          0x0002  /*  Upload DEBI. */
-#define MC2_UPLD_IIC           0x0001  /*  Upload I2C. */
-#define MC2_RPSSIG2            0x2000  /*  RPS signal 2 (not used). */
-#define MC2_RPSSIG1            0x1000  /*  RPS signal 1 (DAC RPS busy). */
-#define MC2_RPSSIG0            0x0800  /*  RPS signal 0 (ADC RPS busy). */
-
-#define MC2_ADC_RPS            MC2_RPSSIG0     /*  ADC RPS busy. */
-#define MC2_DAC_RPS            MC2_RPSSIG1     /*  DAC RPS busy. */
-
-/* ***** oldies ***** */
-#define MC2_UPLD_DEBIQ         0x00020002      /*  Upload DEBI registers. */
-#define MC2_UPLD_IICQ          0x00010001      /*  Upload I2C registers. */
-
-/*  PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
-#define P_PCI_BT_A             0x004C  /* Audio DMA burst/threshold control. */
-#define P_DEBICFG               0x007C /* DEBI configuration. */
-#define P_DEBICMD               0x0080 /* DEBI command. */
-#define P_DEBIPAGE              0x0084 /* DEBI page. */
-#define P_DEBIAD                0x0088 /* DEBI target address. */
-#define P_I2CCTRL               0x008C /* I2C control. */
-#define P_I2CSTAT               0x0090 /* I2C status. */
-#define P_BASEA2_IN            0x00AC  /* Audio input 2 base physical DMAbuf
+#define S626_IRQ_COINT1A       0x0400  /* counter 1A overflow interrupt mask */
+#define S626_IRQ_COINT1B       0x0800  /* counter 1B overflow interrupt mask */
+#define S626_IRQ_COINT2A       0x1000  /* counter 2A overflow interrupt mask */
+#define S626_IRQ_COINT2B       0x2000  /* counter 2B overflow interrupt mask */
+#define S626_IRQ_COINT3A       0x4000  /* counter 3A overflow interrupt mask */
+#define S626_IRQ_COINT3B       0x8000  /* counter 3B overflow interrupt mask */
+
+/* RPS command codes. */
+#define S626_RPS_CLRSIGNAL     0x00000000      /* CLEAR SIGNAL */
+#define S626_RPS_SETSIGNAL     0x10000000      /* SET SIGNAL */
+#define S626_RPS_NOP           0x00000000      /* NOP */
+#define S626_RPS_PAUSE         0x20000000      /* PAUSE */
+#define S626_RPS_UPLOAD                0x40000000      /* UPLOAD */
+#define S626_RPS_JUMP          0x80000000      /* JUMP */
+#define S626_RPS_LDREG         0x90000100      /* LDREG (1 uint32_t only) */
+#define S626_RPS_STREG         0xA0000100      /* STREG (1 uint32_t only) */
+#define S626_RPS_STOP          0x50000000      /* STOP */
+#define S626_RPS_IRQ           0x60000000      /* IRQ */
+
+#define S626_RPS_LOGICAL_OR    0x08000000      /* Logical OR conditionals. */
+#define S626_RPS_INVERT                0x04000000      /* Test for negated
+                                                * semaphores. */
+#define S626_RPS_DEBI          0x00000002      /* DEBI done */
+
+#define S626_RPS_SIG0          0x00200000      /* RPS semaphore 0
+                                                * (used by ADC). */
+#define S626_RPS_SIG1          0x00400000      /* RPS semaphore 1
+                                                * (used by DAC). */
+#define S626_RPS_SIG2          0x00800000      /* RPS semaphore 2
+                                                * (not used). */
+#define S626_RPS_GPIO2         0x00080000      /* RPS GPIO2 */
+#define S626_RPS_GPIO3         0x00100000      /* RPS GPIO3 */
+
+#define S626_RPS_SIGADC                S626_RPS_SIG0   /* Trigger/status for
+                                                * ADC's RPS program. */
+#define S626_RPS_SIGDAC                S626_RPS_SIG1   /* Trigger/status for
+                                                * DAC's RPS program. */
+
+/* RPS clock parameters. */
+#define S626_RPSCLK_SCALAR     8       /* This is apparent ratio of
+                                        * PCI/RPS clks (undocumented!!). */
+#define S626_RPSCLK_PER_US     (33 / S626_RPSCLK_SCALAR)
+                                       /* Number of RPS clocks in one
+                                        * microsecond. */
+
+/* Event counter source addresses. */
+#define S626_SBA_RPS_A0                0x27    /* Time of RPS0 busy, in PCI clocks. */
+
+/* GPIO constants. */
+#define S626_GPIO_BASE         0x10004000      /* GPIO 0,2,3 = inputs,
+                                                * GPIO3 = IRQ; GPIO1 = out. */
+#define S626_GPIO1_LO          0x00000000      /* GPIO1 set to LOW. */
+#define S626_GPIO1_HI          0x00001000      /* GPIO1 set to HIGH. */
+
+/* Primary Status Register (PSR) constants. */
+#define S626_PSR_DEBI_E                0x00040000      /* DEBI event flag. */
+#define S626_PSR_DEBI_S                0x00080000      /* DEBI status flag. */
+#define S626_PSR_A2_IN         0x00008000      /* Audio output DMA2 protection
+                                                * address reached. */
+#define S626_PSR_AFOU          0x00000800      /* Audio FIFO under/overflow
+                                                * detected. */
+#define S626_PSR_GPIO2         0x00000020      /* GPIO2 input pin: 0=AdcBusy,
+                                                * 1=AdcIdle. */
+#define S626_PSR_EC0S          0x00000001      /* Event counter 0 threshold
+                                                * reached. */
+
+/* Secondary Status Register (SSR) constants. */
+#define S626_SSR_AF2_OUT       0x00000200      /* Audio 2 output FIFO
+                                                * under/overflow detected. */
+
+/* Master Control Register 1 (MC1) constants. */
+#define S626_MC1_SOFT_RESET    0x80000000      /* Invoke 7146 soft reset. */
+#define S626_MC1_SHUTDOWN      0x3FFF0000      /* Shut down all MC1-controlled
+                                                * enables. */
+
+#define S626_MC1_ERPS1         0x2000  /* Enab/disable RPS task 1. */
+#define S626_MC1_ERPS0         0x1000  /* Enab/disable RPS task 0. */
+#define S626_MC1_DEBI          0x0800  /* Enab/disable DEBI pins. */
+#define S626_MC1_AUDIO         0x0200  /* Enab/disable audio port pins. */
+#define S626_MC1_I2C           0x0100  /* Enab/disable I2C interface. */
+#define S626_MC1_A2OUT         0x0008  /* Enab/disable transfer on A2 out. */
+#define S626_MC1_A2IN          0x0004  /* Enab/disable transfer on A2 in. */
+#define S626_MC1_A1IN          0x0001  /* Enab/disable transfer on A1 in. */
+
+/* Master Control Register 2 (MC2) constants. */
+#define S626_MC2_UPLD_DEBI     0x0002  /* Upload DEBI. */
+#define S626_MC2_UPLD_IIC      0x0001  /* Upload I2C. */
+#define S626_MC2_RPSSIG2       0x2000  /* RPS signal 2 (not used). */
+#define S626_MC2_RPSSIG1       0x1000  /* RPS signal 1 (DAC RPS busy). */
+#define S626_MC2_RPSSIG0       0x0800  /* RPS signal 0 (ADC RPS busy). */
+
+#define S626_MC2_ADC_RPS       S626_MC2_RPSSIG0        /* ADC RPS busy. */
+#define S626_MC2_DAC_RPS       S626_MC2_RPSSIG1        /* DAC RPS busy. */
+
+/* PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
+#define S626_P_PCI_BT_A                0x004C  /* Audio DMA burst/threshold control. */
+#define S626_P_DEBICFG         0x007C  /* DEBI configuration. */
+#define S626_P_DEBICMD         0x0080  /* DEBI command. */
+#define S626_P_DEBIPAGE                0x0084  /* DEBI page. */
+#define S626_P_DEBIAD          0x0088  /* DEBI target address. */
+#define S626_P_I2CCTRL         0x008C  /* I2C control. */
+#define S626_P_I2CSTAT         0x0090  /* I2C status. */
+#define S626_P_BASEA2_IN       0x00AC  /* Audio input 2 base physical DMAbuf
                                         * address. */
-#define P_PROTA2_IN            0x00B0  /* Audio input 2 physical DMAbuf
+#define S626_P_PROTA2_IN       0x00B0  /* Audio input 2 physical DMAbuf
                                         * protection address. */
-#define P_PAGEA2_IN            0x00B4  /* Audio input 2 paging attributes. */
-#define P_BASEA2_OUT           0x00B8  /* Audio output 2 base physical DMAbuf
+#define S626_P_PAGEA2_IN       0x00B4  /* Audio input 2 paging attributes. */
+#define S626_P_BASEA2_OUT      0x00B8  /* Audio output 2 base physical DMAbuf
                                         * address. */
-#define P_PROTA2_OUT           0x00BC  /* Audio output 2 physical DMAbuf
+#define S626_P_PROTA2_OUT      0x00BC  /* Audio output 2 physical DMAbuf
                                         * protection address. */
-#define P_PAGEA2_OUT           0x00C0  /* Audio output 2 paging attributes. */
-#define P_RPSPAGE0              0x00C4 /* RPS0 page. */
-#define P_RPSPAGE1              0x00C8 /* RPS1 page. */
-#define P_RPS0_TOUT            0x00D4  /* RPS0 time-out. */
-#define P_RPS1_TOUT            0x00D8  /* RPS1 time-out. */
-#define P_IER                   0x00DC /* Interrupt enable. */
-#define P_GPIO                  0x00E0 /* General-purpose I/O. */
-#define P_EC1SSR               0x00E4  /* Event counter set 1 source select. */
-#define P_ECT1R                        0x00EC  /* Event counter threshold set 1. */
-#define P_ACON1                 0x00F4 /* Audio control 1. */
-#define P_ACON2                 0x00F8 /* Audio control 2. */
-#define P_MC1                   0x00FC /* Master control 1. */
-#define P_MC2                   0x0100 /* Master control 2. */
-#define P_RPSADDR0              0x0104 /* RPS0 instruction pointer. */
-#define P_RPSADDR1              0x0108 /* RPS1 instruction pointer. */
-#define P_ISR                   0x010C /* Interrupt status. */
-#define P_PSR                   0x0110 /* Primary status. */
-#define P_SSR                   0x0114 /* Secondary status. */
-#define P_EC1R                 0x0118  /* Event counter set 1. */
-#define P_ADP4                 0x0138  /* Logical audio DMA pointer of audio
+#define S626_P_PAGEA2_OUT      0x00C0  /* Audio output 2 paging attributes. */
+#define S626_P_RPSPAGE0                0x00C4  /* RPS0 page. */
+#define S626_P_RPSPAGE1                0x00C8  /* RPS1 page. */
+#define S626_P_RPS0_TOUT       0x00D4  /* RPS0 time-out. */
+#define S626_P_RPS1_TOUT       0x00D8  /* RPS1 time-out. */
+#define S626_P_IER             0x00DC  /* Interrupt enable. */
+#define S626_P_GPIO            0x00E0  /* General-purpose I/O. */
+#define S626_P_EC1SSR          0x00E4  /* Event counter set 1 source select. */
+#define S626_P_ECT1R           0x00EC  /* Event counter threshold set 1. */
+#define S626_P_ACON1           0x00F4  /* Audio control 1. */
+#define S626_P_ACON2           0x00F8  /* Audio control 2. */
+#define S626_P_MC1             0x00FC  /* Master control 1. */
+#define S626_P_MC2             0x0100  /* Master control 2. */
+#define S626_P_RPSADDR0                0x0104  /* RPS0 instruction pointer. */
+#define S626_P_RPSADDR1                0x0108  /* RPS1 instruction pointer. */
+#define S626_P_ISR             0x010C  /* Interrupt status. */
+#define S626_P_PSR             0x0110  /* Primary status. */
+#define S626_P_SSR             0x0114  /* Secondary status. */
+#define S626_P_EC1R            0x0118  /* Event counter set 1. */
+#define S626_P_ADP4            0x0138  /* Logical audio DMA pointer of audio
                                         * input FIFO A2_IN. */
-#define P_FB_BUFFER1            0x0144 /* Audio feedback buffer 1. */
-#define P_FB_BUFFER2            0x0148 /* Audio feedback buffer 2. */
-#define P_TSL1                  0x0180 /* Audio time slot list 1. */
-#define P_TSL2                  0x01C0 /* Audio time slot list 2. */
+#define S626_P_FB_BUFFER1      0x0144  /* Audio feedback buffer 1. */
+#define S626_P_FB_BUFFER2      0x0148  /* Audio feedback buffer 2. */
+#define S626_P_TSL1            0x0180  /* Audio time slot list 1. */
+#define S626_P_TSL2            0x01C0  /* Audio time slot list 2. */
 
-/*  LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
-/*  Analog I/O registers: */
-#define LP_DACPOL              0x0082  /*   Write DAC polarity. */
-#define LP_GSEL                        0x0084  /*   Write ADC gain. */
-#define LP_ISEL                        0x0086  /*   Write ADC channel select. */
+/* LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
+/* Analog I/O registers: */
+#define S626_LP_DACPOL         0x0082  /* Write DAC polarity. */
+#define S626_LP_GSEL           0x0084  /* Write ADC gain. */
+#define S626_LP_ISEL           0x0086  /* Write ADC channel select. */
 
 /* Digital I/O registers */
-#define LP_RDDIN(x)            (0x0040 + (x) * 0x10)   /* R: digital input */
-#define LP_WRINTSEL(x)         (0x0042 + (x) * 0x10)   /* W: int enable */
-#define LP_WREDGSEL(x)         (0x0044 + (x) * 0x10)   /* W: edge selection */
-#define LP_WRCAPSEL(x)         (0x0046 + (x) * 0x10)   /* W: capture enable */
-#define LP_RDCAPFLG(x)         (0x0048 + (x) * 0x10)   /* R: edges captured */
-#define LP_WRDOUT(x)           (0x0048 + (x) * 0x10)   /* W: digital output */
-#define LP_RDINTSEL(x)         (0x004a + (x) * 0x10)   /* R: int enable */
-#define LP_RDEDGSEL(x)         (0x004c + (x) * 0x10)   /* R: edge selection */
-#define LP_RDCAPSEL(x)         (0x004e + (x) * 0x10)   /* R: capture enable */
-
-/*  Counter Registers (read/write): */
-#define LP_CR0A                        0x0000  /*   0A setup register. */
-#define LP_CR0B                        0x0002  /*   0B setup register. */
-#define LP_CR1A                        0x0004  /*   1A setup register. */
-#define LP_CR1B                        0x0006  /*   1B setup register. */
-#define LP_CR2A                        0x0008  /*   2A setup register. */
-#define LP_CR2B                        0x000A  /*   2B setup register. */
-
-/*  Counter PreLoad (write) and Latch (read) Registers: */
-#define        LP_CNTR0ALSW            0x000C  /*   0A lsw. */
-#define        LP_CNTR0AMSW            0x000E  /*   0A msw. */
-#define        LP_CNTR0BLSW            0x0010  /*   0B lsw. */
-#define        LP_CNTR0BMSW            0x0012  /*   0B msw. */
-#define        LP_CNTR1ALSW            0x0014  /*   1A lsw. */
-#define        LP_CNTR1AMSW            0x0016  /*   1A msw. */
-#define        LP_CNTR1BLSW            0x0018  /*   1B lsw. */
-#define        LP_CNTR1BMSW            0x001A  /*   1B msw. */
-#define        LP_CNTR2ALSW            0x001C  /*   2A lsw. */
-#define        LP_CNTR2AMSW            0x001E  /*   2A msw. */
-#define        LP_CNTR2BLSW            0x0020  /*   2B lsw. */
-#define        LP_CNTR2BMSW            0x0022  /*   2B msw. */
-
-/*  Miscellaneous Registers (read/write): */
-#define LP_MISC1               0x0088  /*   Read/write Misc1. */
-#define LP_WRMISC2             0x0090  /*   Write Misc2. */
-#define LP_RDMISC2             0x0082  /*   Read Misc2. */
-
-/*  Bit masks for MISC1 register that are the same for reads and writes. */
-#define MISC1_WENABLE          0x8000  /* enab writes to MISC2 (except Clear
+#define S626_LP_RDDIN(x)       (0x0040 + (x) * 0x10)   /* R: digital input */
+#define S626_LP_WRINTSEL(x)    (0x0042 + (x) * 0x10)   /* W: int enable */
+#define S626_LP_WREDGSEL(x)    (0x0044 + (x) * 0x10)   /* W: edge selection */
+#define S626_LP_WRCAPSEL(x)    (0x0046 + (x) * 0x10)   /* W: capture enable */
+#define S626_LP_RDCAPFLG(x)    (0x0048 + (x) * 0x10)   /* R: edges captured */
+#define S626_LP_WRDOUT(x)      (0x0048 + (x) * 0x10)   /* W: digital output */
+#define S626_LP_RDINTSEL(x)    (0x004a + (x) * 0x10)   /* R: int enable */
+#define S626_LP_RDEDGSEL(x)    (0x004c + (x) * 0x10)   /* R: edge selection */
+#define S626_LP_RDCAPSEL(x)    (0x004e + (x) * 0x10)   /* R: capture enable */
+
+/* Counter Registers (read/write): */
+#define S626_LP_CR0A           0x0000  /* 0A setup register. */
+#define S626_LP_CR0B           0x0002  /* 0B setup register. */
+#define S626_LP_CR1A           0x0004  /* 1A setup register. */
+#define S626_LP_CR1B           0x0006  /* 1B setup register. */
+#define S626_LP_CR2A           0x0008  /* 2A setup register. */
+#define S626_LP_CR2B           0x000A  /* 2B setup register. */
+
+/* Counter PreLoad (write) and Latch (read) Registers: */
+#define        S626_LP_CNTR0ALSW       0x000C  /* 0A lsw. */
+#define        S626_LP_CNTR0AMSW       0x000E  /* 0A msw. */
+#define        S626_LP_CNTR0BLSW       0x0010  /* 0B lsw. */
+#define        S626_LP_CNTR0BMSW       0x0012  /* 0B msw. */
+#define        S626_LP_CNTR1ALSW       0x0014  /* 1A lsw. */
+#define        S626_LP_CNTR1AMSW       0x0016  /* 1A msw. */
+#define        S626_LP_CNTR1BLSW       0x0018  /* 1B lsw. */
+#define        S626_LP_CNTR1BMSW       0x001A  /* 1B msw. */
+#define        S626_LP_CNTR2ALSW       0x001C  /* 2A lsw. */
+#define        S626_LP_CNTR2AMSW       0x001E  /* 2A msw. */
+#define        S626_LP_CNTR2BLSW       0x0020  /* 2B lsw. */
+#define        S626_LP_CNTR2BMSW       0x0022  /* 2B msw. */
+
+/* Miscellaneous Registers (read/write): */
+#define S626_LP_MISC1          0x0088  /* Read/write Misc1. */
+#define S626_LP_WRMISC2                0x0090  /* Write Misc2. */
+#define S626_LP_RDMISC2                0x0082  /* Read Misc2. */
+
+/* Bit masks for MISC1 register that are the same for reads and writes. */
+#define S626_MISC1_WENABLE     0x8000  /* enab writes to MISC2 (except Clear
                                         * Watchdog bit). */
-#define MISC1_WDISABLE         0x0000  /* Disable writes to MISC2. */
-#define MISC1_EDCAP            0x1000  /* enab edge capture on DIO chans
-                                        * specified by  LP_WRCAPSELx. */
-#define MISC1_NOEDCAP          0x0000  /* Disable edge capture on specified
+#define S626_MISC1_WDISABLE    0x0000  /* Disable writes to MISC2. */
+#define S626_MISC1_EDCAP       0x1000  /* Enable edge capture on DIO chans
+                                        * specified by S626_LP_WRCAPSELx. */
+#define S626_MISC1_NOEDCAP     0x0000  /* Disable edge capture on specified
                                         * DIO chans. */
 
-/*  Bit masks for MISC1 register reads. */
-#define RDMISC1_WDTIMEOUT      0x4000  /*  Watchdog timer timed out. */
-
-/*  Bit masks for MISC2 register writes. */
-#define WRMISC2_WDCLEAR                0x8000  /*  Reset watchdog timer to zero. */
-#define WRMISC2_CHARGE_ENABLE  0x4000  /*  enab battery trickle charging. */
-
-/*  Bit masks for MISC2 register that are the same for reads and writes. */
-#define MISC2_BATT_ENABLE      0x0008  /*  Backup battery enable. */
-#define MISC2_WDENABLE         0x0004  /*  Watchdog timer enable. */
-#define MISC2_WDPERIOD_MASK    0x0003  /*  Watchdog interval */
-                                               /*  select mask. */
-
-/*  Bit masks for ACON1 register. */
-#define A2_RUN                 0x40000000      /*  Run A2 based on TSL2. */
-#define A1_RUN                 0x20000000      /*  Run A1 based on TSL1. */
-#define A1_SWAP                        0x00200000      /*  Use big-endian for A1. */
-#define A2_SWAP                        0x00100000      /*  Use big-endian for A2. */
-#define WS_MODES               0x00019999      /*  WS0 = TSL1 trigger */
-                                               /*  input, WS1-WS4 = */
-                                               /*  CS* outputs. */
-
-#if PLATFORM == INTEL          /* Base ACON1 config: always run A1 based
-                                * on TSL1. */
-#define ACON1_BASE             (WS_MODES | A1_RUN)
-#elif PLATFORM == MOTOROLA
-#define ACON1_BASE             (WS_MODES | A1_RUN | A1_SWAP | A2_SWAP)
+/* Bit masks for MISC1 register reads. */
+#define S626_RDMISC1_WDTIMEOUT 0x4000  /* Watchdog timer timed out. */
+
+/* Bit masks for MISC2 register writes. */
+#define S626_WRMISC2_WDCLEAR   0x8000  /* Reset watchdog timer to zero. */
+#define S626_WRMISC2_CHARGE_ENABLE 0x4000 /* Enable battery trickle charging. */
+
+/* Bit masks for MISC2 register that are the same for reads and writes. */
+#define S626_MISC2_BATT_ENABLE 0x0008  /* Backup battery enable. */
+#define S626_MISC2_WDENABLE    0x0004  /* Watchdog timer enable. */
+#define S626_MISC2_WDPERIOD_MASK 0x0003        /* Watchdog interval select mask. */
+
+/* Bit masks for ACON1 register. */
+#define S626_A2_RUN            0x40000000      /* Run A2 based on TSL2. */
+#define S626_A1_RUN            0x20000000      /* Run A1 based on TSL1. */
+#define S626_A1_SWAP           0x00200000      /* Use big-endian for A1. */
+#define S626_A2_SWAP           0x00100000      /* Use big-endian for A2. */
+#define S626_WS_MODES          0x00019999      /* WS0 = TSL1 trigger input,
+                                                * WS1-WS4 = CS* outputs. */
+
+#if S626_PLATFORM == S626_INTEL                /* Base ACON1 config: always run
+                                        * A1 based on TSL1. */
+#define S626_ACON1_BASE                (S626_WS_MODES | S626_A1_RUN)
+#elif S626_PLATFORM == S626_MOTOROLA
+#define S626_ACON1_BASE                \
+       (S626_WS_MODES | S626_A1_RUN | S626_A1_SWAP | S626_A2_SWAP)
 #endif
 
-#define ACON1_ADCSTART         ACON1_BASE      /* Start ADC: run A1
-                                                *  based on TSL1. */
-#define ACON1_DACSTART         (ACON1_BASE | A2_RUN)
+#define S626_ACON1_ADCSTART    S626_ACON1_BASE /* Start ADC: run A1
+                                                * based on TSL1. */
+#define S626_ACON1_DACSTART    (S626_ACON1_BASE | S626_A2_RUN)
 /* Start transmit to DAC: run A2 based on TSL2. */
-#define ACON1_DACSTOP          ACON1_BASE      /*  Halt A2. */
-
-/*  Bit masks for ACON2 register. */
-#define A1_CLKSRC_BCLK1                0x00000000      /*  A1 bit rate = BCLK1 (ADC). */
-#define A2_CLKSRC_X1           0x00800000      /*  A2 bit rate = ACLK/1 (DACs). */
-#define A2_CLKSRC_X2           0x00C00000      /*  A2 bit rate = ACLK/2 (DACs). */
-#define A2_CLKSRC_X4           0x01400000      /*  A2 bit rate = ACLK/4 (DACs). */
-#define INVERT_BCLK2           0x00100000      /*  Invert BCLK2 (DACs). */
-#define BCLK2_OE               0x00040000      /*  enab BCLK2 (DACs). */
-#define ACON2_XORMASK          0x000C0000      /*  XOR mask for ACON2 */
-                                               /*  active-low bits. */
-
-#define ACON2_INIT             (ACON2_XORMASK ^ (A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE))
-
-/*  Bit masks for timeslot records. */
-#define WS1                    0x40000000      /*  WS output to assert. */
-#define WS2                    0x20000000
-#define WS3                    0x10000000
-#define WS4                    0x08000000
-#define RSD1                   0x01000000      /* Shift A1 data in on SD1. */
-#define SDW_A1                 0x00800000      /* Store rcv'd char at next
-                                                * char slot of DWORD1 buffer. */
-#define SIB_A1                 0x00400000      /* Store rcv'd char at next
+#define S626_ACON1_DACSTOP     S626_ACON1_BASE /* Halt A2. */
+
+/* Bit masks for ACON2 register. */
+#define S626_A1_CLKSRC_BCLK1   0x00000000      /* A1 bit rate = BCLK1 (ADC). */
+#define S626_A2_CLKSRC_X1      0x00800000      /* A2 bit rate = ACLK/1
+                                                * (DACs). */
+#define S626_A2_CLKSRC_X2      0x00C00000      /* A2 bit rate = ACLK/2
+                                                * (DACs). */
+#define S626_A2_CLKSRC_X4      0x01400000      /* A2 bit rate = ACLK/4
+                                                * (DACs). */
+#define S626_INVERT_BCLK2      0x00100000      /* Invert BCLK2 (DACs). */
+#define S626_BCLK2_OE          0x00040000      /* Enable BCLK2 (DACs). */
+#define S626_ACON2_XORMASK     0x000C0000      /* XOR mask for ACON2
+                                                * active-low bits. */
+
+#define S626_ACON2_INIT                (S626_ACON2_XORMASK ^ \
+                                (S626_A1_CLKSRC_BCLK1 | S626_A2_CLKSRC_X2 | \
+                                 S626_INVERT_BCLK2 | S626_BCLK2_OE))
+
+/* Bit masks for timeslot records. */
+#define S626_WS1               0x40000000      /* WS output to assert. */
+#define S626_WS2               0x20000000
+#define S626_WS3               0x10000000
+#define S626_WS4               0x08000000
+#define S626_RSD1              0x01000000      /* Shift A1 data in on SD1. */
+#define S626_SDW_A1            0x00800000      /* Store rcv'd char at next char
+                                                * slot of DWORD1 buffer. */
+#define S626_SIB_A1            0x00400000      /* Store rcv'd char at next
                                                 * char slot of FB1 buffer. */
-#define SF_A1                  0x00200000      /* Write unsigned long
+#define S626_SF_A1             0x00200000      /* Write unsigned long
                                                 * buffer to input FIFO. */
 
 /* Select parallel-to-serial converter's data source: */
-#define XFIFO_0                        0x00000000      /*    Data fifo byte 0. */
-#define XFIFO_1                        0x00000010      /*    Data fifo byte 1. */
-#define XFIFO_2                        0x00000020      /*    Data fifo byte 2. */
-#define XFIFO_3                        0x00000030      /*    Data fifo byte 3. */
-#define XFB0                   0x00000040      /*    FB_BUFFER byte 0. */
-#define XFB1                   0x00000050      /*    FB_BUFFER byte 1. */
-#define XFB2                   0x00000060      /*    FB_BUFFER byte 2. */
-#define XFB3                   0x00000070      /*    FB_BUFFER byte 3. */
-#define SIB_A2                 0x00000200      /* Store next dword from A2's
-                                                * input shifter to FB2 buffer. */
-#define SF_A2                  0x00000100      /* Store next dword from A2's
+#define S626_XFIFO_0           0x00000000      /* Data fifo byte 0. */
+#define S626_XFIFO_1           0x00000010      /* Data fifo byte 1. */
+#define S626_XFIFO_2           0x00000020      /* Data fifo byte 2. */
+#define S626_XFIFO_3           0x00000030      /* Data fifo byte 3. */
+#define S626_XFB0              0x00000040      /* FB_BUFFER byte 0. */
+#define S626_XFB1              0x00000050      /* FB_BUFFER byte 1. */
+#define S626_XFB2              0x00000060      /* FB_BUFFER byte 2. */
+#define S626_XFB3              0x00000070      /* FB_BUFFER byte 3. */
+#define S626_SIB_A2            0x00000200      /* Store next dword from A2's
+                                                * input shifter to FB2
+                                                * buffer. */
+#define S626_SF_A2             0x00000100      /* Store next dword from A2's
                                                 * input shifter to its input
                                                 * fifo. */
-#define LF_A2                  0x00000080      /* Load next dword from A2's
+#define S626_LF_A2             0x00000080      /* Load next dword from A2's
                                                 * output fifo into its
                                                 * output dword buffer. */
-#define XSD2                   0x00000008      /*  Shift data out on SD2. */
-#define RSD3                   0x00001800      /*  Shift data in on SD3. */
-#define RSD2                   0x00001000      /*  Shift data in on SD2. */
-#define LOW_A2                 0x00000002      /*  Drive last SD low */
-                                               /*  for 7 clks, then */
-                                               /*  tri-state. */
-#define EOS                    0x00000001      /*  End of superframe. */
-
-/*  I2C configuration constants. */
-#define I2C_CLKSEL             0x0400
-/* I2C bit rate = PCIclk/480 = 68.75 KHz. */
-
-#define I2C_BITRATE            68.75
-/* I2C bus data bit rate (determined by I2C_CLKSEL) in KHz. */
-
-#define I2C_WRTIME             15.0
-/* Worst case time, in msec, for EEPROM internal write op. */
-
-/*  I2C manifest constants. */
-
-/*  Max retries to wait for EEPROM write. */
-#define I2C_RETRIES            (I2C_WRTIME * I2C_BITRATE / 9.0)
-#define I2C_ERR                        0x0002  /*  I2C control/status */
-                                               /*  flag ERROR. */
-#define I2C_BUSY               0x0001  /*  I2C control/status */
-                                               /*  flag BUSY. */
-#define I2C_ABORT              0x0080  /*  I2C status flag ABORT. */
-#define I2C_ATTRSTART          0x3     /*  I2C attribute START. */
-#define I2C_ATTRCONT           0x2     /*  I2C attribute CONT. */
-#define I2C_ATTRSTOP           0x1     /*  I2C attribute STOP. */
-#define I2C_ATTRNOP            0x0     /*  I2C attribute NOP. */
-
-/*  I2C read command  | EEPROM address. */
-#define I2CR                   (devpriv->I2CAdrs | 1)
-
-/*  I2C write command | EEPROM address. */
-#define I2CW                   (devpriv->I2CAdrs)
-
-/*  Code macros used for constructing I2C command bytes. */
-#define I2C_B2(ATTR, VAL)      (((ATTR) << 6) | ((VAL) << 24))
-#define I2C_B1(ATTR, VAL)      (((ATTR) << 4) | ((VAL) << 16))
-#define I2C_B0(ATTR, VAL)      (((ATTR) << 2) | ((VAL) <<  8))
-
-/* oldest */
-#define P_DEBICFGq              0x007C /*  DEBI configuration. */
-#define P_DEBICMDq              0x0080 /*  DEBI command. */
-#define P_DEBIPAGEq             0x0084 /*  DEBI page. */
-#define P_DEBIADq               0x0088 /*  DEBI target address. */
-
-#define DEBI_CFG_TOQ           0x03C00000      /*  timeout (15 PCI cycles) */
-#define DEBI_CFG_FASTQ         0x10000000      /*  fast mode enable */
-#define DEBI_CFG_16Q           0x00080000      /*  16-bit access enable */
-#define DEBI_CFG_INCQ          0x00040000      /*  enable address increment */
-#define DEBI_CFG_TIMEROFFQ     0x00010000      /*  disable timer */
-#define DEBI_CMD_RDQ           0x00050000      /*  read immediate 2 bytes */
-#define DEBI_CMD_WRQ           0x00040000      /*  write immediate 2 bytes */
-#define DEBI_PAGE_DISABLEQ     0x00000000      /*  paging disable */
-
-/*  DEBI command constants. */
-#define DEBI_CMD_SIZE16                (2 << 17)       /*  Transfer size is */
-                                               /*  always 2 bytes. */
-#define DEBI_CMD_READ          0x00010000      /*  Read operation. */
-#define DEBI_CMD_WRITE         0x00000000      /*  Write operation. */
-
-/*  Read immediate 2 bytes. */
-#define DEBI_CMD_RDWORD                (DEBI_CMD_READ  | DEBI_CMD_SIZE16)
-
-/*  Write immediate 2 bytes. */
-#define DEBI_CMD_WRWORD                (DEBI_CMD_WRITE | DEBI_CMD_SIZE16)
-
-/*  DEBI configuration constants. */
-#define DEBI_CFG_XIRQ_EN       0x80000000      /*  enab external */
-                                               /*  interrupt on GPIO3. */
-#define DEBI_CFG_XRESUME       0x40000000      /*  Resume block */
-                                               /*  transfer when XIRQ */
-                                               /*  deasserted. */
-#define DEBI_CFG_FAST          0x10000000      /*  Fast mode enable. */
-
-/*  4-bit field that specifies DEBI timeout value in PCI clock cycles: */
-#define DEBI_CFG_TOUT_BIT      22      /*    Finish DEBI cycle after */
-                                       /*    this many clocks. */
-
-/*  2-bit field that specifies Endian byte lane steering: */
-#define DEBI_CFG_SWAP_NONE     0x00000000      /*    Straight - don't */
-                                               /*    swap any bytes */
-                                               /*    (Intel). */
-#define DEBI_CFG_SWAP_2                0x00100000      /*    2-byte swap (Motorola). */
-#define DEBI_CFG_SWAP_4                0x00200000      /*    4-byte swap. */
-#define DEBI_CFG_16            0x00080000      /*  Slave is able to */
-                                               /*  serve 16-bit */
-                                               /*  cycles. */
-
-#define DEBI_CFG_SLAVE16       0x00080000      /*  Slave is able to */
-                                               /*  serve 16-bit */
-                                               /*  cycles. */
-#define DEBI_CFG_INC           0x00040000      /*  enab address */
-                                               /*  increment for block */
-                                               /*  transfers. */
-#define DEBI_CFG_INTEL         0x00020000      /*  Intel style local bus. */
-#define DEBI_CFG_TIMEROFF      0x00010000      /*  Disable timer. */
-
-#if PLATFORM == INTEL
-
-#define DEBI_TOUT              7       /*  Wait 7 PCI clocks */
-                                               /*  (212 ns) before */
-                                               /*  polling RDY. */
-
-/*  Intel byte lane steering (pass through all byte lanes). */
-#define DEBI_SWAP              DEBI_CFG_SWAP_NONE
-
-#elif PLATFORM == MOTOROLA
-
-#define DEBI_TOUT              15      /*  Wait 15 PCI clocks (454 ns) */
-                                       /*  maximum before timing out. */
-#define DEBI_SWAP              DEBI_CFG_SWAP_2 /*  Motorola byte lane steering. */
+#define S626_XSD2              0x00000008      /* Shift data out on SD2. */
+#define S626_RSD3              0x00001800      /* Shift data in on SD3. */
+#define S626_RSD2              0x00001000      /* Shift data in on SD2. */
+#define S626_LOW_A2            0x00000002      /* Drive last SD low for 7 clks,
+                                                * then tri-state. */
+#define S626_EOS               0x00000001      /* End of superframe. */
+
+/* I2C configuration constants. */
+#define S626_I2C_CLKSEL                0x0400          /* I2C bit rate =
+                                                * PCIclk/480 = 68.75 KHz. */
+#define S626_I2C_BITRATE       68.75           /* I2C bus data bit rate
+                                                * (determined by
+                                                * S626_I2C_CLKSEL) in KHz. */
+#define S626_I2C_WRTIME                15.0            /* Worst case time, in msec,
+                                                * for EEPROM internal write
+                                                * op. */
+
+/* I2C manifest constants. */
+
+/* Max retries to wait for EEPROM write. */
+#define S626_I2C_RETRIES       (S626_I2C_WRTIME * S626_I2C_BITRATE / 9.0)
+#define S626_I2C_ERR           0x0002  /* I2C control/status flag ERROR. */
+#define S626_I2C_BUSY          0x0001  /* I2C control/status flag BUSY. */
+#define S626_I2C_ABORT         0x0080  /* I2C status flag ABORT. */
+#define S626_I2C_ATTRSTART     0x3     /* I2C attribute START. */
+#define S626_I2C_ATTRCONT      0x2     /* I2C attribute CONT. */
+#define S626_I2C_ATTRSTOP      0x1     /* I2C attribute STOP. */
+#define S626_I2C_ATTRNOP       0x0     /* I2C attribute NOP. */
+
+/* Code macros used for constructing I2C command bytes. */
+#define S626_I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
+#define S626_I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
+#define S626_I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) <<  8))
+
+/* DEBI command constants. */
+#define S626_DEBI_CMD_SIZE16   (2 << 17)       /* Transfer size is always
+                                                * 2 bytes. */
+#define S626_DEBI_CMD_READ     0x00010000      /* Read operation. */
+#define S626_DEBI_CMD_WRITE    0x00000000      /* Write operation. */
+
+/* Read immediate 2 bytes. */
+#define S626_DEBI_CMD_RDWORD   (S626_DEBI_CMD_READ | S626_DEBI_CMD_SIZE16)
+
+/* Write immediate 2 bytes. */
+#define S626_DEBI_CMD_WRWORD   (S626_DEBI_CMD_WRITE | S626_DEBI_CMD_SIZE16)
+
+/* DEBI configuration constants. */
+#define S626_DEBI_CFG_XIRQ_EN  0x80000000      /* Enable external interrupt
+                                                * on GPIO3. */
+#define S626_DEBI_CFG_XRESUME  0x40000000      /* Resume block */
+                                               /* Transfer when XIRQ
+                                                * deasserted. */
+#define S626_DEBI_CFG_TOQ      0x03C00000      /* Timeout (15 PCI cycles). */
+#define S626_DEBI_CFG_FAST     0x10000000      /* Fast mode enable. */
+
+/* 4-bit field that specifies DEBI timeout value in PCI clock cycles: */
+#define S626_DEBI_CFG_TOUT_BIT 22      /* Finish DEBI cycle after this many
+                                        * clocks. */
+
+/* 2-bit field that specifies Endian byte lane steering: */
+#define S626_DEBI_CFG_SWAP_NONE        0x00000000      /* Straight - don't swap any
+                                                * bytes (Intel). */
+#define S626_DEBI_CFG_SWAP_2   0x00100000      /* 2-byte swap (Motorola). */
+#define S626_DEBI_CFG_SWAP_4   0x00200000      /* 4-byte swap. */
+#define S626_DEBI_CFG_SLAVE16  0x00080000      /* Slave is able to serve
+                                                * 16-bit cycles. */
+#define S626_DEBI_CFG_INC      0x00040000      /* Enable address increment
+                                                * for block transfers. */
+#define S626_DEBI_CFG_INTEL    0x00020000      /* Intel style local bus. */
+#define S626_DEBI_CFG_TIMEROFF 0x00010000      /* Disable timer. */
+
+#if S626_PLATFORM == S626_INTEL
+
+#define S626_DEBI_TOUT         7       /* Wait 7 PCI clocks (212 ns) before
+                                        * polling RDY. */
+
+/* Intel byte lane steering (pass through all byte lanes). */
+#define S626_DEBI_SWAP         S626_DEBI_CFG_SWAP_NONE
+
+#elif S626_PLATFORM == S626_MOTOROLA
+
+#define S626_DEBI_TOUT         15      /* Wait 15 PCI clocks (454 ns) maximum
+                                        * before timing out. */
+
+/* Motorola byte lane steering. */
+#define S626_DEBI_SWAP         S626_DEBI_CFG_SWAP_2
 
 #endif
 
-/*  DEBI page table constants. */
-#define DEBI_PAGE_DISABLE      0x00000000      /*  Paging disable. */
-
-/* ******* EXTRA FROM OTHER SANSORAY  * .h  ******* */
-
-/*  LoadSrc values: */
-#define LOADSRC_INDX           0       /*  Preload core in response to */
-                                       /*  Index. */
-#define LOADSRC_OVER           1       /*  Preload core in response to */
-                                       /*  Overflow. */
-#define LOADSRCB_OVERA         2       /*  Preload B core in response */
-                                       /*  to A Overflow. */
-#define LOADSRC_NONE           3       /*  Never preload core. */
-
-/*  IntSrc values: */
-#define INTSRC_NONE            0       /*  Interrupts disabled. */
-#define INTSRC_OVER            1       /*  Interrupt on Overflow. */
-#define INTSRC_INDX            2       /*  Interrupt on Index. */
-#define INTSRC_BOTH            3       /*  Interrupt on Index or Overflow. */
-
-/*  LatchSrc values: */
-#define LATCHSRC_AB_READ       0       /*  Latch on read. */
-#define LATCHSRC_A_INDXA       1       /*  Latch A on A Index. */
-#define LATCHSRC_B_INDXB       2       /*  Latch B on B Index. */
-#define LATCHSRC_B_OVERA       3       /*  Latch B on A Overflow. */
-
-/*  IndxSrc values: */
-#define INDXSRC_HARD           0       /*  Hardware or software index. */
-#define INDXSRC_SOFT           1       /*  Software index only. */
-
-/*  IndxPol values: */
-#define INDXPOL_POS            0       /*  Index input is active high. */
-#define INDXPOL_NEG            1       /*  Index input is active low. */
-
-/*  ClkSrc values: */
-#define CLKSRC_COUNTER         0       /*  Counter mode. */
-#define CLKSRC_TIMER           2       /*  Timer mode. */
-#define CLKSRC_EXTENDER                3       /*  Extender mode. */
-
-/*  ClkPol values: */
-#define CLKPOL_POS             0       /*  Counter/Extender clock is */
-                                       /*  active high. */
-#define CLKPOL_NEG             1       /*  Counter/Extender clock is */
-                                       /*  active low. */
-#define CNTDIR_UP              0       /*  Timer counts up. */
-#define CNTDIR_DOWN            1       /*  Timer counts down. */
-
-/*  ClkEnab values: */
-#define CLKENAB_ALWAYS         0       /*  Clock always enabled. */
-#define CLKENAB_INDEX          1       /*  Clock is enabled by index. */
-
-/*  ClkMult values: */
-#define CLKMULT_4X             0       /*  4x clock multiplier. */
-#define CLKMULT_2X             1       /*  2x clock multiplier. */
-#define CLKMULT_1X             2       /*  1x clock multiplier. */
-
-/*  Bit Field positions in COUNTER_SETUP structure: */
-#define BF_LOADSRC             9       /*  Preload trigger. */
-#define BF_INDXSRC             7       /*  Index source. */
-#define BF_INDXPOL             6       /*  Index polarity. */
-#define BF_CLKSRC              4       /*  Clock source. */
-#define BF_CLKPOL              3       /*  Clock polarity/count direction. */
-#define BF_CLKMULT             1       /*  Clock multiplier. */
-#define BF_CLKENAB             0       /*  Clock enable. */
-
-/*  Enumerated counter operating modes specified by ClkSrc bit field in */
-/*  a COUNTER_SETUP. */
-
-#define CLKSRC_COUNTER         0       /*  Counter: ENC_C clock, ENC_D */
-                                       /*  direction. */
-#define CLKSRC_TIMER           2       /*  Timer: SYS_C clock, */
-                                       /*  direction specified by */
-                                       /*  ClkPol. */
-#define CLKSRC_EXTENDER                3       /*  Extender: OVR_A clock, */
-                                       /*  ENC_D direction. */
-
-/*  Enumerated counter clock multipliers. */
-
-#define MULT_X0                        0x0003  /*  Supports no multipliers; */
-                                       /*  fixed physical multiplier = */
-                                       /*  3. */
-#define MULT_X1                        0x0002  /*  Supports multiplier x1; */
-                                       /*  fixed physical multiplier = */
-                                       /*  2. */
-#define MULT_X2                        0x0001  /*  Supports multipliers x1, */
-                                       /*  x2; physical multipliers = */
-                                       /*  1 or 2. */
-#define MULT_X4                        0x0000  /*  Supports multipliers x1, */
-                                       /*  x2, x4; physical */
-                                       /*  multipliers = 0, 1 or 2. */
-
-/*  Sanity-check limits for parameters. */
-
-#define NUM_COUNTERS           6       /*  Maximum valid counter */
-                                       /*  logical channel number. */
-#define NUM_INTSOURCES         4
-#define NUM_LATCHSOURCES       4
-#define NUM_CLKMULTS           4
-#define NUM_CLKSOURCES         4
-#define NUM_CLKPOLS            2
-#define NUM_INDEXPOLS          2
-#define NUM_INDEXSOURCES       2
-#define NUM_LOADTRIGS          4
-
-/*  Bit field positions in CRA and CRB counter control registers. */
-
-/*  Bit field positions in CRA: */
-#define CRABIT_INDXSRC_B       14      /*    B index source. */
-#define CRABIT_CLKSRC_B                12      /*    B clock source. */
-#define CRABIT_INDXPOL_A       11      /*    A index polarity. */
-#define CRABIT_LOADSRC_A        9      /*    A preload trigger. */
-#define CRABIT_CLKMULT_A        7      /*    A clock multiplier. */
-#define CRABIT_INTSRC_A                 5      /*    A interrupt source. */
-#define CRABIT_CLKPOL_A                 4      /*    A clock polarity. */
-#define CRABIT_INDXSRC_A        2      /*    A index source. */
-#define CRABIT_CLKSRC_A                 0      /*    A clock source. */
-
-/*  Bit field positions in CRB: */
-#define CRBBIT_INTRESETCMD     15      /*    Interrupt reset command. */
-#define CRBBIT_INTRESET_B      14      /*    B interrupt reset enable. */
-#define CRBBIT_INTRESET_A      13      /*    A interrupt reset enable. */
-#define CRBBIT_CLKENAB_A       12      /*    A clock enable. */
-#define CRBBIT_INTSRC_B                10      /*    B interrupt source. */
-#define CRBBIT_LATCHSRC                 8      /*    A/B latch source. */
-#define CRBBIT_LOADSRC_B        6      /*    B preload trigger. */
-#define CRBBIT_CLKMULT_B        3      /*    B clock multiplier. */
-#define CRBBIT_CLKENAB_B        2      /*    B clock enable. */
-#define CRBBIT_INDXPOL_B        1      /*    B index polarity. */
-#define CRBBIT_CLKPOL_B                 0      /*    B clock polarity. */
-
-/*  Bit field masks for CRA and CRB. */
-
-#define CRAMSK_INDXSRC_B       (3 << CRABIT_INDXSRC_B)
-#define CRAMSK_CLKSRC_B                (3 << CRABIT_CLKSRC_B)
-#define CRAMSK_INDXPOL_A       (1 << CRABIT_INDXPOL_A)
-#define CRAMSK_LOADSRC_A       (3 << CRABIT_LOADSRC_A)
-#define CRAMSK_CLKMULT_A       (3 << CRABIT_CLKMULT_A)
-#define CRAMSK_INTSRC_A                (3 << CRABIT_INTSRC_A)
-#define CRAMSK_CLKPOL_A                (3 << CRABIT_CLKPOL_A)
-#define CRAMSK_INDXSRC_A       (3 << CRABIT_INDXSRC_A)
-#define CRAMSK_CLKSRC_A                (3 << CRABIT_CLKSRC_A)
-
-#define CRBMSK_INTRESETCMD     (1 << CRBBIT_INTRESETCMD)
-#define CRBMSK_INTRESET_B      (1 << CRBBIT_INTRESET_B)
-#define CRBMSK_INTRESET_A      (1 << CRBBIT_INTRESET_A)
-#define CRBMSK_CLKENAB_A       (1 << CRBBIT_CLKENAB_A)
-#define CRBMSK_INTSRC_B                (3 << CRBBIT_INTSRC_B)
-#define CRBMSK_LATCHSRC                (3 << CRBBIT_LATCHSRC)
-#define CRBMSK_LOADSRC_B       (3 << CRBBIT_LOADSRC_B)
-#define CRBMSK_CLKMULT_B       (3 << CRBBIT_CLKMULT_B)
-#define CRBMSK_CLKENAB_B       (1 << CRBBIT_CLKENAB_B)
-#define CRBMSK_INDXPOL_B       (1 << CRBBIT_INDXPOL_B)
-#define CRBMSK_CLKPOL_B                (1 << CRBBIT_CLKPOL_B)
-
-#define CRBMSK_INTCTRL         (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B)    /*  Interrupt reset control bits. */
-
-/*  Bit field positions for standardized SETUP structure. */
-
-#define STDBIT_INTSRC          13
-#define STDBIT_LATCHSRC                11
-#define STDBIT_LOADSRC          9
-#define STDBIT_INDXSRC          7
-#define STDBIT_INDXPOL          6
-#define STDBIT_CLKSRC           4
-#define STDBIT_CLKPOL           3
-#define STDBIT_CLKMULT          1
-#define STDBIT_CLKENAB          0
-
-/*  Bit field masks for standardized SETUP structure. */
-
-#define STDMSK_INTSRC          (3 << STDBIT_INTSRC)
-#define STDMSK_LATCHSRC                (3 << STDBIT_LATCHSRC)
-#define STDMSK_LOADSRC         (3 << STDBIT_LOADSRC)
-#define STDMSK_INDXSRC         (1 << STDBIT_INDXSRC)
-#define STDMSK_INDXPOL         (1 << STDBIT_INDXPOL)
-#define STDMSK_CLKSRC          (3 << STDBIT_CLKSRC)
-#define STDMSK_CLKPOL          (1 << STDBIT_CLKPOL)
-#define STDMSK_CLKMULT         (3 << STDBIT_CLKMULT)
-#define STDMSK_CLKENAB         (1 << STDBIT_CLKENAB)
-
-struct bufferDMA {
-       dma_addr_t PhysicalBase;
-       void *LogicalBase;
-       uint32_t DMAHandle;
-};
+/* DEBI page table constants. */
+#define S626_DEBI_PAGE_DISABLE 0x00000000      /* Paging disable. */
+
+/* ******* EXTRA FROM OTHER SENSORAY  * .h  ******* */
+
+/* LoadSrc values: */
+#define S626_LOADSRC_INDX      0       /* Preload core in response to Index. */
+#define S626_LOADSRC_OVER      1       /* Preload core in response to
+                                        * Overflow. */
+#define S626_LOADSRCB_OVERA    2       /* Preload B core in response to
+                                        * A Overflow. */
+#define S626_LOADSRC_NONE      3       /* Never preload core. */
+
+/* IntSrc values: */
+#define S626_INTSRC_NONE       0       /* Interrupts disabled. */
+#define S626_INTSRC_OVER       1       /* Interrupt on Overflow. */
+#define S626_INTSRC_INDX       2       /* Interrupt on Index. */
+#define S626_INTSRC_BOTH       3       /* Interrupt on Index or Overflow. */
+
+/* LatchSrc values: */
+#define S626_LATCHSRC_AB_READ  0       /* Latch on read. */
+#define S626_LATCHSRC_A_INDXA  1       /* Latch A on A Index. */
+#define S626_LATCHSRC_B_INDXB  2       /* Latch B on B Index. */
+#define S626_LATCHSRC_B_OVERA  3       /* Latch B on A Overflow. */
+
+/* IndxSrc values: */
+#define S626_INDXSRC_ENCODER   0       /* Encoder. */
+#define S626_INDXSRC_DIGIN     1       /* Digital inputs. */
+#define S626_INDXSRC_SOFT      2       /* S/w controlled by IndxPol bit. */
+#define S626_INDXSRC_DISABLED  3       /* Index disabled. */
+
+/* IndxPol values: */
+#define S626_INDXPOL_POS       0       /* Index input is active high. */
+#define S626_INDXPOL_NEG       1       /* Index input is active low. */
+
+/* Logical encoder mode values: */
+#define S626_ENCMODE_COUNTER   0       /* Counter mode. */
+#define S626_ENCMODE_TIMER     2       /* Timer mode. */
+#define S626_ENCMODE_EXTENDER  3       /* Extender mode. */
+
+/* Physical CntSrc values (for Counter A source and Counter B source): */
+#define S626_CNTSRC_ENCODER    0       /* Encoder */
+#define S626_CNTSRC_DIGIN      1       /* Digital inputs */
+#define S626_CNTSRC_SYSCLK     2       /* System clock up */
+#define S626_CNTSRC_SYSCLK_DOWN        3       /* System clock down */
+
+/* ClkPol values: */
+#define S626_CLKPOL_POS                0       /* Counter/Extender clock is
+                                        * active high. */
+#define S626_CLKPOL_NEG                1       /* Counter/Extender clock is
+                                        * active low. */
+#define S626_CNTDIR_UP         0       /* Timer counts up. */
+#define S626_CNTDIR_DOWN       1       /* Timer counts down. */
+
+/* ClkEnab values: */
+#define S626_CLKENAB_ALWAYS    0       /* Clock always enabled. */
+#define S626_CLKENAB_INDEX     1       /* Clock is enabled by index. */
+
+/* ClkMult values: */
+#define S626_CLKMULT_4X                0       /* 4x clock multiplier. */
+#define S626_CLKMULT_2X                1       /* 2x clock multiplier. */
+#define S626_CLKMULT_1X                2       /* 1x clock multiplier. */
+#define S626_CLKMULT_SPECIAL   3       /* Special clock multiplier value. */
+
+/* Sanity-check limits for parameters. */
+
+#define S626_NUM_COUNTERS      6       /* Maximum valid counter
+                                        * logical channel number. */
+#define S626_NUM_INTSOURCES    4
+#define S626_NUM_LATCHSOURCES  4
+#define S626_NUM_CLKMULTS      4
+#define S626_NUM_CLKSOURCES    4
+#define S626_NUM_CLKPOLS       2
+#define S626_NUM_INDEXPOLS     2
+#define S626_NUM_INDEXSOURCES  2
+#define S626_NUM_LOADTRIGS     4
+
+/* General macros for manipulating bitfields: */
+#define S626_MAKE(x, w, p)     (((x) & ((1 << (w)) - 1)) << (p))
+#define S626_UNMAKE(v, w, p)   (((v) >> (p)) & ((1 << (w)) - 1))
+
+/* Bit field positions in CRA: */
+#define S626_CRABIT_INDXSRC_B  14      /* B index source. */
+#define S626_CRABIT_CNTSRC_B   12      /* B counter source. */
+#define S626_CRABIT_INDXPOL_A  11      /* A index polarity. */
+#define S626_CRABIT_LOADSRC_A   9      /* A preload trigger. */
+#define S626_CRABIT_CLKMULT_A   7      /* A clock multiplier. */
+#define S626_CRABIT_INTSRC_A    5      /* A interrupt source. */
+#define S626_CRABIT_CLKPOL_A    4      /* A clock polarity. */
+#define S626_CRABIT_INDXSRC_A   2      /* A index source. */
+#define S626_CRABIT_CNTSRC_A    0      /* A counter source. */
+
+/* Bit field widths in CRA: */
+#define S626_CRAWID_INDXSRC_B  2
+#define S626_CRAWID_CNTSRC_B   2
+#define S626_CRAWID_INDXPOL_A  1
+#define S626_CRAWID_LOADSRC_A  2
+#define S626_CRAWID_CLKMULT_A  2
+#define S626_CRAWID_INTSRC_A   2
+#define S626_CRAWID_CLKPOL_A   1
+#define S626_CRAWID_INDXSRC_A  2
+#define S626_CRAWID_CNTSRC_A   2
+
+/* Bit field masks for CRA: */
+#define S626_CRAMSK_INDXSRC_B  S626_SET_CRA_INDXSRC_B(~0)
+#define S626_CRAMSK_CNTSRC_B   S626_SET_CRA_CNTSRC_B(~0)
+#define S626_CRAMSK_INDXPOL_A  S626_SET_CRA_INDXPOL_A(~0)
+#define S626_CRAMSK_LOADSRC_A  S626_SET_CRA_LOADSRC_A(~0)
+#define S626_CRAMSK_CLKMULT_A  S626_SET_CRA_CLKMULT_A(~0)
+#define S626_CRAMSK_INTSRC_A   S626_SET_CRA_INTSRC_A(~0)
+#define S626_CRAMSK_CLKPOL_A   S626_SET_CRA_CLKPOL_A(~0)
+#define S626_CRAMSK_INDXSRC_A  S626_SET_CRA_INDXSRC_A(~0)
+#define S626_CRAMSK_CNTSRC_A   S626_SET_CRA_CNTSRC_A(~0)
+
+/* Construct parts of the CRA value: */
+#define S626_SET_CRA_INDXSRC_B(x)      \
+       S626_MAKE((x), S626_CRAWID_INDXSRC_B, S626_CRABIT_INDXSRC_B)
+#define S626_SET_CRA_CNTSRC_B(x)       \
+       S626_MAKE((x), S626_CRAWID_CNTSRC_B, S626_CRABIT_CNTSRC_B)
+#define S626_SET_CRA_INDXPOL_A(x)      \
+       S626_MAKE((x), S626_CRAWID_INDXPOL_A, S626_CRABIT_INDXPOL_A)
+#define S626_SET_CRA_LOADSRC_A(x)      \
+       S626_MAKE((x), S626_CRAWID_LOADSRC_A, S626_CRABIT_LOADSRC_A)
+#define S626_SET_CRA_CLKMULT_A(x)      \
+       S626_MAKE((x), S626_CRAWID_CLKMULT_A, S626_CRABIT_CLKMULT_A)
+#define S626_SET_CRA_INTSRC_A(x)       \
+       S626_MAKE((x), S626_CRAWID_INTSRC_A, S626_CRABIT_INTSRC_A)
+#define S626_SET_CRA_CLKPOL_A(x)       \
+       S626_MAKE((x), S626_CRAWID_CLKPOL_A, S626_CRABIT_CLKPOL_A)
+#define S626_SET_CRA_INDXSRC_A(x)      \
+       S626_MAKE((x), S626_CRAWID_INDXSRC_A, S626_CRABIT_INDXSRC_A)
+#define S626_SET_CRA_CNTSRC_A(x)       \
+       S626_MAKE((x), S626_CRAWID_CNTSRC_A, S626_CRABIT_CNTSRC_A)
+
+/* Extract parts of the CRA value: */
+#define S626_GET_CRA_INDXSRC_B(v)      \
+       S626_UNMAKE((v), S626_CRAWID_INDXSRC_B, S626_CRABIT_INDXSRC_B)
+#define S626_GET_CRA_CNTSRC_B(v)       \
+       S626_UNMAKE((v), S626_CRAWID_CNTSRC_B, S626_CRABIT_CNTSRC_B)
+#define S626_GET_CRA_INDXPOL_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_INDXPOL_A, S626_CRABIT_INDXPOL_A)
+#define S626_GET_CRA_LOADSRC_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_LOADSRC_A, S626_CRABIT_LOADSRC_A)
+#define S626_GET_CRA_CLKMULT_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_CLKMULT_A, S626_CRABIT_CLKMULT_A)
+#define S626_GET_CRA_INTSRC_A(v)       \
+       S626_UNMAKE((v), S626_CRAWID_INTSRC_A, S626_CRABIT_INTSRC_A)
+#define S626_GET_CRA_CLKPOL_A(v)       \
+       S626_UNMAKE((v), S626_CRAWID_CLKPOL_A, S626_CRABIT_CLKPOL_A)
+#define S626_GET_CRA_INDXSRC_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_INDXSRC_A, S626_CRABIT_INDXSRC_A)
+#define S626_GET_CRA_CNTSRC_A(v)       \
+       S626_UNMAKE((v), S626_CRAWID_CNTSRC_A, S626_CRABIT_CNTSRC_A)
+
+/* Bit field positions in CRB: */
+#define S626_CRBBIT_INTRESETCMD        15      /* (w) Interrupt reset command. */
+#define S626_CRBBIT_CNTDIR_B   15      /* (r) B counter direction. */
+#define S626_CRBBIT_INTRESET_B 14      /* (w) B interrupt reset enable. */
+#define S626_CRBBIT_OVERDO_A   14      /* (r) A overflow routed to dig. out. */
+#define S626_CRBBIT_INTRESET_A 13      /* (w) A interrupt reset enable. */
+#define S626_CRBBIT_OVERDO_B   13      /* (r) B overflow routed to dig. out. */
+#define S626_CRBBIT_CLKENAB_A  12      /* A clock enable. */
+#define S626_CRBBIT_INTSRC_B   10      /* B interrupt source. */
+#define S626_CRBBIT_LATCHSRC    8      /* A/B latch source. */
+#define S626_CRBBIT_LOADSRC_B   6      /* B preload trigger. */
+#define S626_CRBBIT_CLEAR_B     7      /* B cleared when A overflows. */
+#define S626_CRBBIT_CLKMULT_B   3      /* B clock multiplier. */
+#define S626_CRBBIT_CLKENAB_B   2      /* B clock enable. */
+#define S626_CRBBIT_INDXPOL_B   1      /* B index polarity. */
+#define S626_CRBBIT_CLKPOL_B    0      /* B clock polarity. */
+
+/* Bit field widths in CRB: */
+#define S626_CRBWID_INTRESETCMD        1
+#define S626_CRBWID_CNTDIR_B   1
+#define S626_CRBWID_INTRESET_B 1
+#define S626_CRBWID_OVERDO_A   1
+#define S626_CRBWID_INTRESET_A 1
+#define S626_CRBWID_OVERDO_B   1
+#define S626_CRBWID_CLKENAB_A  1
+#define S626_CRBWID_INTSRC_B   2
+#define S626_CRBWID_LATCHSRC   2
+#define S626_CRBWID_LOADSRC_B  2
+#define S626_CRBWID_CLEAR_B    1
+#define S626_CRBWID_CLKMULT_B  2
+#define S626_CRBWID_CLKENAB_B  1
+#define S626_CRBWID_INDXPOL_B  1
+#define S626_CRBWID_CLKPOL_B   1
+
+/* Bit field masks for CRB: */
+#define S626_CRBMSK_INTRESETCMD        S626_SET_CRB_INTRESETCMD(~0)    /* (w) */
+#define S626_CRBMSK_CNTDIR_B   S626_CRBMSK_INTRESETCMD         /* (r) */
+#define S626_CRBMSK_INTRESET_B S626_SET_CRB_INTRESET_B(~0)     /* (w) */
+#define S626_CRBMSK_OVERDO_A   S626_CRBMSK_INTRESET_B          /* (r) */
+#define S626_CRBMSK_INTRESET_A S626_SET_CRB_INTRESET_A(~0)     /* (w) */
+#define S626_CRBMSK_OVERDO_B   S626_CRBMSK_INTRESET_A          /* (r) */
+#define S626_CRBMSK_CLKENAB_A  S626_SET_CRB_CLKENAB_A(~0)
+#define S626_CRBMSK_INTSRC_B   S626_SET_CRB_INTSRC_B(~0)
+#define S626_CRBMSK_LATCHSRC   S626_SET_CRB_LATCHSRC(~0)
+#define S626_CRBMSK_LOADSRC_B  S626_SET_CRB_LOADSRC_B(~0)
+#define S626_CRBMSK_CLEAR_B    S626_SET_CRB_CLEAR_B(~0)
+#define S626_CRBMSK_CLKMULT_B  S626_SET_CRB_CLKMULT_B(~0)
+#define S626_CRBMSK_CLKENAB_B  S626_SET_CRB_CLKENAB_B(~0)
+#define S626_CRBMSK_INDXPOL_B  S626_SET_CRB_INDXPOL_B(~0)
+#define S626_CRBMSK_CLKPOL_B   S626_SET_CRB_CLKPOL_B(~0)
+
+/* Interrupt reset control bits. */
+#define S626_CRBMSK_INTCTRL    (S626_CRBMSK_INTRESETCMD | \
+                                S626_CRBMSK_INTRESET_A | \
+                                S626_CRBMSK_INTRESET_B)
+
+/* Construct parts of the CRB value: */
+#define S626_SET_CRB_INTRESETCMD(x)    \
+       S626_MAKE((x), S626_CRBWID_INTRESETCMD, S626_CRBBIT_INTRESETCMD)
+#define S626_SET_CRB_INTRESET_B(x)     \
+       S626_MAKE((x), S626_CRBWID_INTRESET_B, S626_CRBBIT_INTRESET_B)
+#define S626_SET_CRB_INTRESET_A(x)     \
+       S626_MAKE((x), S626_CRBWID_INTRESET_A, S626_CRBBIT_INTRESET_A)
+#define S626_SET_CRB_CLKENAB_A(x)      \
+       S626_MAKE((x), S626_CRBWID_CLKENAB_A, S626_CRBBIT_CLKENAB_A)
+#define S626_SET_CRB_INTSRC_B(x)       \
+       S626_MAKE((x), S626_CRBWID_INTSRC_B, S626_CRBBIT_INTSRC_B)
+#define S626_SET_CRB_LATCHSRC(x)       \
+       S626_MAKE((x), S626_CRBWID_LATCHSRC, S626_CRBBIT_LATCHSRC)
+#define S626_SET_CRB_LOADSRC_B(x)      \
+       S626_MAKE((x), S626_CRBWID_LOADSRC_B, S626_CRBBIT_LOADSRC_B)
+#define S626_SET_CRB_CLEAR_B(x)        \
+       S626_MAKE((x), S626_CRBWID_CLEAR_B, S626_CRBBIT_CLEAR_B)
+#define S626_SET_CRB_CLKMULT_B(x)      \
+       S626_MAKE((x), S626_CRBWID_CLKMULT_B, S626_CRBBIT_CLKMULT_B)
+#define S626_SET_CRB_CLKENAB_B(x)      \
+       S626_MAKE((x), S626_CRBWID_CLKENAB_B, S626_CRBBIT_CLKENAB_B)
+#define S626_SET_CRB_INDXPOL_B(x)      \
+       S626_MAKE((x), S626_CRBWID_INDXPOL_B, S626_CRBBIT_INDXPOL_B)
+#define S626_SET_CRB_CLKPOL_B(x)       \
+       S626_MAKE((x), S626_CRBWID_CLKPOL_B, S626_CRBBIT_CLKPOL_B)
+
+/* Extract parts of the CRB value: */
+#define S626_GET_CRB_CNTDIR_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_CNTDIR_B, S626_CRBBIT_CNTDIR_B)
+#define S626_GET_CRB_OVERDO_A(v)       \
+       S626_UNMAKE((v), S626_CRBWID_OVERDO_A, S626_CRBBIT_OVERDO_A)
+#define S626_GET_CRB_OVERDO_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_OVERDO_B, S626_CRBBIT_OVERDO_B)
+#define S626_GET_CRB_CLKENAB_A(v)      \
+       S626_UNMAKE((v), S626_CRBWID_CLKENAB_A, S626_CRBBIT_CLKENAB_A)
+#define S626_GET_CRB_INTSRC_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_INTSRC_B, S626_CRBBIT_INTSRC_B)
+#define S626_GET_CRB_LATCHSRC(v)       \
+       S626_UNMAKE((v), S626_CRBWID_LATCHSRC, S626_CRBBIT_LATCHSRC)
+#define S626_GET_CRB_LOADSRC_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_LOADSRC_B, S626_CRBBIT_LOADSRC_B)
+#define S626_GET_CRB_CLEAR_B(v)        \
+       S626_UNMAKE((v), S626_CRBWID_CLEAR_B, S626_CRBBIT_CLEAR_B)
+#define S626_GET_CRB_CLKMULT_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_CLKMULT_B, S626_CRBBIT_CLKMULT_B)
+#define S626_GET_CRB_CLKENAB_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_CLKENAB_B, S626_CRBBIT_CLKENAB_B)
+#define S626_GET_CRB_INDXPOL_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_INDXPOL_B, S626_CRBBIT_INDXPOL_B)
+#define S626_GET_CRB_CLKPOL_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_CLKPOL_B, S626_CRBBIT_CLKPOL_B)
+
+/* Bit field positions for standardized SETUP structure: */
+#define S626_STDBIT_INTSRC     13
+#define S626_STDBIT_LATCHSRC   11
+#define S626_STDBIT_LOADSRC     9
+#define S626_STDBIT_INDXSRC     7
+#define S626_STDBIT_INDXPOL     6
+#define S626_STDBIT_ENCMODE     4
+#define S626_STDBIT_CLKPOL      3
+#define S626_STDBIT_CLKMULT     1
+#define S626_STDBIT_CLKENAB     0
+
+/* Bit field widths for standardized SETUP structure: */
+#define S626_STDWID_INTSRC     2
+#define S626_STDWID_LATCHSRC   2
+#define S626_STDWID_LOADSRC    2
+#define S626_STDWID_INDXSRC    2
+#define S626_STDWID_INDXPOL    1
+#define S626_STDWID_ENCMODE    2
+#define S626_STDWID_CLKPOL     1
+#define S626_STDWID_CLKMULT    2
+#define S626_STDWID_CLKENAB    1
+
+/* Bit field masks for standardized SETUP structure: */
+#define S626_STDMSK_INTSRC     S626_SET_STD_INTSRC(~0)
+#define S626_STDMSK_LATCHSRC   S626_SET_STD_LATCHSRC(~0)
+#define S626_STDMSK_LOADSRC    S626_SET_STD_LOADSRC(~0)
+#define S626_STDMSK_INDXSRC    S626_SET_STD_INDXSRC(~0)
+#define S626_STDMSK_INDXPOL    S626_SET_STD_INDXPOL(~0)
+#define S626_STDMSK_ENCMODE    S626_SET_STD_ENCMODE(~0)
+#define S626_STDMSK_CLKPOL     S626_SET_STD_CLKPOL(~0)
+#define S626_STDMSK_CLKMULT    S626_SET_STD_CLKMULT(~0)
+#define S626_STDMSK_CLKENAB    S626_SET_STD_CLKENAB(~0)
+
+/* Construct parts of standardized SETUP structure: */
+#define S626_SET_STD_INTSRC(x) \
+       S626_MAKE((x), S626_STDWID_INTSRC, S626_STDBIT_INTSRC)
+#define S626_SET_STD_LATCHSRC(x)       \
+       S626_MAKE((x), S626_STDWID_LATCHSRC, S626_STDBIT_LATCHSRC)
+#define S626_SET_STD_LOADSRC(x)        \
+       S626_MAKE((x), S626_STDWID_LOADSRC, S626_STDBIT_LOADSRC)
+#define S626_SET_STD_INDXSRC(x)        \
+       S626_MAKE((x), S626_STDWID_INDXSRC, S626_STDBIT_INDXSRC)
+#define S626_SET_STD_INDXPOL(x)        \
+       S626_MAKE((x), S626_STDWID_INDXPOL, S626_STDBIT_INDXPOL)
+#define S626_SET_STD_ENCMODE(x)        \
+       S626_MAKE((x), S626_STDWID_ENCMODE, S626_STDBIT_ENCMODE)
+#define S626_SET_STD_CLKPOL(x) \
+       S626_MAKE((x), S626_STDWID_CLKPOL, S626_STDBIT_CLKPOL)
+#define S626_SET_STD_CLKMULT(x)        \
+       S626_MAKE((x), S626_STDWID_CLKMULT, S626_STDBIT_CLKMULT)
+#define S626_SET_STD_CLKENAB(x)        \
+       S626_MAKE((x), S626_STDWID_CLKENAB, S626_STDBIT_CLKENAB)
+
+/* Extract parts of standardized SETUP structure: */
+#define S626_GET_STD_INTSRC(v) \
+       S626_UNMAKE((v), S626_STDWID_INTSRC, S626_STDBIT_INTSRC)
+#define S626_GET_STD_LATCHSRC(v)       \
+       S626_UNMAKE((v), S626_STDWID_LATCHSRC, S626_STDBIT_LATCHSRC)
+#define S626_GET_STD_LOADSRC(v)        \
+       S626_UNMAKE((v), S626_STDWID_LOADSRC, S626_STDBIT_LOADSRC)
+#define S626_GET_STD_INDXSRC(v)        \
+       S626_UNMAKE((v), S626_STDWID_INDXSRC, S626_STDBIT_INDXSRC)
+#define S626_GET_STD_INDXPOL(v)        \
+       S626_UNMAKE((v), S626_STDWID_INDXPOL, S626_STDBIT_INDXPOL)
+#define S626_GET_STD_ENCMODE(v)        \
+       S626_UNMAKE((v), S626_STDWID_ENCMODE, S626_STDBIT_ENCMODE)
+#define S626_GET_STD_CLKPOL(v) \
+       S626_UNMAKE((v), S626_STDWID_CLKPOL, S626_STDBIT_CLKPOL)
+#define S626_GET_STD_CLKMULT(v)        \
+       S626_UNMAKE((v), S626_STDWID_CLKMULT, S626_STDBIT_CLKMULT)
+#define S626_GET_STD_CLKENAB(v)        \
+       S626_UNMAKE((v), S626_STDWID_CLKENAB, S626_STDBIT_CLKENAB)
+
+#endif
index 9e964950a560ed92d9f37599d6138fd9c1a360b6..daee2f42bde0632c2cd05a38640ba1346a7bfeb6 100644 (file)
@@ -332,30 +332,44 @@ static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
        return i;
 }
 
-/* DIO devices are slightly special.  Although it is possible to
+/*
+ * DIO devices are slightly special. Although it is possible to
  * implement the insn_read/insn_write interface, it is much more
  * useful to applications if you implement the insn_bits interface.
- * This allows packed reading/writing of the DIO channels.  The
- * comedi core can convert between insn_bits and insn_read/write */
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write.
+ */
 static int skel_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       /*
+        * The insn data is a mask in data[0] and the new data
+        * in data[1], each channel cooresponding to a bit.
+        *
+        * The core provided comedi_dio_update_state() function can
+        * be used to handle the internal state update to DIO subdevices
+        * with <= 32 channels. This function will return '0' if the
+        * state does not change or the mask of the channels that need
+        * to be updated.
+        */
+       if (comedi_dio_update_state(s, data)) {
                /* Write out the new digital output lines */
-               /* outw(s->state,dev->iobase + SKEL_DIO); */
+               /* outw(s->state, dev->iobase + SKEL_DIO); */
        }
 
-       /* on return, data[1] contains the value of the digital
-        * input and output lines. */
-       /* data[1]=inw(dev->iobase + SKEL_DIO); */
-       /* or we could just return the software copy of the output values if
-        * it was a purely digital output subdevice */
-       /* data[1]=s->state; */
+       /*
+        * On return, data[1] contains the value of the digital
+        * input and output lines.
+        */
+       /* data[1] = inw(dev->iobase + SKEL_DIO); */
+
+       /*
+        * Or we could just return the software copy of the output
+        * values if it was a purely digital output subdevice.
+        */
+       /* data[1] = s->state; */
 
        return insn->n;
 }
index 11758a515c1bfed78ac7025b7f26d74a212368c6..df22a78d2b7e0879394953cb6f4987d77d6bc271 100644 (file)
@@ -46,51 +46,43 @@ Status: unknown
 #define PCMR  0xa3             /* Port C Mode Register                      */
 #define PCDR  0xa7             /* Port C Data Register                      */
 
-/* ------------------------------------------------------------------------- */
-/* The insn_bits interface allows packed reading/writing of DIO channels.    */
-/* The comedi core can convert between insn_bits and insn_read/write, so you */
-/* are able to use these instructions as well.                               */
-/* ------------------------------------------------------------------------- */
-
 static int dnp_dio_insn_bits(struct comedi_device *dev,
                             struct comedi_subdevice *s,
-                            struct comedi_insn *insn, unsigned int *data)
+                            struct comedi_insn *insn,
+                            unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data in data[1],   */
-       /* each channel cooresponding to a bit.                              */
-
-       /* Ports A and B are straight forward: each bit corresponds to an    */
-       /* output pin with the same order. Port C is different: bits 0...3   */
-       /* correspond to bits 4...7 of the output register (PCDR).           */
+       unsigned int mask;
+       unsigned int val;
 
-       if (data[0]) {
+       /*
+        * Ports A and B are straight forward: each bit corresponds to an
+        * output pin with the same order. Port C is different: bits 0...3
+        * correspond to bits 4...7 of the output register (PCDR).
+        */
 
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
                outb(PADR, CSCIR);
-               outb((inb(CSCDR)
-                     & ~(u8) (data[0] & 0x0000FF))
-                    | (u8) (data[1] & 0x0000FF), CSCDR);
+               outb(s->state & 0xff, CSCDR);
 
                outb(PBDR, CSCIR);
-               outb((inb(CSCDR)
-                     & ~(u8) ((data[0] & 0x00FF00) >> 8))
-                    | (u8) ((data[1] & 0x00FF00) >> 8), CSCDR);
+               outb((s->state >> 8) & 0xff, CSCDR);
 
                outb(PCDR, CSCIR);
-               outb((inb(CSCDR)
-                     & ~(u8) ((data[0] & 0x0F0000) >> 12))
-                    | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR);
+               val = inb(CSCDR) & 0x0f;
+               outb(((s->state >> 12) & 0xf0) | val, CSCDR);
        }
 
-       /* on return, data[1] contains the value of the digital input lines. */
        outb(PADR, CSCIR);
-       data[0] = inb(CSCDR);
+       val = inb(CSCDR);
        outb(PBDR, CSCIR);
-       data[0] += inb(CSCDR) << 8;
+       val |= (inb(CSCDR) << 8);
        outb(PCDR, CSCIR);
-       data[0] += ((inb(CSCDR) & 0xF0) << 12);
+       val |= ((inb(CSCDR) & 0xf0) << 12);
 
-       return insn->n;
+       data[1] = val;
 
+       return insn->n;
 }
 
 static int dnp_dio_insn_config(struct comedi_device *dev,
index 701ad1a6939469d04df237ed71971006d7ed60ee..da1d501d9e4e64304e82f04a5f1e6e618f8d1647 100644 (file)
@@ -122,7 +122,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
 
 /* Size of one A/D value */
-#define SIZEADIN          ((sizeof(int16_t)))
+#define SIZEADIN          ((sizeof(uint16_t)))
 
 /*
  * Size of the input-buffer IN BYTES
@@ -134,7 +134,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 #define SIZEINSNBUF       16
 
 /* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT          ((sizeof(int8_t)+sizeof(int16_t)))
+#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
 
 /*
  * Size of the output-buffer in bytes
@@ -195,15 +195,15 @@ struct usbdux_private {
        /* PWM period */
        unsigned int pwm_period;
        /* PWM internal delay for the GPIF in the FX2 */
-       int8_t pwm_delay;
+       uint8_t pwm_delay;
        /* size of the PWM buffer which holds the bit pattern */
        int pwm_buf_sz;
        /* input buffer for the ISO-transfer */
-       int16_t *in_buf;
+       uint16_t *in_buf;
        /* input buffer for single insn */
-       int16_t *insn_buf;
+       uint16_t *insn_buf;
 
-       int8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
+       uint8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
        unsigned int ao_readback[USBDUX_NUM_AO_CHAN];
 
        unsigned int high_speed:1;
@@ -225,7 +225,7 @@ struct usbdux_private {
        /* interval in frames/uframes */
        unsigned int ai_interval;
        /* commands */
-       int8_t *dux_commands;
+       uint8_t *dux_commands;
        struct semaphore sem;
 };
 
@@ -367,7 +367,7 @@ static void usbduxsub_ai_isoc_irq(struct urb *urb)
        n = s->async->cmd.chanlist_len;
        for (i = 0; i < n; i++) {
                unsigned int range = CR_RANGE(s->async->cmd.chanlist[i]);
-               int16_t val = le16_to_cpu(devpriv->in_buf[i]);
+               uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
 
                /* bipolar data is two's-complement */
                if (comedi_range_is_bipolar(s, range))
@@ -415,7 +415,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb)
        struct comedi_device *dev = urb->context;
        struct comedi_subdevice *s = dev->write_subdev;
        struct usbdux_private *devpriv = dev->private;
-       int8_t *datap;
+       uint8_t *datap;
        int len;
        int ret;
        int i;
@@ -483,7 +483,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb)
                *datap++ = len;
                for (i = 0; i < s->async->cmd.chanlist_len; i++) {
                        unsigned int chan = devpriv->ao_chanlist[i];
-                       short val;
+                       unsigned short val;
 
                        ret = comedi_buf_get(s->async, &val);
                        if (ret < 0) {
@@ -649,14 +649,15 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
  * creates the ADC command for the MAX1271
  * range is the range value from comedi
  */
-static int8_t create_adc_command(unsigned int chan, int range)
+static uint8_t create_adc_command(unsigned int chan, unsigned int range)
 {
-       int8_t p = (range <= 1);
-       int8_t r = ((range % 2) == 0);
+       uint8_t p = (range <= 1);
+       uint8_t r = ((range % 2) == 0);
+
        return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
 }
 
-static int send_dux_commands(struct comedi_device *dev, int cmd_type)
+static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
 {
        struct usb_device *usb = comedi_to_usb_dev(dev);
        struct usbdux_private *devpriv = dev->private;
@@ -669,7 +670,7 @@ static int send_dux_commands(struct comedi_device *dev, int cmd_type)
                            &nsent, BULK_TIMEOUT);
 }
 
-static int receive_dux_commands(struct comedi_device *dev, int command)
+static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
 {
        struct usb_device *usb = comedi_to_usb_dev(dev);
        struct usbdux_private *devpriv = dev->private;
@@ -879,7 +880,7 @@ static int usbdux_ao_insn_write(struct comedi_device *dev,
        struct usbdux_private *devpriv = dev->private;
        unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int val = devpriv->ao_readback[chan];
-       int16_t *p = (int16_t *)&devpriv->dux_commands[2];
+       uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
        int ret = -EBUSY;
        int i;
 
@@ -1133,15 +1134,13 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev,
 {
 
        struct usbdux_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        int ret;
 
        down(&devpriv->sem);
 
-       s->state &= ~mask;
-       s->state |= (bits & mask);
+       comedi_dio_update_state(s, data);
 
+       /* Always update the hardware. See the (*insn_config). */
        devpriv->dux_commands[1] = s->io_bits;
        devpriv->dux_commands[2] = s->state;
 
@@ -1200,7 +1199,7 @@ static int usbdux_counter_write(struct comedi_device *dev,
 {
        struct usbdux_private *devpriv = dev->private;
        unsigned int chan = CR_CHAN(insn->chanspec);
-       int16_t *p = (int16_t *)&devpriv->dux_commands[2];
+       uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
        int ret = 0;
        int i;
 
index c47f4087568fc0e4fae91c83433c49f9dba6c0eb..a5363ded3668329f60353b0462487195e842ff8f 100644 (file)
@@ -78,7 +78,7 @@
 #define USBDUXSIGMA_NUM_AO_CHAN                4
 
 /* Size of one A/D value */
-#define SIZEADIN          ((sizeof(int32_t)))
+#define SIZEADIN          ((sizeof(uint32_t)))
 
 /*
  * Size of the async input-buffer IN BYTES, the DIO state is transmitted
@@ -93,7 +93,7 @@
 #define NUMOUTCHANNELS    8
 
 /* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(int16_t)))
+#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
 
 /*
  * Size of the output-buffer in bytes
@@ -157,11 +157,11 @@ struct usbduxsigma_private {
        /* size of the PWM buffer which holds the bit pattern */
        int pwm_buf_sz;
        /* input buffer for the ISO-transfer */
-       int32_t *in_buf;
+       uint32_t *in_buf;
        /* input buffer for single insn */
-       int8_t *insn_buf;
+       uint8_t *insn_buf;
 
-       int8_t ao_chanlist[USBDUXSIGMA_NUM_AO_CHAN];
+       uint8_t ao_chanlist[USBDUXSIGMA_NUM_AO_CHAN];
        unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
 
        unsigned high_speed:1;
@@ -224,7 +224,7 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb)
        struct usbduxsigma_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
        unsigned int dio_state;
-       int32_t val;
+       uint32_t val;
        int ret;
        int i;
 
@@ -421,7 +421,7 @@ static void usbduxsigma_ao_urb_complete(struct urb *urb)
                *datap++ = len;
                for (i = 0; i < len; i++) {
                        unsigned int chan = devpriv->ao_chanlist[i];
-                       short val;
+                       unsigned short val;
 
                        ret = comedi_buf_get(s->async, &val);
                        if (ret < 0) {
@@ -784,7 +784,7 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
        }
 
        for (i = 0; i < insn->n; i++) {
-               int32_t val;
+               uint32_t val;
 
                ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
                if (ret < 0) {
@@ -793,7 +793,7 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
                }
 
                /* 32 bits big endian from the A/D converter */
-               val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf) + 1)));
+               val = be32_to_cpu(*((uint32_t *)((devpriv->insn_buf) + 1)));
                val &= 0x00ffffff;      /* strip status byte */
                val ^= 0x00800000;      /* convert to unsigned */
 
@@ -1059,15 +1059,13 @@ static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
                                     unsigned int *data)
 {
        struct usbduxsigma_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        int ret;
 
        down(&devpriv->sem);
 
-       s->state &= ~mask;
-       s->state |= (bits & mask);
+       comedi_dio_update_state(s, data);
 
+       /* Always update the hardware. See the (*insn_config). */
        devpriv->dux_commands[1] = s->io_bits & 0xff;
        devpriv->dux_commands[4] = s->state & 0xff;
        devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
@@ -1360,7 +1358,7 @@ static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
                return ret;
 
        /* 32 bits big endian from the A/D converter */
-       val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf)+1)));
+       val = be32_to_cpu(*((uint32_t *)((devpriv->insn_buf)+1)));
        val &= 0x00ffffff;      /* strip status byte */
        val ^= 0x00800000;      /* convert to unsigned */
 
index 06efa16b9af2377a0370952815d701dc344d51c4..933b01a0f03d4274e4f82ced6240a79f78b2c742 100644 (file)
@@ -462,9 +462,10 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
                                unsigned int *data)
 {
        struct vmk80xx_private *devpriv = dev->private;
-       unsigned char *rx_buf, *tx_buf;
+       unsigned char *rx_buf = devpriv->usb_rx_buf;
+       unsigned char *tx_buf = devpriv->usb_tx_buf;
        int reg, cmd;
-       int retval;
+       int ret;
 
        if (devpriv->model == VMK8061_MODEL) {
                reg = VMK8061_DO_REG;
@@ -476,37 +477,27 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
 
        down(&devpriv->limit_sem);
 
-       rx_buf = devpriv->usb_rx_buf;
-       tx_buf = devpriv->usb_tx_buf;
-
-       if (data[0]) {
-               tx_buf[reg] &= ~data[0];
-               tx_buf[reg] |= (data[0] & data[1]);
-
-               retval = vmk80xx_write_packet(dev, cmd);
-
-               if (retval)
+       if (comedi_dio_update_state(s, data)) {
+               tx_buf[reg] = s->state;
+               ret = vmk80xx_write_packet(dev, cmd);
+               if (ret)
                        goto out;
        }
 
        if (devpriv->model == VMK8061_MODEL) {
                tx_buf[0] = VMK8061_CMD_RD_DO;
-
-               retval = vmk80xx_read_packet(dev);
-
-               if (!retval) {
-                       data[1] = rx_buf[reg];
-                       retval = 2;
-               }
+               ret = vmk80xx_read_packet(dev);
+               if (ret)
+                       goto out;
+               data[1] = rx_buf[reg];
        } else {
-               data[1] = tx_buf[reg];
-               retval = 2;
+               data[1] = s->state;
        }
 
 out:
        up(&devpriv->limit_sem);
 
-       return retval;
+       return ret ? ret : insn->n;
 }
 
 static int vmk80xx_cnt_insn_read(struct comedi_device *dev,
index 42a5f5c8d3d181e224be7d2b6b2d14ca24be9592..ca4c2c67dd880d4253909850a7811badcc24b7b9 100644 (file)
@@ -457,8 +457,6 @@ static int cp_tm1217_probe(struct i2c_client *client,
        for (i = 0; i < TOUCH_SUPPORTED; i++) {
                input_dev = input_allocate_device();
                if (input_dev == NULL) {
-                       dev_err(ts->dev,
-                               "cp_tm1217:Input Device Struct alloc failed\n");
                        retval = -ENOMEM;
                        goto fail;
                }
index 5845e899ee806402d39dbfbe621aa7f2639818d2..043bd49843ffd4082b1303ca305a9842418293cf 100644 (file)
@@ -1517,7 +1517,7 @@ static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts)
        uint32_t i, list_avail = 0;
        enum BC_STATUS comp_sts = BC_STS_NO_DATA;
        uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0;
-       bool ret = 0;
+       bool ret = false;
 
        if (!hw) {
                BCMLOG_ERR("Invalid Arguments\n");
@@ -1852,7 +1852,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
 {
        uint32_t intr_sts = 0;
        uint32_t deco_intr = 0;
-       bool rc = 0;
+       bool rc = false;
 
        if (!adp || !hw->dev_started)
                return rc;
@@ -1865,7 +1865,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
 
        if (intr_sts) {
                /* let system know we processed interrupt..*/
-               rc = 1;
+               rc = true;
                hw->stats.dev_interrupts++;
        }
 
@@ -1886,7 +1886,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
                /* FIXME: jarod: No udelay? might this be
                 the real reason mini pci-e cards were stalling out? */
                bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
-               rc = 1;
+               rc = true;
        }
 
        /* Rx interrupts */
index b17fbf8181cf424459eb3010a1ca4922117ec931..190b9b924368843f6f688a8ea32819ea329d8af9 100644 (file)
@@ -75,8 +75,9 @@ static int chd_dec_disable_int(struct crystalhd_adp *adp)
        return 0;
 }
 
-struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
-                                        bool isr)
+static struct
+crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
+                                          bool isr)
 {
        unsigned long flags = 0;
        struct crystalhd_ioctl_data *temp;
@@ -96,8 +97,8 @@ struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
        return temp;
 }
 
-void chd_dec_free_iodata(struct crystalhd_adp *adp,
-                        struct crystalhd_ioctl_data *iodata, bool isr)
+static void chd_dec_free_iodata(struct crystalhd_adp *adp,
+                               struct crystalhd_ioctl_data *iodata, bool isr)
 {
        unsigned long flags = 0;
 
@@ -156,7 +157,7 @@ static int chd_dec_fetch_cdata(struct crystalhd_adp *adp,
        if (rc) {
                BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
                           io->add_cdata_sz, (unsigned int)ua_off);
-               kfree(io->add_cdata);
+               vfree(io->add_cdata);
                io->add_cdata = NULL;
                return -ENODATA;
        }
@@ -627,7 +628,7 @@ err:
 }
 
 #ifdef CONFIG_PM
-int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct crystalhd_adp *adp;
        struct crystalhd_ioctl_data *temp;
@@ -661,7 +662,7 @@ int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        return 0;
 }
 
-int chd_dec_pci_resume(struct pci_dev *pdev)
+static int chd_dec_pci_resume(struct pci_dev *pdev)
 {
        struct crystalhd_adp *adp;
        enum BC_STATUS sts = BC_STS_SUCCESS;
index d71aea541811cab5e65ce0dca0e6079be84121a9..46a0d92173e0979e471eae2e467acbec2b573781 100644 (file)
@@ -145,10 +145,8 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
     /* Enable 8 out of 10 validation */
         /* t1RBOC enable(BOC:BitOriented Code) */
        pci_write_32((u_int32_t *) &comet->t1_rboc_ena, 0x00);
-       if (isT1mode)
-       {
-
-       /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
+       if (isT1mode) {
+               /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
                /* 6 bit down, 5 bit up (assert) */
                pci_write_32((u_int32_t *) &comet->ibcd_cfg, 0x04);
                /* line loopback activate pattern */
@@ -353,7 +351,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
        /* RLPS Configuration Status */
        pci_write_32((u_int32_t *) &comet->rlps_cfgsts, 0x11);
        if (isT1mode)
-                /* ? */
+               /* ? */
                pci_write_32((u_int32_t *) &comet->rlps_alos_thresh, 0x55);
        else
                /* ? */
@@ -452,7 +450,7 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
        volatile u_int32_t value;
 
        for (ramaddr = 0; ramaddr < 256; ramaddr++) {
-       /*** the following lines are per Errata 7, 2.5 ***/
+               /*** the following lines are per Errata 7, 2.5 ***/
                {
                /* Set up for a read operation */
                pci_write_32((u_int32_t *) &comet->rlps_eq_rwsel, 0x80);
index e06da4a6f6f640dc8c1876ecfb05b2644ea90798..03b9bb77a8097066c0018bce79f701f39e4bd66e 100644 (file)
@@ -338,7 +338,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 *, comet_t *, u_int32_t, int, u_int8_t);
 #endif
 
 #endif                          /* _INC_COMET_H_ */
index 53e923701ae6d4099a27c7f6457b5830a4b4ba35..02b4f8f1aca5d6197407c693d34a6025a8b813a1 100644 (file)
@@ -157,7 +157,7 @@ prep_hdw_info (void)
         hi->pci_slot = 0xff;
         hi->pci_pin[0] = 0;
         hi->pci_pin[1] = 0;
-        hi->ndev = 0;
+        hi->ndev = NULL;
         hi->addr[0] = 0L;
         hi->addr[1] = 0L;
         hi->addr_mapped[0] = 0L;
@@ -309,7 +309,7 @@ c4hw_attach_all (void)
     if (!found)
     {
         pr_warning("No boards found\n");
-        return ENODEV;
+        return -ENODEV;
     }
     /* sanity check for consistent hardware found */
     for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
@@ -318,7 +318,7 @@ c4hw_attach_all (void)
         {
             pr_warning("%s: something very wrong with pci_get_device\n",
                        hi->devname);
-            return EIO;
+            return -EIO;
         }
     }
     /* bring board's memory regions on/line */
@@ -328,12 +328,12 @@ c4hw_attach_all (void)
             break;
         for (j = 0; j < 2; j++)
         {
-            if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0)
+           if (!request_mem_region (hi->addr[j], hi->len[j], hi->devname))
             {
                 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
                            hi->devname, hi->addr[j], hi->len[j]);
                 cleanup_ioremap ();
-                return ENOMEM;
+                return -ENOMEM;
             }
             hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]);
             if (!hi->addr_mapped[j])
@@ -341,7 +341,7 @@ c4hw_attach_all (void)
                 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
                            hi->devname, hi->addr[j], hi->len[j]);
                 cleanup_ioremap ();
-                return ENOMEM;
+                return -ENOMEM;
             }
 #ifdef SBE_MAP_DEBUG
             pr_warning("%s: io remapped from phys %x to virt %x\n",
@@ -365,7 +365,7 @@ c4hw_attach_all (void)
                        hi->devname, i, hi->pci_slot);
             cleanup_devs ();
             cleanup_ioremap ();
-            return EIO;
+            return -EIO;
         }
         pci_set_master (hi->pdev[0]);
         pci_set_master (hi->pdev[1]);
index 142691c8d8d1c035b9b44b1b6900e117b79e312e..9b483739881a6acecaa7e09c10f0c6f5288f5183 100644 (file)
@@ -133,7 +133,7 @@ getuserbychan (int channum)
     mch_t      *ch;
 
     ch = c4_find_chan (channum);
-    return ch ? ch->user : 0;
+    return ch ? ch->user : NULL;
 }
 
 
@@ -230,7 +230,7 @@ c4_wq_port_init (mpi_t *pi)
             __func__, name, pi->portnum); /* RLD DEBUG */
 #endif
     if (!(pi->wq_port = create_singlethread_workqueue (name)))
-        return ENOMEM;
+        return -ENOMEM;
     return 0;                       /* success */
 }
 
@@ -245,7 +245,7 @@ c4_wq_port_cleanup (mpi_t *pi)
     {
         destroy_workqueue (pi->wq_port);        /* this also calls
                                                  * flush_workqueue() */
-        pi->wq_port = 0;
+        pi->wq_port = NULL;
     }
 }
 
@@ -420,7 +420,7 @@ create_chan (struct net_device *ndev, ci_t *ci,
     int         ret;
 
     if (c4_find_chan (cp->channum))
-        return 0;                   /* channel already exists */
+        return NULL;                   /* channel already exists */
 
     {
         struct c4_priv *priv;
@@ -430,14 +430,14 @@ create_chan (struct net_device *ndev, ci_t *ci,
         if (!priv)
         {
             pr_warning("%s: no memory for net_device !\n", ci->devname);
-            return 0;
+           return NULL;
         }
         dev = alloc_hdlcdev (priv);
         if (!dev)
         {
             pr_warning("%s: no memory for hdlc_device !\n", ci->devname);
             OS_kfree (priv);
-            return 0;
+           return NULL;
         }
         priv->ci = ci;
         priv->channum = cp->channum;
@@ -496,7 +496,7 @@ create_chan (struct net_device *ndev, ci_t *ci,
             pr_info("%s: create_chan[%d] registration error = %d.\n",
                     ci->devname, cp->channum, ret);
         free_netdev (dev);          /* cleanup */
-        return 0;                   /* failed to register */
+       return NULL;            /* failed to register */
     }
     return dev;
 }
@@ -744,7 +744,7 @@ do_deluser (struct net_device *ndev, int lockit)
         ch = c4_find_chan (channum);
         if (ch == NULL)
             return -ENOENT;
-        ch->user = 0;               /* will be freed, below */
+       ch->user = NULL;        /* will be freed, below */
     }
 
     if (lockit)
@@ -959,7 +959,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
     {
         pr_warning("%s: no memory for struct net_device !\n", hi->devname);
         error_flag = ENOMEM;
-        return 0;
+       return NULL;
     }
     ci = (ci_t *)(netdev_priv(ndev));
     ndev->irq = irq0;
@@ -970,7 +970,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
     c4_list = ci;
     ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
 
-    if (CI == 0)
+    if (!CI)
         CI = ci;                    /* DEBUG, only board 0 usage */
 
     strcpy (ci->devname, hi->devname);
@@ -996,7 +996,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
         error_flag = ENODEV;
-        return 0;
+       return NULL;
     }
     /*************************************************************
      *  int request_irq(unsigned int irq,
@@ -1022,7 +1022,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
         error_flag = EIO;
-        return 0;
+       return NULL;
     }
 #ifdef CONFIG_SBE_PMCC4_NCOMM
     if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev))
@@ -1033,7 +1033,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
         error_flag = EIO;
-        return 0;
+       return NULL;
     }
 #endif
 
@@ -1091,7 +1091,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         free_irq (irq0, ndev);
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
-        return 0;                   /* failure, error_flag is set */
+       return NULL;            /* failure, error_flag is set */
     }
     return ndev;
 }
index 52b6d7f5fd4758329cfa9cdec474175c1f92d405..0ba8c3ae673bd19cb86617a6b3ad0aea32ecf228 100644 (file)
@@ -745,8 +745,8 @@ musycc_init(ci_t *ci)
 #define INT_QUEUE_BOUNDARY  4
 
     regaddr = OS_kmalloc((INT_QUEUE_SIZE + 1) * sizeof(u_int32_t));
-    if (regaddr == 0)
-       return ENOMEM;
+    if (!regaddr)
+       return -ENOMEM;
     ci->iqd_p_saved = regaddr;      /* save orig value for free's usage */
     ci->iqd_p = (u_int32_t *) ((unsigned long) (regaddr + INT_QUEUE_BOUNDARY - 1) &
                               (~(INT_QUEUE_BOUNDARY - 1)));    /* this calculates
@@ -766,13 +766,13 @@ musycc_init(ci_t *ci)
 #define GROUP_BOUNDARY   0x800
 
        regaddr = OS_kmalloc(sizeof(struct musycc_groupr) + GROUP_BOUNDARY);
-       if (regaddr == 0) {
+       if (!regaddr) {
            for (gchan = 0; gchan < i; gchan++) {
                pi = &ci->port[gchan];
                OS_kfree(pi->reg);
-               pi->reg = 0;
+               pi->reg = NULL;
            }
-           return ENOMEM;
+           return -ENOMEM;
        }
        pi->regram_saved = regaddr; /* save orig value for free's usage */
        pi->regram = (struct musycc_groupr *) ((unsigned long) (regaddr + GROUP_BOUNDARY - 1) &
@@ -839,12 +839,12 @@ musycc_bh_tx_eom(mpi_t *pi, int gchan)
     volatile u_int32_t status;
 
     ch = pi->chan[gchan];
-    if (ch == 0 || ch->state != UP) {
+    if (!ch || ch->state != UP) {
        if (cxt1e1_log_level >= LOG_ERROR)
            pr_info("%s: intr: xmit EOM on uninitialized channel %d\n",
                    pi->up->devname, gchan);
     }
-    if (ch == 0 || ch->mdt == 0)
+    if (!ch || !ch->mdt)
        return;                     /* note: mdt==0 implies a malloc()
                                     * failure w/in chan_up() routine */
 
@@ -907,7 +907,7 @@ musycc_bh_tx_eom(mpi_t *pi, int gchan)
        ch->txd_irq_srv = md->snext;
 
        md->data = 0;
-       if (md->mem_token != 0) {
+       if (md->mem_token)      {
            /* upcount channel */
            atomic_sub(OS_mem_token_tlen(md->mem_token), &ch->tx_pending);
            /* upcount card */
@@ -931,7 +931,7 @@ musycc_bh_tx_eom(mpi_t *pi, int gchan)
 #endif                              /*** CONFIG_SBE_WAN256T3_NCOMM ***/
 
            OS_mem_token_free_irq(md->mem_token);
-           md->mem_token = 0;
+           md->mem_token = NULL;
        }
        md->status = 0;
 #ifdef RLD_TXFULL_DEBUG
@@ -1012,13 +1012,13 @@ musycc_bh_rx_eom(mpi_t *pi, int gchan)
     u_int32_t   error;
 
     ch = pi->chan[gchan];
-    if (ch == 0 || ch->state != UP) {
+    if (!ch || ch->state != UP) {
        if (cxt1e1_log_level > LOG_ERROR)
            pr_info("%s: intr: receive EOM on uninitialized channel %d\n",
                    pi->up->devname, gchan);
        return;
     }
-    if (ch->mdr == 0)
+    if (!ch->mdr)
        return;                     /* can this happen ? */
 
     for (;;) {
@@ -1566,18 +1566,18 @@ musycc_chan_down(ci_t *dummy, int channum)
     pi->regram->rmp[gchan] = 0;
     FLUSH_MEM_WRITE();
     for (i = 0; i < ch->txd_num; i++)
-       if (ch->mdt[i].mem_token != 0)
+       if (ch->mdt[i].mem_token)
            OS_mem_token_free(ch->mdt[i].mem_token);
 
     for (i = 0; i < ch->rxd_num; i++)
-       if (ch->mdr[i].mem_token != 0)
+       if (ch->mdr[i].mem_token)
            OS_mem_token_free(ch->mdr[i].mem_token);
 
     OS_kfree(ch->mdr);
-    ch->mdr = 0;
+    ch->mdr = NULL;
     ch->rxd_num = 0;
     OS_kfree(ch->mdt);
-    ch->mdt = 0;
+    ch->mdt = NULL;
     ch->txd_num = 0;
 
     musycc_update_timeslots(pi);
@@ -1746,7 +1746,7 @@ musycc_start_xmit(ci_t *ci, int channum, void *mem_token)
 #endif
            u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS));
        }
-       md->mem_token = len ? 0 : mem_token;    /* Fill in mds on last
+       md->mem_token = len ? NULL : mem_token;    /* Fill in mds on last
                                                 * segment, others set ZERO
                                                 * so that entire token is
                                                 * removed ONLY when ALL
index 2383c609bf39078bf2fe935957b105eb288ee00b..4028ea11c4423bc14096d80f7423bec5391b4297 100644 (file)
@@ -70,7 +70,7 @@ extern void *memset (void *s, int c, size_t n);
 #endif
 
 int         drvr_state = SBE_DRVR_INIT;
-ci_t       *c4_list = 0;
+ci_t       *c4_list = NULL;
 ci_t       *CI;                 /* dummy pointer to board ZEROE's data -
                                  * DEBUG USAGE */
 
@@ -119,7 +119,7 @@ c4_find_chan (int channum)
                         return ch;
                 }
             }
-    return 0;
+    return NULL;
 }
 
 
@@ -145,7 +145,7 @@ c4_new (void *hi)
         pr_warning("failed CI malloc, size %u.\n",
                    (unsigned int) sizeof (ci_t));
 
-    if (CI == 0)
+    if (!CI)
         CI = ci;                    /* DEBUG, only board 0 usage */
     return ci;
 }
@@ -831,7 +831,7 @@ c4_musycc_rw (ci_t *ci, struct c4_musycc_param *mcp)
 {
     mpi_t      *pi;
     volatile u_int32_t *dph;    /* hardware implemented register */
-    u_int32_t  *dpr = 0;        /* RAM image of registers for group command
+    u_int32_t *dpr = NULL;     /* RAM image of registers for group command
                                  * usage */
     int         offset = mcp->offset % 0x800;   /* group relative address
                                                  * offset, mcp->portnum is
@@ -1060,7 +1060,7 @@ c4_new_chan (ci_t *ci, int portnum, int channum, void *user)
     }
 
     /* save off interface assignments which bound a board */
-    if (ci->first_if == 0)          /* first channel registered is assumed to
+    if (!ci->first_if)         /* first channel registered is assumed to
                                      * be the lowest channel */
     {
         ci->first_if = ci->last_if = user;
@@ -1392,7 +1392,7 @@ c4_chan_up (ci_t *ci, int channum)
         md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING
                                      * NOTE: HOST_TX_OWNED = 0 so no need to
                                      * byteSwap */
-        md->mem_token = 0;
+        md->mem_token = NULL;
         md->data = 0;
         if (i == (txnum - 1))
         {
@@ -1448,10 +1448,10 @@ errfree:
         OS_mem_token_free (ch->mdr[i].mem_token);
     }
     OS_kfree (ch->mdt);
-    ch->mdt = 0;
+    ch->mdt = NULL;
     ch->txd_num = 0;
     OS_kfree (ch->mdr);
-    ch->mdr = 0;
+    ch->mdr = NULL;
     ch->rxd_num = 0;
     ch->state = DOWN;
     return ENOBUFS;
index 3c6d1c0fc6d69050c893a320781facd7419114d8..ba3ff3efe0634356cb7488aa61f168ac798a0223 100644 (file)
@@ -73,7 +73,7 @@ OS_mem_token_alloc (size_t size)
     if (!skb)
     {
         //pr_warning("no mem in OS_mem_token_alloc !\n");
-        return 0;
+        return NULL;
     }
     return skb;
 }
@@ -103,7 +103,7 @@ OS_mem_token_data (void *token)
 static inline void *
 OS_mem_token_next (void *token)
 {
-    return 0;
+    return NULL;
 }
 
 
index 87512a53f7203b8ea66335cbcc6cbb2801708260..81fa8a3a462cc6e216b052b455791dcc7b544207 100644 (file)
@@ -88,7 +88,7 @@ sbeCrc(u_int8_t *buffer,          /* data buffer to crc */
        u_int32_t initialCrc,      /* starting CRC */
        u_int32_t *result)
 {
-       u_int32_t     *tbl = 0;
+       u_int32_t     *tbl = NULL;
        u_int32_t      temp1, temp2, crc;
 
        /*
@@ -102,7 +102,7 @@ sbeCrc(u_int8_t *buffer,          /* data buffer to crc */
                genCrcTable(tbl);
 #else
                tbl = (u_int32_t *) OS_kmalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t));
-               if (tbl == 0) {
+               if (!tbl) {
                        *result = 0;   /* dummy up return value due to malloc
                                        * failure */
                        return;
index 791993fec96bac3eb6c232673282e7ce4194d593..6ec51bccceb11844270321aab3e7b256d54a1d8d 100644 (file)
@@ -22,7 +22,7 @@
 char       *
 sbeid_get_bdname (ci_t *ci)
 {
-    char       *np = 0;
+    char       *np = NULL;
 
     switch (ci->brd_id)
     {
index 9361dd8ce1255b6d7a4afa356bd477b219774296..353c001d3fbeec2f7f836c131a1181a2b3a9bf82 100644 (file)
@@ -44,7 +44,7 @@ void sbecom_proc_brd_cleanup(ci_t *ci)
 static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip)
 {
        hdw_info_t *hi = &hdw_info[ci->brdno];
-       u_int8_t *bsn = 0;
+       u_int8_t *bsn = NULL;
 
        switch (hi->promfmt)
        {
index ce9b15c71894726629805c4be41d12131bffa5a0..e1e5bfc9ad376316d1d9feb7ced1f3614562b4bc 100644 (file)
  */
 
 #define SBE_IOC_LOGLEVEL       _IOW(SBE_IOC_MAGIC, 0x00, int)
-#define SBE_IOC_CHAN_NEW       _IOW(SBE_IOC_MAGIC, 0x01,int)    /* unused */
-#define SBE_IOC_CHAN_UP        _IOW(SBE_IOC_MAGIC, 0x02,int)    /* unused */
-#define SBE_IOC_CHAN_DOWN      _IOW(SBE_IOC_MAGIC, 0x03,int)    /* unused */
-#define SBE_IOC_CHAN_GET       _IOWR(SBE_IOC_MAGIC,0x04, struct sbecom_chan_param)
+#define SBE_IOC_CHAN_NEW       _IOW(SBE_IOC_MAGIC, 0x01, int)    /* unused */
+#define SBE_IOC_CHAN_UP        _IOW(SBE_IOC_MAGIC, 0x02, int)    /* unused */
+#define SBE_IOC_CHAN_DOWN      _IOW(SBE_IOC_MAGIC, 0x03, int)    /* unused */
+#define SBE_IOC_CHAN_GET       _IOWR(SBE_IOC_MAGIC, 0x04, struct sbecom_chan_param)
 #define SBE_IOC_CHAN_SET       _IOW(SBE_IOC_MAGIC, 0x05, struct sbecom_chan_param)
-#define SBE_IOC_CHAN_GET_STAT  _IOWR(SBE_IOC_MAGIC,0x06, struct sbecom_chan_stats)
+#define SBE_IOC_CHAN_GET_STAT  _IOWR(SBE_IOC_MAGIC, 0x06, struct sbecom_chan_stats)
 #define SBE_IOC_CHAN_DEL_STAT  _IOW(SBE_IOC_MAGIC, 0x07, int)
 #define SBE_IOC_PORTS_ENABLE   _IOW(SBE_IOC_MAGIC, 0x0A, int)
-#define SBE_IOC_PORT_GET       _IOWR(SBE_IOC_MAGIC,0x0C, struct sbecom_port_param)
+#define SBE_IOC_PORT_GET       _IOWR(SBE_IOC_MAGIC, 0x0C, struct sbecom_port_param)
 #define SBE_IOC_PORT_SET       _IOW(SBE_IOC_MAGIC, 0x0D, struct sbecom_port_param)
-#define SBE_IOC_READ_VEC       _IOWR(SBE_IOC_MAGIC,0x10, struct sbecom_wrt_vec)
-#define SBE_IOC_WRITE_VEC      _IOWR(SBE_IOC_MAGIC,0x11, struct sbecom_wrt_vec)
+#define SBE_IOC_READ_VEC       _IOWR(SBE_IOC_MAGIC, 0x10, struct sbecom_wrt_vec)
+#define SBE_IOC_WRITE_VEC      _IOWR(SBE_IOC_MAGIC, 0x11, struct sbecom_wrt_vec)
 #define SBE_IOC_GET_SN         _IOR(SBE_IOC_MAGIC, 0x12, u_int32_t)
 #define SBE_IOC_RESET_DEV      _IOW(SBE_IOC_MAGIC, 0x13, int)
-#define SBE_IOC_FRAMER_GET     _IOWR(SBE_IOC_MAGIC,0x14, struct sbecom_framer_param)
+#define SBE_IOC_FRAMER_GET     _IOWR(SBE_IOC_MAGIC, 0x14, struct sbecom_framer_param)
 #define SBE_IOC_FRAMER_SET     _IOW(SBE_IOC_MAGIC, 0x15, struct sbecom_framer_param)
 #define SBE_IOC_CARD_GET       _IOR(SBE_IOC_MAGIC, 0x20, struct sbecom_card_param)
 #define SBE_IOC_CARD_SET       _IOW(SBE_IOC_MAGIC, 0x21, struct sbecom_card_param)
 #define SBE_IOC_CARD_DEL_STAT  _IO(SBE_IOC_MAGIC,  0x23)
 #define SBE_IOC_CARD_CHAN_STAT _IOR(SBE_IOC_MAGIC, 0x24, struct sbecom_chan_stats)
 #define SBE_IOC_CARD_BLINK     _IOW(SBE_IOC_MAGIC, 0x30, int)
-#define SBE_IOC_DRVINFO_GET    _IOWR(SBE_IOC_MAGIC,0x31, struct sbe_drv_info)
+#define SBE_IOC_DRVINFO_GET    _IOWR(SBE_IOC_MAGIC, 0x31, struct sbe_drv_info)
 #define SBE_IOC_BRDINFO_GET    _IOR(SBE_IOC_MAGIC, 0x32, struct sbe_brd_info)
-#define SBE_IOC_IID_GET        _IOWR(SBE_IOC_MAGIC,0x33, struct sbe_iid_info)
+#define SBE_IOC_IID_GET        _IOWR(SBE_IOC_MAGIC, 0x33, struct sbe_iid_info)
 #define SBE_IOC_BRDADDR_GET    _IOWR(SBE_IOC_MAGIC, 0x34, struct sbe_brd_addr)
 
 #ifdef NOT_YET_COMMON
-#define SBE_IOC_TSIOC_GET      _IOWR(SBE_IOC_MAGIC,0x16, struct wanc1t3_ts_param)
+#define SBE_IOC_TSIOC_GET      _IOWR(SBE_IOC_MAGIC, 0x16, struct wanc1t3_ts_param)
 #define SBE_IOC_TSIOC_SET      _IOW(SBE_IOC_MAGIC, 0x17, struct wanc1t3_ts_param)
 #endif
 
index 9f1fce157c77180260b758f0a1057d7959fd1dcb..3abe8d2bb748b3794c2c15430fb7a81b9b8464ab 100644 (file)
@@ -1,5 +1,3 @@
-EXTRA_CFLAGS += -DDG_NAME=\"dgap-1.3-16\" -DDG_PART=\"40002347_C\"
-
 obj-$(CONFIG_DGAP) += dgap.o
 
 
index f79e65cd1d51522aaf41fe8ecf4703263cc26773..271ac19257f9f32fd2aae6ee4c7ac180c02e6119 100644 (file)
@@ -35,7 +35,7 @@
 struct fepimg {
     int type;                          /* board type */
     int        len;                            /* length of image */
-    char fepimage[1];                  /* begining of image */
+    char fepimage[1];                  /* beginning of image */
 };
 
 struct downldio {
index 40ef785a04284d9a4c79633f2877a957b8c405dc..4c1515ee56e58a9e2d00f7385cb3494ac1a392bb 100644 (file)
 
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/delay.h>       /* For udelay */
 #include <linux/slab.h>
 #include <asm/uaccess.h>       /* For copy_from_user/copy_to_user */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 #include <linux/sched.h>
-#endif
 
 #include "dgap_driver.h"
 #include "dgap_pci.h"
@@ -420,8 +416,7 @@ void dgap_cleanup_module(void)
                unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
        }
 
-       if (dgap_config_buf)
-               kfree(dgap_config_buf);
+       kfree(dgap_config_buf);
 
        for (i = 0; i < dgap_NumBoards; ++i) {
                dgap_remove_ports_sysfiles(dgap_Board[i]);
@@ -488,10 +483,8 @@ static void dgap_cleanup_board(struct board_t *brd)
                }
        }
 
-       if (brd->flipbuf)
-               kfree(brd->flipbuf);
-       if (brd->flipflagbuf)
-               kfree(brd->flipflagbuf);
+       kfree(brd->flipbuf);
+       kfree(brd->flipflagbuf);
 
        dgap_Board[brd->boardnum] = NULL;
 
index b1cf489a729c8d66327a15dfe3f1bef54733c272..7d631e80c00e8856dda9136cf14117250f4fc81d 100644 (file)
 /*
  * Driver identification, error and debugging statments
  *
- * In theory, you can change all occurances of "digi" in the next
+ * In theory, you can change all occurrences of "digi" in the next
  * three lines, and the driver printk's will all automagically change.
  *
  * APR((fmt, args, ...));      Always prints message
  * DPR((fmt, args, ...));      Only prints if DGAP_TRACER is defined at
  *                               compile time and dgap_debug!=0
  */
+#define        DG_NAME         "dgap-1.3-16"
+#define        DG_PART         "40002347_C"
+
 #define        PROCSTR         "dgap"                  /* /proc entries         */
 #define        DEVSTR          "/dev/dg/dgap"          /* /dev entries          */
 #define        DRVSTR          "dgap"                  /* Driver name string 
index 4464f02c9575731bca8de334cd44f0475814bdf1..794cf9db8b8308f63c494759bacbd101296552af 100644 (file)
@@ -134,7 +134,7 @@ int dgap_after_config_loaded(void)
                dgap_Board[i]->flipflagbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC);
        }
 
-       return (rc);
+       return rc;
 }
 
 
@@ -150,14 +150,14 @@ static int dgap_usertoboard(struct board_t *brd, char *to_addr, char __user *fro
        int n = U2BSIZE;
 
        if (!brd || brd->magic != DGAP_BOARD_MAGIC)
-               return(-EFAULT);
+               return -EFAULT;
 
        while (len) {
                if (n > len)
                        n = len;
 
                if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
-                       return(-EFAULT);
+                       return -EFAULT;
                }
 
                /* Copy data from buffer to card memory */
@@ -169,7 +169,7 @@ static int dgap_usertoboard(struct board_t *brd, char *to_addr, char __user *fro
                from_addr += n;   
                n = U2BSIZE;
         }
-       return(0);
+       return 0;
 }
 
 
@@ -1155,20 +1155,20 @@ uint dgap_get_custom_baud(struct channel_t *ch)
        uint value = 0;
 
        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
-               return (0);
+               return 0;
        }
 
        if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) {
-               return (0);
+               return 0;
        }
 
        if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS))
-               return (0);
+               return 0;
 
        vaddr = ch->ch_bd->re_map_membase;
 
        if (!vaddr)
-               return (0);
+               return 0;
 
        /*
         * Go get from fep mem, what the fep
@@ -1178,7 +1178,7 @@ uint dgap_get_custom_baud(struct channel_t *ch)
                (ch->ch_portnum * 0x28) + LINE_SPEED));
 
        value = readw(vaddr + offset);
-       return (value);
+       return value;
 }
 
 
@@ -1229,29 +1229,24 @@ int dgap_param(struct tty_struct *tty)
        uchar   mval;
        uchar   hflow;
 
-       if (!tty || tty->magic != TTY_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!tty || tty->magic != TTY_MAGIC)
+               return -ENXIO;
 
        un = (struct un_t *) tty->driver_data;
-       if (!un || un->magic != DGAP_UNIT_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!un || un->magic != DGAP_UNIT_MAGIC)
+               return -ENXIO;
 
        ch = un->un_ch;
-       if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
+               return -ENXIO;
 
        bd = ch->ch_bd;
-       if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!bd || bd->magic != DGAP_BOARD_MAGIC)
+               return -ENXIO;
 
         bs = ch->ch_bs;
-       if (bs == 0) {
-               return (-ENXIO);
-       }
+       if (!bs)
+               return -ENXIO;
 
        DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
                ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
@@ -1558,7 +1553,7 @@ int dgap_param(struct tty_struct *tty)
 
        DPR_PARAM(("param finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -1675,7 +1670,7 @@ static int dgap_event(struct board_t *bd)
        int             b1;
 
        if (!bd || bd->magic != DGAP_BOARD_MAGIC)
-               return (-ENXIO);
+               return -ENXIO;
 
        DGAP_LOCK(bd->bd_lock, lock_flags);
 
@@ -1683,7 +1678,7 @@ static int dgap_event(struct board_t *bd)
 
        if (!vaddr) {
                DGAP_UNLOCK(bd->bd_lock, lock_flags);
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        eaddr = (struct ev_t *) (vaddr + EVBUF);
@@ -1701,7 +1696,7 @@ static int dgap_event(struct board_t *bd)
                DPR_EVENT(("should be calling xxfail %d\n", __LINE__));
                /* Let go of board lock */
                DGAP_UNLOCK(bd->bd_lock, lock_flags);
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        /*
@@ -1949,5 +1944,5 @@ next:
        writew(tail, &(eaddr->ev_tail));
        DGAP_UNLOCK(bd->bd_lock, lock_flags);
 
-       return (0);
+       return 0;
 }               
index 3a12ba5e3c2ade2f34a2f376ec962e52c71ac74f..c9abc406a1e0cb5fe23f5b074e7f91607279d0b5 100644 (file)
@@ -211,7 +211,7 @@ struct bs_t {
 #define SIFLAG         0xea            /* Set UNIX iflags              */
 #define SFLOWC         0xeb            /* Set flow control characters  */
 #define STLOW          0xec            /* Set transmit low water mark  */
-#define RPAUSE         0xee            /* Pause recieve                */
+#define RPAUSE         0xee            /* Pause receive                */
 #define RRESUME                0xef            /* Resume receive               */  
 #define CHRESET                0xf0            /* Reset Channel                */
 #define BUFSETALL      0xf2            /* Set Tx & Rx buffer size avail*/
index 8ebf4b7373b74c8a696f919f1a10e189053b69d7..0dc2404922ff0a485bfe5e2b72e6e6898e3a32e2 100644 (file)
 #ifndef __DGAP_KCOMPAT_H
 #define __DGAP_KCOMPAT_H
 
-# ifndef KERNEL_VERSION
-#  define KERNEL_VERSION(a,b,c)  (((a) << 16) + ((b) << 8) + (c))
-# endif
-
-
 #if !defined(TTY_FLIPBUF_SIZE)
 # define TTY_FLIPBUF_SIZE 512
 #endif
                module_param(VAR, long, PERM); \
                MODULE_PARM_DESC(VAR, DESC);
 
-
-
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-
-
-
-
-/* NOTHING YET */
-
-
-
-
-# else
-
-
-
-# error "this driver does not support anything below the 2.6.27 kernel series."
-
-
-
-# endif
-
 #endif /* ! __DGAP_KCOMPAT_H */
index 5497e6de06088f21c88cc11a3b53b92ed46d584b..ff9d19449b43c1dc41d8b0a8ba0e9bdc3c2a0116 100644 (file)
@@ -904,7 +904,7 @@ int dgap_parsefile(char **in, int Remove)
 /*
  * dgap_sindex: much like index(), but it looks for a match of any character in
  * the group, and returns that position.  If the first character is a ^, then
- * this will match the first occurence not in that group.
+ * this will match the first occurrence not in that group.
  */
 static char *dgap_sindex (char *string, char *group)
 {
@@ -1013,8 +1013,10 @@ static void dgap_err(char *s)
 static struct cnode *dgap_newnode(int t)
 {
        struct cnode *n;
-       if ( (n = (struct cnode *) kmalloc(sizeof(struct cnode ), GFP_ATOMIC) ) != NULL) {
-               memset( (char *)n, 0, sizeof(struct cnode ) );
+
+       n = kmalloc(sizeof(struct cnode), GFP_ATOMIC);
+       if (n != NULL) {
+               memset((char *)n, 0, sizeof(struct cnode));
                n->type = t;
        }
        return(n);
@@ -1150,7 +1152,7 @@ uint dgap_config_get_altpin(struct board_t *bd)
 
 /*
  * Given a specific type of board, if found, detached link and 
- * returns the first occurance in the list.
+ * returns the first occurrence in the list.
  */
 struct cnode *dgap_find_config(int type, int bus, int slot)
 {
index 94da06fcf7e9b869a9de127f3465660745905bf1..7f4ec9a1829398f87c2bd58a3a3be339c1151b80 100644 (file)
@@ -395,7 +395,7 @@ static ssize_t dgap_tty_state_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -420,7 +420,7 @@ static ssize_t dgap_tty_baud_show(struct device *d, struct device_attribute *att
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -445,7 +445,7 @@ static ssize_t dgap_tty_msignals_show(struct device *d, struct device_attribute
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -479,7 +479,7 @@ static ssize_t dgap_tty_iflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -504,7 +504,7 @@ static ssize_t dgap_tty_cflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -529,7 +529,7 @@ static ssize_t dgap_tty_oflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -554,7 +554,7 @@ static ssize_t dgap_tty_lflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -579,7 +579,7 @@ static ssize_t dgap_tty_digi_flag_show(struct device *d, struct device_attribute
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -604,7 +604,7 @@ static ssize_t dgap_tty_rxcount_show(struct device *d, struct device_attribute *
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -629,7 +629,7 @@ static ssize_t dgap_tty_txcount_show(struct device *d, struct device_attribute *
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -661,7 +661,7 @@ static ssize_t dgap_tty_name_show(struct device *d, struct device_attribute *att
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
index b906db30b617678a648f6a910800a98a7c95c6be..2a7a37298da4456ddbcab91a81b7cb6d407d5dcd 100644 (file)
@@ -249,7 +249,7 @@ int dgap_tty_register(struct board_t *brd)
 
        /*
         * If we're doing transparent print, we have to do all of the above
-        * again, seperately so we don't get the LD confused about what major
+        * again, separately so we don't get the LD confused about what major
         * we are when we get into the dgap_tty_open() routine.
         */
        brd->PrintDriver = alloc_tty_driver(MAXPORTS);
@@ -497,10 +497,8 @@ int dgap_tty_init(struct board_t *brd)
  */
 void dgap_tty_post_uninit(void)
 {
-       if (dgap_TmpWriteBuf) {
-               kfree(dgap_TmpWriteBuf);
-               dgap_TmpWriteBuf = NULL;
-       }
+       kfree(dgap_TmpWriteBuf);
+       dgap_TmpWriteBuf = NULL;
 }
 
 
@@ -522,10 +520,8 @@ void dgap_tty_uninit(struct board_t *brd)
                        tty_unregister_device(brd->SerialDriver, i);
                }
                tty_unregister_driver(brd->SerialDriver);
-               if (brd->SerialDriver->ttys) {
-                       kfree(brd->SerialDriver->ttys);
-                       brd->SerialDriver->ttys = NULL;
-               }
+               kfree(brd->SerialDriver->ttys);
+               brd->SerialDriver->ttys = NULL;
                put_tty_driver(brd->SerialDriver);
                brd->dgap_Major_Serial_Registered = FALSE;
        }
@@ -538,10 +534,8 @@ void dgap_tty_uninit(struct board_t *brd)
                        tty_unregister_device(brd->PrintDriver, i);
                }
                tty_unregister_driver(brd->PrintDriver);
-               if (brd->PrintDriver->ttys) {
-                       kfree(brd->PrintDriver->ttys);
-                       brd->PrintDriver->ttys = NULL;
-               }
+               kfree(brd->PrintDriver->ttys);
+               brd->PrintDriver->ttys = NULL;
                put_tty_driver(brd->PrintDriver);
                brd->dgap_Major_TransparentPrint_Registered = FALSE;
        }
@@ -601,7 +595,7 @@ static void dgap_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *b
                /*
                 *  Loop while data remains.
                 */
-               while (nbuf > 0 && ch->ch_sniff_buf != 0) {
+               while (nbuf > 0 && ch->ch_sniff_buf) {
                        /*
                         *  Determine the amount of available space left in the
                         *  buffer.  If there's none, wait until some appears.
@@ -1069,7 +1063,7 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file)
 
        DGAP_LOCK(brd->bd_lock, lock_flags);
 
-       /* The wait above should guarentee this cannot happen */
+       /* The wait above should guarantee this cannot happen */
        if (brd->state != BOARD_READY) {
                DGAP_UNLOCK(brd->bd_lock, lock_flags);
                return -ENXIO;
@@ -1113,9 +1107,10 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file)
                MAJOR(tty_devnum(tty)), MINOR(tty_devnum(tty)), un, brd->name));
 
        /*
-        * Error if channel info pointer is 0.
+        * Error if channel info pointer is NULL.
         */
-       if ((bs = ch->ch_bs) == 0) {
+       bs = ch->ch_bs;
+       if (!bs) {
                DGAP_UNLOCK(ch->ch_lock, lock_flags2);
                DGAP_UNLOCK(brd->bd_lock, lock_flags);
                DPR_OPEN(("%d BS is 0!\n", __LINE__));
@@ -3513,10 +3508,6 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        return(-EINVAL);
                }
 
-               DGAP_UNLOCK(ch->ch_lock, lock_flags2);
-               DGAP_UNLOCK(bd->bd_lock, lock_flags);
-               return(-ENOIOCTLCMD);
-
        case DIGI_GETA:
                /* get information for ditty */
                DGAP_UNLOCK(ch->ch_lock, lock_flags2);
@@ -3586,12 +3577,4 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                return(-ENOIOCTLCMD);
        }
-
-       DGAP_UNLOCK(ch->ch_lock, lock_flags2);
-       DGAP_UNLOCK(bd->bd_lock, lock_flags);
-
-       DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n", 
-               dgap_ioctl_name(cmd), cmd, arg));
-                        
-       return(0);
 }
index 651e2e5e93c7780765d0f2c9a9bc6c8d91f6d20f..bcea4f734a329c6a18de37d2e67eba2b7bc9fc92 100644 (file)
@@ -203,9 +203,9 @@ struct shrink_buf_struct {
        unsigned long   shrink_buf_vaddr;       /* Virtual address of board */
        unsigned long   shrink_buf_phys;        /* Physical address of board */
        unsigned long   shrink_buf_bseg;        /* Amount of board memory */
-       unsigned long   shrink_buf_hseg;        /* '186 Begining of Dual-Port */
+       unsigned long   shrink_buf_hseg;        /* '186 Beginning of Dual-Port */
 
-       unsigned long   shrink_buf_lseg;        /* '186 Begining of freed memory                                                */ 
+       unsigned long   shrink_buf_lseg;        /* '186 Beginning of freed memory                                               */ 
        unsigned long   shrink_buf_mseg;        /* Linear address from start of
                                                   dual-port were freed memory
                                                   begins, host viewpoint. */
index 57dfd6bafcf69a2ba3450b65a43c858607a73bc3..638c5da43c85fbad924797369c8349582aedd321 100644 (file)
@@ -52,7 +52,7 @@ char          *pgm;
 void           myperror();
 
 /*
-**  This structure is used to keep track of the diferent images available
+**  This structure is used to keep track of the different images available
 **  to give to the driver.  It is arranged so that the things that are
 **  constants or that have defaults are first inthe strucutre to simplify
 **  the table of initializers.
@@ -789,7 +789,7 @@ int main(int argc, char **argv)
 /*
 ** myperror()
 **
-**  Same as normal perror(), but places the program name at the begining
+**  Same as normal perror(), but places the program name at the beginning
 **  of the message.
 */
 void myperror(char *s)
index 117e158082402ddc5b32ace5dfcadc3201300e2d..fdc1aabc7fdeb649085a746c4c8f61c54e69425a 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/sched.h>       /* For jiffies, task states */
 #include <linux/interrupt.h>   /* For tasklet and interrupt structs/defines */
 #include <linux/delay.h>       /* For udelay */
-#include <asm/io.h>            /* For read[bwl]/write[bwl] */
+#include <linux/io.h>          /* For read[bwl]/write[bwl] */
 #include <linux/serial.h>      /* For struct async_serial */
 #include <linux/serial_reg.h>  /* For the various UART offsets */
 #include <linux/pci.h>
@@ -43,7 +43,7 @@
 #include "dgnc_tty.h"
 #include "dgnc_trace.h"
 
-static inline void cls_parse_isr(struct board_t *brd, uint port);
+static inline void cls_parse_isr(struct dgnc_board *brd, uint port);
 static inline void cls_clear_break(struct channel_t *ch, int force);
 static inline void cls_set_cts_flow_control(struct channel_t *ch);
 static inline void cls_set_rts_flow_control(struct channel_t *ch);
@@ -53,7 +53,7 @@ static inline void cls_set_no_output_flow_control(struct channel_t *ch);
 static inline void cls_set_no_input_flow_control(struct channel_t *ch);
 static void cls_parse_modem(struct channel_t *ch, uchar signals);
 static void cls_tasklet(unsigned long data);
-static void cls_vpd(struct board_t *brd);
+static void cls_vpd(struct dgnc_board *brd);
 static void cls_uart_init(struct channel_t *ch);
 static void cls_uart_off(struct channel_t *ch);
 static int cls_drain(struct tty_struct *tty, uint seconds);
@@ -393,7 +393,7 @@ static inline void cls_clear_break(struct channel_t *ch, int force)
 
 
 /* Parse the ISR register for the specific port */
-static inline void cls_parse_isr(struct board_t *brd, uint port)
+static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
 {
        struct channel_t *ch;
        uchar isr = 0;
@@ -417,9 +417,8 @@ static inline void cls_parse_isr(struct board_t *brd, uint port)
                isr = readb(&ch->ch_cls_uart->isr_fcr);
 
                /* Bail if no pending interrupt on port */
-               if (isr & UART_IIR_NO_INT)  {
+               if (isr & UART_IIR_NO_INT)
                        break;
-               }
 
                DPR_INTR(("%s:%d port: %x isr: %x\n", __FILE__, __LINE__, port, isr));
 
@@ -444,9 +443,8 @@ static inline void cls_parse_isr(struct board_t *brd, uint port)
                }
 
                /* Received Xoff signal/Special character */
-               if (isr & UART_IIR_XOFF) {
+               if (isr & UART_IIR_XOFF)
                        /* Empty */
-               }
 
                /* CTS/RTS change of state */
                if (isr & UART_IIR_CTSRTS) {
@@ -477,28 +475,24 @@ static void cls_param(struct tty_struct *tty)
        uchar uart_ier = 0;
         uint baud = 9600;
        int quot = 0;
-        struct board_t *bd;
+        struct dgnc_board *bd;
        struct channel_t *ch;
         struct un_t   *un;
 
-       if (!tty || tty->magic != TTY_MAGIC) {
+       if (!tty || tty->magic != TTY_MAGIC)
                return;
-       }
 
        un = (struct un_t *) tty->driver_data;
-       if (!un || un->magic != DGNC_UNIT_MAGIC) {
+       if (!un || un->magic != DGNC_UNIT_MAGIC)
                return;
-       }
 
        ch = un->un_ch;
-       if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) {
+       if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
                return;
-       }
 
        bd = ch->ch_bd;
-       if (!bd || bd->magic != DGNC_BOARD_MAGIC) {
+       if (!bd || bd->magic != DGNC_BOARD_MAGIC)
                return;
-       }
 
        DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
                ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
@@ -725,7 +719,7 @@ static void cls_param(struct tty_struct *tty)
  */
 static void cls_tasklet(unsigned long data)
 {
-        struct board_t *bd = (struct board_t *) data;
+        struct dgnc_board *bd = (struct dgnc_board *) data;
        struct channel_t *ch;
        ulong  lock_flags;
        int i;
@@ -802,7 +796,7 @@ static void cls_tasklet(unsigned long data)
  */
 static irqreturn_t cls_intr(int irq, void *voidbrd)
 {
-       struct board_t *brd = (struct board_t *) voidbrd;
+       struct dgnc_board *brd = (struct dgnc_board *) voidbrd;
        uint i = 0;
        uchar poll_reg;
        unsigned long lock_flags;
@@ -976,17 +970,17 @@ static int cls_drain(struct tty_struct *tty, uint seconds)
        int rc = 0;
 
        if (!tty || tty->magic != TTY_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        un = (struct un_t *) tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -1002,7 +996,7 @@ static int cls_drain(struct tty_struct *tty, uint seconds)
        if (rc)
                DPR_IOCTL(("%d Drain - User ctrl c'ed\n", __LINE__));
 
-        return (rc);
+        return rc;
 }
 
 
@@ -1305,9 +1299,8 @@ static uint cls_get_uart_bytes_left(struct channel_t *ch)
 
        /* Determine whether the Transmitter is empty or not */
        if (!(lsr & UART_LSR_TEMT)) {
-               if (ch->ch_flags & CH_TX_FIFO_EMPTY) {
+               if (ch->ch_flags & CH_TX_FIFO_EMPTY)
                        tasklet_schedule(&ch->ch_bd->helper_tasklet);
-               }
                left = 1;
        }
        else {
@@ -1378,7 +1371,7 @@ static void cls_send_immediate_char(struct channel_t *ch, unsigned char c)
        writeb(c, &ch->ch_cls_uart->txrx);
 }
 
-static void cls_vpd(struct board_t *brd)
+static void cls_vpd(struct dgnc_board *brd)
 {
         ulong           vpdbase;        /* Start of io base of the card */
         u8 __iomem           *re_map_vpdbase;/* Remapped memory of the card */
index 71d2b83cc3a12e365823df2e40fd176ac26120ef..c204266cb69fc7ab8a1ec3c2284878bfdaee0232 100644 (file)
 
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 #include <linux/sched.h>
-#endif
-
 #include "dgnc_driver.h"
 #include "dgnc_pci.h"
 #include "dpacompat.h"
@@ -71,16 +66,16 @@ PARM_INT(trcbuf_size,       0x100000,       0644,   "Debugging trace buffer size.");
  *
  */
 static int             dgnc_start(void);
-static int             dgnc_finalize_board_init(struct board_t *brd);
+static int             dgnc_finalize_board_init(struct dgnc_board *brd);
 static void            dgnc_init_globals(void);
 static int             dgnc_found_board(struct pci_dev *pdev, int id);
-static void            dgnc_cleanup_board(struct board_t *brd);
+static void            dgnc_cleanup_board(struct dgnc_board *brd);
 static void            dgnc_poll_handler(ulong dummy);
 static int             dgnc_init_pci(void);
 static int             dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void            dgnc_remove_one(struct pci_dev *dev);
 static int             dgnc_probe1(struct pci_dev *pdev, int card_type);
-static void            dgnc_do_remap(struct board_t *brd);
+static void            dgnc_do_remap(struct dgnc_board *brd);
 
 /* Driver load/unload functions */
 int            dgnc_init_module(void);
@@ -106,7 +101,7 @@ static struct file_operations dgnc_BoardFops =
  * Globals
  */
 uint                   dgnc_NumBoards;
-struct board_t         *dgnc_Board[MAXBOARDS];
+struct dgnc_board              *dgnc_Board[MAXBOARDS];
 DEFINE_SPINLOCK(dgnc_global_lock);
 int                    dgnc_driver_state = DRIVER_INITIALIZED;
 ulong                  dgnc_poll_counter;
@@ -225,7 +220,7 @@ int dgnc_init_module(void)
        rc = dgnc_start();
 
        if (rc < 0) {
-               return(rc);
+               return rc;
        }
 
        /*
@@ -250,7 +245,7 @@ int dgnc_init_module(void)
        }
 
        DPR_INIT(("Finished init_module. Returning %d\n", rc));
-       return (rc);
+       return rc;
 }
 
 
@@ -286,21 +281,14 @@ static int dgnc_start(void)
                        if (rc <= 0) {
                                APR(("Can't register dgnc driver device (%d)\n", rc));
                                rc = -ENXIO;
-                               return(rc);
+                               return rc;
                        }
                        dgnc_Major = rc;
 
                        dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-                       device_create_drvdata(dgnc_class, NULL,
-                               MKDEV(dgnc_Major, 0),
-                               NULL, "dgnc_mgmt");
-#else
                        device_create(dgnc_class, NULL,
                                MKDEV(dgnc_Major, 0),
                                NULL, "dgnc_mgmt");
-#endif
-
                        dgnc_Major_Control_Registered = TRUE;
                }
 
@@ -311,7 +299,7 @@ static int dgnc_start(void)
 
                if (rc < 0) {
                        APR(("tty preinit - not enough memory (%d)\n", rc));
-                       return(rc);
+                       return rc;
                }
 
                /* Start the poller */
@@ -328,7 +316,7 @@ static int dgnc_start(void)
                dgnc_driver_state = DRIVER_READY;
        }
 
-       return(rc);
+       return rc;
 }
 
 /*
@@ -418,7 +406,7 @@ void dgnc_cleanup_module(void)
  *
  * Free all the memory associated with a board
  */
-static void dgnc_cleanup_board(struct board_t *brd)
+static void dgnc_cleanup_board(struct dgnc_board *brd)
 {
        int i = 0;
 
@@ -491,7 +479,7 @@ static void dgnc_cleanup_board(struct board_t *brd)
  */
 static int dgnc_found_board(struct pci_dev *pdev, int id)
 {
-       struct board_t *brd;
+       struct dgnc_board *brd;
        unsigned int pci_irq;
        int i = 0;
        int rc = 0;
@@ -499,19 +487,16 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        /* get the board structure and prep it */
        brd = dgnc_Board[dgnc_NumBoards] =
-       (struct board_t *) kzalloc(sizeof(struct board_t), GFP_KERNEL);
-       if (!brd) {
-               APR(("memory allocation for board structure failed\n"));
-               return(-ENOMEM);
-       }
+               kzalloc(sizeof(*brd), GFP_KERNEL);
+       if (!brd) 
+               return -ENOMEM;
 
        /* make a temporary message buffer for the boot messages */
        brd->msgbuf = brd->msgbuf_head =
-               (char *) kzalloc(sizeof(char) * 8192, GFP_KERNEL);
+               kzalloc(sizeof(u8) * 8192, GFP_KERNEL);
        if (!brd->msgbuf) {
                kfree(brd);
-               APR(("memory allocation for board msgbuf failed\n"));
-               return(-ENOMEM);
+               return -ENOMEM;
        }
 
        /* store the info for the board we've found */
@@ -663,7 +648,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        default:
                APR(("Did not find any compatible Neo or Classic PCI boards in system.\n"));
-               return (-ENXIO);
+               return -ENXIO;
 
        }
 
@@ -725,22 +710,22 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        wake_up_interruptible(&brd->state_wait);
 
-       return(0);
+       return 0;
 
 failed:
 
-       return (-ENXIO);
+       return -ENXIO;
 
 }
 
 
-static int dgnc_finalize_board_init(struct board_t *brd) {
+static int dgnc_finalize_board_init(struct dgnc_board *brd) {
        int rc = 0;
 
        DPR_INIT(("dgnc_finalize_board_init() - start\n"));
 
        if (!brd || brd->magic != DGNC_BOARD_MAGIC)
-               return(-ENODEV);
+               return -ENODEV;
 
        DPR_INIT(("dgnc_finalize_board_init() - start #2\n"));
 
@@ -756,13 +741,13 @@ static int dgnc_finalize_board_init(struct board_t *brd) {
                        DPR_INIT(("Requested and received usage of IRQ %d\n", brd->irq));
                }
        }
-       return(rc);
+       return rc;
 }
 
 /*
  * Remap PCI memory.
  */
-static void dgnc_do_remap(struct board_t *brd)
+static void dgnc_do_remap(struct dgnc_board *brd)
 {
 
        if (!brd || brd->magic != DGNC_BOARD_MAGIC)
@@ -802,7 +787,7 @@ static void dgnc_do_remap(struct board_t *brd)
 
 static void dgnc_poll_handler(ulong dummy)
 {
-       struct board_t *brd;
+       struct dgnc_board *brd;
        unsigned long lock_flags;
        int i;
        unsigned long new_time;
@@ -900,7 +885,7 @@ int dgnc_ms_sleep(ulong ms)
 {
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout((ms * HZ) / 1000);
-       return (signal_pending(current));
+       return signal_pending(current);
 }
 
 
@@ -912,47 +897,47 @@ char *dgnc_ioctl_name(int cmd)
 {
        switch(cmd) {
 
-       case TCGETA:            return("TCGETA");
-       case TCGETS:            return("TCGETS");
-       case TCSETA:            return("TCSETA");
-       case TCSETS:            return("TCSETS");
-       case TCSETAW:           return("TCSETAW");
-       case TCSETSW:           return("TCSETSW");
-       case TCSETAF:           return("TCSETAF");
-       case TCSETSF:           return("TCSETSF");
-       case TCSBRK:            return("TCSBRK");
-       case TCXONC:            return("TCXONC");
-       case TCFLSH:            return("TCFLSH");
-       case TIOCGSID:          return("TIOCGSID");
-
-       case TIOCGETD:          return("TIOCGETD");
-       case TIOCSETD:          return("TIOCSETD");
-       case TIOCGWINSZ:        return("TIOCGWINSZ");
-       case TIOCSWINSZ:        return("TIOCSWINSZ");
-
-       case TIOCMGET:          return("TIOCMGET");
-       case TIOCMSET:          return("TIOCMSET");
-       case TIOCMBIS:          return("TIOCMBIS");
-       case TIOCMBIC:          return("TIOCMBIC");
+       case TCGETA:            return "TCGETA";
+       case TCGETS:            return "TCGETS";
+       case TCSETA:            return "TCSETA";
+       case TCSETS:            return "TCSETS";
+       case TCSETAW:           return "TCSETAW";
+       case TCSETSW:           return "TCSETSW";
+       case TCSETAF:           return "TCSETAF";
+       case TCSETSF:           return "TCSETSF";
+       case TCSBRK:            return "TCSBRK";
+       case TCXONC:            return "TCXONC";
+       case TCFLSH:            return "TCFLSH";
+       case TIOCGSID:          return "TIOCGSID";
+
+       case TIOCGETD:          return "TIOCGETD";
+       case TIOCSETD:          return "TIOCSETD";
+       case TIOCGWINSZ:        return "TIOCGWINSZ";
+       case TIOCSWINSZ:        return "TIOCSWINSZ";
+
+       case TIOCMGET:          return "TIOCMGET";
+       case TIOCMSET:          return "TIOCMSET";
+       case TIOCMBIS:          return "TIOCMBIS";
+       case TIOCMBIC:          return "TIOCMBIC";
 
        /* from digi.h */
-       case DIGI_SETA:         return("DIGI_SETA");
-       case DIGI_SETAW:        return("DIGI_SETAW");
-       case DIGI_SETAF:        return("DIGI_SETAF");
-       case DIGI_SETFLOW:      return("DIGI_SETFLOW");
-       case DIGI_SETAFLOW:     return("DIGI_SETAFLOW");
-       case DIGI_GETFLOW:      return("DIGI_GETFLOW");
-       case DIGI_GETAFLOW:     return("DIGI_GETAFLOW");
-       case DIGI_GETA:         return("DIGI_GETA");
-       case DIGI_GEDELAY:      return("DIGI_GEDELAY");
-       case DIGI_SEDELAY:      return("DIGI_SEDELAY");
-       case DIGI_GETCUSTOMBAUD: return("DIGI_GETCUSTOMBAUD");
-       case DIGI_SETCUSTOMBAUD: return("DIGI_SETCUSTOMBAUD");
-       case TIOCMODG:          return("TIOCMODG");
-       case TIOCMODS:          return("TIOCMODS");
-       case TIOCSDTR:          return("TIOCSDTR");
-       case TIOCCDTR:          return("TIOCCDTR");
-
-       default:                return("unknown");
+       case DIGI_SETA:         return "DIGI_SETA";
+       case DIGI_SETAW:        return "DIGI_SETAW";
+       case DIGI_SETAF:        return "DIGI_SETAF";
+       case DIGI_SETFLOW:      return "DIGI_SETFLOW";
+       case DIGI_SETAFLOW:     return "DIGI_SETAFLOW";
+       case DIGI_GETFLOW:      return "DIGI_GETFLOW";
+       case DIGI_GETAFLOW:     return "DIGI_GETAFLOW";
+       case DIGI_GETA:         return "DIGI_GETA";
+       case DIGI_GEDELAY:      return "DIGI_GEDELAY";
+       case DIGI_SEDELAY:      return "DIGI_SEDELAY";
+       case DIGI_GETCUSTOMBAUD: return "DIGI_GETCUSTOMBAUD";
+       case DIGI_SETCUSTOMBAUD: return "DIGI_SETCUSTOMBAUD";
+       case TIOCMODG:          return "TIOCMODG";
+       case TIOCMODS:          return "TIOCMODS";
+       case TIOCSDTR:          return "TIOCSDTR";
+       case TIOCCDTR:          return "TIOCCDTR";
+
+       default:                return "unknown";
        }
 }
index 218b15dccb7dc970bef7bd1d56d491b51ad16884..3519b803e7535be17d22adc9e7f889859f9ff577 100644 (file)
@@ -45,7 +45,7 @@
 /*
  * Driver identification, error and debugging statments
  *
- * In theory, you can change all occurances of "digi" in the next
+ * In theory, you can change all occurrences of "digi" in the next
  * three lines, and the driver printk's will all automagically change.
  *
  * APR((fmt, args, ...));      Always prints message
@@ -246,7 +246,7 @@ enum {
  *
  *************************************************************************/
 
-struct board_t;
+struct dgnc_board;
 struct channel_t;
 
 /************************************************************************
@@ -259,7 +259,7 @@ struct board_ops {
        void (*uart_off) (struct channel_t *ch);
        int  (*drain) (struct tty_struct *tty, uint seconds);
        void (*param) (struct tty_struct *tty);
-       void (*vpd) (struct board_t *brd);
+       void (*vpd) (struct dgnc_board *brd);
        void (*assert_modem_signals) (struct channel_t *ch);
        void (*flush_uart_write) (struct channel_t *ch);
        void (*flush_uart_read) (struct channel_t *ch);
@@ -282,7 +282,7 @@ struct board_ops {
 /*
  *     Per-board information
  */
-struct board_t {
+struct dgnc_board {
        int             magic;          /* Board Magic number.  */
        int             boardnum;       /* Board number: 0-32 */
 
@@ -449,7 +449,7 @@ struct un_t {
  ************************************************************************/
 struct channel_t {
        int magic;                      /* Channel Magic Number         */
-       struct board_t  *ch_bd;         /* Board structure pointer      */
+       struct dgnc_board       *ch_bd;         /* Board structure pointer      */
        struct digi_t   ch_digi;        /* Transparent Print structure  */
        struct un_t     ch_tun;         /* Terminal unit info      */
        struct un_t     ch_pun;         /* Printer unit info        */
@@ -555,7 +555,7 @@ extern int          dgnc_poll_tick;         /* Poll interval - 20 ms        */
 extern int             dgnc_trcbuf_size;       /* Size of the ringbuffer       */
 extern spinlock_t      dgnc_global_lock;       /* Driver global spinlock       */
 extern uint            dgnc_NumBoards;         /* Total number of boards       */
-extern struct board_t  *dgnc_Board[MAXBOARDS]; /* Array of board structs       */
+extern struct dgnc_board       *dgnc_Board[MAXBOARDS]; /* Array of board structs       */
 extern ulong           dgnc_poll_counter;      /* Times the poller has run     */
 extern char            *dgnc_state_text[];     /* Array of state text          */
 extern char            *dgnc_driver_state_text[];/* Array of driver state text */
index 00f589a13ab9d4ad7dc0dd82a4f1ef04a406bcbf..eaec7e6a28e131eabaae19139496be79e8422ac1 100644 (file)
 #ifndef __DGNC_KCOMPAT_H
 #define __DGNC_KCOMPAT_H
 
-#include <linux/version.h>
-
-# ifndef KERNEL_VERSION
-#  define KERNEL_VERSION(a,b,c)  (((a) << 16) + ((b) << 8) + (c))
-# endif
-
-
 #if !defined(TTY_FLIPBUF_SIZE)
 # define TTY_FLIPBUF_SIZE 512
 #endif
                module_param(VAR, long, PERM); \
                MODULE_PARM_DESC(VAR, DESC);
 
-
-
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-
-
-
-/* NOTHING YET */
-
-
-
-# else
-
-
-
-# error "this driver does not support anything below the 2.6.27 kernel series."
-
-
-
-# endif
-
 #endif /* ! __DGNC_KCOMPAT_H */
index c4629d7c80b21bb72400e1074662438ce518192a..1c5ab3d007b00e126348cf0b3cace1b250b9a81f 100644 (file)
@@ -74,13 +74,13 @@ int dgnc_mgmt_open(struct inode *inode, struct file *file)
                /* Only allow 1 open at a time on mgmt device */
                if (dgnc_mgmt_in_use[minor]) {
                        DGNC_UNLOCK(dgnc_global_lock, lock_flags);
-                       return (-EBUSY);
+                       return -EBUSY;
                }
                dgnc_mgmt_in_use[minor]++;
        }
        else {
                DGNC_UNLOCK(dgnc_global_lock, lock_flags);
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DGNC_UNLOCK(dgnc_global_lock, lock_flags);
@@ -154,7 +154,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        ddi.dinfo_nboards, ddi.dinfo_version));
 
                if (copy_to_user(uarg, &ddi, sizeof (ddi)))
-                       return(-EFAULT);
+                       return -EFAULT;
 
                break;
        }
@@ -166,13 +166,13 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                struct digi_info di;
 
                if (copy_from_user(&brd, uarg, sizeof(int))) {
-                       return(-EFAULT);
+                       return -EFAULT;
                }
 
                DPR_MGMT(("DIGI_GETBD asking about board: %d\n", brd));
 
                if ((brd < 0) || (brd > dgnc_NumBoards) || (dgnc_NumBoards == 0))
-                       return (-ENODEV);
+                       return -ENODEV;
 
                memset(&di, 0, sizeof(di));
 
@@ -196,7 +196,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        di.info_bdtype, di.info_bdstate, di.info_nports, di.info_physsize));
 
                if (copy_to_user(uarg, &di, sizeof (di)))
-                       return (-EFAULT);
+                       return -EFAULT;
 
                break;
        }
@@ -209,8 +209,8 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                uint board = 0;
                uint channel = 0;
 
-               if (copy_from_user(&ni, uarg, sizeof(struct ni_info))) {
-                       return(-EFAULT);
+               if (copy_from_user(&ni, uarg, sizeof(ni))) {
+                       return -EFAULT;
                }
 
                DPR_MGMT(("DIGI_GETBD asking about board: %d channel: %d\n",
@@ -220,17 +220,17 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                channel = ni.channel;
 
                /* Verify boundaries on board */
-               if ((board < 0) || (board > dgnc_NumBoards) || (dgnc_NumBoards == 0))
-                       return (-ENODEV);
+               if ((board > dgnc_NumBoards) || (dgnc_NumBoards == 0))
+                       return -ENODEV;
 
                /* Verify boundaries on channel */
                if ((channel < 0) || (channel > dgnc_Board[board]->nasync))
-                       return (-ENODEV);
+                       return -ENODEV;
 
                ch = dgnc_Board[board]->channels[channel];
 
                if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-                       return (-ENODEV);
+                       return -ENODEV;
 
                memset(&ni, 0, sizeof(ni));
                ni.board = board;
@@ -291,7 +291,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
                if (copy_to_user(uarg, &ni, sizeof(ni)))
-                       return (-EFAULT);
+                       return -EFAULT;
 
                break;
        }
index 8b9e09a83f757efb410ac4159180b235923ae8ef..dc5a138d8d4ad6aefa947fe5c24ed3015ef04b44 100644 (file)
@@ -43,8 +43,8 @@
 #include "dgnc_tty.h"
 #include "dgnc_trace.h"
 
-static inline void neo_parse_lsr(struct board_t *brd, uint port);
-static inline void neo_parse_isr(struct board_t *brd, uint port);
+static inline void neo_parse_lsr(struct dgnc_board *brd, uint port);
+static inline void neo_parse_isr(struct dgnc_board *brd, uint port);
 static void neo_copy_data_from_uart_to_queue(struct channel_t *ch);
 static inline void neo_clear_break(struct channel_t *ch, int force);
 static inline void neo_set_cts_flow_control(struct channel_t *ch);
@@ -56,7 +56,7 @@ static inline void neo_set_no_input_flow_control(struct channel_t *ch);
 static inline void neo_set_new_start_stop_chars(struct channel_t *ch);
 static void neo_parse_modem(struct channel_t *ch, uchar signals);
 static void neo_tasklet(unsigned long data);
-static void neo_vpd(struct board_t *brd);
+static void neo_vpd(struct dgnc_board *brd);
 static void neo_uart_init(struct channel_t *ch);
 static void neo_uart_off(struct channel_t *ch);
 static int neo_drain(struct tty_struct *tty, uint seconds);
@@ -107,7 +107,7 @@ static uint dgnc_offset_table[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0
  * In this case, we are reading the DVID (Read-only Device Identification)
  * value of the Neo card.
  */
-static inline void neo_pci_posting_flush(struct board_t *bd)
+static inline void neo_pci_posting_flush(struct dgnc_board *bd)
 {
        readb(bd->re_map_membase + 0x8D);
 }
@@ -411,7 +411,7 @@ static inline void neo_clear_break(struct channel_t *ch, int force)
 /*
  * Parse the ISR register.
  */
-static inline void neo_parse_isr(struct board_t *brd, uint port)
+static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
 {
        struct channel_t *ch;
        uchar isr;
@@ -538,7 +538,7 @@ static inline void neo_parse_isr(struct board_t *brd, uint port)
 }
 
 
-static inline void neo_parse_lsr(struct board_t *brd, uint port)
+static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
 {
        struct channel_t *ch;
        int linestatus;
@@ -650,7 +650,7 @@ static void neo_param(struct tty_struct *tty)
        uchar uart_ier = 0;
        uint baud = 9600;
        int quot = 0;
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t   *un;
 
@@ -911,7 +911,7 @@ static void neo_param(struct tty_struct *tty)
  */
 static void neo_tasklet(unsigned long data)
 {
-       struct board_t *bd = (struct board_t *) data;
+       struct dgnc_board *bd = (struct dgnc_board *) data;
        struct channel_t *ch;
        ulong  lock_flags;
        int i;
@@ -994,7 +994,7 @@ static void neo_tasklet(unsigned long data)
  */
 static irqreturn_t neo_intr(int irq, void *voidbrd)
 {
-       struct board_t *brd = (struct board_t *) voidbrd;
+       struct dgnc_board *brd = (struct dgnc_board *) voidbrd;
        struct channel_t *ch;
        int port = 0;
        int type = 0;
@@ -1111,7 +1111,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
                         * Why would I check EVERY possibility of type of
                         * interrupt, when we know its TXRDY???
                         * Becuz for some reason, even tho we got triggered for TXRDY,
-                        * it seems to be occassionally wrong. Instead of TX, which
+                        * it seems to be occasionally wrong. Instead of TX, which
                         * it should be, I was getting things like RXDY too. Weird.
                         */
                        neo_parse_isr(brd, port);
@@ -1404,17 +1404,17 @@ static int neo_drain(struct tty_struct *tty, uint seconds)
        int rc = 0;
 
        if (!tty || tty->magic != TTY_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        un = (struct un_t *) tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DPR_IOCTL(("%d Drain wait started.\n", __LINE__));
@@ -1439,7 +1439,7 @@ static int neo_drain(struct tty_struct *tty, uint seconds)
                DPR_IOCTL(("%d Drain wait finished.\n", __LINE__));
        }
 
-       return (rc);
+       return rc;
 }
 
 
@@ -1939,7 +1939,7 @@ static unsigned int neo_read_eeprom(unsigned char __iomem *base, unsigned int ad
 }
 
 
-static void neo_vpd(struct board_t *brd)
+static void neo_vpd(struct dgnc_board *brd)
 {
        unsigned int i = 0;
        unsigned int a;
@@ -1965,7 +1965,7 @@ static void neo_vpd(struct board_t *brd)
        }
        else {
                /* Search for the serial number */
-               for (i = 0; i < NEO_VPD_IMAGESIZE * 2; i++) {
+               for (i = 0; i < NEO_VPD_IMAGEBYTES - 3; i++) {
                        if (brd->vpd[i] == 'S' && brd->vpd[i + 1] == 'N') {
                                strncpy(brd->serial_num, &(brd->vpd[i + 3]), 9);
                        }
index 7ec5710a4340f7ce54c462cb29df2d4929d925e3..1a4abb128693657bfc1fcfc7520f313fe18317b6 100644 (file)
@@ -47,7 +47,7 @@ struct neo_uart_struct {
        u8 fctr;                /* WR  FCTR - Feature Control Reg */
        u8 efr;         /* WR  EFR - Enhanced Function Reg */
        u8 tfifo;               /* WR  TXCNT/TXTRG - Transmit FIFO Reg */
-       u8 rfifo;               /* WR  RXCNT/RXTRG - Recieve  FIFO Reg */
+       u8 rfifo;               /* WR  RXCNT/RXTRG - Receive  FIFO Reg */
        u8 xoffchar1;   /* WR  XOFF 1 - XOff Character 1 Reg */
        u8 xoffchar2;   /* WR  XOFF 2 - XOff Character 2 Reg */
        u8 xonchar1;    /* WR  XON 1 - Xon Character 1 Reg */
index 0ea6c800280505639b2df05f554e7210f6888275..946230c234875009b07070a6ef22ca345552b74c 100644 (file)
@@ -152,19 +152,19 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
 
 #define DGNC_VERIFY_BOARD(p, bd)                       \
        if (!p)                                         \
-               return (0);                             \
+               return 0;                               \
                                                        \
        bd = dev_get_drvdata(p);                        \
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)       \
-               return (0);                             \
+               return 0;                               \
        if (bd->state != BOARD_READY)                   \
-               return (0);                             \
+               return 0;                               \
 
 
 
 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -184,7 +184,7 @@ static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
 
 static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
 
        DGNC_VERIFY_BOARD(p, bd);
@@ -201,7 +201,7 @@ static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
 
 static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -219,7 +219,7 @@ static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
 
 static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -236,7 +236,7 @@ static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
 
 static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -264,7 +264,7 @@ static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
 
 static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -281,7 +281,7 @@ static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
 
 static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -298,7 +298,7 @@ static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
 
 static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -315,7 +315,7 @@ static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
 
 static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -332,7 +332,7 @@ static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
 
 static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -349,7 +349,7 @@ static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
 
 static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -366,7 +366,7 @@ static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
 
 static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -384,7 +384,7 @@ static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
 /* this function creates the sys files that will export each signal status
  * to sysfs each value will be put in a separate filename
  */
-void dgnc_create_ports_sysfiles(struct board_t *bd)
+void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
 {
        int rc = 0;
 
@@ -408,7 +408,7 @@ void dgnc_create_ports_sysfiles(struct board_t *bd)
 
 
 /* removes all the sys files created for that port */
-void dgnc_remove_ports_sysfiles(struct board_t *bd)
+void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
 {
        device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
        device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
@@ -427,23 +427,23 @@ void dgnc_remove_ports_sysfiles(struct board_t *bd)
 
 static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
 }
@@ -452,23 +452,23 @@ static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
 
 static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
 }
@@ -477,23 +477,23 @@ static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
 
 static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        if (ch->ch_open_count) {
                return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
@@ -511,23 +511,23 @@ static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
 
 static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
 }
@@ -536,23 +536,23 @@ static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
 
 static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
 }
@@ -561,23 +561,23 @@ static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
 
 static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
 }
@@ -586,23 +586,23 @@ static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
 
 static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
 }
@@ -611,23 +611,23 @@ static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
 
 static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
 }
@@ -636,23 +636,23 @@ static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
 
 static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
 }
@@ -661,23 +661,23 @@ static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
 
 static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
 }
@@ -686,23 +686,23 @@ static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
 
 static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
                (un->un_type == DGNC_PRINT) ? "pr" : "tty",
index 4b87ce1cc7a2434c5b56124fabdba2751c1a0dd7..68c0de5898a483c6c918c7cd10d69932e56f7129 100644 (file)
 
 #include <linux/device.h>
 
-struct board_t;
+struct dgnc_board;
 struct channel_t;
 struct un_t;
 struct pci_driver;
 struct class_device;
 
-extern void dgnc_create_ports_sysfiles(struct board_t *bd);
-extern void dgnc_remove_ports_sysfiles(struct board_t *bd);
+extern void dgnc_create_ports_sysfiles(struct dgnc_board *bd);
+extern void dgnc_remove_ports_sysfiles(struct dgnc_board *bd);
 
 extern void dgnc_create_driver_sysfiles(struct pci_driver *);
 extern void dgnc_remove_driver_sysfiles(struct pci_driver *);
index a7bb6bceb9e7b738ee072c7040df97c72a0ec7d7..a6c6aba82d724d1f6a97029a39e83de385366337 100644 (file)
@@ -38,7 +38,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/sched.h>       /* For jiffies, task states */
 #include <linux/interrupt.h>   /* For tasklet and interrupt structs/defines */
 #include <linux/module.h>
 #include "dpacompat.h"
 #include "dgnc_sysfs.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
 #define init_MUTEX(sem)         sema_init(sem, 1)
 #define DECLARE_MUTEX(name)     \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
-#endif
 
 /*
  * internal variables
  */
-static struct board_t  *dgnc_BoardsByMajor[256];
+static struct dgnc_board       *dgnc_BoardsByMajor[256];
 static uchar           *dgnc_TmpWriteBuf = NULL;
 static DECLARE_MUTEX(dgnc_TmpWriteSem);
 
@@ -126,13 +123,8 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty);
 static void dgnc_tty_hangup(struct tty_struct *tty);
 static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int __user *value);
 static int dgnc_get_modem_info(struct channel_t *ch, unsigned int __user *value);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 static int dgnc_tty_tiocmget(struct tty_struct *tty);
 static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear);
-#else
-static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file);
-static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
-#endif
 static int dgnc_tty_send_break(struct tty_struct *tty, int msec);
 static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout);
 static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count);
@@ -190,10 +182,10 @@ int dgnc_tty_preinit(void)
 
        if (!dgnc_TmpWriteBuf) {
                DPR_INIT(("unable to allocate tmp write buf"));
-               return (-ENOMEM);
+               return -ENOMEM;
        }
 
-       return(0);
+       return 0;
 }
 
 
@@ -202,14 +194,14 @@ int dgnc_tty_preinit(void)
  *
  * Init the tty subsystem for this board.
  */
-int dgnc_tty_register(struct board_t *brd)
+int dgnc_tty_register(struct dgnc_board *brd)
 {
        int rc = 0;
 
        DPR_INIT(("tty_register start\n"));
 
-       memset(&brd->SerialDriver, 0, sizeof(struct tty_driver));
-       memset(&brd->PrintDriver, 0, sizeof(struct tty_driver));
+       memset(&brd->SerialDriver, 0, sizeof(brd->SerialDriver));
+       memset(&brd->PrintDriver, 0, sizeof(brd->PrintDriver));
 
        brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
 
@@ -230,25 +222,15 @@ int dgnc_tty_register(struct board_t *brd)
         * The kernel wants space to store pointers to
         * tty_struct's and termios's.
         */
-       brd->SerialDriver.ttys = kzalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
+       brd->SerialDriver.ttys = kzalloc(brd->maxports * sizeof(*brd->SerialDriver.ttys), GFP_KERNEL);
        if (!brd->SerialDriver.ttys)
-               return(-ENOMEM);
+               return -ENOMEM;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-       brd->SerialDriver.refcount = brd->TtyRefCnt;
-#else
        kref_init(&brd->SerialDriver.kref);
-#endif
-
-       brd->SerialDriver.termios = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
+       brd->SerialDriver.termios = kzalloc(brd->maxports * sizeof(*brd->SerialDriver.termios), GFP_KERNEL);
        if (!brd->SerialDriver.termios)
-               return(-ENOMEM);
+               return -ENOMEM;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
-       brd->SerialDriver.termios_locked = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
-       if (!brd->SerialDriver.termios_locked)
-               return(-ENOMEM);
-#endif
        /*
         * Entry points for driver.  Called by the kernel from
         * tty_io.c and n_tty.c.
@@ -260,14 +242,14 @@ int dgnc_tty_register(struct board_t *brd)
                rc = tty_register_driver(&brd->SerialDriver);
                if (rc < 0) {
                        APR(("Can't register tty device (%d)\n", rc));
-                       return(rc);
+                       return rc;
                }
                brd->dgnc_Major_Serial_Registered = TRUE;
        }
 
        /*
         * If we're doing transparent print, we have to do all of the above
-        * again, seperately so we don't get the LD confused about what major
+        * again, separately so we don't get the LD confused about what major
         * we are when we get into the dgnc_tty_open() routine.
         */
        brd->PrintDriver.magic = TTY_DRIVER_MAGIC;
@@ -286,28 +268,16 @@ int dgnc_tty_register(struct board_t *brd)
 
        /*
         * The kernel wants space to store pointers to
-        * tty_struct's and termios's.  Must be seperate from
+        * tty_struct's and termios's.  Must be separated from
         * the Serial Driver so we don't get confused
         */
-       brd->PrintDriver.ttys = kzalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
+       brd->PrintDriver.ttys = kzalloc(brd->maxports * sizeof(*brd->PrintDriver.ttys), GFP_KERNEL);
        if (!brd->PrintDriver.ttys)
-               return(-ENOMEM);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-       brd->PrintDriver.refcount = brd->TtyRefCnt;
-#else
+               return -ENOMEM;
        kref_init(&brd->PrintDriver.kref);
-#endif
-
-       brd->PrintDriver.termios = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
+       brd->PrintDriver.termios = kzalloc(brd->maxports * sizeof(*brd->PrintDriver.termios), GFP_KERNEL);
        if (!brd->PrintDriver.termios)
-               return(-ENOMEM);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
-       brd->PrintDriver.termios_locked = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
-       if (!brd->PrintDriver.termios_locked)
-               return(-ENOMEM);
-#endif
+               return -ENOMEM;
 
        /*
         * Entry points for driver.  Called by the kernel from
@@ -320,7 +290,7 @@ int dgnc_tty_register(struct board_t *brd)
                rc = tty_register_driver(&brd->PrintDriver);
                if (rc < 0) {
                        APR(("Can't register Transparent Print device (%d)\n", rc));
-                       return(rc);
+                       return rc;
                }
                brd->dgnc_Major_TransparentPrint_Registered = TRUE;
        }
@@ -331,7 +301,7 @@ int dgnc_tty_register(struct board_t *brd)
 
        DPR_INIT(("DGNC REGISTER TTY: MAJOR: %d\n", brd->SerialDriver.major));
 
-       return (rc);
+       return rc;
 }
 
 
@@ -341,14 +311,14 @@ int dgnc_tty_register(struct board_t *brd)
  * Init the tty subsystem.  Called once per board after board has been
  * downloaded and init'ed.
  */
-int dgnc_tty_init(struct board_t *brd)
+int dgnc_tty_init(struct dgnc_board *brd)
 {
        int i;
        void __iomem *vaddr;
        struct channel_t *ch;
 
        if (!brd)
-               return (-ENXIO);
+               return -ENXIO;
 
        DPR_INIT(("dgnc_tty_init start\n"));
 
@@ -371,7 +341,7 @@ int dgnc_tty_init(struct board_t *brd)
                         * Okay to malloc with GFP_KERNEL, we are not at
                         * interrupt context, and there are no locks held.
                         */
-                       brd->channels[i] = kzalloc(sizeof(struct channel_t), GFP_KERNEL);
+                       brd->channels[i] = kzalloc(sizeof(*brd->channels[i]), GFP_KERNEL);
                        if (!brd->channels[i]) {
                                DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n",
                                    __FILE__, __LINE__));
@@ -436,7 +406,7 @@ int dgnc_tty_init(struct board_t *brd)
 
        DPR_INIT(("dgnc_tty_init finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -460,7 +430,7 @@ void dgnc_tty_post_uninit(void)
  * Uninitialize the TTY portion of this driver.  Free all memory and
  * resources.
  */
-void dgnc_tty_uninit(struct board_t *brd)
+void dgnc_tty_uninit(struct dgnc_board *brd)
 {
        int i = 0;
 
@@ -550,7 +520,7 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int
                /*
                 *  Loop while data remains.
                 */
-               while (nbuf > 0 && ch->ch_sniff_buf != 0) {
+               while (nbuf > 0 && ch->ch_sniff_buf) {
                        /*
                         *  Determine the amount of available space left in the
                         *  buffer.  If there's none, wait until some appears.
@@ -671,7 +641,7 @@ static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
  *=======================================================================*/
 void dgnc_input(struct channel_t *ch)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct tty_struct *tp;
        struct tty_ldisc *ld;
        uint    rmask;
@@ -867,7 +837,7 @@ void dgnc_input(struct channel_t *ch)
  ************************************************************************/
 void dgnc_carrier(struct channel_t *ch)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
 
        int virt_carrier = 0;
        int phys_carrier = 0;
@@ -1158,7 +1128,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
        }
 
        if (ch->ch_tun.un_flags & UN_ISOPEN) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
                if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                        ch->ch_tun.un_tty->ldisc->ops->write_wakeup)
                {
@@ -1166,15 +1135,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
                        (ch->ch_tun.un_tty->ldisc->ops->write_wakeup)(ch->ch_tun.un_tty);
                        DGNC_LOCK(ch->ch_lock, lock_flags);
                }
-#else
-               if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                       ch->ch_tun.un_tty->ldisc.ops->write_wakeup)
-               {
-                       DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       (ch->ch_tun.un_tty->ldisc.ops->write_wakeup)(ch->ch_tun.un_tty);
-                       DGNC_LOCK(ch->ch_lock, lock_flags);
-               }
-#endif
 
                wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
 
@@ -1210,7 +1170,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
        }
 
        if (ch->ch_pun.un_flags & UN_ISOPEN) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
                if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                        ch->ch_pun.un_tty->ldisc->ops->write_wakeup)
                {
@@ -1218,15 +1177,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
                        (ch->ch_pun.un_tty->ldisc->ops->write_wakeup)(ch->ch_pun.un_tty);
                        DGNC_LOCK(ch->ch_lock, lock_flags);
                }
-#else
-               if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                       ch->ch_pun.un_tty->ldisc.ops->write_wakeup)
-               {
-                       DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       (ch->ch_pun.un_tty->ldisc.ops->write_wakeup)(ch->ch_pun.un_tty);
-                       DGNC_LOCK(ch->ch_lock, lock_flags);
-               }
-#endif
 
                wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
 
@@ -1260,7 +1210,7 @@ void dgnc_wakeup_writes(struct channel_t *ch)
  */
 static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
 {
-       struct board_t  *brd;
+       struct dgnc_board       *brd;
        struct channel_t *ch;
        struct un_t     *un;
        uint            major = 0;
@@ -1473,7 +1423,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
        DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
        DPR_OPEN(("dgnc_tty_open finished\n"));
-       return (rc);
+       return rc;
 }
 
 
@@ -1491,12 +1441,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struc
        int     sleep_on_un_flags = 0;
 
        if (!tty || tty->magic != TTY_MAGIC || !file || !ch || ch->magic != DGNC_CHANNEL_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DPR_OPEN(("dgnc_block_til_ready - before block.\n"));
@@ -1624,12 +1574,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struc
 
        if (retval) {
                DPR_OPEN(("dgnc_block_til_ready - done. error. retval: %x\n", retval));
-               return(retval);
+               return retval;
        }
 
        DPR_OPEN(("dgnc_block_til_ready - done no error. jiffies: %lu\n", jiffies));
 
-       return(0);
+       return 0;
 }
 
 
@@ -1667,7 +1617,7 @@ static void dgnc_tty_hangup(struct tty_struct *tty)
 static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
 {
        struct ktermios *ts;
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -1843,15 +1793,15 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
        ulong   lock_flags = 0;
 
        if (tty == NULL)
-               return(0);
+               return 0;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
 
@@ -1873,7 +1823,7 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
        DPR_WRITE(("dgnc_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d)\n",
                ch->ch_portnum, chars, thead, ttail));
 
-       return(chars);
+       return chars;
 }
 
 
@@ -1891,22 +1841,22 @@ static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
        struct un_t *un = NULL;
 
        if (!tty)
-               return (bytes_available);
+               return bytes_available;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (bytes_available);
+               return bytes_available;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (bytes_available);
+               return bytes_available;
 
        /*
         * If its not the Transparent print device, return
         * the full data amount.
         */
        if (un->un_type != DGNC_PRINT)
-               return (bytes_available);
+               return bytes_available;
 
        if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0 ) {
                int cps_limit = 0;
@@ -1931,7 +1881,7 @@ static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
                bytes_available = min(cps_limit, bytes_available);
        }
 
-       return (bytes_available);
+       return bytes_available;
 }
 
 
@@ -1951,15 +1901,15 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
        ulong   lock_flags = 0;
 
        if (tty == NULL || dgnc_TmpWriteBuf == NULL)
-               return(0);
+               return 0;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
 
@@ -1994,7 +1944,7 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
 
        DPR_WRITE(("dgnc_tty_write_room - %d tail: %d head: %d\n", ret, tail, head));
 
-       return(ret);
+       return ret;
 }
 
 
@@ -2037,18 +1987,18 @@ static int dgnc_tty_write(struct tty_struct *tty,
        int from_user = 0;
 
        if (tty == NULL || dgnc_TmpWriteBuf == NULL)
-               return(0);
+               return 0;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return(0);
+               return 0;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return(0);
+               return 0;
 
        if (!count)
-               return(0);
+               return 0;
 
        DPR_WRITE(("dgnc_tty_write: Port: %x tty=%p user=%d len=%d\n",
                ch->ch_portnum, tty, from_user, count));
@@ -2090,7 +2040,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
         */
        if (count <= 0) {
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        /*
@@ -2120,7 +2070,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
         */
        if (count <= 0) {
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        if (from_user) {
@@ -2136,7 +2086,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
                 */
                /* we're allowed to block if it's from_user */
                if (down_interruptible(&dgnc_TmpWriteSem)) {
-                       return (-EINTR);
+                       return -EINTR;
                }
 
                /*
@@ -2147,7 +2097,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
 
                if (!count) {
                        up(&dgnc_TmpWriteSem);
-                       return(-EFAULT);
+                       return -EFAULT;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -2229,18 +2179,15 @@ static int dgnc_tty_write(struct tty_struct *tty,
                ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch);
        }
 
-       return (count);
+       return count;
 }
 
 
 /*
  * Return modem signals to ld.
  */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+
 static int dgnc_tty_tiocmget(struct tty_struct *tty)
-#else
-static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file)
-#endif
 {
        struct channel_t *ch;
        struct un_t *un;
@@ -2293,15 +2240,11 @@ static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file)
  *
  * Set modem signals, called by ld.
  */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+
 static int dgnc_tty_tiocmset(struct tty_struct *tty,
                unsigned int set, unsigned int clear)
-#else
-static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
-               unsigned int set, unsigned int clear)
-#endif
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int ret = -EIO;
@@ -2349,7 +2292,7 @@ static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
 
        DPR_IOCTL(("dgnc_tty_tiocmset finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -2360,7 +2303,7 @@ static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
  */
 static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int ret = -EIO;
@@ -2402,7 +2345,7 @@ static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
 
        DPR_IOCTL(("dgnc_tty_send_break finish\n"));
 
-       return (0);
+       return 0;
 
 }
 
@@ -2414,7 +2357,7 @@ static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
  */
 static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int rc;
@@ -2450,7 +2393,7 @@ static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
  */
 static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong   lock_flags;
@@ -2497,7 +2440,7 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
        DPR_IOCTL(("dgnc_getmstat start\n"));
 
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return(-ENXIO);
+               return -ENXIO;
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
 
@@ -2522,7 +2465,7 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
 
        DPR_IOCTL(("dgnc_getmstat finish\n"));
 
-       return(result);
+       return result;
 }
 
 
@@ -2538,17 +2481,17 @@ static int dgnc_get_modem_info(struct channel_t *ch, unsigned int  __user *value
        DPR_IOCTL(("dgnc_get_modem_info start\n"));
 
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return(-ENXIO);
+               return -ENXIO;
 
        result = dgnc_get_mstat(ch);
 
        if (result < 0)
-               return (-ENXIO);
+               return -ENXIO;
 
        rc = put_user(result, value);
 
        DPR_IOCTL(("dgnc_get_modem_info finish\n"));
-       return(rc);
+       return rc;
 }
 
 
@@ -2559,7 +2502,7 @@ static int dgnc_get_modem_info(struct channel_t *ch, unsigned int  __user *value
  */
 static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int __user *value)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int ret = -ENXIO;
@@ -2587,7 +2530,7 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns
 
        ret = get_user(arg, value);
        if (ret)
-               return(ret);
+               return ret;
 
        switch (command) {
        case TIOCMBIS:
@@ -2631,7 +2574,7 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns
                break;
 
        default:
-               return(-EINVAL);
+               return -EINVAL;
        }
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -2642,7 +2585,7 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns
 
        DPR_IOCTL(("dgnc_set_modem_info finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -2662,18 +2605,18 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin
        ulong   lock_flags;
 
        if (!retinfo)
-               return (-EFAULT);
+               return -EFAULT;
 
        if (!tty || tty->magic != TTY_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        memset(&tmp, 0, sizeof(tmp));
 
@@ -2682,9 +2625,9 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin
        DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-               return (-EFAULT);
+               return -EFAULT;
 
-       return (0);
+       return 0;
 }
 
 
@@ -2698,7 +2641,7 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin
  */
 static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_info)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        struct digi_t new_digi;
@@ -2707,23 +2650,23 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
        DPR_IOCTL(("DIGI_SETA start\n"));
 
        if (!tty || tty->magic != TTY_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
-       if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) {
+       if (copy_from_user(&new_digi, new_info, sizeof(new_digi))) {
                DPR_IOCTL(("DIGI_SETA failed copy_from_user\n"));
-               return(-EFAULT);
+               return -EFAULT;
        }
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -2744,7 +2687,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
        if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) && !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
                ch->ch_mostat |= (UART_MCR_DTR);
 
-       memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t));
+       memcpy(&ch->ch_digi, &new_digi, sizeof(new_digi));
 
        if (ch->ch_digi.digi_maxcps < 1)
                ch->ch_digi.digi_maxcps = 1;
@@ -2773,7 +2716,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
 
        DPR_IOCTL(("DIGI_SETA finish\n"));
 
-       return(0);
+       return 0;
 }
 
 
@@ -2782,7 +2725,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
  */
 static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        unsigned long lock_flags;
@@ -2878,7 +2821,7 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty)
 
 static void dgnc_tty_start(struct tty_struct *tty)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -2912,7 +2855,7 @@ static void dgnc_tty_start(struct tty_struct *tty)
 
 static void dgnc_tty_stop(struct tty_struct *tty)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -2959,7 +2902,7 @@ static void dgnc_tty_stop(struct tty_struct *tty)
  */
 static void dgnc_tty_flush_chars(struct tty_struct *tty)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -3056,7 +2999,7 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty)
 static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                unsigned long arg)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int rc;
@@ -3064,19 +3007,19 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        void __user *uarg = (void __user *) arg;
 
        if (!tty || tty->magic != TTY_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        DPR_IOCTL(("dgnc_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n",
                ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
@@ -3086,7 +3029,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        if (un->un_open_count <= 0) {
                DPR_BASIC(("dgnc_tty_ioctl - unit not open.\n"));
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(-EIO);
+               return -EIO;
        }
 
        switch (cmd) {
@@ -3105,14 +3048,14 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = tty_check_change(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                if (rc) {
-                       return(rc);
+                       return rc;
                }
 
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
 
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3126,7 +3069,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(0);
+               return 0;
 
 
        case TCSBRKP:
@@ -3138,13 +3081,13 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = tty_check_change(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                if (rc) {
-                       return(rc);
+                       return rc;
                }
 
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3156,19 +3099,19 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(0);
+               return 0;
 
        case TIOCSBRK:
                rc = tty_check_change(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                if (rc) {
-                       return(rc);
+                       return rc;
                }
 
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3180,7 +3123,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(0);
+               return 0;
 
        case TIOCCBRK:
                /* Do Nothing */
@@ -3192,31 +3135,31 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
                rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg);
-               return(rc);
+               return rc;
 
        case TIOCSSOFTCAR:
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = get_user(arg, (unsigned long __user *) arg);
                if (rc)
-                       return(rc);
+                       return rc;
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
                tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
                ch->ch_bd->bd_ops->param(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               return(0);
+               return 0;
 
        case TIOCMGET:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_get_modem_info(ch, uarg));
+               return dgnc_get_modem_info(ch, uarg);
 
        case TIOCMBIS:
        case TIOCMBIC:
        case TIOCMSET:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_set_modem_info(tty, cmd, uarg));
+               return dgnc_set_modem_info(tty, cmd, uarg);
 
                /*
                 * Here are any additional ioctl's that we want to implement
@@ -3235,7 +3178,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = tty_check_change(tty);
                if (rc) {
                        DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       return(rc);
+                       return rc;
                }
 
                if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
@@ -3265,7 +3208,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                /* pretend we didn't recognize this IOCTL */
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
        case TCSETSF:
        case TCSETSW:
                /*
@@ -3291,14 +3234,14 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d\n", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
                /* pretend we didn't recognize this */
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
 
        case TCSETAW:
 
@@ -3306,21 +3249,21 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                /* pretend we didn't recognize this */
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
 
        case TCXONC:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                /* Make the ld do it */
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
 
        case DIGI_GETA:
                /* get information for ditty */
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_tty_digigeta(tty, uarg));
+               return dgnc_tty_digigeta(tty, uarg);
 
        case DIGI_SETAW:
        case DIGI_SETAF:
@@ -3332,7 +3275,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        rc = ch->ch_bd->bd_ops->drain(tty, 0);
                        if (rc) {
                                DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                               return(-EINTR);
+                               return -EINTR;
                        }
                        DGNC_LOCK(ch->ch_lock, lock_flags);
                }
@@ -3343,7 +3286,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
        case DIGI_SETA:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_tty_digiseta(tty, uarg));
+               return dgnc_tty_digiseta(tty, uarg);
 
        case DIGI_LOOPBACK:
                {
@@ -3352,7 +3295,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        DGNC_UNLOCK(ch->ch_lock, lock_flags);
                        rc = get_user(loopback, (unsigned int __user *) arg);
                        if (rc)
-                               return(rc);
+                               return rc;
                        DGNC_LOCK(ch->ch_lock, lock_flags);
 
                        /* Enable/disable internal loopback for this port */
@@ -3363,13 +3306,13 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                        ch->ch_bd->bd_ops->param(tty);
                        DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       return(0);
+                       return 0;
                }
 
        case DIGI_GETCUSTOMBAUD:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
-               return(rc);
+               return rc;
 
        case DIGI_SETCUSTOMBAUD:
        {
@@ -3378,12 +3321,12 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = get_user(new_rate, (unsigned int __user *) arg);
                if (rc)
-                       return(rc);
+                       return rc;
                DGNC_LOCK(ch->ch_lock, lock_flags);
                dgnc_set_custom_speed(ch, new_rate);
                ch->ch_bd->bd_ops->param(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        /*
@@ -3399,11 +3342,11 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = get_user(c, (unsigned char __user *) arg);
                if (rc)
-                       return(rc);
+                       return rc;
                DGNC_LOCK(ch->ch_lock, lock_flags);
                ch->ch_bd->bd_ops->send_immediate_char(ch, c);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        /*
@@ -3426,10 +3369,10 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               if (copy_to_user(uarg, &buf, sizeof(struct digi_getcounter))) {
-                       return (-EFAULT);
+               if (copy_to_user(uarg, &buf, sizeof(buf))) {
+                       return -EFAULT;
                }
-               return(0);
+               return 0;
        }
 
        /*
@@ -3454,7 +3397,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = put_user(events, (unsigned int __user *) arg);
-               return(rc);
+               return rc;
        }
 
        /*
@@ -3474,8 +3417,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                /*
                 * Get data from user first.
                 */
-               if (copy_from_user(&buf, uarg, sizeof(struct digi_getbuffer))) {
-                       return (-EFAULT);
+               if (copy_from_user(&buf, uarg, sizeof(buf))) {
+                       return -EFAULT;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3520,10 +3463,10 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               if (copy_to_user(uarg, &buf, sizeof(struct digi_getbuffer))) {
-                       return (-EFAULT);
+               if (copy_to_user(uarg, &buf, sizeof(buf))) {
+                       return -EFAULT;
                }
-               return(0);
+               return 0;
        }
        default:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
@@ -3532,7 +3475,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
                        dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
        }
 
        DGNC_UNLOCK(ch->ch_lock, lock_flags);
@@ -3540,5 +3483,5 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
                dgnc_ioctl_name(cmd), cmd, arg));
 
-       return(0);
+       return 0;
 }
index deb388d2f4cff0861dbad385c35f3d6ce27dc1e2..9d1c2847bd9429617a7a10ff16538c03daf45435 100644 (file)
 
 #include "dgnc_driver.h"
 
-int    dgnc_tty_register(struct board_t *brd);
+int    dgnc_tty_register(struct dgnc_board *brd);
 
 int    dgnc_tty_preinit(void);
-int     dgnc_tty_init(struct board_t *);
+int     dgnc_tty_init(struct dgnc_board *);
 
 void   dgnc_tty_post_uninit(void);
-void   dgnc_tty_uninit(struct board_t *);
+void   dgnc_tty_uninit(struct dgnc_board *);
 
 void   dgnc_input(struct channel_t *ch);
 void   dgnc_carrier(struct channel_t *ch);
index eb6e3712572763c77987e45baed1a06b1c084bf1..6a9adf6591ebcaabf480c1e63d222d2d03ea807d 100644 (file)
@@ -201,9 +201,9 @@ struct shrink_buf_struct {
        unsigned int    shrink_buf_vaddr;       /* Virtual address of board */
        unsigned int    shrink_buf_phys;        /* Physical address of board */
        unsigned int    shrink_buf_bseg;        /* Amount of board memory */
-       unsigned int    shrink_buf_hseg;        /* '186 Begining of Dual-Port */
+       unsigned int    shrink_buf_hseg;        /* '186 Beginning of Dual-Port */
 
-       unsigned int    shrink_buf_lseg;        /* '186 Begining of freed memory */
+       unsigned int    shrink_buf_lseg;        /* '186 Beginning of freed memory */
        unsigned int    shrink_buf_mseg;        /* Linear address from start of
                                                   dual-port were freed memory
                                                   begins, host viewpoint. */
index 8cee9c8bc38b1850b8bdcc3edad37e91a6996515..9a18a2c9e73b20932ecb72d7fd6469617580c7c8 100644 (file)
@@ -157,7 +157,7 @@ static ssize_t dgrp_node_state_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -174,7 +174,7 @@ static ssize_t dgrp_node_description_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -192,7 +192,7 @@ static ssize_t dgrp_node_hw_version_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -212,7 +212,7 @@ static ssize_t dgrp_node_hw_id_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -232,7 +232,7 @@ static ssize_t dgrp_node_sw_version_show(struct device *c,
        if (!c)
                return 0;
 
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -311,7 +311,7 @@ static ssize_t dgrp_tty_state_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
 
@@ -328,7 +328,7 @@ static ssize_t dgrp_tty_baud_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -348,7 +348,7 @@ static ssize_t dgrp_tty_msignals_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -377,7 +377,7 @@ static ssize_t dgrp_tty_iflag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -396,7 +396,7 @@ static ssize_t dgrp_tty_cflag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -415,7 +415,7 @@ static ssize_t dgrp_tty_oflag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -434,7 +434,7 @@ static ssize_t dgrp_tty_digi_flag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -453,7 +453,7 @@ static ssize_t dgrp_tty_rxcount_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -472,7 +472,7 @@ static ssize_t dgrp_tty_txcount_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -493,7 +493,7 @@ static ssize_t dgrp_tty_name_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
diff --git a/drivers/staging/dwc2/TODO b/drivers/staging/dwc2/TODO
new file mode 100644 (file)
index 0000000..282470d
--- /dev/null
@@ -0,0 +1,33 @@
+TODO:
+       - Dan Carpenter would like to see some cleanups to the microframe
+         scheduler code:
+         http://www.mail-archive.com/linux-usb@vger.kernel.org/msg26650.html
+
+       - Should merge the NAK holdoff patch from Raspberry Pi
+         (http://marc.info/?l=linux-usb&m=137625067103833). But as it stands
+         that patch is incomplete, it needs more investigation to see if it
+         can be made to work for non-Raspberry Pi platforms that lack the
+         special FIQ interrupt that the Pi has. Without this patch, the driver
+         has a high interrupt rate (8K/sec).
+
+       - The Raspberry Pi platform needs to have support for its FIQ interrupt
+         added, to get the same level of functionality as the downstream
+         driver. The raspberrypi.org developers have indicated they are
+         willing to help with that.
+
+       - Some of the default driver parameters (see 'struct dwc2_core_params'
+         in core.h) won't work for many platforms. So DT attributes will need
+         to be added for some of these. But that can be done as-needed as new
+         platforms are added.
+
+       - Eventually the driver should be merged with the s3c-hsotg peripheral
+         mode driver, so that both modes of operation can be supported with a
+         single driver. But I think that can wait till after the driver has
+         been moved to mainline.
+
+       - After that, OTG support can be added. I'm not sure how much demand
+         there is for that, though, so I have that as a low priority.
+
+Please send any patches for this driver to Paul Zimmerman <paulz@synopsys.com>
+and Greg Kroah-Hartman <gregkh@linuxfoundation.org>. And please CC linux-usb
+<linux-usb@vger.kernel.org> too.
index 06dae67a9d6294499ebf5926a7734bd56e1dc1ec..6d001b52f6524a564360658eee2b37c55ddaf8a6 100644 (file)
@@ -564,7 +564,7 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 
        /*
         * This bit allows dynamic reloading of the HFIR register during
-        * runtime. This bit needs to be programmed during inital configuration
+        * runtime. This bit needs to be programmed during initial configuration
         * and its value must not be changed during runtime.
         */
        if (hsotg->core_params->reload_ctl > 0) {
@@ -2205,7 +2205,7 @@ int 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;
+       u32 hs_phy_type, fs_phy_type;
 #endif
        int retval = 0;
 
@@ -2553,7 +2553,7 @@ int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
                hsotg->core_params->ahbcfg = val;
        else
                hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4 <<
-                                             GAHBCFG_HBSTLEN_SHIFT;
+                                               GAHBCFG_HBSTLEN_SHIFT;
        return 0;
 }
 
@@ -2736,6 +2736,26 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
        return 0;
 }
 
+int dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
+{
+       int retval = 0;
+
+       if (DWC2_PARAM_TEST(val, 0, 1)) {
+               if (val >= 0) {
+                       dev_err(hsotg->dev,
+                               "'%d' invalid for parameter uframe_sched\n",
+                               val);
+                       dev_err(hsotg->dev, "uframe_sched must be 0 or 1\n");
+               }
+               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.
@@ -2782,6 +2802,7 @@ int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
        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;
 }
index 9102f66d0111e8676ebd5be2ce1bc00dbdc4c8c5..fab718d9b326344860ed6af876a9a2e840893bb1 100644 (file)
@@ -188,6 +188,7 @@ enum dwc2_lx_state {
  *                      bits defined by GAHBCFG_CTRL_MASK are controlled
  *                      by the driver and are ignored in this
  *                      configuration value.
+ * @uframe_sched:       True to enable the microframe scheduler
  *
  * The following parameters may be specified when starting the module. These
  * parameters define how the DWC_otg controller should be configured. A
@@ -224,6 +225,7 @@ struct dwc2_core_params {
        int ts_dline;
        int reload_ctl;
        int ahbcfg;
+       int uframe_sched;
 };
 
 /**
@@ -292,7 +294,7 @@ struct dwc2_hw_params {
        unsigned dev_token_q_depth:5;
        unsigned max_transfer_size:26;
        unsigned max_packet_count:11;
-       unsigned host_channels:4;
+       unsigned host_channels:5;
        unsigned hs_phy_type:2;
        unsigned fs_phy_type:2;
        unsigned i2c_enable:1;
@@ -370,6 +372,7 @@ struct dwc2_hw_params {
  *                      This value is in microseconds per (micro)frame. The
  *                      assumption is that all periodic transfers may occur in
  *                      the same (micro)frame.
+ * @frame_usecs:        Internal variable used by the microframe scheduler
  * @frame_number:       Frame number read from the core at SOF. The value ranges
  *                      from 0 to HFNUM_MAX_FRNUM.
  * @periodic_qh_count:  Count of periodic QHs, if using several eps. Used for
@@ -382,6 +385,8 @@ struct dwc2_hw_params {
  *                      host channel is available for non-periodic transactions.
  * @non_periodic_channels: Number of host channels assigned to non-periodic
  *                      transfers
+ * @available_host_channels Number of host channels available for the microframe
+ *                      scheduler to use
  * @hc_ptr_array:       Array of pointers to the host channel descriptors.
  *                      Allows accessing a host channel descriptor given the
  *                      host channel number. This is useful in interrupt
@@ -436,6 +441,7 @@ struct dwc2_hsotg {
        struct list_head periodic_sched_assigned;
        struct list_head periodic_sched_queued;
        u16 periodic_usecs;
+       u16 frame_usecs[8];
        u16 frame_number;
        u16 periodic_qh_count;
 
@@ -451,6 +457,7 @@ struct dwc2_hsotg {
        struct list_head free_hc_list;
        int periodic_channels;
        int non_periodic_channels;
+       int available_host_channels;
        struct dwc2_host_chan *hc_ptr_array[MAX_EPS_CHANNELS];
        u8 *status_buf;
        dma_addr_t status_buf_dma;
index da0d35cc33ce7dd3bc79245163b27c3f51fd8bbb..3cfd2d5152c92b001ce3fba0752665612a04d2c7 100644 (file)
@@ -537,10 +537,15 @@ static void dwc2_hcd_reinit(struct dwc2_hsotg *hsotg)
        int i;
 
        hsotg->flags.d32 = 0;
-
        hsotg->non_periodic_qh_ptr = &hsotg->non_periodic_sched_active;
-       hsotg->non_periodic_channels = 0;
-       hsotg->periodic_channels = 0;
+
+       if (hsotg->core_params->uframe_sched > 0) {
+               hsotg->available_host_channels =
+                       hsotg->core_params->host_channels;
+       } else {
+               hsotg->non_periodic_channels = 0;
+               hsotg->periodic_channels = 0;
+       }
 
        /*
         * Put all channels in the free channel list and clean up channel
@@ -716,8 +721,7 @@ static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
  * @qh:    Transactions from the first QTD for this QH are selected and assigned
  *         to a free host channel
  */
-static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
-                                   struct dwc2_qh *qh)
+static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
        struct dwc2_host_chan *chan;
        struct dwc2_hcd_urb *urb;
@@ -729,18 +733,18 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
 
        if (list_empty(&qh->qtd_list)) {
                dev_dbg(hsotg->dev, "No QTDs in QH list\n");
-               return;
+               return -ENOMEM;
        }
 
        if (list_empty(&hsotg->free_hc_list)) {
                dev_dbg(hsotg->dev, "No free channel to assign\n");
-               return;
+               return -ENOMEM;
        }
 
        chan = list_first_entry(&hsotg->free_hc_list, struct dwc2_host_chan,
                                hc_list_entry);
 
-       /* Remove the host channel from the free list */
+       /* Remove host channel from free list */
        list_del_init(&chan->hc_list_entry);
 
        qtd = list_first_entry(&qh->qtd_list, struct dwc2_qtd, qtd_list_entry);
@@ -780,6 +784,10 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
        chan->data_pid_start = qh->data_toggle;
        chan->multi_count = 1;
 
+       if (urb->actual_length > urb->length &&
+               !dwc2_hcd_is_pipe_in(&urb->pipe_info))
+               urb->actual_length = urb->length;
+
        if (hsotg->core_params->dma_enable > 0) {
                chan->xfer_dma = urb->dma + urb->actual_length;
 
@@ -817,7 +825,7 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
                                      &hsotg->free_hc_list);
                        qtd->in_process = 0;
                        qh->channel = NULL;
-                       return;
+                       return -ENOMEM;
                }
        } else {
                chan->align_buf = 0;
@@ -836,6 +844,8 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
 
        dwc2_hc_init(hsotg, chan);
        chan->qh = qh;
+
+       return 0;
 }
 
 /**
@@ -864,8 +874,14 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
        while (qh_ptr != &hsotg->periodic_sched_ready) {
                if (list_empty(&hsotg->free_hc_list))
                        break;
+               if (hsotg->core_params->uframe_sched > 0) {
+                       if (hsotg->available_host_channels <= 1)
+                               break;
+                       hsotg->available_host_channels--;
+               }
                qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
-               dwc2_assign_and_init_hc(hsotg, qh);
+               if (dwc2_assign_and_init_hc(hsotg, qh))
+                       break;
 
                /*
                 * Move the QH from the periodic ready schedule to the
@@ -884,13 +900,21 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
        num_channels = hsotg->core_params->host_channels;
        qh_ptr = hsotg->non_periodic_sched_inactive.next;
        while (qh_ptr != &hsotg->non_periodic_sched_inactive) {
-               if (hsotg->non_periodic_channels >= num_channels -
+               if (hsotg->core_params->uframe_sched <= 0 &&
+                   hsotg->non_periodic_channels >= num_channels -
                                                hsotg->periodic_channels)
                        break;
                if (list_empty(&hsotg->free_hc_list))
                        break;
                qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
-               dwc2_assign_and_init_hc(hsotg, qh);
+               if (hsotg->core_params->uframe_sched > 0) {
+                       if (hsotg->available_host_channels < 1)
+                               break;
+                       hsotg->available_host_channels--;
+               }
+
+               if (dwc2_assign_and_init_hc(hsotg, qh))
+                       break;
 
                /*
                 * Move the QH from the non-periodic inactive schedule to the
@@ -905,7 +929,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
                else
                        ret_val = DWC2_TRANSACTION_ALL;
 
-               hsotg->non_periodic_channels++;
+               if (hsotg->core_params->uframe_sched <= 0)
+                       hsotg->non_periodic_channels++;
        }
 
        return ret_val;
@@ -2848,6 +2873,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
                hsotg->hc_ptr_array[i] = channel;
        }
 
+       if (hsotg->core_params->uframe_sched > 0)
+               dwc2_hcd_init_usecs(hsotg);
+
        /* Initialize hsotg start work */
        INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func);
 
index cc0a117083194c2ec7d962591e9ba41ff4a8e237..89a5484f5b740eeb30f742d4308d212c6cee2480 100644 (file)
@@ -238,6 +238,7 @@ enum dwc2_transaction_type {
  * @interval:           Interval between transfers in (micro)frames
  * @sched_frame:        (Micro)frame to initialize a periodic transfer.
  *                      The transfer executes in the following (micro)frame.
+ * @frame_usecs:        Internal variable used by the microframe scheduler
  * @start_split_frame:  (Micro)frame at which last start split was initialized
  * @ntd:                Actual number of transfer descriptors in a list
  * @dw_align_buf:       Used instead of original buffer if its physical address
@@ -271,6 +272,7 @@ struct dwc2_qh {
        u16 usecs;
        u16 interval;
        u16 sched_frame;
+       u16 frame_usecs[8];
        u16 start_split_frame;
        u16 ntd;
        u8 *dw_align_buf;
@@ -463,6 +465,7 @@ extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
 
 /* Schedule Queue Functions */
 /* Implemented in hcd_queue.c */
+extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg);
 extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
 extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
 extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
index 69070f4442a81ad9c7e77cc2b1d1eac0ed5c4bc2..c7d434519776eb4fdf42fa69a5566639dc6a7e06 100644 (file)
@@ -271,10 +271,14 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
 {
        struct dwc2_host_chan *chan = qh->channel;
 
-       if (dwc2_qh_is_non_per(qh))
-               hsotg->non_periodic_channels--;
-       else
+       if (dwc2_qh_is_non_per(qh)) {
+               if (hsotg->core_params->uframe_sched > 0)
+                       hsotg->available_host_channels++;
+               else
+                       hsotg->non_periodic_channels--;
+       } else {
                dwc2_update_frame_list(hsotg, qh, 0);
+       }
 
        /*
         * The condition is added to prevent double cleanup try in case of
@@ -370,7 +374,8 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 
        if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC ||
             qh->ep_type == USB_ENDPOINT_XFER_INT) &&
-           !hsotg->periodic_channels && hsotg->frame_list) {
+           (hsotg->core_params->uframe_sched > 0 ||
+            !hsotg->periodic_channels) && hsotg->frame_list) {
                dwc2_per_sched_disable(hsotg);
                dwc2_frame_list_free(hsotg);
        }
index e143f69939f526dd5b8b3115f71aab2e7e9e92bd..dda18540f5a7f306b3b003cd9b47f7e0b7c87c05 100644 (file)
@@ -748,18 +748,23 @@ cleanup:
        dwc2_hc_cleanup(hsotg, chan);
        list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
 
-       switch (chan->ep_type) {
-       case USB_ENDPOINT_XFER_CONTROL:
-       case USB_ENDPOINT_XFER_BULK:
-               hsotg->non_periodic_channels--;
-               break;
-       default:
-               /*
-                * Don't release reservations for periodic channels here.
-                * That's done when a periodic transfer is descheduled (i.e.
-                * when the QH is removed from the periodic schedule).
-                */
-               break;
+       if (hsotg->core_params->uframe_sched > 0) {
+               hsotg->available_host_channels++;
+       } else {
+               switch (chan->ep_type) {
+               case USB_ENDPOINT_XFER_CONTROL:
+               case USB_ENDPOINT_XFER_BULK:
+                       hsotg->non_periodic_channels--;
+                       break;
+               default:
+                       /*
+                        * Don't release reservations for periodic channels
+                        * here. That's done when a periodic transfer is
+                        * descheduled (i.e. when the QH is removed from the
+                        * periodic schedule).
+                        */
+                       break;
+               }
        }
 
        haintmsk = readl(hsotg->regs + HAINTMSK);
@@ -1927,23 +1932,22 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 
        chan = hsotg->hc_ptr_array[chnum];
 
-       if (dbg_hc(chan))
-               dev_vdbg(hsotg->dev, "--Host Channel Interrupt--, Channel %d\n",
-                        chnum);
-
        hcint = readl(hsotg->regs + HCINT(chnum));
        hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
-       if (dbg_hc(chan))
-               dev_vdbg(hsotg->dev,
-                        "  hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
-                        hcint, hcintmsk, hcint & hcintmsk);
-
        if (!chan) {
                dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n");
                writel(hcint, hsotg->regs + HCINT(chnum));
                return;
        }
 
+       if (dbg_hc(chan)) {
+               dev_vdbg(hsotg->dev, "--Host Channel Interrupt--, Channel %d\n",
+                        chnum);
+               dev_vdbg(hsotg->dev,
+                        "  hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
+                        hcint, hcintmsk, hcint & hcintmsk);
+       }
+
        writel(hcint, hsotg->regs + HCINT(chnum));
        chan->hcint = hcint;
        hcint &= hcintmsk;
index b1980ef28fa30ce2581e7a3516a4e5ee807e5a8d..f200f1f6e1c67ddf3d151552e3aeed0088b5b8f8 100644 (file)
@@ -251,12 +251,12 @@ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
  *
  * @hsotg: The HCD state structure for the DWC OTG controller
  *
- * Return: 0 if successful, negative error code otherise
+ * Return: 0 if successful, negative error code otherwise
  */
 static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg)
 {
        /*
-        * Currently assuming that there is a dedicated host channnel for
+        * Currently assuming that there is a dedicated host channel for
         * each periodic transaction plus at least one host channel for
         * non-periodic transactions
         */
@@ -323,6 +323,146 @@ static int dwc2_check_periodic_bandwidth(struct dwc2_hsotg *hsotg,
        return status;
 }
 
+/**
+ * Microframe scheduler
+ * track the total use in hsotg->frame_usecs
+ * keep each qh use in qh->frame_usecs
+ * when surrendering the qh then donate the time back
+ */
+static const unsigned short max_uframe_usecs[] = {
+       100, 100, 100, 100, 100, 100, 30, 0
+};
+
+void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg)
+{
+       int i;
+
+       for (i = 0; i < 8; i++)
+               hsotg->frame_usecs[i] = max_uframe_usecs[i];
+}
+
+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;
+
+       while (!done) {
+               /* 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 ret;
+}
+
+/*
+ * use this for FS apps that can span multiple uframes
+ */
+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 j;
+       int ret = -1;
+
+       while (!done) {
+               if (hsotg->frame_usecs[i] <= 0) {
+                       i++;
+                       if (i == 8) {
+                               ret = -1;
+                               done = 1;
+                       }
+                       continue;
+               }
+
+               /*
+                * we need n consecutive slots so use j as a start slot
+                * j plus j+1 must be enough time (for now)
+                */
+               xtime = hsotg->frame_usecs[i];
+               for (j = i + 1; j < 8; j++) {
+                       /*
+                        * if we add this frame remaining time to xtime we may
+                        * be OK, if not we need to test j for a complete frame
+                        */
+                       if (xtime + hsotg->frame_usecs[j] < utime) {
+                               if (hsotg->frame_usecs[j] <
+                                                       max_uframe_usecs[j]) {
+                                       ret = -1;
+                                       break;
+                               }
+                       }
+                       if (xtime >= utime) {
+                               ret = i;
+                               break;
+                       }
+                       /* 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;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static int dwc2_find_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
+{
+       int ret;
+
+       if (qh->dev_speed == USB_SPEED_HIGH) {
+               /* if this is a hs transaction we need a full frame */
+               ret = dwc2_find_single_uframe(hsotg, qh);
+       } else {
+               /*
+                * if this is a fs transaction we may need a sequence
+                * of frames
+                */
+               ret = dwc2_find_multi_uframe(hsotg, qh);
+       }
+       return ret;
+}
+
 /**
  * dwc2_check_max_xfer_size() - Checks that the max transfer size allowed in a
  * host channel is large enough to handle the maximum data transfer in a single
@@ -367,15 +507,35 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
        int status;
 
-       status = dwc2_periodic_channel_available(hsotg);
-       if (status) {
-               dev_dbg(hsotg->dev,
-                       "%s: No host channel available for periodic transfer\n",
-                       __func__);
-               return status;
+       if (hsotg->core_params->uframe_sched > 0) {
+               int frame = -1;
+
+               status = dwc2_find_uframe(hsotg, qh);
+               if (status == 0)
+                       frame = 7;
+               else if (status > 0)
+                       frame = status - 1;
+
+               /* Set the new frame up */
+               if (frame > -1) {
+                       qh->sched_frame &= ~0x7;
+                       qh->sched_frame |= (frame & 7);
+               }
+
+               if (status != -1)
+                       status = 0;
+       } else {
+               status = dwc2_periodic_channel_available(hsotg);
+               if (status) {
+                       dev_info(hsotg->dev,
+                                "%s: No host channel available for periodic transfer\n",
+                                __func__);
+                       return status;
+               }
+
+               status = dwc2_check_periodic_bandwidth(hsotg, qh);
        }
 
-       status = dwc2_check_periodic_bandwidth(hsotg, qh);
        if (status) {
                dev_dbg(hsotg->dev,
                        "%s: Insufficient periodic bandwidth for periodic transfer\n",
@@ -399,8 +559,9 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
                list_add_tail(&qh->qh_list_entry,
                              &hsotg->periodic_sched_inactive);
 
-       /* Reserve periodic channel */
-       hsotg->periodic_channels++;
+       if (hsotg->core_params->uframe_sched <= 0)
+               /* Reserve periodic channel */
+               hsotg->periodic_channels++;
 
        /* Update claimed usecs per (micro)frame */
        hsotg->periodic_usecs += qh->usecs;
@@ -418,13 +579,22 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg,
                                     struct dwc2_qh *qh)
 {
-       list_del_init(&qh->qh_list_entry);
+       int i;
 
-       /* Release periodic channel reservation */
-       hsotg->periodic_channels--;
+       list_del_init(&qh->qh_list_entry);
 
        /* Update claimed usecs per (micro)frame */
        hsotg->periodic_usecs -= qh->usecs;
+
+       if (hsotg->core_params->uframe_sched > 0) {
+               for (i = 0; i < 8; i++) {
+                       hsotg->frame_usecs[i] += qh->frame_usecs[i];
+                       qh->frame_usecs[i] = 0;
+               }
+       } else {
+               /* Release periodic channel reservation */
+               hsotg->periodic_channels--;
+       }
 }
 
 /**
@@ -581,7 +751,10 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
                         * Remove from periodic_sched_queued and move to
                         * appropriate queue
                         */
-                       if (qh->sched_frame == frame_number)
+                       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
index 9020260d5df8f96b53ff1697f6b0f568341be3bd..3d14c8870fcac75f6f1e6af1ef315b49c23778a7 100644 (file)
@@ -84,6 +84,7 @@ static const struct dwc2_core_params dwc2_module_params = {
        .ts_dline                       = -1,
        .reload_ctl                     = -1,
        .ahbcfg                         = -1,
+       .uframe_sched                   = -1,
 };
 
 /**
index 44cce2fa6361194a36ac72dff5825575fd324bf5..76ae6e210f55ea2709d8a3a46a1d01e231461e38 100644 (file)
@@ -106,7 +106,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
        irq = platform_get_irq(dev, 0);
        if (irq < 0) {
                dev_err(&dev->dev, "missing IRQ resource\n");
-               return -EINVAL;
+               return irq;
        }
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
diff --git a/drivers/staging/et131x/Module.symvers b/drivers/staging/et131x/Module.symvers
new file mode 100644 (file)
index 0000000..e69de29
index 9272a24ae61c8250ba770acf8f85e69c610d0f99..8da96a6d2c927946d0c1444fca0472904af7b21b 100644 (file)
@@ -11,7 +11,12 @@ TODO:
        - Look at reducing the number of spinlocks
        - Simplify code in nic_rx_pkts(), when determining multicast_pkts_rcvd
        - Implement NAPI support
-       - in et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with          kfree_skb().
+       - In et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with kfree_skb().
+       - Reduce the number of split lines by careful consideration of variable names etc.
+       - Do this in et131x.c:
+                struct fbr_lookup *fbr;
+                fbr = rx_local->fbr[id];
+         Then replace all the instances of "rx_local->fbr[id]" with fbr.
 
 Please send patches to:
        Greg Kroah-Hartman <gregkh@linuxfoundation.org>
index f73e58f5ef8d0390f8b4068db2030d9d1b42592c..d9446c47bf2eb85a0417f888e8766e4cd8124b92 100644 (file)
@@ -493,11 +493,8 @@ struct et131x_adapter {
        spinlock_t send_hw_lock;
 
        spinlock_t rcv_lock;
-       spinlock_t rcv_pend_lock;
        spinlock_t fbr_lock;
 
-       spinlock_t phy_lock;
-
        /* Packet Filter and look ahead size */
        u32 packet_filter;
 
@@ -2777,10 +2774,9 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
                adapter->net_stats.rx_packets++;
 
                /* Set the status on the packet, either resources or success */
-               if (adapter->rx_ring.num_ready_recv < RFD_LOW_WATER_MARK) {
-                       dev_warn(&adapter->pdev->dev,
-                                   "RFD's are running out\n");
-               }
+               if (adapter->rx_ring.num_ready_recv < RFD_LOW_WATER_MARK)
+                       dev_warn(&adapter->pdev->dev, "RFD's are running out\n");
+
                count++;
        }
 
@@ -2906,8 +2902,9 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
         * number of fragments. If needed, we can call this function,
         * although it is less efficient.
         */
-       if (nr_frags > 23)
-               return -EIO;
+
+       /* nr_frags should be no more than 18. */
+       BUILD_BUG_ON(MAX_SKB_FRAGS + 1 > 23);
 
        memset(desc, 0, sizeof(struct tx_desc) * (nr_frags + 1));
 
@@ -3100,11 +3097,10 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter)
                shbufva = (u16 *) skb->data;
 
                if ((shbufva[0] == 0xffff) &&
-                   (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) {
+                   (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff))
                        tcb->flags |= FMP_DEST_BROAD;
-               } else if ((shbufva[0] & 0x3) == 0x0001) {
+               else if ((shbufva[0] & 0x3) == 0x0001)
                        tcb->flags |=  FMP_DEST_MULTI;
-               }
        }
 
        tcb->next = NULL;
@@ -3926,9 +3922,7 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev,
        spin_lock_init(&adapter->tcb_ready_qlock);
        spin_lock_init(&adapter->send_hw_lock);
        spin_lock_init(&adapter->rcv_lock);
-       spin_lock_init(&adapter->rcv_pend_lock);
        spin_lock_init(&adapter->fbr_lock);
-       spin_lock_init(&adapter->phy_lock);
 
        adapter->registry_jumbo_packet = 1514;  /* 1514-9216 */
 
index 1fc4ac12e247a71e310e2ebf30dbf78a34a697c6..9dce54eae1cf5b9d6f2897f9e678643cf3952ecc 100644 (file)
@@ -27,7 +27,7 @@
 #define _BOOTH_
 
 // Official bootloader
-unsigned char bootimage [] = {
+static unsigned char bootimage [] = {
 0x00,0x00,0x01,0x5E,0x00,0x00
 ,0x00,0x00,0x00,0x00,0x02,0xD7
 ,0x00,0x00,0x01,0x5E,0x46,0xB3
index 6311b2ff58161e0433e7ff1065c9b63bd1ca533f..d44e8583ad1eb71627d9f8c60a357784a3d3e122 100644 (file)
@@ -304,7 +304,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart,
        struct dsp_file_hdr *pFileHdr5;
        struct dsp_image_info *pDspImageInfoV6 = NULL;
        long requested_version;
-       bool bGoodVersion = 0;
+       bool bGoodVersion = false;
        struct drv_msg *pMailBoxData;
        u16 *pUsData = NULL;
        u16 *pUsFile = NULL;
index b2330f1df7e7066ab15aae5707a79f6fc7b32b2e..88f6f9ce304a57ad2c433e642c4d04e313b505bb 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])
index 5190c8ac4e0a77cbb03e4f5b4d14c4dd764469a0..68ded17c0f5c7f9302613d37ed48238f9f54422b 100644 (file)
@@ -1,12 +1,8 @@
-//=====================================================
-// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
-//
-//
-// This file is part of Express Card USB Driver
-//
-// $Id:
-//====================================================
-// 20090926; aelias; removed compiler warnings; ubuntu 9.04; 2.6.28-15-generic
+/*
+* 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>
@@ -111,23 +107,12 @@ struct dsp_image_info {
 };
 
 
-//---------------------------------------------------------------------------
-// Function:    check_usb_db
-//
-// Parameters:  struct ft1000_usb  - device structure
-//
-// Returns:     0 - success
-//
-// Description: This function checks if the doorbell register is cleared
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static u32 check_usb_db (struct ft1000_usb *ft1000dev)
+/* checks if the doorbell register is cleared */
+static int check_usb_db(struct ft1000_usb *ft1000dev)
 {
        int loopcnt;
        u16 temp;
-       u32 status;
+       int status;
 
        loopcnt = 0;
 
@@ -169,25 +154,12 @@ static u32 check_usb_db (struct ft1000_usb *ft1000dev)
        return HANDSHAKE_MAG_TIMEOUT_VALUE;
 }
 
-//---------------------------------------------------------------------------
-// Function:    get_handshake
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 expected_value - the handshake value expected
-//
-// Returns:     handshakevalue - success
-//              HANDSHAKE_TIMEOUT_VALUE - failure
-//
-// Description: This function gets the handshake and compare with the expected value
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* gets the handshake and compares it with the expected value */
 static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
 {
        u16 handshake;
        int loopcnt;
-       u32 status = 0;
+       int status = 0;
 
        loopcnt = 0;
 
@@ -229,25 +201,12 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
        return HANDSHAKE_TIMEOUT_VALUE;
 }
 
-//---------------------------------------------------------------------------
-// Function:    put_handshake
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 handshake_value - handshake to be written
-//
-// Returns:     none
-//
-// Description: This function write the handshake value to the handshake location
-//              in DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* write the handshake value to the handshake location */
 static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value)
 {
        u32 tempx;
        u16 tempword;
-       u32 status;
+       int status;
 
        tempx = (u32)handshake_value;
        tempx = ntohl(tempx);
@@ -267,7 +226,7 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value)
        u16 handshake;
        int loopcnt;
        u16 temp;
-       u32 status = 0;
+       int status = 0;
 
        loopcnt = 0;
        handshake = 0;
@@ -316,22 +275,10 @@ static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value)
         for (i=0; i<1000; i++);
 }
 
-//---------------------------------------------------------------------------
-// Function:    get_request_type
-//
-// Parameters:  struct ft1000_usb  - device structure
-//
-// Returns:     request type - success
-//
-// Description: This function returns the request type
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
 static u16 get_request_type(struct ft1000_usb *ft1000dev)
 {
        u16 request_type;
-       u32 status;
+       int status;
        u16 tempword;
        u32 tempx;
 
@@ -354,7 +301,7 @@ static u16 get_request_type(struct ft1000_usb *ft1000dev)
 static u16 get_request_type_usb(struct ft1000_usb *ft1000dev)
 {
        u16 request_type;
-       u32 status;
+       int status;
        u16 tempword;
        u32 tempx;
 
@@ -380,23 +327,11 @@ static u16 get_request_type_usb(struct ft1000_usb *ft1000dev)
        return request_type;
 }
 
-//---------------------------------------------------------------------------
-// Function:    get_request_value
-//
-// Parameters:  struct ft1000_usb  - device structure
-//
-// Returns:     request value - success
-//
-// Description: This function returns the request value
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
 static long get_request_value(struct ft1000_usb *ft1000dev)
 {
        u32 value;
        u16 tempword;
-       u32 status;
+       int status;
 
        if (ft1000dev->bootmode == 1) {
                status = fix_ft1000_read_dpram32(ft1000dev,
@@ -416,23 +351,11 @@ static long get_request_value(struct ft1000_usb *ft1000dev)
 }
 
 
-//---------------------------------------------------------------------------
-// Function:    put_request_value
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
-//
-// Returns:     none
-//
-// Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* writes a value to DWNLD_MAG1_SIZE_LOC */
 static void put_request_value(struct ft1000_usb *ft1000dev, long lvalue)
 {
        u32    tempx;
-       u32    status;
+       int    status;
 
        tempx = ntohl(lvalue);
        status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC,
@@ -441,18 +364,7 @@ static void put_request_value(struct ft1000_usb *ft1000dev, long lvalue)
 
 
 
-//---------------------------------------------------------------------------
-// Function:    hdr_checksum
-//
-// Parameters:  struct pseudo_hdr *pHdr - Pseudo header pointer
-//
-// Returns:     checksum - success
-//
-// Description: This function returns the checksum of the pseudo header
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* returns the checksum of the pseudo header */
 static u16 hdr_checksum(struct pseudo_hdr *pHdr)
 {
        u16   *usPtr = (u16 *)pHdr;
@@ -471,144 +383,130 @@ static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset)
 
        for (i = 0; i < len; i++) {
                if (buff_w[i] != buff_r[i + offset])
-                       return -1;
+                       return -EREMOTEIO;
        }
 
        return 0;
 }
 
-//---------------------------------------------------------------------------
-// Function:    write_blk
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 **pUsFile - DSP image file pointer in u16
-//              u8  **pUcFile - DSP image file pointer in u8
-//              long   word_length - length of the buffer to be written
-//                                   to DPRAM
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes a block of DSP image to DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static u32 write_blk (struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length)
+static int write_dpram32_and_check(struct ft1000_usb *ft1000dev,
+               u16 tempbuffer[], u16 dpram)
 {
-   u32 Status = STATUS_SUCCESS;
-   u16 dpram;
-   int loopcnt, i, j;
-   u16 tempword;
-   u16 tempbuffer[64];
-   u16 resultbuffer[64];
-
-   //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
-   dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
-   tempword = *(*pUsFile);
-   (*pUsFile)++;
-   Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
-   tempword = *(*pUsFile);
-   (*pUsFile)++;
-   Status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
-
-   *pUcFile = *pUcFile + 4;
-   word_length--;
-   tempword = (u16)word_length;
-   word_length = (word_length / 16) + 1;
-   for (; word_length > 0; word_length--) /* In words */
-   {
-          loopcnt = 0;
-
-             for (i=0; i<32; i++)
-             {
-                      if (tempword != 0)
-                      {
-                          tempbuffer[i++] = *(*pUsFile);
-                          (*pUsFile)++;
-                          tempbuffer[i] = *(*pUsFile);
-                          (*pUsFile)++;
-                          *pUcFile = *pUcFile + 4;
-                          loopcnt++;
-                          tempword--;
-                      }
-                      else
-                      {
-                          tempbuffer[i++] = 0;
-                          tempbuffer[i] = 0;
-                       }
-             }
-
-              //DEBUG("write_blk: loopcnt is %d\n", loopcnt);
-              //DEBUG("write_blk: bootmode = %d\n", bootmode);
-              //DEBUG("write_blk: dpram = %x\n", dpram);
-             if (ft1000dev->bootmode == 0)
-             {
-                if (dpram >= 0x3F4)
-                     Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 8);
-                else
-                    Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64);
-             }
-             else
-             {
-                 for (j=0; j<10; j++)
-                 {
-                   Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64);
-                  if (Status == STATUS_SUCCESS)
-                  {
-                      // Work around for ASIC bit stuffing problem.
-                      if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
-                      {
-                          Status = ft1000_write_dpram32(ft1000dev, dpram+12, (u8 *)&tempbuffer[24], 64);
-                      }
-                      // Let's check the data written
-                      Status = ft1000_read_dpram32 (ft1000dev, dpram, (u8 *)&resultbuffer[0], 64);
-                      if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
-                      {
-                               if (check_buffers(tempbuffer, resultbuffer, 28, 0)) {
+       int status;
+       u16 resultbuffer[64];
+       int i;
+
+       for (i = 0; i < 10; i++) {
+               status = ft1000_write_dpram32(ft1000dev, dpram,
+                               (u8 *)&tempbuffer[0], 64);
+               if (status == 0) {
+                       /* Work around for ASIC bit stuffing problem. */
+                       if ((tempbuffer[31] & 0xfe00) == 0xfe00) {
+                               status = ft1000_write_dpram32(ft1000dev,
+                                               dpram+12, (u8 *)&tempbuffer[24],
+                                               64);
+                       }
+                       /* Let's check the data written */
+                       status = ft1000_read_dpram32(ft1000dev, dpram,
+                                       (u8 *)&resultbuffer[0], 64);
+                       if ((tempbuffer[31] & 0xfe00) == 0xfe00) {
+                               if (check_buffers(tempbuffer, resultbuffer, 28,
+                                                       0)) {
                                        DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
-                                       msleep(10);
-                                       Status = STATUS_FAILURE;
+                                       usleep_range(9000, 11000);
                                        break;
                                }
-                          Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (u8 *)&resultbuffer[0], 64);
+                               status = ft1000_read_dpram32(ft1000dev,
+                                               dpram+12,
+                                               (u8 *)&resultbuffer[0], 64);
 
-                               if (check_buffers(tempbuffer, resultbuffer, 16, 24)) {
+                               if (check_buffers(tempbuffer, resultbuffer, 16,
+                                                       24)) {
                                        DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
-                                       msleep(10);
-                                       Status = STATUS_FAILURE;
+                                       usleep_range(9000, 11000);
                                        break;
                                }
-                          
-                       }
-                       else
-                       {
-                               if (check_buffers(tempbuffer, resultbuffer, 32, 0)) {
+                       } else {
+                               if (check_buffers(tempbuffer, resultbuffer, 32,
+                                                       0)) {
                                        DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
-                                       msleep(10);
-                                       Status = STATUS_FAILURE;
+                                       usleep_range(9000, 11000);
                                        break;
                                }
-                           
                        }
-
-                       if (Status == STATUS_SUCCESS)
-                           break;
-
-                   }
+                       if (status == 0)
+                               break;
                }
+       }
+       return status;
+}
 
-               if (Status != STATUS_SUCCESS)
-               {
-                    DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
-                   break;
+/* writes a block of DSP image to DPRAM
+ * Parameters:  struct ft1000_usb  - device structure
+ *              u16 **pUsFile - DSP image file pointer in u16
+ *              u8  **pUcFile - DSP image file pointer in u8
+ *              long word_length - length of the buffer to be written to DPRAM
+ */
+static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile,
+               long word_length)
+{
+       int status = STATUS_SUCCESS;
+       u16 dpram;
+       int loopcnt, i;
+       u16 tempword;
+       u16 tempbuffer[64];
+
+       /*DEBUG("FT1000:download:start word_length = %d\n",(int)word_length); */
+       dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
+       tempword = *(*pUsFile);
+       (*pUsFile)++;
+       status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
+       tempword = *(*pUsFile);
+       (*pUsFile)++;
+       status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
+
+       *pUcFile = *pUcFile + 4;
+       word_length--;
+       tempword = (u16)word_length;
+       word_length = (word_length / 16) + 1;
+       for (; word_length > 0; word_length--) { /* In words */
+               loopcnt = 0;
+               for (i = 0; i < 32; i++) {
+                       if (tempword != 0) {
+                               tempbuffer[i++] = *(*pUsFile);
+                               (*pUsFile)++;
+                               tempbuffer[i] = *(*pUsFile);
+                               (*pUsFile)++;
+                               *pUcFile = *pUcFile + 4;
+                               loopcnt++;
+                               tempword--;
+                       } else {
+                               tempbuffer[i++] = 0;
+                               tempbuffer[i] = 0;
+                       }
                }
 
-            }
-            dpram = dpram + loopcnt;
-   }
-
-   return Status;
+               /*DEBUG("write_blk: loopcnt is %d\n", loopcnt); */
+               /*DEBUG("write_blk: bootmode = %d\n", bootmode); */
+               /*DEBUG("write_blk: dpram = %x\n", dpram); */
+               if (ft1000dev->bootmode == 0) {
+                       if (dpram >= 0x3F4)
+                               status = ft1000_write_dpram32(ft1000dev, dpram,
+                                               (u8 *)&tempbuffer[0], 8);
+                       else
+                               status = ft1000_write_dpram32(ft1000dev, dpram,
+                                               (u8 *)&tempbuffer[0], 64);
+               } else {
+                       status = write_dpram32_and_check(ft1000dev, tempbuffer,
+                                       dpram);
+                       if (status != STATUS_SUCCESS) {
+                               DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
+                               break;
+                       }
+               }
+               dpram = dpram + loopcnt;
+       }
+       return status;
 }
 
 static void usb_dnld_complete (struct urb *urb)
@@ -616,27 +514,16 @@ static void usb_dnld_complete (struct urb *urb)
     //DEBUG("****** usb_dnld_complete\n");
 }
 
-//---------------------------------------------------------------------------
-// Function:    write_blk_fifo
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 **pUsFile - DSP image file pointer in u16
-//              u8  **pUcFile - DSP image file pointer in u8
-//              long   word_length - length of the buffer to be written
-//                                   to DPRAM
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes a block of DSP image to DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static u32 write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
+/* writes a block of DSP image to DPRAM
+ * Parameters:  struct ft1000_usb  - device structure
+ *              u16 **pUsFile - DSP image file pointer in u16
+ *              u8  **pUcFile - DSP image file pointer in u8
+ *              long word_length - length of the buffer to be written to DPRAM
+ */
+static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
                          u8 **pUcFile, long word_length)
 {
-       u32 Status = STATUS_SUCCESS;
+       int Status = STATUS_SUCCESS;
        int byte_length;
 
        byte_length = word_length * 4;
@@ -664,22 +551,71 @@ static u32 write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
        return Status;
 }
 
-//---------------------------------------------------------------------------
-//
-//  Function:   scram_dnldr
-//
-//  Synopsis:   Scramble downloader for Harley based ASIC via USB interface
-//
-//  Arguments:  pFileStart              - pointer to start of file
-//              FileLength              - file length
-//
-//  Returns:    status                  - return code
-//---------------------------------------------------------------------------
-
-u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
+static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake,
+               u32 *state)
+{
+       int status = 0;
+
+       DEBUG("FT1000:STATE_START_DWNLD\n");
+       if (ft1000dev->usbboot)
+               *hshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY);
+       else
+               *hshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY);
+       if (*hshake == HANDSHAKE_DSP_BL_READY) {
+               DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
+               put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY);
+       } else if (*hshake == HANDSHAKE_TIMEOUT_VALUE) {
+               status = -ETIMEDOUT;
+       } else {
+               DEBUG("FT1000:download:Download error: Handshake failed\n");
+               status = -ENETRESET;
+       }
+       *state = STATE_BOOT_DWNLD;
+       return status;
+}
+
+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;
+
+       /*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/
+       word_length = get_request_value(ft1000dev);
+       /*DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); */
+       /*NdisMSleep (100); */
+       if (word_length > MAX_LENGTH) {
+               DEBUG("FT1000:download:Download error: Max length exceeded\n");
+               return STATUS_FAILURE;
+       }
+       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;
+       }
+       if (word_length & 0x1)
+               word_length++;
+       word_length = word_length / 2;
+
+       if (boot_case) {
+               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);
+               if (ft1000dev->usbboot == 0)
+                       ft1000dev->usbboot++;
+               if (ft1000dev->usbboot == 1)
+                       ft1000_write_dpram16(ft1000dev,
+                                       DWNLD_MAG1_PS_HDR_LOC, 0, 0);
+       }
+       return status;
+}
+
+/* Scramble downloader for Harley based ASIC via USB interface */
+int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                u32 FileLength)
 {
-       u16 status = STATUS_SUCCESS;
+       int status = STATUS_SUCCESS;
        u32 state;
        u16 handshake;
        struct pseudo_hdr *pseudo_header;
@@ -687,7 +623,6 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
        long word_length;
        u16 request;
        u16 temp;
-       u16 tempword;
 
        struct dsp_file_hdr *file_hdr;
        struct dsp_image_info *dsp_img_info = NULL;
@@ -733,34 +668,13 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
 
        loader_code_address = file_hdr->loader_code_address;
        loader_code_size = file_hdr->loader_code_size;
-       correct_version = FALSE;
+       correct_version = false;
 
        while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) {
                switch (state) {
                case STATE_START_DWNLD:
-                       DEBUG("FT1000:STATE_START_DWNLD\n");
-                       if (ft1000dev->usbboot)
-                               handshake =
-                                   get_handshake_usb(ft1000dev,
-                                                     HANDSHAKE_DSP_BL_READY);
-                       else
-                               handshake =
-                                   get_handshake(ft1000dev,
-                                                 HANDSHAKE_DSP_BL_READY);
-
-                       if (handshake == HANDSHAKE_DSP_BL_READY) {
-                               DEBUG
-                                   ("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
-                               put_handshake(ft1000dev,
-                                             HANDSHAKE_DRIVER_READY);
-                       } else {
-                               DEBUG
-                                   ("FT1000:download:Download error: Handshake failed\n");
-                               status = STATUS_FAILURE;
-                       }
-
-                       state = STATE_BOOT_DWNLD;
-
+                       status = scram_start_dwnld(ft1000dev, &handshake,
+                                                  &state);
                        break;
 
                case STATE_BOOT_DWNLD:
@@ -794,41 +708,11 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                        ft1000dev->fcodeldr = 1;
                                        break;
                                case REQUEST_CODE_SEGMENT:
-                                       //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
-                                       word_length =
-                                           get_request_value(ft1000dev);
-                                       //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
-                                       //NdisMSleep (100);
-                                       if (word_length > MAX_LENGTH) {
-                                               DEBUG
-                                                   ("FT1000:download:Download error: Max length exceeded\n");
-                                               status = STATUS_FAILURE;
-                                               break;
-                                       }
-                                       if ((word_length * 2 + c_file) >
-                                           boot_end) {
-                                               /*
-                                                * Error, beyond boot code range.
-                                                */
-                                               DEBUG
-                                                   ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n",
-                                                    (int)word_length);
-                                               status = STATUS_FAILURE;
-                                               break;
-                                       }
-                                       /*
-                                        * Position ASIC DPRAM auto-increment pointer.
-                                        */
-                                       dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
-                                       if (word_length & 0x1)
-                                               word_length++;
-                                       word_length = word_length / 2;
-
-                                       status =
-                                           write_blk(ft1000dev, &s_file,
-                                                     &c_file, word_length);
-                                       //DEBUG("write_blk returned %d\n", status);
-                                       break;
+                                       status = request_code_segment(ft1000dev,
+                                                       &s_file, &c_file,
+                                                       (const u8 *)boot_end,
+                                                       true);
+                               break;
                                default:
                                        DEBUG
                                            ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
@@ -929,45 +813,10 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                                break;
                                        }
 
-                                       word_length =
-                                           get_request_value(ft1000dev);
-                                       //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
-                                       if (word_length > MAX_LENGTH) {
-                                               DEBUG
-                                                   ("FT1000:download:Download error: Max length exceeded\n");
-                                               status = STATUS_FAILURE;
-                                               break;
-                                       }
-                                       if ((word_length * 2 + c_file) >
-                                           code_end) {
-                                               /*
-                                                * Error, beyond boot code range.
-                                                */
-                                               DEBUG
-                                                   ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundary.\n",
-                                                    (int)word_length);
-                                               status = STATUS_FAILURE;
-                                               break;
-                                       }
-                                       /*
-                                        * Position ASIC DPRAM auto-increment pointer.
-                                        */
-                                       dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
-                                       if (word_length & 0x1)
-                                               word_length++;
-                                       word_length = word_length / 2;
-
-                                       write_blk_fifo(ft1000dev, &s_file,
-                                                      &c_file, word_length);
-                                       if (ft1000dev->usbboot == 0)
-                                               ft1000dev->usbboot++;
-                                       if (ft1000dev->usbboot == 1) {
-                                               tempword = 0;
-                                               ft1000_write_dpram16(ft1000dev,
-                                                                    DWNLD_MAG1_PS_HDR_LOC,
-                                                                    tempword,
-                                                                    0);
-                                       }
+                                       status = request_code_segment(ft1000dev,
+                                                       &s_file, &c_file,
+                                                       (const u8 *)code_end,
+                                                       false);
 
                                        break;
 
@@ -1036,7 +885,7 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                                status =
                                                    fix_ft1000_write_dpram32
                                                    (ft1000dev, dpram++,
-                                                    (u8 *) & templong);
+                                                    (u8 *) &templong);
 
                                        }
                                        break;
@@ -1044,7 +893,7 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                case REQUEST_CODE_BY_VERSION:
                                        DEBUG
                                            ("FT1000:download:REQUEST_CODE_BY_VERSION\n");
-                                       correct_version = FALSE;
+                                       correct_version = false;
                                        requested_version =
                                            get_request_value(ft1000dev);
 
@@ -1061,7 +910,7 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
 
                                                if (dsp_img_info->version ==
                                                    requested_version) {
-                                                       correct_version = TRUE;
+                                                       correct_version = true;
                                                        DEBUG
                                                            ("FT1000:download: correct_version is TRUE\n");
                                                        s_file =
@@ -1137,13 +986,13 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        if (pseudo_header->checksum ==
                            hdr_checksum(pseudo_header)) {
                                if (pseudo_header->portdest !=
-                                   0x80 /* Dsp OAM */ ) {
+                                   0x80 /* Dsp OAM */) {
                                        state = STATE_DONE_PROV;
                                        break;
                                }
                                pseudo_header_len = ntohs(pseudo_header->length);       /* Byte length for PROV records */
 
-                               // Get buffer for provisioning data
+                               /* Get buffer for provisioning data */
                                pbuffer =
                                    kmalloc((pseudo_header_len +
                                             sizeof(struct pseudo_hdr)),
@@ -1201,9 +1050,8 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        break;
                }               /* End Switch */
 
-               if (status != STATUS_SUCCESS) {
+               if (status != STATUS_SUCCESS)
                        break;
-               }
 
 /****
       // Check if Card is present
index 9b8fed7b405b141ac234821b1a0ddfc0b7347326..0d4931b2c2e26f766f161d4b9c97b473e78952be 100644 (file)
 
 //#define JDEBUG
 
-static int ft1000_reset(void *ft1000dev);
 static int ft1000_submit_rx_urb(struct ft1000_info *info);
-static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int ft1000_open (struct net_device *dev);
-static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev);
-static int ft1000_chkcard (struct ft1000_usb *dev);
 
 static u8 tempbuffer[1600];
 
@@ -526,7 +521,7 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
 //-----------------------------------------------------------------------
 int dsp_reload(struct ft1000_usb *ft1000dev)
 {
-       u16 status;
+       int status;
        u16 tempword;
        u32 templong;
 
@@ -633,9 +628,9 @@ static int ft1000_reset_card(struct net_device *dev)
 
        DEBUG("ft1000_hw:ft1000_reset_card called.....\n");
 
-       ft1000dev->fCondResetPend = 1;
+       ft1000dev->fCondResetPend = true;
        info->CardReady = 0;
-       ft1000dev->fProvComplete = 0;
+       ft1000dev->fProvComplete = false;
 
        /* Make sure we free any memory reserve for provisioning */
        while (list_empty(&info->prov_list) == 0) {
@@ -666,11 +661,216 @@ static int ft1000_reset_card(struct net_device *dev)
 
        info->CardReady = 1;
 
-       ft1000dev->fCondResetPend = 0;
+       ft1000dev->fCondResetPend = false;
 
        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:
+//
+//---------------------------------------------------------------------------
+static void ft1000_usb_transmit_complete(struct urb *urb)
+{
+
+       struct ft1000_usb *ft1000dev = urb->context;
+
+       if (urb->status)
+               pr_err("%s: TX status %d\n", ft1000dev->net->name, urb->status);
+
+       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)
+{
+       struct ft1000_info *pInfo = netdev_priv(netdev);
+       struct ft1000_usb *pFt1000Dev = pInfo->priv;
+
+       int count, ret;
+       u8 *t;
+       struct pseudo_hdr hdr;
+
+       if (!pInfo->CardReady) {
+               DEBUG("ft1000_copy_down_pkt::Card Not Ready\n");
+               return -ENODEV;
+       }
+
+       count = sizeof(struct pseudo_hdr) + len;
+       if (count > MAX_BUF_SIZE) {
+               DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n");
+               DEBUG("size = %d\n", count);
+               return -EINVAL;
+       }
+
+       if (count % 4)
+               count = count + (4 - (count % 4));
+
+       memset(&hdr, 0, sizeof(struct pseudo_hdr));
+
+       hdr.length = ntohs(count);
+       hdr.source = 0x10;
+       hdr.destination = 0x20;
+       hdr.portdest = 0x20;
+       hdr.portsrc = 0x10;
+       hdr.sh_str_id = 0x91;
+       hdr.control = 0x00;
+
+       hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^
+           hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control;
+
+       memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr));
+       memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len);
+
+       netif_stop_queue(netdev);
+
+       usb_fill_bulk_urb(pFt1000Dev->tx_urb,
+                         pFt1000Dev->dev,
+                         usb_sndbulkpipe(pFt1000Dev->dev,
+                                         pFt1000Dev->bulk_out_endpointAddr),
+                         pFt1000Dev->tx_buf, count,
+                         ft1000_usb_transmit_complete, (void *)pFt1000Dev);
+
+       t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer;
+
+       ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
+
+       if (ret) {
+               DEBUG("ft1000 failed tx_urb %d\n", ret);
+               return ret;
+       } else {
+               pInfo->stats.tx_packets++;
+               pInfo->stats.tx_bytes += (len + 14);
+       }
+
+       return 0;
+}
+
+//---------------------------------------------------------------------------
+// Function:    ft1000_start_xmit
+//
+// Parameters:  skb - socket buffer to be sent
+//              dev - network device
+//
+//
+// Returns:     none
+//
+// Description: transmit a ethernet packet
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct ft1000_info *pInfo = netdev_priv(dev);
+       struct ft1000_usb *pFt1000Dev = pInfo->priv;
+       u8 *pdata;
+       int maxlen, pipe;
+
+       if (skb == NULL) {
+               DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
+               return NETDEV_TX_OK;
+       }
+
+       if (pFt1000Dev->status & FT1000_STATUS_CLOSING) {
+               DEBUG("network driver is closed, return\n");
+               goto err;
+       }
+
+       pipe =
+           usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr);
+       maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe));
+
+       pdata = (u8 *) skb->data;
+
+       if (pInfo->mediastate == 0) {
+               /* Drop packet is mediastate is down */
+               DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n");
+               goto err;
+       }
+
+       if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
+               /* Drop packet which has invalid size */
+               DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n");
+               goto err;
+       }
+
+       ft1000_copy_down_pkt(dev, (pdata + ENET_HEADER_SIZE - 2),
+                            skb->len - ENET_HEADER_SIZE + 2);
+
+err:
+       dev_kfree_skb(skb);
+
+       return NETDEV_TX_OK;
+}
+
+//---------------------------------------------------------------------------
+// Function:    ft1000_open
+//
+// Parameters:
+//              dev - network device
+//
+//
+// Returns:     none
+//
+// Description: open the network driver
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+static int ft1000_open(struct net_device *dev)
+{
+       struct ft1000_info *pInfo = netdev_priv(dev);
+       struct ft1000_usb *pFt1000Dev = pInfo->priv;
+       struct timeval tv;
+
+       DEBUG("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber);
+
+       pInfo->stats.rx_bytes = 0;
+       pInfo->stats.tx_bytes = 0;
+       pInfo->stats.rx_packets = 0;
+       pInfo->stats.tx_packets = 0;
+       do_gettimeofday(&tv);
+       pInfo->ConTm = tv.tv_sec;
+       pInfo->ProgConStat = 0;
+
+       netif_start_queue(dev);
+
+       netif_carrier_on(dev);
+
+       return ft1000_submit_rx_urb(pInfo);
+}
+
+static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev)
+{
+       struct ft1000_info *info = netdev_priv(dev);
+
+       return &(info->stats);
+}
+
 static const struct net_device_ops ftnet_ops =
 {
        .ndo_open = &ft1000_open,
@@ -679,7 +879,6 @@ static const struct net_device_ops ftnet_ops =
        .ndo_get_stats = &ft1000_netdev_stats,
 };
 
-
 //---------------------------------------------------------------------------
 // Function:    init_ft1000_netdev
 //
@@ -694,6 +893,13 @@ static const struct net_device_ops ftnet_ops =
 // Notes:
 //
 //---------------------------------------------------------------------------
+
+static int ft1000_reset(void *dev)
+{
+       ft1000_reset_card(dev);
+       return 0;
+}
+
 int init_ft1000_netdev(struct ft1000_usb *ft1000dev)
 {
        struct net_device *netdev;
@@ -752,8 +958,8 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev)
        pInfo->DSP_TIME[1] = 0;
        pInfo->DSP_TIME[2] = 0;
        pInfo->DSP_TIME[3] = 0;
-       ft1000dev->fAppMsgPend = 0;
-       ft1000dev->fCondResetPend = 0;
+       ft1000dev->fAppMsgPend = false;
+       ft1000dev->fCondResetPend = false;
        ft1000dev->usbboot = 0;
        ft1000dev->dspalive = 0;
        memset(&ft1000dev->tempbuf[0], 0, sizeof(ft1000dev->tempbuf));
@@ -854,175 +1060,6 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev,
        return 0;
 }
 
-int ft1000_reset(void *dev)
-{
-       ft1000_reset_card(dev);
-       return 0;
-}
-
-//---------------------------------------------------------------------------
-// Function:    ft1000_usb_transmit_complete
-//
-// Parameters:  urb  - transmitted usb urb
-//
-//
-// Returns:     none
-//
-// Description: This is the callback function when a urb is transmitted
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static void ft1000_usb_transmit_complete(struct urb *urb)
-{
-
-       struct ft1000_usb *ft1000dev = urb->context;
-
-       if (urb->status)
-               pr_err("%s: TX status %d\n", ft1000dev->net->name, urb->status);
-
-       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)
-{
-       struct ft1000_info *pInfo = netdev_priv(netdev);
-       struct ft1000_usb *pFt1000Dev = pInfo->priv;
-
-       int count, ret;
-       u8 *t;
-       struct pseudo_hdr hdr;
-
-       if (!pInfo->CardReady) {
-               DEBUG("ft1000_copy_down_pkt::Card Not Ready\n");
-               return -ENODEV;
-       }
-
-       count = sizeof(struct pseudo_hdr) + len;
-       if (count > MAX_BUF_SIZE) {
-               DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n");
-               DEBUG("size = %d\n", count);
-               return -EINVAL;
-       }
-
-       if (count % 4)
-               count = count + (4 - (count % 4));
-
-       memset(&hdr, 0, sizeof(struct pseudo_hdr));
-
-       hdr.length = ntohs(count);
-       hdr.source = 0x10;
-       hdr.destination = 0x20;
-       hdr.portdest = 0x20;
-       hdr.portsrc = 0x10;
-       hdr.sh_str_id = 0x91;
-       hdr.control = 0x00;
-
-       hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^
-           hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control;
-
-       memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr));
-       memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len);
-
-       netif_stop_queue(netdev);
-
-       usb_fill_bulk_urb(pFt1000Dev->tx_urb,
-                         pFt1000Dev->dev,
-                         usb_sndbulkpipe(pFt1000Dev->dev,
-                                         pFt1000Dev->bulk_out_endpointAddr),
-                         pFt1000Dev->tx_buf, count,
-                         ft1000_usb_transmit_complete, (void *)pFt1000Dev);
-
-       t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer;
-
-       ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
-
-       if (ret) {
-               DEBUG("ft1000 failed tx_urb %d\n", ret);
-               return ret;
-       } else {
-               pInfo->stats.tx_packets++;
-               pInfo->stats.tx_bytes += (len + 14);
-       }
-
-       return 0;
-}
-
-
-//---------------------------------------------------------------------------
-// Function:    ft1000_start_xmit
-//
-// Parameters:  skb - socket buffer to be sent
-//              dev - network device
-//
-//
-// Returns:     none
-//
-// Description: transmit a ethernet packet
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct ft1000_info *pInfo = netdev_priv(dev);
-       struct ft1000_usb *pFt1000Dev = pInfo->priv;
-       u8 *pdata;
-       int maxlen, pipe;
-
-       if (skb == NULL) {
-               DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
-               return NETDEV_TX_OK;
-       }
-
-       if (pFt1000Dev->status & FT1000_STATUS_CLOSING) {
-               DEBUG("network driver is closed, return\n");
-               goto err;
-       }
-
-       pipe =
-           usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr);
-       maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe));
-
-       pdata = (u8 *) skb->data;
-
-       if (pInfo->mediastate == 0) {
-               /* Drop packet is mediastate is down */
-               DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n");
-               goto err;
-       }
-
-       if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
-               /* Drop packet which has invalid size */
-               DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n");
-               goto err;
-       }
-
-       ft1000_copy_down_pkt(dev, (pdata + ENET_HEADER_SIZE - 2),
-                            skb->len - ENET_HEADER_SIZE + 2);
-
-err:
-       dev_kfree_skb(skb);
-
-       return NETDEV_TX_OK;
-}
-
-
 //---------------------------------------------------------------------------
 //
 // Function:   ft1000_copy_up_pkt
@@ -1159,44 +1196,6 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info)
        return 0;
 }
 
-
-//---------------------------------------------------------------------------
-// Function:    ft1000_open
-//
-// Parameters:
-//              dev - network device
-//
-//
-// Returns:     none
-//
-// Description: open the network driver
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static int ft1000_open(struct net_device *dev)
-{
-       struct ft1000_info *pInfo = netdev_priv(dev);
-       struct ft1000_usb *pFt1000Dev = pInfo->priv;
-       struct timeval tv;
-
-       DEBUG("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber);
-
-       pInfo->stats.rx_bytes = 0;
-       pInfo->stats.tx_bytes = 0;
-       pInfo->stats.rx_packets = 0;
-       pInfo->stats.tx_packets = 0;
-       do_gettimeofday(&tv);
-       pInfo->ConTm = tv.tv_sec;
-       pInfo->ProgConStat = 0;
-
-       netif_start_queue(dev);
-
-       netif_carrier_on(dev);
-
-       return ft1000_submit_rx_urb(pInfo);
-}
-
 //---------------------------------------------------------------------------
 // Function:    ft1000_close
 //
@@ -1228,14 +1227,6 @@ int ft1000_close(struct net_device *net)
        return 0;
 }
 
-static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-
-       return &(info->stats);
-}
-
-
 //---------------------------------------------------------------------------
 //
 // Function:   ft1000_chkcard
@@ -1441,7 +1432,7 @@ static int ft1000_dsp_prov(void *arg)
 
        msleep(100);
 
-       dev->fProvComplete = 1;
+       dev->fProvComplete = true;
        info->CardReady = 1;
 
        return STATUS_SUCCESS;
@@ -1567,12 +1558,12 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
                         * Send provisioning data to DSP
                         */
                        if (list_empty(&info->prov_list) == 0) {
-                               dev->fProvComplete = 0;
+                               dev->fProvComplete = false;
                                status = ft1000_dsp_prov(dev);
                                if (status != STATUS_SUCCESS)
                                        goto out;
                        } else {
-                               dev->fProvComplete = 1;
+                               dev->fProvComplete = true;
                                status =
                                    ft1000_write_register(dev, FT1000_DB_HB,
                                                          FT1000_REG_DOORBELL);
@@ -1921,7 +1912,7 @@ int ft1000_poll(void* dev_id)
         else if (tempword & FT1000_DB_COND_RESET) {
             DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_COND_RESET\n");
 
-           if (dev->fAppMsgPend == 0) {
+           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);
@@ -1934,8 +1925,8 @@ int ft1000_poll(void* dev_id)
                 info->ft1000_reset(dev->net);
             }
             else {
-                dev->fProvComplete = 0;
-                dev->fCondResetPend = 1;
+                dev->fProvComplete = false;
+                dev->fCondResetPend = true;
             }
 
             ft1000_write_register(dev, FT1000_DB_COND_RESET, FT1000_REG_DOORBELL);
index 29a7cd23845d4a6b578f977c6a8fc169b19f7c31..a8dd1e54878cb7a3a3914c097896bd6377216b8f 100644 (file)
@@ -36,7 +36,7 @@ static struct usb_device_id id_table[] = {
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static bool gPollingfailed = FALSE;
+static bool gPollingfailed = false;
 static int ft1000_poll_thread(void *arg)
 {
        int ret;
@@ -47,7 +47,7 @@ static int ft1000_poll_thread(void *arg)
                        ret = ft1000_poll(arg);
                        if (ret != STATUS_SUCCESS) {
                                DEBUG("ft1000_poll_thread: polling failed\n");
-                               gPollingfailed = TRUE;
+                               gPollingfailed = true;
                        }
                }
        }
@@ -171,7 +171,7 @@ static int ft1000_probe(struct usb_interface *interface,
                goto err_load;
        }
 
-       gPollingfailed = FALSE;
+       gPollingfailed = false;
        ft1000dev->pPollThread =
            kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll");
 
index bd1da1f19cd269430f31b804e5ec63ca8c313edc..e8d00a930dc64bb08e5b7b34d42896dc3cd5b6c4 100644 (file)
@@ -125,7 +125,7 @@ extern size_t FileLength;
 extern int numofmsgbuf;
 
 int ft1000_close(struct net_device *dev);
-u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
+int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                u32  FileLength);
 
 extern struct list_head freercvpool;
index ff92f34e4746f3e9e0239abe945c866115e86605..62df009e5ac7c8e9bcd5779bf57e9b8c1d2c309d 100644 (file)
@@ -2394,7 +2394,8 @@ static int fwserial_create(struct fw_unit *unit)
 
        list_del_rcu(&serial->list);
        if (create_loop_dev)
-               tty_unregister_device(fwloop_driver, loop_idx(serial->ports[j]));
+               tty_unregister_device(fwloop_driver,
+                                     loop_idx(serial->ports[j]));
 unregister_ttys:
        for (--j; j >= 0; --j)
                tty_unregister_device(fwtty_driver, serial->ports[j]->index);
index bc0d510fb0af3539033fdf11642bd820627c5083..c57a6ba5d010e84464632590c20e48e805d8681e 100644 (file)
@@ -110,7 +110,7 @@ static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type)
        return 0;
 }
 
-int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
+static int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
 {
        struct nic *nic = netdev_priv(skb_in->dev);
        struct sk_buff *skb_out;
@@ -186,7 +186,7 @@ int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
        return 0;
 }
 
-int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
+static int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
 {
        unsigned short *w = ptr;
        int sum = 0;
@@ -226,7 +226,7 @@ int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
        return sum;
 }
 
-int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type)
+static int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type)
 {
        struct nic *nic = netdev_priv(skb_in->dev);
        struct sk_buff *skb_out;
index 5b1ef4000d0fe4a06086fb5ca8e7a14c896b653f..62163673976c309e93f004ba5082b80f2a8f240d 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "gdm_mux.h"
 
-struct workqueue_struct *mux_rx_wq;
+static struct workqueue_struct *mux_rx_wq;
 
 static u16 packet_type[TTY_MAX_COUNT] = {0xF011, 0xF010};
 
@@ -51,7 +51,7 @@ static const struct usb_device_id id_table[] = {
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-int packet_type_to_index(u16 packetType)
+static int packet_type_to_index(u16 packetType)
 {
        int i;
 
@@ -96,12 +96,12 @@ static struct mux_rx *alloc_mux_rx(void)
 {
        struct mux_rx *r = NULL;
 
-       r = kzalloc(sizeof(struct mux_rx), GFP_ATOMIC);
+       r = kzalloc(sizeof(struct mux_rx), GFP_KERNEL);
        if (!r)
                return NULL;
 
-       r->urb = usb_alloc_urb(0, GFP_ATOMIC);
-       r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_ATOMIC);
+       r->urb = usb_alloc_urb(0, GFP_KERNEL);
+       r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_KERNEL);
        if (!r->urb || !r->buf) {
                usb_free_urb(r->urb);
                kfree(r->buf);
@@ -541,7 +541,7 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id
 
        ret = init_usb(mux_dev);
        if (ret)
-               goto err_free_tty;
+               goto err_free_usb;
 
        tty_dev->priv_dev = (void *)mux_dev;
        tty_dev->send_func = gdm_mux_send;
@@ -565,8 +565,8 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id
 
 err_unregister_tty:
        unregister_lte_tty_device(tty_dev);
+err_free_usb:
        release_usb(mux_dev);
-err_free_tty:
        kfree(tty_dev);
 err_free_mux:
        kfree(mux_dev);
index 0247a2055e8d68097388c6aaf9331a6b5ea4800c..c0f7cd75116b1f294b90b6373cdb594e07a2c53e 100644 (file)
@@ -171,7 +171,8 @@ static void gdm_tty_send_complete(void *arg)
        tty_port_tty_wakeup(&gdm->port);
 }
 
-static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
+static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf,
+                        int len)
 {
        struct gdm *gdm = tty->driver_data;
        int remain = len;
@@ -185,7 +186,8 @@ static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int l
                return 0;
 
        while (1) {
-               sending_len = remain > MUX_TX_MAX_SIZE ? MUX_TX_MAX_SIZE : remain;
+               sending_len = remain > MUX_TX_MAX_SIZE ? MUX_TX_MAX_SIZE :
+                                                        remain;
                gdm_tty_send(gdm,
                             (void *)(buf+sent_len),
                             sending_len,
@@ -247,7 +249,8 @@ int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device)
                gdm->minor = j;
                gdm->tty_dev = tty_dev;
 
-               tty_port_register_device(&gdm->port, gdm_driver[i], gdm->minor, device);
+               tty_port_register_device(&gdm->port, gdm_driver[i],
+                                        gdm->minor, device);
        }
 
        for (i = 0; i < MAX_ISSUE_NUM; i++)
@@ -309,7 +312,8 @@ int register_lte_tty_driver(void)
                tty_driver->major = GDM_TTY_MAJOR;
                tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
                tty_driver->subtype = SERIAL_TYPE_NORMAL;
-               tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+               tty_driver->flags = TTY_DRIVER_REAL_RAW |
+                                       TTY_DRIVER_DYNAMIC_DEV;
                tty_driver->init_termios = tty_std_termios;
                tty_driver->init_termios.c_cflag = B9600 | CS8 | HUPCL | CLOCAL;
                tty_driver->init_termios.c_lflag = ISIG | ICANON | IEXTEN;
index bdc96370e4306a325e15c80d17b32becfef71bd8..781134af69d13fe37481ed06f4685fc746f34f64 100644 (file)
@@ -88,12 +88,11 @@ static struct usb_tx *alloc_tx_struct(int len)
        struct usb_tx *t = NULL;
        int ret = 0;
 
-       t = kmalloc(sizeof(struct usb_tx), GFP_ATOMIC);
+       t = kzalloc(sizeof(struct usb_tx), GFP_ATOMIC);
        if (!t) {
                ret = -ENOMEM;
                goto out;
        }
-       memset(t, 0, sizeof(struct usb_tx));
 
        t->urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!(len % 512))
@@ -124,12 +123,11 @@ static struct usb_tx_sdu *alloc_tx_sdu_struct(void)
        int ret = 0;
 
 
-       t_sdu = kmalloc(sizeof(struct usb_tx_sdu), GFP_ATOMIC);
+       t_sdu = kzalloc(sizeof(struct usb_tx_sdu), GFP_ATOMIC);
        if (!t_sdu) {
                ret = -ENOMEM;
                goto out;
        }
-       memset(t_sdu, 0, sizeof(struct usb_tx_sdu));
 
        t_sdu->buf = kmalloc(SDU_BUF_SIZE, GFP_ATOMIC);
        if (!t_sdu->buf) {
index cf32ae099cd68aef662b78f92936cd8cfc657265..35154d60faf6120813bb26bf2477994e66fd259f 100644 (file)
@@ -502,7 +502,7 @@ inline int find_type_by_name(const char *name, const char *type)
 
 inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
 {
-       int ret;
+       int ret = 0;
        FILE *sysfsfp;
        int test;
        char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
index 04c23262f8e201a8a52ce8a0e7de0f0542891059..c22a0edd1528776f359ec321b5d72ba94bacb839 100644 (file)
@@ -13,6 +13,17 @@ Would be nice
 3) Expand device set. Lots of other maxim adc's have very
    similar interfaces.
 
+MXS LRADC driver:
+This is a classic MFD device as it combines the following subdevices
+ - touchscreen controller (input subsystem related device)
+ - general purpose ADC channels
+ - battery voltage monitor (power subsystem related device)
+ - die temperature monitor (thermal management)
+
+At least the battery voltage and die temperature feature is required in-kernel
+by a driver of the SoC's battery charging unit to avoid any damage to the
+silicon and the battery.
+
 TSL2561
 Would be nice
 1) Open question of userspace vs kernel space balance when
index 5c289614357c578e9df243c3b0b03572bbbf5c3e..4c9364b63c77d61a1088298993ad46435c0cca6e 100644 (file)
@@ -102,7 +102,6 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
                                        int addr)
 {
        struct adis16220_state *st = iio_priv(indio_dev);
-       struct spi_message msg;
        struct spi_transfer xfers[] = {
                {
                        .tx_buf = st->tx,
@@ -147,10 +146,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
        }
        xfers[1].len = count;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(st->adis.spi, &msg);
+       ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers));
        if (ret) {
 
                mutex_unlock(&st->buf_lock);
index bb852dc9c9870c703d261734f5408770758cbb75..735c0a34fa93a19888c498f85d34bfde7d39d578 100644 (file)
@@ -190,15 +190,26 @@ static u8 lis3l02dq_axis_map[3][3] = {
 };
 
 static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
-                                u64 e,
-                                int *val)
+                                const struct iio_chan_spec *chan,
+                                enum iio_event_type type,
+                                enum iio_event_direction dir,
+                                enum iio_event_info info,
+                                int *val, int *val2)
 {
-       return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
+       int ret;
+
+       ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
+       if (ret)
+               return ret;
+       return IIO_VAL_INT;
 }
 
 static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
-                                 u64 event_code,
-                                 int val)
+                                 const struct iio_chan_spec *chan,
+                                 enum iio_event_type type,
+                                 enum iio_event_direction dir,
+                                 enum iio_event_info info,
+                                 int val, int val2)
 {
        u16 value = val;
        return lis3l02dq_spi_write_reg_s16(indio_dev,
@@ -503,9 +514,19 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
        return IRQ_HANDLED;
 }
 
-#define LIS3L02DQ_EVENT_MASK                                   \
-       (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |    \
-        IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec lis3l02dq_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+               .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+               .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+       }
+};
 
 #define LIS3L02DQ_CHAN(index, mod)                             \
        {                                                       \
@@ -523,7 +544,8 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
                        .realbits = 12,                         \
                        .storagebits = 16,                      \
                },                                              \
-               .event_mask = LIS3L02DQ_EVENT_MASK,             \
+               .event_spec = lis3l02dq_event,                  \
+               .num_event_specs = ARRAY_SIZE(lis3l02dq_event), \
         }
 
 static const struct iio_chan_spec lis3l02dq_channels[] = {
@@ -535,14 +557,14 @@ static const struct iio_chan_spec lis3l02dq_channels[] = {
 
 
 static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
-                                          u64 event_code)
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir)
 {
 
        u8 val;
        int ret;
-       u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
-                        (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                         IIO_EV_DIR_RISING)));
+       u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
        ret = lis3l02dq_spi_read_reg_8(indio_dev,
                                       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
                                       &val);
@@ -587,16 +609,16 @@ error_ret:
 }
 
 static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
-                                       u64 event_code,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
                                        int state)
 {
        int ret = 0;
        u8 val, control;
        u8 currentlyset;
        bool changed = false;
-       u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
-                        (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                         IIO_EV_DIR_RISING)));
+       u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
 
        mutex_lock(&indio_dev->mlock);
        /* read current control */
@@ -654,10 +676,10 @@ static const struct attribute_group lis3l02dq_attribute_group = {
 static const struct iio_info lis3l02dq_info = {
        .read_raw = &lis3l02dq_read_raw,
        .write_raw = &lis3l02dq_write_raw,
-       .read_event_value = &lis3l02dq_read_thresh,
-       .write_event_value = &lis3l02dq_write_thresh,
-       .write_event_config = &lis3l02dq_write_event_config,
-       .read_event_config = &lis3l02dq_read_event_config,
+       .read_event_value_new = &lis3l02dq_read_thresh,
+       .write_event_value_new = &lis3l02dq_write_thresh,
+       .write_event_config_new = &lis3l02dq_write_event_config,
+       .read_event_config_new = &lis3l02dq_read_event_config,
        .driver_module = THIS_MODULE,
        .attrs = &lis3l02dq_attribute_group,
 };
@@ -694,7 +716,7 @@ static int lis3l02dq_probe(struct spi_device *spi)
                                  lis3l02dq_channels,
                                  ARRAY_SIZE(lis3l02dq_channels));
        if (ret) {
-               printk(KERN_ERR "failed to initialize the buffer\n");
+               dev_err(&spi->dev, "failed to initialize the buffer\n");
                goto error_unreg_buffer_funcs;
        }
 
index 5b8f0f6c99385d409ba471acfe902a041518da38..79cefe0a516a7316269546a36c2eec1fb3648556 100644 (file)
@@ -111,7 +111,7 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,
                                u8 *buf)
 {
        int ret, i;
-       u8 *rx_array ;
+       u8 *rx_array;
        s16 *data = (s16 *)buf;
        int scan_count = bitmap_weight(indio_dev->active_scan_mask,
                                       indio_dev->masklength);
@@ -146,11 +146,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
        if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
                len = lis3l02dq_get_buffer_element(indio_dev, data);
 
-         /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
-                       = pf->timestamp;
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
 
        kfree(data);
 done:
@@ -264,8 +260,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
                else
                        break;
        if (i == 5)
-               printk(KERN_INFO
-                      "Failed to clear the interrupt for lis3l02dq\n");
+               pr_info("Failed to clear the interrupt for lis3l02dq\n");
 
        /* irq reenabled so success! */
        return 0;
@@ -387,7 +382,6 @@ error_ret:
 }
 
 static const struct iio_buffer_setup_ops lis3l02dq_buffer_setup_ops = {
-       .preenable = &iio_sw_buffer_preenable,
        .postenable = &lis3l02dq_buffer_postenable,
        .predisable = &lis3l02dq_buffer_predisable,
 };
@@ -401,7 +395,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
        if (!buffer)
                return -ENOMEM;
 
-       indio_dev->buffer = buffer;
+       iio_device_attach_buffer(indio_dev, buffer);
 
        buffer->scan_timestamp = true;
        indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
index 48a25ba290f5ae8a19c18c824a155c082321c66e..c49e6ef9d05f866fe6bacc56bdbeab9dd44b6b4a 100644 (file)
@@ -419,8 +419,11 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
 
 static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
 
-#define SCA3000_EVENT_MASK                                     \
-       (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
+static const struct iio_event_spec sca3000_event = {
+       .type = IIO_EV_TYPE_MAG,
+       .dir = IIO_EV_DIR_RISING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
 
 #define SCA3000_CHAN(index, mod)                               \
        {                                                       \
@@ -437,7 +440,8 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
                        .storagebits = 16,                      \
                        .shift = 5,                             \
                },                                              \
-               .event_mask = SCA3000_EVENT_MASK,               \
+               .event_spec = &sca3000_event,                   \
+               .num_event_specs = 1,                           \
         }
 
 static const struct iio_chan_spec sca3000_channels[] = {
@@ -624,9 +628,9 @@ static ssize_t sca3000_set_frequency(struct device *dev,
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret, base_freq = 0;
        int ctrlval;
-       long val;
+       int val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtoint(buf, 10, &val);
        if (ret)
                return ret;
 
@@ -703,12 +707,15 @@ static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
  * sca3000_read_thresh() - query of a threshold
  **/
 static int sca3000_read_thresh(struct iio_dev *indio_dev,
-                              u64 e,
-                              int *val)
+                              const struct iio_chan_spec *chan,
+                              enum iio_event_type type,
+                              enum iio_event_direction dir,
+                              enum iio_event_info info,
+                              int *val, int *val2)
 {
        int ret, i;
        struct sca3000_state *st = iio_priv(indio_dev);
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
        mutex_lock(&st->lock);
        ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
        mutex_unlock(&st->lock);
@@ -724,18 +731,21 @@ static int sca3000_read_thresh(struct iio_dev *indio_dev,
                                 ARRAY_SIZE(st->info->mot_det_mult_xz))
                        *val += st->info->mot_det_mult_xz[i];
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 /**
  * sca3000_write_thresh() control of threshold
  **/
 static int sca3000_write_thresh(struct iio_dev *indio_dev,
-                               u64 e,
-                               int val)
+                               const struct iio_chan_spec *chan,
+                               enum iio_event_type type,
+                               enum iio_event_direction dir,
+                               enum iio_event_info info,
+                               int val, int val2)
 {
        struct sca3000_state *st = iio_priv(indio_dev);
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
        int ret;
        int i;
        u8 nonlinear = 0;
@@ -866,12 +876,14 @@ done:
  * sca3000_read_event_config() what events are enabled
  **/
 static int sca3000_read_event_config(struct iio_dev *indio_dev,
-                                    u64 e)
+                                    const struct iio_chan_spec *chan,
+                                    enum iio_event_type type,
+                                    enum iio_event_direction dir)
 {
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret;
        u8 protect_mask = 0x03;
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
 
        /* read current value of mode register */
        mutex_lock(&st->lock);
@@ -931,12 +943,12 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct sca3000_state *st = iio_priv(indio_dev);
-       long val;
+       u8 val;
        int ret;
        u8 protect_mask = SCA3000_FREE_FALL_DETECT;
 
        mutex_lock(&st->lock);
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
 
@@ -969,13 +981,15 @@ error_ret:
  * this mode is disabled.  Currently normal mode is assumed.
  **/
 static int sca3000_write_event_config(struct iio_dev *indio_dev,
-                                     u64 e,
+                                     const struct iio_chan_spec *chan,
+                                     enum iio_event_type type,
+                                     enum iio_event_direction dir,
                                      int state)
 {
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret, ctrlval;
        u8 protect_mask = 0x03;
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
 
        mutex_lock(&st->lock);
        /* First read the motion detector config to find out if
@@ -1112,20 +1126,20 @@ static const struct iio_info sca3000_info = {
        .attrs = &sca3000_attribute_group,
        .read_raw = &sca3000_read_raw,
        .event_attrs = &sca3000_event_attribute_group,
-       .read_event_value = &sca3000_read_thresh,
-       .write_event_value = &sca3000_write_thresh,
-       .read_event_config = &sca3000_read_event_config,
-       .write_event_config = &sca3000_write_event_config,
+       .read_event_value_new = &sca3000_read_thresh,
+       .write_event_value_new = &sca3000_write_thresh,
+       .read_event_config_new = &sca3000_read_event_config,
+       .write_event_config_new = &sca3000_write_event_config,
        .driver_module = THIS_MODULE,
 };
 
 static const struct iio_info sca3000_info_with_temp = {
        .attrs = &sca3000_attribute_group_with_temp,
        .read_raw = &sca3000_read_raw,
-       .read_event_value = &sca3000_read_thresh,
-       .write_event_value = &sca3000_write_thresh,
-       .read_event_config = &sca3000_read_event_config,
-       .write_event_config = &sca3000_write_event_config,
+       .read_event_value_new = &sca3000_read_thresh,
+       .write_event_value_new = &sca3000_write_thresh,
+       .read_event_config_new = &sca3000_read_event_config,
+       .write_event_config_new = &sca3000_write_event_config,
        .driver_module = THIS_MODULE,
 };
 
index 3e5e860aa38eec64ad8805c6b33c03952d6acad0..ea0af6d81d2b8ac3cdf1d31c5bd5fee61844ab73 100644 (file)
@@ -177,11 +177,11 @@ static ssize_t sca3000_set_ring_int(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct sca3000_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       long val;
+       u8 val;
        int ret;
 
        mutex_lock(&st->lock);
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
@@ -252,7 +252,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
        struct iio_buffer *buf;
        struct iio_hw_buffer *ring;
 
-       ring = kzalloc(sizeof *ring, GFP_KERNEL);
+       ring = kzalloc(sizeof(*ring), GFP_KERNEL);
        if (!ring)
                return NULL;
 
@@ -265,7 +265,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
        return buf;
 }
 
-static inline void sca3000_rb_free(struct iio_buffer *r)
+static void sca3000_ring_release(struct iio_buffer *r)
 {
        kfree(iio_to_hw_buf(r));
 }
@@ -274,23 +274,28 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
        .read_first_n = &sca3000_read_first_n_hw_rb,
        .get_length = &sca3000_ring_get_length,
        .get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
+       .release = sca3000_ring_release,
 };
 
 int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
-       indio_dev->buffer = sca3000_rb_allocate(indio_dev);
-       if (indio_dev->buffer == NULL)
+       struct iio_buffer *buffer;
+
+       buffer = sca3000_rb_allocate(indio_dev);
+       if (buffer == NULL)
                return -ENOMEM;
        indio_dev->modes |= INDIO_BUFFER_HARDWARE;
 
        indio_dev->buffer->access = &sca3000_ring_access_funcs;
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        return 0;
 }
 
 void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
 {
-       sca3000_rb_free(indio_dev->buffer);
+       iio_buffer_put(indio_dev->buffer);
 }
 
 static inline
index cabc7a367db50833f6e40dc55ebec4efb9cb57bb..e3d643001952c2fd46dc7f3355cb834da693cf9c 100644 (file)
@@ -102,7 +102,7 @@ config AD7280
 
 config LPC32XX_ADC
        tristate "NXP LPC32XX ADC"
-       depends on ARCH_LPC32XX
+       depends on ARCH_LPC32XX || COMPILE_TEST
        help
          Say yes here to build support for the integrated ADC inside the
          LPC32XX SoC. Note that this feature uses the same hardware as the
@@ -113,7 +113,9 @@ config LPC32XX_ADC
 
 config MXS_LRADC
        tristate "Freescale i.MX23/i.MX28 LRADC"
-       depends on ARCH_MXS
+       depends on ARCH_MXS || COMPILE_TEST
+       depends on INPUT
+       select STMP_DEVICE
        select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
@@ -125,7 +127,7 @@ config MXS_LRADC
 
 config SPEAR_ADC
        tristate "ST SPEAr ADC"
-       depends on PLAT_SPEAR
+       depends on PLAT_SPEAR || COMPILE_TEST
        help
          Say yes here to build support for the integrated ADC inside the
          ST SPEAr SoC. Provides direct access via sysfs.
index 3283e282953653eab17c098c8df6bcfe64f9d602..83bb44b381524bc448929ccab8fe29ffad92c496 100644 (file)
@@ -623,17 +623,17 @@ static int ad7192_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
        st = iio_priv(indio_dev);
 
-       st->reg = regulator_get(&spi->dev, "vcc");
+       st->reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
 
                voltage_uv = regulator_get_voltage(st->reg);
        }
@@ -677,11 +677,6 @@ error_remove_trigger:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -694,10 +689,8 @@ static int ad7192_remove(struct spi_device *spi)
        iio_device_unregister(indio_dev);
        ad_sd_cleanup_buffer_and_trigger(indio_dev);
 
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
 
        return 0;
 }
index c19618bc37c4a004e21206e9ae55e5116ad4016e..8209fa542a8a00275103d87585f415d281a69781 100644 (file)
@@ -783,7 +783,6 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad7280_state *st = iio_priv(indio_dev);
-       unsigned int scale_uv;
        int ret;
 
        switch (m) {
@@ -804,13 +803,12 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
                if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6)
-                       scale_uv = (4000 * 1000) >> AD7280A_BITS;
+                       *val = 4000;
                else
-                       scale_uv = (5000 * 1000) >> AD7280A_BITS;
+                       *val = 5000;
 
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val2 = AD7280A_BITS;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -835,8 +833,9 @@ static int ad7280_probe(struct spi_device *spi)
        int ret;
        const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890};
        const unsigned short nAVG[4] = {1, 2, 4, 8};
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -860,7 +859,7 @@ static int ad7280_probe(struct spi_device *spi)
 
        ret = ad7280_chain_setup(st);
        if (ret < 0)
-               goto error_free_device;
+               return ret;
 
        st->slave_num = ret;
        st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH;
@@ -891,7 +890,7 @@ static int ad7280_probe(struct spi_device *spi)
 
        ret = ad7280_channel_init(st);
        if (ret < 0)
-               goto error_free_device;
+               return ret;
 
        indio_dev->num_channels = ret;
        indio_dev->channels = st->channels;
@@ -940,9 +939,6 @@ error_free_attr:
 error_free_channels:
        kfree(st->channels);
 
-error_free_device:
-       iio_device_free(indio_dev);
-
        return ret;
 }
 
@@ -960,7 +956,6 @@ static int ad7280_remove(struct spi_device *spi)
 
        kfree(st->channels);
        kfree(st->iio_attr);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index a2e61c2fc8d19a319aa1d29e4bfadc7866d6c3f3..d13f8aeeb62fef53460485f6539fab3dbc1b79d3 100644 (file)
@@ -164,97 +164,14 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
        return IRQ_HANDLED;
 }
 
-static inline ssize_t ad7291_show_hyst(struct device *dev,
-               struct device_attribute *attr,
-               char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad7291_chip_info *chip = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       u16 data;
-       int ret;
-
-       ret = ad7291_i2c_read(chip, this_attr->address, &data);
-       if (ret < 0)
-               return ret;
-
-       return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK);
-}
-
-static inline ssize_t ad7291_set_hyst(struct device *dev,
-                                     struct device_attribute *attr,
-                                     const char *buf,
-                                     size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad7291_chip_info *chip = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       u16 data;
-       int ret;
-
-       ret = kstrtou16(buf, 10, &data);
-
-       if (ret < 0)
-               return ret;
-       if (data > AD7291_VALUE_MASK)
-               return -EINVAL;
-
-       ret = ad7291_i2c_write(chip, this_attr->address, data);
-       if (ret < 0)
-               return ret;
-
-       return len;
-}
-
-static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst,
-                      AD7291_HYST(8));
-static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0));
-static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1));
-static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2));
-static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3));
-static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4));
-static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5));
-static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6));
-static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7));
-
-static struct attribute *ad7291_event_attributes[] = {
-       &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
-       NULL,
-};
-
-static unsigned int ad7291_threshold_reg(u64 event_code)
+static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
+       enum iio_event_direction dir, enum iio_event_info info)
 {
        unsigned int offset;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+               offset = chan->channel;
                break;
        case IIO_TEMP:
                offset = 8;
@@ -263,69 +180,78 @@ static unsigned int ad7291_threshold_reg(u64 event_code)
            return 0;
        }
 
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
-               return AD7291_DATA_LOW(offset);
-       else
-               return AD7291_DATA_HIGH(offset);
+       switch (info) {
+       case IIO_EV_INFO_VALUE:
+                       if (dir == IIO_EV_DIR_FALLING)
+                                       return AD7291_DATA_HIGH(offset);
+                       else
+                                       return AD7291_DATA_LOW(offset);
+       case IIO_EV_INFO_HYSTERESIS:
+                       return AD7291_HYST(offset);
+       default:
+                       break;
+       }
+       return 0;
 }
 
 static int ad7291_read_event_value(struct iio_dev *indio_dev,
-                                  u64 event_code,
-                                  int *val)
+                                  const struct iio_chan_spec *chan,
+                                  enum iio_event_type type,
+                                  enum iio_event_direction dir,
+                                  enum iio_event_info info,
+                                  int *val, int *val2)
 {
        struct ad7291_chip_info *chip = iio_priv(indio_dev);
        int ret;
        u16 uval;
 
-       ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval);
+       ret = ad7291_i2c_read(chip, ad7291_threshold_reg(chan, dir, info),
+               &uval);
        if (ret < 0)
                return ret;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_VOLTAGE:
+       if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE)
                *val = uval & AD7291_VALUE_MASK;
-               return 0;
-       case IIO_TEMP:
+
+       else
                *val = sign_extend32(uval, 11);
-               return 0;
-       default:
-               return -EINVAL;
-       };
+
+       return IIO_VAL_INT;
 }
 
 static int ad7291_write_event_value(struct iio_dev *indio_dev,
-                                   u64 event_code,
-                                   int val)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir,
+                                   enum iio_event_info info,
+                                   int val, int val2)
 {
        struct ad7291_chip_info *chip = iio_priv(indio_dev);
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_VOLTAGE:
+       if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE) {
                if (val > AD7291_VALUE_MASK || val < 0)
                        return -EINVAL;
-               break;
-       case IIO_TEMP:
+       } else {
                if (val > 2047 || val < -2048)
                        return -EINVAL;
-               break;
-       default:
-               return -EINVAL;
        }
 
-       return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val);
+       return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
+               val);
 }
 
 static int ad7291_read_event_config(struct iio_dev *indio_dev,
-                                   u64 event_code)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir)
 {
        struct ad7291_chip_info *chip = iio_priv(indio_dev);
        /* To be enabled the channel must simply be on. If any are enabled
           we are in continuous sampling mode */
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               if (chip->c_mask &
-                   (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))
+               if (chip->c_mask & (1 << (15 - chan->channel)))
                        return 1;
                else
                        return 0;
@@ -339,11 +265,14 @@ static int ad7291_read_event_config(struct iio_dev *indio_dev,
 }
 
 static int ad7291_write_event_config(struct iio_dev *indio_dev,
-                                    u64 event_code,
+                                    const struct iio_chan_spec *chan,
+                                    enum iio_event_type type,
+                                    enum iio_event_direction dir,
                                     int state)
 {
        int ret = 0;
        struct ad7291_chip_info *chip = iio_priv(indio_dev);
+       unsigned int mask;
        u16 regval;
 
        mutex_lock(&chip->state_lock);
@@ -354,16 +283,14 @@ static int ad7291_write_event_config(struct iio_dev *indio_dev,
         * Possible to disable temp as well but that makes single read tricky.
         */
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       mask = BIT(15 - chan->channel);
+
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               if ((!state) && (chip->c_mask & (1 << (15 -
-                               IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))
-                       chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
-                                                       (event_code)));
-               else if (state && (!(chip->c_mask & (1 << (15 -
-                               IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))))
-                       chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
-                                                       (event_code)));
+               if ((!state) && (chip->c_mask & mask))
+                       chip->c_mask &= ~mask;
+               else if (state && (!(chip->c_mask & mask)))
+                       chip->c_mask |= mask;
                else
                        break;
 
@@ -473,6 +400,24 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
        }
 }
 
+static const struct iio_event_spec ad7291_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_EITHER,
+               .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+       },
+};
+
 #define AD7291_VOLTAGE_CHAN(_chan)                                     \
 {                                                                      \
        .type = IIO_VOLTAGE,                                            \
@@ -480,8 +425,8 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),           \
        .indexed = 1,                                                   \
        .channel = _chan,                                               \
-       .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
-       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)              \
+       .event_spec = ad7291_events,                                    \
+       .num_event_specs = ARRAY_SIZE(ad7291_events),                   \
 }
 
 static const struct iio_chan_spec ad7291_channels[] = {
@@ -500,23 +445,17 @@ static const struct iio_chan_spec ad7291_channels[] = {
                                BIT(IIO_CHAN_INFO_SCALE),
                .indexed = 1,
                .channel = 0,
-               .event_mask =
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
+               .event_spec = ad7291_events,
+               .num_event_specs = ARRAY_SIZE(ad7291_events),
        }
 };
 
-static struct attribute_group ad7291_event_attribute_group = {
-       .attrs = ad7291_event_attributes,
-};
-
 static const struct iio_info ad7291_info = {
        .read_raw = &ad7291_read_raw,
-       .read_event_config = &ad7291_read_event_config,
-       .write_event_config = &ad7291_write_event_config,
-       .read_event_value = &ad7291_read_event_value,
-       .write_event_value = &ad7291_write_event_value,
-       .event_attrs = &ad7291_event_attribute_group,
+       .read_event_config_new = &ad7291_read_event_config,
+       .write_event_config_new = &ad7291_write_event_config,
+       .read_event_value_new = &ad7291_read_event_value,
+       .write_event_value_new = &ad7291_write_event_value,
        .driver_module = THIS_MODULE,
 };
 
@@ -528,21 +467,19 @@ static int ad7291_probe(struct i2c_client *client,
        struct iio_dev *indio_dev;
        int ret = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
 
        if (pdata && pdata->use_external_ref) {
-               chip->reg = regulator_get(&client->dev, "vref");
+               chip->reg = devm_regulator_get(&client->dev, "vref");
                if (IS_ERR(chip->reg))
-                       goto error_free;
+                       return ret;
 
                ret = regulator_enable(chip->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
 
        mutex_init(&chip->state_lock);
@@ -601,12 +538,7 @@ error_unreg_irq:
 error_disable_reg:
        if (chip->reg)
                regulator_disable(chip->reg);
-error_put_reg:
-       if (chip->reg)
-               regulator_put(chip->reg);
-error_free:
-       iio_device_free(indio_dev);
-error_ret:
+
        return ret;
 }
 
@@ -620,12 +552,8 @@ static int ad7291_remove(struct i2c_client *client)
        if (client->irq)
                free_irq(client->irq, indio_dev);
 
-       if (chip->reg) {
+       if (chip->reg)
                regulator_disable(chip->reg);
-               regulator_put(chip->reg);
-       }
-
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 72868ceda360cdd969cae70ddc6b1e50b2b33bb6..2083673a79ca676f0460274c160cfc5fb4ca6c4f 100644 (file)
@@ -85,7 +85,6 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
 {
        int ret;
        struct ad7606_state *st = iio_priv(indio_dev);
-       unsigned int scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
@@ -101,11 +100,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
                *val = (short) ret;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->range * 1000 * 2)
-                       >> st->chip_info->channels[0].scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->range * 2;
+               *val2 = st->chip_info->channels[0].scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -425,8 +422,7 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
        struct ad7606_state *st = iio_priv(indio_dev);
 
        if (iio_buffer_enabled(indio_dev)) {
-               if (!work_pending(&st->poll_work))
-                       schedule_work(&st->poll_work);
+               schedule_work(&st->poll_work);
        } else {
                st->done = true;
                wake_up_interruptible(&st->wq_data_avail);
@@ -466,12 +462,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
        struct ad7606_platform_data *pdata = dev->platform_data;
        struct ad7606_state *st;
        int ret;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+       if (!indio_dev)
+               return ERR_PTR(-ENOMEM);
 
        st = iio_priv(indio_dev);
 
@@ -489,11 +484,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
                st->oversampling = pdata->default_os;
        }
 
-       st->reg = regulator_get(dev, "vcc");
+       st->reg = devm_regulator_get(dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ERR_PTR(ret);
        }
 
        st->pdata = pdata;
@@ -554,11 +549,6 @@ error_free_gpios:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-       iio_device_free(indio_dev);
-error_ret:
        return ERR_PTR(ret);
 }
 
@@ -570,13 +560,10 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq)
        ad7606_ring_cleanup(indio_dev);
 
        free_irq(irq, indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
 
        ad7606_free_gpios(st);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 2b25cb07fe41d1470513424380de4ab439657191..3bf174cb19b1ef3573482896fef1848a3f7941ff 100644 (file)
@@ -46,7 +46,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
        struct ad7606_state *st = container_of(work_s, struct ad7606_state,
                                                poll_work);
        struct iio_dev *indio_dev = iio_priv_to_dev(st);
-       s64 time_ns;
        __u8 *buf;
        int ret;
 
@@ -78,12 +77,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
                        goto done;
        }
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
-
-       iio_push_to_buffers(indio_dev, buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns());
 done:
        gpio_set_value(st->pdata->gpio_convst, 0);
        iio_trigger_notify_done(indio_dev->trig);
index e1f88603d7e023f2fe389ceb1af865de43141de9..273add3ed63fd8e80532110a1f793b218175caf0 100644 (file)
@@ -90,17 +90,14 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad7780_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
                return ad_sigma_delta_single_conversion(indio_dev, chan, val);
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->int_vref_mv * 100000 * st->gain)
-                       >> (chan->scan_type.realbits - 1);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->int_vref_mv * st->gain;
+               *val2 = chan->scan_type.realbits - 1;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                *val -= (1 << (chan->scan_type.realbits - 1));
                return IIO_VAL_INT;
@@ -171,7 +168,7 @@ static int ad7780_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        int ret, voltage_uv = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -180,11 +177,11 @@ static int ad7780_probe(struct spi_device *spi)
 
        ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
 
-       st->reg = regulator_get(&spi->dev, "vcc");
+       st->reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
 
                voltage_uv = regulator_get_voltage(st->reg);
        }
@@ -210,8 +207,8 @@ static int ad7780_probe(struct spi_device *spi)
 
        if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
 
-               ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
-                              "AD7780 /PDRST");
+               ret = devm_gpio_request_one(&spi->dev, pdata->gpio_pdrst,
+                                       GPIOF_OUT_INIT_LOW, "AD7780 /PDRST");
                if (ret) {
                        dev_err(&spi->dev, "failed to request GPIO PDRST\n");
                        goto error_disable_reg;
@@ -223,7 +220,7 @@ static int ad7780_probe(struct spi_device *spi)
 
        ret = ad_sd_setup_buffer_and_trigger(indio_dev);
        if (ret)
-               goto error_free_gpio;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
@@ -233,17 +230,9 @@ static int ad7780_probe(struct spi_device *spi)
 
 error_cleanup_buffer_and_trigger:
        ad_sd_cleanup_buffer_and_trigger(indio_dev);
-error_free_gpio:
-       if (pdata && gpio_is_valid(pdata->gpio_pdrst))
-               gpio_free(pdata->gpio_pdrst);
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -256,14 +245,8 @@ static int ad7780_remove(struct spi_device *spi)
        iio_device_unregister(indio_dev);
        ad_sd_cleanup_buffer_and_trigger(indio_dev);
 
-       if (gpio_is_valid(st->powerdown_gpio))
-               gpio_free(st->powerdown_gpio);
-
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 8470036a3378cba40d787f1e45fcb0410bd5d676..9f48e5c74eed85c8f164208d4ddbaf4ed108dfb8 100644 (file)
@@ -356,11 +356,9 @@ static int ad7816_probe(struct spi_device *spi_dev)
                return -EINVAL;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
        /* this is only used for device removal purposes */
        dev_set_drvdata(&spi_dev->dev, indio_dev);
@@ -372,25 +370,28 @@ static int ad7816_probe(struct spi_device *spi_dev)
        chip->convert_pin = pins[1];
        chip->busy_pin = pins[2];
 
-       ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
+       ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin,
+                                       spi_get_device_id(spi_dev)->name);
        if (ret) {
                dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
                        chip->rdwr_pin);
-               goto error_free_device;
+               return ret;
        }
        gpio_direction_input(chip->rdwr_pin);
-       ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
+       ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin,
+                                       spi_get_device_id(spi_dev)->name);
        if (ret) {
                dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
                        chip->convert_pin);
-               goto error_free_gpio_rdwr;
+               return ret;
        }
        gpio_direction_input(chip->convert_pin);
-       ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
+       ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin,
+                                       spi_get_device_id(spi_dev)->name);
        if (ret) {
                dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
                        chip->busy_pin);
-               goto error_free_gpio_convert;
+               return ret;
        }
        gpio_direction_input(chip->busy_pin);
 
@@ -401,51 +402,31 @@ static int ad7816_probe(struct spi_device *spi_dev)
 
        if (spi_dev->irq) {
                /* Only low trigger is supported in ad7816/7/8 */
-               ret = request_threaded_irq(spi_dev->irq,
-                                          NULL,
-                                          &ad7816_event_handler,
-                                          IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                          indio_dev->name,
-                                          indio_dev);
+               ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
+                                               NULL,
+                                               &ad7816_event_handler,
+                                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                               indio_dev->name,
+                                               indio_dev);
                if (ret)
-                       goto error_free_gpio;
+                       return ret;
        }
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_irq;
+               return ret;
 
        dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
                         indio_dev->name);
 
        return 0;
-error_free_irq:
-       free_irq(spi_dev->irq, indio_dev);
-error_free_gpio:
-       gpio_free(chip->busy_pin);
-error_free_gpio_convert:
-       gpio_free(chip->convert_pin);
-error_free_gpio_rdwr:
-       gpio_free(chip->rdwr_pin);
-error_free_device:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 
 static int ad7816_remove(struct spi_device *spi_dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
-       struct ad7816_chip_info *chip = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       dev_set_drvdata(&spi_dev->dev, NULL);
-       if (spi_dev->irq)
-               free_irq(spi_dev->irq, indio_dev);
-       gpio_free(chip->busy_pin);
-       gpio_free(chip->convert_pin);
-       gpio_free(chip->rdwr_pin);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index b51680c1c331a65593a531a93ec6f1bd6f1b191c..a591aa6feae142dc0eaa3507e8f5ad0279396ab7 100644 (file)
 #define AD7998_ALERT_STAT_REG                  0x1
 #define AD7998_CONF_REG                                0x2
 #define AD7998_CYCLE_TMR_REG                   0x3
-#define AD7998_DATALOW_CH1_REG                 0x4
-#define AD7998_DATAHIGH_CH1_REG                        0x5
-#define AD7998_HYST_CH1_REG                    0x6
-#define AD7998_DATALOW_CH2_REG                 0x7
-#define AD7998_DATAHIGH_CH2_REG                        0x8
-#define AD7998_HYST_CH2_REG                    0x9
-#define AD7998_DATALOW_CH3_REG                 0xA
-#define AD7998_DATAHIGH_CH3_REG                        0xB
-#define AD7998_HYST_CH3_REG                    0xC
-#define AD7998_DATALOW_CH4_REG                 0xD
-#define AD7998_DATAHIGH_CH4_REG                        0xE
-#define AD7998_HYST_CH4_REG                    0xF
+
+#define AD7998_DATALOW_REG(x)                  ((x) * 3 + 0x4)
+#define AD7998_DATAHIGH_REG(x)                 ((x) * 3 + 0x5)
+#define AD7998_HYST_REG(x)                     ((x) * 3 + 0x6)
 
 #define AD7998_CYC_MASK                                0x7
 #define AD7998_CYC_DIS                         0x0
index 2b2049c8bc6ba969896168f6b22b58ed7336afcc..9428be82b655f0d6456e5d4c0dec3d0d6661dcc2 100644 (file)
@@ -163,7 +163,6 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
 {
        int ret;
        struct ad799x_state *st = iio_priv(indio_dev);
-       unsigned int scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
@@ -180,10 +179,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
                        RES_MASK(chan->scan_type.realbits);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->int_vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -254,98 +252,70 @@ error_ret_mutex:
 }
 
 static int ad799x_read_event_config(struct iio_dev *indio_dev,
-                                   u64 event_code)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir)
 {
        return 1;
 }
 
-static const u8 ad799x_threshold_addresses[][2] = {
-       { AD7998_DATALOW_CH1_REG, AD7998_DATAHIGH_CH1_REG },
-       { AD7998_DATALOW_CH2_REG, AD7998_DATAHIGH_CH2_REG },
-       { AD7998_DATALOW_CH3_REG, AD7998_DATAHIGH_CH3_REG },
-       { AD7998_DATALOW_CH4_REG, AD7998_DATAHIGH_CH4_REG },
-};
+static unsigned int ad799x_threshold_reg(const struct iio_chan_spec *chan,
+                                        enum iio_event_direction dir,
+                                        enum iio_event_info info)
+{
+       switch (info) {
+       case IIO_EV_INFO_VALUE:
+               if (dir == IIO_EV_DIR_FALLING)
+                       return AD7998_DATALOW_REG(chan->channel);
+               else
+                       return AD7998_DATAHIGH_REG(chan->channel);
+       case IIO_EV_INFO_HYSTERESIS:
+               return AD7998_HYST_REG(chan->channel);
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
 
 static int ad799x_write_event_value(struct iio_dev *indio_dev,
-                                   u64 event_code,
-                                   int val)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir,
+                                   enum iio_event_info info,
+                                   int val, int val2)
 {
        int ret;
        struct ad799x_state *st = iio_priv(indio_dev);
-       int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                          IIO_EV_DIR_FALLING);
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 
        mutex_lock(&indio_dev->mlock);
-       ret = ad799x_i2c_write16(st,
-                                ad799x_threshold_addresses[number][direction],
-                                val);
+       ret = ad799x_i2c_write16(st, ad799x_threshold_reg(chan, dir, info),
+               val);
        mutex_unlock(&indio_dev->mlock);
 
        return ret;
 }
 
 static int ad799x_read_event_value(struct iio_dev *indio_dev,
-                                   u64 event_code,
-                                   int *val)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir,
+                                   enum iio_event_info info,
+                                   int *val, int *val2)
 {
        int ret;
        struct ad799x_state *st = iio_priv(indio_dev);
-       int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                          IIO_EV_DIR_FALLING);
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
        u16 valin;
 
        mutex_lock(&indio_dev->mlock);
-       ret = ad799x_i2c_read16(st,
-                               ad799x_threshold_addresses[number][direction],
-                               &valin);
+       ret = ad799x_i2c_read16(st, ad799x_threshold_reg(chan, dir, info),
+               &valin);
        mutex_unlock(&indio_dev->mlock);
        if (ret < 0)
                return ret;
        *val = valin;
 
-       return 0;
-}
-
-static ssize_t ad799x_read_channel_config(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad799x_state *st = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-       int ret;
-       u16 val;
-       ret = ad799x_i2c_read16(st, this_attr->address, &val);
-       if (ret)
-               return ret;
-
-       return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t ad799x_write_channel_config(struct device *dev,
-                                        struct device_attribute *attr,
-                                        const char *buf,
-                                        size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad799x_state *st = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-       long val;
-       int ret;
-
-       ret = kstrtol(buf, 10, &val);
-       if (ret)
-               return ret;
-
-       mutex_lock(&indio_dev->mlock);
-       ret = ad799x_i2c_write16(st, this_attr->address, val);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret ? ret : len;
+       return IIO_VAL_INT;
 }
 
 static irqreturn_t ad799x_event_handler(int irq, void *private)
@@ -383,60 +353,19 @@ done:
        return IRQ_HANDLED;
 }
 
-static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH1_REG);
-
-static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH2_REG);
-
-static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH3_REG);
-
-static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH4_REG);
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
                              ad799x_read_frequency,
                              ad799x_write_frequency);
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0");
 
-static struct attribute *ad7993_4_7_8_event_attributes[] = {
-       &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
-       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
-       NULL,
-};
-
-static struct attribute_group ad7993_4_7_8_event_attrs_group = {
-       .attrs = ad7993_4_7_8_event_attributes,
-       .name = "events",
-};
-
-static struct attribute *ad7992_event_attributes[] = {
-       &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
+static struct attribute *ad799x_event_attributes[] = {
        &iio_dev_attr_sampling_frequency.dev_attr.attr,
        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        NULL,
 };
 
-static struct attribute_group ad7992_event_attrs_group = {
-       .attrs = ad7992_event_attributes,
+static struct attribute_group ad799x_event_attrs_group = {
+       .attrs = ad799x_event_attributes,
        .name = "events",
 };
 
@@ -445,29 +374,35 @@ static const struct iio_info ad7991_info = {
        .driver_module = THIS_MODULE,
 };
 
-static const struct iio_info ad7992_info = {
-       .read_raw = &ad799x_read_raw,
-       .event_attrs = &ad7992_event_attrs_group,
-       .read_event_config = &ad799x_read_event_config,
-       .read_event_value = &ad799x_read_event_value,
-       .write_event_value = &ad799x_write_event_value,
-       .driver_module = THIS_MODULE,
-};
-
 static const struct iio_info ad7993_4_7_8_info = {
        .read_raw = &ad799x_read_raw,
-       .event_attrs = &ad7993_4_7_8_event_attrs_group,
-       .read_event_config = &ad799x_read_event_config,
-       .read_event_value = &ad799x_read_event_value,
-       .write_event_value = &ad799x_write_event_value,
+       .event_attrs = &ad799x_event_attrs_group,
+       .read_event_config_new = &ad799x_read_event_config,
+       .read_event_value_new = &ad799x_read_event_value,
+       .write_event_value_new = &ad799x_write_event_value,
        .driver_module = THIS_MODULE,
        .update_scan_mode = ad7997_8_update_scan_mode,
 };
 
-#define AD799X_EV_MASK (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
-                       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec ad799x_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE),
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_EITHER,
+               .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+       },
+};
 
-#define AD799X_CHANNEL(_index, _realbits, _evmask) { \
+#define _AD799X_CHANNEL(_index, _realbits, _ev_spec, _num_ev_spec) { \
        .type = IIO_VOLTAGE, \
        .indexed = 1, \
        .channel = (_index), \
@@ -475,16 +410,24 @@ static const struct iio_info ad7993_4_7_8_info = {
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
        .scan_index = (_index), \
        .scan_type = IIO_ST('u', _realbits, 16, 12 - (_realbits)), \
-       .event_mask = (_evmask), \
+       .event_spec = _ev_spec, \
+       .num_event_specs = _num_ev_spec, \
 }
 
+#define AD799X_CHANNEL(_index, _realbits) \
+       _AD799X_CHANNEL(_index, _realbits, NULL, 0)
+
+#define AD799X_CHANNEL_WITH_EVENTS(_index, _realbits) \
+       _AD799X_CHANNEL(_index, _realbits, ad799x_events, \
+               ARRAY_SIZE(ad799x_events))
+
 static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        [ad7991] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, 0),
-                       AD799X_CHANNEL(1, 12, 0),
-                       AD799X_CHANNEL(2, 12, 0),
-                       AD799X_CHANNEL(3, 12, 0),
+                       AD799X_CHANNEL(0, 12),
+                       AD799X_CHANNEL(1, 12),
+                       AD799X_CHANNEL(2, 12),
+                       AD799X_CHANNEL(3, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -492,10 +435,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7995] = {
                .channel = {
-                       AD799X_CHANNEL(0, 10, 0),
-                       AD799X_CHANNEL(1, 10, 0),
-                       AD799X_CHANNEL(2, 10, 0),
-                       AD799X_CHANNEL(3, 10, 0),
+                       AD799X_CHANNEL(0, 10),
+                       AD799X_CHANNEL(1, 10),
+                       AD799X_CHANNEL(2, 10),
+                       AD799X_CHANNEL(3, 10),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -503,10 +446,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7999] = {
                .channel = {
-                       AD799X_CHANNEL(0, 8, 0),
-                       AD799X_CHANNEL(1, 8, 0),
-                       AD799X_CHANNEL(2, 8, 0),
-                       AD799X_CHANNEL(3, 8, 0),
+                       AD799X_CHANNEL(0, 8),
+                       AD799X_CHANNEL(1, 8),
+                       AD799X_CHANNEL(2, 8),
+                       AD799X_CHANNEL(3, 8),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -514,20 +457,20 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7992] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(3),
                },
                .num_channels = 3,
                .default_config = AD7998_ALERT_EN,
-               .info = &ad7992_info,
+               .info = &ad7993_4_7_8_info,
        },
        [ad7993] = {
                .channel = {
-                       AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 10),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -536,10 +479,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7994] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -548,14 +491,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7997] = {
                .channel = {
-                       AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(4, 10, 0),
-                       AD799X_CHANNEL(5, 10, 0),
-                       AD799X_CHANNEL(6, 10, 0),
-                       AD799X_CHANNEL(7, 10, 0),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 10),
+                       AD799X_CHANNEL(4, 10),
+                       AD799X_CHANNEL(5, 10),
+                       AD799X_CHANNEL(6, 10),
+                       AD799X_CHANNEL(7, 10),
                        IIO_CHAN_SOFT_TIMESTAMP(8),
                },
                .num_channels = 9,
@@ -564,14 +507,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7998] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(4, 12, 0),
-                       AD799X_CHANNEL(5, 12, 0),
-                       AD799X_CHANNEL(6, 12, 0),
-                       AD799X_CHANNEL(7, 12, 0),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 12),
+                       AD799X_CHANNEL(4, 12),
+                       AD799X_CHANNEL(5, 12),
+                       AD799X_CHANNEL(6, 12),
+                       AD799X_CHANNEL(7, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(8),
                },
                .num_channels = 9,
@@ -586,8 +529,9 @@ static int ad799x_probe(struct i2c_client *client,
        int ret;
        struct ad799x_platform_data *pdata = client->dev.platform_data;
        struct ad799x_state *st;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -606,11 +550,11 @@ static int ad799x_probe(struct i2c_client *client,
 
        st->int_vref_mv = pdata->vref_mv;
 
-       st->reg = regulator_get(&client->dev, "vcc");
+       st->reg = devm_regulator_get(&client->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
        st->client = client;
 
@@ -650,10 +594,6 @@ error_cleanup_ring:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -668,12 +608,9 @@ static int ad799x_remove(struct i2c_client *client)
                free_irq(client->irq, indio_dev);
 
        ad799x_ring_cleanup(indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
        kfree(st->rx_buf);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index c2ebae12ee1961852e83f73a818860d7b8af7550..0ff6c03a483ec0bd72909c0eb49228baf2f555c7 100644 (file)
@@ -35,7 +35,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad799x_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        int b_sent;
        u8 cmd;
 
@@ -65,13 +64,8 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
        if (b_sent < 0)
                goto out;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               memcpy(st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
-                       &time_ns, sizeof(time_ns));
-
-       iio_push_to_buffers(indio_dev, st->rx_buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+                       iio_get_time_ns());
 out:
        iio_trigger_notify_done(indio_dev->trig);
 
index 9a4bb0999b51244d3e621610aa626477f5f851f5..ef0a21d8ce15ce76ea4ae39bb72d0523f3bfc230 100644 (file)
@@ -137,43 +137,39 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "failed to get platform I/O memory\n");
-               retval = -EBUSY;
-               goto errout1;
+               return -EBUSY;
        }
 
-       iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info));
-       if (!iodev) {
-               dev_err(&pdev->dev, "failed allocating iio device\n");
-               retval = -ENOMEM;
-               goto errout1;
-       }
+       iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+       if (!iodev)
+               return -ENOMEM;
 
        info = iio_priv(iodev);
 
-       info->adc_base = ioremap(res->start, resource_size(res));
+       info->adc_base = devm_ioremap(&pdev->dev, res->start,
+                                               resource_size(res));
        if (!info->adc_base) {
                dev_err(&pdev->dev, "failed mapping memory\n");
-               retval = -EBUSY;
-               goto errout2;
+               return -EBUSY;
        }
 
-       info->clk = clk_get(&pdev->dev, NULL);
+       info->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(info->clk)) {
                dev_err(&pdev->dev, "failed getting clock\n");
-               goto errout3;
+               return PTR_ERR(info->clk);
        }
 
        irq = platform_get_irq(pdev, 0);
-       if ((irq < 0) || (irq >= NR_IRQS)) {
+       if (irq <= 0) {
                dev_err(&pdev->dev, "failed getting interrupt resource\n");
-               retval = -EINVAL;
-               goto errout4;
+               return -EINVAL;
        }
 
-       retval = request_irq(irq, lpc32xx_adc_isr, 0, MOD_NAME, info);
+       retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
+                                                               MOD_NAME, info);
        if (retval < 0) {
                dev_err(&pdev->dev, "failed requesting interrupt\n");
-               goto errout4;
+               return retval;
        }
 
        platform_set_drvdata(pdev, iodev);
@@ -189,35 +185,18 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
 
        retval = iio_device_register(iodev);
        if (retval)
-               goto errout5;
+               return retval;
 
        dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
 
        return 0;
-
-errout5:
-       free_irq(irq, info);
-errout4:
-       clk_put(info->clk);
-errout3:
-       iounmap(info->adc_base);
-errout2:
-       iio_device_free(iodev);
-errout1:
-       return retval;
 }
 
 static int lpc32xx_adc_remove(struct platform_device *pdev)
 {
        struct iio_dev *iodev = platform_get_drvdata(pdev);
-       struct lpc32xx_adc_info *info = iio_priv(iodev);
-       int irq = platform_get_irq(pdev, 0);
 
        iio_device_unregister(iodev);
-       free_irq(irq, info);
-       clk_put(info->clk);
-       iounmap(info->adc_base);
-       iio_device_free(iodev);
 
        return 0;
 }
index a08c1736458b4f2cfab9af87c408a65e430d8020..aeae76b77be5732eebd2756a8c07353f99d4be0c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/clk.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
@@ -129,11 +130,24 @@ enum mxs_lradc_ts {
        MXS_LRADC_TOUCHSCREEN_5WIRE,
 };
 
+/*
+ * Touchscreen handling
+ */
+enum lradc_ts_plate {
+       LRADC_TOUCH = 0,
+       LRADC_SAMPLE_X,
+       LRADC_SAMPLE_Y,
+       LRADC_SAMPLE_PRESSURE,
+       LRADC_SAMPLE_VALID,
+};
+
 struct mxs_lradc {
        struct device           *dev;
        void __iomem            *base;
        int                     irq[13];
 
+       struct clk              *clk;
+
        uint32_t                *buffer;
        struct iio_trigger      *trig;
 
@@ -169,32 +183,63 @@ struct mxs_lradc {
 #define CHAN_MASK_TOUCHSCREEN_4WIRE    (0xf << 2)
 #define CHAN_MASK_TOUCHSCREEN_5WIRE    (0x1f << 2)
        enum mxs_lradc_ts       use_touchscreen;
-       bool                    stop_touchscreen;
        bool                    use_touchbutton;
 
        struct input_dev        *ts_input;
-       struct work_struct      ts_work;
+
+       enum mxs_lradc_id       soc;
+       enum lradc_ts_plate     cur_plate; /* statemachine */
+       bool                    ts_valid;
+       unsigned                ts_x_pos;
+       unsigned                ts_y_pos;
+       unsigned                ts_pressure;
+
+       /* handle touchscreen's physical behaviour */
+       /* samples per coordinate */
+       unsigned                over_sample_cnt;
+       /* time clocks between samples */
+       unsigned                over_sample_delay;
+       /* time in clocks to wait after the plates where switched */
+       unsigned                settling_delay;
 };
 
 #define        LRADC_CTRL0                             0x00
-#define        LRADC_CTRL0_TOUCH_DETECT_ENABLE         (1 << 23)
-#define        LRADC_CTRL0_TOUCH_SCREEN_TYPE           (1 << 22)
-#define        LRADC_CTRL0_YNNSW       /* YM */        (1 << 21)
-#define        LRADC_CTRL0_YPNSW       /* YP */        (1 << 20)
-#define        LRADC_CTRL0_YPPSW       /* YP */        (1 << 19)
-#define        LRADC_CTRL0_XNNSW       /* XM */        (1 << 18)
-#define        LRADC_CTRL0_XNPSW       /* XM */        (1 << 17)
-#define        LRADC_CTRL0_XPPSW       /* XP */        (1 << 16)
-#define        LRADC_CTRL0_PLATE_MASK                  (0x3f << 16)
+# define LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE  (1 << 23)
+# define LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE    (1 << 22)
+# define LRADC_CTRL0_MX28_YNNSW        /* YM */        (1 << 21)
+# define LRADC_CTRL0_MX28_YPNSW        /* YP */        (1 << 20)
+# define LRADC_CTRL0_MX28_YPPSW        /* YP */        (1 << 19)
+# define LRADC_CTRL0_MX28_XNNSW        /* XM */        (1 << 18)
+# define LRADC_CTRL0_MX28_XNPSW        /* XM */        (1 << 17)
+# define LRADC_CTRL0_MX28_XPPSW        /* XP */        (1 << 16)
+
+# define LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE  (1 << 20)
+# define LRADC_CTRL0_MX23_YM                   (1 << 19)
+# define LRADC_CTRL0_MX23_XM                   (1 << 18)
+# define LRADC_CTRL0_MX23_YP                   (1 << 17)
+# define LRADC_CTRL0_MX23_XP                   (1 << 16)
+
+# define LRADC_CTRL0_MX28_PLATE_MASK \
+               (LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE | \
+               LRADC_CTRL0_MX28_YNNSW | LRADC_CTRL0_MX28_YPNSW | \
+               LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW | \
+               LRADC_CTRL0_MX28_XNPSW | LRADC_CTRL0_MX28_XPPSW)
+
+# define LRADC_CTRL0_MX23_PLATE_MASK \
+               (LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE | \
+               LRADC_CTRL0_MX23_YM | LRADC_CTRL0_MX23_XM | \
+               LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XP)
 
 #define        LRADC_CTRL1                             0x10
 #define        LRADC_CTRL1_TOUCH_DETECT_IRQ_EN         (1 << 24)
 #define        LRADC_CTRL1_LRADC_IRQ_EN(n)             (1 << ((n) + 16))
-#define        LRADC_CTRL1_LRADC_IRQ_EN_MASK           (0x1fff << 16)
+#define        LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK      (0x1fff << 16)
+#define        LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK      (0x01ff << 16)
 #define        LRADC_CTRL1_LRADC_IRQ_EN_OFFSET         16
 #define        LRADC_CTRL1_TOUCH_DETECT_IRQ            (1 << 8)
 #define        LRADC_CTRL1_LRADC_IRQ(n)                (1 << (n))
-#define        LRADC_CTRL1_LRADC_IRQ_MASK              0x1fff
+#define        LRADC_CTRL1_MX28_LRADC_IRQ_MASK         0x1fff
+#define        LRADC_CTRL1_MX23_LRADC_IRQ_MASK         0x01ff
 #define        LRADC_CTRL1_LRADC_IRQ_OFFSET            0
 
 #define        LRADC_CTRL2                             0x20
@@ -207,19 +252,33 @@ struct mxs_lradc {
 #define        LRADC_CH_ACCUMULATE                     (1 << 29)
 #define        LRADC_CH_NUM_SAMPLES_MASK               (0x1f << 24)
 #define        LRADC_CH_NUM_SAMPLES_OFFSET             24
+#define        LRADC_CH_NUM_SAMPLES(x) \
+                               ((x) << LRADC_CH_NUM_SAMPLES_OFFSET)
 #define        LRADC_CH_VALUE_MASK                     0x3ffff
 #define        LRADC_CH_VALUE_OFFSET                   0
 
 #define        LRADC_DELAY(n)                          (0xd0 + (0x10 * (n)))
 #define        LRADC_DELAY_TRIGGER_LRADCS_MASK         (0xff << 24)
 #define        LRADC_DELAY_TRIGGER_LRADCS_OFFSET       24
+#define        LRADC_DELAY_TRIGGER(x) \
+                               (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
+                               LRADC_DELAY_TRIGGER_LRADCS_MASK)
 #define        LRADC_DELAY_KICK                        (1 << 20)
 #define        LRADC_DELAY_TRIGGER_DELAYS_MASK         (0xf << 16)
 #define        LRADC_DELAY_TRIGGER_DELAYS_OFFSET       16
+#define        LRADC_DELAY_TRIGGER_DELAYS(x) \
+                               (((x) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) & \
+                               LRADC_DELAY_TRIGGER_DELAYS_MASK)
 #define        LRADC_DELAY_LOOP_COUNT_MASK             (0x1f << 11)
 #define        LRADC_DELAY_LOOP_COUNT_OFFSET           11
+#define        LRADC_DELAY_LOOP(x) \
+                               (((x) << LRADC_DELAY_LOOP_COUNT_OFFSET) & \
+                               LRADC_DELAY_LOOP_COUNT_MASK)
 #define        LRADC_DELAY_DELAY_MASK                  0x7ff
 #define        LRADC_DELAY_DELAY_OFFSET                0
+#define        LRADC_DELAY_DELAY(x) \
+                               (((x) << LRADC_DELAY_DELAY_OFFSET) & \
+                               LRADC_DELAY_DELAY_MASK)
 
 #define        LRADC_CTRL4                             0x140
 #define        LRADC_CTRL4_LRADCSELECT_MASK(n)         (0xf << ((n) * 4))
@@ -228,6 +287,475 @@ struct mxs_lradc {
 #define LRADC_RESOLUTION                       12
 #define LRADC_SINGLE_SAMPLE_MASK               ((1 << LRADC_RESOLUTION) - 1)
 
+static void mxs_lradc_reg_set(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+       writel(val, lradc->base + reg + STMP_OFFSET_REG_SET);
+}
+
+static void mxs_lradc_reg_clear(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+       writel(val, lradc->base + reg + STMP_OFFSET_REG_CLR);
+}
+
+static void mxs_lradc_reg_wrt(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+       writel(val, lradc->base + reg);
+}
+
+static u32 mxs_lradc_plate_mask(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_PLATE_MASK;
+       else
+               return LRADC_CTRL0_MX28_PLATE_MASK;
+}
+
+static u32 mxs_lradc_irq_en_mask(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK;
+       else
+               return LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK;
+}
+
+static u32 mxs_lradc_irq_mask(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL1_MX23_LRADC_IRQ_MASK;
+       else
+               return LRADC_CTRL1_MX28_LRADC_IRQ_MASK;
+}
+
+static u32 mxs_lradc_touch_detect_bit(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE;
+       else
+               return LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE;
+}
+
+static u32 mxs_lradc_drive_x_plate(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM;
+       else
+               return LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW;
+}
+
+static u32 mxs_lradc_drive_y_plate(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM;
+       else
+               return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW;
+}
+
+static u32 mxs_lradc_drive_pressure(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM;
+       else
+               return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW;
+}
+
+static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
+{
+       return !!(readl(lradc->base + LRADC_STATUS) &
+                                       LRADC_STATUS_TOUCH_DETECT_RAW);
+}
+
+static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
+{
+       /*
+        * prepare for oversampling conversion
+        *
+        * from the datasheet:
+        * "The ACCUMULATE bit in the appropriate channel register
+        * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
+        * otherwise, the IRQs will not fire."
+        */
+       mxs_lradc_reg_wrt(lradc, LRADC_CH_ACCUMULATE |
+                       LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1),
+                       LRADC_CH(ch));
+
+       /* from the datasheet:
+        * "Software must clear this register in preparation for a
+        * multi-cycle accumulation.
+        */
+       mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
+
+       /* prepare the delay/loop unit according to the oversampling count */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
+               LRADC_DELAY_TRIGGER_DELAYS(0) |
+               LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
+               LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+                       LRADC_DELAY(3));
+
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+                       LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+                       LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+
+       /* wake us again, when the complete conversion is done */
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
+       /*
+        * after changing the touchscreen plates setting
+        * the signals need some initial time to settle. Start the
+        * SoC's delay unit and start the conversion later
+        * and automatically.
+        */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
+               LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
+               LRADC_DELAY_KICK |
+               LRADC_DELAY_DELAY(lradc->settling_delay),
+                       LRADC_DELAY(2));
+}
+
+/*
+ * Pressure detection is special:
+ * We want to do both required measurements for the pressure detection in
+ * one turn. Use the hardware features to chain both conversions and let the
+ * hardware report one interrupt if both conversions are done
+ */
+static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
+                                                       unsigned ch2)
+{
+       u32 reg;
+
+       /*
+        * prepare for oversampling conversion
+        *
+        * from the datasheet:
+        * "The ACCUMULATE bit in the appropriate channel register
+        * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
+        * otherwise, the IRQs will not fire."
+        */
+       reg = LRADC_CH_ACCUMULATE |
+               LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1);
+       mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch1));
+       mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch2));
+
+       /* from the datasheet:
+        * "Software must clear this register in preparation for a
+        * multi-cycle accumulation.
+        */
+       mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch1));
+       mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch2));
+
+       /* prepare the delay/loop unit according to the oversampling count */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch1) |
+               LRADC_DELAY_TRIGGER(1 << ch2) | /* start both channels */
+               LRADC_DELAY_TRIGGER_DELAYS(0) |
+               LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
+               LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+                                       LRADC_DELAY(3));
+
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+                       LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+                       LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+
+       /* wake us again, when the conversions are done */
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
+       /*
+        * after changing the touchscreen plates setting
+        * the signals need some initial time to settle. Start the
+        * SoC's delay unit and start the conversion later
+        * and automatically.
+        */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
+               LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
+               LRADC_DELAY_KICK |
+               LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2));
+}
+
+static unsigned mxs_lradc_read_raw_channel(struct mxs_lradc *lradc,
+                                                       unsigned channel)
+{
+       u32 reg;
+       unsigned num_samples, val;
+
+       reg = readl(lradc->base + LRADC_CH(channel));
+       if (reg & LRADC_CH_ACCUMULATE)
+               num_samples = lradc->over_sample_cnt;
+       else
+               num_samples = 1;
+
+       val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
+       return val / num_samples;
+}
+
+static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
+                                               unsigned ch1, unsigned ch2)
+{
+       u32 reg, mask;
+       unsigned pressure, m1, m2;
+
+       mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
+       reg = readl(lradc->base + LRADC_CTRL1) & mask;
+
+       while (reg != mask) {
+               reg = readl(lradc->base + LRADC_CTRL1) & mask;
+               dev_dbg(lradc->dev, "One channel is still busy: %X\n", reg);
+       }
+
+       m1 = mxs_lradc_read_raw_channel(lradc, ch1);
+       m2 = mxs_lradc_read_raw_channel(lradc, ch2);
+
+       if (m2 == 0) {
+               dev_warn(lradc->dev, "Cannot calculate pressure\n");
+               return 1 << (LRADC_RESOLUTION - 1);
+       }
+
+       /* simply scale the value from 0 ... max ADC resolution */
+       pressure = m1;
+       pressure *= (1 << LRADC_RESOLUTION);
+       pressure /= m2;
+
+       dev_dbg(lradc->dev, "Pressure = %u\n", pressure);
+       return pressure;
+}
+
+#define TS_CH_XP 2
+#define TS_CH_YP 3
+#define TS_CH_XM 4
+#define TS_CH_YM 5
+
+static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
+{
+       u32 reg;
+       int val;
+
+       reg = readl(lradc->base + LRADC_CTRL1);
+
+       /* only channels 3 to 5 are of interest here */
+       if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
+                       LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
+               val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
+       } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
+                       LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
+               val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
+       } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
+                       LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
+               val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
+       } else {
+               return -EIO;
+       }
+
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
+
+       return val;
+}
+
+/*
+ * YP(open)--+-------------+
+ *           |             |--+
+ *           |             |  |
+ *    YM(-)--+-------------+  |
+ *             +--------------+
+ *             |              |
+ *         XP(weak+)        XM(open)
+ *
+ * "weak+" means 200k Ohm VDDIO
+ * (-) means GND
+ */
+static void mxs_lradc_setup_touch_detection(struct mxs_lradc *lradc)
+{
+       /*
+        * In order to detect a touch event the 'touch detect enable' bit
+        * enables:
+        *  - a weak pullup to the X+ connector
+        *  - a strong ground at the Y- connector
+        */
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_touch_detect_bit(lradc),
+                               LRADC_CTRL0);
+}
+
+/*
+ * YP(meas)--+-------------+
+ *           |             |--+
+ *           |             |  |
+ * YM(open)--+-------------+  |
+ *             +--------------+
+ *             |              |
+ *           XP(+)          XM(-)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
+{
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
+
+       lradc->cur_plate = LRADC_SAMPLE_X;
+       mxs_lradc_setup_ts_channel(lradc, TS_CH_YP);
+}
+
+/*
+ *   YP(+)--+-------------+
+ *          |             |--+
+ *          |             |  |
+ *   YM(-)--+-------------+  |
+ *            +--------------+
+ *            |              |
+ *         XP(open)        XM(meas)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
+{
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
+
+       lradc->cur_plate = LRADC_SAMPLE_Y;
+       mxs_lradc_setup_ts_channel(lradc, TS_CH_XM);
+}
+
+/*
+ *    YP(+)--+-------------+
+ *           |             |--+
+ *           |             |  |
+ * YM(meas)--+-------------+  |
+ *             +--------------+
+ *             |              |
+ *          XP(meas)        XM(-)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
+{
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
+
+       lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
+       mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
+}
+
+static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
+{
+       mxs_lradc_setup_touch_detection(lradc);
+
+       lradc->cur_plate = LRADC_TOUCH;
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
+                               LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+}
+
+static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
+{
+       input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
+       input_report_abs(lradc->ts_input, ABS_Y, lradc->ts_y_pos);
+       input_report_abs(lradc->ts_input, ABS_PRESSURE, lradc->ts_pressure);
+       input_report_key(lradc->ts_input, BTN_TOUCH, 1);
+       input_sync(lradc->ts_input);
+}
+
+static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
+{
+       mxs_lradc_setup_touch_detection(lradc);
+       lradc->cur_plate = LRADC_SAMPLE_VALID;
+       /*
+        * start a dummy conversion to burn time to settle the signals
+        * note: we are not interested in the conversion's value
+        */
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5));
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1);
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) |
+               LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
+                       LRADC_DELAY(2));
+}
+
+/*
+ * in order to avoid false measurements, report only samples where
+ * the surface is still touched after the position measurement
+ */
+static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
+{
+       /* if it is still touched, report the sample */
+       if (valid && mxs_lradc_check_touch_event(lradc)) {
+               lradc->ts_valid = true;
+               mxs_lradc_report_ts_event(lradc);
+       }
+
+       /* if it is even still touched, continue with the next measurement */
+       if (mxs_lradc_check_touch_event(lradc)) {
+               mxs_lradc_prepare_y_pos(lradc);
+               return;
+       }
+
+       if (lradc->ts_valid) {
+               /* signal the release */
+               lradc->ts_valid = false;
+               input_report_key(lradc->ts_input, BTN_TOUCH, 0);
+               input_sync(lradc->ts_input);
+       }
+
+       /* if it is released, wait for the next touch via IRQ */
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+}
+
+/* touchscreen's state machine */
+static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
+{
+       int val;
+
+       switch (lradc->cur_plate) {
+       case LRADC_TOUCH:
+               /*
+                * start with the Y-pos, because it uses nearly the same plate
+                * settings like the touch detection
+                */
+               if (mxs_lradc_check_touch_event(lradc)) {
+                       mxs_lradc_reg_clear(lradc,
+                                       LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+                                       LRADC_CTRL1);
+                       mxs_lradc_prepare_y_pos(lradc);
+               }
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
+                                       LRADC_CTRL1);
+               return;
+
+       case LRADC_SAMPLE_Y:
+               val = mxs_lradc_read_ts_channel(lradc);
+               if (val < 0) {
+                       mxs_lradc_enable_touch_detection(lradc); /* re-start */
+                       return;
+               }
+               lradc->ts_y_pos = val;
+               mxs_lradc_prepare_x_pos(lradc);
+               return;
+
+       case LRADC_SAMPLE_X:
+               val = mxs_lradc_read_ts_channel(lradc);
+               if (val < 0) {
+                       mxs_lradc_enable_touch_detection(lradc); /* re-start */
+                       return;
+               }
+               lradc->ts_x_pos = val;
+               mxs_lradc_prepare_pressure(lradc);
+               return;
+
+       case LRADC_SAMPLE_PRESSURE:
+               lradc->ts_pressure =
+                       mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
+               mxs_lradc_complete_touch_event(lradc);
+               return;
+
+       case LRADC_SAMPLE_VALID:
+               val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */
+               mxs_lradc_finish_touch_event(lradc, 1);
+               break;
+       }
+}
+
 /*
  * Raw I/O operations
  */
@@ -262,21 +790,20 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
         * Virtual channel 0 is always used here as the others are always not
         * used if doing raw sampling.
         */
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-       writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+                       LRADC_CTRL1);
+       mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
        /* Clean the slot's previous content, then set new one. */
-       writel(LRADC_CTRL4_LRADCSELECT_MASK(0),
-               lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
-       writel(chan->channel, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0), LRADC_CTRL4);
+       mxs_lradc_reg_set(lradc, chan->channel, LRADC_CTRL4);
 
-       writel(0, lradc->base + LRADC_CH(0));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
 
        /* Enable the IRQ and start sampling the channel. */
-       writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-       writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, 1 << 0, LRADC_CTRL0);
 
        /* Wait for completion on the channel, 1 second max. */
        ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
@@ -290,8 +817,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
        ret = IIO_VAL_INT;
 
 err:
-       writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
 
        mutex_unlock(&lradc->lock);
 
@@ -303,220 +829,33 @@ static const struct iio_info mxs_lradc_iio_info = {
        .read_raw               = mxs_lradc_read_raw,
 };
 
-/*
- * Touchscreen handling
- */
-enum lradc_ts_plate {
-       LRADC_SAMPLE_X,
-       LRADC_SAMPLE_Y,
-       LRADC_SAMPLE_PRESSURE,
-};
-
-static int mxs_lradc_ts_touched(struct mxs_lradc *lradc)
-{
-       uint32_t reg;
-
-       /* Enable touch detection. */
-       writel(LRADC_CTRL0_PLATE_MASK,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-       writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-       msleep(LRADC_TS_SAMPLE_DELAY_MS);
-
-       reg = readl(lradc->base + LRADC_STATUS);
-
-       return reg & LRADC_STATUS_TOUCH_DETECT_RAW;
-}
-
-static int32_t mxs_lradc_ts_sample(struct mxs_lradc *lradc,
-                               enum lradc_ts_plate plate, int change)
-{
-       unsigned long delay, jiff;
-       uint32_t reg, ctrl0 = 0, chan = 0;
-       /* The touchscreen always uses CTRL4 slot #7. */
-       const uint8_t slot = 7;
-       uint32_t val;
-
-       /*
-        * There are three correct configurations of the controller sampling
-        * the touchscreen, each of these configuration provides different
-        * information from the touchscreen.
-        *
-        * The following table describes the sampling configurations:
-        * +-------------+-------+-------+-------+
-        * | Wire \ Axis |   X   |   Y   |   Z   |
-        * +---------------------+-------+-------+
-        * |   X+ (CH2)  |   HI  |   TS  |   TS  |
-        * +-------------+-------+-------+-------+
-        * |   X- (CH4)  |   LO  |   SH  |   HI  |
-        * +-------------+-------+-------+-------+
-        * |   Y+ (CH3)  |   SH  |   HI  |   HI  |
-        * +-------------+-------+-------+-------+
-        * |   Y- (CH5)  |   TS  |   LO  |   SH  |
-        * +-------------+-------+-------+-------+
-        *
-        * HI ... strong '1'  ; LO ... strong '0'
-        * SH ... sample here ; TS ... tri-state
-        *
-        * There are a few other ways of obtaining the Z coordinate
-        * (aka. pressure), but the one in the table seems to be the
-        * most reliable one.
-        */
-       switch (plate) {
-       case LRADC_SAMPLE_X:
-               ctrl0 = LRADC_CTRL0_XPPSW | LRADC_CTRL0_XNNSW;
-               chan = 3;
-               break;
-       case LRADC_SAMPLE_Y:
-               ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_YNNSW;
-               chan = 4;
-               break;
-       case LRADC_SAMPLE_PRESSURE:
-               ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_XNNSW;
-               chan = 5;
-               break;
-       }
-
-       if (change) {
-               writel(LRADC_CTRL0_PLATE_MASK,
-                       lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-               writel(ctrl0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-               writel(LRADC_CTRL4_LRADCSELECT_MASK(slot),
-                       lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
-               writel(chan << LRADC_CTRL4_LRADCSELECT_OFFSET(slot),
-                       lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
-       }
-
-       writel(0xffffffff, lradc->base + LRADC_CH(slot) + STMP_OFFSET_REG_CLR);
-       writel(1 << slot, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-       delay = jiffies + msecs_to_jiffies(LRADC_TS_SAMPLE_DELAY_MS);
-       do {
-               jiff = jiffies;
-               reg = readl_relaxed(lradc->base + LRADC_CTRL1);
-               if (reg & LRADC_CTRL1_LRADC_IRQ(slot))
-                       break;
-       } while (time_before(jiff, delay));
-
-       writel(LRADC_CTRL1_LRADC_IRQ(slot),
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-
-       if (time_after_eq(jiff, delay))
-               return -ETIMEDOUT;
-
-       val = readl(lradc->base + LRADC_CH(slot));
-       val &= LRADC_CH_VALUE_MASK;
-
-       return val;
-}
-
-static int32_t mxs_lradc_ts_sample_filter(struct mxs_lradc *lradc,
-                               enum lradc_ts_plate plate)
-{
-       int32_t val, tot = 0;
-       int i;
-
-       val = mxs_lradc_ts_sample(lradc, plate, 1);
-
-       /* Delay a bit so the touchscreen is stable. */
-       mdelay(2);
-
-       for (i = 0; i < LRADC_TS_SAMPLE_AMOUNT; i++) {
-               val = mxs_lradc_ts_sample(lradc, plate, 0);
-               tot += val;
-       }
-
-       return tot / LRADC_TS_SAMPLE_AMOUNT;
-}
-
-static void mxs_lradc_ts_work(struct work_struct *ts_work)
-{
-       struct mxs_lradc *lradc = container_of(ts_work,
-                               struct mxs_lradc, ts_work);
-       int val_x, val_y, val_p;
-       bool valid = false;
-
-       while (mxs_lradc_ts_touched(lradc)) {
-               /* Disable touch detector so we can sample the touchscreen. */
-               writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-                       lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-
-               if (likely(valid)) {
-                       input_report_abs(lradc->ts_input, ABS_X, val_x);
-                       input_report_abs(lradc->ts_input, ABS_Y, val_y);
-                       input_report_abs(lradc->ts_input, ABS_PRESSURE, val_p);
-                       input_report_key(lradc->ts_input, BTN_TOUCH, 1);
-                       input_sync(lradc->ts_input);
-               }
-
-               valid = false;
-
-               val_x = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_X);
-               if (val_x < 0)
-                       continue;
-               val_y = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_Y);
-               if (val_y < 0)
-                       continue;
-               val_p = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_PRESSURE);
-               if (val_p < 0)
-                       continue;
-
-               valid = true;
-       }
-
-       input_report_abs(lradc->ts_input, ABS_PRESSURE, 0);
-       input_report_key(lradc->ts_input, BTN_TOUCH, 0);
-       input_sync(lradc->ts_input);
-
-       /* Do not restart the TS IRQ if the driver is shutting down. */
-       if (lradc->stop_touchscreen)
-               return;
-
-       /* Restart the touchscreen interrupts. */
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-}
-
 static int mxs_lradc_ts_open(struct input_dev *dev)
 {
        struct mxs_lradc *lradc = input_get_drvdata(dev);
 
-       /* The touchscreen is starting. */
-       lradc->stop_touchscreen = false;
-
        /* Enable the touch-detect circuitry. */
-       writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-       /* Enable the touch-detect IRQ. */
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+       mxs_lradc_enable_touch_detection(lradc);
 
        return 0;
 }
 
-static void mxs_lradc_ts_close(struct input_dev *dev)
+static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
 {
-       struct mxs_lradc *lradc = input_get_drvdata(dev);
+       /* stop all interrupts from firing */
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
+               LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) |
+               LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5),
+               LRADC_CTRL1);
 
-       /* Indicate the touchscreen is stopping. */
-       lradc->stop_touchscreen = true;
-       mb();
-
-       /* Wait until touchscreen thread finishes any possible remnants. */
-       cancel_work_sync(&lradc->ts_work);
+       /* Power-down touchscreen touch-detect circuitry. */
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+}
 
-       /* Disable touchscreen touch-detect IRQ. */
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+static void mxs_lradc_ts_close(struct input_dev *dev)
+{
+       struct mxs_lradc *lradc = input_get_drvdata(dev);
 
-       /* Power-down touchscreen touch-detect circuitry. */
-       writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_disable_ts(lradc);
 }
 
 static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
@@ -529,10 +868,8 @@ static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
                return 0;
 
        input = input_allocate_device();
-       if (!input) {
-               dev_err(dev, "Failed to allocate TS device!\n");
+       if (!input)
                return -ENOMEM;
-       }
 
        input->name = DRIVER_NAME;
        input->id.bustype = BUS_HOST;
@@ -562,8 +899,7 @@ static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
        if (!lradc->use_touchscreen)
                return;
 
-       cancel_work_sync(&lradc->ts_work);
-
+       mxs_lradc_disable_ts(lradc);
        input_unregister_device(lradc->ts_input);
 }
 
@@ -576,31 +912,24 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
        struct mxs_lradc *lradc = iio_priv(iio);
        unsigned long reg = readl(lradc->base + LRADC_CTRL1);
        const uint32_t ts_irq_mask =
-               LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
-               LRADC_CTRL1_TOUCH_DETECT_IRQ;
+               LRADC_CTRL1_TOUCH_DETECT_IRQ |
+               LRADC_CTRL1_LRADC_IRQ(2) |
+               LRADC_CTRL1_LRADC_IRQ(3) |
+               LRADC_CTRL1_LRADC_IRQ(4) |
+               LRADC_CTRL1_LRADC_IRQ(5);
 
-       if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK))
+       if (!(reg & mxs_lradc_irq_mask(lradc)))
                return IRQ_NONE;
 
-       /*
-        * Touchscreen IRQ handling code has priority and therefore
-        * is placed here. In case touchscreen IRQ arrives, disable
-        * it ASAP
-        */
-       if (reg & LRADC_CTRL1_TOUCH_DETECT_IRQ) {
-               writel(ts_irq_mask,
-                       lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-               if (!lradc->stop_touchscreen)
-                       schedule_work(&lradc->ts_work);
-       }
+       if (lradc->use_touchscreen && (reg & ts_irq_mask))
+               mxs_lradc_handle_touch(lradc);
 
        if (iio_buffer_enabled(iio))
                iio_trigger_poll(iio->trig, iio_get_time_ns());
        else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
                complete(&lradc->completion);
 
-       writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc), LRADC_CTRL1);
 
        return IRQ_HANDLED;
 }
@@ -619,19 +948,13 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
 
        for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
                lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
-               writel(chan_value, lradc->base + LRADC_CH(j));
+               mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(j));
                lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
                lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
                j++;
        }
 
-       if (iio->scan_timestamp) {
-               s64 *timestamp = (s64 *)((u8 *)lradc->buffer +
-                                       ALIGN(j, sizeof(s64)));
-               *timestamp = pf->timestamp;
-       }
-
-       iio_push_to_buffers(iio, (u8 *)lradc->buffer);
+       iio_push_to_buffers_with_timestamp(iio, lradc->buffer, pf->timestamp);
 
        iio_trigger_notify_done(iio->trig);
 
@@ -644,7 +967,7 @@ static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
        struct mxs_lradc *lradc = iio_priv(iio);
        const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
 
-       writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st);
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
 
        return 0;
 }
@@ -716,38 +1039,30 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
                goto err_mem;
        }
 
-       ret = iio_sw_buffer_preenable(iio);
-       if (ret < 0)
-               goto err_buf;
-
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-       writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+                                                       LRADC_CTRL1);
+       mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
        for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
                ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
                ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
                ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
-               writel(chan_value, lradc->base + LRADC_CH(ofs));
+               mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
                bitmap_set(&enable, ofs, 1);
                ofs++;
        }
 
-       writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
-               lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
-
-       writel(ctrl4_clr, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
-       writel(ctrl4_set, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
-
-       writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-
-       writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
-               lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);
+       mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+                                       LRADC_DELAY_KICK, LRADC_DELAY(0));
+       mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
+       mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
+       mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
+                                       LRADC_DELAY(0));
 
        return 0;
 
-err_buf:
-       kfree(lradc->buffer);
 err_mem:
        mutex_unlock(&lradc->lock);
        return ret;
@@ -757,12 +1072,13 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
 {
        struct mxs_lradc *lradc = iio_priv(iio);
 
-       writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
-               lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+                                       LRADC_DELAY_KICK, LRADC_DELAY(0));
 
-       writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+                                       LRADC_CTRL1);
 
        kfree(lradc->buffer);
        mutex_unlock(&lradc->lock);
@@ -857,24 +1173,25 @@ static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
                return ret;
 
        /* Configure DELAY CHANNEL 0 for generic ADC sampling. */
-       writel(adc_cfg, lradc->base + LRADC_DELAY(0));
+       mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
 
        /* Disable remaining DELAY CHANNELs */
-       writel(0, lradc->base + LRADC_DELAY(1));
-       writel(0, lradc->base + LRADC_DELAY(2));
-       writel(0, lradc->base + LRADC_DELAY(3));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(1));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
 
        /* Configure the touchscreen type */
-       writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       if (lradc->soc == IMX28_LRADC) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
+                                                       LRADC_CTRL0);
 
-       if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE) {
-               writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
-                       lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+       if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
+               mxs_lradc_reg_set(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
+                               LRADC_CTRL0);
        }
 
        /* Start internal temperature sensing. */
-       writel(0, lradc->base + LRADC_CTRL2);
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
 
        return 0;
 }
@@ -883,11 +1200,10 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
 {
        int i;
 
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, mxs_lradc_irq_en_mask(lradc), LRADC_CTRL1);
 
        for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
-               writel(0, lradc->base + LRADC_DELAY(i));
+               mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
 }
 
 static const struct of_device_id mxs_lradc_dt_ids[] = {
@@ -897,6 +1213,52 @@ static const struct of_device_id mxs_lradc_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
 
+static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
+                                               struct device_node *lradc_node)
+{
+       int ret;
+       u32 ts_wires = 0, adapt;
+
+       ret = of_property_read_u32(lradc_node, "fsl,lradc-touchscreen-wires",
+                               &ts_wires);
+       if (ret)
+               return -ENODEV; /* touchscreen feature disabled */
+
+       switch (ts_wires) {
+       case 4:
+               lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
+               break;
+       case 5:
+               if (lradc->soc == IMX28_LRADC) {
+                       lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
+                       break;
+               }
+               /* fall through an error message for i.MX23 */
+       default:
+               dev_err(lradc->dev,
+                       "Unsupported number of touchscreen wires (%d)\n",
+                       ts_wires);
+               return -EINVAL;
+       }
+
+       lradc->over_sample_cnt = 4;
+       ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt);
+       if (ret == 0)
+               lradc->over_sample_cnt = adapt;
+
+       lradc->over_sample_delay = 2;
+       ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt);
+       if (ret == 0)
+               lradc->over_sample_delay = adapt;
+
+       lradc->settling_delay = 10;
+       ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt);
+       if (ret == 0)
+               lradc->settling_delay = adapt;
+
+       return 0;
+}
+
 static int mxs_lradc_probe(struct platform_device *pdev)
 {
        const struct of_device_id *of_id =
@@ -908,8 +1270,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
        struct mxs_lradc *lradc;
        struct iio_dev *iio;
        struct resource *iores;
-       uint32_t ts_wires = 0;
-       int ret = 0;
+       int ret = 0, touch_ret;
        int i;
 
        /* Allocate the IIO device. */
@@ -920,6 +1281,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
        }
 
        lradc = iio_priv(iio);
+       lradc->soc = (enum mxs_lradc_id)of_id->data;
 
        /* Grab the memory area */
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -928,20 +1290,18 @@ static int mxs_lradc_probe(struct platform_device *pdev)
        if (IS_ERR(lradc->base))
                return PTR_ERR(lradc->base);
 
-       INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
+       lradc->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(lradc->clk)) {
+               dev_err(dev, "Failed to get the delay unit clock\n");
+               return PTR_ERR(lradc->clk);
+       }
+       ret = clk_prepare_enable(lradc->clk);
+       if (ret != 0) {
+               dev_err(dev, "Failed to enable the delay unit clock\n");
+               return ret;
+       }
 
-       /* Check if touchscreen is enabled in DT. */
-       ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
-                               &ts_wires);
-       if (ret)
-               dev_info(dev, "Touchscreen not enabled.\n");
-       else if (ts_wires == 4)
-               lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
-       else if (ts_wires == 5)
-               lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
-       else
-               dev_warn(dev, "Unsupported number of touchscreen wires (%d)\n",
-                               ts_wires);
+       touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
 
        /* Grab all IRQ sources */
        for (i = 0; i < of_cfg->irq_count; i++) {
@@ -985,9 +1345,11 @@ static int mxs_lradc_probe(struct platform_device *pdev)
                goto err_dev;
 
        /* Register the touchscreen input device. */
-       ret = mxs_lradc_ts_register(lradc);
-       if (ret)
-               goto err_dev;
+       if (touch_ret == 0) {
+               ret = mxs_lradc_ts_register(lradc);
+               if (ret)
+                       goto err_ts_register;
+       }
 
        /* Register IIO device. */
        ret = iio_device_register(iio);
@@ -1000,6 +1362,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
 
 err_ts:
        mxs_lradc_ts_unregister(lradc);
+err_ts_register:
+       mxs_lradc_hw_stop(lradc);
 err_dev:
        mxs_lradc_trigger_remove(iio);
 err_trig:
@@ -1012,14 +1376,13 @@ static int mxs_lradc_remove(struct platform_device *pdev)
        struct iio_dev *iio = platform_get_drvdata(pdev);
        struct mxs_lradc *lradc = iio_priv(iio);
 
+       iio_device_unregister(iio);
        mxs_lradc_ts_unregister(lradc);
-
        mxs_lradc_hw_stop(lradc);
-
-       iio_device_unregister(iio);
-       iio_triggered_buffer_cleanup(iio);
        mxs_lradc_trigger_remove(iio);
+       iio_triggered_buffer_cleanup(iio);
 
+       clk_disable_unprepare(lradc->clk);
        return 0;
 }
 
@@ -1038,3 +1401,4 @@ module_platform_driver(mxs_lradc_driver);
 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
 MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 20f2d555e7cdc695ede30907abaf40e6561b170f..970d9edc73b6cc0d978a6a21a100de6c1a7a6994 100644 (file)
@@ -146,7 +146,6 @@ static int spear_read_raw(struct iio_dev *indio_dev,
                          long mask)
 {
        struct spear_adc_info *info = iio_priv(indio_dev);
-       u32 scale_mv;
        u32 status;
 
        switch (mask) {
@@ -168,10 +167,9 @@ static int spear_read_raw(struct iio_dev *indio_dev,
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
-               scale_mv = (info->vref_external * 1000) >> DATA_BITS;
-               *val =  scale_mv / 1000;
-               *val2 = (scale_mv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = info->vref_external;
+               *val2 = DATA_BITS;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
 
        return -EINVAL;
@@ -320,7 +318,7 @@ static int spear_adc_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        info->adc_base_spear3xx =
-               (struct adc_regs_spear3xx *)info->adc_base_spear6xx;
+               (struct adc_regs_spear3xx __iomem *)info->adc_base_spear6xx;
 
        info->clk = clk_get(dev, NULL);
        if (IS_ERR(info->clk)) {
@@ -335,7 +333,7 @@ static int spear_adc_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if ((irq < 0) || (irq >= NR_IRQS)) {
+       if (irq <= 0) {
                dev_err(dev, "failed getting interrupt resource\n");
                ret = -EINVAL;
                goto errout3;
index ce7d91cb331c015e031213e95fb4ed4e6c40807e..0feea5541d02d5f98f24023ffcd4623480a0cc6b 100644 (file)
@@ -138,6 +138,5 @@ static struct i2c_driver adt7316_driver = {
 module_i2c_driver(adt7316_driver);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and"
-                       "ADT7516/7/8 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and ADT7516/7/8 digital temperature sensor, ADC and DAC");
 MODULE_LICENSE("GPL v2");
index 0db8ef5835a07761e5472b160ca3c263997f2ced..7f4f0a8245b480090387c0f03aab24dbbb8ee178 100644 (file)
@@ -146,6 +146,5 @@ static struct spi_driver adt7316_driver = {
 module_spi_driver(adt7316_driver);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
-                       "ADT7516/7/9 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and ADT7516/7/9 digital temperature sensor, ADC and DAC");
 MODULE_LICENSE("GPL v2");
index 1e1356825d6dadd98b7e9d14e8bc3a896890080d..80266e801d5673919533c9208241b3a0e3868d7f 100644 (file)
@@ -412,13 +412,13 @@ static ssize_t adt7316_store_ad_channel(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 config2;
-       unsigned long data = 0;
+       u8 data;
        int ret;
 
        if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
                return -EPERM;
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou8(buf, 10, &data);
        if (ret)
                return -EINVAL;
 
@@ -823,10 +823,10 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 dac_config;
-       unsigned long data = 0;
+       u8 data;
        int ret;
 
-       ret = strict_strtoul(buf, 16, &data);
+       ret = kstrtou8(buf, 16, &data);
        if (ret || data > ADT7316_DA_2VREF_CH_MASK)
                return -EINVAL;
 
@@ -878,13 +878,13 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 dac_config;
-       unsigned long data;
+       u8 data;
        int ret;
 
        if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
                return -EPERM;
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou8(buf, 10, &data);
        if (ret || data > ADT7316_DA_EN_MODE_MASK)
                return -EINVAL;
 
@@ -933,7 +933,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 ldac_config;
-       unsigned long data;
+       u8 data;
        int ret;
 
        if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
@@ -941,7 +941,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
                        ADT7316_DA_EN_MODE_LDAC)
                        return -EPERM;
 
-               ret = strict_strtoul(buf, 16, &data);
+               ret = kstrtou8(buf, 16, &data);
                if (ret || data > ADT7316_LDAC_EN_DA_MASK)
                        return -EINVAL;
 
@@ -1079,11 +1079,11 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 ldac_config;
-       unsigned long data;
+       u8 data;
        int ret;
 
        if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
-               ret = strict_strtoul(buf, 16, &data);
+               ret = kstrtou8(buf, 16, &data);
                if (ret || data > 3)
                        return -EINVAL;
 
@@ -1093,7 +1093,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
                else if (data & 0x2)
                        ldac_config |= ADT7516_DAC_CD_IN_VREF;
        } else {
-               ret = strict_strtoul(buf, 16, &data);
+               ret = kstrtou8(buf, 16, &data);
                if (ret)
                        return -EINVAL;
 
@@ -1281,11 +1281,11 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
 static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
                int offset_addr, const char *buf, size_t len)
 {
-       long data;
+       int data;
        u8 val;
        int ret;
 
-       ret = strict_strtol(buf, 10, &data);
+       ret = kstrtoint(buf, 10, &data);
        if (ret || data > 127 || data < -128)
                return -EINVAL;
 
@@ -1442,7 +1442,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
                int channel, const char *buf, size_t len)
 {
        u8 msb, lsb, offset;
-       unsigned long data;
+       u16 data;
        int ret;
 
        if (channel >= ADT7316_DA_MSB_DATA_REGS ||
@@ -1454,7 +1454,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
 
        offset = chip->dac_bits - 8;
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou16(buf, 10, &data);
        if (ret || data >= (1 << chip->dac_bits))
                return -EINVAL;
 
@@ -1830,11 +1830,11 @@ static ssize_t adt7316_set_int_mask(struct device *dev,
 {
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
-       unsigned long data;
+       u16 data;
        int ret;
        u8 mask;
 
-       ret = strict_strtoul(buf, 16, &data);
+       ret = kstrtou16(buf, 16, &data);
        if (ret || data >= ADT7316_VDD_INT_MASK + 1)
                return -EINVAL;
 
@@ -1901,7 +1901,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
-       long data;
+       int data;
        u8 val;
        int ret;
 
@@ -1909,7 +1909,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
                this_attr->address > ADT7316_EX_TEMP_LOW)
                return -EPERM;
 
-       ret = strict_strtol(buf, 10, &data);
+       ret = kstrtoint(buf, 10, &data);
        if (ret)
                return -EINVAL;
 
@@ -2106,11 +2106,9 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
        unsigned short *adt7316_platform_data = dev->platform_data;
        int ret = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
        /* this is only used for device removal purposes */
        dev_set_drvdata(dev, indio_dev);
@@ -2146,58 +2144,44 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
                if (adt7316_platform_data[0])
                        chip->bus.irq_flags = adt7316_platform_data[0];
 
-               ret = request_threaded_irq(chip->bus.irq,
-                                          NULL,
-                                          &adt7316_event_handler,
-                                          chip->bus.irq_flags | IRQF_ONESHOT,
-                                          indio_dev->name,
-                                          indio_dev);
+               ret = devm_request_threaded_irq(dev, chip->bus.irq,
+                                               NULL,
+                                               &adt7316_event_handler,
+                                               chip->bus.irq_flags |
+                                               IRQF_ONESHOT,
+                                               indio_dev->name,
+                                               indio_dev);
                if (ret)
-                       goto error_free_dev;
+                       return ret;
 
                if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
                        chip->config1 |= ADT7316_INT_POLARITY;
        }
 
        ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
-       if (ret) {
-               ret = -EIO;
-               goto error_unreg_irq;
-       }
+       if (ret)
+               return -EIO;
 
        ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
-       if (ret) {
-               ret = -EIO;
-               goto error_unreg_irq;
-       }
+       if (ret)
+               return -EIO;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_unreg_irq;
+               return ret;
 
        dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
                        indio_dev->name);
 
        return 0;
-
-error_unreg_irq:
-       free_irq(chip->bus.irq, indio_dev);
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 EXPORT_SYMBOL(adt7316_probe);
 
 int adt7316_remove(struct device *dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct adt7316_chip_info *chip = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (chip->bus.irq)
-               free_irq(chip->bus.irq, indio_dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index f4a0341cc70c1355dcab30e6113c3cddba5a1a82..7e7f9890a642ad7816f05f4a1ffa3952ff6a0f8d 100644 (file)
@@ -123,14 +123,14 @@ static int ad7150_read_raw(struct iio_dev *indio_dev,
        }
 }
 
-static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
+static int ad7150_read_event_config(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        int ret;
        u8 threshtype;
        bool adaptive;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
 
        ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
        if (ret < 0)
@@ -139,42 +139,47 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
        threshtype = (ret >> 5) & 0x03;
        adaptive = !!(ret & 0x80);
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
-               if (rising)
+               if (dir == IIO_EV_DIR_RISING)
                        return adaptive && (threshtype == 0x1);
                else
                        return adaptive && (threshtype == 0x0);
        case IIO_EV_TYPE_THRESH_ADAPTIVE:
-               if (rising)
+               if (dir == IIO_EV_DIR_RISING)
                        return adaptive && (threshtype == 0x3);
                else
                        return adaptive && (threshtype == 0x2);
 
        case IIO_EV_TYPE_THRESH:
-               if (rising)
+               if (dir == IIO_EV_DIR_RISING)
                        return !adaptive && (threshtype == 0x1);
                else
                        return !adaptive && (threshtype == 0x0);
+       default:
+               break;
        }
        return -EINVAL;
 }
 
 /* lock should be held */
-static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
+static int ad7150_write_event_params(struct iio_dev *indio_dev,
+        unsigned int chan, enum iio_event_type type,
+        enum iio_event_direction dir)
 {
        int ret;
        u16 value;
        u8 sens, timeout;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
+       u64 event_code;
+
+       event_code = IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE, chan, type, dir);
 
        if (event_code != chip->current_event)
                return 0;
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
                /* Note completely different from the adaptive versions */
        case IIO_EV_TYPE_THRESH:
                value = chip->threshold[rising][chan];
@@ -211,18 +216,20 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
 }
 
 static int ad7150_write_event_config(struct iio_dev *indio_dev,
-                                    u64 event_code, int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        u8 thresh_type, cfg, adaptive;
        int ret;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
+       u64 event_code;
 
        /* Something must always be turned on */
        if (state == 0)
                return -EINVAL;
 
+       event_code = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, type, dir);
        if (event_code == chip->current_event)
                return 0;
        mutex_lock(&chip->state_lock);
@@ -232,7 +239,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
 
        cfg = ret & ~((0x03 << 5) | (0x1 << 7));
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
                adaptive = 1;
                if (rising)
@@ -268,7 +275,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
        chip->current_event = event_code;
 
        /* update control attributes */
-       ret = ad7150_write_event_params(indio_dev, event_code);
+       ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
 error_ret:
        mutex_unlock(&chip->state_lock);
 
@@ -276,53 +283,52 @@ error_ret:
 }
 
 static int ad7150_read_event_value(struct iio_dev *indio_dev,
-                                  u64 event_code,
-                                  int *val)
+                                  const struct iio_chan_spec *chan,
+                                  enum iio_event_type type,
+                                  enum iio_event_direction dir,
+                                  enum iio_event_info info,
+                                  int *val, int *val2)
 {
-       int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
 
        /* Complex register sharing going on here */
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
-               *val = chip->mag_sensitivity[rising][chan];
-               return 0;
-
+               *val = chip->mag_sensitivity[rising][chan->channel];
+               return IIO_VAL_INT;
        case IIO_EV_TYPE_THRESH_ADAPTIVE:
-               *val = chip->thresh_sensitivity[rising][chan];
-               return 0;
-
+               *val = chip->thresh_sensitivity[rising][chan->channel];
+               return IIO_VAL_INT;
        case IIO_EV_TYPE_THRESH:
-               *val = chip->threshold[rising][chan];
-               return 0;
-
+               *val = chip->threshold[rising][chan->channel];
+               return IIO_VAL_INT;
        default:
                return -EINVAL;
-       };
+       }
 }
 
 static int ad7150_write_event_value(struct iio_dev *indio_dev,
-                                  u64 event_code,
-                                  int val)
+                                  const struct iio_chan_spec *chan,
+                                  enum iio_event_type type,
+                                  enum iio_event_direction dir,
+                                  enum iio_event_info info,
+                                  int val, int val2)
 {
        int ret;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
 
        mutex_lock(&chip->state_lock);
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
-               chip->mag_sensitivity[rising][chan] = val;
+               chip->mag_sensitivity[rising][chan->channel] = val;
                break;
        case IIO_EV_TYPE_THRESH_ADAPTIVE:
-               chip->thresh_sensitivity[rising][chan] = val;
+               chip->thresh_sensitivity[rising][chan->channel] = val;
                break;
        case IIO_EV_TYPE_THRESH:
-               chip->threshold[rising][chan] = val;
+               chip->threshold[rising][chan->channel] = val;
                break;
        default:
                ret = -EINVAL;
@@ -330,7 +336,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev,
        }
 
        /* write back if active */
-       ret = ad7150_write_event_params(indio_dev, event_code);
+       ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
 
 error_ret:
        mutex_unlock(&chip->state_lock);
@@ -374,17 +380,22 @@ static ssize_t ad7150_store_timeout(struct device *dev,
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) ==
-                       IIO_EV_DIR_RISING);
+       enum iio_event_direction dir;
+       enum iio_event_type type;
+       int rising;
        u8 data;
        int ret;
 
+       type = IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address);
+       dir = IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address);
+       rising = (dir == IIO_EV_DIR_RISING);
+
        ret = kstrtou8(buf, 10, &data);
        if (ret < 0)
                return ret;
 
        mutex_lock(&chip->state_lock);
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
                chip->mag_timeout[rising][chan] = data;
                break;
@@ -396,7 +407,7 @@ static ssize_t ad7150_store_timeout(struct device *dev,
                goto error_ret;
        }
 
-       ret = ad7150_write_event_params(indio_dev, this_attr->address);
+       ret = ad7150_write_event_params(indio_dev, chan, type, dir);
 error_ret:
        mutex_unlock(&chip->state_lock);
 
@@ -424,6 +435,40 @@ static AD7150_TIMEOUT(0, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
 static AD7150_TIMEOUT(1, thresh_adaptive, rising, THRESH_ADAPTIVE, RISING);
 static AD7150_TIMEOUT(1, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
 
+static const struct iio_event_spec ad7150_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_MAG_ADAPTIVE,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_MAG_ADAPTIVE,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
 static const struct iio_chan_spec ad7150_channels[] = {
        {
                .type = IIO_CAPACITANCE,
@@ -431,26 +476,16 @@ static const struct iio_chan_spec ad7150_channels[] = {
                .channel = 0,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                BIT(IIO_CHAN_INFO_AVERAGE_RAW),
-               .event_mask =
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+               .event_spec = ad7150_events,
+               .num_event_specs = ARRAY_SIZE(ad7150_events),
        }, {
                .type = IIO_CAPACITANCE,
                .indexed = 1,
                .channel = 1,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                BIT(IIO_CHAN_INFO_AVERAGE_RAW),
-               .event_mask =
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+               .event_spec = ad7150_events,
+               .num_event_specs = ARRAY_SIZE(ad7150_events),
        },
 };
 
@@ -541,10 +576,10 @@ static const struct iio_info ad7150_info = {
        .event_attrs = &ad7150_event_attribute_group,
        .driver_module = THIS_MODULE,
        .read_raw = &ad7150_read_raw,
-       .read_event_config = &ad7150_read_event_config,
-       .write_event_config = &ad7150_write_event_config,
-       .read_event_value = &ad7150_read_event_value,
-       .write_event_value = &ad7150_write_event_value,
+       .read_event_config_new = &ad7150_read_event_config,
+       .write_event_config_new = &ad7150_write_event_config,
+       .read_event_value_new = &ad7150_read_event_value,
+       .write_event_value_new = &ad7150_write_event_value,
 };
 
 /*
index 75a533bce0217739354bfe1dad6cd1ed5e483940..862d68d99630c7249db561ff126d9011a3015052 100644 (file)
@@ -656,20 +656,21 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
                switch (chan->type) {
                case IIO_CAPACITANCE:
                        /* 8.192pf / 2^24 */
-                       *val2 = 488;
                        *val =  0;
+                       *val2 = 488;
+                       ret = IIO_VAL_INT_PLUS_NANO;
                        break;
                case IIO_VOLTAGE:
                        /* 1170mV / 2^23 */
-                       *val2 = 139475;
-                       *val =  0;
+                       *val = 1170;
+                       *val2 = 23;
+                       ret = IIO_VAL_FRACTIONAL_LOG2;
                        break;
                default:
-                       ret =  -EINVAL;
-                       goto out;
+                       ret = -EINVAL;
+                       break;
                }
 
-               ret = IIO_VAL_INT_PLUS_NANO;
                break;
        default:
                ret = -EINVAL;
index 69e90e9e60eaa9642075a5402655bf3e94d03401..a4aeee6ffdf2a6248e095f74d00397376f4105ab 100644 (file)
@@ -94,11 +94,9 @@ static int ad5930_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
 
@@ -110,24 +108,18 @@ static int ad5930_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 16;
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-error_ret:
-       return ret;
 }
 
 static int ad5930_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 4e18380c514103a40ce01a21640697b385dd2707..c7d0307c8e76110044bf37580f35e963fc46c4da 100644 (file)
@@ -81,9 +81,9 @@ static ssize_t ad9832_write(struct device *dev,
        struct ad9832_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       unsigned long val;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoul(buf, 10, &val);
        if (ret)
                goto error_ret;
 
@@ -214,14 +214,14 @@ static int ad9832_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       reg = regulator_get(&spi->dev, "vcc");
+       reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(reg)) {
                ret = regulator_enable(reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL) {
                ret = -ENOMEM;
                goto error_disable_reg;
@@ -279,47 +279,42 @@ static int ad9832_probe(struct spi_device *spi)
        ret = spi_sync(st->spi, &st->msg);
        if (ret) {
                dev_err(&spi->dev, "device init failed\n");
-               goto error_free_device;
+               goto error_disable_reg;
        }
 
        ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        return 0;
 
-error_free_device:
-       iio_device_free(indio_dev);
 error_disable_reg:
        if (!IS_ERR(reg))
                regulator_disable(reg);
-error_put_reg:
-       if (!IS_ERR(reg))
-               regulator_put(reg);
 
        return ret;
 }
@@ -330,11 +325,8 @@ static int ad9832_remove(struct spi_device *spi)
        struct ad9832_state *st = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 5cba3c01f41720f57148bfe994263b17e18f71e9..86cda617609330d6183bbaea05bae90f4599b152 100644 (file)
@@ -70,9 +70,9 @@ static ssize_t ad9834_write(struct device *dev,
        struct ad9834_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       unsigned long val;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoul(buf, 10, &val);
        if (ret)
                goto error_ret;
 
@@ -327,14 +327,14 @@ static int ad9834_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       reg = regulator_get(&spi->dev, "vcc");
+       reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(reg)) {
                ret = regulator_enable(reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL) {
                ret = -ENOMEM;
                goto error_disable_reg;
@@ -388,39 +388,35 @@ static int ad9834_probe(struct spi_device *spi)
        ret = spi_sync(st->spi, &st->msg);
        if (ret) {
                dev_err(&spi->dev, "device init failed\n");
-               goto error_free_device;
+               goto error_disable_reg;
        }
 
        ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        return 0;
 
-error_free_device:
-       iio_device_free(indio_dev);
 error_disable_reg:
        if (!IS_ERR(reg))
                regulator_disable(reg);
-error_put_reg:
-       if (!IS_ERR(reg))
-               regulator_put(reg);
+
        return ret;
 }
 
@@ -430,11 +426,8 @@ static int ad9834_remove(struct spi_device *spi)
        struct ad9834_state *st = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 01a8a93031f54887d76961afe781f504bd65d8d8..af877ff680e9eda37711181842327e93ade39f7f 100644 (file)
@@ -80,11 +80,9 @@ static int ad9850_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
        mutex_init(&st->lock);
@@ -96,24 +94,18 @@ static int ad9850_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 16;
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-error_ret:
-       return ret;
 }
 
 static int ad9850_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 1344031232bca7cb2c0ce93e3c11a427d9a136e0..11e4367375d20cd18fd25177f2372b254f6edf65 100644 (file)
@@ -67,7 +67,6 @@ static ssize_t ad9852_set_parameter(struct device *dev,
                                        const char *buf,
                                        size_t len)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        struct ad9852_config *config = (struct ad9852_config *)buf;
@@ -78,99 +77,77 @@ static ssize_t ad9852_set_parameter(struct device *dev,
        xfer.tx_buf = &config->phajst0[0];
        mutex_lock(&st->lock);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->phajst1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 6;
        xfer.tx_buf = &config->fretun1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 6;
        xfer.tx_buf = &config->fretun2[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 6;
        xfer.tx_buf = &config->dltafre[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->updtclk[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 4;
        xfer.tx_buf = &config->ramprat[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->control[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->outpskm[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 2;
        xfer.tx_buf = &config->outpskr[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->daccntl[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 error_ret:
@@ -229,11 +206,9 @@ static int ad9852_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        st = iio_priv(idev);
        spi_set_drvdata(spi, idev);
        mutex_init(&st->lock);
@@ -245,7 +220,7 @@ static int ad9852_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
@@ -253,18 +228,11 @@ static int ad9852_probe(struct spi_device *spi)
        ad9852_init(st);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-
-error_ret:
-       return ret;
 }
 
 static int ad9852_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index e48f874c1fc2a8c1c05dcfbb8312d95f2155c9f9..755e0482681ab62e066aa919dcb96bfb157c8d12 100644 (file)
@@ -119,7 +119,6 @@ static ssize_t ad9910_set_parameter(struct device *dev,
                                        const char *buf,
                                        size_t len)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        struct ad9910_config *config = (struct ad9910_config *)buf;
@@ -130,152 +129,118 @@ static ssize_t ad9910_set_parameter(struct device *dev,
        xfer.tx_buf = &config->auxdac[0];
        mutex_lock(&st->lock);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->ioupd[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->ftw[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->pow[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->asf[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->multc[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->dig_rampl[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->dig_ramps[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->dig_rampr[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep0[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep2[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep3[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep4[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep5[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep6[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep7[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 error_ret:
@@ -288,7 +253,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
 
 static void ad9910_init(struct ad9910_state *st)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        u8 cfr[5];
@@ -304,9 +268,7 @@ static void ad9910_init(struct ad9910_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -319,9 +281,7 @@ static void ad9910_init(struct ad9910_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -334,9 +294,7 @@ static void ad9910_init(struct ad9910_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -367,11 +325,9 @@ static int ad9910_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
        mutex_init(&st->lock);
@@ -383,24 +339,18 @@ static int ad9910_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
        spi_setup(spi);
        ad9910_init(st);
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-error_ret:
-       return ret;
 }
 
 static int ad9910_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 8234e3c915c441ffb6291d22a0ae50c6cbb6cd72..5e8990a0210bf1d297d4eb8134c532fc17ff78fb 100644 (file)
@@ -60,7 +60,6 @@ static ssize_t ad9951_set_parameter(struct device *dev,
                                        const char *buf,
                                        size_t len)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        struct ad9951_config *config = (struct ad9951_config *)buf;
@@ -71,36 +70,28 @@ static ssize_t ad9951_set_parameter(struct device *dev,
        xfer.tx_buf = &config->asf[0];
        mutex_lock(&st->lock);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 2;
        xfer.tx_buf = &config->arr[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->ftw0[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->ftw1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 error_ret:
@@ -113,7 +104,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
 
 static void ad9951_init(struct ad9951_state *st)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        u8 cfr[5];
@@ -129,9 +119,7 @@ static void ad9951_init(struct ad9951_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -143,9 +131,7 @@ static void ad9951_init(struct ad9951_state *st)
        xfer.len = 4;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -176,11 +162,9 @@ static int ad9951_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
        mutex_init(&st->lock);
@@ -193,25 +177,18 @@ static int ad9951_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
        spi_setup(spi);
        ad9951_init(st);
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-
-error_ret:
-       return ret;
 }
 
 static int ad9951_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 0e8e02a3cf5bb1b933106c7c8cff50467f923568..1fac9894b18c2fbf2e40ad249ad66ae856ee6862 100644 (file)
@@ -57,6 +57,20 @@ static const struct iio_dummy_accel_calibscale dummy_scales[] = {
        { 733, 13, 0x9 }, /* 733.000013 */
 };
 
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+
+/*
+ * simple event - triggered when value rises above
+ * a threshold
+ */
+static const struct iio_event_spec iio_dummy_event = {
+       .type = IIO_EV_TYPE_THRESH,
+       .dir = IIO_EV_DIR_RISING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+
+#endif
+
 /*
  * iio_dummy_channels - Description of available channels
  *
@@ -90,6 +104,11 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                 * when converting to standard units (microvolts)
                 */
                BIT(IIO_CHAN_INFO_SCALE),
+               /*
+                * sampling_frequency
+                * The frequency in Hz at which the channels are sampled
+                */
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
                /* The ordering of elements in the buffer via an enum */
                .scan_index = voltage0,
                .scan_type = { /* Description of storage in buffer */
@@ -99,12 +118,8 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                        .shift = 0, /* zero shift */
                },
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-               /*
-                * simple event - triggered when value rises above
-                * a threshold
-                */
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                        IIO_EV_DIR_RISING),
+               .event_spec = &iio_dummy_event,
+               .num_event_specs = 1,
 #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
        },
        /* Differential ADC channel in_voltage1-voltage2_raw etc*/
@@ -130,6 +145,10 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                 * input channels of type IIO_VOLTAGE.
                 */
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+               /*
+                * sampling_frequency
+                * The frequency in Hz at which the channels are sampled
+                */
                .scan_index = diffvoltage1m2,
                .scan_type = { /* Description of storage in buffer */
                        .sign = 's', /* signed */
@@ -147,6 +166,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                .channel2 = 4,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
                .scan_index = diffvoltage3m4,
                .scan_type = {
                        .sign = 's',
@@ -173,6 +193,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                 */
                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                BIT(IIO_CHAN_INFO_CALIBBIAS),
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
                .scan_index = accelx,
                .scan_type = { /* Description of storage in buffer */
                        .sign = 's', /* signed */
@@ -272,6 +293,11 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
                *val2 = st->accel_calibscale->val2;
                ret = IIO_VAL_INT_PLUS_MICRO;
                break;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = 3;
+               *val2 = 33;
+               ret = IIO_VAL_INT_PLUS_NANO;
+               break;
        default:
                break;
        }
@@ -344,10 +370,10 @@ static const struct iio_info iio_dummy_info = {
        .read_raw = &iio_dummy_read_raw,
        .write_raw = &iio_dummy_write_raw,
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-       .read_event_config = &iio_simple_dummy_read_event_config,
-       .write_event_config = &iio_simple_dummy_write_event_config,
-       .read_event_value = &iio_simple_dummy_read_event_value,
-       .write_event_value = &iio_simple_dummy_write_event_value,
+       .read_event_config_new = &iio_simple_dummy_read_event_config,
+       .write_event_config_new = &iio_simple_dummy_write_event_config,
+       .read_event_value_new = &iio_simple_dummy_read_event_value,
+       .write_event_value_new = &iio_simple_dummy_write_event_value,
 #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
 };
 
@@ -454,7 +480,8 @@ static int iio_dummy_probe(int index)
         * buffer, but avoid the output channel being registered by reducing the
         * number of channels by 1.
         */
-       ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
+       ret = iio_simple_dummy_configure_buffer(indio_dev,
+                                               iio_dummy_channels, 5);
        if (ret < 0)
                goto error_unregister_events;
 
index c9e8702caca41890ce5f9f6e14b91ea07f0a4329..b126196cdf3d99562bd855496b18a9dc2cafa1f3 100644 (file)
@@ -45,19 +45,29 @@ struct iio_dummy_state {
 struct iio_dev;
 
 int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
-                                      u64 event_code);
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir);
 
 int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
-                                       u64 event_code,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
                                        int state);
 
 int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
-                                     u64 event_code,
-                                     int *val);
+                                     const struct iio_chan_spec *chan,
+                                     enum iio_event_type type,
+                                     enum iio_event_direction dir,
+                                     enum iio_event_info info, int *val,
+                                     int *val2);
 
 int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
-                                      u64 event_code,
-                                      int val);
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir,
+                                      enum iio_event_info info, int val,
+                                      int val2);
 
 int iio_simple_dummy_events_register(struct iio_dev *indio_dev);
 int iio_simple_dummy_events_unregister(struct iio_dev *indio_dev);
index 72f400c3cbcbbdc88391a02ae14cb87fc589d2da..46c134b2a5d101a4a257b1948b4af8ee90911ace 100644 (file)
@@ -82,11 +82,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
                        len += 2;
                }
        }
-       /* Store the timestamp at an 8 byte aligned offset */
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
-                       = iio_get_time_ns();
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
 
        kfree(data);
 
@@ -101,14 +98,6 @@ done:
 }
 
 static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
-       /*
-        * iio_sw_buffer_preenable:
-        * Generic function for equal sized ring elements + 64 bit timestamp
-        * Assumes that any combination of channels can be enabled.
-        * Typically replaced to implement restrictions on what combinations
-        * can be captured (hardware scan modes).
-        */
-       .preenable = &iio_sw_buffer_preenable,
        /*
         * iio_triggered_buffer_postenable:
         * Generic function that simply attaches the pollfunc to the trigger.
@@ -138,7 +127,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
                goto error_ret;
        }
 
-       indio_dev->buffer = buffer;
+       iio_device_attach_buffer(indio_dev, buffer);
 
        /* Enable timestamps by default */
        buffer->scan_timestamp = true;
index 317b77465db42261a64f82a26e72fbcef7b1fc7e..812ebd05a7fe889c7437da2c89697de06b9e2882 100644 (file)
 /**
  * iio_simple_dummy_read_event_config() - is event enabled?
  * @indio_dev: the device instance data
- * @event_code: event code of the event being queried
+ * @chan: channel for the event whose state is being queried
+ * @type: type of the event whose state is being queried
+ * @dir: direction of the vent whose state is being queried
  *
  * This function would normally query the relevant registers or a cache to
  * discover if the event generation is enabled on the device.
  */
 int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
-                                      u64 event_code)
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir)
 {
        struct iio_dummy_state *st = iio_priv(indio_dev);
 
@@ -39,7 +43,9 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
 /**
  * iio_simple_dummy_write_event_config() - set whether event is enabled
  * @indio_dev: the device instance data
- * @event_code: event code of event being enabled/disabled
+ * @chan: channel for the event whose state is being set
+ * @type: type of the event whose state is being set
+ * @dir: direction of the vent whose state is being set
  * @state: whether to enable or disable the device.
  *
  * This function would normally set the relevant registers on the devices
@@ -47,7 +53,9 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
  * value.
  */
 int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
-                                       u64 event_code,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
                                        int state)
 {
        struct iio_dummy_state *st = iio_priv(indio_dev);
@@ -56,12 +64,11 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
         *  Deliberately over the top code splitting to illustrate
         * how this is done when multiple events exist.
         */
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+               switch (type) {
                case IIO_EV_TYPE_THRESH:
-                       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                           IIO_EV_DIR_RISING)
+                       if (dir == IIO_EV_DIR_RISING)
                                st->event_en = state;
                        else
                                return -EINVAL;
@@ -79,7 +86,10 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
 /**
  * iio_simple_dummy_read_event_value() - get value associated with event
  * @indio_dev: device instance specific data
- * @event_code: event code for the event whose value is being queried
+ * @chan: channel for the event whose value is being read
+ * @type: type of the event whose value is being read
+ * @dir: direction of the vent whose value is being read
+ * @info: info type of the event whose value is being read
  * @val: value for the event code.
  *
  * Many devices provide a large set of events of which only a subset may
@@ -89,25 +99,34 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
  * the enabled event is changed.
  */
 int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
-                                     u64 event_code,
-                                     int *val)
+                                     const struct iio_chan_spec *chan,
+                                     enum iio_event_type type,
+                                     enum iio_event_direction dir,
+                                         enum iio_event_info info,
+                                     int *val, int *val2)
 {
        struct iio_dummy_state *st = iio_priv(indio_dev);
 
        *val = st->event_val;
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 /**
  * iio_simple_dummy_write_event_value() - set value associate with event
  * @indio_dev: device instance specific data
- * @event_code: event code for the event whose value is being set
+ * @chan: channel for the event whose value is being set
+ * @type: type of the event whose value is being set
+ * @dir: direction of the vent whose value is being set
+ * @info: info type of the event whose value is being set
  * @val: the value to be set.
  */
 int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
-                                      u64 event_code,
-                                      int val)
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir,
+                                          enum iio_event_info info,
+                                      int val, int val2)
 {
        struct iio_dummy_state *st = iio_priv(indio_dev);
 
index 6330af656a0f536d6a56580a5503eac75bdd3e53..0a4298b744e6e686f8bdef9175d06666c1b5cf49 100644 (file)
@@ -323,10 +323,10 @@ static ssize_t ad5933_store_frequency(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ad5933_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       long val;
+       unsigned long val;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoul(buf, 10, &val);
        if (ret)
                return ret;
 
@@ -400,12 +400,12 @@ static ssize_t ad5933_store(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ad5933_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       long val;
+       u16 val;
        int i, ret = 0;
        unsigned short dat;
 
        if (this_attr->address != AD5933_IN_PGA_GAIN) {
-               ret = strict_strtol(buf, 10, &val);
+               ret = kstrtou16(buf, 10, &val);
                if (ret)
                        return ret;
        }
@@ -434,7 +434,7 @@ static ssize_t ad5933_store(struct device *dev,
                ret = ad5933_cmd(st, 0);
                break;
        case AD5933_OUT_SETTLING_CYCLES:
-               val = clamp(val, 0L, 0x7FFL);
+               val = clamp(val, (u16)0, (u16)0x7FF);
                st->settling_cycles = val;
 
                /* 2x, 4x handling, see datasheet */
@@ -448,7 +448,7 @@ static ssize_t ad5933_store(struct device *dev,
                                AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
                break;
        case AD5933_FREQ_POINTS:
-               val = clamp(val, 0L, 511L);
+               val = clamp(val, (u16)0, (u16)511);
                st->freq_points = val;
 
                dat = cpu_to_be16(val);
@@ -574,10 +574,6 @@ static int ad5933_ring_preenable(struct iio_dev *indio_dev)
        if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
                return -EINVAL;
 
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret < 0)
-               return ret;
-
        ret = ad5933_reset(st);
        if (ret < 0)
                return ret;
@@ -630,10 +626,14 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
 
 static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
-       if (!indio_dev->buffer)
+       struct iio_buffer *buffer;
+
+       buffer = iio_kfifo_allocate(indio_dev);
+       if (buffer)
                return -ENOMEM;
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        /* Ring buffer functions - here trigger setup related */
        indio_dev->setup_ops = &ad5933_ring_setup_ops;
 
@@ -676,7 +676,7 @@ static void ad5933_work(struct work_struct *work)
                } else {
                        buf[0] = be16_to_cpu(buf[0]);
                }
-               iio_push_to_buffers(indio_dev, (u8 *)buf);
+               iio_push_to_buffers(indio_dev, buf);
        } else {
                /* no data available - try again later */
                schedule_delayed_work(&st->work, st->poll_time_jiffies);
@@ -703,7 +703,9 @@ static int ad5933_probe(struct i2c_client *client,
        int ret, voltage_uv = 0;
        struct ad5933_platform_data *pdata = client->dev.platform_data;
        struct ad5933_state *st;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -716,11 +718,11 @@ static int ad5933_probe(struct i2c_client *client,
        else
                st->pdata = pdata;
 
-       st->reg = regulator_get(&client->dev, "vcc");
+       st->reg = devm_regulator_get(&client->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
                voltage_uv = regulator_get_voltage(st->reg);
        }
 
@@ -778,11 +780,6 @@ error_unreg_ring:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -795,11 +792,8 @@ static int ad5933_remove(struct i2c_client *client)
        iio_device_unregister(indio_dev);
        iio_buffer_unregister(indio_dev);
        iio_kfifo_free(indio_dev->buffer);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index e4998e4d4434b2af9365aacc1a8c4137a4c70544..488e690388c948dc3cda08afdc334cebc15966ef 100644 (file)
@@ -240,7 +240,7 @@ static ssize_t store_range(struct device *dev,
        unsigned long lval;
        unsigned int new_range;
 
-       if (strict_strtoul(buf, 10, &lval))
+       if (kstrtoul(buf, 10, &lval))
                return -EINVAL;
 
        if (!(lval == 1000UL || lval == 4000UL ||
@@ -279,18 +279,18 @@ static ssize_t store_resolution(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct isl29018_chip *chip = iio_priv(indio_dev);
        int status;
-       unsigned long lval;
+       unsigned int val;
        unsigned int new_adc_bit;
 
-       if (strict_strtoul(buf, 10, &lval))
+       if (kstrtouint(buf, 10, &val))
                return -EINVAL;
-       if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) {
+       if (!(val == 4 || val == 8 || val == 12 || val == 16)) {
                dev_err(dev, "The resolution is not supported\n");
                return -EINVAL;
        }
 
        mutex_lock(&chip->lock);
-       status = isl29018_set_resolution(chip, lval, &new_adc_bit);
+       status = isl29018_set_resolution(chip, val, &new_adc_bit);
        if (status < 0) {
                mutex_unlock(&chip->lock);
                dev_err(dev, "Error in setting resolution\n");
@@ -319,11 +319,11 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct isl29018_chip *chip = iio_priv(indio_dev);
-       unsigned long lval;
+       int val;
 
-       if (strict_strtoul(buf, 10, &lval))
+       if (kstrtoint(buf, 10, &val))
                return -EINVAL;
-       if (!(lval == 0UL || lval == 1UL)) {
+       if (!(val == 0 || val == 1)) {
                dev_err(dev, "The mode is not supported\n");
                return -EINVAL;
        }
@@ -331,7 +331,7 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
        /* get the  "proximity scheme" i.e. if the chip does on chip
        infrared suppression (1 means perform on chip suppression) */
        mutex_lock(&chip->lock);
-       chip->prox_scheme = (int)lval;
+       chip->prox_scheme = val;
        mutex_unlock(&chip->lock);
 
        return count;
index b377dd3b76ad3a2eea33e34025923859bb1b477b..f8c659568c384f1884e74757df2981deb508b0ab 100644 (file)
@@ -493,9 +493,9 @@ static ssize_t taos_power_state_store(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value == 0)
@@ -536,9 +536,9 @@ static ssize_t taos_gain_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        switch (value) {
@@ -582,9 +582,9 @@ static ssize_t taos_als_time_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if ((value < 50) || (value > 650))
@@ -619,9 +619,9 @@ static ssize_t taos_als_trim_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value)
@@ -644,9 +644,9 @@ static ssize_t taos_als_cal_target_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value)
@@ -671,9 +671,9 @@ static ssize_t taos_do_calibrate(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value == 1)
@@ -815,12 +815,9 @@ static int taos_probe(struct i2c_client *clientp,
                return -EOPNOTSUPP;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               dev_err(&clientp->dev, "iio allocation failed\n");
-               goto fail1;
-       }
+       indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
        chip->client = clientp;
        i2c_set_clientdata(clientp, indio_dev);
@@ -835,14 +832,14 @@ static int taos_probe(struct i2c_client *clientp,
                if (ret < 0) {
                        dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
                                "reg failed in taos_probe(), err = %d\n", ret);
-                       goto fail2;
+                       return ret;
                }
                ret = i2c_smbus_read_byte(clientp);
                if (ret < 0) {
                        dev_err(&clientp->dev, "i2c_smbus_read_byte from "
                                "reg failed in taos_probe(), err = %d\n", ret);
 
-                       goto fail2;
+                       return ret;
                }
                buf[i] = ret;
        }
@@ -850,14 +847,14 @@ static int taos_probe(struct i2c_client *clientp,
        if (!taos_tsl258x_device(buf)) {
                dev_info(&clientp->dev, "i2c device found but does not match "
                        "expected id in taos_probe()\n");
-               goto fail2;
+               return -EINVAL;
        }
 
        ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
        if (ret < 0) {
                dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
                        "failed in taos_probe(), err = %d\n", ret);
-               goto fail2;
+               return ret;
        }
 
        indio_dev->info = &tsl2583_info;
@@ -867,7 +864,7 @@ static int taos_probe(struct i2c_client *clientp,
        ret = iio_device_register(indio_dev);
        if (ret) {
                dev_err(&clientp->dev, "iio registration failed\n");
-               goto fail2;
+               return ret;
        }
 
        /* Load up the V2 defaults (these are hard coded defaults for now) */
@@ -878,10 +875,6 @@ static int taos_probe(struct i2c_client *clientp,
 
        dev_info(&clientp->dev, "Light sensor found.\n");
        return 0;
-fail1:
-       iio_device_free(indio_dev);
-fail2:
-       return ret;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -926,7 +919,6 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
 static int taos_remove(struct i2c_client *client)
 {
        iio_device_unregister(i2c_get_clientdata(client));
-       iio_device_free(i2c_get_clientdata(client));
 
        return 0;
 }
index c99f890cc6c65ae9ea13a9aafa8c8258e21e3cb8..18805029d2a915a72cbbe1c28579954a57aac679 100644 (file)
 #define TSL2X7X_mA13                   0xD0
 #define TSL2X7X_MAX_TIMER_CNT          (0xFF)
 
-/*Common device IIO EventMask */
-#define TSL2X7X_EVENT_MASK \
-               (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
-
 #define TSL2X7X_MIN_ITIME 3
 
 /* TAOS txx2x7x Device family members */
@@ -550,7 +545,7 @@ prox_poll_err:
 static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
 {
        /* If Operational settings defined elsewhere.. */
-       if (chip->pdata && chip->pdata->platform_default_settings != 0)
+       if (chip->pdata && chip->pdata->platform_default_settings)
                memcpy(&(chip->tsl2x7x_settings),
                        chip->pdata->platform_default_settings,
                        sizeof(tsl2x7x_default_settings));
@@ -951,7 +946,6 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
        case tsl2771:
        case tmd2771:
                return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
-       break;
        }
 
        return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
@@ -1223,12 +1217,14 @@ static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
 }
 
 static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
-                                        u64 event_code)
+                                        const struct iio_chan_spec *chan,
+                                        enum iio_event_type type,
+                                        enum iio_event_direction dir)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
        int ret;
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY)
+       if (chan->type == IIO_INTENSITY)
                ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
        else
                ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
@@ -1237,12 +1233,14 @@ static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
 }
 
 static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
-                                         u64 event_code,
+                                         const struct iio_chan_spec *chan,
+                                         enum iio_event_type type,
+                                         enum iio_event_direction dir,
                                          int val)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
+       if (chan->type == IIO_INTENSITY) {
                if (val)
                        chip->tsl2x7x_settings.interrupts_en |= 0x10;
                else
@@ -1260,13 +1258,16 @@ static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
 }
 
 static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
-                                 u64 event_code,
-                                 int val)
+                               const struct iio_chan_spec *chan,
+                               enum iio_event_type type,
+                               enum iio_event_direction dir,
+                               enum iio_event_info info,
+                               int val, int val2)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       if (chan->type == IIO_INTENSITY) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        chip->tsl2x7x_settings.als_thresh_high = val;
                        break;
@@ -1277,7 +1278,7 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
                        return -EINVAL;
                }
        } else {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        chip->tsl2x7x_settings.prox_thres_high = val;
                        break;
@@ -1295,13 +1296,16 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
 }
 
 static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
-                              u64 event_code,
-                              int *val)
+                              const struct iio_chan_spec *chan,
+                              enum iio_event_type type,
+                              enum iio_event_direction dir,
+                                  enum iio_event_info info,
+                              int *val, int *val2)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       if (chan->type == IIO_INTENSITY) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        *val = chip->tsl2x7x_settings.als_thresh_high;
                        break;
@@ -1312,7 +1316,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
                        return -EINVAL;
                }
        } else {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        *val = chip->tsl2x7x_settings.prox_thres_high;
                        break;
@@ -1324,7 +1328,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
                }
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
@@ -1346,7 +1350,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
                        break;
                default:
                        return -EINVAL;
-                       break;
                }
                break;
        case IIO_CHAN_INFO_RAW:
@@ -1366,7 +1369,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
                        break;
                default:
                        return -EINVAL;
-                       break;
                }
                break;
        case IIO_CHAN_INFO_CALIBSCALE:
@@ -1419,7 +1421,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
                                case tsl2772:
                                case tmd2772:
                                        return -EINVAL;
-                               break;
                                }
                                chip->tsl2x7x_settings.als_gain = 3;
                                break;
@@ -1431,7 +1432,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
                                case tsl2771:
                                case tmd2771:
                                        return -EINVAL;
-                               break;
                                }
                                chip->tsl2x7x_settings.als_gain = 3;
                                break;
@@ -1508,18 +1508,15 @@ static int tsl2x7x_device_id(unsigned char *id, int target)
        case tsl2671:
        case tsl2771:
                return ((*id & 0xf0) == TRITON_ID);
-       break;
        case tmd2671:
        case tmd2771:
                return ((*id & 0xf0) == HALIBUT_ID);
-       break;
        case tsl2572:
        case tsl2672:
        case tmd2672:
        case tsl2772:
        case tmd2772:
                return ((*id & 0xf0) == SWORDFISH_ID);
-       break;
        }
 
        return -EINVAL;
@@ -1675,10 +1672,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [PRX] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[PRX],
@@ -1686,10 +1683,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [ALSPRX] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
@@ -1697,10 +1694,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [PRX2] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
@@ -1708,10 +1705,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [ALSPRX2] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
@@ -1719,10 +1716,24 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
+       },
+};
+
+static const struct iio_event_spec tsl2x7x_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
        },
 };
 
@@ -1741,7 +1752,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                                BIT(IIO_CHAN_INFO_CALIBBIAS),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        }, {
                        .type = IIO_INTENSITY,
                        .indexed = 1,
@@ -1758,7 +1770,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .indexed = 1,
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 1,
@@ -1778,7 +1791,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                                BIT(IIO_CHAN_INFO_CALIBBIAS),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        }, {
                        .type = IIO_INTENSITY,
                        .indexed = 1,
@@ -1789,7 +1803,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .indexed = 1,
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 4,
@@ -1803,7 +1818,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 1,
@@ -1823,7 +1839,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                                BIT(IIO_CHAN_INFO_CALIBBIAS),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        }, {
                        .type = IIO_INTENSITY,
                        .indexed = 1,
@@ -1835,7 +1852,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 4,
@@ -1851,7 +1869,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        struct iio_dev *indio_dev;
        struct tsl2X7X_chip *chip;
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
+       indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
        if (!indio_dev)
                return -ENOMEM;
 
@@ -1862,22 +1880,21 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        ret = tsl2x7x_i2c_read(chip->client,
                TSL2X7X_CHIPID, &device_id);
        if (ret < 0)
-               goto fail1;
+               return ret;
 
        if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
                (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
                dev_info(&chip->client->dev,
                                "%s: i2c device found does not match expected id\n",
                                __func__);
-               ret = -EINVAL;
-               goto fail1;
+               return -EINVAL;
        }
 
        ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
        if (ret < 0) {
                dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
                                __func__, ret);
-               goto fail1;
+               return ret;
        }
 
        /* ALS and PROX functions can be invoked via user space poll
@@ -1899,16 +1916,17 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        indio_dev->num_channels = chip->chip_info->chan_table_elements;
 
        if (clientp->irq) {
-               ret = request_threaded_irq(clientp->irq,
-                                          NULL,
-                                          &tsl2x7x_event_handler,
-                                          IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                                          "TSL2X7X_event",
-                                          indio_dev);
+               ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
+                                               NULL,
+                                               &tsl2x7x_event_handler,
+                                               IRQF_TRIGGER_RISING |
+                                               IRQF_ONESHOT,
+                                               "TSL2X7X_event",
+                                               indio_dev);
                if (ret) {
                        dev_err(&clientp->dev,
                                "%s: irq request failed", __func__);
-                       goto fail1;
+                       return ret;
                }
        }
 
@@ -1921,20 +1939,12 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        if (ret) {
                dev_err(&clientp->dev,
                        "%s: iio registration failed\n", __func__);
-               goto fail2;
+               return ret;
        }
 
        dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
 
        return 0;
-
-fail2:
-       if (clientp->irq)
-               free_irq(clientp->irq, indio_dev);
-fail1:
-       iio_device_free(indio_dev);
-
-       return ret;
 }
 
 static int tsl2x7x_suspend(struct device *dev)
@@ -1980,10 +1990,6 @@ static int tsl2x7x_remove(struct i2c_client *client)
        tsl2x7x_chip_off(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (client->irq)
-               free_irq(client->irq, indio_dev);
-
-       iio_device_free(indio_dev);
 
        return 0;
 }
index c3f3f539e787e926b54f793958d8e9dac13aa6d7..99421f90d1895f6a0691d4443c457f5aac2335db 100644 (file)
 #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 HMC5843_CONFIG_REG_A                   0x00
 #define HMC5843_CONFIG_REG_B                   0x01
 #define HMC5843_MODE_REG                       0x02
-#define HMC5843_DATA_OUT_X_MSB_REG             0x03
-#define HMC5843_DATA_OUT_X_LSB_REG             0x04
-#define HMC5843_DATA_OUT_Y_MSB_REG             0x05
-#define HMC5843_DATA_OUT_Y_LSB_REG             0x06
-#define HMC5843_DATA_OUT_Z_MSB_REG             0x07
-#define HMC5843_DATA_OUT_Z_LSB_REG             0x08
-/* Beware: Y and Z are exchanged on HMC5883 */
-#define HMC5883_DATA_OUT_Z_MSB_REG             0x05
-#define HMC5883_DATA_OUT_Z_LSB_REG             0x06
-#define HMC5883_DATA_OUT_Y_MSB_REG             0x07
-#define HMC5883_DATA_OUT_Y_LSB_REG             0x08
+#define HMC5843_DATA_OUT_MSB_REGS              0x03
 #define HMC5843_STATUS_REG                     0x09
+#define HMC5843_ID_REG                         0x0a
 
 enum hmc5843_ids {
        HMC5843_ID,
@@ -54,19 +48,13 @@ enum hmc5843_ids {
  */
 #define HMC5843_RANGE_GAIN_OFFSET              0x05
 #define HMC5843_RANGE_GAIN_DEFAULT             0x01
-#define HMC5843_RANGE_GAIN_MAX                 0x07
+#define HMC5843_RANGE_GAINS                    8
 
-/*
- * Device status
- */
+/* Device status */
 #define HMC5843_DATA_READY                     0x01
 #define HMC5843_DATA_OUTPUT_LOCK               0x02
-/* Does not exist on HMC5883, not used */
-#define HMC5843_VOLTAGE_REGULATOR_ENABLED      0x04
 
-/*
- * Mode register configuration
- */
+/* Mode register configuration */
 #define HMC5843_MODE_CONVERSION_CONTINUOUS     0x00
 #define HMC5843_MODE_CONVERSION_SINGLE         0x01
 #define HMC5843_MODE_IDLE                      0x02
@@ -78,79 +66,28 @@ enum hmc5843_ids {
  * HMC5883: Typical data output rate
  */
 #define HMC5843_RATE_OFFSET                    0x02
-#define HMC5843_RATE_BITMASK                   0x1C
-#define HMC5843_RATE_NOT_USED                  0x07
+#define HMC5843_RATE_DEFAULT                   0x04
+#define HMC5843_RATES                          7
 
-/*
- * Device measurement configuration
- */
+/* Device measurement configuration */
 #define HMC5843_MEAS_CONF_NORMAL               0x00
 #define HMC5843_MEAS_CONF_POSITIVE_BIAS                0x01
 #define HMC5843_MEAS_CONF_NEGATIVE_BIAS                0x02
-#define HMC5843_MEAS_CONF_NOT_USED             0x03
 #define HMC5843_MEAS_CONF_MASK                 0x03
 
-/*
- * Scaling factors: 10000000/Gain
- */
-static const int hmc5843_regval_to_nanoscale[] = {
+/* Scaling factors: 10000000/Gain */
+static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
        6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
 };
 
-static const int hmc5883_regval_to_nanoscale[] = {
+static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
        7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
 };
 
-static const int hmc5883l_regval_to_nanoscale[] = {
+static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
        7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
 };
 
-/*
- * From the HMC5843 datasheet:
- * Value       | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
- * 0           | (+-)0.7                       | 1620
- * 1           | (+-)1.0                       | 1300
- * 2           | (+-)1.5                       | 970
- * 3           | (+-)2.0                       | 780
- * 4           | (+-)3.2                       | 530
- * 5           | (+-)3.8                       | 460
- * 6           | (+-)4.5                       | 390
- * 7           | (+-)6.5                       | 280
- *
- * From the HMC5883 datasheet:
- * Value       | Recommended sensor field range (Ga)   | Gain (counts/Gauss)
- * 0           | (+-)0.9                               | 1280
- * 1           | (+-)1.2                               | 1024
- * 2           | (+-)1.9                               | 768
- * 3           | (+-)2.5                               | 614
- * 4           | (+-)4.0                               | 415
- * 5           | (+-)4.6                               | 361
- * 6           | (+-)5.5                               | 307
- * 7           | (+-)7.9                               | 219
- *
- * From the HMC5883L datasheet:
- * Value       | Recommended sensor field range (Ga)   | Gain (LSB/Gauss)
- * 0           | (+-)0.88                              | 1370
- * 1           | (+-)1.3                               | 1090
- * 2           | (+-)1.9                               | 820
- * 3           | (+-)2.5                               | 660
- * 4           | (+-)4.0                               | 440
- * 5           | (+-)4.7                               | 390
- * 6           | (+-)5.6                               | 330
- * 7           | (+-)8.1                               | 230
- */
-static const int hmc5843_regval_to_input_field_mga[] = {
-       700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
-};
-
-static const int hmc5883_regval_to_input_field_mga[] = {
-       900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
-};
-
-static const int hmc5883l_regval_to_input_field_mga[] = {
-       880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
-};
-
 /*
  * From the datasheet:
  * Value       | HMC5843               | HMC5883/HMC5883L
@@ -164,141 +101,94 @@ static const int hmc5883l_regval_to_input_field_mga[] = {
  * 6           | 50                    | 75
  * 7           | Not used              | Not used
  */
-static const char * const hmc5843_regval_to_sample_freq[] = {
-       "0.5", "1", "2", "5", "10", "20", "50",
+static const int hmc5843_regval_to_samp_freq[7][2] = {
+       {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
 };
 
-static const char * const hmc5883_regval_to_sample_freq[] = {
-       "0.75", "1.5", "3", "7.5", "15", "30", "75",
+static const int hmc5883_regval_to_samp_freq[7][2] = {
+       {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
+       {75, 0}
 };
 
 /* Describe chip variants */
 struct hmc5843_chip_info {
        const struct iio_chan_spec *channels;
-       const char * const *regval_to_sample_freq;
-       const int *regval_to_input_field_mga;
+       const int (*regval_to_samp_freq)[2];
        const int *regval_to_nanoscale;
 };
 
 /* Each client has this additional data */
 struct hmc5843_data {
+       struct i2c_client *client;
        struct mutex lock;
        u8 rate;
        u8 meas_conf;
        u8 operating_mode;
        u8 range;
        const struct hmc5843_chip_info *variant;
+       __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
 };
 
 /* The lower two bits contain the current conversion mode */
-static s32 hmc5843_configure(struct i2c_client *client,
-                                      u8 operating_mode)
+static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
 {
-       return i2c_smbus_write_byte_data(client,
-                                       HMC5843_MODE_REG,
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
                                        operating_mode & HMC5843_MODE_MASK);
+       if (ret >= 0)
+               data->operating_mode = operating_mode;
+       mutex_unlock(&data->lock);
+
+       return ret;
 }
 
-/* Return the measurement value from the specified channel */
-static int hmc5843_read_measurement(struct iio_dev *indio_dev,
-                                   int address,
-                                   int *val)
+static int hmc5843_wait_measurement(struct hmc5843_data *data)
 {
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
        s32 result;
        int tries = 150;
 
-       mutex_lock(&data->lock);
        while (tries-- > 0) {
-               result = i2c_smbus_read_byte_data(client,
+               result = i2c_smbus_read_byte_data(data->client,
                        HMC5843_STATUS_REG);
+               if (result < 0)
+                       return result;
                if (result & HMC5843_DATA_READY)
                        break;
                msleep(20);
        }
 
        if (tries < 0) {
-               dev_err(&client->dev, "data not ready\n");
-               mutex_unlock(&data->lock);
+               dev_err(&data->client->dev, "data not ready\n");
                return -EIO;
        }
 
-       result = i2c_smbus_read_word_swapped(client, address);
-       mutex_unlock(&data->lock);
-       if (result < 0)
-               return -EINVAL;
-
-       *val = sign_extend32(result, 15);
-       return IIO_VAL_INT;
-}
-
-/*
- * From the datasheet:
- * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
- *     device continuously performs conversions and places the result in
- *     the data register.
- *
- * 1 - Single-Conversion Mode : Device performs a single measurement,
- *     sets RDY high and returns to sleep mode.
- *
- * 2 - Idle Mode : Device is placed in idle mode.
- *
- * 3 - Sleep Mode : Device is placed in sleep mode.
- *
- */
-static ssize_t hmc5843_show_operating_mode(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       return sprintf(buf, "%d\n", data->operating_mode);
+       return 0;
 }
 
-static ssize_t hmc5843_set_operating_mode(struct device *dev,
-                               struct device_attribute *attr,
-                               const char *buf,
-                               size_t count)
+/* Return the measurement value from the specified channel */
+static int hmc5843_read_measurement(struct hmc5843_data *data,
+                                   int idx, int *val)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       unsigned long operating_mode = 0;
-       s32 status;
-       int error;
+       s32 result;
+       __be16 values[3];
 
        mutex_lock(&data->lock);
-       error = kstrtoul(buf, 10, &operating_mode);
-       if (error) {
-               count = error;
-               goto exit;
-       }
-       dev_dbg(dev, "set conversion mode to %lu\n", operating_mode);
-       if (operating_mode > HMC5843_MODE_SLEEP) {
-               count = -EINVAL;
-               goto exit;
-       }
-
-       status = i2c_smbus_write_byte_data(client, this_attr->address,
-                                       operating_mode);
-       if (status) {
-               count = -EINVAL;
-               goto exit;
+       result = hmc5843_wait_measurement(data);
+       if (result < 0) {
+               mutex_unlock(&data->lock);
+               return result;
        }
-       data->operating_mode = operating_mode;
-
-exit:
+       result = i2c_smbus_read_i2c_block_data(data->client,
+               HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
        mutex_unlock(&data->lock);
-       return count;
-}
+       if (result < 0)
+               return -EINVAL;
 
-static IIO_DEVICE_ATTR(operating_mode,
-                       S_IWUSR | S_IRUGO,
-                       hmc5843_show_operating_mode,
-                       hmc5843_set_operating_mode,
-                       HMC5843_MODE_REG);
+       *val = sign_extend32(be16_to_cpu(values[idx]), 15);
+       return IIO_VAL_INT;
+}
 
 /*
  * API for setting the measurement configuration to
@@ -318,23 +208,26 @@ static IIO_DEVICE_ATTR(operating_mode,
  *     and BN.
  *
  */
-static s32 hmc5843_set_meas_conf(struct i2c_client *client,
-                                     u8 meas_conf)
+static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
 {
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       u8 reg_val;
-       reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
-               (data->rate << HMC5843_RATE_OFFSET);
-       return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
+               (meas_conf & HMC5843_MEAS_CONF_MASK) |
+               (data->rate << HMC5843_RATE_OFFSET));
+       if (ret >= 0)
+               data->meas_conf = meas_conf;
+       mutex_unlock(&data->lock);
+
+       return ret;
 }
 
 static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
                                                struct device_attribute *attr,
                                                char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
        return sprintf(buf, "%d\n", data->meas_conf);
 }
 
@@ -343,29 +236,19 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
                                                const char *buf,
                                                size_t count)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
        unsigned long meas_conf = 0;
-       int error;
+       int ret;
 
-       error = kstrtoul(buf, 10, &meas_conf);
-       if (error)
-               return error;
-       if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED)
+       ret = kstrtoul(buf, 10, &meas_conf);
+       if (ret)
+               return ret;
+       if (meas_conf >= HMC5843_MEAS_CONF_MASK)
                return -EINVAL;
 
-       mutex_lock(&data->lock);
-       dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf);
-       if (hmc5843_set_meas_conf(client, meas_conf)) {
-               count = -EINVAL;
-               goto exit;
-       }
-       data->meas_conf = meas_conf;
+       ret = hmc5843_set_meas_conf(data, meas_conf);
 
-exit:
-       mutex_unlock(&data->lock);
-       return count;
+       return (ret < 0) ? ret : count;
 }
 
 static IIO_DEVICE_ATTR(meas_conf,
@@ -374,211 +257,221 @@ static IIO_DEVICE_ATTR(meas_conf,
                        hmc5843_set_measurement_configuration,
                        0);
 
-static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev,
-                                               struct device_attribute *attr,
-                                               char *buf)
+static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       ssize_t total_n = 0;
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
+       size_t len = 0;
        int i;
 
-       for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
-               ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]);
-               buf += n;
-               total_n += n;
-       }
+       for (i = 0; i < HMC5843_RATES; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                       "%d.%d ", data->variant->regval_to_samp_freq[i][0],
+                       data->variant->regval_to_samp_freq[i][1]);
+
        /* replace trailing space by newline */
-       buf[-1] = '\n';
+       buf[len - 1] = '\n';
 
-       return total_n;
+       return len;
 }
 
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
 
-static s32 hmc5843_set_rate(struct i2c_client *client,
-                               u8 rate)
+static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
 {
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       u8 reg_val;
+       int ret;
 
-       if (rate >= HMC5843_RATE_NOT_USED) {
-               dev_err(&client->dev,
-                       "data output rate is not supported\n");
-               return -EINVAL;
-       }
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
+               data->meas_conf | (rate << HMC5843_RATE_OFFSET));
+       if (ret >= 0)
+               data->rate = rate;
+       mutex_unlock(&data->lock);
 
-       reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
-       return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+       return ret;
 }
 
-static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
-                                               const char *buf)
+static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
+                                  int val, int val2)
 {
-       const char * const *samp_freq = data->variant->regval_to_sample_freq;
        int i;
 
-       for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
-               if (sysfs_streq(buf, samp_freq[i]))
+       for (i = 0; i < HMC5843_RATES; i++)
+               if (val == data->variant->regval_to_samp_freq[i][0] &&
+                       val2 == data->variant->regval_to_samp_freq[i][1])
                        return i;
-       }
 
        return -EINVAL;
 }
 
-static ssize_t hmc5843_set_sampling_frequency(struct device *dev,
-                                       struct device_attribute *attr,
-                                       const char *buf, size_t count)
+static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
 {
-
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       int rate;
-
-       rate = hmc5843_check_sampling_frequency(data, buf);
-       if (rate < 0) {
-               dev_err(&client->dev,
-                       "sampling frequency is not supported\n");
-               return rate;
-       }
+       int ret;
 
        mutex_lock(&data->lock);
-       dev_dbg(dev, "set rate to %d\n", rate);
-       if (hmc5843_set_rate(client, rate)) {
-               count = -EINVAL;
-               goto exit;
-       }
-       data->rate = rate;
-
-exit:
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
+               range << HMC5843_RANGE_GAIN_OFFSET);
+       if (ret >= 0)
+               data->range = range;
        mutex_unlock(&data->lock);
-       return count;
+
+       return ret;
 }
 
-static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
-                       struct device_attribute *attr, char *buf)
+static ssize_t hmc5843_show_scale_avail(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       s32 rate;
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
 
-       rate = i2c_smbus_read_byte_data(client, this_attr->address);
-       if (rate < 0)
-               return rate;
-       rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
-       return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
-}
+       size_t len = 0;
+       int i;
 
-static IIO_DEVICE_ATTR(sampling_frequency,
-                       S_IWUSR | S_IRUGO,
-                       hmc5843_show_sampling_frequency,
-                       hmc5843_set_sampling_frequency,
-                       HMC5843_CONFIG_REG_A);
+       for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                       "0.%09d ", data->variant->regval_to_nanoscale[i]);
 
-static ssize_t hmc5843_show_range_gain(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf)
-{
-       u8 range;
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       /* replace trailing space by newline */
+       buf[len - 1] = '\n';
 
-       range = data->range;
-       return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]);
+       return len;
 }
 
-static ssize_t hmc5843_set_range_gain(struct device *dev,
-                       struct device_attribute *attr,
-                       const char *buf,
-                       size_t count)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       unsigned long range = 0;
-       int error;
+static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
+       hmc5843_show_scale_avail, NULL, 0);
 
-       mutex_lock(&data->lock);
-       error = kstrtoul(buf, 10, &range);
-       if (error) {
-               count = error;
-               goto exit;
-       }
-       dev_dbg(dev, "set range to %lu\n", range);
+static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
+{
+       int i;
 
-       if (range > HMC5843_RANGE_GAIN_MAX) {
-               count = -EINVAL;
-               goto exit;
-       }
+       if (val != 0)
+               return -EINVAL;
 
-       data->range = range;
-       range = range << HMC5843_RANGE_GAIN_OFFSET;
-       if (i2c_smbus_write_byte_data(client, this_attr->address, range))
-               count = -EINVAL;
+       for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+               if (val2 == data->variant->regval_to_nanoscale[i])
+                       return i;
 
-exit:
-       mutex_unlock(&data->lock);
-       return count;
+       return -EINVAL;
 }
 
-static IIO_DEVICE_ATTR(in_magn_range,
-                       S_IWUSR | S_IRUGO,
-                       hmc5843_show_range_gain,
-                       hmc5843_set_range_gain,
-                       HMC5843_CONFIG_REG_B);
-
 static int hmc5843_read_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *chan,
-                           int *val, int *val2,
-                           long mask)
+                           int *val, int *val2, long mask)
 {
        struct hmc5843_data *data = iio_priv(indio_dev);
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
-               return hmc5843_read_measurement(indio_dev,
-                                               chan->address,
-                                               val);
+               return hmc5843_read_measurement(data, chan->scan_index, val);
        case IIO_CHAN_INFO_SCALE:
                *val = 0;
                *val2 = data->variant->regval_to_nanoscale[data->range];
                return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = data->variant->regval_to_samp_freq[data->rate][0];
+               *val2 = data->variant->regval_to_samp_freq[data->rate][1];
+               return IIO_VAL_INT_PLUS_MICRO;
        }
        return -EINVAL;
 }
 
-#define HMC5843_CHANNEL(axis, addr)                                    \
+static int hmc5843_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct hmc5843_data *data = iio_priv(indio_dev);
+       int rate, range;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               rate = hmc5843_get_samp_freq_index(data, val, val2);
+               if (rate < 0)
+                       return -EINVAL;
+
+               return hmc5843_set_samp_freq(data, rate);
+       case IIO_CHAN_INFO_SCALE:
+               range = hmc5843_get_scale_index(data, val, val2);
+               if (range < 0)
+                       return -EINVAL;
+
+               return hmc5843_set_range_gain(data, range);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan, long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SCALE:
+               return IIO_VAL_INT_PLUS_NANO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct hmc5843_data *data = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = hmc5843_wait_measurement(data);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               goto done;
+       }
+
+       ret = i2c_smbus_read_i2c_block_data(data->client,
+               HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
+                       (u8 *) data->buffer);
+       mutex_unlock(&data->lock);
+       if (ret < 0)
+               goto done;
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+               iio_get_time_ns());
+
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+#define HMC5843_CHANNEL(axis, idx)                                     \
        {                                                               \
                .type = IIO_MAGN,                                       \
                .modified = 1,                                          \
                .channel2 = IIO_MOD_##axis,                             \
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
-               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
-               .address = addr                                         \
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
+                       BIT(IIO_CHAN_INFO_SAMP_FREQ),                   \
+               .scan_index = idx,                                      \
+               .scan_type = IIO_ST('s', 16, 16, IIO_BE),               \
        }
 
 static const struct iio_chan_spec hmc5843_channels[] = {
-       HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
-       HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG),
-       HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
+       HMC5843_CHANNEL(X, 0),
+       HMC5843_CHANNEL(Y, 1),
+       HMC5843_CHANNEL(Z, 2),
+       IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 
+/* Beware: Y and Z are exchanged on HMC5883 */
 static const struct iio_chan_spec hmc5883_channels[] = {
-       HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
-       HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG),
-       HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG),
+       HMC5843_CHANNEL(X, 0),
+       HMC5843_CHANNEL(Z, 1),
+       HMC5843_CHANNEL(Y, 2),
+       IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 
 static struct attribute *hmc5843_attributes[] = {
        &iio_dev_attr_meas_conf.dev_attr.attr,
-       &iio_dev_attr_operating_mode.dev_attr.attr,
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
-       &iio_dev_attr_in_magn_range.dev_attr.attr,
+       &iio_dev_attr_scale_available.dev_attr.attr,
        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
        NULL
 };
@@ -590,89 +483,101 @@ static const struct attribute_group hmc5843_group = {
 static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
        [HMC5843_ID] = {
                .channels = hmc5843_channels,
-               .regval_to_sample_freq = hmc5843_regval_to_sample_freq,
-               .regval_to_input_field_mga =
-                       hmc5843_regval_to_input_field_mga,
+               .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
                .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
        },
        [HMC5883_ID] = {
                .channels = hmc5883_channels,
-               .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
-               .regval_to_input_field_mga =
-                       hmc5883_regval_to_input_field_mga,
+               .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
                .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
        },
        [HMC5883L_ID] = {
                .channels = hmc5883_channels,
-               .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
-               .regval_to_input_field_mga =
-                       hmc5883l_regval_to_input_field_mga,
+               .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
                .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
        },
 };
 
-/* Called when we have found a new HMC58X3 */
-static void hmc5843_init_client(struct i2c_client *client,
-                               const struct i2c_device_id *id)
+static int hmc5843_init(struct hmc5843_data *data)
 {
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-
-       data->variant = &hmc5843_chip_info_tbl[id->driver_data];
-       indio_dev->channels = data->variant->channels;
-       indio_dev->num_channels = 3;
-       hmc5843_set_meas_conf(client, data->meas_conf);
-       hmc5843_set_rate(client, data->rate);
-       hmc5843_configure(client, data->operating_mode);
-       i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
-       mutex_init(&data->lock);
+       int ret;
+       u8 id[3];
+
+       ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
+               sizeof(id), id);
+       if (ret < 0)
+               return ret;
+       if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
+               dev_err(&data->client->dev, "no HMC5843/5883/5883L sensor\n");
+               return -ENODEV;
+       }
 
-       pr_info("%s initialized\n", id->name);
+       ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
+       if (ret < 0)
+               return ret;
+       ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
+       if (ret < 0)
+               return ret;
+       ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
+       if (ret < 0)
+               return ret;
+       return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
 }
 
 static const struct iio_info hmc5843_info = {
        .attrs = &hmc5843_group,
        .read_raw = &hmc5843_read_raw,
+       .write_raw = &hmc5843_write_raw,
+       .write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
        .driver_module = THIS_MODULE,
 };
 
+static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
+
 static int hmc5843_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        struct hmc5843_data *data;
        struct iio_dev *indio_dev;
-       int err = 0;
+       int ret;
 
-       indio_dev = iio_device_alloc(sizeof(*data));
-       if (indio_dev == NULL) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (indio_dev == NULL)
+               return -ENOMEM;
 
        /* default settings at probe */
        data = iio_priv(indio_dev);
-       data->meas_conf = HMC5843_MEAS_CONF_NORMAL;
-       data->range = HMC5843_RANGE_GAIN_DEFAULT;
-       data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
+       data->client = client;
+       data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+       mutex_init(&data->lock);
 
        i2c_set_clientdata(client, indio_dev);
-       hmc5843_init_client(client, id);
-
        indio_dev->info = &hmc5843_info;
        indio_dev->name = id->name;
        indio_dev->dev.parent = &client->dev;
        indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = data->variant->channels;
+       indio_dev->num_channels = 4;
+       indio_dev->available_scan_masks = hmc5843_scan_masks;
+
+       ret = hmc5843_init(data);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_triggered_buffer_setup(indio_dev, NULL,
+               hmc5843_trigger_handler, NULL);
+       if (ret < 0)
+               return ret;
 
-       err = iio_device_register(indio_dev);
-       if (err)
-               goto exit_free2;
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               goto buffer_cleanup;
 
        return 0;
 
-exit_free2:
-       iio_device_free(indio_dev);
-exit:
-       return err;
+buffer_cleanup:
+       iio_triggered_buffer_cleanup(indio_dev);
+       return ret;
 }
 
 static int hmc5843_remove(struct i2c_client *client)
@@ -680,9 +585,10 @@ static int hmc5843_remove(struct i2c_client *client)
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 
        iio_device_unregister(indio_dev);
-        /*  sleep mode to save power */
-       hmc5843_configure(client, HMC5843_MODE_SLEEP);
-       iio_device_free(indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+
+       /*  sleep mode to save power */
+       hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
 
        return 0;
 }
@@ -690,19 +596,18 @@ static int hmc5843_remove(struct i2c_client *client)
 #ifdef CONFIG_PM_SLEEP
 static int hmc5843_suspend(struct device *dev)
 {
-       hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
-       return 0;
+       struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+
+       return hmc5843_set_mode(data, HMC5843_MODE_SLEEP);
 }
 
 static int hmc5843_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
 
-       hmc5843_configure(client, data->operating_mode);
-
-       return 0;
+       return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
 }
 
 static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
@@ -730,6 +635,6 @@ static struct i2c_driver hmc5843_driver = {
 };
 module_i2c_driver(hmc5843_driver);
 
-MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
+MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
 MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
 MODULE_LICENSE("GPL");
index 74025fbae6794f3c5f6226efd1b137ef42ec450c..6200335d12f7171b460c060df7a02dc86235dd3c 100644 (file)
@@ -186,9 +186,9 @@ static ssize_t ade7753_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
@@ -204,9 +204,9 @@ static ssize_t ade7753_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
@@ -399,11 +399,11 @@ static ssize_t ade7753_write_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ade7753_state *st = iio_priv(indio_dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u16 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
        if (val == 0)
@@ -497,11 +497,9 @@ static int ade7753_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
 
        /* setup the industrialio driver allocated elements */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        /* this is only used for removal purposes */
        spi_set_drvdata(spi, indio_dev);
 
@@ -517,19 +515,13 @@ static int ade7753_probe(struct spi_device *spi)
        /* Get the device into a sane initial state */
        ret = ade7753_initial_setup(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-
-error_ret:
-       return ret;
 }
 
 /* fixme, confirm ordering in this function */
@@ -539,7 +531,6 @@ static int ade7753_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ade7753_stop_device(&indio_dev->dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index f649ebe55a04d49da431c9c8ff5d45947d7e8ac7..2e046f6e4fb4873e1917983ff6c1474ad803dba3 100644 (file)
@@ -186,9 +186,9 @@ static ssize_t ade7754_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
@@ -204,9 +204,9 @@ static ssize_t ade7754_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
@@ -419,11 +419,11 @@ static ssize_t ade7754_write_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ade7754_state *st = iio_priv(indio_dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u8 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
        if (val == 0)
@@ -520,11 +520,9 @@ static int ade7754_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
 
        /* setup the industrialio driver allocated elements */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        /* this is only used for removal purposes */
        spi_set_drvdata(spi, indio_dev);
 
@@ -540,18 +538,12 @@ static int ade7754_probe(struct spi_device *spi)
        /* Get the device into a sane initial state */
        ret = ade7754_initial_setup(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-
-error_ret:
-       return ret;
 }
 
 /* fixme, confirm ordering in this function */
@@ -561,7 +553,6 @@ static int ade7754_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ade7754_stop_device(&indio_dev->dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 6005d4aab0c346365c7f76ed0047bfb6f2b81cda..cba183e24838e64bd4f69d5e102981118ac9e262 100644 (file)
@@ -269,9 +269,9 @@ static ssize_t ade7758_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
@@ -287,9 +287,9 @@ static ssize_t ade7758_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
@@ -502,11 +502,11 @@ static ssize_t ade7758_write_frequency(struct device *dev,
                size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u8 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
 
@@ -849,12 +849,11 @@ static int ade7758_probe(struct spi_device *spi)
 {
        int ret;
        struct ade7758_state *st;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
 
        st = iio_priv(indio_dev);
        /* this is only used for removal purposes */
@@ -862,10 +861,8 @@ static int ade7758_probe(struct spi_device *spi)
 
        /* Allocate the comms buffers */
        st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
-       if (st->rx == NULL) {
-               ret = -ENOMEM;
-               goto error_free_dev;
-       }
+       if (!st->rx)
+               return -ENOMEM;
        st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
        if (st->tx == NULL) {
                ret = -ENOMEM;
@@ -920,9 +917,6 @@ error_free_tx:
        kfree(st->tx);
 error_free_rx:
        kfree(st->rx);
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
        return ret;
 }
 
@@ -939,8 +933,6 @@ static int ade7758_remove(struct spi_device *spi)
        kfree(st->tx);
        kfree(st->rx);
 
-       iio_device_free(indio_dev);
-
        return 0;
 }
 
index 7d5db71755788372638035b49917e5470cf4bc68..c0accf8cce93f1fdbd3ad3a3d4213220ddb87b17 100644 (file)
@@ -69,11 +69,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
                if (ade7758_spi_read_burst(indio_dev) >= 0)
                        *dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp)
-               dat64[1] = pf->timestamp;
-
-       iio_push_to_buffers(indio_dev, (u8 *)dat64);
+       iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
 
@@ -91,15 +87,10 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
 {
        struct ade7758_state *st = iio_priv(indio_dev);
        unsigned channel;
-       int ret;
 
        if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
                return -EINVAL;
 
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret < 0)
-               return ret;
-
        channel = find_first_bit(indio_dev->active_scan_mask,
                                 indio_dev->masklength);
 
@@ -125,14 +116,17 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
        struct ade7758_state *st = iio_priv(indio_dev);
+       struct iio_buffer *buffer;
        int ret = 0;
 
-       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
-       if (!indio_dev->buffer) {
+       buffer = iio_kfifo_allocate(indio_dev);
+       if (!buffer) {
                ret = -ENOMEM;
                return ret;
        }
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        indio_dev->setup_ops = &ade7758_ring_setup_ops;
 
        indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
index d214ac4932cbef428c4d414967146eb7c92cce4d..145f896aae2b4c38d3663809863f0ff9db2652b6 100644 (file)
@@ -185,9 +185,9 @@ static ssize_t ade7759_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
@@ -203,9 +203,9 @@ static ssize_t ade7759_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
@@ -360,11 +360,11 @@ static ssize_t ade7759_write_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ade7759_state *st = iio_priv(indio_dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u16 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
        if (val == 0)
@@ -444,11 +444,9 @@ static int ade7759_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
 
        /* setup the industrialio driver allocated elements */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        /* this is only used for removal purposes */
        spi_set_drvdata(spi, indio_dev);
 
@@ -463,18 +461,13 @@ static int ade7759_probe(struct spi_device *spi)
        /* Get the device into a sane initial state */
        ret = ade7759_initial_setup(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 
 /* fixme, confirm ordering in this function */
@@ -484,7 +477,6 @@ static int ade7759_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ade7759_stop_device(&indio_dev->dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index db9ef6c86c1edad8df8ef5f94e725ff8021a5c25..5b33c7f1aa9108652fb4d6f7d8ceb81048646113 100644 (file)
@@ -208,7 +208,7 @@ static int ade7854_i2c_probe(struct i2c_client *client,
        struct ade7854_state *st;
        struct iio_dev *indio_dev;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
        st = iio_priv(indio_dev);
@@ -225,8 +225,6 @@ static int ade7854_i2c_probe(struct i2c_client *client,
        st->irq = client->irq;
 
        ret = ade7854_probe(indio_dev, &client->dev);
-       if (ret)
-               iio_device_free(indio_dev);
 
        return ret;
 }
index 4c6d2041260bed259f7cba174c64ceb9a9c1a3f8..94f73bbbc0fd28ec65153b401ef5a401d32d24d2 100644 (file)
@@ -278,7 +278,7 @@ static int ade7854_spi_probe(struct spi_device *spi)
        struct ade7854_state *st;
        struct iio_dev *indio_dev;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
        st = iio_priv(indio_dev);
@@ -296,8 +296,6 @@ static int ade7854_spi_probe(struct spi_device *spi)
 
 
        ret = ade7854_probe(indio_dev, &spi->dev);
-       if (ret)
-               iio_device_free(indio_dev);
 
        return ret;
 }
index e8379c0f1173ffc454067788d16cd39ee8bc48fb..d620bbd603a30db2264bb5f8499c142eb19a3d8c 100644 (file)
@@ -100,9 +100,9 @@ static ssize_t ade7854_write_8bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_8(dev, this_attr->address, val);
@@ -121,9 +121,9 @@ static ssize_t ade7854_write_16bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_16(dev, this_attr->address, val);
@@ -142,9 +142,9 @@ static ssize_t ade7854_write_24bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u32 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou32(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_24(dev, this_attr->address, val);
@@ -163,9 +163,9 @@ static ssize_t ade7854_write_32bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u32 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou32(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_32(dev, this_attr->address, val);
@@ -550,7 +550,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        /* Get the device into a sane initial state */
        ret = ade7854_initial_setup(indio_dev);
@@ -561,9 +561,6 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
 
 error_unreg_dev:
        iio_device_unregister(indio_dev);
-error_free_dev:
-       iio_device_free(indio_dev);
-
        return ret;
 }
 EXPORT_SYMBOL(ade7854_probe);
@@ -571,7 +568,6 @@ EXPORT_SYMBOL(ade7854_probe);
 int ade7854_remove(struct iio_dev *indio_dev)
 {
        iio_device_unregister(indio_dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 71221161aa6b983f37c438755c1d3a5085d34bf5..62d30179301fa52e0d6b9322d553371641b952e2 100644 (file)
@@ -107,16 +107,16 @@ static int ad2s1200_probe(struct spi_device *spi)
        unsigned short *pins = spi->dev.platform_data;
 
        for (pn = 0; pn < AD2S1200_PN; pn++)
-               if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) {
-                       pr_err("%s: request gpio pin %d failed\n",
-                                               DRV_NAME, pins[pn]);
-                       goto error_ret;
+               ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
+                                           DRV_NAME);
+               if (ret) {
+                       dev_err(&spi->dev, "request gpio pin %d failed\n",
+                                                       pins[pn]);
+                       return ret;
                }
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        spi_set_drvdata(spi, indio_dev);
        st = iio_priv(indio_dev);
        mutex_init(&st->lock);
@@ -133,26 +133,18 @@ static int ad2s1200_probe(struct spi_device *spi)
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        spi->max_speed_hz = AD2S1200_HZ;
        spi->mode = SPI_MODE_3;
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       for (--pn; pn >= 0; pn--)
-               gpio_free(pins[pn]);
-       return ret;
 }
 
 static int ad2s1200_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index dcdadbbcf7e864978fbd119721f1cf058ba69234..6966d5f766481befae4cb5d250434842acc06bc1 100644 (file)
@@ -206,10 +206,10 @@ static ssize_t ad2s1210_store_fclkin(struct device *dev,
                                     size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long fclkin;
+       unsigned int fclkin;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &fclkin);
+       ret = kstrtouint(buf, 10, &fclkin);
        if (ret)
                return ret;
        if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
@@ -243,10 +243,10 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
                                     const char *buf, size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long fexcit;
+       unsigned int fexcit;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &fexcit);
+       ret = kstrtouint(buf, 10, &fexcit);
        if (ret < 0)
                return ret;
        if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
@@ -282,11 +282,11 @@ static ssize_t ad2s1210_store_control(struct device *dev,
                        const char *buf, size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long udata;
+       unsigned char udata;
        unsigned char data;
        int ret;
 
-       ret = strict_strtoul(buf, 16, &udata);
+       ret = kstrtou8(buf, 16, &udata);
        if (ret)
                return -EINVAL;
 
@@ -337,10 +337,10 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
        unsigned char data;
-       unsigned long udata;
+       unsigned char udata;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &udata);
+       ret = kstrtou8(buf, 10, &udata);
        if (ret || udata < 10 || udata > 16) {
                pr_err("ad2s1210: resolution out of range\n");
                return -EINVAL;
@@ -438,11 +438,11 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long data;
+       unsigned char data;
        int ret;
        struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou8(buf, 10, &data);
        if (ret)
                return -EINVAL;
        mutex_lock(&st->lock);
@@ -669,16 +669,14 @@ static int ad2s1210_probe(struct spi_device *spi)
        if (spi->dev.platform_data == NULL)
                return -EINVAL;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        st = iio_priv(indio_dev);
        st->pdata = spi->dev.platform_data;
        ret = ad2s1210_setup_gpios(st);
        if (ret < 0)
-               goto error_free_dev;
+               return ret;
 
        spi_set_drvdata(spi, indio_dev);
 
@@ -709,9 +707,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 
 error_free_gpios:
        ad2s1210_free_gpios(st);
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
        return ret;
 }
 
@@ -721,7 +716,6 @@ static int ad2s1210_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ad2s1210_free_gpios(iio_priv(indio_dev));
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 40b825286d4af65dfe9228baa76c0af392096fa9..e24c5890652f8d1c1b0280875f25cde6fb0050a5 100644 (file)
@@ -64,11 +64,9 @@ static int ad2s90_probe(struct spi_device *spi)
        struct ad2s90_state *st;
        int ret = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        st = iio_priv(indio_dev);
        spi_set_drvdata(spi, indio_dev);
 
@@ -83,7 +81,7 @@ static int ad2s90_probe(struct spi_device *spi)
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        /* need 600ns between CS and the first falling edge of SCLK */
        spi->max_speed_hz = 830000;
@@ -91,17 +89,11 @@ static int ad2s90_probe(struct spi_device *spi)
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 
 static int ad2s90_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 38a158b77b1d24f3d55ac12c08ae13b0792b8d20..26e1ca0b7800223b88f3102d562d0c7c084087bb 100644 (file)
@@ -83,32 +83,28 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
 {
        struct iio_trigger *trig = to_iio_trigger(dev);
        struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);
-       unsigned long val;
+       unsigned int val;
        bool enabled;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtouint(buf, 10, &val);
        if (ret)
-               goto error_ret;
+               return ret;
 
-       if (val > 100000) {
-               ret = -EINVAL;
-               goto error_ret;
-       }
+       if (val > 100000)
+               return -EINVAL;
 
        enabled = get_enabled_gptimers() & st->t->bit;
 
        if (enabled)
                disable_gptimers(st->t->bit);
 
-       if (!val)
-               goto error_ret;
+       if (val == 0)
+               return count;
 
        val = get_sclk() / val;
-       if (val <= 4 || val <= st->duty) {
-               ret = -EINVAL;
-               goto error_ret;
-       }
+       if (val <= 4 || val <= st->duty)
+               return -EINVAL;
 
        set_gptimer_period(st->t->id, val);
        set_gptimer_pwidth(st->t->id, val - st->duty);
@@ -116,8 +112,7 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
        if (enabled)
                enable_gptimers(st->t->bit);
 
-error_ret:
-       return ret ? ret : count;
+       return count;
 }
 
 static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
index 79695974b1d43dde0a46e1dbf60e00254edd0807..48a6afa8408805ff3a8f2ab25689ebccc3e419cf 100644 (file)
@@ -53,10 +53,10 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
 {
        struct iio_trigger *trig = to_iio_trigger(dev);
        struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
-       unsigned long val;
+       int val;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoint(buf, 10, &val);
        if (ret)
                goto error_ret;
 
index bfaf69378ac208b33f8ec3e956be0d2136b802dc..2c3a9e178fb5e65a073dc777b1c7dd86c7a9f34f 100644 (file)
@@ -8,4 +8,4 @@ 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
+obj-$(CONFIG_DRM_IMX_IPUV3)    += ipuv3-crtc.o ipuv3-plane.o
index 9cfa2a7efdc06818a91fa81e11f8ee34530fcddf..6a9da94c957341a1a09312414bb687848cb688d2 100644 (file)
@@ -9,7 +9,6 @@ TODO:
 
 Missing features (not necessarily for moving out of staging):
 
-- Add KMS plane support for CRTC driver
 - Add i.MX6 HDMI support
 - Add support for IC (Image converter)
 - Add support for CSI (CMOS Sensor interface)
index a2e52a0c53c981690dc7b711a1a97625c01a9a0f..4483d47f739525a19faed977860a3e8daf931aab 100644 (file)
@@ -68,6 +68,11 @@ struct imx_drm_connector {
        struct module                           *owner;
 };
 
+int imx_drm_crtc_id(struct imx_drm_crtc *crtc)
+{
+       return crtc->pipe;
+}
+
 static void imx_drm_driver_lastclose(struct drm_device *drm)
 {
        struct imx_drm_device *imxdrm = drm->dev_private;
@@ -110,18 +115,12 @@ int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type,
        struct imx_drm_crtc *imx_crtc;
        struct imx_drm_crtc_helper_funcs *helper;
 
-       mutex_lock(&imxdrm->mutex);
-
        list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list)
                if (imx_crtc->crtc == crtc)
                        goto found;
 
-       mutex_unlock(&imxdrm->mutex);
-
        return -EINVAL;
 found:
-       mutex_unlock(&imxdrm->mutex);
-
        helper = &imx_crtc->imx_drm_helper_funcs;
        if (helper->set_interface_pix_fmt)
                return helper->set_interface_pix_fmt(crtc,
@@ -191,6 +190,18 @@ static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
        imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
 }
 
+static void imx_drm_driver_preclose(struct drm_device *drm,
+               struct drm_file *file)
+{
+       int i;
+
+       if (!file->is_master)
+               return;
+
+       for (i = 0; i < 4; i++)
+               imx_drm_disable_vblank(drm , i);
+}
+
 static const struct file_operations imx_drm_driver_fops = {
        .owner = THIS_MODULE,
        .open = drm_open,
@@ -647,20 +658,14 @@ int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder,
        struct imx_drm_crtc *imx_crtc;
        int i = 0;
 
-       mutex_lock(&imxdrm->mutex);
-
        list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) {
                if (imx_crtc->crtc == crtc)
                        goto found;
                i++;
        }
 
-       mutex_unlock(&imxdrm->mutex);
-
        return -EINVAL;
 found:
-       mutex_unlock(&imxdrm->mutex);
-
        return i;
 }
 EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id);
@@ -774,16 +779,26 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
 };
 
 static struct drm_driver imx_drm_driver = {
-       .driver_features        = DRIVER_MODESET | DRIVER_GEM,
+       .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
        .load                   = imx_drm_driver_load,
        .unload                 = imx_drm_driver_unload,
        .lastclose              = imx_drm_driver_lastclose,
+       .preclose               = imx_drm_driver_preclose,
        .gem_free_object        = drm_gem_cma_free_object,
        .gem_vm_ops             = &drm_gem_cma_vm_ops,
        .dumb_create            = drm_gem_cma_dumb_create,
        .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
        .dumb_destroy           = drm_gem_dumb_destroy,
 
+       .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
+       .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
+       .gem_prime_import       = drm_gem_prime_import,
+       .gem_prime_export       = drm_gem_prime_export,
+       .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+       .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+       .gem_prime_vmap         = drm_gem_cma_prime_vmap,
+       .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
+       .gem_prime_mmap         = drm_gem_cma_prime_mmap,
        .get_vblank_counter     = drm_vblank_count,
        .enable_vblank          = imx_drm_enable_vblank,
        .disable_vblank         = imx_drm_disable_vblank,
@@ -837,8 +852,8 @@ static int __init imx_drm_init(void)
        INIT_LIST_HEAD(&imx_drm_device->encoder_list);
 
        imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0);
-       if (!imx_drm_pdev) {
-               ret = -EINVAL;
+       if (IS_ERR(imx_drm_pdev)) {
+               ret = PTR_ERR(imx_drm_pdev);
                goto err_pdev;
        }
 
index f2aac91ddf5d51e45f739c041e57b53c5eb868e5..ae90c9c15312c2ca57fb1884b622a8bf0469cf0e 100644 (file)
@@ -14,6 +14,8 @@ struct drm_fbdev_cma;
 struct drm_framebuffer;
 struct platform_device;
 
+int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
+
 struct imx_drm_crtc_helper_funcs {
        int (*enable_vblank)(struct drm_crtc *crtc);
        void (*disable_vblank)(struct drm_crtc *crtc);
index af733ea485656877e86cc9ae760846fa81deb3d0..654bf03e05ff8b34450674ce3142f5942b924420 100644 (file)
@@ -359,10 +359,8 @@ static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
 
        sprintf(clkname, "di%d_pll", chno);
        ldb->clk_pll[chno] = devm_clk_get(ldb->dev, clkname);
-       if (IS_ERR(ldb->clk_pll[chno]))
-               return PTR_ERR(ldb->clk_pll[chno]);
 
-       return 0;
+       return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]);
 }
 
 static int imx_ldb_register(struct imx_ldb_channel *imx_ldb_ch)
@@ -421,7 +419,7 @@ static const char *imx_ldb_bit_mappings[] = {
        [LVDS_BIT_MAP_JEIDA] = "jeida",
 };
 
-const int of_get_data_mapping(struct device_node *np)
+static const int of_get_data_mapping(struct device_node *np)
 {
        const char *bm;
        int ret, i;
@@ -466,8 +464,7 @@ static int imx_ldb_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *of_id =
-                       of_match_device(of_match_ptr(imx_ldb_dt_ids),
-                                       &pdev->dev);
+                       of_match_device(imx_ldb_dt_ids, &pdev->dev);
        struct device_node *child;
        const u8 *edidp;
        struct imx_ldb *imx_ldb;
index 33d6525cf9960c5b4a36b2114a6f9fffc9ca7711..680f4c8fa0815481a410621eb616879dbb149109 100644 (file)
@@ -151,7 +151,7 @@ static void tve_enable(struct imx_tve *tve)
 
        spin_lock_irqsave(&tve->enable_lock, flags);
        if (!tve->enabled) {
-               tve->enabled = 1;
+               tve->enabled = true;
                clk_prepare_enable(tve->clk);
                ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
                                         TVE_IPU_CLK_EN | TVE_EN,
@@ -180,7 +180,7 @@ static void tve_disable(struct imx_tve *tve)
 
        spin_lock_irqsave(&tve->enable_lock, flags);
        if (tve->enabled) {
-               tve->enabled = 0;
+               tve->enabled = false;
                ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
                                         TVE_IPU_CLK_EN | TVE_EN, 0);
                clk_disable_unprepare(tve->clk);
@@ -696,7 +696,7 @@ static int imx_tve_probe(struct platform_device *pdev)
        if (val != 0x00100000) {
                dev_err(&pdev->dev, "configuration register default value indicates this is not a TVEv2\n");
                return -ENODEV;
-       };
+       }
 
        /* disable cable detection for VGA mode */
        ret = regmap_write(tve->regmap, TVE_CD_CONT_REG, 0);
index 74c022e2a5324ce2042363890d84f9e530075988..4826b5c0249d1b202cd69b8474d35a2729962c18 100644 (file)
@@ -97,6 +97,7 @@ void ipu_idmac_put(struct ipuv3_channel *);
 
 int ipu_idmac_enable_channel(struct ipuv3_channel *channel);
 int ipu_idmac_disable_channel(struct ipuv3_channel *channel);
+int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms);
 
 void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
                bool doublebuffer);
@@ -283,7 +284,7 @@ int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p,
                int width);
 
 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *,
-               struct ipu_rgb *rgb);
+               const struct ipu_rgb *rgb);
 
 static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p,
                int stride)
@@ -303,6 +304,7 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat);
 int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
                struct ipu_image *image);
 
+enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc);
 enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat);
 
 static inline void ipu_cpmem_set_burstsize(struct ipu_ch_param __iomem *p,
index ba464e5d9f125ede776ad56a47f9181442667d11..7a22ce619ed264ba536de785650700b02f6d3ef3 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/irqdomain.h>
 #include <linux/of_device.h>
 
+#include <drm/drm_fourcc.h>
+
 #include "imx-ipu-v3.h"
 #include "ipu-prv.h"
 
@@ -139,7 +141,7 @@ u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs)
 EXPORT_SYMBOL_GPL(ipu_ch_param_read_field);
 
 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *p,
-               struct ipu_rgb *rgb)
+               const struct ipu_rgb *rgb)
 {
        int bpp = 0, npb = 0, ro, go, bo, to;
 
@@ -282,7 +284,7 @@ void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
 }
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar);
 
-static struct ipu_rgb def_rgb_32 = {
+static const struct ipu_rgb def_rgb_32 = {
        .red    = { .offset = 16, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
        .blue   = { .offset =  0, .length = 8, },
@@ -290,31 +292,31 @@ static struct ipu_rgb def_rgb_32 = {
        .bits_per_pixel = 32,
 };
 
-static struct ipu_rgb def_bgr_32 = {
-       .red    = { .offset = 16, .length = 8, },
+static const struct ipu_rgb def_bgr_32 = {
+       .red    = { .offset =  0, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
-       .blue   = { .offset =  0, .length = 8, },
+       .blue   = { .offset = 16, .length = 8, },
        .transp = { .offset = 24, .length = 8, },
        .bits_per_pixel = 32,
 };
 
-static struct ipu_rgb def_rgb_24 = {
-       .red    = { .offset =  0, .length = 8, },
+static const struct ipu_rgb def_rgb_24 = {
+       .red    = { .offset = 16, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
-       .blue   = { .offset = 16, .length = 8, },
+       .blue   = { .offset =  0, .length = 8, },
        .transp = { .offset =  0, .length = 0, },
        .bits_per_pixel = 24,
 };
 
-static struct ipu_rgb def_bgr_24 = {
-       .red    = { .offset = 16, .length = 8, },
+static const struct ipu_rgb def_bgr_24 = {
+       .red    = { .offset =  0, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
-       .blue   = { .offset =  0, .length = 8, },
+       .blue   = { .offset = 16, .length = 8, },
        .transp = { .offset =  0, .length = 0, },
        .bits_per_pixel = 24,
 };
 
-static struct ipu_rgb def_rgb_16 = {
+static const struct ipu_rgb def_rgb_16 = {
        .red    = { .offset = 11, .length = 5, },
        .green  = { .offset =  5, .length = 6, },
        .blue   = { .offset =  0, .length = 5, },
@@ -322,6 +324,14 @@ static struct ipu_rgb def_rgb_16 = {
        .bits_per_pixel = 16,
 };
 
+static const struct ipu_rgb def_bgr_16 = {
+       .red    = { .offset =  0, .length = 5, },
+       .green  = { .offset =  5, .length = 6, },
+       .blue   = { .offset = 11, .length = 5, },
+       .transp = { .offset =  0, .length = 0, },
+       .bits_per_pixel = 16,
+};
+
 #define Y_OFFSET(pix, x, y)    ((x) + pix->width * (y))
 #define U_OFFSET(pix, x, y)    ((pix->width * pix->height) + \
                                        (pix->width * (y) / 4) + (x) / 2)
@@ -329,17 +339,17 @@ static struct ipu_rgb def_rgb_16 = {
                                        (pix->width * pix->height / 4) + \
                                        (pix->width * (y) / 4) + (x) / 2)
 
-int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
+int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 drm_fourcc)
 {
-       switch (pixelformat) {
-       case V4L2_PIX_FMT_YUV420:
-       case V4L2_PIX_FMT_YVU420:
+       switch (drm_fourcc) {
+       case DRM_FORMAT_YUV420:
+       case DRM_FORMAT_YVU420:
                /* pix format */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2);
                /* burst size */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 63);
                break;
-       case V4L2_PIX_FMT_UYVY:
+       case DRM_FORMAT_UYVY:
                /* bits/pixel */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
                /* pix format */
@@ -347,7 +357,7 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
                /* burst size */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
                break;
-       case V4L2_PIX_FMT_YUYV:
+       case DRM_FORMAT_YUYV:
                /* bits/pixel */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
                /* pix format */
@@ -355,20 +365,25 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
                /* burst size */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
                break;
-       case V4L2_PIX_FMT_RGB32:
-               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32);
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_XBGR8888:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32);
                break;
-       case V4L2_PIX_FMT_RGB565:
-               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16);
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_XRGB8888:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32);
                break;
-       case V4L2_PIX_FMT_BGR32:
-               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32);
+       case DRM_FORMAT_BGR888:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24);
                break;
-       case V4L2_PIX_FMT_RGB24:
+       case DRM_FORMAT_RGB888:
                ipu_cpmem_set_format_rgb(cpmem, &def_rgb_24);
                break;
-       case V4L2_PIX_FMT_BGR24:
-               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24);
+       case DRM_FORMAT_RGB565:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16);
+               break;
+       case DRM_FORMAT_BGR565:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_16);
                break;
        default:
                return -EINVAL;
@@ -378,6 +393,79 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
 }
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt);
 
+/*
+ * The V4L2 spec defines packed RGB formats in memory byte order, which from
+ * point of view of the IPU corresponds to little-endian words with the first
+ * component in the least significant bits.
+ * The DRM pixel formats and IPU internal representation are ordered the other
+ * way around, with the first named component ordered at the most significant
+ * bits. Further, V4L2 formats are not well defined:
+ *     http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html
+ * We choose the interpretation which matches GStreamer behavior.
+ */
+static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat)
+{
+       switch (pixelformat) {
+       case V4L2_PIX_FMT_RGB565:
+               /*
+                * Here we choose the 'corrected' interpretation of RGBP, a
+                * little-endian 16-bit word with the red component at the most
+                * significant bits:
+                * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B
+                */
+               return DRM_FORMAT_RGB565;
+       case V4L2_PIX_FMT_BGR24:
+               /* B G R <=> [24:0] R:G:B */
+               return DRM_FORMAT_RGB888;
+       case V4L2_PIX_FMT_RGB24:
+               /* R G B <=> [24:0] B:G:R */
+               return DRM_FORMAT_BGR888;
+       case V4L2_PIX_FMT_BGR32:
+               /* B G R A <=> [32:0] A:B:G:R */
+               return DRM_FORMAT_XRGB8888;
+       case V4L2_PIX_FMT_RGB32:
+               /* R G B A <=> [32:0] A:B:G:R */
+               return DRM_FORMAT_XBGR8888;
+       case V4L2_PIX_FMT_UYVY:
+               return DRM_FORMAT_UYVY;
+       case V4L2_PIX_FMT_YUYV:
+               return DRM_FORMAT_YUYV;
+       case V4L2_PIX_FMT_YUV420:
+               return DRM_FORMAT_YUV420;
+       case V4L2_PIX_FMT_YVU420:
+               return DRM_FORMAT_YVU420;
+       }
+
+       return -EINVAL;
+}
+
+enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc)
+{
+       switch (drm_fourcc) {
+       case DRM_FORMAT_RGB565:
+       case DRM_FORMAT_BGR565:
+       case DRM_FORMAT_RGB888:
+       case DRM_FORMAT_BGR888:
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_RGBX8888:
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_RGBA8888:
+       case DRM_FORMAT_BGRA8888:
+               return IPUV3_COLORSPACE_RGB;
+       case DRM_FORMAT_YUYV:
+       case DRM_FORMAT_UYVY:
+       case DRM_FORMAT_YUV420:
+       case DRM_FORMAT_YVU420:
+               return IPUV3_COLORSPACE_YUV;
+       default:
+               return IPUV3_COLORSPACE_UNKNOWN;
+       }
+}
+EXPORT_SYMBOL_GPL(ipu_drm_fourcc_to_colorspace);
+
 int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
                struct ipu_image *image)
 {
@@ -392,7 +480,7 @@ int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
                        image->rect.height);
        ipu_cpmem_set_stride(cpmem, pix->bytesperline);
 
-       ipu_cpmem_set_fmt(cpmem, pix->pixelformat);
+       ipu_cpmem_set_fmt(cpmem, v4l2_pix_fmt_to_drm_fourcc(pix->pixelformat));
 
        switch (pix->pixelformat) {
        case V4L2_PIX_FMT_YUV420:
@@ -476,7 +564,7 @@ struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num)
                goto out;
        }
 
-       channel->busy = 1;
+       channel->busy = true;
        channel->num = num;
 
 out:
@@ -494,7 +582,7 @@ void ipu_idmac_put(struct ipuv3_channel *channel)
 
        mutex_lock(&ipu->channel_lock);
 
-       channel->busy = 0;
+       channel->busy = false;
 
        mutex_unlock(&ipu->channel_lock);
 }
@@ -610,24 +698,29 @@ int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
 }
 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
 
-int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
 {
        struct ipu_soc *ipu = channel->ipu;
-       u32 val;
-       unsigned long flags;
        unsigned long timeout;
 
-       timeout = jiffies + msecs_to_jiffies(50);
+       timeout = jiffies + msecs_to_jiffies(ms);
        while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
                        idma_mask(channel->num)) {
-               if (time_after(jiffies, timeout)) {
-                       dev_warn(ipu->dev, "disabling busy idmac channel %d\n",
-                                       channel->num);
-                       break;
-               }
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
                cpu_relax();
        }
 
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
+
+int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       u32 val;
+       unsigned long flags;
+
        spin_lock_irqsave(&ipu->lock, flags);
 
        /* Disable DMA channel(s) */
@@ -888,7 +981,7 @@ static const struct ipu_platform_reg client_reg[] = {
                        .dc = 5,
                        .dp = IPU_DP_FLOW_SYNC_BG,
                        .dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC,
-                       .dma[1] = -EINVAL,
+                       .dma[1] = IPUV3_CHANNEL_MEM_FG_SYNC,
                },
                .name = "imx-ipuv3-crtc",
        }, {
@@ -913,7 +1006,7 @@ static int ipu_add_subdevice_pdata(struct device *dev,
        pdev = platform_device_register_data(dev, reg->name, ipu_client_id++,
                        &reg->pdata, sizeof(struct ipu_platform_reg));
 
-       return pdev ? 0 : -EINVAL;
+       return PTR_ERR_OR_ZERO(pdev);
 }
 
 static int ipu_add_client_devices(struct ipu_soc *ipu)
index 21bf1c8065288edb83c34108f65885f264185434..d0e3bc3c53e708dbf761e4e9a5760935f55c26b8 100644 (file)
@@ -91,6 +91,7 @@ enum ipu_dc_map {
        IPU_DC_MAP_RGB565,
        IPU_DC_MAP_GBR24, /* TVEv2 */
        IPU_DC_MAP_BGR666,
+       IPU_DC_MAP_BGR24,
 };
 
 struct ipu_dc {
@@ -152,6 +153,8 @@ static int ipu_pixfmt_to_map(u32 fmt)
                return IPU_DC_MAP_GBR24;
        case V4L2_PIX_FMT_BGR666:
                return IPU_DC_MAP_BGR666;
+       case V4L2_PIX_FMT_BGR24:
+               return IPU_DC_MAP_BGR24;
        default:
                return -EINVAL;
        }
@@ -313,7 +316,7 @@ struct ipu_dc *ipu_dc_get(struct ipu_soc *ipu, int channel)
                return ERR_PTR(-EBUSY);
        }
 
-       dc->in_use = 1;
+       dc->in_use = true;
 
        mutex_unlock(&priv->mutex);
 
@@ -326,7 +329,7 @@ void ipu_dc_put(struct ipu_dc *dc)
        struct ipu_dc_priv *priv = dc->priv;
 
        mutex_lock(&priv->mutex);
-       dc->in_use = 0;
+       dc->in_use = false;
        mutex_unlock(&priv->mutex);
 }
 EXPORT_SYMBOL_GPL(ipu_dc_put);
@@ -395,6 +398,12 @@ int ipu_dc_init(struct ipu_soc *ipu, struct device *dev,
        ipu_dc_map_config(priv, IPU_DC_MAP_BGR666, 1, 11, 0xfc); /* green */
        ipu_dc_map_config(priv, IPU_DC_MAP_BGR666, 2, 17, 0xfc); /* red */
 
+       /* bgr24 */
+       ipu_dc_map_clear(priv, IPU_DC_MAP_BGR24);
+       ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 2, 7, 0xff); /* red */
+       ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 1, 15, 0xff); /* green */
+       ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 0, 23, 0xff); /* blue */
+
        return 0;
 }
 
index 2e97c33b81e7ca32ed9498aa05f0be1b470bb961..98070dd8c92057c85b6a9aea1b9236fbb504b89f 100644 (file)
@@ -307,13 +307,13 @@ int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc,
                goto out;
        }
 
-       /* Always allocate at least 128*4 bytes (2 slots) */
-       if (slots < 2)
-               slots = 2;
-
        /* For the MEM_BG channel, first try to allocate twice the slots */
        if (dmfc->data->ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC)
                segment = dmfc_find_slots(priv, slots * 2);
+       else if (slots < 2)
+               /* Always allocate at least 128*4 bytes (2 slots) */
+               slots = 2;
+
        if (segment >= 0)
                slots *= 2;
        else
index 231afd6c60f848fb13b8fc6f6b66ef6684aa8e75..58f87c8d7c07ad611a09d0c0bae62df482adb121 100644 (file)
@@ -325,7 +325,7 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
        mutex_init(&priv->mutex);
 
        for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
-               priv->flow[i].foreground.foreground = 1;
+               priv->flow[i].foreground.foreground = true;
                priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
                priv->flow[i].priv = priv;
        }
index 6fd37a7453e9691ac573c414d396e69357e7b38f..670a56a834f112b590e05d357fe0e0a099c45b48 100644 (file)
 #include <drm/drm_crtc_helper.h>
 #include <linux/fb.h>
 #include <linux/clk.h>
+#include <linux/errno.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_fb_cma_helper.h>
 
 #include "ipu-v3/imx-ipu-v3.h"
 #include "imx-drm.h"
+#include "ipuv3-plane.h"
 
 #define DRIVER_DESC            "i.MX IPUv3 Graphics"
 
-struct ipu_framebuffer {
-       struct drm_framebuffer  base;
-       void                    *virt;
-       dma_addr_t              phys;
-       size_t                  len;
-};
-
 struct ipu_crtc {
        struct device           *dev;
        struct drm_crtc         base;
        struct imx_drm_crtc     *imx_crtc;
-       struct ipuv3_channel    *ipu_ch;
+
+       /* plane[0] is the full plane, plane[1] is the partial plane */
+       struct ipu_plane        *plane[2];
+
        struct ipu_dc           *dc;
-       struct ipu_dp           *dp;
-       struct dmfc_channel     *dmfc;
        struct ipu_di           *di;
        int                     enabled;
        struct drm_pending_vblank_event *page_flip_event;
@@ -61,35 +57,14 @@ struct ipu_crtc {
 
 #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
 
-static int calc_vref(struct drm_display_mode *mode)
-{
-       unsigned long htotal, vtotal;
-
-       htotal = mode->htotal;
-       vtotal = mode->vtotal;
-
-       if (!htotal || !vtotal)
-               return 60;
-
-       return mode->clock * 1000 / vtotal / htotal;
-}
-
-static int calc_bandwidth(struct drm_display_mode *mode, unsigned int vref)
-{
-       return mode->hdisplay * mode->vdisplay * vref;
-}
-
 static void ipu_fb_enable(struct ipu_crtc *ipu_crtc)
 {
        if (ipu_crtc->enabled)
                return;
 
        ipu_di_enable(ipu_crtc->di);
-       ipu_dmfc_enable_channel(ipu_crtc->dmfc);
-       ipu_idmac_enable_channel(ipu_crtc->ipu_ch);
        ipu_dc_enable_channel(ipu_crtc->dc);
-       if (ipu_crtc->dp)
-               ipu_dp_enable_channel(ipu_crtc->dp);
+       ipu_plane_enable(ipu_crtc->plane[0]);
 
        ipu_crtc->enabled = 1;
 }
@@ -99,11 +74,8 @@ static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
        if (!ipu_crtc->enabled)
                return;
 
-       if (ipu_crtc->dp)
-               ipu_dp_disable_channel(ipu_crtc->dp);
+       ipu_plane_disable(ipu_crtc->plane[0]);
        ipu_dc_disable_channel(ipu_crtc->dc);
-       ipu_idmac_disable_channel(ipu_crtc->ipu_ch);
-       ipu_dmfc_disable_channel(ipu_crtc->dmfc);
        ipu_di_disable(ipu_crtc->di);
 
        ipu_crtc->enabled = 0;
@@ -159,33 +131,6 @@ static const struct drm_crtc_funcs ipu_crtc_funcs = {
        .page_flip = ipu_page_flip,
 };
 
-static int ipu_drm_set_base(struct drm_crtc *crtc, int x, int y)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-       struct drm_gem_cma_object *cma_obj;
-       struct drm_framebuffer *fb = crtc->fb;
-       unsigned long phys;
-
-       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
-       if (!cma_obj) {
-               DRM_LOG_KMS("entry is null.\n");
-               return -EFAULT;
-       }
-
-       phys = cma_obj->paddr;
-       phys += x * (fb->bits_per_pixel >> 3);
-       phys += y * fb->pitches[0];
-
-       dev_dbg(ipu_crtc->dev, "%s: phys: 0x%lx\n", __func__, phys);
-       dev_dbg(ipu_crtc->dev, "%s: xy: %dx%d\n", __func__, x, y);
-
-       ipu_cpmem_set_stride(ipu_get_cpmem(ipu_crtc->ipu_ch), fb->pitches[0]);
-       ipu_cpmem_set_buffer(ipu_get_cpmem(ipu_crtc->ipu_ch),
-                         0, phys);
-
-       return 0;
-}
-
 static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                               struct drm_display_mode *orig_mode,
                               struct drm_display_mode *mode,
@@ -193,41 +138,15 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                               struct drm_framebuffer *old_fb)
 {
        struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-       struct drm_framebuffer *fb = ipu_crtc->base.fb;
        int ret;
        struct ipu_di_signal_cfg sig_cfg = {};
        u32 out_pixel_fmt;
-       struct ipu_ch_param __iomem *cpmem = ipu_get_cpmem(ipu_crtc->ipu_ch);
-       int bpp;
-       u32 v4l2_fmt;
 
        dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
                        mode->hdisplay);
        dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
                        mode->vdisplay);
 
-       ipu_ch_param_zero(cpmem);
-
-       switch (fb->pixel_format) {
-       case DRM_FORMAT_XRGB8888:
-       case DRM_FORMAT_ARGB8888:
-               v4l2_fmt = V4L2_PIX_FMT_RGB32;
-               bpp = 32;
-               break;
-       case DRM_FORMAT_RGB565:
-               v4l2_fmt = V4L2_PIX_FMT_RGB565;
-               bpp = 16;
-               break;
-       case DRM_FORMAT_RGB888:
-               v4l2_fmt = V4L2_PIX_FMT_RGB24;
-               bpp = 24;
-               break;
-       default:
-               dev_err(ipu_crtc->dev, "unsupported pixel format 0x%08x\n",
-                               fb->pixel_format);
-               return -EINVAL;
-       }
-
        out_pixel_fmt = ipu_crtc->interface_pix_fmt;
 
        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
@@ -238,7 +157,7 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                sig_cfg.Vsync_pol = 1;
 
        sig_cfg.enable_pol = 1;
-       sig_cfg.clk_pol = 0;
+       sig_cfg.clk_pol = 1;
        sig_cfg.width = mode->hdisplay;
        sig_cfg.height = mode->vdisplay;
        sig_cfg.pixel_fmt = out_pixel_fmt;
@@ -257,18 +176,6 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
        sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
        sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
 
-       if (ipu_crtc->dp) {
-               ret = ipu_dp_setup_channel(ipu_crtc->dp, IPUV3_COLORSPACE_RGB,
-                               IPUV3_COLORSPACE_RGB);
-               if (ret) {
-                       dev_err(ipu_crtc->dev,
-                               "initializing display processor failed with %d\n",
-                               ret);
-                       return ret;
-               }
-               ipu_dp_set_global_alpha(ipu_crtc->dp, 1, 0, 1);
-       }
-
        ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced,
                        out_pixel_fmt, mode->hdisplay);
        if (ret) {
@@ -285,30 +192,9 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                return ret;
        }
 
-       ipu_cpmem_set_resolution(cpmem, mode->hdisplay, mode->vdisplay);
-       ipu_cpmem_set_fmt(cpmem, v4l2_fmt);
-       ipu_cpmem_set_high_priority(ipu_crtc->ipu_ch);
-
-       ret = ipu_dmfc_init_channel(ipu_crtc->dmfc, mode->hdisplay);
-       if (ret) {
-               dev_err(ipu_crtc->dev,
-                               "initializing dmfc channel failed with %d\n",
-                               ret);
-               return ret;
-       }
-
-       ret = ipu_dmfc_alloc_bandwidth(ipu_crtc->dmfc,
-                       calc_bandwidth(mode, calc_vref(mode)), 64);
-       if (ret) {
-               dev_err(ipu_crtc->dev,
-                               "allocating dmfc bandwidth failed with %d\n",
-                               ret);
-               return ret;
-       }
-
-       ipu_drm_set_base(crtc, x, y);
-
-       return 0;
+       return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, crtc->fb,
+                                 0, 0, mode->hdisplay, mode->vdisplay,
+                                 x, y, mode->hdisplay, mode->vdisplay);
 }
 
 static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
@@ -332,7 +218,7 @@ static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
 
        if (ipu_crtc->newfb) {
                ipu_crtc->newfb = NULL;
-               ipu_drm_set_base(&ipu_crtc->base, 0, 0);
+               ipu_plane_set_base(ipu_crtc->plane[0], ipu_crtc->base.fb, 0, 0);
                ipu_crtc_handle_pageflip(ipu_crtc);
        }
 
@@ -370,10 +256,6 @@ static struct drm_crtc_helper_funcs ipu_helper_funcs = {
 
 static int ipu_enable_vblank(struct drm_crtc *crtc)
 {
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       enable_irq(ipu_crtc->irq);
-
        return 0;
 }
 
@@ -381,7 +263,8 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
 {
        struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
 
-       disable_irq(ipu_crtc->irq);
+       ipu_crtc->page_flip_event = NULL;
+       ipu_crtc->newfb = NULL;
 }
 
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
@@ -418,12 +301,8 @@ static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = {
 
 static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
 {
-       if (!IS_ERR_OR_NULL(ipu_crtc->ipu_ch))
-               ipu_idmac_put(ipu_crtc->ipu_ch);
-       if (!IS_ERR_OR_NULL(ipu_crtc->dmfc))
-               ipu_dmfc_put(ipu_crtc->dmfc);
-       if (!IS_ERR_OR_NULL(ipu_crtc->dp))
-               ipu_dp_put(ipu_crtc->dp);
+       if (!IS_ERR_OR_NULL(ipu_crtc->dc))
+               ipu_dc_put(ipu_crtc->dc);
        if (!IS_ERR_OR_NULL(ipu_crtc->di))
                ipu_di_put(ipu_crtc->di);
 }
@@ -434,32 +313,12 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
        struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
        int ret;
 
-       ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]);
-       if (IS_ERR(ipu_crtc->ipu_ch)) {
-               ret = PTR_ERR(ipu_crtc->ipu_ch);
-               goto err_out;
-       }
-
        ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
        if (IS_ERR(ipu_crtc->dc)) {
                ret = PTR_ERR(ipu_crtc->dc);
                goto err_out;
        }
 
-       ipu_crtc->dmfc = ipu_dmfc_get(ipu, pdata->dma[0]);
-       if (IS_ERR(ipu_crtc->dmfc)) {
-               ret = PTR_ERR(ipu_crtc->dmfc);
-               goto err_out;
-       }
-
-       if (pdata->dp >= 0) {
-               ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp);
-               if (IS_ERR(ipu_crtc->dp)) {
-                       ret = PTR_ERR(ipu_crtc->dp);
-                       goto err_out;
-               }
-       }
-
        ipu_crtc->di = ipu_di_get(ipu, pdata->di);
        if (IS_ERR(ipu_crtc->di)) {
                ret = PTR_ERR(ipu_crtc->di);
@@ -477,7 +336,9 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                struct ipu_client_platformdata *pdata)
 {
        struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+       int dp = -EINVAL;
        int ret;
+       int id;
 
        ret = ipu_get_resources(ipu_crtc, pdata);
        if (ret) {
@@ -495,19 +356,42 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                goto err_put_resources;
        }
 
-       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
-                       IPU_IRQ_EOF);
+       if (pdata->dp >= 0)
+               dp = IPU_DP_FLOW_SYNC_BG;
+       id = imx_drm_crtc_id(ipu_crtc->imx_crtc);
+       ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu,
+                                           pdata->dma[0], dp, BIT(id), true);
+       ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n",
+                       ret);
+               goto err_remove_crtc;
+       }
+
+       /* If this crtc is using the DP, add an overlay plane */
+       if (pdata->dp >= 0 && pdata->dma[1] > 0) {
+               ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu,
+                                                   pdata->dma[1],
+                                                   IPU_DP_FLOW_SYNC_FG,
+                                                   BIT(id), false);
+               if (IS_ERR(ipu_crtc->plane[1]))
+                       ipu_crtc->plane[1] = NULL;
+       }
+
+       ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
        ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
                        "imx_drm", ipu_crtc);
        if (ret < 0) {
                dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-               goto err_put_resources;
+               goto err_put_plane_res;
        }
 
-       disable_irq(ipu_crtc->irq);
-
        return 0;
 
+err_put_plane_res:
+       ipu_plane_put_resources(ipu_crtc->plane[0]);
+err_remove_crtc:
+       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
 err_put_resources:
        ipu_put_resources(ipu_crtc);
 
@@ -546,6 +430,7 @@ static int ipu_drm_remove(struct platform_device *pdev)
 
        imx_drm_remove_crtc(ipu_crtc->imx_crtc);
 
+       ipu_plane_put_resources(ipu_crtc->plane[0]);
        ipu_put_resources(ipu_crtc);
 
        return 0;
diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c
new file mode 100644 (file)
index 0000000..d97454a
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * i.MX IPUv3 DP Overlay Planes
+ *
+ * Copyright (C) 2013 Philipp Zabel, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "ipu-v3/imx-ipu-v3.h"
+#include "ipuv3-plane.h"
+
+#define to_ipu_plane(x)        container_of(x, struct ipu_plane, base)
+
+static const uint32_t ipu_plane_formats[] = {
+       DRM_FORMAT_XRGB1555,
+       DRM_FORMAT_XBGR1555,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ABGR8888,
+       DRM_FORMAT_XBGR8888,
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_YVYU,
+       DRM_FORMAT_YUV420,
+       DRM_FORMAT_YVU420,
+};
+
+int ipu_plane_irq(struct ipu_plane *ipu_plane)
+{
+       return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch,
+                                    IPU_IRQ_EOF);
+}
+
+static int calc_vref(struct drm_display_mode *mode)
+{
+       unsigned long htotal, vtotal;
+
+       htotal = mode->htotal;
+       vtotal = mode->vtotal;
+
+       if (!htotal || !vtotal)
+               return 60;
+
+       return DIV_ROUND_UP(mode->clock * 1000, vtotal * htotal);
+}
+
+static inline int calc_bandwidth(int width, int height, unsigned int vref)
+{
+       return width * height * vref;
+}
+
+int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb,
+                      int x, int y)
+{
+       struct ipu_ch_param __iomem *cpmem;
+       struct drm_gem_cma_object *cma_obj;
+
+       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+       if (!cma_obj) {
+               DRM_LOG_KMS("entry is null.\n");
+               return -EFAULT;
+       }
+
+       dev_dbg(ipu_plane->base.dev->dev, "phys = 0x%x, x = %d, y = %d",
+               cma_obj->paddr, x, y);
+
+       cpmem = ipu_get_cpmem(ipu_plane->ipu_ch);
+       ipu_cpmem_set_stride(cpmem, fb->pitches[0]);
+       ipu_cpmem_set_buffer(cpmem, 0, cma_obj->paddr + fb->offsets[0] +
+                            fb->pitches[0] * y + x);
+
+       return 0;
+}
+
+int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
+                      struct drm_display_mode *mode,
+                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                      unsigned int crtc_w, unsigned int crtc_h,
+                      uint32_t src_x, uint32_t src_y,
+                      uint32_t src_w, uint32_t src_h)
+{
+       struct ipu_ch_param __iomem *cpmem;
+       struct device *dev = ipu_plane->base.dev->dev;
+       int ret;
+
+       /* no scaling */
+       if (src_w != crtc_w || src_h != crtc_h)
+               return -EINVAL;
+
+       /* clip to crtc bounds */
+       if (crtc_x < 0) {
+               if (-crtc_x > crtc_w)
+                       return -EINVAL;
+               src_x += -crtc_x;
+               src_w -= -crtc_x;
+               crtc_w -= -crtc_x;
+               crtc_x = 0;
+       }
+       if (crtc_y < 0) {
+               if (-crtc_y > crtc_h)
+                       return -EINVAL;
+               src_y += -crtc_y;
+               src_h -= -crtc_y;
+               crtc_h -= -crtc_y;
+               crtc_y = 0;
+       }
+       if (crtc_x + crtc_w > mode->hdisplay) {
+               if (crtc_x > mode->hdisplay)
+                       return -EINVAL;
+               crtc_w = mode->hdisplay - crtc_x;
+               src_w = crtc_w;
+       }
+       if (crtc_y + crtc_h > mode->vdisplay) {
+               if (crtc_y > mode->vdisplay)
+                       return -EINVAL;
+               crtc_h = mode->vdisplay - crtc_y;
+               src_h = crtc_h;
+       }
+       /* full plane minimum width is 13 pixels */
+       if (crtc_w < 13 && (ipu_plane->dp_flow != IPU_DP_FLOW_SYNC_FG))
+               return -EINVAL;
+       if (crtc_h < 2)
+               return -EINVAL;
+
+       switch (ipu_plane->dp_flow) {
+       case IPU_DP_FLOW_SYNC_BG:
+               ret = ipu_dp_setup_channel(ipu_plane->dp,
+                               IPUV3_COLORSPACE_RGB,
+                               IPUV3_COLORSPACE_RGB);
+               if (ret) {
+                       dev_err(dev,
+                               "initializing display processor failed with %d\n",
+                               ret);
+                       return ret;
+               }
+               ipu_dp_set_global_alpha(ipu_plane->dp, 1, 0, 1);
+               break;
+       case IPU_DP_FLOW_SYNC_FG:
+               ipu_dp_setup_channel(ipu_plane->dp,
+                               ipu_drm_fourcc_to_colorspace(fb->pixel_format),
+                               IPUV3_COLORSPACE_UNKNOWN);
+               ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y);
+               break;
+       }
+
+       ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w);
+       if (ret) {
+               dev_err(dev, "initializing dmfc channel failed with %d\n", ret);
+               return ret;
+       }
+
+       ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc,
+                       calc_bandwidth(crtc_w, crtc_h,
+                                      calc_vref(mode)), 64);
+       if (ret) {
+               dev_err(dev, "allocating dmfc bandwidth failed with %d\n", ret);
+               return ret;
+       }
+
+       cpmem = ipu_get_cpmem(ipu_plane->ipu_ch);
+       ipu_ch_param_zero(cpmem);
+       ipu_cpmem_set_resolution(cpmem, src_w, src_h);
+       ret = ipu_cpmem_set_fmt(cpmem, fb->pixel_format);
+       if (ret < 0) {
+               dev_err(dev, "unsupported pixel format 0x%08x\n",
+                       fb->pixel_format);
+               return ret;
+       }
+       ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
+
+       ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
+{
+       if (!IS_ERR_OR_NULL(ipu_plane->dp))
+               ipu_dp_put(ipu_plane->dp);
+       if (!IS_ERR_OR_NULL(ipu_plane->dmfc))
+               ipu_dmfc_put(ipu_plane->dmfc);
+       if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch))
+               ipu_idmac_put(ipu_plane->ipu_ch);
+}
+
+int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
+{
+       int ret;
+
+       ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma);
+       if (IS_ERR(ipu_plane->ipu_ch)) {
+               ret = PTR_ERR(ipu_plane->ipu_ch);
+               DRM_ERROR("failed to get idmac channel: %d\n", ret);
+               return ret;
+       }
+
+       ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma);
+       if (IS_ERR(ipu_plane->dmfc)) {
+               ret = PTR_ERR(ipu_plane->dmfc);
+               DRM_ERROR("failed to get dmfc: ret %d\n", ret);
+               goto err_out;
+       }
+
+       if (ipu_plane->dp_flow >= 0) {
+               ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow);
+               if (IS_ERR(ipu_plane->dp)) {
+                       ret = PTR_ERR(ipu_plane->dp);
+                       DRM_ERROR("failed to get dp flow: %d\n", ret);
+                       goto err_out;
+               }
+       }
+
+       return 0;
+err_out:
+       ipu_plane_put_resources(ipu_plane);
+
+       return ret;
+}
+
+void ipu_plane_enable(struct ipu_plane *ipu_plane)
+{
+       ipu_dmfc_enable_channel(ipu_plane->dmfc);
+       ipu_idmac_enable_channel(ipu_plane->ipu_ch);
+       if (ipu_plane->dp)
+               ipu_dp_enable_channel(ipu_plane->dp);
+
+       ipu_plane->enabled = true;
+}
+
+void ipu_plane_disable(struct ipu_plane *ipu_plane)
+{
+       ipu_plane->enabled = false;
+
+       ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
+
+       if (ipu_plane->dp)
+               ipu_dp_disable_channel(ipu_plane->dp);
+       ipu_idmac_disable_channel(ipu_plane->ipu_ch);
+       ipu_dmfc_disable_channel(ipu_plane->dmfc);
+}
+
+static void ipu_plane_dpms(struct ipu_plane *ipu_plane, int mode)
+{
+       bool enable;
+
+       DRM_DEBUG_KMS("mode = %d", mode);
+
+       enable = (mode == DRM_MODE_DPMS_ON);
+
+       if (enable == ipu_plane->enabled)
+               return;
+
+       if (enable) {
+               ipu_plane_enable(ipu_plane);
+       } else {
+               ipu_plane_disable(ipu_plane);
+
+               ipu_idmac_put(ipu_plane->ipu_ch);
+               ipu_dmfc_put(ipu_plane->dmfc);
+               ipu_dp_put(ipu_plane->dp);
+       }
+}
+
+/*
+ * drm_plane API
+ */
+
+static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+                           struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                           unsigned int crtc_w, unsigned int crtc_h,
+                           uint32_t src_x, uint32_t src_y,
+                           uint32_t src_w, uint32_t src_h)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+       int ret = 0;
+
+       DRM_DEBUG_KMS("plane - %p\n", plane);
+
+       if (!ipu_plane->enabled)
+               ret = ipu_plane_get_resources(ipu_plane);
+       if (ret < 0)
+               return ret;
+
+       ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb,
+                       crtc_x, crtc_y, crtc_w, crtc_h,
+                       src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16);
+       if (ret < 0) {
+               ipu_plane_put_resources(ipu_plane);
+               return ret;
+       }
+
+       if (crtc != plane->crtc)
+               dev_info(plane->dev->dev, "crtc change: %p -> %p\n",
+                               plane->crtc, crtc);
+       plane->crtc = crtc;
+
+       ipu_plane_dpms(ipu_plane, DRM_MODE_DPMS_ON);
+
+       return 0;
+}
+
+static int ipu_disable_plane(struct drm_plane *plane)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       ipu_plane_dpms(ipu_plane, DRM_MODE_DPMS_OFF);
+
+       ipu_plane_put_resources(ipu_plane);
+
+       return 0;
+}
+
+static void ipu_plane_destroy(struct drm_plane *plane)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       ipu_disable_plane(plane);
+       drm_plane_cleanup(plane);
+       kfree(ipu_plane);
+}
+
+static struct drm_plane_funcs ipu_plane_funcs = {
+       .update_plane   = ipu_update_plane,
+       .disable_plane  = ipu_disable_plane,
+       .destroy        = ipu_plane_destroy,
+};
+
+struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+                                int dma, int dp, unsigned int possible_crtcs,
+                                bool priv)
+{
+       struct ipu_plane *ipu_plane;
+       int ret;
+
+       DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
+                     dma, dp, possible_crtcs);
+
+       ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL);
+       if (!ipu_plane) {
+               DRM_ERROR("failed to allocate plane\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ipu_plane->ipu = ipu;
+       ipu_plane->dma = dma;
+       ipu_plane->dp_flow = dp;
+
+       ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs,
+                            &ipu_plane_funcs, ipu_plane_formats,
+                            ARRAY_SIZE(ipu_plane_formats),
+                            priv);
+       if (ret) {
+               DRM_ERROR("failed to initialize plane\n");
+               kfree(ipu_plane);
+               return ERR_PTR(ret);
+       }
+
+       return ipu_plane;
+}
diff --git a/drivers/staging/imx-drm/ipuv3-plane.h b/drivers/staging/imx-drm/ipuv3-plane.h
new file mode 100644 (file)
index 0000000..c0aae5b
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __IPUV3_PLANE_H__
+#define __IPUV3_PLANE_H__
+
+#include <drm/drm_crtc.h> /* drm_plane */
+
+struct drm_plane;
+struct drm_device;
+struct ipu_soc;
+struct drm_crtc;
+struct drm_framebuffer;
+
+struct ipuv3_channel;
+struct dmfc_channel;
+struct ipu_dp;
+
+struct ipu_plane {
+       struct drm_plane        base;
+
+       struct ipu_soc          *ipu;
+       struct ipuv3_channel    *ipu_ch;
+       struct dmfc_channel     *dmfc;
+       struct ipu_dp           *dp;
+
+       int                     dma;
+       int                     dp_flow;
+
+       int                     x;
+       int                     y;
+
+       bool                    enabled;
+};
+
+struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+                                int dma, int dp, unsigned int possible_crtcs,
+                                bool priv);
+
+/* Init IDMAC, DMFC, DP */
+int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
+                      struct drm_display_mode *mode,
+                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                      unsigned int crtc_w, unsigned int crtc_h,
+                      uint32_t src_x, uint32_t src_y, uint32_t src_w,
+                      uint32_t src_h);
+
+void ipu_plane_enable(struct ipu_plane *plane);
+void ipu_plane_disable(struct ipu_plane *plane);
+int ipu_plane_set_base(struct ipu_plane *plane, struct drm_framebuffer *fb,
+                      int x, int y);
+
+int ipu_plane_get_resources(struct ipu_plane *plane);
+void ipu_plane_put_resources(struct ipu_plane *plane);
+
+int ipu_plane_irq(struct ipu_plane *plane);
+
+#endif
index ddd2e7390b4611b9df23d282874210e3b915f312..a84ee6303368422468b4656e27d62d098c303eeb 100644 (file)
@@ -604,9 +604,7 @@ static int eucr_probe(struct usb_interface *intf,
        if (!(MiscReg03 & 0x02)) {
                result = -ENODEV;
                quiesce_and_remove_host(us);
-               pr_info("keucr: The driver only supports SM/MS card. "
-                       "To use SD card, "
-                       "please build driver/usb/storage/ums-eneub6250.ko\n");
+               pr_info("keucr: The driver only supports SM/MS card. To use SD card, please build driver/usb/storage/ums-eneub6250.ko\n");
                goto BadDevice;
        }
 
index 471c10c116ec823d54587c5426d79881cfc0db46..cc5d62d2b01f4a37f373a3ef9f0fdb8faa256c7d 100644 (file)
@@ -205,7 +205,7 @@ static int line6_send_raw_message_async_part(struct message *msg,
                        __func__, retval);
                usb_free_urb(urb);
                kfree(msg);
-               return -EINVAL;
+               return retval;
        }
 
        return 0;
@@ -340,7 +340,7 @@ static void line6_data_received(struct urb *urb)
                line6->message_length = done;
                line6_midi_receive(line6, line6->buffer_message, done);
 
-               switch (line6->usbdev->descriptor.idProduct) {
+               switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
                case LINE6_DEVID_BASSPODXT:
                case LINE6_DEVID_BASSPODXTLIVE:
                case LINE6_DEVID_BASSPODXTPRO:
@@ -1010,7 +1010,7 @@ static void line6_disconnect(struct usb_interface *interface)
                        dev_err(line6->ifcdev,
                                "driver bug: inconsistent usb device\n");
 
-               switch (line6->usbdev->descriptor.idProduct) {
+               switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
                case LINE6_DEVID_BASSPODXT:
                case LINE6_DEVID_BASSPODXTLIVE:
                case LINE6_DEVID_BASSPODXTPRO:
@@ -1114,7 +1114,7 @@ static int line6_reset_resume(struct usb_interface *interface)
 {
        struct usb_line6 *line6 = usb_get_intfdata(interface);
 
-       switch (line6->usbdev->descriptor.idProduct) {
+       switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
        case LINE6_DEVID_PODSTUDIO_GX:
        case LINE6_DEVID_PODSTUDIO_UX1:
        case LINE6_DEVID_PODSTUDIO_UX2:
index e3f9a53dbd96604ee5c6ab6e9eccd06511a96be7..3f6d78c585fb925d75bb630e07dab6f67c124b95 100644 (file)
@@ -144,7 +144,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
        if (retval < 0) {
                dev_err(line6->ifcdev, "usb_submit_urb failed\n");
                usb_free_urb(urb);
-               return -EINVAL;
+               return retval;
        }
 
        ++line6->line6midi->num_active_send_urbs;
@@ -205,7 +205,7 @@ static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
        if (up)
                line6->line6midi->substream_receive = substream;
        else
-               line6->line6midi->substream_receive = 0;
+               line6->line6midi->substream_receive = NULL;
 }
 
 static struct snd_rawmidi_ops line6_midi_output_ops = {
index f9135c7cb19534bd909b14fce55d3fa5d8d79f0c..41869caf19a70d2b250aaffba94cf6df9f0f67c9 100644 (file)
@@ -242,13 +242,14 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
                if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) {
                        create_impulse_test_signal(line6pcm, urb_out,
                                                   bytes_per_frame);
-                       if (line6pcm->flags & LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) {
+                       if (line6pcm->flags &
+                           LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) {
                                line6_capture_copy(line6pcm,
                                                   urb_out->transfer_buffer,
                                                   urb_out->
                                                   transfer_buffer_length);
                                line6_capture_check_period(line6pcm,
-                                                          urb_out->transfer_buffer_length);
+                                       urb_out->transfer_buffer_length);
                        }
                } else {
 #endif
index 776d3632dc7d52988738b105d648161b2e99b9a2..af2e7e50c135079cb7fa97154fdd72000458d39e 100644 (file)
@@ -307,6 +307,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
        int ticks;
        struct usb_line6 *line6 = &toneport->line6;
        struct usb_device *usbdev = line6->usbdev;
+       u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
 
        /* sync time on device with host: */
        ticks = (int)get_seconds();
@@ -316,7 +317,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
        toneport_send_cmd(usbdev, 0x0301, 0x0000);
 
        /* initialize source select: */
-       switch (usbdev->descriptor.idProduct) {
+       switch (le16_to_cpu(usbdev->descriptor.idProduct)) {
        case LINE6_DEVID_TONEPORT_UX1:
        case LINE6_DEVID_TONEPORT_UX2:
        case LINE6_DEVID_PODSTUDIO_UX1:
@@ -326,7 +327,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
                                  0x0000);
        }
 
-       if (toneport_has_led(usbdev->descriptor.idProduct))
+       if (toneport_has_led(idProduct))
                toneport_update_led(&usbdev->dev);
 }
 
@@ -339,6 +340,7 @@ static int toneport_try_init(struct usb_interface *interface,
        int err;
        struct usb_line6 *line6 = &toneport->line6;
        struct usb_device *usbdev = line6->usbdev;
+       u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
 
        if ((interface == NULL) || (toneport == NULL))
                return -ENODEV;
@@ -361,7 +363,7 @@ static int toneport_try_init(struct usb_interface *interface,
                return err;
 
        /* register source select control: */
-       switch (usbdev->descriptor.idProduct) {
+       switch (le16_to_cpu(usbdev->descriptor.idProduct)) {
        case LINE6_DEVID_TONEPORT_UX1:
        case LINE6_DEVID_TONEPORT_UX2:
        case LINE6_DEVID_PODSTUDIO_UX1:
@@ -382,7 +384,7 @@ static int toneport_try_init(struct usb_interface *interface,
        line6_read_serial_number(line6, &toneport->serial_number);
        line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
 
-       if (toneport_has_led(usbdev->descriptor.idProduct)) {
+       if (toneport_has_led(idProduct)) {
                CHECK_RETURN(device_create_file
                             (&interface->dev, &dev_attr_led_red));
                CHECK_RETURN(device_create_file
@@ -428,14 +430,16 @@ void line6_toneport_reset_resume(struct usb_line6_toneport *toneport)
 void line6_toneport_disconnect(struct usb_interface *interface)
 {
        struct usb_line6_toneport *toneport;
+       u16 idProduct;
 
        if (interface == NULL)
                return;
 
        toneport = usb_get_intfdata(interface);
        del_timer_sync(&toneport->timer);
+       idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct);
 
-       if (toneport_has_led(toneport->line6.usbdev->descriptor.idProduct)) {
+       if (toneport_has_led(idProduct)) {
                device_remove_file(&interface->dev, &dev_attr_led_red);
                device_remove_file(&interface->dev, &dev_attr_led_green);
        }
index f3d4a896a75a1045282f6fa951e93eaa01bcee8e..8b137891791fe96927ad78e64b0aad7bded08bdc 100644 (file)
@@ -1,111 +1 @@
-/*
- * 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.
- */
-#ifndef _LIBCFS_BITMAP_H_
-#define _LIBCFS_BITMAP_H_
 
-
-typedef struct {
-       int          size;
-       unsigned long   data[0];
-} cfs_bitmap_t;
-
-#define CFS_BITMAP_SIZE(nbits) \
-     (((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(cfs_bitmap_t))
-
-static inline
-cfs_bitmap_t *CFS_ALLOCATE_BITMAP(int size)
-{
-       cfs_bitmap_t *ptr;
-
-       OBD_ALLOC(ptr, CFS_BITMAP_SIZE(size));
-       if (ptr == NULL)
-               return ptr;
-
-       ptr->size = size;
-
-       return ptr;
-}
-
-#define CFS_FREE_BITMAP(ptr)   OBD_FREE(ptr, CFS_BITMAP_SIZE(ptr->size))
-
-static inline
-void cfs_bitmap_set(cfs_bitmap_t *bitmap, int nbit)
-{
-       set_bit(nbit, bitmap->data);
-}
-
-static inline
-void cfs_bitmap_clear(cfs_bitmap_t *bitmap, int nbit)
-{
-       test_and_clear_bit(nbit, bitmap->data);
-}
-
-static inline
-int cfs_bitmap_check(cfs_bitmap_t *bitmap, int nbit)
-{
-       return test_bit(nbit, bitmap->data);
-}
-
-static inline
-int cfs_bitmap_test_and_clear(cfs_bitmap_t *bitmap, int nbit)
-{
-       return test_and_clear_bit(nbit, bitmap->data);
-}
-
-/* return 0 is bitmap has none set bits */
-static inline
-int cfs_bitmap_check_empty(cfs_bitmap_t *bitmap)
-{
-       return find_first_bit(bitmap->data, bitmap->size) == bitmap->size;
-}
-
-static inline
-void cfs_bitmap_copy(cfs_bitmap_t *new, cfs_bitmap_t *old)
-{
-       int newsize;
-
-       LASSERT(new->size >= old->size);
-       newsize = new->size;
-       memcpy(new, old, CFS_BITMAP_SIZE(old->size));
-       new->size = newsize;
-}
-
-#define cfs_foreach_bit(bitmap, pos)                                   \
-       for ((pos) = find_first_bit((bitmap)->data, bitmap->size);      \
-            (pos) < (bitmap)->size;                                    \
-            (pos) = find_next_bit((bitmap)->data, (bitmap)->size, (pos) + 1))
-
-#endif
index e6439d19f3e55939d98f2bd240442b2d31258e14..40282b70bd1bd6e665a99d82a912ff50b52add8f 100644 (file)
@@ -165,11 +165,11 @@ struct ptldebug_header {
 #define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))        /* jiffies */
 #define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
 #define CDEBUG_DEFAULT_BACKOFF   2
-typedef struct {
+struct cfs_debug_limit_state {
        cfs_time_t      cdls_next;
        unsigned int    cdls_delay;
        int          cdls_count;
-} cfs_debug_limit_state_t;
+};
 
 struct libcfs_debug_msg_data {
        const char             *msg_file;
@@ -177,7 +177,7 @@ struct libcfs_debug_msg_data {
        int                   msg_subsys;
        int                   msg_line;
        int                   msg_mask;
-       cfs_debug_limit_state_t  *msg_cdls;
+       struct cfs_debug_limit_state  *msg_cdls;
 };
 
 #define LIBCFS_DEBUG_MSG_DATA_INIT(data, mask, cdls)   \
@@ -226,7 +226,7 @@ do {                                                                    \
 
 #define CDEBUG_LIMIT(mask, format, ...)         \
 do {                                       \
-       static cfs_debug_limit_state_t cdls;    \
+       static struct cfs_debug_limit_state cdls;    \
                                                \
        __CDEBUG(&cdls, mask, format, ## __VA_ARGS__);\
 } while (0)
index 98f5be243c8ece7af42641ef8d08a1761c1c6e26..9d5ee1a69c0c899eb6801bb8a872085ec3b54fb2 100644 (file)
@@ -81,10 +81,10 @@ struct cfs_hash_ops;
 struct cfs_hash_lock_ops;
 struct cfs_hash_hlist_ops;
 
-typedef union {
+union cfs_hash_lock {
        rwlock_t                rw;             /**< rwlock */
        spinlock_t              spin;           /**< spinlock */
-} cfs_hash_lock_t;
+};
 
 /**
  * cfs_hash_bucket is a container of:
@@ -97,22 +97,22 @@ typedef union {
  *   which depends on requirement of user
  * - some extra bytes (caller can require it while creating hash)
  */
-typedef struct cfs_hash_bucket {
-       cfs_hash_lock_t         hsb_lock;       /**< bucket lock */
+struct cfs_hash_bucket {
+       union cfs_hash_lock     hsb_lock;       /**< bucket lock */
        __u32                   hsb_count;      /**< current entries */
        __u32                   hsb_version;    /**< change version */
        unsigned int            hsb_index;      /**< index of bucket */
        int                     hsb_depmax;     /**< max depth on bucket */
        long                    hsb_head[0];    /**< hash-head array */
-} cfs_hash_bucket_t;
+};
 
 /**
  * cfs_hash bucket descriptor, it's normally in stack of caller
  */
-typedef struct cfs_hash_bd {
-       cfs_hash_bucket_t         *bd_bucket;      /**< address of bucket */
+struct cfs_hash_bd {
+       struct cfs_hash_bucket  *bd_bucket;      /**< address of bucket */
        unsigned int            bd_offset;      /**< offset in bucket */
-} cfs_hash_bd_t;
+};
 
 #define CFS_HASH_NAME_LEN         16      /**< default name length */
 #define CFS_HASH_BIGNAME_LEN   64      /**< bigname for param tree */
@@ -210,10 +210,10 @@ enum cfs_hash_tag {
  * locations; additions must take care to only insert into the new bucket.
  */
 
-typedef struct cfs_hash {
+struct cfs_hash {
        /** serialize with rehash, or serialize all operations if
         * the hash-table has CFS_HASH_NO_BKTLOCK */
-       cfs_hash_lock_t      hs_lock;
+       union cfs_hash_lock          hs_lock;
        /** hash operations */
        struct cfs_hash_ops     *hs_ops;
        /** hash lock operations */
@@ -221,7 +221,7 @@ typedef struct cfs_hash {
        /** hash list operations */
        struct cfs_hash_hlist_ops  *hs_hops;
        /** hash buckets-table */
-       cfs_hash_bucket_t        **hs_buckets;
+       struct cfs_hash_bucket   **hs_buckets;
        /** total number of items on this hash-table */
        atomic_t                hs_count;
        /** hash flags, see cfs_hash_tag for detail */
@@ -255,7 +255,7 @@ typedef struct cfs_hash {
        /** refcount on this hash table */
        atomic_t                hs_refcount;
        /** rehash buckets-table */
-       cfs_hash_bucket_t        **hs_rehash_buckets;
+       struct cfs_hash_bucket   **hs_rehash_buckets;
 #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
        /** serialize debug members */
        spinlock_t                      hs_dep_lock;
@@ -272,35 +272,35 @@ typedef struct cfs_hash {
 #endif
        /** name of htable */
        char                    hs_name[0];
-} cfs_hash_t;
+};
 
 typedef struct cfs_hash_lock_ops {
        /** lock the hash table */
-       void    (*hs_lock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_lock)(union cfs_hash_lock *lock, int exclusive);
        /** unlock the hash table */
-       void    (*hs_unlock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_unlock)(union cfs_hash_lock *lock, int exclusive);
        /** lock the hash bucket */
-       void    (*hs_bkt_lock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_bkt_lock)(union cfs_hash_lock *lock, int exclusive);
        /** unlock the hash bucket */
-       void    (*hs_bkt_unlock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_bkt_unlock)(union cfs_hash_lock *lock, int exclusive);
 } cfs_hash_lock_ops_t;
 
 typedef struct cfs_hash_hlist_ops {
        /** return hlist_head of hash-head of @bd */
-       struct hlist_head *(*hop_hhead)(cfs_hash_t *hs, cfs_hash_bd_t *bd);
+       struct hlist_head *(*hop_hhead)(struct cfs_hash *hs, struct cfs_hash_bd *bd);
        /** return hash-head size */
-       int (*hop_hhead_size)(cfs_hash_t *hs);
+       int (*hop_hhead_size)(struct cfs_hash *hs);
        /** add @hnode to hash-head of @bd */
-       int (*hop_hnode_add)(cfs_hash_t *hs,
-                            cfs_hash_bd_t *bd, struct hlist_node *hnode);
+       int (*hop_hnode_add)(struct cfs_hash *hs,
+                            struct cfs_hash_bd *bd, struct hlist_node *hnode);
        /** remove @hnode from hash-head of @bd */
-       int (*hop_hnode_del)(cfs_hash_t *hs,
-                            cfs_hash_bd_t *bd, struct hlist_node *hnode);
+       int (*hop_hnode_del)(struct cfs_hash *hs,
+                            struct cfs_hash_bd *bd, struct hlist_node *hnode);
 } cfs_hash_hlist_ops_t;
 
 typedef struct cfs_hash_ops {
        /** return hashed value from @key */
-       unsigned (*hs_hash)(cfs_hash_t *hs, const void *key, unsigned mask);
+       unsigned (*hs_hash)(struct cfs_hash *hs, const void *key, unsigned mask);
        /** return key address of @hnode */
        void *   (*hs_key)(struct hlist_node *hnode);
        /** copy key from @hnode to @key */
@@ -313,13 +313,13 @@ typedef struct cfs_hash_ops {
        /** return object address of @hnode, i.e: container_of(...hnode) */
        void *   (*hs_object)(struct hlist_node *hnode);
        /** get refcount of item, always called with holding bucket-lock */
-       void     (*hs_get)(cfs_hash_t *hs, struct hlist_node *hnode);
+       void     (*hs_get)(struct cfs_hash *hs, struct hlist_node *hnode);
        /** release refcount of item */
-       void     (*hs_put)(cfs_hash_t *hs, struct hlist_node *hnode);
+       void     (*hs_put)(struct cfs_hash *hs, struct hlist_node *hnode);
        /** release refcount of item, always called with holding bucket-lock */
-       void     (*hs_put_locked)(cfs_hash_t *hs, struct hlist_node *hnode);
+       void     (*hs_put_locked)(struct cfs_hash *hs, struct hlist_node *hnode);
        /** it's called before removing of @hnode */
-       void     (*hs_exit)(cfs_hash_t *hs, struct hlist_node *hnode);
+       void     (*hs_exit)(struct cfs_hash *hs, struct hlist_node *hnode);
 } cfs_hash_ops_t;
 
 /** total number of buckets in @hs */
@@ -340,41 +340,41 @@ typedef struct cfs_hash_ops {
 #define CFS_HASH_RH_NHLIST(hs)  (1U << (hs)->hs_rehash_bits)
 
 static inline int
-cfs_hash_with_no_lock(cfs_hash_t *hs)
+cfs_hash_with_no_lock(struct cfs_hash *hs)
 {
        /* caller will serialize all operations for this hash-table */
        return (hs->hs_flags & CFS_HASH_NO_LOCK) != 0;
 }
 
 static inline int
-cfs_hash_with_no_bktlock(cfs_hash_t *hs)
+cfs_hash_with_no_bktlock(struct cfs_hash *hs)
 {
        /* no bucket lock, one single lock to protect the hash-table */
        return (hs->hs_flags & CFS_HASH_NO_BKTLOCK) != 0;
 }
 
 static inline int
-cfs_hash_with_rw_bktlock(cfs_hash_t *hs)
+cfs_hash_with_rw_bktlock(struct cfs_hash *hs)
 {
        /* rwlock to protect hash bucket */
        return (hs->hs_flags & CFS_HASH_RW_BKTLOCK) != 0;
 }
 
 static inline int
-cfs_hash_with_spin_bktlock(cfs_hash_t *hs)
+cfs_hash_with_spin_bktlock(struct cfs_hash *hs)
 {
        /* spinlock to protect hash bucket */
        return (hs->hs_flags & CFS_HASH_SPIN_BKTLOCK) != 0;
 }
 
 static inline int
-cfs_hash_with_add_tail(cfs_hash_t *hs)
+cfs_hash_with_add_tail(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_ADD_TAIL) != 0;
 }
 
 static inline int
-cfs_hash_with_no_itemref(cfs_hash_t *hs)
+cfs_hash_with_no_itemref(struct cfs_hash *hs)
 {
        /* hash-table doesn't keep refcount on item,
         * item can't be removed from hash unless it's
@@ -383,75 +383,75 @@ cfs_hash_with_no_itemref(cfs_hash_t *hs)
 }
 
 static inline int
-cfs_hash_with_bigname(cfs_hash_t *hs)
+cfs_hash_with_bigname(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_BIGNAME) != 0;
 }
 
 static inline int
-cfs_hash_with_counter(cfs_hash_t *hs)
+cfs_hash_with_counter(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_COUNTER) != 0;
 }
 
 static inline int
-cfs_hash_with_rehash(cfs_hash_t *hs)
+cfs_hash_with_rehash(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_REHASH) != 0;
 }
 
 static inline int
-cfs_hash_with_rehash_key(cfs_hash_t *hs)
+cfs_hash_with_rehash_key(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_REHASH_KEY) != 0;
 }
 
 static inline int
-cfs_hash_with_shrink(cfs_hash_t *hs)
+cfs_hash_with_shrink(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_SHRINK) != 0;
 }
 
 static inline int
-cfs_hash_with_assert_empty(cfs_hash_t *hs)
+cfs_hash_with_assert_empty(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_ASSERT_EMPTY) != 0;
 }
 
 static inline int
-cfs_hash_with_depth(cfs_hash_t *hs)
+cfs_hash_with_depth(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_DEPTH) != 0;
 }
 
 static inline int
-cfs_hash_with_nblk_change(cfs_hash_t *hs)
+cfs_hash_with_nblk_change(struct cfs_hash *hs)
 {
        return (hs->hs_flags & CFS_HASH_NBLK_CHANGE) != 0;
 }
 
 static inline int
-cfs_hash_is_exiting(cfs_hash_t *hs)
+cfs_hash_is_exiting(struct cfs_hash *hs)
 {       /* cfs_hash_destroy is called */
        return hs->hs_exiting;
 }
 
 static inline int
-cfs_hash_is_rehashing(cfs_hash_t *hs)
+cfs_hash_is_rehashing(struct cfs_hash *hs)
 {       /* rehash is launched */
        return hs->hs_rehash_bits != 0;
 }
 
 static inline int
-cfs_hash_is_iterating(cfs_hash_t *hs)
+cfs_hash_is_iterating(struct cfs_hash *hs)
 {       /* someone is calling cfs_hash_for_each_* */
        return hs->hs_iterating || hs->hs_iterators != 0;
 }
 
 static inline int
-cfs_hash_bkt_size(cfs_hash_t *hs)
+cfs_hash_bkt_size(struct cfs_hash *hs)
 {
-       return offsetof(cfs_hash_bucket_t, hsb_head[0]) +
+       return offsetof(struct cfs_hash_bucket, hsb_head[0]) +
               hs->hs_hops->hop_hhead_size(hs) * CFS_HASH_BKT_NHLIST(hs) +
               hs->hs_extra_bytes;
 }
@@ -459,19 +459,19 @@ cfs_hash_bkt_size(cfs_hash_t *hs)
 #define CFS_HOP(hs, op)           (hs)->hs_ops->hs_ ## op
 
 static inline unsigned
-cfs_hash_id(cfs_hash_t *hs, const void *key, unsigned mask)
+cfs_hash_id(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return CFS_HOP(hs, hash)(hs, key, mask);
 }
 
 static inline void *
-cfs_hash_key(cfs_hash_t *hs, struct hlist_node *hnode)
+cfs_hash_key(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        return CFS_HOP(hs, key)(hnode);
 }
 
 static inline void
-cfs_hash_keycpy(cfs_hash_t *hs, struct hlist_node *hnode, void *key)
+cfs_hash_keycpy(struct cfs_hash *hs, struct hlist_node *hnode, void *key)
 {
        if (CFS_HOP(hs, keycpy) != NULL)
                CFS_HOP(hs, keycpy)(hnode, key);
@@ -481,25 +481,25 @@ cfs_hash_keycpy(cfs_hash_t *hs, struct hlist_node *hnode, void *key)
  * Returns 1 on a match,
  */
 static inline int
-cfs_hash_keycmp(cfs_hash_t *hs, const void *key, struct hlist_node *hnode)
+cfs_hash_keycmp(struct cfs_hash *hs, const void *key, struct hlist_node *hnode)
 {
        return CFS_HOP(hs, keycmp)(key, hnode);
 }
 
 static inline void *
-cfs_hash_object(cfs_hash_t *hs, struct hlist_node *hnode)
+cfs_hash_object(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        return CFS_HOP(hs, object)(hnode);
 }
 
 static inline void
-cfs_hash_get(cfs_hash_t *hs, struct hlist_node *hnode)
+cfs_hash_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        return CFS_HOP(hs, get)(hs, hnode);
 }
 
 static inline void
-cfs_hash_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+cfs_hash_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        LASSERT(CFS_HOP(hs, put_locked) != NULL);
 
@@ -507,7 +507,7 @@ cfs_hash_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static inline void
-cfs_hash_put(cfs_hash_t *hs, struct hlist_node *hnode)
+cfs_hash_put(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        LASSERT(CFS_HOP(hs, put) != NULL);
 
@@ -515,37 +515,37 @@ cfs_hash_put(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static inline void
-cfs_hash_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+cfs_hash_exit(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        if (CFS_HOP(hs, exit))
                CFS_HOP(hs, exit)(hs, hnode);
 }
 
-static inline void cfs_hash_lock(cfs_hash_t *hs, int excl)
+static inline void cfs_hash_lock(struct cfs_hash *hs, int excl)
 {
        hs->hs_lops->hs_lock(&hs->hs_lock, excl);
 }
 
-static inline void cfs_hash_unlock(cfs_hash_t *hs, int excl)
+static inline void cfs_hash_unlock(struct cfs_hash *hs, int excl)
 {
        hs->hs_lops->hs_unlock(&hs->hs_lock, excl);
 }
 
-static inline int cfs_hash_dec_and_lock(cfs_hash_t *hs,
+static inline int cfs_hash_dec_and_lock(struct cfs_hash *hs,
                                        atomic_t *condition)
 {
        LASSERT(cfs_hash_with_no_bktlock(hs));
        return atomic_dec_and_lock(condition, &hs->hs_lock.spin);
 }
 
-static inline void cfs_hash_bd_lock(cfs_hash_t *hs,
-                                   cfs_hash_bd_t *bd, int excl)
+static inline void cfs_hash_bd_lock(struct cfs_hash *hs,
+                                   struct cfs_hash_bd *bd, int excl)
 {
        hs->hs_lops->hs_bkt_lock(&bd->bd_bucket->hsb_lock, excl);
 }
 
-static inline void cfs_hash_bd_unlock(cfs_hash_t *hs,
-                                     cfs_hash_bd_t *bd, int excl)
+static inline void cfs_hash_bd_unlock(struct cfs_hash *hs,
+                                     struct cfs_hash_bd *bd, int excl)
 {
        hs->hs_lops->hs_bkt_unlock(&bd->bd_bucket->hsb_lock, excl);
 }
@@ -554,56 +554,56 @@ static inline void cfs_hash_bd_unlock(cfs_hash_t *hs,
  * operations on cfs_hash bucket (bd: bucket descriptor),
  * they are normally for hash-table without rehash
  */
-void cfs_hash_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bd);
+void cfs_hash_bd_get(struct cfs_hash *hs, const void *key, struct cfs_hash_bd *bd);
 
-static inline void cfs_hash_bd_get_and_lock(cfs_hash_t *hs, const void *key,
-                                           cfs_hash_bd_t *bd, int excl)
+static inline void cfs_hash_bd_get_and_lock(struct cfs_hash *hs, const void *key,
+                                           struct cfs_hash_bd *bd, int excl)
 {
        cfs_hash_bd_get(hs, key, bd);
        cfs_hash_bd_lock(hs, bd, excl);
 }
 
-static inline unsigned cfs_hash_bd_index_get(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+static inline unsigned cfs_hash_bd_index_get(struct cfs_hash *hs, struct cfs_hash_bd *bd)
 {
        return bd->bd_offset | (bd->bd_bucket->hsb_index << hs->hs_bkt_bits);
 }
 
-static inline void cfs_hash_bd_index_set(cfs_hash_t *hs,
-                                        unsigned index, cfs_hash_bd_t *bd)
+static inline void cfs_hash_bd_index_set(struct cfs_hash *hs,
+                                        unsigned index, struct cfs_hash_bd *bd)
 {
        bd->bd_bucket = hs->hs_buckets[index >> hs->hs_bkt_bits];
        bd->bd_offset = index & (CFS_HASH_BKT_NHLIST(hs) - 1U);
 }
 
 static inline void *
-cfs_hash_bd_extra_get(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+cfs_hash_bd_extra_get(struct cfs_hash *hs, struct cfs_hash_bd *bd)
 {
        return (void *)bd->bd_bucket +
               cfs_hash_bkt_size(hs) - hs->hs_extra_bytes;
 }
 
 static inline __u32
-cfs_hash_bd_version_get(cfs_hash_bd_t *bd)
+cfs_hash_bd_version_get(struct cfs_hash_bd *bd)
 {
        /* need hold cfs_hash_bd_lock */
        return bd->bd_bucket->hsb_version;
 }
 
 static inline __u32
-cfs_hash_bd_count_get(cfs_hash_bd_t *bd)
+cfs_hash_bd_count_get(struct cfs_hash_bd *bd)
 {
        /* need hold cfs_hash_bd_lock */
        return bd->bd_bucket->hsb_count;
 }
 
 static inline int
-cfs_hash_bd_depmax_get(cfs_hash_bd_t *bd)
+cfs_hash_bd_depmax_get(struct cfs_hash_bd *bd)
 {
        return bd->bd_bucket->hsb_depmax;
 }
 
 static inline int
-cfs_hash_bd_compare(cfs_hash_bd_t *bd1, cfs_hash_bd_t *bd2)
+cfs_hash_bd_compare(struct cfs_hash_bd *bd1, struct cfs_hash_bd *bd2)
 {
        if (bd1->bd_bucket->hsb_index != bd2->bd_bucket->hsb_index)
                return bd1->bd_bucket->hsb_index - bd2->bd_bucket->hsb_index;
@@ -614,14 +614,14 @@ cfs_hash_bd_compare(cfs_hash_bd_t *bd1, cfs_hash_bd_t *bd2)
        return 0;
 }
 
-void cfs_hash_bd_add_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+void cfs_hash_bd_add_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                            struct hlist_node *hnode);
-void cfs_hash_bd_del_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+void cfs_hash_bd_del_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                            struct hlist_node *hnode);
-void cfs_hash_bd_move_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd_old,
-                            cfs_hash_bd_t *bd_new, struct hlist_node *hnode);
+void cfs_hash_bd_move_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd_old,
+                            struct cfs_hash_bd *bd_new, struct hlist_node *hnode);
 
-static inline int cfs_hash_bd_dec_and_lock(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static inline int cfs_hash_bd_dec_and_lock(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                                           atomic_t *condition)
 {
        LASSERT(cfs_hash_with_spin_bktlock(hs));
@@ -629,109 +629,109 @@ static inline int cfs_hash_bd_dec_and_lock(cfs_hash_t *hs, cfs_hash_bd_t *bd,
                                       &bd->bd_bucket->hsb_lock.spin);
 }
 
-static inline struct hlist_head *cfs_hash_bd_hhead(cfs_hash_t *hs,
-                                                 cfs_hash_bd_t *bd)
+static inline struct hlist_head *cfs_hash_bd_hhead(struct cfs_hash *hs,
+                                                 struct cfs_hash_bd *bd)
 {
        return hs->hs_hops->hop_hhead(hs, bd);
 }
 
-struct hlist_node *cfs_hash_bd_lookup_locked(cfs_hash_t *hs,
-                                           cfs_hash_bd_t *bd, const void *key);
-struct hlist_node *cfs_hash_bd_peek_locked(cfs_hash_t *hs,
-                                         cfs_hash_bd_t *bd, const void *key);
-struct hlist_node *cfs_hash_bd_findadd_locked(cfs_hash_t *hs,
-                                            cfs_hash_bd_t *bd, const void *key,
+struct hlist_node *cfs_hash_bd_lookup_locked(struct cfs_hash *hs,
+                                           struct cfs_hash_bd *bd, const void *key);
+struct hlist_node *cfs_hash_bd_peek_locked(struct cfs_hash *hs,
+                                         struct cfs_hash_bd *bd, const void *key);
+struct hlist_node *cfs_hash_bd_findadd_locked(struct cfs_hash *hs,
+                                            struct cfs_hash_bd *bd, const void *key,
                                             struct hlist_node *hnode,
                                             int insist_add);
-struct hlist_node *cfs_hash_bd_finddel_locked(cfs_hash_t *hs,
-                                            cfs_hash_bd_t *bd, const void *key,
+struct hlist_node *cfs_hash_bd_finddel_locked(struct cfs_hash *hs,
+                                            struct cfs_hash_bd *bd, const void *key,
                                             struct hlist_node *hnode);
 
 /**
  * operations on cfs_hash bucket (bd: bucket descriptor),
  * they are safe for hash-table with rehash
  */
-void cfs_hash_dual_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bds);
-void cfs_hash_dual_bd_lock(cfs_hash_t *hs, cfs_hash_bd_t *bds, int excl);
-void cfs_hash_dual_bd_unlock(cfs_hash_t *hs, cfs_hash_bd_t *bds, int excl);
+void cfs_hash_dual_bd_get(struct cfs_hash *hs, const void *key, struct cfs_hash_bd *bds);
+void cfs_hash_dual_bd_lock(struct cfs_hash *hs, struct cfs_hash_bd *bds, int excl);
+void cfs_hash_dual_bd_unlock(struct cfs_hash *hs, struct cfs_hash_bd *bds, int excl);
 
-static inline void cfs_hash_dual_bd_get_and_lock(cfs_hash_t *hs, const void *key,
-                                                cfs_hash_bd_t *bds, int excl)
+static inline void cfs_hash_dual_bd_get_and_lock(struct cfs_hash *hs, const void *key,
+                                                struct cfs_hash_bd *bds, int excl)
 {
        cfs_hash_dual_bd_get(hs, key, bds);
        cfs_hash_dual_bd_lock(hs, bds, excl);
 }
 
-struct hlist_node *cfs_hash_dual_bd_lookup_locked(cfs_hash_t *hs,
-                                                cfs_hash_bd_t *bds,
+struct hlist_node *cfs_hash_dual_bd_lookup_locked(struct cfs_hash *hs,
+                                                struct cfs_hash_bd *bds,
                                                 const void *key);
-struct hlist_node *cfs_hash_dual_bd_findadd_locked(cfs_hash_t *hs,
-                                                 cfs_hash_bd_t *bds,
+struct hlist_node *cfs_hash_dual_bd_findadd_locked(struct cfs_hash *hs,
+                                                 struct cfs_hash_bd *bds,
                                                  const void *key,
                                                  struct hlist_node *hnode,
                                                  int insist_add);
-struct hlist_node *cfs_hash_dual_bd_finddel_locked(cfs_hash_t *hs,
-                                                 cfs_hash_bd_t *bds,
+struct hlist_node *cfs_hash_dual_bd_finddel_locked(struct cfs_hash *hs,
+                                                 struct cfs_hash_bd *bds,
                                                  const void *key,
                                                  struct hlist_node *hnode);
 
 /* Hash init/cleanup functions */
-cfs_hash_t *cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
+struct cfs_hash *cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
                            unsigned bkt_bits, unsigned extra_bytes,
                            unsigned min_theta, unsigned max_theta,
                            cfs_hash_ops_t *ops, unsigned flags);
 
-cfs_hash_t *cfs_hash_getref(cfs_hash_t *hs);
-void cfs_hash_putref(cfs_hash_t *hs);
+struct cfs_hash *cfs_hash_getref(struct cfs_hash *hs);
+void cfs_hash_putref(struct cfs_hash *hs);
 
 /* Hash addition functions */
-void cfs_hash_add(cfs_hash_t *hs, const void *key,
+void cfs_hash_add(struct cfs_hash *hs, const void *key,
                  struct hlist_node *hnode);
-int cfs_hash_add_unique(cfs_hash_t *hs, const void *key,
+int cfs_hash_add_unique(struct cfs_hash *hs, const void *key,
                        struct hlist_node *hnode);
-void *cfs_hash_findadd_unique(cfs_hash_t *hs, const void *key,
+void *cfs_hash_findadd_unique(struct cfs_hash *hs, const void *key,
                              struct hlist_node *hnode);
 
 /* Hash deletion functions */
-void *cfs_hash_del(cfs_hash_t *hs, const void *key, struct hlist_node *hnode);
-void *cfs_hash_del_key(cfs_hash_t *hs, const void *key);
+void *cfs_hash_del(struct cfs_hash *hs, const void *key, struct hlist_node *hnode);
+void *cfs_hash_del_key(struct cfs_hash *hs, const void *key);
 
 /* Hash lookup/for_each functions */
 #define CFS_HASH_LOOP_HOG       1024
 
-typedef int (*cfs_hash_for_each_cb_t)(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+typedef int (*cfs_hash_for_each_cb_t)(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                                      struct hlist_node *node, void *data);
-void *cfs_hash_lookup(cfs_hash_t *hs, const void *key);
-void cfs_hash_for_each(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
-void cfs_hash_for_each_safe(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
-int  cfs_hash_for_each_nolock(cfs_hash_t *hs,
+void *cfs_hash_lookup(struct cfs_hash *hs, const void *key);
+void cfs_hash_for_each(struct cfs_hash *hs, cfs_hash_for_each_cb_t, void *data);
+void cfs_hash_for_each_safe(struct cfs_hash *hs, cfs_hash_for_each_cb_t, void *data);
+int  cfs_hash_for_each_nolock(struct cfs_hash *hs,
                              cfs_hash_for_each_cb_t, void *data);
-int  cfs_hash_for_each_empty(cfs_hash_t *hs,
+int  cfs_hash_for_each_empty(struct cfs_hash *hs,
                             cfs_hash_for_each_cb_t, void *data);
-void cfs_hash_for_each_key(cfs_hash_t *hs, const void *key,
+void cfs_hash_for_each_key(struct cfs_hash *hs, const void *key,
                           cfs_hash_for_each_cb_t, void *data);
 typedef int (*cfs_hash_cond_opt_cb_t)(void *obj, void *data);
-void cfs_hash_cond_del(cfs_hash_t *hs, cfs_hash_cond_opt_cb_t, void *data);
+void cfs_hash_cond_del(struct cfs_hash *hs, cfs_hash_cond_opt_cb_t, void *data);
 
-void cfs_hash_hlist_for_each(cfs_hash_t *hs, unsigned hindex,
+void cfs_hash_hlist_for_each(struct cfs_hash *hs, unsigned hindex,
                             cfs_hash_for_each_cb_t, void *data);
-int  cfs_hash_is_empty(cfs_hash_t *hs);
-__u64 cfs_hash_size_get(cfs_hash_t *hs);
+int  cfs_hash_is_empty(struct cfs_hash *hs);
+__u64 cfs_hash_size_get(struct cfs_hash *hs);
 
 /*
  * Rehash - Theta is calculated to be the average chained
  * hash depth assuming a perfectly uniform hash function.
  */
-void cfs_hash_rehash_cancel_locked(cfs_hash_t *hs);
-void cfs_hash_rehash_cancel(cfs_hash_t *hs);
-int  cfs_hash_rehash(cfs_hash_t *hs, int do_rehash);
-void cfs_hash_rehash_key(cfs_hash_t *hs, const void *old_key,
+void cfs_hash_rehash_cancel_locked(struct cfs_hash *hs);
+void cfs_hash_rehash_cancel(struct cfs_hash *hs);
+int  cfs_hash_rehash(struct cfs_hash *hs, int do_rehash);
+void cfs_hash_rehash_key(struct cfs_hash *hs, const void *old_key,
                         void *new_key, struct hlist_node *hnode);
 
 #if CFS_HASH_DEBUG_LEVEL > CFS_HASH_DEBUG_1
 /* Validate hnode references the correct key */
 static inline void
-cfs_hash_key_validate(cfs_hash_t *hs, const void *key,
+cfs_hash_key_validate(struct cfs_hash *hs, const void *key,
                      struct hlist_node *hnode)
 {
        LASSERT(cfs_hash_keycmp(hs, key, hnode));
@@ -739,10 +739,10 @@ cfs_hash_key_validate(cfs_hash_t *hs, const void *key,
 
 /* Validate hnode is in the correct bucket */
 static inline void
-cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bucket_validate(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                         struct hlist_node *hnode)
 {
-       cfs_hash_bd_t   bds[2];
+       struct cfs_hash_bd   bds[2];
 
        cfs_hash_dual_bd_get(hs, cfs_hash_key(hs, hnode), bds);
        LASSERT(bds[0].bd_bucket == bd->bd_bucket ||
@@ -752,11 +752,11 @@ cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 #else /* CFS_HASH_DEBUG_LEVEL > CFS_HASH_DEBUG_1 */
 
 static inline void
-cfs_hash_key_validate(cfs_hash_t *hs, const void *key,
+cfs_hash_key_validate(struct cfs_hash *hs, const void *key,
                      struct hlist_node *hnode) {}
 
 static inline void
-cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bucket_validate(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                         struct hlist_node *hnode) {}
 
 #endif /* CFS_HASH_DEBUG_LEVEL */
@@ -778,13 +778,13 @@ static inline int __cfs_hash_theta_frac(int theta)
               (__cfs_hash_theta_int(theta) * 1000);
 }
 
-static inline int __cfs_hash_theta(cfs_hash_t *hs)
+static inline int __cfs_hash_theta(struct cfs_hash *hs)
 {
        return (atomic_read(&hs->hs_count) <<
                CFS_HASH_THETA_BITS) >> hs->hs_cur_bits;
 }
 
-static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
+static inline void __cfs_hash_set_theta(struct cfs_hash *hs, int min, int max)
 {
        LASSERT(min < max);
        hs->hs_min_theta = (__u16)min;
@@ -794,7 +794,7 @@ static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
 /* Generic debug formatting routines mainly for proc handler */
 struct seq_file;
 int cfs_hash_debug_header(struct seq_file *m);
-int cfs_hash_debug_str(cfs_hash_t *hs, struct seq_file *m);
+int cfs_hash_debug_str(struct cfs_hash *hs, struct seq_file *m);
 
 /*
  * Generic djb2 hash algorithm for character arrays.
@@ -830,7 +830,7 @@ cfs_hash_u64_hash(const __u64 key, unsigned mask)
        return ((unsigned)(key * CFS_GOLDEN_RATIO_PRIME_64) & mask);
 }
 
-/** iterate over all buckets in @bds (array of cfs_hash_bd_t) */
+/** iterate over all buckets in @bds (array of struct cfs_hash_bd) */
 #define cfs_hash_for_each_bd(bds, n, i) \
        for (i = 0; i < n && (bds)[i].bd_bucket != NULL; i++)
 
index 59bff0bea816a66c71b47825749a74fb4efb182a..bf301048c7ab791c950550d86b06789264e980f0 100644 (file)
@@ -79,20 +79,20 @@ extern lnet_t  the_lnet;                    /* THE network */
 /** exclusive lock */
 #define LNET_LOCK_EX       CFS_PERCPT_LOCK_EX
 
-static inline int lnet_is_wire_handle_none (lnet_handle_wire_t *wh)
+static inline int lnet_is_wire_handle_none(lnet_handle_wire_t *wh)
 {
        return (wh->wh_interface_cookie == LNET_WIRE_HANDLE_COOKIE_NONE &&
                wh->wh_object_cookie == LNET_WIRE_HANDLE_COOKIE_NONE);
 }
 
-static inline int lnet_md_exhausted (lnet_libmd_t *md)
+static inline int lnet_md_exhausted(lnet_libmd_t *md)
 {
        return (md->md_threshold == 0 ||
                ((md->md_options & LNET_MD_MAX_SIZE) != 0 &&
                 md->md_offset + md->md_max_size > md->md_length));
 }
 
-static inline int lnet_md_unlinkable (lnet_libmd_t *md)
+static inline int lnet_md_unlinkable(lnet_libmd_t *md)
 {
        /* Should unlink md when its refcount is 0 and either:
         *  - md has been flagged for deletion (by auto unlink or LNetM[DE]Unlink,
@@ -193,31 +193,31 @@ int lnet_freelist_init(lnet_freelist_t *fl, int n, int size);
 void lnet_freelist_fini(lnet_freelist_t *fl);
 
 static inline void *
-lnet_freelist_alloc (lnet_freelist_t *fl)
+lnet_freelist_alloc(lnet_freelist_t *fl)
 {
        /* ALWAYS called with liblock held */
        lnet_freeobj_t *o;
 
-       if (list_empty (&fl->fl_list))
-               return (NULL);
+       if (list_empty(&fl->fl_list))
+               return NULL;
 
-       o = list_entry (fl->fl_list.next, lnet_freeobj_t, fo_list);
-       list_del (&o->fo_list);
-       return ((void *)&o->fo_contents);
+       o = list_entry(fl->fl_list.next, lnet_freeobj_t, fo_list);
+       list_del(&o->fo_list);
+       return (void *)&o->fo_contents;
 }
 
 static inline void
-lnet_freelist_free (lnet_freelist_t *fl, void *obj)
+lnet_freelist_free(lnet_freelist_t *fl, void *obj)
 {
        /* ALWAYS called with liblock held */
-       lnet_freeobj_t *o = list_entry (obj, lnet_freeobj_t, fo_contents);
+       lnet_freeobj_t *o = list_entry(obj, lnet_freeobj_t, fo_contents);
 
-       list_add (&o->fo_list, &fl->fl_list);
+       list_add(&o->fo_list, &fl->fl_list);
 }
 
 
 static inline lnet_eq_t *
-lnet_eq_alloc (void)
+lnet_eq_alloc(void)
 {
        /* NEVER called with resource lock held */
        struct lnet_res_container *rec = &the_lnet.ln_eq_container;
@@ -251,7 +251,7 @@ lnet_eq_free(lnet_eq_t *eq)
 }
 
 static inline lnet_libmd_t *
-lnet_md_alloc (lnet_md_t *umd)
+lnet_md_alloc(lnet_md_t *umd)
 {
        /* NEVER called with resource lock held */
        struct lnet_res_container *rec = the_lnet.ln_md_containers[0];
@@ -322,7 +322,7 @@ lnet_me_free(lnet_me_t *me)
 }
 
 static inline lnet_msg_t *
-lnet_msg_alloc (void)
+lnet_msg_alloc(void)
 {
        /* NEVER called with network lock held */
        struct lnet_msg_container *msc = the_lnet.ln_msg_containers[0];
@@ -353,7 +353,7 @@ lnet_msg_free_locked(lnet_msg_t *msg)
 }
 
 static inline void
-lnet_msg_free (lnet_msg_t *msg)
+lnet_msg_free(lnet_msg_t *msg)
 {
        lnet_net_lock(0);
        lnet_msg_free_locked(msg);
@@ -363,13 +363,13 @@ lnet_msg_free (lnet_msg_t *msg)
 #else /* !LNET_USE_LIB_FREELIST */
 
 static inline lnet_eq_t *
-lnet_eq_alloc (void)
+lnet_eq_alloc(void)
 {
        /* NEVER called with liblock held */
        lnet_eq_t *eq;
 
        LIBCFS_ALLOC(eq, sizeof(*eq));
-       return (eq);
+       return eq;
 }
 
 static inline void
@@ -380,7 +380,7 @@ lnet_eq_free(lnet_eq_t *eq)
 }
 
 static inline lnet_libmd_t *
-lnet_md_alloc (lnet_md_t *umd)
+lnet_md_alloc(lnet_md_t *umd)
 {
        /* NEVER called with liblock held */
        lnet_libmd_t *md;
@@ -405,7 +405,7 @@ lnet_md_alloc (lnet_md_t *umd)
                INIT_LIST_HEAD(&md->md_list);
        }
 
-       return (md);
+       return md;
 }
 
 static inline void
@@ -423,13 +423,13 @@ lnet_md_free(lnet_libmd_t *md)
 }
 
 static inline lnet_me_t *
-lnet_me_alloc (void)
+lnet_me_alloc(void)
 {
        /* NEVER called with liblock held */
        lnet_me_t *me;
 
        LIBCFS_ALLOC(me, sizeof(*me));
-       return (me);
+       return me;
 }
 
 static inline void
@@ -448,7 +448,7 @@ lnet_msg_alloc(void)
        LIBCFS_ALLOC(msg, sizeof(*msg));
 
        /* no need to zero, LIBCFS_ALLOC does for us */
-       return (msg);
+       return msg;
 }
 
 static inline void
@@ -479,7 +479,7 @@ lnet_res_lh_invalidate(lnet_libhandle_t *lh)
 }
 
 static inline void
-lnet_eq2handle (lnet_handle_eq_t *handle, lnet_eq_t *eq)
+lnet_eq2handle(lnet_handle_eq_t *handle, lnet_eq_t *eq)
 {
        if (eq == NULL) {
                LNetInvalidateHandle(handle);
@@ -503,7 +503,7 @@ lnet_handle2eq(lnet_handle_eq_t *handle)
 }
 
 static inline void
-lnet_md2handle (lnet_handle_md_t *handle, lnet_libmd_t *md)
+lnet_md2handle(lnet_handle_md_t *handle, lnet_libmd_t *md)
 {
        handle->cookie = md->md_lh.lh_cookie;
 }
@@ -544,7 +544,7 @@ lnet_wire_handle2md(lnet_handle_wire_t *wh)
 }
 
 static inline void
-lnet_me2handle (lnet_handle_me_t *handle, lnet_me_t *me)
+lnet_me2handle(lnet_handle_me_t *handle, lnet_me_t *me)
 {
        handle->cookie = me->me_lh.lh_cookie;
 }
@@ -568,7 +568,7 @@ lnet_handle2me(lnet_handle_me_t *handle)
 static inline void
 lnet_peer_addref_locked(lnet_peer_t *lp)
 {
-       LASSERT (lp->lp_refcount > 0);
+       LASSERT(lp->lp_refcount > 0);
        lp->lp_refcount++;
 }
 
@@ -577,7 +577,7 @@ extern void lnet_destroy_peer_locked(lnet_peer_t *lp);
 static inline void
 lnet_peer_decref_locked(lnet_peer_t *lp)
 {
-       LASSERT (lp->lp_refcount > 0);
+       LASSERT(lp->lp_refcount > 0);
        lp->lp_refcount--;
        if (lp->lp_refcount == 0)
                lnet_destroy_peer_locked(lp);
@@ -660,7 +660,7 @@ void lnet_proc_init(void);
 void lnet_proc_fini(void);
 int  lnet_rtrpools_alloc(int im_a_router);
 void lnet_rtrpools_free(void);
-lnet_remotenet_t *lnet_find_net_locked (__u32 net);
+lnet_remotenet_t *lnet_find_net_locked(__u32 net);
 
 int lnet_islocalnid(lnet_nid_t nid);
 int lnet_islocalnet(__u32 net);
@@ -733,11 +733,11 @@ int lnet_portals_create(void);
 void lnet_portals_destroy(void);
 
 /* message functions */
-int lnet_parse (lnet_ni_t *ni, lnet_hdr_t *hdr,
+int lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr,
                lnet_nid_t fromnid, void *private, int rdma_req);
 void lnet_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
               unsigned int offset, unsigned int mlen, unsigned int rlen);
-lnet_msg_t *lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *get_msg);
+lnet_msg_t *lnet_create_reply_msg(lnet_ni_t *ni, lnet_msg_t *get_msg);
 void lnet_set_reply_msg_len(lnet_ni_t *ni, lnet_msg_t *msg, unsigned int len);
 void lnet_finalize(lnet_ni_t *ni, lnet_msg_t *msg, int rc);
 void lnet_drop_delayed_msg_list(struct list_head *head, char *reason);
@@ -748,36 +748,36 @@ void lnet_msg_container_cleanup(struct lnet_msg_container *container);
 void lnet_msg_containers_destroy(void);
 int lnet_msg_containers_create(void);
 
-char *lnet_msgtyp2str (int type);
-void lnet_print_hdr (lnet_hdr_t * hdr);
+char *lnet_msgtyp2str(int type);
+void lnet_print_hdr(lnet_hdr_t *hdr);
 int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
 
 void lnet_counters_get(lnet_counters_t *counters);
 void lnet_counters_reset(void);
 
-unsigned int lnet_iov_nob (unsigned int niov, struct iovec *iov);
-int lnet_extract_iov (int dst_niov, struct iovec *dst,
+unsigned int lnet_iov_nob(unsigned int niov, struct iovec *iov);
+int lnet_extract_iov(int dst_niov, struct iovec *dst,
                      int src_niov, struct iovec *src,
                      unsigned int offset, unsigned int len);
 
-unsigned int lnet_kiov_nob (unsigned int niov, lnet_kiov_t *iov);
-int lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
+unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov);
+int lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
                      int src_niov, lnet_kiov_t *src,
                      unsigned int offset, unsigned int len);
 
-void lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov,
+void lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov,
                        unsigned int doffset,
                        unsigned int nsiov, struct iovec *siov,
                        unsigned int soffset, unsigned int nob);
-void lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov,
+void lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov,
                         unsigned int iovoffset,
                         unsigned int nkiov, lnet_kiov_t *kiov,
                         unsigned int kiovoffset, unsigned int nob);
-void lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov,
+void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
                         unsigned int kiovoffset,
                         unsigned int niov, struct iovec *iov,
                         unsigned int iovoffset, unsigned int nob);
-void lnet_copy_kiov2kiov (unsigned int ndkiov, lnet_kiov_t *dkiov,
+void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
                          unsigned int doffset,
                          unsigned int nskiov, lnet_kiov_t *skiov,
                          unsigned int soffset, unsigned int nob);
@@ -829,7 +829,7 @@ void lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd);
 
 void lnet_register_lnd(lnd_t *lnd);
 void lnet_unregister_lnd(lnd_t *lnd);
-int lnet_set_ip_niaddr (lnet_ni_t *ni);
+int lnet_set_ip_niaddr(lnet_ni_t *ni);
 
 int lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
                 __u32 local_ip, __u32 peer_ip, int peer_port);
@@ -858,9 +858,9 @@ void lnet_ping_target_fini(void);
 int lnet_ping(lnet_process_id_t id, int timeout_ms,
              lnet_process_id_t *ids, int n_ids);
 
-int lnet_parse_ip2nets (char **networksp, char *ip2nets);
-int lnet_parse_routes (char *route_str, int *im_a_router);
-int lnet_parse_networks (struct list_head *nilist, char *networks);
+int lnet_parse_ip2nets(char **networksp, char *ip2nets);
+int lnet_parse_routes(char *route_str, int *im_a_router);
+int lnet_parse_networks(struct list_head *nilist, char *networks);
 
 int lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid, int cpt);
 lnet_peer_t *lnet_find_peer_locked(struct lnet_peer_table *ptable,
index 6825b452e5fe6a44f4fa33434101f5429de63778..2ddc3aadb8d6a19c1b40f91c57d52fa091972dfb 100644 (file)
@@ -1768,7 +1768,10 @@ ksocknal_close_matching_conns (lnet_process_id_t id, __u32 ipaddr)
        if (id.nid == LNET_NID_ANY || id.pid == LNET_PID_ANY || ipaddr == 0)
                return (0);
 
-       return (count == 0 ? -ENOENT : 0);
+       if (count == 0)
+               return -ENOENT;
+       else
+               return 0;
 }
 
 void
index bb15bde0704c060c50db0bc28bbf55ff37b11e00..92c60a756644400b0f73122d258794948addf069 100644 (file)
@@ -53,6 +53,7 @@ lnet_acceptor_port(void)
 {
        return accept_port;
 }
+EXPORT_SYMBOL(lnet_acceptor_port);
 
 static inline int
 lnet_accept_magic(__u32 magic, __u32 constant)
@@ -61,9 +62,6 @@ lnet_accept_magic(__u32 magic, __u32 constant)
                magic == __swab32(constant));
 }
 
-
-EXPORT_SYMBOL(lnet_acceptor_port);
-
 static char *accept = "secure";
 
 CFS_MODULE_PARM(accept, "s", charp, 0444,
@@ -75,7 +73,7 @@ CFS_MODULE_PARM(accept_backlog, "i", int, 0444,
 CFS_MODULE_PARM(accept_timeout, "i", int, 0644,
                "Acceptor's timeout (seconds)");
 
-static char *accept_type = NULL;
+static char *accept_type;
 
 int
 lnet_acceptor_get_tunables(void)
@@ -95,57 +93,45 @@ lnet_acceptor_timeout(void)
 EXPORT_SYMBOL(lnet_acceptor_timeout);
 
 void
-lnet_connect_console_error (int rc, lnet_nid_t peer_nid,
+lnet_connect_console_error(int rc, lnet_nid_t peer_nid,
                           __u32 peer_ip, int peer_port)
 {
        switch (rc) {
        /* "normal" errors */
        case -ECONNREFUSED:
-               CNETERR("Connection to %s at host %pI4h on port %d was "
-                       "refused: check that Lustre is running on that node.\n",
+               CNETERR("Connection to %s at host %pI4h on port %d was refused: check that Lustre is running on that node.\n",
                        libcfs_nid2str(peer_nid),
                        &peer_ip, peer_port);
                break;
        case -EHOSTUNREACH:
        case -ENETUNREACH:
-               CNETERR("Connection to %s at host %pI4h "
-                       "was unreachable: the network or that node may "
-                       "be down, or Lustre may be misconfigured.\n",
+               CNETERR("Connection to %s at host %pI4h was unreachable: the network or that node may be down, or Lustre may be misconfigured.\n",
                        libcfs_nid2str(peer_nid), &peer_ip);
                break;
        case -ETIMEDOUT:
-               CNETERR("Connection to %s at host %pI4h on "
-                       "port %d took too long: that node may be hung "
-                       "or experiencing high load.\n",
+               CNETERR("Connection to %s at host %pI4h on port %d took too long: that node may be hung or experiencing high load.\n",
                        libcfs_nid2str(peer_nid),
                        &peer_ip, peer_port);
                break;
        case -ECONNRESET:
-               LCONSOLE_ERROR_MSG(0x11b, "Connection to %s at host %pI4h"
-                                  " on port %d was reset: "
-                                  "is it running a compatible version of "
-                                  "Lustre and is %s one of its NIDs?\n",
+               LCONSOLE_ERROR_MSG(0x11b, "Connection to %s at host %pI4h on port %d was reset: is it running a compatible version of Lustre and is %s one of its NIDs?\n",
                                   libcfs_nid2str(peer_nid),
                                   &peer_ip, peer_port,
                                   libcfs_nid2str(peer_nid));
                break;
        case -EPROTO:
-               LCONSOLE_ERROR_MSG(0x11c, "Protocol error connecting to %s at "
-                                  "host %pI4h on port %d: is it running "
-                                  "a compatible version of Lustre?\n",
+               LCONSOLE_ERROR_MSG(0x11c, "Protocol error connecting to %s at host %pI4h on port %d: is it running a compatible version of Lustre?\n",
                                   libcfs_nid2str(peer_nid),
                                   &peer_ip, peer_port);
                break;
        case -EADDRINUSE:
-               LCONSOLE_ERROR_MSG(0x11d, "No privileged ports available to "
-                                  "connect to %s at host %pI4h on port "
-                                  "%d\n", libcfs_nid2str(peer_nid),
+               LCONSOLE_ERROR_MSG(0x11d, "No privileged ports available to connect to %s at host %pI4h on port %d\n",
+                                  libcfs_nid2str(peer_nid),
                                   &peer_ip, peer_port);
                break;
        default:
-               LCONSOLE_ERROR_MSG(0x11e, "Unexpected error %d connecting to %s"
-                                  " at host %pI4h on port %d\n", rc,
-                                  libcfs_nid2str(peer_nid),
+               LCONSOLE_ERROR_MSG(0x11e, "Unexpected error %d connecting to %s at host %pI4h on port %d\n",
+                                  rc, libcfs_nid2str(peer_nid),
                                   &peer_ip, peer_port);
                break;
        }
@@ -162,7 +148,7 @@ lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
        int                  port;
        int                  fatal;
 
-       CLASSERT (sizeof(cr) <= 16);        /* not too big to be on the stack */
+       CLASSERT(sizeof(cr) <= 16);         /* not too big to be on the stack */
 
        for (port = LNET_ACCEPTOR_MAX_RESERVED_PORT;
             port >= LNET_ACCEPTOR_MIN_RESERVED_PORT;
@@ -178,7 +164,7 @@ lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
                        continue;
                }
 
-               CLASSERT (LNET_PROTO_ACCEPTOR_VERSION == 1);
+               CLASSERT(LNET_PROTO_ACCEPTOR_VERSION == 1);
 
                cr.acr_magic   = LNET_PROTO_ACCEPTOR_MAGIC;
                cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
@@ -232,10 +218,10 @@ lnet_accept(socket_t *sock, __u32 magic)
        lnet_ni_t             *ni;
        char               *str;
 
-       LASSERT (sizeof(cr) <= 16);          /* not too big for the stack */
+       LASSERT(sizeof(cr) <= 16);           /* not too big for the stack */
 
        rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port);
-       LASSERT (rc == 0);                    /* we succeeded before */
+       LASSERT(rc == 0);                     /* we succeeded before */
 
        if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) {
 
@@ -245,15 +231,14 @@ lnet_accept(socket_t *sock, __u32 magic)
                         * thing sent will be a version query.  I send back
                         * LNET_PROTO_ACCEPTOR_MAGIC to tell her I'm "old" */
 
-                       memset (&cr, 0, sizeof(cr));
+                       memset(&cr, 0, sizeof(cr));
                        cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
                        cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
                        rc = libcfs_sock_write(sock, &cr, sizeof(cr),
                                               accept_timeout);
 
                        if (rc != 0)
-                               CERROR("Error sending magic+version in response"
-                                      "to LNET magic from %pI4h: %d\n",
+                               CERROR("Error sending magic+version in response to LNET magic from %pI4h: %d\n",
                                       &peer_ip, rc);
                        return -EPROTO;
                }
@@ -265,8 +250,7 @@ lnet_accept(socket_t *sock, __u32 magic)
                else
                        str = "unrecognised";
 
-               LCONSOLE_ERROR_MSG(0x11f, "Refusing connection from %pI4h"
-                                  " magic %08x: %s acceptor protocol\n",
+               LCONSOLE_ERROR_MSG(0x11f, "Refusing connection from %pI4h magic %08x: %s acceptor protocol\n",
                                   &peer_ip, magic, str);
                return -EPROTO;
        }
@@ -277,8 +261,8 @@ lnet_accept(socket_t *sock, __u32 magic)
                              sizeof(cr.acr_version),
                              accept_timeout);
        if (rc != 0) {
-               CERROR("Error %d reading connection request version from "
-                      "%pI4h\n", rc, &peer_ip);
+               CERROR("Error %d reading connection request version from %pI4h\n",
+                       rc, &peer_ip);
                return -EIO;
        }
 
@@ -292,7 +276,7 @@ lnet_accept(socket_t *sock, __u32 magic)
                 * "old". */
                int peer_version = cr.acr_version;
 
-               memset (&cr, 0, sizeof(cr));
+               memset(&cr, 0, sizeof(cr));
                cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
                cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
 
@@ -300,8 +284,7 @@ lnet_accept(socket_t *sock, __u32 magic)
                                       accept_timeout);
 
                if (rc != 0)
-                       CERROR("Error sending magic+version in response"
-                              "to version %d from %pI4h: %d\n",
+                       CERROR("Error sending magic+version in response to version %d from %pI4h: %d\n",
                               peer_version, &peer_ip, rc);
                return -EPROTO;
        }
@@ -311,8 +294,8 @@ lnet_accept(socket_t *sock, __u32 magic)
                              offsetof(lnet_acceptor_connreq_t, acr_nid),
                              accept_timeout);
        if (rc != 0) {
-               CERROR("Error %d reading connection request from "
-                      "%pI4h\n", rc, &peer_ip);
+               CERROR("Error %d reading connection request from %pI4h\n",
+                       rc, &peer_ip);
                return -EIO;
        }
 
@@ -324,8 +307,7 @@ lnet_accept(socket_t *sock, __u32 magic)
            ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */
                if (ni != NULL)
                        lnet_ni_decref(ni);
-               LCONSOLE_ERROR_MSG(0x120, "Refusing connection from %pI4h"
-                                  " for %s: No matching NI\n",
+               LCONSOLE_ERROR_MSG(0x120, "Refusing connection from %pI4h for %s: No matching NI\n",
                                   &peer_ip, libcfs_nid2str(cr.acr_nid));
                return -EPERM;
        }
@@ -333,8 +315,7 @@ lnet_accept(socket_t *sock, __u32 magic)
        if (ni->ni_lnd->lnd_accept == NULL) {
                /* This catches a request for the loopback LND */
                lnet_ni_decref(ni);
-               LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h"
-                                 " for %s: NI doesn not accept IP connections\n",
+               LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n",
                                  &peer_ip, libcfs_nid2str(cr.acr_nid));
                return -EPERM;
        }
@@ -358,7 +339,7 @@ lnet_acceptor(void *arg)
        int         peer_port;
        int         secure = (int)((long_ptr_t)arg);
 
-       LASSERT (lnet_acceptor_state.pta_sock == NULL);
+       LASSERT(lnet_acceptor_state.pta_sock == NULL);
 
        cfs_block_allsigs();
 
@@ -366,12 +347,10 @@ lnet_acceptor(void *arg)
                                0, accept_port, accept_backlog);
        if (rc != 0) {
                if (rc == -EADDRINUSE)
-                       LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port"
-                                          " %d: port already in use\n",
+                       LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port %d: port already in use\n",
                                           accept_port);
                else
-                       LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port "
-                                          "%d: unexpected error %d\n",
+                       LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port %d: unexpected error %d\n",
                                           accept_port, rc);
 
                lnet_acceptor_state.pta_sock = NULL;
@@ -410,8 +389,7 @@ lnet_acceptor(void *arg)
                }
 
                if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
-                       CERROR("Refusing connection from %pI4h: "
-                              "insecure port %d\n",
+                       CERROR("Refusing connection from %pI4h: insecure port %d\n",
                               &peer_ip, peer_port);
                        goto failed;
                }
@@ -419,8 +397,8 @@ lnet_acceptor(void *arg)
                rc = libcfs_sock_read(newsock, &magic, sizeof(magic),
                                      accept_timeout);
                if (rc != 0) {
-                       CERROR("Error %d reading connection request from "
-                              "%pI4h\n", rc, &peer_ip);
+                       CERROR("Error %d reading connection request from %pI4h\n",
+                               rc, &peer_ip);
                        goto failed;
                }
 
@@ -430,7 +408,7 @@ lnet_acceptor(void *arg)
 
                continue;
 
-       failed:
+failed:
                libcfs_sock_release(newsock);
        }
 
@@ -469,7 +447,7 @@ lnet_acceptor_start(void)
        long rc2;
        long secure;
 
-       LASSERT (lnet_acceptor_state.pta_sock == NULL);
+       LASSERT(lnet_acceptor_state.pta_sock == NULL);
 
        rc = lnet_acceptor_get_tunables();
        if (rc != 0)
index 28711e6e8b03f17731b239e13f05dd6ff7034bd5..de323f779db871435ba96c7f7cb73c06112d24c8 100644 (file)
@@ -43,7 +43,7 @@ typedef struct {                          /* tmp struct for parsing routes */
        char           ltb_text[0];     /* text buffer */
 } lnet_text_buf_t;
 
-static int lnet_tbnob = 0;                     /* track text buf allocation */
+static int lnet_tbnob;                 /* track text buf allocation */
 #define LNET_MAX_TEXTBUF_NOB     (64<<10)      /* bound allocation */
 #define LNET_SINGLE_TEXTBUF_NOB  (4<<10)
 
@@ -65,7 +65,7 @@ lnet_syntax(char *name, char *str, int offset, int width)
 }
 
 int
-lnet_issep (char c)
+lnet_issep(char c)
 {
        switch (c) {
        case '\n':
@@ -83,7 +83,7 @@ lnet_net_unique(__u32 net, struct list_head *nilist)
        struct list_head       *tmp;
        lnet_ni_t       *ni;
 
-       list_for_each (tmp, nilist) {
+       list_for_each(tmp, nilist) {
                ni = list_entry(tmp, lnet_ni_t, ni_list);
 
                if (LNET_NIDNET(ni->ni_nid) == net)
@@ -188,8 +188,8 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
 
        if (strlen(networks) > LNET_SINGLE_TEXTBUF_NOB) {
                /* _WAY_ conservative */
-               LCONSOLE_ERROR_MSG(0x112, "Can't parse networks: string too "
-                                  "long\n");
+               LCONSOLE_ERROR_MSG(0x112,
+                                  "Can't parse networks: string too long\n");
                return -EINVAL;
        }
 
@@ -201,7 +201,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
 
        the_lnet.ln_network_tokens = tokens;
        the_lnet.ln_network_tokens_nob = tokensize;
-       memcpy (tokens, networks, tokensize);
+       memcpy(tokens, networks, tokensize);
        str = tmp = tokens;
 
        /* Add in the loopback network */
@@ -255,8 +255,8 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
                        net = libcfs_str2net(cfs_trimwhite(str));
 
                        if (net == LNET_NIDNET(LNET_NID_ANY)) {
-                               LCONSOLE_ERROR_MSG(0x113, "Unrecognised network"
-                                                  " type\n");
+                               LCONSOLE_ERROR_MSG(0x113,
+                                                  "Unrecognised network type\n");
                                tmp = str;
                                goto failed_syntax;
                        }
@@ -313,8 +313,8 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
                        }
 
                        if (niface == LNET_MAX_INTERFACES) {
-                               LCONSOLE_ERROR_MSG(0x115, "Too many interfaces "
-                                                  "for net %s\n",
+                               LCONSOLE_ERROR_MSG(0x115,
+                                                  "Too many interfaces for net %s\n",
                                                   libcfs_net2str(net));
                                goto failed;
                        }
@@ -366,7 +366,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
 }
 
 lnet_text_buf_t *
-lnet_new_text_buf (int str_len)
+lnet_new_text_buf(int str_len)
 {
        lnet_text_buf_t *ltb;
        int           nob;
@@ -395,7 +395,7 @@ lnet_new_text_buf (int str_len)
 }
 
 void
-lnet_free_text_buf (lnet_text_buf_t *ltb)
+lnet_free_text_buf(lnet_text_buf_t *ltb)
 {
        lnet_tbnob -= ltb->ltb_size;
        LIBCFS_FREE(ltb, ltb->ltb_size);
@@ -420,7 +420,7 @@ lnet_print_text_bufs(struct list_head *tbs)
        struct list_head        *tmp;
        lnet_text_buf_t   *ltb;
 
-       list_for_each (tmp, tbs) {
+       list_for_each(tmp, tbs) {
                ltb = list_entry(tmp, lnet_text_buf_t, ltb_list);
 
                CDEBUG(D_WARNING, "%s\n", ltb->ltb_text);
@@ -430,7 +430,7 @@ lnet_print_text_bufs(struct list_head *tbs)
 }
 
 int
-lnet_str2tbs_sep (struct list_head *tbs, char *str)
+lnet_str2tbs_sep(struct list_head *tbs, char *str)
 {
        struct list_head        pending;
        char         *sep;
@@ -488,7 +488,7 @@ lnet_str2tbs_sep (struct list_head *tbs, char *str)
 }
 
 int
-lnet_expand1tb (struct list_head *list,
+lnet_expand1tb(struct list_head *list,
               char *str, char *sep1, char *sep2,
               char *item, int itemlen)
 {
@@ -496,8 +496,8 @@ lnet_expand1tb (struct list_head *list,
        int           len2 = strlen(sep2 + 1);
        lnet_text_buf_t *ltb;
 
-       LASSERT (*sep1 == '[');
-       LASSERT (*sep2 == ']');
+       LASSERT(*sep1 == '[');
+       LASSERT(*sep2 == ']');
 
        ltb = lnet_new_text_buf(len1 + itemlen + len2);
        if (ltb == NULL)
@@ -513,7 +513,7 @@ lnet_expand1tb (struct list_head *list,
 }
 
 int
-lnet_str2tbs_expand (struct list_head *tbs, char *str)
+lnet_str2tbs_expand(struct list_head *tbs, char *str)
 {
        char          num[16];
        struct list_head        pending;
@@ -593,7 +593,7 @@ lnet_str2tbs_expand (struct list_head *tbs, char *str)
 }
 
 int
-lnet_parse_hops (char *str, unsigned int *hops)
+lnet_parse_hops(char *str, unsigned int *hops)
 {
        int     len = strlen(str);
        int     nob = len;
@@ -605,7 +605,7 @@ lnet_parse_hops (char *str, unsigned int *hops)
 
 
 int
-lnet_parse_route (char *str, int *im_a_router)
+lnet_parse_route(char *str, int *im_a_router)
 {
        /* static scratch buffer OK (single threaded) */
        static char       cmd[LNET_SINGLE_TEXTBUF_NOB];
@@ -702,28 +702,27 @@ lnet_parse_route (char *str, int *im_a_router)
        if (!got_hops)
                hops = 1;
 
-       LASSERT (!list_empty(&nets));
-       LASSERT (!list_empty(&gateways));
+       LASSERT(!list_empty(&nets));
+       LASSERT(!list_empty(&gateways));
 
-       list_for_each (tmp1, &nets) {
+       list_for_each(tmp1, &nets) {
                ltb = list_entry(tmp1, lnet_text_buf_t, ltb_list);
                net = libcfs_str2net(ltb->ltb_text);
-               LASSERT (net != LNET_NIDNET(LNET_NID_ANY));
+               LASSERT(net != LNET_NIDNET(LNET_NID_ANY));
 
-               list_for_each (tmp2, &gateways) {
+               list_for_each(tmp2, &gateways) {
                        ltb = list_entry(tmp2, lnet_text_buf_t, ltb_list);
                        nid = libcfs_str2nid(ltb->ltb_text);
-                       LASSERT (nid != LNET_NID_ANY);
+                       LASSERT(nid != LNET_NID_ANY);
 
                        if (lnet_islocalnid(nid)) {
                                *im_a_router = 1;
                                continue;
                        }
 
-                       rc = lnet_add_route (net, hops, nid);
+                       rc = lnet_add_route(net, hops, nid);
                        if (rc != 0) {
-                               CERROR("Can't create route "
-                                      "to %s via %s\n",
+                               CERROR("Can't create route to %s via %s\n",
                                       libcfs_net2str(net),
                                       libcfs_nid2str(nid));
                                goto out;
@@ -763,7 +762,7 @@ lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router)
 }
 
 int
-lnet_parse_routes (char *routes, int *im_a_router)
+lnet_parse_routes(char *routes, int *im_a_router)
 {
        struct list_head        tbs;
        int            rc = 0;
@@ -779,14 +778,14 @@ lnet_parse_routes (char *routes, int *im_a_router)
                rc = lnet_parse_route_tbs(&tbs, im_a_router);
        }
 
-       LASSERT (lnet_tbnob == 0);
+       LASSERT(lnet_tbnob == 0);
        return rc;
 }
 
 int
 lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip)
 {
-       LIST_HEAD       (list);
+       LIST_HEAD(list);
        int             rc;
        int             i;
 
@@ -815,7 +814,7 @@ lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip)
        char *token;
        int   rc;
 
-       LASSERT (strlen(net_entry) < sizeof(tokens));
+       LASSERT(strlen(net_entry) < sizeof(tokens));
 
        /* work on a copy of the string */
        strcpy(tokens, net_entry);
@@ -889,8 +888,8 @@ lnet_splitnets(char *source, struct list_head *nets)
        char         *bracket;
        __u32        net;
 
-       LASSERT (!list_empty(nets));
-       LASSERT (nets->next == nets->prev);     /* single entry */
+       LASSERT(!list_empty(nets));
+       LASSERT(nets->next == nets->prev);     /* single entry */
 
        tb = list_entry(nets->next, lnet_text_buf_t, ltb_list);
 
@@ -957,7 +956,7 @@ lnet_splitnets(char *source, struct list_head *nets)
 }
 
 int
-lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
+lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
 {
        static char     networks[LNET_SINGLE_TEXTBUF_NOB];
        static char     source[LNET_SINGLE_TEXTBUF_NOB];
@@ -979,7 +978,7 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
        INIT_LIST_HEAD(&raw_entries);
        if (lnet_str2tbs_sep(&raw_entries, ip2nets) < 0) {
                CERROR("Error parsing ip2nets\n");
-               LASSERT (lnet_tbnob == 0);
+               LASSERT(lnet_tbnob == 0);
                return -EINVAL;
        }
 
@@ -1017,16 +1016,16 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
                        break;
 
                dup = 0;
-               list_for_each (t, &current_nets) {
+               list_for_each(t, &current_nets) {
                        tb = list_entry(t, lnet_text_buf_t, ltb_list);
                        net1 = lnet_netspec2net(tb->ltb_text);
-                       LASSERT (net1 != LNET_NIDNET(LNET_NID_ANY));
+                       LASSERT(net1 != LNET_NIDNET(LNET_NID_ANY));
 
                        list_for_each(t2, &matched_nets) {
                                tb2 = list_entry(t2, lnet_text_buf_t,
                                                     ltb_list);
                                net2 = lnet_netspec2net(tb2->ltb_text);
-                               LASSERT (net2 != LNET_NIDNET(LNET_NID_ANY));
+                               LASSERT(net2 != LNET_NIDNET(LNET_NID_ANY));
 
                                if (net1 == net2) {
                                        dup = 1;
@@ -1067,7 +1066,7 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
        lnet_free_text_bufs(&raw_entries);
        lnet_free_text_bufs(&matched_nets);
        lnet_free_text_bufs(&current_nets);
-       LASSERT (lnet_tbnob == 0);
+       LASSERT(lnet_tbnob == 0);
 
        if (rc < 0)
                return rc;
@@ -1083,7 +1082,7 @@ lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
 }
 
 int
-lnet_ipaddr_enumerate (__u32 **ipaddrsp)
+lnet_ipaddr_enumerate(__u32 **ipaddrsp)
 {
        int     up;
        __u32      netmask;
@@ -1149,21 +1148,22 @@ lnet_ipaddr_enumerate (__u32 **ipaddrsp)
 }
 
 int
-lnet_parse_ip2nets (char **networksp, char *ip2nets)
+lnet_parse_ip2nets(char **networksp, char *ip2nets)
 {
        __u32     *ipaddrs;
        int     nip = lnet_ipaddr_enumerate(&ipaddrs);
        int     rc;
 
        if (nip < 0) {
-               LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
-                                  "interfaces for ip2nets to match\n", nip);
+               LCONSOLE_ERROR_MSG(0x117,
+                                  "Error %d enumerating local IP interfaces for ip2nets to match\n",
+                                  nip);
                return nip;
        }
 
        if (nip == 0) {
-               LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
-                                  "for ip2nets to match\n");
+               LCONSOLE_ERROR_MSG(0x118,
+                                  "No local IP interfaces for ip2nets to match\n");
                return -ENOENT;
        }
 
@@ -1176,8 +1176,8 @@ lnet_parse_ip2nets (char **networksp, char *ip2nets)
        }
 
        if (rc == 0) {
-               LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
-                                  "any local IP interfaces\n");
+               LCONSOLE_ERROR_MSG(0x11a,
+                                  "ip2nets does not match any local IP interfaces\n");
                return -ENOENT;
        }
 
@@ -1185,7 +1185,7 @@ lnet_parse_ip2nets (char **networksp, char *ip2nets)
 }
 
 int
-lnet_set_ip_niaddr (lnet_ni_t *ni)
+lnet_set_ip_niaddr(lnet_ni_t *ni)
 {
        __u32  net = LNET_NIDNET(ni->ni_nid);
        char **names;
@@ -1201,7 +1201,7 @@ lnet_set_ip_niaddr (lnet_ni_t *ni)
 
        if (ni->ni_interfaces[0] != NULL) {
 
-               CLASSERT (LNET_MAX_INTERFACES > 1);
+               CLASSERT(LNET_MAX_INTERFACES > 1);
 
                if (ni->ni_interfaces[1] != NULL) {
                        CERROR("Net %s doesn't support multiple interfaces\n",
index 49b0f1287a69ca85172b590bcec15d56144cd453..b6f8ad38628baec5cce918aca15e7462872680b3 100644 (file)
@@ -47,14 +47,14 @@ CFS_MODULE_PARM(local_nid_dist_zero, "i", int, 0444,
                "Reserved");
 
 int
-lnet_fail_nid (lnet_nid_t nid, unsigned int threshold)
+lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
 {
        lnet_test_peer_t  *tp;
        struct list_head        *el;
        struct list_head        *next;
        struct list_head         cull;
 
-       LASSERT (the_lnet.ln_init);
+       LASSERT(the_lnet.ln_init);
 
        /* NB: use lnet_net_lock(0) to serialize operations on test peers */
        if (threshold != 0) {
@@ -77,31 +77,30 @@ lnet_fail_nid (lnet_nid_t nid, unsigned int threshold)
 
        lnet_net_lock(0);
 
-       list_for_each_safe (el, next, &the_lnet.ln_test_peers) {
-               tp = list_entry (el, lnet_test_peer_t, tp_list);
+       list_for_each_safe(el, next, &the_lnet.ln_test_peers) {
+               tp = list_entry(el, lnet_test_peer_t, tp_list);
 
                if (tp->tp_threshold == 0 ||    /* needs culling anyway */
                    nid == LNET_NID_ANY ||       /* removing all entries */
-                   tp->tp_nid == nid)    /* matched this one */
-               {
-                       list_del (&tp->tp_list);
-                       list_add (&tp->tp_list, &cull);
+                   tp->tp_nid == nid) {          /* matched this one */
+                       list_del(&tp->tp_list);
+                       list_add(&tp->tp_list, &cull);
                }
        }
 
        lnet_net_unlock(0);
 
-       while (!list_empty (&cull)) {
-               tp = list_entry (cull.next, lnet_test_peer_t, tp_list);
+       while (!list_empty(&cull)) {
+               tp = list_entry(cull.next, lnet_test_peer_t, tp_list);
 
-               list_del (&tp->tp_list);
-               LIBCFS_FREE(tp, sizeof (*tp));
+               list_del(&tp->tp_list);
+               LIBCFS_FREE(tp, sizeof(*tp));
        }
        return 0;
 }
 
 static int
-fail_peer (lnet_nid_t nid, int outgoing)
+fail_peer(lnet_nid_t nid, int outgoing)
 {
        lnet_test_peer_t *tp;
        struct list_head       *el;
@@ -109,13 +108,13 @@ fail_peer (lnet_nid_t nid, int outgoing)
        struct list_head        cull;
        int            fail = 0;
 
-       INIT_LIST_HEAD (&cull);
+       INIT_LIST_HEAD(&cull);
 
        /* NB: use lnet_net_lock(0) to serialize operations on test peers */
        lnet_net_lock(0);
 
-       list_for_each_safe (el, next, &the_lnet.ln_test_peers) {
-               tp = list_entry (el, lnet_test_peer_t, tp_list);
+       list_for_each_safe(el, next, &the_lnet.ln_test_peers) {
+               tp = list_entry(el, lnet_test_peer_t, tp_list);
 
                if (tp->tp_threshold == 0) {
                        /* zombie entry */
@@ -123,8 +122,8 @@ fail_peer (lnet_nid_t nid, int outgoing)
                                /* only cull zombies on outgoing tests,
                                 * since we may be at interrupt priority on
                                 * incoming messages. */
-                               list_del (&tp->tp_list);
-                               list_add (&tp->tp_list, &cull);
+                               list_del(&tp->tp_list);
+                               list_add(&tp->tp_list, &cull);
                        }
                        continue;
                }
@@ -138,8 +137,8 @@ fail_peer (lnet_nid_t nid, int outgoing)
                                if (outgoing &&
                                    tp->tp_threshold == 0) {
                                        /* see above */
-                                       list_del (&tp->tp_list);
-                                       list_add (&tp->tp_list, &cull);
+                                       list_del(&tp->tp_list);
+                                       list_add(&tp->tp_list, &cull);
                                }
                        }
                        break;
@@ -148,30 +147,30 @@ fail_peer (lnet_nid_t nid, int outgoing)
 
        lnet_net_unlock(0);
 
-       while (!list_empty (&cull)) {
-               tp = list_entry (cull.next, lnet_test_peer_t, tp_list);
-               list_del (&tp->tp_list);
+       while (!list_empty(&cull)) {
+               tp = list_entry(cull.next, lnet_test_peer_t, tp_list);
+               list_del(&tp->tp_list);
 
-               LIBCFS_FREE(tp, sizeof (*tp));
+               LIBCFS_FREE(tp, sizeof(*tp));
        }
 
-       return (fail);
+       return fail;
 }
 
 unsigned int
-lnet_iov_nob (unsigned int niov, struct iovec *iov)
+lnet_iov_nob(unsigned int niov, struct iovec *iov)
 {
        unsigned int nob = 0;
 
        while (niov-- > 0)
                nob += (iov++)->iov_len;
 
-       return (nob);
+       return nob;
 }
 EXPORT_SYMBOL(lnet_iov_nob);
 
 void
-lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
+lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
                   unsigned int nsiov, struct iovec *siov, unsigned int soffset,
                   unsigned int nob)
 {
@@ -182,31 +181,31 @@ lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
                return;
 
        /* skip complete frags before 'doffset' */
-       LASSERT (ndiov > 0);
+       LASSERT(ndiov > 0);
        while (doffset >= diov->iov_len) {
                doffset -= diov->iov_len;
                diov++;
                ndiov--;
-               LASSERT (ndiov > 0);
+               LASSERT(ndiov > 0);
        }
 
        /* skip complete frags before 'soffset' */
-       LASSERT (nsiov > 0);
+       LASSERT(nsiov > 0);
        while (soffset >= siov->iov_len) {
                soffset -= siov->iov_len;
                siov++;
                nsiov--;
-               LASSERT (nsiov > 0);
+               LASSERT(nsiov > 0);
        }
 
        do {
-               LASSERT (ndiov > 0);
-               LASSERT (nsiov > 0);
+               LASSERT(ndiov > 0);
+               LASSERT(nsiov > 0);
                this_nob = MIN(diov->iov_len - doffset,
                               siov->iov_len - soffset);
                this_nob = MIN(this_nob, nob);
 
-               memcpy ((char *)diov->iov_base + doffset,
+               memcpy((char *)diov->iov_base + doffset,
                        (char *)siov->iov_base + soffset, this_nob);
                nob -= this_nob;
 
@@ -230,7 +229,7 @@ lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
 EXPORT_SYMBOL(lnet_copy_iov2iov);
 
 int
-lnet_extract_iov (int dst_niov, struct iovec *dst,
+lnet_extract_iov(int dst_niov, struct iovec *dst,
                  int src_niov, struct iovec *src,
                  unsigned int offset, unsigned int len)
 {
@@ -241,27 +240,27 @@ lnet_extract_iov (int dst_niov, struct iovec *dst,
        unsigned int    niov;
 
        if (len == 0)                      /* no data => */
-               return (0);                  /* no frags */
+               return 0;                    /* no frags */
 
-       LASSERT (src_niov > 0);
+       LASSERT(src_niov > 0);
        while (offset >= src->iov_len) {      /* skip initial frags */
                offset -= src->iov_len;
                src_niov--;
                src++;
-               LASSERT (src_niov > 0);
+               LASSERT(src_niov > 0);
        }
 
        niov = 1;
        for (;;) {
-               LASSERT (src_niov > 0);
-               LASSERT ((int)niov <= dst_niov);
+               LASSERT(src_niov > 0);
+               LASSERT((int)niov <= dst_niov);
 
                frag_len = src->iov_len - offset;
                dst->iov_base = ((char *)src->iov_base) + offset;
 
                if (len <= frag_len) {
                        dst->iov_len = len;
-                       return (niov);
+                       return niov;
                }
 
                dst->iov_len = frag_len;
@@ -278,21 +277,21 @@ EXPORT_SYMBOL(lnet_extract_iov);
 
 
 unsigned int
-lnet_kiov_nob (unsigned int niov, lnet_kiov_t *kiov)
+lnet_kiov_nob(unsigned int niov, lnet_kiov_t *kiov)
 {
        unsigned int  nob = 0;
 
        while (niov-- > 0)
                nob += (kiov++)->kiov_len;
 
-       return (nob);
+       return nob;
 }
 EXPORT_SYMBOL(lnet_kiov_nob);
 
 void
-lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
-                    unsigned int nsiov, lnet_kiov_t *siov, unsigned int soffset,
-                    unsigned int nob)
+lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
+                   unsigned int nsiov, lnet_kiov_t *siov, unsigned int soffset,
+                   unsigned int nob)
 {
        /* NB diov, siov are READ-ONLY */
        unsigned int    this_nob;
@@ -302,27 +301,27 @@ lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset
        if (nob == 0)
                return;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
-       LASSERT (ndiov > 0);
+       LASSERT(ndiov > 0);
        while (doffset >= diov->kiov_len) {
                doffset -= diov->kiov_len;
                diov++;
                ndiov--;
-               LASSERT (ndiov > 0);
+               LASSERT(ndiov > 0);
        }
 
-       LASSERT (nsiov > 0);
+       LASSERT(nsiov > 0);
        while (soffset >= siov->kiov_len) {
                soffset -= siov->kiov_len;
                siov++;
                nsiov--;
-               LASSERT (nsiov > 0);
+               LASSERT(nsiov > 0);
        }
 
        do {
-               LASSERT (ndiov > 0);
-               LASSERT (nsiov > 0);
+               LASSERT(ndiov > 0);
+               LASSERT(nsiov > 0);
                this_nob = MIN(diov->kiov_len - doffset,
                               siov->kiov_len - soffset);
                this_nob = MIN(this_nob, nob);
@@ -338,7 +337,7 @@ lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset
                 * However in practice at least one of the kiovs will be mapped
                 * kernel pages and the map/unmap will be NOOPs */
 
-               memcpy (daddr, saddr, this_nob);
+               memcpy(daddr, saddr, this_nob);
                nob -= this_nob;
 
                if (diov->kiov_len > doffset + this_nob) {
@@ -372,9 +371,9 @@ lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset
 EXPORT_SYMBOL(lnet_copy_kiov2kiov);
 
 void
-lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset,
-                   unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffset,
-                   unsigned int nob)
+lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, unsigned int iovoffset,
+                  unsigned int nkiov, lnet_kiov_t *kiov,
+                  unsigned int kiovoffset, unsigned int nob)
 {
        /* NB iov, kiov are READ-ONLY */
        unsigned int    this_nob;
@@ -383,27 +382,27 @@ lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset
        if (nob == 0)
                return;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
-       LASSERT (niov > 0);
+       LASSERT(niov > 0);
        while (iovoffset >= iov->iov_len) {
                iovoffset -= iov->iov_len;
                iov++;
                niov--;
-               LASSERT (niov > 0);
+               LASSERT(niov > 0);
        }
 
-       LASSERT (nkiov > 0);
+       LASSERT(nkiov > 0);
        while (kiovoffset >= kiov->kiov_len) {
                kiovoffset -= kiov->kiov_len;
                kiov++;
                nkiov--;
-               LASSERT (nkiov > 0);
+               LASSERT(nkiov > 0);
        }
 
        do {
-               LASSERT (niov > 0);
-               LASSERT (nkiov > 0);
+               LASSERT(niov > 0);
+               LASSERT(nkiov > 0);
                this_nob = MIN(iov->iov_len - iovoffset,
                               kiov->kiov_len - kiovoffset);
                this_nob = MIN(this_nob, nob);
@@ -412,7 +411,7 @@ lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset
                        addr = ((char *)kmap(kiov->kiov_page)) +
                                kiov->kiov_offset + kiovoffset;
 
-               memcpy ((char *)iov->iov_base + iovoffset, addr, this_nob);
+               memcpy((char *)iov->iov_base + iovoffset, addr, this_nob);
                nob -= this_nob;
 
                if (iov->iov_len > iovoffset + this_nob) {
@@ -442,9 +441,10 @@ lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset
 EXPORT_SYMBOL(lnet_copy_kiov2iov);
 
 void
-lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffset,
-                   unsigned int niov, struct iovec *iov, unsigned int iovoffset,
-                   unsigned int nob)
+lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
+                  unsigned int kiovoffset, unsigned int niov,
+                  struct iovec *iov, unsigned int iovoffset,
+                  unsigned int nob)
 {
        /* NB kiov, iov are READ-ONLY */
        unsigned int    this_nob;
@@ -453,27 +453,27 @@ lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffs
        if (nob == 0)
                return;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
-       LASSERT (nkiov > 0);
+       LASSERT(nkiov > 0);
        while (kiovoffset >= kiov->kiov_len) {
                kiovoffset -= kiov->kiov_len;
                kiov++;
                nkiov--;
-               LASSERT (nkiov > 0);
+               LASSERT(nkiov > 0);
        }
 
-       LASSERT (niov > 0);
+       LASSERT(niov > 0);
        while (iovoffset >= iov->iov_len) {
                iovoffset -= iov->iov_len;
                iov++;
                niov--;
-               LASSERT (niov > 0);
+               LASSERT(niov > 0);
        }
 
        do {
-               LASSERT (nkiov > 0);
-               LASSERT (niov > 0);
+               LASSERT(nkiov > 0);
+               LASSERT(niov > 0);
                this_nob = MIN(kiov->kiov_len - kiovoffset,
                               iov->iov_len - iovoffset);
                this_nob = MIN(this_nob, nob);
@@ -482,7 +482,7 @@ lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffs
                        addr = ((char *)kmap(kiov->kiov_page)) +
                                kiov->kiov_offset + kiovoffset;
 
-               memcpy (addr, (char *)iov->iov_base + iovoffset, this_nob);
+               memcpy(addr, (char *)iov->iov_base + iovoffset, this_nob);
                nob -= this_nob;
 
                if (kiov->kiov_len > kiovoffset + this_nob) {
@@ -511,7 +511,7 @@ lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffs
 EXPORT_SYMBOL(lnet_copy_iov2kiov);
 
 int
-lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
+lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
                   int src_niov, lnet_kiov_t *src,
                   unsigned int offset, unsigned int len)
 {
@@ -522,20 +522,20 @@ lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
        unsigned int    niov;
 
        if (len == 0)                      /* no data => */
-               return (0);                  /* no frags */
+               return 0;                    /* no frags */
 
-       LASSERT (src_niov > 0);
+       LASSERT(src_niov > 0);
        while (offset >= src->kiov_len) {      /* skip initial frags */
                offset -= src->kiov_len;
                src_niov--;
                src++;
-               LASSERT (src_niov > 0);
+               LASSERT(src_niov > 0);
        }
 
        niov = 1;
        for (;;) {
-               LASSERT (src_niov > 0);
-               LASSERT ((int)niov <= dst_niov);
+               LASSERT(src_niov > 0);
+               LASSERT((int)niov <= dst_niov);
 
                frag_len = src->kiov_len - offset;
                dst->kiov_page = src->kiov_page;
@@ -543,12 +543,13 @@ lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
 
                if (len <= frag_len) {
                        dst->kiov_len = len;
-                       LASSERT (dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
-                       return (niov);
+                       LASSERT(dst->kiov_offset + dst->kiov_len
+                                            <= PAGE_CACHE_SIZE);
+                       return niov;
                }
 
                dst->kiov_len = frag_len;
-               LASSERT (dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
+               LASSERT(dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
 
                len -= frag_len;
                dst++;
@@ -569,8 +570,8 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
        lnet_kiov_t  *kiov = NULL;
        int        rc;
 
-       LASSERT (!in_interrupt ());
-       LASSERT (mlen == 0 || msg != NULL);
+       LASSERT(!in_interrupt());
+       LASSERT(mlen == 0 || msg != NULL);
 
        if (msg != NULL) {
                LASSERT(msg->msg_receiving);
@@ -587,8 +588,8 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
                        iov  = msg->msg_iov;
                        kiov = msg->msg_kiov;
 
-                       LASSERT (niov > 0);
-                       LASSERT ((iov == NULL) != (kiov == NULL));
+                       LASSERT(niov > 0);
+                       LASSERT((iov == NULL) != (kiov == NULL));
                }
        }
 
@@ -603,12 +604,12 @@ lnet_setpayloadbuffer(lnet_msg_t *msg)
 {
        lnet_libmd_t *md = msg->msg_md;
 
-       LASSERT (msg->msg_len > 0);
-       LASSERT (!msg->msg_routing);
-       LASSERT (md != NULL);
-       LASSERT (msg->msg_niov == 0);
-       LASSERT (msg->msg_iov == NULL);
-       LASSERT (msg->msg_kiov == NULL);
+       LASSERT(msg->msg_len > 0);
+       LASSERT(!msg->msg_routing);
+       LASSERT(md != NULL);
+       LASSERT(msg->msg_niov == 0);
+       LASSERT(msg->msg_iov == NULL);
+       LASSERT(msg->msg_kiov == NULL);
 
        msg->msg_niov = md->md_niov;
        if ((md->md_options & LNET_MD_KIOV) != 0)
@@ -629,7 +630,7 @@ lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target,
        if (len != 0)
                lnet_setpayloadbuffer(msg);
 
-       memset (&msg->msg_hdr, 0, sizeof (msg->msg_hdr));
+       memset(&msg->msg_hdr, 0, sizeof(msg->msg_hdr));
        msg->msg_hdr.type          = cpu_to_le32(type);
        msg->msg_hdr.dest_nid       = cpu_to_le64(target.nid);
        msg->msg_hdr.dest_pid       = cpu_to_le32(target.pid);
@@ -644,8 +645,8 @@ lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg)
        void   *priv = msg->msg_private;
        int     rc;
 
-       LASSERT (!in_interrupt ());
-       LASSERT (LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND ||
+       LASSERT(!in_interrupt());
+       LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND ||
                 (msg->msg_txcredit && msg->msg_peertxcredit));
 
        rc = (ni->ni_lnd->lnd_send)(ni, priv, msg);
@@ -698,12 +699,12 @@ lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp)
 
 /* NB: always called with lnet_net_lock held */
 static inline int
-lnet_peer_is_alive (lnet_peer_t *lp, cfs_time_t now)
+lnet_peer_is_alive(lnet_peer_t *lp, cfs_time_t now)
 {
        int     alive;
        cfs_time_t deadline;
 
-       LASSERT (lnet_peer_aliveness_enabled(lp));
+       LASSERT(lnet_peer_aliveness_enabled(lp));
 
        /* Trust lnet_notify() if it has more recent aliveness news, but
         * ignore the initial assumed death (see lnet_peers_start_down()).
@@ -731,7 +732,7 @@ lnet_peer_is_alive (lnet_peer_t *lp, cfs_time_t now)
 /* NB: returns 1 when alive, 0 when dead, negative when error;
  *     may drop the lnet_net_lock */
 int
-lnet_peer_alive_locked (lnet_peer_t *lp)
+lnet_peer_alive_locked(lnet_peer_t *lp)
 {
        cfs_time_t now = cfs_time_current();
 
@@ -809,7 +810,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send)
        }
 
        if (!msg->msg_peertxcredit) {
-               LASSERT ((lp->lp_txcredits < 0) ==
+               LASSERT((lp->lp_txcredits < 0) ==
                         !list_empty(&lp->lp_txq));
 
                msg->msg_peertxcredit = 1;
@@ -873,7 +874,7 @@ lnet_msg2bufpool(lnet_msg_t *msg)
 }
 
 int
-lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
+lnet_post_routed_recv_locked(lnet_msg_t *msg, int do_recv)
 {
        /* lnet_parse is going to lnet_net_unlock immediately after this, so it
         * sets do_recv FALSE and I don't do the unlock/send/lock bit.  I
@@ -882,18 +883,18 @@ lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
        lnet_rtrbufpool_t   *rbp;
        lnet_rtrbuf_t       *rb;
 
-       LASSERT (msg->msg_iov == NULL);
-       LASSERT (msg->msg_kiov == NULL);
-       LASSERT (msg->msg_niov == 0);
-       LASSERT (msg->msg_routing);
-       LASSERT (msg->msg_receiving);
-       LASSERT (!msg->msg_sending);
+       LASSERT(msg->msg_iov == NULL);
+       LASSERT(msg->msg_kiov == NULL);
+       LASSERT(msg->msg_niov == 0);
+       LASSERT(msg->msg_routing);
+       LASSERT(msg->msg_receiving);
+       LASSERT(!msg->msg_sending);
 
        /* non-lnet_parse callers only receive delayed messages */
        LASSERT(!do_recv || msg->msg_rx_delayed);
 
        if (!msg->msg_peerrtrcredit) {
-               LASSERT ((lp->lp_rtrcredits < 0) ==
+               LASSERT((lp->lp_rtrcredits < 0) ==
                         !list_empty(&lp->lp_rtrq));
 
                msg->msg_peerrtrcredit = 1;
@@ -913,7 +914,7 @@ lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
        rbp = lnet_msg2bufpool(msg);
 
        if (!msg->msg_rtrcredit) {
-               LASSERT ((rbp->rbp_credits < 0) ==
+               LASSERT((rbp->rbp_credits < 0) ==
                         !list_empty(&rbp->rbp_msgs));
 
                msg->msg_rtrcredit = 1;
@@ -930,7 +931,7 @@ lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
                }
        }
 
-       LASSERT (!list_empty(&rbp->rbp_bufs));
+       LASSERT(!list_empty(&rbp->rbp_bufs));
        rb = list_entry(rbp->rbp_bufs.next, lnet_rtrbuf_t, rb_list);
        list_del(&rb->rb_list);
 
@@ -985,7 +986,7 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg)
                        !list_empty(&txpeer->lp_txq));
 
                txpeer->lp_txqnob -= msg->msg_len + sizeof(lnet_hdr_t);
-               LASSERT (txpeer->lp_txqnob >= 0);
+               LASSERT(txpeer->lp_txqnob >= 0);
 
                txpeer->lp_txcredits++;
                if (txpeer->lp_txcredits <= 0) {
@@ -1020,11 +1021,11 @@ lnet_return_rx_credits_locked(lnet_msg_t *msg)
                /* NB If a msg ever blocks for a buffer in rbp_msgs, it stays
                 * there until it gets one allocated, or aborts the wait
                 * itself */
-               LASSERT (msg->msg_kiov != NULL);
+               LASSERT(msg->msg_kiov != NULL);
 
                rb = list_entry(msg->msg_kiov, lnet_rtrbuf_t, rb_kiov[0]);
                rbp = rb->rb_pool;
-               LASSERT (rbp == lnet_msg2bufpool(msg));
+               LASSERT(rbp == lnet_msg2bufpool(msg));
 
                msg->msg_kiov = NULL;
                msg->msg_rtrcredit = 0;
@@ -1172,10 +1173,10 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
         * but we might want to use pre-determined router for ACK/REPLY
         * in the future */
        /* NB: ni != NULL == interface pre-determined (ACK/REPLY) */
-       LASSERT (msg->msg_txpeer == NULL);
-       LASSERT (!msg->msg_sending);
-       LASSERT (!msg->msg_target_is_router);
-       LASSERT (!msg->msg_receiving);
+       LASSERT(msg->msg_txpeer == NULL);
+       LASSERT(!msg->msg_sending);
+       LASSERT(!msg->msg_target_is_router);
+       LASSERT(!msg->msg_receiving);
 
        msg->msg_sending = 1;
 
@@ -1200,7 +1201,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
                                      libcfs_nid2str(src_nid));
                        return -EINVAL;
                }
-               LASSERT (!msg->msg_routing);
+               LASSERT(!msg->msg_routing);
        }
 
        /* Is this for someone on a local network? */
@@ -1249,7 +1250,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
                        /* ENOMEM or shutting down */
                        return rc;
                }
-               LASSERT (lp->lp_ni == src_ni);
+               LASSERT(lp->lp_ni == src_ni);
        } else {
                /* sending to a remote network */
                lp = lnet_find_route_locked(src_ni, dst_nid, rtr_nid);
@@ -1290,7 +1291,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
                        src_ni = lp->lp_ni;
                        src_nid = src_ni->ni_nid;
                } else {
-                       LASSERT (src_ni == lp->lp_ni);
+                       LASSERT(src_ni == lp->lp_ni);
                        lnet_ni_decref_locked(src_ni, cpt);
                }
 
@@ -1311,9 +1312,9 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
 
        /* 'lp' is our best choice of peer */
 
-       LASSERT (!msg->msg_peertxcredit);
-       LASSERT (!msg->msg_txcredit);
-       LASSERT (msg->msg_txpeer == NULL);
+       LASSERT(!msg->msg_peertxcredit);
+       LASSERT(!msg->msg_txcredit);
+       LASSERT(msg->msg_txpeer == NULL);
 
        msg->msg_txpeer = lp;              /* msg takes my ref on lp */
 
@@ -1509,7 +1510,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
                return ENOENT;            /* +ve: OK but no match */
        }
 
-       LASSERT (md->md_offset == 0);
+       LASSERT(md->md_offset == 0);
 
        rlength = hdr->payload_length;
        mlength = MIN(rlength, (int)md->md_length);
@@ -1614,31 +1615,31 @@ lnet_parse_forward_locked(lnet_ni_t *ni, lnet_msg_t *msg)
 }
 
 char *
-lnet_msgtyp2str (int type)
+lnet_msgtyp2str(int type)
 {
        switch (type) {
        case LNET_MSG_ACK:
-               return ("ACK");
+               return "ACK";
        case LNET_MSG_PUT:
-               return ("PUT");
+               return "PUT";
        case LNET_MSG_GET:
-               return ("GET");
+               return "GET";
        case LNET_MSG_REPLY:
-               return ("REPLY");
+               return "REPLY";
        case LNET_MSG_HELLO:
-               return ("HELLO");
+               return "HELLO";
        default:
-               return ("<UNKNOWN>");
+               return "<UNKNOWN>";
        }
 }
 EXPORT_SYMBOL(lnet_msgtyp2str);
 
 void
-lnet_print_hdr(lnet_hdr_t * hdr)
+lnet_print_hdr(lnet_hdr_t *hdr)
 {
        lnet_process_id_t src = {0};
        lnet_process_id_t dst = {0};
-       char *type_str = lnet_msgtyp2str (hdr->type);
+       char *type_str = lnet_msgtyp2str(hdr->type);
 
        src.nid = hdr->src_nid;
        src.pid = hdr->src_pid;
@@ -1709,7 +1710,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        __u32     payload_length;
        __u32     type;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
        type = le32_to_cpu(hdr->type);
        src_nid = le64_to_cpu(hdr->src_nid);
@@ -1734,7 +1735,8 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
 
        case LNET_MSG_PUT:
        case LNET_MSG_REPLY:
-               if (payload_length > (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) {
+               if (payload_length >
+                  (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) {
                        CERROR("%s, src %s: bad %s payload %d "
                               "(%d max expected)\n",
                               libcfs_nid2str(from_nid),
@@ -1772,7 +1774,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        if (!for_me) {
                if (LNET_NIDNET(dest_nid) == LNET_NIDNET(ni->ni_nid)) {
                        /* should have gone direct */
-                       CERROR ("%s, src %s: Bad dest nid %s "
+                       CERROR("%s, src %s: Bad dest nid %s "
                                "(should have been sent direct)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1783,7 +1785,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                if (lnet_islocalnid(dest_nid)) {
                        /* dest is another local NI; sender should have used
                         * this node's NID on its own network */
-                       CERROR ("%s, src %s: Bad dest nid %s "
+                       CERROR("%s, src %s: Bad dest nid %s "
                                "(it's my nid but on a different network)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1792,7 +1794,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                }
 
                if (rdma_req && type == LNET_MSG_GET) {
-                       CERROR ("%s, src %s: Bad optimized GET for %s "
+                       CERROR("%s, src %s: Bad optimized GET for %s "
                                "(final destination must be me)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1801,7 +1803,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                }
 
                if (!the_lnet.ln_routing) {
-                       CERROR ("%s, src %s: Dropping message for %s "
+                       CERROR("%s, src %s: Dropping message for %s "
                                "(routing not enabled)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1813,9 +1815,8 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        /* Message looks OK; we're not going to return an error, so we MUST
         * call back lnd_recv() come what may... */
 
-       if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
-           fail_peer (src_nid, 0))          /* shall we now? */
-       {
+       if (!list_empty(&the_lnet.ln_test_peers) && /* normally we don't */
+           fail_peer(src_nid, 0)) {         /* shall we now? */
                CERROR("%s, src %s: Dropping %s to simulate failure\n",
                       libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
                       lnet_msgtyp2str(type));
@@ -1830,7 +1831,9 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                goto drop;
        }
 
-       /* msg zeroed in lnet_msg_alloc; i.e. flags all clear, pointers NULL etc */
+       /* msg zeroed in lnet_msg_alloc;
+        * i.e. flags all clear, pointers NULL etc
+        */
 
        msg->msg_type = type;
        msg->msg_private = private;
@@ -1906,7 +1909,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        if (rc == 0)
                return 0;
 
-       LASSERT (rc == ENOENT);
+       LASSERT(rc == ENOENT);
 
  free_drop:
        LASSERT(msg->msg_md == NULL);
@@ -2047,12 +2050,11 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
        int                     cpt;
        int                     rc;
 
-       LASSERT (the_lnet.ln_init);
-       LASSERT (the_lnet.ln_refcount > 0);
+       LASSERT(the_lnet.ln_init);
+       LASSERT(the_lnet.ln_refcount > 0);
 
-       if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
-           fail_peer (target.nid, 1))    /* shall we now? */
-       {
+       if (!list_empty(&the_lnet.ln_test_peers) && /* normally we don't */
+           fail_peer(target.nid, 1)) { /* shall we now? */
                CERROR("Dropping PUT to %s: simulated failure\n",
                       libcfs_id2str(target));
                return -EIO;
@@ -2113,9 +2115,9 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
 
        rc = lnet_send(self, msg, LNET_NID_ANY);
        if (rc != 0) {
-               CNETERR( "Error sending PUT to %s: %d\n",
+               CNETERR("Error sending PUT to %s: %d\n",
                       libcfs_id2str(target), rc);
-               lnet_finalize (NULL, msg, rc);
+               lnet_finalize(NULL, msg, rc);
        }
 
        /* completion will be signalled by an event */
@@ -2124,7 +2126,7 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
 EXPORT_SYMBOL(LNetPut);
 
 lnet_msg_t *
-lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *getmsg)
+lnet_create_reply_msg(lnet_ni_t *ni, lnet_msg_t *getmsg)
 {
        /* The LND can DMA direct to the GET md (i.e. no REPLY msg).  This
         * returns a msg for the LND to pass to lnet_finalize() when the sink
@@ -2144,16 +2146,16 @@ lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *getmsg)
        cpt = lnet_cpt_of_cookie(getmd->md_lh.lh_cookie);
        lnet_res_lock(cpt);
 
-       LASSERT (getmd->md_refcount > 0);
+       LASSERT(getmd->md_refcount > 0);
 
        if (msg == NULL) {
-               CERROR ("%s: Dropping REPLY from %s: can't allocate msg\n",
+               CERROR("%s: Dropping REPLY from %s: can't allocate msg\n",
                        libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id));
                goto drop;
        }
 
        if (getmd->md_threshold == 0) {
-               CERROR ("%s: Dropping REPLY from %s for inactive MD %p\n",
+               CERROR("%s: Dropping REPLY from %s for inactive MD %p\n",
                        libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id),
                        getmd);
                lnet_res_unlock(cpt);
@@ -2205,13 +2207,13 @@ lnet_set_reply_msg_len(lnet_ni_t *ni, lnet_msg_t *reply, unsigned int len)
 {
        /* Set the REPLY length, now the RDMA that elides the REPLY message has
         * completed and I know it. */
-       LASSERT (reply != NULL);
-       LASSERT (reply->msg_type == LNET_MSG_GET);
-       LASSERT (reply->msg_ev.type == LNET_EVENT_REPLY);
+       LASSERT(reply != NULL);
+       LASSERT(reply->msg_type == LNET_MSG_GET);
+       LASSERT(reply->msg_ev.type == LNET_EVENT_REPLY);
 
        /* NB I trusted my peer to RDMA.  If she tells me she's written beyond
         * the end of my buffer, I might as well be dead. */
-       LASSERT (len <= reply->msg_ev.mlength);
+       LASSERT(len <= reply->msg_ev.mlength);
 
        reply->msg_ev.mlength = len;
 }
@@ -2229,7 +2231,8 @@ EXPORT_SYMBOL(lnet_set_reply_msg_len);
  *
  * \param self,target,portal,match_bits,offset See the discussion in LNetPut().
  * \param mdh A handle for the MD that describes the memory into which the
- * requested data will be received. The MD must be "free floating" (See LNetMDBind()).
+ * requested data will be received. The MD must be "free floating"
+ * (See LNetMDBind()).
  *
  * \retval  0      Success, and only in this case events will be generated
  * and logged to EQ (if it exists) of the MD.
@@ -2247,12 +2250,11 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
        int                     cpt;
        int                     rc;
 
-       LASSERT (the_lnet.ln_init);
-       LASSERT (the_lnet.ln_refcount > 0);
+       LASSERT(the_lnet.ln_init);
+       LASSERT(the_lnet.ln_refcount > 0);
 
-       if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
-           fail_peer (target.nid, 1))    /* shall we now? */
-       {
+       if (!list_empty(&the_lnet.ln_test_peers) && /* normally we don't */
+           fail_peer(target.nid, 1)) {   /* shall we now? */
                CERROR("Dropping GET to %s: simulated failure\n",
                       libcfs_id2str(target));
                return -EIO;
@@ -2307,9 +2309,9 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
 
        rc = lnet_send(self, msg, LNET_NID_ANY);
        if (rc < 0) {
-               CNETERR( "Error sending GET to %s: %d\n",
+               CNETERR("Error sending GET to %s: %d\n",
                       libcfs_id2str(target), rc);
-               lnet_finalize (NULL, msg, rc);
+               lnet_finalize(NULL, msg, rc);
        }
 
        /* completion will be signalled by an event */
@@ -2348,12 +2350,12 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
         * keep order 0 free for 0@lo and order 1 free for a local NID
         * match */
 
-       LASSERT (the_lnet.ln_init);
-       LASSERT (the_lnet.ln_refcount > 0);
+       LASSERT(the_lnet.ln_init);
+       LASSERT(the_lnet.ln_refcount > 0);
 
        cpt = lnet_net_lock_current();
 
-       list_for_each (e, &the_lnet.ln_nis) {
+       list_for_each(e, &the_lnet.ln_nis) {
                ni = list_entry(e, lnet_ni_t, ni_list);
 
                if (ni->ni_nid == dstnid) {
@@ -2390,7 +2392,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
                        lnet_route_t *route;
                        lnet_route_t *shortest = NULL;
 
-                       LASSERT (!list_empty(&rnet->lrn_routes));
+                       LASSERT(!list_empty(&rnet->lrn_routes));
 
                        list_for_each_entry(route, &rnet->lrn_routes,
                                                lr_list) {
@@ -2399,7 +2401,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
                                        shortest = route;
                        }
 
-                       LASSERT (shortest != NULL);
+                       LASSERT(shortest != NULL);
                        hops = shortest->lr_hops;
                        if (srcnidp != NULL)
                                *srcnidp = shortest->lr_gateway->lp_ni->ni_nid;
index 670dae34107c5208f3b1c383abdd6ae0c2c58fbe..efc798e01934d795b3b422fd0275c96caf24ffa4 100644 (file)
 #include <linux/lnet/lib-lnet.h>
 
 int
-lolnd_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
+lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
 {
-       LASSERT (!lntmsg->msg_routing);
-       LASSERT (!lntmsg->msg_target_is_router);
+       LASSERT(!lntmsg->msg_routing);
+       LASSERT(!lntmsg->msg_target_is_router);
 
        return lnet_parse(ni, &lntmsg->msg_hdr, ni->ni_nid, lntmsg, 0);
 }
 
 int
-lolnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
+lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
            int delayed, unsigned int niov,
            struct iovec *iov, lnet_kiov_t *kiov,
            unsigned int offset, unsigned int mlen, unsigned int rlen)
@@ -89,20 +89,20 @@ static int lolnd_instanced;
 void
 lolnd_shutdown(lnet_ni_t *ni)
 {
-       CDEBUG (D_NET, "shutdown\n");
-       LASSERT (lolnd_instanced);
+       CDEBUG(D_NET, "shutdown\n");
+       LASSERT(lolnd_instanced);
 
        lolnd_instanced = 0;
 }
 
 int
-lolnd_startup (lnet_ni_t *ni)
+lolnd_startup(lnet_ni_t *ni)
 {
-       LASSERT (ni->ni_lnd == &the_lolnd);
-       LASSERT (!lolnd_instanced);
+       LASSERT(ni->ni_lnd == &the_lolnd);
+       LASSERT(!lolnd_instanced);
        lolnd_instanced = 1;
 
-       return (0);
+       return 0;
 }
 
 lnd_t the_lolnd = {
index afb81755cbad19390adddc59a546f4f6445cc401..6db8774ff7b7161f8ec71f90cf4224a08af34ccb 100644 (file)
 #define DEBUG_SUBSYSTEM S_LNET
 #include <linux/lnet/lib-lnet.h>
 
-static int config_on_load = 0;
+static int config_on_load;
 CFS_MODULE_PARM(config_on_load, "i", int, 0444,
                "configure network at module load");
 
 static struct mutex lnet_config_mutex;
 
 int
-lnet_configure (void *arg)
+lnet_configure(void *arg)
 {
        /* 'arg' only there so I can be passed to cfs_create_thread() */
        int    rc = 0;
@@ -64,7 +64,7 @@ lnet_configure (void *arg)
 }
 
 int
-lnet_unconfigure (void)
+lnet_unconfigure(void)
 {
        int   refcount;
 
@@ -124,7 +124,7 @@ init_lnet(void)
        }
 
        rc = libcfs_register_ioctl(&lnet_ioctl_handler);
-       LASSERT (rc == 0);
+       LASSERT(rc == 0);
 
        if (config_on_load) {
                /* Have to schedule a separate thread to avoid deadlocking
@@ -141,7 +141,7 @@ fini_lnet(void)
        int rc;
 
        rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
-       LASSERT (rc == 0);
+       LASSERT(rc == 0);
 
        LNetFini();
 }
index 931f6ca25dc72268a11043281d7714bff72b3d99..5e47de36c184526cf09d8293782d135842c77a44 100644 (file)
@@ -30,7 +30,7 @@
 /* This is really lnet_proc.c. You might need to update sanity test 215
  * if any file format is changed. */
 
-static ctl_table_header_t *lnet_table_header = NULL;
+static ctl_table_header_t *lnet_table_header;
 
 #define CTL_LNET        (0x100)
 enum {
@@ -158,7 +158,7 @@ int LL_PROC_PROTO(proc_lnet_routes)
        off = LNET_PROC_HOFF_GET(*ppos);
        ver = LNET_PROC_VER_GET(*ppos);
 
-       LASSERT (!write);
+       LASSERT(!write);
 
        if (*lenp == 0)
                return 0;
@@ -172,11 +172,11 @@ int LL_PROC_PROTO(proc_lnet_routes)
        if (*ppos == 0) {
                s += snprintf(s, tmpstr + tmpsiz - s, "Routing %s\n",
                              the_lnet.ln_routing ? "enabled" : "disabled");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
 
                s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4s %7s %s\n",
                              "net", "hops", "state", "router");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
 
                lnet_net_lock(0);
                ver = (unsigned int)the_lnet.ln_remote_nets_version;
@@ -281,7 +281,7 @@ int LL_PROC_PROTO(proc_lnet_routers)
        off = LNET_PROC_HOFF_GET(*ppos);
        ver = LNET_PROC_VER_GET(*ppos);
 
-       LASSERT (!write);
+       LASSERT(!write);
 
        if (*lenp == 0)
                return 0;
@@ -375,7 +375,7 @@ int LL_PROC_PROTO(proc_lnet_routers)
                                              pingsent,
                                              cfs_duration_sec(cfs_time_sub(deadline, now)),
                                              down_ni, libcfs_nid2str(nid));
-                       LASSERT (tmpstr + tmpsiz - s > 0);
+                       LASSERT(tmpstr + tmpsiz - s > 0);
                }
 
                lnet_net_unlock(0);
@@ -437,7 +437,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                              "%-24s %4s %5s %5s %5s %5s %5s %5s %5s %s\n",
                              "nid", "refs", "state", "last", "max",
                              "rtr", "min", "tx", "min", "queue");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
 
                hoff++;
        } else {
@@ -534,7 +534,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                                      libcfs_nid2str(nid), nrefs, aliveness,
                                      lastalive, maxcr, rtrcr, minrtrcr, txcr,
                                      mintxcr, txqnob);
-                       LASSERT (tmpstr + tmpsiz - s > 0);
+                       LASSERT(tmpstr + tmpsiz - s > 0);
 
                } else { /* peer is NULL */
                        lnet_net_unlock(cpt);
@@ -592,7 +592,7 @@ static int __proc_lnet_buffers(void *data, int write,
        s += snprintf(s, tmpstr + tmpsiz - s,
                      "%5s %5s %7s %7s\n",
                      "pages", "count", "credits", "min");
-       LASSERT (tmpstr + tmpsiz - s > 0);
+       LASSERT(tmpstr + tmpsiz - s > 0);
 
        if (the_lnet.ln_rtrpools == NULL)
                goto out; /* I'm not a router */
@@ -638,7 +638,7 @@ int LL_PROC_PROTO(proc_lnet_nis)
 
        DECLARE_LL_PROC_PPOS_DECL;
 
-       LASSERT (!write);
+       LASSERT(!write);
 
        if (*lenp == 0)
                return 0;
@@ -654,7 +654,7 @@ int LL_PROC_PROTO(proc_lnet_nis)
                              "%-24s %6s %5s %4s %4s %4s %5s %5s %5s\n",
                              "nid", "status", "alive", "refs", "peer",
                              "rtr", "max", "tx", "min");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
        } else {
                struct list_head        *n;
                lnet_ni_t        *ni   = NULL;
index ef5064e0055f26bae931f656cd603f5c0db4d2e9..b7613c828e763431c766607604e636f073036f68 100644 (file)
@@ -48,16 +48,17 @@ CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644,
                "# data errors to inject randomly, zero by default");
 
 static void
-brw_client_fini (sfw_test_instance_t *tsi)
+brw_client_fini(sfw_test_instance_t *tsi)
 {
        srpc_bulk_t     *bulk;
        sfw_test_unit_t *tsu;
 
-       LASSERT (tsi->tsi_is_client);
+       LASSERT(tsi->tsi_is_client);
 
-       list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) {
+       list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) {
                bulk = tsu->tsu_private;
-               if (bulk == NULL) continue;
+               if (bulk == NULL)
+                       continue;
 
                srpc_free_bulk(bulk);
                tsu->tsu_private = NULL;
@@ -65,7 +66,7 @@ brw_client_fini (sfw_test_instance_t *tsi)
 }
 
 int
-brw_client_init (sfw_test_instance_t *tsi)
+brw_client_init(sfw_test_instance_t *tsi)
 {
        sfw_session_t    *sn = tsi->tsi_batch->bat_session;
        int               flags;
@@ -130,28 +131,31 @@ brw_client_init (sfw_test_instance_t *tsi)
 #define BRW_MSIZE       sizeof(__u64)
 
 int
-brw_inject_one_error (void)
+brw_inject_one_error(void)
 {
        struct timeval tv;
 
-       if (brw_inject_errors <= 0) return 0;
+       if (brw_inject_errors <= 0)
+               return 0;
 
        do_gettimeofday(&tv);
 
-       if ((tv.tv_usec & 1) == 0) return 0;
+       if ((tv.tv_usec & 1) == 0)
+               return 0;
 
        return brw_inject_errors--;
 }
 
 void
-brw_fill_page (struct page *pg, int pattern, __u64 magic)
+brw_fill_page(struct page *pg, int pattern, __u64 magic)
 {
        char *addr = page_address(pg);
        int   i;
 
-       LASSERT (addr != NULL);
+       LASSERT(addr != NULL);
 
-       if (pattern == LST_BRW_CHECK_NONE) return;
+       if (pattern == LST_BRW_CHECK_NONE)
+               return;
 
        if (magic == BRW_MAGIC)
                magic += brw_inject_one_error();
@@ -169,29 +173,31 @@ brw_fill_page (struct page *pg, int pattern, __u64 magic)
                return;
        }
 
-       LBUG ();
+       LBUG();
        return;
 }
 
 int
-brw_check_page (struct page *pg, int pattern, __u64 magic)
+brw_check_page(struct page *pg, int pattern, __u64 magic)
 {
        char  *addr = page_address(pg);
        __u64  data = 0; /* make compiler happy */
        int    i;
 
-       LASSERT (addr != NULL);
+       LASSERT(addr != NULL);
 
        if (pattern == LST_BRW_CHECK_NONE)
                return 0;
 
        if (pattern == LST_BRW_CHECK_SIMPLE) {
                data = *((__u64 *) addr);
-               if (data != magic) goto bad_data;
+               if (data != magic)
+                       goto bad_data;
 
                addr += PAGE_CACHE_SIZE - BRW_MSIZE;
                data = *((__u64 *) addr);
-               if (data != magic) goto bad_data;
+               if (data != magic)
+                       goto bad_data;
 
                return 0;
        }
@@ -199,22 +205,23 @@ brw_check_page (struct page *pg, int pattern, __u64 magic)
        if (pattern == LST_BRW_CHECK_FULL) {
                for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++) {
                        data = *(((__u64 *) addr) + i);
-                       if (data != magic) goto bad_data;
+                       if (data != magic)
+                               goto bad_data;
                }
 
                return 0;
        }
 
-       LBUG ();
+       LBUG();
 
 bad_data:
-       CERROR ("Bad data in page %p: "LPX64", "LPX64" expected\n",
+       CERROR("Bad data in page %p: "LPX64", "LPX64" expected\n",
                pg, data, magic);
        return 1;
 }
 
 void
-brw_fill_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
+brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
 {
        int      i;
        struct page *pg;
@@ -226,7 +233,7 @@ brw_fill_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
 }
 
 int
-brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
+brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
 {
        int      i;
        struct page *pg;
@@ -234,7 +241,7 @@ brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
        for (i = 0; i < bk->bk_niov; i++) {
                pg = bk->bk_iovs[i].kiov_page;
                if (brw_check_page(pg, pattern, magic) != 0) {
-                       CERROR ("Bulk page %p (%d/%d) is corrupted!\n",
+                       CERROR("Bulk page %p (%d/%d) is corrupted!\n",
                                pg, i, bk->bk_niov);
                        return 1;
                }
@@ -244,7 +251,7 @@ brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
 }
 
 static int
-brw_client_prep_rpc (sfw_test_unit_t *tsu,
+brw_client_prep_rpc(sfw_test_unit_t *tsu,
                     lnet_process_id_t dest, srpc_client_rpc_t **rpcpp)
 {
        srpc_bulk_t      *bulk = tsu->tsu_private;
@@ -302,7 +309,7 @@ brw_client_prep_rpc (sfw_test_unit_t *tsu,
 }
 
 static void
-brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
+brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
 {
        __u64           magic = BRW_MAGIC;
        sfw_test_instance_t *tsi = tsu->tsu_instance;
@@ -311,10 +318,10 @@ brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
        srpc_brw_reply_t    *reply = &msg->msg_body.brw_reply;
        srpc_brw_reqst_t    *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
 
-       LASSERT (sn != NULL);
+       LASSERT(sn != NULL);
 
        if (rpc->crpc_status != 0) {
-               CERROR ("BRW RPC to %s failed with %d\n",
+               CERROR("BRW RPC to %s failed with %d\n",
                        libcfs_id2str(rpc->crpc_dest), rpc->crpc_status);
                if (!tsi->tsi_stopping) /* rpc could have been aborted */
                        atomic_inc(&sn->sn_brw_errors);
@@ -326,7 +333,7 @@ brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
                __swab32s(&reply->brw_status);
        }
 
-       CDEBUG (reply->brw_status ? D_WARNING : D_NET,
+       CDEBUG(reply->brw_status ? D_WARNING : D_NET,
                "BRW RPC to %s finished with brw_status: %d\n",
                libcfs_id2str(rpc->crpc_dest), reply->brw_status);
 
@@ -336,10 +343,11 @@ brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
                goto out;
        }
 
-       if (reqst->brw_rw == LST_BRW_WRITE) goto out;
+       if (reqst->brw_rw == LST_BRW_WRITE)
+               goto out;
 
        if (brw_check_bulk(&rpc->crpc_bulk, reqst->brw_flags, magic) != 0) {
-               CERROR ("Bulk data from %s is corrupted!\n",
+               CERROR("Bulk data from %s is corrupted!\n",
                        libcfs_id2str(rpc->crpc_dest));
                atomic_inc(&sn->sn_brw_errors);
                rpc->crpc_status = -EBADMSG;
@@ -350,18 +358,19 @@ out:
 }
 
 void
-brw_server_rpc_done (srpc_server_rpc_t *rpc)
+brw_server_rpc_done(srpc_server_rpc_t *rpc)
 {
        srpc_bulk_t *blk = rpc->srpc_bulk;
 
-       if (blk == NULL) return;
+       if (blk == NULL)
+               return;
 
        if (rpc->srpc_status != 0)
-               CERROR ("Bulk transfer %s %s has failed: %d\n",
+               CERROR("Bulk transfer %s %s has failed: %d\n",
                        blk->bk_sink ? "from" : "to",
                        libcfs_id2str(rpc->srpc_peer), rpc->srpc_status);
        else
-               CDEBUG (D_NET, "Transferred %d pages bulk data %s %s\n",
+               CDEBUG(D_NET, "Transferred %d pages bulk data %s %s\n",
                        blk->bk_niov, blk->bk_sink ? "from" : "to",
                        libcfs_id2str(rpc->srpc_peer));
 
@@ -369,21 +378,21 @@ brw_server_rpc_done (srpc_server_rpc_t *rpc)
 }
 
 int
-brw_bulk_ready (srpc_server_rpc_t *rpc, int status)
+brw_bulk_ready(srpc_server_rpc_t *rpc, int status)
 {
        __u64        magic = BRW_MAGIC;
        srpc_brw_reply_t *reply = &rpc->srpc_replymsg.msg_body.brw_reply;
        srpc_brw_reqst_t *reqst;
        srpc_msg_t       *reqstmsg;
 
-       LASSERT (rpc->srpc_bulk != NULL);
-       LASSERT (rpc->srpc_reqstbuf != NULL);
+       LASSERT(rpc->srpc_bulk != NULL);
+       LASSERT(rpc->srpc_reqstbuf != NULL);
 
        reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
        reqst = &reqstmsg->msg_body.brw_reqst;
 
        if (status != 0) {
-               CERROR ("BRW bulk %s failed for RPC from %s: %d\n",
+               CERROR("BRW bulk %s failed for RPC from %s: %d\n",
                        reqst->brw_rw == LST_BRW_READ ? "READ" : "WRITE",
                        libcfs_id2str(rpc->srpc_peer), status);
                return -EIO;
@@ -396,7 +405,7 @@ brw_bulk_ready (srpc_server_rpc_t *rpc, int status)
                __swab64s(&magic);
 
        if (brw_check_bulk(rpc->srpc_bulk, reqst->brw_flags, magic) != 0) {
-               CERROR ("Bulk data from %s is corrupted!\n",
+               CERROR("Bulk data from %s is corrupted!\n",
                        libcfs_id2str(rpc->srpc_peer));
                reply->brw_status = EBADMSG;
        }
@@ -415,10 +424,10 @@ brw_server_handle(struct srpc_server_rpc *rpc)
        int               npg;
        int            rc;
 
-       LASSERT (sv->sv_id == SRPC_SERVICE_BRW);
+       LASSERT(sv->sv_id == SRPC_SERVICE_BRW);
 
        if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) {
-               LASSERT (reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));
+               LASSERT(reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));
 
                __swab32s(&reqst->brw_rw);
                __swab32s(&reqst->brw_len);
@@ -426,7 +435,7 @@ brw_server_handle(struct srpc_server_rpc *rpc)
                __swab64s(&reqst->brw_rpyid);
                __swab64s(&reqst->brw_bulkid);
        }
-       LASSERT (reqstmsg->msg_type == (__u32)srpc_service2request(sv->sv_id));
+       LASSERT(reqstmsg->msg_type == (__u32)srpc_service2request(sv->sv_id));
 
        reply->brw_status = 0;
        rpc->srpc_done = brw_server_rpc_done;
index cbce662b987bdce0ce2f6ac4b84e7490a5f68f33..9a52f25b72e90931053c7bf642789797ca522325 100644 (file)
@@ -75,7 +75,7 @@ lstcon_rpc_done(srpc_client_rpc_t *rpc)
 
        if (crpc->crp_stamp == 0) {
                /* not aborted */
-               LASSERT (crpc->crp_status == 0);
+               LASSERT(crpc->crp_status == 0);
 
                crpc->crp_stamp  = cfs_time_current();
                crpc->crp_status = rpc->crpc_status;
@@ -153,7 +153,7 @@ lstcon_rpc_put(lstcon_rpc_t *crpc)
        srpc_bulk_t *bulk = &crpc->crp_rpc->crpc_bulk;
        int       i;
 
-       LASSERT (list_empty(&crpc->crp_link));
+       LASSERT(list_empty(&crpc->crp_link));
 
        for (i = 0; i < bulk->bk_niov; i++) {
                if (bulk->bk_iovs[i].kiov_page == NULL)
@@ -187,7 +187,7 @@ lstcon_rpc_post(lstcon_rpc_t *crpc)
 {
        lstcon_rpc_trans_t *trans = crpc->crp_trans;
 
-       LASSERT (trans != NULL);
+       LASSERT(trans != NULL);
 
        atomic_inc(&trans->tas_remaining);
        crpc->crp_posted = 1;
@@ -289,7 +289,7 @@ lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error)
        lstcon_rpc_t      *crpc;
        lstcon_node_t     *nd;
 
-       list_for_each_entry (crpc, &trans->tas_rpcs_list, crp_link) {
+       list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
                rpc = crpc->crp_rpc;
 
                spin_lock(&rpc->crpc_lock);
@@ -330,7 +330,7 @@ lstcon_rpc_trans_check(lstcon_rpc_trans_t *trans)
            !list_empty(&trans->tas_olink)) /* Not an end session RPC */
                return 1;
 
-       return (atomic_read(&trans->tas_remaining) == 0) ? 1: 0;
+       return (atomic_read(&trans->tas_remaining) == 0) ? 1 : 0;
 }
 
 int
@@ -349,8 +349,8 @@ lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout)
               lstcon_rpc_trans_name(trans->tas_opc));
 
        /* post all requests */
-       list_for_each_entry (crpc, &trans->tas_rpcs_list, crp_link) {
-               LASSERT (!crpc->crp_posted);
+       list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
+               LASSERT(!crpc->crp_posted);
 
                lstcon_rpc_post(crpc);
        }
@@ -390,8 +390,8 @@ lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp)
        srpc_client_rpc_t    *rpc = crpc->crp_rpc;
        srpc_generic_reply_t *rep;
 
-       LASSERT (nd != NULL && rpc != NULL);
-       LASSERT (crpc->crp_stamp != 0);
+       LASSERT(nd != NULL && rpc != NULL);
+       LASSERT(crpc->crp_stamp != 0);
 
        if (crpc->crp_status != 0) {
                *msgpp = NULL;
@@ -427,14 +427,14 @@ lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
        srpc_msg_t      *rep;
        int             error;
 
-       LASSERT (stat != NULL);
+       LASSERT(stat != NULL);
 
        memset(stat, 0, sizeof(*stat));
 
        list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
                lstcon_rpc_stat_total(stat, 1);
 
-               LASSERT (crpc->crp_stamp != 0);
+               LASSERT(crpc->crp_stamp != 0);
 
                error = lstcon_rpc_get_reply(crpc, &rep);
                if (error != 0) {
@@ -455,8 +455,7 @@ lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
                      lstcon_session_feats_check(trans->tas_features);
        }
 
-       CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, "
-                     "RPC error(%d), Framework error(%d)\n",
+       CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, RPC error(%d), Framework error(%d)\n",
               lstcon_rpc_trans_name(trans->tas_opc),
               lstcon_rpc_stat_success(stat, 0),
               lstcon_rpc_stat_failure(stat, 0),
@@ -482,7 +481,7 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
        struct timeval  tv;
        int                error;
 
-       LASSERT (head_up != NULL);
+       LASSERT(head_up != NULL);
 
        next = head_up;
 
@@ -498,7 +497,7 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
 
                ent = list_entry(next, lstcon_rpc_ent_t, rpe_link);
 
-               LASSERT (crpc->crp_stamp != 0);
+               LASSERT(crpc->crp_stamp != 0);
 
                error = lstcon_rpc_get_reply(crpc, &msg);
 
@@ -532,7 +531,9 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
                if (readent == NULL)
                        continue;
 
-               if ((error = readent(trans->tas_opc, msg, ent)) != 0)
+               error = readent(trans->tas_opc, msg, ent);
+
+               if (error != 0)
                        return error;
        }
 
@@ -568,19 +569,19 @@ lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans)
                 * user wait for them, just abandon them, they will be recycled
                 * in callback */
 
-               LASSERT (crpc->crp_status != 0);
+               LASSERT(crpc->crp_status != 0);
 
                crpc->crp_node  = NULL;
                crpc->crp_trans = NULL;
                list_del_init(&crpc->crp_link);
-               count ++;
+               count++;
 
                spin_unlock(&rpc->crpc_lock);
 
                atomic_dec(&trans->tas_remaining);
        }
 
-       LASSERT (atomic_read(&trans->tas_remaining) == 0);
+       LASSERT(atomic_read(&trans->tas_remaining) == 0);
 
        list_del(&trans->tas_link);
        if (!list_empty(&trans->tas_olink))
@@ -669,14 +670,14 @@ lstcon_batrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
        brq->bar_bid     = tsb->tsb_id;
        brq->bar_testidx = tsb->tsb_index;
        brq->bar_opc     = transop == LST_TRANS_TSBRUN ? SRPC_BATCH_OPC_RUN :
-                          (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP:
+                          (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP :
                            SRPC_BATCH_OPC_QUERY);
 
        if (transop != LST_TRANS_TSBRUN &&
            transop != LST_TRANS_TSBSTOP)
                return 0;
 
-       LASSERT (tsb->tsb_index == 0);
+       LASSERT(tsb->tsb_index == 0);
 
        batch = (lstcon_batch_t *)tsb;
        brq->bar_arg = batch->bat_arg;
@@ -710,7 +711,7 @@ lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
 
        i = idx / SFW_ID_PER_PAGE;
 
-       LASSERT (i < nkiov);
+       LASSERT(i < nkiov);
 
        pid = (lnet_process_id_packed_t *)page_address(kiov[i].kiov_page);
 
@@ -728,9 +729,9 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
        int                    end;
        int                    i = 0;
 
-       LASSERT (dist >= 1);
-       LASSERT (span >= 1);
-       LASSERT (grp->grp_nnode >= 1);
+       LASSERT(dist >= 1);
+       LASSERT(span >= 1);
+       LASSERT(grp->grp_nnode >= 1);
 
        if (span > grp->grp_nnode)
                return -EINVAL;
@@ -741,11 +742,11 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
        list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
                nd = ndl->ndl_node;
                if (i < start) {
-                       i ++;
+                       i++;
                        continue;
                }
 
-               if (i > (end >= start ? end: grp->grp_nnode))
+               if (i > (end >= start ? end : grp->grp_nnode))
                        break;
 
                pid = lstcon_next_id((i - start), nkiov, kiov);
@@ -866,7 +867,7 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
 
                bulk->bk_sink = 0;
 
-               LASSERT (transop == LST_TRANS_TSBCLIADD);
+               LASSERT(transop == LST_TRANS_TSBCLIADD);
 
                rc = lstcon_dstnodes_prep(test->tes_dst_grp,
                                          test->tes_cliidx++,
@@ -942,8 +943,7 @@ lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans,
        }
 
        if (reply->msg_ses_feats != trans->tas_features) {
-               CNETERR("Framework features %x from %s is different with "
-                       "features on this transaction: %x\n",
+               CNETERR("Framework features %x from %s is different with features on this transaction: %x\n",
                         reply->msg_ses_feats, libcfs_nid2str(nd->nd_id.nid),
                         trans->tas_features);
                status = mksn_rep->mksn_status = EPROTO;
@@ -1107,8 +1107,8 @@ lstcon_rpc_trans_ndlist(struct list_head *ndlist,
                        continue;
 
                if (rc < 0) {
-                       CDEBUG(D_NET, "Condition error while creating RPC "
-                                     " for transaction %d: %d\n", transop, rc);
+                       CDEBUG(D_NET, "Condition error while creating RPC for transaction %d: %d\n",
+                                       transop, rc);
                        break;
                }
 
@@ -1193,7 +1193,7 @@ lstcon_rpc_pinger(void *arg)
 
        trans = console_session.ses_ping;
 
-       LASSERT (trans != NULL);
+       LASSERT(trans != NULL);
 
        list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link) {
                nd = ndl->ndl_node;
@@ -1219,8 +1219,8 @@ lstcon_rpc_pinger(void *arg)
                crpc = &nd->nd_ping;
 
                if (crpc->crp_rpc != NULL) {
-                       LASSERT (crpc->crp_trans == trans);
-                       LASSERT (!list_empty(&crpc->crp_link));
+                       LASSERT(crpc->crp_trans == trans);
+                       LASSERT(!list_empty(&crpc->crp_link));
 
                        spin_lock(&crpc->crp_rpc->crpc_lock);
 
@@ -1264,7 +1264,7 @@ lstcon_rpc_pinger(void *arg)
                lstcon_rpc_trans_addreq(trans, crpc);
                lstcon_rpc_post(crpc);
 
-               count ++;
+               count++;
        }
 
        if (console_session.ses_expired) {
@@ -1286,8 +1286,8 @@ lstcon_rpc_pinger_start(void)
        stt_timer_t    *ptimer;
        int          rc;
 
-       LASSERT (list_empty(&console_session.ses_rpc_freelist));
-       LASSERT (atomic_read(&console_session.ses_rpc_counter) == 0);
+       LASSERT(list_empty(&console_session.ses_rpc_freelist));
+       LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
 
        rc = lstcon_rpc_trans_prep(NULL, LST_TRANS_SESPING,
                                   &console_session.ses_ping);
@@ -1307,7 +1307,7 @@ lstcon_rpc_pinger_start(void)
 void
 lstcon_rpc_pinger_stop(void)
 {
-       LASSERT (console_session.ses_shutdown);
+       LASSERT(console_session.ses_shutdown);
 
        stt_del_timer(&console_session.ses_ping_timer);
 
@@ -1330,7 +1330,7 @@ lstcon_rpc_cleanup_wait(void)
 
        /* Called with hold of global mutex */
 
-       LASSERT (console_session.ses_shutdown);
+       LASSERT(console_session.ses_shutdown);
 
        while (!list_empty(&console_session.ses_trans_list)) {
                list_for_each(pacer, &console_session.ses_trans_list) {
@@ -1345,8 +1345,7 @@ lstcon_rpc_cleanup_wait(void)
 
                mutex_unlock(&console_session.ses_mutex);
 
-               CWARN("Session is shutting down, "
-                     "waiting for termination of transactions\n");
+               CWARN("Session is shutting down, waiting for termination of transactions\n");
                cfs_pause(cfs_time_seconds(1));
 
                mutex_lock(&console_session.ses_mutex);
@@ -1356,8 +1355,7 @@ lstcon_rpc_cleanup_wait(void)
 
        lst_wait_until((atomic_read(&console_session.ses_rpc_counter) == 0),
                       console_session.ses_rpc_lock,
-                      "Network is not accessible or target is down, "
-                      "waiting for %d console RPCs to being recycled\n",
+                      "Network is not accessible or target is down, waiting for %d console RPCs to being recycled\n",
                       atomic_read(&console_session.ses_rpc_counter));
 
        list_add(&zlist, &console_session.ses_rpc_freelist);
@@ -1392,6 +1390,6 @@ lstcon_rpc_module_init(void)
 void
 lstcon_rpc_module_fini(void)
 {
-       LASSERT (list_empty(&console_session.ses_rpc_freelist));
-       LASSERT (atomic_read(&console_session.ses_rpc_counter) == 0);
+       LASSERT(list_empty(&console_session.ses_rpc_freelist));
+       LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
 }
index 09e4700af6405b5429dd2aa5c41f5485b29cd8f5..f1152e4fbcc41972fd115517348344d2122b9aa2 100644 (file)
@@ -797,7 +797,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p,
                return rc;
        }
 
-       if (dents_up != 0) {
+       if (dents_up) {
                /* verbose query */
                rc = lstcon_nodes_getent(&grp->grp_ndl_list,
                                         index_p, count_p, dents_up);
index 3bf4afb42ffe3c1bc03ea67bedbef87467b015d1..82fd363679cb94d9e5a2a0e1d28e8cdce8c048b3 100644 (file)
@@ -74,14 +74,14 @@ stt_add_timer(stt_timer_t *timer)
 
        spin_lock(&stt_data.stt_lock);
 
-       LASSERT (stt_data.stt_nthreads > 0);
-       LASSERT (!stt_data.stt_shuttingdown);
-       LASSERT (timer->stt_func != NULL);
-       LASSERT (list_empty(&timer->stt_list));
-       LASSERT (cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
+       LASSERT(stt_data.stt_nthreads > 0);
+       LASSERT(!stt_data.stt_shuttingdown);
+       LASSERT(timer->stt_func != NULL);
+       LASSERT(list_empty(&timer->stt_list));
+       LASSERT(cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
 
        /* a simple insertion sort */
-       list_for_each_prev (pos, STTIMER_SLOT(timer->stt_expires)) {
+       list_for_each_prev(pos, STTIMER_SLOT(timer->stt_expires)) {
                stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list);
 
                if (cfs_time_aftereq(timer->stt_expires, old->stt_expires))
@@ -102,14 +102,14 @@ stt_add_timer(stt_timer_t *timer)
  * another CPU.
  */
 int
-stt_del_timer (stt_timer_t *timer)
+stt_del_timer(stt_timer_t *timer)
 {
        int ret = 0;
 
        spin_lock(&stt_data.stt_lock);
 
-       LASSERT (stt_data.stt_nthreads > 0);
-       LASSERT (!stt_data.stt_shuttingdown);
+       LASSERT(stt_data.stt_nthreads > 0);
+       LASSERT(!stt_data.stt_shuttingdown);
 
        if (!list_empty(&timer->stt_list)) {
                ret = 1;
@@ -122,7 +122,7 @@ stt_del_timer (stt_timer_t *timer)
 
 /* called with stt_data.stt_lock held */
 int
-stt_expire_list (struct list_head *slot, cfs_time_t now)
+stt_expire_list(struct list_head *slot, cfs_time_t now)
 {
        int       expired = 0;
        stt_timer_t *timer;
@@ -146,7 +146,7 @@ stt_expire_list (struct list_head *slot, cfs_time_t now)
 }
 
 int
-stt_check_timers (cfs_time_t *last)
+stt_check_timers(cfs_time_t *last)
 {
        int     expired = 0;
        cfs_time_t now;
@@ -169,7 +169,7 @@ stt_check_timers (cfs_time_t *last)
 
 
 int
-stt_timer_main (void *arg)
+stt_timer_main(void *arg)
 {
        int rc = 0;
        UNUSED(arg);
@@ -193,7 +193,7 @@ stt_timer_main (void *arg)
 }
 
 int
-stt_start_timer_thread (void)
+stt_start_timer_thread(void)
 {
        struct task_struct *task;
 
@@ -211,7 +211,7 @@ stt_start_timer_thread (void)
 
 
 int
-stt_startup (void)
+stt_startup(void)
 {
        int rc = 0;
        int i;
@@ -227,20 +227,20 @@ stt_startup (void)
        init_waitqueue_head(&stt_data.stt_waitq);
        rc = stt_start_timer_thread();
        if (rc != 0)
-               CERROR ("Can't spawn timer thread: %d\n", rc);
+               CERROR("Can't spawn timer thread: %d\n", rc);
 
        return rc;
 }
 
 void
-stt_shutdown (void)
+stt_shutdown(void)
 {
        int i;
 
        spin_lock(&stt_data.stt_lock);
 
        for (i = 0; i < STTIMER_NSLOTS; i++)
-               LASSERT (list_empty(&stt_data.stt_hash[i]));
+               LASSERT(list_empty(&stt_data.stt_hash[i]));
 
        stt_data.stt_shuttingdown = 1;
 
index 2156a44d07409c0501cba726ccb33ee99d1d9c92..93d59b6a60daa6cb1916281016421ce0c84fbf4a 100644 (file)
@@ -16,7 +16,7 @@ config LUSTRE_FS
          this file system support as a module, choose M here: the module will
          be called lustre.
 
-         To mount Lustre file systems , you also need to install the user space
+         To mount Lustre file systems, you also need to install the user space
          mount.lustre and other user space commands which can be found in the
          lustre-client package, available from
          http://downloads.whamcloud.com/public/lustre/
index 66007b57018bd67a99ea38b1bbdc1c9749aea47a..79fc2fe131a2d2f7da4e057b3588564ba13ceaa5 100644 (file)
@@ -548,9 +548,7 @@ static int __init fid_mod_init(void)
        seq_type_proc_dir = lprocfs_register(LUSTRE_SEQ_NAME,
                                             proc_lustre_root,
                                             NULL, NULL);
-       if (IS_ERR(seq_type_proc_dir))
-               return PTR_ERR(seq_type_proc_dir);
-       return 0;
+       return PTR_ERR_OR_ZERO(seq_type_proc_dir);
 }
 
 static void __exit fid_mod_exit(void)
index 25099cbe37eb7bf9a7b95911322cde1400407b5c..45315101848cba68799853291361930a6bc0be44 100644 (file)
@@ -267,7 +267,7 @@ void fld_cache_punch_hole(struct fld_cache *cache,
        const seqno_t new_end  = range->lsr_end;
        struct fld_cache_entry *fldt;
 
-       OBD_ALLOC_GFP(fldt, sizeof *fldt, GFP_ATOMIC);
+       OBD_ALLOC_GFP(fldt, sizeof(*fldt), GFP_ATOMIC);
        if (!fldt) {
                OBD_FREE_PTR(f_new);
                /* overlap is not allowed, so dont mess up list. */
index 078e98bda684195bb36b6533f63496e3bd3a80ed..e47fd50b2a2ed53c1fa87226eb170e3a2d92c686 100644 (file)
@@ -59,8 +59,6 @@
 #include <lustre_mdc.h>
 #include "fld_internal.h"
 
-struct lu_context_key fld_thread_key;
-
 /* TODO: these 3 functions are copies of flow-control code from mdc_lib.c
  * It should be common thing. The same about mdc RPC lock */
 static int fld_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw)
@@ -509,14 +507,11 @@ static int __init fld_mod_init(void)
        if (IS_ERR(fld_type_proc_dir))
                return PTR_ERR(fld_type_proc_dir);
 
-       LU_CONTEXT_KEY_INIT(&fld_thread_key);
-       lu_context_key_register(&fld_thread_key);
        return 0;
 }
 
 static void __exit fld_mod_exit(void)
 {
-       lu_context_key_degister(&fld_thread_key);
        if (fld_type_proc_dir != NULL && !IS_ERR(fld_type_proc_dir)) {
                lprocfs_remove(&fld_type_proc_dir);
                fld_type_proc_dir = NULL;
index edb40afe66f122be83e83e4b871064a96dc8e30a..c485206fc6c2207f1933a1cc4b19598c35a281bf 100644 (file)
@@ -3096,13 +3096,13 @@ struct cl_io *cl_io_top(struct cl_io *io);
 void cl_io_print(const struct lu_env *env, void *cookie,
                 lu_printer_t printer, const struct cl_io *io);
 
-#define CL_IO_SLICE_CLEAN(foo_io, base)                                 \
-do {                                                               \
-       typeof(foo_io) __foo_io = (foo_io);                          \
+#define CL_IO_SLICE_CLEAN(foo_io, base)                                        \
+do {                                                                   \
+       typeof(foo_io) __foo_io = (foo_io);                             \
                                                                        \
-       CLASSERT(offsetof(typeof(*__foo_io), base) == 0);              \
-       memset(&__foo_io->base + 1, 0,                            \
-              (sizeof *__foo_io) - sizeof __foo_io->base);          \
+       CLASSERT(offsetof(typeof(*__foo_io), base) == 0);               \
+       memset(&__foo_io->base + 1, 0,                                  \
+              sizeof(*__foo_io) - sizeof(__foo_io->base));             \
 } while (0)
 
 /** @} cl_io */
index 9d4011f2908b91752e73c05143dd2bc718118734..27316f7b7a70013ccf765d76686db595e77bf4bd 100644 (file)
@@ -388,8 +388,8 @@ __u16 ll_dirent_type_get(struct lu_dirent *ent);
 __u64 cl_fid_build_ino(const struct lu_fid *fid, int api32);
 __u32 cl_fid_build_gen(const struct lu_fid *fid);
 
-# define CLOBINVRNT(env, clob, expr)                               \
-       ((void)sizeof(env), (void)sizeof(clob), (void)sizeof !!(expr))
+# define CLOBINVRNT(env, clob, expr)                                   \
+       ((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr)))
 
 int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp);
 int cl_ocd_update(struct obd_device *host,
index 9243dfab43d393f360a0f78c7dd7b8677455676f..359c6c1ba68d013589b92765c3bb40e48044b07b 100644 (file)
@@ -232,9 +232,6 @@ static inline int ll_namei_to_lookup_intent_flag(int flag)
        return flag;
 }
 
-# define ll_mrf_ret void
-# define LL_MRF_RETURN(rc)
-
 #include <linux/fs.h>
 
 # define ll_umode_t    umode_t
index fa31be886ef8c052327a5455a921fe193ef9a761..d5b8225ef1a73d2d5d03a8a8d71ca3fe3a1871e1 100644 (file)
@@ -622,7 +622,7 @@ struct lu_site {
        /**
         * objects hash table
         */
-       cfs_hash_t             *ls_obj_hash;
+       struct cfs_hash        *ls_obj_hash;
        /**
         * index of bucket on hash table while purging
         */
@@ -659,7 +659,7 @@ struct lu_site {
 static inline struct lu_site_bkt_data *
 lu_site_bkt_from_fid(struct lu_site *site, struct lu_fid *fid)
 {
-       cfs_hash_bd_t bd;
+       struct cfs_hash_bd bd;
 
        cfs_hash_bd_get(site->ls_obj_hash, fid, &bd);
        return cfs_hash_bd_extra_get(site->ls_obj_hash, &bd);
index 984235ccd3a5fb92a687e3ca538f4a339afc53bd..5ca18d01601429e5452bee9b1a839d7ce1df4bd3 100644 (file)
@@ -831,9 +831,10 @@ static inline void lu_igif_build(struct lu_fid *fid, __u32 ino, __u32 gen)
 static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = cpu_to_le64(fid_seq(src));
        dst->f_oid = cpu_to_le32(fid_oid(src));
        dst->f_ver = cpu_to_le32(fid_ver(src));
@@ -842,9 +843,10 @@ static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
 static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = le64_to_cpu(fid_seq(src));
        dst->f_oid = le32_to_cpu(fid_oid(src));
        dst->f_ver = le32_to_cpu(fid_ver(src));
@@ -853,9 +855,10 @@ static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
 static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = cpu_to_be64(fid_seq(src));
        dst->f_oid = cpu_to_be32(fid_oid(src));
        dst->f_ver = cpu_to_be32(fid_ver(src));
@@ -864,9 +867,10 @@ static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
 static inline void fid_be_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = be64_to_cpu(fid_seq(src));
        dst->f_oid = be32_to_cpu(fid_oid(src));
        dst->f_ver = be32_to_cpu(fid_ver(src));
@@ -891,9 +895,11 @@ extern void lustre_swab_lu_seq_range(struct lu_seq_range *range);
 static inline int lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
 {
        /* Check that there is no alignment padding. */
-       CLASSERT(sizeof *f0 ==
-                sizeof f0->f_seq + sizeof f0->f_oid + sizeof f0->f_ver);
-       return memcmp(f0, f1, sizeof *f0) == 0;
+       CLASSERT(sizeof(*f0) ==
+                sizeof(f0->f_seq) +
+                sizeof(f0->f_oid) +
+                sizeof(f0->f_ver));
+       return memcmp(f0, f1, sizeof(*f0)) == 0;
 }
 
 #define __diff_normalize(val0, val1)                       \
@@ -1638,8 +1644,10 @@ static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
 
 /* extern void lustre_swab_lov_mds_md(struct lov_mds_md *llm); */
 
-#define MAX_MD_SIZE (sizeof(struct lov_mds_md) + 4 * sizeof(struct lov_ost_data))
-#define MIN_MD_SIZE (sizeof(struct lov_mds_md) + 1 * sizeof(struct lov_ost_data))
+#define MAX_MD_SIZE                                                    \
+       (sizeof(struct lov_mds_md) + 4 * sizeof(struct lov_ost_data))
+#define MIN_MD_SIZE                                                    \
+       (sizeof(struct lov_mds_md) + 1 * sizeof(struct lov_ost_data))
 
 #define XATTR_NAME_ACL_ACCESS   "system.posix_acl_access"
 #define XATTR_NAME_ACL_DEFAULT  "system.posix_acl_default"
index 7020d9cd9eb2bb5794e59df0c13169bb4790e58c..bc2b82ffae92a694f728e110f710afe83b21f83c 100644 (file)
@@ -375,7 +375,7 @@ struct ldlm_namespace {
        ldlm_side_t             ns_client;
 
        /** Resource hash table for namespace. */
-       cfs_hash_t              *ns_rs_hash;
+       struct cfs_hash         *ns_rs_hash;
 
        /** serialize */
        spinlock_t              ns_lock;
@@ -1083,7 +1083,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
  * Rate-limited version of lock printing function.
  */
 #define LDLM_DEBUG_LIMIT(mask, lock, fmt, a...) do {                    \
-       static cfs_debug_limit_state_t _ldlm_cdls;                         \
+       static struct cfs_debug_limit_state _ldlm_cdls;                    \
        LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_ldlm_cdls);       \
        ldlm_lock_debug(&msgdata, mask, &_ldlm_cdls, lock, "### " fmt , ##a);\
 } while (0)
index d61c020a464300704eaf770d52da08958ac9cca3..2feb38b51af2d8d69da7f13f9aa966434e387726 100644 (file)
@@ -197,12 +197,12 @@ struct obd_export {
        /** Connection count value from last succesful reconnect rpc */
        __u32                exp_conn_cnt;
        /** Hash list of all ldlm locks granted on this export */
-       cfs_hash_t             *exp_lock_hash;
+       struct cfs_hash        *exp_lock_hash;
        /**
         * Hash list for Posix lock deadlock detection, added with
         * ldlm_lock::l_exp_flock_hash.
         */
-       cfs_hash_t             *exp_flock_hash;
+       struct cfs_hash        *exp_flock_hash;
        struct list_head                exp_outstanding_replies;
        struct list_head                exp_uncommitted_replies;
        spinlock_t                exp_uncommitted_replies_lock;
index d9d5814e318d9e8105195d7bbc17db5e043c6815..ff119532dafb352b7a6f7f57bbba59b5791a14ca 100644 (file)
@@ -590,7 +590,7 @@ fid_build_pdo_res_name(const struct lu_fid *fid, unsigned int hash,
 static inline void ostid_build_res_name(struct ost_id *oi,
                                        struct ldlm_res_id *name)
 {
-       memset(name, 0, sizeof *name);
+       memset(name, 0, sizeof(*name));
        if (fid_seq_is_mdt0(ostid_seq(oi))) {
                name->name[LUSTRE_RES_ID_SEQ_OFF] = ostid_id(oi);
                name->name[LUSTRE_RES_ID_VER_OID_OFF] = ostid_seq(oi);
index 25f8bfaccef350ab0f08317f9fcd65f0bbf5fd02..beccb5e4065ffbd795ce27bcfb1e9b7c34726e3c 100644 (file)
@@ -139,7 +139,11 @@ static inline unsigned long hash_x_index(__u64 hash, int hash64)
 {
        if (BITS_PER_LONG == 32 && hash64)
                hash >>= 32;
-       return ~0UL - hash;
+       /* save hash 0 as index 0 because otherwise we'll save it at
+        * page index end (~0UL) and it causes truncate_inode_pages_range()
+        * to loop forever.
+        */
+       return ~0UL - (hash + !hash);
 }
 
 /** @} lite */
index e947002fae04048258c0c99ccf76e501a0a36eb3..72edf01b58a21e3b0c36b99f8399d1ba1f7ca26d 100644 (file)
@@ -1427,7 +1427,7 @@ struct nrs_fifo_req {
 struct nrs_crrn_net {
        struct ptlrpc_nrs_resource      cn_res;
        cfs_binheap_t                  *cn_binheap;
-       cfs_hash_t                     *cn_cli_hash;
+       struct cfs_hash                *cn_cli_hash;
        /**
         * Used when a new scheduling round commences, in order to synchronize
         * all clients with the new round number.
@@ -1568,7 +1568,7 @@ struct nrs_orr_key {
 struct nrs_orr_data {
        struct ptlrpc_nrs_resource      od_res;
        cfs_binheap_t                  *od_binheap;
-       cfs_hash_t                     *od_obj_hash;
+       struct cfs_hash                *od_obj_hash;
        struct kmem_cache                      *od_cache;
        /**
         * Used when a new scheduling round commences, in order to synchronize
@@ -2206,7 +2206,7 @@ do {                                                                        \
 #define DEBUG_REQ(level, req, fmt, args...)                               \
 do {                                                                     \
        if ((level) & (D_ERROR | D_WARNING)) {                          \
-               static cfs_debug_limit_state_t cdls;                      \
+               static struct cfs_debug_limit_state cdls;                         \
                LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, level, &cdls);          \
                debug_req(&msgdata, level, &cdls, req, "@@@ "fmt" ", ## args);\
        } else {                                                              \
index a6122559d55d20fc01680414e7fb637f54fc16bb..d0aea15b7c398e1e9a20475716b638c4723e2502 100644 (file)
@@ -177,7 +177,7 @@ static inline int lov_stripe_md_cmp(struct lov_stripe_md *m1,
         * ->lsm_wire contains padding, but it should be zeroed out during
         * allocation.
         */
-       return memcmp(&m1->lsm_wire, &m2->lsm_wire, sizeof m1->lsm_wire);
+       return memcmp(&m1->lsm_wire, &m2->lsm_wire, sizeof(m1->lsm_wire));
 }
 
 static inline int lov_lum_lsm_cmp(struct lov_user_md *lum,
@@ -429,7 +429,7 @@ struct client_obd {
        /* ptlrpc work for writeback in ptlrpcd context */
        void                *cl_writeback_work;
        /* hash tables for osc_quota_info */
-       cfs_hash_t            *cl_quota_hash[MAXQUOTAS];
+       struct cfs_hash       *cl_quota_hash[MAXQUOTAS];
 };
 #define obd2cli_tgt(obd) ((char *)(obd)->u.cli.cl_target_uuid.uuid)
 
@@ -556,7 +556,7 @@ struct lov_obd {
        __u32              lov_tgt_size;   /* size of tgts array */
        int                  lov_connects;
        int                  lov_pool_count;
-       cfs_hash_t           *lov_pools_hash_body; /* used for key access */
+       struct cfs_hash      *lov_pools_hash_body; /* used for key access */
        struct list_head              lov_pool_list; /* used for sequential access */
        struct proc_dir_entry   *lov_pool_proc_entry;
        enum lustre_sec_part    lov_sp_me;
@@ -855,11 +855,11 @@ struct obd_device {
         * protection of other bits using _bh lock */
        unsigned long obd_recovery_expired:1;
        /* uuid-export hash body */
-       cfs_hash_t           *obd_uuid_hash;
+       struct cfs_hash      *obd_uuid_hash;
        /* nid-export hash body */
-       cfs_hash_t           *obd_nid_hash;
+       struct cfs_hash      *obd_nid_hash;
        /* nid stats body */
-       cfs_hash_t           *obd_nid_stats_hash;
+       struct cfs_hash      *obd_nid_stats_hash;
        struct list_head              obd_nid_stats;
        atomic_t            obd_refcount;
        wait_queue_head_t            obd_refcount_waitq;
index 03e6133ef50fc74fb969dc2a6203196675163c05..9697e7faff2fddbb62e484121e7186adcab4077c 100644 (file)
@@ -633,8 +633,8 @@ do {                                                                              \
 
 #define OBD_ALLOC(ptr, size) OBD_ALLOC_GFP(ptr, size, __GFP_IO)
 #define OBD_ALLOC_WAIT(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_IOFS)
-#define OBD_ALLOC_PTR(ptr) OBD_ALLOC(ptr, sizeof *(ptr))
-#define OBD_ALLOC_PTR_WAIT(ptr) OBD_ALLOC_WAIT(ptr, sizeof *(ptr))
+#define OBD_ALLOC_PTR(ptr) OBD_ALLOC(ptr, sizeof(*(ptr)))
+#define OBD_ALLOC_PTR_WAIT(ptr) OBD_ALLOC_WAIT(ptr, sizeof(*(ptr)))
 
 #define OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, gfp_mask)                   \
        __OBD_MALLOC_VERBOSE(ptr, cptab, cpt, size, gfp_mask)
@@ -643,7 +643,7 @@ do {                                                                              \
        OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, __GFP_IO)
 
 #define OBD_CPT_ALLOC_PTR(ptr, cptab, cpt)                                   \
-       OBD_CPT_ALLOC(ptr, cptab, cpt, sizeof *(ptr))
+       OBD_CPT_ALLOC(ptr, cptab, cpt, sizeof(*(ptr)))
 
 # define __OBD_VMALLOC_VEROBSE(ptr, cptab, cpt, size)                        \
 do {                                                                         \
@@ -773,7 +773,7 @@ do {                                                                              \
 #define OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, flags)           \
        __OBD_SLAB_ALLOC_VERBOSE(ptr, slab, cptab, cpt, size, flags)
 
-#define OBD_FREE_PTR(ptr) OBD_FREE(ptr, sizeof *(ptr))
+#define OBD_FREE_PTR(ptr) OBD_FREE(ptr, sizeof(*(ptr)))
 
 #define OBD_SLAB_FREE(ptr, slab, size)                                 \
 do {                                                                     \
@@ -789,19 +789,19 @@ do {                                                                        \
        OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, __GFP_IO)
 
 #define OBD_SLAB_ALLOC_PTR(ptr, slab)                                        \
-       OBD_SLAB_ALLOC(ptr, slab, sizeof *(ptr))
+       OBD_SLAB_ALLOC(ptr, slab, sizeof(*(ptr)))
 
 #define OBD_SLAB_CPT_ALLOC_PTR(ptr, slab, cptab, cpt)                        \
-       OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, sizeof *(ptr))
+       OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, sizeof(*(ptr)))
 
 #define OBD_SLAB_ALLOC_PTR_GFP(ptr, slab, flags)                             \
-       OBD_SLAB_ALLOC_GFP(ptr, slab, sizeof *(ptr), flags)
+       OBD_SLAB_ALLOC_GFP(ptr, slab, sizeof(*(ptr)), flags)
 
 #define OBD_SLAB_CPT_ALLOC_PTR_GFP(ptr, slab, cptab, cpt, flags)                     \
-       OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, sizeof *(ptr), flags)
+       OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, sizeof(*(ptr)), flags)
 
 #define OBD_SLAB_FREE_PTR(ptr, slab)                                         \
-       OBD_SLAB_FREE((ptr), (slab), sizeof *(ptr))
+       OBD_SLAB_FREE((ptr), (slab), sizeof(*(ptr)))
 
 #define KEY_IS(str) \
        (keylen >= (sizeof(str)-1) && memcmp(key, str, (sizeof(str)-1)) == 0)
index 8ff38c64b7a1fcf5e28c4f148f9b7d869464bd1a..e60c04d5393abaf6bf51ac3834adaf274d432d45 100644 (file)
@@ -701,7 +701,7 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
 
        CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end);
 
-       memset(&cio->cui_link, 0, sizeof cio->cui_link);
+       memset(&cio->cui_link, 0, sizeof(cio->cui_link));
 
        if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
                descr->cld_mode = CLM_GROUP;
index c65b13c800f96e4f2f5da959bd168644d7bebc58..1de1d8eb9b415dca27b8b05b861242f402093ae9 100644 (file)
@@ -125,11 +125,11 @@ static inline __u64 min_u64(__u64 x, __u64 y)
 
 #define interval_for_each(node, root)             \
 for (node = interval_first(root); node != NULL;         \
-     node = interval_next(node))
+       node = interval_next(node))
 
 #define interval_for_each_reverse(node, root)     \
 for (node = interval_last(root); node != NULL;   \
-     node = interval_prev(node))
+       node = interval_prev(node))
 
 static struct interval_node *interval_first(struct interval_node *node)
 {
@@ -239,7 +239,7 @@ static void __rotate_change_maxhigh(struct interval_node *node,
        left_max = node->in_left ? node->in_left->in_max_high : 0;
        right_max = node->in_right ? node->in_right->in_max_high : 0;
        node->in_max_high  = max_u64(interval_high(node),
-                                    max_u64(left_max,right_max));
+                                    max_u64(left_max, right_max));
 }
 
 /* The left rotation "pivots" around the link from node to node->right, and
@@ -427,8 +427,9 @@ static void interval_erase_color(struct interval_node *node,
                        } else {
                                if (node_is_black_or_0(tmp->in_right)) {
                                        struct interval_node *o_left;
-                                       if ((o_left = tmp->in_left))
-                                            o_left->in_color = INTERVAL_BLACK;
+                                       o_left = tmp->in_left;
+                                       if (o_left)
+                                               o_left->in_color = INTERVAL_BLACK;
                                        tmp->in_color = INTERVAL_RED;
                                        __rotate_right(tmp, root);
                                        tmp = parent->in_right;
@@ -436,7 +437,7 @@ static void interval_erase_color(struct interval_node *node,
                                tmp->in_color = parent->in_color;
                                parent->in_color = INTERVAL_BLACK;
                                if (tmp->in_right)
-                                   tmp->in_right->in_color = INTERVAL_BLACK;
+                                       tmp->in_right->in_color = INTERVAL_BLACK;
                                __rotate_left(parent, root);
                                node = *root;
                                break;
@@ -457,8 +458,9 @@ static void interval_erase_color(struct interval_node *node,
                        } else {
                                if (node_is_black_or_0(tmp->in_left)) {
                                        struct interval_node *o_right;
-                                       if ((o_right = tmp->in_right))
-                                           o_right->in_color = INTERVAL_BLACK;
+                                       o_right = tmp->in_right;
+                                       if (o_right)
+                                               o_right->in_color = INTERVAL_BLACK;
                                        tmp->in_color = INTERVAL_RED;
                                        __rotate_left(tmp, root);
                                        tmp = parent->in_left;
@@ -545,7 +547,7 @@ void interval_erase(struct interval_node *node,
                update_maxhigh(child ? : parent, node->in_max_high);
                update_maxhigh(node, old->in_max_high);
                if (parent == old)
-                        parent = node;
+                       parent = node;
                goto color;
        }
        parent = node->in_parent;
index 7e316637369b71b3039133aaf134db181adfa380..ac5d66aa7f022969fd7e37e6f3cc31f1965a76cc 100644 (file)
@@ -144,7 +144,7 @@ struct ldlm_interval *ldlm_interval_detach(struct ldlm_lock *l)
        l->l_tree_node = NULL;
        list_del_init(&l->l_sl_policy);
 
-       return (list_empty(&n->li_group) ? n : NULL);
+       return list_empty(&n->li_group) ? n : NULL;
 }
 
 static inline int lock_mode_to_index(ldlm_mode_t mode)
index c68ed27663334491c0765547ca5e5590541053cd..39fcdacc51ed2c5c9d9f3d40368ccc91c333f39a 100644 (file)
@@ -745,7 +745,7 @@ void ldlm_flock_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
  * Export handle<->flock hash operations.
  */
 static unsigned
-ldlm_export_flock_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+ldlm_export_flock_hash(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return cfs_hash_u64_hash(*(__u64 *)key, mask);
 }
@@ -772,7 +772,7 @@ ldlm_export_flock_object(struct hlist_node *hnode)
 }
 
 static void
-ldlm_export_flock_get(cfs_hash_t *hs, struct hlist_node *hnode)
+ldlm_export_flock_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_lock *lock;
        struct ldlm_flock *flock;
@@ -787,7 +787,7 @@ ldlm_export_flock_get(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-ldlm_export_flock_put(cfs_hash_t *hs, struct hlist_node *hnode)
+ldlm_export_flock_put(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_lock *lock;
        struct ldlm_flock *flock;
index 6133b3f347182f1d202f412ce4b10556fc1df3d2..3900a69742fc5bc84b4b1ba99949a88ac2c99cc3 100644 (file)
@@ -529,7 +529,7 @@ int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock,
                lock_res_nested(oldres, LRT_NEW);
        }
        LASSERT(memcmp(new_resid, &oldres->lr_name,
-                      sizeof oldres->lr_name) != 0);
+                      sizeof(oldres->lr_name)) != 0);
        lock->l_resource = newres;
        unlock_res(oldres);
        unlock_res_and_lock(lock);
@@ -1891,7 +1891,7 @@ static int reprocess_one_queue(struct ldlm_resource *res, void *closure)
        return LDLM_ITER_CONTINUE;
 }
 
-static int ldlm_reprocess_res(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int ldlm_reprocess_res(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                              struct hlist_node *hnode, void *arg)
 {
        struct ldlm_resource *res = cfs_hash_object(hs, hnode);
@@ -2040,7 +2040,7 @@ struct export_cl_data {
  * Iterator function for ldlm_cancel_locks_for_export.
  * Cancels passed locks.
  */
-int ldlm_cancel_locks_for_export_cb(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+int ldlm_cancel_locks_for_export_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                                    struct hlist_node *hnode, void *data)
 
 {
index a100a0b96381d6ef0a55242c969ab41b7adb05be..fde9bcd1d48dfbe73c35cb1cfb21445412ea2c79 100644 (file)
@@ -937,7 +937,7 @@ EXPORT_SYMBOL(ldlm_put_ref);
  * Export handle<->lock hash operations.
  */
 static unsigned
-ldlm_export_lock_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+ldlm_export_lock_hash(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return cfs_hash_u64_hash(((struct lustre_handle *)key)->cookie, mask);
 }
@@ -973,7 +973,7 @@ ldlm_export_lock_object(struct hlist_node *hnode)
 }
 
 static void
-ldlm_export_lock_get(cfs_hash_t *hs, struct hlist_node *hnode)
+ldlm_export_lock_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_lock *lock;
 
@@ -982,7 +982,7 @@ ldlm_export_lock_get(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-ldlm_export_lock_put(cfs_hash_t *hs, struct hlist_node *hnode)
+ldlm_export_lock_put(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_lock *lock;
 
index 21cb523ac4afc47f05837dddd3772fa668a6a0e9..dcc2784031367c0cd5187c2e3891f05be79957cd 100644 (file)
@@ -1652,7 +1652,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, struct list_head *ca
 
                LDLM_LOCK_GET(lock);
                spin_unlock(&ns->ns_lock);
-               lu_ref_add(&lock->l_reference, __FUNCTION__, current);
+               lu_ref_add(&lock->l_reference, __func__, current);
 
                /* Pass the lock through the policy filter and see if it
                 * should stay in LRU.
@@ -1670,7 +1670,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, struct list_head *ca
                result = pf(ns, lock, unused, added, count);
                if (result == LDLM_POLICY_KEEP_LOCK) {
                        lu_ref_del(&lock->l_reference,
-                                  __FUNCTION__, current);
+                                  __func__, current);
                        LDLM_LOCK_RELEASE(lock);
                        spin_lock(&ns->ns_lock);
                        break;
@@ -1693,7 +1693,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, struct list_head *ca
                         * by itself, or the lock is no longer unused. */
                        unlock_res_and_lock(lock);
                        lu_ref_del(&lock->l_reference,
-                                  __FUNCTION__, current);
+                                  __func__, current);
                        LDLM_LOCK_RELEASE(lock);
                        spin_lock(&ns->ns_lock);
                        continue;
@@ -1724,7 +1724,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, struct list_head *ca
                LASSERT(list_empty(&lock->l_bl_ast));
                list_add(&lock->l_bl_ast, cancels);
                unlock_res_and_lock(lock);
-               lu_ref_del(&lock->l_reference, __FUNCTION__, current);
+               lu_ref_del(&lock->l_reference, __func__, current);
                spin_lock(&ns->ns_lock);
                added++;
                unused--;
@@ -1925,7 +1925,7 @@ struct ldlm_cli_cancel_arg {
        void   *lc_opaque;
 };
 
-static int ldlm_cli_hash_cancel_unused(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int ldlm_cli_hash_cancel_unused(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                                       struct hlist_node *hnode, void *arg)
 {
        struct ldlm_resource       *res = cfs_hash_object(hs, hnode);
@@ -2023,7 +2023,7 @@ static int ldlm_iter_helper(struct ldlm_lock *lock, void *closure)
        return helper->iter(lock, helper->closure);
 }
 
-static int ldlm_res_iter_helper(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int ldlm_res_iter_helper(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                                struct hlist_node *hnode, void *arg)
 
 {
index 208751a154b3c6de28194b30b937f48ddee54653..77e022bf8bcc891d068ccf5518bc03b603c85073 100644 (file)
@@ -159,7 +159,7 @@ static int lprocfs_ns_resources_seq_show(struct seq_file *m, void *v)
 {
        struct ldlm_namespace *ns  = m->private;
        __u64             res = 0;
-       cfs_hash_bd_t     bd;
+       struct cfs_hash_bd        bd;
        int                 i;
 
        /* result is not strictly consistant */
@@ -389,7 +389,7 @@ int ldlm_namespace_proc_register(struct ldlm_namespace *ns)
 
 #endif /* LPROCFS */
 
-static unsigned ldlm_res_hop_hash(cfs_hash_t *hs,
+static unsigned ldlm_res_hop_hash(struct cfs_hash *hs,
                                  const void *key, unsigned mask)
 {
        const struct ldlm_res_id     *id  = key;
@@ -401,7 +401,7 @@ static unsigned ldlm_res_hop_hash(cfs_hash_t *hs,
        return val & mask;
 }
 
-static unsigned ldlm_res_hop_fid_hash(cfs_hash_t *hs,
+static unsigned ldlm_res_hop_fid_hash(struct cfs_hash *hs,
                                      const void *key, unsigned mask)
 {
        const struct ldlm_res_id *id = key;
@@ -453,7 +453,7 @@ static void *ldlm_res_hop_object(struct hlist_node *hnode)
        return hlist_entry(hnode, struct ldlm_resource, lr_hash);
 }
 
-static void ldlm_res_hop_get_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+static void ldlm_res_hop_get_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_resource *res;
 
@@ -461,7 +461,7 @@ static void ldlm_res_hop_get_locked(cfs_hash_t *hs, struct hlist_node *hnode)
        ldlm_resource_getref(res);
 }
 
-static void ldlm_res_hop_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+static void ldlm_res_hop_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_resource *res;
 
@@ -470,7 +470,7 @@ static void ldlm_res_hop_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
        ldlm_resource_putref_locked(res);
 }
 
-static void ldlm_res_hop_put(cfs_hash_t *hs, struct hlist_node *hnode)
+static void ldlm_res_hop_put(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ldlm_resource *res;
 
@@ -564,7 +564,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
        struct ldlm_namespace *ns = NULL;
        struct ldlm_ns_bucket *nsb;
        ldlm_ns_hash_def_t    *nsd;
-       cfs_hash_bd_t     bd;
+       struct cfs_hash_bd        bd;
        int                 idx;
        int                 rc;
 
@@ -743,7 +743,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
        } while (1);
 }
 
-static int ldlm_resource_clean(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int ldlm_resource_clean(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                               struct hlist_node *hnode, void *arg)
 {
        struct ldlm_resource *res = cfs_hash_object(hs, hnode);
@@ -756,7 +756,7 @@ static int ldlm_resource_clean(cfs_hash_t *hs, cfs_hash_bd_t *bd,
        return 0;
 }
 
-static int ldlm_resource_complain(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int ldlm_resource_complain(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                                  struct hlist_node *hnode, void *arg)
 {
        struct ldlm_resource  *res = cfs_hash_object(hs, hnode);
@@ -1060,7 +1060,7 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
 {
        struct hlist_node     *hnode;
        struct ldlm_resource *res;
-       cfs_hash_bd_t    bd;
+       struct cfs_hash_bd       bd;
        __u64            version;
        int                   ns_refcount = 0;
 
@@ -1115,7 +1115,7 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
                lu_ref_fini(&res->lr_reference);
                /* We have taken lr_lvb_mutex. Drop it. */
                mutex_unlock(&res->lr_lvb_mutex);
-               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
+               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof(*res));
 
                res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
                /* Synchronize with regard to resource creation. */
@@ -1183,7 +1183,7 @@ struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res)
        return res;
 }
 
-static void __ldlm_resource_putref_final(cfs_hash_bd_t *bd,
+static void __ldlm_resource_putref_final(struct cfs_hash_bd *bd,
                                         struct ldlm_resource *res)
 {
        struct ldlm_ns_bucket *nsb = res->lr_ns_bucket;
@@ -1214,7 +1214,7 @@ static void __ldlm_resource_putref_final(cfs_hash_bd_t *bd,
 int ldlm_resource_putref(struct ldlm_resource *res)
 {
        struct ldlm_namespace *ns = ldlm_res_to_ns(res);
-       cfs_hash_bd_t   bd;
+       struct cfs_hash_bd   bd;
 
        LASSERT_ATOMIC_GT_LT(&res->lr_refcount, 0, LI_POISON);
        CDEBUG(D_INFO, "putref res: %p count: %d\n",
@@ -1226,7 +1226,7 @@ int ldlm_resource_putref(struct ldlm_resource *res)
                cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
                if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
                        ns->ns_lvbo->lvbo_free(res);
-               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
+               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof(*res));
                return 1;
        }
        return 0;
@@ -1243,7 +1243,7 @@ int ldlm_resource_putref_locked(struct ldlm_resource *res)
               res, atomic_read(&res->lr_refcount) - 1);
 
        if (atomic_dec_and_test(&res->lr_refcount)) {
-               cfs_hash_bd_t bd;
+               struct cfs_hash_bd bd;
 
                cfs_hash_bd_get(ldlm_res_to_ns(res)->ns_rs_hash,
                                &res->lr_name, &bd);
@@ -1256,7 +1256,7 @@ int ldlm_resource_putref_locked(struct ldlm_resource *res)
                 */
                if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
                        ns->ns_lvbo->lvbo_free(res);
-               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
+               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof(*res));
 
                cfs_hash_bd_lock(ns->ns_rs_hash, &bd, 1);
                return 1;
@@ -1352,7 +1352,7 @@ void ldlm_dump_all_namespaces(ldlm_side_t client, int level)
 }
 EXPORT_SYMBOL(ldlm_dump_all_namespaces);
 
-static int ldlm_res_hash_dump(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int ldlm_res_hash_dump(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                              struct hlist_node *hnode, void *arg)
 {
        struct ldlm_resource *res = cfs_hash_object(hs, hnode);
index 0dd12c8c91b6126c0c790ef8932e033dcdc0d468..e3e0578b27f91a80ef69914a142a370ee84abe54 100644 (file)
@@ -119,25 +119,25 @@ CFS_MODULE_PARM(warn_on_depth, "i", uint, 0644,
 struct cfs_wi_sched *cfs_sched_rehash;
 
 static inline void
-cfs_hash_nl_lock(cfs_hash_lock_t *lock, int exclusive) {}
+cfs_hash_nl_lock(union cfs_hash_lock *lock, int exclusive) {}
 
 static inline void
-cfs_hash_nl_unlock(cfs_hash_lock_t *lock, int exclusive) {}
+cfs_hash_nl_unlock(union cfs_hash_lock *lock, int exclusive) {}
 
 static inline void
-cfs_hash_spin_lock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_spin_lock(union cfs_hash_lock *lock, int exclusive)
 {
        spin_lock(&lock->spin);
 }
 
 static inline void
-cfs_hash_spin_unlock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_spin_unlock(union cfs_hash_lock *lock, int exclusive)
 {
        spin_unlock(&lock->spin);
 }
 
 static inline void
-cfs_hash_rw_lock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive)
 {
        if (!exclusive)
                read_lock(&lock->rw);
@@ -146,7 +146,7 @@ cfs_hash_rw_lock(cfs_hash_lock_t *lock, int exclusive)
 }
 
 static inline void
-cfs_hash_rw_unlock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_rw_unlock(union cfs_hash_lock *lock, int exclusive)
 {
        if (!exclusive)
                read_unlock(&lock->rw);
@@ -209,7 +209,7 @@ static cfs_hash_lock_ops_t cfs_hash_nr_bkt_rw_lops =
 };
 
 static void
-cfs_hash_lock_setup(cfs_hash_t *hs)
+cfs_hash_lock_setup(struct cfs_hash *hs)
 {
        if (cfs_hash_with_no_lock(hs)) {
                hs->hs_lops = &cfs_hash_nl_lops;
@@ -246,13 +246,13 @@ typedef struct {
 } cfs_hash_head_t;
 
 static int
-cfs_hash_hh_hhead_size(cfs_hash_t *hs)
+cfs_hash_hh_hhead_size(struct cfs_hash *hs)
 {
        return sizeof(cfs_hash_head_t);
 }
 
 static struct hlist_head *
-cfs_hash_hh_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+cfs_hash_hh_hhead(struct cfs_hash *hs, struct cfs_hash_bd *bd)
 {
        cfs_hash_head_t *head = (cfs_hash_head_t *)&bd->bd_bucket->hsb_head[0];
 
@@ -260,7 +260,7 @@ cfs_hash_hh_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
 }
 
 static int
-cfs_hash_hh_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_hh_hnode_add(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnode)
 {
        hlist_add_head(hnode, cfs_hash_hh_hhead(hs, bd));
@@ -268,7 +268,7 @@ cfs_hash_hh_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 }
 
 static int
-cfs_hash_hh_hnode_del(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_hh_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnode)
 {
        hlist_del_init(hnode);
@@ -285,13 +285,13 @@ typedef struct {
 } cfs_hash_head_dep_t;
 
 static int
-cfs_hash_hd_hhead_size(cfs_hash_t *hs)
+cfs_hash_hd_hhead_size(struct cfs_hash *hs)
 {
        return sizeof(cfs_hash_head_dep_t);
 }
 
 static struct hlist_head *
-cfs_hash_hd_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+cfs_hash_hd_hhead(struct cfs_hash *hs, struct cfs_hash_bd *bd)
 {
        cfs_hash_head_dep_t   *head;
 
@@ -300,7 +300,7 @@ cfs_hash_hd_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
 }
 
 static int
-cfs_hash_hd_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_hd_hnode_add(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnode)
 {
        cfs_hash_head_dep_t *hh = container_of(cfs_hash_hd_hhead(hs, bd),
@@ -310,7 +310,7 @@ cfs_hash_hd_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 }
 
 static int
-cfs_hash_hd_hnode_del(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_hd_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnode)
 {
        cfs_hash_head_dep_t *hh = container_of(cfs_hash_hd_hhead(hs, bd),
@@ -329,13 +329,13 @@ typedef struct {
 } cfs_hash_dhead_t;
 
 static int
-cfs_hash_dh_hhead_size(cfs_hash_t *hs)
+cfs_hash_dh_hhead_size(struct cfs_hash *hs)
 {
        return sizeof(cfs_hash_dhead_t);
 }
 
 static struct hlist_head *
-cfs_hash_dh_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+cfs_hash_dh_hhead(struct cfs_hash *hs, struct cfs_hash_bd *bd)
 {
        cfs_hash_dhead_t *head;
 
@@ -344,7 +344,7 @@ cfs_hash_dh_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
 }
 
 static int
-cfs_hash_dh_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_dh_hnode_add(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnode)
 {
        cfs_hash_dhead_t *dh = container_of(cfs_hash_dh_hhead(hs, bd),
@@ -359,7 +359,7 @@ cfs_hash_dh_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 }
 
 static int
-cfs_hash_dh_hnode_del(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_dh_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnd)
 {
        cfs_hash_dhead_t *dh = container_of(cfs_hash_dh_hhead(hs, bd),
@@ -384,13 +384,13 @@ typedef struct {
 } cfs_hash_dhead_dep_t;
 
 static int
-cfs_hash_dd_hhead_size(cfs_hash_t *hs)
+cfs_hash_dd_hhead_size(struct cfs_hash *hs)
 {
        return sizeof(cfs_hash_dhead_dep_t);
 }
 
 static struct hlist_head *
-cfs_hash_dd_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+cfs_hash_dd_hhead(struct cfs_hash *hs, struct cfs_hash_bd *bd)
 {
        cfs_hash_dhead_dep_t *head;
 
@@ -399,7 +399,7 @@ cfs_hash_dd_hhead(cfs_hash_t *hs, cfs_hash_bd_t *bd)
 }
 
 static int
-cfs_hash_dd_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_dd_hnode_add(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnode)
 {
        cfs_hash_dhead_dep_t *dh = container_of(cfs_hash_dd_hhead(hs, bd),
@@ -414,7 +414,7 @@ cfs_hash_dd_hnode_add(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 }
 
 static int
-cfs_hash_dd_hnode_del(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_dd_hnode_del(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                      struct hlist_node *hnd)
 {
        cfs_hash_dhead_dep_t *dh = container_of(cfs_hash_dd_hhead(hs, bd),
@@ -457,7 +457,7 @@ static cfs_hash_hlist_ops_t cfs_hash_dd_hops = {
 };
 
 static void
-cfs_hash_hlist_setup(cfs_hash_t *hs)
+cfs_hash_hlist_setup(struct cfs_hash *hs)
 {
        if (cfs_hash_with_add_tail(hs)) {
                hs->hs_hops = cfs_hash_with_depth(hs) ?
@@ -469,8 +469,8 @@ cfs_hash_hlist_setup(cfs_hash_t *hs)
 }
 
 static void
-cfs_hash_bd_from_key(cfs_hash_t *hs, cfs_hash_bucket_t **bkts,
-                    unsigned int bits, const void *key, cfs_hash_bd_t *bd)
+cfs_hash_bd_from_key(struct cfs_hash *hs, struct cfs_hash_bucket **bkts,
+                    unsigned int bits, const void *key, struct cfs_hash_bd *bd)
 {
        unsigned int index = cfs_hash_id(hs, key, (1U << bits) - 1);
 
@@ -481,7 +481,7 @@ cfs_hash_bd_from_key(cfs_hash_t *hs, cfs_hash_bucket_t **bkts,
 }
 
 void
-cfs_hash_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bd)
+cfs_hash_bd_get(struct cfs_hash *hs, const void *key, struct cfs_hash_bd *bd)
 {
        /* NB: caller should hold hs->hs_rwlock if REHASH is set */
        if (likely(hs->hs_rehash_buckets == NULL)) {
@@ -496,7 +496,7 @@ cfs_hash_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bd)
 EXPORT_SYMBOL(cfs_hash_bd_get);
 
 static inline void
-cfs_hash_bd_dep_record(cfs_hash_t *hs, cfs_hash_bd_t *bd, int dep_cur)
+cfs_hash_bd_dep_record(struct cfs_hash *hs, struct cfs_hash_bd *bd, int dep_cur)
 {
        if (likely(dep_cur <= bd->bd_bucket->hsb_depmax))
                return;
@@ -519,7 +519,7 @@ cfs_hash_bd_dep_record(cfs_hash_t *hs, cfs_hash_bd_t *bd, int dep_cur)
 }
 
 void
-cfs_hash_bd_add_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bd_add_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                       struct hlist_node *hnode)
 {
        int             rc;
@@ -539,7 +539,7 @@ cfs_hash_bd_add_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 EXPORT_SYMBOL(cfs_hash_bd_add_locked);
 
 void
-cfs_hash_bd_del_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bd_del_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                       struct hlist_node *hnode)
 {
        hs->hs_hops->hop_hnode_del(hs, bd, hnode);
@@ -560,11 +560,11 @@ cfs_hash_bd_del_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 EXPORT_SYMBOL(cfs_hash_bd_del_locked);
 
 void
-cfs_hash_bd_move_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd_old,
-                       cfs_hash_bd_t *bd_new, struct hlist_node *hnode)
+cfs_hash_bd_move_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd_old,
+                       struct cfs_hash_bd *bd_new, struct hlist_node *hnode)
 {
-       cfs_hash_bucket_t *obkt = bd_old->bd_bucket;
-       cfs_hash_bucket_t *nbkt = bd_new->bd_bucket;
+       struct cfs_hash_bucket *obkt = bd_old->bd_bucket;
+       struct cfs_hash_bucket *nbkt = bd_new->bd_bucket;
        int             rc;
 
        if (cfs_hash_bd_compare(bd_old, bd_new) == 0)
@@ -617,7 +617,7 @@ typedef enum cfs_hash_lookup_intent {
 } cfs_hash_lookup_intent_t;
 
 static struct hlist_node *
-cfs_hash_bd_lookup_intent(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bd_lookup_intent(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                          const void *key, struct hlist_node *hnode,
                          cfs_hash_lookup_intent_t intent)
 
@@ -658,7 +658,7 @@ cfs_hash_bd_lookup_intent(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 }
 
 struct hlist_node *
-cfs_hash_bd_lookup_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd, const void *key)
+cfs_hash_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, const void *key)
 {
        return cfs_hash_bd_lookup_intent(hs, bd, key, NULL,
                                         CFS_HS_LOOKUP_IT_FIND);
@@ -666,7 +666,7 @@ cfs_hash_bd_lookup_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd, const void *key)
 EXPORT_SYMBOL(cfs_hash_bd_lookup_locked);
 
 struct hlist_node *
-cfs_hash_bd_peek_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd, const void *key)
+cfs_hash_bd_peek_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, const void *key)
 {
        return cfs_hash_bd_lookup_intent(hs, bd, key, NULL,
                                         CFS_HS_LOOKUP_IT_PEEK);
@@ -674,7 +674,7 @@ cfs_hash_bd_peek_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd, const void *key)
 EXPORT_SYMBOL(cfs_hash_bd_peek_locked);
 
 struct hlist_node *
-cfs_hash_bd_findadd_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                           const void *key, struct hlist_node *hnode,
                           int noref)
 {
@@ -685,7 +685,7 @@ cfs_hash_bd_findadd_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 EXPORT_SYMBOL(cfs_hash_bd_findadd_locked);
 
 struct hlist_node *
-cfs_hash_bd_finddel_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                           const void *key, struct hlist_node *hnode)
 {
        /* hnode can be NULL, we find the first item with @key */
@@ -695,10 +695,10 @@ cfs_hash_bd_finddel_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 EXPORT_SYMBOL(cfs_hash_bd_finddel_locked);
 
 static void
-cfs_hash_multi_bd_lock(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_multi_bd_lock(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                       unsigned n, int excl)
 {
-       cfs_hash_bucket_t *prev = NULL;
+       struct cfs_hash_bucket *prev = NULL;
        int             i;
 
        /**
@@ -718,10 +718,10 @@ cfs_hash_multi_bd_lock(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 }
 
 static void
-cfs_hash_multi_bd_unlock(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_multi_bd_unlock(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                         unsigned n, int excl)
 {
-       cfs_hash_bucket_t *prev = NULL;
+       struct cfs_hash_bucket *prev = NULL;
        int             i;
 
        cfs_hash_for_each_bd(bds, n, i) {
@@ -733,7 +733,7 @@ cfs_hash_multi_bd_unlock(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 }
 
 static struct hlist_node *
-cfs_hash_multi_bd_lookup_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_multi_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                                unsigned n, const void *key)
 {
        struct hlist_node  *ehnode;
@@ -749,8 +749,8 @@ cfs_hash_multi_bd_lookup_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 }
 
 static struct hlist_node *
-cfs_hash_multi_bd_findadd_locked(cfs_hash_t *hs,
-                                cfs_hash_bd_t *bds, unsigned n, const void *key,
+cfs_hash_multi_bd_findadd_locked(struct cfs_hash *hs,
+                                struct cfs_hash_bd *bds, unsigned n, const void *key,
                                 struct hlist_node *hnode, int noref)
 {
        struct hlist_node  *ehnode;
@@ -770,7 +770,7 @@ cfs_hash_multi_bd_findadd_locked(cfs_hash_t *hs,
        if (i == 1) { /* only one bucket */
                cfs_hash_bd_add_locked(hs, &bds[0], hnode);
        } else {
-               cfs_hash_bd_t      mybd;
+               struct cfs_hash_bd      mybd;
 
                cfs_hash_bd_get(hs, key, &mybd);
                cfs_hash_bd_add_locked(hs, &mybd, hnode);
@@ -780,7 +780,7 @@ cfs_hash_multi_bd_findadd_locked(cfs_hash_t *hs,
 }
 
 static struct hlist_node *
-cfs_hash_multi_bd_finddel_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_multi_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                                 unsigned n, const void *key,
                                 struct hlist_node *hnode)
 {
@@ -797,7 +797,7 @@ cfs_hash_multi_bd_finddel_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 }
 
 static void
-cfs_hash_bd_order(cfs_hash_bd_t *bd1, cfs_hash_bd_t *bd2)
+cfs_hash_bd_order(struct cfs_hash_bd *bd1, struct cfs_hash_bd *bd2)
 {
        int     rc;
 
@@ -815,7 +815,7 @@ cfs_hash_bd_order(cfs_hash_bd_t *bd1, cfs_hash_bd_t *bd2)
                bd2->bd_bucket = NULL;
 
        } else if (rc > 0) { /* swab bd1 and bd2 */
-               cfs_hash_bd_t tmp;
+               struct cfs_hash_bd tmp;
 
                tmp = *bd2;
                *bd2 = *bd1;
@@ -824,7 +824,7 @@ cfs_hash_bd_order(cfs_hash_bd_t *bd1, cfs_hash_bd_t *bd2)
 }
 
 void
-cfs_hash_dual_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bds)
+cfs_hash_dual_bd_get(struct cfs_hash *hs, const void *key, struct cfs_hash_bd *bds)
 {
        /* NB: caller should hold hs_lock.rw if REHASH is set */
        cfs_hash_bd_from_key(hs, hs->hs_buckets,
@@ -844,21 +844,21 @@ cfs_hash_dual_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bds)
 EXPORT_SYMBOL(cfs_hash_dual_bd_get);
 
 void
-cfs_hash_dual_bd_lock(cfs_hash_t *hs, cfs_hash_bd_t *bds, int excl)
+cfs_hash_dual_bd_lock(struct cfs_hash *hs, struct cfs_hash_bd *bds, int excl)
 {
        cfs_hash_multi_bd_lock(hs, bds, 2, excl);
 }
 EXPORT_SYMBOL(cfs_hash_dual_bd_lock);
 
 void
-cfs_hash_dual_bd_unlock(cfs_hash_t *hs, cfs_hash_bd_t *bds, int excl)
+cfs_hash_dual_bd_unlock(struct cfs_hash *hs, struct cfs_hash_bd *bds, int excl)
 {
        cfs_hash_multi_bd_unlock(hs, bds, 2, excl);
 }
 EXPORT_SYMBOL(cfs_hash_dual_bd_unlock);
 
 struct hlist_node *
-cfs_hash_dual_bd_lookup_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_dual_bd_lookup_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                               const void *key)
 {
        return cfs_hash_multi_bd_lookup_locked(hs, bds, 2, key);
@@ -866,7 +866,7 @@ cfs_hash_dual_bd_lookup_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 EXPORT_SYMBOL(cfs_hash_dual_bd_lookup_locked);
 
 struct hlist_node *
-cfs_hash_dual_bd_findadd_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_dual_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                                const void *key, struct hlist_node *hnode,
                                int noref)
 {
@@ -876,7 +876,7 @@ cfs_hash_dual_bd_findadd_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 EXPORT_SYMBOL(cfs_hash_dual_bd_findadd_locked);
 
 struct hlist_node *
-cfs_hash_dual_bd_finddel_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
+cfs_hash_dual_bd_finddel_locked(struct cfs_hash *hs, struct cfs_hash_bd *bds,
                                const void *key, struct hlist_node *hnode)
 {
        return cfs_hash_multi_bd_finddel_locked(hs, bds, 2, key, hnode);
@@ -884,7 +884,7 @@ cfs_hash_dual_bd_finddel_locked(cfs_hash_t *hs, cfs_hash_bd_t *bds,
 EXPORT_SYMBOL(cfs_hash_dual_bd_finddel_locked);
 
 static void
-cfs_hash_buckets_free(cfs_hash_bucket_t **buckets,
+cfs_hash_buckets_free(struct cfs_hash_bucket **buckets,
                      int bkt_size, int prev_size, int size)
 {
        int     i;
@@ -902,11 +902,11 @@ cfs_hash_buckets_free(cfs_hash_bucket_t **buckets,
  * needed, the newly allocated buckets if allocation was needed and
  * successful, and NULL on error.
  */
-static cfs_hash_bucket_t **
-cfs_hash_buckets_realloc(cfs_hash_t *hs, cfs_hash_bucket_t **old_bkts,
+static struct cfs_hash_bucket **
+cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts,
                         unsigned int old_size, unsigned int new_size)
 {
-       cfs_hash_bucket_t **new_bkts;
+       struct cfs_hash_bucket **new_bkts;
        int              i;
 
        LASSERT(old_size == 0 || old_bkts != NULL);
@@ -925,7 +925,7 @@ cfs_hash_buckets_realloc(cfs_hash_t *hs, cfs_hash_bucket_t **old_bkts,
 
        for (i = old_size; i < new_size; i++) {
                struct hlist_head *hhead;
-               cfs_hash_bd_t     bd;
+               struct cfs_hash_bd     bd;
 
                LIBCFS_ALLOC(new_bkts[i], cfs_hash_bkt_size(hs));
                if (new_bkts[i] == NULL) {
@@ -969,7 +969,7 @@ static int cfs_hash_rehash_worker(cfs_workitem_t *wi);
 #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
 static int cfs_hash_dep_print(cfs_workitem_t *wi)
 {
-       cfs_hash_t *hs = container_of(wi, cfs_hash_t, hs_dep_wi);
+       struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_dep_wi);
        int      dep;
        int      bkt;
        int      off;
@@ -990,13 +990,13 @@ static int cfs_hash_dep_print(cfs_workitem_t *wi)
        return 0;
 }
 
-static void cfs_hash_depth_wi_init(cfs_hash_t *hs)
+static void cfs_hash_depth_wi_init(struct cfs_hash *hs)
 {
        spin_lock_init(&hs->hs_dep_lock);
        cfs_wi_init(&hs->hs_dep_wi, hs, cfs_hash_dep_print);
 }
 
-static void cfs_hash_depth_wi_cancel(cfs_hash_t *hs)
+static void cfs_hash_depth_wi_cancel(struct cfs_hash *hs)
 {
        if (cfs_wi_deschedule(cfs_sched_rehash, &hs->hs_dep_wi))
                return;
@@ -1012,18 +1012,18 @@ static void cfs_hash_depth_wi_cancel(cfs_hash_t *hs)
 
 #else /* CFS_HASH_DEBUG_LEVEL < CFS_HASH_DEBUG_1 */
 
-static inline void cfs_hash_depth_wi_init(cfs_hash_t *hs) {}
-static inline void cfs_hash_depth_wi_cancel(cfs_hash_t *hs) {}
+static inline void cfs_hash_depth_wi_init(struct cfs_hash *hs) {}
+static inline void cfs_hash_depth_wi_cancel(struct cfs_hash *hs) {}
 
 #endif /* CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1 */
 
-cfs_hash_t *
+struct cfs_hash *
 cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
                unsigned bkt_bits, unsigned extra_bytes,
                unsigned min_theta, unsigned max_theta,
                cfs_hash_ops_t *ops, unsigned flags)
 {
-       cfs_hash_t *hs;
+       struct cfs_hash *hs;
        int      len;
 
        CLASSERT(CFS_HASH_THETA_BITS < 15);
@@ -1051,7 +1051,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
 
        len = (flags & CFS_HASH_BIGNAME) == 0 ?
              CFS_HASH_NAME_LEN : CFS_HASH_BIGNAME_LEN;
-       LIBCFS_ALLOC(hs, offsetof(cfs_hash_t, hs_name[len]));
+       LIBCFS_ALLOC(hs, offsetof(struct cfs_hash, hs_name[len]));
        if (hs == NULL)
                return NULL;
 
@@ -1084,7 +1084,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
        if (hs->hs_buckets != NULL)
                return hs;
 
-       LIBCFS_FREE(hs, offsetof(cfs_hash_t, hs_name[len]));
+       LIBCFS_FREE(hs, offsetof(struct cfs_hash, hs_name[len]));
        return NULL;
 }
 EXPORT_SYMBOL(cfs_hash_create);
@@ -1093,11 +1093,11 @@ EXPORT_SYMBOL(cfs_hash_create);
  * Cleanup libcfs hash @hs.
  */
 static void
-cfs_hash_destroy(cfs_hash_t *hs)
+cfs_hash_destroy(struct cfs_hash *hs)
 {
        struct hlist_node     *hnode;
        struct hlist_node     *pos;
-       cfs_hash_bd_t    bd;
+       struct cfs_hash_bd       bd;
        int                i;
 
        LASSERT(hs != NULL);
@@ -1148,10 +1148,10 @@ cfs_hash_destroy(cfs_hash_t *hs)
                              0, CFS_HASH_NBKT(hs));
        i = cfs_hash_with_bigname(hs) ?
            CFS_HASH_BIGNAME_LEN : CFS_HASH_NAME_LEN;
-       LIBCFS_FREE(hs, offsetof(cfs_hash_t, hs_name[i]));
+       LIBCFS_FREE(hs, offsetof(struct cfs_hash, hs_name[i]));
 }
 
-cfs_hash_t *cfs_hash_getref(cfs_hash_t *hs)
+struct cfs_hash *cfs_hash_getref(struct cfs_hash *hs)
 {
        if (atomic_inc_not_zero(&hs->hs_refcount))
                return hs;
@@ -1159,7 +1159,7 @@ cfs_hash_t *cfs_hash_getref(cfs_hash_t *hs)
 }
 EXPORT_SYMBOL(cfs_hash_getref);
 
-void cfs_hash_putref(cfs_hash_t *hs)
+void cfs_hash_putref(struct cfs_hash *hs)
 {
        if (atomic_dec_and_test(&hs->hs_refcount))
                cfs_hash_destroy(hs);
@@ -1167,7 +1167,7 @@ void cfs_hash_putref(cfs_hash_t *hs)
 EXPORT_SYMBOL(cfs_hash_putref);
 
 static inline int
-cfs_hash_rehash_bits(cfs_hash_t *hs)
+cfs_hash_rehash_bits(struct cfs_hash *hs)
 {
        if (cfs_hash_with_no_lock(hs) ||
            !cfs_hash_with_rehash(hs))
@@ -1204,7 +1204,7 @@ cfs_hash_rehash_bits(cfs_hash_t *hs)
  * - too many elements
  */
 static inline int
-cfs_hash_rehash_inline(cfs_hash_t *hs)
+cfs_hash_rehash_inline(struct cfs_hash *hs)
 {
        return !cfs_hash_with_nblk_change(hs) &&
               atomic_read(&hs->hs_count) < CFS_HASH_LOOP_HOG;
@@ -1215,9 +1215,9 @@ cfs_hash_rehash_inline(cfs_hash_t *hs)
  * ops->hs_get function will be called when the item is added.
  */
 void
-cfs_hash_add(cfs_hash_t *hs, const void *key, struct hlist_node *hnode)
+cfs_hash_add(struct cfs_hash *hs, const void *key, struct hlist_node *hnode)
 {
-       cfs_hash_bd_t   bd;
+       struct cfs_hash_bd   bd;
        int          bits;
 
        LASSERT(hlist_unhashed(hnode));
@@ -1238,11 +1238,11 @@ cfs_hash_add(cfs_hash_t *hs, const void *key, struct hlist_node *hnode)
 EXPORT_SYMBOL(cfs_hash_add);
 
 static struct hlist_node *
-cfs_hash_find_or_add(cfs_hash_t *hs, const void *key,
+cfs_hash_find_or_add(struct cfs_hash *hs, const void *key,
                     struct hlist_node *hnode, int noref)
 {
        struct hlist_node *ehnode;
-       cfs_hash_bd_t     bds[2];
+       struct cfs_hash_bd     bds[2];
        int            bits = 0;
 
        LASSERT(hlist_unhashed(hnode));
@@ -1270,7 +1270,7 @@ cfs_hash_find_or_add(cfs_hash_t *hs, const void *key,
  * Returns 0 on success or -EALREADY on key collisions.
  */
 int
-cfs_hash_add_unique(cfs_hash_t *hs, const void *key, struct hlist_node *hnode)
+cfs_hash_add_unique(struct cfs_hash *hs, const void *key, struct hlist_node *hnode)
 {
        return cfs_hash_find_or_add(hs, key, hnode, 1) != hnode ?
               -EALREADY : 0;
@@ -1284,7 +1284,7 @@ EXPORT_SYMBOL(cfs_hash_add_unique);
  * Otherwise ops->hs_get is called on the item which was added.
  */
 void *
-cfs_hash_findadd_unique(cfs_hash_t *hs, const void *key,
+cfs_hash_findadd_unique(struct cfs_hash *hs, const void *key,
                        struct hlist_node *hnode)
 {
        hnode = cfs_hash_find_or_add(hs, key, hnode, 0);
@@ -1301,11 +1301,11 @@ EXPORT_SYMBOL(cfs_hash_findadd_unique);
  * on the removed object.
  */
 void *
-cfs_hash_del(cfs_hash_t *hs, const void *key, struct hlist_node *hnode)
+cfs_hash_del(struct cfs_hash *hs, const void *key, struct hlist_node *hnode)
 {
        void       *obj  = NULL;
        int          bits = 0;
-       cfs_hash_bd_t   bds[2];
+       struct cfs_hash_bd   bds[2];
 
        cfs_hash_lock(hs, 0);
        cfs_hash_dual_bd_get_and_lock(hs, key, bds, 1);
@@ -1341,7 +1341,7 @@ EXPORT_SYMBOL(cfs_hash_del);
  * will be returned and ops->hs_put is called on the removed object.
  */
 void *
-cfs_hash_del_key(cfs_hash_t *hs, const void *key)
+cfs_hash_del_key(struct cfs_hash *hs, const void *key)
 {
        return cfs_hash_del(hs, key, NULL);
 }
@@ -1356,11 +1356,11 @@ EXPORT_SYMBOL(cfs_hash_del_key);
  * in the hash @hs NULL is returned.
  */
 void *
-cfs_hash_lookup(cfs_hash_t *hs, const void *key)
+cfs_hash_lookup(struct cfs_hash *hs, const void *key)
 {
        void             *obj = NULL;
        struct hlist_node     *hnode;
-       cfs_hash_bd_t    bds[2];
+       struct cfs_hash_bd       bds[2];
 
        cfs_hash_lock(hs, 0);
        cfs_hash_dual_bd_get_and_lock(hs, key, bds, 0);
@@ -1377,7 +1377,7 @@ cfs_hash_lookup(cfs_hash_t *hs, const void *key)
 EXPORT_SYMBOL(cfs_hash_lookup);
 
 static void
-cfs_hash_for_each_enter(cfs_hash_t *hs)
+cfs_hash_for_each_enter(struct cfs_hash *hs)
 {
        LASSERT(!cfs_hash_is_exiting(hs));
 
@@ -1403,7 +1403,7 @@ cfs_hash_for_each_enter(cfs_hash_t *hs)
 }
 
 static void
-cfs_hash_for_each_exit(cfs_hash_t *hs)
+cfs_hash_for_each_exit(struct cfs_hash *hs)
 {
        int remained;
        int bits;
@@ -1434,12 +1434,12 @@ cfs_hash_for_each_exit(cfs_hash_t *hs)
  *      cfs_hash_bd_del_locked
  */
 static __u64
-cfs_hash_for_each_tight(cfs_hash_t *hs, cfs_hash_for_each_cb_t func,
+cfs_hash_for_each_tight(struct cfs_hash *hs, cfs_hash_for_each_cb_t func,
                        void *data, int remove_safe)
 {
        struct hlist_node     *hnode;
        struct hlist_node     *pos;
-       cfs_hash_bd_t    bd;
+       struct cfs_hash_bd       bd;
        __u64            count = 0;
        int                excl  = !!remove_safe;
        int                loop  = 0;
@@ -1492,7 +1492,7 @@ typedef struct {
 } cfs_hash_cond_arg_t;
 
 static int
-cfs_hash_cond_del_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_cond_del_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                         struct hlist_node *hnode, void *data)
 {
        cfs_hash_cond_arg_t *cond = data;
@@ -1508,7 +1508,7 @@ cfs_hash_cond_del_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
  * any object be reference.
  */
 void
-cfs_hash_cond_del(cfs_hash_t *hs, cfs_hash_cond_opt_cb_t func, void *data)
+cfs_hash_cond_del(struct cfs_hash *hs, cfs_hash_cond_opt_cb_t func, void *data)
 {
        cfs_hash_cond_arg_t arg = {
                .func   = func,
@@ -1520,7 +1520,7 @@ cfs_hash_cond_del(cfs_hash_t *hs, cfs_hash_cond_opt_cb_t func, void *data)
 EXPORT_SYMBOL(cfs_hash_cond_del);
 
 void
-cfs_hash_for_each(cfs_hash_t *hs,
+cfs_hash_for_each(struct cfs_hash *hs,
                  cfs_hash_for_each_cb_t func, void *data)
 {
        cfs_hash_for_each_tight(hs, func, data, 0);
@@ -1528,7 +1528,7 @@ cfs_hash_for_each(cfs_hash_t *hs,
 EXPORT_SYMBOL(cfs_hash_for_each);
 
 void
-cfs_hash_for_each_safe(cfs_hash_t *hs,
+cfs_hash_for_each_safe(struct cfs_hash *hs,
                       cfs_hash_for_each_cb_t func, void *data)
 {
        cfs_hash_for_each_tight(hs, func, data, 1);
@@ -1536,7 +1536,7 @@ cfs_hash_for_each_safe(cfs_hash_t *hs,
 EXPORT_SYMBOL(cfs_hash_for_each_safe);
 
 static int
-cfs_hash_peek(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+cfs_hash_peek(struct cfs_hash *hs, struct cfs_hash_bd *bd,
              struct hlist_node *hnode, void *data)
 {
        *(int *)data = 0;
@@ -1544,7 +1544,7 @@ cfs_hash_peek(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 }
 
 int
-cfs_hash_is_empty(cfs_hash_t *hs)
+cfs_hash_is_empty(struct cfs_hash *hs)
 {
        int empty = 1;
 
@@ -1554,7 +1554,7 @@ cfs_hash_is_empty(cfs_hash_t *hs)
 EXPORT_SYMBOL(cfs_hash_is_empty);
 
 __u64
-cfs_hash_size_get(cfs_hash_t *hs)
+cfs_hash_size_get(struct cfs_hash *hs)
 {
        return cfs_hash_with_counter(hs) ?
               atomic_read(&hs->hs_count) :
@@ -1578,11 +1578,11 @@ EXPORT_SYMBOL(cfs_hash_size_get);
  * two cases, so iteration has to be stopped on change.
  */
 static int
-cfs_hash_for_each_relax(cfs_hash_t *hs, cfs_hash_for_each_cb_t func, void *data)
+cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, void *data)
 {
        struct hlist_node *hnode;
        struct hlist_node *tmp;
-       cfs_hash_bd_t     bd;
+       struct cfs_hash_bd     bd;
        __u32        version;
        int            count = 0;
        int            stop_on_change;
@@ -1639,7 +1639,7 @@ cfs_hash_for_each_relax(cfs_hash_t *hs, cfs_hash_for_each_cb_t func, void *data)
 }
 
 int
-cfs_hash_for_each_nolock(cfs_hash_t *hs,
+cfs_hash_for_each_nolock(struct cfs_hash *hs,
                         cfs_hash_for_each_cb_t func, void *data)
 {
        if (cfs_hash_with_no_lock(hs) ||
@@ -1672,7 +1672,7 @@ EXPORT_SYMBOL(cfs_hash_for_each_nolock);
  * the required locking is in place to prevent concurrent insertions.
  */
 int
-cfs_hash_for_each_empty(cfs_hash_t *hs,
+cfs_hash_for_each_empty(struct cfs_hash *hs,
                        cfs_hash_for_each_cb_t func, void *data)
 {
        unsigned  i = 0;
@@ -1696,12 +1696,12 @@ cfs_hash_for_each_empty(cfs_hash_t *hs,
 EXPORT_SYMBOL(cfs_hash_for_each_empty);
 
 void
-cfs_hash_hlist_for_each(cfs_hash_t *hs, unsigned hindex,
+cfs_hash_hlist_for_each(struct cfs_hash *hs, unsigned hindex,
                        cfs_hash_for_each_cb_t func, void *data)
 {
        struct hlist_head   *hhead;
        struct hlist_node   *hnode;
-       cfs_hash_bd_t       bd;
+       struct cfs_hash_bd       bd;
 
        cfs_hash_for_each_enter(hs);
        cfs_hash_lock(hs, 0);
@@ -1731,11 +1731,11 @@ EXPORT_SYMBOL(cfs_hash_hlist_for_each);
  * is held so the callback must never sleep.
    */
 void
-cfs_hash_for_each_key(cfs_hash_t *hs, const void *key,
+cfs_hash_for_each_key(struct cfs_hash *hs, const void *key,
                      cfs_hash_for_each_cb_t func, void *data)
 {
        struct hlist_node   *hnode;
-       cfs_hash_bd_t       bds[2];
+       struct cfs_hash_bd       bds[2];
        unsigned            i;
 
        cfs_hash_lock(hs, 0);
@@ -1772,7 +1772,7 @@ EXPORT_SYMBOL(cfs_hash_for_each_key);
  * theta thresholds for @hs are tunable via cfs_hash_set_theta().
  */
 void
-cfs_hash_rehash_cancel_locked(cfs_hash_t *hs)
+cfs_hash_rehash_cancel_locked(struct cfs_hash *hs)
 {
        int     i;
 
@@ -1801,7 +1801,7 @@ cfs_hash_rehash_cancel_locked(cfs_hash_t *hs)
 EXPORT_SYMBOL(cfs_hash_rehash_cancel_locked);
 
 void
-cfs_hash_rehash_cancel(cfs_hash_t *hs)
+cfs_hash_rehash_cancel(struct cfs_hash *hs)
 {
        cfs_hash_lock(hs, 1);
        cfs_hash_rehash_cancel_locked(hs);
@@ -1810,7 +1810,7 @@ cfs_hash_rehash_cancel(cfs_hash_t *hs)
 EXPORT_SYMBOL(cfs_hash_rehash_cancel);
 
 int
-cfs_hash_rehash(cfs_hash_t *hs, int do_rehash)
+cfs_hash_rehash(struct cfs_hash *hs, int do_rehash)
 {
        int     rc;
 
@@ -1840,9 +1840,9 @@ cfs_hash_rehash(cfs_hash_t *hs, int do_rehash)
 EXPORT_SYMBOL(cfs_hash_rehash);
 
 static int
-cfs_hash_rehash_bd(cfs_hash_t *hs, cfs_hash_bd_t *old)
+cfs_hash_rehash_bd(struct cfs_hash *hs, struct cfs_hash_bd *old)
 {
-       cfs_hash_bd_t      new;
+       struct cfs_hash_bd      new;
        struct hlist_head  *hhead;
        struct hlist_node  *hnode;
        struct hlist_node  *pos;
@@ -1873,9 +1873,9 @@ cfs_hash_rehash_bd(cfs_hash_t *hs, cfs_hash_bd_t *old)
 static int
 cfs_hash_rehash_worker(cfs_workitem_t *wi)
 {
-       cfs_hash_t       *hs = container_of(wi, cfs_hash_t, hs_rehash_wi);
-       cfs_hash_bucket_t **bkts;
-       cfs_hash_bd_t       bd;
+       struct cfs_hash  *hs = container_of(wi, struct cfs_hash, hs_rehash_wi);
+       struct cfs_hash_bucket **bkts;
+       struct cfs_hash_bd       bd;
        unsigned int    old_size;
        unsigned int    new_size;
        int              bsize;
@@ -1965,7 +1965,7 @@ cfs_hash_rehash_worker(cfs_workitem_t *wi)
        if (bkts != NULL)
                cfs_hash_buckets_free(bkts, bsize, new_size, old_size);
        if (rc != 0)
-               CDEBUG(D_INFO, "early quit of of rehashing: %d\n", rc);
+               CDEBUG(D_INFO, "early quit of rehashing: %d\n", rc);
        /* return 1 only if cfs_wi_exit is called */
        return rc == -ESRCH;
 }
@@ -1980,12 +1980,12 @@ cfs_hash_rehash_worker(cfs_workitem_t *wi)
  * the registered cfs_hash_get() and cfs_hash_put() functions will
  * not be called.
  */
-void cfs_hash_rehash_key(cfs_hash_t *hs, const void *old_key,
+void cfs_hash_rehash_key(struct cfs_hash *hs, const void *old_key,
                         void *new_key, struct hlist_node *hnode)
 {
-       cfs_hash_bd_t   bds[3];
-       cfs_hash_bd_t   old_bds[2];
-       cfs_hash_bd_t   new_bd;
+       struct cfs_hash_bd      bds[3];
+       struct cfs_hash_bd      old_bds[2];
+       struct cfs_hash_bd      new_bd;
 
        LASSERT(!hlist_unhashed(hnode));
 
@@ -2028,8 +2028,8 @@ int cfs_hash_debug_header(struct seq_file *m)
 }
 EXPORT_SYMBOL(cfs_hash_debug_header);
 
-static cfs_hash_bucket_t **
-cfs_hash_full_bkts(cfs_hash_t *hs)
+static struct cfs_hash_bucket **
+cfs_hash_full_bkts(struct cfs_hash *hs)
 {
        /* NB: caller should hold hs->hs_rwlock if REHASH is set */
        if (hs->hs_rehash_buckets == NULL)
@@ -2041,7 +2041,7 @@ cfs_hash_full_bkts(cfs_hash_t *hs)
 }
 
 static unsigned int
-cfs_hash_full_nbkt(cfs_hash_t *hs)
+cfs_hash_full_nbkt(struct cfs_hash *hs)
 {
        /* NB: caller should hold hs->hs_rwlock if REHASH is set */
        if (hs->hs_rehash_buckets == NULL)
@@ -2052,7 +2052,7 @@ cfs_hash_full_nbkt(cfs_hash_t *hs)
               CFS_HASH_RH_NBKT(hs) : CFS_HASH_NBKT(hs);
 }
 
-int cfs_hash_debug_str(cfs_hash_t *hs, struct seq_file *m)
+int cfs_hash_debug_str(struct cfs_hash *hs, struct seq_file *m)
 {
        int                 dist[8] = { 0, };
        int                 maxdep  = -1;
@@ -2089,7 +2089,7 @@ int cfs_hash_debug_str(cfs_hash_t *hs, struct seq_file *m)
         * Non-Uniform hash distribution:  128/125/0/0/0/0/2/1
         */
        for (i = 0; i < cfs_hash_full_nbkt(hs); i++) {
-               cfs_hash_bd_t  bd;
+               struct cfs_hash_bd  bd;
 
                bd.bd_bucket = cfs_hash_full_bkts(hs)[i];
                cfs_hash_bd_lock(hs, &bd, 0);
index ea9e9490031fc81573e7a37f5fe6ca00b3723652..0bf8e5d87f1ad483035a3f0f93813530da56edc6 100644 (file)
@@ -167,7 +167,7 @@ static int cfs_access_process_vm(struct task_struct *tsk, unsigned long addr,
                return 0;
 
        down_read(&mm->mmap_sem);
-       /* ignore errors, just check how much was sucessfully transfered */
+       /* ignore errors, just check how much was successfully transferred */
        while (len) {
                int bytes, rc, offset;
                void *maddr;
@@ -227,8 +227,10 @@ int cfs_get_environ(const char *key, char *value, int *val_len)
         * which is already holding mmap_sem for writes.  If some other
         * thread gets the write lock in the meantime, this thread will
         * block, but at least it won't deadlock on itself.  LU-1735 */
-       if (down_read_trylock(&mm->mmap_sem) == 0)
+       if (down_read_trylock(&mm->mmap_sem) == 0) {
+               kfree(buffer);
                return -EDEADLK;
+       }
        up_read(&mm->mmap_sem);
 
        addr = mm->env_start;
index ab1e73168472445cc59b5b1e9c3165325684510b..cc565b1fb994397e8322d5dc7a66701c546e3c8d 100644 (file)
@@ -137,7 +137,7 @@ void libcfs_run_lbug_upcall(struct libcfs_debug_msg_data *msgdata)
        char *argv[6];
        char buf[32];
 
-       snprintf (buf, sizeof buf, "%d", msgdata->msg_line);
+       snprintf(buf, sizeof(buf), "%d", msgdata->msg_line);
 
        argv[1] = "LBUG";
        argv[2] = (char *)msgdata->msg_file;
index 69224d84bc4be87e00fa6ca12518612994800712..f87e9e516546f992998e6f8bb0ee07af09b1300f 100644 (file)
@@ -70,7 +70,7 @@ static unsigned int seed_y = 362436069;
  * cfs_rand - creates new seeds
  *
  * First it creates new seeds from the previous seeds. Then it generates a
- * new psuedo random number for use.
+ * new pseudo random number for use.
  *
  * Returns a pseudo-random 32-bit integer
  */
@@ -84,7 +84,7 @@ unsigned int cfs_rand(void)
 EXPORT_SYMBOL(cfs_rand);
 
 /**
- * cfs_srand - sets the inital seed
+ * cfs_srand - sets the initial seed
  * @seed1 : (seed_x) should have the most entropy in the low bits of the word
  * @seed2 : (seed_y) should have the most entropy in the high bits of the word
  *
index 357f40079ae097ff709ad21ea0bf0b4aeb7f5e28..f71a3cc63ad85032226e37630be781d25088bd9d 100644 (file)
@@ -276,7 +276,7 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
        int                     remain;
        int                     mask = msgdata->msg_mask;
        const char              *file = kbasename(msgdata->msg_file);
-       cfs_debug_limit_state_t   *cdls = msgdata->msg_cdls;
+       struct cfs_debug_limit_state   *cdls = msgdata->msg_cdls;
 
        tcd = cfs_trace_get_tcd();
 
index 09844be5eec4f09f9a4cdd24fb17127c9111019a..1f079034bd8f49aaed764925ef0dfc50c2ed65f2 100644 (file)
@@ -743,7 +743,7 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
 
        /* In the following we use the fact that LOV_USER_MAGIC_V1 and
         LOV_USER_MAGIC_V3 have the same initial fields so we do not
-        need the make the distiction between the 2 versions */
+        need to make the distinction between the 2 versions */
        if (set_default && mgc->u.cli.cl_mgc_mgsexp) {
                char *param = NULL;
                char *buf;
index bc534db1243169b8866f84b4875ed4852a66c963..fb85a58db058ec3f34cf80065e4b9cdb5e35c05f 100644 (file)
@@ -364,7 +364,7 @@ static int ll_intent_file_open(struct file *file, void *lmm,
           that case that lock is also ok */
        /* We can also get here if there was cached open handle in revalidate_it
         * but it disappeared while we were getting from there to ll_file_open.
-        * But this means this file was closed and immediatelly opened which
+        * But this means this file was closed and immediately opened which
         * makes a good candidate for using OPEN lock */
        /* If lmmsize & lmm are not 0, we are just setting stripe info
         * parameters. No need for the open lock */
@@ -2456,8 +2456,8 @@ static int ll_inode_revalidate_fini(struct inode *inode, int rc)
        if (rc == -ENOENT) {
                clear_nlink(inode);
                /* This path cannot be hit for regular files unless in
-                * case of obscure races, so no need to to validate
-                * size. */
+                * case of obscure races, so no need to validate size.
+                */
                if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
                        return 0;
        } else if (rc != 0) {
@@ -3011,7 +3011,7 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, ldlm_mode_t mode,
 
        /* set layout to file. Unlikely this will fail as old layout was
         * surely eliminated */
-       memset(&conf, 0, sizeof conf);
+       memset(&conf, 0, sizeof(conf));
        conf.coc_opc = OBJECT_CONF_SET;
        conf.coc_inode = inode;
        conf.coc_lock = lock;
@@ -3034,7 +3034,7 @@ out:
                        ll_get_fsname(inode->i_sb, NULL, 0),
                        inode, PFID(&lli->lli_fid));
 
-               memset(&conf, 0, sizeof conf);
+               memset(&conf, 0, sizeof(conf));
                conf.coc_opc = OBJECT_CONF_WAIT;
                conf.coc_inode = inode;
                rc = ll_layout_conf(inode, &conf);
index 1f5825c87a79cdb861c2e21976f8f12dd988d721..e2996c46b2c02a2cb2602daeaff362b1ff128555 100644 (file)
@@ -159,7 +159,7 @@ void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data,
                }
                if (flags & LLIF_DONE_WRITING) {
                        /* Some pages are still dirty, it is early to send
-                        * DONE_WRITE. Wait untill all pages will be flushed
+                        * DONE_WRITE. Wait until all pages will be flushed
                         * and try DONE_WRITE again later. */
                        LASSERT(!(lli->lli_flags & LLIF_DONE_WRITING));
                        lli->lli_flags |= LLIF_DONE_WRITING;
index b868c2bd58d2a78787e2336d2c4b4a6259c3dd90..fd584ff7e2df0e22602347199a1ccfe02544ca41 100644 (file)
@@ -1973,10 +1973,10 @@ void ll_umount_begin(struct super_block *sb)
        OBD_ALLOC_PTR(ioc_data);
        if (ioc_data) {
                obd_iocontrol(IOC_OSC_SET_ACTIVE, sbi->ll_md_exp,
-                             sizeof *ioc_data, ioc_data, NULL);
+                             sizeof(*ioc_data), ioc_data, NULL);
 
                obd_iocontrol(IOC_OSC_SET_ACTIVE, sbi->ll_dt_exp,
-                             sizeof *ioc_data, ioc_data, NULL);
+                             sizeof(*ioc_data), ioc_data, NULL);
 
                OBD_FREE_PTR(ioc_data);
        }
index 2340458b8a04e6bcba5935e32ea9aad6a7e28861..e2421ea6135292aa37af132259356602770dcb67 100644 (file)
@@ -337,8 +337,7 @@ static unsigned int loop_get_bio(struct lloop_device *lo, struct bio **req)
        return count;
 }
 
-static ll_mrf_ret
-loop_make_request(struct request_queue *q, struct bio *old_bio)
+static void loop_make_request(struct request_queue *q, struct bio *old_bio)
 {
        struct lloop_device *lo = q->queuedata;
        int rw = bio_rw(old_bio);
@@ -366,10 +365,9 @@ loop_make_request(struct request_queue *q, struct bio *old_bio)
                goto err;
        }
        loop_add_bio(lo, old_bio);
-       LL_MRF_RETURN(0);
+       return;
 err:
        cfs_bio_io_error(old_bio, old_bio->bi_size);
-       LL_MRF_RETURN(0);
 }
 
 
index d4d3c17547cae93d8a7cf8f6cc445d446646f32a..4bf09c4a0c9dd1bad15a8d55186254cc9d987e42 100644 (file)
@@ -1063,7 +1063,7 @@ static int ll_rw_extents_stats_pp_seq_show(struct seq_file *seq, void *v)
                return 0;
        }
        seq_printf(seq, "snapshot_time:  %lu.%lu (secs.usecs)\n",
-                  now.tv_sec, now.tv_usec);
+                  now.tv_sec, (unsigned long)now.tv_usec);
        seq_printf(seq, "%15s %19s       | %20s\n", " ", "read", "write");
        seq_printf(seq, "%13s   %14s %4s %4s  | %14s %4s %4s\n",
                   "extents", "calls", "%", "cum%",
@@ -1127,7 +1127,7 @@ static int ll_rw_extents_stats_seq_show(struct seq_file *seq, void *v)
                return 0;
        }
        seq_printf(seq, "snapshot_time:  %lu.%lu (secs.usecs)\n",
-                  now.tv_sec, now.tv_usec);
+                  now.tv_sec, (unsigned long)now.tv_usec);
 
        seq_printf(seq, "%15s %19s       | %20s\n", " ", "read", "write");
        seq_printf(seq, "%13s   %14s %4s %4s  | %14s %4s %4s\n",
@@ -1293,7 +1293,7 @@ static int ll_rw_offset_stats_seq_show(struct seq_file *seq, void *v)
        spin_lock(&sbi->ll_process_lock);
 
        seq_printf(seq, "snapshot_time:  %lu.%lu (secs.usecs)\n",
-                  now.tv_sec, now.tv_usec);
+                  now.tv_sec, (unsigned long)now.tv_usec);
        seq_printf(seq, "%3s %10s %14s %14s %17s %17s %14s\n",
                   "R/W", "PID", "RANGE START", "RANGE END",
                   "SMALLEST EXTENT", "LARGEST EXTENT", "OFFSET");
index ae0dc441d1d9dd238ce0bfb4a5b37b46eeca607b..e9ba38a553cf3e62b90dfab2529efb8c491b1b72 100644 (file)
@@ -717,7 +717,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io,
        lli = ll_i2info(inode);
        clob = lli->lli_clob;
 
-       memset(ria, 0, sizeof *ria);
+       memset(ria, 0, sizeof(*ria));
 
        cl_object_attr_lock(clob);
        ret = cl_object_attr_get(env, clob, attr);
index 96c29ad2fc8c5cd2992e766cba674bd4981fba06..7e3e0967993b5f6fecc7bfa965ef9a444cd0037f 100644 (file)
@@ -202,11 +202,8 @@ static inline int ll_get_user_pages(int rw, unsigned long user_addr,
 
        OBD_ALLOC_LARGE(*pages, *max_pages * sizeof(**pages));
        if (*pages) {
-               down_read(&current->mm->mmap_sem);
-               result = get_user_pages(current, current->mm, user_addr,
-                                       *max_pages, (rw == READ), 0, *pages,
-                                       NULL);
-               up_read(&current->mm->mmap_sem);
+               result = get_user_pages_fast(user_addr, *max_pages,
+                                            (rw == READ), *pages);
                if (unlikely(result <= 0))
                        OBD_FREE_LARGE(*pages, *max_pages * sizeof(**pages));
        }
index 8eaa38e91b9922084900660a08a6b15ecdb5cd08..f6b5f4b95f371de95f6ecaee5651c3c4e4201ecc 100644 (file)
@@ -647,7 +647,7 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
                 */
                LASSERT(fid_is_zero(&minfo->mi_data.op_fid2));
 
-               /* XXX: No fid in reply, this is probaly cross-ref case.
+               /* XXX: No fid in reply, this is probably cross-ref case.
                 * SA can't handle it yet. */
                if (body->valid & OBD_MD_MDS)
                        GOTO(out, rc = -EAGAIN);
index be125b98b7f0434e7078f94f2257e63bb7692e18..c4d1580b7be53530a646f054db571043c46ff23a 100644 (file)
@@ -297,7 +297,7 @@ static loff_t vvp_pgcache_id_pack(struct vvp_pgcache_id *id)
                ((__u64)id->vpi_bucket << PGC_OBJ_SHIFT);
 }
 
-static int vvp_pgcache_obj_get(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+static int vvp_pgcache_obj_get(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                               struct hlist_node *hnode, void *data)
 {
        struct vvp_pgcache_id   *id  = data;
index 33d9ce68feddf8bb07fa70a56e7a81a7a76dff71..4276124d92e9837f7648835ddce7c55db5398a81 100644 (file)
@@ -564,50 +564,50 @@ extern struct kmem_cache *lovsub_req_kmem;
 
 extern struct kmem_cache *lov_lock_link_kmem;
 
-int   lov_object_init     (const struct lu_env *env, struct lu_object *obj,
+int   lov_object_init(const struct lu_env *env, struct lu_object *obj,
                           const struct lu_object_conf *conf);
-int   lovsub_object_init  (const struct lu_env *env, struct lu_object *obj,
+int   lovsub_object_init(const struct lu_env *env, struct lu_object *obj,
                           const struct lu_object_conf *conf);
-int   lov_lock_init       (const struct lu_env *env, struct cl_object *obj,
+int   lov_lock_init(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
-int   lov_io_init       (const struct lu_env *env, struct cl_object *obj,
+int   lov_io_init(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
-int   lovsub_lock_init    (const struct lu_env *env, struct cl_object *obj,
+int   lovsub_lock_init(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
 
-int   lov_lock_init_raid0 (const struct lu_env *env, struct cl_object *obj,
+int   lov_lock_init_raid0(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
-int   lov_lock_init_empty (const struct lu_env *env, struct cl_object *obj,
+int   lov_lock_init_empty(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
-int   lov_io_init_raid0   (const struct lu_env *env, struct cl_object *obj,
+int   lov_io_init_raid0(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
-int   lov_io_init_empty   (const struct lu_env *env, struct cl_object *obj,
+int   lov_io_init_empty(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
 int   lov_io_init_released(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
-void  lov_lock_unlink     (const struct lu_env *env, struct lov_lock_link *link,
+void  lov_lock_unlink(const struct lu_env *env, struct lov_lock_link *link,
                           struct lovsub_lock *sub);
 
 struct lov_io_sub *lov_sub_get(const struct lu_env *env, struct lov_io *lio,
                               int stripe);
-void  lov_sub_put           (struct lov_io_sub *sub);
-int   lov_sublock_modify  (const struct lu_env *env, struct lov_lock *lov,
+void  lov_sub_put(struct lov_io_sub *sub);
+int   lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov,
                           struct lovsub_lock *sublock,
                           const struct cl_lock_descr *d, int idx);
 
 
-int   lov_page_init       (const struct lu_env *env, struct cl_object *ob,
+int   lov_page_init(const struct lu_env *env, struct cl_object *ob,
                           struct cl_page *page, struct page *vmpage);
-int   lovsub_page_init    (const struct lu_env *env, struct cl_object *ob,
+int   lovsub_page_init(const struct lu_env *env, struct cl_object *ob,
                           struct cl_page *page, struct page *vmpage);
 
-int   lov_page_init_empty (const struct lu_env *env,
+int   lov_page_init_empty(const struct lu_env *env,
                           struct cl_object *obj,
                           struct cl_page *page, struct page *vmpage);
-int   lov_page_init_raid0 (const struct lu_env *env,
+int   lov_page_init_raid0(const struct lu_env *env,
                           struct cl_object *obj,
                           struct cl_page *page, struct page *vmpage);
-struct lu_object *lov_object_alloc   (const struct lu_env *env,
+struct lu_object *lov_object_alloc(const struct lu_env *env,
                                      const struct lu_object_header *hdr,
                                      struct lu_device *dev);
 struct lu_object *lovsub_object_alloc(const struct lu_env *env,
@@ -617,7 +617,7 @@ struct lu_object *lovsub_object_alloc(const struct lu_env *env,
 struct lov_lock_link *lov_lock_link_find(const struct lu_env *env,
                                         struct lov_lock *lck,
                                         struct lovsub_lock *sub);
-struct lov_io_sub    *lov_page_subio    (const struct lu_env *env,
+struct lov_io_sub    *lov_page_subio(const struct lu_env *env,
                                         struct lov_io *lio,
                                         const struct cl_page_slice *slice);
 
index a4006ef46ad2a794eede17ee883fef91e6a259ea..1f33b04b0c38c06c02f9dae360ff5269666d63e4 100644 (file)
@@ -44,6 +44,8 @@
 #include <obd_class.h>
 
 #include "lov_cl_internal.h"
+#include "lov_internal.h"
+
 
 struct kmem_cache *lov_lock_kmem;
 struct kmem_cache *lov_object_kmem;
@@ -64,47 +66,47 @@ struct lu_kmem_descr lov_caches[] = {
        {
                .ckd_cache = &lov_lock_kmem,
                .ckd_name  = "lov_lock_kmem",
-               .ckd_size  = sizeof (struct lov_lock)
+               .ckd_size  = sizeof(struct lov_lock)
        },
        {
                .ckd_cache = &lov_object_kmem,
                .ckd_name  = "lov_object_kmem",
-               .ckd_size  = sizeof (struct lov_object)
+               .ckd_size  = sizeof(struct lov_object)
        },
        {
                .ckd_cache = &lov_thread_kmem,
                .ckd_name  = "lov_thread_kmem",
-               .ckd_size  = sizeof (struct lov_thread_info)
+               .ckd_size  = sizeof(struct lov_thread_info)
        },
        {
                .ckd_cache = &lov_session_kmem,
                .ckd_name  = "lov_session_kmem",
-               .ckd_size  = sizeof (struct lov_session)
+               .ckd_size  = sizeof(struct lov_session)
        },
        {
                .ckd_cache = &lov_req_kmem,
                .ckd_name  = "lov_req_kmem",
-               .ckd_size  = sizeof (struct lov_req)
+               .ckd_size  = sizeof(struct lov_req)
        },
        {
                .ckd_cache = &lovsub_lock_kmem,
                .ckd_name  = "lovsub_lock_kmem",
-               .ckd_size  = sizeof (struct lovsub_lock)
+               .ckd_size  = sizeof(struct lovsub_lock)
        },
        {
                .ckd_cache = &lovsub_object_kmem,
                .ckd_name  = "lovsub_object_kmem",
-               .ckd_size  = sizeof (struct lovsub_object)
+               .ckd_size  = sizeof(struct lovsub_object)
        },
        {
                .ckd_cache = &lovsub_req_kmem,
                .ckd_name  = "lovsub_req_kmem",
-               .ckd_size  = sizeof (struct lovsub_req)
+               .ckd_size  = sizeof(struct lovsub_req)
        },
        {
                .ckd_cache = &lov_lock_link_kmem,
                .ckd_name  = "lov_lock_link_kmem",
-               .ckd_size  = sizeof (struct lov_lock_link)
+               .ckd_size  = sizeof(struct lov_lock_link)
        },
        {
                .ckd_cache = NULL
@@ -286,7 +288,7 @@ static void lov_emerg_free(struct lov_device_emerg **emrg, int nr)
                        OBD_FREE_PTR(em);
                }
        }
-       OBD_FREE(emrg, nr * sizeof emrg[0]);
+       OBD_FREE(emrg, nr * sizeof(emrg[0]));
 }
 
 static struct lu_device *lov_device_free(const struct lu_env *env,
@@ -297,7 +299,7 @@ static struct lu_device *lov_device_free(const struct lu_env *env,
 
        cl_device_fini(lu2cl_dev(d));
        if (ld->ld_target != NULL)
-               OBD_FREE(ld->ld_target, nr * sizeof ld->ld_target[0]);
+               OBD_FREE(ld->ld_target, nr * sizeof(ld->ld_target[0]));
        if (ld->ld_emrg != NULL)
                lov_emerg_free(ld->ld_emrg, nr);
        OBD_FREE_PTR(ld);
@@ -321,7 +323,7 @@ static struct lov_device_emerg **lov_emerg_alloc(int nr)
        int i;
        int result;
 
-       OBD_ALLOC(emerg, nr * sizeof emerg[0]);
+       OBD_ALLOC(emerg, nr * sizeof(emerg[0]));
        if (emerg == NULL)
                return ERR_PTR(-ENOMEM);
        for (result = i = 0; i < nr && result == 0; i++) {
@@ -361,7 +363,7 @@ static int lov_expand_targets(const struct lu_env *env, struct lov_device *dev)
        if (sub_size < tgt_size) {
                struct lovsub_device    **newd;
                struct lov_device_emerg **emerg;
-               const size_t          sz   = sizeof newd[0];
+               const size_t          sz   = sizeof(newd[0]);
 
                emerg = lov_emerg_alloc(tgt_size);
                if (IS_ERR(emerg))
@@ -446,7 +448,7 @@ static int lov_process_config(const struct lu_env *env,
        cmd = cfg->lcfg_command;
        rc = lov_process_config_base(d->ld_obd, cfg, &index, &gen);
        if (rc == 0) {
-               switch(cmd) {
+               switch (cmd) {
                case LCFG_LOV_ADD_OBD:
                case LCFG_LOV_ADD_INA:
                        rc = lov_cl_add_target(env, d, index);
index 16770d14ee04d8686204b3cfc94af6cd5e777b5c..796da893087605bf520626ead6b5e37526317707 100644 (file)
@@ -89,6 +89,8 @@ struct lov_request_set {
 
 extern struct kmem_cache *lov_oinfo_slab;
 
+extern struct lu_kmem_descr lov_caches[];
+
 void lov_finish_set(struct lov_request_set *set);
 
 static inline void lov_get_reqset(struct lov_request_set *set)
@@ -124,7 +126,7 @@ static inline void lov_llh_put(struct lov_lock_handles *llh)
                if (atomic_read(&llh->llh_refcount))
                        return;
 
-               OBD_FREE_RCU(llh, sizeof *llh +
+               OBD_FREE_RCU(llh, sizeof(*llh) +
                             sizeof(*llh->llh_handles) * llh->llh_stripe_count,
                             &llh->llh_handle);
        }
index b611aa4e9dcb9b9a97640317e994bd6dc08975a5..2792fa5c4be2fb38dff7fc9b3d2082dbb1476a02 100644 (file)
@@ -86,7 +86,7 @@ static void lov_io_sub_inherit(struct cl_io *io, struct lov_io *lio,
        struct lov_stripe_md *lsm    = lio->lis_object->lo_lsm;
        struct cl_io     *parent = lio->lis_cl.cis_io;
 
-       switch(io->ci_type) {
+       switch (io->ci_type) {
        case CIT_SETATTR: {
                io->u.ci_setattr.sa_attr = parent->u.ci_setattr.sa_attr;
                io->u.ci_setattr.sa_valid = parent->u.ci_setattr.sa_valid;
@@ -282,7 +282,7 @@ static int lov_io_subio_init(const struct lu_env *env, struct lov_io *lio,
         * when writing a page. -jay
         */
        OBD_ALLOC_LARGE(lio->lis_subs,
-                       lsm->lsm_stripe_count * sizeof lio->lis_subs[0]);
+                       lsm->lsm_stripe_count * sizeof(lio->lis_subs[0]));
        if (lio->lis_subs != NULL) {
                lio->lis_nr_subios = lio->lis_stripe_count;
                lio->lis_single_subio_index = -1;
@@ -356,7 +356,7 @@ static void lov_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
                for (i = 0; i < lio->lis_nr_subios; i++)
                        lov_io_sub_fini(env, lio, &lio->lis_subs[i]);
                OBD_FREE_LARGE(lio->lis_subs,
-                        lio->lis_nr_subios * sizeof lio->lis_subs[0]);
+                        lio->lis_nr_subios * sizeof(lio->lis_subs[0]));
                lio->lis_nr_subios = 0;
        }
 
index ec297e87c2a2c2a048b8aa57a61203af92fbd0e3..26bc719b6dc87c5b29fc3ab829dc0d0c4ba36a91 100644 (file)
@@ -88,7 +88,7 @@ static struct lov_sublock_env *lov_sublock_env_get(const struct lu_env *env,
                        subenv->lse_io  = sub->sub_io;
                        subenv->lse_sub = sub;
                } else {
-                       subenv = (void*)sub;
+                       subenv = (void *)sub;
                }
        }
        return subenv;
@@ -167,7 +167,7 @@ static struct cl_lock *lov_sublock_alloc(const struct lu_env *env,
                        lov_sublock_env_put(subenv);
                } else {
                        /* error occurs. */
-                       sublock = (void*)subenv;
+                       sublock = (void *)subenv;
                }
 
                if (!IS_ERR(sublock))
@@ -313,7 +313,7 @@ static int lov_lock_sub_init(const struct lu_env *env,
                        nr++;
        }
        LASSERT(nr > 0);
-       OBD_ALLOC_LARGE(lck->lls_sub, nr * sizeof lck->lls_sub[0]);
+       OBD_ALLOC_LARGE(lck->lls_sub, nr * sizeof(lck->lls_sub[0]));
        if (lck->lls_sub == NULL)
                return -ENOMEM;
 
@@ -474,7 +474,7 @@ static void lov_lock_fini(const struct lu_env *env,
                         */
                        LASSERT(lck->lls_sub[i].sub_lock == NULL);
                OBD_FREE_LARGE(lck->lls_sub,
-                              lck->lls_nr * sizeof lck->lls_sub[0]);
+                              lck->lls_nr * sizeof(lck->lls_sub[0]));
        }
        OBD_SLAB_FREE_PTR(lck, lov_lock_kmem);
 }
@@ -742,7 +742,7 @@ static void lov_lock_cancel(const struct lu_env *env,
                                continue;
                        }
 
-                       switch(sublock->cll_state) {
+                       switch (sublock->cll_state) {
                        case CLS_HELD:
                                rc = cl_unuse_try(subenv->lse_env, sublock);
                                lov_sublock_release(env, lck, i, 0, 0);
index 0b47aba1332a15161fe39ea7aff15af275f11318..4783450774cd1909a39fbeaaa2d92d925eb88dad 100644 (file)
@@ -554,7 +554,7 @@ static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
                struct lov_tgt_desc **newtgts, **old = NULL;
                __u32 newsize, oldsize = 0;
 
-               newsize = max(lov->lov_tgt_size, (__u32)2);
+               newsize = max_t(__u32, lov->lov_tgt_size, 2);
                while (newsize < index + 1)
                        newsize = newsize << 1;
                OBD_ALLOC(newtgts, sizeof(*newtgts) * newsize);
@@ -923,7 +923,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg,
        int cmd;
        int rc = 0;
 
-       switch(cmd = lcfg->lcfg_command) {
+       switch (cmd = lcfg->lcfg_command) {
        case LCFG_LOV_ADD_OBD:
        case LCFG_LOV_ADD_INA:
        case LCFG_LOV_DEL_OBD: {
@@ -1090,7 +1090,7 @@ static int lov_destroy(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                GOTO(out, rc);
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                if (oa->o_valid & OBD_MD_FLCOOKIE)
@@ -1141,7 +1141,7 @@ static int lov_getattr(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx"
@@ -1227,7 +1227,7 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo,
 
        if (!list_empty(&rqset->set_requests)) {
                LASSERT(rc == 0);
-               LASSERT (rqset->set_interpret == NULL);
+               LASSERT(rqset->set_interpret == NULL);
                rqset->set_interpret = lov_getattr_interpret;
                rqset->set_arg = (void *)lovset;
                return rc;
@@ -1267,7 +1267,7 @@ static int lov_setattr(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_setattr(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1408,7 +1408,7 @@ static int lov_punch(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_punch(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1472,7 +1472,7 @@ static int lov_sync(const struct lu_env *env, struct obd_export *exp,
        CDEBUG(D_INFO, "fsync objid "DOSTID" ["LPX64", "LPX64"]\n",
               POSTID(&set->set_oi->oi_oa->o_oi), start, end);
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_sync(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1557,7 +1557,7 @@ static int lov_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                struct obd_export *sub_exp;
                struct brw_page *sub_pga;
                req = list_entry(pos, struct lov_request, rq_link);
@@ -1612,7 +1612,7 @@ static int lov_enqueue(struct obd_export *exp, struct obd_info *oinfo,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_enqueue(lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1828,7 +1828,7 @@ static int lov_statfs_async(struct obd_export *exp, struct obd_info *oinfo,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
                rc = obd_statfs_async(lov->lov_tgts[req->rq_idx]->ltd_exp,
                                      &req->rq_oi, max_age, rqset);
@@ -1909,7 +1909,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                                         (int) sizeof(struct obd_uuid))))
                        return -EFAULT;
 
-               flags = uarg ? *(__u32*)uarg : 0;
+               flags = uarg ? *(__u32 *)uarg : 0;
                /* got statfs data */
                rc = obd_statfs(NULL, lov->lov_tgts[index]->ltd_exp, &stat_buf,
                                cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
@@ -2495,7 +2495,7 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp,
                GOTO(out, rc);
        } else if (KEY_IS(KEY_CONNECT_FLAG)) {
                struct lov_tgt_desc *tgt;
-               __u64 ost_idx = *((__u64*)val);
+               __u64 ost_idx = *((__u64 *)val);
 
                LASSERT(*vallen == sizeof(__u64));
                LASSERT(ost_idx < lov->desc.ld_tgt_count);
@@ -2564,7 +2564,7 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
 
        for (i = 0; i < count; i++, val = (char *)val + incr) {
                if (next_id) {
-                       tgt = lov->lov_tgts[((struct obd_id_info*)val)->idx];
+                       tgt = lov->lov_tgts[((struct obd_id_info *)val)->idx];
                } else {
                        tgt = lov->lov_tgts[i];
                }
@@ -2593,9 +2593,9 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
                } else if (next_id) {
                        err = obd_set_info_async(env, tgt->ltd_exp,
                                         keylen, key, vallen,
-                                        ((struct obd_id_info*)val)->data, set);
+                                        ((struct obd_id_info *)val)->data, set);
                } else if (capa) {
-                       struct mds_capa_info *info = (struct mds_capa_info*)val;
+                       struct mds_capa_info *info = (struct mds_capa_info *)val;
 
                        LASSERT(vallen == sizeof(*info));
 
@@ -2781,7 +2781,7 @@ struct obd_ops lov_obd_ops = {
        .o_setup               = lov_setup,
        .o_precleanup     = lov_precleanup,
        .o_cleanup           = lov_cleanup,
-       //.o_process_config      = lov_process_config,
+       /*.o_process_config      = lov_process_config,*/
        .o_connect           = lov_connect,
        .o_disconnect     = lov_disconnect,
        .o_statfs             = lov_statfs,
@@ -2823,8 +2823,6 @@ struct obd_ops lov_obd_ops = {
 
 struct kmem_cache *lov_oinfo_slab;
 
-extern struct lu_kmem_descr lov_caches[];
-
 int __init lov_init(void)
 {
        struct lprocfs_static_vars lvars = { 0 };
index 84e55ce3ccd2217236ce176fe3ee7cb7b20cc762..cf2fa8abfb1dede0e69de8d8a59a5f97a82816c9 100644 (file)
@@ -214,7 +214,7 @@ static int lov_init_raid0(const struct lu_env *env,
        r0->lo_nr  = lsm->lsm_stripe_count;
        LASSERT(r0->lo_nr <= lov_targets_nr(dev));
 
-       OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof r0->lo_sub[0]);
+       OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof(r0->lo_sub[0]));
        if (r0->lo_sub != NULL) {
                result = 0;
                subconf->coc_inode = conf->coc_inode;
@@ -368,7 +368,7 @@ static void lov_fini_raid0(const struct lu_env *env, struct lov_object *lov,
        struct lov_layout_raid0 *r0 = &state->raid0;
 
        if (r0->lo_sub != NULL) {
-               OBD_FREE_LARGE(r0->lo_sub, r0->lo_nr * sizeof r0->lo_sub[0]);
+               OBD_FREE_LARGE(r0->lo_sub, r0->lo_nr * sizeof(r0->lo_sub[0]));
                r0->lo_sub = NULL;
        }
 
index 55ec26778f8043cb16276f7b1c35404d772c92af..ec6f6e0572ae906fd43ce7f3530449cd0e1eee62 100644 (file)
@@ -121,7 +121,7 @@ void lov_dump_lmm(int level, void *lmm)
 do {                                                               \
        if (!(test)) lov_dump_lmm(D_ERROR, lmm);                        \
        LASSERT(test); /* so we know what assertion failed */      \
-} while(0)
+} while (0)
 
 /* Pack LOV object metadata for disk storage.  It is packed in LE byte
  * order and is opaque to the networking layer.
@@ -630,22 +630,22 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
        /* FIXME: Bug 1185 - copy fields properly when structs change */
        /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */
        CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3));
-       CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]);
+       CLASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lmmk->lmm_objects[0]));
 
        if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
            ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
            (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) {
                lustre_swab_lov_mds_md(lmmk);
                lustre_swab_lov_user_md_objects(
-                               (struct lov_user_ost_data*)lmmk->lmm_objects,
+                               (struct lov_user_ost_data *)lmmk->lmm_objects,
                                lmmk->lmm_stripe_count);
        }
        if (lum.lmm_magic == LOV_USER_MAGIC) {
                /* User request for v1, we need skip lmm_pool_name */
                if (lmmk->lmm_magic == LOV_MAGIC_V3) {
-                       memmove((char*)(&lmmk->lmm_stripe_count) +
+                       memmove((char *)(&lmmk->lmm_stripe_count) +
                                sizeof(lmmk->lmm_stripe_count),
-                               ((struct lov_mds_md_v3*)lmmk)->lmm_objects,
+                               ((struct lov_mds_md_v3 *)lmmk)->lmm_objects,
                                lmmk->lmm_stripe_count *
                                sizeof(struct lov_ost_data_v1));
                        lmm_size -= LOV_MAXPOOLNAME;
index dd3c07d5c4de4f9974b1e2d4bc512a81877884dd..a1701dfe4083978764a403281c5f71be540ef037 100644 (file)
@@ -86,7 +86,7 @@ void lov_pool_putref_locked(struct pool_desc *pool)
  * Chapter 6.4.
  * Addison Wesley, 1973
  */
-static __u32 pool_hashfn(cfs_hash_t *hash_body, const void *key, unsigned mask)
+static __u32 pool_hashfn(struct cfs_hash *hash_body, const void *key, unsigned mask)
 {
        int i;
        __u32 result;
@@ -125,7 +125,7 @@ static void *pool_hashobject(struct hlist_node *hnode)
        return hlist_entry(hnode, struct pool_desc, pool_hash);
 }
 
-static void pool_hashrefcount_get(cfs_hash_t *hs, struct hlist_node *hnode)
+static void pool_hashrefcount_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct pool_desc *pool;
 
@@ -133,7 +133,7 @@ static void pool_hashrefcount_get(cfs_hash_t *hs, struct hlist_node *hnode)
        lov_pool_getref(pool);
 }
 
-static void pool_hashrefcount_put_locked(cfs_hash_t *hs,
+static void pool_hashrefcount_put_locked(struct cfs_hash *hs,
                                         struct hlist_node *hnode)
 {
        struct pool_desc *pool;
index 61e6d0b46c98e4898a43867ea0e79b20f8ada587..bf324ae2946f11cac0b0cdd4a04796094756d102 100644 (file)
@@ -245,7 +245,7 @@ int lov_update_enqueue_set(struct lov_request *req, __u32 mode, int rc)
        osc_update_enqueue(lov_lockhp, loi, oi->oi_flags,
                           &req->rq_oi.oi_md->lsm_oinfo[0]->loi_lvb, mode, rc);
        if (rc == ELDLM_LOCK_ABORTED && (oi->oi_flags & LDLM_FL_HAS_INTENT))
-               memset(lov_lockhp, 0, sizeof *lov_lockhp);
+               memset(lov_lockhp, 0, sizeof(*lov_lockhp));
        rc = lov_update_enqueue_lov(set->set_exp, lov_lockhp, loi, oi->oi_flags,
                                    req->rq_idx, &oi->oi_md->lsm_oi, rc);
        lov_stripe_unlock(oi->oi_md);
@@ -343,7 +343,7 @@ static struct lov_lock_handles *lov_llh_new(struct lov_stripe_md *lsm)
 {
        struct lov_lock_handles *llh;
 
-       OBD_ALLOC(llh, sizeof *llh +
+       OBD_ALLOC(llh, sizeof(*llh) +
                  sizeof(*llh->llh_handles) * lsm->lsm_stripe_count);
        if (llh == NULL)
                return NULL;
@@ -630,7 +630,7 @@ static int common_attr_done(struct lov_request_set *set)
        if (tmp_oa == NULL)
                GOTO(out, rc = -ENOMEM);
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                if (!req->rq_complete || req->rq_rc)
@@ -669,7 +669,7 @@ static int brw_done(struct lov_request_set *set)
        struct list_head *pos;
        struct lov_request *req;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                if (!req->rq_complete || req->rq_rc)
@@ -1315,7 +1315,7 @@ out_set:
                        (tot) = LOV_U64_MAX;                        \
                else                                                \
                        (tot) += (add);                          \
-       } while(0)
+       } while (0)
 
 int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,int success)
 {
index e86df7356cb1ee141e637d29b7e503f883bdbace..0d6ed69ddb223af36efff72419abad7bf6a91038 100644 (file)
@@ -50,9 +50,8 @@ static struct fsfilt_operations *fsfilt_search_type(const char *type)
 
        list_for_each(p, &fsfilt_types) {
                found = list_entry(p, struct fsfilt_operations, fs_list);
-               if (!strcmp(found->fs_type, type)) {
+               if (!strcmp(found->fs_type, type))
                        return found;
-               }
        }
        return NULL;
 }
@@ -62,7 +61,8 @@ int fsfilt_register_ops(struct fsfilt_operations *fs_ops)
        struct fsfilt_operations *found;
 
        /* lock fsfilt_types list */
-       if ((found = fsfilt_search_type(fs_ops->fs_type))) {
+       found = fsfilt_search_type(fs_ops->fs_type);
+       if (found) {
                if (found != fs_ops) {
                        CERROR("different operations for type %s\n",
                               fs_ops->fs_type);
@@ -103,14 +103,16 @@ struct fsfilt_operations *fsfilt_get_ops(const char *type)
        struct fsfilt_operations *fs_ops;
 
        /* lock fsfilt_types list */
-       if (!(fs_ops = fsfilt_search_type(type))) {
+       fs_ops = fsfilt_search_type(type);
+       if (!fs_ops) {
                char name[32];
                int rc;
 
                snprintf(name, sizeof(name) - 1, "fsfilt_%s", type);
                name[sizeof(name) - 1] = '\0';
 
-               if (!(rc = request_module("%s", name))) {
+               rc = request_module("%s", name);
+               if (!rc) {
                        fs_ops = fsfilt_search_type(type);
                        CDEBUG(D_INFO, "Loaded module '%s'\n", name);
                        if (!fs_ops)
index 97a8be2300dd1ad2ee417d617107766aad895f3b..b21e40cdacab21b6f80f94b1c3f324577e2ee9db 100644 (file)
@@ -154,11 +154,10 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid)
                                spin_lock(&stats->ls_lock);
                        if (stats->ls_biggest_alloc_num <= cpuid)
                                stats->ls_biggest_alloc_num = cpuid + 1;
-                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
+                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
                                spin_unlock_irqrestore(&stats->ls_lock, flags);
-                       } else {
+                       else
                                spin_unlock(&stats->ls_lock);
-                       }
                }
                /* initialize the ls_percpu[cpuid] non-zero counter */
                for (i = 0; i < stats->ls_num; ++i) {
index 18e1b47a1d65aaebf5c3312670e43017232780f8..1ef06fea793be43f83499785de2be71427b64815 100644 (file)
@@ -65,9 +65,9 @@ EXPORT_SYMBOL(obd_memory);
                                              msg)
 # define ASSERT_KERNEL_CTXT(msg) LASSERTF(segment_eq(get_fs(), get_ds()), msg)
 #else
-# define ASSERT_CTXT_MAGIC(magic) do {} while(0)
-# define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0)
-# define ASSERT_KERNEL_CTXT(msg) do {} while(0)
+# define ASSERT_CTXT_MAGIC(magic) do {} while (0)
+# define ASSERT_NOT_KERNEL_CTXT(msg) do {} while (0)
+# define ASSERT_KERNEL_CTXT(msg) do {} while (0)
 #endif
 
 static void push_group_info(struct lvfs_run_ctxt *save,
@@ -80,7 +80,8 @@ static void push_group_info(struct lvfs_run_ctxt *save,
                struct cred *cred;
                task_lock(current);
                save->group_info = current_cred()->group_info;
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->group_info = ginfo;
                        commit_creds(cred);
                }
@@ -96,7 +97,8 @@ static void pop_group_info(struct lvfs_run_ctxt *save,
        } else {
                struct cred *cred;
                task_lock(current);
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->group_info = save->group_info;
                        commit_creds(cred);
                }
@@ -112,7 +114,7 @@ void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
        if (new_ctx->dt != NULL)
                return;
 
-       //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n");
+       /* ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n"); */
        ASSERT_CTXT_MAGIC(new_ctx->magic);
        OBD_SET_CTXT_MAGIC(save);
 
@@ -137,7 +139,8 @@ void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
                save->luc.luc_fsgid = current_fsgid();
                save->luc.luc_cap = current_cap();
 
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->uid = uc->luc_uid;
                        cred->gid = uc->luc_gid;
                        cred->fsuid = uc->luc_fsuid;
@@ -180,7 +183,8 @@ void pop_ctxt(struct lvfs_run_ctxt *saved, struct lvfs_run_ctxt *new_ctx,
        current->fs->umask = saved->luc.luc_umask;
        if (uc) {
                struct cred *cred;
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->uid = saved->luc.luc_uid;
                        cred->gid = saved->luc.luc_gid;
                        cred->fsuid = saved->luc.luc_fsuid;
@@ -253,32 +257,32 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc,
                return 0;
 
        switch (field) {
-               case LPROCFS_FIELDS_FLAGS_CONFIG:
-                       ret = header->lc_config;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_SUM:
-                       ret = lc->lc_sum;
-                       if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
-                               ret += lc->lc_sum_irq;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_MIN:
-                       ret = lc->lc_min;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_MAX:
-                       ret = lc->lc_max;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_AVG:
-                       ret = (lc->lc_max - lc->lc_min) / 2;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_SUMSQUARE:
-                       ret = lc->lc_sumsquare;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_COUNT:
-                       ret = lc->lc_count;
-                       break;
-               default:
-                       break;
-       };
+       case LPROCFS_FIELDS_FLAGS_CONFIG:
+               ret = header->lc_config;
+               break;
+       case LPROCFS_FIELDS_FLAGS_SUM:
+               ret = lc->lc_sum;
+               if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
+                       ret += lc->lc_sum_irq;
+               break;
+       case LPROCFS_FIELDS_FLAGS_MIN:
+               ret = lc->lc_min;
+               break;
+       case LPROCFS_FIELDS_FLAGS_MAX:
+               ret = lc->lc_max;
+               break;
+       case LPROCFS_FIELDS_FLAGS_AVG:
+               ret = (lc->lc_max - lc->lc_min) / 2;
+               break;
+       case LPROCFS_FIELDS_FLAGS_SUMSQUARE:
+               ret = lc->lc_sumsquare;
+               break;
+       case LPROCFS_FIELDS_FLAGS_COUNT:
+               ret = lc->lc_count;
+               break;
+       default:
+               break;
+       }
 
        return ret;
 }
index 42697934155493e5c1c5a79576bce699f3f1ee28..e048500edd60c680aa280d872fe34f576ba66172 100644 (file)
@@ -1387,7 +1387,7 @@ static void cl_req_free(const struct lu_env *env, struct cl_req *req)
                                cl_object_put(env, obj);
                        }
                }
-               OBD_FREE(req->crq_o, req->crq_nrobjs * sizeof req->crq_o[0]);
+               OBD_FREE(req->crq_o, req->crq_nrobjs * sizeof(req->crq_o[0]));
        }
        OBD_FREE_PTR(req);
 }
@@ -1452,7 +1452,7 @@ struct cl_req *cl_req_alloc(const struct lu_env *env, struct cl_page *page,
        if (req != NULL) {
                int result;
 
-               OBD_ALLOC(req->crq_o, nr_objects * sizeof req->crq_o[0]);
+               OBD_ALLOC(req->crq_o, nr_objects * sizeof(req->crq_o[0]));
                if (req->crq_o != NULL) {
                        req->crq_nrobjs = nr_objects;
                        req->crq_type = crt;
@@ -1642,7 +1642,7 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
                cpu_relax();
        }
 
-       POISON(anchor, 0x5a, sizeof *anchor);
+       POISON(anchor, 0x5a, sizeof(*anchor));
        return rc;
 }
 EXPORT_SYMBOL(cl_sync_io_wait);
index 7b0e9d26b6c10aa1ad30509eb5c13e9c5b7b6c66..1a926036724b8f7d30c5bb8ab5b0b03158b5ebc6 100644 (file)
@@ -577,9 +577,9 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
  * The implementation of using hash table to connect cl_env and thread
  */
 
-static cfs_hash_t *cl_env_hash;
+static struct cfs_hash *cl_env_hash;
 
-static unsigned cl_env_hops_hash(cfs_hash_t *lh,
+static unsigned cl_env_hops_hash(struct cfs_hash *lh,
                                 const void *key, unsigned mask)
 {
 #if BITS_PER_LONG == 64
@@ -604,7 +604,7 @@ static int cl_env_hops_keycmp(const void *key, struct hlist_node *hn)
        return (key == cle->ce_owner);
 }
 
-static void cl_env_hops_noop(cfs_hash_t *hs, struct hlist_node *hn)
+static void cl_env_hops_noop(struct cfs_hash *hs, struct hlist_node *hn)
 {
        struct cl_env *cle = hlist_entry(hn, struct cl_env, ce_node);
        LASSERT(cle->ce_magic == &cl_env_init0);
index b1024a6d37dd95ef215a489d07b5de76f2ec3f66..4afd962cdb64db50c83f5312b656ed0fe6131b4f 100644 (file)
@@ -178,7 +178,7 @@ EXPORT_SYMBOL(obd_alloc_fail);
 static inline void obd_data2conn(struct lustre_handle *conn,
                                 struct obd_ioctl_data *data)
 {
-       memset(conn, 0, sizeof *conn);
+       memset(conn, 0, sizeof(*conn));
        conn->cookie = data->ioc_cookie;
 }
 
index 68fe71c8a2a9dbf0d8f18aa4f018debe38d842b7..f6fae16fc7f7f75d0cdd507707d29d0eb7e3f8b0 100644 (file)
@@ -816,7 +816,7 @@ struct obd_export *class_new_export(struct obd_device *obd,
                                    struct obd_uuid *cluuid)
 {
        struct obd_export *export;
-       cfs_hash_t *hash = NULL;
+       struct cfs_hash *hash = NULL;
        int rc = 0;
 
        OBD_ALLOC_PTR(export);
@@ -1384,7 +1384,7 @@ EXPORT_SYMBOL(obd_export_nid2str);
 
 int obd_export_evict_by_nid(struct obd_device *obd, const char *nid)
 {
-       cfs_hash_t *nid_hash;
+       struct cfs_hash *nid_hash;
        struct obd_export *doomed_exp = NULL;
        int exports_evicted = 0;
 
@@ -1432,7 +1432,7 @@ EXPORT_SYMBOL(obd_export_evict_by_nid);
 
 int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid)
 {
-       cfs_hash_t *uuid_hash;
+       struct cfs_hash *uuid_hash;
        struct obd_export *doomed_exp = NULL;
        struct obd_uuid doomed_uuid;
        int exports_evicted = 0;
index d9e6d12215f904307b7d42483fbac272a19b002e..178f89eccab11d25229c801f2e2ad9f244f33c07 100644 (file)
@@ -242,7 +242,7 @@ static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
 
                hdr.lrh_len = 8;
                hdr.lrh_type = OBD_CFG_REC;
-               memset(buf, 0, sizeof buf);
+               memset(buf, 0, sizeof(buf));
                rc = llog_write(env, llh, &hdr, NULL, 0, buf, -1);
                if (rc < 0) {
                        CERROR("3b: write 10 records failed at #%d: %d\n",
@@ -277,8 +277,8 @@ static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
                char                    buf_even[24];
                char                    buf_odd[32];
 
-               memset(buf_odd, 0, sizeof buf_odd);
-               memset(buf_even, 0, sizeof buf_even);
+               memset(buf_odd, 0, sizeof(buf_odd));
+               memset(buf_even, 0, sizeof(buf_even));
                if ((i % 2) == 0) {
                        hdr.lrh_len = 24;
                        hdr.lrh_type = OBD_CFG_REC;
index a95f60a4f90e7b8bc4cadbf2917eccfd5ca491cc..02d76f8dbcb9b58da43d253433c69099d3b073b4 100644 (file)
@@ -898,7 +898,7 @@ static void lprocfs_free_client_stats(struct nid_stat *client_stat)
 
 void lprocfs_free_per_client_stats(struct obd_device *obd)
 {
-       cfs_hash_t *hash = obd->obd_nid_stats_hash;
+       struct cfs_hash *hash = obd->obd_nid_stats_hash;
        struct nid_stat *stat;
 
        /* we need extra list - because hash_exit called to early */
@@ -1069,7 +1069,7 @@ static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
                struct timeval now;
                do_gettimeofday(&now);
                rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
-                               "snapshot_time", now.tv_sec, now.tv_usec);
+                               "snapshot_time", now.tv_sec, (unsigned long)now.tv_usec);
                if (rc < 0)
                        return rc;
        }
@@ -1422,7 +1422,7 @@ void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
 }
 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
 
-int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+int lprocfs_exp_print_uuid(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                           struct hlist_node *hnode, void *data)
 
 {
@@ -1453,7 +1453,7 @@ struct exp_hash_cb_data {
        bool            first;
 };
 
-int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+int lprocfs_exp_print_hash(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                           struct hlist_node *hnode, void *cb_data)
 
 {
index 3a3d5bc5a628a05e45def8d74112e55138655a80..212823ab937b759f6dbe7537e4e4a45d100d00e5 100644 (file)
@@ -71,7 +71,7 @@ void lu_object_put(const struct lu_env *env, struct lu_object *o)
        struct lu_object_header *top;
        struct lu_site    *site;
        struct lu_object        *orig;
-       cfs_hash_bd_t       bd;
+       struct cfs_hash_bd          bd;
        const struct lu_fid     *fid;
 
        top  = o->lo_header;
@@ -175,8 +175,8 @@ void lu_object_unhash(const struct lu_env *env, struct lu_object *o)
        top = o->lo_header;
        set_bit(LU_OBJECT_HEARD_BANSHEE, &top->loh_flags);
        if (!test_and_set_bit(LU_OBJECT_UNHASHED, &top->loh_flags)) {
-               cfs_hash_t *obj_hash = o->lo_dev->ld_site->ls_obj_hash;
-               cfs_hash_bd_t bd;
+               struct cfs_hash *obj_hash = o->lo_dev->ld_site->ls_obj_hash;
+               struct cfs_hash_bd bd;
 
                cfs_hash_bd_get_and_lock(obj_hash, &top->loh_fid, &bd, 1);
                list_del_init(&top->loh_lru);
@@ -306,8 +306,8 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr)
        struct lu_object_header *h;
        struct lu_object_header *temp;
        struct lu_site_bkt_data *bkt;
-       cfs_hash_bd_t       bd;
-       cfs_hash_bd_t       bd2;
+       struct cfs_hash_bd          bd;
+       struct cfs_hash_bd          bd2;
        struct list_head               dispose;
        int                   did_sth;
        int                   start;
@@ -526,7 +526,7 @@ int lu_object_invariant(const struct lu_object *o)
 EXPORT_SYMBOL(lu_object_invariant);
 
 static struct lu_object *htable_lookup(struct lu_site *s,
-                                      cfs_hash_bd_t *bd,
+                                      struct cfs_hash_bd *bd,
                                       const struct lu_fid *f,
                                       wait_queue_t *waiter,
                                       __u64 *version)
@@ -589,8 +589,8 @@ static struct lu_object *lu_object_new(const struct lu_env *env,
                                       const struct lu_object_conf *conf)
 {
        struct lu_object        *o;
-       cfs_hash_t            *hs;
-       cfs_hash_bd_t       bd;
+       struct cfs_hash       *hs;
+       struct cfs_hash_bd          bd;
        struct lu_site_bkt_data *bkt;
 
        o = lu_object_alloc(env, dev, f, conf);
@@ -618,8 +618,8 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env,
        struct lu_object      *o;
        struct lu_object      *shadow;
        struct lu_site  *s;
-       cfs_hash_t          *hs;
-       cfs_hash_bd_t     bd;
+       struct cfs_hash     *hs;
+       struct cfs_hash_bd        bd;
        __u64             version = 0;
 
        /*
@@ -788,7 +788,7 @@ struct lu_site_print_arg {
 };
 
 static int
-lu_site_obj_print(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+lu_site_obj_print(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                  struct hlist_node *hnode, void *data)
 {
        struct lu_site_print_arg *arg = (struct lu_site_print_arg *)data;
@@ -874,7 +874,7 @@ static int lu_htable_order(void)
        return bits;
 }
 
-static unsigned lu_obj_hop_hash(cfs_hash_t *hs,
+static unsigned lu_obj_hop_hash(struct cfs_hash *hs,
                                const void *key, unsigned mask)
 {
        struct lu_fid  *fid = (struct lu_fid *)key;
@@ -914,14 +914,14 @@ static int lu_obj_hop_keycmp(const void *key, struct hlist_node *hnode)
        return lu_fid_eq(&h->loh_fid, (struct lu_fid *)key);
 }
 
-static void lu_obj_hop_get(cfs_hash_t *hs, struct hlist_node *hnode)
+static void lu_obj_hop_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct lu_object_header *h;
 
        h = hlist_entry(hnode, struct lu_object_header, loh_hash);
        if (atomic_add_return(1, &h->loh_ref) == 1) {
                struct lu_site_bkt_data *bkt;
-               cfs_hash_bd_t       bd;
+               struct cfs_hash_bd          bd;
 
                cfs_hash_bd_get(hs, &h->loh_fid, &bd);
                bkt = cfs_hash_bd_extra_get(hs, &bd);
@@ -929,7 +929,7 @@ static void lu_obj_hop_get(cfs_hash_t *hs, struct hlist_node *hnode)
        }
 }
 
-static void lu_obj_hop_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+static void lu_obj_hop_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        LBUG(); /* we should never called it */
 }
@@ -975,12 +975,12 @@ EXPORT_SYMBOL(lu_dev_del_linkage);
 int lu_site_init(struct lu_site *s, struct lu_device *top)
 {
        struct lu_site_bkt_data *bkt;
-       cfs_hash_bd_t bd;
+       struct cfs_hash_bd bd;
        char name[16];
        int bits;
        int i;
 
-       memset(s, 0, sizeof *s);
+       memset(s, 0, sizeof(*s));
        bits = lu_htable_order();
        snprintf(name, 16, "lu_site_%s", top->ld_type->ldt_name);
        for (bits = min(max(LU_SITE_BITS_MIN, bits), LU_SITE_BITS_MAX);
@@ -1110,7 +1110,7 @@ int lu_device_init(struct lu_device *d, struct lu_device_type *t)
 {
        if (t->ldt_device_nr++ == 0 && t->ldt_ops->ldto_start != NULL)
                t->ldt_ops->ldto_start(t);
-       memset(d, 0, sizeof *d);
+       memset(d, 0, sizeof(*d));
        atomic_set(&d->ld_ref, 0);
        d->ld_type = t;
        lu_ref_init(&d->ld_reference);
@@ -1206,7 +1206,7 @@ EXPORT_SYMBOL(lu_object_add);
  */
 int lu_object_header_init(struct lu_object_header *h)
 {
-       memset(h, 0, sizeof *h);
+       memset(h, 0, sizeof(*h));
        atomic_set(&h->loh_ref, 1);
        INIT_HLIST_NODE(&h->loh_hash);
        INIT_LIST_HEAD(&h->loh_lru);
@@ -1525,7 +1525,7 @@ static void keys_fini(struct lu_context *ctx)
        for (i = 0; i < ARRAY_SIZE(lu_keys); ++i)
                key_fini(ctx, i);
 
-       OBD_FREE(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
+       OBD_FREE(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof(ctx->lc_value[0]));
        ctx->lc_value = NULL;
 }
 
@@ -1574,7 +1574,8 @@ static int keys_fill(struct lu_context *ctx)
 
 static int keys_init(struct lu_context *ctx)
 {
-       OBD_ALLOC(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
+       OBD_ALLOC(ctx->lc_value,
+                 ARRAY_SIZE(lu_keys) * sizeof(ctx->lc_value[0]));
        if (likely(ctx->lc_value != NULL))
                return keys_fill(ctx);
 
@@ -1588,7 +1589,7 @@ int lu_context_init(struct lu_context *ctx, __u32 tags)
 {
        int     rc;
 
-       memset(ctx, 0, sizeof *ctx);
+       memset(ctx, 0, sizeof(*ctx));
        ctx->lc_state = LCS_INITIALIZED;
        ctx->lc_tags = tags;
        if (tags & LCT_REMEMBER) {
@@ -1787,10 +1788,10 @@ typedef struct lu_site_stats{
        unsigned        lss_busy;
 } lu_site_stats_t;
 
-static void lu_site_stats_get(cfs_hash_t *hs,
+static void lu_site_stats_get(struct cfs_hash *hs,
                              lu_site_stats_t *stats, int populated)
 {
-       cfs_hash_bd_t bd;
+       struct cfs_hash_bd bd;
        int        i;
 
        cfs_hash_for_each_bucket(hs, &bd, i) {
@@ -2071,8 +2072,8 @@ void lu_object_assign_fid(const struct lu_env *env, struct lu_object *o,
        struct lu_site_bkt_data *bkt;
        struct lu_object        *shadow;
        wait_queue_t             waiter;
-       cfs_hash_t              *hs;
-       cfs_hash_bd_t            bd;
+       struct cfs_hash         *hs;
+       struct cfs_hash_bd       bd;
        __u64                    version = 0;
 
        LASSERT(fid_is_zero(old));
index d0a64ff53581e5871abf99379fe387e0b979dd2c..362ae541b209ea90a263d62131d8b0f450bdd6f0 100644 (file)
@@ -417,7 +417,7 @@ int class_attach(struct lustre_cfg *lcfg)
 
        /* do the attach */
        if (OBP(obd, attach)) {
-               rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
+               rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
                if (rc)
                        GOTO(out, rc = -EINVAL);
        }
@@ -900,7 +900,7 @@ void class_del_profile(const char *prof)
                OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
                if (lprof->lp_md)
                        OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
-               OBD_FREE(lprof, sizeof *lprof);
+               OBD_FREE(lprof, sizeof(*lprof));
        }
 }
 EXPORT_SYMBOL(class_del_profile);
@@ -916,7 +916,7 @@ void class_del_profiles(void)
                OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
                if (lprof->lp_md)
                        OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
-               OBD_FREE(lprof, sizeof *lprof);
+               OBD_FREE(lprof, sizeof(*lprof));
        }
 }
 EXPORT_SYMBOL(class_del_profiles);
@@ -1692,7 +1692,7 @@ EXPORT_SYMBOL(class_manual_cleanup);
  */
 
 static unsigned
-uuid_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+uuid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return cfs_hash_djb2_hash(((struct obd_uuid *)key)->uuid,
                                  sizeof(((struct obd_uuid *)key)->uuid), mask);
@@ -1731,7 +1731,7 @@ uuid_export_object(struct hlist_node *hnode)
 }
 
 static void
-uuid_export_get(cfs_hash_t *hs, struct hlist_node *hnode)
+uuid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct obd_export *exp;
 
@@ -1740,7 +1740,7 @@ uuid_export_get(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-uuid_export_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+uuid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct obd_export *exp;
 
@@ -1763,7 +1763,7 @@ static cfs_hash_ops_t uuid_hash_ops = {
  */
 
 static unsigned
-nid_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+nid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return cfs_hash_djb2_hash(key, sizeof(lnet_nid_t), mask);
 }
@@ -1801,7 +1801,7 @@ nid_export_object(struct hlist_node *hnode)
 }
 
 static void
-nid_export_get(cfs_hash_t *hs, struct hlist_node *hnode)
+nid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct obd_export *exp;
 
@@ -1810,7 +1810,7 @@ nid_export_get(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-nid_export_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+nid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct obd_export *exp;
 
@@ -1855,7 +1855,7 @@ nidstats_object(struct hlist_node *hnode)
 }
 
 static void
-nidstats_get(cfs_hash_t *hs, struct hlist_node *hnode)
+nidstats_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct nid_stat *ns;
 
@@ -1864,7 +1864,7 @@ nidstats_get(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-nidstats_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+nidstats_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct nid_stat *ns;
 
index af5f27f82bc5b157b02de284c2dff886c6974dee..e87a19900770574282e8a3da3357efc78b0292b1 100644 (file)
@@ -48,7 +48,7 @@ static inline __u32 consume(int nob, __u8 **ptr)
 {
        __u32 value;
 
-       LASSERT(nob <= sizeof value);
+       LASSERT(nob <= sizeof(value));
 
        for (value = 0; nob > 0; --nob)
                value = (value << 8) | *((*ptr)++);
@@ -61,7 +61,7 @@ static void uuid_unpack(class_uuid_t in, __u16 *uu, int nr)
 {
        __u8 *ptr = in;
 
-       LASSERT(nr * sizeof *uu == sizeof(class_uuid_t));
+       LASSERT(nr * sizeof(*uu) == sizeof(class_uuid_t));
 
        while (nr-- > 0)
                CONSUME(uu[nr], &ptr);
index c8b43442dc74be8c8cf1ee3f5b38470f63617e71..1fb0ac4e920d58136163b7bd244fe782ecdc493a 100644 (file)
@@ -1089,7 +1089,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d,
                } else {
                        struct lustre_md *md;
                        md = &info->eti_md;
-                       memset(md, 0, sizeof *md);
+                       memset(md, 0, sizeof(*md));
                        md->lsm = lsm;
                        conf->eoc_cl.u.coc_md = md;
                }
index 90d24d8dea21cad71b39120244b748910160198a..ef10e2af787f9dc8bce0b78717da82a443c009e7 100644 (file)
@@ -571,7 +571,7 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
        client_obd_list_lock(&cli->cl_loi_list_lock);
 
        seq_printf(seq, "snapshot_time:  %lu.%lu (secs.usecs)\n",
-                  now.tv_sec, now.tv_usec);
+                  now.tv_sec, (unsigned long)now.tv_usec);
        seq_printf(seq, "read RPCs in flight:  %d\n",
                   cli->cl_r_in_flight);
        seq_printf(seq, "write RPCs in flight: %d\n",
@@ -683,7 +683,7 @@ static int osc_stats_seq_show(struct seq_file *seq, void *v)
        do_gettimeofday(&now);
 
        seq_printf(seq, "snapshot_time:  %lu.%lu (secs.usecs)\n",
-                  now.tv_sec, now.tv_usec);
+                  now.tv_sec, (unsigned long)now.tv_usec);
        seq_printf(seq, "lockless_write_bytes\t\t"LPU64"\n",
                   stats->os_lockless_writes);
        seq_printf(seq, "lockless_read_bytes\t\t"LPU64"\n",
index 3aeaf845cf278f69b917198aba4460c60ac50a7a..681d60a7d5efc3faf0696f0a17fc1931d424cde7 100644 (file)
@@ -105,7 +105,7 @@ static int osc_io_submit(const struct lu_env *env,
        struct osc_object *osc  = NULL; /* to keep gcc happy */
        struct osc_page   *opg;
        struct cl_io      *io;
-       LIST_HEAD     (list);
+       LIST_HEAD(list);
 
        struct cl_page_list *qin      = &queue->c2_qin;
        struct cl_page_list *qout     = &queue->c2_qout;
index 5d7bdbfc871af2c9e0e2dd3b4bad76e3771f1a31..c90abfbb1d7a52cd25374d1336ab014a5252d08a 100644 (file)
@@ -862,7 +862,7 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data)
                        cap = &req->rq_pill;
                        req_capsule_extend(cap, &RQF_LDLM_GL_CALLBACK);
                        req_capsule_set_size(cap, &RMF_DLM_LVB, RCL_SERVER,
-                                            sizeof *lvb);
+                                            sizeof(*lvb));
                        result = req_capsule_server_pack(cap);
                        if (result == 0) {
                                lvb = req_capsule_server_get(cap, &RMF_DLM_LVB);
index d272322b29b6618ddad867720ae8be6c0b5825c2..6c20b8ecfb8200080c599236c6cb4445bde940ff 100644 (file)
@@ -245,7 +245,7 @@ static int osc_page_cache_add(const struct lu_env *env,
 void osc_index2policy(ldlm_policy_data_t *policy, const struct cl_object *obj,
                      pgoff_t start, pgoff_t end)
 {
-       memset(policy, 0, sizeof *policy);
+       memset(policy, 0, sizeof(*policy));
        policy->l_extent.start = cl_offset(obj, start);
        policy->l_extent.end   = cl_offset(obj, end + 1) - 1;
 }
index 9720c0e865c8d49c55f6d6b6d0360561523d1178..6045a78a2baa21d309bbc3ba7712f2d23996527a 100644 (file)
@@ -139,7 +139,7 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
  * Hash operations for uid/gid <-> osc_quota_info
  */
 static unsigned
-oqi_hashfn(cfs_hash_t *hs, const void *key, unsigned mask)
+oqi_hashfn(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return cfs_hash_u32_hash(*((__u32*)key), mask);
 }
@@ -172,17 +172,17 @@ oqi_object(struct hlist_node *hnode)
 }
 
 static void
-oqi_get(cfs_hash_t *hs, struct hlist_node *hnode)
+oqi_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
 }
 
 static void
-oqi_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+oqi_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
 }
 
 static void
-oqi_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+oqi_exit(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct osc_quota_info *oqi;
 
index ee6707a5ea9d8e9ddb99053fa479836bfcc5cb77..cb197782d9a3378c0060a21614a8a5fda06be166 100644 (file)
@@ -2554,7 +2554,7 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
                }
 
                req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
-                                    sizeof *lvb);
+                                    sizeof(*lvb));
                ptlrpc_request_set_replen(req);
        }
 
index 810a458caed73aaea8a34e0ba1abb65f12336d0a..c2ab0c8c4d42520b16be642385636240f7cb8a9e 100644 (file)
@@ -817,7 +817,7 @@ struct ptlrpc_request_set *ptlrpc_prep_set(void)
 {
        struct ptlrpc_request_set *set;
 
-       OBD_ALLOC(set, sizeof *set);
+       OBD_ALLOC(set, sizeof(*set));
        if (!set)
                return NULL;
        atomic_set(&set->set_refcount, 1);
@@ -2690,7 +2690,7 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
 
        LASSERT (sizeof (*aa) <= sizeof (req->rq_async_args));
        aa = ptlrpc_req_async_args(req);
-       memset(aa, 0, sizeof *aa);
+       memset(aa, 0, sizeof(*aa));
 
        /* Prepare request to be resent with ptlrpcd */
        aa->praa_old_state = req->rq_send_state;
index 17ca84208873f51bc9025b1b306606c1fe803e1c..6756356faac1be1be5855f8e6221441ad804d45f 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "ptlrpc_internal.h"
 
-static cfs_hash_t *conn_hash = NULL;
+static struct cfs_hash *conn_hash = NULL;
 static cfs_hash_ops_t conn_hash_ops;
 
 struct ptlrpc_connection *
@@ -161,7 +161,7 @@ EXPORT_SYMBOL(ptlrpc_connection_fini);
  * Hash operations for net_peer<->connection
  */
 static unsigned
-conn_hashfn(cfs_hash_t *hs, const void *key, unsigned mask)
+conn_hashfn(struct cfs_hash *hs, const void *key, unsigned mask)
 {
        return cfs_hash_djb2_hash(key, sizeof(lnet_process_id_t), mask);
 }
@@ -195,7 +195,7 @@ conn_object(struct hlist_node *hnode)
 }
 
 static void
-conn_get(cfs_hash_t *hs, struct hlist_node *hnode)
+conn_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ptlrpc_connection *conn;
 
@@ -204,7 +204,7 @@ conn_get(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-conn_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+conn_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ptlrpc_connection *conn;
 
@@ -213,7 +213,7 @@ conn_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
 }
 
 static void
-conn_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+conn_exit(struct cfs_hash *hs, struct hlist_node *hnode)
 {
        struct ptlrpc_connection *conn;
 
index 5ca69aec72e1594ffc8235ede4447ee63c31ead8..7b96a0e88cdbb5cd1f63d0096c2d7d81d737ea05 100644 (file)
@@ -682,7 +682,7 @@ int ptlrpc_connect_import(struct obd_import *imp)
 
        CLASSERT(sizeof (*aa) <= sizeof (request->rq_async_args));
        aa = ptlrpc_req_async_args(request);
-       memset(aa, 0, sizeof *aa);
+       memset(aa, 0, sizeof(*aa));
 
        aa->pcaa_peer_committed = committed_before_reconnect;
        aa->pcaa_initial_connect = initial_connect;
index 2f55ce26ccbafc6dbded4a8ad08c69af9fb4c617..d0a6e56892271c2bc00072e207f74248f84209a1 100644 (file)
@@ -1669,7 +1669,7 @@ void req_capsule_init(struct req_capsule *pill,
        if (req != NULL && pill == &req->rq_pill && req->rq_pill_init)
                return;
 
-       memset(pill, 0, sizeof *pill);
+       memset(pill, 0, sizeof(*pill));
        pill->rc_req = req;
        pill->rc_loc = location;
        req_capsule_init_area(pill);
index 6547f46a7729f2f95c16f9bdff5e334a43806eea..316103ab7c3c056fa760db06cc49babb9d6ab28b 100644 (file)
@@ -207,7 +207,7 @@ static void enc_pools_release_free_pages(long npages)
                        p_idx++;
                        g_idx = 0;
                }
-       };
+       }
 
        /* free unused pools */
        while (p_idx_max1 < p_idx_max2) {
index acf75f3873d1ffb0ab9cc4258150b3a9a1b2e3ba..21de868da522ae813d798d588132f74c5d819f7b 100644 (file)
@@ -263,7 +263,7 @@ static struct ptlrpc_hr_service             ptlrpc_hr;
  */
 static void rs_batch_init(struct rs_batch *b)
 {
-       memset(b, 0, sizeof *b);
+       memset(b, 0, sizeof(*b));
        INIT_LIST_HEAD(&b->rsb_replies);
 }
 
@@ -1306,12 +1306,12 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
        }
        newdl = cfs_time_current_sec() + at_get(&svcpt->scp_at_estimate);
 
-       OBD_ALLOC(reqcopy, sizeof *reqcopy);
+       OBD_ALLOC(reqcopy, sizeof(*reqcopy));
        if (reqcopy == NULL)
                return -ENOMEM;
        OBD_ALLOC_LARGE(reqmsg, req->rq_reqlen);
        if (!reqmsg) {
-               OBD_FREE(reqcopy, sizeof *reqcopy);
+               OBD_FREE(reqcopy, sizeof(*reqcopy));
                return -ENOMEM;
        }
 
@@ -1370,7 +1370,7 @@ out_put:
 out:
        sptlrpc_svc_ctx_decref(reqcopy);
        OBD_FREE_LARGE(reqmsg, req->rq_reqlen);
-       OBD_FREE(reqcopy, sizeof *reqcopy);
+       OBD_FREE(reqcopy, sizeof(*reqcopy));
        return rc;
 }
 
index 46ed8324503500290885268e36cd0587639c8b8f..58684da45e6c2927cb042ceb0dc4a364b3037a5c 100644 (file)
 
 static unsigned int assume_endura;
 module_param(assume_endura, int, 0644);
-MODULE_PARM_DESC(assume_endura, "when probing fails, "
-                               "hardware is a Pelco Endura");
+MODULE_PARM_DESC(assume_endura,
+                       "when probing fails, hardware is a Pelco Endura");
 
-/* #define GO7007_USB_DEBUG */
 /* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
 
 #define        HPI_STATUS_ADDR 0xFFF4
@@ -662,9 +661,7 @@ static int go7007_usb_interface_reset(struct go7007 *go)
 
        if (usb->board->flags & GO7007_USB_EZUSB) {
                /* Reset buffer in EZ-USB */
-#ifdef GO7007_USB_DEBUG
-               printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
-#endif
+               dev_dbg(go->dev, "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;
@@ -678,8 +675,7 @@ static int go7007_usb_interface_reset(struct go7007 *go)
        /* Wait for an interrupt to indicate successful hardware reset */
        if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
                        (intr_val & ~0x1) != 0x55aa) {
-               printk(KERN_ERR
-                       "go7007-usb: unable to reset the USB interface\n");
+               dev_err(go->dev, "unable to reset the USB interface\n");
                return -1;
        }
        return 0;
@@ -693,10 +689,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        u16 status_reg = 0;
        int timeout = 500;
 
-#ifdef GO7007_USB_DEBUG
-       printk(KERN_DEBUG
-               "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
+       dev_dbg(go->dev, "WriteInterrupt: %04x %04x\n", addr, data);
 
        for (i = 0; i < 100; ++i) {
                r = usb_control_msg(usb->usbdev,
@@ -714,9 +707,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        if (r < 0)
                goto write_int_error;
        if (i == 100) {
-               printk(KERN_ERR
-                       "go7007-usb: device is hung, status reg = 0x%04x\n",
-                       status_reg);
+               dev_err(go->dev, "device is hung, status reg = 0x%04x\n", status_reg);
                return -1;
        }
        r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
@@ -732,7 +723,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        return 0;
 
 write_int_error:
-       printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
+       dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
        return r;
 }
 
@@ -743,10 +734,7 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
        int r;
        int timeout = 500;
 
-#ifdef GO7007_USB_DEBUG
-       printk(KERN_DEBUG
-               "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
+       dev_dbg(go->dev, "WriteInterrupt: %04x %04x\n", addr, data);
 
        go->usb_buf[0] = data & 0xff;
        go->usb_buf[1] = data >> 8;
@@ -757,7 +745,7 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
                        USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
                        0xf0f0, go->usb_buf, 8, timeout);
        if (r < 0) {
-               printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
+               dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
                return r;
        }
        return 0;
@@ -772,23 +760,19 @@ static void go7007_usb_readinterrupt_complete(struct urb *urb)
        if (status) {
                if (status != -ESHUTDOWN &&
                                go->status != STATUS_SHUTDOWN) {
-                       printk(KERN_ERR
-                               "go7007-usb: error in read interrupt: %d\n",
-                               urb->status);
+                       dev_err(go->dev, "error in read interrupt: %d\n", urb->status);
                } else {
                        wake_up(&go->interrupt_waitq);
                        return;
                }
        } else if (urb->actual_length != urb->transfer_buffer_length) {
-               printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
+               dev_err(go->dev, "short read in interrupt pipe!\n");
        } else {
                go->interrupt_available = 1;
                go->interrupt_data = __le16_to_cpu(regs[0]);
                go->interrupt_value = __le16_to_cpu(regs[1]);
-#ifdef GO7007_USB_DEBUG
-               printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
+               dev_dbg(go->dev, "ReadInterrupt: %04x %04x\n",
                                go->interrupt_value, go->interrupt_data);
-#endif
        }
 
        wake_up(&go->interrupt_waitq);
@@ -801,8 +785,7 @@ static int go7007_usb_read_interrupt(struct go7007 *go)
 
        r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
        if (r < 0) {
-               printk(KERN_ERR
-                       "go7007-usb: unable to submit interrupt urb: %d\n", r);
+               dev_err(go->dev, "unable to submit interrupt urb: %d\n", r);
                return r;
        }
        return 0;
@@ -818,18 +801,17 @@ static void go7007_usb_read_video_pipe_complete(struct urb *urb)
                return;
        }
        if (status) {
-               printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
-                       status);
+               dev_err(go->dev, "error in video pipe: %d\n", status);
                return;
        }
        if (urb->actual_length != urb->transfer_buffer_length) {
-               printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
+               dev_err(go->dev, "short read in video pipe!\n");
                return;
        }
        go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r < 0)
-               printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
+               dev_err(go->dev, "error in video pipe: %d\n", r);
 }
 
 static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
@@ -840,19 +822,19 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
        if (!vb2_is_streaming(&go->vidq))
                return;
        if (status) {
-               printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
+               dev_err(go->dev, "error in audio pipe: %d\n",
                        status);
                return;
        }
        if (urb->actual_length != urb->transfer_buffer_length) {
-               printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
+               dev_err(go->dev, "short read in audio pipe!\n");
                return;
        }
        if (go->audio_deliver != NULL)
                go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r < 0)
-               printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
+               dev_err(go->dev, "error in audio pipe: %d\n", r);
 }
 
 static int go7007_usb_stream_start(struct go7007 *go)
@@ -863,8 +845,7 @@ static int go7007_usb_stream_start(struct go7007 *go)
        for (i = 0; i < 8; ++i) {
                r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
                if (r < 0) {
-                       printk(KERN_ERR "go7007-usb: error submitting video "
-                                       "urb %d: %d\n", i, r);
+                       dev_err(go->dev, "error submitting video urb %d: %d\n", i, r);
                        goto video_submit_failed;
                }
        }
@@ -874,8 +855,7 @@ static int go7007_usb_stream_start(struct go7007 *go)
        for (i = 0; i < 8; ++i) {
                r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
                if (r < 0) {
-                       printk(KERN_ERR "go7007-usb: error submitting audio "
-                                       "urb %d: %d\n", i, r);
+                       dev_err(go->dev, "error submitting audio urb %d: %d\n", i, r);
                        goto audio_submit_failed;
                }
        }
@@ -911,9 +891,7 @@ static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
        int transferred, pipe;
        int timeout = 500;
 
-#ifdef GO7007_USB_DEBUG
-       printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
-#endif
+       dev_dbg(go->dev, "DownloadBuffer sending %d bytes\n", len);
 
        if (usb->board->flags & GO7007_USB_EZUSB)
                pipe = usb_sndbulkpipe(usb->usbdev, 2);
@@ -999,9 +977,8 @@ 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
-                       printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
-                                       "bytes on %02x\n", msgs[i].len,
-                                       msgs[i + 1].len, msgs[i].addr);
+                       dev_dbg(go->dev, "i2c write/read %d/%d bytes on %02x\n",
+                               msgs[i].len, msgs[i + 1].len, msgs[i].addr);
 #endif
                        buf[0] = 0x01;
                        buf[1] = msgs[i].len + 1;
@@ -1011,9 +988,8 @@ 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
-                       printk(KERN_DEBUG "go7007-usb: i2c read %d "
-                                       "bytes on %02x\n", msgs[i].len,
-                                       msgs[i].addr);
+                       dev_dbg(go->dev, "i2c read %d bytes on %02x\n",
+                                       msgs[i].len, msgs[i].addr);
 #endif
                        buf[0] = 0x01;
                        buf[1] = 1;
@@ -1022,9 +998,8 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                        buf_len = 4;
                } else {
 #ifdef GO7007_I2C_DEBUG
-                       printk(KERN_DEBUG "go7007-usb: i2c write %d "
-                                       "bytes on %02x\n", msgs[i].len,
-                                       msgs[i].addr);
+                       dev_dbg(go->dev, "i2c write %d bytes on %02x\n",
+                                       msgs[i].len, msgs[i].addr);
 #endif
                        buf[0] = 0x00;
                        buf[1] = msgs[i].len + 1;
@@ -1082,7 +1057,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
        char *name;
        int video_pipe, i, v_urb_len;
 
-       printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
+       dev_dbg(go->dev, "probing new GO7007 USB board\n");
 
        switch (id->driver_info) {
        case GO7007_BOARDID_MATRIX_II:
@@ -1122,14 +1097,13 @@ static int go7007_usb_probe(struct usb_interface *intf,
                board = &board_px_tv402u;
                break;
        case GO7007_BOARDID_LIFEVIEW_LR192:
-               printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
-                               "is not supported.  Sorry!\n");
+               dev_err(go->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:
-               printk(KERN_INFO "Sensoray 2250 found\n");
+               dev_info(go->dev, "Sensoray 2250 found\n");
                name = "Sensoray 2250/2251";
                board = &board_sensoray_2250;
                break;
@@ -1138,7 +1112,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
                board = &board_ads_usbav_709;
                break;
        default:
-               printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
+               dev_err(go->dev, "unknown board ID %d!\n",
                                (unsigned int)id->driver_info);
                return -ENODEV;
        }
@@ -1197,8 +1171,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
                go->i2c_adapter.dev.parent = go->dev;
                i2c_set_adapdata(&go->i2c_adapter, go);
                if (i2c_add_adapter(&go->i2c_adapter) < 0) {
-                       printk(KERN_ERR
-                               "go7007-usb: error: i2c_add_adapter failed\n");
+                       dev_err(go->dev, "error: i2c_add_adapter failed\n");
                        goto allocfail;
                }
                go->i2c_adapter_online = 1;
@@ -1248,8 +1221,9 @@ static int go7007_usb_probe(struct usb_interface *intf,
        /* Probe the tuner model on the TV402U */
        if (go->board_id == GO7007_BOARDID_PX_TV402U) {
                /* Board strapping indicates tuner model */
-               if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) {
-                       printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
+               if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3,
+                                       1) < 0) {
+                       dev_err(go->dev, "GPIO read failed!\n");
                        goto allocfail;
                }
                switch (go->usb_buf[0] >> 6) {
@@ -1273,15 +1247,14 @@ static int go7007_usb_probe(struct usb_interface *intf,
                                        sizeof(go->name));
                        break;
                default:
-                       printk(KERN_DEBUG "go7007-usb: unable to detect "
-                                               "tuner type!\n");
+                       dev_dbg(go->dev, "unable to detect tuner type!\n");
                        break;
                }
                /* Configure tuner mode selection inputs connected
                 * to the EZ-USB GPIO output pins */
                if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
                                        NULL, 0, 0) < 0) {
-                       printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
+                       dev_err(go->dev, "GPIO write failed!\n");
                        goto allocfail;
                }
        }
@@ -1290,11 +1263,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
         * a USB1.1 port.  There will be silent corruption of the stream. */
        if ((board->flags & GO7007_USB_EZUSB) &&
                        usbdev->speed != USB_SPEED_HIGH)
-               printk(KERN_ERR "go7007-usb: *** WARNING ***  This device "
-                               "must be connected to a USB 2.0 port!  "
-                               "Attempting to capture video through a USB 1.1 "
-                               "port will result in stream corruption, even "
-                               "at low bitrates!\n");
+               dev_err(go->dev, "*** WARNING ***  This device must be connected to a USB 2.0 port! Attempting to capture video through a USB 1.1 port will result in stream corruption, even at low bitrates!\n");
 
        /* Allocate the URBs and buffers for receiving the video stream */
        if (board->flags & GO7007_USB_EZUSB) {
index fa31ee7dd6a9e5f742dafb117426cd801d9318e2..fbbdce4c119f71cab122bde5c203bb03b9ee43de 100644 (file)
@@ -132,7 +132,7 @@ int init_module(void)
        atir_driver.minor       = -1;
        atir_driver.code_length = 8;
        atir_driver.sample_rate = 10;
-       atir_driver.data        = 0;
+       atir_driver.data        = NULL;
        atir_driver.add_to_buf  = atir_add_to_buf;
        atir_driver.set_use_inc = atir_set_use_inc;
        atir_driver.set_use_dec = atir_set_use_dec;
@@ -159,7 +159,7 @@ void cleanup_module(void)
 static int atir_init_start(void)
 {
        pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
-       if (pci_addr_lin == 0) {
+       if (!pci_addr_lin) {
                pr_info("pci mem must be mapped\n");
                return 0;
        }
index 4afa7da11f375cfbbf9e08f0df0676dfae62302d..ab2ae115b524eac74a54759bc471d1c6dff2c2aa 100644 (file)
@@ -625,7 +625,7 @@ static void imon_incoming_packet(struct imon_context *context,
        }
 
        if (debug) {
-               printk(KERN_INFO "raw packet: ");
+               dev_info(dev, "raw packet: ");
                for (i = 0; i < len; ++i)
                        printk("%02x ", buf[i]);
                printk("\n");
diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig
new file mode 100644 (file)
index 0000000..4031748
--- /dev/null
@@ -0,0 +1,16 @@
+config MTD_SPINAND_MT29F
+       tristate "SPINAND Device Support for Micron"
+       depends on MTD_NAND && SPI
+       help
+         This enables support for accessing Micron SPI NAND flash
+         devices.
+         If you have Micron SPI NAND chip say yes.
+
+         If unsure, say no here.
+
+config MTD_SPINAND_ONDIEECC
+       bool "Use SPINAND internal ECC"
+       depends on MTD_SPINAND_MT29F
+       help
+         Internel ECC.
+         Enables Hardware ECC support for Micron SPI NAND.
diff --git a/drivers/staging/mt29f_spinand/Makefile b/drivers/staging/mt29f_spinand/Makefile
new file mode 100644 (file)
index 0000000..e47af0f
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand.o
diff --git a/drivers/staging/mt29f_spinand/TODO b/drivers/staging/mt29f_spinand/TODO
new file mode 100644 (file)
index 0000000..a2209b7
--- /dev/null
@@ -0,0 +1,13 @@
+TODO:
+       - Tested on XLP platform, needs to be tested on other platforms.
+       - Checkpatch.pl cleanups
+       - Sparce fixes.
+       - Clean up coding style to meet kernel standard.
+
+Please send patches
+To:
+Kamlakant Patel <kamlakant.patel@broadcom.com>
+Cc:
+Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Mona Anonuevo <manonuevo@micron.com>
+linux-mtd@lists.infradead.org
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
new file mode 100644 (file)
index 0000000..51dbc13
--- /dev/null
@@ -0,0 +1,947 @@
+/*
+ * Copyright (c) 2003-2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/spi/spi.h>
+
+#include "mt29f_spinand.h"
+
+#define BUFSIZE (10 * 64 * 2048)
+#define CACHE_BUF 2112
+/*
+ * OOB area specification layout:  Total 32 available free bytes.
+ */
+
+static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+       struct spinand_state *state = (struct spinand_state *)info->priv;
+
+       return state;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int enable_hw_ecc;
+static int enable_read_hw_ecc;
+
+static struct nand_ecclayout spinand_oob_64 = {
+       .eccbytes = 24,
+       .eccpos = {
+               1, 2, 3, 4, 5, 6,
+               17, 18, 19, 20, 21, 22,
+               33, 34, 35, 36, 37, 38,
+               49, 50, 51, 52, 53, 54, },
+       .oobavail = 32,
+       .oobfree = {
+               {.offset = 8,
+                       .length = 8},
+               {.offset = 24,
+                       .length = 8},
+               {.offset = 40,
+                       .length = 8},
+               {.offset = 56,
+                       .length = 8},
+       }
+};
+#endif
+
+/*
+ * spinand_cmd - to process a command to send to the SPI Nand
+ * Description:
+ *    Set up the command buffer to send to the SPI controller.
+ *    The command buffer has to initialized to 0.
+ */
+
+static int spinand_cmd(struct spi_device *spi, struct spinand_cmd *cmd)
+{
+       struct spi_message message;
+       struct spi_transfer x[4];
+       u8 dummy = 0xff;
+
+       spi_message_init(&message);
+       memset(x, 0, sizeof(x));
+
+       x[0].len = 1;
+       x[0].tx_buf = &cmd->cmd;
+       spi_message_add_tail(&x[0], &message);
+
+       if (cmd->n_addr) {
+               x[1].len = cmd->n_addr;
+               x[1].tx_buf = cmd->addr;
+               spi_message_add_tail(&x[1], &message);
+       }
+
+       if (cmd->n_dummy) {
+               x[2].len = cmd->n_dummy;
+               x[2].tx_buf = &dummy;
+               spi_message_add_tail(&x[2], &message);
+       }
+
+       if (cmd->n_tx) {
+               x[3].len = cmd->n_tx;
+               x[3].tx_buf = cmd->tx_buf;
+               spi_message_add_tail(&x[3], &message);
+       }
+
+       if (cmd->n_rx) {
+               x[3].len = cmd->n_rx;
+               x[3].rx_buf = cmd->rx_buf;
+               spi_message_add_tail(&x[3], &message);
+       }
+
+       return spi_sync(spi, &message);
+}
+
+/*
+ * spinand_read_id- Read SPI Nand ID
+ * Description:
+ *    Read ID: read two ID bytes from the SPI Nand device
+ */
+static int spinand_read_id(struct spi_device *spi_nand, u8 *id)
+{
+       int retval;
+       u8 nand_id[3];
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_READ_ID;
+       cmd.n_rx = 3;
+       cmd.rx_buf = &nand_id[0];
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0) {
+               dev_err(&spi_nand->dev, "error %d reading id\n", retval);
+               return retval;
+       }
+       id[0] = nand_id[1];
+       id[1] = nand_id[2];
+       return retval;
+}
+
+/*
+ * spinand_read_status- send command 0xf to the SPI Nand status register
+ * Description:
+ *    After read, write, or erase, the Nand device is expected to set the
+ *    busy status.
+ *    This function is to allow reading the status of the command: read,
+ *    write, and erase.
+ *    Once the status turns to be ready, the other status bits also are
+ *    valid status bits.
+ */
+static int spinand_read_status(struct spi_device *spi_nand, uint8_t *status)
+{
+       struct spinand_cmd cmd = {0};
+       int ret;
+
+       cmd.cmd = CMD_READ_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_STATUS;
+       cmd.n_rx = 1;
+       cmd.rx_buf = status;
+
+       ret = spinand_cmd(spi_nand, &cmd);
+       if (ret < 0)
+               dev_err(&spi_nand->dev, "err: %d read status register\n", ret);
+
+       return ret;
+}
+
+#define MAX_WAIT_JIFFIES  (40 * HZ)
+static int wait_till_ready(struct spi_device *spi_nand)
+{
+       unsigned long deadline;
+       int retval;
+       u8 stat = 0;
+
+       deadline = jiffies + MAX_WAIT_JIFFIES;
+       do {
+               retval = spinand_read_status(spi_nand, &stat);
+               if (retval < 0)
+                       return -1;
+               else if (!(stat & 0x1))
+                       break;
+
+               cond_resched();
+       } while (!time_after_eq(jiffies, deadline));
+
+       if ((stat & 0x1) == 0)
+               return 0;
+
+       return -1;
+}
+/**
+ * spinand_get_otp- send command 0xf to read the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_get_otp(struct spi_device *spi_nand, u8 *otp)
+{
+       struct spinand_cmd cmd = {0};
+       int retval;
+
+       cmd.cmd = CMD_READ_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_OTP;
+       cmd.n_rx = 1;
+       cmd.rx_buf = otp;
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0)
+               dev_err(&spi_nand->dev, "error %d get otp\n", retval);
+       return retval;
+}
+
+/**
+ * spinand_set_otp- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_set_otp(struct spi_device *spi_nand, u8 *otp)
+{
+       int retval;
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_WRITE_REG,
+       cmd.n_addr = 1,
+       cmd.addr[0] = REG_OTP,
+       cmd.n_tx = 1,
+       cmd.tx_buf = otp,
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0)
+               dev_err(&spi_nand->dev, "error %d set otp\n", retval);
+
+       return retval;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+/**
+ * spinand_enable_ecc- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_enable_ecc(struct spi_device *spi_nand)
+{
+       int retval;
+       u8 otp = 0;
+
+       retval = spinand_get_otp(spi_nand, &otp);
+       if (retval < 0)
+               return retval;
+
+       if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+               return 0;
+       } else {
+               otp |= OTP_ECC_MASK;
+               retval = spinand_set_otp(spi_nand, &otp);
+               if (retval < 0)
+                       return retval;
+               return spinand_get_otp(spi_nand, &otp);
+       }
+}
+#endif
+
+static int spinand_disable_ecc(struct spi_device *spi_nand)
+{
+       int retval;
+       u8 otp = 0;
+
+       retval = spinand_get_otp(spi_nand, &otp);
+       if (retval < 0)
+               return retval;
+
+       if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+               otp &= ~OTP_ECC_MASK;
+               retval = spinand_set_otp(spi_nand, &otp);
+               if (retval < 0)
+                       return retval;
+               return spinand_get_otp(spi_nand, &otp);
+       } else
+               return 0;
+}
+
+/**
+ * spinand_write_enable- send command 0x06 to enable write or erase the
+ * Nand cells
+ * Description:
+ *   Before write and erase the Nand cells, the write enable has to be set.
+ *   After the write or erase, the write enable bit is automatically
+ *   cleared (status register bit 2)
+ *   Set the bit 2 of the status register has the same effect
+ */
+static int spinand_write_enable(struct spi_device *spi_nand)
+{
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_WR_ENABLE;
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+static int spinand_read_page_to_cache(struct spi_device *spi_nand, u16 page_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = page_id;
+       cmd.cmd = CMD_READ;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_from_cache- send command 0x03 to read out the data from the
+ * cache register(2112 bytes max)
+ * Description:
+ *   The read can specify 1 to 2112 bytes of data read at the corresponding
+ *   locations.
+ *   No tRd delay.
+ */
+static int spinand_read_from_cache(struct spi_device *spi_nand, u16 page_id,
+               u16 byte_id, u16 len, u8 *rbuf)
+{
+       struct spinand_cmd cmd = {0};
+       u16 column;
+
+       column = byte_id;
+       cmd.cmd = CMD_READ_RDM;
+       cmd.n_addr = 3;
+       cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+       cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+       cmd.addr[1] = (u8)(column & 0x00ff);
+       cmd.addr[2] = (u8)(0xff);
+       cmd.n_dummy = 0;
+       cmd.n_rx = len;
+       cmd.rx_buf = rbuf;
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_page-to read a page with:
+ * @page_id: the physical page number
+ * @offset:  the location from 0 to 2111
+ * @len:     number of bytes to read
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The read includes two commands to the Nand: 0x13 and 0x03 commands
+ *   Poll to read status to wait for tRD time.
+ */
+static int spinand_read_page(struct spi_device *spi_nand, u16 page_id,
+               u16 offset, u16 len, u8 *rbuf)
+{
+       int ret;
+       u8 status = 0;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_read_hw_ecc) {
+               if (spinand_enable_ecc(spi_nand) < 0)
+                       dev_err(&spi_nand->dev, "enable HW ECC failed!");
+       }
+#endif
+       ret = spinand_read_page_to_cache(spi_nand, page_id);
+       if (ret < 0)
+               return ret;
+
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "WAIT timedout!!!\n");
+
+       while (1) {
+               ret = spinand_read_status(spi_nand, &status);
+               if (ret < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "err %d read status register\n", ret);
+                       return ret;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+                               dev_err(&spi_nand->dev, "ecc error, page=%d\n",
+                                               page_id);
+                               return 0;
+                       }
+                       break;
+               }
+       }
+
+       ret = spinand_read_from_cache(spi_nand, page_id, offset, len, rbuf);
+       if (ret < 0) {
+               dev_err(&spi_nand->dev, "read from cache failed!!\n");
+               return ret;
+       }
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_read_hw_ecc) {
+               ret = spinand_disable_ecc(spi_nand);
+               if (ret < 0) {
+                       dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+                       return ret;
+               }
+               enable_read_hw_ecc = 0;
+       }
+#endif
+       return ret;
+}
+
+/*
+ * spinand_program_data_to_cache--to write a page to cache with:
+ * @byte_id: the location to write to the cache
+ * @len:     number of bytes to write
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The write command used here is 0x84--indicating that the cache is
+ *   not cleared first.
+ *   Since it is writing the data to cache, there is no tPROG time.
+ */
+static int spinand_program_data_to_cache(struct spi_device *spi_nand,
+               u16 page_id, u16 byte_id, u16 len, u8 *wbuf)
+{
+       struct spinand_cmd cmd = {0};
+       u16 column;
+
+       column = byte_id;
+       cmd.cmd = CMD_PROG_PAGE_CLRCACHE;
+       cmd.n_addr = 2;
+       cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+       cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+       cmd.addr[1] = (u8)(column & 0x00ff);
+       cmd.n_tx = len;
+       cmd.tx_buf = wbuf;
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_execute--to write a page from cache to the Nand array with
+ * @page_id: the physical page location to write the page.
+ *
+ * Description:
+ *   The write command used here is 0x10--indicating the cache is writing to
+ *   the Nand array.
+ *   Need to wait for tPROG time to finish the transaction.
+ */
+static int spinand_program_execute(struct spi_device *spi_nand, u16 page_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = page_id;
+       cmd.cmd = CMD_PROG_PAGE_EXC;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_page--to write a page with:
+ * @page_id: the physical page location to write the page.
+ * @offset:  the location from the cache starting from 0 to 2111
+ * @len:     the number of bytes to write
+ * @wbuf:    the buffer to hold the number of bytes
+ *
+ * Description:
+ *   The commands used here are 0x06, 0x84, and 0x10--indicating that
+ *   the write enable is first sent, the write cache command, and the
+ *   write execute command.
+ *   Poll to wait for the tPROG time to finish the transaction.
+ */
+static int spinand_program_page(struct spi_device *spi_nand,
+               u16 page_id, u16 offset, u16 len, u8 *buf)
+{
+       int retval;
+       u8 status = 0;
+       uint8_t *wbuf;
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       unsigned int i, j;
+
+       enable_read_hw_ecc = 0;
+       wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL);
+       spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf);
+
+       for (i = offset, j = 0; i < len; i++, j++)
+               wbuf[i] &= buf[j];
+
+       if (enable_hw_ecc) {
+               retval = spinand_enable_ecc(spi_nand);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev, "enable ecc failed!!\n");
+                       return retval;
+               }
+       }
+#else
+       wbuf = buf;
+#endif
+       retval = spinand_write_enable(spi_nand);
+       if (retval < 0) {
+               dev_err(&spi_nand->dev, "write enable failed!!\n");
+               return retval;
+       }
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+       retval = spinand_program_data_to_cache(spi_nand, page_id,
+                       offset, len, wbuf);
+       if (retval < 0)
+               return retval;
+       retval = spinand_program_execute(spi_nand, page_id);
+       if (retval < 0)
+               return retval;
+       while (1) {
+               retval = spinand_read_status(spi_nand, &status);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "error %d reading status register\n",
+                                       retval);
+                       return retval;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) {
+                               dev_err(&spi_nand->dev,
+                                       "program error, page %d\n", page_id);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_hw_ecc) {
+               retval = spinand_disable_ecc(spi_nand);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+                       return retval;
+               }
+               enable_hw_ecc = 0;
+       }
+#endif
+
+       return 0;
+}
+
+/**
+ * spinand_erase_block_erase--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The command used here is 0xd8--indicating an erase command to erase
+ *   one block--64 pages
+ *   Need to wait for tERS.
+ */
+static int spinand_erase_block_erase(struct spi_device *spi_nand, u16 block_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = block_id;
+       cmd.cmd = CMD_ERASE_BLK;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_erase_block--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The commands used here are 0x06 and 0xd8--indicating an erase
+ *   command to erase one block--64 pages
+ *   It will first to enable the write enable bit (0x06 command),
+ *   and then send the 0xd8 erase command
+ *   Poll to wait for the tERS time to complete the tranaction.
+ */
+static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id)
+{
+       int retval;
+       u8 status = 0;
+
+       retval = spinand_write_enable(spi_nand);
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+       retval = spinand_erase_block_erase(spi_nand, block_id);
+       while (1) {
+               retval = spinand_read_status(spi_nand, &status);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "error %d reading status register\n",
+                                       (int) retval);
+                       return retval;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL) {
+                               dev_err(&spi_nand->dev,
+                                       "erase error, block %d\n", block_id);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+       return 0;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int spinand_write_page_hwecc(struct mtd_info *mtd,
+               struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+       const uint8_t *p = buf;
+       int eccsize = chip->ecc.size;
+       int eccsteps = chip->ecc.steps;
+
+       enable_hw_ecc = 1;
+       chip->write_buf(mtd, p, eccsize * eccsteps);
+       return 0;
+}
+
+static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+               uint8_t *buf, int oob_required, int page)
+{
+       u8 retval, status;
+       uint8_t *p = buf;
+       int eccsize = chip->ecc.size;
+       int eccsteps = chip->ecc.steps;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+       enable_read_hw_ecc = 1;
+
+       chip->read_buf(mtd, p, eccsize * eccsteps);
+       if (oob_required)
+               chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       while (1) {
+               retval = spinand_read_status(info->spi, &status);
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+                               pr_info("spinand: ECC error\n");
+                               mtd->ecc_stats.failed++;
+                       } else if ((status & STATUS_ECC_MASK) ==
+                                       STATUS_ECC_1BIT_CORRECTED)
+                               mtd->ecc_stats.corrected++;
+                       break;
+               }
+       }
+       return 0;
+
+}
+#endif
+
+static void spinand_select_chip(struct mtd_info *mtd, int dev)
+{
+}
+
+static uint8_t spinand_read_byte(struct mtd_info *mtd)
+{
+       struct spinand_state *state = mtd_to_state(mtd);
+       u8 data;
+
+       data = state->buf[state->buf_ptr];
+       state->buf_ptr++;
+       return data;
+}
+
+
+static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
+{
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+       unsigned long timeo = jiffies;
+       int retval, state = chip->state;
+       u8 status;
+
+       if (state == FL_ERASING)
+               timeo += (HZ * 400) / 1000;
+       else
+               timeo += (HZ * 20) / 1000;
+
+       while (time_before(jiffies, timeo)) {
+               retval = spinand_read_status(info->spi, &status);
+               if ((status & STATUS_OIP_MASK) == STATUS_READY)
+                       return 0;
+
+               cond_resched();
+       }
+       return 0;
+}
+
+static void spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+
+       struct spinand_state *state = mtd_to_state(mtd);
+       memcpy(state->buf + state->buf_ptr, buf, len);
+       state->buf_ptr += len;
+}
+
+static void spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+       struct spinand_state *state = mtd_to_state(mtd);
+       memcpy(buf, state->buf + state->buf_ptr, len);
+       state->buf_ptr += len;
+}
+
+/*
+ * spinand_reset- send RESET command "0xff" to the Nand device.
+ */
+static void spinand_reset(struct spi_device *spi_nand)
+{
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_RESET;
+
+       if (spinand_cmd(spi_nand, &cmd) < 0)
+               pr_info("spinand reset failed!\n");
+
+       /* elapse 1ms before issuing any other command */
+       udelay(1000);
+
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!\n");
+}
+
+static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
+               int column, int page)
+{
+       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+       struct spinand_state *state = (struct spinand_state *)info->priv;
+
+       switch (command) {
+       /*
+        * READ0 - read in first  0x800 bytes
+        */
+       case NAND_CMD_READ1:
+       case NAND_CMD_READ0:
+               state->buf_ptr = 0;
+               spinand_read_page(info->spi, page, 0x0, 0x840, state->buf);
+               break;
+       /* READOOB reads only the OOB because no ECC is performed. */
+       case NAND_CMD_READOOB:
+               state->buf_ptr = 0;
+               spinand_read_page(info->spi, page, 0x800, 0x40, state->buf);
+               break;
+       case NAND_CMD_RNDOUT:
+               state->buf_ptr = column;
+               break;
+       case NAND_CMD_READID:
+               state->buf_ptr = 0;
+               spinand_read_id(info->spi, (u8 *)state->buf);
+               break;
+       case NAND_CMD_PARAM:
+               state->buf_ptr = 0;
+               break;
+       /* ERASE1 stores the block and page address */
+       case NAND_CMD_ERASE1:
+               spinand_erase_block(info->spi, page);
+               break;
+       /* ERASE2 uses the block and page address from ERASE1 */
+       case NAND_CMD_ERASE2:
+               break;
+       /* SEQIN sets up the addr buffer and all registers except the length */
+       case NAND_CMD_SEQIN:
+               state->col = column;
+               state->row = page;
+               state->buf_ptr = 0;
+               break;
+       /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
+       case NAND_CMD_PAGEPROG:
+               spinand_program_page(info->spi, state->row, state->col,
+                               state->buf_ptr, state->buf);
+               break;
+       case NAND_CMD_STATUS:
+               spinand_get_otp(info->spi, state->buf);
+               if (!(state->buf[0] & 0x80))
+                       state->buf[0] = 0x80;
+               state->buf_ptr = 0;
+               break;
+       /* RESET command */
+       case NAND_CMD_RESET:
+               if (wait_till_ready(info->spi))
+                       dev_err(&info->spi->dev, "WAIT timedout!!!\n");
+               /* a minimum of 250us must elapse before issuing RESET cmd*/
+               udelay(250);
+               spinand_reset(info->spi);
+               break;
+       default:
+               dev_err(&mtd->dev, "Unknown CMD: 0x%x\n", command);
+       }
+}
+
+/**
+ * spinand_lock_block- send write register 0x1f command to the Nand device
+ *
+ * Description:
+ *    After power up, all the Nand blocks are locked.  This function allows
+ *    one to unlock the blocks, and so it can be written or erased.
+ */
+static int spinand_lock_block(struct spi_device *spi_nand, u8 lock)
+{
+       struct spinand_cmd cmd = {0};
+       int ret;
+       u8 otp = 0;
+
+       ret = spinand_get_otp(spi_nand, &otp);
+
+       cmd.cmd = CMD_WRITE_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_BLOCK_LOCK;
+       cmd.n_tx = 1;
+       cmd.tx_buf = &lock;
+
+       ret = spinand_cmd(spi_nand, &cmd);
+       if (ret < 0)
+               dev_err(&spi_nand->dev, "error %d lock block\n", ret);
+
+       return ret;
+}
+/*
+ * spinand_probe - [spinand Interface]
+ * @spi_nand: registered device driver.
+ *
+ * Description:
+ *   To set up the device driver parameters to make the device available.
+ */
+static int spinand_probe(struct spi_device *spi_nand)
+{
+       struct mtd_info *mtd;
+       struct nand_chip *chip;
+       struct spinand_info *info;
+       struct spinand_state *state;
+       struct mtd_part_parser_data ppdata;
+
+       info  = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info),
+                       GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->spi = spi_nand;
+
+       spinand_lock_block(spi_nand, BL_ALL_UNLOCKED);
+
+       state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state),
+                       GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       info->priv      = state;
+       state->buf_ptr  = 0;
+       state->buf      = devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL);
+       if (!state->buf)
+               return -ENOMEM;
+
+       chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip),
+                       GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       chip->ecc.mode  = NAND_ECC_HW;
+       chip->ecc.size  = 0x200;
+       chip->ecc.bytes = 0x6;
+       chip->ecc.steps = 0x4;
+
+       chip->ecc.strength = 1;
+       chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
+       chip->ecc.layout = &spinand_oob_64;
+       chip->ecc.read_page = spinand_read_page_hwecc;
+       chip->ecc.write_page = spinand_write_page_hwecc;
+#else
+       chip->ecc.mode  = NAND_ECC_SOFT;
+       if (spinand_disable_ecc(spi_nand) < 0)
+               pr_info("%s: disable ecc failed!\n", __func__);
+#endif
+
+       chip->priv      = info;
+       chip->read_buf  = spinand_read_buf;
+       chip->write_buf = spinand_write_buf;
+       chip->read_byte = spinand_read_byte;
+       chip->cmdfunc   = spinand_cmdfunc;
+       chip->waitfunc  = spinand_wait;
+       chip->options   |= NAND_CACHEPRG;
+       chip->select_chip = spinand_select_chip;
+
+       mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL);
+       if (!mtd)
+               return -ENOMEM;
+
+       dev_set_drvdata(&spi_nand->dev, mtd);
+
+       mtd->priv = chip;
+       mtd->name = dev_name(&spi_nand->dev);
+       mtd->owner = THIS_MODULE;
+       mtd->oobsize = 64;
+
+       if (nand_scan(mtd, 1))
+               return -ENXIO;
+
+       ppdata.of_node = spi_nand->dev.of_node;
+       return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+}
+
+/*
+ * spinand_remove: Remove the device driver
+ * @spi: the spi device.
+ *
+ * Description:
+ *   To remove the device driver parameters and free up allocated memories.
+ */
+static int spinand_remove(struct spi_device *spi)
+{
+       mtd_device_unregister(dev_get_drvdata(&spi->dev));
+
+       return 0;
+}
+
+static const struct of_device_id spinand_dt[] = {
+       { .compatible = "spinand,mt29f", },
+};
+
+/*
+ * Device name structure description
+ */
+static struct spi_driver spinand_driver = {
+       .driver = {
+               .name           = "mt29f",
+               .bus            = &spi_bus_type,
+               .owner          = THIS_MODULE,
+               .of_match_table = spinand_dt,
+       },
+       .probe          = spinand_probe,
+       .remove         = spinand_remove,
+};
+
+module_spi_driver(spinand_driver);
+
+MODULE_DESCRIPTION("SPI NAND driver for Micron");
+MODULE_AUTHOR("Henry Pan <hspan@micron.com>, Kamlakant Patel <kamlakant.patel@broadcom.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.h b/drivers/staging/mt29f_spinand/mt29f_spinand.h
new file mode 100644 (file)
index 0000000..7f2c24d
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * Copyright 2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Henry Pan <hspan@micron.com>
+ *
+ * based on nand.h
+ */
+#ifndef __LINUX_MTD_SPI_NAND_H
+#define __LINUX_MTD_SPI_NAND_H
+
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/mtd/mtd.h>
+
+/* cmd */
+#define CMD_READ                       0x13
+#define CMD_READ_RDM                   0x03
+#define CMD_PROG_PAGE_CLRCACHE         0x02
+#define CMD_PROG_PAGE                  0x84
+#define CMD_PROG_PAGE_EXC              0x10
+#define CMD_ERASE_BLK                  0xd8
+#define CMD_WR_ENABLE                  0x06
+#define CMD_WR_DISABLE                 0x04
+#define CMD_READ_ID                    0x9f
+#define CMD_RESET                      0xff
+#define CMD_READ_REG                   0x0f
+#define CMD_WRITE_REG                  0x1f
+
+/* feature/ status reg */
+#define REG_BLOCK_LOCK                 0xa0
+#define REG_OTP                                0xb0
+#define REG_STATUS                     0xc0/* timing */
+
+/* status */
+#define STATUS_OIP_MASK                        0x01
+#define STATUS_READY                   (0 << 0)
+#define STATUS_BUSY                    (1 << 0)
+
+#define STATUS_E_FAIL_MASK             0x04
+#define STATUS_E_FAIL                  (1 << 2)
+
+#define STATUS_P_FAIL_MASK             0x08
+#define STATUS_P_FAIL                  (1 << 3)
+
+#define STATUS_ECC_MASK                        0x30
+#define STATUS_ECC_1BIT_CORRECTED      (1 << 4)
+#define STATUS_ECC_ERROR               (2 << 4)
+#define STATUS_ECC_RESERVED            (3 << 4)
+
+/*ECC enable defines*/
+#define OTP_ECC_MASK                   0x10
+#define OTP_ECC_OFF                    0
+#define OTP_ECC_ON                     1
+
+#define ECC_DISABLED
+#define ECC_IN_NAND
+#define ECC_SOFT
+
+/* block lock */
+#define BL_ALL_LOCKED      0x38
+#define BL_1_2_LOCKED      0x30
+#define BL_1_4_LOCKED      0x28
+#define BL_1_8_LOCKED      0x20
+#define BL_1_16_LOCKED     0x18
+#define BL_1_32_LOCKED     0x10
+#define BL_1_64_LOCKED     0x08
+#define BL_ALL_UNLOCKED    0
+
+struct spinand_info {
+       struct nand_ecclayout *ecclayout;
+       struct spi_device *spi;
+       void *priv;
+};
+
+struct spinand_state {
+       uint32_t        col;
+       uint32_t        row;
+       int             buf_ptr;
+       u8              *buf;
+};
+
+struct spinand_cmd {
+       u8              cmd;
+       u32             n_addr;         /* Number of address */
+       u8              addr[3];        /* Reg Offset */
+       u32             n_dummy;        /* Dummy use */
+       u32             n_tx;           /* Number of tx bytes */
+       u8              *tx_buf;        /* Tx buf */
+       u32             n_rx;           /* Number of rx bytes */
+       u8              *rx_buf;        /* Rx buf */
+};
+
+extern int spinand_mtd(struct mtd_info *mtd);
+extern void spinand_mtd_release(struct mtd_info *mtd);
+
+#endif /* __LINUX_MTD_SPI_NAND_H */
index 46eabd0e426ac9a1c5f06c0fbfcf1cf3e8fa6499..235d2b1ec593c4dfba7a83c4eb5fd0f578e0c5c4 100644 (file)
@@ -44,8 +44,8 @@
 #include <linux/platform_device.h>
 
 #include <asm/mipsregs.h>
-
-/* fmn.h - For FMN credit configuration and registering fmn_handler.
+/*
+ * fmn.h - For FMN credit configuration and registering fmn_handler.
  * FMN is communication mechanism that allows processing agents within
  * XLR/XLS to communicate each other.
  */
@@ -90,7 +90,8 @@ static inline struct sk_buff *mac_get_skb_back_ptr(void *addr)
 {
        struct sk_buff **back_ptr;
 
-       /* this function should be used only for newly allocated packets.
+       /*
+        * this function should be used only for newly allocated packets.
         * It assumes the first cacheline is for the back pointer related
         * book keeping info.
         */
@@ -102,7 +103,8 @@ static inline void mac_put_skb_back_ptr(struct sk_buff *skb)
 {
        struct sk_buff **back_ptr = (struct sk_buff **)skb->data;
 
-       /* this function should be used only for newly allocated packets.
+       /*
+        * this function should be used only for newly allocated packets.
         * It assumes the first cacheline is for the back pointer related
         * book keeping info.
         */
@@ -500,8 +502,10 @@ static void xlr_config_fifo_spill_area(struct xlr_net_priv *priv)
                        sizeof(u64));
 }
 
-/* Configure PDE to Round-Robin distribution of packets to the
- * available cpu */
+/*
+ * Configure PDE to Round-Robin distribution of packets to the
+ * available cpu
+ */
 static void xlr_config_pde(struct xlr_net_priv *priv)
 {
        int i = 0;
@@ -528,8 +532,10 @@ static void xlr_config_pde(struct xlr_net_priv *priv)
                        ((bkt_map >> 32) & 0xffffffff));
 }
 
-/* Setup the Message ring credits, bucket size and other
- * common configuration */
+/*
+ * Setup the Message ring credits, bucket size and other
+ * common configuration
+ */
 static void xlr_config_common(struct xlr_net_priv *priv)
 {
        struct xlr_fmn_info *gmac = priv->nd->gmac_fmn_info;
@@ -545,8 +551,10 @@ static void xlr_config_common(struct xlr_net_priv *priv)
                                bucket_size[i]);
        }
 
-       /* Setting non-core Credit counter register
-        * Distributing Gmac's credit to CPU's*/
+       /*
+        * Setting non-core Credit counter register
+        * Distributing Gmac's credit to CPU's
+        */
        for (i = 0; i < 8; i++) {
                for (j = 0; j < 8; j++)
                        xlr_nae_wreg(priv->base_addr,
@@ -593,7 +601,8 @@ static void xlr_config_translate_table(struct xlr_net_priv *priv)
        c1 = 3;
        c2 = 0;
        for (i = 0; i < 64; i++) {
-               /* On use_bkt set the b0, b1 are used, else
+               /*
+                * On use_bkt set the b0, b1 are used, else
                 * the 4 classes are used, here implemented
                 * a logic to distribute the packets to the
                 * buckets equally or based on the class
@@ -736,7 +745,8 @@ static int xlr_mii_read(struct mii_bus *bus, int phy_addr, int regnum)
        return ret;
 }
 
-/* XLR ports are RGMII. XLS ports are SGMII mostly except the port0,
+/*
+ * XLR ports are RGMII. XLS ports are SGMII mostly except the port0,
  * which can be configured either SGMII or RGMII, considered SGMII
  * by default, if board setup to RGMII the port_type need to set
  * accordingly.Serdes and PCS layer need to configured for SGMII
index f91d27e9d7c4b135e427e0e467709fefde7460b6..cea796633711976b116f5cddc46612be02ddec4d 100644 (file)
@@ -1096,4 +1096,4 @@ struct xlr_net_priv {
        u64 *class_3_spill;
 };
 
-extern void xlr_set_gmac_speed(struct xlr_net_priv *priv);
+void xlr_set_gmac_speed(struct xlr_net_priv *priv);
index 7e61adacd15dcca1fb611adbfce4045367b86d39..9475e20c3d646f85c2e1d164aaf4c8c3dbe84c63 100644 (file)
@@ -10,7 +10,7 @@ config KEYBOARD_NVEC
        tristate "Keyboard on nVidia compliant EC"
        depends on MFD_NVEC && INPUT
        help
-         Say Y here to enable support for a keyboard connected to 
+         Say Y here to enable support for a keyboard connected to
          a nVidia compliant embedded controller.
 
 config SERIO_NVEC_PS2
index 5a5c6397e74069000d66350c07fcc1fafafc01a6..3066ee2e753be3ed887d11b9615b41b78261b6bb 100644 (file)
@@ -802,7 +802,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
                unmute_speakers[] = { NVEC_OEM0, 0x10, 0x59, 0x95 },
                enable_event[7] = { NVEC_SYS, CNF_EVENT_REPORTING, true };
 
-       if(!pdev->dev.of_node) {
+       if (!pdev->dev.of_node) {
                dev_err(&pdev->dev, "must be instantiated using device tree\n");
                return -ENODEV;
        }
index 89df1ad8be308bfc7376f5a919f64a0f52d6fa9b..5588be395f2a7a967192d7f8ea478085865809a7 100644 (file)
@@ -1,3 +1 @@
-obj-${CONFIG_OCTEON_USB} := octeon-usb.o
-octeon-usb-y := octeon-hcd.o
-octeon-usb-y += cvmx-usb.o
+obj-${CONFIG_OCTEON_USB} := octeon-hcd.o
diff --git a/drivers/staging/octeon-usb/cvmx-usb.c b/drivers/staging/octeon-usb/cvmx-usb.c
deleted file mode 100644 (file)
index 45dfe94..0000000
+++ /dev/null
@@ -1,3158 +0,0 @@
-/***********************license start***************
- * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). 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 Cavium Networks 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, including technical data, may be subject to U.S. export  control
- * laws, including the U.S. Export Administration Act and its  associated
- * regulations, and may be subject to export or import  regulations in other
- * countries.
-
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
- * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
- * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
- * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- ***********************license end**************************************/
-
-
-/**
- * @file
- *
- * "cvmx-usb.c" defines a set of low level USB functions to help
- * developers create Octeon USB drivers for various operating
- * systems. These functions provide a generic API to the Octeon
- * USB blocks, hiding the internal hardware specific
- * operations.
- */
-#include <linux/delay.h>
-#include <asm/octeon/cvmx.h>
-#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-sysinfo.h>
-#include "cvmx-usbnx-defs.h"
-#include "cvmx-usbcx-defs.h"
-#include "cvmx-usb.h"
-#include <asm/octeon/cvmx-helper.h>
-#include <asm/octeon/cvmx-helper-board.h>
-
-#define CVMX_PREFETCH0(address) CVMX_PREFETCH(address, 0)
-#define CVMX_PREFETCH128(address) CVMX_PREFETCH(address, 128)
-// a normal prefetch
-#define CVMX_PREFETCH(address, offset) CVMX_PREFETCH_PREF0(address, offset)
-// normal prefetches that use the pref instruction
-#define CVMX_PREFETCH_PREFX(X, address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (X))
-#define CVMX_PREFETCH_PREF0(address, offset) CVMX_PREFETCH_PREFX(0, address, offset)
-#define CVMX_CLZ(result, input) asm ("clz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
-
-#define MAX_RETRIES            3               /* Maximum number of times to retry failed transactions */
-#define MAX_PIPES              32              /* Maximum number of pipes that can be open at once */
-#define MAX_TRANSACTIONS       256             /* Maximum number of outstanding transactions across all pipes */
-#define MAX_CHANNELS           8               /* Maximum number of hardware channels supported by the USB block */
-#define MAX_USB_ADDRESS                127             /* The highest valid USB device address */
-#define MAX_USB_ENDPOINT       15              /* The highest valid USB endpoint number */
-#define MAX_USB_HUB_PORT       15              /* The highest valid port number on a hub */
-#define MAX_TRANSFER_BYTES     ((1<<19)-1)     /* The low level hardware can transfer a maximum of this number of bytes in each transfer. The field is 19 bits wide */
-#define MAX_TRANSFER_PACKETS   ((1<<10)-1)     /* The low level hardware can transfer a maximum of this number of packets in each transfer. The field is 10 bits wide */
-
-/*
- * These defines disable the normal read and write csr. This is so I can add
- * extra debug stuff to the usb specific version and I won't use the normal
- * version by mistake
- */
-#define cvmx_read_csr use_cvmx_usb_read_csr64_instead_of_cvmx_read_csr
-#define cvmx_write_csr use_cvmx_usb_write_csr64_instead_of_cvmx_write_csr
-
-enum cvmx_usb_transaction_flags {
-       __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16,
-};
-
-enum {
-       USB_CLOCK_TYPE_REF_12,
-       USB_CLOCK_TYPE_REF_24,
-       USB_CLOCK_TYPE_REF_48,
-       USB_CLOCK_TYPE_CRYSTAL_12,
-};
-
-/**
- * Logical transactions may take numerous low level
- * transactions, especially when splits are concerned. This
- * enum represents all of the possible stages a transaction can
- * be in. Note that split completes are always even. This is so
- * the NAK handler can backup to the previous low level
- * transaction with a simple clearing of bit 0.
- */
-enum cvmx_usb_stage {
-       CVMX_USB_STAGE_NON_CONTROL,
-       CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE,
-       CVMX_USB_STAGE_SETUP,
-       CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE,
-       CVMX_USB_STAGE_DATA,
-       CVMX_USB_STAGE_DATA_SPLIT_COMPLETE,
-       CVMX_USB_STAGE_STATUS,
-       CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE,
-};
-
-/**
- * struct cvmx_usb_transaction - describes each pending USB transaction
- *                              regardless of type. These are linked together
- *                              to form a list of pending requests for a pipe.
- *
- * @prev:              Transaction before this one in the pipe.
- * @next:              Transaction after this one in the pipe.
- * @type:              Type of transaction, duplicated of the pipe.
- * @flags:             State flags for this transaction.
- * @buffer:            User's physical buffer address to read/write.
- * @buffer_length:     Size of the user's buffer in bytes.
- * @control_header:    For control transactions, physical address of the 8
- *                     byte standard header.
- * @iso_start_frame:   For ISO transactions, the starting frame number.
- * @iso_number_packets:        For ISO transactions, the number of packets in the
- *                     request.
- * @iso_packets:       For ISO transactions, the sub packets in the request.
- * @actual_bytes:      Actual bytes transfer for this transaction.
- * @stage:             For control transactions, the current stage.
- * @callback:          User's callback function when complete.
- * @callback_data:     User's data.
- */
-struct cvmx_usb_transaction {
-       struct cvmx_usb_transaction *prev;
-       struct cvmx_usb_transaction *next;
-       enum cvmx_usb_transfer type;
-       enum cvmx_usb_transaction_flags flags;
-       uint64_t buffer;
-       int buffer_length;
-       uint64_t control_header;
-       int iso_start_frame;
-       int iso_number_packets;
-       struct cvmx_usb_iso_packet *iso_packets;
-       int xfersize;
-       int pktcnt;
-       int retries;
-       int actual_bytes;
-       enum cvmx_usb_stage stage;
-       cvmx_usb_callback_func_t callback;
-       void *callback_data;
-};
-
-/**
- * struct cvmx_usb_pipe - a pipe represents a virtual connection between Octeon
- *                       and some USB device. It contains a list of pending
- *                       request to the device.
- *
- * @prev:              Pipe before this one in the list
- * @next:              Pipe after this one in the list
- * @head:              The first pending transaction
- * @tail:              The last pending transaction
- * @interval:          For periodic pipes, the interval between packets in
- *                     frames
- * @next_tx_frame:     The next frame this pipe is allowed to transmit on
- * @flags:             State flags for this pipe
- * @device_speed:      Speed of device connected to this pipe
- * @transfer_type:     Type of transaction supported by this pipe
- * @transfer_dir:      IN or OUT. Ignored for Control
- * @multi_count:       Max packet in a row for the device
- * @max_packet:                The device's maximum packet size in bytes
- * @device_addr:       USB device address at other end of pipe
- * @endpoint_num:      USB endpoint number at other end of pipe
- * @hub_device_addr:   Hub address this device is connected to
- * @hub_port:          Hub port this device is connected to
- * @pid_toggle:                This toggles between 0/1 on every packet send to track
- *                     the data pid needed
- * @channel:           Hardware DMA channel for this pipe
- * @split_sc_frame:    The low order bits of the frame number the split
- *                     complete should be sent on
- */
-struct cvmx_usb_pipe {
-       struct cvmx_usb_pipe *prev;
-       struct cvmx_usb_pipe *next;
-       struct cvmx_usb_transaction *head;
-       struct cvmx_usb_transaction *tail;
-       uint64_t interval;
-       uint64_t next_tx_frame;
-       enum cvmx_usb_pipe_flags flags;
-       enum cvmx_usb_speed device_speed;
-       enum cvmx_usb_transfer transfer_type;
-       enum cvmx_usb_direction transfer_dir;
-       int multi_count;
-       uint16_t max_packet;
-       uint8_t device_addr;
-       uint8_t endpoint_num;
-       uint8_t hub_device_addr;
-       uint8_t hub_port;
-       uint8_t pid_toggle;
-       uint8_t channel;
-       int8_t split_sc_frame;
-};
-
-/**
- * struct cvmx_usb_pipe_list
- *
- * @head: Head of the list, or NULL if empty.
- * @tail: Tail if the list, or NULL if empty.
- */
-struct cvmx_usb_pipe_list {
-       struct cvmx_usb_pipe *head;
-       struct cvmx_usb_pipe *tail;
-};
-
-struct cvmx_usb_tx_fifo {
-       struct {
-               int channel;
-               int size;
-               uint64_t address;
-       } entry[MAX_CHANNELS+1];
-       int head;
-       int tail;
-};
-
-/**
- * struct cvmx_usb_internal_state - the state of the USB block
- *
- * init_flags:            Flags passed to initialize.
- * index:                 Which USB block this is for.
- * idle_hardware_channels: Bit set for every idle hardware channel.
- * usbcx_hprt:            Stored port status so we don't need to read a CSR to
- *                        determine splits.
- * pipe_for_channel:      Map channels to pipes.
- * free_transaction_head:  List of free transactions head.
- * free_transaction_tail:  List of free transactions tail.
- * pipe:                  Storage for pipes.
- * transaction:                   Storage for transactions.
- * callback:              User global callbacks.
- * callback_data:         User data for each callback.
- * indent:                Used by debug output to indent functions.
- * port_status:                   Last port status used for change notification.
- * free_pipes:            List of all pipes that are currently closed.
- * idle_pipes:            List of open pipes that have no transactions.
- * active_pipes:          Active pipes indexed by transfer type.
- * frame_number:          Increments every SOF interrupt for time keeping.
- * active_split:          Points to the current active split, or NULL.
- */
-struct cvmx_usb_internal_state {
-       int init_flags;
-       int index;
-       int idle_hardware_channels;
-       union cvmx_usbcx_hprt usbcx_hprt;
-       struct cvmx_usb_pipe *pipe_for_channel[MAX_CHANNELS];
-       struct cvmx_usb_transaction *free_transaction_head;
-       struct cvmx_usb_transaction *free_transaction_tail;
-       struct cvmx_usb_pipe pipe[MAX_PIPES];
-       struct cvmx_usb_transaction transaction[MAX_TRANSACTIONS];
-       cvmx_usb_callback_func_t callback[__CVMX_USB_CALLBACK_END];
-       void *callback_data[__CVMX_USB_CALLBACK_END];
-       int indent;
-       struct cvmx_usb_port_status port_status;
-       struct cvmx_usb_pipe_list free_pipes;
-       struct cvmx_usb_pipe_list idle_pipes;
-       struct cvmx_usb_pipe_list active_pipes[4];
-       uint64_t frame_number;
-       struct cvmx_usb_transaction *active_split;
-       struct cvmx_usb_tx_fifo periodic;
-       struct cvmx_usb_tx_fifo nonperiodic;
-};
-
-/* This macro spins on a field waiting for it to reach a value */
-#define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
-       ({int result;                                                       \
-       do {                                                                \
-               uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
-                       octeon_get_clock_rate() / 1000000;                  \
-               type c;                                                     \
-               while (1) {                                                 \
-                       c.u32 = __cvmx_usb_read_csr32(usb, address);        \
-                       if (c.s.field op (value)) {                         \
-                               result = 0;                                 \
-                               break;                                      \
-                       } else if (cvmx_get_cycle() > done) {               \
-                               result = -1;                                \
-                               break;                                      \
-                       } else                                              \
-                               cvmx_wait(100);                             \
-               }                                                           \
-       } while (0);                                                        \
-       result; })
-
-/*
- * This macro logically sets a single field in a CSR. It does the sequence
- * read, modify, and write
- */
-#define USB_SET_FIELD32(address, type, field, value)           \
-       do {                                                    \
-               type c;                                         \
-               c.u32 = __cvmx_usb_read_csr32(usb, address);    \
-               c.s.field = value;                              \
-               __cvmx_usb_write_csr32(usb, address, c.u32);    \
-       } while (0)
-
-/* Returns the IO address to push/pop stuff data from the FIFOs */
-#define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
-
-static int octeon_usb_get_clock_type(void)
-{
-       switch (cvmx_sysinfo_get()->board_type) {
-       case CVMX_BOARD_TYPE_BBGW_REF:
-       case CVMX_BOARD_TYPE_LANAI2_A:
-       case CVMX_BOARD_TYPE_LANAI2_U:
-       case CVMX_BOARD_TYPE_LANAI2_G:
-       case CVMX_BOARD_TYPE_UBNT_E100:
-               return USB_CLOCK_TYPE_CRYSTAL_12;
-       }
-       return USB_CLOCK_TYPE_REF_48;
-}
-
-/**
- * Read a USB 32bit CSR. It performs the necessary address swizzle
- * for 32bit CSRs and logs the value in a readable format if
- * debugging is on.
- *
- * @usb:     USB block this access is for
- * @address: 64bit address to read
- *
- * Returns: Result of the read
- */
-static inline uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_internal_state *usb,
-                                            uint64_t address)
-{
-       uint32_t result = cvmx_read64_uint32(address ^ 4);
-       return result;
-}
-
-
-/**
- * Write a USB 32bit CSR. It performs the necessary address
- * swizzle for 32bit CSRs and logs the value in a readable format
- * if debugging is on.
- *
- * @usb:     USB block this access is for
- * @address: 64bit address to write
- * @value:   Value to write
- */
-static inline void __cvmx_usb_write_csr32(struct cvmx_usb_internal_state *usb,
-                                         uint64_t address, uint32_t value)
-{
-       cvmx_write64_uint32(address ^ 4, value);
-       cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
-}
-
-
-/**
- * Read a USB 64bit CSR. It logs the value in a readable format if
- * debugging is on.
- *
- * @usb:     USB block this access is for
- * @address: 64bit address to read
- *
- * Returns: Result of the read
- */
-static inline uint64_t __cvmx_usb_read_csr64(struct cvmx_usb_internal_state *usb,
-                                            uint64_t address)
-{
-       uint64_t result = cvmx_read64_uint64(address);
-       return result;
-}
-
-
-/**
- * Write a USB 64bit CSR. It logs the value in a readable format
- * if debugging is on.
- *
- * @usb:     USB block this access is for
- * @address: 64bit address to write
- * @value:   Value to write
- */
-static inline void __cvmx_usb_write_csr64(struct cvmx_usb_internal_state *usb,
-                                         uint64_t address, uint64_t value)
-{
-       cvmx_write64_uint64(address, value);
-}
-
-/**
- * Return non zero if this pipe connects to a non HIGH speed
- * device through a high speed hub.
- *
- * @usb:    USB block this access is for
- * @pipe:   Pipe to check
- *
- * Returns: Non zero if we need to do split transactions
- */
-static inline int __cvmx_usb_pipe_needs_split(struct cvmx_usb_internal_state *usb, struct cvmx_usb_pipe *pipe)
-{
-       return ((pipe->device_speed != CVMX_USB_SPEED_HIGH) && (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH));
-}
-
-
-/**
- * Trivial utility function to return the correct PID for a pipe
- *
- * @pipe:   pipe to check
- *
- * Returns: PID for pipe
- */
-static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
-{
-       if (pipe->pid_toggle)
-               return 2; /* Data1 */
-       else
-               return 0; /* Data0 */
-}
-
-
-/**
- * Return the number of USB ports supported by this Octeon
- * chip. If the chip doesn't support USB, or is not supported
- * by this API, a zero will be returned. Most Octeon chips
- * support one usb port, but some support two ports.
- * cvmx_usb_initialize() must be called on independent
- * struct cvmx_usb_state.
- *
- * Returns: Number of port, zero if usb isn't supported
- */
-int cvmx_usb_get_num_ports(void)
-{
-       int arch_ports = 0;
-
-       if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-               arch_ports = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
-               arch_ports = 2;
-       else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
-               arch_ports = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-               arch_ports = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
-               arch_ports = 1;
-       else
-               arch_ports = 0;
-
-       return arch_ports;
-}
-
-
-/**
- * Allocate a usb transaction for use
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- *
- * Returns: Transaction or NULL
- */
-static inline struct cvmx_usb_transaction *__cvmx_usb_alloc_transaction(struct cvmx_usb_internal_state *usb)
-{
-       struct cvmx_usb_transaction *t;
-       t = usb->free_transaction_head;
-       if (t) {
-               usb->free_transaction_head = t->next;
-               if (!usb->free_transaction_head)
-                       usb->free_transaction_tail = NULL;
-       }
-       if (t) {
-               memset(t, 0, sizeof(*t));
-               t->flags = __CVMX_USB_TRANSACTION_FLAGS_IN_USE;
-       }
-       return t;
-}
-
-
-/**
- * Free a usb transaction
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @transaction:
- *              Transaction to free
- */
-static inline void __cvmx_usb_free_transaction(struct cvmx_usb_internal_state *usb,
-                                              struct cvmx_usb_transaction *transaction)
-{
-       transaction->flags = 0;
-       transaction->prev = NULL;
-       transaction->next = NULL;
-       if (usb->free_transaction_tail)
-               usb->free_transaction_tail->next = transaction;
-       else
-               usb->free_transaction_head = transaction;
-       usb->free_transaction_tail = transaction;
-}
-
-
-/**
- * Add a pipe to the tail of a list
- * @list:   List to add pipe to
- * @pipe:   Pipe to add
- */
-static inline void __cvmx_usb_append_pipe(struct cvmx_usb_pipe_list *list, struct cvmx_usb_pipe *pipe)
-{
-       pipe->next = NULL;
-       pipe->prev = list->tail;
-       if (list->tail)
-               list->tail->next = pipe;
-       else
-               list->head = pipe;
-       list->tail = pipe;
-}
-
-
-/**
- * Remove a pipe from a list
- * @list:   List to remove pipe from
- * @pipe:   Pipe to remove
- */
-static inline void __cvmx_usb_remove_pipe(struct cvmx_usb_pipe_list *list, struct cvmx_usb_pipe *pipe)
-{
-       if (list->head == pipe) {
-               list->head = pipe->next;
-               pipe->next = NULL;
-               if (list->head)
-                       list->head->prev = NULL;
-               else
-                       list->tail = NULL;
-       } else if (list->tail == pipe) {
-               list->tail = pipe->prev;
-               list->tail->next = NULL;
-               pipe->prev = NULL;
-       } else {
-               pipe->prev->next = pipe->next;
-               pipe->next->prev = pipe->prev;
-               pipe->prev = NULL;
-               pipe->next = NULL;
-       }
-}
-
-
-/**
- * Initialize a USB port for use. This must be called before any
- * other access to the Octeon USB port is made. The port starts
- * off in the disabled state.
- *
- * @state:      Pointer to an empty struct cvmx_usb_state
- *              that will be populated by the initialize call.
- *              This structure is then passed to all other USB
- *              functions.
- * @usb_port_number:
- *              Which Octeon USB port to initialize.
- * @flags:      Flags to control hardware initialization. See
- *              enum cvmx_usb_initialize_flags for the flag
- *              definitions. Some flags are mandatory.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
-                       enum cvmx_usb_initialize_flags flags)
-{
-       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
-       union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       usb->init_flags = flags;
-
-       /* Make sure that state is large enough to store the internal state */
-       if (sizeof(*state) < sizeof(*usb))
-               return -EINVAL;
-       /* At first allow 0-1 for the usb port number */
-       if ((usb_port_number < 0) || (usb_port_number > 1))
-               return -EINVAL;
-       /* For all chips except 52XX there is only one port */
-       if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
-               return -EINVAL;
-       /* Try to determine clock type automatically */
-       if ((flags & (CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI |
-                     CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)) == 0) {
-               if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12)
-                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;  /* Only 12 MHZ crystals are supported */
-               else
-                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
-       }
-
-       if (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
-               /* Check for auto ref clock frequency */
-               if (!(flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK))
-                       switch (octeon_usb_get_clock_type()) {
-                       case USB_CLOCK_TYPE_REF_12:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
-                               break;
-                       case USB_CLOCK_TYPE_REF_24:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
-                               break;
-                       case USB_CLOCK_TYPE_REF_48:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
-                               break;
-                       default:
-                               return -EINVAL;
-                               break;
-                       }
-       }
-
-       memset(usb, 0, sizeof(*usb));
-       usb->init_flags = flags;
-
-       /* Initialize the USB state structure */
-       {
-               int i;
-               usb->index = usb_port_number;
-
-               /* Initialize the transaction double linked list */
-               usb->free_transaction_head = NULL;
-               usb->free_transaction_tail = NULL;
-               for (i = 0; i < MAX_TRANSACTIONS; i++)
-                       __cvmx_usb_free_transaction(usb, usb->transaction + i);
-               for (i = 0; i < MAX_PIPES; i++)
-                       __cvmx_usb_append_pipe(&usb->free_pipes, usb->pipe + i);
-       }
-
-       /*
-        * Power On Reset and PHY Initialization
-        *
-        * 1. Wait for DCOK to assert (nothing to do)
-        *
-        * 2a. Write USBN0/1_CLK_CTL[POR] = 1 and
-        *     USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0
-        */
-       usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
-       usbn_clk_ctl.s.por = 1;
-       usbn_clk_ctl.s.hrst = 0;
-       usbn_clk_ctl.s.prst = 0;
-       usbn_clk_ctl.s.hclk_rst = 0;
-       usbn_clk_ctl.s.enable = 0;
-       /*
-        * 2b. Select the USB reference clock/crystal parameters by writing
-        *     appropriate values to USBN0/1_CLK_CTL[P_C_SEL, P_RTYPE, P_COM_ON]
-        */
-       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
-               /*
-                * The USB port uses 12/24/48MHz 2.5V board clock
-                * source at USB_XO. USB_XI should be tied to GND.
-                * Most Octeon evaluation boards require this setting
-                */
-               if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
-                       usbn_clk_ctl.cn31xx.p_xenbn = 0;
-               } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       usbn_clk_ctl.cn56xx.p_rtype = 2; /* From CN56XX,CN50XX manual */
-               else
-                       usbn_clk_ctl.cn52xx.p_rtype = 1; /* From CN52XX manual */
-
-               switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
-               case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
-                       usbn_clk_ctl.s.p_c_sel = 0;
-                       break;
-               case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:
-                       usbn_clk_ctl.s.p_c_sel = 1;
-                       break;
-               case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:
-                       usbn_clk_ctl.s.p_c_sel = 2;
-                       break;
-               }
-       } else {
-               /*
-                * The USB port uses a 12MHz crystal as clock source
-                * at USB_XO and USB_XI
-                */
-               if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
-                       usbn_clk_ctl.cn31xx.p_xenbn = 1;
-               } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       usbn_clk_ctl.cn56xx.p_rtype = 0; /* From CN56XX,CN50XX manual */
-               else
-                       usbn_clk_ctl.cn52xx.p_rtype = 0; /* From CN52XX manual */
-
-               usbn_clk_ctl.s.p_c_sel = 0;
-       }
-       /*
-        * 2c. Select the HCLK via writing USBN0/1_CLK_CTL[DIVIDE, DIVIDE2] and
-        *     setting USBN0/1_CLK_CTL[ENABLE] = 1. Divide the core clock down
-        *     such that USB is as close as possible to 125Mhz
-        */
-       {
-               int divisor = (octeon_get_clock_rate()+125000000-1)/125000000;
-               if (divisor < 4)  /* Lower than 4 doesn't seem to work properly */
-                       divisor = 4;
-               usbn_clk_ctl.s.divide = divisor;
-               usbn_clk_ctl.s.divide2 = 0;
-       }
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */
-       usbn_clk_ctl.s.hclk_rst = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /* 2e.  Wait 64 core-clock cycles for HCLK to stabilize */
-       cvmx_wait(64);
-       /*
-        * 3. Program the power-on reset field in the USBN clock-control
-        *    register:
-        *    USBN_CLK_CTL[POR] = 0
-        */
-       usbn_clk_ctl.s.por = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /* 4. Wait 1 ms for PHY clock to start */
-       mdelay(1);
-       /*
-        * 5. Program the Reset input from automatic test equipment field in the
-        *    USBP control and status register:
-        *    USBN_USBP_CTL_STATUS[ATE_RESET] = 1
-        */
-       usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
-       usbn_usbp_ctl_status.s.ate_reset = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
-       /* 6. Wait 10 cycles */
-       cvmx_wait(10);
-       /*
-        * 7. Clear ATE_RESET field in the USBN clock-control register:
-        *    USBN_USBP_CTL_STATUS[ATE_RESET] = 0
-        */
-       usbn_usbp_ctl_status.s.ate_reset = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
-       /*
-        * 8. Program the PHY reset field in the USBN clock-control register:
-        *    USBN_CLK_CTL[PRST] = 1
-        */
-       usbn_clk_ctl.s.prst = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /*
-        * 9. Program the USBP control and status register to select host or
-        *    device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for
-        *    device
-        */
-       usbn_usbp_ctl_status.s.hst_mode = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
-       /* 10. Wait 1 us */
-       udelay(1);
-       /*
-        * 11. Program the hreset_n field in the USBN clock-control register:
-        *     USBN_CLK_CTL[HRST] = 1
-        */
-       usbn_clk_ctl.s.hrst = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /* 12. Proceed to USB core initialization */
-       usbn_clk_ctl.s.enable = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       udelay(1);
-
-       /*
-        * USB Core Initialization
-        *
-        * 1. Read USBC_GHWCFG1, USBC_GHWCFG2, USBC_GHWCFG3, USBC_GHWCFG4 to
-        *    determine USB core configuration parameters.
-        *
-        *    Nothing needed
-        *
-        * 2. Program the following fields in the global AHB configuration
-        *    register (USBC_GAHBCFG)
-        *    DMA mode, USBC_GAHBCFG[DMAEn]: 1 = DMA mode, 0 = slave mode
-        *    Burst length, USBC_GAHBCFG[HBSTLEN] = 0
-        *    Nonperiodic TxFIFO empty level (slave mode only),
-        *    USBC_GAHBCFG[NPTXFEMPLVL]
-        *    Periodic TxFIFO empty level (slave mode only),
-        *    USBC_GAHBCFG[PTXFEMPLVL]
-        *    Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1
-        */
-       {
-               union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
-               /* Due to an errata, CN31XX doesn't support DMA */
-               if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-                       usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
-               usbcx_gahbcfg.u32 = 0;
-               usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       usb->idle_hardware_channels = 0x1;  /* Only use one channel with non DMA */
-               else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
-                       usb->idle_hardware_channels = 0xf7; /* CN5XXX have an errata with channel 3 */
-               else
-                       usb->idle_hardware_channels = 0xff;
-               usbcx_gahbcfg.s.hbstlen = 0;
-               usbcx_gahbcfg.s.nptxfemplvl = 1;
-               usbcx_gahbcfg.s.ptxfemplvl = 1;
-               usbcx_gahbcfg.s.glblintrmsk = 1;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
-                                      usbcx_gahbcfg.u32);
-       }
-       /*
-        * 3. Program the following fields in USBC_GUSBCFG register.
-        *    HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0
-        *    ULPI DDR select, USBC_GUSBCFG[DDRSEL] = 0
-        *    USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5
-        *    PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0
-        */
-       {
-               union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
-               usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index));
-               usbcx_gusbcfg.s.toutcal = 0;
-               usbcx_gusbcfg.s.ddrsel = 0;
-               usbcx_gusbcfg.s.usbtrdtim = 0x5;
-               usbcx_gusbcfg.s.phylpwrclksel = 0;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
-                                      usbcx_gusbcfg.u32);
-       }
-       /*
-        * 4. The software must unmask the following bits in the USBC_GINTMSK
-        *    register.
-        *    OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1
-        *    Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1
-        */
-       {
-               union cvmx_usbcx_gintmsk usbcx_gintmsk;
-               int channel;
-
-               usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTMSK(usb->index));
-               usbcx_gintmsk.s.otgintmsk = 1;
-               usbcx_gintmsk.s.modemismsk = 1;
-               usbcx_gintmsk.s.hchintmsk = 1;
-               usbcx_gintmsk.s.sofmsk = 0;
-               /* We need RX FIFO interrupts if we don't have DMA */
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       usbcx_gintmsk.s.rxflvlmsk = 1;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
-                                      usbcx_gintmsk.u32);
-
-               /* Disable all channel interrupts. We'll enable them per channel later */
-               for (channel = 0; channel < 8; channel++)
-                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
-       }
-
-       {
-               /*
-                * Host Port Initialization
-                *
-                * 1. Program the host-port interrupt-mask field to unmask,
-                *    USBC_GINTMSK[PRTINT] = 1
-                */
-               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
-                               prtintmsk, 1);
-               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
-                               disconnintmsk, 1);
-               /*
-                * 2. Program the USBC_HCFG register to select full-speed host
-                *    or high-speed host.
-                */
-               {
-                       union cvmx_usbcx_hcfg usbcx_hcfg;
-                       usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
-                       usbcx_hcfg.s.fslssupp = 0;
-                       usbcx_hcfg.s.fslspclksel = 0;
-                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
-               }
-               /*
-                * 3. Program the port power bit to drive VBUS on the USB,
-                *    USBC_HPRT[PRTPWR] = 1
-                */
-               USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtpwr, 1);
-
-               /*
-                * Steps 4-15 from the manual are done later in the port enable
-                */
-       }
-
-       return 0;
-}
-
-
-/**
- * Shutdown a USB port after a call to cvmx_usb_initialize().
- * The port should be disabled with all pipes closed when this
- * function is called.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_shutdown(struct cvmx_usb_state *state)
-{
-       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Make sure all pipes are closed */
-       if (usb->idle_pipes.head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS].head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT].head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_CONTROL].head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_BULK].head)
-               return -EBUSY;
-
-       /* Disable the clocks and put them in power on reset */
-       usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
-       usbn_clk_ctl.s.enable = 1;
-       usbn_clk_ctl.s.por = 1;
-       usbn_clk_ctl.s.hclk_rst = 1;
-       usbn_clk_ctl.s.prst = 0;
-       usbn_clk_ctl.s.hrst = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       return 0;
-}
-
-
-/**
- * Enable a USB port. After this call succeeds, the USB port is
- * online and servicing requests.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_enable(struct cvmx_usb_state *state)
-{
-       union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
-
-       /*
-        * If the port is already enabled the just return. We don't need to do
-        * anything
-        */
-       if (usb->usbcx_hprt.s.prtena)
-               return 0;
-
-       /* If there is nothing plugged into the port then fail immediately */
-       if (!usb->usbcx_hprt.s.prtconnsts) {
-               return -ETIMEDOUT;
-       }
-
-       /* Program the port reset bit to start the reset process */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtrst, 1);
-
-       /*
-        * Wait at least 50ms (high speed), or 10ms (full speed) for the reset
-        * process to complete.
-        */
-       mdelay(50);
-
-       /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtrst, 0);
-
-       /* Wait for the USBC_HPRT[PRTENA]. */
-       if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
-                                 prtena, ==, 1, 100000))
-               return -ETIMEDOUT;
-
-       /* Read the port speed field to get the enumerated speed, USBC_HPRT[PRTSPD]. */
-       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
-       usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
-
-       /*
-        * 13. Program the USBC_GRXFSIZ register to select the size of the
-        *     receive FIFO (25%).
-        */
-       USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), union cvmx_usbcx_grxfsiz,
-                       rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
-       /*
-        * 14. Program the USBC_GNPTXFSIZ register to select the size and the
-        *     start address of the non- periodic transmit FIFO for nonperiodic
-        *     transactions (50%).
-        */
-       {
-               union cvmx_usbcx_gnptxfsiz siz;
-               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
-               siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
-               siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
-       }
-       /*
-        * 15. Program the USBC_HPTXFSIZ register to select the size and start
-        *     address of the periodic transmit FIFO for periodic transactions
-        *     (25%).
-        */
-       {
-               union cvmx_usbcx_hptxfsiz siz;
-               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
-               siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
-               siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
-       }
-       /* Flush all FIFOs */
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfnum, 0x10);
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
-                             txfflsh, ==, 0, 100);
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, rxfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
-                             rxfflsh, ==, 0, 100);
-
-       return 0;
-}
-
-
-/**
- * Disable a USB port. After this call the USB port will not
- * generate data transfers and will not generate events.
- * Transactions in process will fail and call their
- * associated callbacks.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_disable(struct cvmx_usb_state *state)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Disable the port */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtena, 1);
-       return 0;
-}
-
-
-/**
- * Get the current state of the USB port. Use this call to
- * determine if the usb port has anything connected, is enabled,
- * or has some sort of error condition. The return value of this
- * call has "changed" bits to signal of the value of some fields
- * have changed between calls. These "changed" fields are based
- * on the last call to cvmx_usb_set_status(). In order to clear
- * them, you must update the status through cvmx_usb_set_status().
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: Port status information
- */
-struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *state)
-{
-       union cvmx_usbcx_hprt usbc_hprt;
-       struct cvmx_usb_port_status result;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       memset(&result, 0, sizeof(result));
-
-       usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
-       result.port_enabled = usbc_hprt.s.prtena;
-       result.port_over_current = usbc_hprt.s.prtovrcurract;
-       result.port_powered = usbc_hprt.s.prtpwr;
-       result.port_speed = usbc_hprt.s.prtspd;
-       result.connected = usbc_hprt.s.prtconnsts;
-       result.connect_change = (result.connected != usb->port_status.connected);
-
-       return result;
-}
-
-
-/**
- * Set the current state of the USB port. The status is used as
- * a reference for the "changed" bits returned by
- * cvmx_usb_get_status(). Other than serving as a reference, the
- * status passed to this function is not used. No fields can be
- * changed through this call.
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @port_status:
- *              Port status to set, most like returned by cvmx_usb_get_status()
- */
-void cvmx_usb_set_status(struct cvmx_usb_state *state, struct cvmx_usb_port_status port_status)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       usb->port_status = port_status;
-       return;
-}
-
-
-/**
- * Convert a USB transaction into a handle
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @transaction:
- *              Transaction to get handle for
- *
- * Returns: Handle
- */
-static inline int __cvmx_usb_get_submit_handle(struct cvmx_usb_internal_state *usb,
-                                              struct cvmx_usb_transaction *transaction)
-{
-       return ((unsigned long)transaction - (unsigned long)usb->transaction) /
-                       sizeof(*transaction);
-}
-
-
-/**
- * Convert a USB pipe into a handle
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe:       Pipe to get handle for
- *
- * Returns: Handle
- */
-static inline int __cvmx_usb_get_pipe_handle(struct cvmx_usb_internal_state *usb,
-                                            struct cvmx_usb_pipe *pipe)
-{
-       return ((unsigned long)pipe - (unsigned long)usb->pipe) / sizeof(*pipe);
-}
-
-
-/**
- * Open a virtual pipe between the host and a USB device. A pipe
- * must be opened before data can be transferred between a device
- * and Octeon.
- *
- * @state:          USB device state populated by
- *                  cvmx_usb_initialize().
- * @flags:          Optional pipe flags defined in
- *                  enum cvmx_usb_pipe_flags.
- * @device_addr:
- *                  USB device address to open the pipe to
- *                  (0-127).
- * @endpoint_num:
- *                  USB endpoint number to open the pipe to
- *                  (0-15).
- * @device_speed:
- *                  The speed of the device the pipe is going
- *                  to. This must match the device's speed,
- *                  which may be different than the port speed.
- * @max_packet:             The maximum packet length the device can
- *                  transmit/receive (low speed=0-8, full
- *                  speed=0-1023, high speed=0-1024). This value
- *                  comes from the standard endpoint descriptor
- *                  field wMaxPacketSize bits <10:0>.
- * @transfer_type:
- *                  The type of transfer this pipe is for.
- * @transfer_dir:
- *                  The direction the pipe is in. This is not
- *                  used for control pipes.
- * @interval:       For ISOCHRONOUS and INTERRUPT transfers,
- *                  this is how often the transfer is scheduled
- *                  for. All other transfers should specify
- *                  zero. The units are in frames (8000/sec at
- *                  high speed, 1000/sec for full speed).
- * @multi_count:
- *                  For high speed devices, this is the maximum
- *                  allowed number of packet per microframe.
- *                  Specify zero for non high speed devices. This
- *                  value comes from the standard endpoint descriptor
- *                  field wMaxPacketSize bits <12:11>.
- * @hub_device_addr:
- *                  Hub device address this device is connected
- *                  to. Devices connected directly to Octeon
- *                  use zero. This is only used when the device
- *                  is full/low speed behind a high speed hub.
- *                  The address will be of the high speed hub,
- *                  not and full speed hubs after it.
- * @hub_port:       Which port on the hub the device is
- *                  connected. Use zero for devices connected
- *                  directly to Octeon. Like hub_device_addr,
- *                  this is only used for full/low speed
- *                  devices behind a high speed hub.
- *
- * Returns: A non negative value is a pipe handle. Negative
- *         values are error codes.
- */
-int cvmx_usb_open_pipe(struct cvmx_usb_state *state, enum cvmx_usb_pipe_flags flags,
-                      int device_addr, int endpoint_num,
-                      enum cvmx_usb_speed device_speed, int max_packet,
-                      enum cvmx_usb_transfer transfer_type,
-                      enum cvmx_usb_direction transfer_dir, int interval,
-                      int multi_count, int hub_device_addr, int hub_port)
-{
-       struct cvmx_usb_pipe *pipe;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       if (unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
-               return -EINVAL;
-       if (unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
-               return -EINVAL;
-       if (unlikely(device_speed > CVMX_USB_SPEED_LOW))
-               return -EINVAL;
-       if (unlikely((max_packet <= 0) || (max_packet > 1024)))
-               return -EINVAL;
-       if (unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
-               return -EINVAL;
-       if (unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
-               (transfer_dir != CVMX_USB_DIRECTION_IN)))
-               return -EINVAL;
-       if (unlikely(interval < 0))
-               return -EINVAL;
-       if (unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
-               return -EINVAL;
-       if (unlikely(multi_count < 0))
-               return -EINVAL;
-       if (unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
-               (multi_count != 0)))
-               return -EINVAL;
-       if (unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
-               return -EINVAL;
-       if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
-               return -EINVAL;
-
-       /* Find a free pipe */
-       pipe = usb->free_pipes.head;
-       if (!pipe)
-               return -ENOMEM;
-       __cvmx_usb_remove_pipe(&usb->free_pipes, pipe);
-       pipe->flags = flags | __CVMX_USB_PIPE_FLAGS_OPEN;
-       if ((device_speed == CVMX_USB_SPEED_HIGH) &&
-               (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
-               (transfer_type == CVMX_USB_TRANSFER_BULK))
-               pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
-       pipe->device_addr = device_addr;
-       pipe->endpoint_num = endpoint_num;
-       pipe->device_speed = device_speed;
-       pipe->max_packet = max_packet;
-       pipe->transfer_type = transfer_type;
-       pipe->transfer_dir = transfer_dir;
-       /*
-        * All pipes use interval to rate limit NAK processing. Force an
-        * interval if one wasn't supplied
-        */
-       if (!interval)
-               interval = 1;
-       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-               pipe->interval = interval*8;
-               /* Force start splits to be schedule on uFrame 0 */
-               pipe->next_tx_frame = ((usb->frame_number+7)&~7) + pipe->interval;
-       } else {
-               pipe->interval = interval;
-               pipe->next_tx_frame = usb->frame_number + pipe->interval;
-       }
-       pipe->multi_count = multi_count;
-       pipe->hub_device_addr = hub_device_addr;
-       pipe->hub_port = hub_port;
-       pipe->pid_toggle = 0;
-       pipe->split_sc_frame = -1;
-       __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
-
-       /*
-        * We don't need to tell the hardware about this pipe yet since
-        * it doesn't have any submitted requests
-        */
-
-       return __cvmx_usb_get_pipe_handle(usb, pipe);
-}
-
-
-/**
- * Poll the RX FIFOs and remove data as needed. This function is only used
- * in non DMA mode. It is very important that this function be called quickly
- * enough to prevent FIFO overflow.
- *
- * @usb:       USB device state populated by
- *             cvmx_usb_initialize().
- */
-static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_internal_state *usb)
-{
-       union cvmx_usbcx_grxstsph rx_status;
-       int channel;
-       int bytes;
-       uint64_t address;
-       uint32_t *ptr;
-
-       rx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GRXSTSPH(usb->index));
-       /* Only read data if IN data is there */
-       if (rx_status.s.pktsts != 2)
-               return;
-       /* Check if no data is available */
-       if (!rx_status.s.bcnt)
-               return;
-
-       channel = rx_status.s.chnum;
-       bytes = rx_status.s.bcnt;
-       if (!bytes)
-               return;
-
-       /* Get where the DMA engine would have written this data */
-       address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
-       ptr = cvmx_phys_to_ptr(address);
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, address + bytes);
-
-       /* Loop writing the FIFO data for this packet into memory */
-       while (bytes > 0) {
-               *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index));
-               bytes -= 4;
-       }
-       CVMX_SYNCW;
-
-       return;
-}
-
-
-/**
- * Fill the TX hardware fifo with data out of the software
- * fifos
- *
- * @usb:           USB device state populated by
- *                 cvmx_usb_initialize().
- * @fifo:          Software fifo to use
- * @available:     Amount of space in the hardware fifo
- *
- * Returns: Non zero if the hardware fifo was too small and needs
- *         to be serviced again.
- */
-static int __cvmx_usb_fill_tx_hw(struct cvmx_usb_internal_state *usb, struct cvmx_usb_tx_fifo *fifo, int available)
-{
-       /*
-        * We're done either when there isn't anymore space or the software FIFO
-        * is empty
-        */
-       while (available && (fifo->head != fifo->tail)) {
-               int i = fifo->tail;
-               const uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
-               uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4;
-               int words = available;
-
-               /* Limit the amount of data to waht the SW fifo has */
-               if (fifo->entry[i].size <= available) {
-                       words = fifo->entry[i].size;
-                       fifo->tail++;
-                       if (fifo->tail > MAX_CHANNELS)
-                               fifo->tail = 0;
-               }
-
-               /* Update the next locations and counts */
-               available -= words;
-               fifo->entry[i].address += words * 4;
-               fifo->entry[i].size -= words;
-
-               /*
-                * Write the HW fifo data. The read every three writes is due
-                * to an errata on CN3XXX chips
-                */
-               while (words > 3) {
-                       cvmx_write64_uint32(csr_address, *ptr++);
-                       cvmx_write64_uint32(csr_address, *ptr++);
-                       cvmx_write64_uint32(csr_address, *ptr++);
-                       cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
-                       words -= 3;
-               }
-               cvmx_write64_uint32(csr_address, *ptr++);
-               if (--words) {
-                       cvmx_write64_uint32(csr_address, *ptr++);
-                       if (--words)
-                               cvmx_write64_uint32(csr_address, *ptr++);
-               }
-               cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
-       }
-       return fifo->head != fifo->tail;
-}
-
-
-/**
- * Check the hardware FIFOs and fill them as needed
- *
- * @usb:       USB device state populated by
- *             cvmx_usb_initialize().
- */
-static void __cvmx_usb_poll_tx_fifo(struct cvmx_usb_internal_state *usb)
-{
-       if (usb->periodic.head != usb->periodic.tail) {
-               union cvmx_usbcx_hptxsts tx_status;
-               tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXSTS(usb->index));
-               if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic, tx_status.s.ptxfspcavail))
-                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, ptxfempmsk, 1);
-               else
-                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, ptxfempmsk, 0);
-       }
-
-       if (usb->nonperiodic.head != usb->nonperiodic.tail) {
-               union cvmx_usbcx_gnptxsts tx_status;
-               tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXSTS(usb->index));
-               if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic, tx_status.s.nptxfspcavail))
-                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 1);
-               else
-                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 0);
-       }
-
-       return;
-}
-
-
-/**
- * Fill the TX FIFO with an outgoing packet
- *
- * @usb:         USB device state populated by
- *               cvmx_usb_initialize().
- * @channel:     Channel number to get packet from
- */
-static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_internal_state *usb, int channel)
-{
-       union cvmx_usbcx_hccharx hcchar;
-       union cvmx_usbcx_hcspltx usbc_hcsplt;
-       union cvmx_usbcx_hctsizx usbc_hctsiz;
-       struct cvmx_usb_tx_fifo *fifo;
-
-       /* We only need to fill data on outbound channels */
-       hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
-       if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT)
-               return;
-
-       /* OUT Splits only have data on the start and not the complete */
-       usbc_hcsplt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index));
-       if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
-               return;
-
-       /* Find out how many bytes we need to fill and convert it into 32bit words */
-       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
-       if (!usbc_hctsiz.s.xfersize)
-               return;
-
-       if ((hcchar.s.eptype == CVMX_USB_TRANSFER_INTERRUPT) ||
-               (hcchar.s.eptype == CVMX_USB_TRANSFER_ISOCHRONOUS))
-               fifo = &usb->periodic;
-       else
-               fifo = &usb->nonperiodic;
-
-       fifo->entry[fifo->head].channel = channel;
-       fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8);
-       fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2;
-       fifo->head++;
-       if (fifo->head > MAX_CHANNELS)
-               fifo->head = 0;
-
-       __cvmx_usb_poll_tx_fifo(usb);
-
-       return;
-}
-
-/**
- * Perform channel specific setup for Control transactions. All
- * the generic stuff will already have been done in
- * __cvmx_usb_start_channel()
- *
- * @usb:         USB device state populated by
- *               cvmx_usb_initialize().
- * @channel:     Channel to setup
- * @pipe:        Pipe for control transaction
- */
-static void __cvmx_usb_start_channel_control(struct cvmx_usb_internal_state *usb,
-                                            int channel,
-                                            struct cvmx_usb_pipe *pipe)
-{
-       struct cvmx_usb_transaction *transaction = pipe->head;
-       union cvmx_usb_control_header *header =
-               cvmx_phys_to_ptr(transaction->control_header);
-       int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
-       int packets_to_transfer;
-       union cvmx_usbcx_hctsizx usbc_hctsiz;
-
-       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
-
-       switch (transaction->stage) {
-       case CVMX_USB_STAGE_NON_CONTROL:
-       case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
-               cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
-               break;
-       case CVMX_USB_STAGE_SETUP:
-               usbc_hctsiz.s.pid = 3; /* Setup */
-               bytes_to_transfer = sizeof(*header);
-               /* All Control operations start with a setup going OUT */
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
-               /*
-                * Setup send the control header instead of the buffer data. The
-                * buffer data will be used in the next stage
-                */
-               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header);
-               break;
-       case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
-               usbc_hctsiz.s.pid = 3; /* Setup */
-               bytes_to_transfer = 0;
-               /* All Control operations start with a setup going OUT */
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
-               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
-               break;
-       case CVMX_USB_STAGE_DATA:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
-               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                       if (header->s.request_type & 0x80)
-                               bytes_to_transfer = 0;
-                       else if (bytes_to_transfer > pipe->max_packet)
-                               bytes_to_transfer = pipe->max_packet;
-               }
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       CVMX_USB_DIRECTION_IN :
-                                       CVMX_USB_DIRECTION_OUT));
-               break;
-       case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
-               if (!(header->s.request_type & 0x80))
-                       bytes_to_transfer = 0;
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       CVMX_USB_DIRECTION_IN :
-                                       CVMX_USB_DIRECTION_OUT));
-               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
-               break;
-       case CVMX_USB_STAGE_STATUS:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
-               bytes_to_transfer = 0;
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       CVMX_USB_DIRECTION_OUT :
-                                       CVMX_USB_DIRECTION_IN));
-               break;
-       case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
-               bytes_to_transfer = 0;
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       CVMX_USB_DIRECTION_OUT :
-                                       CVMX_USB_DIRECTION_IN));
-               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
-               break;
-       }
-
-       /*
-        * Make sure the transfer never exceeds the byte limit of the hardware.
-        * Further bytes will be sent as continued transactions
-        */
-       if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
-               /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */
-               bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
-               bytes_to_transfer *= pipe->max_packet;
-       }
-
-       /*
-        * Calculate the number of packets to transfer. If the length is zero
-        * we still need to transfer one packet
-        */
-       packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
-       if (packets_to_transfer == 0)
-               packets_to_transfer = 1;
-       else if ((packets_to_transfer > 1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
-               /*
-                * Limit to one packet when not using DMA. Channels must be
-                * restarted between every packet for IN transactions, so there
-                * is no reason to do multiple packets in a row
-                */
-               packets_to_transfer = 1;
-               bytes_to_transfer = packets_to_transfer * pipe->max_packet;
-       } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
-               /*
-                * Limit the number of packet and data transferred to what the
-                * hardware can handle
-                */
-               packets_to_transfer = MAX_TRANSFER_PACKETS;
-               bytes_to_transfer = packets_to_transfer * pipe->max_packet;
-       }
-
-       usbc_hctsiz.s.xfersize = bytes_to_transfer;
-       usbc_hctsiz.s.pktcnt = packets_to_transfer;
-
-       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
-       return;
-}
-
-
-/**
- * Start a channel to perform the pipe's head transaction
- *
- * @usb:         USB device state populated by
- *               cvmx_usb_initialize().
- * @channel:     Channel to setup
- * @pipe:        Pipe to start
- */
-static void __cvmx_usb_start_channel(struct cvmx_usb_internal_state *usb,
-                                    int channel,
-                                    struct cvmx_usb_pipe *pipe)
-{
-       struct cvmx_usb_transaction *transaction = pipe->head;
-
-       /* Make sure all writes to the DMA region get flushed */
-       CVMX_SYNCW;
-
-       /* Attach the channel to the pipe */
-       usb->pipe_for_channel[channel] = pipe;
-       pipe->channel = channel;
-       pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED;
-
-       /* Mark this channel as in use */
-       usb->idle_hardware_channels &= ~(1<<channel);
-
-       /* Enable the channel interrupt bits */
-       {
-               union cvmx_usbcx_hcintx usbc_hcint;
-               union cvmx_usbcx_hcintmskx usbc_hcintmsk;
-               union cvmx_usbcx_haintmsk usbc_haintmsk;
-
-               /* Clear all channel status bits */
-               usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
-
-               usbc_hcintmsk.u32 = 0;
-               usbc_hcintmsk.s.chhltdmsk = 1;
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
-                       /* Channels need these extra interrupts when we aren't in DMA mode */
-                       usbc_hcintmsk.s.datatglerrmsk = 1;
-                       usbc_hcintmsk.s.frmovrunmsk = 1;
-                       usbc_hcintmsk.s.bblerrmsk = 1;
-                       usbc_hcintmsk.s.xacterrmsk = 1;
-                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                               /* Splits don't generate xfercompl, so we need ACK and NYET */
-                               usbc_hcintmsk.s.nyetmsk = 1;
-                               usbc_hcintmsk.s.ackmsk = 1;
-                       }
-                       usbc_hcintmsk.s.nakmsk = 1;
-                       usbc_hcintmsk.s.stallmsk = 1;
-                       usbc_hcintmsk.s.xfercomplmsk = 1;
-               }
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32);
-
-               /* Enable the channel interrupt to propagate */
-               usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index));
-               usbc_haintmsk.s.haintmsk |= 1<<channel;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index), usbc_haintmsk.u32);
-       }
-
-       /* Setup the locations the DMA engines use  */
-       {
-               uint64_t dma_address = transaction->buffer + transaction->actual_bytes;
-               if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
-                       dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes;
-               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
-               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, dma_address);
-       }
-
-       /* Setup both the size of the transfer and the SPLIT characteristics */
-       {
-               union cvmx_usbcx_hcspltx usbc_hcsplt = {.u32 = 0};
-               union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = 0};
-               int packets_to_transfer;
-               int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
-
-               /*
-                * ISOCHRONOUS transactions store each individual transfer size
-                * in the packet structure, not the global buffer_length
-                */
-               if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
-                       bytes_to_transfer = transaction->iso_packets[0].length - transaction->actual_bytes;
-
-               /*
-                * We need to do split transactions when we are talking to non
-                * high speed devices that are behind a high speed hub
-                */
-               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                       /*
-                        * On the start split phase (stage is even) record the
-                        * frame number we will need to send the split complete.
-                        * We only store the lower two bits since the time ahead
-                        * can only be two frames
-                        */
-                       if ((transaction->stage&1) == 0) {
-                               if (transaction->type == CVMX_USB_TRANSFER_BULK)
-                                       pipe->split_sc_frame = (usb->frame_number + 1) & 0x7f;
-                               else
-                                       pipe->split_sc_frame = (usb->frame_number + 2) & 0x7f;
-                       } else
-                               pipe->split_sc_frame = -1;
-
-                       usbc_hcsplt.s.spltena = 1;
-                       usbc_hcsplt.s.hubaddr = pipe->hub_device_addr;
-                       usbc_hcsplt.s.prtaddr = pipe->hub_port;
-                       usbc_hcsplt.s.compsplt = (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE);
-
-                       /*
-                        * SPLIT transactions can only ever transmit one data
-                        * packet so limit the transfer size to the max packet
-                        * size
-                        */
-                       if (bytes_to_transfer > pipe->max_packet)
-                               bytes_to_transfer = pipe->max_packet;
-
-                       /*
-                        * ISOCHRONOUS OUT splits are unique in that they limit
-                        * data transfers to 188 byte chunks representing the
-                        * begin/middle/end of the data or all
-                        */
-                       if (!usbc_hcsplt.s.compsplt &&
-                               (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
-                               (pipe->transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
-                               /*
-                                * Clear the split complete frame number as
-                                * there isn't going to be a split complete
-                                */
-                               pipe->split_sc_frame = -1;
-                               /*
-                                * See if we've started this transfer and sent
-                                * data
-                                */
-                               if (transaction->actual_bytes == 0) {
-                                       /*
-                                        * Nothing sent yet, this is either a
-                                        * begin or the entire payload
-                                        */
-                                       if (bytes_to_transfer <= 188)
-                                               usbc_hcsplt.s.xactpos = 3; /* Entire payload in one go */
-                                       else
-                                               usbc_hcsplt.s.xactpos = 2; /* First part of payload */
-                               } else {
-                                       /*
-                                        * Continuing the previous data, we must
-                                        * either be in the middle or at the end
-                                        */
-                                       if (bytes_to_transfer <= 188)
-                                               usbc_hcsplt.s.xactpos = 1; /* End of payload */
-                                       else
-                                               usbc_hcsplt.s.xactpos = 0; /* Middle of payload */
-                               }
-                               /*
-                                * Again, the transfer size is limited to 188
-                                * bytes
-                                */
-                               if (bytes_to_transfer > 188)
-                                       bytes_to_transfer = 188;
-                       }
-               }
-
-               /*
-                * Make sure the transfer never exceeds the byte limit of the
-                * hardware. Further bytes will be sent as continued
-                * transactions
-                */
-               if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
-                       /*
-                        * Round MAX_TRANSFER_BYTES to a multiple of out packet
-                        * size
-                        */
-                       bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
-                       bytes_to_transfer *= pipe->max_packet;
-               }
-
-               /*
-                * Calculate the number of packets to transfer. If the length is
-                * zero we still need to transfer one packet
-                */
-               packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
-               if (packets_to_transfer == 0)
-                       packets_to_transfer = 1;
-               else if ((packets_to_transfer > 1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
-                       /*
-                        * Limit to one packet when not using DMA. Channels must
-                        * be restarted between every packet for IN
-                        * transactions, so there is no reason to do multiple
-                        * packets in a row
-                        */
-                       packets_to_transfer = 1;
-                       bytes_to_transfer = packets_to_transfer * pipe->max_packet;
-               } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
-                       /*
-                        * Limit the number of packet and data transferred to
-                        * what the hardware can handle
-                        */
-                       packets_to_transfer = MAX_TRANSFER_PACKETS;
-                       bytes_to_transfer = packets_to_transfer * pipe->max_packet;
-               }
-
-               usbc_hctsiz.s.xfersize = bytes_to_transfer;
-               usbc_hctsiz.s.pktcnt = packets_to_transfer;
-
-               /* Update the DATA0/DATA1 toggle */
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
-               /*
-                * High speed pipes may need a hardware ping before they start
-                */
-               if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING)
-                       usbc_hctsiz.s.dopng = 1;
-
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index), usbc_hcsplt.u32);
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
-       }
-
-       /* Setup the Host Channel Characteristics Register */
-       {
-               union cvmx_usbcx_hccharx usbc_hcchar = {.u32 = 0};
-
-               /*
-                * Set the startframe odd/even properly. This is only used for
-                * periodic
-                */
-               usbc_hcchar.s.oddfrm = usb->frame_number&1;
-
-               /*
-                * Set the number of back to back packets allowed by this
-                * endpoint. Split transactions interpret "ec" as the number of
-                * immediate retries of failure. These retries happen too
-                * quickly, so we disable these entirely for splits
-                */
-               if (__cvmx_usb_pipe_needs_split(usb, pipe))
-                       usbc_hcchar.s.ec = 1;
-               else if (pipe->multi_count < 1)
-                       usbc_hcchar.s.ec = 1;
-               else if (pipe->multi_count > 3)
-                       usbc_hcchar.s.ec = 3;
-               else
-                       usbc_hcchar.s.ec = pipe->multi_count;
-
-               /* Set the rest of the endpoint specific settings */
-               usbc_hcchar.s.devaddr = pipe->device_addr;
-               usbc_hcchar.s.eptype = transaction->type;
-               usbc_hcchar.s.lspddev = (pipe->device_speed == CVMX_USB_SPEED_LOW);
-               usbc_hcchar.s.epdir = pipe->transfer_dir;
-               usbc_hcchar.s.epnum = pipe->endpoint_num;
-               usbc_hcchar.s.mps = pipe->max_packet;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
-       }
-
-       /* Do transaction type specific fixups as needed */
-       switch (transaction->type) {
-       case CVMX_USB_TRANSFER_CONTROL:
-               __cvmx_usb_start_channel_control(usb, channel, pipe);
-               break;
-       case CVMX_USB_TRANSFER_BULK:
-       case CVMX_USB_TRANSFER_INTERRUPT:
-               break;
-       case CVMX_USB_TRANSFER_ISOCHRONOUS:
-               if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                       /*
-                        * ISO transactions require different PIDs depending on
-                        * direction and how many packets are needed
-                        */
-                       if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
-                               if (pipe->multi_count < 2) /* Need DATA0 */
-                                       USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union cvmx_usbcx_hctsizx, pid, 0);
-                               else /* Need MDATA */
-                                       USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union cvmx_usbcx_hctsizx, pid, 3);
-                       }
-               }
-               break;
-       }
-       {
-               union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index))};
-               transaction->xfersize = usbc_hctsiz.s.xfersize;
-               transaction->pktcnt = usbc_hctsiz.s.pktcnt;
-       }
-       /* Remeber when we start a split transaction */
-       if (__cvmx_usb_pipe_needs_split(usb, pipe))
-               usb->active_split = transaction;
-       USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, chena, 1);
-       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-               __cvmx_usb_fill_tx_fifo(usb, channel);
-       return;
-}
-
-
-/**
- * Find a pipe that is ready to be scheduled to hardware.
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @list:       Pipe list to search
- * @current_frame:
- *              Frame counter to use as a time reference.
- *
- * Returns: Pipe or NULL if none are ready
- */
-static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_internal_state *usb, struct cvmx_usb_pipe_list *list, uint64_t current_frame)
-{
-       struct cvmx_usb_pipe *pipe = list->head;
-       while (pipe) {
-               if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && pipe->head &&
-                       (pipe->next_tx_frame <= current_frame) &&
-                       ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
-                       (!usb->active_split || (usb->active_split == pipe->head))) {
-                       CVMX_PREFETCH(pipe, 128);
-                       CVMX_PREFETCH(pipe->head, 0);
-                       return pipe;
-               }
-               pipe = pipe->next;
-       }
-       return NULL;
-}
-
-
-/**
- * Called whenever a pipe might need to be scheduled to the
- * hardware.
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @is_sof:     True if this schedule was called on a SOF interrupt.
- */
-static void __cvmx_usb_schedule(struct cvmx_usb_internal_state *usb, int is_sof)
-{
-       int channel;
-       struct cvmx_usb_pipe *pipe;
-       int need_sof;
-       enum cvmx_usb_transfer ttype;
-
-       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
-               /* Without DMA we need to be careful to not schedule something at the end of a frame and cause an overrun */
-               union cvmx_usbcx_hfnum hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))};
-               union cvmx_usbcx_hfir hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))};
-               if (hfnum.s.frrem < hfir.s.frint/4)
-                       goto done;
-       }
-
-       while (usb->idle_hardware_channels) {
-               /* Find an idle channel */
-               CVMX_CLZ(channel, usb->idle_hardware_channels);
-               channel = 31 - channel;
-               if (unlikely(channel > 7))
-                       break;
-
-               /* Find a pipe needing service */
-               pipe = NULL;
-               if (is_sof) {
-                       /*
-                        * Only process periodic pipes on SOF interrupts. This
-                        * way we are sure that the periodic data is sent in the
-                        * beginning of the frame
-                        */
-                       pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number);
-                       if (likely(!pipe))
-                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number);
-               }
-               if (likely(!pipe)) {
-                       pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number);
-                       if (likely(!pipe))
-                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number);
-               }
-               if (!pipe)
-                       break;
-
-               __cvmx_usb_start_channel(usb, channel, pipe);
-       }
-
-done:
-       /*
-        * Only enable SOF interrupts when we have transactions pending in the
-        * future that might need to be scheduled
-        */
-       need_sof = 0;
-       for (ttype = CVMX_USB_TRANSFER_CONTROL; ttype <= CVMX_USB_TRANSFER_INTERRUPT; ttype++) {
-               pipe = usb->active_pipes[ttype].head;
-               while (pipe) {
-                       if (pipe->next_tx_frame > usb->frame_number) {
-                               need_sof = 1;
-                               break;
-                       }
-                       pipe = pipe->next;
-               }
-       }
-       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, sofmsk, need_sof);
-       return;
-}
-
-
-/**
- * Call a user's callback for a specific reason.
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe:       Pipe the callback is for or NULL
- * @transaction:
- *              Transaction the callback is for or NULL
- * @reason:     Reason this callback is being called
- * @complete_code:
- *              Completion code for the transaction, if any
- */
-static void __cvmx_usb_perform_callback(struct cvmx_usb_internal_state *usb,
-                                       struct cvmx_usb_pipe *pipe,
-                                       struct cvmx_usb_transaction *transaction,
-                                       enum cvmx_usb_callback reason,
-                                       enum cvmx_usb_complete complete_code)
-{
-       cvmx_usb_callback_func_t callback = usb->callback[reason];
-       void *user_data = usb->callback_data[reason];
-       int submit_handle = -1;
-       int pipe_handle = -1;
-       int bytes_transferred = 0;
-
-       if (pipe)
-               pipe_handle = __cvmx_usb_get_pipe_handle(usb, pipe);
-
-       if (transaction) {
-               submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
-               bytes_transferred = transaction->actual_bytes;
-               /* Transactions are allowed to override the default callback */
-               if ((reason == CVMX_USB_CALLBACK_TRANSFER_COMPLETE) && transaction->callback) {
-                       callback = transaction->callback;
-                       user_data = transaction->callback_data;
-               }
-       }
-
-       if (!callback)
-               return;
-
-       callback((struct cvmx_usb_state *)usb, reason, complete_code, pipe_handle, submit_handle,
-                bytes_transferred, user_data);
-}
-
-
-/**
- * Signal the completion of a transaction and free it. The
- * transaction will be removed from the pipe transaction list.
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe:       Pipe the transaction is on
- * @transaction:
- *              Transaction that completed
- * @complete_code:
- *              Completion code
- */
-static void __cvmx_usb_perform_complete(struct cvmx_usb_internal_state *usb,
-                                       struct cvmx_usb_pipe *pipe,
-                                       struct cvmx_usb_transaction *transaction,
-                                       enum cvmx_usb_complete complete_code)
-{
-       /* If this was a split then clear our split in progress marker */
-       if (usb->active_split == transaction)
-               usb->active_split = NULL;
-
-       /*
-        * Isochronous transactions need extra processing as they might not be
-        * done after a single data transfer
-        */
-       if (unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
-               /* Update the number of bytes transferred in this ISO packet */
-               transaction->iso_packets[0].length = transaction->actual_bytes;
-               transaction->iso_packets[0].status = complete_code;
-
-               /*
-                * If there are more ISOs pending and we succeeded, schedule the
-                * next one
-                */
-               if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS)) {
-                       transaction->actual_bytes = 0;     /* No bytes transferred for this packet as of yet */
-                       transaction->iso_number_packets--; /* One less ISO waiting to transfer */
-                       transaction->iso_packets++;        /* Increment to the next location in our packet array */
-                       transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
-                       goto done;
-               }
-       }
-
-       /* Remove the transaction from the pipe list */
-       if (transaction->next)
-               transaction->next->prev = transaction->prev;
-       else
-               pipe->tail = transaction->prev;
-       if (transaction->prev)
-               transaction->prev->next = transaction->next;
-       else
-               pipe->head = transaction->next;
-       if (!pipe->head) {
-               __cvmx_usb_remove_pipe(usb->active_pipes + pipe->transfer_type, pipe);
-               __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
-
-       }
-       __cvmx_usb_perform_callback(usb, pipe, transaction,
-                                   CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
-                                   complete_code);
-       __cvmx_usb_free_transaction(usb, transaction);
-done:
-       return;
-}
-
-
-/**
- * Submit a usb transaction to a pipe. Called for all types
- * of transactions.
- *
- * @usb:
- * @pipe_handle:
- *                 Which pipe to submit to. Will be validated in this function.
- * @type:          Transaction type
- * @flags:         Flags for the transaction
- * @buffer:        User buffer for the transaction
- * @buffer_length:
- *                 User buffer's length in bytes
- * @control_header:
- *                 For control transactions, the 8 byte standard header
- * @iso_start_frame:
- *                 For ISO transactions, the start frame
- * @iso_number_packets:
- *                 For ISO, the number of packet in the transaction.
- * @iso_packets:
- *                 A description of each ISO packet
- * @callback:      User callback to call when the transaction completes
- * @user_data:     User's data for the callback
- *
- * Returns: Submit handle or negative on failure. Matches the result
- *         in the external API.
- */
-static int __cvmx_usb_submit_transaction(struct cvmx_usb_internal_state *usb,
-                                        int pipe_handle,
-                                        enum cvmx_usb_transfer type,
-                                        int flags,
-                                        uint64_t buffer,
-                                        int buffer_length,
-                                        uint64_t control_header,
-                                        int iso_start_frame,
-                                        int iso_number_packets,
-                                        struct cvmx_usb_iso_packet *iso_packets,
-                                        cvmx_usb_callback_func_t callback,
-                                        void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_transaction *transaction;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-       if (unlikely(pipe->transfer_type != type))
-               return -EINVAL;
-
-       transaction = __cvmx_usb_alloc_transaction(usb);
-       if (unlikely(!transaction))
-               return -ENOMEM;
-
-       transaction->type = type;
-       transaction->flags |= flags;
-       transaction->buffer = buffer;
-       transaction->buffer_length = buffer_length;
-       transaction->control_header = control_header;
-       transaction->iso_start_frame = iso_start_frame; // FIXME: This is not used, implement it
-       transaction->iso_number_packets = iso_number_packets;
-       transaction->iso_packets = iso_packets;
-       transaction->callback = callback;
-       transaction->callback_data = user_data;
-       if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
-               transaction->stage = CVMX_USB_STAGE_SETUP;
-       else
-               transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
-
-       transaction->next = NULL;
-       if (pipe->tail) {
-               transaction->prev = pipe->tail;
-               transaction->prev->next = transaction;
-       } else {
-               if (pipe->next_tx_frame < usb->frame_number)
-                       pipe->next_tx_frame = usb->frame_number + pipe->interval -
-                               (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
-               transaction->prev = NULL;
-               pipe->head = transaction;
-               __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
-               __cvmx_usb_append_pipe(usb->active_pipes + pipe->transfer_type, pipe);
-       }
-       pipe->tail = transaction;
-
-       submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
-
-       /* We may need to schedule the pipe if this was the head of the pipe */
-       if (!transaction->prev)
-               __cvmx_usb_schedule(usb, 0);
-
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Bulk transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_bulk(struct cvmx_usb_state *state, int pipe_handle,
-                        uint64_t buffer, int buffer_length,
-                        cvmx_usb_callback_func_t callback,
-                        void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(!buffer))
-               return -EINVAL;
-       if (unlikely(buffer_length < 0))
-               return -EINVAL;
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_BULK,
-                                                     0, /* flags */
-                                                     buffer,
-                                                     buffer_length,
-                                                     0, /* control_header */
-                                                     0, /* iso_start_frame */
-                                                     0, /* iso_number_packets */
-                                                     NULL, /* iso_packets */
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Interrupt transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_interrupt(struct cvmx_usb_state *state, int pipe_handle,
-                             uint64_t buffer, int buffer_length,
-                             cvmx_usb_callback_func_t callback,
-                             void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(!buffer))
-               return -EINVAL;
-       if (unlikely(buffer_length < 0))
-               return -EINVAL;
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_INTERRUPT,
-                                                     0, /* flags */
-                                                     buffer,
-                                                     buffer_length,
-                                                     0, /* control_header */
-                                                     0, /* iso_start_frame */
-                                                     0, /* iso_number_packets */
-                                                     NULL, /* iso_packets */
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Control transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @control_header:
- *                 USB 8 byte control header physical address.
- *                 Note that this is NOT A POINTER, but the
- *                 full 64bit physical address of the buffer.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
-                           uint64_t control_header,
-                           uint64_t buffer, int buffer_length,
-                           cvmx_usb_callback_func_t callback,
-                           void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       union cvmx_usb_control_header *header =
-               cvmx_phys_to_ptr(control_header);
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(!control_header))
-               return -EINVAL;
-       /* Some drivers send a buffer with a zero length. God only knows why */
-       if (unlikely(buffer && (buffer_length < 0)))
-               return -EINVAL;
-       if (unlikely(!buffer && (buffer_length != 0)))
-               return -EINVAL;
-       if ((header->s.request_type & 0x80) == 0)
-               buffer_length = le16_to_cpu(header->s.length);
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_CONTROL,
-                                                     0, /* flags */
-                                                     buffer,
-                                                     buffer_length,
-                                                     control_header,
-                                                     0, /* iso_start_frame */
-                                                     0, /* iso_number_packets */
-                                                     NULL, /* iso_packets */
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Isochronous transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @start_frame:
- *                 Number of frames into the future to schedule
- *                 this transaction.
- * @flags:         Flags to control the transfer. See
- *                 enum cvmx_usb_isochronous_flags for the flag
- *                 definitions.
- * @number_packets:
- *                 Number of sequential packets to transfer.
- *                 "packets" is a pointer to an array of this
- *                 many packet structures.
- * @packets:       Description of each transfer packet as
- *                 defined by struct cvmx_usb_iso_packet. The array
- *                 pointed to here must stay valid until the
- *                 complete callback is called.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
-                               int start_frame, int flags,
-                               int number_packets,
-                               struct cvmx_usb_iso_packet packets[],
-                               uint64_t buffer, int buffer_length,
-                               cvmx_usb_callback_func_t callback,
-                               void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(start_frame < 0))
-               return -EINVAL;
-       if (unlikely(flags & ~(CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP)))
-               return -EINVAL;
-       if (unlikely(number_packets < 1))
-               return -EINVAL;
-       if (unlikely(!packets))
-               return -EINVAL;
-       if (unlikely(!buffer))
-               return -EINVAL;
-       if (unlikely(buffer_length < 0))
-               return -EINVAL;
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_ISOCHRONOUS,
-                                                     flags,
-                                                     buffer,
-                                                     buffer_length,
-                                                     0, /* control_header */
-                                                     start_frame,
-                                                     number_packets,
-                                                     packets,
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Cancel one outstanding request in a pipe. Canceling a request
- * can fail if the transaction has already completed before cancel
- * is called. Even after a successful cancel call, it may take
- * a frame or two for the cvmx_usb_poll() function to call the
- * associated callback.
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe_handle:
- *              Pipe handle to cancel requests in.
- * @submit_handle:
- *              Handle to transaction to cancel, returned by the submit function.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_cancel(struct cvmx_usb_state *state, int pipe_handle, int submit_handle)
-{
-       struct cvmx_usb_transaction *transaction;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-       if (unlikely((submit_handle < 0) || (submit_handle >= MAX_TRANSACTIONS)))
-               return -EINVAL;
-
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       transaction = usb->transaction + submit_handle;
-
-       /* Fail if this transaction already completed */
-       if (unlikely((transaction->flags & __CVMX_USB_TRANSACTION_FLAGS_IN_USE) == 0))
-               return -EINVAL;
-
-       /*
-        * If the transaction is the HEAD of the queue and scheduled. We need to
-        * treat it special
-        */
-       if ((pipe->head == transaction) &&
-               (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
-               union cvmx_usbcx_hccharx usbc_hcchar;
-
-               usb->pipe_for_channel[pipe->channel] = NULL;
-               pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
-
-               CVMX_SYNCW;
-
-               usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
-               /* If the channel isn't enabled then the transaction already completed */
-               if (usbc_hcchar.s.chena) {
-                       usbc_hcchar.s.chdis = 1;
-                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32);
-               }
-       }
-       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL);
-       return 0;
-}
-
-
-/**
- * Cancel all outstanding requests in a pipe. Logically all this
- * does is call cvmx_usb_cancel() in a loop.
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe_handle:
- *              Pipe handle to cancel requests in.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_cancel_all(struct cvmx_usb_state *state, int pipe_handle)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       /* Simply loop through and attempt to cancel each transaction */
-       while (pipe->head) {
-               int result = cvmx_usb_cancel(state, pipe_handle,
-                       __cvmx_usb_get_submit_handle(usb, pipe->head));
-               if (unlikely(result != 0))
-                       return result;
-       }
-       return 0;
-}
-
-
-/**
- * Close a pipe created with cvmx_usb_open_pipe().
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe_handle:
- *              Pipe handle to close.
- *
- * Returns: 0 or a negative error code. EBUSY is returned if the pipe has
- *         outstanding transfers.
- */
-int cvmx_usb_close_pipe(struct cvmx_usb_state *state, int pipe_handle)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       /* Fail if the pipe has pending transactions */
-       if (unlikely(pipe->head))
-               return -EBUSY;
-
-       pipe->flags = 0;
-       __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
-       __cvmx_usb_append_pipe(&usb->free_pipes, pipe);
-
-       return 0;
-}
-
-
-/**
- * Register a function to be called when various USB events occur.
- *
- * @state:     USB device state populated by
- *            cvmx_usb_initialize().
- * @reason:    Which event to register for.
- * @callback:  Function to call when the event occurs.
- * @user_data: User data parameter to the function.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_register_callback(struct cvmx_usb_state *state,
-                              enum cvmx_usb_callback reason,
-                              cvmx_usb_callback_func_t callback,
-                              void *user_data)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       if (unlikely(reason >= __CVMX_USB_CALLBACK_END))
-               return -EINVAL;
-       if (unlikely(!callback))
-               return -EINVAL;
-
-       usb->callback[reason] = callback;
-       usb->callback_data[reason] = user_data;
-
-       return 0;
-}
-
-
-/**
- * Get the current USB protocol level frame number. The frame
- * number is always in the range of 0-0x7ff.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: USB frame number
- */
-int cvmx_usb_get_frame_number(struct cvmx_usb_state *state)
-{
-       int frame_number;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       union cvmx_usbcx_hfnum usbc_hfnum;
-
-       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
-       frame_number = usbc_hfnum.s.frnum;
-
-       return frame_number;
-}
-
-
-/**
- * Poll a channel for status
- *
- * @usb:     USB device
- * @channel: Channel to poll
- *
- * Returns: Zero on success
- */
-static int __cvmx_usb_poll_channel(struct cvmx_usb_internal_state *usb, int channel)
-{
-       union cvmx_usbcx_hcintx usbc_hcint;
-       union cvmx_usbcx_hctsizx usbc_hctsiz;
-       union cvmx_usbcx_hccharx usbc_hcchar;
-       struct cvmx_usb_pipe *pipe;
-       struct cvmx_usb_transaction *transaction;
-       int bytes_this_transfer;
-       int bytes_in_last_packet;
-       int packets_processed;
-       int buffer_space_left;
-
-       /* Read the interrupt status bits for the channel */
-       usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
-
-       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
-               usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
-
-               if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis) {
-                       /*
-                        * There seems to be a bug in CN31XX which can cause
-                        * interrupt IN transfers to get stuck until we do a
-                        * write of HCCHARX without changing things
-                        */
-                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
-                       return 0;
-               }
-
-               /*
-                * In non DMA mode the channels don't halt themselves. We need
-                * to manually disable channels that are left running
-                */
-               if (!usbc_hcint.s.chhltd) {
-                       if (usbc_hcchar.s.chena) {
-                               union cvmx_usbcx_hcintmskx hcintmsk;
-                               /* Disable all interrupts except CHHLTD */
-                               hcintmsk.u32 = 0;
-                               hcintmsk.s.chhltdmsk = 1;
-                               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), hcintmsk.u32);
-                               usbc_hcchar.s.chdis = 1;
-                               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
-                               return 0;
-                       } else if (usbc_hcint.s.xfercompl) {
-                               /* Successful IN/OUT with transfer complete. Channel halt isn't needed */
-                       } else {
-                               cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", usb->index, channel);
-                               return 0;
-                       }
-               }
-       } else {
-               /*
-                * There is are no interrupts that we need to process when the
-                * channel is still running
-                */
-               if (!usbc_hcint.s.chhltd)
-                       return 0;
-       }
-
-       /* Disable the channel interrupts now that it is done */
-       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
-       usb->idle_hardware_channels |= (1<<channel);
-
-       /* Make sure this channel is tied to a valid pipe */
-       pipe = usb->pipe_for_channel[channel];
-       CVMX_PREFETCH(pipe, 0);
-       CVMX_PREFETCH(pipe, 128);
-       if (!pipe)
-               return 0;
-       transaction = pipe->head;
-       CVMX_PREFETCH0(transaction);
-
-       /*
-        * Disconnect this pipe from the HW channel. Later the schedule
-        * function will figure out which pipe needs to go
-        */
-       usb->pipe_for_channel[channel] = NULL;
-       pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
-
-       /*
-        * Read the channel config info so we can figure out how much data
-        * transfered
-        */
-       usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
-       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
-
-       /*
-        * Calculating the number of bytes successfully transferred is dependent
-        * on the transfer direction
-        */
-       packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt;
-       if (usbc_hcchar.s.epdir) {
-               /*
-                * IN transactions are easy. For every byte received the
-                * hardware decrements xfersize. All we need to do is subtract
-                * the current value of xfersize from its starting value and we
-                * know how many bytes were written to the buffer
-                */
-               bytes_this_transfer = transaction->xfersize - usbc_hctsiz.s.xfersize;
-       } else {
-               /*
-                * OUT transaction don't decrement xfersize. Instead pktcnt is
-                * decremented on every successful packet send. The hardware
-                * does this when it receives an ACK, or NYET. If it doesn't
-                * receive one of these responses pktcnt doesn't change
-                */
-               bytes_this_transfer = packets_processed * usbc_hcchar.s.mps;
-               /*
-                * The last packet may not be a full transfer if we didn't have
-                * enough data
-                */
-               if (bytes_this_transfer > transaction->xfersize)
-                       bytes_this_transfer = transaction->xfersize;
-       }
-       /* Figure out how many bytes were in the last packet of the transfer */
-       if (packets_processed)
-               bytes_in_last_packet = bytes_this_transfer - (packets_processed-1) * usbc_hcchar.s.mps;
-       else
-               bytes_in_last_packet = bytes_this_transfer;
-
-       /*
-        * As a special case, setup transactions output the setup header, not
-        * the user's data. For this reason we don't count setup data as bytes
-        * transferred
-        */
-       if ((transaction->stage == CVMX_USB_STAGE_SETUP) ||
-               (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE))
-               bytes_this_transfer = 0;
-
-       /*
-        * Add the bytes transferred to the running total. It is important that
-        * bytes_this_transfer doesn't count any data that needs to be
-        * retransmitted
-        */
-       transaction->actual_bytes += bytes_this_transfer;
-       if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
-               buffer_space_left = transaction->iso_packets[0].length - transaction->actual_bytes;
-       else
-               buffer_space_left = transaction->buffer_length - transaction->actual_bytes;
-
-       /*
-        * We need to remember the PID toggle state for the next transaction.
-        * The hardware already updated it for the next transaction
-        */
-       pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0);
-
-       /*
-        * For high speed bulk out, assume the next transaction will need to do
-        * a ping before proceeding. If this isn't true the ACK processing below
-        * will clear this flag
-        */
-       if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
-               (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
-               (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
-               pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
-
-       if (usbc_hcint.s.stall) {
-               /*
-                * STALL as a response means this transaction cannot be
-                * completed because the device can't process transactions. Tell
-                * the user. Any data that was transferred will be counted on
-                * the actual bytes transferred
-                */
-               pipe->pid_toggle = 0;
-               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
-       } else if (usbc_hcint.s.xacterr) {
-               /*
-                * We know at least one packet worked if we get a ACK or NAK.
-                * Reset the retry counter
-                */
-               if (usbc_hcint.s.nak || usbc_hcint.s.ack)
-                       transaction->retries = 0;
-               transaction->retries++;
-               if (transaction->retries > MAX_RETRIES) {
-                       /*
-                        * XactErr as a response means the device signaled
-                        * something wrong with the transfer. For example, PID
-                        * toggle errors cause these
-                        */
-                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
-               } else {
-                       /*
-                        * If this was a split then clear our split in progress
-                        * marker
-                        */
-                       if (usb->active_split == transaction)
-                               usb->active_split = NULL;
-                       /*
-                        * Rewind to the beginning of the transaction by anding
-                        * off the split complete bit
-                        */
-                       transaction->stage &= ~1;
-                       pipe->split_sc_frame = -1;
-                       pipe->next_tx_frame += pipe->interval;
-                       if (pipe->next_tx_frame < usb->frame_number)
-                               pipe->next_tx_frame = usb->frame_number + pipe->interval -
-                                                     (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
-               }
-       } else if (usbc_hcint.s.bblerr) {
-               /* Babble Error (BblErr) */
-               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
-       } else if (usbc_hcint.s.datatglerr) {
-               /* We'll retry the exact same transaction again */
-               transaction->retries++;
-       } else if (usbc_hcint.s.nyet) {
-               /*
-                * NYET as a response is only allowed in three cases: as a
-                * response to a ping, as a response to a split transaction, and
-                * as a response to a bulk out. The ping case is handled by
-                * hardware, so we only have splits and bulk out
-                */
-               if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                       transaction->retries = 0;
-                       /*
-                        * If there is more data to go then we need to try
-                        * again. Otherwise this transaction is complete
-                        */
-                       if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-               } else {
-                       /*
-                        * Split transactions retry the split complete 4 times
-                        * then rewind to the start split and do the entire
-                        * transactions again
-                        */
-                       transaction->retries++;
-                       if ((transaction->retries & 0x3) == 0) {
-                               /*
-                                * Rewind to the beginning of the transaction by
-                                * anding off the split complete bit
-                                */
-                               transaction->stage &= ~1;
-                               pipe->split_sc_frame = -1;
-                       }
-               }
-       } else if (usbc_hcint.s.ack) {
-               transaction->retries = 0;
-               /*
-                * The ACK bit can only be checked after the other error bits.
-                * This is because a multi packet transfer may succeed in a
-                * number of packets and then get a different response on the
-                * last packet. In this case both ACK and the last response bit
-                * will be set. If none of the other response bits is set, then
-                * the last packet must have been an ACK
-                *
-                * Since we got an ACK, we know we don't need to do a ping on
-                * this pipe
-                */
-               pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING;
-
-               switch (transaction->type) {
-               case CVMX_USB_TRANSFER_CONTROL:
-                       switch (transaction->stage) {
-                       case CVMX_USB_STAGE_NON_CONTROL:
-                       case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
-                               /* This should be impossible */
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
-                               break;
-                       case CVMX_USB_STAGE_SETUP:
-                               pipe->pid_toggle = 1;
-                               if (__cvmx_usb_pipe_needs_split(usb, pipe))
-                                       transaction->stage = CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
-                               else {
-                                       union cvmx_usb_control_header *header =
-                                               cvmx_phys_to_ptr(transaction->control_header);
-                                       if (header->s.length)
-                                               transaction->stage = CVMX_USB_STAGE_DATA;
-                                       else
-                                               transaction->stage = CVMX_USB_STAGE_STATUS;
-                               }
-                               break;
-                       case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
-                               {
-                                       union cvmx_usb_control_header *header =
-                                               cvmx_phys_to_ptr(transaction->control_header);
-                                       if (header->s.length)
-                                               transaction->stage = CVMX_USB_STAGE_DATA;
-                                       else
-                                               transaction->stage = CVMX_USB_STAGE_STATUS;
-                               }
-                               break;
-                       case CVMX_USB_STAGE_DATA:
-                               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                                       transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
-                                       /*
-                                        * For setup OUT data that are splits,
-                                        * the hardware doesn't appear to count
-                                        * transferred data. Here we manually
-                                        * update the data transferred
-                                        */
-                                       if (!usbc_hcchar.s.epdir) {
-                                               if (buffer_space_left < pipe->max_packet)
-                                                       transaction->actual_bytes += buffer_space_left;
-                                               else
-                                                       transaction->actual_bytes += pipe->max_packet;
-                                       }
-                               } else if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
-                                       pipe->pid_toggle = 1;
-                                       transaction->stage = CVMX_USB_STAGE_STATUS;
-                               }
-                               break;
-                       case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
-                               if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
-                                       pipe->pid_toggle = 1;
-                                       transaction->stage = CVMX_USB_STAGE_STATUS;
-                               } else {
-                                       transaction->stage = CVMX_USB_STAGE_DATA;
-                               }
-                               break;
-                       case CVMX_USB_STAGE_STATUS:
-                               if (__cvmx_usb_pipe_needs_split(usb, pipe))
-                                       transaction->stage = CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
-                               else
-                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                               break;
-                       case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                               break;
-                       }
-                       break;
-               case CVMX_USB_TRANSFER_BULK:
-               case CVMX_USB_TRANSFER_INTERRUPT:
-                       /*
-                        * The only time a bulk transfer isn't complete when it
-                        * finishes with an ACK is during a split transaction.
-                        * For splits we need to continue the transfer if more
-                        * data is needed
-                        */
-                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                               if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL)
-                                       transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
-                               else {
-                                       if (buffer_space_left && (bytes_in_last_packet == pipe->max_packet))
-                                               transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
-                                       else {
-                                               if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
-                                                       pipe->next_tx_frame += pipe->interval;
-                                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                                       }
-                               }
-                       } else {
-                               if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
-                                   (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
-                                   (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
-                                   (usbc_hcint.s.nak))
-                                       pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
-                               if (!buffer_space_left || (bytes_in_last_packet < pipe->max_packet)) {
-                                       if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
-                                               pipe->next_tx_frame += pipe->interval;
-                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                               }
-                       }
-                       break;
-               case CVMX_USB_TRANSFER_ISOCHRONOUS:
-                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                               /*
-                                * ISOCHRONOUS OUT splits don't require a
-                                * complete split stage. Instead they use a
-                                * sequence of begin OUT splits to transfer the
-                                * data 188 bytes at a time. Once the transfer
-                                * is complete, the pipe sleeps until the next
-                                * schedule interval
-                                */
-                               if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
-                                       /*
-                                        * If no space left or this wasn't a max
-                                        * size packet then this transfer is
-                                        * complete. Otherwise start it again to
-                                        * send the next 188 bytes
-                                        */
-                                       if (!buffer_space_left || (bytes_this_transfer < 188)) {
-                                               pipe->next_tx_frame += pipe->interval;
-                                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                                       }
-                               } else {
-                                       if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE) {
-                                               /*
-                                                * We are in the incoming data
-                                                * phase. Keep getting data
-                                                * until we run out of space or
-                                                * get a small packet
-                                                */
-                                               if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
-                                                       pipe->next_tx_frame += pipe->interval;
-                                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                                               }
-                                       } else
-                                               transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
-                               }
-                       } else {
-                               pipe->next_tx_frame += pipe->interval;
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                       }
-                       break;
-               }
-       } else if (usbc_hcint.s.nak) {
-               /* If this was a split then clear our split in progress marker */
-               if (usb->active_split == transaction)
-                       usb->active_split = NULL;
-               /*
-                * NAK as a response means the device couldn't accept the
-                * transaction, but it should be retried in the future. Rewind
-                * to the beginning of the transaction by anding off the split
-                * complete bit. Retry in the next interval
-                */
-               transaction->retries = 0;
-               transaction->stage &= ~1;
-               pipe->next_tx_frame += pipe->interval;
-               if (pipe->next_tx_frame < usb->frame_number)
-                       pipe->next_tx_frame = usb->frame_number + pipe->interval -
-                               (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
-       } else {
-               struct cvmx_usb_port_status port;
-               port = cvmx_usb_get_status((struct cvmx_usb_state *)usb);
-               if (port.port_enabled) {
-                       /* We'll retry the exact same transaction again */
-                       transaction->retries++;
-               } else {
-                       /*
-                        * We get channel halted interrupts with no result bits
-                        * sets when the cable is unplugged
-                        */
-                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
-               }
-       }
-       return 0;
-}
-
-
-/**
- * Poll the USB block for status and call all needed callback
- * handlers. This function is meant to be called in the interrupt
- * handler for the USB controller. It can also be called
- * periodically in a loop for non-interrupt based operation.
- *
- * @state:     USB device state populated by
- *             cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_poll(struct cvmx_usb_state *state)
-{
-       union cvmx_usbcx_hfnum usbc_hfnum;
-       union cvmx_usbcx_gintsts usbc_gintsts;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       CVMX_PREFETCH(usb, 0);
-       CVMX_PREFETCH(usb, 1*128);
-       CVMX_PREFETCH(usb, 2*128);
-       CVMX_PREFETCH(usb, 3*128);
-       CVMX_PREFETCH(usb, 4*128);
-
-       /* Update the frame counter */
-       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
-       if ((usb->frame_number&0x3fff) > usbc_hfnum.s.frnum)
-               usb->frame_number += 0x4000;
-       usb->frame_number &= ~0x3fffull;
-       usb->frame_number |= usbc_hfnum.s.frnum;
-
-       /* Read the pending interrupts */
-       usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTSTS(usb->index));
-
-       /* Clear the interrupts now that we know about them */
-       __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index), usbc_gintsts.u32);
-
-       if (usbc_gintsts.s.rxflvl) {
-               /*
-                * RxFIFO Non-Empty (RxFLvl)
-                * Indicates that there is at least one packet pending to be
-                * read from the RxFIFO.
-                *
-                * In DMA mode this is handled by hardware
-                */
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       __cvmx_usb_poll_rx_fifo(usb);
-       }
-       if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp) {
-               /* Fill the Tx FIFOs when not in DMA mode */
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       __cvmx_usb_poll_tx_fifo(usb);
-       }
-       if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint) {
-               union cvmx_usbcx_hprt usbc_hprt;
-               /*
-                * Disconnect Detected Interrupt (DisconnInt)
-                * Asserted when a device disconnect is detected.
-                *
-                * Host Port Interrupt (PrtInt)
-                * The core sets this bit to indicate a change in port status of
-                * one of the O2P USB core ports in Host mode. The application
-                * must read the Host Port Control and Status (HPRT) register to
-                * determine the exact event that caused this interrupt. The
-                * application must clear the appropriate status bit in the Host
-                * Port Control and Status register to clear this bit.
-                *
-                * Call the user's port callback
-                */
-               __cvmx_usb_perform_callback(usb, NULL, NULL,
-                                           CVMX_USB_CALLBACK_PORT_CHANGED,
-                                           CVMX_USB_COMPLETE_SUCCESS);
-               /* Clear the port change bits */
-               usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
-               usbc_hprt.s.prtena = 0;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index), usbc_hprt.u32);
-       }
-       if (usbc_gintsts.s.hchint) {
-               /*
-                * Host Channels Interrupt (HChInt)
-                * The core sets this bit to indicate that an interrupt is
-                * pending on one of the channels of the core (in Host mode).
-                * The application must read the Host All Channels Interrupt
-                * (HAINT) register to determine the exact number of the channel
-                * on which the interrupt occurred, and then read the
-                * corresponding Host Channel-n Interrupt (HCINTn) register to
-                * determine the exact cause of the interrupt. The application
-                * must clear the appropriate status bit in the HCINTn register
-                * to clear this bit.
-                */
-               union cvmx_usbcx_haint usbc_haint;
-               usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
-               while (usbc_haint.u32) {
-                       int channel;
-                       CVMX_CLZ(channel, usbc_haint.u32);
-                       channel = 31 - channel;
-                       __cvmx_usb_poll_channel(usb, channel);
-                       usbc_haint.u32 ^= 1<<channel;
-               }
-       }
-
-       __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
-
-       return 0;
-}
diff --git a/drivers/staging/octeon-usb/cvmx-usb.h b/drivers/staging/octeon-usb/cvmx-usb.h
deleted file mode 100644 (file)
index 8bf3696..0000000
+++ /dev/null
@@ -1,542 +0,0 @@
-/***********************license start***************
- * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). 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 Cavium Networks 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, including technical data, may be subject to U.S. export  control
- * laws, including the U.S. Export Administration Act and its  associated
- * regulations, and may be subject to export or import  regulations in other
- * countries.
-
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
- * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
- * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
- * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- ***********************license end**************************************/
-
-
-/**
- * "cvmx-usb.h" defines a set of low level USB functions to help
- * developers create Octeon USB drivers for various operating
- * systems. These functions provide a generic API to the Octeon
- * USB blocks, hiding the internal hardware specific
- * operations.
- *
- * At a high level the device driver needs to:
- *
- * - Call cvmx_usb_get_num_ports() to get the number of
- *   supported ports.
- * - Call cvmx_usb_initialize() for each Octeon USB port.
- * - Enable the port using cvmx_usb_enable().
- * - Either periodically, or in an interrupt handler, call
- *   cvmx_usb_poll() to service USB events.
- * - Manage pipes using cvmx_usb_open_pipe() and
- *   cvmx_usb_close_pipe().
- * - Manage transfers using cvmx_usb_submit_*() and
- *   cvmx_usb_cancel*().
- * - Shutdown USB on unload using cvmx_usb_shutdown().
- *
- * To monitor USB status changes, the device driver must use
- * cvmx_usb_register_callback() to register for events that it
- * is interested in. Below are a few hints on successfully
- * implementing a driver on top of this API.
- *
- * == Initialization ==
- *
- * When a driver is first loaded, it is normally not necessary
- * to bring up the USB port completely. Most operating systems
- * expect to initialize and enable the port in two independent
- * steps. Normally an operating system will probe hardware,
- * initialize anything found, and then enable the hardware.
- *
- * In the probe phase you should:
- * - Use cvmx_usb_get_num_ports() to determine the number of
- *   USB port to be supported.
- * - Allocate space for a struct cvmx_usb_state for each
- *   port.
- * - Tell the operating system about each port
- *
- * In the initialization phase you should:
- * - Use cvmx_usb_initialize() on each port.
- * - Do not call cvmx_usb_enable(). This leaves the USB port in
- *   the disabled state until the operating system is ready.
- *
- * Finally, in the enable phase you should:
- * - Call cvmx_usb_enable() on the appropriate port.
- * - Note that some operating system use a RESET instead of an
- *   enable call. To implement RESET, you should call
- *   cvmx_usb_disable() followed by cvmx_usb_enable().
- *
- * == Locking ==
- *
- * All of the functions in the cvmx-usb API assume exclusive
- * access to the USB hardware and internal data structures. This
- * means that the driver must provide locking as necessary.
- *
- * In the single CPU state it is normally enough to disable
- * interrupts before every call to cvmx_usb*() and enable them
- * again after the call is complete. Keep in mind that it is
- * very common for the callback handlers to make additional
- * calls into cvmx-usb, so the disable/enable must be protected
- * against recursion. As an example, the Linux kernel
- * local_irq_save() and local_irq_restore() are perfect for this
- * in the non SMP case.
- *
- * In the SMP case, locking is more complicated. For SMP you not
- * only need to disable interrupts on the local core, but also
- * take a lock to make sure that another core cannot call
- * cvmx-usb.
- *
- * == Port callback ==
- *
- * The port callback prototype needs to look as follows:
- *
- * void port_callback(struct cvmx_usb_state *usb,
- *                    enum cvmx_usb_callback reason,
- *                    enum cvmx_usb_complete status,
- *                    int pipe_handle,
- *                    int submit_handle,
- *                    int bytes_transferred,
- *                    void *user_data);
- * - "usb" is the struct cvmx_usb_state for the port.
- * - "reason" will always be CVMX_USB_CALLBACK_PORT_CHANGED.
- * - "status" will always be CVMX_USB_COMPLETE_SUCCESS.
- * - "pipe_handle" will always be -1.
- * - "submit_handle" will always be -1.
- * - "bytes_transferred" will always be 0.
- * - "user_data" is the void pointer originally passed along
- *   with the callback. Use this for any state information you
- *   need.
- *
- * The port callback will be called whenever the user plugs /
- * unplugs a device from the port. It will not be called when a
- * device is plugged / unplugged from a hub connected to the
- * root port. Normally all the callback needs to do is tell the
- * operating system to poll the root hub for status. Under
- * Linux, this is performed by calling usb_hcd_poll_rh_status().
- * In the Linux driver we use "user_data". to pass around the
- * Linux "hcd" structure. Once the port callback completes,
- * Linux automatically calls octeon_usb_hub_status_data() which
- * uses cvmx_usb_get_status() to determine the root port status.
- *
- * == Complete callback ==
- *
- * The completion callback prototype needs to look as follows:
- *
- * void complete_callback(struct cvmx_usb_state *usb,
- *                        enum cvmx_usb_callback reason,
- *                        enum cvmx_usb_complete status,
- *                        int pipe_handle,
- *                        int submit_handle,
- *                        int bytes_transferred,
- *                        void *user_data);
- * - "usb" is the struct cvmx_usb_state for the port.
- * - "reason" will always be CVMX_USB_CALLBACK_TRANSFER_COMPLETE.
- * - "status" will be one of the cvmx_usb_complete enumerations.
- * - "pipe_handle" is the handle to the pipe the transaction
- *   was originally submitted on.
- * - "submit_handle" is the handle returned by the original
- *   cvmx_usb_submit_* call.
- * - "bytes_transferred" is the number of bytes successfully
- *   transferred in the transaction. This will be zero on most
- *   error conditions.
- * - "user_data" is the void pointer originally passed along
- *   with the callback. Use this for any state information you
- *   need. For example, the Linux "urb" is stored in here in the
- *   Linux driver.
- *
- * In general your callback handler should use "status" and
- * "bytes_transferred" to tell the operating system the how the
- * transaction completed. Normally the pipe is not changed in
- * this callback.
- *
- * == Canceling transactions ==
- *
- * When a transaction is cancelled using cvmx_usb_cancel*(), the
- * actual length of time until the complete callback is called
- * can vary greatly. It may be called before cvmx_usb_cancel*()
- * returns, or it may be called a number of usb frames in the
- * future once the hardware frees the transaction. In either of
- * these cases, the complete handler will receive
- * CVMX_USB_COMPLETE_CANCEL.
- *
- * == Handling pipes ==
- *
- * USB "pipes" is a software construct created by this API to
- * enable the ordering of usb transactions to a device endpoint.
- * Octeon's underlying hardware doesn't have any concept
- * equivalent to "pipes". The hardware instead has eight
- * channels that can be used simultaneously to have up to eight
- * transaction in process at the same time. In order to maintain
- * ordering in a pipe, the transactions for a pipe will only be
- * active in one hardware channel at a time. From an API user's
- * perspective, this doesn't matter but it can be helpful to
- * keep this in mind when you are probing hardware while
- * debugging.
- *
- * Also keep in mind that usb transactions contain state
- * information about the previous transaction to the same
- * endpoint. Each transaction has a PID toggle that changes 0/1
- * between each sub packet. This is maintained in the pipe data
- * structures. For this reason, you generally cannot create and
- * destroy a pipe for every transaction. A sequence of
- * transaction to the same endpoint must use the same pipe.
- *
- * == Root Hub ==
- *
- * Some operating systems view the usb root port as a normal usb
- * hub. These systems attempt to control the root hub with
- * messages similar to the usb 2.0 spec for hub control and
- * status. For these systems it may be necessary to write
- * function to decode standard usb control messages into
- * equivalent cvmx-usb API calls.
- *
- * == Interrupts ==
- *
- * If you plan on using usb interrupts, cvmx_usb_poll() must be
- * called on every usb interrupt. It will read the usb state,
- * call any needed callbacks, and schedule transactions as
- * needed. Your device driver needs only to hookup an interrupt
- * handler and call cvmx_usb_poll(). Octeon's usb port 0 causes
- * CIU bit CIU_INT*_SUM0[USB] to be set (bit 56). For port 1,
- * CIU bit CIU_INT_SUM1[USB1] is set (bit 17). How these bits
- * are turned into interrupt numbers is operating system
- * specific. For Linux, there are the convenient defines
- * OCTEON_IRQ_USB0 and OCTEON_IRQ_USB1 for the IRQ numbers.
- *
- * If you aren't using interrupts, simple call cvmx_usb_poll()
- * in your main processing loop.
- */
-
-#ifndef __CVMX_USB_H__
-#define __CVMX_USB_H__
-
-/**
- * enum cvmx_usb_speed - the possible USB device speeds
- *
- * @CVMX_USB_SPEED_HIGH: Device is operation at 480Mbps
- * @CVMX_USB_SPEED_FULL: Device is operation at 12Mbps
- * @CVMX_USB_SPEED_LOW:  Device is operation at 1.5Mbps
- */
-enum cvmx_usb_speed {
-       CVMX_USB_SPEED_HIGH = 0,
-       CVMX_USB_SPEED_FULL = 1,
-       CVMX_USB_SPEED_LOW = 2,
-};
-
-/**
- * enum cvmx_usb_transfer - the possible USB transfer types
- *
- * @CVMX_USB_TRANSFER_CONTROL:    USB transfer type control for hub and status
- *                                transfers
- * @CVMX_USB_TRANSFER_ISOCHRONOUS: USB transfer type isochronous for low
- *                                priority periodic transfers
- * @CVMX_USB_TRANSFER_BULK:       USB transfer type bulk for large low priority
- *                                transfers
- * @CVMX_USB_TRANSFER_INTERRUPT:   USB transfer type interrupt for high priority
- *                                periodic transfers
- */
-enum cvmx_usb_transfer {
-       CVMX_USB_TRANSFER_CONTROL = 0,
-       CVMX_USB_TRANSFER_ISOCHRONOUS = 1,
-       CVMX_USB_TRANSFER_BULK = 2,
-       CVMX_USB_TRANSFER_INTERRUPT = 3,
-};
-
-/**
- * enum cvmx_usb_direction - the transfer directions
- *
- * @CVMX_USB_DIRECTION_OUT: Data is transferring from Octeon to the device/host
- * @CVMX_USB_DIRECTION_IN:  Data is transferring from the device/host to Octeon
- */
-enum cvmx_usb_direction {
-       CVMX_USB_DIRECTION_OUT,
-       CVMX_USB_DIRECTION_IN,
-};
-
-/**
- * enum cvmx_usb_complete - possible callback function status codes
- *
- * @CVMX_USB_COMPLETE_SUCCESS:   The transaction / operation finished without
- *                               any errors
- * @CVMX_USB_COMPLETE_SHORT:     FIXME: This is currently not implemented
- * @CVMX_USB_COMPLETE_CANCEL:    The transaction was canceled while in flight by
- *                               a user call to cvmx_usb_cancel
- * @CVMX_USB_COMPLETE_ERROR:     The transaction aborted with an unexpected
- *                               error status
- * @CVMX_USB_COMPLETE_STALL:     The transaction received a USB STALL response
- *                               from the device
- * @CVMX_USB_COMPLETE_XACTERR:   The transaction failed with an error from the
- *                               device even after a number of retries
- * @CVMX_USB_COMPLETE_DATATGLERR: The transaction failed with a data toggle
- *                               error even after a number of retries
- * @CVMX_USB_COMPLETE_BABBLEERR:  The transaction failed with a babble error
- * @CVMX_USB_COMPLETE_FRAMEERR:          The transaction failed with a frame error
- *                               even after a number of retries
- */
-enum cvmx_usb_complete {
-       CVMX_USB_COMPLETE_SUCCESS,
-       CVMX_USB_COMPLETE_SHORT,
-       CVMX_USB_COMPLETE_CANCEL,
-       CVMX_USB_COMPLETE_ERROR,
-       CVMX_USB_COMPLETE_STALL,
-       CVMX_USB_COMPLETE_XACTERR,
-       CVMX_USB_COMPLETE_DATATGLERR,
-       CVMX_USB_COMPLETE_BABBLEERR,
-       CVMX_USB_COMPLETE_FRAMEERR,
-};
-
-/**
- * struct cvmx_usb_port_status - the USB port status information
- *
- * @port_enabled:      1 = Usb port is enabled, 0 = disabled
- * @port_over_current: 1 = Over current detected, 0 = Over current not
- *                     detected. Octeon doesn't support over current detection.
- * @port_powered:      1 = Port power is being supplied to the device, 0 =
- *                     power is off. Octeon doesn't support turning port power
- *                     off.
- * @port_speed:                Current port speed.
- * @connected:         1 = A device is connected to the port, 0 = No device is
- *                     connected.
- * @connect_change:    1 = Device connected state changed since the last set
- *                     status call.
- */
-struct cvmx_usb_port_status {
-       uint32_t reserved               : 25;
-       uint32_t port_enabled           : 1;
-       uint32_t port_over_current      : 1;
-       uint32_t port_powered           : 1;
-       enum cvmx_usb_speed port_speed  : 2;
-       uint32_t connected              : 1;
-       uint32_t connect_change         : 1;
-};
-
-/**
- * union cvmx_usb_control_header - the structure of a Control packet header
- *
- * @s.request_type:    Bit 7 tells the direction: 1=IN, 0=OUT
- * @s.request          The standard usb request to make
- * @s.value            Value parameter for the request in little endian format
- * @s.index            Index for the request in little endian format
- * @s.length           Length of the data associated with this request in
- *                     little endian format
- */
-union cvmx_usb_control_header {
-       uint64_t u64;
-       struct {
-               uint64_t request_type   : 8;
-               uint64_t request        : 8;
-               uint64_t value          : 16;
-               uint64_t index          : 16;
-               uint64_t length         : 16;
-       } s;
-};
-
-/**
- * struct cvmx_usb_iso_packet - descriptor for Isochronous packets
- *
- * @offset:    This is the offset in bytes into the main buffer where this data
- *             is stored.
- * @length:    This is the length in bytes of the data.
- * @status:    This is the status of this individual packet transfer.
- */
-struct cvmx_usb_iso_packet {
-       int offset;
-       int length;
-       enum cvmx_usb_complete status;
-};
-
-/**
- * enum cvmx_usb_callback - possible callback reasons for the USB API
- *
- * @CVMX_USB_CALLBACK_TRANSFER_COMPLETE: A callback of this type is called when
- *                                      a submitted transfer completes. The
- *                                      completion callback will be called even
- *                                      if the transfer fails or is canceled.
- *                                      The status parameter will contain
- *                                      details of why he callback was called.
- * @CVMX_USB_CALLBACK_PORT_CHANGED:     The status of the port changed. For
- *                                      example, someone may have plugged a
- *                                      device in. The status parameter
- *                                      contains CVMX_USB_COMPLETE_SUCCESS. Use
- *                                      cvmx_usb_get_status() to get the new
- *                                      port status.
- * @__CVMX_USB_CALLBACK_END:            Do not use. Used internally for array
- *                                      bounds.
- */
-enum cvmx_usb_callback {
-       CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
-       CVMX_USB_CALLBACK_PORT_CHANGED,
-       __CVMX_USB_CALLBACK_END
-};
-
-/**
- * USB state internal data. The contents of this structure
- * may change in future SDKs. No data in it should be referenced
- * by user's of this API.
- */
-struct cvmx_usb_state {
-       char data[65536];
-};
-
-/**
- * USB callback functions are always of the following type.
- * The parameters are as follows:
- *      - state = USB device state populated by
- *        cvmx_usb_initialize().
- *      - reason = The enum cvmx_usb_callback used to register
- *        the callback.
- *      - status = The enum cvmx_usb_complete representing the
- *        status code of a transaction.
- *      - pipe_handle = The Pipe that caused this callback, or
- *        -1 if this callback wasn't associated with a pipe.
- *      - submit_handle = Transfer submit handle causing this
- *        callback, or -1 if this callback wasn't associated
- *        with a transfer.
- *      - Actual number of bytes transfer.
- *      - user_data = The user pointer supplied to the
- *        function cvmx_usb_submit() or
- *        cvmx_usb_register_callback() */
-typedef void (*cvmx_usb_callback_func_t)(struct cvmx_usb_state *state,
-                                         enum cvmx_usb_callback reason,
-                                         enum cvmx_usb_complete status,
-                                         int pipe_handle, int submit_handle,
-                                         int bytes_transferred, void *user_data);
-
-/**
- * enum cvmx_usb_initialize_flags - flags to pass the initialization function
- *
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI:    The USB port uses a 12MHz crystal
- *                                           as clock source at USB_XO and
- *                                           USB_XI.
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND:   The USB port uses 12/24/48MHz 2.5V
- *                                           board clock source at USB_XO.
- *                                           USB_XI should be tied to GND.
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO:     Automatically determine clock type
- *                                           based on function in
- *                                           cvmx-helper-board.c.
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK: Mask for clock speed field
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:    Speed of reference clock or
- *                                           crystal
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:    Speed of reference clock
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:    Speed of reference clock
- * @CVMX_USB_INITIALIZE_FLAGS_NO_DMA:        Disable DMA and used polled IO for
- *                                           data transfer use for the USB
- */
-enum cvmx_usb_initialize_flags {
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI           = 1 << 0,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND          = 1 << 1,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO            = 0,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK        = 3 << 3,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ           = 1 << 3,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ           = 2 << 3,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ           = 3 << 3,
-       /* Bits 3-4 used to encode the clock frequency */
-       CVMX_USB_INITIALIZE_FLAGS_NO_DMA                = 1 << 5,
-};
-
-/**
- * enum cvmx_usb_pipe_flags - flags for passing when a pipe is created.
- *                           Currently no flags need to be passed.
- *
- * @__CVMX_USB_PIPE_FLAGS_OPEN:             Used internally to determine if a pipe is
- *                                  open. Do not use.
- * @__CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
- *                                  actively using hardware. Do not use.
- * @__CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high
- *                                  speed pipe is in the ping state. Do not
- *                                  use.
- */
-enum cvmx_usb_pipe_flags {
-       __CVMX_USB_PIPE_FLAGS_OPEN      = 1 << 16,
-       __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
-       __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
-};
-
-extern int cvmx_usb_get_num_ports(void);
-extern int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
-                              enum cvmx_usb_initialize_flags flags);
-extern int cvmx_usb_shutdown(struct cvmx_usb_state *state);
-extern int cvmx_usb_enable(struct cvmx_usb_state *state);
-extern int cvmx_usb_disable(struct cvmx_usb_state *state);
-extern struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *state);
-extern void cvmx_usb_set_status(struct cvmx_usb_state *state, struct cvmx_usb_port_status port_status);
-extern int cvmx_usb_open_pipe(struct cvmx_usb_state *state,
-                              enum cvmx_usb_pipe_flags flags,
-                              int device_addr, int endpoint_num,
-                              enum cvmx_usb_speed device_speed, int max_packet,
-                              enum cvmx_usb_transfer transfer_type,
-                              enum cvmx_usb_direction transfer_dir, int interval,
-                              int multi_count, int hub_device_addr,
-                              int hub_port);
-extern int cvmx_usb_submit_bulk(struct cvmx_usb_state *state, int pipe_handle,
-                                uint64_t buffer, int buffer_length,
-                                cvmx_usb_callback_func_t callback,
-                                void *user_data);
-extern int cvmx_usb_submit_interrupt(struct cvmx_usb_state *state, int pipe_handle,
-                                     uint64_t buffer, int buffer_length,
-                                     cvmx_usb_callback_func_t callback,
-                                     void *user_data);
-extern int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
-                                   uint64_t control_header,
-                                   uint64_t buffer, int buffer_length,
-                                   cvmx_usb_callback_func_t callback,
-                                   void *user_data);
-
-/**
- * enum cvmx_usb_isochronous_flags - flags to pass the
- *                                  cvmx_usb_submit_isochronous() function.
- *
- * @CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT: Do not return an error if a transfer
- *                                         is less than the maximum packet size
- *                                         of the device.
- * @CVMX_USB_ISOCHRONOUS_FLAGS_ASAP:       Schedule the transaction as soon as
- *                                         possible.
- */
-enum cvmx_usb_isochronous_flags {
-       CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT  = 1 << 0,
-       CVMX_USB_ISOCHRONOUS_FLAGS_ASAP         = 1 << 1,
-};
-
-extern int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
-                                       int start_frame, int flags,
-                                       int number_packets,
-                                       struct cvmx_usb_iso_packet packets[],
-                                       uint64_t buffer, int buffer_length,
-                                       cvmx_usb_callback_func_t callback,
-                                       void *user_data);
-extern int cvmx_usb_cancel(struct cvmx_usb_state *state, int pipe_handle,
-                          int submit_handle);
-extern int cvmx_usb_cancel_all(struct cvmx_usb_state *state, int pipe_handle);
-extern int cvmx_usb_close_pipe(struct cvmx_usb_state *state, int pipe_handle);
-extern int cvmx_usb_register_callback(struct cvmx_usb_state *state,
-                                     enum cvmx_usb_callback reason,
-                                     cvmx_usb_callback_func_t callback,
-                                     void *user_data);
-extern int cvmx_usb_get_frame_number(struct cvmx_usb_state *state);
-extern int cvmx_usb_poll(struct cvmx_usb_state *state);
-
-#endif  /* __CVMX_USB_H__ */
diff --git a/drivers/staging/octeon-usb/cvmx-usbcx-defs.h b/drivers/staging/octeon-usb/cvmx-usbcx-defs.h
deleted file mode 100644 (file)
index d349d77..0000000
+++ /dev/null
@@ -1,1528 +0,0 @@
-/***********************license start***************
- * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). 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 Cavium Networks 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, including technical data, may be subject to U.S. export
- * control laws, including the U.S. Export Administration Act and its associated
- * regulations, and may be subject to export or import  regulations in other
- * countries.
-
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
- * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
- * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
- * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- ***********************license end**************************************/
-
-
-/**
- * cvmx-usbcx-defs.h
- *
- * Configuration and status register (CSR) type definitions for
- * Octeon usbcx.
- *
- */
-#ifndef __CVMX_USBCX_TYPEDEFS_H__
-#define __CVMX_USBCX_TYPEDEFS_H__
-
-#define CVMX_USBCXBASE 0x00016F0010000000ull
-#define CVMX_USBCXREG1(reg, bid) \
-       (CVMX_ADD_IO_SEG(CVMX_USBCXBASE | reg) + \
-        ((bid) & 1) * 0x100000000000ull)
-#define CVMX_USBCXREG2(reg, bid, off) \
-       (CVMX_ADD_IO_SEG(CVMX_USBCXBASE | reg) + \
-        (((off) & 7) + ((bid) & 1) * 0x8000000000ull) * 32)
-
-#define CVMX_USBCX_GAHBCFG(bid)                CVMX_USBCXREG1(0x008, bid)
-#define CVMX_USBCX_GHWCFG3(bid)                CVMX_USBCXREG1(0x04c, bid)
-#define CVMX_USBCX_GINTMSK(bid)                CVMX_USBCXREG1(0x018, bid)
-#define CVMX_USBCX_GINTSTS(bid)                CVMX_USBCXREG1(0x014, bid)
-#define CVMX_USBCX_GNPTXFSIZ(bid)      CVMX_USBCXREG1(0x028, bid)
-#define CVMX_USBCX_GNPTXSTS(bid)       CVMX_USBCXREG1(0x02c, bid)
-#define CVMX_USBCX_GOTGCTL(bid)                CVMX_USBCXREG1(0x000, bid)
-#define CVMX_USBCX_GRSTCTL(bid)                CVMX_USBCXREG1(0x010, bid)
-#define CVMX_USBCX_GRXFSIZ(bid)                CVMX_USBCXREG1(0x024, bid)
-#define CVMX_USBCX_GRXSTSPH(bid)       CVMX_USBCXREG1(0x020, bid)
-#define CVMX_USBCX_GUSBCFG(bid)                CVMX_USBCXREG1(0x00c, bid)
-#define CVMX_USBCX_HAINT(bid)          CVMX_USBCXREG1(0x414, bid)
-#define CVMX_USBCX_HAINTMSK(bid)       CVMX_USBCXREG1(0x418, bid)
-#define CVMX_USBCX_HCCHARX(off, bid)   CVMX_USBCXREG2(0x500, bid, off)
-#define CVMX_USBCX_HCFG(bid)           CVMX_USBCXREG1(0x400, bid)
-#define CVMX_USBCX_HCINTMSKX(off, bid) CVMX_USBCXREG2(0x50c, bid, off)
-#define CVMX_USBCX_HCINTX(off, bid)    CVMX_USBCXREG2(0x508, bid, off)
-#define CVMX_USBCX_HCSPLTX(off, bid)   CVMX_USBCXREG2(0x504, bid, off)
-#define CVMX_USBCX_HCTSIZX(off, bid)   CVMX_USBCXREG2(0x510, bid, off)
-#define CVMX_USBCX_HFIR(bid)           CVMX_USBCXREG1(0x404, bid)
-#define CVMX_USBCX_HFNUM(bid)          CVMX_USBCXREG1(0x408, bid)
-#define CVMX_USBCX_HPRT(bid)           CVMX_USBCXREG1(0x440, bid)
-#define CVMX_USBCX_HPTXFSIZ(bid)       CVMX_USBCXREG1(0x100, bid)
-#define CVMX_USBCX_HPTXSTS(bid)                CVMX_USBCXREG1(0x410, bid)
-
-/**
- * cvmx_usbc#_gahbcfg
- *
- * Core AHB Configuration Register (GAHBCFG)
- *
- * This register can be used to configure the core after power-on or a change in
- * mode of operation. This register mainly contains AHB system-related
- * configuration parameters. The AHB is the processor interface to the O2P USB
- * core. In general, software need not know about this interface except to
- * program the values as specified.
- *
- * The application must program this register as part of the O2P USB core
- * initialization. Do not change this register after the initial programming.
- */
-union cvmx_usbcx_gahbcfg {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_gahbcfg_s
-        * @ptxfemplvl: Periodic TxFIFO Empty Level (PTxFEmpLvl)
-        *      Software should set this bit to 0x1.
-        *      Indicates when the Periodic TxFIFO Empty Interrupt bit in the
-        *      Core Interrupt register (GINTSTS.PTxFEmp) is triggered. This
-        *      bit is used only in Slave mode.
-        *      * 1'b0: GINTSTS.PTxFEmp interrupt indicates that the Periodic
-        *      TxFIFO is half empty
-        *      * 1'b1: GINTSTS.PTxFEmp interrupt indicates that the Periodic
-        *      TxFIFO is completely empty
-        * @nptxfemplvl: Non-Periodic TxFIFO Empty Level (NPTxFEmpLvl)
-        *      Software should set this bit to 0x1.
-        *      Indicates when the Non-Periodic TxFIFO Empty Interrupt bit in
-        *      the Core Interrupt register (GINTSTS.NPTxFEmp) is triggered.
-        *      This bit is used only in Slave mode.
-        *      * 1'b0: GINTSTS.NPTxFEmp interrupt indicates that the Non-
-        *      Periodic TxFIFO is half empty
-        *      * 1'b1: GINTSTS.NPTxFEmp interrupt indicates that the Non-
-        *      Periodic TxFIFO is completely empty
-        * @dmaen: DMA Enable (DMAEn)
-        *      * 1'b0: Core operates in Slave mode
-        *      * 1'b1: Core operates in a DMA mode
-        * @hbstlen: Burst Length/Type (HBstLen)
-        *      This field has not effect and should be left as 0x0.
-        * @glblintrmsk: Global Interrupt Mask (GlblIntrMsk)
-        *      Software should set this field to 0x1.
-        *      The application uses this bit to mask or unmask the interrupt
-        *      line assertion to itself. Irrespective of this bit's setting,
-        *      the interrupt status registers are updated by the core.
-        *      * 1'b0: Mask the interrupt assertion to the application.
-        *      * 1'b1: Unmask the interrupt assertion to the application.
-        */
-       struct cvmx_usbcx_gahbcfg_s {
-               uint32_t reserved_9_31  : 23;
-               uint32_t ptxfemplvl     : 1;
-               uint32_t nptxfemplvl    : 1;
-               uint32_t reserved_6_6   : 1;
-               uint32_t dmaen          : 1;
-               uint32_t hbstlen        : 4;
-               uint32_t glblintrmsk    : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_ghwcfg3
- *
- * User HW Config3 Register (GHWCFG3)
- *
- * This register contains the configuration options of the O2P USB core.
- */
-union cvmx_usbcx_ghwcfg3 {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_ghwcfg3_s
-        * @dfifodepth: DFIFO Depth (DfifoDepth)
-        *      This value is in terms of 32-bit words.
-        *      * Minimum value is 32
-        *      * Maximum value is 32768
-        * @ahbphysync: AHB and PHY Synchronous (AhbPhySync)
-        *      Indicates whether AHB and PHY clocks are synchronous to
-        *      each other.
-        *      * 1'b0: No
-        *      * 1'b1: Yes
-        *      This bit is tied to 1.
-        * @rsttype: Reset Style for Clocked always Blocks in RTL (RstType)
-        *      * 1'b0: Asynchronous reset is used in the core
-        *      * 1'b1: Synchronous reset is used in the core
-        * @optfeature: Optional Features Removed (OptFeature)
-        *      Indicates whether the User ID register, GPIO interface ports,
-        *      and SOF toggle and counter ports were removed for gate count
-        *      optimization.
-        * @vendor_control_interface_support: Vendor Control Interface Support
-        *      * 1'b0: Vendor Control Interface is not available on the core.
-        *      * 1'b1: Vendor Control Interface is available.
-        * @i2c_selection: I2C Selection
-        *      * 1'b0: I2C Interface is not available on the core.
-        *      * 1'b1: I2C Interface is available on the core.
-        * @otgen: OTG Function Enabled (OtgEn)
-        *      The application uses this bit to indicate the O2P USB core's
-        *      OTG capabilities.
-        *      * 1'b0: Not OTG capable
-        *      * 1'b1: OTG Capable
-        * @pktsizewidth: Width of Packet Size Counters (PktSizeWidth)
-        *      * 3'b000: 4 bits
-        *      * 3'b001: 5 bits
-        *      * 3'b010: 6 bits
-        *      * 3'b011: 7 bits
-        *      * 3'b100: 8 bits
-        *      * 3'b101: 9 bits
-        *      * 3'b110: 10 bits
-        *      * Others: Reserved
-        * @xfersizewidth: Width of Transfer Size Counters (XferSizeWidth)
-        *      * 4'b0000: 11 bits
-        *      * 4'b0001: 12 bits
-        *      - ...
-        *      * 4'b1000: 19 bits
-        *      * Others: Reserved
-        */
-       struct cvmx_usbcx_ghwcfg3_s {
-               uint32_t dfifodepth                             : 16;
-               uint32_t reserved_13_15                         : 3;
-               uint32_t ahbphysync                             : 1;
-               uint32_t rsttype                                : 1;
-               uint32_t optfeature                             : 1;
-               uint32_t vendor_control_interface_support       : 1;
-               uint32_t i2c_selection                          : 1;
-               uint32_t otgen                                  : 1;
-               uint32_t pktsizewidth                           : 3;
-               uint32_t xfersizewidth                          : 4;
-       } s;
-};
-
-/**
- * cvmx_usbc#_gintmsk
- *
- * Core Interrupt Mask Register (GINTMSK)
- *
- * This register works with the Core Interrupt register to interrupt the
- * application. When an interrupt bit is masked, the interrupt associated with
- * that bit will not be generated. However, the Core Interrupt (GINTSTS)
- * register bit corresponding to that interrupt will still be set.
- * Mask interrupt: 1'b0, Unmask interrupt: 1'b1
- */
-union cvmx_usbcx_gintmsk {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_gintmsk_s
-        * @wkupintmsk: Resume/Remote Wakeup Detected Interrupt Mask
-        *      (WkUpIntMsk)
-        * @sessreqintmsk: Session Request/New Session Detected Interrupt Mask
-        *      (SessReqIntMsk)
-        * @disconnintmsk: Disconnect Detected Interrupt Mask (DisconnIntMsk)
-        * @conidstschngmsk: Connector ID Status Change Mask (ConIDStsChngMsk)
-        * @ptxfempmsk: Periodic TxFIFO Empty Mask (PTxFEmpMsk)
-        * @hchintmsk: Host Channels Interrupt Mask (HChIntMsk)
-        * @prtintmsk: Host Port Interrupt Mask (PrtIntMsk)
-        * @fetsuspmsk: Data Fetch Suspended Mask (FetSuspMsk)
-        * @incomplpmsk: Incomplete Periodic Transfer Mask (incomplPMsk)
-        *      Incomplete Isochronous OUT Transfer Mask
-        *      (incompISOOUTMsk)
-        * @incompisoinmsk: Incomplete Isochronous IN Transfer Mask
-        *                  (incompISOINMsk)
-        * @oepintmsk: OUT Endpoints Interrupt Mask (OEPIntMsk)
-        * @inepintmsk: IN Endpoints Interrupt Mask (INEPIntMsk)
-        * @epmismsk: Endpoint Mismatch Interrupt Mask (EPMisMsk)
-        * @eopfmsk: End of Periodic Frame Interrupt Mask (EOPFMsk)
-        * @isooutdropmsk: Isochronous OUT Packet Dropped Interrupt Mask
-        *      (ISOOutDropMsk)
-        * @enumdonemsk: Enumeration Done Mask (EnumDoneMsk)
-        * @usbrstmsk: USB Reset Mask (USBRstMsk)
-        * @usbsuspmsk: USB Suspend Mask (USBSuspMsk)
-        * @erlysuspmsk: Early Suspend Mask (ErlySuspMsk)
-        * @i2cint: I2C Interrupt Mask (I2CINT)
-        * @ulpickintmsk: ULPI Carkit Interrupt Mask (ULPICKINTMsk)
-        *      I2C Carkit Interrupt Mask (I2CCKINTMsk)
-        * @goutnakeffmsk: Global OUT NAK Effective Mask (GOUTNakEffMsk)
-        * @ginnakeffmsk: Global Non-Periodic IN NAK Effective Mask
-        *                (GINNakEffMsk)
-        * @nptxfempmsk: Non-Periodic TxFIFO Empty Mask (NPTxFEmpMsk)
-        * @rxflvlmsk: Receive FIFO Non-Empty Mask (RxFLvlMsk)
-        * @sofmsk: Start of (micro)Frame Mask (SofMsk)
-        * @otgintmsk: OTG Interrupt Mask (OTGIntMsk)
-        * @modemismsk: Mode Mismatch Interrupt Mask (ModeMisMsk)
-        */
-       struct cvmx_usbcx_gintmsk_s {
-               uint32_t wkupintmsk             : 1;
-               uint32_t sessreqintmsk          : 1;
-               uint32_t disconnintmsk          : 1;
-               uint32_t conidstschngmsk        : 1;
-               uint32_t reserved_27_27         : 1;
-               uint32_t ptxfempmsk             : 1;
-               uint32_t hchintmsk              : 1;
-               uint32_t prtintmsk              : 1;
-               uint32_t reserved_23_23         : 1;
-               uint32_t fetsuspmsk             : 1;
-               uint32_t incomplpmsk            : 1;
-               uint32_t incompisoinmsk         : 1;
-               uint32_t oepintmsk              : 1;
-               uint32_t inepintmsk             : 1;
-               uint32_t epmismsk               : 1;
-               uint32_t reserved_16_16         : 1;
-               uint32_t eopfmsk                : 1;
-               uint32_t isooutdropmsk          : 1;
-               uint32_t enumdonemsk            : 1;
-               uint32_t usbrstmsk              : 1;
-               uint32_t usbsuspmsk             : 1;
-               uint32_t erlysuspmsk            : 1;
-               uint32_t i2cint                 : 1;
-               uint32_t ulpickintmsk           : 1;
-               uint32_t goutnakeffmsk          : 1;
-               uint32_t ginnakeffmsk           : 1;
-               uint32_t nptxfempmsk            : 1;
-               uint32_t rxflvlmsk              : 1;
-               uint32_t sofmsk                 : 1;
-               uint32_t otgintmsk              : 1;
-               uint32_t modemismsk             : 1;
-               uint32_t reserved_0_0           : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_gintsts
- *
- * Core Interrupt Register (GINTSTS)
- *
- * This register interrupts the application for system-level events in the
- * current mode of operation (Device mode or Host mode). It is shown in
- * Interrupt. Some of the bits in this register are valid only in Host mode,
- * while others are valid in Device mode only. This register also indicates the
- * current mode of operation. In order to clear the interrupt status bits of
- * type R_SS_WC, the application must write 1'b1 into the bit. The FIFO status
- * interrupts are read only; once software reads from or writes to the FIFO
- * while servicing these interrupts, FIFO interrupt conditions are cleared
- * automatically.
- */
-union cvmx_usbcx_gintsts {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_gintsts_s
-        * @wkupint: Resume/Remote Wakeup Detected Interrupt (WkUpInt)
-        *      In Device mode, this interrupt is asserted when a resume is
-        *      detected on the USB. In Host mode, this interrupt is asserted
-        *      when a remote wakeup is detected on the USB.
-        *      For more information on how to use this interrupt, see "Partial
-        *      Power-Down and Clock Gating Programming Model" on
-        *      page 353.
-        * @sessreqint: Session Request/New Session Detected Interrupt
-        *              (SessReqInt)
-        *      In Host mode, this interrupt is asserted when a session request
-        *      is detected from the device. In Device mode, this interrupt is
-        *      asserted when the utmiotg_bvalid signal goes high.
-        *      For more information on how to use this interrupt, see "Partial
-        *      Power-Down and Clock Gating Programming Model" on
-        *      page 353.
-        * @disconnint: Disconnect Detected Interrupt (DisconnInt)
-        *      Asserted when a device disconnect is detected.
-        * @conidstschng: Connector ID Status Change (ConIDStsChng)
-        *      The core sets this bit when there is a change in connector ID
-        *      status.
-        * @ptxfemp: Periodic TxFIFO Empty (PTxFEmp)
-        *      Asserted when the Periodic Transmit FIFO is either half or
-        *      completely empty and there is space for at least one entry to be
-        *      written in the Periodic Request Queue. The half or completely
-        *      empty status is determined by the Periodic TxFIFO Empty Level
-        *      bit in the Core AHB Configuration register
-        *      (GAHBCFG.PTxFEmpLvl).
-        * @hchint: Host Channels Interrupt (HChInt)
-        *      The core sets this bit to indicate that an interrupt is pending
-        *      on one of the channels of the core (in Host mode). The
-        *      application must read the Host All Channels Interrupt (HAINT)
-        *      register to determine the exact number of the channel on which
-        *      the interrupt occurred, and then read the corresponding Host
-        *      Channel-n Interrupt (HCINTn) register to determine the exact
-        *      cause of the interrupt. The application must clear the
-        *      appropriate status bit in the HCINTn register to clear this bit.
-        * @prtint: Host Port Interrupt (PrtInt)
-        *      The core sets this bit to indicate a change in port status of
-        *      one of the O2P USB core ports in Host mode. The application must
-        *      read the Host Port Control and Status (HPRT) register to
-        *      determine the exact event that caused this interrupt. The
-        *      application must clear the appropriate status bit in the Host
-        *      Port Control and Status register to clear this bit.
-        * @fetsusp: Data Fetch Suspended (FetSusp)
-        *      This interrupt is valid only in DMA mode. This interrupt
-        *      indicates that the core has stopped fetching data for IN
-        *      endpoints due to the unavailability of TxFIFO space or Request
-        *      Queue space. This interrupt is used by the application for an
-        *      endpoint mismatch algorithm.
-        * @incomplp: Incomplete Periodic Transfer (incomplP)
-        *      In Host mode, the core sets this interrupt bit when there are
-        *      incomplete periodic transactions still pending which are
-        *      scheduled for the current microframe.
-        *      Incomplete Isochronous OUT Transfer (incompISOOUT)
-        *      The Device mode, the core sets this interrupt to indicate that
-        *      there is at least one isochronous OUT endpoint on which the
-        *      transfer is not completed in the current microframe. This
-        *      interrupt is asserted along with the End of Periodic Frame
-        *      Interrupt (EOPF) bit in this register.
-        * @incompisoin: Incomplete Isochronous IN Transfer (incompISOIN)
-        *      The core sets this interrupt to indicate that there is at least
-        *      one isochronous IN endpoint on which the transfer is not
-        *      completed in the current microframe. This interrupt is asserted
-        *      along with the End of Periodic Frame Interrupt (EOPF) bit in
-        *      this register.
-        * @oepint: OUT Endpoints Interrupt (OEPInt)
-        *      The core sets this bit to indicate that an interrupt is pending
-        *      on one of the OUT endpoints of the core (in Device mode). The
-        *      application must read the Device All Endpoints Interrupt
-        *      (DAINT) register to determine the exact number of the OUT
-        *      endpoint on which the interrupt occurred, and then read the
-        *      corresponding Device OUT Endpoint-n Interrupt (DOEPINTn)
-        *      register to determine the exact cause of the interrupt. The
-        *      application must clear the appropriate status bit in the
-        *      corresponding DOEPINTn register to clear this bit.
-        * @iepint: IN Endpoints Interrupt (IEPInt)
-        *      The core sets this bit to indicate that an interrupt is pending
-        *      on one of the IN endpoints of the core (in Device mode). The
-        *      application must read the Device All Endpoints Interrupt
-        *      (DAINT) register to determine the exact number of the IN
-        *      endpoint on which the interrupt occurred, and then read the
-        *      corresponding Device IN Endpoint-n Interrupt (DIEPINTn)
-        *      register to determine the exact cause of the interrupt. The
-        *      application must clear the appropriate status bit in the
-        *      corresponding DIEPINTn register to clear this bit.
-        * @epmis: Endpoint Mismatch Interrupt (EPMis)
-        *      Indicates that an IN token has been received for a non-periodic
-        *      endpoint, but the data for another endpoint is present in the
-        *      top of the Non-Periodic Transmit FIFO and the IN endpoint
-        *      mismatch count programmed by the application has expired.
-        * @eopf: End of Periodic Frame Interrupt (EOPF)
-        *      Indicates that the period specified in the Periodic Frame
-        *      Interval field of the Device Configuration register
-        *      (DCFG.PerFrInt) has been reached in the current microframe.
-        * @isooutdrop: Isochronous OUT Packet Dropped Interrupt (ISOOutDrop)
-        *      The core sets this bit when it fails to write an isochronous OUT
-        *      packet into the RxFIFO because the RxFIFO doesn't have
-        *      enough space to accommodate a maximum packet size packet
-        *      for the isochronous OUT endpoint.
-        * @enumdone: Enumeration Done (EnumDone)
-        *      The core sets this bit to indicate that speed enumeration is
-        *      complete. The application must read the Device Status (DSTS)
-        *      register to obtain the enumerated speed.
-        * @usbrst: USB Reset (USBRst)
-        *      The core sets this bit to indicate that a reset is detected on
-        *      the USB.
-        * @usbsusp: USB Suspend (USBSusp)
-        *      The core sets this bit to indicate that a suspend was detected
-        *      on the USB. The core enters the Suspended state when there
-        *      is no activity on the phy_line_state_i signal for an extended
-        *      period of time.
-        * @erlysusp: Early Suspend (ErlySusp)
-        *      The core sets this bit to indicate that an Idle state has been
-        *      detected on the USB for 3 ms.
-        * @i2cint: I2C Interrupt (I2CINT)
-        *      This bit is always 0x0.
-        * @ulpickint: ULPI Carkit Interrupt (ULPICKINT)
-        *      This bit is always 0x0.
-        * @goutnakeff: Global OUT NAK Effective (GOUTNakEff)
-        *      Indicates that the Set Global OUT NAK bit in the Device Control
-        *      register (DCTL.SGOUTNak), set by the application, has taken
-        *      effect in the core. This bit can be cleared by writing the Clear
-        *      Global OUT NAK bit in the Device Control register
-        *      (DCTL.CGOUTNak).
-        * @ginnakeff: Global IN Non-Periodic NAK Effective (GINNakEff)
-        *      Indicates that the Set Global Non-Periodic IN NAK bit in the
-        *      Device Control register (DCTL.SGNPInNak), set by the
-        *      application, has taken effect in the core. That is, the core has
-        *      sampled the Global IN NAK bit set by the application. This bit
-        *      can be cleared by clearing the Clear Global Non-Periodic IN
-        *      NAK bit in the Device Control register (DCTL.CGNPInNak).
-        *      This interrupt does not necessarily mean that a NAK handshake
-        *      is sent out on the USB. The STALL bit takes precedence over
-        *      the NAK bit.
-        * @nptxfemp: Non-Periodic TxFIFO Empty (NPTxFEmp)
-        *      This interrupt is asserted when the Non-Periodic TxFIFO is
-        *      either half or completely empty, and there is space for at least
-        *      one entry to be written to the Non-Periodic Transmit Request
-        *      Queue. The half or completely empty status is determined by
-        *      the Non-Periodic TxFIFO Empty Level bit in the Core AHB
-        *      Configuration register (GAHBCFG.NPTxFEmpLvl).
-        * @rxflvl: RxFIFO Non-Empty (RxFLvl)
-        *      Indicates that there is at least one packet pending to be read
-        *      from the RxFIFO.
-        * @sof: Start of (micro)Frame (Sof)
-        *      In Host mode, the core sets this bit to indicate that an SOF
-        *      (FS), micro-SOF (HS), or Keep-Alive (LS) is transmitted on the
-        *      USB. The application must write a 1 to this bit to clear the
-        *      interrupt.
-        *      In Device mode, in the core sets this bit to indicate that an
-        *      SOF token has been received on the USB. The application can read
-        *      the Device Status register to get the current (micro)frame
-        *      number. This interrupt is seen only when the core is operating
-        *      at either HS or FS.
-        * @otgint: OTG Interrupt (OTGInt)
-        *      The core sets this bit to indicate an OTG protocol event. The
-        *      application must read the OTG Interrupt Status (GOTGINT)
-        *      register to determine the exact event that caused this
-        *      interrupt. The application must clear the appropriate status bit
-        *      in the GOTGINT register to clear this bit.
-        * @modemis: Mode Mismatch Interrupt (ModeMis)
-        *      The core sets this bit when the application is trying to access:
-        *      * A Host mode register, when the core is operating in Device
-        *      mode
-        *      * A Device mode register, when the core is operating in Host
-        *      mode
-        *      The register access is completed on the AHB with an OKAY
-        *      response, but is ignored by the core internally and doesn't
-        *      affect the operation of the core.
-        * @curmod: Current Mode of Operation (CurMod)
-        *      Indicates the current mode of operation.
-        *      * 1'b0: Device mode
-        *      * 1'b1: Host mode
-        */
-       struct cvmx_usbcx_gintsts_s {
-               uint32_t wkupint        : 1;
-               uint32_t sessreqint     : 1;
-               uint32_t disconnint     : 1;
-               uint32_t conidstschng   : 1;
-               uint32_t reserved_27_27 : 1;
-               uint32_t ptxfemp        : 1;
-               uint32_t hchint         : 1;
-               uint32_t prtint         : 1;
-               uint32_t reserved_23_23 : 1;
-               uint32_t fetsusp        : 1;
-               uint32_t incomplp       : 1;
-               uint32_t incompisoin    : 1;
-               uint32_t oepint         : 1;
-               uint32_t iepint         : 1;
-               uint32_t epmis          : 1;
-               uint32_t reserved_16_16 : 1;
-               uint32_t eopf           : 1;
-               uint32_t isooutdrop     : 1;
-               uint32_t enumdone       : 1;
-               uint32_t usbrst         : 1;
-               uint32_t usbsusp        : 1;
-               uint32_t erlysusp       : 1;
-               uint32_t i2cint         : 1;
-               uint32_t ulpickint      : 1;
-               uint32_t goutnakeff     : 1;
-               uint32_t ginnakeff      : 1;
-               uint32_t nptxfemp       : 1;
-               uint32_t rxflvl         : 1;
-               uint32_t sof            : 1;
-               uint32_t otgint         : 1;
-               uint32_t modemis        : 1;
-               uint32_t curmod         : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_gnptxfsiz
- *
- * Non-Periodic Transmit FIFO Size Register (GNPTXFSIZ)
- *
- * The application can program the RAM size and the memory start address for the
- * Non-Periodic TxFIFO.
- */
-union cvmx_usbcx_gnptxfsiz {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_gnptxfsiz_s
-        * @nptxfdep: Non-Periodic TxFIFO Depth (NPTxFDep)
-        *      This value is in terms of 32-bit words.
-        *      Minimum value is 16
-        *      Maximum value is 32768
-        * @nptxfstaddr: Non-Periodic Transmit RAM Start Address (NPTxFStAddr)
-        *      This field contains the memory start address for Non-Periodic
-        *      Transmit FIFO RAM.
-        */
-       struct cvmx_usbcx_gnptxfsiz_s {
-               uint32_t nptxfdep       : 16;
-               uint32_t nptxfstaddr    : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_gnptxsts
- *
- * Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS)
- *
- * This read-only register contains the free space information for the
- * Non-Periodic TxFIFO and the Non-Periodic Transmit Request Queue.
- */
-union cvmx_usbcx_gnptxsts {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_gnptxsts_s
-        * @nptxqtop: Top of the Non-Periodic Transmit Request Queue (NPTxQTop)
-        *      Entry in the Non-Periodic Tx Request Queue that is currently
-        *      being processed by the MAC.
-        *      * Bits [30:27]: Channel/endpoint number
-        *      * Bits [26:25]:
-        *      - 2'b00: IN/OUT token
-        *      - 2'b01: Zero-length transmit packet (device IN/host OUT)
-        *      - 2'b10: PING/CSPLIT token
-        *      - 2'b11: Channel halt command
-        *      * Bit [24]: Terminate (last entry for selected channel/endpoint)
-        * @nptxqspcavail: Non-Periodic Transmit Request Queue Space Available
-        *      (NPTxQSpcAvail)
-        *      Indicates the amount of free space available in the Non-
-        *      Periodic Transmit Request Queue. This queue holds both IN
-        *      and OUT requests in Host mode. Device mode has only IN
-        *      requests.
-        *      * 8'h0: Non-Periodic Transmit Request Queue is full
-        *      * 8'h1: 1 location available
-        *      * 8'h2: 2 locations available
-        *      * n: n locations available (0..8)
-        *      * Others: Reserved
-        * @nptxfspcavail: Non-Periodic TxFIFO Space Avail (NPTxFSpcAvail)
-        *      Indicates the amount of free space available in the Non-
-        *      Periodic TxFIFO.
-        *      Values are in terms of 32-bit words.
-        *      * 16'h0: Non-Periodic TxFIFO is full
-        *      * 16'h1: 1 word available
-        *      * 16'h2: 2 words available
-        *      * 16'hn: n words available (where 0..32768)
-        *      * 16'h8000: 32768 words available
-        *      * Others: Reserved
-        */
-       struct cvmx_usbcx_gnptxsts_s {
-               uint32_t reserved_31_31 : 1;
-               uint32_t nptxqtop       : 7;
-               uint32_t nptxqspcavail  : 8;
-               uint32_t nptxfspcavail  : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_grstctl
- *
- * Core Reset Register (GRSTCTL)
- *
- * The application uses this register to reset various hardware features inside
- * the core.
- */
-union cvmx_usbcx_grstctl {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_grstctl_s
-        * @ahbidle: AHB Master Idle (AHBIdle)
-        *      Indicates that the AHB Master State Machine is in the IDLE
-        *      condition.
-        * @dmareq: DMA Request Signal (DMAReq)
-        *      Indicates that the DMA request is in progress. Used for debug.
-        * @txfnum: TxFIFO Number (TxFNum)
-        *      This is the FIFO number that must be flushed using the TxFIFO
-        *      Flush bit. This field must not be changed until the core clears
-        *      the TxFIFO Flush bit.
-        *      * 5'h0: Non-Periodic TxFIFO flush
-        *      * 5'h1: Periodic TxFIFO 1 flush in Device mode or Periodic
-        *      TxFIFO flush in Host mode
-        *      * 5'h2: Periodic TxFIFO 2 flush in Device mode
-        *      - ...
-        *      * 5'hF: Periodic TxFIFO 15 flush in Device mode
-        *      * 5'h10: Flush all the Periodic and Non-Periodic TxFIFOs in the
-        *      core
-        * @txfflsh: TxFIFO Flush (TxFFlsh)
-        *      This bit selectively flushes a single or all transmit FIFOs, but
-        *      cannot do so if the core is in the midst of a transaction.
-        *      The application must only write this bit after checking that the
-        *      core is neither writing to the TxFIFO nor reading from the
-        *      TxFIFO.
-        *      The application must wait until the core clears this bit before
-        *      performing any operations. This bit takes 8 clocks (of phy_clk
-        *      or hclk, whichever is slower) to clear.
-        * @rxfflsh: RxFIFO Flush (RxFFlsh)
-        *      The application can flush the entire RxFIFO using this bit, but
-        *      must first ensure that the core is not in the middle of a
-        *      transaction.
-        *      The application must only write to this bit after checking that
-        *      the core is neither reading from the RxFIFO nor writing to the
-        *      RxFIFO.
-        *      The application must wait until the bit is cleared before
-        *      performing any other operations. This bit will take 8 clocks
-        *      (slowest of PHY or AHB clock) to clear.
-        * @intknqflsh: IN Token Sequence Learning Queue Flush (INTknQFlsh)
-        *      The application writes this bit to flush the IN Token Sequence
-        *      Learning Queue.
-        * @frmcntrrst: Host Frame Counter Reset (FrmCntrRst)
-        *      The application writes this bit to reset the (micro)frame number
-        *      counter inside the core. When the (micro)frame counter is reset,
-        *      the subsequent SOF sent out by the core will have a
-        *      (micro)frame number of 0.
-        * @hsftrst: HClk Soft Reset (HSftRst)
-        *      The application uses this bit to flush the control logic in the
-        *      AHB Clock domain. Only AHB Clock Domain pipelines are reset.
-        *      * FIFOs are not flushed with this bit.
-        *      * All state machines in the AHB clock domain are reset to the
-        *      Idle state after terminating the transactions on the AHB,
-        *      following the protocol.
-        *      * CSR control bits used by the AHB clock domain state
-        *      machines are cleared.
-        *      * To clear this interrupt, status mask bits that control the
-        *      interrupt status and are generated by the AHB clock domain
-        *      state machine are cleared.
-        *      * Because interrupt status bits are not cleared, the application
-        *      can get the status of any core events that occurred after it set
-        *      this bit.
-        *      This is a self-clearing bit that the core clears after all
-        *      necessary logic is reset in the core. This may take several
-        *      clocks, depending on the core's current state.
-        * @csftrst: Core Soft Reset (CSftRst)
-        *      Resets the hclk and phy_clock domains as follows:
-        *      * Clears the interrupts and all the CSR registers except the
-        *      following register bits:
-        *      - PCGCCTL.RstPdwnModule
-        *      - PCGCCTL.GateHclk
-        *      - PCGCCTL.PwrClmp
-        *      - PCGCCTL.StopPPhyLPwrClkSelclk
-        *      - GUSBCFG.PhyLPwrClkSel
-        *      - GUSBCFG.DDRSel
-        *      - GUSBCFG.PHYSel
-        *      - GUSBCFG.FSIntf
-        *      - GUSBCFG.ULPI_UTMI_Sel
-        *      - GUSBCFG.PHYIf
-        *      - HCFG.FSLSPclkSel
-        *      - DCFG.DevSpd
-        *      * All module state machines (except the AHB Slave Unit) are
-        *      reset to the IDLE state, and all the transmit FIFOs and the
-        *      receive FIFO are flushed.
-        *      * Any transactions on the AHB Master are terminated as soon
-        *      as possible, after gracefully completing the last data phase of
-        *      an AHB transfer. Any transactions on the USB are terminated
-        *      immediately.
-        *      The application can write to this bit any time it wants to reset
-        *      the core. This is a self-clearing bit and the core clears this
-        *      bit after all the necessary logic is reset in the core, which
-        *      may take several clocks, depending on the current state of the
-        *      core. Once this bit is cleared software should wait at least 3
-        *      PHY clocks before doing any access to the PHY domain
-        *      (synchronization delay). Software should also should check that
-        *      bit 31 of this register is 1 (AHB Master is IDLE) before
-        *      starting any operation.
-        *      Typically software reset is used during software development
-        *      and also when you dynamically change the PHY selection bits
-        *      in the USB configuration registers listed above. When you
-        *      change the PHY, the corresponding clock for the PHY is
-        *      selected and used in the PHY domain. Once a new clock is
-        *      selected, the PHY domain has to be reset for proper operation.
-        */
-       struct cvmx_usbcx_grstctl_s {
-               uint32_t ahbidle        : 1;
-               uint32_t dmareq         : 1;
-               uint32_t reserved_11_29 : 19;
-               uint32_t txfnum         : 5;
-               uint32_t txfflsh        : 1;
-               uint32_t rxfflsh        : 1;
-               uint32_t intknqflsh     : 1;
-               uint32_t frmcntrrst     : 1;
-               uint32_t hsftrst        : 1;
-               uint32_t csftrst        : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_grxfsiz
- *
- * Receive FIFO Size Register (GRXFSIZ)
- *
- * The application can program the RAM size that must be allocated to the
- * RxFIFO.
- */
-union cvmx_usbcx_grxfsiz {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_grxfsiz_s
-        * @rxfdep: RxFIFO Depth (RxFDep)
-        *      This value is in terms of 32-bit words.
-        *      * Minimum value is 16
-        *      * Maximum value is 32768
-        */
-       struct cvmx_usbcx_grxfsiz_s {
-               uint32_t reserved_16_31 : 16;
-               uint32_t rxfdep         : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_grxstsph
- *
- * Receive Status Read and Pop Register, Host Mode (GRXSTSPH)
- *
- * A read to the Receive Status Read and Pop register returns and additionally
- * pops the top data entry out of the RxFIFO.
- * This Description is only valid when the core is in Host Mode. For Device Mode
- * use USBC_GRXSTSPD instead.
- * NOTE: GRXSTSPH and GRXSTSPD are physically the same register and share the
- *      same offset in the O2P USB core. The offset difference shown in this
- *      document is for software clarity and is actually ignored by the
- *       hardware.
- */
-union cvmx_usbcx_grxstsph {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_grxstsph_s
-        * @pktsts: Packet Status (PktSts)
-        *      Indicates the status of the received packet
-        *      * 4'b0010: IN data packet received
-        *      * 4'b0011: IN transfer completed (triggers an interrupt)
-        *      * 4'b0101: Data toggle error (triggers an interrupt)
-        *      * 4'b0111: Channel halted (triggers an interrupt)
-        *      * Others: Reserved
-        * @dpid: Data PID (DPID)
-        *      * 2'b00: DATA0
-        *      * 2'b10: DATA1
-        *      * 2'b01: DATA2
-        *      * 2'b11: MDATA
-        * @bcnt: Byte Count (BCnt)
-        *      Indicates the byte count of the received IN data packet
-        * @chnum: Channel Number (ChNum)
-        *      Indicates the channel number to which the current received
-        *      packet belongs.
-        */
-       struct cvmx_usbcx_grxstsph_s {
-               uint32_t reserved_21_31 : 11;
-               uint32_t pktsts         : 4;
-               uint32_t dpid           : 2;
-               uint32_t bcnt           : 11;
-               uint32_t chnum          : 4;
-       } s;
-};
-
-/**
- * cvmx_usbc#_gusbcfg
- *
- * Core USB Configuration Register (GUSBCFG)
- *
- * This register can be used to configure the core after power-on or a changing
- * to Host mode or Device mode. It contains USB and USB-PHY related
- * configuration parameters. The application must program this register before
- * starting any transactions on either the AHB or the USB. Do not make changes
- * to this register after the initial programming.
- */
-union cvmx_usbcx_gusbcfg {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_gusbcfg_s
-        * @otgi2csel: UTMIFS or I2C Interface Select (OtgI2CSel)
-        *      This bit is always 0x0.
-        * @phylpwrclksel: PHY Low-Power Clock Select (PhyLPwrClkSel)
-        *      Software should set this bit to 0x0.
-        *      Selects either 480-MHz or 48-MHz (low-power) PHY mode. In
-        *      FS and LS modes, the PHY can usually operate on a 48-MHz
-        *      clock to save power.
-        *      * 1'b0: 480-MHz Internal PLL clock
-        *      * 1'b1: 48-MHz External Clock
-        *      In 480 MHz mode, the UTMI interface operates at either 60 or
-        *      30-MHz, depending upon whether 8- or 16-bit data width is
-        *      selected. In 48-MHz mode, the UTMI interface operates at 48
-        *      MHz in FS mode and at either 48 or 6 MHz in LS mode
-        *      (depending on the PHY vendor).
-        *      This bit drives the utmi_fsls_low_power core output signal, and
-        *      is valid only for UTMI+ PHYs.
-        * @usbtrdtim: USB Turnaround Time (USBTrdTim)
-        *      Sets the turnaround time in PHY clocks.
-        *      Specifies the response time for a MAC request to the Packet
-        *      FIFO Controller (PFC) to fetch data from the DFIFO (SPRAM).
-        *      This must be programmed to 0x5.
-        * @hnpcap: HNP-Capable (HNPCap)
-        *      This bit is always 0x0.
-        * @srpcap: SRP-Capable (SRPCap)
-        *      This bit is always 0x0.
-        * @ddrsel: ULPI DDR Select (DDRSel)
-        *      Software should set this bit to 0x0.
-        * @physel: USB 2.0 High-Speed PHY or USB 1.1 Full-Speed Serial
-        *      Software should set this bit to 0x0.
-        * @fsintf: Full-Speed Serial Interface Select (FSIntf)
-        *      Software should set this bit to 0x0.
-        * @ulpi_utmi_sel: ULPI or UTMI+ Select (ULPI_UTMI_Sel)
-        *      This bit is always 0x0.
-        * @phyif: PHY Interface (PHYIf)
-        *      This bit is always 0x1.
-        * @toutcal: HS/FS Timeout Calibration (TOutCal)
-        *      The number of PHY clocks that the application programs in this
-        *      field is added to the high-speed/full-speed interpacket timeout
-        *      duration in the core to account for any additional delays
-        *      introduced by the PHY. This may be required, since the delay
-        *      introduced by the PHY in generating the linestate condition may
-        *      vary from one PHY to another.
-        *      The USB standard timeout value for high-speed operation is
-        *      736 to 816 (inclusive) bit times. The USB standard timeout
-        *      value for full-speed operation is 16 to 18 (inclusive) bit
-        *      times. The application must program this field based on the
-        *      speed of enumeration. The number of bit times added per PHY
-        *      clock are:
-        *      High-speed operation:
-        *      * One 30-MHz PHY clock = 16 bit times
-        *      * One 60-MHz PHY clock = 8 bit times
-        *      Full-speed operation:
-        *      * One 30-MHz PHY clock = 0.4 bit times
-        *      * One 60-MHz PHY clock = 0.2 bit times
-        *      * One 48-MHz PHY clock = 0.25 bit times
-        */
-       struct cvmx_usbcx_gusbcfg_s {
-               uint32_t reserved_17_31 : 15;
-               uint32_t otgi2csel      : 1;
-               uint32_t phylpwrclksel  : 1;
-               uint32_t reserved_14_14 : 1;
-               uint32_t usbtrdtim      : 4;
-               uint32_t hnpcap         : 1;
-               uint32_t srpcap         : 1;
-               uint32_t ddrsel         : 1;
-               uint32_t physel         : 1;
-               uint32_t fsintf         : 1;
-               uint32_t ulpi_utmi_sel  : 1;
-               uint32_t phyif          : 1;
-               uint32_t toutcal        : 3;
-       } s;
-};
-
-/**
- * cvmx_usbc#_haint
- *
- * Host All Channels Interrupt Register (HAINT)
- *
- * When a significant event occurs on a channel, the Host All Channels Interrupt
- * register interrupts the application using the Host Channels Interrupt bit of
- * the Core Interrupt register (GINTSTS.HChInt). This is shown in Interrupt.
- * There is one interrupt bit per channel, up to a maximum of 16 bits. Bits in
- * this register are set and cleared when the application sets and clears bits
- * in the corresponding Host Channel-n Interrupt register.
- */
-union cvmx_usbcx_haint {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_haint_s
-        * @haint: Channel Interrupts (HAINT)
-        *      One bit per channel: Bit 0 for Channel 0, bit 15 for Channel 15
-        */
-       struct cvmx_usbcx_haint_s {
-               uint32_t reserved_16_31 : 16;
-               uint32_t haint          : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_haintmsk
- *
- * Host All Channels Interrupt Mask Register (HAINTMSK)
- *
- * The Host All Channel Interrupt Mask register works with the Host All Channel
- * Interrupt register to interrupt the application when an event occurs on a
- * channel. There is one interrupt mask bit per channel, up to a maximum of 16
- * bits.
- * Mask interrupt: 1'b0 Unmask interrupt: 1'b1
- */
-union cvmx_usbcx_haintmsk {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_haintmsk_s
-        * @haintmsk: Channel Interrupt Mask (HAINTMsk)
-        *      One bit per channel: Bit 0 for channel 0, bit 15 for channel 15
-        */
-       struct cvmx_usbcx_haintmsk_s {
-               uint32_t reserved_16_31 : 16;
-               uint32_t haintmsk       : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hcchar#
- *
- * Host Channel-n Characteristics Register (HCCHAR)
- *
- */
-union cvmx_usbcx_hccharx {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hccharx_s
-        * @chena: Channel Enable (ChEna)
-        *      This field is set by the application and cleared by the OTG
-        *      host.
-        *      * 1'b0: Channel disabled
-        *      * 1'b1: Channel enabled
-        * @chdis: Channel Disable (ChDis)
-        *      The application sets this bit to stop transmitting/receiving
-        *      data on a channel, even before the transfer for that channel is
-        *      complete. The application must wait for the Channel Disabled
-        *      interrupt before treating the channel as disabled.
-        * @oddfrm: Odd Frame (OddFrm)
-        *      This field is set (reset) by the application to indicate that
-        *      the OTG host must perform a transfer in an odd (micro)frame.
-        *      This field is applicable for only periodic (isochronous and
-        *      interrupt) transactions.
-        *      * 1'b0: Even (micro)frame
-        *      * 1'b1: Odd (micro)frame
-        * @devaddr: Device Address (DevAddr)
-        *      This field selects the specific device serving as the data
-        *      source or sink.
-        * @ec: Multi Count (MC) / Error Count (EC)
-        *      When the Split Enable bit of the Host Channel-n Split Control
-        *      register (HCSPLTn.SpltEna) is reset (1'b0), this field indicates
-        *      to the host the number of transactions that should be executed
-        *      per microframe for this endpoint.
-        *      * 2'b00: Reserved. This field yields undefined results.
-        *      * 2'b01: 1 transaction
-        *      * 2'b10: 2 transactions to be issued for this endpoint per
-        *      microframe
-        *      * 2'b11: 3 transactions to be issued for this endpoint per
-        *      microframe
-        *      When HCSPLTn.SpltEna is set (1'b1), this field indicates the
-        *      number of immediate retries to be performed for a periodic split
-        *      transactions on transaction errors. This field must be set to at
-        *      least 2'b01.
-        * @eptype: Endpoint Type (EPType)
-        *      Indicates the transfer type selected.
-        *      * 2'b00: Control
-        *      * 2'b01: Isochronous
-        *      * 2'b10: Bulk
-        *      * 2'b11: Interrupt
-        * @lspddev: Low-Speed Device (LSpdDev)
-        *      This field is set by the application to indicate that this
-        *      channel is communicating to a low-speed device.
-        * @epdir: Endpoint Direction (EPDir)
-        *      Indicates whether the transaction is IN or OUT.
-        *      * 1'b0: OUT
-        *      * 1'b1: IN
-        * @epnum: Endpoint Number (EPNum)
-        *      Indicates the endpoint number on the device serving as the
-        *      data source or sink.
-        * @mps: Maximum Packet Size (MPS)
-        *      Indicates the maximum packet size of the associated endpoint.
-        */
-       struct cvmx_usbcx_hccharx_s {
-               uint32_t chena          : 1;
-               uint32_t chdis          : 1;
-               uint32_t oddfrm         : 1;
-               uint32_t devaddr        : 7;
-               uint32_t ec             : 2;
-               uint32_t eptype         : 2;
-               uint32_t lspddev        : 1;
-               uint32_t reserved_16_16 : 1;
-               uint32_t epdir          : 1;
-               uint32_t epnum          : 4;
-               uint32_t mps            : 11;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hcfg
- *
- * Host Configuration Register (HCFG)
- *
- * This register configures the core after power-on. Do not make changes to this
- * register after initializing the host.
- */
-union cvmx_usbcx_hcfg {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hcfg_s
-        * @fslssupp: FS- and LS-Only Support (FSLSSupp)
-        *      The application uses this bit to control the core's enumeration
-        *      speed. Using this bit, the application can make the core
-        *      enumerate as a FS host, even if the connected device supports
-        *      HS traffic. Do not make changes to this field after initial
-        *      programming.
-        *      * 1'b0: HS/FS/LS, based on the maximum speed supported by
-        *      the connected device
-        *      * 1'b1: FS/LS-only, even if the connected device can support HS
-        * @fslspclksel: FS/LS PHY Clock Select (FSLSPclkSel)
-        *      When the core is in FS Host mode
-        *      * 2'b00: PHY clock is running at 30/60 MHz
-        *      * 2'b01: PHY clock is running at 48 MHz
-        *      * Others: Reserved
-        *      When the core is in LS Host mode
-        *      * 2'b00: PHY clock is running at 30/60 MHz. When the
-        *      UTMI+/ULPI PHY Low Power mode is not selected, use
-        *      30/60 MHz.
-        *      * 2'b01: PHY clock is running at 48 MHz. When the UTMI+
-        *      PHY Low Power mode is selected, use 48MHz if the PHY
-        *      supplies a 48 MHz clock during LS mode.
-        *      * 2'b10: PHY clock is running at 6 MHz. In USB 1.1 FS mode,
-        *      use 6 MHz when the UTMI+ PHY Low Power mode is
-        *      selected and the PHY supplies a 6 MHz clock during LS
-        *      mode. If you select a 6 MHz clock during LS mode, you must
-        *      do a soft reset.
-        *      * 2'b11: Reserved
-        */
-       struct cvmx_usbcx_hcfg_s {
-               uint32_t reserved_3_31  : 29;
-               uint32_t fslssupp       : 1;
-               uint32_t fslspclksel    : 2;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hcint#
- *
- * Host Channel-n Interrupt Register (HCINT)
- *
- * This register indicates the status of a channel with respect to USB- and
- * AHB-related events. The application must read this register when the Host
- * Channels Interrupt bit of the Core Interrupt register (GINTSTS.HChInt) is
- * set. Before the application can read this register, it must first read
- * the Host All Channels Interrupt (HAINT) register to get the exact channel
- * number for the Host Channel-n Interrupt register. The application must clear
- * the appropriate bit in this register to clear the corresponding bits in the
- * HAINT and GINTSTS registers.
- */
-union cvmx_usbcx_hcintx {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hcintx_s
-        * @datatglerr: Data Toggle Error (DataTglErr)
-        * @frmovrun: Frame Overrun (FrmOvrun)
-        * @bblerr: Babble Error (BblErr)
-        * @xacterr: Transaction Error (XactErr)
-        * @nyet: NYET Response Received Interrupt (NYET)
-        * @ack: ACK Response Received Interrupt (ACK)
-        * @nak: NAK Response Received Interrupt (NAK)
-        * @stall: STALL Response Received Interrupt (STALL)
-        * @ahberr: This bit is always 0x0.
-        * @chhltd: Channel Halted (ChHltd)
-        *      Indicates the transfer completed abnormally either because of
-        *      any USB transaction error or in response to disable request by
-        *      the application.
-        * @xfercompl: Transfer Completed (XferCompl)
-        *      Transfer completed normally without any errors.
-        */
-       struct cvmx_usbcx_hcintx_s {
-               uint32_t reserved_11_31 : 21;
-               uint32_t datatglerr     : 1;
-               uint32_t frmovrun       : 1;
-               uint32_t bblerr         : 1;
-               uint32_t xacterr        : 1;
-               uint32_t nyet           : 1;
-               uint32_t ack            : 1;
-               uint32_t nak            : 1;
-               uint32_t stall          : 1;
-               uint32_t ahberr         : 1;
-               uint32_t chhltd         : 1;
-               uint32_t xfercompl      : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hcintmsk#
- *
- * Host Channel-n Interrupt Mask Register (HCINTMSKn)
- *
- * This register reflects the mask for each channel status described in the
- * previous section.
- * Mask interrupt: 1'b0 Unmask interrupt: 1'b1
- */
-union cvmx_usbcx_hcintmskx {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hcintmskx_s
-        * @datatglerrmsk: Data Toggle Error Mask (DataTglErrMsk)
-        * @frmovrunmsk: Frame Overrun Mask (FrmOvrunMsk)
-        * @bblerrmsk: Babble Error Mask (BblErrMsk)
-        * @xacterrmsk: Transaction Error Mask (XactErrMsk)
-        * @nyetmsk: NYET Response Received Interrupt Mask (NyetMsk)
-        * @ackmsk: ACK Response Received Interrupt Mask (AckMsk)
-        * @nakmsk: NAK Response Received Interrupt Mask (NakMsk)
-        * @stallmsk: STALL Response Received Interrupt Mask (StallMsk)
-        * @ahberrmsk: AHB Error Mask (AHBErrMsk)
-        * @chhltdmsk: Channel Halted Mask (ChHltdMsk)
-        * @xfercomplmsk: Transfer Completed Mask (XferComplMsk)
-        */
-       struct cvmx_usbcx_hcintmskx_s {
-               uint32_t reserved_11_31 : 21;
-               uint32_t datatglerrmsk  : 1;
-               uint32_t frmovrunmsk    : 1;
-               uint32_t bblerrmsk      : 1;
-               uint32_t xacterrmsk     : 1;
-               uint32_t nyetmsk        : 1;
-               uint32_t ackmsk         : 1;
-               uint32_t nakmsk         : 1;
-               uint32_t stallmsk       : 1;
-               uint32_t ahberrmsk      : 1;
-               uint32_t chhltdmsk      : 1;
-               uint32_t xfercomplmsk   : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hcsplt#
- *
- * Host Channel-n Split Control Register (HCSPLT)
- *
- */
-union cvmx_usbcx_hcspltx {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hcspltx_s
-        * @spltena: Split Enable (SpltEna)
-        *      The application sets this field to indicate that this channel is
-        *      enabled to perform split transactions.
-        * @compsplt: Do Complete Split (CompSplt)
-        *      The application sets this field to request the OTG host to
-        *      perform a complete split transaction.
-        * @xactpos: Transaction Position (XactPos)
-        *      This field is used to determine whether to send all, first,
-        *      middle, or last payloads with each OUT transaction.
-        *      * 2'b11: All. This is the entire data payload is of this
-        *      transaction (which is less than or equal to 188 bytes).
-        *      * 2'b10: Begin. This is the first data payload of this
-        *      transaction (which is larger than 188 bytes).
-        *      * 2'b00: Mid. This is the middle payload of this transaction
-        *      (which is larger than 188 bytes).
-        *      * 2'b01: End. This is the last payload of this transaction
-        *      (which is larger than 188 bytes).
-        * @hubaddr: Hub Address (HubAddr)
-        *      This field holds the device address of the transaction
-        *      translator's hub.
-        * @prtaddr: Port Address (PrtAddr)
-        *      This field is the port number of the recipient transaction
-        *      translator.
-        */
-       struct cvmx_usbcx_hcspltx_s {
-               uint32_t spltena        : 1;
-               uint32_t reserved_17_30 : 14;
-               uint32_t compsplt       : 1;
-               uint32_t xactpos        : 2;
-               uint32_t hubaddr        : 7;
-               uint32_t prtaddr        : 7;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hctsiz#
- *
- * Host Channel-n Transfer Size Register (HCTSIZ)
- *
- */
-union cvmx_usbcx_hctsizx {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hctsizx_s
-        * @dopng: Do Ping (DoPng)
-        *      Setting this field to 1 directs the host to do PING protocol.
-        * @pid: PID (Pid)
-        *      The application programs this field with the type of PID to use
-        *      for the initial transaction. The host will maintain this field
-        *      for the rest of the transfer.
-        *      * 2'b00: DATA0
-        *      * 2'b01: DATA2
-        *      * 2'b10: DATA1
-        *      * 2'b11: MDATA (non-control)/SETUP (control)
-        * @pktcnt: Packet Count (PktCnt)
-        *      This field is programmed by the application with the expected
-        *      number of packets to be transmitted (OUT) or received (IN).
-        *      The host decrements this count on every successful
-        *      transmission or reception of an OUT/IN packet. Once this count
-        *      reaches zero, the application is interrupted to indicate normal
-        *      completion.
-        * @xfersize: Transfer Size (XferSize)
-        *      For an OUT, this field is the number of data bytes the host will
-        *      send during the transfer.
-        *      For an IN, this field is the buffer size that the application
-        *      has reserved for the transfer. The application is expected to
-        *      program this field as an integer multiple of the maximum packet
-        *      size for IN transactions (periodic and non-periodic).
-        */
-       struct cvmx_usbcx_hctsizx_s {
-               uint32_t dopng          : 1;
-               uint32_t pid            : 2;
-               uint32_t pktcnt         : 10;
-               uint32_t xfersize       : 19;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hfir
- *
- * Host Frame Interval Register (HFIR)
- *
- * This register stores the frame interval information for the current speed to
- * which the O2P USB core has enumerated.
- */
-union cvmx_usbcx_hfir {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hfir_s
-        * @frint: Frame Interval (FrInt)
-        *      The value that the application programs to this field specifies
-        *      the interval between two consecutive SOFs (FS) or micro-
-        *      SOFs (HS) or Keep-Alive tokens (HS). This field contains the
-        *      number of PHY clocks that constitute the required frame
-        *      interval. The default value set in this field for a FS operation
-        *      when the PHY clock frequency is 60 MHz. The application can
-        *      write a value to this register only after the Port Enable bit of
-        *      the Host Port Control and Status register (HPRT.PrtEnaPort)
-        *      has been set. If no value is programmed, the core calculates
-        *      the value based on the PHY clock specified in the FS/LS PHY
-        *      Clock Select field of the Host Configuration register
-        *      (HCFG.FSLSPclkSel). Do not change the value of this field
-        *      after the initial configuration.
-        *      * 125 us (PHY clock frequency for HS)
-        *      * 1 ms (PHY clock frequency for FS/LS)
-        */
-       struct cvmx_usbcx_hfir_s {
-               uint32_t reserved_16_31 : 16;
-               uint32_t frint          : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hfnum
- *
- * Host Frame Number/Frame Time Remaining Register (HFNUM)
- *
- * This register indicates the current frame number.
- * It also indicates the time remaining (in terms of the number of PHY clocks)
- * in the current (micro)frame.
- */
-union cvmx_usbcx_hfnum {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hfnum_s
-        * @frrem: Frame Time Remaining (FrRem)
-        *      Indicates the amount of time remaining in the current
-        *      microframe (HS) or frame (FS/LS), in terms of PHY clocks.
-        *      This field decrements on each PHY clock. When it reaches
-        *      zero, this field is reloaded with the value in the Frame
-        *      Interval register and a new SOF is transmitted on the USB.
-        * @frnum: Frame Number (FrNum)
-        *      This field increments when a new SOF is transmitted on the
-        *      USB, and is reset to 0 when it reaches 16'h3FFF.
-        */
-       struct cvmx_usbcx_hfnum_s {
-               uint32_t frrem  : 16;
-               uint32_t frnum  : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hprt
- *
- * Host Port Control and Status Register (HPRT)
- *
- * This register is available in both Host and Device modes.
- * Currently, the OTG Host supports only one port.
- * A single register holds USB port-related information such as USB reset,
- * enable, suspend, resume, connect status, and test mode for each port. The
- * R_SS_WC bits in this register can trigger an interrupt to the application
- * through the Host Port Interrupt bit of the Core Interrupt register
- * (GINTSTS.PrtInt). On a Port Interrupt, the application must read this
- * register and clear the bit that caused the interrupt. For the R_SS_WC bits,
- * the application must write a 1 to the bit to clear the interrupt.
- */
-union cvmx_usbcx_hprt {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hprt_s
-        * @prtspd: Port Speed (PrtSpd)
-        *      Indicates the speed of the device attached to this port.
-        *      * 2'b00: High speed
-        *      * 2'b01: Full speed
-        *      * 2'b10: Low speed
-        *      * 2'b11: Reserved
-        * @prttstctl: Port Test Control (PrtTstCtl)
-        *      The application writes a nonzero value to this field to put
-        *      the port into a Test mode, and the corresponding pattern is
-        *      signaled on the port.
-        *      * 4'b0000: Test mode disabled
-        *      * 4'b0001: Test_J mode
-        *      * 4'b0010: Test_K mode
-        *      * 4'b0011: Test_SE0_NAK mode
-        *      * 4'b0100: Test_Packet mode
-        *      * 4'b0101: Test_Force_Enable
-        *      * Others: Reserved
-        *      PrtSpd must be zero (i.e. the interface must be in high-speed
-        *      mode) to use the PrtTstCtl test modes.
-        * @prtpwr: Port Power (PrtPwr)
-        *      The application uses this field to control power to this port,
-        *      and the core clears this bit on an overcurrent condition.
-        *      * 1'b0: Power off
-        *      * 1'b1: Power on
-        * @prtlnsts: Port Line Status (PrtLnSts)
-        *      Indicates the current logic level USB data lines
-        *      * Bit [10]: Logic level of D-
-        *      * Bit [11]: Logic level of D+
-        * @prtrst: Port Reset (PrtRst)
-        *      When the application sets this bit, a reset sequence is
-        *      started on this port. The application must time the reset
-        *      period and clear this bit after the reset sequence is
-        *      complete.
-        *      * 1'b0: Port not in reset
-        *      * 1'b1: Port in reset
-        *      The application must leave this bit set for at least a
-        *      minimum duration mentioned below to start a reset on the
-        *      port. The application can leave it set for another 10 ms in
-        *      addition to the required minimum duration, before clearing
-        *      the bit, even though there is no maximum limit set by the
-        *      USB standard.
-        *      * High speed: 50 ms
-        *      * Full speed/Low speed: 10 ms
-        * @prtsusp: Port Suspend (PrtSusp)
-        *      The application sets this bit to put this port in Suspend
-        *      mode. The core only stops sending SOFs when this is set.
-        *      To stop the PHY clock, the application must set the Port
-        *      Clock Stop bit, which will assert the suspend input pin of
-        *      the PHY.
-        *      The read value of this bit reflects the current suspend
-        *      status of the port. This bit is cleared by the core after a
-        *      remote wakeup signal is detected or the application sets
-        *      the Port Reset bit or Port Resume bit in this register or the
-        *      Resume/Remote Wakeup Detected Interrupt bit or
-        *      Disconnect Detected Interrupt bit in the Core Interrupt
-        *      register (GINTSTS.WkUpInt or GINTSTS.DisconnInt,
-        *      respectively).
-        *      * 1'b0: Port not in Suspend mode
-        *      * 1'b1: Port in Suspend mode
-        * @prtres: Port Resume (PrtRes)
-        *      The application sets this bit to drive resume signaling on
-        *      the port. The core continues to drive the resume signal
-        *      until the application clears this bit.
-        *      If the core detects a USB remote wakeup sequence, as
-        *      indicated by the Port Resume/Remote Wakeup Detected
-        *      Interrupt bit of the Core Interrupt register
-        *      (GINTSTS.WkUpInt), the core starts driving resume
-        *      signaling without application intervention and clears this bit
-        *      when it detects a disconnect condition. The read value of
-        *      this bit indicates whether the core is currently driving
-        *      resume signaling.
-        *      * 1'b0: No resume driven
-        *      * 1'b1: Resume driven
-        * @prtovrcurrchng: Port Overcurrent Change (PrtOvrCurrChng)
-        *      The core sets this bit when the status of the Port
-        *      Overcurrent Active bit (bit 4) in this register changes.
-        * @prtovrcurract: Port Overcurrent Active (PrtOvrCurrAct)
-        *      Indicates the overcurrent condition of the port.
-        *      * 1'b0: No overcurrent condition
-        *      * 1'b1: Overcurrent condition
-        * @prtenchng: Port Enable/Disable Change (PrtEnChng)
-        *      The core sets this bit when the status of the Port Enable bit
-        *      [2] of this register changes.
-        * @prtena: Port Enable (PrtEna)
-        *      A port is enabled only by the core after a reset sequence,
-        *      and is disabled by an overcurrent condition, a disconnect
-        *      condition, or by the application clearing this bit. The
-        *      application cannot set this bit by a register write. It can only
-        *      clear it to disable the port. This bit does not trigger any
-        *      interrupt to the application.
-        *      * 1'b0: Port disabled
-        *      * 1'b1: Port enabled
-        * @prtconndet: Port Connect Detected (PrtConnDet)
-        *      The core sets this bit when a device connection is detected
-        *      to trigger an interrupt to the application using the Host Port
-        *      Interrupt bit of the Core Interrupt register (GINTSTS.PrtInt).
-        *      The application must write a 1 to this bit to clear the
-        *      interrupt.
-        * @prtconnsts: Port Connect Status (PrtConnSts)
-        *      * 0: No device is attached to the port.
-        *      * 1: A device is attached to the port.
-        */
-       struct cvmx_usbcx_hprt_s {
-               uint32_t reserved_19_31 : 13;
-               uint32_t prtspd         : 2;
-               uint32_t prttstctl      : 4;
-               uint32_t prtpwr         : 1;
-               uint32_t prtlnsts       : 2;
-               uint32_t reserved_9_9   : 1;
-               uint32_t prtrst         : 1;
-               uint32_t prtsusp        : 1;
-               uint32_t prtres         : 1;
-               uint32_t prtovrcurrchng : 1;
-               uint32_t prtovrcurract  : 1;
-               uint32_t prtenchng      : 1;
-               uint32_t prtena         : 1;
-               uint32_t prtconndet     : 1;
-               uint32_t prtconnsts     : 1;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hptxfsiz
- *
- * Host Periodic Transmit FIFO Size Register (HPTXFSIZ)
- *
- * This register holds the size and the memory start address of the Periodic
- * TxFIFO, as shown in Figures 310 and 311.
- */
-union cvmx_usbcx_hptxfsiz {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hptxfsiz_s
-        * @ptxfsize: Host Periodic TxFIFO Depth (PTxFSize)
-        *      This value is in terms of 32-bit words.
-        *      * Minimum value is 16
-        *      * Maximum value is 32768
-        * @ptxfstaddr: Host Periodic TxFIFO Start Address (PTxFStAddr)
-        */
-       struct cvmx_usbcx_hptxfsiz_s {
-               uint32_t ptxfsize       : 16;
-               uint32_t ptxfstaddr     : 16;
-       } s;
-};
-
-/**
- * cvmx_usbc#_hptxsts
- *
- * Host Periodic Transmit FIFO/Queue Status Register (HPTXSTS)
- *
- * This read-only register contains the free space information for the Periodic
- * TxFIFO and the Periodic Transmit Request Queue
- */
-union cvmx_usbcx_hptxsts {
-       uint32_t u32;
-       /**
-        * struct cvmx_usbcx_hptxsts_s
-        * @ptxqtop: Top of the Periodic Transmit Request Queue (PTxQTop)
-        *      This indicates the entry in the Periodic Tx Request Queue that
-        *      is currently being processes by the MAC.
-        *      This register is used for debugging.
-        *      * Bit [31]: Odd/Even (micro)frame
-        *      - 1'b0: send in even (micro)frame
-        *      - 1'b1: send in odd (micro)frame
-        *      * Bits [30:27]: Channel/endpoint number
-        *      * Bits [26:25]: Type
-        *      - 2'b00: IN/OUT
-        *      - 2'b01: Zero-length packet
-        *      - 2'b10: CSPLIT
-        *      - 2'b11: Disable channel command
-        *      * Bit [24]: Terminate (last entry for the selected
-        *      channel/endpoint)
-        * @ptxqspcavail: Periodic Transmit Request Queue Space Available
-        *      (PTxQSpcAvail)
-        *      Indicates the number of free locations available to be written
-        *      in the Periodic Transmit Request Queue. This queue holds both
-        *      IN and OUT requests.
-        *      * 8'h0: Periodic Transmit Request Queue is full
-        *      * 8'h1: 1 location available
-        *      * 8'h2: 2 locations available
-        *      * n: n locations available (0..8)
-        *      * Others: Reserved
-        * @ptxfspcavail: Periodic Transmit Data FIFO Space Available
-        *                (PTxFSpcAvail)
-        *      Indicates the number of free locations available to be written
-        *      to in the Periodic TxFIFO.
-        *      Values are in terms of 32-bit words
-        *      * 16'h0: Periodic TxFIFO is full
-        *      * 16'h1: 1 word available
-        *      * 16'h2: 2 words available
-        *      * 16'hn: n words available (where 0..32768)
-        *      * 16'h8000: 32768 words available
-        *      * Others: Reserved
-        */
-       struct cvmx_usbcx_hptxsts_s {
-               uint32_t ptxqtop        : 8;
-               uint32_t ptxqspcavail   : 8;
-               uint32_t ptxfspcavail   : 16;
-       } s;
-};
-
-#endif
diff --git a/drivers/staging/octeon-usb/cvmx-usbnx-defs.h b/drivers/staging/octeon-usb/cvmx-usbnx-defs.h
deleted file mode 100644 (file)
index e06aafa..0000000
+++ /dev/null
@@ -1,885 +0,0 @@
-/***********************license start***************
- * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). 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 Cavium Networks 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, including technical data, may be subject to U.S. export
- * control laws, including the U.S. Export Administration Act and its associated
- * regulations, and may be subject to export or import  regulations in other
- * countries.
-
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
- * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
- * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
- * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- ***********************license end**************************************/
-
-
-/**
- * cvmx-usbnx-defs.h
- *
- * Configuration and status register (CSR) type definitions for
- * Octeon usbnx.
- *
- */
-#ifndef __CVMX_USBNX_TYPEDEFS_H__
-#define __CVMX_USBNX_TYPEDEFS_H__
-
-#define CVMX_USBNXBID1(bid) (((bid) & 1) * 0x10000000ull)
-#define CVMX_USBNXBID2(bid) (((bid) & 1) * 0x100000000000ull)
-
-#define CVMX_USBNXREG1(reg, bid) \
-       (CVMX_ADD_IO_SEG(0x0001180068000000ull | reg) + CVMX_USBNXBID1(bid))
-#define CVMX_USBNXREG2(reg, bid) \
-       (CVMX_ADD_IO_SEG(0x00016F0000000000ull | reg) + CVMX_USBNXBID2(bid))
-
-#define CVMX_USBNX_CLK_CTL(bid)                CVMX_USBNXREG1(0x10, bid)
-#define CVMX_USBNX_DMA0_INB_CHN0(bid)  CVMX_USBNXREG2(0x818, bid)
-#define CVMX_USBNX_DMA0_OUTB_CHN0(bid) CVMX_USBNXREG2(0x858, bid)
-#define CVMX_USBNX_USBP_CTL_STATUS(bid)        CVMX_USBNXREG1(0x18, bid)
-
-/**
- * cvmx_usbn#_clk_ctl
- *
- * USBN_CLK_CTL = USBN's Clock Control
- *
- * This register is used to control the frequency of the hclk and the
- * hreset and phy_rst signals.
- */
-union cvmx_usbnx_clk_ctl {
-       uint64_t u64;
-       /**
-        * struct cvmx_usbnx_clk_ctl_s
-        * @divide2: The 'hclk' used by the USB subsystem is derived
-        *      from the eclk.
-        *      Also see the field DIVIDE. DIVIDE2<1> must currently
-        *      be zero because it is not implemented, so the maximum
-        *      ratio of eclk/hclk is currently 16.
-        *      The actual divide number for hclk is:
-        *      (DIVIDE2 + 1) * (DIVIDE + 1)
-        * @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
-        *      generate the hclk in the USB Subsystem is held
-        *      in reset. This bit must be set to '0' before
-        *      changing the value os DIVIDE in this register.
-        *      The reset to the HCLK_DIVIDERis also asserted
-        *      when core reset is asserted.
-        * @p_x_on: Force USB-PHY on during suspend.
-        *      '1' USB-PHY XO block is powered-down during
-        *      suspend.
-        *      '0' USB-PHY XO block is powered-up during
-        *      suspend.
-        *      The value of this field must be set while POR is
-        *      active.
-        * @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
-        *      remain powered in Suspend Mode.
-        *      '1' The USB-PHY XO Bias, Bandgap and PLL are
-        *      powered down in suspend mode.
-        *      The value of this field must be set while POR is
-        *      active.
-        * @p_c_sel: Phy clock speed select.
-        *      Selects the reference clock / crystal frequency.
-        *      '11': Reserved
-        *      '10': 48 MHz (reserved when a crystal is used)
-        *      '01': 24 MHz (reserved when a crystal is used)
-        *      '00': 12 MHz
-        *      The value of this field must be set while POR is
-        *      active.
-        *      NOTE: if a crystal is used as a reference clock,
-        *      this field must be set to 12 MHz.
-        * @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
-        * @sd_mode: Scaledown mode for the USBC. Control timing events
-        *      in the USBC, for normal operation this must be '0'.
-        * @s_bist: Starts bist on the hclk memories, during the '0'
-        *      to '1' transition.
-        * @por: Power On Reset for the PHY.
-        *      Resets all the PHYS registers and state machines.
-        * @enable: When '1' allows the generation of the hclk. When
-        *      '0' the hclk will not be generated. SEE DIVIDE
-        *      field of this register.
-        * @prst: When this field is '0' the reset associated with
-        *      the phy_clk functionality in the USB Subsystem is
-        *      help in reset. This bit should not be set to '1'
-        *      until the time it takes 6 clocks (hclk or phy_clk,
-        *      whichever is slower) has passed. Under normal
-        *      operation once this bit is set to '1' it should not
-        *      be set to '0'.
-        * @hrst: When this field is '0' the reset associated with
-        *      the hclk functioanlity in the USB Subsystem is
-        *      held in reset.This bit should not be set to '1'
-        *      until 12ms after phy_clk is stable. Under normal
-        *      operation, once this bit is set to '1' it should
-        *      not be set to '0'.
-        * @divide: The frequency of 'hclk' used by the USB subsystem
-        *      is the eclk frequency divided by the value of
-        *      (DIVIDE2 + 1) * (DIVIDE + 1), also see the field
-        *      DIVIDE2 of this register.
-        *      The hclk frequency should be less than 125Mhz.
-        *      After writing a value to this field the SW should
-        *      read the field for the value written.
-        *      The ENABLE field of this register should not be set
-        *      until AFTER this field is set and then read.
-        */
-       struct cvmx_usbnx_clk_ctl_s {
-               uint64_t reserved_20_63 : 44;
-               uint64_t divide2        : 2;
-               uint64_t hclk_rst       : 1;
-               uint64_t p_x_on         : 1;
-               uint64_t reserved_14_15 : 2;
-               uint64_t p_com_on       : 1;
-               uint64_t p_c_sel        : 2;
-               uint64_t cdiv_byp       : 1;
-               uint64_t sd_mode        : 2;
-               uint64_t s_bist         : 1;
-               uint64_t por            : 1;
-               uint64_t enable         : 1;
-               uint64_t prst           : 1;
-               uint64_t hrst           : 1;
-               uint64_t divide         : 3;
-       } s;
-       /**
-        * struct cvmx_usbnx_clk_ctl_cn30xx
-        * @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
-        *      generate the hclk in the USB Subsystem is held
-        *      in reset. This bit must be set to '0' before
-        *      changing the value os DIVIDE in this register.
-        *      The reset to the HCLK_DIVIDERis also asserted
-        *      when core reset is asserted.
-        * @p_x_on: Force USB-PHY on during suspend.
-        *      '1' USB-PHY XO block is powered-down during
-        *      suspend.
-        *      '0' USB-PHY XO block is powered-up during
-        *      suspend.
-        *      The value of this field must be set while POR is
-        *      active.
-        * @p_rclk: Phy refrence clock enable.
-        *      '1' The PHY PLL uses the XO block output as a
-        *      reference.
-        *      '0' Reserved.
-        * @p_xenbn: Phy external clock enable.
-        *      '1' The XO block uses the clock from a crystal.
-        *      '0' The XO block uses an external clock supplied
-        *      on the XO pin. USB_XI should be tied to
-        *      ground for this usage.
-        * @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
-        *      remain powered in Suspend Mode.
-        *      '1' The USB-PHY XO Bias, Bandgap and PLL are
-        *      powered down in suspend mode.
-        *      The value of this field must be set while POR is
-        *      active.
-        * @p_c_sel: Phy clock speed select.
-        *      Selects the reference clock / crystal frequency.
-        *      '11': Reserved
-        *      '10': 48 MHz
-        *      '01': 24 MHz
-        *      '00': 12 MHz
-        *      The value of this field must be set while POR is
-        *      active.
-        * @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
-        * @sd_mode: Scaledown mode for the USBC. Control timing events
-        *      in the USBC, for normal operation this must be '0'.
-        * @s_bist: Starts bist on the hclk memories, during the '0'
-        *      to '1' transition.
-        * @por: Power On Reset for the PHY.
-        *      Resets all the PHYS registers and state machines.
-        * @enable: When '1' allows the generation of the hclk. When
-        *      '0' the hclk will not be generated.
-        * @prst: When this field is '0' the reset associated with
-        *      the phy_clk functionality in the USB Subsystem is
-        *      help in reset. This bit should not be set to '1'
-        *      until the time it takes 6 clocks (hclk or phy_clk,
-        *      whichever is slower) has passed. Under normal
-        *      operation once this bit is set to '1' it should not
-        *      be set to '0'.
-        * @hrst: When this field is '0' the reset associated with
-        *      the hclk functioanlity in the USB Subsystem is
-        *      held in reset.This bit should not be set to '1'
-        *      until 12ms after phy_clk is stable. Under normal
-        *      operation, once this bit is set to '1' it should
-        *      not be set to '0'.
-        * @divide: The 'hclk' used by the USB subsystem is derived
-        *      from the eclk. The eclk will be divided by the
-        *      value of this field +1 to determine the hclk
-        *      frequency. (Also see HRST of this register).
-        *      The hclk frequency must be less than 125 MHz.
-        */
-       struct cvmx_usbnx_clk_ctl_cn30xx {
-               uint64_t reserved_18_63 : 46;
-               uint64_t hclk_rst       : 1;
-               uint64_t p_x_on         : 1;
-               uint64_t p_rclk         : 1;
-               uint64_t p_xenbn        : 1;
-               uint64_t p_com_on       : 1;
-               uint64_t p_c_sel        : 2;
-               uint64_t cdiv_byp       : 1;
-               uint64_t sd_mode        : 2;
-               uint64_t s_bist         : 1;
-               uint64_t por            : 1;
-               uint64_t enable         : 1;
-               uint64_t prst           : 1;
-               uint64_t hrst           : 1;
-               uint64_t divide         : 3;
-       } cn30xx;
-       struct cvmx_usbnx_clk_ctl_cn30xx cn31xx;
-       /**
-        * struct cvmx_usbnx_clk_ctl_cn50xx
-        * @divide2: The 'hclk' used by the USB subsystem is derived
-        *      from the eclk.
-        *      Also see the field DIVIDE. DIVIDE2<1> must currently
-        *      be zero because it is not implemented, so the maximum
-        *      ratio of eclk/hclk is currently 16.
-        *      The actual divide number for hclk is:
-        *      (DIVIDE2 + 1) * (DIVIDE + 1)
-        * @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
-        *      generate the hclk in the USB Subsystem is held
-        *      in reset. This bit must be set to '0' before
-        *      changing the value os DIVIDE in this register.
-        *      The reset to the HCLK_DIVIDERis also asserted
-        *      when core reset is asserted.
-        * @p_rtype: PHY reference clock type
-        *      '0' The USB-PHY uses a 12MHz crystal as a clock
-        *      source at the USB_XO and USB_XI pins
-        *      '1' Reserved
-        *      '2' The USB_PHY uses 12/24/48MHz 2.5V board clock
-        *      at the USB_XO pin. USB_XI should be tied to
-        *      ground in this case.
-        *      '3' Reserved
-        *      (bit 14 was P_XENBN on 3xxx)
-        *      (bit 15 was P_RCLK on 3xxx)
-        * @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
-        *      remain powered in Suspend Mode.
-        *      '1' The USB-PHY XO Bias, Bandgap and PLL are
-        *      powered down in suspend mode.
-        *      The value of this field must be set while POR is
-        *      active.
-        * @p_c_sel: Phy clock speed select.
-        *      Selects the reference clock / crystal frequency.
-        *      '11': Reserved
-        *      '10': 48 MHz (reserved when a crystal is used)
-        *      '01': 24 MHz (reserved when a crystal is used)
-        *      '00': 12 MHz
-        *      The value of this field must be set while POR is
-        *      active.
-        *      NOTE: if a crystal is used as a reference clock,
-        *      this field must be set to 12 MHz.
-        * @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
-        * @sd_mode: Scaledown mode for the USBC. Control timing events
-        *      in the USBC, for normal operation this must be '0'.
-        * @s_bist: Starts bist on the hclk memories, during the '0'
-        *      to '1' transition.
-        * @por: Power On Reset for the PHY.
-        *      Resets all the PHYS registers and state machines.
-        * @enable: When '1' allows the generation of the hclk. When
-        *      '0' the hclk will not be generated. SEE DIVIDE
-        *      field of this register.
-        * @prst: When this field is '0' the reset associated with
-        *      the phy_clk functionality in the USB Subsystem is
-        *      help in reset. This bit should not be set to '1'
-        *      until the time it takes 6 clocks (hclk or phy_clk,
-        *      whichever is slower) has passed. Under normal
-        *      operation once this bit is set to '1' it should not
-        *      be set to '0'.
-        * @hrst: When this field is '0' the reset associated with
-        *      the hclk functioanlity in the USB Subsystem is
-        *      held in reset.This bit should not be set to '1'
-        *      until 12ms after phy_clk is stable. Under normal
-        *      operation, once this bit is set to '1' it should
-        *      not be set to '0'.
-        * @divide: The frequency of 'hclk' used by the USB subsystem
-        *      is the eclk frequency divided by the value of
-        *      (DIVIDE2 + 1) * (DIVIDE + 1), also see the field
-        *      DIVIDE2 of this register.
-        *      The hclk frequency should be less than 125Mhz.
-        *      After writing a value to this field the SW should
-        *      read the field for the value written.
-        *      The ENABLE field of this register should not be set
-        *      until AFTER this field is set and then read.
-        */
-       struct cvmx_usbnx_clk_ctl_cn50xx {
-               uint64_t reserved_20_63 : 44;
-               uint64_t divide2        : 2;
-               uint64_t hclk_rst       : 1;
-               uint64_t reserved_16_16 : 1;
-               uint64_t p_rtype        : 2;
-               uint64_t p_com_on       : 1;
-               uint64_t p_c_sel        : 2;
-               uint64_t cdiv_byp       : 1;
-               uint64_t sd_mode        : 2;
-               uint64_t s_bist         : 1;
-               uint64_t por            : 1;
-               uint64_t enable         : 1;
-               uint64_t prst           : 1;
-               uint64_t hrst           : 1;
-               uint64_t divide         : 3;
-       } cn50xx;
-       struct cvmx_usbnx_clk_ctl_cn50xx cn52xx;
-       struct cvmx_usbnx_clk_ctl_cn50xx cn56xx;
-};
-
-/**
- * cvmx_usbn#_usbp_ctl_status
- *
- * USBN_USBP_CTL_STATUS = USBP Control And Status Register
- *
- * Contains general control and status information for the USBN block.
- */
-union cvmx_usbnx_usbp_ctl_status {
-       uint64_t u64;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_s
-        * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
-        * @txvreftune: HS DC Voltage Level Adjustment
-        * @txfslstune: FS/LS Source Impedence Adjustment
-        * @txhsxvtune: Transmitter High-Speed Crossover Adjustment
-        * @sqrxtune: Squelch Threshold Adjustment
-        * @compdistune: Disconnect Threshold Adjustment
-        * @otgtune: VBUS Valid Threshold Adjustment
-        * @otgdisable: OTG Block Disable
-        * @portreset: Per_Port Reset
-        * @drvvbus: Drive VBUS
-        * @lsbist: Low-Speed BIST Enable.
-        * @fsbist: Full-Speed BIST Enable.
-        * @hsbist: High-Speed BIST Enable.
-        * @bist_done: PHY Bist Done.
-        *      Asserted at the end of the PHY BIST sequence.
-        * @bist_err: PHY Bist Error.
-        *      Indicates an internal error was detected during
-        *      the BIST sequence.
-        * @tdata_out: PHY Test Data Out.
-        *      Presents either internaly generated signals or
-        *      test register contents, based upon the value of
-        *      test_data_out_sel.
-        * @siddq: Drives the USBP (USB-PHY) SIDDQ input.
-        *      Normally should be set to zero.
-        *      When customers have no intent to use USB PHY
-        *      interface, they should:
-        *      - still provide 3.3V to USB_VDD33, and
-        *      - tie USB_REXT to 3.3V supply, and
-        *      - set USBN*_USBP_CTL_STATUS[SIDDQ]=1
-        * @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
-        * @dma_bmode: When set to 1 the L2C DMA address will be updated
-        *      with byte-counts between packets. When set to 0
-        *      the L2C DMA address is incremented to the next
-        *      4-byte aligned address after adding byte-count.
-        * @usbc_end: Bigendian input to the USB Core. This should be
-        *      set to '0' for operation.
-        * @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
-        * @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
-        * @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D+ line. '1' pull down-resistance is connected
-        *      to D+/ '0' pull down resistance is not connected
-        *      to D+. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D- line. '1' pull down-resistance is connected
-        *      to D-. '0' pull down resistance is not connected
-        *      to D-. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @hst_mode: When '0' the USB is acting as HOST, when '1'
-        *      USB is acting as device. This field needs to be
-        *      set while the USB is in reset.
-        * @tuning: Transmitter Tuning for High-Speed Operation.
-        *      Tunes the current supply and rise/fall output
-        *      times for high-speed operation.
-        *      [20:19] == 11: Current supply increased
-        *      approximately 9%
-        *      [20:19] == 10: Current supply increased
-        *      approximately 4.5%
-        *      [20:19] == 01: Design default.
-        *      [20:19] == 00: Current supply decreased
-        *      approximately 4.5%
-        *      [22:21] == 11: Rise and fall times are increased.
-        *      [22:21] == 10: Design default.
-        *      [22:21] == 01: Rise and fall times are decreased.
-        *      [22:21] == 00: Rise and fall times are decreased
-        *      further as compared to the 01 setting.
-        * @tx_bs_enh: Transmit Bit Stuffing on [15:8].
-        *      Enables or disables bit stuffing on data[15:8]
-        *      when bit-stuffing is enabled.
-        * @tx_bs_en: Transmit Bit Stuffing on [7:0].
-        *      Enables or disables bit stuffing on data[7:0]
-        *      when bit-stuffing is enabled.
-        * @loop_enb: PHY Loopback Test Enable.
-        *      '1': During data transmission the receive is
-        *      enabled.
-        *      '0': During data transmission the receive is
-        *      disabled.
-        *      Must be '0' for normal operation.
-        * @vtest_enb: Analog Test Pin Enable.
-        *      '1' The PHY's analog_test pin is enabled for the
-        *      input and output of applicable analog test signals.
-        *      '0' THe analog_test pin is disabled.
-        * @bist_enb: Built-In Self Test Enable.
-        *      Used to activate BIST in the PHY.
-        * @tdata_sel: Test Data Out Select.
-        *      '1' test_data_out[3:0] (PHY) register contents
-        *      are output. '0' internaly generated signals are
-        *      output.
-        * @taddr_in: Mode Address for Test Interface.
-        *      Specifies the register address for writing to or
-        *      reading from the PHY test interface register.
-        * @tdata_in: Internal Testing Register Input Data and Select
-        *      This is a test bus. Data is present on [3:0],
-        *      and its corresponding select (enable) is present
-        *      on bits [7:4].
-        * @ate_reset: Reset input from automatic test equipment.
-        *      This is a test signal. When the USB Core is
-        *      powered up (not in Susned Mode), an automatic
-        *      tester can use this to disable phy_clock and
-        *      free_clk, then re-eanable them with an aligned
-        *      phase.
-        *      '1': The phy_clk and free_clk outputs are
-        *      disabled. "0": The phy_clock and free_clk outputs
-        *      are available within a specific period after the
-        *      de-assertion.
-        */
-       struct cvmx_usbnx_usbp_ctl_status_s {
-               uint64_t txrisetune             : 1;
-               uint64_t txvreftune             : 4;
-               uint64_t txfslstune             : 4;
-               uint64_t txhsxvtune             : 2;
-               uint64_t sqrxtune               : 3;
-               uint64_t compdistune            : 3;
-               uint64_t otgtune                : 3;
-               uint64_t otgdisable             : 1;
-               uint64_t portreset              : 1;
-               uint64_t drvvbus                : 1;
-               uint64_t lsbist                 : 1;
-               uint64_t fsbist                 : 1;
-               uint64_t hsbist                 : 1;
-               uint64_t bist_done              : 1;
-               uint64_t bist_err               : 1;
-               uint64_t tdata_out              : 4;
-               uint64_t siddq                  : 1;
-               uint64_t txpreemphasistune      : 1;
-               uint64_t dma_bmode              : 1;
-               uint64_t usbc_end               : 1;
-               uint64_t usbp_bist              : 1;
-               uint64_t tclk                   : 1;
-               uint64_t dp_pulld               : 1;
-               uint64_t dm_pulld               : 1;
-               uint64_t hst_mode               : 1;
-               uint64_t tuning                 : 4;
-               uint64_t tx_bs_enh              : 1;
-               uint64_t tx_bs_en               : 1;
-               uint64_t loop_enb               : 1;
-               uint64_t vtest_enb              : 1;
-               uint64_t bist_enb               : 1;
-               uint64_t tdata_sel              : 1;
-               uint64_t taddr_in               : 4;
-               uint64_t tdata_in               : 8;
-               uint64_t ate_reset              : 1;
-       } s;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_cn30xx
-        * @bist_done: PHY Bist Done.
-        *      Asserted at the end of the PHY BIST sequence.
-        * @bist_err: PHY Bist Error.
-        *      Indicates an internal error was detected during
-        *      the BIST sequence.
-        * @tdata_out: PHY Test Data Out.
-        *      Presents either internaly generated signals or
-        *      test register contents, based upon the value of
-        *      test_data_out_sel.
-        * @dma_bmode: When set to 1 the L2C DMA address will be updated
-        *      with byte-counts between packets. When set to 0
-        *      the L2C DMA address is incremented to the next
-        *      4-byte aligned address after adding byte-count.
-        * @usbc_end: Bigendian input to the USB Core. This should be
-        *      set to '0' for operation.
-        * @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
-        * @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
-        * @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D+ line. '1' pull down-resistance is connected
-        *      to D+/ '0' pull down resistance is not connected
-        *      to D+. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D- line. '1' pull down-resistance is connected
-        *      to D-. '0' pull down resistance is not connected
-        *      to D-. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @hst_mode: When '0' the USB is acting as HOST, when '1'
-        *      USB is acting as device. This field needs to be
-        *      set while the USB is in reset.
-        * @tuning: Transmitter Tuning for High-Speed Operation.
-        *      Tunes the current supply and rise/fall output
-        *      times for high-speed operation.
-        *      [20:19] == 11: Current supply increased
-        *      approximately 9%
-        *      [20:19] == 10: Current supply increased
-        *      approximately 4.5%
-        *      [20:19] == 01: Design default.
-        *      [20:19] == 00: Current supply decreased
-        *      approximately 4.5%
-        *      [22:21] == 11: Rise and fall times are increased.
-        *      [22:21] == 10: Design default.
-        *      [22:21] == 01: Rise and fall times are decreased.
-        *      [22:21] == 00: Rise and fall times are decreased
-        *      further as compared to the 01 setting.
-        * @tx_bs_enh: Transmit Bit Stuffing on [15:8].
-        *      Enables or disables bit stuffing on data[15:8]
-        *      when bit-stuffing is enabled.
-        * @tx_bs_en: Transmit Bit Stuffing on [7:0].
-        *      Enables or disables bit stuffing on data[7:0]
-        *      when bit-stuffing is enabled.
-        * @loop_enb: PHY Loopback Test Enable.
-        *      '1': During data transmission the receive is
-        *      enabled.
-        *      '0': During data transmission the receive is
-        *      disabled.
-        *      Must be '0' for normal operation.
-        * @vtest_enb: Analog Test Pin Enable.
-        *      '1' The PHY's analog_test pin is enabled for the
-        *      input and output of applicable analog test signals.
-        *      '0' THe analog_test pin is disabled.
-        * @bist_enb: Built-In Self Test Enable.
-        *      Used to activate BIST in the PHY.
-        * @tdata_sel: Test Data Out Select.
-        *      '1' test_data_out[3:0] (PHY) register contents
-        *      are output. '0' internaly generated signals are
-        *      output.
-        * @taddr_in: Mode Address for Test Interface.
-        *      Specifies the register address for writing to or
-        *      reading from the PHY test interface register.
-        * @tdata_in: Internal Testing Register Input Data and Select
-        *      This is a test bus. Data is present on [3:0],
-        *      and its corresponding select (enable) is present
-        *      on bits [7:4].
-        * @ate_reset: Reset input from automatic test equipment.
-        *      This is a test signal. When the USB Core is
-        *      powered up (not in Susned Mode), an automatic
-        *      tester can use this to disable phy_clock and
-        *      free_clk, then re-eanable them with an aligned
-        *      phase.
-        *      '1': The phy_clk and free_clk outputs are
-        *      disabled. "0": The phy_clock and free_clk outputs
-        *      are available within a specific period after the
-        *      de-assertion.
-        */
-       struct cvmx_usbnx_usbp_ctl_status_cn30xx {
-               uint64_t reserved_38_63 : 26;
-               uint64_t bist_done      : 1;
-               uint64_t bist_err       : 1;
-               uint64_t tdata_out      : 4;
-               uint64_t reserved_30_31 : 2;
-               uint64_t dma_bmode      : 1;
-               uint64_t usbc_end       : 1;
-               uint64_t usbp_bist      : 1;
-               uint64_t tclk           : 1;
-               uint64_t dp_pulld       : 1;
-               uint64_t dm_pulld       : 1;
-               uint64_t hst_mode       : 1;
-               uint64_t tuning         : 4;
-               uint64_t tx_bs_enh      : 1;
-               uint64_t tx_bs_en       : 1;
-               uint64_t loop_enb       : 1;
-               uint64_t vtest_enb      : 1;
-               uint64_t bist_enb       : 1;
-               uint64_t tdata_sel      : 1;
-               uint64_t taddr_in       : 4;
-               uint64_t tdata_in       : 8;
-               uint64_t ate_reset      : 1;
-       } cn30xx;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_cn50xx
-        * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
-        * @txvreftune: HS DC Voltage Level Adjustment
-        * @txfslstune: FS/LS Source Impedence Adjustment
-        * @txhsxvtune: Transmitter High-Speed Crossover Adjustment
-        * @sqrxtune: Squelch Threshold Adjustment
-        * @compdistune: Disconnect Threshold Adjustment
-        * @otgtune: VBUS Valid Threshold Adjustment
-        * @otgdisable: OTG Block Disable
-        * @portreset: Per_Port Reset
-        * @drvvbus: Drive VBUS
-        * @lsbist: Low-Speed BIST Enable.
-        * @fsbist: Full-Speed BIST Enable.
-        * @hsbist: High-Speed BIST Enable.
-        * @bist_done: PHY Bist Done.
-        *      Asserted at the end of the PHY BIST sequence.
-        * @bist_err: PHY Bist Error.
-        *      Indicates an internal error was detected during
-        *      the BIST sequence.
-        * @tdata_out: PHY Test Data Out.
-        *      Presents either internaly generated signals or
-        *      test register contents, based upon the value of
-        *      test_data_out_sel.
-        * @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
-        * @dma_bmode: When set to 1 the L2C DMA address will be updated
-        *      with byte-counts between packets. When set to 0
-        *      the L2C DMA address is incremented to the next
-        *      4-byte aligned address after adding byte-count.
-        * @usbc_end: Bigendian input to the USB Core. This should be
-        *      set to '0' for operation.
-        * @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
-        * @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
-        * @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D+ line. '1' pull down-resistance is connected
-        *      to D+/ '0' pull down resistance is not connected
-        *      to D+. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D- line. '1' pull down-resistance is connected
-        *      to D-. '0' pull down resistance is not connected
-        *      to D-. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @hst_mode: When '0' the USB is acting as HOST, when '1'
-        *      USB is acting as device. This field needs to be
-        *      set while the USB is in reset.
-        * @tx_bs_enh: Transmit Bit Stuffing on [15:8].
-        *      Enables or disables bit stuffing on data[15:8]
-        *      when bit-stuffing is enabled.
-        * @tx_bs_en: Transmit Bit Stuffing on [7:0].
-        *      Enables or disables bit stuffing on data[7:0]
-        *      when bit-stuffing is enabled.
-        * @loop_enb: PHY Loopback Test Enable.
-        *      '1': During data transmission the receive is
-        *      enabled.
-        *      '0': During data transmission the receive is
-        *      disabled.
-        *      Must be '0' for normal operation.
-        * @vtest_enb: Analog Test Pin Enable.
-        *      '1' The PHY's analog_test pin is enabled for the
-        *      input and output of applicable analog test signals.
-        *      '0' THe analog_test pin is disabled.
-        * @bist_enb: Built-In Self Test Enable.
-        *      Used to activate BIST in the PHY.
-        * @tdata_sel: Test Data Out Select.
-        *      '1' test_data_out[3:0] (PHY) register contents
-        *      are output. '0' internaly generated signals are
-        *      output.
-        * @taddr_in: Mode Address for Test Interface.
-        *      Specifies the register address for writing to or
-        *      reading from the PHY test interface register.
-        * @tdata_in: Internal Testing Register Input Data and Select
-        *      This is a test bus. Data is present on [3:0],
-        *      and its corresponding select (enable) is present
-        *      on bits [7:4].
-        * @ate_reset: Reset input from automatic test equipment.
-        *      This is a test signal. When the USB Core is
-        *      powered up (not in Susned Mode), an automatic
-        *      tester can use this to disable phy_clock and
-        *      free_clk, then re-eanable them with an aligned
-        *      phase.
-        *      '1': The phy_clk and free_clk outputs are
-        *      disabled. "0": The phy_clock and free_clk outputs
-        *      are available within a specific period after the
-        *      de-assertion.
-        */
-       struct cvmx_usbnx_usbp_ctl_status_cn50xx {
-               uint64_t txrisetune             : 1;
-               uint64_t txvreftune             : 4;
-               uint64_t txfslstune             : 4;
-               uint64_t txhsxvtune             : 2;
-               uint64_t sqrxtune               : 3;
-               uint64_t compdistune            : 3;
-               uint64_t otgtune                : 3;
-               uint64_t otgdisable             : 1;
-               uint64_t portreset              : 1;
-               uint64_t drvvbus                : 1;
-               uint64_t lsbist                 : 1;
-               uint64_t fsbist                 : 1;
-               uint64_t hsbist                 : 1;
-               uint64_t bist_done              : 1;
-               uint64_t bist_err               : 1;
-               uint64_t tdata_out              : 4;
-               uint64_t reserved_31_31         : 1;
-               uint64_t txpreemphasistune      : 1;
-               uint64_t dma_bmode              : 1;
-               uint64_t usbc_end               : 1;
-               uint64_t usbp_bist              : 1;
-               uint64_t tclk                   : 1;
-               uint64_t dp_pulld               : 1;
-               uint64_t dm_pulld               : 1;
-               uint64_t hst_mode               : 1;
-               uint64_t reserved_19_22         : 4;
-               uint64_t tx_bs_enh              : 1;
-               uint64_t tx_bs_en               : 1;
-               uint64_t loop_enb               : 1;
-               uint64_t vtest_enb              : 1;
-               uint64_t bist_enb               : 1;
-               uint64_t tdata_sel              : 1;
-               uint64_t taddr_in               : 4;
-               uint64_t tdata_in               : 8;
-               uint64_t ate_reset              : 1;
-       } cn50xx;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_cn52xx
-        * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
-        * @txvreftune: HS DC Voltage Level Adjustment
-        * @txfslstune: FS/LS Source Impedence Adjustment
-        * @txhsxvtune: Transmitter High-Speed Crossover Adjustment
-        * @sqrxtune: Squelch Threshold Adjustment
-        * @compdistune: Disconnect Threshold Adjustment
-        * @otgtune: VBUS Valid Threshold Adjustment
-        * @otgdisable: OTG Block Disable
-        * @portreset: Per_Port Reset
-        * @drvvbus: Drive VBUS
-        * @lsbist: Low-Speed BIST Enable.
-        * @fsbist: Full-Speed BIST Enable.
-        * @hsbist: High-Speed BIST Enable.
-        * @bist_done: PHY Bist Done.
-        *      Asserted at the end of the PHY BIST sequence.
-        * @bist_err: PHY Bist Error.
-        *      Indicates an internal error was detected during
-        *      the BIST sequence.
-        * @tdata_out: PHY Test Data Out.
-        *      Presents either internaly generated signals or
-        *      test register contents, based upon the value of
-        *      test_data_out_sel.
-        * @siddq: Drives the USBP (USB-PHY) SIDDQ input.
-        *      Normally should be set to zero.
-        *      When customers have no intent to use USB PHY
-        *      interface, they should:
-        *      - still provide 3.3V to USB_VDD33, and
-        *      - tie USB_REXT to 3.3V supply, and
-        *      - set USBN*_USBP_CTL_STATUS[SIDDQ]=1
-        * @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
-        * @dma_bmode: When set to 1 the L2C DMA address will be updated
-        *      with byte-counts between packets. When set to 0
-        *      the L2C DMA address is incremented to the next
-        *      4-byte aligned address after adding byte-count.
-        * @usbc_end: Bigendian input to the USB Core. This should be
-        *      set to '0' for operation.
-        * @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
-        * @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
-        * @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D+ line. '1' pull down-resistance is connected
-        *      to D+/ '0' pull down resistance is not connected
-        *      to D+. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
-        *      This signal enables the pull-down resistance on
-        *      the D- line. '1' pull down-resistance is connected
-        *      to D-. '0' pull down resistance is not connected
-        *      to D-. When an A/B device is acting as a host
-        *      (downstream-facing port), dp_pulldown and
-        *      dm_pulldown are enabled. This must not toggle
-        *      during normal opeartion.
-        * @hst_mode: When '0' the USB is acting as HOST, when '1'
-        *      USB is acting as device. This field needs to be
-        *      set while the USB is in reset.
-        * @tx_bs_enh: Transmit Bit Stuffing on [15:8].
-        *      Enables or disables bit stuffing on data[15:8]
-        *      when bit-stuffing is enabled.
-        * @tx_bs_en: Transmit Bit Stuffing on [7:0].
-        *      Enables or disables bit stuffing on data[7:0]
-        *      when bit-stuffing is enabled.
-        * @loop_enb: PHY Loopback Test Enable.
-        *      '1': During data transmission the receive is
-        *      enabled.
-        *      '0': During data transmission the receive is
-        *      disabled.
-        *      Must be '0' for normal operation.
-        * @vtest_enb: Analog Test Pin Enable.
-        *      '1' The PHY's analog_test pin is enabled for the
-        *      input and output of applicable analog test signals.
-        *      '0' THe analog_test pin is disabled.
-        * @bist_enb: Built-In Self Test Enable.
-        *      Used to activate BIST in the PHY.
-        * @tdata_sel: Test Data Out Select.
-        *      '1' test_data_out[3:0] (PHY) register contents
-        *      are output. '0' internaly generated signals are
-        *      output.
-        * @taddr_in: Mode Address for Test Interface.
-        *      Specifies the register address for writing to or
-        *      reading from the PHY test interface register.
-        * @tdata_in: Internal Testing Register Input Data and Select
-        *      This is a test bus. Data is present on [3:0],
-        *      and its corresponding select (enable) is present
-        *      on bits [7:4].
-        * @ate_reset: Reset input from automatic test equipment.
-        *      This is a test signal. When the USB Core is
-        *      powered up (not in Susned Mode), an automatic
-        *      tester can use this to disable phy_clock and
-        *      free_clk, then re-eanable them with an aligned
-        *      phase.
-        *      '1': The phy_clk and free_clk outputs are
-        *      disabled. "0": The phy_clock and free_clk outputs
-        *      are available within a specific period after the
-        *      de-assertion.
-        */
-       struct cvmx_usbnx_usbp_ctl_status_cn52xx {
-               uint64_t txrisetune             : 1;
-               uint64_t txvreftune             : 4;
-               uint64_t txfslstune             : 4;
-               uint64_t txhsxvtune             : 2;
-               uint64_t sqrxtune               : 3;
-               uint64_t compdistune            : 3;
-               uint64_t otgtune                : 3;
-               uint64_t otgdisable             : 1;
-               uint64_t portreset              : 1;
-               uint64_t drvvbus                : 1;
-               uint64_t lsbist                 : 1;
-               uint64_t fsbist                 : 1;
-               uint64_t hsbist                 : 1;
-               uint64_t bist_done              : 1;
-               uint64_t bist_err               : 1;
-               uint64_t tdata_out              : 4;
-               uint64_t siddq                  : 1;
-               uint64_t txpreemphasistune      : 1;
-               uint64_t dma_bmode              : 1;
-               uint64_t usbc_end               : 1;
-               uint64_t usbp_bist              : 1;
-               uint64_t tclk                   : 1;
-               uint64_t dp_pulld               : 1;
-               uint64_t dm_pulld               : 1;
-               uint64_t hst_mode               : 1;
-               uint64_t reserved_19_22         : 4;
-               uint64_t tx_bs_enh              : 1;
-               uint64_t tx_bs_en               : 1;
-               uint64_t loop_enb               : 1;
-               uint64_t vtest_enb              : 1;
-               uint64_t bist_enb               : 1;
-               uint64_t tdata_sel              : 1;
-               uint64_t taddr_in               : 4;
-               uint64_t tdata_in               : 8;
-               uint64_t ate_reset              : 1;
-       } cn52xx;
-};
-
-#endif
index 5dbbd14ec615aba59d16c72a2e7acbe08f9073cf..d118952c0a74c9ff7d59597ccf76e5a16a4bd60d 100644 (file)
@@ -4,6 +4,44 @@
  * for more details.
  *
  * Copyright (C) 2008 Cavium Networks
+ *
+ * Some parts of the code were originally released under BSD license:
+ *
+ * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). 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 Cavium Networks 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, including technical data, may be subject to U.S. export
+ * control laws, including the U.S. Export Administration Act and its associated
+ * regulations, and may be subject to export or import regulations in other
+ * countries.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
+ * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
+ * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
+ * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
+ * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
+ * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
+ * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 
 #include <asm/octeon/cvmx.h>
-#include "cvmx-usb.h"
 #include <asm/octeon/cvmx-iob-defs.h>
 
 #include <linux/usb/hcd.h>
 
 #include <linux/err.h>
 
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-sysinfo.h>
+#include <asm/octeon/cvmx-helper-board.h>
+
+#include "octeon-hcd.h"
+
+/**
+ * enum cvmx_usb_speed - the possible USB device speeds
+ *
+ * @CVMX_USB_SPEED_HIGH: Device is operation at 480Mbps
+ * @CVMX_USB_SPEED_FULL: Device is operation at 12Mbps
+ * @CVMX_USB_SPEED_LOW:  Device is operation at 1.5Mbps
+ */
+enum cvmx_usb_speed {
+       CVMX_USB_SPEED_HIGH = 0,
+       CVMX_USB_SPEED_FULL = 1,
+       CVMX_USB_SPEED_LOW = 2,
+};
+
+/**
+ * enum cvmx_usb_transfer - the possible USB transfer types
+ *
+ * @CVMX_USB_TRANSFER_CONTROL:    USB transfer type control for hub and status
+ *                                transfers
+ * @CVMX_USB_TRANSFER_ISOCHRONOUS: USB transfer type isochronous for low
+ *                                priority periodic transfers
+ * @CVMX_USB_TRANSFER_BULK:       USB transfer type bulk for large low priority
+ *                                transfers
+ * @CVMX_USB_TRANSFER_INTERRUPT:   USB transfer type interrupt for high priority
+ *                                periodic transfers
+ */
+enum cvmx_usb_transfer {
+       CVMX_USB_TRANSFER_CONTROL = 0,
+       CVMX_USB_TRANSFER_ISOCHRONOUS = 1,
+       CVMX_USB_TRANSFER_BULK = 2,
+       CVMX_USB_TRANSFER_INTERRUPT = 3,
+};
+
+/**
+ * enum cvmx_usb_direction - the transfer directions
+ *
+ * @CVMX_USB_DIRECTION_OUT: Data is transferring from Octeon to the device/host
+ * @CVMX_USB_DIRECTION_IN:  Data is transferring from the device/host to Octeon
+ */
+enum cvmx_usb_direction {
+       CVMX_USB_DIRECTION_OUT,
+       CVMX_USB_DIRECTION_IN,
+};
+
+/**
+ * enum cvmx_usb_complete - possible callback function status codes
+ *
+ * @CVMX_USB_COMPLETE_SUCCESS:   The transaction / operation finished without
+ *                               any errors
+ * @CVMX_USB_COMPLETE_SHORT:     FIXME: This is currently not implemented
+ * @CVMX_USB_COMPLETE_CANCEL:    The transaction was canceled while in flight
+ *                               by a user call to cvmx_usb_cancel
+ * @CVMX_USB_COMPLETE_ERROR:     The transaction aborted with an unexpected
+ *                               error status
+ * @CVMX_USB_COMPLETE_STALL:     The transaction received a USB STALL response
+ *                               from the device
+ * @CVMX_USB_COMPLETE_XACTERR:   The transaction failed with an error from the
+ *                               device even after a number of retries
+ * @CVMX_USB_COMPLETE_DATATGLERR: The transaction failed with a data toggle
+ *                               error even after a number of retries
+ * @CVMX_USB_COMPLETE_BABBLEERR:  The transaction failed with a babble error
+ * @CVMX_USB_COMPLETE_FRAMEERR:          The transaction failed with a frame error
+ *                               even after a number of retries
+ */
+enum cvmx_usb_complete {
+       CVMX_USB_COMPLETE_SUCCESS,
+       CVMX_USB_COMPLETE_SHORT,
+       CVMX_USB_COMPLETE_CANCEL,
+       CVMX_USB_COMPLETE_ERROR,
+       CVMX_USB_COMPLETE_STALL,
+       CVMX_USB_COMPLETE_XACTERR,
+       CVMX_USB_COMPLETE_DATATGLERR,
+       CVMX_USB_COMPLETE_BABBLEERR,
+       CVMX_USB_COMPLETE_FRAMEERR,
+};
+
+/**
+ * struct cvmx_usb_port_status - the USB port status information
+ *
+ * @port_enabled:      1 = Usb port is enabled, 0 = disabled
+ * @port_over_current: 1 = Over current detected, 0 = Over current not
+ *                     detected. Octeon doesn't support over current detection.
+ * @port_powered:      1 = Port power is being supplied to the device, 0 =
+ *                     power is off. Octeon doesn't support turning port power
+ *                     off.
+ * @port_speed:                Current port speed.
+ * @connected:         1 = A device is connected to the port, 0 = No device is
+ *                     connected.
+ * @connect_change:    1 = Device connected state changed since the last set
+ *                     status call.
+ */
+struct cvmx_usb_port_status {
+       uint32_t reserved               : 25;
+       uint32_t port_enabled           : 1;
+       uint32_t port_over_current      : 1;
+       uint32_t port_powered           : 1;
+       enum cvmx_usb_speed port_speed  : 2;
+       uint32_t connected              : 1;
+       uint32_t connect_change         : 1;
+};
+
+/**
+ * union cvmx_usb_control_header - the structure of a Control packet header
+ *
+ * @s.request_type:    Bit 7 tells the direction: 1=IN, 0=OUT
+ * @s.request          The standard usb request to make
+ * @s.value            Value parameter for the request in little endian format
+ * @s.index            Index for the request in little endian format
+ * @s.length           Length of the data associated with this request in
+ *                     little endian format
+ */
+union cvmx_usb_control_header {
+       uint64_t u64;
+       struct {
+               uint64_t request_type   : 8;
+               uint64_t request        : 8;
+               uint64_t value          : 16;
+               uint64_t index          : 16;
+               uint64_t length         : 16;
+       } s;
+};
+
+/**
+ * struct cvmx_usb_iso_packet - descriptor for Isochronous packets
+ *
+ * @offset:    This is the offset in bytes into the main buffer where this data
+ *             is stored.
+ * @length:    This is the length in bytes of the data.
+ * @status:    This is the status of this individual packet transfer.
+ */
+struct cvmx_usb_iso_packet {
+       int offset;
+       int length;
+       enum cvmx_usb_complete status;
+};
+
+/**
+ * enum cvmx_usb_initialize_flags - flags used by the initialization function
+ *
+ * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI:    The USB port uses a 12MHz crystal
+ *                                           as clock source at USB_XO and
+ *                                           USB_XI.
+ * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND:   The USB port uses 12/24/48MHz 2.5V
+ *                                           board clock source at USB_XO.
+ *                                           USB_XI should be tied to GND.
+ * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK: Mask for clock speed field
+ * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:    Speed of reference clock or
+ *                                           crystal
+ * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:    Speed of reference clock
+ * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:    Speed of reference clock
+ * @CVMX_USB_INITIALIZE_FLAGS_NO_DMA:        Disable DMA and used polled IO for
+ *                                           data transfer use for the USB
+ */
+enum cvmx_usb_initialize_flags {
+       CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI           = 1 << 0,
+       CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND          = 1 << 1,
+       CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK        = 3 << 3,
+       CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ           = 1 << 3,
+       CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ           = 2 << 3,
+       CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ           = 3 << 3,
+       /* Bits 3-4 used to encode the clock frequency */
+       CVMX_USB_INITIALIZE_FLAGS_NO_DMA                = 1 << 5,
+};
+
+/**
+ * enum cvmx_usb_pipe_flags - internal flags for a pipe.
+ *
+ * @__CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
+ *                                  actively using hardware. Do not use.
+ * @__CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high
+ *                                  speed pipe is in the ping state. Do not
+ *                                  use.
+ */
+enum cvmx_usb_pipe_flags {
+       __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
+       __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
+};
+
+/* Normal prefetch that use the pref instruction. */
+#define CVMX_PREFETCH(address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (0))
+
+/* Maximum number of times to retry failed transactions */
+#define MAX_RETRIES            3
+
+/* Maximum number of hardware channels supported by the USB block */
+#define MAX_CHANNELS           8
+
+/* The highest valid USB device address */
+#define MAX_USB_ADDRESS                127
+
+/* The highest valid USB endpoint number */
+#define MAX_USB_ENDPOINT       15
+
+/* The highest valid port number on a hub */
+#define MAX_USB_HUB_PORT       15
+
+/*
+ * The low level hardware can transfer a maximum of this number of bytes in each
+ * transfer. The field is 19 bits wide
+ */
+#define MAX_TRANSFER_BYTES     ((1<<19)-1)
+
+/*
+ * The low level hardware can transfer a maximum of this number of packets in
+ * each transfer. The field is 10 bits wide
+ */
+#define MAX_TRANSFER_PACKETS   ((1<<10)-1)
+
+enum {
+       USB_CLOCK_TYPE_REF_12,
+       USB_CLOCK_TYPE_REF_24,
+       USB_CLOCK_TYPE_REF_48,
+       USB_CLOCK_TYPE_CRYSTAL_12,
+};
+
+/**
+ * Logical transactions may take numerous low level
+ * transactions, especially when splits are concerned. This
+ * enum represents all of the possible stages a transaction can
+ * be in. Note that split completes are always even. This is so
+ * the NAK handler can backup to the previous low level
+ * transaction with a simple clearing of bit 0.
+ */
+enum cvmx_usb_stage {
+       CVMX_USB_STAGE_NON_CONTROL,
+       CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE,
+       CVMX_USB_STAGE_SETUP,
+       CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE,
+       CVMX_USB_STAGE_DATA,
+       CVMX_USB_STAGE_DATA_SPLIT_COMPLETE,
+       CVMX_USB_STAGE_STATUS,
+       CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE,
+};
+
+/**
+ * struct cvmx_usb_transaction - describes each pending USB transaction
+ *                              regardless of type. These are linked together
+ *                              to form a list of pending requests for a pipe.
+ *
+ * @node:              List node for transactions in the pipe.
+ * @type:              Type of transaction, duplicated of the pipe.
+ * @flags:             State flags for this transaction.
+ * @buffer:            User's physical buffer address to read/write.
+ * @buffer_length:     Size of the user's buffer in bytes.
+ * @control_header:    For control transactions, physical address of the 8
+ *                     byte standard header.
+ * @iso_start_frame:   For ISO transactions, the starting frame number.
+ * @iso_number_packets:        For ISO transactions, the number of packets in the
+ *                     request.
+ * @iso_packets:       For ISO transactions, the sub packets in the request.
+ * @actual_bytes:      Actual bytes transfer for this transaction.
+ * @stage:             For control transactions, the current stage.
+ * @urb:               URB.
+ */
+struct cvmx_usb_transaction {
+       struct list_head node;
+       enum cvmx_usb_transfer type;
+       uint64_t buffer;
+       int buffer_length;
+       uint64_t control_header;
+       int iso_start_frame;
+       int iso_number_packets;
+       struct cvmx_usb_iso_packet *iso_packets;
+       int xfersize;
+       int pktcnt;
+       int retries;
+       int actual_bytes;
+       enum cvmx_usb_stage stage;
+       struct urb *urb;
+};
+
+/**
+ * struct cvmx_usb_pipe - a pipe represents a virtual connection between Octeon
+ *                       and some USB device. It contains a list of pending
+ *                       request to the device.
+ *
+ * @node:              List node for pipe list
+ * @next:              Pipe after this one in the list
+ * @transactions:      List of pending transactions
+ * @interval:          For periodic pipes, the interval between packets in
+ *                     frames
+ * @next_tx_frame:     The next frame this pipe is allowed to transmit on
+ * @flags:             State flags for this pipe
+ * @device_speed:      Speed of device connected to this pipe
+ * @transfer_type:     Type of transaction supported by this pipe
+ * @transfer_dir:      IN or OUT. Ignored for Control
+ * @multi_count:       Max packet in a row for the device
+ * @max_packet:                The device's maximum packet size in bytes
+ * @device_addr:       USB device address at other end of pipe
+ * @endpoint_num:      USB endpoint number at other end of pipe
+ * @hub_device_addr:   Hub address this device is connected to
+ * @hub_port:          Hub port this device is connected to
+ * @pid_toggle:                This toggles between 0/1 on every packet send to track
+ *                     the data pid needed
+ * @channel:           Hardware DMA channel for this pipe
+ * @split_sc_frame:    The low order bits of the frame number the split
+ *                     complete should be sent on
+ */
+struct cvmx_usb_pipe {
+       struct list_head node;
+       struct list_head transactions;
+       uint64_t interval;
+       uint64_t next_tx_frame;
+       enum cvmx_usb_pipe_flags flags;
+       enum cvmx_usb_speed device_speed;
+       enum cvmx_usb_transfer transfer_type;
+       enum cvmx_usb_direction transfer_dir;
+       int multi_count;
+       uint16_t max_packet;
+       uint8_t device_addr;
+       uint8_t endpoint_num;
+       uint8_t hub_device_addr;
+       uint8_t hub_port;
+       uint8_t pid_toggle;
+       uint8_t channel;
+       int8_t split_sc_frame;
+};
+
+struct cvmx_usb_tx_fifo {
+       struct {
+               int channel;
+               int size;
+               uint64_t address;
+       } entry[MAX_CHANNELS+1];
+       int head;
+       int tail;
+};
+
+/**
+ * struct cvmx_usb_state - the state of the USB block
+ *
+ * init_flags:            Flags passed to initialize.
+ * index:                 Which USB block this is for.
+ * idle_hardware_channels: Bit set for every idle hardware channel.
+ * usbcx_hprt:            Stored port status so we don't need to read a CSR to
+ *                        determine splits.
+ * pipe_for_channel:      Map channels to pipes.
+ * pipe:                  Storage for pipes.
+ * indent:                Used by debug output to indent functions.
+ * port_status:                   Last port status used for change notification.
+ * idle_pipes:            List of open pipes that have no transactions.
+ * active_pipes:          Active pipes indexed by transfer type.
+ * frame_number:          Increments every SOF interrupt for time keeping.
+ * active_split:          Points to the current active split, or NULL.
+ */
+struct cvmx_usb_state {
+       int init_flags;
+       int index;
+       int idle_hardware_channels;
+       union cvmx_usbcx_hprt usbcx_hprt;
+       struct cvmx_usb_pipe *pipe_for_channel[MAX_CHANNELS];
+       int indent;
+       struct cvmx_usb_port_status port_status;
+       struct list_head idle_pipes;
+       struct list_head active_pipes[4];
+       uint64_t frame_number;
+       struct cvmx_usb_transaction *active_split;
+       struct cvmx_usb_tx_fifo periodic;
+       struct cvmx_usb_tx_fifo nonperiodic;
+};
+
 struct octeon_hcd {
        spinlock_t lock;
        struct cvmx_usb_state usb;
@@ -31,173 +435,2569 @@ struct octeon_hcd {
        struct list_head dequeue_list;
 };
 
-/* convert between an HCD pointer and the corresponding struct octeon_hcd */
-static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
+/* This macro spins on a field waiting for it to reach a value */
+#define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
+       ({int result;                                                       \
+       do {                                                                \
+               uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
+                       octeon_get_clock_rate() / 1000000;                  \
+               type c;                                                     \
+               while (1) {                                                 \
+                       c.u32 = __cvmx_usb_read_csr32(usb, address);        \
+                       if (c.s.field op (value)) {                         \
+                               result = 0;                                 \
+                               break;                                      \
+                       } else if (cvmx_get_cycle() > done) {               \
+                               result = -1;                                \
+                               break;                                      \
+                       } else                                              \
+                               cvmx_wait(100);                             \
+               }                                                           \
+       } while (0);                                                        \
+       result; })
+
+/*
+ * This macro logically sets a single field in a CSR. It does the sequence
+ * read, modify, and write
+ */
+#define USB_SET_FIELD32(address, type, field, value)           \
+       do {                                                    \
+               type c;                                         \
+               c.u32 = __cvmx_usb_read_csr32(usb, address);    \
+               c.s.field = value;                              \
+               __cvmx_usb_write_csr32(usb, address, c.u32);    \
+       } while (0)
+
+/* Returns the IO address to push/pop stuff data from the FIFOs */
+#define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
+
+static int octeon_usb_get_clock_type(void)
 {
-       return (struct octeon_hcd *)(hcd->hcd_priv);
+       switch (cvmx_sysinfo_get()->board_type) {
+       case CVMX_BOARD_TYPE_BBGW_REF:
+       case CVMX_BOARD_TYPE_LANAI2_A:
+       case CVMX_BOARD_TYPE_LANAI2_U:
+       case CVMX_BOARD_TYPE_LANAI2_G:
+       case CVMX_BOARD_TYPE_UBNT_E100:
+               return USB_CLOCK_TYPE_CRYSTAL_12;
+       }
+       return USB_CLOCK_TYPE_REF_48;
 }
 
-static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
+/**
+ * Read a USB 32bit CSR. It performs the necessary address swizzle
+ * for 32bit CSRs and logs the value in a readable format if
+ * debugging is on.
+ *
+ * @usb:     USB block this access is for
+ * @address: 64bit address to read
+ *
+ * Returns: Result of the read
+ */
+static inline uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_state *usb,
+                                            uint64_t address)
 {
-       return container_of((void *)p, struct usb_hcd, hcd_priv);
+       uint32_t result = cvmx_read64_uint32(address ^ 4);
+       return result;
 }
 
-static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p)
+
+/**
+ * Write a USB 32bit CSR. It performs the necessary address
+ * swizzle for 32bit CSRs and logs the value in a readable format
+ * if debugging is on.
+ *
+ * @usb:     USB block this access is for
+ * @address: 64bit address to write
+ * @value:   Value to write
+ */
+static inline void __cvmx_usb_write_csr32(struct cvmx_usb_state *usb,
+                                         uint64_t address, uint32_t value)
 {
-       return container_of(p, struct octeon_hcd, usb);
+       cvmx_write64_uint32(address ^ 4, value);
+       cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
 }
 
-static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
-{
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_poll(&priv->usb);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return IRQ_HANDLED;
+/**
+ * Read a USB 64bit CSR. It logs the value in a readable format if
+ * debugging is on.
+ *
+ * @usb:     USB block this access is for
+ * @address: 64bit address to read
+ *
+ * Returns: Result of the read
+ */
+static inline uint64_t __cvmx_usb_read_csr64(struct cvmx_usb_state *usb,
+                                            uint64_t address)
+{
+       uint64_t result = cvmx_read64_uint64(address);
+       return result;
 }
 
-static void octeon_usb_port_callback(struct cvmx_usb_state *usb,
-                                    enum cvmx_usb_callback reason,
-                                    enum cvmx_usb_complete status,
-                                    int pipe_handle,
-                                    int submit_handle,
-                                    int bytes_transferred,
-                                    void *user_data)
-{
-       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
 
-       spin_unlock(&priv->lock);
-       usb_hcd_poll_rh_status(octeon_to_hcd(priv));
-       spin_lock(&priv->lock);
+/**
+ * Write a USB 64bit CSR. It logs the value in a readable format
+ * if debugging is on.
+ *
+ * @usb:     USB block this access is for
+ * @address: 64bit address to write
+ * @value:   Value to write
+ */
+static inline void __cvmx_usb_write_csr64(struct cvmx_usb_state *usb,
+                                         uint64_t address, uint64_t value)
+{
+       cvmx_write64_uint64(address, value);
 }
 
-static int octeon_usb_start(struct usb_hcd *hcd)
+/**
+ * Return non zero if this pipe connects to a non HIGH speed
+ * device through a high speed hub.
+ *
+ * @usb:    USB block this access is for
+ * @pipe:   Pipe to check
+ *
+ * Returns: Non zero if we need to do split transactions
+ */
+static inline int __cvmx_usb_pipe_needs_split(struct cvmx_usb_state *usb,
+                                             struct cvmx_usb_pipe *pipe)
 {
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
-       unsigned long flags;
-
-       hcd->state = HC_STATE_RUNNING;
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
-                                  octeon_usb_port_callback, NULL);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return 0;
+       return pipe->device_speed != CVMX_USB_SPEED_HIGH &&
+              usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH;
 }
 
-static void octeon_usb_stop(struct usb_hcd *hcd)
-{
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
-                                  NULL, NULL);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       hcd->state = HC_STATE_HALT;
+/**
+ * Trivial utility function to return the correct PID for a pipe
+ *
+ * @pipe:   pipe to check
+ *
+ * Returns: PID for pipe
+ */
+static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
+{
+       if (pipe->pid_toggle)
+               return 2; /* Data1 */
+       else
+               return 0; /* Data0 */
 }
 
-static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
-{
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
 
-       return cvmx_usb_get_frame_number(&priv->usb);
+/**
+ * Return the number of USB ports supported by this Octeon
+ * chip. If the chip doesn't support USB, or is not supported
+ * by this API, a zero will be returned. Most Octeon chips
+ * support one usb port, but some support two ports.
+ * cvmx_usb_initialize() must be called on independent
+ * struct cvmx_usb_state.
+ *
+ * Returns: Number of port, zero if usb isn't supported
+ */
+static int cvmx_usb_get_num_ports(void)
+{
+       int arch_ports = 0;
+
+       if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+               arch_ports = 1;
+       else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+               arch_ports = 2;
+       else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
+               arch_ports = 1;
+       else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
+               arch_ports = 1;
+       else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
+               arch_ports = 1;
+       else
+               arch_ports = 0;
+
+       return arch_ports;
 }
 
-static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
-                                            enum cvmx_usb_callback reason,
-                                            enum cvmx_usb_complete status,
-                                            int pipe_handle,
-                                            int submit_handle,
-                                            int bytes_transferred,
-                                            void *user_data)
+/**
+ * Initialize a USB port for use. This must be called before any
+ * other access to the Octeon USB port is made. The port starts
+ * off in the disabled state.
+ *
+ * @usb:        Pointer to an empty struct cvmx_usb_state
+ *              that will be populated by the initialize call.
+ *              This structure is then passed to all other USB
+ *              functions.
+ * @usb_port_number:
+ *              Which Octeon USB port to initialize.
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
+                              int usb_port_number)
 {
-       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
-       struct usb_hcd *hcd = octeon_to_hcd(priv);
-       struct device *dev = hcd->self.controller;
-       struct urb *urb = user_data;
+       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
+       union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
+       enum cvmx_usb_initialize_flags flags = 0;
+       int i;
 
-       urb->actual_length = bytes_transferred;
-       urb->hcpriv = NULL;
+       /* At first allow 0-1 for the usb port number */
+       if ((usb_port_number < 0) || (usb_port_number > 1))
+               return -EINVAL;
+       /* For all chips except 52XX there is only one port */
+       if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
+               return -EINVAL;
+       /* Try to determine clock type automatically */
+       if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
+               /* Only 12 MHZ crystals are supported */
+               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
+       } else {
+               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
+
+               switch (octeon_usb_get_clock_type()) {
+               case USB_CLOCK_TYPE_REF_12:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
+                       break;
+               case USB_CLOCK_TYPE_REF_24:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
+                       break;
+               case USB_CLOCK_TYPE_REF_48:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }
+       }
 
-       if (!list_empty(&urb->urb_list)) {
+       memset(usb, 0, sizeof(*usb));
+       usb->init_flags = flags;
+
+       /* Initialize the USB state structure */
+       usb->index = usb_port_number;
+       INIT_LIST_HEAD(&usb->idle_pipes);
+       for (i = 0; i < ARRAY_SIZE(usb->active_pipes); i++)
+               INIT_LIST_HEAD(&usb->active_pipes[i]);
+
+       /*
+        * Power On Reset and PHY Initialization
+        *
+        * 1. Wait for DCOK to assert (nothing to do)
+        *
+        * 2a. Write USBN0/1_CLK_CTL[POR] = 1 and
+        *     USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0
+        */
+       usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
+       usbn_clk_ctl.s.por = 1;
+       usbn_clk_ctl.s.hrst = 0;
+       usbn_clk_ctl.s.prst = 0;
+       usbn_clk_ctl.s.hclk_rst = 0;
+       usbn_clk_ctl.s.enable = 0;
+       /*
+        * 2b. Select the USB reference clock/crystal parameters by writing
+        *     appropriate values to USBN0/1_CLK_CTL[P_C_SEL, P_RTYPE, P_COM_ON]
+        */
+       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
                /*
-                * It is on the dequeue_list, but we are going to call
-                * usb_hcd_giveback_urb(), so we must clear it from
-                * the list.  We got to it before the
-                * octeon_usb_urb_dequeue_work() tasklet did.
+                * The USB port uses 12/24/48MHz 2.5V board clock
+                * source at USB_XO. USB_XI should be tied to GND.
+                * Most Octeon evaluation boards require this setting
+                */
+               if (OCTEON_IS_MODEL(OCTEON_CN3XXX) ||
+                   OCTEON_IS_MODEL(OCTEON_CN56XX) ||
+                   OCTEON_IS_MODEL(OCTEON_CN50XX))
+                       /* From CN56XX,CN50XX,CN31XX,CN30XX manuals */
+                       usbn_clk_ctl.s.p_rtype = 2; /* p_rclk=1 & p_xenbn=0 */
+               else
+                       /* From CN52XX manual */
+                       usbn_clk_ctl.s.p_rtype = 1;
+
+               switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
+               case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
+                       usbn_clk_ctl.s.p_c_sel = 0;
+                       break;
+               case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:
+                       usbn_clk_ctl.s.p_c_sel = 1;
+                       break;
+               case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:
+                       usbn_clk_ctl.s.p_c_sel = 2;
+                       break;
+               }
+       } else {
+               /*
+                * The USB port uses a 12MHz crystal as clock source
+                * at USB_XO and USB_XI
+                */
+               if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       /* From CN31XX,CN30XX manual */
+                       usbn_clk_ctl.s.p_rtype = 3; /* p_rclk=1 & p_xenbn=1 */
+               else
+                       /* From CN56XX,CN52XX,CN50XX manuals. */
+                       usbn_clk_ctl.s.p_rtype = 0;
+
+               usbn_clk_ctl.s.p_c_sel = 0;
+       }
+       /*
+        * 2c. Select the HCLK via writing USBN0/1_CLK_CTL[DIVIDE, DIVIDE2] and
+        *     setting USBN0/1_CLK_CTL[ENABLE] = 1. Divide the core clock down
+        *     such that USB is as close as possible to 125Mhz
+        */
+       {
+               int divisor = (octeon_get_clock_rate()+125000000-1)/125000000;
+               /* Lower than 4 doesn't seem to work properly */
+               if (divisor < 4)
+                       divisor = 4;
+               usbn_clk_ctl.s.divide = divisor;
+               usbn_clk_ctl.s.divide2 = 0;
+       }
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */
+       usbn_clk_ctl.s.hclk_rst = 1;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /* 2e.  Wait 64 core-clock cycles for HCLK to stabilize */
+       cvmx_wait(64);
+       /*
+        * 3. Program the power-on reset field in the USBN clock-control
+        *    register:
+        *    USBN_CLK_CTL[POR] = 0
+        */
+       usbn_clk_ctl.s.por = 0;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /* 4. Wait 1 ms for PHY clock to start */
+       mdelay(1);
+       /*
+        * 5. Program the Reset input from automatic test equipment field in the
+        *    USBP control and status register:
+        *    USBN_USBP_CTL_STATUS[ATE_RESET] = 1
+        */
+       usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
+       usbn_usbp_ctl_status.s.ate_reset = 1;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                              usbn_usbp_ctl_status.u64);
+       /* 6. Wait 10 cycles */
+       cvmx_wait(10);
+       /*
+        * 7. Clear ATE_RESET field in the USBN clock-control register:
+        *    USBN_USBP_CTL_STATUS[ATE_RESET] = 0
+        */
+       usbn_usbp_ctl_status.s.ate_reset = 0;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                              usbn_usbp_ctl_status.u64);
+       /*
+        * 8. Program the PHY reset field in the USBN clock-control register:
+        *    USBN_CLK_CTL[PRST] = 1
+        */
+       usbn_clk_ctl.s.prst = 1;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /*
+        * 9. Program the USBP control and status register to select host or
+        *    device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for
+        *    device
+        */
+       usbn_usbp_ctl_status.s.hst_mode = 0;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                              usbn_usbp_ctl_status.u64);
+       /* 10. Wait 1 us */
+       udelay(1);
+       /*
+        * 11. Program the hreset_n field in the USBN clock-control register:
+        *     USBN_CLK_CTL[HRST] = 1
+        */
+       usbn_clk_ctl.s.hrst = 1;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /* 12. Proceed to USB core initialization */
+       usbn_clk_ctl.s.enable = 1;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       udelay(1);
+
+       /*
+        * USB Core Initialization
+        *
+        * 1. Read USBC_GHWCFG1, USBC_GHWCFG2, USBC_GHWCFG3, USBC_GHWCFG4 to
+        *    determine USB core configuration parameters.
+        *
+        *    Nothing needed
+        *
+        * 2. Program the following fields in the global AHB configuration
+        *    register (USBC_GAHBCFG)
+        *    DMA mode, USBC_GAHBCFG[DMAEn]: 1 = DMA mode, 0 = slave mode
+        *    Burst length, USBC_GAHBCFG[HBSTLEN] = 0
+        *    Nonperiodic TxFIFO empty level (slave mode only),
+        *    USBC_GAHBCFG[NPTXFEMPLVL]
+        *    Periodic TxFIFO empty level (slave mode only),
+        *    USBC_GAHBCFG[PTXFEMPLVL]
+        *    Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1
+        */
+       {
+               union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
+               /* Due to an errata, CN31XX doesn't support DMA */
+               if (OCTEON_IS_MODEL(OCTEON_CN31XX))
+                       usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
+               usbcx_gahbcfg.u32 = 0;
+               usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
+               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+                       /* Only use one channel with non DMA */
+                       usb->idle_hardware_channels = 0x1;
+               else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
+                       /* CN5XXX have an errata with channel 3 */
+                       usb->idle_hardware_channels = 0xf7;
+               else
+                       usb->idle_hardware_channels = 0xff;
+               usbcx_gahbcfg.s.hbstlen = 0;
+               usbcx_gahbcfg.s.nptxfemplvl = 1;
+               usbcx_gahbcfg.s.ptxfemplvl = 1;
+               usbcx_gahbcfg.s.glblintrmsk = 1;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
+                                      usbcx_gahbcfg.u32);
+       }
+       /*
+        * 3. Program the following fields in USBC_GUSBCFG register.
+        *    HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0
+        *    ULPI DDR select, USBC_GUSBCFG[DDRSEL] = 0
+        *    USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5
+        *    PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0
+        */
+       {
+               union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
+               usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index));
+               usbcx_gusbcfg.s.toutcal = 0;
+               usbcx_gusbcfg.s.ddrsel = 0;
+               usbcx_gusbcfg.s.usbtrdtim = 0x5;
+               usbcx_gusbcfg.s.phylpwrclksel = 0;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
+                                      usbcx_gusbcfg.u32);
+       }
+       /*
+        * 4. The software must unmask the following bits in the USBC_GINTMSK
+        *    register.
+        *    OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1
+        *    Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1
+        */
+       {
+               union cvmx_usbcx_gintmsk usbcx_gintmsk;
+               int channel;
+
+               usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTMSK(usb->index));
+               usbcx_gintmsk.s.otgintmsk = 1;
+               usbcx_gintmsk.s.modemismsk = 1;
+               usbcx_gintmsk.s.hchintmsk = 1;
+               usbcx_gintmsk.s.sofmsk = 0;
+               /* We need RX FIFO interrupts if we don't have DMA */
+               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+                       usbcx_gintmsk.s.rxflvlmsk = 1;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
+                                      usbcx_gintmsk.u32);
+
+               /*
+                * Disable all channel interrupts. We'll enable them per channel
+                * later.
                 */
-               list_del(&urb->urb_list);
-               /* No longer on the dequeue_list. */
-               INIT_LIST_HEAD(&urb->urb_list);
+               for (channel = 0; channel < 8; channel++)
+                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
        }
 
-       /* For Isochronous transactions we need to update the URB packet status
-          list from data in our private copy */
-       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-               int i;
+       {
                /*
-                * The pointer to the private list is stored in the setup_packet
-                * field.
+                * Host Port Initialization
+                *
+                * 1. Program the host-port interrupt-mask field to unmask,
+                *    USBC_GINTMSK[PRTINT] = 1
                 */
-               struct cvmx_usb_iso_packet *iso_packet =
-                       (struct cvmx_usb_iso_packet *) urb->setup_packet;
-               /* Recalculate the transfer size by adding up each packet */
-               urb->actual_length = 0;
-               for (i = 0; i < urb->number_of_packets; i++) {
-                       if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) {
-                               urb->iso_frame_desc[i].status = 0;
-                               urb->iso_frame_desc[i].actual_length = iso_packet[i].length;
-                               urb->actual_length += urb->iso_frame_desc[i].actual_length;
-                       } else {
-                               dev_dbg(dev, "ISOCHRONOUS packet=%d of %d status=%d pipe=%d submit=%d size=%d\n",
-                                       i, urb->number_of_packets,
-                                       iso_packet[i].status, pipe_handle,
-                                       submit_handle, iso_packet[i].length);
-                               urb->iso_frame_desc[i].status = -EREMOTEIO;
-                       }
+               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
+                               prtintmsk, 1);
+               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
+                               disconnintmsk, 1);
+               /*
+                * 2. Program the USBC_HCFG register to select full-speed host
+                *    or high-speed host.
+                */
+               {
+                       union cvmx_usbcx_hcfg usbcx_hcfg;
+                       usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
+                       usbcx_hcfg.s.fslssupp = 0;
+                       usbcx_hcfg.s.fslspclksel = 0;
+                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
                }
-               /* Free the private list now that we don't need it anymore */
-               kfree(iso_packet);
-               urb->setup_packet = NULL;
+               /*
+                * 3. Program the port power bit to drive VBUS on the USB,
+                *    USBC_HPRT[PRTPWR] = 1
+                */
+               USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtpwr, 1);
+
+               /*
+                * Steps 4-15 from the manual are done later in the port enable
+                */
        }
 
-       switch (status) {
-       case CVMX_USB_COMPLETE_SUCCESS:
-               urb->status = 0;
-               break;
-       case CVMX_USB_COMPLETE_CANCEL:
-               if (urb->status == 0)
-                       urb->status = -ENOENT;
-               break;
-       case CVMX_USB_COMPLETE_STALL:
-               dev_dbg(dev, "status=stall pipe=%d submit=%d size=%d\n",
-                       pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EPIPE;
+       return 0;
+}
+
+
+/**
+ * Shutdown a USB port after a call to cvmx_usb_initialize().
+ * The port should be disabled with all pipes closed when this
+ * function is called.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_shutdown(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
+
+       /* Make sure all pipes are closed */
+       if (!list_empty(&usb->idle_pipes) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS]) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT]) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_CONTROL]) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_BULK]))
+               return -EBUSY;
+
+       /* Disable the clocks and put them in power on reset */
+       usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
+       usbn_clk_ctl.s.enable = 1;
+       usbn_clk_ctl.s.por = 1;
+       usbn_clk_ctl.s.hclk_rst = 1;
+       usbn_clk_ctl.s.prst = 0;
+       usbn_clk_ctl.s.hrst = 0;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       return 0;
+}
+
+
+/**
+ * Enable a USB port. After this call succeeds, the USB port is
+ * online and servicing requests.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_enable(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
+
+       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
+
+       /*
+        * If the port is already enabled the just return. We don't need to do
+        * anything
+        */
+       if (usb->usbcx_hprt.s.prtena)
+               return 0;
+
+       /* If there is nothing plugged into the port then fail immediately */
+       if (!usb->usbcx_hprt.s.prtconnsts) {
+               return -ETIMEDOUT;
+       }
+
+       /* Program the port reset bit to start the reset process */
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtrst, 1);
+
+       /*
+        * Wait at least 50ms (high speed), or 10ms (full speed) for the reset
+        * process to complete.
+        */
+       mdelay(50);
+
+       /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtrst, 0);
+
+       /* Wait for the USBC_HPRT[PRTENA]. */
+       if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
+                                 prtena, ==, 1, 100000))
+               return -ETIMEDOUT;
+
+       /*
+        * Read the port speed field to get the enumerated speed,
+        * USBC_HPRT[PRTSPD].
+        */
+       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
+       usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
+
+       /*
+        * 13. Program the USBC_GRXFSIZ register to select the size of the
+        *     receive FIFO (25%).
+        */
+       USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), union cvmx_usbcx_grxfsiz,
+                       rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
+       /*
+        * 14. Program the USBC_GNPTXFSIZ register to select the size and the
+        *     start address of the non- periodic transmit FIFO for nonperiodic
+        *     transactions (50%).
+        */
+       {
+               union cvmx_usbcx_gnptxfsiz siz;
+               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
+               siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
+               siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
+       }
+       /*
+        * 15. Program the USBC_HPTXFSIZ register to select the size and start
+        *     address of the periodic transmit FIFO for periodic transactions
+        *     (25%).
+        */
+       {
+               union cvmx_usbcx_hptxfsiz siz;
+               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
+               siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
+               siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
+       }
+       /* Flush all FIFOs */
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfnum, 0x10);
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfflsh, 1);
+       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
+                             txfflsh, ==, 0, 100);
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, rxfflsh, 1);
+       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
+                             rxfflsh, ==, 0, 100);
+
+       return 0;
+}
+
+
+/**
+ * Disable a USB port. After this call the USB port will not
+ * generate data transfers and will not generate events.
+ * Transactions in process will fail and call their
+ * associated callbacks.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_disable(struct cvmx_usb_state *usb)
+{
+       /* Disable the port */
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtena, 1);
+       return 0;
+}
+
+
+/**
+ * Get the current state of the USB port. Use this call to
+ * determine if the usb port has anything connected, is enabled,
+ * or has some sort of error condition. The return value of this
+ * call has "changed" bits to signal of the value of some fields
+ * have changed between calls.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: Port status information
+ */
+static struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_hprt usbc_hprt;
+       struct cvmx_usb_port_status result;
+
+       memset(&result, 0, sizeof(result));
+
+       usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
+       result.port_enabled = usbc_hprt.s.prtena;
+       result.port_over_current = usbc_hprt.s.prtovrcurract;
+       result.port_powered = usbc_hprt.s.prtpwr;
+       result.port_speed = usbc_hprt.s.prtspd;
+       result.connected = usbc_hprt.s.prtconnsts;
+       result.connect_change = (result.connected != usb->port_status.connected);
+
+       return result;
+}
+
+/**
+ * Open a virtual pipe between the host and a USB device. A pipe
+ * must be opened before data can be transferred between a device
+ * and Octeon.
+ *
+ * @usb:            USB device state populated by cvmx_usb_initialize().
+ * @device_addr:
+ *                  USB device address to open the pipe to
+ *                  (0-127).
+ * @endpoint_num:
+ *                  USB endpoint number to open the pipe to
+ *                  (0-15).
+ * @device_speed:
+ *                  The speed of the device the pipe is going
+ *                  to. This must match the device's speed,
+ *                  which may be different than the port speed.
+ * @max_packet:             The maximum packet length the device can
+ *                  transmit/receive (low speed=0-8, full
+ *                  speed=0-1023, high speed=0-1024). This value
+ *                  comes from the standard endpoint descriptor
+ *                  field wMaxPacketSize bits <10:0>.
+ * @transfer_type:
+ *                  The type of transfer this pipe is for.
+ * @transfer_dir:
+ *                  The direction the pipe is in. This is not
+ *                  used for control pipes.
+ * @interval:       For ISOCHRONOUS and INTERRUPT transfers,
+ *                  this is how often the transfer is scheduled
+ *                  for. All other transfers should specify
+ *                  zero. The units are in frames (8000/sec at
+ *                  high speed, 1000/sec for full speed).
+ * @multi_count:
+ *                  For high speed devices, this is the maximum
+ *                  allowed number of packet per microframe.
+ *                  Specify zero for non high speed devices. This
+ *                  value comes from the standard endpoint descriptor
+ *                  field wMaxPacketSize bits <12:11>.
+ * @hub_device_addr:
+ *                  Hub device address this device is connected
+ *                  to. Devices connected directly to Octeon
+ *                  use zero. This is only used when the device
+ *                  is full/low speed behind a high speed hub.
+ *                  The address will be of the high speed hub,
+ *                  not and full speed hubs after it.
+ * @hub_port:       Which port on the hub the device is
+ *                  connected. Use zero for devices connected
+ *                  directly to Octeon. Like hub_device_addr,
+ *                  this is only used for full/low speed
+ *                  devices behind a high speed hub.
+ *
+ * Returns: A non-NULL value is a pipe. NULL means an error.
+ */
+static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
+                                               int device_addr, int
+                                               endpoint_num,
+                                               enum cvmx_usb_speed
+                                                       device_speed,
+                                               int max_packet,
+                                               enum cvmx_usb_transfer
+                                                       transfer_type,
+                                               enum cvmx_usb_direction
+                                                       transfer_dir,
+                                               int interval, int multi_count,
+                                               int hub_device_addr,
+                                               int hub_port)
+{
+       struct cvmx_usb_pipe *pipe;
+
+       if (unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
+               return NULL;
+       if (unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
+               return NULL;
+       if (unlikely(device_speed > CVMX_USB_SPEED_LOW))
+               return NULL;
+       if (unlikely((max_packet <= 0) || (max_packet > 1024)))
+               return NULL;
+       if (unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
+               return NULL;
+       if (unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
+               (transfer_dir != CVMX_USB_DIRECTION_IN)))
+               return NULL;
+       if (unlikely(interval < 0))
+               return NULL;
+       if (unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
+               return NULL;
+       if (unlikely(multi_count < 0))
+               return NULL;
+       if (unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
+               (multi_count != 0)))
+               return NULL;
+       if (unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
+               return NULL;
+       if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
+               return NULL;
+
+       pipe = kzalloc(sizeof(*pipe), GFP_ATOMIC);
+       if (!pipe)
+               return NULL;
+       if ((device_speed == CVMX_USB_SPEED_HIGH) &&
+               (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
+               (transfer_type == CVMX_USB_TRANSFER_BULK))
+               pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
+       pipe->device_addr = device_addr;
+       pipe->endpoint_num = endpoint_num;
+       pipe->device_speed = device_speed;
+       pipe->max_packet = max_packet;
+       pipe->transfer_type = transfer_type;
+       pipe->transfer_dir = transfer_dir;
+       INIT_LIST_HEAD(&pipe->transactions);
+
+       /*
+        * All pipes use interval to rate limit NAK processing. Force an
+        * interval if one wasn't supplied
+        */
+       if (!interval)
+               interval = 1;
+       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+               pipe->interval = interval*8;
+               /* Force start splits to be schedule on uFrame 0 */
+               pipe->next_tx_frame = ((usb->frame_number+7)&~7) + pipe->interval;
+       } else {
+               pipe->interval = interval;
+               pipe->next_tx_frame = usb->frame_number + pipe->interval;
+       }
+       pipe->multi_count = multi_count;
+       pipe->hub_device_addr = hub_device_addr;
+       pipe->hub_port = hub_port;
+       pipe->pid_toggle = 0;
+       pipe->split_sc_frame = -1;
+       list_add_tail(&pipe->node, &usb->idle_pipes);
+
+       /*
+        * We don't need to tell the hardware about this pipe yet since
+        * it doesn't have any submitted requests
+        */
+
+       return pipe;
+}
+
+
+/**
+ * Poll the RX FIFOs and remove data as needed. This function is only used
+ * in non DMA mode. It is very important that this function be called quickly
+ * enough to prevent FIFO overflow.
+ *
+ * @usb:       USB device state populated by cvmx_usb_initialize().
+ */
+static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_grxstsph rx_status;
+       int channel;
+       int bytes;
+       uint64_t address;
+       uint32_t *ptr;
+
+       rx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GRXSTSPH(usb->index));
+       /* Only read data if IN data is there */
+       if (rx_status.s.pktsts != 2)
+               return;
+       /* Check if no data is available */
+       if (!rx_status.s.bcnt)
+               return;
+
+       channel = rx_status.s.chnum;
+       bytes = rx_status.s.bcnt;
+       if (!bytes)
+               return;
+
+       /* Get where the DMA engine would have written this data */
+       address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
+       ptr = cvmx_phys_to_ptr(address);
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, address + bytes);
+
+       /* Loop writing the FIFO data for this packet into memory */
+       while (bytes > 0) {
+               *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index));
+               bytes -= 4;
+       }
+       CVMX_SYNCW;
+
+       return;
+}
+
+
+/**
+ * Fill the TX hardware fifo with data out of the software
+ * fifos
+ *
+ * @usb:           USB device state populated by cvmx_usb_initialize().
+ * @fifo:          Software fifo to use
+ * @available:     Amount of space in the hardware fifo
+ *
+ * Returns: Non zero if the hardware fifo was too small and needs
+ *         to be serviced again.
+ */
+static int __cvmx_usb_fill_tx_hw(struct cvmx_usb_state *usb,
+                                struct cvmx_usb_tx_fifo *fifo, int available)
+{
+       /*
+        * We're done either when there isn't anymore space or the software FIFO
+        * is empty
+        */
+       while (available && (fifo->head != fifo->tail)) {
+               int i = fifo->tail;
+               const uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
+               uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4;
+               int words = available;
+
+               /* Limit the amount of data to waht the SW fifo has */
+               if (fifo->entry[i].size <= available) {
+                       words = fifo->entry[i].size;
+                       fifo->tail++;
+                       if (fifo->tail > MAX_CHANNELS)
+                               fifo->tail = 0;
+               }
+
+               /* Update the next locations and counts */
+               available -= words;
+               fifo->entry[i].address += words * 4;
+               fifo->entry[i].size -= words;
+
+               /*
+                * Write the HW fifo data. The read every three writes is due
+                * to an errata on CN3XXX chips
+                */
+               while (words > 3) {
+                       cvmx_write64_uint32(csr_address, *ptr++);
+                       cvmx_write64_uint32(csr_address, *ptr++);
+                       cvmx_write64_uint32(csr_address, *ptr++);
+                       cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
+                       words -= 3;
+               }
+               cvmx_write64_uint32(csr_address, *ptr++);
+               if (--words) {
+                       cvmx_write64_uint32(csr_address, *ptr++);
+                       if (--words)
+                               cvmx_write64_uint32(csr_address, *ptr++);
+               }
+               cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
+       }
+       return fifo->head != fifo->tail;
+}
+
+
+/**
+ * Check the hardware FIFOs and fill them as needed
+ *
+ * @usb:       USB device state populated by cvmx_usb_initialize().
+ */
+static void __cvmx_usb_poll_tx_fifo(struct cvmx_usb_state *usb)
+{
+       if (usb->periodic.head != usb->periodic.tail) {
+               union cvmx_usbcx_hptxsts tx_status;
+               tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXSTS(usb->index));
+               if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic, tx_status.s.ptxfspcavail))
+                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, ptxfempmsk, 1);
+               else
+                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, ptxfempmsk, 0);
+       }
+
+       if (usb->nonperiodic.head != usb->nonperiodic.tail) {
+               union cvmx_usbcx_gnptxsts tx_status;
+               tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXSTS(usb->index));
+               if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic, tx_status.s.nptxfspcavail))
+                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 1);
+               else
+                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 0);
+       }
+
+       return;
+}
+
+
+/**
+ * Fill the TX FIFO with an outgoing packet
+ *
+ * @usb:         USB device state populated by cvmx_usb_initialize().
+ * @channel:     Channel number to get packet from
+ */
+static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
+{
+       union cvmx_usbcx_hccharx hcchar;
+       union cvmx_usbcx_hcspltx usbc_hcsplt;
+       union cvmx_usbcx_hctsizx usbc_hctsiz;
+       struct cvmx_usb_tx_fifo *fifo;
+
+       /* We only need to fill data on outbound channels */
+       hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
+       if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT)
+               return;
+
+       /* OUT Splits only have data on the start and not the complete */
+       usbc_hcsplt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index));
+       if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
+               return;
+
+       /*
+        * Find out how many bytes we need to fill and convert it into 32bit
+        * words.
+        */
+       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
+       if (!usbc_hctsiz.s.xfersize)
+               return;
+
+       if ((hcchar.s.eptype == CVMX_USB_TRANSFER_INTERRUPT) ||
+               (hcchar.s.eptype == CVMX_USB_TRANSFER_ISOCHRONOUS))
+               fifo = &usb->periodic;
+       else
+               fifo = &usb->nonperiodic;
+
+       fifo->entry[fifo->head].channel = channel;
+       fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8);
+       fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2;
+       fifo->head++;
+       if (fifo->head > MAX_CHANNELS)
+               fifo->head = 0;
+
+       __cvmx_usb_poll_tx_fifo(usb);
+
+       return;
+}
+
+/**
+ * Perform channel specific setup for Control transactions. All
+ * the generic stuff will already have been done in
+ * __cvmx_usb_start_channel()
+ *
+ * @usb:         USB device state populated by cvmx_usb_initialize().
+ * @channel:     Channel to setup
+ * @pipe:        Pipe for control transaction
+ */
+static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
+                                            int channel,
+                                            struct cvmx_usb_pipe *pipe)
+{
+       struct cvmx_usb_transaction *transaction =
+               list_first_entry(&pipe->transactions, typeof(*transaction),
+                                node);
+       union cvmx_usb_control_header *header =
+               cvmx_phys_to_ptr(transaction->control_header);
+       int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
+       int packets_to_transfer;
+       union cvmx_usbcx_hctsizx usbc_hctsiz;
+
+       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
+
+       switch (transaction->stage) {
+       case CVMX_USB_STAGE_NON_CONTROL:
+       case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
+               cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
                break;
-       case CVMX_USB_COMPLETE_BABBLEERR:
-               dev_dbg(dev, "status=babble pipe=%d submit=%d size=%d\n",
-                       pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EPIPE;
+       case CVMX_USB_STAGE_SETUP:
+               usbc_hctsiz.s.pid = 3; /* Setup */
+               bytes_to_transfer = sizeof(*header);
+               /* All Control operations start with a setup going OUT */
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
+               /*
+                * Setup send the control header instead of the buffer data. The
+                * buffer data will be used in the next stage
+                */
+               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header);
                break;
-       case CVMX_USB_COMPLETE_SHORT:
-               dev_dbg(dev, "status=short pipe=%d submit=%d size=%d\n",
-                       pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EREMOTEIO;
+       case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
+               usbc_hctsiz.s.pid = 3; /* Setup */
+               bytes_to_transfer = 0;
+               /* All Control operations start with a setup going OUT */
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
+               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
                break;
-       case CVMX_USB_COMPLETE_ERROR:
-       case CVMX_USB_COMPLETE_XACTERR:
-       case CVMX_USB_COMPLETE_DATATGLERR:
-       case CVMX_USB_COMPLETE_FRAMEERR:
-               dev_dbg(dev, "status=%d pipe=%d submit=%d size=%d\n",
-                       status, pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EPROTO;
+       case CVMX_USB_STAGE_DATA:
+               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       if (header->s.request_type & 0x80)
+                               bytes_to_transfer = 0;
+                       else if (bytes_to_transfer > pipe->max_packet)
+                               bytes_to_transfer = pipe->max_packet;
+               }
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
+                               union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       CVMX_USB_DIRECTION_IN :
+                                       CVMX_USB_DIRECTION_OUT));
+               break;
+       case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
+               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               if (!(header->s.request_type & 0x80))
+                       bytes_to_transfer = 0;
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
+                               union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       CVMX_USB_DIRECTION_IN :
+                                       CVMX_USB_DIRECTION_OUT));
+               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
+               break;
+       case CVMX_USB_STAGE_STATUS:
+               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               bytes_to_transfer = 0;
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       CVMX_USB_DIRECTION_OUT :
+                                       CVMX_USB_DIRECTION_IN));
+               break;
+       case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
+               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               bytes_to_transfer = 0;
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       CVMX_USB_DIRECTION_OUT :
+                                       CVMX_USB_DIRECTION_IN));
+               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
                break;
        }
-       spin_unlock(&priv->lock);
-       usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
-       spin_lock(&priv->lock);
+
+       /*
+        * Make sure the transfer never exceeds the byte limit of the hardware.
+        * Further bytes will be sent as continued transactions
+        */
+       if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
+               /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */
+               bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
+               bytes_to_transfer *= pipe->max_packet;
+       }
+
+       /*
+        * Calculate the number of packets to transfer. If the length is zero
+        * we still need to transfer one packet
+        */
+       packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
+       if (packets_to_transfer == 0)
+               packets_to_transfer = 1;
+       else if ((packets_to_transfer > 1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
+               /*
+                * Limit to one packet when not using DMA. Channels must be
+                * restarted between every packet for IN transactions, so there
+                * is no reason to do multiple packets in a row
+                */
+               packets_to_transfer = 1;
+               bytes_to_transfer = packets_to_transfer * pipe->max_packet;
+       } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
+               /*
+                * Limit the number of packet and data transferred to what the
+                * hardware can handle
+                */
+               packets_to_transfer = MAX_TRANSFER_PACKETS;
+               bytes_to_transfer = packets_to_transfer * pipe->max_packet;
+       }
+
+       usbc_hctsiz.s.xfersize = bytes_to_transfer;
+       usbc_hctsiz.s.pktcnt = packets_to_transfer;
+
+       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
+       return;
+}
+
+
+/**
+ * Start a channel to perform the pipe's head transaction
+ *
+ * @usb:         USB device state populated by cvmx_usb_initialize().
+ * @channel:     Channel to setup
+ * @pipe:        Pipe to start
+ */
+static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
+                                    int channel,
+                                    struct cvmx_usb_pipe *pipe)
+{
+       struct cvmx_usb_transaction *transaction =
+               list_first_entry(&pipe->transactions, typeof(*transaction),
+                                node);
+
+       /* Make sure all writes to the DMA region get flushed */
+       CVMX_SYNCW;
+
+       /* Attach the channel to the pipe */
+       usb->pipe_for_channel[channel] = pipe;
+       pipe->channel = channel;
+       pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED;
+
+       /* Mark this channel as in use */
+       usb->idle_hardware_channels &= ~(1<<channel);
+
+       /* Enable the channel interrupt bits */
+       {
+               union cvmx_usbcx_hcintx usbc_hcint;
+               union cvmx_usbcx_hcintmskx usbc_hcintmsk;
+               union cvmx_usbcx_haintmsk usbc_haintmsk;
+
+               /* Clear all channel status bits */
+               usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
+
+               usbc_hcintmsk.u32 = 0;
+               usbc_hcintmsk.s.chhltdmsk = 1;
+               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
+                       /*
+                        * Channels need these extra interrupts when we aren't
+                        * in DMA mode.
+                        */
+                       usbc_hcintmsk.s.datatglerrmsk = 1;
+                       usbc_hcintmsk.s.frmovrunmsk = 1;
+                       usbc_hcintmsk.s.bblerrmsk = 1;
+                       usbc_hcintmsk.s.xacterrmsk = 1;
+                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                               /*
+                                * Splits don't generate xfercompl, so we need
+                                * ACK and NYET.
+                                */
+                               usbc_hcintmsk.s.nyetmsk = 1;
+                               usbc_hcintmsk.s.ackmsk = 1;
+                       }
+                       usbc_hcintmsk.s.nakmsk = 1;
+                       usbc_hcintmsk.s.stallmsk = 1;
+                       usbc_hcintmsk.s.xfercomplmsk = 1;
+               }
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32);
+
+               /* Enable the channel interrupt to propagate */
+               usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index));
+               usbc_haintmsk.s.haintmsk |= 1<<channel;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index), usbc_haintmsk.u32);
+       }
+
+       /* Setup the locations the DMA engines use  */
+       {
+               uint64_t dma_address = transaction->buffer + transaction->actual_bytes;
+               if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
+                       dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes;
+               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
+               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, dma_address);
+       }
+
+       /* Setup both the size of the transfer and the SPLIT characteristics */
+       {
+               union cvmx_usbcx_hcspltx usbc_hcsplt = {.u32 = 0};
+               union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = 0};
+               int packets_to_transfer;
+               int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
+
+               /*
+                * ISOCHRONOUS transactions store each individual transfer size
+                * in the packet structure, not the global buffer_length
+                */
+               if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
+                       bytes_to_transfer = transaction->iso_packets[0].length - transaction->actual_bytes;
+
+               /*
+                * We need to do split transactions when we are talking to non
+                * high speed devices that are behind a high speed hub
+                */
+               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       /*
+                        * On the start split phase (stage is even) record the
+                        * frame number we will need to send the split complete.
+                        * We only store the lower two bits since the time ahead
+                        * can only be two frames
+                        */
+                       if ((transaction->stage&1) == 0) {
+                               if (transaction->type == CVMX_USB_TRANSFER_BULK)
+                                       pipe->split_sc_frame = (usb->frame_number + 1) & 0x7f;
+                               else
+                                       pipe->split_sc_frame = (usb->frame_number + 2) & 0x7f;
+                       } else
+                               pipe->split_sc_frame = -1;
+
+                       usbc_hcsplt.s.spltena = 1;
+                       usbc_hcsplt.s.hubaddr = pipe->hub_device_addr;
+                       usbc_hcsplt.s.prtaddr = pipe->hub_port;
+                       usbc_hcsplt.s.compsplt = (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE);
+
+                       /*
+                        * SPLIT transactions can only ever transmit one data
+                        * packet so limit the transfer size to the max packet
+                        * size
+                        */
+                       if (bytes_to_transfer > pipe->max_packet)
+                               bytes_to_transfer = pipe->max_packet;
+
+                       /*
+                        * ISOCHRONOUS OUT splits are unique in that they limit
+                        * data transfers to 188 byte chunks representing the
+                        * begin/middle/end of the data or all
+                        */
+                       if (!usbc_hcsplt.s.compsplt &&
+                               (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
+                               (pipe->transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
+                               /*
+                                * Clear the split complete frame number as
+                                * there isn't going to be a split complete
+                                */
+                               pipe->split_sc_frame = -1;
+                               /*
+                                * See if we've started this transfer and sent
+                                * data
+                                */
+                               if (transaction->actual_bytes == 0) {
+                                       /*
+                                        * Nothing sent yet, this is either a
+                                        * begin or the entire payload
+                                        */
+                                       if (bytes_to_transfer <= 188)
+                                               /* Entire payload in one go */
+                                               usbc_hcsplt.s.xactpos = 3;
+                                       else
+                                               /* First part of payload */
+                                               usbc_hcsplt.s.xactpos = 2;
+                               } else {
+                                       /*
+                                        * Continuing the previous data, we must
+                                        * either be in the middle or at the end
+                                        */
+                                       if (bytes_to_transfer <= 188)
+                                               /* End of payload */
+                                               usbc_hcsplt.s.xactpos = 1;
+                                       else
+                                               /* Middle of payload */
+                                               usbc_hcsplt.s.xactpos = 0;
+                               }
+                               /*
+                                * Again, the transfer size is limited to 188
+                                * bytes
+                                */
+                               if (bytes_to_transfer > 188)
+                                       bytes_to_transfer = 188;
+                       }
+               }
+
+               /*
+                * Make sure the transfer never exceeds the byte limit of the
+                * hardware. Further bytes will be sent as continued
+                * transactions
+                */
+               if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
+                       /*
+                        * Round MAX_TRANSFER_BYTES to a multiple of out packet
+                        * size
+                        */
+                       bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
+                       bytes_to_transfer *= pipe->max_packet;
+               }
+
+               /*
+                * Calculate the number of packets to transfer. If the length is
+                * zero we still need to transfer one packet
+                */
+               packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
+               if (packets_to_transfer == 0)
+                       packets_to_transfer = 1;
+               else if ((packets_to_transfer > 1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
+                       /*
+                        * Limit to one packet when not using DMA. Channels must
+                        * be restarted between every packet for IN
+                        * transactions, so there is no reason to do multiple
+                        * packets in a row
+                        */
+                       packets_to_transfer = 1;
+                       bytes_to_transfer = packets_to_transfer * pipe->max_packet;
+               } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
+                       /*
+                        * Limit the number of packet and data transferred to
+                        * what the hardware can handle
+                        */
+                       packets_to_transfer = MAX_TRANSFER_PACKETS;
+                       bytes_to_transfer = packets_to_transfer * pipe->max_packet;
+               }
+
+               usbc_hctsiz.s.xfersize = bytes_to_transfer;
+               usbc_hctsiz.s.pktcnt = packets_to_transfer;
+
+               /* Update the DATA0/DATA1 toggle */
+               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               /*
+                * High speed pipes may need a hardware ping before they start
+                */
+               if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING)
+                       usbc_hctsiz.s.dopng = 1;
+
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index), usbc_hcsplt.u32);
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
+       }
+
+       /* Setup the Host Channel Characteristics Register */
+       {
+               union cvmx_usbcx_hccharx usbc_hcchar = {.u32 = 0};
+
+               /*
+                * Set the startframe odd/even properly. This is only used for
+                * periodic
+                */
+               usbc_hcchar.s.oddfrm = usb->frame_number&1;
+
+               /*
+                * Set the number of back to back packets allowed by this
+                * endpoint. Split transactions interpret "ec" as the number of
+                * immediate retries of failure. These retries happen too
+                * quickly, so we disable these entirely for splits
+                */
+               if (__cvmx_usb_pipe_needs_split(usb, pipe))
+                       usbc_hcchar.s.ec = 1;
+               else if (pipe->multi_count < 1)
+                       usbc_hcchar.s.ec = 1;
+               else if (pipe->multi_count > 3)
+                       usbc_hcchar.s.ec = 3;
+               else
+                       usbc_hcchar.s.ec = pipe->multi_count;
+
+               /* Set the rest of the endpoint specific settings */
+               usbc_hcchar.s.devaddr = pipe->device_addr;
+               usbc_hcchar.s.eptype = transaction->type;
+               usbc_hcchar.s.lspddev = (pipe->device_speed == CVMX_USB_SPEED_LOW);
+               usbc_hcchar.s.epdir = pipe->transfer_dir;
+               usbc_hcchar.s.epnum = pipe->endpoint_num;
+               usbc_hcchar.s.mps = pipe->max_packet;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
+       }
+
+       /* Do transaction type specific fixups as needed */
+       switch (transaction->type) {
+       case CVMX_USB_TRANSFER_CONTROL:
+               __cvmx_usb_start_channel_control(usb, channel, pipe);
+               break;
+       case CVMX_USB_TRANSFER_BULK:
+       case CVMX_USB_TRANSFER_INTERRUPT:
+               break;
+       case CVMX_USB_TRANSFER_ISOCHRONOUS:
+               if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       /*
+                        * ISO transactions require different PIDs depending on
+                        * direction and how many packets are needed
+                        */
+                       if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
+                               if (pipe->multi_count < 2) /* Need DATA0 */
+                                       USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union cvmx_usbcx_hctsizx, pid, 0);
+                               else /* Need MDATA */
+                                       USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union cvmx_usbcx_hctsizx, pid, 3);
+                       }
+               }
+               break;
+       }
+       {
+               union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index))};
+               transaction->xfersize = usbc_hctsiz.s.xfersize;
+               transaction->pktcnt = usbc_hctsiz.s.pktcnt;
+       }
+       /* Remeber when we start a split transaction */
+       if (__cvmx_usb_pipe_needs_split(usb, pipe))
+               usb->active_split = transaction;
+       USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, chena, 1);
+       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+               __cvmx_usb_fill_tx_fifo(usb, channel);
+       return;
+}
+
+
+/**
+ * Find a pipe that is ready to be scheduled to hardware.
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @list:       Pipe list to search
+ * @current_frame:
+ *              Frame counter to use as a time reference.
+ *
+ * Returns: Pipe or NULL if none are ready
+ */
+static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_state *usb, struct list_head *list, uint64_t current_frame)
+{
+       struct cvmx_usb_pipe *pipe;
+
+       list_for_each_entry(pipe, list, node) {
+               struct cvmx_usb_transaction *t =
+                       list_first_entry(&pipe->transactions, typeof(*t), node);
+               if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && t &&
+                       (pipe->next_tx_frame <= current_frame) &&
+                       ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
+                       (!usb->active_split || (usb->active_split == t))) {
+                       CVMX_PREFETCH(pipe, 128);
+                       CVMX_PREFETCH(t, 0);
+                       return pipe;
+               }
+       }
+       return NULL;
+}
+
+
+/**
+ * Called whenever a pipe might need to be scheduled to the
+ * hardware.
+ *
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @is_sof:     True if this schedule was called on a SOF interrupt.
+ */
+static void __cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
+{
+       int channel;
+       struct cvmx_usb_pipe *pipe;
+       int need_sof;
+       enum cvmx_usb_transfer ttype;
+
+       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
+               /*
+                * Without DMA we need to be careful to not schedule something
+                * at the end of a frame and cause an overrun.
+                */
+               union cvmx_usbcx_hfnum hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))};
+               union cvmx_usbcx_hfir hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))};
+               if (hfnum.s.frrem < hfir.s.frint/4)
+                       goto done;
+       }
+
+       while (usb->idle_hardware_channels) {
+               /* Find an idle channel */
+               channel = __fls(usb->idle_hardware_channels);
+               if (unlikely(channel > 7))
+                       break;
+
+               /* Find a pipe needing service */
+               pipe = NULL;
+               if (is_sof) {
+                       /*
+                        * Only process periodic pipes on SOF interrupts. This
+                        * way we are sure that the periodic data is sent in the
+                        * beginning of the frame
+                        */
+                       pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number);
+                       if (likely(!pipe))
+                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number);
+               }
+               if (likely(!pipe)) {
+                       pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number);
+                       if (likely(!pipe))
+                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number);
+               }
+               if (!pipe)
+                       break;
+
+               __cvmx_usb_start_channel(usb, channel, pipe);
+       }
+
+done:
+       /*
+        * Only enable SOF interrupts when we have transactions pending in the
+        * future that might need to be scheduled
+        */
+       need_sof = 0;
+       for (ttype = CVMX_USB_TRANSFER_CONTROL; ttype <= CVMX_USB_TRANSFER_INTERRUPT; ttype++) {
+               list_for_each_entry(pipe, &usb->active_pipes[ttype], node) {
+                       if (pipe->next_tx_frame > usb->frame_number) {
+                               need_sof = 1;
+                               break;
+                       }
+               }
+       }
+       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, sofmsk, need_sof);
+       return;
+}
+
+static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p)
+{
+       return container_of(p, struct octeon_hcd, usb);
+}
+
+static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
+{
+       return container_of((void *)p, struct usb_hcd, hcd_priv);
+}
+
+static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
+                                            enum cvmx_usb_complete status,
+                                            struct cvmx_usb_pipe *pipe,
+                                            struct cvmx_usb_transaction
+                                               *transaction,
+                                            int bytes_transferred,
+                                            struct urb *urb)
+{
+       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
+       struct usb_hcd *hcd = octeon_to_hcd(priv);
+       struct device *dev = hcd->self.controller;
+
+       urb->actual_length = bytes_transferred;
+       urb->hcpriv = NULL;
+
+       if (!list_empty(&urb->urb_list))
+               /*
+                * It is on the dequeue_list, but we are going to call
+                * usb_hcd_giveback_urb(), so we must clear it from
+                * the list.  We got to it before the
+                * octeon_usb_urb_dequeue_work() tasklet did.
+                */
+               list_del_init(&urb->urb_list);
+
+       /* For Isochronous transactions we need to update the URB packet status
+          list from data in our private copy */
+       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+               int i;
+               /*
+                * The pointer to the private list is stored in the setup_packet
+                * field.
+                */
+               struct cvmx_usb_iso_packet *iso_packet =
+                       (struct cvmx_usb_iso_packet *) urb->setup_packet;
+               /* Recalculate the transfer size by adding up each packet */
+               urb->actual_length = 0;
+               for (i = 0; i < urb->number_of_packets; i++) {
+                       if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) {
+                               urb->iso_frame_desc[i].status = 0;
+                               urb->iso_frame_desc[i].actual_length = iso_packet[i].length;
+                               urb->actual_length += urb->iso_frame_desc[i].actual_length;
+                       } else {
+                               dev_dbg(dev, "ISOCHRONOUS packet=%d of %d status=%d pipe=%p transaction=%p size=%d\n",
+                                       i, urb->number_of_packets,
+                                       iso_packet[i].status, pipe,
+                                       transaction, iso_packet[i].length);
+                               urb->iso_frame_desc[i].status = -EREMOTEIO;
+                       }
+               }
+               /* Free the private list now that we don't need it anymore */
+               kfree(iso_packet);
+               urb->setup_packet = NULL;
+       }
+
+       switch (status) {
+       case CVMX_USB_COMPLETE_SUCCESS:
+               urb->status = 0;
+               break;
+       case CVMX_USB_COMPLETE_CANCEL:
+               if (urb->status == 0)
+                       urb->status = -ENOENT;
+               break;
+       case CVMX_USB_COMPLETE_STALL:
+               dev_dbg(dev, "status=stall pipe=%p transaction=%p size=%d\n",
+                       pipe, transaction, bytes_transferred);
+               urb->status = -EPIPE;
+               break;
+       case CVMX_USB_COMPLETE_BABBLEERR:
+               dev_dbg(dev, "status=babble pipe=%p transaction=%p size=%d\n",
+                       pipe, transaction, bytes_transferred);
+               urb->status = -EPIPE;
+               break;
+       case CVMX_USB_COMPLETE_SHORT:
+               dev_dbg(dev, "status=short pipe=%p transaction=%p size=%d\n",
+                       pipe, transaction, bytes_transferred);
+               urb->status = -EREMOTEIO;
+               break;
+       case CVMX_USB_COMPLETE_ERROR:
+       case CVMX_USB_COMPLETE_XACTERR:
+       case CVMX_USB_COMPLETE_DATATGLERR:
+       case CVMX_USB_COMPLETE_FRAMEERR:
+               dev_dbg(dev, "status=%d pipe=%p transaction=%p size=%d\n",
+                       status, pipe, transaction, bytes_transferred);
+               urb->status = -EPROTO;
+               break;
+       }
+       spin_unlock(&priv->lock);
+       usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
+       spin_lock(&priv->lock);
+}
+
+/**
+ * Signal the completion of a transaction and free it. The
+ * transaction will be removed from the pipe transaction list.
+ *
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @pipe:       Pipe the transaction is on
+ * @transaction:
+ *              Transaction that completed
+ * @complete_code:
+ *              Completion code
+ */
+static void __cvmx_usb_perform_complete(struct cvmx_usb_state *usb,
+                                       struct cvmx_usb_pipe *pipe,
+                                       struct cvmx_usb_transaction *transaction,
+                                       enum cvmx_usb_complete complete_code)
+{
+       /* If this was a split then clear our split in progress marker */
+       if (usb->active_split == transaction)
+               usb->active_split = NULL;
+
+       /*
+        * Isochronous transactions need extra processing as they might not be
+        * done after a single data transfer
+        */
+       if (unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
+               /* Update the number of bytes transferred in this ISO packet */
+               transaction->iso_packets[0].length = transaction->actual_bytes;
+               transaction->iso_packets[0].status = complete_code;
+
+               /*
+                * If there are more ISOs pending and we succeeded, schedule the
+                * next one
+                */
+               if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS)) {
+                       /* No bytes transferred for this packet as of yet */
+                       transaction->actual_bytes = 0;
+                       /* One less ISO waiting to transfer */
+                       transaction->iso_number_packets--;
+                       /* Increment to the next location in our packet array */
+                       transaction->iso_packets++;
+                       transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
+                       goto done;
+               }
+       }
+
+       /* Remove the transaction from the pipe list */
+       list_del(&transaction->node);
+       if (list_empty(&pipe->transactions))
+               list_move_tail(&pipe->node, &usb->idle_pipes);
+       octeon_usb_urb_complete_callback(usb, complete_code, pipe,
+                                        transaction,
+                                        transaction->actual_bytes,
+                                        transaction->urb);
+       kfree(transaction);
+done:
+       return;
+}
+
+
+/**
+ * Submit a usb transaction to a pipe. Called for all types
+ * of transactions.
+ *
+ * @usb:
+ * @pipe:          Which pipe to submit to.
+ * @type:          Transaction type
+ * @buffer:        User buffer for the transaction
+ * @buffer_length:
+ *                 User buffer's length in bytes
+ * @control_header:
+ *                 For control transactions, the 8 byte standard header
+ * @iso_start_frame:
+ *                 For ISO transactions, the start frame
+ * @iso_number_packets:
+ *                 For ISO, the number of packet in the transaction.
+ * @iso_packets:
+ *                 A description of each ISO packet
+ * @urb:           URB for the callback
+ *
+ * Returns: Transaction or NULL on failure.
+ */
+static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(struct cvmx_usb_state *usb,
+                                                                 struct cvmx_usb_pipe *pipe,
+                                                                 enum cvmx_usb_transfer type,
+                                                                 uint64_t buffer,
+                                                                 int buffer_length,
+                                                                 uint64_t control_header,
+                                                                 int iso_start_frame,
+                                                                 int iso_number_packets,
+                                                                 struct cvmx_usb_iso_packet *iso_packets,
+                                                                 struct urb *urb)
+{
+       struct cvmx_usb_transaction *transaction;
+
+       if (unlikely(pipe->transfer_type != type))
+               return NULL;
+
+       transaction = kzalloc(sizeof(*transaction), GFP_ATOMIC);
+       if (unlikely(!transaction))
+               return NULL;
+
+       transaction->type = type;
+       transaction->buffer = buffer;
+       transaction->buffer_length = buffer_length;
+       transaction->control_header = control_header;
+       /* FIXME: This is not used, implement it. */
+       transaction->iso_start_frame = iso_start_frame;
+       transaction->iso_number_packets = iso_number_packets;
+       transaction->iso_packets = iso_packets;
+       transaction->urb = urb;
+       if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
+               transaction->stage = CVMX_USB_STAGE_SETUP;
+       else
+               transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
+
+       if (!list_empty(&pipe->transactions)) {
+               list_add_tail(&transaction->node, &pipe->transactions);
+       } else {
+               list_add_tail(&transaction->node, &pipe->transactions);
+               list_move_tail(&pipe->node,
+                              &usb->active_pipes[pipe->transfer_type]);
+
+               /*
+                * We may need to schedule the pipe if this was the head of the
+                * pipe.
+                */
+               __cvmx_usb_schedule(usb, 0);
+       }
+
+       return transaction;
+}
+
+
+/**
+ * Call to submit a USB Bulk transfer to a pipe.
+ *
+ * @usb:           USB device state populated by cvmx_usb_initialize().
+ * @pipe:          Handle to the pipe for the transfer.
+ * @urb:           URB.
+ *
+ * Returns: A submitted transaction or NULL on failure.
+ */
+static struct cvmx_usb_transaction *cvmx_usb_submit_bulk(struct cvmx_usb_state *usb,
+                                                        struct cvmx_usb_pipe *pipe,
+                                                        struct urb *urb)
+{
+       return __cvmx_usb_submit_transaction(usb, pipe, CVMX_USB_TRANSFER_BULK,
+                                            urb->transfer_dma,
+                                            urb->transfer_buffer_length,
+                                            0, /* control_header */
+                                            0, /* iso_start_frame */
+                                            0, /* iso_number_packets */
+                                            NULL, /* iso_packets */
+                                            urb);
+}
+
+
+/**
+ * Call to submit a USB Interrupt transfer to a pipe.
+ *
+ * @usb:           USB device state populated by cvmx_usb_initialize().
+ * @pipe:          Handle to the pipe for the transfer.
+ * @urb:           URB returned when the callback is called.
+ *
+ * Returns: A submitted transaction or NULL on failure.
+ */
+static struct cvmx_usb_transaction *cvmx_usb_submit_interrupt(struct cvmx_usb_state *usb,
+                                                             struct cvmx_usb_pipe *pipe,
+                                                             struct urb *urb)
+{
+       return __cvmx_usb_submit_transaction(usb, pipe,
+                                            CVMX_USB_TRANSFER_INTERRUPT,
+                                            urb->transfer_dma,
+                                            urb->transfer_buffer_length,
+                                            0, /* control_header */
+                                            0, /* iso_start_frame */
+                                            0, /* iso_number_packets */
+                                            NULL, /* iso_packets */
+                                            urb);
+}
+
+
+/**
+ * Call to submit a USB Control transfer to a pipe.
+ *
+ * @usb:           USB device state populated by cvmx_usb_initialize().
+ * @pipe:          Handle to the pipe for the transfer.
+ * @urb:           URB.
+ *
+ * Returns: A submitted transaction or NULL on failure.
+ */
+static struct cvmx_usb_transaction *cvmx_usb_submit_control(struct cvmx_usb_state *usb,
+                                                           struct cvmx_usb_pipe *pipe,
+                                                           struct urb *urb)
+{
+       int buffer_length = urb->transfer_buffer_length;
+       uint64_t control_header = urb->setup_dma;
+       union cvmx_usb_control_header *header =
+               cvmx_phys_to_ptr(control_header);
+
+       if ((header->s.request_type & 0x80) == 0)
+               buffer_length = le16_to_cpu(header->s.length);
+
+       return __cvmx_usb_submit_transaction(usb, pipe,
+                                            CVMX_USB_TRANSFER_CONTROL,
+                                            urb->transfer_dma, buffer_length,
+                                            control_header,
+                                            0, /* iso_start_frame */
+                                            0, /* iso_number_packets */
+                                            NULL, /* iso_packets */
+                                            urb);
+}
+
+
+/**
+ * Call to submit a USB Isochronous transfer to a pipe.
+ *
+ * @usb:           USB device state populated by cvmx_usb_initialize().
+ * @pipe:          Handle to the pipe for the transfer.
+ * @urb:           URB returned when the callback is called.
+ *
+ * Returns: A submitted transaction or NULL on failure.
+ */
+static struct cvmx_usb_transaction *cvmx_usb_submit_isochronous(struct cvmx_usb_state *usb,
+                                                               struct cvmx_usb_pipe *pipe,
+                                                               struct urb *urb)
+{
+       struct cvmx_usb_iso_packet *packets;
+
+       packets = (struct cvmx_usb_iso_packet *) urb->setup_packet;
+       return __cvmx_usb_submit_transaction(usb, pipe,
+                                            CVMX_USB_TRANSFER_ISOCHRONOUS,
+                                            urb->transfer_dma,
+                                            urb->transfer_buffer_length,
+                                            0, /* control_header */
+                                            urb->start_frame,
+                                            urb->number_of_packets,
+                                            packets, urb);
+}
+
+
+/**
+ * Cancel one outstanding request in a pipe. Canceling a request
+ * can fail if the transaction has already completed before cancel
+ * is called. Even after a successful cancel call, it may take
+ * a frame or two for the cvmx_usb_poll() function to call the
+ * associated callback.
+ *
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @pipe:       Pipe to cancel requests in.
+ * @transaction: Transaction to cancel, returned by the submit function.
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
+                          struct cvmx_usb_pipe *pipe,
+                          struct cvmx_usb_transaction *transaction)
+{
+       /*
+        * If the transaction is the HEAD of the queue and scheduled. We need to
+        * treat it special
+        */
+       if (list_first_entry(&pipe->transactions, typeof(*transaction), node) ==
+           transaction && (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
+               union cvmx_usbcx_hccharx usbc_hcchar;
+
+               usb->pipe_for_channel[pipe->channel] = NULL;
+               pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
+
+               CVMX_SYNCW;
+
+               usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
+               /*
+                * If the channel isn't enabled then the transaction already
+                * completed.
+                */
+               if (usbc_hcchar.s.chena) {
+                       usbc_hcchar.s.chdis = 1;
+                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32);
+               }
+       }
+       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL);
+       return 0;
+}
+
+
+/**
+ * Cancel all outstanding requests in a pipe. Logically all this
+ * does is call cvmx_usb_cancel() in a loop.
+ *
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @pipe:       Pipe to cancel requests in.
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_cancel_all(struct cvmx_usb_state *usb,
+                              struct cvmx_usb_pipe *pipe)
+{
+       struct cvmx_usb_transaction *transaction, *next;
+
+       /* Simply loop through and attempt to cancel each transaction */
+       list_for_each_entry_safe(transaction, next, &pipe->transactions, node) {
+               int result = cvmx_usb_cancel(usb, pipe, transaction);
+               if (unlikely(result != 0))
+                       return result;
+       }
+       return 0;
+}
+
+
+/**
+ * Close a pipe created with cvmx_usb_open_pipe().
+ *
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @pipe:       Pipe to close.
+ *
+ * Returns: 0 or a negative error code. EBUSY is returned if the pipe has
+ *         outstanding transfers.
+ */
+static int cvmx_usb_close_pipe(struct cvmx_usb_state *usb,
+                              struct cvmx_usb_pipe *pipe)
+{
+       /* Fail if the pipe has pending transactions */
+       if (!list_empty(&pipe->transactions))
+               return -EBUSY;
+
+       list_del(&pipe->node);
+       kfree(pipe);
+
+       return 0;
+}
+
+/**
+ * Get the current USB protocol level frame number. The frame
+ * number is always in the range of 0-0x7ff.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: USB frame number
+ */
+static int cvmx_usb_get_frame_number(struct cvmx_usb_state *usb)
+{
+       int frame_number;
+       union cvmx_usbcx_hfnum usbc_hfnum;
+
+       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
+       frame_number = usbc_hfnum.s.frnum;
+
+       return frame_number;
+}
+
+
+/**
+ * Poll a channel for status
+ *
+ * @usb:     USB device
+ * @channel: Channel to poll
+ *
+ * Returns: Zero on success
+ */
+static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
+{
+       union cvmx_usbcx_hcintx usbc_hcint;
+       union cvmx_usbcx_hctsizx usbc_hctsiz;
+       union cvmx_usbcx_hccharx usbc_hcchar;
+       struct cvmx_usb_pipe *pipe;
+       struct cvmx_usb_transaction *transaction;
+       int bytes_this_transfer;
+       int bytes_in_last_packet;
+       int packets_processed;
+       int buffer_space_left;
+
+       /* Read the interrupt status bits for the channel */
+       usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
+
+       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
+               usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
+
+               if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis) {
+                       /*
+                        * There seems to be a bug in CN31XX which can cause
+                        * interrupt IN transfers to get stuck until we do a
+                        * write of HCCHARX without changing things
+                        */
+                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
+                       return 0;
+               }
+
+               /*
+                * In non DMA mode the channels don't halt themselves. We need
+                * to manually disable channels that are left running
+                */
+               if (!usbc_hcint.s.chhltd) {
+                       if (usbc_hcchar.s.chena) {
+                               union cvmx_usbcx_hcintmskx hcintmsk;
+                               /* Disable all interrupts except CHHLTD */
+                               hcintmsk.u32 = 0;
+                               hcintmsk.s.chhltdmsk = 1;
+                               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), hcintmsk.u32);
+                               usbc_hcchar.s.chdis = 1;
+                               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
+                               return 0;
+                       } else if (usbc_hcint.s.xfercompl) {
+                               /*
+                                * Successful IN/OUT with transfer complete.
+                                * Channel halt isn't needed.
+                                */
+                       } else {
+                               cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", usb->index, channel);
+                               return 0;
+                       }
+               }
+       } else {
+               /*
+                * There is are no interrupts that we need to process when the
+                * channel is still running
+                */
+               if (!usbc_hcint.s.chhltd)
+                       return 0;
+       }
+
+       /* Disable the channel interrupts now that it is done */
+       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
+       usb->idle_hardware_channels |= (1<<channel);
+
+       /* Make sure this channel is tied to a valid pipe */
+       pipe = usb->pipe_for_channel[channel];
+       CVMX_PREFETCH(pipe, 0);
+       CVMX_PREFETCH(pipe, 128);
+       if (!pipe)
+               return 0;
+       transaction = list_first_entry(&pipe->transactions, typeof(*transaction),
+                                      node);
+       CVMX_PREFETCH(transaction, 0);
+
+       /*
+        * Disconnect this pipe from the HW channel. Later the schedule
+        * function will figure out which pipe needs to go
+        */
+       usb->pipe_for_channel[channel] = NULL;
+       pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
+
+       /*
+        * Read the channel config info so we can figure out how much data
+        * transfered
+        */
+       usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
+       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
+
+       /*
+        * Calculating the number of bytes successfully transferred is dependent
+        * on the transfer direction
+        */
+       packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt;
+       if (usbc_hcchar.s.epdir) {
+               /*
+                * IN transactions are easy. For every byte received the
+                * hardware decrements xfersize. All we need to do is subtract
+                * the current value of xfersize from its starting value and we
+                * know how many bytes were written to the buffer
+                */
+               bytes_this_transfer = transaction->xfersize - usbc_hctsiz.s.xfersize;
+       } else {
+               /*
+                * OUT transaction don't decrement xfersize. Instead pktcnt is
+                * decremented on every successful packet send. The hardware
+                * does this when it receives an ACK, or NYET. If it doesn't
+                * receive one of these responses pktcnt doesn't change
+                */
+               bytes_this_transfer = packets_processed * usbc_hcchar.s.mps;
+               /*
+                * The last packet may not be a full transfer if we didn't have
+                * enough data
+                */
+               if (bytes_this_transfer > transaction->xfersize)
+                       bytes_this_transfer = transaction->xfersize;
+       }
+       /* Figure out how many bytes were in the last packet of the transfer */
+       if (packets_processed)
+               bytes_in_last_packet = bytes_this_transfer - (packets_processed-1) * usbc_hcchar.s.mps;
+       else
+               bytes_in_last_packet = bytes_this_transfer;
+
+       /*
+        * As a special case, setup transactions output the setup header, not
+        * the user's data. For this reason we don't count setup data as bytes
+        * transferred
+        */
+       if ((transaction->stage == CVMX_USB_STAGE_SETUP) ||
+               (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE))
+               bytes_this_transfer = 0;
+
+       /*
+        * Add the bytes transferred to the running total. It is important that
+        * bytes_this_transfer doesn't count any data that needs to be
+        * retransmitted
+        */
+       transaction->actual_bytes += bytes_this_transfer;
+       if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
+               buffer_space_left = transaction->iso_packets[0].length - transaction->actual_bytes;
+       else
+               buffer_space_left = transaction->buffer_length - transaction->actual_bytes;
+
+       /*
+        * We need to remember the PID toggle state for the next transaction.
+        * The hardware already updated it for the next transaction
+        */
+       pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0);
+
+       /*
+        * For high speed bulk out, assume the next transaction will need to do
+        * a ping before proceeding. If this isn't true the ACK processing below
+        * will clear this flag
+        */
+       if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
+               (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
+               (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
+               pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
+
+       if (usbc_hcint.s.stall) {
+               /*
+                * STALL as a response means this transaction cannot be
+                * completed because the device can't process transactions. Tell
+                * the user. Any data that was transferred will be counted on
+                * the actual bytes transferred
+                */
+               pipe->pid_toggle = 0;
+               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
+       } else if (usbc_hcint.s.xacterr) {
+               /*
+                * We know at least one packet worked if we get a ACK or NAK.
+                * Reset the retry counter
+                */
+               if (usbc_hcint.s.nak || usbc_hcint.s.ack)
+                       transaction->retries = 0;
+               transaction->retries++;
+               if (transaction->retries > MAX_RETRIES) {
+                       /*
+                        * XactErr as a response means the device signaled
+                        * something wrong with the transfer. For example, PID
+                        * toggle errors cause these
+                        */
+                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
+               } else {
+                       /*
+                        * If this was a split then clear our split in progress
+                        * marker
+                        */
+                       if (usb->active_split == transaction)
+                               usb->active_split = NULL;
+                       /*
+                        * Rewind to the beginning of the transaction by anding
+                        * off the split complete bit
+                        */
+                       transaction->stage &= ~1;
+                       pipe->split_sc_frame = -1;
+                       pipe->next_tx_frame += pipe->interval;
+                       if (pipe->next_tx_frame < usb->frame_number)
+                               pipe->next_tx_frame = usb->frame_number + pipe->interval -
+                                                     (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
+               }
+       } else if (usbc_hcint.s.bblerr) {
+               /* Babble Error (BblErr) */
+               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
+       } else if (usbc_hcint.s.datatglerr) {
+               /* We'll retry the exact same transaction again */
+               transaction->retries++;
+       } else if (usbc_hcint.s.nyet) {
+               /*
+                * NYET as a response is only allowed in three cases: as a
+                * response to a ping, as a response to a split transaction, and
+                * as a response to a bulk out. The ping case is handled by
+                * hardware, so we only have splits and bulk out
+                */
+               if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       transaction->retries = 0;
+                       /*
+                        * If there is more data to go then we need to try
+                        * again. Otherwise this transaction is complete
+                        */
+                       if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+               } else {
+                       /*
+                        * Split transactions retry the split complete 4 times
+                        * then rewind to the start split and do the entire
+                        * transactions again
+                        */
+                       transaction->retries++;
+                       if ((transaction->retries & 0x3) == 0) {
+                               /*
+                                * Rewind to the beginning of the transaction by
+                                * anding off the split complete bit
+                                */
+                               transaction->stage &= ~1;
+                               pipe->split_sc_frame = -1;
+                       }
+               }
+       } else if (usbc_hcint.s.ack) {
+               transaction->retries = 0;
+               /*
+                * The ACK bit can only be checked after the other error bits.
+                * This is because a multi packet transfer may succeed in a
+                * number of packets and then get a different response on the
+                * last packet. In this case both ACK and the last response bit
+                * will be set. If none of the other response bits is set, then
+                * the last packet must have been an ACK
+                *
+                * Since we got an ACK, we know we don't need to do a ping on
+                * this pipe
+                */
+               pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING;
+
+               switch (transaction->type) {
+               case CVMX_USB_TRANSFER_CONTROL:
+                       switch (transaction->stage) {
+                       case CVMX_USB_STAGE_NON_CONTROL:
+                       case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
+                               /* This should be impossible */
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
+                               break;
+                       case CVMX_USB_STAGE_SETUP:
+                               pipe->pid_toggle = 1;
+                               if (__cvmx_usb_pipe_needs_split(usb, pipe))
+                                       transaction->stage = CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
+                               else {
+                                       union cvmx_usb_control_header *header =
+                                               cvmx_phys_to_ptr(transaction->control_header);
+                                       if (header->s.length)
+                                               transaction->stage = CVMX_USB_STAGE_DATA;
+                                       else
+                                               transaction->stage = CVMX_USB_STAGE_STATUS;
+                               }
+                               break;
+                       case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
+                               {
+                                       union cvmx_usb_control_header *header =
+                                               cvmx_phys_to_ptr(transaction->control_header);
+                                       if (header->s.length)
+                                               transaction->stage = CVMX_USB_STAGE_DATA;
+                                       else
+                                               transaction->stage = CVMX_USB_STAGE_STATUS;
+                               }
+                               break;
+                       case CVMX_USB_STAGE_DATA:
+                               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                                       transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
+                                       /*
+                                        * For setup OUT data that are splits,
+                                        * the hardware doesn't appear to count
+                                        * transferred data. Here we manually
+                                        * update the data transferred
+                                        */
+                                       if (!usbc_hcchar.s.epdir) {
+                                               if (buffer_space_left < pipe->max_packet)
+                                                       transaction->actual_bytes += buffer_space_left;
+                                               else
+                                                       transaction->actual_bytes += pipe->max_packet;
+                                       }
+                               } else if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
+                                       pipe->pid_toggle = 1;
+                                       transaction->stage = CVMX_USB_STAGE_STATUS;
+                               }
+                               break;
+                       case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
+                               if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
+                                       pipe->pid_toggle = 1;
+                                       transaction->stage = CVMX_USB_STAGE_STATUS;
+                               } else {
+                                       transaction->stage = CVMX_USB_STAGE_DATA;
+                               }
+                               break;
+                       case CVMX_USB_STAGE_STATUS:
+                               if (__cvmx_usb_pipe_needs_split(usb, pipe))
+                                       transaction->stage = CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
+                               else
+                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                               break;
+                       case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                               break;
+                       }
+                       break;
+               case CVMX_USB_TRANSFER_BULK:
+               case CVMX_USB_TRANSFER_INTERRUPT:
+                       /*
+                        * The only time a bulk transfer isn't complete when it
+                        * finishes with an ACK is during a split transaction.
+                        * For splits we need to continue the transfer if more
+                        * data is needed
+                        */
+                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                               if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL)
+                                       transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
+                               else {
+                                       if (buffer_space_left && (bytes_in_last_packet == pipe->max_packet))
+                                               transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
+                                       else {
+                                               if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
+                                                       pipe->next_tx_frame += pipe->interval;
+                                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                                       }
+                               }
+                       } else {
+                               if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
+                                   (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
+                                   (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
+                                   (usbc_hcint.s.nak))
+                                       pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
+                               if (!buffer_space_left || (bytes_in_last_packet < pipe->max_packet)) {
+                                       if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
+                                               pipe->next_tx_frame += pipe->interval;
+                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                               }
+                       }
+                       break;
+               case CVMX_USB_TRANSFER_ISOCHRONOUS:
+                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                               /*
+                                * ISOCHRONOUS OUT splits don't require a
+                                * complete split stage. Instead they use a
+                                * sequence of begin OUT splits to transfer the
+                                * data 188 bytes at a time. Once the transfer
+                                * is complete, the pipe sleeps until the next
+                                * schedule interval
+                                */
+                               if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
+                                       /*
+                                        * If no space left or this wasn't a max
+                                        * size packet then this transfer is
+                                        * complete. Otherwise start it again to
+                                        * send the next 188 bytes
+                                        */
+                                       if (!buffer_space_left || (bytes_this_transfer < 188)) {
+                                               pipe->next_tx_frame += pipe->interval;
+                                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                                       }
+                               } else {
+                                       if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE) {
+                                               /*
+                                                * We are in the incoming data
+                                                * phase. Keep getting data
+                                                * until we run out of space or
+                                                * get a small packet
+                                                */
+                                               if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
+                                                       pipe->next_tx_frame += pipe->interval;
+                                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                                               }
+                                       } else
+                                               transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
+                               }
+                       } else {
+                               pipe->next_tx_frame += pipe->interval;
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                       }
+                       break;
+               }
+       } else if (usbc_hcint.s.nak) {
+               /*
+                * If this was a split then clear our split in progress marker.
+                */
+               if (usb->active_split == transaction)
+                       usb->active_split = NULL;
+               /*
+                * NAK as a response means the device couldn't accept the
+                * transaction, but it should be retried in the future. Rewind
+                * to the beginning of the transaction by anding off the split
+                * complete bit. Retry in the next interval
+                */
+               transaction->retries = 0;
+               transaction->stage &= ~1;
+               pipe->next_tx_frame += pipe->interval;
+               if (pipe->next_tx_frame < usb->frame_number)
+                       pipe->next_tx_frame = usb->frame_number + pipe->interval -
+                               (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
+       } else {
+               struct cvmx_usb_port_status port;
+               port = cvmx_usb_get_status(usb);
+               if (port.port_enabled) {
+                       /* We'll retry the exact same transaction again */
+                       transaction->retries++;
+               } else {
+                       /*
+                        * We get channel halted interrupts with no result bits
+                        * sets when the cable is unplugged
+                        */
+                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
+               }
+       }
+       return 0;
+}
+
+static void octeon_usb_port_callback(struct cvmx_usb_state *usb)
+{
+       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
+
+       spin_unlock(&priv->lock);
+       usb_hcd_poll_rh_status(octeon_to_hcd(priv));
+       spin_lock(&priv->lock);
+}
+
+/**
+ * Poll the USB block for status and call all needed callback
+ * handlers. This function is meant to be called in the interrupt
+ * handler for the USB controller. It can also be called
+ * periodically in a loop for non-interrupt based operation.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_poll(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_hfnum usbc_hfnum;
+       union cvmx_usbcx_gintsts usbc_gintsts;
+
+       CVMX_PREFETCH(usb, 0);
+       CVMX_PREFETCH(usb, 1*128);
+       CVMX_PREFETCH(usb, 2*128);
+       CVMX_PREFETCH(usb, 3*128);
+       CVMX_PREFETCH(usb, 4*128);
+
+       /* Update the frame counter */
+       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
+       if ((usb->frame_number&0x3fff) > usbc_hfnum.s.frnum)
+               usb->frame_number += 0x4000;
+       usb->frame_number &= ~0x3fffull;
+       usb->frame_number |= usbc_hfnum.s.frnum;
+
+       /* Read the pending interrupts */
+       usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTSTS(usb->index));
+
+       /* Clear the interrupts now that we know about them */
+       __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index), usbc_gintsts.u32);
+
+       if (usbc_gintsts.s.rxflvl) {
+               /*
+                * RxFIFO Non-Empty (RxFLvl)
+                * Indicates that there is at least one packet pending to be
+                * read from the RxFIFO.
+                *
+                * In DMA mode this is handled by hardware
+                */
+               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+                       __cvmx_usb_poll_rx_fifo(usb);
+       }
+       if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp) {
+               /* Fill the Tx FIFOs when not in DMA mode */
+               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+                       __cvmx_usb_poll_tx_fifo(usb);
+       }
+       if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint) {
+               union cvmx_usbcx_hprt usbc_hprt;
+               /*
+                * Disconnect Detected Interrupt (DisconnInt)
+                * Asserted when a device disconnect is detected.
+                *
+                * Host Port Interrupt (PrtInt)
+                * The core sets this bit to indicate a change in port status of
+                * one of the O2P USB core ports in Host mode. The application
+                * must read the Host Port Control and Status (HPRT) register to
+                * determine the exact event that caused this interrupt. The
+                * application must clear the appropriate status bit in the Host
+                * Port Control and Status register to clear this bit.
+                *
+                * Call the user's port callback
+                */
+               octeon_usb_port_callback(usb);
+               /* Clear the port change bits */
+               usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
+               usbc_hprt.s.prtena = 0;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index), usbc_hprt.u32);
+       }
+       if (usbc_gintsts.s.hchint) {
+               /*
+                * Host Channels Interrupt (HChInt)
+                * The core sets this bit to indicate that an interrupt is
+                * pending on one of the channels of the core (in Host mode).
+                * The application must read the Host All Channels Interrupt
+                * (HAINT) register to determine the exact number of the channel
+                * on which the interrupt occurred, and then read the
+                * corresponding Host Channel-n Interrupt (HCINTn) register to
+                * determine the exact cause of the interrupt. The application
+                * must clear the appropriate status bit in the HCINTn register
+                * to clear this bit.
+                */
+               union cvmx_usbcx_haint usbc_haint;
+               usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
+               while (usbc_haint.u32) {
+                       int channel;
+
+                       channel = __fls(usbc_haint.u32);
+                       __cvmx_usb_poll_channel(usb, channel);
+                       usbc_haint.u32 ^= 1<<channel;
+               }
+       }
+
+       __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
+
+       return 0;
+}
+
+/* convert between an HCD pointer and the corresponding struct octeon_hcd */
+static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
+{
+       return (struct octeon_hcd *)(hcd->hcd_priv);
+}
+
+static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
+{
+       struct octeon_hcd *priv = hcd_to_octeon(hcd);
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       cvmx_usb_poll(&priv->usb);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return IRQ_HANDLED;
+}
+
+static int octeon_usb_start(struct usb_hcd *hcd)
+{
+       hcd->state = HC_STATE_RUNNING;
+       return 0;
+}
+
+static void octeon_usb_stop(struct usb_hcd *hcd)
+{
+       hcd->state = HC_STATE_HALT;
+}
+
+static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
+{
+       struct octeon_hcd *priv = hcd_to_octeon(hcd);
+
+       return cvmx_usb_get_frame_number(&priv->usb);
 }
 
 static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
@@ -206,8 +3006,8 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
 {
        struct octeon_hcd *priv = hcd_to_octeon(hcd);
        struct device *dev = hcd->self.controller;
-       int submit_handle = -1;
-       int pipe_handle;
+       struct cvmx_usb_transaction *transaction = NULL;
+       struct cvmx_usb_pipe *pipe;
        unsigned long flags;
        struct cvmx_usb_iso_packet *iso_packet;
        struct usb_host_endpoint *ep = urb->ep;
@@ -276,26 +3076,24 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
                                dev = dev->parent;
                        }
                }
-               pipe_handle = cvmx_usb_open_pipe(&priv->usb,
-                                                0,
-                                                usb_pipedevice(urb->pipe),
-                                                usb_pipeendpoint(urb->pipe),
-                                                speed,
-                                                le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff,
-                                                transfer_type,
-                                                usb_pipein(urb->pipe) ? CVMX_USB_DIRECTION_IN : CVMX_USB_DIRECTION_OUT,
-                                                urb->interval,
-                                                (le16_to_cpu(ep->desc.wMaxPacketSize) >> 11) & 0x3,
-                                                split_device,
-                                                split_port);
-               if (pipe_handle < 0) {
+               pipe = cvmx_usb_open_pipe(&priv->usb, usb_pipedevice(urb->pipe),
+                                         usb_pipeendpoint(urb->pipe), speed,
+                                         le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff,
+                                         transfer_type,
+                                         usb_pipein(urb->pipe) ?
+                                               CVMX_USB_DIRECTION_IN :
+                                               CVMX_USB_DIRECTION_OUT,
+                                         urb->interval,
+                                         (le16_to_cpu(ep->desc.wMaxPacketSize) >> 11) & 0x3,
+                                         split_device, split_port);
+               if (!pipe) {
                        spin_unlock_irqrestore(&priv->lock, flags);
                        dev_dbg(dev, "Failed to create pipe\n");
                        return -ENOMEM;
                }
-               ep->hcpriv = (void *)(0x10000L + pipe_handle);
+               ep->hcpriv = pipe;
        } else {
-               pipe_handle = 0xffff & (long)ep->hcpriv;
+               pipe = ep->hcpriv;
        }
 
        switch (usb_pipetype(urb->pipe)) {
@@ -323,20 +3121,13 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
                         * this saves us a bunch of logic.
                         */
                        urb->setup_packet = (char *)iso_packet;
-                       submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
-                                                       urb->start_frame,
-                                                       0 /* flags */ ,
-                                                       urb->number_of_packets,
-                                                       iso_packet,
-                                                       urb->transfer_dma,
-                                                       urb->transfer_buffer_length,
-                                                       octeon_usb_urb_complete_callback,
-                                                       urb);
+                       transaction = cvmx_usb_submit_isochronous(&priv->usb,
+                                                                 pipe, urb);
                        /*
                         * If submit failed we need to free our private packet
                         * list.
                         */
-                       if (submit_handle < 0) {
+                       if (!transaction) {
                                urb->setup_packet = NULL;
                                kfree(iso_packet);
                        }
@@ -345,59 +3136,41 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
        case PIPE_INTERRUPT:
                dev_dbg(dev, "Submit interrupt to %d.%d\n",
                        usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
-               submit_handle = cvmx_usb_submit_interrupt(&priv->usb, pipe_handle,
-                                             urb->transfer_dma,
-                                             urb->transfer_buffer_length,
-                                             octeon_usb_urb_complete_callback,
-                                             urb);
+               transaction = cvmx_usb_submit_interrupt(&priv->usb, pipe, urb);
                break;
        case PIPE_CONTROL:
                dev_dbg(dev, "Submit control to %d.%d\n",
                        usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
-               submit_handle = cvmx_usb_submit_control(&priv->usb, pipe_handle,
-                                           urb->setup_dma,
-                                           urb->transfer_dma,
-                                           urb->transfer_buffer_length,
-                                           octeon_usb_urb_complete_callback,
-                                           urb);
+               transaction = cvmx_usb_submit_control(&priv->usb, pipe, urb);
                break;
        case PIPE_BULK:
                dev_dbg(dev, "Submit bulk to %d.%d\n",
                        usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
-               submit_handle = cvmx_usb_submit_bulk(&priv->usb, pipe_handle,
-                                        urb->transfer_dma,
-                                        urb->transfer_buffer_length,
-                                        octeon_usb_urb_complete_callback,
-                                        urb);
+               transaction = cvmx_usb_submit_bulk(&priv->usb, pipe, urb);
                break;
        }
-       if (submit_handle < 0) {
+       if (!transaction) {
                spin_unlock_irqrestore(&priv->lock, flags);
                dev_dbg(dev, "Failed to submit\n");
                return -ENOMEM;
        }
-       urb->hcpriv = (void *)(long)(((submit_handle & 0xffff) << 16) | pipe_handle);
+       urb->hcpriv = transaction;
        spin_unlock_irqrestore(&priv->lock, flags);
        return 0;
 }
 
 static void octeon_usb_urb_dequeue_work(unsigned long arg)
 {
+       struct urb *urb;
+       struct urb *next;
        unsigned long flags;
        struct octeon_hcd *priv = (struct octeon_hcd *)arg;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       while (!list_empty(&priv->dequeue_list)) {
-               int pipe_handle;
-               int submit_handle;
-               struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list);
-               list_del(&urb->urb_list);
-               /* not enqueued on dequeue_list */
-               INIT_LIST_HEAD(&urb->urb_list);
-               pipe_handle = 0xffff & (long)urb->hcpriv;
-               submit_handle = ((long)urb->hcpriv) >> 16;
-               cvmx_usb_cancel(&priv->usb, pipe_handle, submit_handle);
+       list_for_each_entry_safe(urb, next, &priv->dequeue_list, urb_list) {
+               list_del_init(&urb->urb_list);
+               cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -429,12 +3202,12 @@ static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_end
 
        if (ep->hcpriv) {
                struct octeon_hcd *priv = hcd_to_octeon(hcd);
-               int pipe_handle = 0xffff & (long)ep->hcpriv;
+               struct cvmx_usb_pipe *pipe = ep->hcpriv;
                unsigned long flags;
                spin_lock_irqsave(&priv->lock, flags);
-               cvmx_usb_cancel_all(&priv->usb, pipe_handle);
-               if (cvmx_usb_close_pipe(&priv->usb, pipe_handle))
-                       dev_dbg(dev, "Closing pipe %d failed\n", pipe_handle);
+               cvmx_usb_cancel_all(&priv->usb, pipe);
+               if (cvmx_usb_close_pipe(&priv->usb, pipe))
+                       dev_dbg(dev, "Closing pipe %p failed\n", pipe);
                spin_unlock_irqrestore(&priv->lock, flags);
                ep->hcpriv = NULL;
        }
@@ -506,7 +3279,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        dev_dbg(dev, " C_CONNECTION\n");
                        /* Clears drivers internal connect status change flag */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                case USB_PORT_FEAT_C_RESET:
@@ -515,7 +3288,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                         * Clears the driver's internal Port Reset Change flag.
                         */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                case USB_PORT_FEAT_C_ENABLE:
@@ -525,7 +3298,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                         * Change flag.
                         */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                case USB_PORT_FEAT_C_SUSPEND:
@@ -540,7 +3313,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        dev_dbg(dev, " C_OVER_CURRENT\n");
                        /* Clears the driver's overcurrent Change flag */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                default:
@@ -705,7 +3478,7 @@ static int octeon_usb_driver_probe(struct device *dev)
        tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
        INIT_LIST_HEAD(&priv->dequeue_list);
 
-       status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
+       status = cvmx_usb_initialize(&priv->usb, usb_num);
        if (status) {
                dev_dbg(dev, "USB initialization failed with %d\n", status);
                kfree(hcd);
diff --git a/drivers/staging/octeon-usb/octeon-hcd.h b/drivers/staging/octeon-usb/octeon-hcd.h
new file mode 100644 (file)
index 0000000..42fe4fe
--- /dev/null
@@ -0,0 +1,1819 @@
+/*
+ * Octeon HCD hardware register definitions.
+ *
+ * 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.
+ *
+ * Some parts of the code were originally released under BSD license:
+ *
+ * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). 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 Cavium Networks 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, including technical data, may be subject to U.S. export
+ * control laws, including the U.S. Export Administration Act and its associated
+ * regulations, and may be subject to export or import regulations in other
+ * countries.
+ *
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
+ * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
+ * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
+ * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
+ * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
+ * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
+ * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ */
+
+#ifndef __OCTEON_HCD_H__
+#define __OCTEON_HCD_H__
+
+#define CVMX_USBCXBASE 0x00016F0010000000ull
+#define CVMX_USBCXREG1(reg, bid) \
+       (CVMX_ADD_IO_SEG(CVMX_USBCXBASE | reg) + \
+        ((bid) & 1) * 0x100000000000ull)
+#define CVMX_USBCXREG2(reg, bid, off) \
+       (CVMX_ADD_IO_SEG(CVMX_USBCXBASE | reg) + \
+        (((off) & 7) + ((bid) & 1) * 0x8000000000ull) * 32)
+
+#define CVMX_USBCX_GAHBCFG(bid)                CVMX_USBCXREG1(0x008, bid)
+#define CVMX_USBCX_GHWCFG3(bid)                CVMX_USBCXREG1(0x04c, bid)
+#define CVMX_USBCX_GINTMSK(bid)                CVMX_USBCXREG1(0x018, bid)
+#define CVMX_USBCX_GINTSTS(bid)                CVMX_USBCXREG1(0x014, bid)
+#define CVMX_USBCX_GNPTXFSIZ(bid)      CVMX_USBCXREG1(0x028, bid)
+#define CVMX_USBCX_GNPTXSTS(bid)       CVMX_USBCXREG1(0x02c, bid)
+#define CVMX_USBCX_GOTGCTL(bid)                CVMX_USBCXREG1(0x000, bid)
+#define CVMX_USBCX_GRSTCTL(bid)                CVMX_USBCXREG1(0x010, bid)
+#define CVMX_USBCX_GRXFSIZ(bid)                CVMX_USBCXREG1(0x024, bid)
+#define CVMX_USBCX_GRXSTSPH(bid)       CVMX_USBCXREG1(0x020, bid)
+#define CVMX_USBCX_GUSBCFG(bid)                CVMX_USBCXREG1(0x00c, bid)
+#define CVMX_USBCX_HAINT(bid)          CVMX_USBCXREG1(0x414, bid)
+#define CVMX_USBCX_HAINTMSK(bid)       CVMX_USBCXREG1(0x418, bid)
+#define CVMX_USBCX_HCCHARX(off, bid)   CVMX_USBCXREG2(0x500, bid, off)
+#define CVMX_USBCX_HCFG(bid)           CVMX_USBCXREG1(0x400, bid)
+#define CVMX_USBCX_HCINTMSKX(off, bid) CVMX_USBCXREG2(0x50c, bid, off)
+#define CVMX_USBCX_HCINTX(off, bid)    CVMX_USBCXREG2(0x508, bid, off)
+#define CVMX_USBCX_HCSPLTX(off, bid)   CVMX_USBCXREG2(0x504, bid, off)
+#define CVMX_USBCX_HCTSIZX(off, bid)   CVMX_USBCXREG2(0x510, bid, off)
+#define CVMX_USBCX_HFIR(bid)           CVMX_USBCXREG1(0x404, bid)
+#define CVMX_USBCX_HFNUM(bid)          CVMX_USBCXREG1(0x408, bid)
+#define CVMX_USBCX_HPRT(bid)           CVMX_USBCXREG1(0x440, bid)
+#define CVMX_USBCX_HPTXFSIZ(bid)       CVMX_USBCXREG1(0x100, bid)
+#define CVMX_USBCX_HPTXSTS(bid)                CVMX_USBCXREG1(0x410, bid)
+
+#define CVMX_USBNXBID1(bid) (((bid) & 1) * 0x10000000ull)
+#define CVMX_USBNXBID2(bid) (((bid) & 1) * 0x100000000000ull)
+
+#define CVMX_USBNXREG1(reg, bid) \
+       (CVMX_ADD_IO_SEG(0x0001180068000000ull | reg) + CVMX_USBNXBID1(bid))
+#define CVMX_USBNXREG2(reg, bid) \
+       (CVMX_ADD_IO_SEG(0x00016F0000000000ull | reg) + CVMX_USBNXBID2(bid))
+
+#define CVMX_USBNX_CLK_CTL(bid)                CVMX_USBNXREG1(0x10, bid)
+#define CVMX_USBNX_DMA0_INB_CHN0(bid)  CVMX_USBNXREG2(0x818, bid)
+#define CVMX_USBNX_DMA0_OUTB_CHN0(bid) CVMX_USBNXREG2(0x858, bid)
+#define CVMX_USBNX_USBP_CTL_STATUS(bid)        CVMX_USBNXREG1(0x18, bid)
+
+/**
+ * cvmx_usbc#_gahbcfg
+ *
+ * Core AHB Configuration Register (GAHBCFG)
+ *
+ * This register can be used to configure the core after power-on or a change in
+ * mode of operation. This register mainly contains AHB system-related
+ * configuration parameters. The AHB is the processor interface to the O2P USB
+ * core. In general, software need not know about this interface except to
+ * program the values as specified.
+ *
+ * The application must program this register as part of the O2P USB core
+ * initialization. Do not change this register after the initial programming.
+ */
+union cvmx_usbcx_gahbcfg {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_gahbcfg_s
+        * @ptxfemplvl: Periodic TxFIFO Empty Level (PTxFEmpLvl)
+        *      Software should set this bit to 0x1.
+        *      Indicates when the Periodic TxFIFO Empty Interrupt bit in the
+        *      Core Interrupt register (GINTSTS.PTxFEmp) is triggered. This
+        *      bit is used only in Slave mode.
+        *      * 1'b0: GINTSTS.PTxFEmp interrupt indicates that the Periodic
+        *      TxFIFO is half empty
+        *      * 1'b1: GINTSTS.PTxFEmp interrupt indicates that the Periodic
+        *      TxFIFO is completely empty
+        * @nptxfemplvl: Non-Periodic TxFIFO Empty Level (NPTxFEmpLvl)
+        *      Software should set this bit to 0x1.
+        *      Indicates when the Non-Periodic TxFIFO Empty Interrupt bit in
+        *      the Core Interrupt register (GINTSTS.NPTxFEmp) is triggered.
+        *      This bit is used only in Slave mode.
+        *      * 1'b0: GINTSTS.NPTxFEmp interrupt indicates that the Non-
+        *      Periodic TxFIFO is half empty
+        *      * 1'b1: GINTSTS.NPTxFEmp interrupt indicates that the Non-
+        *      Periodic TxFIFO is completely empty
+        * @dmaen: DMA Enable (DMAEn)
+        *      * 1'b0: Core operates in Slave mode
+        *      * 1'b1: Core operates in a DMA mode
+        * @hbstlen: Burst Length/Type (HBstLen)
+        *      This field has not effect and should be left as 0x0.
+        * @glblintrmsk: Global Interrupt Mask (GlblIntrMsk)
+        *      Software should set this field to 0x1.
+        *      The application uses this bit to mask or unmask the interrupt
+        *      line assertion to itself. Irrespective of this bit's setting,
+        *      the interrupt status registers are updated by the core.
+        *      * 1'b0: Mask the interrupt assertion to the application.
+        *      * 1'b1: Unmask the interrupt assertion to the application.
+        */
+       struct cvmx_usbcx_gahbcfg_s {
+               uint32_t reserved_9_31  : 23;
+               uint32_t ptxfemplvl     : 1;
+               uint32_t nptxfemplvl    : 1;
+               uint32_t reserved_6_6   : 1;
+               uint32_t dmaen          : 1;
+               uint32_t hbstlen        : 4;
+               uint32_t glblintrmsk    : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_ghwcfg3
+ *
+ * User HW Config3 Register (GHWCFG3)
+ *
+ * This register contains the configuration options of the O2P USB core.
+ */
+union cvmx_usbcx_ghwcfg3 {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_ghwcfg3_s
+        * @dfifodepth: DFIFO Depth (DfifoDepth)
+        *      This value is in terms of 32-bit words.
+        *      * Minimum value is 32
+        *      * Maximum value is 32768
+        * @ahbphysync: AHB and PHY Synchronous (AhbPhySync)
+        *      Indicates whether AHB and PHY clocks are synchronous to
+        *      each other.
+        *      * 1'b0: No
+        *      * 1'b1: Yes
+        *      This bit is tied to 1.
+        * @rsttype: Reset Style for Clocked always Blocks in RTL (RstType)
+        *      * 1'b0: Asynchronous reset is used in the core
+        *      * 1'b1: Synchronous reset is used in the core
+        * @optfeature: Optional Features Removed (OptFeature)
+        *      Indicates whether the User ID register, GPIO interface ports,
+        *      and SOF toggle and counter ports were removed for gate count
+        *      optimization.
+        * @vendor_control_interface_support: Vendor Control Interface Support
+        *      * 1'b0: Vendor Control Interface is not available on the core.
+        *      * 1'b1: Vendor Control Interface is available.
+        * @i2c_selection: I2C Selection
+        *      * 1'b0: I2C Interface is not available on the core.
+        *      * 1'b1: I2C Interface is available on the core.
+        * @otgen: OTG Function Enabled (OtgEn)
+        *      The application uses this bit to indicate the O2P USB core's
+        *      OTG capabilities.
+        *      * 1'b0: Not OTG capable
+        *      * 1'b1: OTG Capable
+        * @pktsizewidth: Width of Packet Size Counters (PktSizeWidth)
+        *      * 3'b000: 4 bits
+        *      * 3'b001: 5 bits
+        *      * 3'b010: 6 bits
+        *      * 3'b011: 7 bits
+        *      * 3'b100: 8 bits
+        *      * 3'b101: 9 bits
+        *      * 3'b110: 10 bits
+        *      * Others: Reserved
+        * @xfersizewidth: Width of Transfer Size Counters (XferSizeWidth)
+        *      * 4'b0000: 11 bits
+        *      * 4'b0001: 12 bits
+        *      - ...
+        *      * 4'b1000: 19 bits
+        *      * Others: Reserved
+        */
+       struct cvmx_usbcx_ghwcfg3_s {
+               uint32_t dfifodepth                             : 16;
+               uint32_t reserved_13_15                         : 3;
+               uint32_t ahbphysync                             : 1;
+               uint32_t rsttype                                : 1;
+               uint32_t optfeature                             : 1;
+               uint32_t vendor_control_interface_support       : 1;
+               uint32_t i2c_selection                          : 1;
+               uint32_t otgen                                  : 1;
+               uint32_t pktsizewidth                           : 3;
+               uint32_t xfersizewidth                          : 4;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_gintmsk
+ *
+ * Core Interrupt Mask Register (GINTMSK)
+ *
+ * This register works with the Core Interrupt register to interrupt the
+ * application. When an interrupt bit is masked, the interrupt associated with
+ * that bit will not be generated. However, the Core Interrupt (GINTSTS)
+ * register bit corresponding to that interrupt will still be set.
+ * Mask interrupt: 1'b0, Unmask interrupt: 1'b1
+ */
+union cvmx_usbcx_gintmsk {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_gintmsk_s
+        * @wkupintmsk: Resume/Remote Wakeup Detected Interrupt Mask
+        *      (WkUpIntMsk)
+        * @sessreqintmsk: Session Request/New Session Detected Interrupt Mask
+        *      (SessReqIntMsk)
+        * @disconnintmsk: Disconnect Detected Interrupt Mask (DisconnIntMsk)
+        * @conidstschngmsk: Connector ID Status Change Mask (ConIDStsChngMsk)
+        * @ptxfempmsk: Periodic TxFIFO Empty Mask (PTxFEmpMsk)
+        * @hchintmsk: Host Channels Interrupt Mask (HChIntMsk)
+        * @prtintmsk: Host Port Interrupt Mask (PrtIntMsk)
+        * @fetsuspmsk: Data Fetch Suspended Mask (FetSuspMsk)
+        * @incomplpmsk: Incomplete Periodic Transfer Mask (incomplPMsk)
+        *      Incomplete Isochronous OUT Transfer Mask
+        *      (incompISOOUTMsk)
+        * @incompisoinmsk: Incomplete Isochronous IN Transfer Mask
+        *                  (incompISOINMsk)
+        * @oepintmsk: OUT Endpoints Interrupt Mask (OEPIntMsk)
+        * @inepintmsk: IN Endpoints Interrupt Mask (INEPIntMsk)
+        * @epmismsk: Endpoint Mismatch Interrupt Mask (EPMisMsk)
+        * @eopfmsk: End of Periodic Frame Interrupt Mask (EOPFMsk)
+        * @isooutdropmsk: Isochronous OUT Packet Dropped Interrupt Mask
+        *      (ISOOutDropMsk)
+        * @enumdonemsk: Enumeration Done Mask (EnumDoneMsk)
+        * @usbrstmsk: USB Reset Mask (USBRstMsk)
+        * @usbsuspmsk: USB Suspend Mask (USBSuspMsk)
+        * @erlysuspmsk: Early Suspend Mask (ErlySuspMsk)
+        * @i2cint: I2C Interrupt Mask (I2CINT)
+        * @ulpickintmsk: ULPI Carkit Interrupt Mask (ULPICKINTMsk)
+        *      I2C Carkit Interrupt Mask (I2CCKINTMsk)
+        * @goutnakeffmsk: Global OUT NAK Effective Mask (GOUTNakEffMsk)
+        * @ginnakeffmsk: Global Non-Periodic IN NAK Effective Mask
+        *                (GINNakEffMsk)
+        * @nptxfempmsk: Non-Periodic TxFIFO Empty Mask (NPTxFEmpMsk)
+        * @rxflvlmsk: Receive FIFO Non-Empty Mask (RxFLvlMsk)
+        * @sofmsk: Start of (micro)Frame Mask (SofMsk)
+        * @otgintmsk: OTG Interrupt Mask (OTGIntMsk)
+        * @modemismsk: Mode Mismatch Interrupt Mask (ModeMisMsk)
+        */
+       struct cvmx_usbcx_gintmsk_s {
+               uint32_t wkupintmsk             : 1;
+               uint32_t sessreqintmsk          : 1;
+               uint32_t disconnintmsk          : 1;
+               uint32_t conidstschngmsk        : 1;
+               uint32_t reserved_27_27         : 1;
+               uint32_t ptxfempmsk             : 1;
+               uint32_t hchintmsk              : 1;
+               uint32_t prtintmsk              : 1;
+               uint32_t reserved_23_23         : 1;
+               uint32_t fetsuspmsk             : 1;
+               uint32_t incomplpmsk            : 1;
+               uint32_t incompisoinmsk         : 1;
+               uint32_t oepintmsk              : 1;
+               uint32_t inepintmsk             : 1;
+               uint32_t epmismsk               : 1;
+               uint32_t reserved_16_16         : 1;
+               uint32_t eopfmsk                : 1;
+               uint32_t isooutdropmsk          : 1;
+               uint32_t enumdonemsk            : 1;
+               uint32_t usbrstmsk              : 1;
+               uint32_t usbsuspmsk             : 1;
+               uint32_t erlysuspmsk            : 1;
+               uint32_t i2cint                 : 1;
+               uint32_t ulpickintmsk           : 1;
+               uint32_t goutnakeffmsk          : 1;
+               uint32_t ginnakeffmsk           : 1;
+               uint32_t nptxfempmsk            : 1;
+               uint32_t rxflvlmsk              : 1;
+               uint32_t sofmsk                 : 1;
+               uint32_t otgintmsk              : 1;
+               uint32_t modemismsk             : 1;
+               uint32_t reserved_0_0           : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_gintsts
+ *
+ * Core Interrupt Register (GINTSTS)
+ *
+ * This register interrupts the application for system-level events in the
+ * current mode of operation (Device mode or Host mode). It is shown in
+ * Interrupt. Some of the bits in this register are valid only in Host mode,
+ * while others are valid in Device mode only. This register also indicates the
+ * current mode of operation. In order to clear the interrupt status bits of
+ * type R_SS_WC, the application must write 1'b1 into the bit. The FIFO status
+ * interrupts are read only; once software reads from or writes to the FIFO
+ * while servicing these interrupts, FIFO interrupt conditions are cleared
+ * automatically.
+ */
+union cvmx_usbcx_gintsts {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_gintsts_s
+        * @wkupint: Resume/Remote Wakeup Detected Interrupt (WkUpInt)
+        *      In Device mode, this interrupt is asserted when a resume is
+        *      detected on the USB. In Host mode, this interrupt is asserted
+        *      when a remote wakeup is detected on the USB.
+        *      For more information on how to use this interrupt, see "Partial
+        *      Power-Down and Clock Gating Programming Model" on
+        *      page 353.
+        * @sessreqint: Session Request/New Session Detected Interrupt
+        *              (SessReqInt)
+        *      In Host mode, this interrupt is asserted when a session request
+        *      is detected from the device. In Device mode, this interrupt is
+        *      asserted when the utmiotg_bvalid signal goes high.
+        *      For more information on how to use this interrupt, see "Partial
+        *      Power-Down and Clock Gating Programming Model" on
+        *      page 353.
+        * @disconnint: Disconnect Detected Interrupt (DisconnInt)
+        *      Asserted when a device disconnect is detected.
+        * @conidstschng: Connector ID Status Change (ConIDStsChng)
+        *      The core sets this bit when there is a change in connector ID
+        *      status.
+        * @ptxfemp: Periodic TxFIFO Empty (PTxFEmp)
+        *      Asserted when the Periodic Transmit FIFO is either half or
+        *      completely empty and there is space for at least one entry to be
+        *      written in the Periodic Request Queue. The half or completely
+        *      empty status is determined by the Periodic TxFIFO Empty Level
+        *      bit in the Core AHB Configuration register
+        *      (GAHBCFG.PTxFEmpLvl).
+        * @hchint: Host Channels Interrupt (HChInt)
+        *      The core sets this bit to indicate that an interrupt is pending
+        *      on one of the channels of the core (in Host mode). The
+        *      application must read the Host All Channels Interrupt (HAINT)
+        *      register to determine the exact number of the channel on which
+        *      the interrupt occurred, and then read the corresponding Host
+        *      Channel-n Interrupt (HCINTn) register to determine the exact
+        *      cause of the interrupt. The application must clear the
+        *      appropriate status bit in the HCINTn register to clear this bit.
+        * @prtint: Host Port Interrupt (PrtInt)
+        *      The core sets this bit to indicate a change in port status of
+        *      one of the O2P USB core ports in Host mode. The application must
+        *      read the Host Port Control and Status (HPRT) register to
+        *      determine the exact event that caused this interrupt. The
+        *      application must clear the appropriate status bit in the Host
+        *      Port Control and Status register to clear this bit.
+        * @fetsusp: Data Fetch Suspended (FetSusp)
+        *      This interrupt is valid only in DMA mode. This interrupt
+        *      indicates that the core has stopped fetching data for IN
+        *      endpoints due to the unavailability of TxFIFO space or Request
+        *      Queue space. This interrupt is used by the application for an
+        *      endpoint mismatch algorithm.
+        * @incomplp: Incomplete Periodic Transfer (incomplP)
+        *      In Host mode, the core sets this interrupt bit when there are
+        *      incomplete periodic transactions still pending which are
+        *      scheduled for the current microframe.
+        *      Incomplete Isochronous OUT Transfer (incompISOOUT)
+        *      The Device mode, the core sets this interrupt to indicate that
+        *      there is at least one isochronous OUT endpoint on which the
+        *      transfer is not completed in the current microframe. This
+        *      interrupt is asserted along with the End of Periodic Frame
+        *      Interrupt (EOPF) bit in this register.
+        * @incompisoin: Incomplete Isochronous IN Transfer (incompISOIN)
+        *      The core sets this interrupt to indicate that there is at least
+        *      one isochronous IN endpoint on which the transfer is not
+        *      completed in the current microframe. This interrupt is asserted
+        *      along with the End of Periodic Frame Interrupt (EOPF) bit in
+        *      this register.
+        * @oepint: OUT Endpoints Interrupt (OEPInt)
+        *      The core sets this bit to indicate that an interrupt is pending
+        *      on one of the OUT endpoints of the core (in Device mode). The
+        *      application must read the Device All Endpoints Interrupt
+        *      (DAINT) register to determine the exact number of the OUT
+        *      endpoint on which the interrupt occurred, and then read the
+        *      corresponding Device OUT Endpoint-n Interrupt (DOEPINTn)
+        *      register to determine the exact cause of the interrupt. The
+        *      application must clear the appropriate status bit in the
+        *      corresponding DOEPINTn register to clear this bit.
+        * @iepint: IN Endpoints Interrupt (IEPInt)
+        *      The core sets this bit to indicate that an interrupt is pending
+        *      on one of the IN endpoints of the core (in Device mode). The
+        *      application must read the Device All Endpoints Interrupt
+        *      (DAINT) register to determine the exact number of the IN
+        *      endpoint on which the interrupt occurred, and then read the
+        *      corresponding Device IN Endpoint-n Interrupt (DIEPINTn)
+        *      register to determine the exact cause of the interrupt. The
+        *      application must clear the appropriate status bit in the
+        *      corresponding DIEPINTn register to clear this bit.
+        * @epmis: Endpoint Mismatch Interrupt (EPMis)
+        *      Indicates that an IN token has been received for a non-periodic
+        *      endpoint, but the data for another endpoint is present in the
+        *      top of the Non-Periodic Transmit FIFO and the IN endpoint
+        *      mismatch count programmed by the application has expired.
+        * @eopf: End of Periodic Frame Interrupt (EOPF)
+        *      Indicates that the period specified in the Periodic Frame
+        *      Interval field of the Device Configuration register
+        *      (DCFG.PerFrInt) has been reached in the current microframe.
+        * @isooutdrop: Isochronous OUT Packet Dropped Interrupt (ISOOutDrop)
+        *      The core sets this bit when it fails to write an isochronous OUT
+        *      packet into the RxFIFO because the RxFIFO doesn't have
+        *      enough space to accommodate a maximum packet size packet
+        *      for the isochronous OUT endpoint.
+        * @enumdone: Enumeration Done (EnumDone)
+        *      The core sets this bit to indicate that speed enumeration is
+        *      complete. The application must read the Device Status (DSTS)
+        *      register to obtain the enumerated speed.
+        * @usbrst: USB Reset (USBRst)
+        *      The core sets this bit to indicate that a reset is detected on
+        *      the USB.
+        * @usbsusp: USB Suspend (USBSusp)
+        *      The core sets this bit to indicate that a suspend was detected
+        *      on the USB. The core enters the Suspended state when there
+        *      is no activity on the phy_line_state_i signal for an extended
+        *      period of time.
+        * @erlysusp: Early Suspend (ErlySusp)
+        *      The core sets this bit to indicate that an Idle state has been
+        *      detected on the USB for 3 ms.
+        * @i2cint: I2C Interrupt (I2CINT)
+        *      This bit is always 0x0.
+        * @ulpickint: ULPI Carkit Interrupt (ULPICKINT)
+        *      This bit is always 0x0.
+        * @goutnakeff: Global OUT NAK Effective (GOUTNakEff)
+        *      Indicates that the Set Global OUT NAK bit in the Device Control
+        *      register (DCTL.SGOUTNak), set by the application, has taken
+        *      effect in the core. This bit can be cleared by writing the Clear
+        *      Global OUT NAK bit in the Device Control register
+        *      (DCTL.CGOUTNak).
+        * @ginnakeff: Global IN Non-Periodic NAK Effective (GINNakEff)
+        *      Indicates that the Set Global Non-Periodic IN NAK bit in the
+        *      Device Control register (DCTL.SGNPInNak), set by the
+        *      application, has taken effect in the core. That is, the core has
+        *      sampled the Global IN NAK bit set by the application. This bit
+        *      can be cleared by clearing the Clear Global Non-Periodic IN
+        *      NAK bit in the Device Control register (DCTL.CGNPInNak).
+        *      This interrupt does not necessarily mean that a NAK handshake
+        *      is sent out on the USB. The STALL bit takes precedence over
+        *      the NAK bit.
+        * @nptxfemp: Non-Periodic TxFIFO Empty (NPTxFEmp)
+        *      This interrupt is asserted when the Non-Periodic TxFIFO is
+        *      either half or completely empty, and there is space for at least
+        *      one entry to be written to the Non-Periodic Transmit Request
+        *      Queue. The half or completely empty status is determined by
+        *      the Non-Periodic TxFIFO Empty Level bit in the Core AHB
+        *      Configuration register (GAHBCFG.NPTxFEmpLvl).
+        * @rxflvl: RxFIFO Non-Empty (RxFLvl)
+        *      Indicates that there is at least one packet pending to be read
+        *      from the RxFIFO.
+        * @sof: Start of (micro)Frame (Sof)
+        *      In Host mode, the core sets this bit to indicate that an SOF
+        *      (FS), micro-SOF (HS), or Keep-Alive (LS) is transmitted on the
+        *      USB. The application must write a 1 to this bit to clear the
+        *      interrupt.
+        *      In Device mode, in the core sets this bit to indicate that an
+        *      SOF token has been received on the USB. The application can read
+        *      the Device Status register to get the current (micro)frame
+        *      number. This interrupt is seen only when the core is operating
+        *      at either HS or FS.
+        * @otgint: OTG Interrupt (OTGInt)
+        *      The core sets this bit to indicate an OTG protocol event. The
+        *      application must read the OTG Interrupt Status (GOTGINT)
+        *      register to determine the exact event that caused this
+        *      interrupt. The application must clear the appropriate status bit
+        *      in the GOTGINT register to clear this bit.
+        * @modemis: Mode Mismatch Interrupt (ModeMis)
+        *      The core sets this bit when the application is trying to access:
+        *      * A Host mode register, when the core is operating in Device
+        *      mode
+        *      * A Device mode register, when the core is operating in Host
+        *      mode
+        *      The register access is completed on the AHB with an OKAY
+        *      response, but is ignored by the core internally and doesn't
+        *      affect the operation of the core.
+        * @curmod: Current Mode of Operation (CurMod)
+        *      Indicates the current mode of operation.
+        *      * 1'b0: Device mode
+        *      * 1'b1: Host mode
+        */
+       struct cvmx_usbcx_gintsts_s {
+               uint32_t wkupint        : 1;
+               uint32_t sessreqint     : 1;
+               uint32_t disconnint     : 1;
+               uint32_t conidstschng   : 1;
+               uint32_t reserved_27_27 : 1;
+               uint32_t ptxfemp        : 1;
+               uint32_t hchint         : 1;
+               uint32_t prtint         : 1;
+               uint32_t reserved_23_23 : 1;
+               uint32_t fetsusp        : 1;
+               uint32_t incomplp       : 1;
+               uint32_t incompisoin    : 1;
+               uint32_t oepint         : 1;
+               uint32_t iepint         : 1;
+               uint32_t epmis          : 1;
+               uint32_t reserved_16_16 : 1;
+               uint32_t eopf           : 1;
+               uint32_t isooutdrop     : 1;
+               uint32_t enumdone       : 1;
+               uint32_t usbrst         : 1;
+               uint32_t usbsusp        : 1;
+               uint32_t erlysusp       : 1;
+               uint32_t i2cint         : 1;
+               uint32_t ulpickint      : 1;
+               uint32_t goutnakeff     : 1;
+               uint32_t ginnakeff      : 1;
+               uint32_t nptxfemp       : 1;
+               uint32_t rxflvl         : 1;
+               uint32_t sof            : 1;
+               uint32_t otgint         : 1;
+               uint32_t modemis        : 1;
+               uint32_t curmod         : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_gnptxfsiz
+ *
+ * Non-Periodic Transmit FIFO Size Register (GNPTXFSIZ)
+ *
+ * The application can program the RAM size and the memory start address for the
+ * Non-Periodic TxFIFO.
+ */
+union cvmx_usbcx_gnptxfsiz {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_gnptxfsiz_s
+        * @nptxfdep: Non-Periodic TxFIFO Depth (NPTxFDep)
+        *      This value is in terms of 32-bit words.
+        *      Minimum value is 16
+        *      Maximum value is 32768
+        * @nptxfstaddr: Non-Periodic Transmit RAM Start Address (NPTxFStAddr)
+        *      This field contains the memory start address for Non-Periodic
+        *      Transmit FIFO RAM.
+        */
+       struct cvmx_usbcx_gnptxfsiz_s {
+               uint32_t nptxfdep       : 16;
+               uint32_t nptxfstaddr    : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_gnptxsts
+ *
+ * Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS)
+ *
+ * This read-only register contains the free space information for the
+ * Non-Periodic TxFIFO and the Non-Periodic Transmit Request Queue.
+ */
+union cvmx_usbcx_gnptxsts {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_gnptxsts_s
+        * @nptxqtop: Top of the Non-Periodic Transmit Request Queue (NPTxQTop)
+        *      Entry in the Non-Periodic Tx Request Queue that is currently
+        *      being processed by the MAC.
+        *      * Bits [30:27]: Channel/endpoint number
+        *      * Bits [26:25]:
+        *      - 2'b00: IN/OUT token
+        *      - 2'b01: Zero-length transmit packet (device IN/host OUT)
+        *      - 2'b10: PING/CSPLIT token
+        *      - 2'b11: Channel halt command
+        *      * Bit [24]: Terminate (last entry for selected channel/endpoint)
+        * @nptxqspcavail: Non-Periodic Transmit Request Queue Space Available
+        *      (NPTxQSpcAvail)
+        *      Indicates the amount of free space available in the Non-
+        *      Periodic Transmit Request Queue. This queue holds both IN
+        *      and OUT requests in Host mode. Device mode has only IN
+        *      requests.
+        *      * 8'h0: Non-Periodic Transmit Request Queue is full
+        *      * 8'h1: 1 location available
+        *      * 8'h2: 2 locations available
+        *      * n: n locations available (0..8)
+        *      * Others: Reserved
+        * @nptxfspcavail: Non-Periodic TxFIFO Space Avail (NPTxFSpcAvail)
+        *      Indicates the amount of free space available in the Non-
+        *      Periodic TxFIFO.
+        *      Values are in terms of 32-bit words.
+        *      * 16'h0: Non-Periodic TxFIFO is full
+        *      * 16'h1: 1 word available
+        *      * 16'h2: 2 words available
+        *      * 16'hn: n words available (where 0..32768)
+        *      * 16'h8000: 32768 words available
+        *      * Others: Reserved
+        */
+       struct cvmx_usbcx_gnptxsts_s {
+               uint32_t reserved_31_31 : 1;
+               uint32_t nptxqtop       : 7;
+               uint32_t nptxqspcavail  : 8;
+               uint32_t nptxfspcavail  : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_grstctl
+ *
+ * Core Reset Register (GRSTCTL)
+ *
+ * The application uses this register to reset various hardware features inside
+ * the core.
+ */
+union cvmx_usbcx_grstctl {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_grstctl_s
+        * @ahbidle: AHB Master Idle (AHBIdle)
+        *      Indicates that the AHB Master State Machine is in the IDLE
+        *      condition.
+        * @dmareq: DMA Request Signal (DMAReq)
+        *      Indicates that the DMA request is in progress. Used for debug.
+        * @txfnum: TxFIFO Number (TxFNum)
+        *      This is the FIFO number that must be flushed using the TxFIFO
+        *      Flush bit. This field must not be changed until the core clears
+        *      the TxFIFO Flush bit.
+        *      * 5'h0: Non-Periodic TxFIFO flush
+        *      * 5'h1: Periodic TxFIFO 1 flush in Device mode or Periodic
+        *      TxFIFO flush in Host mode
+        *      * 5'h2: Periodic TxFIFO 2 flush in Device mode
+        *      - ...
+        *      * 5'hF: Periodic TxFIFO 15 flush in Device mode
+        *      * 5'h10: Flush all the Periodic and Non-Periodic TxFIFOs in the
+        *      core
+        * @txfflsh: TxFIFO Flush (TxFFlsh)
+        *      This bit selectively flushes a single or all transmit FIFOs, but
+        *      cannot do so if the core is in the midst of a transaction.
+        *      The application must only write this bit after checking that the
+        *      core is neither writing to the TxFIFO nor reading from the
+        *      TxFIFO.
+        *      The application must wait until the core clears this bit before
+        *      performing any operations. This bit takes 8 clocks (of phy_clk
+        *      or hclk, whichever is slower) to clear.
+        * @rxfflsh: RxFIFO Flush (RxFFlsh)
+        *      The application can flush the entire RxFIFO using this bit, but
+        *      must first ensure that the core is not in the middle of a
+        *      transaction.
+        *      The application must only write to this bit after checking that
+        *      the core is neither reading from the RxFIFO nor writing to the
+        *      RxFIFO.
+        *      The application must wait until the bit is cleared before
+        *      performing any other operations. This bit will take 8 clocks
+        *      (slowest of PHY or AHB clock) to clear.
+        * @intknqflsh: IN Token Sequence Learning Queue Flush (INTknQFlsh)
+        *      The application writes this bit to flush the IN Token Sequence
+        *      Learning Queue.
+        * @frmcntrrst: Host Frame Counter Reset (FrmCntrRst)
+        *      The application writes this bit to reset the (micro)frame number
+        *      counter inside the core. When the (micro)frame counter is reset,
+        *      the subsequent SOF sent out by the core will have a
+        *      (micro)frame number of 0.
+        * @hsftrst: HClk Soft Reset (HSftRst)
+        *      The application uses this bit to flush the control logic in the
+        *      AHB Clock domain. Only AHB Clock Domain pipelines are reset.
+        *      * FIFOs are not flushed with this bit.
+        *      * All state machines in the AHB clock domain are reset to the
+        *      Idle state after terminating the transactions on the AHB,
+        *      following the protocol.
+        *      * CSR control bits used by the AHB clock domain state
+        *      machines are cleared.
+        *      * To clear this interrupt, status mask bits that control the
+        *      interrupt status and are generated by the AHB clock domain
+        *      state machine are cleared.
+        *      * Because interrupt status bits are not cleared, the application
+        *      can get the status of any core events that occurred after it set
+        *      this bit.
+        *      This is a self-clearing bit that the core clears after all
+        *      necessary logic is reset in the core. This may take several
+        *      clocks, depending on the core's current state.
+        * @csftrst: Core Soft Reset (CSftRst)
+        *      Resets the hclk and phy_clock domains as follows:
+        *      * Clears the interrupts and all the CSR registers except the
+        *      following register bits:
+        *      - PCGCCTL.RstPdwnModule
+        *      - PCGCCTL.GateHclk
+        *      - PCGCCTL.PwrClmp
+        *      - PCGCCTL.StopPPhyLPwrClkSelclk
+        *      - GUSBCFG.PhyLPwrClkSel
+        *      - GUSBCFG.DDRSel
+        *      - GUSBCFG.PHYSel
+        *      - GUSBCFG.FSIntf
+        *      - GUSBCFG.ULPI_UTMI_Sel
+        *      - GUSBCFG.PHYIf
+        *      - HCFG.FSLSPclkSel
+        *      - DCFG.DevSpd
+        *      * All module state machines (except the AHB Slave Unit) are
+        *      reset to the IDLE state, and all the transmit FIFOs and the
+        *      receive FIFO are flushed.
+        *      * Any transactions on the AHB Master are terminated as soon
+        *      as possible, after gracefully completing the last data phase of
+        *      an AHB transfer. Any transactions on the USB are terminated
+        *      immediately.
+        *      The application can write to this bit any time it wants to reset
+        *      the core. This is a self-clearing bit and the core clears this
+        *      bit after all the necessary logic is reset in the core, which
+        *      may take several clocks, depending on the current state of the
+        *      core. Once this bit is cleared software should wait at least 3
+        *      PHY clocks before doing any access to the PHY domain
+        *      (synchronization delay). Software should also should check that
+        *      bit 31 of this register is 1 (AHB Master is IDLE) before
+        *      starting any operation.
+        *      Typically software reset is used during software development
+        *      and also when you dynamically change the PHY selection bits
+        *      in the USB configuration registers listed above. When you
+        *      change the PHY, the corresponding clock for the PHY is
+        *      selected and used in the PHY domain. Once a new clock is
+        *      selected, the PHY domain has to be reset for proper operation.
+        */
+       struct cvmx_usbcx_grstctl_s {
+               uint32_t ahbidle        : 1;
+               uint32_t dmareq         : 1;
+               uint32_t reserved_11_29 : 19;
+               uint32_t txfnum         : 5;
+               uint32_t txfflsh        : 1;
+               uint32_t rxfflsh        : 1;
+               uint32_t intknqflsh     : 1;
+               uint32_t frmcntrrst     : 1;
+               uint32_t hsftrst        : 1;
+               uint32_t csftrst        : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_grxfsiz
+ *
+ * Receive FIFO Size Register (GRXFSIZ)
+ *
+ * The application can program the RAM size that must be allocated to the
+ * RxFIFO.
+ */
+union cvmx_usbcx_grxfsiz {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_grxfsiz_s
+        * @rxfdep: RxFIFO Depth (RxFDep)
+        *      This value is in terms of 32-bit words.
+        *      * Minimum value is 16
+        *      * Maximum value is 32768
+        */
+       struct cvmx_usbcx_grxfsiz_s {
+               uint32_t reserved_16_31 : 16;
+               uint32_t rxfdep         : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_grxstsph
+ *
+ * Receive Status Read and Pop Register, Host Mode (GRXSTSPH)
+ *
+ * A read to the Receive Status Read and Pop register returns and additionally
+ * pops the top data entry out of the RxFIFO.
+ * This Description is only valid when the core is in Host Mode. For Device Mode
+ * use USBC_GRXSTSPD instead.
+ * NOTE: GRXSTSPH and GRXSTSPD are physically the same register and share the
+ *      same offset in the O2P USB core. The offset difference shown in this
+ *      document is for software clarity and is actually ignored by the
+ *       hardware.
+ */
+union cvmx_usbcx_grxstsph {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_grxstsph_s
+        * @pktsts: Packet Status (PktSts)
+        *      Indicates the status of the received packet
+        *      * 4'b0010: IN data packet received
+        *      * 4'b0011: IN transfer completed (triggers an interrupt)
+        *      * 4'b0101: Data toggle error (triggers an interrupt)
+        *      * 4'b0111: Channel halted (triggers an interrupt)
+        *      * Others: Reserved
+        * @dpid: Data PID (DPID)
+        *      * 2'b00: DATA0
+        *      * 2'b10: DATA1
+        *      * 2'b01: DATA2
+        *      * 2'b11: MDATA
+        * @bcnt: Byte Count (BCnt)
+        *      Indicates the byte count of the received IN data packet
+        * @chnum: Channel Number (ChNum)
+        *      Indicates the channel number to which the current received
+        *      packet belongs.
+        */
+       struct cvmx_usbcx_grxstsph_s {
+               uint32_t reserved_21_31 : 11;
+               uint32_t pktsts         : 4;
+               uint32_t dpid           : 2;
+               uint32_t bcnt           : 11;
+               uint32_t chnum          : 4;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_gusbcfg
+ *
+ * Core USB Configuration Register (GUSBCFG)
+ *
+ * This register can be used to configure the core after power-on or a changing
+ * to Host mode or Device mode. It contains USB and USB-PHY related
+ * configuration parameters. The application must program this register before
+ * starting any transactions on either the AHB or the USB. Do not make changes
+ * to this register after the initial programming.
+ */
+union cvmx_usbcx_gusbcfg {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_gusbcfg_s
+        * @otgi2csel: UTMIFS or I2C Interface Select (OtgI2CSel)
+        *      This bit is always 0x0.
+        * @phylpwrclksel: PHY Low-Power Clock Select (PhyLPwrClkSel)
+        *      Software should set this bit to 0x0.
+        *      Selects either 480-MHz or 48-MHz (low-power) PHY mode. In
+        *      FS and LS modes, the PHY can usually operate on a 48-MHz
+        *      clock to save power.
+        *      * 1'b0: 480-MHz Internal PLL clock
+        *      * 1'b1: 48-MHz External Clock
+        *      In 480 MHz mode, the UTMI interface operates at either 60 or
+        *      30-MHz, depending upon whether 8- or 16-bit data width is
+        *      selected. In 48-MHz mode, the UTMI interface operates at 48
+        *      MHz in FS mode and at either 48 or 6 MHz in LS mode
+        *      (depending on the PHY vendor).
+        *      This bit drives the utmi_fsls_low_power core output signal, and
+        *      is valid only for UTMI+ PHYs.
+        * @usbtrdtim: USB Turnaround Time (USBTrdTim)
+        *      Sets the turnaround time in PHY clocks.
+        *      Specifies the response time for a MAC request to the Packet
+        *      FIFO Controller (PFC) to fetch data from the DFIFO (SPRAM).
+        *      This must be programmed to 0x5.
+        * @hnpcap: HNP-Capable (HNPCap)
+        *      This bit is always 0x0.
+        * @srpcap: SRP-Capable (SRPCap)
+        *      This bit is always 0x0.
+        * @ddrsel: ULPI DDR Select (DDRSel)
+        *      Software should set this bit to 0x0.
+        * @physel: USB 2.0 High-Speed PHY or USB 1.1 Full-Speed Serial
+        *      Software should set this bit to 0x0.
+        * @fsintf: Full-Speed Serial Interface Select (FSIntf)
+        *      Software should set this bit to 0x0.
+        * @ulpi_utmi_sel: ULPI or UTMI+ Select (ULPI_UTMI_Sel)
+        *      This bit is always 0x0.
+        * @phyif: PHY Interface (PHYIf)
+        *      This bit is always 0x1.
+        * @toutcal: HS/FS Timeout Calibration (TOutCal)
+        *      The number of PHY clocks that the application programs in this
+        *      field is added to the high-speed/full-speed interpacket timeout
+        *      duration in the core to account for any additional delays
+        *      introduced by the PHY. This may be required, since the delay
+        *      introduced by the PHY in generating the linestate condition may
+        *      vary from one PHY to another.
+        *      The USB standard timeout value for high-speed operation is
+        *      736 to 816 (inclusive) bit times. The USB standard timeout
+        *      value for full-speed operation is 16 to 18 (inclusive) bit
+        *      times. The application must program this field based on the
+        *      speed of enumeration. The number of bit times added per PHY
+        *      clock are:
+        *      High-speed operation:
+        *      * One 30-MHz PHY clock = 16 bit times
+        *      * One 60-MHz PHY clock = 8 bit times
+        *      Full-speed operation:
+        *      * One 30-MHz PHY clock = 0.4 bit times
+        *      * One 60-MHz PHY clock = 0.2 bit times
+        *      * One 48-MHz PHY clock = 0.25 bit times
+        */
+       struct cvmx_usbcx_gusbcfg_s {
+               uint32_t reserved_17_31 : 15;
+               uint32_t otgi2csel      : 1;
+               uint32_t phylpwrclksel  : 1;
+               uint32_t reserved_14_14 : 1;
+               uint32_t usbtrdtim      : 4;
+               uint32_t hnpcap         : 1;
+               uint32_t srpcap         : 1;
+               uint32_t ddrsel         : 1;
+               uint32_t physel         : 1;
+               uint32_t fsintf         : 1;
+               uint32_t ulpi_utmi_sel  : 1;
+               uint32_t phyif          : 1;
+               uint32_t toutcal        : 3;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_haint
+ *
+ * Host All Channels Interrupt Register (HAINT)
+ *
+ * When a significant event occurs on a channel, the Host All Channels Interrupt
+ * register interrupts the application using the Host Channels Interrupt bit of
+ * the Core Interrupt register (GINTSTS.HChInt). This is shown in Interrupt.
+ * There is one interrupt bit per channel, up to a maximum of 16 bits. Bits in
+ * this register are set and cleared when the application sets and clears bits
+ * in the corresponding Host Channel-n Interrupt register.
+ */
+union cvmx_usbcx_haint {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_haint_s
+        * @haint: Channel Interrupts (HAINT)
+        *      One bit per channel: Bit 0 for Channel 0, bit 15 for Channel 15
+        */
+       struct cvmx_usbcx_haint_s {
+               uint32_t reserved_16_31 : 16;
+               uint32_t haint          : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_haintmsk
+ *
+ * Host All Channels Interrupt Mask Register (HAINTMSK)
+ *
+ * The Host All Channel Interrupt Mask register works with the Host All Channel
+ * Interrupt register to interrupt the application when an event occurs on a
+ * channel. There is one interrupt mask bit per channel, up to a maximum of 16
+ * bits.
+ * Mask interrupt: 1'b0 Unmask interrupt: 1'b1
+ */
+union cvmx_usbcx_haintmsk {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_haintmsk_s
+        * @haintmsk: Channel Interrupt Mask (HAINTMsk)
+        *      One bit per channel: Bit 0 for channel 0, bit 15 for channel 15
+        */
+       struct cvmx_usbcx_haintmsk_s {
+               uint32_t reserved_16_31 : 16;
+               uint32_t haintmsk       : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hcchar#
+ *
+ * Host Channel-n Characteristics Register (HCCHAR)
+ *
+ */
+union cvmx_usbcx_hccharx {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hccharx_s
+        * @chena: Channel Enable (ChEna)
+        *      This field is set by the application and cleared by the OTG
+        *      host.
+        *      * 1'b0: Channel disabled
+        *      * 1'b1: Channel enabled
+        * @chdis: Channel Disable (ChDis)
+        *      The application sets this bit to stop transmitting/receiving
+        *      data on a channel, even before the transfer for that channel is
+        *      complete. The application must wait for the Channel Disabled
+        *      interrupt before treating the channel as disabled.
+        * @oddfrm: Odd Frame (OddFrm)
+        *      This field is set (reset) by the application to indicate that
+        *      the OTG host must perform a transfer in an odd (micro)frame.
+        *      This field is applicable for only periodic (isochronous and
+        *      interrupt) transactions.
+        *      * 1'b0: Even (micro)frame
+        *      * 1'b1: Odd (micro)frame
+        * @devaddr: Device Address (DevAddr)
+        *      This field selects the specific device serving as the data
+        *      source or sink.
+        * @ec: Multi Count (MC) / Error Count (EC)
+        *      When the Split Enable bit of the Host Channel-n Split Control
+        *      register (HCSPLTn.SpltEna) is reset (1'b0), this field indicates
+        *      to the host the number of transactions that should be executed
+        *      per microframe for this endpoint.
+        *      * 2'b00: Reserved. This field yields undefined results.
+        *      * 2'b01: 1 transaction
+        *      * 2'b10: 2 transactions to be issued for this endpoint per
+        *      microframe
+        *      * 2'b11: 3 transactions to be issued for this endpoint per
+        *      microframe
+        *      When HCSPLTn.SpltEna is set (1'b1), this field indicates the
+        *      number of immediate retries to be performed for a periodic split
+        *      transactions on transaction errors. This field must be set to at
+        *      least 2'b01.
+        * @eptype: Endpoint Type (EPType)
+        *      Indicates the transfer type selected.
+        *      * 2'b00: Control
+        *      * 2'b01: Isochronous
+        *      * 2'b10: Bulk
+        *      * 2'b11: Interrupt
+        * @lspddev: Low-Speed Device (LSpdDev)
+        *      This field is set by the application to indicate that this
+        *      channel is communicating to a low-speed device.
+        * @epdir: Endpoint Direction (EPDir)
+        *      Indicates whether the transaction is IN or OUT.
+        *      * 1'b0: OUT
+        *      * 1'b1: IN
+        * @epnum: Endpoint Number (EPNum)
+        *      Indicates the endpoint number on the device serving as the
+        *      data source or sink.
+        * @mps: Maximum Packet Size (MPS)
+        *      Indicates the maximum packet size of the associated endpoint.
+        */
+       struct cvmx_usbcx_hccharx_s {
+               uint32_t chena          : 1;
+               uint32_t chdis          : 1;
+               uint32_t oddfrm         : 1;
+               uint32_t devaddr        : 7;
+               uint32_t ec             : 2;
+               uint32_t eptype         : 2;
+               uint32_t lspddev        : 1;
+               uint32_t reserved_16_16 : 1;
+               uint32_t epdir          : 1;
+               uint32_t epnum          : 4;
+               uint32_t mps            : 11;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hcfg
+ *
+ * Host Configuration Register (HCFG)
+ *
+ * This register configures the core after power-on. Do not make changes to this
+ * register after initializing the host.
+ */
+union cvmx_usbcx_hcfg {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hcfg_s
+        * @fslssupp: FS- and LS-Only Support (FSLSSupp)
+        *      The application uses this bit to control the core's enumeration
+        *      speed. Using this bit, the application can make the core
+        *      enumerate as a FS host, even if the connected device supports
+        *      HS traffic. Do not make changes to this field after initial
+        *      programming.
+        *      * 1'b0: HS/FS/LS, based on the maximum speed supported by
+        *      the connected device
+        *      * 1'b1: FS/LS-only, even if the connected device can support HS
+        * @fslspclksel: FS/LS PHY Clock Select (FSLSPclkSel)
+        *      When the core is in FS Host mode
+        *      * 2'b00: PHY clock is running at 30/60 MHz
+        *      * 2'b01: PHY clock is running at 48 MHz
+        *      * Others: Reserved
+        *      When the core is in LS Host mode
+        *      * 2'b00: PHY clock is running at 30/60 MHz. When the
+        *      UTMI+/ULPI PHY Low Power mode is not selected, use
+        *      30/60 MHz.
+        *      * 2'b01: PHY clock is running at 48 MHz. When the UTMI+
+        *      PHY Low Power mode is selected, use 48MHz if the PHY
+        *      supplies a 48 MHz clock during LS mode.
+        *      * 2'b10: PHY clock is running at 6 MHz. In USB 1.1 FS mode,
+        *      use 6 MHz when the UTMI+ PHY Low Power mode is
+        *      selected and the PHY supplies a 6 MHz clock during LS
+        *      mode. If you select a 6 MHz clock during LS mode, you must
+        *      do a soft reset.
+        *      * 2'b11: Reserved
+        */
+       struct cvmx_usbcx_hcfg_s {
+               uint32_t reserved_3_31  : 29;
+               uint32_t fslssupp       : 1;
+               uint32_t fslspclksel    : 2;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hcint#
+ *
+ * Host Channel-n Interrupt Register (HCINT)
+ *
+ * This register indicates the status of a channel with respect to USB- and
+ * AHB-related events. The application must read this register when the Host
+ * Channels Interrupt bit of the Core Interrupt register (GINTSTS.HChInt) is
+ * set. Before the application can read this register, it must first read
+ * the Host All Channels Interrupt (HAINT) register to get the exact channel
+ * number for the Host Channel-n Interrupt register. The application must clear
+ * the appropriate bit in this register to clear the corresponding bits in the
+ * HAINT and GINTSTS registers.
+ */
+union cvmx_usbcx_hcintx {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hcintx_s
+        * @datatglerr: Data Toggle Error (DataTglErr)
+        * @frmovrun: Frame Overrun (FrmOvrun)
+        * @bblerr: Babble Error (BblErr)
+        * @xacterr: Transaction Error (XactErr)
+        * @nyet: NYET Response Received Interrupt (NYET)
+        * @ack: ACK Response Received Interrupt (ACK)
+        * @nak: NAK Response Received Interrupt (NAK)
+        * @stall: STALL Response Received Interrupt (STALL)
+        * @ahberr: This bit is always 0x0.
+        * @chhltd: Channel Halted (ChHltd)
+        *      Indicates the transfer completed abnormally either because of
+        *      any USB transaction error or in response to disable request by
+        *      the application.
+        * @xfercompl: Transfer Completed (XferCompl)
+        *      Transfer completed normally without any errors.
+        */
+       struct cvmx_usbcx_hcintx_s {
+               uint32_t reserved_11_31 : 21;
+               uint32_t datatglerr     : 1;
+               uint32_t frmovrun       : 1;
+               uint32_t bblerr         : 1;
+               uint32_t xacterr        : 1;
+               uint32_t nyet           : 1;
+               uint32_t ack            : 1;
+               uint32_t nak            : 1;
+               uint32_t stall          : 1;
+               uint32_t ahberr         : 1;
+               uint32_t chhltd         : 1;
+               uint32_t xfercompl      : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hcintmsk#
+ *
+ * Host Channel-n Interrupt Mask Register (HCINTMSKn)
+ *
+ * This register reflects the mask for each channel status described in the
+ * previous section.
+ * Mask interrupt: 1'b0 Unmask interrupt: 1'b1
+ */
+union cvmx_usbcx_hcintmskx {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hcintmskx_s
+        * @datatglerrmsk: Data Toggle Error Mask (DataTglErrMsk)
+        * @frmovrunmsk: Frame Overrun Mask (FrmOvrunMsk)
+        * @bblerrmsk: Babble Error Mask (BblErrMsk)
+        * @xacterrmsk: Transaction Error Mask (XactErrMsk)
+        * @nyetmsk: NYET Response Received Interrupt Mask (NyetMsk)
+        * @ackmsk: ACK Response Received Interrupt Mask (AckMsk)
+        * @nakmsk: NAK Response Received Interrupt Mask (NakMsk)
+        * @stallmsk: STALL Response Received Interrupt Mask (StallMsk)
+        * @ahberrmsk: AHB Error Mask (AHBErrMsk)
+        * @chhltdmsk: Channel Halted Mask (ChHltdMsk)
+        * @xfercomplmsk: Transfer Completed Mask (XferComplMsk)
+        */
+       struct cvmx_usbcx_hcintmskx_s {
+               uint32_t reserved_11_31 : 21;
+               uint32_t datatglerrmsk  : 1;
+               uint32_t frmovrunmsk    : 1;
+               uint32_t bblerrmsk      : 1;
+               uint32_t xacterrmsk     : 1;
+               uint32_t nyetmsk        : 1;
+               uint32_t ackmsk         : 1;
+               uint32_t nakmsk         : 1;
+               uint32_t stallmsk       : 1;
+               uint32_t ahberrmsk      : 1;
+               uint32_t chhltdmsk      : 1;
+               uint32_t xfercomplmsk   : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hcsplt#
+ *
+ * Host Channel-n Split Control Register (HCSPLT)
+ *
+ */
+union cvmx_usbcx_hcspltx {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hcspltx_s
+        * @spltena: Split Enable (SpltEna)
+        *      The application sets this field to indicate that this channel is
+        *      enabled to perform split transactions.
+        * @compsplt: Do Complete Split (CompSplt)
+        *      The application sets this field to request the OTG host to
+        *      perform a complete split transaction.
+        * @xactpos: Transaction Position (XactPos)
+        *      This field is used to determine whether to send all, first,
+        *      middle, or last payloads with each OUT transaction.
+        *      * 2'b11: All. This is the entire data payload is of this
+        *      transaction (which is less than or equal to 188 bytes).
+        *      * 2'b10: Begin. This is the first data payload of this
+        *      transaction (which is larger than 188 bytes).
+        *      * 2'b00: Mid. This is the middle payload of this transaction
+        *      (which is larger than 188 bytes).
+        *      * 2'b01: End. This is the last payload of this transaction
+        *      (which is larger than 188 bytes).
+        * @hubaddr: Hub Address (HubAddr)
+        *      This field holds the device address of the transaction
+        *      translator's hub.
+        * @prtaddr: Port Address (PrtAddr)
+        *      This field is the port number of the recipient transaction
+        *      translator.
+        */
+       struct cvmx_usbcx_hcspltx_s {
+               uint32_t spltena        : 1;
+               uint32_t reserved_17_30 : 14;
+               uint32_t compsplt       : 1;
+               uint32_t xactpos        : 2;
+               uint32_t hubaddr        : 7;
+               uint32_t prtaddr        : 7;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hctsiz#
+ *
+ * Host Channel-n Transfer Size Register (HCTSIZ)
+ *
+ */
+union cvmx_usbcx_hctsizx {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hctsizx_s
+        * @dopng: Do Ping (DoPng)
+        *      Setting this field to 1 directs the host to do PING protocol.
+        * @pid: PID (Pid)
+        *      The application programs this field with the type of PID to use
+        *      for the initial transaction. The host will maintain this field
+        *      for the rest of the transfer.
+        *      * 2'b00: DATA0
+        *      * 2'b01: DATA2
+        *      * 2'b10: DATA1
+        *      * 2'b11: MDATA (non-control)/SETUP (control)
+        * @pktcnt: Packet Count (PktCnt)
+        *      This field is programmed by the application with the expected
+        *      number of packets to be transmitted (OUT) or received (IN).
+        *      The host decrements this count on every successful
+        *      transmission or reception of an OUT/IN packet. Once this count
+        *      reaches zero, the application is interrupted to indicate normal
+        *      completion.
+        * @xfersize: Transfer Size (XferSize)
+        *      For an OUT, this field is the number of data bytes the host will
+        *      send during the transfer.
+        *      For an IN, this field is the buffer size that the application
+        *      has reserved for the transfer. The application is expected to
+        *      program this field as an integer multiple of the maximum packet
+        *      size for IN transactions (periodic and non-periodic).
+        */
+       struct cvmx_usbcx_hctsizx_s {
+               uint32_t dopng          : 1;
+               uint32_t pid            : 2;
+               uint32_t pktcnt         : 10;
+               uint32_t xfersize       : 19;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hfir
+ *
+ * Host Frame Interval Register (HFIR)
+ *
+ * This register stores the frame interval information for the current speed to
+ * which the O2P USB core has enumerated.
+ */
+union cvmx_usbcx_hfir {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hfir_s
+        * @frint: Frame Interval (FrInt)
+        *      The value that the application programs to this field specifies
+        *      the interval between two consecutive SOFs (FS) or micro-
+        *      SOFs (HS) or Keep-Alive tokens (HS). This field contains the
+        *      number of PHY clocks that constitute the required frame
+        *      interval. The default value set in this field for a FS operation
+        *      when the PHY clock frequency is 60 MHz. The application can
+        *      write a value to this register only after the Port Enable bit of
+        *      the Host Port Control and Status register (HPRT.PrtEnaPort)
+        *      has been set. If no value is programmed, the core calculates
+        *      the value based on the PHY clock specified in the FS/LS PHY
+        *      Clock Select field of the Host Configuration register
+        *      (HCFG.FSLSPclkSel). Do not change the value of this field
+        *      after the initial configuration.
+        *      * 125 us (PHY clock frequency for HS)
+        *      * 1 ms (PHY clock frequency for FS/LS)
+        */
+       struct cvmx_usbcx_hfir_s {
+               uint32_t reserved_16_31 : 16;
+               uint32_t frint          : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hfnum
+ *
+ * Host Frame Number/Frame Time Remaining Register (HFNUM)
+ *
+ * This register indicates the current frame number.
+ * It also indicates the time remaining (in terms of the number of PHY clocks)
+ * in the current (micro)frame.
+ */
+union cvmx_usbcx_hfnum {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hfnum_s
+        * @frrem: Frame Time Remaining (FrRem)
+        *      Indicates the amount of time remaining in the current
+        *      microframe (HS) or frame (FS/LS), in terms of PHY clocks.
+        *      This field decrements on each PHY clock. When it reaches
+        *      zero, this field is reloaded with the value in the Frame
+        *      Interval register and a new SOF is transmitted on the USB.
+        * @frnum: Frame Number (FrNum)
+        *      This field increments when a new SOF is transmitted on the
+        *      USB, and is reset to 0 when it reaches 16'h3FFF.
+        */
+       struct cvmx_usbcx_hfnum_s {
+               uint32_t frrem  : 16;
+               uint32_t frnum  : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hprt
+ *
+ * Host Port Control and Status Register (HPRT)
+ *
+ * This register is available in both Host and Device modes.
+ * Currently, the OTG Host supports only one port.
+ * A single register holds USB port-related information such as USB reset,
+ * enable, suspend, resume, connect status, and test mode for each port. The
+ * R_SS_WC bits in this register can trigger an interrupt to the application
+ * through the Host Port Interrupt bit of the Core Interrupt register
+ * (GINTSTS.PrtInt). On a Port Interrupt, the application must read this
+ * register and clear the bit that caused the interrupt. For the R_SS_WC bits,
+ * the application must write a 1 to the bit to clear the interrupt.
+ */
+union cvmx_usbcx_hprt {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hprt_s
+        * @prtspd: Port Speed (PrtSpd)
+        *      Indicates the speed of the device attached to this port.
+        *      * 2'b00: High speed
+        *      * 2'b01: Full speed
+        *      * 2'b10: Low speed
+        *      * 2'b11: Reserved
+        * @prttstctl: Port Test Control (PrtTstCtl)
+        *      The application writes a nonzero value to this field to put
+        *      the port into a Test mode, and the corresponding pattern is
+        *      signaled on the port.
+        *      * 4'b0000: Test mode disabled
+        *      * 4'b0001: Test_J mode
+        *      * 4'b0010: Test_K mode
+        *      * 4'b0011: Test_SE0_NAK mode
+        *      * 4'b0100: Test_Packet mode
+        *      * 4'b0101: Test_Force_Enable
+        *      * Others: Reserved
+        *      PrtSpd must be zero (i.e. the interface must be in high-speed
+        *      mode) to use the PrtTstCtl test modes.
+        * @prtpwr: Port Power (PrtPwr)
+        *      The application uses this field to control power to this port,
+        *      and the core clears this bit on an overcurrent condition.
+        *      * 1'b0: Power off
+        *      * 1'b1: Power on
+        * @prtlnsts: Port Line Status (PrtLnSts)
+        *      Indicates the current logic level USB data lines
+        *      * Bit [10]: Logic level of D-
+        *      * Bit [11]: Logic level of D+
+        * @prtrst: Port Reset (PrtRst)
+        *      When the application sets this bit, a reset sequence is
+        *      started on this port. The application must time the reset
+        *      period and clear this bit after the reset sequence is
+        *      complete.
+        *      * 1'b0: Port not in reset
+        *      * 1'b1: Port in reset
+        *      The application must leave this bit set for at least a
+        *      minimum duration mentioned below to start a reset on the
+        *      port. The application can leave it set for another 10 ms in
+        *      addition to the required minimum duration, before clearing
+        *      the bit, even though there is no maximum limit set by the
+        *      USB standard.
+        *      * High speed: 50 ms
+        *      * Full speed/Low speed: 10 ms
+        * @prtsusp: Port Suspend (PrtSusp)
+        *      The application sets this bit to put this port in Suspend
+        *      mode. The core only stops sending SOFs when this is set.
+        *      To stop the PHY clock, the application must set the Port
+        *      Clock Stop bit, which will assert the suspend input pin of
+        *      the PHY.
+        *      The read value of this bit reflects the current suspend
+        *      status of the port. This bit is cleared by the core after a
+        *      remote wakeup signal is detected or the application sets
+        *      the Port Reset bit or Port Resume bit in this register or the
+        *      Resume/Remote Wakeup Detected Interrupt bit or
+        *      Disconnect Detected Interrupt bit in the Core Interrupt
+        *      register (GINTSTS.WkUpInt or GINTSTS.DisconnInt,
+        *      respectively).
+        *      * 1'b0: Port not in Suspend mode
+        *      * 1'b1: Port in Suspend mode
+        * @prtres: Port Resume (PrtRes)
+        *      The application sets this bit to drive resume signaling on
+        *      the port. The core continues to drive the resume signal
+        *      until the application clears this bit.
+        *      If the core detects a USB remote wakeup sequence, as
+        *      indicated by the Port Resume/Remote Wakeup Detected
+        *      Interrupt bit of the Core Interrupt register
+        *      (GINTSTS.WkUpInt), the core starts driving resume
+        *      signaling without application intervention and clears this bit
+        *      when it detects a disconnect condition. The read value of
+        *      this bit indicates whether the core is currently driving
+        *      resume signaling.
+        *      * 1'b0: No resume driven
+        *      * 1'b1: Resume driven
+        * @prtovrcurrchng: Port Overcurrent Change (PrtOvrCurrChng)
+        *      The core sets this bit when the status of the Port
+        *      Overcurrent Active bit (bit 4) in this register changes.
+        * @prtovrcurract: Port Overcurrent Active (PrtOvrCurrAct)
+        *      Indicates the overcurrent condition of the port.
+        *      * 1'b0: No overcurrent condition
+        *      * 1'b1: Overcurrent condition
+        * @prtenchng: Port Enable/Disable Change (PrtEnChng)
+        *      The core sets this bit when the status of the Port Enable bit
+        *      [2] of this register changes.
+        * @prtena: Port Enable (PrtEna)
+        *      A port is enabled only by the core after a reset sequence,
+        *      and is disabled by an overcurrent condition, a disconnect
+        *      condition, or by the application clearing this bit. The
+        *      application cannot set this bit by a register write. It can only
+        *      clear it to disable the port. This bit does not trigger any
+        *      interrupt to the application.
+        *      * 1'b0: Port disabled
+        *      * 1'b1: Port enabled
+        * @prtconndet: Port Connect Detected (PrtConnDet)
+        *      The core sets this bit when a device connection is detected
+        *      to trigger an interrupt to the application using the Host Port
+        *      Interrupt bit of the Core Interrupt register (GINTSTS.PrtInt).
+        *      The application must write a 1 to this bit to clear the
+        *      interrupt.
+        * @prtconnsts: Port Connect Status (PrtConnSts)
+        *      * 0: No device is attached to the port.
+        *      * 1: A device is attached to the port.
+        */
+       struct cvmx_usbcx_hprt_s {
+               uint32_t reserved_19_31 : 13;
+               uint32_t prtspd         : 2;
+               uint32_t prttstctl      : 4;
+               uint32_t prtpwr         : 1;
+               uint32_t prtlnsts       : 2;
+               uint32_t reserved_9_9   : 1;
+               uint32_t prtrst         : 1;
+               uint32_t prtsusp        : 1;
+               uint32_t prtres         : 1;
+               uint32_t prtovrcurrchng : 1;
+               uint32_t prtovrcurract  : 1;
+               uint32_t prtenchng      : 1;
+               uint32_t prtena         : 1;
+               uint32_t prtconndet     : 1;
+               uint32_t prtconnsts     : 1;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hptxfsiz
+ *
+ * Host Periodic Transmit FIFO Size Register (HPTXFSIZ)
+ *
+ * This register holds the size and the memory start address of the Periodic
+ * TxFIFO, as shown in Figures 310 and 311.
+ */
+union cvmx_usbcx_hptxfsiz {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hptxfsiz_s
+        * @ptxfsize: Host Periodic TxFIFO Depth (PTxFSize)
+        *      This value is in terms of 32-bit words.
+        *      * Minimum value is 16
+        *      * Maximum value is 32768
+        * @ptxfstaddr: Host Periodic TxFIFO Start Address (PTxFStAddr)
+        */
+       struct cvmx_usbcx_hptxfsiz_s {
+               uint32_t ptxfsize       : 16;
+               uint32_t ptxfstaddr     : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbc#_hptxsts
+ *
+ * Host Periodic Transmit FIFO/Queue Status Register (HPTXSTS)
+ *
+ * This read-only register contains the free space information for the Periodic
+ * TxFIFO and the Periodic Transmit Request Queue
+ */
+union cvmx_usbcx_hptxsts {
+       uint32_t u32;
+       /**
+        * struct cvmx_usbcx_hptxsts_s
+        * @ptxqtop: Top of the Periodic Transmit Request Queue (PTxQTop)
+        *      This indicates the entry in the Periodic Tx Request Queue that
+        *      is currently being processes by the MAC.
+        *      This register is used for debugging.
+        *      * Bit [31]: Odd/Even (micro)frame
+        *      - 1'b0: send in even (micro)frame
+        *      - 1'b1: send in odd (micro)frame
+        *      * Bits [30:27]: Channel/endpoint number
+        *      * Bits [26:25]: Type
+        *      - 2'b00: IN/OUT
+        *      - 2'b01: Zero-length packet
+        *      - 2'b10: CSPLIT
+        *      - 2'b11: Disable channel command
+        *      * Bit [24]: Terminate (last entry for the selected
+        *      channel/endpoint)
+        * @ptxqspcavail: Periodic Transmit Request Queue Space Available
+        *      (PTxQSpcAvail)
+        *      Indicates the number of free locations available to be written
+        *      in the Periodic Transmit Request Queue. This queue holds both
+        *      IN and OUT requests.
+        *      * 8'h0: Periodic Transmit Request Queue is full
+        *      * 8'h1: 1 location available
+        *      * 8'h2: 2 locations available
+        *      * n: n locations available (0..8)
+        *      * Others: Reserved
+        * @ptxfspcavail: Periodic Transmit Data FIFO Space Available
+        *                (PTxFSpcAvail)
+        *      Indicates the number of free locations available to be written
+        *      to in the Periodic TxFIFO.
+        *      Values are in terms of 32-bit words
+        *      * 16'h0: Periodic TxFIFO is full
+        *      * 16'h1: 1 word available
+        *      * 16'h2: 2 words available
+        *      * 16'hn: n words available (where 0..32768)
+        *      * 16'h8000: 32768 words available
+        *      * Others: Reserved
+        */
+       struct cvmx_usbcx_hptxsts_s {
+               uint32_t ptxqtop        : 8;
+               uint32_t ptxqspcavail   : 8;
+               uint32_t ptxfspcavail   : 16;
+       } s;
+};
+
+/**
+ * cvmx_usbn#_clk_ctl
+ *
+ * USBN_CLK_CTL = USBN's Clock Control
+ *
+ * This register is used to control the frequency of the hclk and the
+ * hreset and phy_rst signals.
+ */
+union cvmx_usbnx_clk_ctl {
+       uint64_t u64;
+       /**
+        * struct cvmx_usbnx_clk_ctl_s
+        * @divide2: The 'hclk' used by the USB subsystem is derived
+        *      from the eclk.
+        *      Also see the field DIVIDE. DIVIDE2<1> must currently
+        *      be zero because it is not implemented, so the maximum
+        *      ratio of eclk/hclk is currently 16.
+        *      The actual divide number for hclk is:
+        *      (DIVIDE2 + 1) * (DIVIDE + 1)
+        * @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
+        *      generate the hclk in the USB Subsystem is held
+        *      in reset. This bit must be set to '0' before
+        *      changing the value os DIVIDE in this register.
+        *      The reset to the HCLK_DIVIDERis also asserted
+        *      when core reset is asserted.
+        * @p_x_on: Force USB-PHY on during suspend.
+        *      '1' USB-PHY XO block is powered-down during
+        *      suspend.
+        *      '0' USB-PHY XO block is powered-up during
+        *      suspend.
+        *      The value of this field must be set while POR is
+        *      active.
+        * @p_rtype: PHY reference clock type
+        *      On CN50XX/CN52XX/CN56XX the values are:
+        *              '0' The USB-PHY uses a 12MHz crystal as a clock source
+        *                  at the USB_XO and USB_XI pins.
+        *              '1' Reserved.
+        *              '2' The USB_PHY uses 12/24/48MHz 2.5V board clock at the
+        *                  USB_XO pin. USB_XI should be tied to ground in this
+        *                  case.
+        *              '3' Reserved.
+        *      On CN3xxx bits 14 and 15 are p_xenbn and p_rclk and values are:
+        *              '0' Reserved.
+        *              '1' Reserved.
+        *              '2' The PHY PLL uses the XO block output as a reference.
+        *                  The XO block uses an external clock supplied on the
+        *                  XO pin. USB_XI should be tied to ground for this
+        *                  usage.
+        *              '3' The XO block uses the clock from a crystal.
+        * @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
+        *      remain powered in Suspend Mode.
+        *      '1' The USB-PHY XO Bias, Bandgap and PLL are
+        *      powered down in suspend mode.
+        *      The value of this field must be set while POR is
+        *      active.
+        * @p_c_sel: Phy clock speed select.
+        *      Selects the reference clock / crystal frequency.
+        *      '11': Reserved
+        *      '10': 48 MHz (reserved when a crystal is used)
+        *      '01': 24 MHz (reserved when a crystal is used)
+        *      '00': 12 MHz
+        *      The value of this field must be set while POR is
+        *      active.
+        *      NOTE: if a crystal is used as a reference clock,
+        *      this field must be set to 12 MHz.
+        * @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
+        * @sd_mode: Scaledown mode for the USBC. Control timing events
+        *      in the USBC, for normal operation this must be '0'.
+        * @s_bist: Starts bist on the hclk memories, during the '0'
+        *      to '1' transition.
+        * @por: Power On Reset for the PHY.
+        *      Resets all the PHYS registers and state machines.
+        * @enable: When '1' allows the generation of the hclk. When
+        *      '0' the hclk will not be generated. SEE DIVIDE
+        *      field of this register.
+        * @prst: When this field is '0' the reset associated with
+        *      the phy_clk functionality in the USB Subsystem is
+        *      help in reset. This bit should not be set to '1'
+        *      until the time it takes 6 clocks (hclk or phy_clk,
+        *      whichever is slower) has passed. Under normal
+        *      operation once this bit is set to '1' it should not
+        *      be set to '0'.
+        * @hrst: When this field is '0' the reset associated with
+        *      the hclk functioanlity in the USB Subsystem is
+        *      held in reset.This bit should not be set to '1'
+        *      until 12ms after phy_clk is stable. Under normal
+        *      operation, once this bit is set to '1' it should
+        *      not be set to '0'.
+        * @divide: The frequency of 'hclk' used by the USB subsystem
+        *      is the eclk frequency divided by the value of
+        *      (DIVIDE2 + 1) * (DIVIDE + 1), also see the field
+        *      DIVIDE2 of this register.
+        *      The hclk frequency should be less than 125Mhz.
+        *      After writing a value to this field the SW should
+        *      read the field for the value written.
+        *      The ENABLE field of this register should not be set
+        *      until AFTER this field is set and then read.
+        */
+       struct cvmx_usbnx_clk_ctl_s {
+               uint64_t reserved_20_63 : 44;
+               uint64_t divide2        : 2;
+               uint64_t hclk_rst       : 1;
+               uint64_t p_x_on         : 1;
+               uint64_t p_rtype        : 2;
+               uint64_t p_com_on       : 1;
+               uint64_t p_c_sel        : 2;
+               uint64_t cdiv_byp       : 1;
+               uint64_t sd_mode        : 2;
+               uint64_t s_bist         : 1;
+               uint64_t por            : 1;
+               uint64_t enable         : 1;
+               uint64_t prst           : 1;
+               uint64_t hrst           : 1;
+               uint64_t divide         : 3;
+       } s;
+};
+
+/**
+ * cvmx_usbn#_usbp_ctl_status
+ *
+ * USBN_USBP_CTL_STATUS = USBP Control And Status Register
+ *
+ * Contains general control and status information for the USBN block.
+ */
+union cvmx_usbnx_usbp_ctl_status {
+       uint64_t u64;
+       /**
+        * struct cvmx_usbnx_usbp_ctl_status_s
+        * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
+        * @txvreftune: HS DC Voltage Level Adjustment
+        * @txfslstune: FS/LS Source Impedence Adjustment
+        * @txhsxvtune: Transmitter High-Speed Crossover Adjustment
+        * @sqrxtune: Squelch Threshold Adjustment
+        * @compdistune: Disconnect Threshold Adjustment
+        * @otgtune: VBUS Valid Threshold Adjustment
+        * @otgdisable: OTG Block Disable
+        * @portreset: Per_Port Reset
+        * @drvvbus: Drive VBUS
+        * @lsbist: Low-Speed BIST Enable.
+        * @fsbist: Full-Speed BIST Enable.
+        * @hsbist: High-Speed BIST Enable.
+        * @bist_done: PHY Bist Done.
+        *      Asserted at the end of the PHY BIST sequence.
+        * @bist_err: PHY Bist Error.
+        *      Indicates an internal error was detected during
+        *      the BIST sequence.
+        * @tdata_out: PHY Test Data Out.
+        *      Presents either internaly generated signals or
+        *      test register contents, based upon the value of
+        *      test_data_out_sel.
+        * @siddq: Drives the USBP (USB-PHY) SIDDQ input.
+        *      Normally should be set to zero.
+        *      When customers have no intent to use USB PHY
+        *      interface, they should:
+        *      - still provide 3.3V to USB_VDD33, and
+        *      - tie USB_REXT to 3.3V supply, and
+        *      - set USBN*_USBP_CTL_STATUS[SIDDQ]=1
+        * @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
+        * @dma_bmode: When set to 1 the L2C DMA address will be updated
+        *      with byte-counts between packets. When set to 0
+        *      the L2C DMA address is incremented to the next
+        *      4-byte aligned address after adding byte-count.
+        * @usbc_end: Bigendian input to the USB Core. This should be
+        *      set to '0' for operation.
+        * @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
+        * @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
+        * @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
+        *      This signal enables the pull-down resistance on
+        *      the D+ line. '1' pull down-resistance is connected
+        *      to D+/ '0' pull down resistance is not connected
+        *      to D+. When an A/B device is acting as a host
+        *      (downstream-facing port), dp_pulldown and
+        *      dm_pulldown are enabled. This must not toggle
+        *      during normal opeartion.
+        * @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
+        *      This signal enables the pull-down resistance on
+        *      the D- line. '1' pull down-resistance is connected
+        *      to D-. '0' pull down resistance is not connected
+        *      to D-. When an A/B device is acting as a host
+        *      (downstream-facing port), dp_pulldown and
+        *      dm_pulldown are enabled. This must not toggle
+        *      during normal opeartion.
+        * @hst_mode: When '0' the USB is acting as HOST, when '1'
+        *      USB is acting as device. This field needs to be
+        *      set while the USB is in reset.
+        * @tuning: Transmitter Tuning for High-Speed Operation.
+        *      Tunes the current supply and rise/fall output
+        *      times for high-speed operation.
+        *      [20:19] == 11: Current supply increased
+        *      approximately 9%
+        *      [20:19] == 10: Current supply increased
+        *      approximately 4.5%
+        *      [20:19] == 01: Design default.
+        *      [20:19] == 00: Current supply decreased
+        *      approximately 4.5%
+        *      [22:21] == 11: Rise and fall times are increased.
+        *      [22:21] == 10: Design default.
+        *      [22:21] == 01: Rise and fall times are decreased.
+        *      [22:21] == 00: Rise and fall times are decreased
+        *      further as compared to the 01 setting.
+        * @tx_bs_enh: Transmit Bit Stuffing on [15:8].
+        *      Enables or disables bit stuffing on data[15:8]
+        *      when bit-stuffing is enabled.
+        * @tx_bs_en: Transmit Bit Stuffing on [7:0].
+        *      Enables or disables bit stuffing on data[7:0]
+        *      when bit-stuffing is enabled.
+        * @loop_enb: PHY Loopback Test Enable.
+        *      '1': During data transmission the receive is
+        *      enabled.
+        *      '0': During data transmission the receive is
+        *      disabled.
+        *      Must be '0' for normal operation.
+        * @vtest_enb: Analog Test Pin Enable.
+        *      '1' The PHY's analog_test pin is enabled for the
+        *      input and output of applicable analog test signals.
+        *      '0' THe analog_test pin is disabled.
+        * @bist_enb: Built-In Self Test Enable.
+        *      Used to activate BIST in the PHY.
+        * @tdata_sel: Test Data Out Select.
+        *      '1' test_data_out[3:0] (PHY) register contents
+        *      are output. '0' internaly generated signals are
+        *      output.
+        * @taddr_in: Mode Address for Test Interface.
+        *      Specifies the register address for writing to or
+        *      reading from the PHY test interface register.
+        * @tdata_in: Internal Testing Register Input Data and Select
+        *      This is a test bus. Data is present on [3:0],
+        *      and its corresponding select (enable) is present
+        *      on bits [7:4].
+        * @ate_reset: Reset input from automatic test equipment.
+        *      This is a test signal. When the USB Core is
+        *      powered up (not in Susned Mode), an automatic
+        *      tester can use this to disable phy_clock and
+        *      free_clk, then re-eanable them with an aligned
+        *      phase.
+        *      '1': The phy_clk and free_clk outputs are
+        *      disabled. "0": The phy_clock and free_clk outputs
+        *      are available within a specific period after the
+        *      de-assertion.
+        */
+       struct cvmx_usbnx_usbp_ctl_status_s {
+               uint64_t txrisetune             : 1;
+               uint64_t txvreftune             : 4;
+               uint64_t txfslstune             : 4;
+               uint64_t txhsxvtune             : 2;
+               uint64_t sqrxtune               : 3;
+               uint64_t compdistune            : 3;
+               uint64_t otgtune                : 3;
+               uint64_t otgdisable             : 1;
+               uint64_t portreset              : 1;
+               uint64_t drvvbus                : 1;
+               uint64_t lsbist                 : 1;
+               uint64_t fsbist                 : 1;
+               uint64_t hsbist                 : 1;
+               uint64_t bist_done              : 1;
+               uint64_t bist_err               : 1;
+               uint64_t tdata_out              : 4;
+               uint64_t siddq                  : 1;
+               uint64_t txpreemphasistune      : 1;
+               uint64_t dma_bmode              : 1;
+               uint64_t usbc_end               : 1;
+               uint64_t usbp_bist              : 1;
+               uint64_t tclk                   : 1;
+               uint64_t dp_pulld               : 1;
+               uint64_t dm_pulld               : 1;
+               uint64_t hst_mode               : 1;
+               uint64_t tuning                 : 4;
+               uint64_t tx_bs_enh              : 1;
+               uint64_t tx_bs_en               : 1;
+               uint64_t loop_enb               : 1;
+               uint64_t vtest_enb              : 1;
+               uint64_t bist_enb               : 1;
+               uint64_t tdata_sel              : 1;
+               uint64_t taddr_in               : 4;
+               uint64_t tdata_in               : 8;
+               uint64_t ate_reset              : 1;
+       } s;
+};
+
+#endif /* __OCTEON_HCD_H__ */
index e14a1bb0436129da4c7f969c4f477063d78da1d9..0315f60497b7fcacc48ca876bb862febed85c759 100644 (file)
@@ -72,7 +72,7 @@ struct cvm_oct_core_state {
        int baseline_cores;
        /*
         * The number of additional cores that could be processing
-        * input packtes.
+        * input packets.
         */
        atomic_t available_cores;
        cpumask_t cpu_state;
@@ -80,6 +80,8 @@ struct cvm_oct_core_state {
 
 static struct cvm_oct_core_state core_state __cacheline_aligned_in_smp;
 
+static int cvm_irq_cpu;
+
 static void cvm_oct_enable_napi(void *_)
 {
        int cpu = smp_processor_id();
@@ -112,11 +114,7 @@ static void cvm_oct_no_more_work(void)
 {
        int cpu = smp_processor_id();
 
-       /*
-        * CPU zero is special.  It always has the irq enabled when
-        * waiting for incoming packets.
-        */
-       if (cpu == 0) {
+       if (cpu == cvm_irq_cpu) {
                enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
                return;
        }
@@ -135,6 +133,7 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
 {
        /* Disable the IRQ and start napi_poll. */
        disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+       cvm_irq_cpu = smp_processor_id();
        cvm_oct_enable_napi(NULL);
 
        return IRQ_HANDLED;
@@ -514,7 +513,7 @@ void cvm_oct_rx_initialize(void)
        if (NULL == dev_for_napi)
                panic("No net_devices were allocated.");
 
-       if (max_rx_cpus > 1  && max_rx_cpus < num_online_cpus())
+       if (max_rx_cpus >= 1 && max_rx_cpus < num_online_cpus())
                atomic_set(&core_state.available_cores, max_rx_cpus);
        else
                atomic_set(&core_state.available_cores, num_online_cpus());
@@ -526,7 +525,7 @@ void cvm_oct_rx_initialize(void)
                               cvm_oct_napi_poll, rx_napi_weight);
                napi_enable(&cvm_oct_napi[i].napi);
        }
-       /* Register an IRQ hander for to receive POW interrupts */
+       /* Register an IRQ handler to receive POW interrupts */
        i = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
                        cvm_oct_do_interrupt, 0, "Ethernet", cvm_oct_device);
 
index af8d62818f13b56e05ada09aedd9f64c4d1da1f0..5108bc0bb573e007bfdcc4981133dab733fed9b6 100644 (file)
@@ -64,31 +64,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
                        if (spx_int_reg.s.spf)
                                pr_err("SPI1: SRX Spi4 interface down\n");
                        if (spx_int_reg.s.calerr)
-                               pr_err("SPI1: SRX Spi4 Calendar table "
-                                      "parity error\n");
+                               pr_err("SPI1: SRX Spi4 Calendar table parity error\n");
                        if (spx_int_reg.s.syncerr)
-                               pr_err("SPI1: SRX Consecutive Spi4 DIP4 "
-                                      "errors have exceeded "
-                                      "SPX_ERR_CTL[ERRCNT]\n");
+                               pr_err("SPI1: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n");
                        if (spx_int_reg.s.diperr)
                                pr_err("SPI1: SRX Spi4 DIP4 error\n");
                        if (spx_int_reg.s.tpaovr)
-                               pr_err("SPI1: SRX Selected port has hit "
-                                      "TPA overflow\n");
+                               pr_err("SPI1: SRX Selected port has hit TPA overflow\n");
                        if (spx_int_reg.s.rsverr)
-                               pr_err("SPI1: SRX Spi4 reserved control "
-                                      "word detected\n");
+                               pr_err("SPI1: SRX Spi4 reserved control word detected\n");
                        if (spx_int_reg.s.drwnng)
-                               pr_err("SPI1: SRX Spi4 receive FIFO "
-                                      "drowning/overflow\n");
+                               pr_err("SPI1: SRX Spi4 receive FIFO drowning/overflow\n");
                        if (spx_int_reg.s.clserr)
-                               pr_err("SPI1: SRX Spi4 packet closed on "
-                                      "non-16B alignment without EOP\n");
+                               pr_err("SPI1: SRX Spi4 packet closed on non-16B alignment without EOP\n");
                        if (spx_int_reg.s.spiovr)
                                pr_err("SPI1: SRX Spi4 async FIFO overflow\n");
                        if (spx_int_reg.s.abnorm)
-                               pr_err("SPI1: SRX Abnormal packet "
-                                      "termination (ERR bit)\n");
+                               pr_err("SPI1: SRX Abnormal packet termination (ERR bit)\n");
                        if (spx_int_reg.s.prtnxa)
                                pr_err("SPI1: SRX Port out of range\n");
                }
@@ -99,31 +91,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
 
                        stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1));
                        if (stx_int_reg.s.syncerr)
-                               pr_err("SPI1: STX Interface encountered a "
-                                      "fatal error\n");
+                               pr_err("SPI1: STX Interface encountered a fatal error\n");
                        if (stx_int_reg.s.frmerr)
-                               pr_err("SPI1: STX FRMCNT has exceeded "
-                                      "STX_DIP_CNT[MAXFRM]\n");
+                               pr_err("SPI1: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n");
                        if (stx_int_reg.s.unxfrm)
-                               pr_err("SPI1: STX Unexpected framing "
-                                      "sequence\n");
+                               pr_err("SPI1: STX Unexpected framing sequence\n");
                        if (stx_int_reg.s.nosync)
-                               pr_err("SPI1: STX ERRCNT has exceeded "
-                                      "STX_DIP_CNT[MAXDIP]\n");
+                               pr_err("SPI1: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n");
                        if (stx_int_reg.s.diperr)
-                               pr_err("SPI1: STX DIP2 error on the Spi4 "
-                                      "Status channel\n");
+                               pr_err("SPI1: STX DIP2 error on the Spi4 Status channel\n");
                        if (stx_int_reg.s.datovr)
                                pr_err("SPI1: STX Spi4 FIFO overflow error\n");
                        if (stx_int_reg.s.ovrbst)
-                               pr_err("SPI1: STX Transmit packet burst "
-                                      "too big\n");
+                               pr_err("SPI1: STX Transmit packet burst too big\n");
                        if (stx_int_reg.s.calpar1)
-                               pr_err("SPI1: STX Calendar Table Parity "
-                                      "Error Bank1\n");
+                               pr_err("SPI1: STX Calendar Table Parity Error Bank1\n");
                        if (stx_int_reg.s.calpar0)
-                               pr_err("SPI1: STX Calendar Table Parity "
-                                      "Error Bank0\n");
+                               pr_err("SPI1: STX Calendar Table Parity Error Bank0\n");
                }
 
                cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0);
@@ -144,31 +128,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
                        if (spx_int_reg.s.spf)
                                pr_err("SPI0: SRX Spi4 interface down\n");
                        if (spx_int_reg.s.calerr)
-                               pr_err("SPI0: SRX Spi4 Calendar table "
-                                      "parity error\n");
+                               pr_err("SPI0: SRX Spi4 Calendar table parity error\n");
                        if (spx_int_reg.s.syncerr)
-                               pr_err("SPI0: SRX Consecutive Spi4 DIP4 "
-                                      "errors have exceeded "
-                                      "SPX_ERR_CTL[ERRCNT]\n");
+                               pr_err("SPI0: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n");
                        if (spx_int_reg.s.diperr)
                                pr_err("SPI0: SRX Spi4 DIP4 error\n");
                        if (spx_int_reg.s.tpaovr)
-                               pr_err("SPI0: SRX Selected port has hit "
-                                      "TPA overflow\n");
+                               pr_err("SPI0: SRX Selected port has hit TPA overflow\n");
                        if (spx_int_reg.s.rsverr)
-                               pr_err("SPI0: SRX Spi4 reserved control "
-                                      "word detected\n");
+                               pr_err("SPI0: SRX Spi4 reserved control word detected\n");
                        if (spx_int_reg.s.drwnng)
-                               pr_err("SPI0: SRX Spi4 receive FIFO "
-                                      "drowning/overflow\n");
+                               pr_err("SPI0: SRX Spi4 receive FIFO drowning/overflow\n");
                        if (spx_int_reg.s.clserr)
-                               pr_err("SPI0: SRX Spi4 packet closed on "
-                                      "non-16B alignment without EOP\n");
+                               pr_err("SPI0: SRX Spi4 packet closed on non-16B alignment without EOP\n");
                        if (spx_int_reg.s.spiovr)
                                pr_err("SPI0: SRX Spi4 async FIFO overflow\n");
                        if (spx_int_reg.s.abnorm)
-                               pr_err("SPI0: SRX Abnormal packet "
-                                      "termination (ERR bit)\n");
+                               pr_err("SPI0: SRX Abnormal packet termination (ERR bit)\n");
                        if (spx_int_reg.s.prtnxa)
                                pr_err("SPI0: SRX Port out of range\n");
                }
@@ -179,31 +155,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
 
                        stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0));
                        if (stx_int_reg.s.syncerr)
-                               pr_err("SPI0: STX Interface encountered a "
-                                      "fatal error\n");
+                               pr_err("SPI0: STX Interface encountered a fatal error\n");
                        if (stx_int_reg.s.frmerr)
-                               pr_err("SPI0: STX FRMCNT has exceeded "
-                                      "STX_DIP_CNT[MAXFRM]\n");
+                               pr_err("SPI0: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n");
                        if (stx_int_reg.s.unxfrm)
-                               pr_err("SPI0: STX Unexpected framing "
-                                      "sequence\n");
+                               pr_err("SPI0: STX Unexpected framing sequence\n");
                        if (stx_int_reg.s.nosync)
-                               pr_err("SPI0: STX ERRCNT has exceeded "
-                                      "STX_DIP_CNT[MAXDIP]\n");
+                               pr_err("SPI0: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n");
                        if (stx_int_reg.s.diperr)
-                               pr_err("SPI0: STX DIP2 error on the Spi4 "
-                                      "Status channel\n");
+                               pr_err("SPI0: STX DIP2 error on the Spi4 Status channel\n");
                        if (stx_int_reg.s.datovr)
                                pr_err("SPI0: STX Spi4 FIFO overflow error\n");
                        if (stx_int_reg.s.ovrbst)
-                               pr_err("SPI0: STX Transmit packet burst "
-                                      "too big\n");
+                               pr_err("SPI0: STX Transmit packet burst too big\n");
                        if (stx_int_reg.s.calpar1)
-                               pr_err("SPI0: STX Calendar Table Parity "
-                                      "Error Bank1\n");
+                               pr_err("SPI0: STX Calendar Table Parity Error Bank1\n");
                        if (stx_int_reg.s.calpar0)
-                               pr_err("SPI0: STX Calendar Table Parity "
-                                      "Error Bank0\n");
+                               pr_err("SPI0: STX Calendar Table Parity Error Bank0\n");
                }
 
                cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0);
index 5631dd9f8201488935799adf5e413611e238d1bd..9b4d0b546b89d8578747470503b0974b2a26b40c 100644 (file)
@@ -78,10 +78,12 @@ static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0);
 static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau)
 {
        int32_t undo;
-       undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE;
+       undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free +
+                                                  MAX_SKB_TO_FREE;
        if (undo > 0)
                cvmx_fau_atomic_add32(fau, -undo);
-       skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? MAX_SKB_TO_FREE : -skb_to_free;
+       skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? MAX_SKB_TO_FREE :
+                                                      -skb_to_free;
        return skb_to_free;
 }
 
@@ -108,8 +110,10 @@ void cvm_oct_free_tx_skbs(struct net_device *dev)
        for (qos = 0; qos < queues_per_port; qos++) {
                if (skb_queue_len(&priv->tx_free_list[qos]) == 0)
                        continue;
-               skb_to_free = cvmx_fau_fetch_and_add32(priv->fau+qos*4, MAX_SKB_TO_FREE);
-               skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, priv->fau+qos*4);
+               skb_to_free = cvmx_fau_fetch_and_add32(priv->fau+qos*4,
+                                                      MAX_SKB_TO_FREE);
+               skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
+                                                        priv->fau+qos*4);
 
 
                total_freed += skb_to_free;
@@ -117,12 +121,14 @@ void cvm_oct_free_tx_skbs(struct net_device *dev)
                        struct sk_buff *to_free_list = NULL;
                        spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
                        while (skb_to_free > 0) {
-                               struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]);
+                               struct sk_buff *t;
+                               t = __skb_dequeue(&priv->tx_free_list[qos]);
                                t->next = to_free_list;
                                to_free_list = t;
                                skb_to_free--;
                        }
-                       spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
+                       spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
+                                              flags);
                        /* Do the actual freeing outside of the lock. */
                        while (to_free_list) {
                                struct sk_buff *t = to_free_list;
@@ -211,15 +217,23 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
                if (unlikely(__skb_linearize(skb))) {
                        queue_type = QUEUE_DROP;
                        if (USE_ASYNC_IOBDMA) {
-                               /* Get the number of skbuffs in use by the hardware */
+                               /*
+                                * Get the number of skbuffs in use
+                                * by the hardware
+                                */
                                CVMX_SYNCIOBDMA;
-                               skb_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
+                               skb_to_free =
+                                       cvmx_scratch_read64(CVMX_SCR_SCRATCH);
                        } else {
-                               /* Get the number of skbuffs in use by the hardware */
-                               skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
-                                                                      MAX_SKB_TO_FREE);
+                               /*
+                                * Get the number of skbuffs in use
+                                * by the hardware
+                                */
+                               skb_to_free = cvmx_fau_fetch_and_add32(
+                                       priv->fau + qos * 4, MAX_SKB_TO_FREE);
                        }
-                       skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, priv->fau + qos * 4);
+                       skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
+                                                       priv->fau + qos * 4);
                        spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
                        goto skip_xmit;
                }
@@ -276,7 +290,9 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
                CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i;
-                       hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page.p) + fs->page_offset));
+                       hw_buffer.s.addr = XKPHYS_TO_PHYS(
+                               (u64)(page_address(fs->page.p) +
+                               fs->page_offset));
                        hw_buffer.s.size = fs->size;
                        CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
                }
@@ -358,7 +374,9 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        pko_command.s.dontfree = 0;
 
-       hw_buffer.s.back = ((unsigned long)skb->data >> 7) - ((unsigned long)fpa_head >> 7);
+       hw_buffer.s.back = ((unsigned long)skb->data >> 7) -
+                          ((unsigned long)fpa_head >> 7);
+
        *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
 
        /*
@@ -422,17 +440,22 @@ dont_put_skbuff_in_hw:
                queue_type = QUEUE_HW;
        }
        if (USE_ASYNC_IOBDMA)
-               cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH, FAU_TOTAL_TX_TO_CLEAN, 1);
+               cvmx_fau_async_fetch_and_add32(
+                               CVMX_SCR_SCRATCH, FAU_TOTAL_TX_TO_CLEAN, 1);
 
        spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
 
        /* Drop this packet if we have too many already queued to the HW */
-       if (unlikely(skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
+       if (unlikely(skb_queue_len(&priv->tx_free_list[qos]) >=
+                    MAX_OUT_QUEUE_DEPTH)) {
+
                if (dev->tx_queue_len != 0) {
                        /* Drop the lock when notifying the core.  */
-                       spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
+                       spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
+                                              flags);
                        netif_stop_queue(dev);
-                       spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+                       spin_lock_irqsave(&priv->tx_free_list[qos].lock,
+                                         flags);
                } else {
                        /* If not using normal queueing.  */
                        queue_type = QUEUE_DROP;
@@ -448,7 +471,8 @@ dont_put_skbuff_in_hw:
                                                 priv->queue + qos,
                                                 pko_command, hw_buffer,
                                                 CVMX_PKO_LOCK_NONE))) {
-               printk_ratelimited("%s: Failed to send the packet\n", dev->name);
+               printk_ratelimited("%s: Failed to send the packet\n",
+                                  dev->name);
                queue_type = QUEUE_DROP;
        }
 skip_xmit:
@@ -493,7 +517,8 @@ skip_xmit:
                cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
                cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
        } else {
-               total_to_clean = cvmx_fau_fetch_and_add32(FAU_TOTAL_TX_TO_CLEAN, 1);
+               total_to_clean = cvmx_fau_fetch_and_add32(
+                                               FAU_TOTAL_TX_TO_CLEAN, 1);
        }
 
        if (total_to_clean & 0x3ff) {
@@ -527,8 +552,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
        /* Get a work queue entry */
        cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
        if (unlikely(work == NULL)) {
-               printk_ratelimited("%s: Failed to allocate a work "
-                                  "queue entry\n", dev->name);
+               printk_ratelimited("%s: Failed to allocate a work queue entry\n",
+                                  dev->name);
                priv->stats.tx_dropped++;
                dev_kfree_skb(skb);
                return 0;
@@ -709,7 +734,7 @@ void cvm_oct_tx_initialize(void)
 
        /* Disable the interrupt.  */
        cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
-       /* Register an IRQ hander for to receive CIU_TIMX(1) interrupts */
+       /* Register an IRQ handler to receive CIU_TIMX(1) interrupts */
        i = request_irq(OCTEON_IRQ_TIMER1,
                        cvm_oct_tx_cleanup_watchdog, 0,
                        "Ethernet", cvm_oct_device);
index c3a90e7012afaddbfa5c0959d35d088de15ab562..bd6ca7164049919288737d569659f0c32c605cb8 100644 (file)
@@ -163,11 +163,13 @@ static void cvm_oct_periodic_worker(struct work_struct *work)
        if (priv->poll)
                priv->poll(cvm_oct_device[priv->port]);
 
-       cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats(cvm_oct_device[priv->port]);
+       cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats(
+                                               cvm_oct_device[priv->port]);
 
        if (!atomic_read(&cvm_oct_poll_queue_stopping))
-               queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ);
- }
+               queue_delayed_work(cvm_oct_poll_queue,
+                                               &priv->port_periodic_work, HZ);
+}
 
 static void cvm_oct_configure_common_hw(void)
 {
@@ -453,7 +455,7 @@ int cvm_oct_common_init(struct net_device *dev)
        if (priv->of_node)
                mac = of_get_mac_address(priv->of_node);
 
-       if (mac && is_valid_ether_addr(mac))
+       if (mac)
                memcpy(dev->dev_addr, mac, ETH_ALEN);
        else
                eth_hw_addr_random(dev);
@@ -584,8 +586,8 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
 
 extern void octeon_mdiobus_force_mod_depencency(void);
 
-static struct device_node *cvm_oct_of_get_child(const struct device_node *parent,
-                                                          int reg_val)
+static struct device_node *cvm_oct_of_get_child(
+                               const struct device_node *parent, int reg_val)
 {
        struct device_node *node = NULL;
        int size;
@@ -603,7 +605,7 @@ static struct device_node *cvm_oct_of_get_child(const struct device_node *parent
 }
 
 static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
-                                                           int interface, int port)
+                                                       int interface, int port)
 {
        struct device_node *ni, *np;
 
@@ -713,7 +715,8 @@ static int cvm_oct_probe(struct platform_device *pdev)
                int port;
                int port_index;
 
-               for (port_index = 0, port = cvmx_helper_get_ipd_port(interface, 0);
+               for (port_index = 0,
+                    port = cvmx_helper_get_ipd_port(interface, 0);
                     port < cvmx_helper_get_ipd_port(interface, num_ports);
                     port_index++, port++) {
                        struct octeon_ethernet *priv;
@@ -726,7 +729,8 @@ static int cvm_oct_probe(struct platform_device *pdev)
 
                        /* Initialize the device private structure. */
                        priv = netdev_priv(dev);
-                       priv->of_node = cvm_oct_node_for_port(pip, interface, port_index);
+                       priv->of_node = cvm_oct_node_for_port(pip, interface,
+                                                               port_index);
 
                        INIT_DELAYED_WORK(&priv->port_periodic_work,
                                          cvm_oct_periodic_worker);
@@ -793,7 +797,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
                                    cvmx_pko_get_num_queues(priv->port) *
                                    sizeof(uint32_t);
                                queue_delayed_work(cvm_oct_poll_queue,
-                                                  &priv->port_periodic_work, HZ);
+                                               &priv->port_periodic_work, HZ);
                        }
                }
        }
index 2ff015d8450991ded2ba4c49ba80d80a286e64a5..d277f048789e615afda6c4db4bbcb81d1f64923c 100644 (file)
@@ -1,7 +1,8 @@
 config FB_OLPC_DCON
        tristate "One Laptop Per Child Display CONtroller support"
        depends on OLPC && FB
-       select I2C
+       depends on I2C
+       depends on (GPIO_CS5535 || GPIO_CS5535=n)
        select BACKLIGHT_CLASS_DEVICE
        ---help---
          In order to support very low power operation, the XO laptop uses a
index 198595e8d742f798256198d57946ca18012295a5..92b02891704d04738365011cd28f6f93b7055dd8 100644 (file)
@@ -383,7 +383,7 @@ static void dcon_set_source(struct dcon_priv *dcon, int arg)
 
        dcon->pending_src = arg;
 
-       if ((dcon->curr_src != arg) && !work_pending(&dcon->switch_source))
+       if (dcon->curr_src != arg)
                schedule_work(&dcon->switch_source);
 }
 
index 4247d60c91861929fd17da303eba9653d3bd993d..9f6ebdb23740596f530e9ab5d52194ca3c9c438e 100644 (file)
@@ -390,10 +390,6 @@ static int __init quickstart_init(void)
 {
        int ret;
 
-       /* ACPI Check */
-       if (acpi_disabled)
-               return -ENODEV;
-
        /* ACPI driver register */
        ret = acpi_bus_register_driver(&quickstart_acpi_driver);
        if (ret)
index 10b22100dd3a223d702487838450850197446329..304579096562aa0011f0159e0b26665aeb4815ea 100644 (file)
@@ -858,7 +858,7 @@ static inline void ieee80211_extract_country_ie(
 
 }
 
-int
+static int
 ieee80211_TranslateToDbm(
        unsigned char SignalStrengthIndex       // 0-100 index.
        )
index b65db542e1ab5025e2185bebb957f43e7eaac8b6..029070603f661861d9081b374b47ffb6873fd0b8 100644 (file)
@@ -887,7 +887,8 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
        return skb;
 }
 
-struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
+static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
+                                           u8 *dest)
 {
        struct sk_buff *skb;
        u8* tag;
@@ -940,7 +941,8 @@ struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
        return skb;
 }
 
-struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
+static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
+                                          int status, u8 *dest)
 {
        struct sk_buff *skb;
        struct ieee80211_authentication *auth;
@@ -2942,14 +2944,9 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin
                goto out;
        }
 
-       param = kmalloc(p->length, GFP_KERNEL);
-       if (param == NULL){
-               ret = -ENOMEM;
-               goto out;
-       }
-       if (copy_from_user(param, p->pointer, p->length)) {
-               kfree(param);
-               ret = -EFAULT;
+       param = memdup_user(p->pointer, p->length);
+       if (IS_ERR(param)) {
+               ret = PTR_ERR(param);
                goto out;
        }
 
index b3466530cf9429a44dba589f3322ba4c2a6a1ca3..f5a5219fe14de4accc234d4f22f12dfd343a2463 100644 (file)
@@ -32,7 +32,6 @@
 ******************************************************************************/
 
 #include <linux/compiler.h>
-//#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -186,9 +185,12 @@ int ieee80211_encrypt_fragment(
        struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
        int res;
 
- /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
-        if (!crypt || !crypt->ops)
-        return -1;
+       /*
+        * added to care about null crypt condition, to solve that system hangs
+        * when shared keys error
+        */
+       if (!crypt || !crypt->ops)
+               return -1;
 
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
        struct ieee80211_hdr_4addr *header;
@@ -197,19 +199,22 @@ int ieee80211_encrypt_fragment(
            crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
                header = (struct ieee80211_hdr_4addr *)frag->data;
                if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "TX packet to %pM\n",
-                              ieee->dev->name, header->addr1);
+                       netdev_dbg(ieee->dev, "TKIP countermeasures: dropped "
+                              "TX packet to %pM\n", header->addr1);
                }
                return -1;
        }
 #endif
-       /* To encrypt, frame format is:
-        * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
-
-       // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
-       /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
-        * call both MSDU and MPDU encryption functions from here. */
+       /*
+        * To encrypt, frame format is:
+        * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes)
+        *
+        * PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU
+        * encryption.
+        *
+        * Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
+        * call both MSDU and MPDU encryption functions from here.
+        */
        atomic_inc(&crypt->refcnt);
        res = 0;
        if (crypt->ops->encrypt_msdu)
@@ -219,8 +224,7 @@ int ieee80211_encrypt_fragment(
 
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
-               printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
-                      ieee->dev->name, frag->len);
+               netdev_info(ieee->dev, "Encryption failed: len=%d.\n", frag->len);
                ieee->ieee_stats.tx_discards++;
                return -1;
        }
@@ -229,7 +233,8 @@ int ieee80211_encrypt_fragment(
 }
 
 
-void ieee80211_txb_free(struct ieee80211_txb *txb) {
+void ieee80211_txb_free(struct ieee80211_txb *txb)
+{
        int i;
        if (unlikely(!txb))
                return;
@@ -239,13 +244,13 @@ void ieee80211_txb_free(struct ieee80211_txb *txb) {
        kfree(txb);
 }
 
-struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
-                                         int gfp_mask)
+static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+                                                gfp_t gfp_mask)
 {
        struct ieee80211_txb *txb;
        int i;
        txb = kmalloc(
-               sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
+               sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
                gfp_mask);
        if (!txb)
                return NULL;
@@ -270,42 +275,43 @@ struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
        return txb;
 }
 
-// Classify the to-be send data packet
-// Need to acquire the sent queue index.
+/*
+ * 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)
 {
-  struct ether_header *eh = (struct ether_header*)skb->data;
-  unsigned int wme_UP = 0;
+       struct ether_header *eh = (struct ether_header *)skb->data;
+       unsigned int wme_UP = 0;
 
-  if(!network->QoS_Enable) {
-     skb->priority = 0;
-     return(wme_UP);
-  }
+       if (!network->QoS_Enable) {
+               skb->priority = 0;
+               return(wme_UP);
+       }
 
-  if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
-    const struct iphdr *ih = (struct iphdr*)(skb->data + \
+       if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
+               const struct iphdr *ih = (struct iphdr *)(skb->data +
                    sizeof(struct ether_header));
-    wme_UP = (ih->tos >> 5)&0x07;
-  } else if (vlan_tx_tag_present(skb)) {//vtag packet
+               wme_UP = (ih->tos >> 5)&0x07;
+       } else if (vlan_tx_tag_present(skb)) {/* vtag packet */
 #ifndef VLAN_PRI_SHIFT
 #define VLAN_PRI_SHIFT  13              /* Shift to find VLAN user priority */
 #define VLAN_PRI_MASK   7               /* Mask for user priority bits in VLAN */
 #endif
-       u32 tag = vlan_tx_tag_get(skb);
-       wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
-  } else if(ETH_P_PAE ==  ntohs(((struct ethhdr *)skb->data)->h_proto)) {
-    //printk(KERN_WARNING "type = normal packet\n");
-    wme_UP = 7;
-  }
-
-  skb->priority = wme_UP;
-  return(wme_UP);
+               u32 tag = vlan_tx_tag_get(skb);
+               wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
+       } else if (ETH_P_PAE ==  ntohs(((struct ethhdr *)skb->data)->h_proto)) {
+               wme_UP = 7;
+       }
+
+       skb->priority = wme_UP;
+       return(wme_UP);
 }
 
 /* SKBs are added to the ieee->tx_queue. */
 int ieee80211_rtl_xmit(struct sk_buff *skb,
-                  struct net_device *dev)
+                      struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
        struct ieee80211_txb *txb = NULL;
@@ -325,24 +331,25 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
 
        struct ieee80211_crypt_data* crypt;
 
-       //printk(KERN_WARNING "upper layer packet!\n");
        spin_lock_irqsave(&ieee->lock, flags);
 
-       /* If there is no driver handler to take the TXB, don't bother
-        * creating it... */
-       if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
-          ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
-               printk(KERN_WARNING "%s: No xmit handler.\n",
-                      ieee->dev->name);
+       /*
+        * If there is no driver handler to take the TXB, don't bother
+        * creating it...
+        */
+       if ((!ieee->hard_start_xmit &&
+            !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) ||
+           ((!ieee->softmac_data_hard_start_xmit &&
+             (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
+               netdev_warn(ieee->dev, "No xmit handler.\n");
                goto success;
        }
 
        ieee80211_classify(skb,&ieee->current_network);
-       if(likely(ieee->raw_tx == 0)){
+       if (likely(ieee->raw_tx == 0)){
 
                if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
-                       printk(KERN_WARNING "%s: skb too small (%d).\n",
-                       ieee->dev->name, skb->len);
+                       netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
                        goto success;
                }
 
@@ -378,7 +385,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                /* Determine total amount of storage required for TXB packets */
                bytes = skb->len + SNAP_SIZE + sizeof(u16);
 
-               if(ieee->current_network.QoS_Enable) {
+               if (ieee->current_network.QoS_Enable) {
                        if (encrypt)
                                fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
                                        IEEE80211_FCTL_WEP;
@@ -395,31 +402,31 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
 
                if (ieee->iw_mode == IW_MODE_INFRA) {
                        fc |= IEEE80211_FCTL_TODS;
-                       /* To DS: Addr1 = BSSID, Addr2 = SA,
-                       Addr3 = DA */
+                       /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
                        memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
                        memcpy(&header.addr2, &src, ETH_ALEN);
                        memcpy(&header.addr3, &dest, ETH_ALEN);
                } else if (ieee->iw_mode == IW_MODE_ADHOC) {
-                       /* not From/To DS: Addr1 = DA, Addr2 = SA,
-                       Addr3 = BSSID */
+                       /*
+                        * not From/To DS: Addr1 = DA, Addr2 = SA,
+                        * Addr3 = BSSID
+                        */
                        memcpy(&header.addr1, dest, ETH_ALEN);
                        memcpy(&header.addr2, src, ETH_ALEN);
                        memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
                }
-       //      printk(KERN_WARNING "essid MAC address is %pM", &header.addr1);
                header.frame_ctl = cpu_to_le16(fc);
-               //hdr_len = IEEE80211_3ADDR_LEN;
 
-               /* Determine fragmentation size based on destination (multicast
-               * and broadcast are not fragmented) */
+               /*
+                * Determine fragmentation size based on destination (multicast
+                * and broadcast are not fragmented)
+                */
                if (is_multicast_ether_addr(header.addr1)) {
                        frag_size = MAX_FRAG_THRESHOLD;
                        qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
-               }
-               else {
-                       //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
-                       frag_size = ieee->fts;//default:392
+               } else {
+                       /* default:392 */
+                       frag_size = ieee->fts;
                        qos_ctl = 0;
                }
 
@@ -432,11 +439,12 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                        hdr_len = IEEE80211_3ADDR_LEN;
                }
 
-               /* Determine amount of payload per fragment.  Regardless of if
-               * this stack is providing the full 802.11 header, one will
-               * eventually be affixed to this fragment -- so we must account for
-               * it when determining the amount of payload space. */
-               //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
+               /*
+                * Determine amount of payload per fragment.  Regardless of if
+                * this stack is providing the full 802.11 header, one will
+                * eventually be affixed to this fragment -- so we must account
+                * for it when determining the amount of payload space.
+                */
                bytes_per_frag = frag_size - hdr_len;
                if (ieee->config &
                (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
@@ -447,8 +455,10 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                        bytes_per_frag -= crypt->ops->extra_prefix_len +
                                crypt->ops->extra_postfix_len;
 
-               /* Number of fragments is the total bytes_per_frag /
-               * payload_per_fragment */
+               /*
+                * Number of fragments is the total bytes_per_frag /
+                * payload_per_fragment
+                */
                nr_frags = bytes / bytes_per_frag;
                bytes_last_frag = bytes % bytes_per_frag;
                if (bytes_last_frag)
@@ -456,13 +466,14 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                else
                        bytes_last_frag = bytes_per_frag;
 
-               /* When we allocate the TXB we allocate enough space for the reserve
-               * and full fragment bytes (bytes_per_frag doesn't include prefix,
-               * postfix, header, FCS, etc.) */
+               /*
+                * When we allocate the TXB we allocate enough space for the 
+                * reserve and full fragment bytes (bytes_per_frag doesn't
+                * include prefix, postfix, header, FCS, etc.)
+                */
                txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
                if (unlikely(!txb)) {
-                       printk(KERN_WARNING "%s: Could not allocate TXB\n",
-                       ieee->dev->name);
+                       netdev_warn(ieee->dev, "Could not allocate TXB\n");
                        goto failed;
                }
                txb->encrypted = encrypt;
@@ -474,11 +485,14 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                        if (encrypt)
                                skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 
-                       frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
+                       frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(
+                               skb_frag, hdr_len);
                        memcpy(frag_hdr, &header, hdr_len);
 
-                       /* If this is not the last fragment, then add the MOREFRAGS
-                       * bit to the frame control */
+                       /*
+                        * If this is not the last fragment, then add the MOREFRAGS
+                        * bit to the frame control
+                        */
                        if (i != nr_frags - 1) {
                                frag_hdr->frame_ctl = cpu_to_le16(
                                        fc | IEEE80211_FCTL_MOREFRAGS);
@@ -488,16 +502,17 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                                /* The last fragment takes the remaining length */
                                bytes = bytes_last_frag;
                        }
-                       if(ieee->current_network.QoS_Enable) {
-                         // add 1 only indicate to corresponding seq number control 2006/7/12
-                         frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
-                         //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
-                         //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
+                       if (ieee->current_network.QoS_Enable) {
+                               /*
+                                * add 1 only indicate to corresponding seq
+                                * number control 2006/7/12
+                                */
+                               frag_hdr->seq_ctl = cpu_to_le16(
+                                       ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
                        } else {
-                         frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
+                               frag_hdr->seq_ctl = cpu_to_le16(
+                                       ieee->seq_ctrl[0]<<4 | i);
                        }
-                       //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
-                       //
 
                        /* Put a SNAP header on the first fragment */
                        if (i == 0) {
@@ -512,54 +527,53 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
                        /* Advance the SKB... */
                        skb_pull(skb, bytes);
 
-                       /* Encryption routine will move the header forward in order
-                       * to insert the IV between the header and the payload */
+                       /*
+                        * Encryption routine will move the header forward in
+                        * order to insert the IV between the header and the
+                        * payload
+                        */
                        if (encrypt)
                                ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
                        if (ieee->config &
                        (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
                                skb_put(skb_frag, 4);
                }
-               // Advance sequence number in data frame.
-               //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
+               /* Advance sequence number in data frame. */
                if (ieee->current_network.QoS_Enable) {
-                 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
-                       ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
-                 else
-                       ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
+                       if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
+                               ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
+                       else
+                               ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
                } else {
-                 if (ieee->seq_ctrl[0] == 0xFFF)
-                       ieee->seq_ctrl[0] = 0;
-                 else
-                       ieee->seq_ctrl[0]++;
+                       if (ieee->seq_ctrl[0] == 0xFFF)
+                               ieee->seq_ctrl[0] = 0;
+                       else
+                               ieee->seq_ctrl[0]++;
                }
-               //---
-       }else{
+       } else {
                if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
-                       printk(KERN_WARNING "%s: skb too small (%d).\n",
-                       ieee->dev->name, skb->len);
+                       netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
                        goto success;
                }
 
                txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
-               if(!txb){
-                       printk(KERN_WARNING "%s: Could not allocate TXB\n",
-                       ieee->dev->name);
+               if (!txb) {
+                       netdev_warn(ieee->dev, "Could not allocate TXB\n");
                        goto failed;
                }
 
                txb->encrypted = 0;
                txb->payload_size = skb->len;
-               memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
+               memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len);
        }
 
  success:
        spin_unlock_irqrestore(&ieee->lock, flags);
                dev_kfree_skb_any(skb);
        if (txb) {
-               if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
+               if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
                        ieee80211_softmac_xmit(txb, ieee);
-               }else{
+               } else {
                        if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
                                stats->tx_packets++;
                                stats->tx_bytes += txb->payload_size;
index e014f7e7439783d4f9caacdef59cc919115d7991..24d39ccc13378e4f16d6c380e9c6b8d754276400 100644 (file)
@@ -145,7 +145,8 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
        /* Add quality statistics */
        /* TODO: Fix these values... */
        if (network->stats.signal == 0 || network->stats.rssi == 0)
-       printk("========>signal:%d, rssi:%d\n", network->stats.signal, network->stats.rssi);
+               printk("========>signal:%d, rssi:%d\n", network->stats.signal,
+                      network->stats.rssi);
        iwe.cmd = IWEVQUAL;
 //     printk("SIGNAL: %d,RSSI: %d,NOISE: %d\n",network->stats.signal,network->stats.rssi,network->stats.noise);
        iwe.u.qual.qual = network->stats.signalstrength;
@@ -622,7 +623,7 @@ done:
        if (ieee->set_security)
                ieee->set_security(ieee->dev, &sec);
 
-        if (ieee->reset_on_keychange &&
+       if (ieee->reset_on_keychange &&
            ieee->iw_mode != IW_MODE_INFRA &&
            ieee->reset_port && ieee->reset_port(dev)) {
                IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
index 5947a6f8e16f971a46ef3d89b363ebae1ed3450e..76a67386b927326e99c793059ce3093d07e52b63 100644 (file)
@@ -160,34 +160,34 @@ static struct pci_driver rtl8180_pci_driver = {
 
 u8 read_nic_byte(struct net_device *dev, int x)
 {
-       return 0xff&readb((u8 *)dev->mem_start + x);
+       return 0xff&readb((u8 __iomem *)dev->mem_start + x);
 }
 
 u32 read_nic_dword(struct net_device *dev, int x)
 {
-       return readl((u8 *)dev->mem_start + x);
+       return readl((u8 __iomem *)dev->mem_start + x);
 }
 
 u16 read_nic_word(struct net_device *dev, int x)
 {
-       return readw((u8 *)dev->mem_start + x);
+       return readw((u8 __iomem *)dev->mem_start + x);
 }
 
 void write_nic_byte(struct net_device *dev, int x, u8 y)
 {
-       writeb(y, (u8 *)dev->mem_start + x);
+       writeb(y, (u8 __iomem *)dev->mem_start + x);
        udelay(20);
 }
 
 void write_nic_dword(struct net_device *dev, int x, u32 y)
 {
-       writel(y, (u8 *)dev->mem_start + x);
+       writel(y, (u8 __iomem *)dev->mem_start + x);
        udelay(20);
 }
 
 void write_nic_word(struct net_device *dev, int x, u16 y)
 {
-       writew(y, (u8 *)dev->mem_start + x);
+       writew(y, (u8 __iomem *)dev->mem_start + x);
        udelay(20);
 }
 
@@ -275,18 +275,18 @@ static int proc_get_stats_tx(struct seq_file *m, void *v)
        return 0;
 }
 
-void rtl8180_proc_module_init(void)
+static void rtl8180_proc_module_init(void)
 {
        DMESG("Initializing proc filesystem");
        rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net);
 }
 
-void rtl8180_proc_module_remove(void)
+static void rtl8180_proc_module_remove(void)
 {
        remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
 }
 
-void rtl8180_proc_remove_one(struct net_device *dev)
+static void rtl8180_proc_remove_one(struct net_device *dev)
 {
        remove_proc_subtree(dev->name, rtl8180_proc);
 }
@@ -325,7 +325,7 @@ static const struct rtl8180_proc_file rtl8180_proc_files[] = {
        { "" }
 };
 
-void rtl8180_proc_init_one(struct net_device *dev)
+static void rtl8180_proc_init_one(struct net_device *dev)
 {
        const struct rtl8180_proc_file *f;
        struct proc_dir_entry *dir;
@@ -351,8 +351,8 @@ void rtl8180_proc_init_one(struct net_device *dev)
   data type+functions in kernel
 */
 
-short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
-               struct buffer **bufferhead)
+static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
+                       struct buffer **bufferhead)
 {
        struct buffer *tmp;
 
@@ -463,7 +463,7 @@ int get_curr_tx_free_desc(struct net_device *dev, int priority)
        return ret;
 }
 
-short check_nic_enought_desc(struct net_device *dev, int priority)
+static short check_nic_enought_desc(struct net_device *dev, int priority)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = netdev_priv(dev);
@@ -589,7 +589,7 @@ void fix_rx_fifo(struct net_device *dev)
        set_nic_rxring(dev);
 }
 
-void rtl8180_irq_disable(struct net_device *dev)
+static void rtl8180_irq_disable(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -705,8 +705,8 @@ void rtl8180_rtx_disable(struct net_device *dev)
                dev_kfree_skb_any(priv->rx_skb);
 }
 
-short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
-                        int addr)
+static short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
+                               int addr)
 {
        int i;
        u32 *desc;
@@ -830,7 +830,7 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
        return 0;
 }
 
-void free_tx_desc_rings(struct net_device *dev)
+static void free_tx_desc_rings(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct pci_dev *pdev = priv->pdev;
@@ -866,7 +866,7 @@ void free_tx_desc_rings(struct net_device *dev)
        buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1);
 }
 
-void free_rx_desc_ring(struct net_device *dev)
+static void free_rx_desc_ring(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct pci_dev *pdev = priv->pdev;
@@ -878,7 +878,7 @@ void free_rx_desc_ring(struct net_device *dev)
        buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0);
 }
 
-short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
+static short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 {
        int i;
        u32 *desc;
@@ -1092,7 +1092,7 @@ u16 N_DBPSOfRate(u16 DataRate)
 /*
  * For Netgear case, they want good-looking signal strength.
  */
-long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
+static long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
 {
        long RetSS;
 
@@ -1128,7 +1128,7 @@ long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
 /*
  * Translate 0-100 signal strength index into dBm.
  */
-long TranslateToDbm8185(u8 SignalStrengthIndex)
+static long TranslateToDbm8185(u8 SignalStrengthIndex)
 {
        long SignalPower;
 
@@ -1145,8 +1145,8 @@ long TranslateToDbm8185(u8 SignalStrengthIndex)
  * No dramatic adjustion is apply because dynamic mechanism need some degree
  * of correctness. Ported from 8187B.
  */
-void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
-                                          bool bCckRate)
+static void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
+                                                 bool bCckRate)
 {
        /* Determin the current packet is CCK rate. */
        priv->bCurCCKPkt = bCckRate;
@@ -1170,7 +1170,7 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
 /*
  * This is rough RX isr handling routine
  */
-void rtl8180_rx(struct net_device *dev)
+static void rtl8180_rx(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct sk_buff *tmp_skb;
@@ -1496,7 +1496,7 @@ drop: /* this is used when we have not enough mem */
 }
 
 
-void rtl8180_dma_kick(struct net_device *dev, int priority)
+static void rtl8180_dma_kick(struct net_device *dev, int priority)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -1508,7 +1508,7 @@ void rtl8180_dma_kick(struct net_device *dev, int priority)
        force_pci_posting(dev);
 }
 
-void rtl8180_data_hard_stop(struct net_device *dev)
+static void rtl8180_data_hard_stop(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -1518,7 +1518,7 @@ void rtl8180_data_hard_stop(struct net_device *dev)
        rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 }
 
-void rtl8180_data_hard_resume(struct net_device *dev)
+static void rtl8180_data_hard_resume(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -1532,8 +1532,9 @@ void rtl8180_data_hard_resume(struct net_device *dev)
  * This function TX data frames when the ieee80211 stack requires this.
  * It checks also if we need to stop the ieee tx queue, eventually do it
  */
-void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int
-rate) {
+static void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
+                                  int rate)
+{
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        int mode;
        struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data;
@@ -1584,7 +1585,7 @@ rate) {
  * might use a different lock than tx_lock (for example mgmt_tx_lock)
  */
 /* these function may loop if invoked with 0 descriptors or 0 len buffer */
-int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        unsigned long flags;
@@ -1660,7 +1661,7 @@ u16 rtl8180_len2duration(u32 len, short rate, short *ext)
        return duration;
 }
 
-void rtl8180_prepare_beacon(struct net_device *dev)
+static void rtl8180_prepare_beacon(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct sk_buff *skb;
@@ -1704,7 +1705,7 @@ short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
        u16                     RtsDur = 0;
        u16                     ThisFrameTime = 0;
        u16                     TxDescDuration = 0;
-       u8                      ownbit_flag = false;
+       bool                    ownbit_flag = false;
 
        switch (priority) {
        case MANAGE_PRIORITY:
@@ -1953,7 +1954,7 @@ short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
 
 void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
 
-void rtl8180_link_change(struct net_device *dev)
+static void rtl8180_link_change(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u16 beacon_interval;
@@ -1976,7 +1977,7 @@ void rtl8180_link_change(struct net_device *dev)
        rtl8180_set_chan(dev, priv->chan);
 }
 
-void rtl8180_rq_tx_ack(struct net_device *dev)
+static void rtl8180_rq_tx_ack(struct net_device *dev)
 {
 
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1985,7 +1986,7 @@ void rtl8180_rq_tx_ack(struct net_device *dev)
        priv->ack_tx_to_ieee = 1;
 }
 
-short rtl8180_is_tx_queue_empty(struct net_device *dev)
+static short rtl8180_is_tx_queue_empty(struct net_device *dev)
 {
 
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2023,7 +2024,7 @@ short rtl8180_is_tx_queue_empty(struct net_device *dev)
        return 1;
 }
 
-void rtl8180_hw_wakeup(struct net_device *dev)
+static void rtl8180_hw_wakeup(struct net_device *dev)
 {
        unsigned long flags;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2035,7 +2036,7 @@ void rtl8180_hw_wakeup(struct net_device *dev)
        spin_unlock_irqrestore(&priv->ps_lock, flags);
 }
 
-void rtl8180_hw_sleep_down(struct net_device *dev)
+static void rtl8180_hw_sleep_down(struct net_device *dev)
 {
        unsigned long flags;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2046,7 +2047,7 @@ void rtl8180_hw_sleep_down(struct net_device *dev)
        spin_unlock_irqrestore(&priv->ps_lock, flags);
 }
 
-void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
+static void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u32 rb = jiffies;
@@ -2093,7 +2094,7 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
        spin_unlock_irqrestore(&priv->ps_lock, flags);
 }
 
-void rtl8180_wmm_param_update(struct work_struct *work)
+static void rtl8180_wmm_param_update(struct work_struct *work)
 {
        struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wmm_param_update_wq);
        struct net_device *dev = ieee->dev;
@@ -2195,7 +2196,7 @@ void rtl8180_hw_sleep_wq(struct work_struct *work);
 void rtl8180_sw_antenna_wq(struct work_struct *work);
 void rtl8180_watch_dog(struct net_device *dev);
 
-void watch_dog_adaptive(unsigned long data)
+static void watch_dog_adaptive(unsigned long data)
 {
        struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
 
@@ -2213,7 +2214,7 @@ void watch_dog_adaptive(unsigned long data)
                TxPwrTracking87SE((struct net_device *)data);
 
        /* Perform DIG immediately. */
-       if (CheckDig((struct net_device *)data) == true)
+       if (CheckDig((struct net_device *)data))
                queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
        rtl8180_watch_dog((struct net_device *)data);
 
@@ -2271,7 +2272,7 @@ static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ie
                }
        case COUNTRY_CODE_GLOBAL_DOMAIN:
                {
-                       GET_DOT11D_INFO(ieee)->bEnabled = 0;
+                       GET_DOT11D_INFO(ieee)->bEnabled = false;
                        Dot11d_Reset(ieee);
                        ieee->bGlobalDomain = true;
                        break;
@@ -2429,7 +2430,7 @@ short rtl8180_init(struct net_device *dev)
        init_timer(&priv->SwAntennaDiversityTimer);
        priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
        priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
-       priv->bDigMechanism = 1;
+       priv->bDigMechanism = true;
        priv->InitialGain = 6;
        priv->bXtalCalibration = false;
        priv->XtalCal_Xin = 0;
@@ -2548,7 +2549,7 @@ short rtl8180_init(struct net_device *dev)
                                (priv->EarlyRxThreshold == 7 ?
                                         RCR_ONLYERLPKT : 0);
 
-       priv->IntrMask          = IMR_TMGDOK | IMR_TBDER | IMR_THPDER |
+       priv->IntrMask          = IMR_TMGDOK | IMR_TBDER |
                                  IMR_THPDER | IMR_THPDOK |
                                  IMR_TVODER | IMR_TVODOK |
                                  IMR_TVIDER | IMR_TVIDOK |
@@ -2757,7 +2758,7 @@ void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
        mdelay(1);
 }
 
-void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
+static void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
 {
        u32 phyw;
 
@@ -2969,7 +2970,7 @@ void rtl8180_watch_dog(struct net_device *dev)
        priv->ieee80211->NumRxBcnInPeriod = 0;
 }
 
-int _rtl8180_up(struct net_device *dev)
+static int _rtl8180_up(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -2991,7 +2992,7 @@ int _rtl8180_up(struct net_device *dev)
        return 0;
 }
 
-int rtl8180_open(struct net_device *dev)
+static int rtl8180_open(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret;
@@ -3012,7 +3013,7 @@ int rtl8180_up(struct net_device *dev)
        return _rtl8180_up(dev);
 }
 
-int rtl8180_close(struct net_device *dev)
+static int rtl8180_close(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret;
@@ -3065,7 +3066,7 @@ void rtl8180_restart_wq(struct work_struct *work)
        up(&priv->wx_sem);
 }
 
-void rtl8180_restart(struct net_device *dev)
+static void rtl8180_restart(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -3106,7 +3107,7 @@ static void r8180_set_multicast(struct net_device *dev)
        priv->promisc = promisc;
 }
 
-int r8180_set_mac_adr(struct net_device *dev, void *mac)
+static int r8180_set_mac_adr(struct net_device *dev, void *mac)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct sockaddr *addr = mac;
@@ -3129,7 +3130,7 @@ int r8180_set_mac_adr(struct net_device *dev, void *mac)
 }
 
 /* based on ipw2200 driver */
-int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct iwreq *wrq = (struct iwreq *) rq;
@@ -3251,7 +3252,7 @@ static int rtl8180_pci_probe(struct pci_dev *pdev,
        return 0;
 fail1:
        if (dev->mem_start != (unsigned long)NULL) {
-               iounmap((void *)dev->mem_start);
+               iounmap((void __iomem *)dev->mem_start);
                release_mem_region(pci_resource_start(pdev, 1),
                                   pci_resource_len(pdev, 1));
        }
@@ -3268,7 +3269,6 @@ fail_free:
        pci_disable_device(pdev);
 
        DMESG("wlan driver load failed\n");
-       pci_set_drvdata(pdev, NULL);
        return ret;
 }
 
@@ -3298,7 +3298,7 @@ static void rtl8180_pci_remove(struct pci_dev *pdev)
                free_tx_desc_rings(dev);
 
                if (dev->mem_start != (unsigned long)NULL) {
-                       iounmap((void *)dev->mem_start);
+                       iounmap((void __iomem *)dev->mem_start);
                        release_mem_region(pci_resource_start(pdev, 1),
                                           pci_resource_len(pdev, 1));
                }
@@ -3369,7 +3369,7 @@ static void __exit rtl8180_pci_module_exit(void)
        DMESG("Exiting");
 }
 
-void rtl8180_try_wake_queue(struct net_device *dev, int pri)
+static void rtl8180_try_wake_queue(struct net_device *dev, int pri)
 {
        unsigned long flags;
        short enough_desc;
@@ -3383,7 +3383,7 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri)
                ieee80211_rtl_wake_queue(priv->ieee80211);
 }
 
-void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
+static void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        u32 *tail; /* tail virtual addr */
index b8f2ba010a04e74af236c7883a546eb11935e792..2ccd2cb70face1c2ea6f0e53a87091c861acba98 100644 (file)
@@ -10,10 +10,10 @@ bool CheckHighPower(struct net_device *dev)
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee80211;
 
-       if(!priv->bRegHighPowerMechanism)
+       if (!priv->bRegHighPowerMechanism)
                return false;
 
-       if(ieee->state == IEEE80211_LINKED_SCANNING)
+       if (ieee->state == IEEE80211_LINKED_SCANNING)
                return false;
 
        return true;
@@ -30,7 +30,7 @@ bool CheckHighPower(struct net_device *dev)
  *             and they are related to OFDM and MAC registers.
  *             So, we don't want to update it so frequently in per-Rx packet base.
  */
-void DoTxHighPower(struct net_device *dev)
+static void DoTxHighPower(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u16                     HiPwrUpperTh = 0;
@@ -57,15 +57,15 @@ void DoTxHighPower(struct net_device *dev)
                /* Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah */
 
                priv->bToUpdateTxPwr = true;
-               u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+               u1bTmp = read_nic_byte(dev, CCK_TXAGC);
 
                /* If it never enter High Power. */
                if (CckTxPwrIdx == u1bTmp) {
-                       u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  /* 8dbm */
+                       u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0;  /* 8dbm */
                        write_nic_byte(dev, CCK_TXAGC, u1bTmp);
 
-                       u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
-                       u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  /* 8dbm */
+                       u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
+                       u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0;  /* 8dbm */
                        write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
                }
 
@@ -74,12 +74,12 @@ void DoTxHighPower(struct net_device *dev)
                if (priv->bToUpdateTxPwr) {
                        priv->bToUpdateTxPwr = false;
                        /* SD3 required. */
-                       u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+                       u1bTmp = read_nic_byte(dev, CCK_TXAGC);
                        if (u1bTmp < CckTxPwrIdx) {
                                write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
                        }
 
-                       u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+                       u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
                        if (u1bTmp < OfdmTxPwrIdx) {
                                write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
                        }
@@ -97,7 +97,7 @@ void DoTxHighPower(struct net_device *dev)
 void rtl8180_tx_pw_wq(struct work_struct *work)
 {
        struct delayed_work *dwork = to_delayed_work(work);
-       struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
+       struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, tx_pw_wq);
        struct net_device *dev = ieee->dev;
 
        DoTxHighPower(dev);
@@ -125,7 +125,7 @@ bool CheckDig(struct net_device *dev)
 /*
  *     Implementation of DIG for Zebra and Zebra2.
  */
-void DIG_Zebra(struct net_device *dev)
+static void DIG_Zebra(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u16                     CCKFalseAlarm, OFDMFalseAlarm;
@@ -149,11 +149,11 @@ void DIG_Zebra(struct net_device *dev)
 
 #if 1 /* lzm reserved 080826 */
        AwakePeriodIn2Sec = (2000 - priv->DozePeriodInPast2Sec);
-       priv ->DozePeriodInPast2Sec = 0;
+       priv->DozePeriodInPast2Sec = 0;
 
        if (AwakePeriodIn2Sec) {
-               OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000) ;
-               OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000) ;
+               OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000);
+               OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000);
        } else {
                ;
        }
@@ -202,7 +202,7 @@ void DIG_Zebra(struct net_device *dev)
 /*
  *     Dispatch DIG implementation according to RF.
  */
-void DynamicInitGain(struct net_device *dev)
+static void DynamicInitGain(struct net_device *dev)
 {
        DIG_Zebra(dev);
 }
@@ -210,7 +210,7 @@ void DynamicInitGain(struct net_device *dev)
 void rtl8180_hw_dig_wq(struct work_struct *work)
 {
        struct delayed_work *dwork = to_delayed_work(work);
-       struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
+       struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_dig_wq);
        struct net_device *dev = ieee->dev;
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -223,7 +223,7 @@ void rtl8180_hw_dig_wq(struct work_struct *work)
 
 }
 
-int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
+static int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
 {
        u8 rate_len;
        u8 rate_ex_len;
@@ -234,7 +234,7 @@ int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
 
        rate_len = priv->ieee80211->current_network.rates_len;
        rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
-       for (idx=0; idx < rate_len; idx++) {
+       for (idx = 0; idx < rate_len; idx++) {
                if ((priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate) {
                        Found = 1;
                        goto found_rate;
@@ -247,7 +247,7 @@ int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
                }
        }
        return Found;
-       found_rate:
+found_rate:
        return Found;
 }
 
@@ -255,7 +255,7 @@ int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
  *     Get the Tx rate one degree up form the input rate in the supported rates.
  *     Return the upgrade rate if it is successed, otherwise return the input rate.
  */
-u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
+static u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u8                      UpRate;
@@ -315,7 +315,7 @@ u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
  *     Return the degrade rate if it is successed, otherwise return the input rate.
  */
 
-u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
+static u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u8                      DownRate;
@@ -375,7 +375,7 @@ u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
  *      CCK rate.
  */
 
-bool MgntIsCckRate(u16 rate)
+static bool MgntIsCckRate(u16 rate)
 {
        bool bReturn = false;
 
@@ -397,7 +397,7 @@ void TxPwrTracking87SE(struct net_device *dev)
 
        tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
        CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */
-       CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c:CurrentThermal;/* lzm add 080826 */
+       CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c : CurrentThermal;/* lzm add 080826 */
 
        if (CurrentThermal != priv->ThermalMeter) {
                /* Update Tx Power level on each channel. */
@@ -435,7 +435,7 @@ void TxPwrTracking87SE(struct net_device *dev)
        }
        priv->ThermalMeter = CurrentThermal;
 }
-void StaRateAdaptive87SE(struct net_device *dev)
+static void StaRateAdaptive87SE(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        unsigned long   CurrTxokCnt;
@@ -513,7 +513,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
         */
 
        /*
-        *  11Mbps or 36Mbps
+        * 11Mbps or 36Mbps
         * Check more times in these rate(key rates).
         */
        if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
@@ -542,7 +542,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                }
        } else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) {
                /*
-                * 2For High Power
+                * 2For High Power
                 *
                 * Return to highest data rate, if signal strength is good enough.
                 * SignalStrength threshold(-50dbm) is for RTL8186.
@@ -577,8 +577,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
 
                if (bTryDown && (CurrSignalStrength < -75)) /* cable link */
                        priv->TryDownCountLowData += TryDownTh;
-       }
-       else if (priv->CurrentOperaRate == 96) {
+       } else if (priv->CurrentOperaRate == 96) {
                /* 2For 48Mbps */
                /* Air Link */
                if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) {
@@ -593,7 +592,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        bTryUp = true;
                }
 
-               if (bTryDown && (CurrSignalStrength < -75)){
+               if (bTryDown && (CurrSignalStrength < -75)) {
                        priv->TryDownCountLowData += TryDownTh;
                }
        } else if (priv->CurrentOperaRate == 72) {
@@ -618,7 +617,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        bTryDown = true;
                } else if (((CurrRetryRate > 33) && (priv->LastRetryRate > 32)) && (CurrSignalStrength > -82)) { /* Cable Link */
                        bTryDown = true;
-               } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2 )) {
+               } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
                        bTryDown = true;
                        priv->TryDownCountLowData += TryDownTh;
                } else if ((CurrRetryRate < 20) && (priv->LastRetryRate < 21)) { /* TO DO: need to consider (RSSI) */
@@ -641,8 +640,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                /* 2For 11Mbps */
                if (CurrRetryRate > 95) {
                        bTryDown = true;
-               }
-               else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
+               } else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
                        bTryUp = true;
                }
        } else if (priv->CurrentOperaRate == 11) {
@@ -667,12 +665,12 @@ void StaRateAdaptive87SE(struct net_device *dev)
        }
 
        if (bTryUp && bTryDown)
-       printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
+               printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
 
        /* 1 Test Upgrading Tx Rate
         * Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
         * To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
-        */ 
+        */
        if (!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
                && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) {
                if (jiffies % (CurrRetryRate + 101) == 0) {
@@ -702,7 +700,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        if (priv->CurrentOperaRate == 22)
                                bUpdateInitialGain = true;
 
-                       /* 
+                       /*
                         * The difference in throughput between 48Mbps and 36Mbps is 8M.
                         * So, we must be careful in this rate scale. Isaiah 2008-02-15.
                         */
@@ -718,7 +716,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        if (priv->CurrentOperaRate == 36) {
                                priv->bUpdateARFR = true;
                                write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
-                       } else if(priv->bUpdateARFR) {
+                       } else if (priv->bUpdateARFR) {
                                priv->bUpdateARFR = false;
                                write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
                        }
@@ -732,7 +730,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                }
        } else {
                if (priv->TryupingCount > 0)
-                       priv->TryupingCount --;
+                       priv->TryupingCount--;
        }
 
        if (bTryDown) {
@@ -757,7 +755,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
 
                        /* Reduce chariot training time at weak signal strength situation. SD3 ED demand. */
-                       if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 )) {
+                       if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72)) {
                                priv->CurrentOperaRate = 72;
                        }
 
@@ -781,8 +779,8 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        priv->TryDownCountLowData--;
        }
 
-       /* 
-        * Keep the Tx fail rate count to equal to 0x15 at most. 
+       /*
+        * Keep the Tx fail rate count to equal to 0x15 at most.
         * Reduce the fail count at least to 10 sec if tx rate is tending stable.
         */
        if (priv->FailTxRateCount >= 0x15 ||
@@ -803,14 +801,14 @@ void StaRateAdaptive87SE(struct net_device *dev)
                if (u1bCck == CckTxPwrIdx) {
                        if (u1bOfdm != (OfdmTxPwrIdx + 2)) {
                        priv->bEnhanceTxPwr = true;
-                       u1bOfdm = ((u1bOfdm + 2) > 35) ? 35: (u1bOfdm + 2);
+                       u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
                        write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
                        }
                } else if (u1bCck < CckTxPwrIdx) {
                /* case 2: enter high power */
                        if (!priv->bEnhanceTxPwr) {
                                priv->bEnhanceTxPwr = true;
-                               u1bOfdm = ((u1bOfdm + 2) > 35) ? 35: (u1bOfdm + 2);
+                               u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
                                write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
                        }
                }
@@ -826,7 +824,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                /* case 2: enter high power */
                else if (u1bCck < CckTxPwrIdx) {
                        priv->bEnhanceTxPwr = false;
-                       u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2): 0;
+                       u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2) : 0;
                        write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
                }
        }
@@ -851,7 +849,7 @@ SetInitialGain:
                                else
                                        priv->InitialGain--;
 
-                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
                                UpdateInitialGain(dev);
                        }
                } else { /* OFDM */
@@ -859,7 +857,7 @@ SetInitialGain:
                                priv->InitialGainBackUp = priv->InitialGain;
 
                                priv->InitialGain++;
-                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
                                UpdateInitialGain(dev);
                        }
                }
@@ -904,7 +902,7 @@ void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength)
        } else { /* Initialization case. */
                priv->AdRxSignalStrength = SignalStrength;
        }
-       
+
        if (priv->LastRxPktAntenna) /* Main antenna. */
                priv->AdMainAntennaRxOkCnt++;
        else     /* Aux antenna. */
@@ -943,7 +941,7 @@ bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex)
                break;
        }
 
-       if(bAntennaSwitched)
+       if (bAntennaSwitched)
                priv->CurrAntennaIndex = u1bAntennaIndex;
 
        return bAntennaSwitched;
@@ -1000,8 +998,8 @@ void SwAntennaDiversity(struct net_device *dev)
                priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
 
                priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
-                                       priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
-               if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
+                                       priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;
+               if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
                /* Rx signal strength is not improved after we swtiched antenna. => Swich back. */
                        /* Increase Antenna Diversity checking period due to bad decision. */
                        priv->AdCheckPeriod *= 2;
@@ -1083,7 +1081,7 @@ void SwAntennaDiversity(struct net_device *dev)
 
                                        priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
                                        priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
-                                                               priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;/* +by amy 080312 */
+                                                               priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */
                                }
 
                                /* Reduce Antenna Diversity checking period if possible. */
index 9ae96b7852f30d328330ac180a822be56cf20eb2..7c9a8bfe6d889c2f0ec3e89cc16192bdb2f0d309 100644 (file)
@@ -136,7 +136,7 @@ static const u16 rtl8225z2_rxgain[] = {
 
 };
 
-void rtl8225z2_set_gain(struct net_device *dev, short gain)
+static void rtl8225z2_set_gain(struct net_device *dev, short gain)
 {
        const u8 *rtl8225_gain;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -279,8 +279,8 @@ void rtl8225z2_rf_close(struct net_device *dev)
  * Map dBm into Tx power index according to current HW model, for example,
  * RF and PA, and current wireless mode.
  */
-s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode,
-                s32 PowerInDbm)
+static s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode,
+                       s32 PowerInDbm)
 {
        bool bUseDefault = true;
        s8 TxPwrIdx = 0;
index dab787542c45d6d9efc2c67ea2e1dfc16443cc20..4e01653e098a3b782e6844fd23430ced355ee2f2 100644 (file)
@@ -50,8 +50,9 @@ static int r8180_wx_get_freq(struct net_device *dev,
 }
 
 
-int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
-                    union iwreq_data *wrqu, char *key)
+static int r8180_wx_set_key(struct net_device *dev,
+                           struct iw_request_info *info,
+                           union iwreq_data *wrqu, char *key)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct iw_point *erq = &(wrqu->encoding);
@@ -1146,12 +1147,12 @@ static int r8180_wx_set_gen_ie(struct net_device *dev,
        if (priv->ieee80211->bHwRadioOff)
                return 0;
 
-               down(&priv->wx_sem);
+       down(&priv->wx_sem);
 #if 1
-               ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
+       ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
 #endif
-               up(&priv->wx_sem);
-               return ret;
+       up(&priv->wx_sem);
+       return ret;
 
 
 }
index 978dc5f4f929f197aa680a407251b6bfa5a6c3d2..dc52a3e584d838a7fca7a64e5d551df729c0a2d7 100644 (file)
 #define TC_3W_POLL_MAX_TRY_CNT 5
 
 static u8 MAC_REG_TABLE[][2] = {
-       /*PAGA 0:       */
-       /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */
-       /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */
-       /* 0x1F0~0x1F8  set in MacConfig_85BASIC() */
+       /*
+        * PAGE 0:
+        * 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in
+        * HwConfigureRTL8185()
+        * 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185().
+        * 0x1F0~0x1F8  set in MacConfig_85BASIC()
+        */
        {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
        {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
        {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
@@ -44,15 +47,20 @@ static u8 MAC_REG_TABLE[][2] =      {
        {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
        {0xff, 0x00},
 
-       /*PAGE 1: */
-       /* For Flextronics system Logo PCIHCT failure: */
-       /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */
+       /*
+        * PAGE 1:
+        * For Flextronics system Logo PCIHCT failure:
+        * 0x1C4~0x1CD set no-zero value to avoid PCI configuration
+        * space 0x45[7]=1
+        */
        {0x5e, 0x01},
        {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
        {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
        {0x82, 0xFF}, {0x83, 0x03},
-       {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */
-       {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22}, /* lzm add 080826 */
+       /* lzm add 080826 */
+       {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22},
+       /* lzm add 080826 */
+       {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},
        {0xe2, 0x00},
 
 
@@ -66,21 +74,24 @@ static u8 MAC_REG_TABLE[][2] =      {
        {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
        {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
 
-       /* PAGA 0: */
+       /* PAGE 0: */
        {0x5e, 0x00}, {0x9f, 0x03}
        };
 
 
 static u8  ZEBRA_AGC[] = {
        0,
-       0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72,
-       0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62,
-       0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
-       0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16,
-       0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
-       0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24,
-       0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
+       0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76,
+       0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A,
+       0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x48, 0x47, 0x46, 0x45,
+       0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
+       0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+       0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x17, 0x18, 0x18,
+       0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
+       0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22,
+       0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
+       0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
        };
 
 static u32 ZEBRA_RF_RX_GAIN_TABLE[] = {
@@ -123,19 +134,27 @@ static u8 PlatformIORead1Byte(struct net_device *dev, u32 offset)
 static void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data)
 {
        write_nic_byte(dev, offset, data);
-       read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
+       /*
+        * To make sure write operation is completed,
+        * 2005.11.09, by rcnjko.
+        */
+       read_nic_byte(dev, offset);
 }
 
 static void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data)
 {
        write_nic_word(dev, offset, data);
-       read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
+       /*
+        * To make sure write operation is completed,
+        *  2005.11.09, by rcnjko.
+        */
+       read_nic_word(dev, offset);
 }
 
 static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
 {
        if (offset == PhyAddr) {
-       /* For Base Band configuration. */
+               /* For Base Band configuration. */
                unsigned char   cmdByte;
                unsigned long   dataBytes;
                unsigned char   idx;
@@ -146,16 +165,17 @@ static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
 
                /*
                 *      071010, rcnjko:
-                *      The critical section is only BB read/write race condition.
-                *      Assumption:
-                *      1. We assume NO one will access BB at DIRQL, otherwise, system will crash for
+                *      The critical section is only BB read/write race
+                *      condition. Assumption:
+                *      1. We assume NO one will access BB at DIRQL, otherwise,
+                *      system will crash for
                 *      acquiring the spinlock in such context.
                 *      2. PlatformIOWrite4Byte() MUST NOT be recursive.
                 */
                /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
 
                for (idx = 0; idx < 30; idx++) {
-               /* Make sure command bit is clear before access it. */
+                       /* Make sure command bit is clear before access it. */
                        u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
                        if ((u1bTmp & BIT7) == 0)
                                break;
@@ -164,14 +184,19 @@ static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
                }
 
                for (idx = 0; idx < 3; idx++)
-                       PlatformIOWrite1Byte(dev, offset+1+idx, ((u8 *)&dataBytes)[idx]);
+                       PlatformIOWrite1Byte(dev, offset+1+idx,
+                                            ((u8 *)&dataBytes)[idx]);
 
                write_nic_byte(dev, offset, cmdByte);
 
                /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
        } else {
                write_nic_dword(dev, offset, data);
-               read_nic_dword(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
+               /*
+                * To make sure write operation is completed, 2005.11.09,
+                *  by rcnjko.
+                */
+               read_nic_dword(dev, offset);
        }
 }
 
@@ -284,9 +309,13 @@ bool SetAntennaConfig87SE(struct net_device *dev,
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        bool   bAntennaSwitched = true;
-       u8      ant_diversity_offset = 0x00; /* 0x00 = disabled, 0x80 = enabled */
+       /* 0x00 = disabled, 0x80 = enabled */
+       u8      ant_diversity_offset = 0x00;
 
-       /* printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity); */
+       /*
+        * printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n",
+        * DefaultAnt, bAntDiversity);
+        */
 
        /* Threshold for antenna diversity. */
        write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
@@ -300,22 +329,27 @@ bool SetAntennaConfig87SE(struct net_device *dev,
 
                /* Config CCK RX antenna. */
                write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
-               write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset); /* Reg01 : 47 | ant_diversity_offset */
+
+               /* Reg01 : 47 | ant_diversity_offset */
+               write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
 
                /* Config OFDM RX antenna. */
                write_phy_ofdm(dev, 0x0D, 0x54);        /* Reg0d : 54 */
-               write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);   /* Reg18 : 32 */
+               /* Reg18 : 32 */
+               write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
        } else { /* main Antenna */
                /* Mac register, main antenna */
                write_nic_byte(dev, ANTSEL, 0x03);
 
                /* Config CCK RX antenna.       */
                write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
-               write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset); /* Reg01 : 47 */
+               /* Reg01 : 47 */
+               write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
 
                /* Config OFDM RX antenna. */
                write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
-               write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset); /*Reg18 : 32 */
+               /*Reg18 : 32 */
+               write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
        }
        priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
        return  bAntennaSwitched;
@@ -382,18 +416,23 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
        RF_WriteReg(dev, 0x05, 0x059b);         mdelay(1);
        RF_WriteReg(dev, 0x06, 0x0081);         mdelay(1);
        RF_WriteReg(dev, 0x07, 0x01A0);         mdelay(1);
-/* Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. */
+/*
+ * Don't write RF23/RF24 to make a difference between 87S C cut and D cut.
+ * asked by SD3 stevenl.
+ */
        RF_WriteReg(dev, 0x0a, 0x0001);         mdelay(1);
        RF_WriteReg(dev, 0x0b, 0x0418);         mdelay(1);
 
        if (d_cut) {
                RF_WriteReg(dev, 0x0c, 0x0fbe);         mdelay(1);
                RF_WriteReg(dev, 0x0d, 0x0008);         mdelay(1);
-               RF_WriteReg(dev, 0x0e, 0x0807);         mdelay(1); /* RX LO buffer */
+               /* RX LO buffer */
+               RF_WriteReg(dev, 0x0e, 0x0807);         mdelay(1);
        } else {
                RF_WriteReg(dev, 0x0c, 0x0fbe);         mdelay(1);
                RF_WriteReg(dev, 0x0d, 0x0008);         mdelay(1);
-               RF_WriteReg(dev, 0x0e, 0x0806);         mdelay(1); /* RX LO buffer */
+               /* RX LO buffer */
+               RF_WriteReg(dev, 0x0e, 0x0806);         mdelay(1);
        }
 
        RF_WriteReg(dev, 0x0f, 0x0acc);         mdelay(1);
@@ -408,19 +447,24 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
 
        RF_WriteReg(dev, 0x05, 0x0203);         mdelay(1); /* 203, 343 */
        RF_WriteReg(dev, 0x06, 0x0200);         mdelay(1); /* 400 */
-       RF_WriteReg(dev, 0x00, 0x0137);         mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */
+       /* switch to reg16-reg30, and HSSI disable 137 */
+       RF_WriteReg(dev, 0x00, 0x0137);         mdelay(1);
        mdelay(10); /* Deay 10 ms. */           /* 0xfd */
 
-       RF_WriteReg(dev, 0x0d, 0x0008);         mdelay(1); /* Z4 synthesizer loop filter setting, 392 */
+       /* Z4 synthesizer loop filter setting, 392 */
+       RF_WriteReg(dev, 0x0d, 0x0008);         mdelay(1);
        mdelay(10); /* Deay 10 ms. */           /* 0xfd */
 
-       RF_WriteReg(dev, 0x00, 0x0037);         mdelay(1); /* switch to reg0-reg15, and HSSI disable */
+       /* switch to reg0-reg15, and HSSI disable */
+       RF_WriteReg(dev, 0x00, 0x0037);         mdelay(1);
        mdelay(10); /* Deay 10 ms. */           /* 0xfd */
 
-       RF_WriteReg(dev, 0x04, 0x0160);         mdelay(1); /* CBC on, Tx Rx disable, High gain */
+       /* CBC on, Tx Rx disable, High gain */
+       RF_WriteReg(dev, 0x04, 0x0160);         mdelay(1);
        mdelay(10); /* Deay 10 ms. */           /* 0xfd */
 
-       RF_WriteReg(dev, 0x07, 0x0080);         mdelay(1); /* Z4 setted channel 1 */
+       /* Z4 setted channel 1 */
+       RF_WriteReg(dev, 0x07, 0x0080);         mdelay(1);
        mdelay(10); /* Deay 10 ms. */           /* 0xfd */
 
        RF_WriteReg(dev, 0x02, 0x088D);         mdelay(1); /* LC calibration */
@@ -428,7 +472,8 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
        mdelay(10);  /* Deay 10 ms. */          /* 0xfd */
        mdelay(10);  /* Deay 10 ms. */          /* 0xfd */
 
-       RF_WriteReg(dev, 0x00, 0x0137);         mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */
+       /* switch to reg16-reg30 137, and HSSI disable 137 */
+       RF_WriteReg(dev, 0x00, 0x0137);         mdelay(1);
        mdelay(10); /* Deay 10 ms. */           /* 0xfd */
 
        RF_WriteReg(dev, 0x07, 0x0000);         mdelay(1);
@@ -442,46 +487,58 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
        /* For crystal calibration, added by Roger, 2007.12.11. */
        if (priv->bXtalCalibration) { /* reg 30.        */
         /*
-         *  enable crystal calibration.
-         *             RF Reg[30], (1)Xin:[12:9], Xout:[8:5],  addr[4:0].
-         *             (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0
-         *             (3)RF signal on/off when calibration[13], default: on, set BIT13=0.
-         *             So we should minus 4 BITs offset. 
+         *     enable crystal calibration.
+         *     RF Reg[30], (1)Xin:[12:9], Xout:[8:5],  addr[4:0].
+         *     (2)PA Pwr delay timer[15:14], default: 2.4us,
+         *     set BIT15=0
+         *     (3)RF signal on/off when calibration[13], default: on,
+         *     set BIT13=0.
+         *     So we should minus 4 BITs offset.
          */
-               RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
+               RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) |
+                           (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
                printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
-                     (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9);
+                     (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) |
+                      BIT11 | BIT9);
        } else {
                /* using default value. Xin=6, Xout=6.  */
                RF_WriteReg(dev, 0x0f, 0x0acc);         mdelay(1);
        }
-
-       RF_WriteReg(dev, 0x00, 0x00bf);         mdelay(1); /* switch to reg0-reg15, and HSSI enable */
-       RF_WriteReg(dev, 0x0d, 0x08df);         mdelay(1); /* Rx BB start calibration, 00c//+edward */
-       RF_WriteReg(dev, 0x02, 0x004d);         mdelay(1); /* temperature meter off */
+       /* switch to reg0-reg15, and HSSI enable */
+       RF_WriteReg(dev, 0x00, 0x00bf);         mdelay(1);
+       /* Rx BB start calibration, 00c//+edward */
+       RF_WriteReg(dev, 0x0d, 0x08df);         mdelay(1);
+       /* temperature meter off */
+       RF_WriteReg(dev, 0x02, 0x004d);         mdelay(1);
        RF_WriteReg(dev, 0x04, 0x0975);         mdelay(1); /* Rx mode */
        mdelay(10);     /* Deay 10 ms.*/        /* 0xfe */
        mdelay(10);     /* Deay 10 ms.*/        /* 0xfe */
        mdelay(10);     /* Deay 10 ms.*/        /* 0xfe */
-       RF_WriteReg(dev, 0x00, 0x0197);         mdelay(1); /* Rx mode*/ /*+edward */
-       RF_WriteReg(dev, 0x05, 0x05ab);         mdelay(1); /* Rx mode*/ /*+edward */
-       RF_WriteReg(dev, 0x00, 0x009f);         mdelay(1); /* Rx mode*/ /*+edward */
-       RF_WriteReg(dev, 0x01, 0x0000);         mdelay(1); /* Rx mode*/ /*+edward */
-       RF_WriteReg(dev, 0x02, 0x0000);         mdelay(1); /* Rx mode*/ /*+edward */
+       /* Rx mode*/    /*+edward */
+       RF_WriteReg(dev, 0x00, 0x0197);         mdelay(1);
+       /* Rx mode*/    /*+edward */
+       RF_WriteReg(dev, 0x05, 0x05ab);         mdelay(1);
+       /* Rx mode*/    /*+edward */
+       RF_WriteReg(dev, 0x00, 0x009f);         mdelay(1);
+       /* Rx mode*/    /*+edward */
+       RF_WriteReg(dev, 0x01, 0x0000);         mdelay(1);
+       /* Rx mode*/    /*+edward */
+       RF_WriteReg(dev, 0x02, 0x0000);         mdelay(1);
        /* power save parameters. */
        u1b24E = read_nic_byte(dev, 0x24E);
        write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
 
-       /*=============================================================================
+       /*======================================================================
         *
-        *===========================================================================
+        *======================================================================
         * CCKCONF.TXT
-        *===========================================================================
+        *======================================================================
         *
         *      [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
         *      CCK reg0x00[7]=1'b1 :power saving for TX (default)
         *      CCK reg0x00[6]=1'b1: power saving for RX (default)
-        *      CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation.
+        *      CCK reg0x06[4]=1'b1: turn off channel estimation related
+        *      circuits if not doing channel estimation.
         *      CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
         *      CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
         */
@@ -501,9 +558,9 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
 
 
        /*
-        *===========================================================================
+        *======================================================================
         *      AGC.txt
-        *===========================================================================
+        *======================================================================
         */
 
        write_phy_ofdm(dev, 0x00, 0x12);
@@ -526,11 +583,11 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
        PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */
 
        /*
-        *===========================================================================
+        *======================================================================
         *
-        *===========================================================================
+        *======================================================================
         * OFDMCONF.TXT
-        *===========================================================================
+        *======================================================================
         */
 
        for (i = 0; i < 60; i++) {
@@ -544,12 +601,16 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
        }
 
        /*
-        *===========================================================================
+        *======================================================================
         * by amy for antenna
-        *===========================================================================
+        *======================================================================
         */
-       /* Config Sw/Hw  Combinational Antenna Diversity. Added by Roger, 2008.02.26.   */
-       SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
+       /*
+        * Config Sw/Hw  Combinational Antenna Diversity. Added by Roger,
+        * 2008.02.26.
+        */
+       SetAntennaConfig87SE(dev, priv->bDefaultAntenna1,
+                            priv->bSwAntennaDiverity);
 }
 
 
@@ -560,7 +621,8 @@ void UpdateInitialGain(struct net_device *dev)
        /* lzm add 080826 */
        if (priv->eRFPowerState != eRfOn) {
                /*      Don't access BB/RF under disable PLL situation.
-                *      RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n"));
+                *      RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain -
+                *      pHalData->eRFPowerState!=eRfOn\n"));
                 *      Back to the original state
                 */
                priv->InitialGain = priv->InitialGainBackUp;
@@ -635,7 +697,7 @@ static void InitTxPwrTracking87SE(struct net_device *dev)
        u4bRfReg = RF_ReadReg(dev, 0x02);
 
        /* Enable Thermal meter indication.     */
-       RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN);                  mdelay(1);
+       RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN);          mdelay(1);
 }
 
 static void PhyConfig8185(struct net_device *dev)
@@ -645,16 +707,18 @@ static void PhyConfig8185(struct net_device *dev)
           priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
        /*  RF config */
        ZEBRA_Config_85BASIC_HardCode(dev);
-       /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. */
+       /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce,
+        * 2007-06-06.
+        */
        if (priv->bDigMechanism) {
                if (priv->InitialGain == 0)
                        priv->InitialGain = 4;
        }
 
        /*
-        *      Enable thermal meter indication to implement TxPower tracking on 87SE.
-        *      We initialize thermal meter here to avoid unsuccessful configuration.
-        *      Added by Roger, 2007.12.11.
+        *      Enable thermal meter indication to implement TxPower tracking
+        *      on 87SE. We initialize thermal meter here to avoid unsuccessful
+        *      configuration. Added by Roger, 2007.12.11.
         */
        if (priv->bTxPowerTrack)
                InitTxPwrTracking87SE(dev);
@@ -667,7 +731,10 @@ static void PhyConfig8185(struct net_device *dev)
 
 static void HwConfigureRTL8185(struct net_device *dev)
 {
-       /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */
+       /*
+        * RTL8185_TODO: Determine Retrylimit, TxAGC,
+        * AutoRateFallback control.
+        */
        u8 bUNIVERSAL_CONTROL_RL = 0;
        u8 bUNIVERSAL_CONTROL_AGC = 1;
        u8 bUNIVERSAL_CONTROL_ANT = 1;
@@ -691,7 +758,7 @@ static void HwConfigureRTL8185(struct net_device *dev)
                write_nic_byte(dev, OFDM_TXAGC, 128);
                val8 = val8 & 0xfe;
        } else {
-               val8 = val8 | 0x01 ;
+               val8 = val8 | 0x01;
        }
 
 
@@ -715,7 +782,9 @@ static void HwConfigureRTL8185(struct net_device *dev)
        if (bAUTO_RATE_FALLBACK_CTL) {
                val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
 
-               /* <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. */
+               /* <RJ_TODO_8185B> We shall set up the ARFR according
+                * to user's setting.
+                */
                PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
        }
        write_nic_byte(dev, RATE_FALLBACK, val8);
@@ -724,9 +793,9 @@ static void HwConfigureRTL8185(struct net_device *dev)
 static void MacConfig_85BASIC_HardCode(struct net_device *dev)
 {
        /*
-        *==========================================================================
+        *======================================================================
         * MACREG.TXT
-        *==========================================================================
+        *======================================================================
         */
        int nLinesRead = 0;
        u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
@@ -745,7 +814,7 @@ static void MacConfig_85BASIC_HardCode(struct net_device *dev)
 
                write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
        }
-       /* ============================================================================ */
+       /* ================================================================= */
 }
 
 static void MacConfig_85BASIC(struct net_device *dev)
@@ -754,12 +823,14 @@ static void MacConfig_85BASIC(struct net_device *dev)
        u8                      u1DA;
        MacConfig_85BASIC_HardCode(dev);
 
-       /* ============================================================================ */
+       /* ================================================================= */
 
        /* Follow TID_AC_MAP of WMac. */
        write_nic_word(dev, TID_AC_MAP, 0xfa50);
 
-       /* Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko. */
+       /* Interrupt Migration, Jong suggested we use set 0x0000 first,
+        * 2005.12.14, by rcnjko.
+        */
        write_nic_word(dev, IntMig, 0x0000);
 
        /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
@@ -768,7 +839,11 @@ static void MacConfig_85BASIC(struct net_device *dev)
        PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
 
        /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */
-       /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */
+
+       /*
+        *  power save parameter based on
+        * "87SE power save parameters 20071127.doc", as follow.
+        */
 
        /* Enable DA10 TX power saving */
        u1DA = read_nic_byte(dev, PHYPR);
@@ -803,31 +878,45 @@ static void ActUpdateChannelAccessSetting(struct net_device *dev,
 
        /*
         *      <RJ_TODO_8185B>
-        *      TODO: We still don't know how to set up these registers, just follow WMAC to
-        *      verify 8185B FPAG.
+        *      TODO: We still don't know how to set up these registers,
+        *      just follow WMAC to verify 8185B FPAG.
         *
         *      <RJ_TODO_8185B>
         *      Jong said CWmin/CWmax register are not functional in 8185B,
-        *      so we shall fill channel access realted register into AC parameter registers,
+        *      so we shall fill channel access realted register into AC
+        *      parameter registers,
         *      even in nQBss.
         */
-       ChnlAccessSetting->SIFS_Timer = 0x22; /* Suggested by Jong, 2005.12.08. */
+
+       /* Suggested by Jong, 2005.12.08. */
+       ChnlAccessSetting->SIFS_Timer = 0x22;
        ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */
        ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */
-       ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
+       /*
+        * Suggested by wcchu, it is the default value of EIFS register,
+        * 2005.12.08.
+        */
+       ChnlAccessSetting->EIFS_Timer = 0x5B;
        ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */
        ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */
 
        write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
-       write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */
+       /*
+        * Rewrited from directly use PlatformEFIOWrite1Byte(),
+        * by Annie, 2006-03-29.
+        */
+       write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer);
 
        write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
 
-       write_nic_byte(dev, AckTimeOutReg, 0x5B); /* <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
+       /*
+        * <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS
+        * register, 2005.12.08.
+        */
+       write_nic_byte(dev, AckTimeOutReg, 0x5B);
 
-       for (eACI = 0; eACI < AC_MAX; eACI++) {
+       for (eACI = 0; eACI < AC_MAX; eACI++)
                write_nic_byte(dev, ACM_CONTROL, 0);
-       }
 }
 
 static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
@@ -837,7 +926,10 @@ static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
        u8      btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
 
        if ((btWirelessMode & btSupportedWirelessMode) == 0)    {
-               /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */
+               /*
+                * Don't switch to unsupported wireless mode, 2006.02.15,
+                * by rcnjko.
+                */
                DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
                        btWirelessMode, btSupportedWirelessMode);
                return;
@@ -859,11 +951,11 @@ static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
                }
        }
 
-       /* 
-        * 2. Swtich band: RF or BB specific actions,
-        * for example, refresh tables in omc8255, or change initial gain if necessary.
-        * Nothing to do for Zebra to switch band.
-        * Update current wireless mode if we switch to specified band successfully. 
+       /*
+        * 2. Swtich band: RF or BB specific actions,
+        * for example, refresh tables in omc8255, or change initial gain if
+        * necessary. Nothing to do for Zebra to switch band. Update current
+        * wireless mode if we switch to specified band successfully.
         */
 
        ieee->mode = (WIRELESS_MODE)btWirelessMode;
@@ -876,7 +968,8 @@ static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
        else if (ieee->mode == WIRELESS_MODE_G)
                DMESG("WIRELESS_MODE_G\n");
 
-       ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
+       ActUpdateChannelAccessSetting(dev, ieee->mode,
+                                     &priv->ChannelAccessSetting);
 }
 
 void rtl8185b_irq_enable(struct net_device *dev)
@@ -892,7 +985,7 @@ static void MgntDisconnectIBSS(struct net_device *dev)
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        u8 i;
 
-       for (i = 0; i < 6 ; i++)
+       for (i = 0; i < 6; i++)
                priv->ieee80211->current_network.bssid[i] = 0x55;
 
 
@@ -901,11 +994,12 @@ static void MgntDisconnectIBSS(struct net_device *dev)
        /*
         *      Stop Beacon.
         *
-        *      Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST
-        *      Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck.
-        *      Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
+        *      Vista add a Adhoc profile, HW radio off until
+        *      OID_DOT11_RESET_REQUEST Driver would set MSR=NO_LINK,
+        *      then HW Radio ON, MgntQueue Stuck. Because Bcn DMA isn't
+        *      complete, mgnt queue would stuck until Bcn packet send.
         *
-        *      Disable Beacon Queue Own bit, suggested by jong 
+        *      Disable Beacon Queue Own bit, suggested by jong
         */
        ieee80211_stop_send_beacons(priv->ieee80211);
 
@@ -938,12 +1032,14 @@ static void MgntDisconnectAP(struct net_device *dev, u8 asRsn)
         * Commented out by rcnjko, 2005.01.27:
         * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
         *
-        *      2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
+        *      2004/09/15, kcwu, the key should be cleared, or the new
+        *      handshaking will not success
         *
-        *      In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
-        *      2004.10.11, by rcnjko. 
+        *      In WPA WPA2 need to Clear all key ... because new key will set
+        *      after new handshaking. 2004.10.11, by rcnjko.
         */
-       MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn);
+       MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid,
+                               asRsn);
 
        priv->ieee80211->state = IEEE80211_NOLINK;
 }
@@ -964,11 +1060,13 @@ static bool MgntDisconnect(struct net_device *dev, u8 asRsn)
 
                if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
                        /*
-                        *      We clear key here instead of MgntDisconnectAP() because that
-                        *      MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
-                        *      e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
-                        *      used to handle disassociation related things to AP, e.g. send Disassoc
-                        *      frame to AP.  2005.01.27, by rcnjko. 
+                        *      We clear key here instead of MgntDisconnectAP()
+                        *      because that MgntActSet_802_11_DISASSOCIATE()
+                        *      is an interface called by OS, e.g.
+                        *      OID_802_11_DISASSOCIATE in Windows while as
+                        *      MgntDisconnectAP() is used to handle
+                        *      disassociation related things to AP, e.g. send
+                        *      Disassoc frame to AP.  2005.01.27, by rcnjko.
                         */
                        MgntDisconnectAP(dev, asRsn);
                }
@@ -979,12 +1077,14 @@ static bool MgntDisconnect(struct net_device *dev, u8 asRsn)
 /*
  *     Description:
  *             Chang RF Power State.
- *             Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
+ *             Note that, only MgntActSet_RF_State() is allowed to set
+ *             HW_VAR_RF_STATE.
  *
  *     Assumption:
  *             PASSIVE LEVEL.
  */
-static bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState)
+static bool SetRFPowerState(struct net_device *dev,
+               RT_RF_POWER_STATE eRFPowerState)
 {
        struct  r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        bool    bResult = false;
@@ -997,7 +1097,8 @@ static bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerSt
        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;
@@ -1006,8 +1107,9 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u
        u16     RFWaitCounter = 0;
        unsigned long flag;
        /*
-        *      Prevent the race condition of RF state change. By Bruce, 2007-11-28.
-        *      Only one thread can change the RF state at one time, and others should wait to be executed.
+        *      Prevent the race condition of RF state change. By Bruce,
+        *      2007-11-28. Only one thread can change the RF state at one time,
+        *      and others should wait to be executed.
         */
        while (true) {
                spin_lock_irqsave(&priv->rf_ps_lock, flag);
@@ -1018,7 +1120,10 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u
                                RFWaitCounter++;
                                udelay(1000); /* 1 ms   */
 
-                               /* Wait too long, return FALSE to avoid to be stuck here. */
+                               /*
+                                *      Wait too long, return FALSE to avoid
+                                *      to be stuck here.
+                                */
                                if (RFWaitCounter > 1000) { /* 1sec */
                                        printk("MgntActSet_RF_State(): Wait too long to set RF\n");
                                        /* TODO: Reset RF state? */
@@ -1036,8 +1141,10 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u
        switch (StateToSet) {
        case eRfOn:
                /*
-                *      Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
-                *      the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
+                *      Turn On RF no matter the IPS setting because we need to
+                *      update the RF state to Ndis under Vista, or the Windows
+                *      does not allow the driver to perform site survey any
+                *      more. By Bruce, 2007-10-02.
                 */
                priv->RfOffReason &= (~ChangeSource);
 
@@ -1045,7 +1152,8 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u
                        priv->RfOffReason = 0;
                        bActionAllowed = true;
 
-                       if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW)
+                       if (rtState == eRfOff &&
+                           ChangeSource >= RF_CHANGE_BY_HW)
                                bConnectBySSID = true;
                }
                break;
@@ -1056,13 +1164,18 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u
                if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
                        /*
                         *      060808, Annie:
-                        *      Disconnect to current BSS when radio off. Asked by QuanTa.
+                        *      Disconnect to current BSS when radio off.
+                        *      Asked by QuanTa.
                         *
-                        *      Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
-                        *      because we do NOT need to set ssid to dummy ones.
+                        *      Calling MgntDisconnect() instead of
+                        *      MgntActSet_802_11_DISASSOCIATE(), because
+                        *      we do NOT need to set ssid to dummy ones.
                         */
                        MgntDisconnect(dev, disas_lv_ss);
-                       /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */
+                       /*
+                        *      Clear content of bssDesc[] and bssDesc4Query[]
+                        *      to avoid reporting old bss to UI.
+                        */
                }
 
                priv->RfOffReason |= ChangeSource;
@@ -1092,18 +1205,21 @@ static void InactivePowerSave(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        /*
-        *      This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
-        *      is really scheduled.
-        *      The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
-        *      previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
-        *      blocks the IPS procedure of switching RF.
+        *      This flag "bSwRfProcessing", indicates the status of IPS
+        *      procedure, should be set if the IPS workitem is really
+        *      scheduled. The old code, sets this flag before scheduling the
+        *      IPS workitem and however, at the same time the previous IPS
+        *      workitem did not end yet, fails to schedule the current
+        *      workitem. Thus, bSwRfProcessing blocks the IPS procedure of
+        *      switching RF.
         */
        priv->bSwRfProcessing = true;
 
        MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
 
        /*
-        *      To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
+        *      To solve CAM values miss in RF OFF, rewrite CAM values after
+        *      RF ON. By Bruce, 2007-09-20.
         */
 
        priv->bSwRfProcessing = false;
@@ -1122,10 +1238,10 @@ void IPSEnter(struct net_device *dev)
 
                /*
                 *      Do not enter IPS in the following conditions:
-                *      (1) RF is already OFF or Sleep
-                *      (2) bSwRfProcessing (indicates the IPS is still under going)
-                *      (3) Connected (only disconnected can trigger IPS)
-                *      (4) IBSS (send Beacon)
+                *      (1) RF is already OFF or
+                *      Sleep (2) bSwRfProcessing (indicates the IPS is still
+                *      under going) (3) Connected (only disconnected can
+                *      trigger IPS)(4) IBSS (send Beacon)
                 *      (5) AP mode (send Beacon)
                 */
                if (rtState == eRfOn && !priv->bSwRfProcessing
@@ -1141,7 +1257,9 @@ void IPSLeave(struct net_device *dev)
        RT_RF_POWER_STATE rtState;
        if (priv->bInactivePs) {
                rtState = priv->eRFPowerState;
-               if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
+               if ((rtState == eRfOff || rtState == eRfSleep) &&
+                   !priv->bSwRfProcessing
+                   && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
                        priv->eInactivePowerState = eRfOn;
                        InactivePowerSave(dev);
                }
@@ -1170,27 +1288,32 @@ void rtl8185b_adapter_start(struct net_device *dev)
        HwConfigureRTL8185(dev);
        write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
        write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
-       write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */
+       /* default network type to 'No Link' */
+       write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3);
        write_nic_word(dev, BcnItv, 100);
        write_nic_word(dev, AtimWnd, 2);
        PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
        write_nic_byte(dev, WPA_CONFIG, 0);
        MacConfig_85BASIC(dev);
-       /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */
+       /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07,
+        * by rcnjko.
+        */
        /* BT_DEMO_BOARD type */
        PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
 
        /*
-        *---------------------------------------------------------------------------
+        *---------------------------------------------------------------------
         *      Set up PHY related.
-        *---------------------------------------------------------------------------
+        *---------------------------------------------------------------------
         */
        /* Enable Config3.PARAM_En to revise AnaaParm. */
        write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
        tmpu8 = read_nic_byte(dev, CONFIG3);
        write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En));
        /* Turn on Analog power. */
-       /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */
+       /* Asked for by William, otherwise, MAC 3-wire can't work,
+        * 2006.06.27, by rcnjko.
+        */
        write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
        write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
        write_nic_word(dev, ANAPARAM3, 0x0010);
@@ -1225,7 +1348,8 @@ void rtl8185b_adapter_start(struct net_device *dev)
        /*
         *      We assume RegWirelessMode has already been initialized before,
         *      however, we has to validate the wireless mode here and provide a
-        *      reasonable initialized value if necessary. 2005.01.13, by rcnjko.
+        *      reasonable initialized value if necessary. 2005.01.13,
+        *      by rcnjko.
         */
        SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
        if ((ieee->mode != WIRELESS_MODE_B) &&
@@ -1272,14 +1396,15 @@ void rtl8185b_adapter_start(struct net_device *dev)
                MgntActSet_RF_State(dev, eRfOn, 0);
        }
                /*
-                *      If inactive power mode is enabled, disable rf while in disconnected state.
+                * If inactive power mode is enabled, disable rf while in
+                * disconnected state.
                 */
        if (priv->bInactivePs)
                MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS);
 
        ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
 
-       /* ----------------------------------------------------------------------------- */
+       /* ----------------------------------------------------------------- */
 
        rtl8185b_irq_enable(dev);
 
@@ -1296,14 +1421,15 @@ void rtl8185b_rx_enable(struct net_device *dev)
        if (dev->flags & IFF_PROMISC)
                DMESG("NIC in promisc mode");
 
-       if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
-          dev->flags & IFF_PROMISC) {
+       if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || dev->flags &
+           IFF_PROMISC) {
                priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
                priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
        }
 
        if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
-               priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
+               priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF |
+                                     RCR_APWRMGT | RCR_AICV;
 
 
        if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
index 1639a45da948252b3c756b7d28cbe70b185a9f5e..0a617b42cc9907f8e6428a78506ea91fa3dad1c3 100644 (file)
@@ -1,5 +1,3 @@
-EXTRA_CFLAGS += -I$(src)/include
-
 r8188eu-y :=                           \
                core/rtw_ap.o           \
                core/rtw_br_ext.o       \
@@ -30,7 +28,6 @@ r8188eu-y :=                          \
                hal/HalPhyRf.o          \
                hal/HalPhyRf_8188e.o    \
                hal/HalPwrSeqCmd.o      \
-               hal/Hal8188EFWImg_CE.o  \
                hal/Hal8188EPwrSeq.o    \
                hal/Hal8188ERateAdaptive.o\
                hal/hal_intf.o          \
@@ -67,4 +64,4 @@ r8188eu-y :=                          \
 
 obj-$(CONFIG_R8188EU)  := r8188eu.o
 
-ccflags-y += -D__CHECK_ENDIAN__
+ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/include
index e50aa50bdb478a974e7c04900183620fc05c9d91..f7f389c40e71429d6ee48fd8742dcb7193afab7a 100644 (file)
@@ -2,7 +2,6 @@ TODO:
 - find and remove remaining code valid only for 5 HGz. Most of the obvious
   ones have been removed, but things like channel > 14 still exist.
 - find and remove any code for other chips that is left over
-- convert to external firmware
 - convert any remaining unusual variable types
 - find codes that can use %pM and %Nph formatting
 - checkpatch.pl fixes - most of the remaining ones are lines too long. Many
index 2c73823d2245be5c1a01a40b34696edf318b8b3a..2c678f4095734698b2fcfcdf6318691b7b8c4855 100644 (file)
@@ -348,7 +348,7 @@ void        expire_timeout_chk(struct adapter *padapter)
 
                        if (psta->state & WIFI_SLEEP_STATE) {
                                if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
-                                       /* to check if alive by another methods if staion is at ps mode. */
+                                       /* to check if alive by another methods if station is at ps mode. */
                                        psta->expire_to = pstapriv->expire_to;
                                        psta->state |= WIFI_STA_ALIVE_CHK_STATE;
 
index fbca394cf4fcd5f02073529422ce9a3bace0bda0..9f40742ee5cfe195c7471db2358bd70559d33481 100644 (file)
@@ -527,7 +527,7 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
                case NAT25_CHECK:
                        return -1;
                case NAT25_INSERT:
-                       /* some muticast with source IP is all zero, maybe other case is illegal */
+                       /* some multicast with source IP is all zero, maybe other case is illegal */
                        /* in class A, B, C, host address is all zero or all one is illegal */
                        if (iph->saddr == 0)
                                return 0;
@@ -677,9 +677,8 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
                        switch (method) {
                        case NAT25_CHECK:
                                if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN))
-                               DEBUG_INFO("NAT25: Check IPX skb_copy\n");
+                                       DEBUG_INFO("NAT25: Check IPX skb_copy\n");
                                return 0;
-                               return -1;
                        case NAT25_INSERT:
                                DEBUG_INFO("NAT25: Insert IPX, Dest =%08x,%02x%02x%02x%02x%02x%02x,%04x Source =%08x,%02x%02x%02x%02x%02x%02x,%04x\n",
                                        ipx->ipx_dest.net,
index 9632ef48fbc1234877a19d031ade4633d14483ad..f45f4eddb741615774dde3af53e9248bf7a82a03 100644 (file)
@@ -218,7 +218,7 @@ _func_enter_;
 _func_exit_;
 }
 
-int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
+static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
 {
        u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
 
@@ -1162,7 +1162,7 @@ _func_enter_;
        else
                memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
 
-       /* jeff: set this becasue at least sw key is ready */
+       /* jeff: set this because at least sw key is ready */
        padapter->securitypriv.busetkipkey = true;
 
        res = rtw_enqueue_cmd(pcmdpriv, ph2c);
@@ -1667,7 +1667,7 @@ static void traffic_status_watchdog(struct adapter *padapter)
        pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
 }
 
-void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
+static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
 {
        struct mlme_priv *pmlmepriv;
 
index 869434c4cf6924d012eaae192cf6093a2cd00247..806f56f1c4378195d326450c0cdcd916d8f3b1f2 100644 (file)
@@ -159,7 +159,7 @@ Efuse_CalculateWordCnts(u8 word_en)
 /*  */
 /*     Description: */
 /*             Execute E-Fuse read byte operation. */
-/*             Refered from SD1 Richard. */
+/*             Referred from SD1 Richard. */
 /*  */
 /*     Assumption: */
 /*             1. Boot from E-Fuse and successfully auto-load. */
@@ -214,7 +214,7 @@ ReadEFuseByte(
 /*     Description: */
 /*             1. Execute E-Fuse read byte operation according as map offset and */
 /*                 save to E-Fuse table. */
-/*             2. Refered from SD1 Richard. */
+/*             2. Referred from SD1 Richard. */
 /*  */
 /*     Assumption: */
 /*             1. Boot from E-Fuse and successfully auto-load. */
@@ -542,7 +542,7 @@ u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
        u8 offset, word_en;
        u8 *map;
-       u8 newdata[PGPKT_DATA_SIZE];
+       u8 newdata[PGPKT_DATA_SIZE + 1];
        s32     i, idx;
        u8 ret = _SUCCESS;
        u16 mapLen = 0;
@@ -564,7 +564,7 @@ u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
        offset = (addr >> 3);
        word_en = 0xF;
-       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
+       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
        i = addr & 0x7; /*  index of one package */
        idx = 0;        /*  data index */
 
@@ -634,7 +634,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data
 {
        u8 offset, word_en;
        u8 *map;
-       u8 newdata[PGPKT_DATA_SIZE];
+       u8 newdata[PGPKT_DATA_SIZE + 1];
        s32     i, idx;
        u8 ret = _SUCCESS;
        u16 mapLen = 0;
@@ -656,7 +656,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data
 
        offset = (addr >> 3);
        word_en = 0xF;
-       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
+       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
        i = addr & 0x7; /*  index of one package */
        idx = 0;        /*  data index */
 
index 6fc77428e83a0c389c51e6cca52ceaa6a8ff7dd9..e6f98fb8f11353e139f41635d589a11eac64b316 100644 (file)
@@ -1129,7 +1129,7 @@ void rtw_macaddr_cfg(u8 *mac_addr)
                mac[3] = 0x87;
                mac[4] = 0x00;
                mac[5] = 0x00;
-               /*  use default mac addresss */
+               /*  use default mac address */
                memcpy(mac_addr, mac, ETH_ALEN);
                DBG_88E("MAC Address from efuse error, assign default one !!!\n");
        }
index ea6607196d84bb1d22c8fcd474144ee8f699d71d..ac3535d33a45a3a42bbdf42b96cde8cad539cafd 100644 (file)
@@ -557,7 +557,7 @@ _func_enter_;
                        sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
                        rssi_final = (src->Rssi+dst->Rssi*4)/5;
                } else {
-                       /* bss info not receving from the right channel, use the original RX signal infos */
+                       /* bss info not receiving from the right channel, use the original RX signal infos */
                        ss_final = dst->PhyInfo.SignalStrength;
                        sq_final = dst->PhyInfo.SignalQuality;
                        rssi_final = dst->Rssi;
@@ -636,7 +636,7 @@ _func_enter_;
                        pnetwork->aid = 0;
                        pnetwork->join_res = 0;
 
-                       /* bss info not receving from the right channel */
+                       /* bss info not receiving from the right channel */
                        if (pnetwork->network.PhyInfo.SignalQuality == 101)
                                pnetwork->network.PhyInfo.SignalQuality = 0;
                } else {
@@ -656,7 +656,7 @@ _func_enter_;
 
                        pnetwork->last_scanned = rtw_get_current_time();
 
-                       /* bss info not receving from the right channel */
+                       /* bss info not receiving from the right channel */
                        if (pnetwork->network.PhyInfo.SignalQuality == 101)
                                pnetwork->network.PhyInfo.SignalQuality = 0;
                        rtw_list_insert_tail(&(pnetwork->list), &(queue->queue));
@@ -670,7 +670,7 @@ _func_enter_;
 
                pnetwork->last_scanned = rtw_get_current_time();
 
-               /* target.Reserved[0]== 1, means that scaned network is a bcn frame. */
+               /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
                if ((pnetwork->network.IELength > target->IELength) && (target->Reserved[0] == 1))
                        update_ie = false;
 
@@ -1130,7 +1130,7 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str
                        padapter->securitypriv.wps_ie_len = 0;
                }
                /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
-               /* if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
+               /* if A-MPDU Rx is enabled, resetting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
                /* todo: check if AP can send A-MPDU packets */
                for (i = 0; i < 16; i++) {
                        /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
@@ -1210,7 +1210,7 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net
        rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength);
 }
 
-/* Notes: the fucntion could be > passive_level (the same context as Rx tasklet) */
+/* Notes: the function could be > passive_level (the same context as Rx tasklet) */
 /* pnetwork: returns from rtw_joinbss_event_callback */
 /* ptarget_wlan: found from scanned_queue */
 /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist. */
@@ -2177,7 +2177,7 @@ _func_enter_;
 _func_exit_;
 }
 
-/* the fucntion is at passive_level */
+/* the function is at passive_level */
 void rtw_joinbss_reset(struct adapter *padapter)
 {
        u8      threshold;
@@ -2205,7 +2205,7 @@ void rtw_joinbss_reset(struct adapter *padapter)
        }
 }
 
-/* the fucntion is >= passive_level */
+/* the function is >= passive_level */
 unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
 {
        u32 ielen, out_len;
@@ -2273,7 +2273,7 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
        return phtpriv->ht_option;
 }
 
-/* the fucntion is > passive_level (in critical_section) */
+/* the function is > passive_level (in critical_section) */
 void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
 {
        u8 *p, max_ampdu_sz;
@@ -2332,7 +2332,7 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
                        else
                                pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
                }
-               /* switch to the 40M Hz mode accoring to the AP */
+               /* switch to the 40M Hz mode according to the AP */
                pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
                switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
                case HT_EXTCHNL_OFFSET_UPPER:
index 4b2eb8e9b5620ab4529ec9ce8af252ef502a65fc..7ab5ff039c8807da5d5d9fbcdac16859a4fa4a3b 100644 (file)
@@ -1852,7 +1852,7 @@ void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr)
        struct pkt_attrib *pattrib;
        unsigned char *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short *fctrl;
+       __le16 *fctrl;
        struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
@@ -2199,7 +2199,7 @@ static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
@@ -2349,7 +2349,7 @@ static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame
        if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
                /*      Commented by Albert 2011/03/08 */
                /*      According to the P2P specification */
-               /*      if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
+               /*      if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */
                p2pie[p2pielen++] = 0;
        } else {
                /*      Be group owner or meet the error case */
@@ -2561,7 +2561,7 @@ static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result)
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
@@ -2729,7 +2729,7 @@ void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr)
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
@@ -2981,7 +2981,7 @@ void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialo
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
@@ -3175,7 +3175,7 @@ void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidle
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
@@ -3283,7 +3283,7 @@ void issue_probersp_p2p(struct adapter *padapter, unsigned char *da)
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        unsigned char                                   *mac;
        struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
@@ -3534,7 +3534,7 @@ static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack)
        struct pkt_attrib               *pattrib;
        unsigned char                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short          *fctrl;
+       __le16 *fctrl;
        unsigned char                   *mac;
        struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
@@ -4484,7 +4484,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
        struct pkt_attrib       *pattrib;
        unsigned char   *pframe;
        struct rtw_ieee80211_hdr *pwlanhdr;
-       unsigned short *fctrl;
+       __le16 *fctrl;
        unsigned int    rate_len;
        struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
 #if defined(CONFIG_88EU_AP_MODE)
@@ -4713,7 +4713,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        unsigned char                                   *mac, *bssid;
        struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
 #if defined (CONFIG_88EU_AP_MODE)
@@ -4876,7 +4876,7 @@ static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps
        struct pkt_attrib               *pattrib;
        unsigned char                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short          *fctrl;
+       __le16 *fctrl;
        unsigned char                   *mac;
        unsigned char                   bssrate[NumRates];
        struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
@@ -5013,7 +5013,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
        struct pkt_attrib *pattrib;
        unsigned char *pframe;
        struct rtw_ieee80211_hdr *pwlanhdr;
-       unsigned short *fctrl;
+       __le16 *fctrl;
        unsigned int val32;
        u16 val16;
 #ifdef CONFIG_88EU_AP_MODE
@@ -5153,7 +5153,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
        struct pkt_attrib *pattrib;
        unsigned char   *pbuf, *pframe;
        unsigned short val;
-       unsigned short *fctrl;
+       __le16 *fctrl;
        struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -5290,7 +5290,7 @@ void issue_assocreq(struct adapter *padapter)
        struct pkt_attrib       *pattrib;
        unsigned char           *pframe, *p;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short  *fctrl;
+       __le16 *fctrl;
        __le16          le_tmp;
        unsigned int    i, j, ie_len, index = 0;
        unsigned char   rf_type, bssrate[NumRates], sta_bssrate[NumRates];
@@ -5625,7 +5625,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv        *pxmitpriv;
        struct mlme_ext_priv    *pmlmeext;
        struct mlme_ext_info    *pmlmeinfo;
@@ -5740,7 +5740,8 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl, *qc;
+       __le16 *fctrl;
+       unsigned short *qc;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -5860,7 +5861,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -5972,7 +5973,7 @@ void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u
        struct pkt_attrib                       *pattrib;
        unsigned char                           *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                  *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
 
@@ -6040,7 +6041,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
        struct pkt_attrib *pattrib;
        u8 *pframe;
        struct rtw_ieee80211_hdr *pwlanhdr;
-       u16 *fctrl;
+       __le16 *fctrl;
        struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
        struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -6162,7 +6163,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
        struct pkt_attrib                       *pattrib;
        unsigned char                           *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                  *fctrl;
+       __le16 *fctrl;
        struct  wlan_network    *pnetwork = NULL;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -6698,7 +6699,7 @@ u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, str
                }
        }
 
-       /*  mark bss info receving from nearby channel as SignalQuality 101 */
+       /*  mark bss info receiving from nearby channel as SignalQuality 101 */
        if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
                bssid->PhyInfo.SignalQuality = 101;
        return _SUCCESS;
@@ -8110,7 +8111,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
                Save_DM_Func_Flag(padapter);
                Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
 
-               /* config the initial gain under scaning, need to write the BB registers */
+               /* config the initial gain under scanning, need to write the BB registers */
 #ifdef CONFIG_88EU_P2P
                if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
                        initialgain = 0x1E;
index 8cf915f4cf982935d93cd1f1ddd9024d3f22ead3..f46cab14a54de44bd570cebddc65d89cf450e65d 100644 (file)
@@ -135,7 +135,7 @@ static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct adapter *padapter = pwdinfo->padapter;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
@@ -192,7 +192,7 @@ static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 s
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct adapter *padapter = pwdinfo->padapter;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
@@ -272,7 +272,7 @@ static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr,
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
 
@@ -342,7 +342,7 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
        struct pkt_attrib                       *pattrib;
        unsigned char                                   *pframe;
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       unsigned short                          *fctrl;
+       __le16 *fctrl;
        struct adapter *padapter = pwdinfo->padapter;
        struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
index 58a1661f5a84714cdf377461c929eb617cc35397..b45461fe20fea50fe86da38e7240e9b18174c315 100644 (file)
@@ -193,7 +193,7 @@ void rtw_ps_processor(struct adapter *padapter)
        if (pwrpriv->ips_mode_req == IPS_NONE)
                goto exit;
 
-       if (rtw_pwr_unassociated_idle(padapter) == false)
+       if (!rtw_pwr_unassociated_idle(padapter))
                goto exit;
 
        if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0)) {
index 201165787362b6ea9d1b2a7613b1c8d7457dffe0..9f0f30f7069a92be71028f670c0aff9173b742be 100644 (file)
@@ -204,11 +204,14 @@ void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpri
 int rtw_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue)
 {
        unsigned long irqL;
-       struct adapter *padapter = precvframe->u.hdr.adapter;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
+       struct adapter *padapter;
+       struct recv_priv *precvpriv;
 
 _func_enter_;
-
+       if (!precvframe)
+               return _FAIL;
+       padapter = precvframe->u.hdr.adapter;
+       precvpriv = &padapter->recvpriv;
        if (precvframe->u.hdr.pkt) {
                dev_kfree_skb_any(precvframe->u.hdr.pkt);/* free skb by driver */
                precvframe->u.hdr.pkt = NULL;
@@ -1583,7 +1586,7 @@ _func_enter_;
 
                pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
                plist = get_next(plist);
-       };
+       }
 
        /* free the defrag_q queue and return the prframe */
        rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
@@ -1798,16 +1801,14 @@ static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe)
                        memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
                }
 
-               /* Indicat the packets to upper layer */
-               if (sub_skb) {
-                       /*  Insert NAT2.5 RX here! */
-                       sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
-                       sub_skb->dev = padapter->pnetdev;
+               /* Indicate the packets to upper layer */
+               /*  Insert NAT2.5 RX here! */
+               sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
+               sub_skb->dev = padapter->pnetdev;
 
-                       sub_skb->ip_summed = CHECKSUM_NONE;
+               sub_skb->ip_summed = CHECKSUM_NONE;
 
-                       netif_rx(sub_skb);
-               }
+               netif_rx(sub_skb);
        }
 
 exit:
index 0f076d0cb5f8571227b8fc58d68a407e22f5863d..e08845729772ff4377decd805a2f6b57cd8d9235 100644 (file)
@@ -916,7 +916,7 @@ _func_enter_;
                        add1b[i] = 0x00;
        }
 
-       swap_halfs[0] = in[2];    /* Swap halfs */
+       swap_halfs[0] = in[2];    /* Swap halves */
        swap_halfs[1] = in[3];
        swap_halfs[2] = in[0];
        swap_halfs[3] = in[1];
index c2977be92fb14d3d4d7f2892b3c9f5baa9c954f7..cd3c9a7c3044c26ea626bf1b8e89070aeedaa3c4 100644 (file)
@@ -267,9 +267,8 @@ _func_enter_;
 
                rtw_mfree_sta_priv_lock(pstapriv);
 
-               if (pstapriv->pallocated_stainfo_buf) {
+               if (pstapriv->pallocated_stainfo_buf)
                        rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4);
-               }
        }
 
 _func_exit_;
@@ -315,7 +314,7 @@ _func_enter_;
 
                rtw_list_insert_tail(&psta->hash_list, phash_list);
 
-               pstapriv->asoc_sta_count++ ;
+               pstapriv->asoc_sta_count++;
 
                _exit_critical_bh(&(pstapriv->sta_hash_lock), &irql2);
 
@@ -419,7 +418,7 @@ _func_enter_;
        _cancel_timer_ex(&psta->addba_retry_timer);
 
        /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
-       for (i = 0; i < 16 ; i++) {
+       for (i = 0; i < 16; i++) {
                unsigned long irql;
                struct list_head *phead, *plist;
                union recv_frame *prframe;
index 8018edd3d42e19fcc0875c7324584d94e6fb02ad..153ec61493ab6ef94a4ec71f886b8a700ecad4ad 100644 (file)
@@ -80,7 +80,7 @@ int cckratesonly_included(unsigned char *rate, int ratelen)
        for (i = 0; i < ratelen; i++) {
                if  ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
                           (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22))
-               return false;
+                       return false;
        }
 
        return true;
@@ -766,7 +766,7 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 
        for (i = 0; i < (pIE->Length); i++) {
                if (i != 2) {
-                       /*      Got the endian issue here. */
+                       /*      Got the endian issue here. */
                        pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
                } else {
                        /* modify from  fw by Thomas 2010/11/17 */
@@ -1096,13 +1096,13 @@ int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
        }
 
        kfree(bssid);
+       _func_exit_;
        return _SUCCESS;
 
 _mismatch:
        kfree(bssid);
-       return _FAIL;
-
        _func_exit_;
+       return _FAIL;
 }
 
 void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
@@ -1186,7 +1186,7 @@ unsigned int should_forbid_n_rate(struct adapter *padapter)
                        case _RSN_IE_2_:
                                if  ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4))  ||
                                       (_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4)))
-                               return false;
+                                       return false;
                        default:
                                break;
                        }
@@ -1368,21 +1368,21 @@ void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
 #ifdef CONFIG_88EU_P2P
        struct wifidirect_info *pwdinfo = &padapter->wdinfo;
 
-       /*      Added by Albert 2011/03/22 */
-       /*      In the P2P mode, the driver should not support the b mode. */
-       /*      So, the Tx packet shouldn't use the CCK rate */
+       /*      Added by Albert 2011/03/22 */
+       /*      In the P2P mode, the driver should not support the b mode. */
+       /*      So, the Tx packet shouldn't use the CCK rate */
        if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
                return;
 #endif /* CONFIG_88EU_P2P */
        _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
 
-       if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) {
+       if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
                memcpy(supported_rates, rtw_basic_rate_cck, 4);
-       } else if (wirelessmode & WIRELESS_11B) {
+       else if (wirelessmode & WIRELESS_11B)
                memcpy(supported_rates, rtw_basic_rate_mix, 7);
-       } else {
+       else
                memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
-       }
+
 
        if (wirelessmode & WIRELESS_11B)
                update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
@@ -1435,7 +1435,7 @@ unsigned char check_assoc_AP(u8 *pframe, uint len)
                                DBG_88E("link to Airgo Cap\n");
                                return HT_IOT_PEER_AIRGO;
                        } else if (_rtw_memcmp(pIE->data, EPIGRAM_OUI, 3)) {
-                                epigram_vendor_flag = 1;
+                               epigram_vendor_flag = 1;
                                if (ralink_vendor_flag) {
                                        DBG_88E("link to Tenda W311R AP\n");
                                         return HT_IOT_PEER_TENDA;
index bb5cd95c564e2089897457f0c066a3ae16850b37..a594e51d2e1ca974b9bb946b56e9e9457c533c2e 100644 (file)
@@ -1556,7 +1556,7 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, str
        xmitframe_phead = get_list_head(pframe_queue);
        xmitframe_plist = get_next(xmitframe_phead);
 
-       while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+       if (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
                pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
 
                xmitframe_plist = get_next(xmitframe_plist);
@@ -1564,12 +1564,7 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, str
                rtw_list_delete(&pxmitframe->list);
 
                ptxservq->qcnt--;
-
-               break;
-
-               pxmitframe = NULL;
        }
-
        return pxmitframe;
 }
 
diff --git a/drivers/staging/rtl8188eu/hal/Hal8188EFWImg_CE.c b/drivers/staging/rtl8188eu/hal/Hal8188EFWImg_CE.c
deleted file mode 100644 (file)
index 95759be..0000000
+++ /dev/null
@@ -1,1761 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. 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 Street, Fifth Floor, Boston, MA 02110, USA
-*
-*
-******************************************************************************/
-#include "odm_precomp.h"
-
-const u8 Rtl8188EFwImgArray[Rtl8188EFWImgArrayLength] = {
-       0xE1, 0x88, 0x10, 0x00, 0x0B, 0x00, 0x01, 0x00,
-       0x01, 0x21, 0x11, 0x27, 0x30, 0x36, 0x00, 0x00,
-       0x2D, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x02, 0x45, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xC1, 0x6F, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xA1, 0xE6, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x02, 0x56, 0xF7, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x42, 0x04,
-       0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
-       0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
-       0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
-       0xEC, 0x24, 0x89, 0xF8, 0xE6, 0xBC, 0x03, 0x02,
-       0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
-       0x40, 0xCE, 0x79, 0x04, 0x78, 0x80, 0x16, 0xE6,
-       0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
-       0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
-       0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
-       0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
-       0x04, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
-       0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
-       0x20, 0x05, 0x0C, 0x74, 0x88, 0x25, 0x0C, 0xF8,
-       0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
-       0xBE, 0x03, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
-       0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
-       0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
-       0x0C, 0x24, 0x89, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
-       0x03, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
-       0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
-       0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x88,
-       0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
-       0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
-       0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
-       0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
-       0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
-       0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x88, 0xA6,
-       0x81, 0x74, 0x03, 0x60, 0x06, 0xFF, 0x08, 0x76,
-       0xFF, 0xDF, 0xFB, 0x7F, 0x04, 0xE4, 0x78, 0x80,
-       0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
-       0x76, 0x30, 0x90, 0x45, 0xDE, 0x74, 0x01, 0x93,
-       0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
-       0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
-       0x8C, 0xD2, 0xAF, 0x22, 0x03, 0xEF, 0xD3, 0x94,
-       0x03, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
-       0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
-       0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
-       0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
-       0x88, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
-       0xBE, 0x03, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
-       0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
-       0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
-       0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
-       0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x88, 0x2E,
-       0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
-       0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
-       0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
-       0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
-       0x24, 0x88, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
-       0x04, 0x90, 0x45, 0xDE, 0x93, 0xF6, 0x08, 0xEF,
-       0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
-       0x94, 0x03, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
-       0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
-       0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
-       0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x88, 0x2F,
-       0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x42, 0x4D, 0x50,
-       0x2E, 0x74, 0x89, 0x2F, 0xF8, 0xE6, 0xBF, 0x03,
-       0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
-       0x88, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
-       0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
-       0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
-       0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
-       0x89, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
-       0x0F, 0x74, 0x88, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
-       0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
-       0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
-       0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
-       0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
-       0xD3, 0x94, 0x03, 0x40, 0x03, 0x7F, 0xFF, 0x22,
-       0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
-       0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
-       0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
-       0xE2, 0x01, 0x0F, 0x02, 0x42, 0x4C, 0x8F, 0xF0,
-       0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
-       0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
-       0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
-       0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
-       0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
-       0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
-       0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
-       0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
-       0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x42, 0x4D, 0x7F,
-       0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
-       0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
-       0x22, 0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0,
-       0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70,
-       0x02, 0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xEF,
-       0x5B, 0xFF, 0xEE, 0x5A, 0xFE, 0xED, 0x59, 0xFD,
-       0xEC, 0x58, 0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE,
-       0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48, 0xFC,
-       0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0,
-       0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xE2, 0xFC, 0x08,
-       0xE2, 0xFD, 0x08, 0xE2, 0xFE, 0x08, 0xE2, 0xFF,
-       0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xF9, 0x08, 0xE2,
-       0xFA, 0x08, 0xE2, 0xCB, 0xF8, 0x22, 0xEC, 0xF2,
-       0x08, 0xED, 0xF2, 0x08, 0xEE, 0xF2, 0x08, 0xEF,
-       0xF2, 0x22, 0xA4, 0x25, 0x82, 0xF5, 0x82, 0xE5,
-       0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB,
-       0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB,
-       0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x22,
-       0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70,
-       0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3,
-       0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88,
-       0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60,
-       0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0x02, 0x45,
-       0x8C, 0x02, 0x42, 0xDD, 0xE4, 0x93, 0xA3, 0xF8,
-       0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01,
-       0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93,
-       0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3,
-       0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83,
-       0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6,
-       0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08,
-       0x10, 0x20, 0x40, 0x80, 0x90, 0x45, 0xD1, 0xE4,
-       0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54,
-       0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4,
-       0x93, 0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0,
-       0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93,
-       0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93,
-       0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83,
-       0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA,
-       0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80,
-       0xBE, 0x00, 0x41, 0x82, 0x09, 0x00, 0x41, 0x82,
-       0x0A, 0x00, 0x41, 0x82, 0x17, 0x00, 0x59, 0xE2,
-       0x5C, 0x24, 0x5E, 0x5D, 0x5F, 0xA1, 0xC0, 0xE0,
-       0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0,
-       0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0,
-       0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
-       0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xE6,
-       0xF0, 0x74, 0x45, 0xA3, 0xF0, 0xD1, 0x35, 0x74,
-       0xE6, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x45,
-       0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
-       0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
-       0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
-       0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x00, 0x54,
-       0xE0, 0x55, 0x35, 0xF5, 0x39, 0xA3, 0xE0, 0x55,
-       0x36, 0xF5, 0x3A, 0xA3, 0xE0, 0x55, 0x37, 0xF5,
-       0x3B, 0xA3, 0xE0, 0x55, 0x38, 0xF5, 0x3C, 0xAD,
-       0x39, 0x7F, 0x54, 0x12, 0x32, 0x1E, 0xAD, 0x3A,
-       0x7F, 0x55, 0x12, 0x32, 0x1E, 0xAD, 0x3B, 0x7F,
-       0x56, 0x12, 0x32, 0x1E, 0xAD, 0x3C, 0x7F, 0x57,
-       0x12, 0x32, 0x1E, 0x53, 0x91, 0xEF, 0x22, 0xC0,
-       0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0,
-       0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01,
-       0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05,
-       0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74,
-       0x6F, 0xF0, 0x74, 0x46, 0xA3, 0xF0, 0x12, 0x6C,
-       0x78, 0xE5, 0x41, 0x30, 0xE4, 0x04, 0x7F, 0x02,
-       0x91, 0x27, 0xE5, 0x41, 0x30, 0xE6, 0x03, 0x12,
-       0x6C, 0xD5, 0xE5, 0x43, 0x30, 0xE0, 0x03, 0x12,
-       0x51, 0xC2, 0xE5, 0x43, 0x30, 0xE1, 0x03, 0x12,
-       0x4D, 0x0C, 0xE5, 0x43, 0x30, 0xE2, 0x03, 0x12,
-       0x4C, 0xC1, 0xE5, 0x43, 0x30, 0xE3, 0x03, 0x12,
-       0x6C, 0xE2, 0xE5, 0x43, 0x30, 0xE4, 0x03, 0x12,
-       0x6D, 0x04, 0xE5, 0x43, 0x30, 0xE5, 0x03, 0x12,
-       0x6D, 0x33, 0xE5, 0x43, 0x30, 0xE6, 0x02, 0xF1,
-       0x0F, 0xE5, 0x44, 0x30, 0xE1, 0x03, 0x12, 0x51,
-       0x7F, 0x74, 0x6F, 0x04, 0x90, 0x01, 0xC4, 0xF0,
-       0x74, 0x46, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06,
-       0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02,
-       0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82,
-       0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90,
-       0x80, 0xDE, 0xE0, 0xB4, 0x01, 0x13, 0x90, 0x81,
-       0x27, 0xE0, 0x60, 0x0D, 0x90, 0x81, 0x2B, 0xE0,
-       0x54, 0xFE, 0xF0, 0x54, 0x07, 0x70, 0x02, 0xF1,
-       0x2A, 0x22, 0x90, 0x81, 0x1F, 0xE0, 0x90, 0x81,
-       0x29, 0x30, 0xE0, 0x05, 0xE0, 0xFF, 0x02, 0x74,
-       0x8F, 0xE0, 0xFF, 0x7D, 0x01, 0xD3, 0x10, 0xAF,
-       0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0x13, 0xED,
-       0xF0, 0x90, 0x81, 0x2A, 0xE0, 0x90, 0x82, 0x14,
-       0xF0, 0x90, 0x81, 0x24, 0xE0, 0xFE, 0xC4, 0x13,
-       0x13, 0x54, 0x03, 0x30, 0xE0, 0x03, 0x02, 0x48,
-       0xA0, 0xEE, 0xC4, 0x13, 0x13, 0x13, 0x54, 0x01,
-       0x30, 0xE0, 0x03, 0x02, 0x48, 0xA0, 0x90, 0x82,
-       0x14, 0xE0, 0xFE, 0x6F, 0x70, 0x03, 0x02, 0x48,
-       0xA0, 0xEF, 0x70, 0x03, 0x02, 0x48, 0x17, 0x24,
-       0xFE, 0x70, 0x03, 0x02, 0x48, 0x50, 0x24, 0xFE,
-       0x60, 0x51, 0x24, 0xFC, 0x70, 0x03, 0x02, 0x48,
-       0x8B, 0x24, 0xFC, 0x60, 0x03, 0x02, 0x48, 0xA0,
-       0xEE, 0xB4, 0x0E, 0x03, 0x12, 0x49, 0x5E, 0x90,
-       0x82, 0x14, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12,
-       0x49, 0x93, 0x90, 0x82, 0x14, 0xE0, 0xB4, 0x06,
-       0x03, 0x12, 0x49, 0x34, 0x90, 0x82, 0x14, 0xE0,
-       0xB4, 0x04, 0x0F, 0x90, 0x82, 0x13, 0xE0, 0xFF,
-       0x60, 0x05, 0x12, 0x73, 0x75, 0x80, 0x03, 0x12,
-       0x66, 0x26, 0x90, 0x82, 0x14, 0xE0, 0x64, 0x08,
-       0x60, 0x03, 0x02, 0x48, 0xA0, 0x12, 0x73, 0xD3,
-       0x02, 0x48, 0xA0, 0x90, 0x82, 0x14, 0xE0, 0x70,
-       0x05, 0x7F, 0x01, 0x12, 0x49, 0x93, 0x90, 0x82,
-       0x14, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x49, 0x34,
-       0x90, 0x82, 0x14, 0xE0, 0xB4, 0x0E, 0x09, 0x12,
-       0x48, 0xA5, 0xBF, 0x01, 0x03, 0x12, 0x49, 0x5E,
-       0x90, 0x82, 0x14, 0xE0, 0x64, 0x0C, 0x60, 0x02,
-       0x01, 0xA0, 0x11, 0xA5, 0xEF, 0x64, 0x01, 0x60,
-       0x02, 0x01, 0xA0, 0x11, 0xFA, 0x01, 0xA0, 0x90,
-       0x82, 0x14, 0xE0, 0xB4, 0x0E, 0x07, 0x11, 0xA5,
-       0xBF, 0x01, 0x02, 0x31, 0x5E, 0x90, 0x82, 0x14,
-       0xE0, 0xB4, 0x06, 0x02, 0x31, 0x34, 0x90, 0x82,
-       0x14, 0xE0, 0xB4, 0x0C, 0x07, 0x11, 0xA5, 0xBF,
-       0x01, 0x02, 0x11, 0xFA, 0x90, 0x82, 0x14, 0xE0,
-       0x64, 0x04, 0x70, 0x5C, 0x12, 0x72, 0xF5, 0xEF,
-       0x64, 0x01, 0x70, 0x54, 0x31, 0xBE, 0x80, 0x50,
-       0x90, 0x82, 0x14, 0xE0, 0xB4, 0x0E, 0x07, 0x11,
-       0xA5, 0xBF, 0x01, 0x02, 0x31, 0x5E, 0x90, 0x82,
-       0x14, 0xE0, 0xB4, 0x06, 0x02, 0x31, 0x34, 0x90,
-       0x82, 0x14, 0xE0, 0xB4, 0x0C, 0x07, 0x11, 0xA5,
-       0xBF, 0x01, 0x02, 0x11, 0xFA, 0x90, 0x82, 0x14,
-       0xE0, 0x70, 0x04, 0x7F, 0x01, 0x31, 0x93, 0x90,
-       0x82, 0x14, 0xE0, 0xB4, 0x04, 0x1A, 0x12, 0x73,
-       0xBB, 0x80, 0x15, 0x90, 0x82, 0x14, 0xE0, 0xB4,
-       0x0C, 0x0E, 0x90, 0x81, 0x25, 0xE0, 0xFF, 0x13,
-       0x13, 0x54, 0x3F, 0x30, 0xE0, 0x02, 0x31, 0xB1,
-       0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD1, 0xAB, 0xEF,
-       0x64, 0x01, 0x60, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x01, 0xF0, 0x80, 0x3D, 0x90, 0x81, 0x24, 0xE0,
-       0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
-       0x08, 0x90, 0x01, 0xB8, 0x74, 0x02, 0xF0, 0x80,
-       0x28, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x08,
-       0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x80, 0x19,
-       0x90, 0x81, 0x29, 0xE0, 0xD3, 0x94, 0x04, 0x40,
-       0x08, 0x90, 0x01, 0xB8, 0x74, 0x08, 0xF0, 0x80,
-       0x08, 0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F, 0x01,
-       0x22, 0x90, 0x01, 0xB9, 0x74, 0x02, 0xF0, 0x7F,
-       0x00, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01,
-       0x70, 0x31, 0x90, 0x81, 0x25, 0xE0, 0x54, 0xFD,
-       0xF0, 0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, 0x7F,
-       0x01, 0xF1, 0x0D, 0xBF, 0x01, 0x12, 0x90, 0x81,
-       0x24, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x81, 0x2A,
-       0x74, 0x0E, 0xF0, 0x90, 0x81, 0x23, 0xF0, 0x22,
-       0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01,
-       0xB8, 0x04, 0xF0, 0x22, 0x90, 0x81, 0x25, 0xE0,
-       0x90, 0x06, 0x04, 0x20, 0xE0, 0x0C, 0xE0, 0x44,
-       0x40, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x04, 0xF0,
-       0x80, 0x0E, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x81,
-       0x2A, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x23, 0xF0,
-       0x90, 0x05, 0x22, 0xE4, 0xF0, 0x22, 0x90, 0x81,
-       0x25, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x08, 0x90,
-       0x81, 0x2A, 0x74, 0x0C, 0xF0, 0x80, 0x1E, 0x90,
-       0x06, 0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, 0x44,
-       0x80, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x04, 0xF0,
-       0x90, 0x05, 0x27, 0xE0, 0x44, 0x80, 0xF0, 0x90,
-       0x81, 0x23, 0x74, 0x04, 0xF0, 0x90, 0x05, 0x22,
-       0xE4, 0xF0, 0x22, 0x90, 0x82, 0x15, 0xEF, 0xF0,
-       0x12, 0x54, 0x65, 0x90, 0x82, 0x15, 0xE0, 0x60,
-       0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x81,
-       0x2A, 0x74, 0x04, 0xF0, 0x90, 0x81, 0x23, 0xF0,
-       0x22, 0x31, 0xE3, 0x90, 0x81, 0x2A, 0x74, 0x08,
-       0xF0, 0x90, 0x81, 0x23, 0xF0, 0x22, 0x90, 0x05,
-       0x22, 0x74, 0xFF, 0xF0, 0xF1, 0x3A, 0x90, 0x01,
-       0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03, 0x51,
-       0x57, 0x31, 0xE3, 0xE4, 0x90, 0x81, 0x2A, 0xF0,
-       0x90, 0x81, 0x23, 0xF0, 0x22, 0x90, 0x05, 0x22,
-       0x74, 0xFF, 0xF0, 0xF1, 0x3A, 0x90, 0x85, 0xBB,
-       0x12, 0x20, 0xDA, 0xCC, 0xF0, 0x00, 0xC0, 0x7F,
-       0x8C, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x85,
-       0xBB, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x14,
-       0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2E, 0xA2, 0x90,
-       0x81, 0xF9, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00,
-       0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x55, 0x1C, 0x7F,
-       0x7C, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEC, 0x44,
-       0x80, 0xFC, 0x90, 0x82, 0x05, 0x12, 0x20, 0xCE,
-       0x90, 0x82, 0x05, 0x12, 0x44, 0xD9, 0x90, 0x85,
-       0xBB, 0x12, 0x20, 0xCE, 0x7F, 0x7C, 0x7E, 0x08,
-       0x12, 0x2E, 0xA2, 0x90, 0x01, 0x00, 0x74, 0x3F,
-       0xF0, 0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05,
-       0x53, 0xE0, 0x44, 0x20, 0xF0, 0x22, 0x90, 0x01,
-       0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x74,
-       0x3D, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74,
-       0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5,
-       0x83, 0xEE, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
-       0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x81, 0xCB, 0xF0,
-       0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x90,
-       0x81, 0x1F, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0,
-       0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F,
-       0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0xFE, 0x54, 0x04,
-       0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0xFF, 0x90, 0x81,
-       0x1F, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54,
-       0xF7, 0x4E, 0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0xFE,
-       0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0x4D, 0xFF,
-       0x90, 0x81, 0x1F, 0xF0, 0xEE, 0x54, 0x20, 0xFE,
-       0xEF, 0x54, 0xDF, 0x4E, 0xF0, 0x12, 0x1F, 0xA4,
-       0xC3, 0x13, 0x20, 0xE0, 0x02, 0x61, 0x5E, 0x90,
-       0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0, 0x6D, 0x90,
-       0x81, 0xCB, 0x74, 0x21, 0xF0, 0xEF, 0x13, 0x13,
-       0x54, 0x3F, 0x30, 0xE0, 0x0B, 0x51, 0x4E, 0x90,
-       0x81, 0xCB, 0xE0, 0x44, 0x08, 0xF0, 0x80, 0x0C,
-       0xE4, 0x90, 0x81, 0x20, 0xF0, 0xA3, 0xF0, 0x7D,
-       0x40, 0xFF, 0x91, 0x26, 0x90, 0x81, 0x1F, 0xE0,
-       0xFD, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
-       0x07, 0x90, 0x81, 0xCB, 0xE0, 0x44, 0x12, 0xF0,
-       0xED, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x07, 0x90,
-       0x81, 0xCB, 0xE0, 0x44, 0x14, 0xF0, 0x90, 0x81,
-       0x1F, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0,
-       0x07, 0x90, 0x81, 0xCB, 0xE0, 0x44, 0x80, 0xF0,
-       0x90, 0x81, 0xCB, 0xE0, 0x90, 0x05, 0x27, 0xF0,
-       0x90, 0x81, 0x22, 0xE0, 0x60, 0x02, 0x81, 0x17,
-       0x7F, 0x01, 0x80, 0x15, 0x90, 0x81, 0xCB, 0x74,
-       0x01, 0xF0, 0x90, 0x05, 0x27, 0xF0, 0x90, 0x81,
-       0x22, 0xE0, 0x64, 0x04, 0x60, 0x02, 0x81, 0x17,
-       0xFF, 0x12, 0x53, 0x0E, 0x81, 0x17, 0x90, 0x81,
-       0x1F, 0xE0, 0xFF, 0x20, 0xE0, 0x02, 0x61, 0xE7,
-       0x90, 0x81, 0xCB, 0x74, 0x31, 0xF0, 0xEF, 0x13,
-       0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0B, 0x51, 0x4E,
-       0x90, 0x81, 0xCB, 0xE0, 0x44, 0x08, 0xF0, 0x80,
-       0x06, 0x7D, 0x40, 0xE4, 0xFF, 0x91, 0x26, 0x90,
-       0x81, 0x1F, 0xE0, 0xFD, 0x13, 0x13, 0x13, 0x54,
-       0x1F, 0x30, 0xE0, 0x07, 0x90, 0x81, 0xCB, 0xE0,
-       0x44, 0x02, 0xF0, 0xED, 0xC4, 0x54, 0x0F, 0x30,
-       0xE0, 0x07, 0x90, 0x81, 0xCB, 0xE0, 0x44, 0x04,
-       0xF0, 0x90, 0x81, 0xCB, 0xE0, 0x90, 0x05, 0x27,
-       0xF0, 0x90, 0x81, 0x23, 0xE0, 0x64, 0x02, 0x70,
-       0x1D, 0xFD, 0x7F, 0x04, 0x12, 0x47, 0x3D, 0x12,
-       0x51, 0x73, 0xBF, 0x01, 0x09, 0x90, 0x81, 0x29,
-       0xE0, 0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, 0xFD,
-       0xFF, 0x12, 0x47, 0x3D, 0x80, 0x41, 0x90, 0x81,
-       0x2A, 0xE0, 0x90, 0x81, 0x23, 0xF0, 0x90, 0x05,
-       0x27, 0xE0, 0x44, 0x40, 0xF0, 0x80, 0x30, 0x90,
-       0x81, 0xCB, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x27,
-       0xF0, 0x90, 0x81, 0x23, 0xE0, 0xB4, 0x02, 0x06,
-       0x7D, 0x01, 0x7F, 0x04, 0x80, 0x0B, 0x90, 0x81,
-       0x23, 0xE0, 0xB4, 0x08, 0x07, 0x7D, 0x01, 0x7F,
-       0x0C, 0x12, 0x47, 0x3D, 0xD1, 0x34, 0x90, 0x81,
-       0x29, 0x12, 0x47, 0x39, 0x12, 0x5A, 0xA7, 0xD0,
-       0xD0, 0x92, 0xAF, 0x22, 0x7D, 0x02, 0x7F, 0x02,
-       0x91, 0x26, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x3D,
-       0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0xFE,
-       0xF6, 0x74, 0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
-       0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xEF, 0x70,
-       0x37, 0x7D, 0x78, 0x7F, 0x02, 0x91, 0x26, 0x7D,
-       0x02, 0x7F, 0x03, 0x91, 0x26, 0x7D, 0xC8, 0x7F,
-       0x02, 0x12, 0x71, 0x8F, 0x90, 0x01, 0x57, 0xE4,
-       0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x7D,
-       0x01, 0x7F, 0x0C, 0x12, 0x47, 0x3D, 0x90, 0x81,
-       0x24, 0xE0, 0x54, 0xF7, 0xF0, 0x54, 0xEF, 0xF0,
-       0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22,
-       0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74,
-       0x02, 0xF0, 0x7D, 0x78, 0xFF, 0x51, 0x57, 0x7D,
-       0x02, 0x7F, 0x03, 0x51, 0x57, 0x90, 0x06, 0x0A,
-       0xE0, 0x44, 0x07, 0xF0, 0x90, 0x81, 0x32, 0xA3,
-       0xE0, 0x90, 0x05, 0x58, 0xF0, 0x90, 0x80, 0xDE,
-       0xE0, 0xB4, 0x01, 0x15, 0x90, 0x81, 0x25, 0xE0,
-       0x54, 0xFB, 0xF0, 0x90, 0x81, 0x2A, 0xE0, 0x20,
-       0xE2, 0x0E, 0x7D, 0x01, 0x7F, 0x04, 0x02, 0x47,
-       0x3D, 0x90, 0x81, 0x25, 0xE0, 0x44, 0x04, 0xF0,
-       0x22, 0x90, 0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0,
-       0x08, 0x90, 0x81, 0x23, 0xE0, 0x64, 0x02, 0x60,
-       0x3A, 0x90, 0x81, 0x27, 0xE0, 0x70, 0x04, 0xEF,
-       0x30, 0xE0, 0x0A, 0x90, 0x81, 0x2A, 0xE0, 0x64,
-       0x02, 0x60, 0x28, 0xB1, 0x83, 0x90, 0x81, 0x25,
-       0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
-       0x14, 0x90, 0x81, 0x2D, 0xE0, 0xFF, 0xA3, 0xE0,
-       0x6F, 0x70, 0x0A, 0xF1, 0xCD, 0x91, 0x1C, 0x90,
-       0x81, 0x2E, 0xE0, 0x14, 0xF0, 0x90, 0x01, 0xE6,
-       0xE0, 0x04, 0xF0, 0x22, 0x90, 0x81, 0x1F, 0xE0,
-       0x30, 0xE0, 0x06, 0x90, 0x81, 0x21, 0x74, 0x01,
-       0xF0, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x45, 0x90,
-       0x81, 0x25, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54,
-       0x1F, 0x30, 0xE0, 0x12, 0x90, 0x01, 0x3B, 0xE0,
-       0x30, 0xE4, 0x0B, 0x91, 0x1C, 0x90, 0x81, 0x2D,
-       0xE0, 0x14, 0x90, 0x05, 0x73, 0xF0, 0x90, 0x82,
-       0x0B, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x44, 0xA9,
-       0xC3, 0x90, 0x82, 0x0C, 0xE0, 0x94, 0x80, 0x90,
-       0x82, 0x0B, 0xE0, 0x64, 0x80, 0x94, 0x80, 0x40,
-       0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0,
-       0xE0, 0x44, 0x01, 0xF0, 0x12, 0x75, 0xF8, 0xD1,
-       0xD6, 0x90, 0x81, 0x3F, 0xE0, 0x30, 0xE0, 0x0C,
-       0xE4, 0xF5, 0x1D, 0xA3, 0xF1, 0xFB, 0x90, 0x01,
-       0x57, 0x74, 0x05, 0xF0, 0x90, 0x01, 0xBE, 0xE0,
-       0x04, 0xF0, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0x64,
-       0x01, 0x60, 0x02, 0xC1, 0x23, 0x90, 0x81, 0x27,
-       0xE0, 0x70, 0x02, 0xC1, 0x23, 0x90, 0x81, 0x26,
-       0xE0, 0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x22,
-       0x90, 0x06, 0xAB, 0xE0, 0x90, 0x81, 0x2E, 0xF0,
-       0x90, 0x06, 0xAA, 0xE0, 0x90, 0x81, 0x2D, 0xF0,
-       0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x81, 0x2D,
-       0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90, 0x81, 0x2E,
-       0xEF, 0xF0, 0x90, 0x81, 0x25, 0xE0, 0x44, 0x04,
-       0xF0, 0xE4, 0x90, 0x81, 0x30, 0xF0, 0x90, 0x81,
-       0x32, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x90,
-       0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
-       0x02, 0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD,
-       0xF0, 0x54, 0xEF, 0xF0, 0x90, 0x81, 0x26, 0xE0,
-       0xFF, 0xC4, 0x54, 0x0F, 0x24, 0xFD, 0x50, 0x02,
-       0x80, 0x0F, 0x90, 0x81, 0x1F, 0xE0, 0x30, 0xE0,
-       0x05, 0x12, 0x6D, 0xF2, 0x80, 0x03, 0x12, 0x6E,
-       0xC9, 0x90, 0x81, 0x25, 0xE0, 0x13, 0x13, 0x13,
-       0x54, 0x1F, 0x30, 0xE0, 0x0E, 0x90, 0x81, 0x2D,
-       0xE0, 0xFF, 0xA3, 0xE0, 0xB5, 0x07, 0x04, 0xF1,
-       0xCD, 0x91, 0x22, 0x90, 0x81, 0x1F, 0xE0, 0xC3,
-       0x13, 0x20, 0xE0, 0x07, 0x90, 0x81, 0x25, 0xE0,
-       0x44, 0x04, 0xF0, 0x22, 0xD1, 0xAB, 0xEF, 0x70,
-       0x02, 0xD1, 0x3C, 0x22, 0x90, 0x81, 0x27, 0xE0,
-       0x64, 0x01, 0x70, 0x66, 0x90, 0x81, 0x26, 0xE0,
-       0x54, 0x0F, 0x60, 0x51, 0x90, 0x81, 0x2A, 0xE0,
-       0x70, 0x03, 0xFF, 0x31, 0x93, 0x90, 0x81, 0x2A,
-       0xE0, 0x64, 0x0C, 0x60, 0x03, 0x12, 0x66, 0x26,
-       0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C,
-       0x74, 0x04, 0xF0, 0xD1, 0xAB, 0xEF, 0x64, 0x01,
-       0x60, 0x38, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x12, 0x50,
-       0x05, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90,
-       0x06, 0x92, 0x74, 0x01, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x81, 0x2A,
-       0xE0, 0x70, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12,
-       0x47, 0x3D, 0x22, 0x90, 0x04, 0x1A, 0xE0, 0xF4,
-       0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, 0x1B,
-       0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, 0x60,
-       0x02, 0x7F, 0x00, 0x22, 0x12, 0x50, 0x60, 0x90,
-       0x81, 0x2D, 0xE0, 0x14, 0x90, 0x05, 0x73, 0xF0,
-       0x7D, 0x02, 0x7F, 0x02, 0x51, 0x57, 0x90, 0x81,
-       0x42, 0xE0, 0x30, 0xE0, 0x2D, 0x90, 0x80, 0xDE,
-       0xE0, 0xB4, 0x01, 0x26, 0x90, 0x82, 0x17, 0xE0,
-       0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x0B, 0x90, 0x81,
-       0x44, 0xE0, 0x04, 0xF0, 0xE4, 0x90, 0x82, 0x17,
-       0xF0, 0x90, 0x81, 0x44, 0xE0, 0xFF, 0x90, 0x81,
-       0x43, 0xE0, 0xB5, 0x07, 0x05, 0xE4, 0xA3, 0xF0,
-       0xF1, 0x0B, 0x22, 0xE4, 0xFF, 0x8F, 0x53, 0x90,
-       0x04, 0x1D, 0xE0, 0x60, 0x19, 0x90, 0x05, 0x22,
-       0xE0, 0xF5, 0x56, 0x74, 0xFF, 0xF0, 0xF1, 0x3A,
-       0xBF, 0x01, 0x03, 0x12, 0x74, 0xFB, 0x90, 0x05,
-       0x22, 0xE5, 0x56, 0xF0, 0x80, 0x03, 0x12, 0x74,
-       0xFB, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x7F,
-       0x01, 0x22, 0xE4, 0x90, 0x82, 0x0F, 0xF0, 0xA3,
-       0xF0, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x0F, 0xA3,
-       0xE0, 0x70, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xA3,
-       0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0xD3, 0x90,
-       0x82, 0x10, 0xE0, 0x94, 0xE8, 0x90, 0x82, 0x0F,
-       0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC0,
-       0xE0, 0x44, 0x20, 0xF0, 0x7F, 0x00, 0x22, 0x7F,
-       0x32, 0x7E, 0x00, 0x12, 0x32, 0xAA, 0x90, 0x82,
-       0x0F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x44, 0xA9,
-       0x80, 0xBF, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4,
-       0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0x3F, 0xF0,
-       0xEF, 0x60, 0x1D, 0x74, 0x21, 0x2D, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x10,
-       0xF0, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x22,
-       0x74, 0x21, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
-       0xF5, 0x83, 0xE0, 0x54, 0xEF, 0xF0, 0x74, 0x1F,
-       0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
-       0xE0, 0x44, 0x40, 0xF0, 0x22, 0xEF, 0x14, 0x90,
-       0x05, 0x73, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10,
-       0xF0, 0xFD, 0x7F, 0x03, 0x74, 0x45, 0x2F, 0xF8,
-       0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5,
-       0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0,
-       0x22, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xF5, 0x1D,
-       0x90, 0x81, 0x39, 0xE0, 0xF5, 0x1E, 0xE4, 0xFB,
-       0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x8E, 0x19, 0x8F,
-       0x1A, 0xE5, 0x1E, 0x54, 0x07, 0xC4, 0x33, 0x54,
-       0xE0, 0x85, 0x19, 0x83, 0x85, 0x1A, 0x82, 0xF0,
-       0xE5, 0x1D, 0x54, 0x07, 0xC4, 0x33, 0x54, 0xE0,
-       0xFF, 0xE5, 0x1E, 0x13, 0x13, 0x13, 0x54, 0x1F,
-       0x4F, 0xA3, 0xF0, 0xEB, 0x54, 0x07, 0xC4, 0x33,
-       0x54, 0xE0, 0xFF, 0xE5, 0x1D, 0x13, 0x13, 0x13,
-       0x54, 0x1F, 0x4F, 0x85, 0x1A, 0x82, 0x85, 0x19,
-       0x83, 0xA3, 0xA3, 0xF0, 0xBD, 0x01, 0x0C, 0x85,
-       0x1A, 0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3, 0x74,
-       0x03, 0xF0, 0x22, 0x85, 0x1A, 0x82, 0x85, 0x19,
-       0x83, 0xA3, 0xA3, 0xA3, 0x74, 0x01, 0xF0, 0x22,
-       0xE4, 0x90, 0x81, 0x4D, 0xF0, 0x90, 0x81, 0x27,
-       0xE0, 0x60, 0x58, 0x90, 0x80, 0xDE, 0xE0, 0x64,
-       0x01, 0x70, 0x50, 0x90, 0x81, 0x4D, 0x04, 0xF0,
-       0xE4, 0x90, 0x81, 0x2E, 0xF0, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x15, 0x90, 0x81, 0x23, 0xE0,
-       0xB4, 0x02, 0x05, 0xE4, 0x90, 0x81, 0x4D, 0xF0,
-       0x31, 0x73, 0xEF, 0x70, 0x04, 0x90, 0x81, 0x4D,
-       0xF0, 0x90, 0x81, 0x4D, 0xE0, 0x60, 0x24, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x10, 0xF0, 0xE4, 0xF5,
-       0x1D, 0x90, 0x81, 0x2F, 0x12, 0x4F, 0xFB, 0x90,
-       0x01, 0x57, 0x74, 0x05, 0xF0, 0x90, 0x81, 0x2A,
-       0xE0, 0x20, 0xE2, 0x07, 0x7D, 0x01, 0x7F, 0x04,
-       0x12, 0x47, 0x3D, 0x22, 0xE4, 0x90, 0x81, 0x4C,
-       0xF0, 0x90, 0x81, 0x27, 0xE0, 0x70, 0x02, 0x21,
-       0x72, 0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01, 0x60,
-       0x02, 0x21, 0x72, 0x90, 0x81, 0x26, 0xE0, 0xFF,
-       0xC4, 0x54, 0x0F, 0x60, 0x22, 0x24, 0xFE, 0x60,
-       0x03, 0x04, 0x70, 0x21, 0x90, 0x81, 0x2E, 0xE0,
-       0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x81,
-       0x30, 0xE0, 0x60, 0x11, 0xEF, 0x70, 0x08, 0x90,
-       0x81, 0x2D, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x90,
-       0x81, 0x4C, 0x74, 0x01, 0xF0, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x15, 0x90, 0x81, 0x23, 0xE0,
-       0xB4, 0x02, 0x05, 0xE4, 0x90, 0x81, 0x4C, 0xF0,
-       0x31, 0x73, 0xEF, 0x70, 0x04, 0x90, 0x81, 0x4C,
-       0xF0, 0x90, 0x81, 0x4C, 0xE0, 0x60, 0x43, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81,
-       0x30, 0xE0, 0x60, 0x03, 0xB4, 0x01, 0x09, 0xE4,
-       0xF5, 0x1D, 0x90, 0x81, 0x30, 0xE0, 0x80, 0x0D,
-       0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x30, 0xE0, 0x75,
-       0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x81,
-       0x2F, 0xE0, 0x2F, 0x12, 0x4F, 0xFC, 0x90, 0x01,
-       0x57, 0x74, 0x05, 0xF0, 0x90, 0x81, 0x2A, 0xE0,
-       0x20, 0xE2, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12,
-       0x47, 0x3D, 0x22, 0x90, 0x05, 0x43, 0xE0, 0x7F,
-       0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22, 0x90,
-       0x81, 0x27, 0xE0, 0x70, 0x07, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x11, 0x90, 0x81, 0x1F, 0xE0,
-       0x30, 0xE0, 0x07, 0x31, 0x73, 0xBF, 0x01, 0x05,
-       0x41, 0x5B, 0x12, 0x4E, 0x3C, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x1E,
-       0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x04, 0x80, 0x0B,
-       0x31, 0x73, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x80,
-       0x02, 0x7F, 0x02, 0x71, 0x0E, 0xD0, 0xD0, 0x92,
-       0xAF, 0x22, 0x90, 0x81, 0x4B, 0xE0, 0x60, 0x0F,
-       0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x02,
-       0xF0, 0x90, 0x05, 0xFC, 0xE0, 0x04, 0xF0, 0x90,
-       0x81, 0x1F, 0xE0, 0x30, 0xE0, 0x10, 0xA3, 0x74,
-       0x01, 0xF0, 0x90, 0x81, 0x1F, 0xE0, 0xFF, 0xC3,
-       0x13, 0x30, 0xE0, 0x02, 0x31, 0x9E, 0x11, 0xC4,
-       0x90, 0x81, 0x3F, 0xE0, 0x30, 0xE0, 0x07, 0x91,
-       0x65, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x22, 0x90,
-       0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0, 0x3D, 0x90,
-       0x81, 0x23, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02,
-       0x7E, 0x01, 0x90, 0x81, 0x22, 0xE0, 0x7D, 0x00,
-       0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70,
-       0x23, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0x21,
-       0x9E, 0x51, 0x45, 0x90, 0x81, 0x23, 0xE0, 0xB4,
-       0x08, 0x06, 0xE4, 0xFD, 0x7F, 0x0C, 0x80, 0x09,
-       0x90, 0x81, 0x23, 0xE0, 0x70, 0x06, 0xFD, 0x7F,
-       0x04, 0x12, 0x47, 0x3D, 0x22, 0x90, 0x81, 0x1E,
-       0xE0, 0xB4, 0x01, 0x0F, 0x90, 0x81, 0x23, 0xE0,
-       0x64, 0x02, 0x60, 0x07, 0x7D, 0x01, 0x7F, 0x02,
-       0x12, 0x47, 0x3D, 0x90, 0x81, 0x27, 0xE0, 0x64,
-       0x02, 0x60, 0x14, 0x90, 0x81, 0x26, 0xE0, 0x54,
-       0x0F, 0x60, 0x0C, 0x12, 0x4E, 0xAB, 0xEF, 0x70,
-       0x06, 0xFD, 0x7F, 0x0C, 0x12, 0x47, 0x3D, 0x22,
-       0x90, 0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0, 0x3F,
-       0x90, 0x81, 0x23, 0xE0, 0x7E, 0x00, 0xB4, 0x02,
-       0x02, 0x7E, 0x01, 0x90, 0x81, 0x22, 0xE0, 0x7D,
-       0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E,
-       0x70, 0x25, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02,
-       0x21, 0x9E, 0x12, 0x74, 0xAC, 0x90, 0x81, 0x23,
-       0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, 0x7F, 0x08,
-       0x80, 0x0A, 0x90, 0x81, 0x23, 0xE0, 0xB4, 0x04,
-       0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x47, 0x3D, 0x22,
-       0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
-       0x81, 0xCB, 0x12, 0x45, 0x1F, 0x12, 0x1F, 0xA4,
-       0xFF, 0x90, 0x81, 0x1E, 0xF0, 0xBF, 0x01, 0x12,
-       0x90, 0x81, 0xCB, 0x12, 0x45, 0x16, 0x90, 0x00,
-       0x01, 0x12, 0x1F, 0xBD, 0x64, 0x01, 0x60, 0x21,
-       0x80, 0x1D, 0x90, 0x81, 0xCB, 0x12, 0x45, 0x16,
-       0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0x64, 0x01,
-       0x60, 0x0F, 0x90, 0x81, 0x1F, 0xE0, 0x20, 0xE0,
-       0x06, 0xE4, 0xFF, 0x71, 0x0E, 0x80, 0x02, 0x31,
-       0x9E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x22,
-       0xE0, 0x90, 0x82, 0x16, 0xF0, 0x6F, 0x70, 0x02,
-       0x81, 0x04, 0xEF, 0x14, 0x60, 0x3E, 0x14, 0x60,
-       0x62, 0x14, 0x70, 0x02, 0x61, 0xB8, 0x14, 0x70,
-       0x02, 0x61, 0xDF, 0x24, 0x04, 0x60, 0x02, 0x81,
-       0x04, 0x90, 0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x04,
-       0x04, 0x91, 0x41, 0x81, 0x04, 0xEF, 0xB4, 0x02,
-       0x04, 0x91, 0x50, 0x81, 0x04, 0x90, 0x82, 0x16,
-       0xE0, 0xFF, 0xB4, 0x03, 0x04, 0x91, 0x54, 0x81,
-       0x04, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x81, 0x04,
-       0x91, 0x43, 0x81, 0x04, 0x90, 0x82, 0x16, 0xE0,
-       0xFF, 0xB4, 0x04, 0x04, 0x91, 0xF3, 0x81, 0x04,
-       0xEF, 0xB4, 0x02, 0x04, 0x91, 0x58, 0x81, 0x04,
-       0x90, 0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x03, 0x04,
-       0x91, 0xE8, 0x81, 0x04, 0xEF, 0x70, 0x7D, 0x91,
-       0x2B, 0x80, 0x79, 0x90, 0x82, 0x16, 0xE0, 0xB4,
-       0x04, 0x05, 0x12, 0x74, 0x60, 0x80, 0x6D, 0x90,
-       0x82, 0x16, 0xE0, 0xB4, 0x01, 0x04, 0x91, 0x21,
-       0x80, 0x62, 0x90, 0x82, 0x16, 0xE0, 0xB4, 0x03,
-       0x05, 0x12, 0x74, 0x71, 0x80, 0x56, 0x90, 0x82,
-       0x16, 0xE0, 0x70, 0x50, 0x91, 0x1F, 0x80, 0x4C,
-       0x90, 0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x04, 0x05,
-       0x12, 0x74, 0x4C, 0x80, 0x3F, 0xEF, 0xB4, 0x01,
-       0x04, 0x91, 0x34, 0x80, 0x37, 0xEF, 0xB4, 0x02,
-       0x04, 0x91, 0xDF, 0x80, 0x2F, 0x90, 0x82, 0x16,
-       0xE0, 0x70, 0x29, 0x91, 0x32, 0x80, 0x25, 0x90,
-       0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x03, 0x05, 0x12,
-       0x74, 0x7B, 0x80, 0x18, 0xEF, 0xB4, 0x01, 0x04,
-       0x91, 0x0B, 0x80, 0x10, 0xEF, 0xB4, 0x02, 0x04,
-       0xB1, 0x06, 0x80, 0x08, 0x90, 0x82, 0x16, 0xE0,
-       0x70, 0x02, 0x91, 0x09, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0x91, 0x2B, 0x90, 0x05, 0x22, 0x74, 0x6F,
-       0xF0, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
-       0x90, 0x81, 0x22, 0x74, 0x04, 0xF0, 0x22, 0x91,
-       0x2B, 0x12, 0x49, 0xDD, 0x90, 0x81, 0x22, 0x74,
-       0x02, 0xF0, 0x22, 0x90, 0x81, 0x22, 0x74, 0x01,
-       0xF0, 0x22, 0x91, 0x2B, 0x90, 0x05, 0x22, 0x74,
-       0xFF, 0xF0, 0x90, 0x81, 0x22, 0x74, 0x03, 0xF0,
-       0x22, 0x91, 0xF3, 0x90, 0x05, 0x27, 0xE0, 0x54,
-       0xBF, 0xF0, 0xE4, 0x90, 0x81, 0x22, 0xF0, 0x22,
-       0x91, 0x58, 0x80, 0xEF, 0x91, 0xE8, 0x80, 0xEB,
-       0x91, 0x65, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90,
-       0x81, 0x22, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
-       0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x01, 0xE0,
-       0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF,
-       0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0, 0x90,
-       0x06, 0xB4, 0x74, 0x86, 0xF0, 0x7F, 0x7C, 0x7E,
-       0x08, 0x12, 0x2D, 0x5C, 0xEC, 0x54, 0x7F, 0xFC,
-       0x90, 0x82, 0x01, 0x12, 0x20, 0xCE, 0x90, 0x82,
-       0x01, 0x12, 0x44, 0xD9, 0x90, 0x85, 0xBB, 0x12,
-       0x20, 0xCE, 0x7F, 0x7C, 0x7E, 0x08, 0x12, 0x2E,
-       0xA2, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA, 0xCC,
-       0xC0, 0x00, 0xC0, 0x7F, 0x8C, 0x7E, 0x08, 0x12,
-       0x2E, 0xA2, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA,
-       0x00, 0xC0, 0x00, 0x14, 0x7F, 0x70, 0x7E, 0x0E,
-       0x12, 0x2E, 0xA2, 0x90, 0x81, 0xF9, 0x12, 0x20,
-       0xDA, 0x00, 0x03, 0x3E, 0x60, 0xE4, 0xFD, 0xFF,
-       0xB1, 0x1C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x91,
-       0x65, 0x90, 0x81, 0x22, 0x74, 0x03, 0xF0, 0x22,
-       0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x81, 0x22,
-       0x04, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0,
-       0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x90,
-       0x81, 0x22, 0x74, 0x01, 0xF0, 0x22, 0x91, 0x65,
-       0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, 0x90, 0x05,
-       0x27, 0xE0, 0x54, 0xBF, 0xF0, 0x90, 0x81, 0x22,
-       0x74, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
-       0xC3, 0xC0, 0xD0, 0xC0, 0x07, 0xC0, 0x05, 0x90,
-       0x81, 0xF9, 0x12, 0x44, 0xD9, 0x90, 0x81, 0xE5,
-       0x12, 0x20, 0xCE, 0xD0, 0x05, 0xD0, 0x07, 0x12,
-       0x60, 0xF5, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
-       0x81, 0xC8, 0x12, 0x45, 0x1F, 0xEF, 0x12, 0x45,
-       0x28, 0x55, 0x71, 0x00, 0x55, 0x7A, 0x01, 0x55,
-       0x83, 0x02, 0x55, 0x8B, 0x03, 0x55, 0x94, 0x04,
-       0x55, 0x9C, 0x20, 0x55, 0xA4, 0x21, 0x55, 0xAD,
-       0x23, 0x55, 0xB5, 0x24, 0x55, 0xBE, 0x25, 0x55,
-       0xC7, 0x26, 0x55, 0xCF, 0xC0, 0x00, 0x00, 0x55,
-       0xD8, 0x90, 0x81, 0xC8, 0x12, 0x45, 0x16, 0x02,
-       0x6A, 0xB0, 0x90, 0x81, 0xC8, 0x12, 0x45, 0x16,
-       0x02, 0x65, 0x81, 0x90, 0x81, 0xC8, 0x12, 0x45,
-       0x16, 0x41, 0xC0, 0x90, 0x81, 0xC8, 0x12, 0x45,
-       0x16, 0x02, 0x75, 0xD8, 0x90, 0x81, 0xC8, 0x12,
-       0x45, 0x16, 0x80, 0x44, 0x90, 0x81, 0xC8, 0x12,
-       0x45, 0x16, 0xC1, 0x4B, 0x90, 0x81, 0xC8, 0x12,
-       0x45, 0x16, 0x02, 0x6A, 0xF8, 0x90, 0x81, 0xC8,
-       0x12, 0x45, 0x16, 0xE1, 0xE1, 0x90, 0x81, 0xC8,
-       0x12, 0x45, 0x16, 0x02, 0x4A, 0x6C, 0x90, 0x81,
-       0xC8, 0x12, 0x45, 0x16, 0x02, 0x6B, 0x3E, 0x90,
-       0x81, 0xC8, 0x12, 0x45, 0x16, 0x80, 0x3E, 0x90,
-       0x81, 0xC8, 0x12, 0x45, 0x16, 0x02, 0x6B, 0x4E,
-       0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x22,
-       0x12, 0x5A, 0x4B, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
-       0x01, 0xFE, 0x90, 0x81, 0x45, 0xE0, 0x54, 0xFE,
-       0x4E, 0xF0, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x14,
-       0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0x90, 0x81,
-       0x46, 0xF0, 0x90, 0x00, 0x02, 0x12, 0x1F, 0xBD,
-       0x90, 0x81, 0x47, 0xF0, 0x22, 0x12, 0x1F, 0xA4,
-       0xFF, 0x54, 0x01, 0xFE, 0x90, 0x81, 0x3F, 0xE0,
-       0x54, 0xFE, 0x4E, 0xF0, 0x90, 0x00, 0x01, 0x12,
-       0x1F, 0xBD, 0xFE, 0x90, 0x05, 0x54, 0xE0, 0xC3,
-       0x9E, 0x90, 0x81, 0x40, 0xF0, 0xEF, 0x20, 0xE0,
-       0x07, 0x91, 0x65, 0x90, 0x05, 0x22, 0xE4, 0xF0,
-       0x90, 0x81, 0x3F, 0xE0, 0x54, 0x01, 0x90, 0x01,
-       0xBC, 0xF0, 0x90, 0x81, 0x40, 0xE0, 0x90, 0x01,
-       0xBD, 0xF0, 0x22, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
-       0x7F, 0x90, 0x81, 0x27, 0xF0, 0xEF, 0xC4, 0x13,
-       0x13, 0x13, 0x54, 0x01, 0xA3, 0xF0, 0x90, 0x00,
-       0x01, 0x12, 0x1F, 0xBD, 0xFF, 0x54, 0xF0, 0xC4,
-       0x54, 0x0F, 0xFE, 0x90, 0x81, 0x26, 0xE0, 0x54,
-       0xF0, 0x4E, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x1F,
-       0xBD, 0x54, 0x01, 0x25, 0xE0, 0xFE, 0x90, 0x81,
-       0x24, 0xE0, 0x54, 0xFD, 0x4E, 0xF0, 0xEF, 0x54,
-       0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0x81, 0x26,
-       0xE0, 0x54, 0x0F, 0x4F, 0xF0, 0x90, 0x00, 0x04,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x29, 0xF0, 0xD1,
-       0xC6, 0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90,
-       0x01, 0xB8, 0xF0, 0x90, 0x81, 0x27, 0xE0, 0x90,
-       0x01, 0xBA, 0xF0, 0x90, 0x81, 0x29, 0xE0, 0x90,
-       0x01, 0xBB, 0xF0, 0x90, 0x81, 0x26, 0xE0, 0x54,
-       0x0F, 0x90, 0x01, 0xBE, 0xF0, 0x22, 0x90, 0x81,
-       0xCB, 0x12, 0x45, 0x1F, 0x12, 0x72, 0xB3, 0x90,
-       0x81, 0x27, 0xE0, 0xFF, 0x12, 0x4C, 0x3E, 0x90,
-       0x81, 0x27, 0xE0, 0x60, 0x19, 0x90, 0x81, 0xCB,
-       0x12, 0x45, 0x16, 0x90, 0x00, 0x01, 0x12, 0x1F,
-       0xBD, 0x54, 0x0F, 0xFF, 0x90, 0x00, 0x02, 0x12,
-       0x1F, 0xBD, 0xFD, 0x12, 0x72, 0xC4, 0x22, 0xC0,
-       0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0,
-       0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01,
-       0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05,
-       0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74,
-       0xF7, 0xF0, 0x74, 0x56, 0xA3, 0xF0, 0x12, 0x6C,
-       0xA5, 0xE5, 0x49, 0x30, 0xE1, 0x03, 0x12, 0x6F,
-       0x79, 0xE5, 0x49, 0x30, 0xE2, 0x02, 0xF1, 0xA5,
-       0xE5, 0x49, 0x30, 0xE3, 0x03, 0x12, 0x6F, 0x8D,
-       0xE5, 0x4A, 0x30, 0xE0, 0x03, 0x12, 0x6F, 0xC9,
-       0xE5, 0x4A, 0x30, 0xE4, 0x03, 0x12, 0x70, 0x22,
-       0xE5, 0x4B, 0x30, 0xE1, 0x02, 0x51, 0x78, 0xE5,
-       0x4B, 0x30, 0xE0, 0x02, 0x31, 0xFF, 0xE5, 0x4B,
-       0x30, 0xE3, 0x02, 0xF1, 0xE0, 0xE5, 0x4C, 0x30,
-       0xE1, 0x05, 0x7F, 0x03, 0x12, 0x44, 0x27, 0xE5,
-       0x4C, 0x30, 0xE4, 0x03, 0x12, 0x4E, 0xC4, 0xE5,
-       0x4C, 0x30, 0xE5, 0x03, 0x12, 0x70, 0x38, 0xE5,
-       0x4C, 0x30, 0xE6, 0x03, 0x12, 0x70, 0xCE, 0x74,
-       0xF7, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x56,
-       0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
-       0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
-       0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
-       0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x81, 0x27,
-       0xE0, 0x60, 0x34, 0x90, 0x06, 0x92, 0xE0, 0x30,
-       0xE0, 0x23, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x11, 0x05,
-       0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06,
-       0x92, 0x74, 0x01, 0xF0, 0x22, 0x90, 0x81, 0x24,
-       0xE0, 0x54, 0xF7, 0xF0, 0x12, 0x47, 0x2A, 0x22,
-       0x22, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0x31, 0xF0,
-       0x22, 0x90, 0x01, 0xC8, 0xE4, 0xF0, 0xA3, 0xF0,
-       0xA3, 0xF0, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x51,
-       0x7F, 0xFF, 0xFE, 0x12, 0x2B, 0x27, 0xBF, 0x01,
-       0x09, 0x90, 0x81, 0x51, 0xE0, 0x64, 0x03, 0x60,
-       0x03, 0x22, 0x01, 0xAB, 0xE4, 0x90, 0x81, 0x56,
-       0xF0, 0x90, 0x81, 0x56, 0xE0, 0xFF, 0xC3, 0x94,
-       0x02, 0x40, 0x02, 0x01, 0xE6, 0xC3, 0x74, 0xFE,
-       0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0x7B, 0x01,
-       0x7A, 0x81, 0x79, 0x52, 0x12, 0x2B, 0x27, 0xEF,
-       0x64, 0x01, 0x70, 0x77, 0x90, 0x81, 0x52, 0xE0,
-       0xFF, 0x54, 0xC0, 0xFE, 0x60, 0x05, 0xEF, 0x54,
-       0x0C, 0x70, 0x16, 0x90, 0x81, 0x52, 0xE0, 0xFF,
-       0x54, 0x30, 0x60, 0x67, 0xEF, 0x54, 0x03, 0x60,
-       0x62, 0x90, 0x81, 0x53, 0x74, 0x01, 0xF0, 0x80,
-       0x05, 0xE4, 0x90, 0x81, 0x53, 0xF0, 0x90, 0x81,
-       0x53, 0xE0, 0x90, 0x81, 0x52, 0x70, 0x16, 0xE0,
-       0xFF, 0xEE, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x81,
-       0x54, 0xF0, 0xEF, 0x54, 0x0C, 0x13, 0x13, 0x54,
-       0x3F, 0xA3, 0xF0, 0x80, 0x0D, 0xE0, 0xFE, 0x54,
-       0x30, 0x90, 0x81, 0x54, 0xF0, 0xEE, 0x54, 0x03,
-       0xA3, 0xF0, 0x90, 0x81, 0x54, 0xE0, 0x64, 0x30,
-       0x70, 0x54, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x4E,
-       0x90, 0x00, 0xF5, 0xE0, 0x54, 0x40, 0x90, 0x81,
-       0x57, 0xF0, 0xE0, 0x70, 0x41, 0xA3, 0x74, 0x02,
-       0xF0, 0x80, 0x10, 0x90, 0x81, 0x58, 0x74, 0x01,
-       0xF0, 0x80, 0x08, 0x90, 0x81, 0x56, 0xE0, 0x04,
-       0xF0, 0x01, 0x11, 0x90, 0x01, 0xC4, 0x74, 0xE9,
-       0xF0, 0x74, 0x57, 0xA3, 0xF0, 0x90, 0x81, 0x58,
-       0xE0, 0x90, 0x01, 0xC8, 0xF0, 0x90, 0x81, 0x52,
-       0xE0, 0x90, 0x01, 0xC9, 0xF0, 0x90, 0x81, 0x53,
-       0xE0, 0x90, 0x01, 0xCA, 0xF0, 0xE4, 0xFD, 0x7F,
-       0x1F, 0x12, 0x32, 0x1E, 0x80, 0xD5, 0x22, 0x90,
-       0x00, 0xF7, 0xE0, 0x20, 0xE7, 0x09, 0xE0, 0x7F,
-       0x01, 0x20, 0xE6, 0x0C, 0x7F, 0x02, 0x22, 0x90,
-       0x00, 0xF7, 0xE0, 0x30, 0xE6, 0x02, 0x7F, 0x03,
-       0x22, 0x11, 0xE7, 0x90, 0x80, 0x3C, 0xEF, 0xF0,
-       0x31, 0x13, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0,
-       0x02, 0x2D, 0xA7, 0x31, 0x81, 0x31, 0xB1, 0x31,
-       0x40, 0x31, 0x5F, 0xE4, 0xF5, 0x35, 0xF5, 0x36,
-       0xF5, 0x37, 0xF5, 0x38, 0xAD, 0x35, 0x7F, 0x50,
-       0x12, 0x32, 0x1E, 0xAD, 0x36, 0x7F, 0x51, 0x12,
-       0x32, 0x1E, 0xAD, 0x37, 0x7F, 0x52, 0x12, 0x32,
-       0x1E, 0xAD, 0x38, 0x7F, 0x53, 0x02, 0x32, 0x1E,
-       0x75, 0x3D, 0x10, 0xE4, 0xF5, 0x3E, 0x75, 0x3F,
-       0x07, 0x75, 0x40, 0x02, 0x90, 0x01, 0x30, 0xE5,
-       0x3D, 0xF0, 0xA3, 0xE5, 0x3E, 0xF0, 0xA3, 0xE5,
-       0x3F, 0xF0, 0xA3, 0xE5, 0x40, 0xF0, 0x22, 0x75,
-       0x45, 0x0E, 0x75, 0x46, 0x01, 0x43, 0x46, 0x10,
-       0x75, 0x47, 0x03, 0x75, 0x48, 0x62, 0x90, 0x01,
-       0x38, 0xE5, 0x45, 0xF0, 0xA3, 0xE5, 0x46, 0xF0,
-       0xA3, 0xE5, 0x47, 0xF0, 0xA3, 0xE5, 0x48, 0xF0,
-       0x22, 0x90, 0x01, 0x30, 0xE4, 0xF0, 0xA3, 0xF0,
-       0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x38, 0xF0,
-       0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xFD, 0x7F,
-       0x50, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x51,
-       0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x52, 0x12,
-       0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x53, 0x02, 0x32,
-       0x1E, 0x90, 0x01, 0x34, 0x74, 0xFF, 0xF0, 0xA3,
-       0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x3C,
-       0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xFD,
-       0x7F, 0x54, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F,
-       0x55, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F, 0x56,
-       0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F, 0x57, 0x02,
-       0x32, 0x1E, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80,
-       0xFD, 0x7F, 0x80, 0x12, 0x32, 0x1E, 0x90, 0xFD,
-       0x00, 0xE0, 0x54, 0xBF, 0xF0, 0x12, 0x57, 0xE9,
-       0x51, 0x77, 0x12, 0x32, 0x77, 0x51, 0xC9, 0x51,
-       0x5E, 0x7F, 0x01, 0x12, 0x43, 0x15, 0x90, 0x81,
-       0x41, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x43, 0x15,
-       0x90, 0x81, 0x41, 0xE0, 0x04, 0xF0, 0x7F, 0x03,
-       0x12, 0x43, 0x15, 0x90, 0x81, 0x41, 0xE0, 0x04,
-       0xF0, 0x31, 0x01, 0x51, 0x3F, 0x90, 0x00, 0x80,
-       0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x32,
-       0x1E, 0x75, 0x20, 0xFF, 0x51, 0x68, 0x51, 0xF9,
-       0x51, 0x7F, 0xE4, 0xFF, 0x02, 0x43, 0x9E, 0x51,
-       0x62, 0x51, 0x6F, 0x51, 0xA7, 0x71, 0x4F, 0x51,
-       0x8A, 0x51, 0x95, 0x90, 0x81, 0x45, 0xE0, 0x54,
-       0xFE, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0xA3, 0xF0,
-       0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xE4, 0xF5,
-       0x4D, 0x22, 0xE4, 0x90, 0x80, 0xDE, 0xF0, 0x22,
-       0x75, 0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22, 0xE4,
-       0x90, 0x80, 0xD8, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
-       0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
-       0x01, 0xE4, 0x74, 0x0B, 0xF0, 0xA3, 0x74, 0x01,
-       0xF0, 0x22, 0x90, 0x81, 0x3F, 0xE0, 0x54, 0xFE,
-       0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90, 0x81, 0x42,
-       0xE0, 0x54, 0xFE, 0xF0, 0x54, 0x7F, 0xF0, 0xA3,
-       0x74, 0x0A, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90,
-       0x81, 0x1F, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFD,
-       0xF0, 0x54, 0xFB, 0xF0, 0x54, 0xF7, 0xF0, 0x54,
-       0xEF, 0xF0, 0x54, 0xDF, 0xF0, 0xE4, 0xA3, 0xF0,
-       0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x0C, 0xF0,
-       0x22, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x04, 0xF0,
-       0x90, 0x01, 0x9C, 0x74, 0x7E, 0xF0, 0xA3, 0x74,
-       0x92, 0xF0, 0xA3, 0x74, 0xA0, 0xF0, 0xA3, 0x74,
-       0x24, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x49, 0xF0,
-       0x90, 0x01, 0x9A, 0x74, 0xE0, 0xF0, 0x90, 0x01,
-       0x99, 0xE4, 0xF0, 0x90, 0x01, 0x98, 0x04, 0xF0,
-       0x22, 0xE4, 0x90, 0x81, 0x51, 0xF0, 0xA3, 0xF0,
-       0x90, 0x01, 0x98, 0xE0, 0x7F, 0x00, 0x30, 0xE4,
-       0x02, 0x7F, 0x01, 0xEF, 0x64, 0x01, 0x60, 0x3E,
-       0xC3, 0x90, 0x81, 0x52, 0xE0, 0x94, 0x88, 0x90,
-       0x81, 0x51, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90,
-       0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90,
-       0x81, 0x51, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x44,
-       0xA9, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x32, 0xAA,
-       0xD3, 0x90, 0x81, 0x52, 0xE0, 0x94, 0x32, 0x90,
-       0x81, 0x51, 0xE0, 0x94, 0x00, 0x40, 0xB9, 0x90,
-       0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xB2, 0x22, 0xE4,
-       0x90, 0x81, 0x27, 0xF0, 0xA3, 0xF0, 0x90, 0x81,
-       0x26, 0xE0, 0x54, 0x0F, 0xF0, 0x54, 0xF0, 0xF0,
-       0x90, 0x81, 0x24, 0xE0, 0x54, 0xFD, 0xF0, 0x54,
-       0xF7, 0xF0, 0x54, 0xEF, 0xF0, 0x90, 0x81, 0x2D,
-       0x74, 0x01, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x54, 0xFB, 0xF0, 0xA3, 0xE0, 0x54, 0xFB,
-       0xF0, 0xE4, 0x90, 0x81, 0x30, 0xF0, 0x90, 0x81,
-       0x2F, 0x74, 0x07, 0xF0, 0x90, 0x81, 0x32, 0xE4,
-       0xF0, 0xA3, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0x81,
-       0x2B, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0x54, 0xFE,
-       0xF0, 0x90, 0x81, 0x29, 0x74, 0x0C, 0xF0, 0x90,
-       0x81, 0x24, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x81,
-       0x2A, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x24, 0xE0,
-       0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0xA3, 0xE0,
-       0x54, 0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xF7,
-       0xF0, 0x90, 0x81, 0x34, 0x12, 0x20, 0xDA, 0x00,
-       0x00, 0x00, 0x00, 0x90, 0x80, 0x3C, 0xE0, 0xB4,
-       0x01, 0x08, 0x90, 0x81, 0x31, 0x74, 0x99, 0xF0,
-       0x80, 0x12, 0x90, 0x80, 0x3C, 0xE0, 0x90, 0x81,
-       0x31, 0xB4, 0x03, 0x05, 0x74, 0x90, 0xF0, 0x80,
-       0x03, 0x74, 0x40, 0xF0, 0x90, 0x81, 0x38, 0x74,
-       0x01, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0xA3, 0xE0,
-       0x54, 0x01, 0x44, 0x28, 0xF0, 0xA3, 0x74, 0x05,
-       0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xE0, 0x54, 0xFD,
-       0xF0, 0x54, 0xFB, 0xF0, 0x54, 0xF7, 0xF0, 0x54,
-       0xEF, 0xF0, 0x54, 0xDF, 0xF0, 0x54, 0xBF, 0xF0,
-       0xE4, 0xA3, 0xF0, 0x22, 0xE4, 0x90, 0x81, 0x59,
-       0xF0, 0x90, 0x81, 0x59, 0xE0, 0x64, 0x01, 0xF0,
-       0x24, 0x24, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x5C,
-       0xA3, 0xF0, 0x90, 0x81, 0x2A, 0xE0, 0xFF, 0x90,
-       0x81, 0x29, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0x47,
-       0x2A, 0xD1, 0x08, 0xBF, 0x01, 0x02, 0x91, 0x5F,
-       0xB1, 0xF2, 0x12, 0x32, 0x9E, 0xBF, 0x01, 0x02,
-       0xB1, 0x67, 0x12, 0x42, 0x4D, 0x80, 0xCA, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81,
-       0x24, 0xE0, 0x30, 0xE0, 0x24, 0x90, 0x81, 0x1F,
-       0xE0, 0xFF, 0x30, 0xE0, 0x1A, 0xC3, 0x13, 0x30,
-       0xE0, 0x07, 0xB1, 0xFB, 0xBF, 0x01, 0x12, 0x80,
-       0x0A, 0x90, 0x81, 0x23, 0xE0, 0xFF, 0x60, 0x03,
-       0xB4, 0x08, 0x06, 0x91, 0x96, 0x80, 0x02, 0x91,
-       0xA6, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xB1, 0x22, 0x91,
-       0xBA, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81,
-       0x2A, 0xE0, 0x70, 0x0D, 0xD1, 0x2F, 0xBF, 0x01,
-       0x08, 0x91, 0x96, 0x90, 0x01, 0xE5, 0xE0, 0x04,
-       0xF0, 0x22, 0xB1, 0xF3, 0x90, 0x00, 0x08, 0xE0,
-       0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E,
-       0xE4, 0xFF, 0x8F, 0x50, 0xE4, 0x90, 0x81, 0x5A,
-       0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x09, 0xE0, 0x7F,
-       0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0xEF, 0x65,
-       0x50, 0x60, 0x3E, 0xC3, 0x90, 0x81, 0x5B, 0xE0,
-       0x94, 0x88, 0x90, 0x81, 0x5A, 0xE0, 0x94, 0x13,
-       0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10,
-       0xF0, 0x22, 0x90, 0x81, 0x5A, 0xE4, 0x75, 0xF0,
-       0x01, 0x12, 0x44, 0xA9, 0x7F, 0x14, 0x7E, 0x00,
-       0x12, 0x32, 0xAA, 0xD3, 0x90, 0x81, 0x5B, 0xE0,
-       0x94, 0x32, 0x90, 0x81, 0x5A, 0xE0, 0x94, 0x00,
-       0x40, 0xB9, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0,
-       0xB2, 0x22, 0x90, 0x81, 0x31, 0xE0, 0xFD, 0x7F,
-       0x93, 0x12, 0x32, 0x1E, 0x90, 0x81, 0x28, 0xE0,
-       0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7,
-       0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01,
-       0x2F, 0x74, 0x90, 0xF0, 0x90, 0x00, 0x08, 0xE0,
-       0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E,
-       0x7F, 0x01, 0x91, 0xCA, 0x90, 0x00, 0x90, 0xE0,
-       0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x32, 0x1E,
-       0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x2D,
-       0xA7, 0xE4, 0xF5, 0x52, 0x12, 0x32, 0x9E, 0xEF,
-       0x60, 0x73, 0x63, 0x52, 0x01, 0xE5, 0x52, 0x24,
-       0x67, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x5D, 0xA3,
-       0xF0, 0x90, 0x00, 0x88, 0xE0, 0xF5, 0x50, 0xF5,
-       0x51, 0x54, 0x0F, 0x60, 0xDF, 0xE5, 0x50, 0x30,
-       0xE0, 0x0B, 0x20, 0xE4, 0x03, 0x12, 0x29, 0xC5,
-       0x53, 0x51, 0xEE, 0x80, 0x3F, 0xE5, 0x50, 0x30,
-       0xE1, 0x16, 0x20, 0xE5, 0x0E, 0x12, 0x11, 0xBD,
-       0xEF, 0x70, 0x03, 0x43, 0x51, 0x20, 0x90, 0x01,
-       0x06, 0xE4, 0xF0, 0x53, 0x51, 0xFD, 0x80, 0x24,
-       0xE5, 0x50, 0x30, 0xE2, 0x0B, 0x20, 0xE6, 0x03,
-       0x12, 0x67, 0x06, 0x53, 0x51, 0xFB, 0x80, 0x14,
-       0xE5, 0x50, 0x30, 0xE3, 0x0F, 0x20, 0xE7, 0x09,
-       0x12, 0x61, 0x6E, 0xEF, 0x70, 0x03, 0x43, 0x51,
-       0x80, 0x53, 0x51, 0xF7, 0xAD, 0x51, 0x7F, 0x88,
-       0x12, 0x32, 0x1E, 0x80, 0x87, 0xD0, 0xD0, 0x92,
-       0xAF, 0x22, 0x22, 0x90, 0x00, 0x90, 0xE0, 0x20,
-       0xE0, 0xF9, 0x22, 0x90, 0x81, 0x22, 0xE0, 0x64,
-       0x02, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22,
-       0x7F, 0x02, 0x90, 0x81, 0x41, 0xE0, 0xFE, 0xEF,
-       0xC3, 0x9E, 0x50, 0x18, 0xEF, 0x25, 0xE0, 0x24,
-       0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01,
-       0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00,
-       0x22, 0x0F, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0x90,
-       0x02, 0x87, 0xE0, 0x60, 0x08, 0x90, 0x01, 0xB8,
-       0x74, 0x01, 0xF0, 0x80, 0x17, 0x90, 0x02, 0x86,
-       0xE0, 0x20, 0xE1, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x04, 0xF0, 0x80, 0x08, 0x90, 0x01, 0xB8, 0xE4,
-       0xF0, 0x7F, 0x01, 0x22, 0x90, 0x01, 0xB9, 0x74,
-       0x08, 0xF0, 0x7F, 0x00, 0x22, 0xE4, 0xFB, 0xFA,
-       0xFD, 0x7F, 0x01, 0x12, 0x44, 0x4E, 0x90, 0x81,
-       0xBD, 0xEF, 0xF0, 0x60, 0xF0, 0xD1, 0x71, 0x80,
-       0xEC, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
-       0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x81,
-       0xBE, 0xF0, 0x90, 0x81, 0xBE, 0xE0, 0xFD, 0x70,
-       0x02, 0xE1, 0x9C, 0x90, 0x82, 0x09, 0xE0, 0xFF,
-       0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80,
-       0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
-       0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xE1, 0x95, 0x90,
-       0x82, 0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01,
-       0xD0, 0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81, 0xBF,
-       0xF0, 0x75, 0x13, 0x01, 0x75, 0x14, 0x81, 0x75,
-       0x15, 0xBF, 0x75, 0x16, 0x01, 0x7B, 0x01, 0x7A,
-       0x81, 0x79, 0xC0, 0x12, 0x2B, 0xED, 0x90, 0x82,
-       0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD1,
-       0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81, 0xC1, 0xF0,
-       0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90,
-       0x01, 0xD2, 0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81,
-       0xC2, 0xF0, 0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0,
-       0x04, 0x90, 0x01, 0xD3, 0x12, 0x45, 0x0A, 0xE0,
-       0x90, 0x81, 0xC3, 0xF0, 0x90, 0x82, 0x09, 0xE0,
-       0x75, 0xF0, 0x04, 0x90, 0x01, 0xF0, 0x12, 0x45,
-       0x0A, 0xE0, 0x90, 0x81, 0xC4, 0xF0, 0x90, 0x82,
-       0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xF1,
-       0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81, 0xC5, 0xF0,
-       0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90,
-       0x01, 0xF2, 0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81,
-       0xC6, 0xF0, 0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0,
-       0x04, 0x90, 0x01, 0xF3, 0x12, 0x45, 0x0A, 0xE0,
-       0x90, 0x81, 0xC7, 0xF0, 0x90, 0x81, 0xBE, 0xE0,
-       0xFF, 0x90, 0x82, 0x09, 0xE0, 0xFE, 0x74, 0x01,
-       0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xF4, 0x5F, 0x90, 0x81, 0xBE, 0xF0, 0x90,
-       0x82, 0x09, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07,
-       0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90,
-       0x01, 0xCC, 0xF0, 0x90, 0x81, 0xC0, 0xE0, 0xFF,
-       0x7B, 0x01, 0x7A, 0x81, 0x79, 0xC1, 0x12, 0x55,
-       0x3F, 0x90, 0x82, 0x09, 0xE0, 0x04, 0xF0, 0xE0,
-       0x54, 0x03, 0xF0, 0xC1, 0x82, 0x90, 0x01, 0xC0,
-       0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12,
-       0x44, 0x4E, 0x90, 0x81, 0xD0, 0xEF, 0xF0, 0x60,
-       0xF0, 0x12, 0x6C, 0x19, 0x80, 0xEB, 0x90, 0x81,
-       0xD4, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0x12,
-       0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x90,
-       0x81, 0xE2, 0xF0, 0x7F, 0x24, 0x7E, 0x08, 0x12,
-       0x2D, 0x5C, 0x90, 0x81, 0xDA, 0x12, 0x20, 0xCE,
-       0x90, 0x81, 0xD4, 0xE0, 0xFB, 0x70, 0x08, 0x90,
-       0x81, 0xDA, 0x12, 0x44, 0xD9, 0x80, 0x16, 0xEB,
-       0x75, 0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82,
-       0xE4, 0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3,
-       0xE0, 0xFF, 0x12, 0x2D, 0x5C, 0x90, 0x81, 0xDE,
-       0x12, 0x20, 0xCE, 0x90, 0x81, 0xD5, 0xE0, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x17, 0x12, 0x20,
-       0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB,
-       0x07, 0x90, 0x81, 0xDE, 0x12, 0x44, 0xD9, 0xED,
-       0x54, 0x7F, 0xFD, 0xEC, 0x54, 0x80, 0xFC, 0x12,
-       0x44, 0xCC, 0xEC, 0x44, 0x80, 0xFC, 0x90, 0x81,
-       0xDE, 0x12, 0x20, 0xCE, 0x90, 0x81, 0xDA, 0x12,
-       0x44, 0xD9, 0xEC, 0x54, 0x7F, 0xFC, 0x90, 0x85,
-       0xBB, 0x12, 0x20, 0xCE, 0x7F, 0x24, 0x7E, 0x08,
-       0x12, 0x2E, 0xA2, 0x90, 0x81, 0xD4, 0xE0, 0x75,
-       0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82, 0xE4,
-       0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0,
-       0xFF, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xDE,
-       0x12, 0x44, 0xD9, 0x90, 0x85, 0xBB, 0x12, 0x20,
-       0xCE, 0xD0, 0x07, 0xD0, 0x06, 0x12, 0x2E, 0xA2,
-       0x90, 0x81, 0xDA, 0x12, 0x44, 0xD9, 0xEC, 0x44,
-       0x80, 0xFC, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xCE,
-       0x7F, 0x24, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90,
-       0x81, 0xD4, 0xE0, 0x70, 0x04, 0x7F, 0x20, 0x80,
-       0x09, 0x90, 0x81, 0xD4, 0xE0, 0xB4, 0x01, 0x16,
-       0x7F, 0x28, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0x78,
-       0x08, 0x12, 0x20, 0xA8, 0xEF, 0x54, 0x01, 0xFF,
-       0xE4, 0x90, 0x81, 0xE2, 0xEF, 0xF0, 0x90, 0x81,
-       0xE2, 0xE0, 0x90, 0x81, 0xD4, 0x60, 0x0E, 0xE0,
-       0x75, 0xF0, 0x08, 0xA4, 0x24, 0x66, 0xF5, 0x82,
-       0xE4, 0x34, 0x87, 0x80, 0x0C, 0xE0, 0x75, 0xF0,
-       0x08, 0xA4, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34,
-       0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
-       0x12, 0x2D, 0x5C, 0xED, 0x54, 0x0F, 0xFD, 0xE4,
-       0xFC, 0x90, 0x81, 0xD6, 0x12, 0x20, 0xCE, 0x90,
-       0x81, 0xD6, 0x02, 0x44, 0xD9, 0x90, 0x81, 0xE3,
-       0xEF, 0xF0, 0xAB, 0x05, 0x90, 0x81, 0xE9, 0x12,
-       0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x03,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x14, 0x12, 0x20,
-       0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB,
-       0x07, 0x90, 0x81, 0xE5, 0x12, 0x44, 0xD9, 0xED,
-       0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12, 0x44, 0xCC,
-       0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x81, 0xE9, 0x12,
-       0x20, 0xCE, 0x90, 0x81, 0xE3, 0xE0, 0x75, 0xF0,
-       0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34,
-       0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
-       0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE9, 0x12,
-       0x44, 0xD9, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xCE,
-       0xD0, 0x07, 0xD0, 0x06, 0x02, 0x2E, 0xA2, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x5F,
-       0xB6, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x78, 0x10,
-       0x74, 0x01, 0xF2, 0x90, 0x02, 0x09, 0xE0, 0x78,
-       0x00, 0xF2, 0x08, 0x74, 0x20, 0xF2, 0x18, 0xE2,
-       0xFF, 0x30, 0xE0, 0x05, 0x08, 0xE2, 0x24, 0x80,
-       0xF2, 0xEF, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0,
-       0x78, 0x01, 0xE2, 0x24, 0x00, 0xF5, 0x82, 0xE4,
-       0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x78, 0x03, 0xF2,
-       0x64, 0x04, 0x60, 0x0D, 0xE2, 0xFF, 0x64, 0x08,
-       0x60, 0x07, 0xEF, 0x64, 0x0C, 0x60, 0x02, 0x61,
-       0xDE, 0xE4, 0x78, 0x02, 0xF2, 0x78, 0x03, 0xE2,
-       0xFF, 0x18, 0xE2, 0xC3, 0x9F, 0x50, 0x2D, 0xE2,
-       0xFD, 0x18, 0xE2, 0x2D, 0x90, 0x81, 0x5A, 0xF0,
-       0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x04, 0x2D,
-       0xF8, 0xEE, 0xF2, 0xEF, 0xB4, 0xFF, 0x06, 0x90,
-       0xFD, 0x10, 0xE0, 0x04, 0xF0, 0x78, 0x02, 0xE2,
-       0x04, 0xF2, 0x80, 0xC9, 0x78, 0x04, 0xE2, 0x78,
-       0x12, 0xF2, 0xFF, 0x78, 0x05, 0xE2, 0x78, 0x11,
-       0xF2, 0x78, 0x06, 0xE2, 0x78, 0x13, 0xF2, 0x78,
-       0x07, 0xE2, 0x78, 0x14, 0xF2, 0x78, 0x08, 0xE2,
-       0x78, 0x33, 0xF2, 0x78, 0x09, 0xE2, 0x78, 0x34,
-       0xF2, 0x78, 0x0A, 0xE2, 0x78, 0x35, 0xF2, 0x78,
-       0x0B, 0xE2, 0x78, 0x36, 0xF2, 0x78, 0x0C, 0xE2,
-       0x78, 0x37, 0xF2, 0x78, 0x0D, 0xE2, 0x78, 0x38,
-       0xF2, 0x78, 0x0E, 0xE2, 0x78, 0x39, 0xF2, 0x78,
-       0x0F, 0xE2, 0x78, 0x3A, 0xF2, 0xE4, 0x78, 0x15,
-       0xF2, 0xEF, 0x24, 0xF8, 0x60, 0x75, 0x24, 0xFC,
-       0x60, 0x6C, 0x24, 0x08, 0x60, 0x02, 0x61, 0xC0,
-       0x78, 0x11, 0xE2, 0xB4, 0x01, 0x05, 0x12, 0x29,
-       0xC5, 0x61, 0xC5, 0x78, 0x11, 0xE2, 0xB4, 0x02,
-       0x05, 0x12, 0x11, 0xBD, 0x61, 0xC5, 0x78, 0x11,
-       0xE2, 0xB4, 0x03, 0x04, 0xF1, 0x06, 0x61, 0xC5,
-       0x78, 0x11, 0xE2, 0xB4, 0x10, 0x17, 0x78, 0x14,
-       0xE2, 0xFE, 0x18, 0xE2, 0xFD, 0xED, 0xFF, 0x78,
-       0x16, 0xEE, 0xF2, 0xFE, 0x08, 0xEF, 0xF2, 0xFF,
-       0x12, 0x32, 0xAA, 0x61, 0xC5, 0x78, 0x11, 0xE2,
-       0xB4, 0x11, 0x17, 0x78, 0x14, 0xE2, 0xFE, 0x18,
-       0xE2, 0xFD, 0xED, 0xFF, 0x78, 0x16, 0xEE, 0xF2,
-       0xFE, 0x08, 0xEF, 0xF2, 0xFF, 0x12, 0x32, 0x06,
-       0x61, 0xC5, 0x78, 0x11, 0xE2, 0xF4, 0x60, 0x02,
-       0x61, 0xC5, 0x18, 0xF2, 0x61, 0xC5, 0x78, 0x15,
-       0x74, 0x01, 0xF2, 0x78, 0x11, 0xE2, 0x64, 0x07,
-       0x60, 0x02, 0x61, 0xAA, 0x78, 0x34, 0xE2, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x08, 0x12, 0x20,
-       0xBB, 0xC0, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB,
-       0x07, 0x78, 0x33, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD,
-       0xFE, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0xC0, 0x04,
-       0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x35,
-       0xE2, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x10,
-       0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
-       0x01, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0x78, 0x18,
-       0x12, 0x44, 0xFE, 0x78, 0x15, 0xE2, 0x70, 0x02,
-       0x61, 0x93, 0x18, 0xE2, 0xFF, 0x18, 0xE2, 0xFD,
-       0x31, 0x5F, 0x78, 0x1C, 0x12, 0x44, 0xFE, 0x78,
-       0x38, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78,
-       0x08, 0x12, 0x20, 0xBB, 0xC0, 0x04, 0xA9, 0x05,
-       0xAA, 0x06, 0xAB, 0x07, 0x78, 0x37, 0xE2, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0xD0, 0x00, 0x12, 0x44,
-       0xCC, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
-       0x07, 0x78, 0x39, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD,
-       0xFE, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03,
-       0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44,
-       0xCC, 0x78, 0x20, 0x12, 0x44, 0xFE, 0x78, 0x20,
-       0x12, 0x44, 0xE5, 0x12, 0x20, 0x9B, 0x78, 0x1C,
-       0x12, 0x44, 0xF1, 0x12, 0x44, 0xBF, 0xC0, 0x04,
-       0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x18,
-       0x12, 0x44, 0xE5, 0x78, 0x20, 0x12, 0x44, 0xF1,
-       0x12, 0x44, 0xBF, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
-       0x01, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0x78, 0x18,
-       0x12, 0x44, 0xFE, 0x78, 0x18, 0x12, 0x44, 0xE5,
-       0x90, 0x81, 0xF9, 0x12, 0x20, 0xCE, 0x78, 0x13,
-       0xE2, 0xFD, 0x08, 0xE2, 0xFF, 0x12, 0x55, 0x1C,
-       0x80, 0x1B, 0x78, 0x13, 0xE2, 0xFF, 0x08, 0xE2,
-       0xFD, 0x78, 0x11, 0xE2, 0xFB, 0x78, 0x15, 0xE2,
-       0x90, 0x81, 0xBC, 0xF0, 0x71, 0xE1, 0x80, 0x05,
-       0x78, 0x10, 0x74, 0x02, 0xF2, 0x78, 0x10, 0xE2,
-       0xFF, 0xC3, 0x94, 0x02, 0x50, 0x10, 0xEF, 0x60,
-       0x0A, 0x78, 0x02, 0xE2, 0xFF, 0x18, 0xE2, 0x2F,
-       0xF2, 0x21, 0x90, 0x7F, 0x01, 0x22, 0x7F, 0x00,
-       0x22, 0xAC, 0x07, 0xED, 0xAD, 0x04, 0x78, 0x24,
-       0xF2, 0xED, 0x08, 0xF2, 0xEB, 0xB4, 0x04, 0x07,
-       0x78, 0x27, 0x74, 0x01, 0xF2, 0x80, 0x0E, 0xEB,
-       0x78, 0x27, 0xB4, 0x05, 0x05, 0x74, 0x02, 0xF2,
-       0x80, 0x03, 0x74, 0x04, 0xF2, 0xD3, 0x78, 0x25,
-       0xE2, 0x94, 0xFF, 0x18, 0xE2, 0x94, 0x00, 0x50,
-       0x63, 0xE4, 0x78, 0x26, 0xF2, 0x78, 0x27, 0xE2,
-       0xFF, 0x18, 0xE2, 0xFE, 0xC3, 0x9F, 0x40, 0x02,
-       0xA1, 0x7F, 0x74, 0x33, 0x2E, 0xF8, 0xE2, 0x78,
-       0x28, 0xF2, 0x90, 0x81, 0xBC, 0xE0, 0x60, 0x2D,
-       0x74, 0x37, 0x2E, 0xF8, 0xE2, 0x78, 0x32, 0xF2,
-       0xEE, 0xFF, 0x78, 0x25, 0xE2, 0x2F, 0xFF, 0x18,
-       0xE2, 0x34, 0x00, 0x8F, 0x82, 0xF5, 0x83, 0xE0,
-       0x78, 0x29, 0xF2, 0x78, 0x32, 0xE2, 0xFF, 0xF4,
-       0xFE, 0x78, 0x29, 0xE2, 0x5E, 0xFE, 0x18, 0xE2,
-       0xFD, 0xEF, 0x5D, 0x4E, 0xF2, 0x78, 0x24, 0x08,
-       0xE2, 0xFF, 0x08, 0xE2, 0x2F, 0xFF, 0x78, 0x28,
-       0xE2, 0xFD, 0x12, 0x32, 0x1E, 0x78, 0x26, 0xE2,
-       0x04, 0xF2, 0x80, 0xA1, 0xD3, 0x78, 0x25, 0xE2,
-       0x94, 0xFF, 0x18, 0xE2, 0x94, 0x07, 0x50, 0x69,
-       0xE4, 0x78, 0x26, 0xF2, 0x78, 0x27, 0xE2, 0xFF,
-       0x18, 0xE2, 0xFE, 0xC3, 0x9F, 0x40, 0x02, 0xA1,
-       0x7F, 0x74, 0x33, 0x2E, 0xF8, 0xE2, 0x78, 0x28,
-       0xF2, 0x90, 0x81, 0xBC, 0xE0, 0x60, 0x2D, 0x78,
-       0x26, 0xE2, 0xFF, 0xFD, 0x18, 0xE2, 0x2D, 0xFD,
-       0x18, 0xE2, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83,
-       0xE0, 0x78, 0x29, 0xF2, 0x74, 0x37, 0x2F, 0xF8,
-       0xE2, 0x78, 0x32, 0xF2, 0xE2, 0xFF, 0xF4, 0xFE,
-       0x78, 0x29, 0xE2, 0x5E, 0xFE, 0x18, 0xE2, 0xFD,
-       0xEF, 0x5D, 0x4E, 0xF2, 0x78, 0x28, 0xE2, 0xFF,
-       0x78, 0x26, 0xE2, 0xFD, 0x18, 0xE2, 0x2D, 0xFD,
-       0x18, 0xE2, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83,
-       0xEF, 0xF0, 0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80,
-       0x9B, 0x90, 0x81, 0xBC, 0xE0, 0x60, 0x0F, 0x78,
-       0x24, 0xE2, 0xFE, 0x08, 0xE2, 0xFF, 0x12, 0x2D,
-       0x5C, 0x78, 0x2E, 0x12, 0x44, 0xFE, 0xE4, 0x78,
-       0x26, 0xF2, 0x78, 0x27, 0xE2, 0xFF, 0x18, 0xE2,
-       0xFE, 0xC3, 0x9F, 0x50, 0x5D, 0x74, 0x33, 0x2E,
-       0xF8, 0xE2, 0x78, 0x28, 0xF2, 0x90, 0x81, 0xBC,
-       0xE0, 0x60, 0x2B, 0x78, 0x2E, 0x12, 0x44, 0xE5,
-       0x78, 0x26, 0xE2, 0xFB, 0x75, 0xF0, 0x08, 0xA4,
-       0xF9, 0xF8, 0x12, 0x20, 0xA8, 0x78, 0x29, 0xEF,
-       0xF2, 0x74, 0x37, 0x2B, 0xF8, 0xE2, 0x78, 0x32,
-       0xF2, 0xE2, 0xFE, 0xF4, 0x5F, 0xFF, 0x78, 0x28,
-       0xE2, 0xFD, 0xEE, 0x5D, 0x4F, 0xF2, 0x78, 0x28,
-       0xE2, 0xFF, 0x78, 0x26, 0xE2, 0xFD, 0xC3, 0x74,
-       0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x7B,
-       0xFE, 0x74, 0x2A, 0x2D, 0xF9, 0x74, 0x80, 0x3C,
-       0xFA, 0xEF, 0x12, 0x1F, 0xEA, 0xE2, 0x04, 0xF2,
-       0x80, 0x98, 0x78, 0x2A, 0x12, 0x44, 0xE5, 0x90,
-       0x85, 0xBB, 0x12, 0x20, 0xCE, 0x78, 0x24, 0xE2,
-       0xFE, 0x08, 0xE2, 0xFF, 0x12, 0x2E, 0xA2, 0x22,
-       0x22, 0x90, 0x81, 0xCB, 0x12, 0x45, 0x1F, 0x90,
-       0x00, 0x01, 0x12, 0x1F, 0xBD, 0xFF, 0xFE, 0x12,
-       0x1F, 0xA4, 0xFD, 0xC3, 0x13, 0x30, 0xE0, 0x12,
-       0x90, 0x81, 0xCB, 0x12, 0x45, 0x16, 0x90, 0x00,
-       0x02, 0x12, 0x1F, 0xBD, 0x90, 0x81, 0xCF, 0xF0,
-       0x80, 0x05, 0x90, 0x81, 0xCF, 0xEF, 0xF0, 0x90,
-       0x81, 0xCE, 0xEE, 0xF0, 0x90, 0x81, 0xCF, 0xE0,
-       0xFE, 0x90, 0x81, 0xCE, 0xE0, 0xFF, 0xD3, 0x9E,
-       0x50, 0x38, 0x90, 0x81, 0xCB, 0x12, 0x45, 0x16,
-       0x12, 0x1F, 0xA4, 0x54, 0x01, 0xFE, 0x74, 0xDE,
-       0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83,
-       0xEE, 0xF0, 0x74, 0xDE, 0x2F, 0xF5, 0x82, 0xE4,
-       0x34, 0x80, 0xF5, 0x83, 0xE0, 0x70, 0x04, 0xD1,
-       0x25, 0x80, 0x07, 0x90, 0x81, 0xCE, 0xE0, 0xFF,
-       0xB1, 0x80, 0x90, 0x81, 0xCE, 0xE0, 0x04, 0xF0,
-       0x80, 0xBA, 0x90, 0x80, 0xDE, 0xE0, 0x70, 0x24,
-       0x90, 0x81, 0x2A, 0xE0, 0x70, 0x04, 0xFF, 0x12,
-       0x49, 0x93, 0x90, 0x81, 0x2A, 0xE0, 0x64, 0x0C,
-       0x60, 0x02, 0xD1, 0x26, 0x90, 0x81, 0x24, 0xE0,
-       0x54, 0xF7, 0xF0, 0x54, 0xEF, 0xF0, 0x54, 0xBF,
-       0xF0, 0x54, 0x7F, 0xF0, 0x22, 0x22, 0x90, 0x06,
-       0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x05, 0x22,
-       0xE4, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x0C, 0xF0,
-       0x22, 0x90, 0x81, 0xED, 0xEF, 0xF0, 0xA3, 0xED,
-       0xF0, 0xAD, 0x03, 0xAC, 0x02, 0xE4, 0x90, 0x81,
-       0xF5, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0xC4, 0x74,
-       0x39, 0xF0, 0x74, 0x66, 0xA3, 0xF0, 0xEC, 0x54,
-       0x3F, 0xFC, 0x90, 0x01, 0x40, 0xED, 0xF0, 0xAE,
-       0x04, 0xEE, 0xA3, 0xF0, 0x90, 0x81, 0xED, 0xE0,
-       0x24, 0x81, 0x60, 0x34, 0x24, 0xDA, 0x60, 0x1C,
-       0x24, 0x3C, 0x70, 0x41, 0x90, 0x81, 0xEE, 0xE0,
-       0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, 0x90, 0x81,
-       0xF2, 0xF0, 0xA3, 0x74, 0x69, 0xF0, 0xA3, 0x74,
-       0x80, 0xF0, 0x80, 0x2C, 0x90, 0x81, 0xEE, 0xE0,
-       0x54, 0x01, 0x90, 0x81, 0xF2, 0xF0, 0xA3, 0x74,
-       0xA5, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x80, 0x18,
-       0x90, 0x81, 0xEE, 0xE0, 0xC4, 0x54, 0x10, 0x90,
-       0x81, 0xF2, 0xF0, 0xA3, 0x74, 0x7F, 0xF0, 0xA3,
-       0x74, 0x10, 0xF0, 0x80, 0x03, 0x7F, 0x00, 0x22,
-       0x90, 0x81, 0xF3, 0xE0, 0x90, 0x01, 0x06, 0xF0,
-       0x90, 0x81, 0xF2, 0xE0, 0x60, 0x0E, 0x90, 0x01,
-       0x42, 0xF0, 0x90, 0x81, 0xF1, 0xE0, 0x90, 0x01,
-       0x43, 0xF0, 0x80, 0x0D, 0x90, 0x01, 0x43, 0xE4,
-       0xF0, 0x90, 0x81, 0xF2, 0xE0, 0x90, 0x01, 0x42,
-       0xF0, 0x90, 0x81, 0xF4, 0xE0, 0xFF, 0x90, 0x01,
-       0x42, 0xE0, 0x5F, 0xFF, 0x90, 0x81, 0xF2, 0xE0,
-       0x6F, 0x60, 0xEE, 0x74, 0x39, 0x04, 0x90, 0x01,
-       0xC4, 0xF0, 0x74, 0x66, 0xA3, 0xF0, 0x90, 0x01,
-       0x43, 0xE4, 0xF0, 0x7F, 0x01, 0x22, 0xE4, 0x90,
-       0x81, 0x6A, 0xF0, 0x90, 0x87, 0x5F, 0xE0, 0x90,
-       0x81, 0x69, 0xF0, 0xE4, 0x90, 0x81, 0x76, 0xF0,
-       0x90, 0x81, 0x66, 0xF0, 0x90, 0x81, 0x66, 0xE0,
-       0xFF, 0xC3, 0x94, 0x40, 0x50, 0x15, 0x74, 0x79,
-       0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
-       0x74, 0xFF, 0xF0, 0x90, 0x81, 0x66, 0xE0, 0x04,
-       0xF0, 0x80, 0xE1, 0xE4, 0x90, 0x81, 0x66, 0xF0,
-       0x90, 0x81, 0x69, 0xE0, 0xFF, 0x90, 0x81, 0x66,
-       0xE0, 0xFE, 0xC3, 0x9F, 0x40, 0x03, 0x02, 0x68,
-       0x12, 0x74, 0xDF, 0x2E, 0xF9, 0xE4, 0x34, 0x86,
-       0x75, 0x13, 0x01, 0xF5, 0x14, 0x89, 0x15, 0x75,
-       0x16, 0x0A, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x5B,
-       0x12, 0x2B, 0xED, 0x90, 0x81, 0x5C, 0xE0, 0xFF,
-       0x12, 0x2F, 0x27, 0xEF, 0x04, 0x90, 0x81, 0x76,
-       0xF0, 0x90, 0x81, 0x5B, 0xE0, 0xFF, 0xA3, 0xE0,
-       0xFD, 0x12, 0x31, 0xEA, 0xEF, 0x24, 0xC8, 0x90,
-       0x81, 0x78, 0xF0, 0x75, 0xF0, 0x08, 0xA4, 0xF0,
-       0x90, 0x81, 0x5C, 0xE0, 0x54, 0x0F, 0x90, 0x81,
-       0x77, 0xF0, 0xE4, 0x90, 0x81, 0x65, 0xF0, 0x90,
-       0x81, 0x67, 0xF0, 0x90, 0x81, 0x67, 0xE0, 0xFF,
-       0xC3, 0x94, 0x04, 0x50, 0x57, 0x90, 0x81, 0x77,
-       0xE0, 0xFE, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3,
-       0x13, 0xD8, 0xFC, 0x20, 0xE0, 0x3E, 0x90, 0x81,
-       0x67, 0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x81, 0x78,
-       0xE0, 0x2F, 0x24, 0x79, 0xF9, 0xE4, 0x34, 0x81,
-       0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x01, 0x90,
-       0x81, 0x65, 0xE0, 0x75, 0xF0, 0x02, 0xA4, 0x24,
-       0x5D, 0xF9, 0x74, 0x81, 0x35, 0xF0, 0x8B, 0x13,
-       0xF5, 0x14, 0x89, 0x15, 0x75, 0x16, 0x02, 0xD0,
-       0x01, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90, 0x81,
-       0x65, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x67, 0xE0,
-       0x04, 0xF0, 0x80, 0x9F, 0x90, 0x81, 0x76, 0xE0,
-       0xFF, 0x90, 0x81, 0x66, 0xE0, 0x2F, 0xF0, 0x02,
-       0x67, 0x40, 0xE4, 0x90, 0x81, 0x6A, 0xF0, 0x90,
-       0x81, 0x6A, 0xE0, 0xC3, 0x94, 0x40, 0x40, 0x02,
-       0x41, 0xAF, 0xE0, 0xFF, 0x24, 0x79, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0x90, 0x81,
-       0x6C, 0xF0, 0xE0, 0xFE, 0x54, 0xF0, 0xC4, 0x54,
-       0x0F, 0xFD, 0x90, 0x81, 0x6B, 0xF0, 0xEE, 0x54,
-       0x0F, 0xFE, 0xA3, 0xF0, 0x74, 0x7A, 0x2F, 0xF5,
-       0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0x90,
-       0x81, 0x6D, 0xF0, 0xFC, 0xEE, 0xFE, 0xEC, 0xFB,
-       0xEB, 0xFF, 0x90, 0x81, 0x72, 0xEE, 0xF0, 0xA3,
-       0xEF, 0xF0, 0xED, 0x12, 0x45, 0x28, 0x68, 0x8B,
-       0x00, 0x68, 0xC2, 0x01, 0x69, 0x73, 0x02, 0x6A,
-       0xA0, 0x03, 0x69, 0x8E, 0x04, 0x69, 0xAF, 0x05,
-       0x69, 0xAF, 0x06, 0x69, 0xAF, 0x07, 0x69, 0xAF,
-       0x08, 0x6A, 0x33, 0x09, 0x6A, 0x69, 0x0A, 0x00,
-       0x00, 0x6A, 0xAF, 0x90, 0x81, 0x6A, 0xE0, 0xFD,
-       0x24, 0x7C, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
-       0x83, 0xE0, 0xFE, 0x74, 0x7B, 0x2D, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFD, 0xED,
-       0xFF, 0x90, 0x81, 0x74, 0xEE, 0xF0, 0xFC, 0xA3,
-       0xEF, 0xF0, 0x90, 0x81, 0x6D, 0xE0, 0xFF, 0x12,
-       0x2F, 0x96, 0x90, 0x81, 0x68, 0x74, 0x02, 0xF0,
-       0x41, 0xA0, 0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7C,
-       0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0,
-       0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x08, 0x12,
-       0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06,
-       0xAB, 0x07, 0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7B,
-       0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0,
-       0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x12, 0x44, 0xCC,
-       0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
-       0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7D, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFF, 0xE4,
-       0xFC, 0xFD, 0xFE, 0x78, 0x10, 0x12, 0x20, 0xBB,
-       0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
-       0x12, 0x44, 0xCC, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
-       0x06, 0xC0, 0x07, 0x90, 0x81, 0x6A, 0xE0, 0x24,
-       0x7E, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
-       0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x18,
-       0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
-       0x01, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0x90, 0x81,
-       0x6E, 0x12, 0x20, 0xCE, 0x90, 0x81, 0x6E, 0x12,
-       0x44, 0xD9, 0x90, 0x85, 0x96, 0x12, 0x20, 0xCE,
-       0x90, 0x81, 0x72, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
-       0x12, 0x2E, 0xE4, 0x90, 0x81, 0x68, 0x74, 0x04,
-       0xF0, 0x41, 0xA0, 0x90, 0x81, 0x6D, 0xE0, 0xFD,
-       0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7B, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFB, 0xE4,
-       0xFF, 0x12, 0x30, 0xC7, 0x80, 0x19, 0x90, 0x81,
-       0x6D, 0xE0, 0xFD, 0x90, 0x81, 0x6A, 0xE0, 0x24,
-       0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
-       0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x30, 0x6A, 0x90,
-       0x81, 0x68, 0x74, 0x01, 0xF0, 0x41, 0xA0, 0x90,
-       0x81, 0x68, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x6A,
-       0xE0, 0x24, 0x7C, 0xF5, 0x82, 0xE4, 0x34, 0x81,
-       0xF5, 0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
-       0x78, 0x08, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9,
-       0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x81, 0x6A,
-       0xE0, 0x24, 0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x81,
-       0xF5, 0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
-       0x12, 0x44, 0xCC, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
-       0x06, 0xC0, 0x07, 0x90, 0x81, 0x6C, 0xE0, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x10, 0x12, 0x20,
-       0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0,
-       0x00, 0x12, 0x44, 0xCC, 0x90, 0x81, 0x6E, 0x12,
-       0x20, 0xCE, 0x90, 0x81, 0x6B, 0xE0, 0x24, 0xFB,
-       0xFF, 0xC0, 0x07, 0x90, 0x81, 0x6E, 0x12, 0x44,
-       0xD9, 0x90, 0x81, 0xF9, 0x12, 0x20, 0xCE, 0x90,
-       0x81, 0x6D, 0xE0, 0xFD, 0xD0, 0x07, 0x12, 0x55,
-       0x1C, 0x80, 0x6D, 0x90, 0x81, 0x68, 0x74, 0x01,
-       0xF0, 0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7B, 0xF9,
-       0xE4, 0x34, 0x81, 0x75, 0x13, 0x01, 0xF5, 0x14,
-       0x89, 0x15, 0x75, 0x16, 0x01, 0x7B, 0xFE, 0x7A,
-       0x80, 0x79, 0x33, 0x12, 0x2B, 0xED, 0x90, 0x81,
-       0x6D, 0xE0, 0xFF, 0x90, 0x81, 0x6C, 0xE0, 0xFD,
-       0xE4, 0x90, 0x81, 0xBC, 0xF0, 0x7B, 0x04, 0x80,
-       0x34, 0x90, 0x81, 0x68, 0x74, 0x04, 0xF0, 0x90,
-       0x81, 0x6A, 0xE0, 0x24, 0x7B, 0xF9, 0xE4, 0x34,
-       0x81, 0x75, 0x13, 0x01, 0xF5, 0x14, 0x89, 0x15,
-       0x75, 0x16, 0x04, 0x7B, 0xFE, 0x7A, 0x80, 0x79,
-       0x33, 0x12, 0x2B, 0xED, 0x90, 0x81, 0x6D, 0xE0,
-       0xFF, 0x90, 0x81, 0x6C, 0xE0, 0xFD, 0xE4, 0x90,
-       0x81, 0xBC, 0xF0, 0x7B, 0x06, 0x12, 0x63, 0xE1,
-       0x90, 0x81, 0x68, 0xE0, 0x24, 0x02, 0xFF, 0x90,
-       0x81, 0x6A, 0xE0, 0x2F, 0xF0, 0x01, 0x17, 0x22,
-       0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x1F, 0xA4,
-       0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x90, 0x80, 0x3D,
-       0xF0, 0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0xFF,
-       0xED, 0x2F, 0x90, 0x80, 0x3E, 0xF0, 0x90, 0x00,
-       0x02, 0x12, 0x1F, 0xBD, 0xFF, 0xED, 0x2F, 0x90,
-       0x80, 0x3F, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x1F,
-       0xBD, 0xFF, 0xED, 0x2F, 0x90, 0x80, 0x40, 0xF0,
-       0x90, 0x00, 0x04, 0x12, 0x1F, 0xBD, 0xFF, 0xAE,
-       0x05, 0xED, 0x2F, 0x90, 0x80, 0x41, 0xF0, 0x22,
-       0x90, 0x00, 0x02, 0x12, 0x1F, 0xBD, 0xFF, 0x30,
-       0xE0, 0x26, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0x38,
-       0xF0, 0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0x90,
-       0x81, 0x39, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0xA3,
-       0xE0, 0x54, 0x01, 0x4F, 0xF0, 0x90, 0x00, 0x03,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x3B, 0xF0, 0x22,
-       0x90, 0x81, 0x38, 0x74, 0x01, 0xF0, 0xA3, 0x74,
-       0x05, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28,
-       0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0x12, 0x1F,
-       0xA4, 0x90, 0x81, 0x3E, 0xF0, 0x90, 0x81, 0x3E,
-       0xE0, 0x90, 0x01, 0xE7, 0xF0, 0x22, 0x12, 0x1F,
-       0xA4, 0x90, 0x81, 0x4A, 0xF0, 0x90, 0x00, 0x01,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x4B, 0xF0, 0x22,
-       0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
-       0x81, 0xFD, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4,
-       0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0xFD, 0xE0,
-       0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xE0,
-       0x60, 0x2D, 0xC3, 0x90, 0x82, 0x00, 0xE0, 0x94,
-       0xE8, 0x90, 0x81, 0xFF, 0xE0, 0x94, 0x03, 0x40,
-       0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0,
-       0x7F, 0x00, 0x80, 0x15, 0x90, 0x81, 0xFF, 0xE4,
-       0x75, 0xF0, 0x01, 0x12, 0x44, 0xA9, 0x7F, 0x0A,
-       0x7E, 0x00, 0x12, 0x32, 0xAA, 0x80, 0xC5, 0x7F,
-       0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0xD1,
-       0x12, 0x45, 0x1F, 0x90, 0x82, 0x0A, 0xE0, 0xFF,
-       0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x1F,
-       0xFC, 0x7F, 0xAF, 0x7E, 0x01, 0x71, 0x60, 0xEF,
-       0x60, 0x3A, 0x90, 0x81, 0xD1, 0x12, 0x45, 0x16,
-       0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x90, 0x00,
-       0x0E, 0x12, 0x1F, 0xBD, 0x24, 0x02, 0xF5, 0x16,
-       0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0x12, 0x2B,
-       0xED, 0x90, 0x81, 0xD1, 0x12, 0x45, 0x16, 0x90,
-       0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x90, 0x01, 0xAE,
-       0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x01, 0xCB,
-       0xE0, 0x64, 0x80, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
-       0xE4, 0xFF, 0x90, 0x80, 0xD9, 0xE0, 0xFE, 0x90,
-       0x80, 0xD8, 0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E,
-       0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x64, 0x01,
-       0x60, 0x32, 0x90, 0x01, 0xAF, 0xE0, 0x70, 0x13,
-       0xED, 0x75, 0xF0, 0x0F, 0xA4, 0x24, 0x42, 0xF9,
-       0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x71,
-       0xB6, 0x7F, 0x01, 0xEF, 0x60, 0x16, 0x90, 0x80,
-       0xD8, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0xB4,
-       0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4,
-       0x90, 0x80, 0xD8, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0x8F, 0x0D, 0x22, 0x8F, 0x0E, 0x22, 0x22,
-       0x90, 0x01, 0x34, 0xE0, 0x55, 0x3D, 0xF5, 0x41,
-       0xA3, 0xE0, 0x55, 0x3E, 0xF5, 0x42, 0xA3, 0xE0,
-       0x55, 0x3F, 0xF5, 0x43, 0xA3, 0xE0, 0x55, 0x40,
-       0xF5, 0x44, 0x90, 0x01, 0x34, 0xE5, 0x41, 0xF0,
-       0xA3, 0xE5, 0x42, 0xF0, 0xA3, 0xE5, 0x43, 0xF0,
-       0xA3, 0xE5, 0x44, 0xF0, 0x22, 0x90, 0x01, 0x3C,
-       0xE0, 0x55, 0x45, 0xF5, 0x49, 0xA3, 0xE0, 0x55,
-       0x46, 0xF5, 0x4A, 0xA3, 0xE0, 0x55, 0x47, 0xF5,
-       0x4B, 0xA3, 0xE0, 0x55, 0x48, 0xF5, 0x4C, 0x90,
-       0x01, 0x3C, 0xE5, 0x49, 0xF0, 0xA3, 0xE5, 0x4A,
-       0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0xA3, 0xE5, 0x4C,
-       0xF0, 0x53, 0x91, 0xDF, 0x22, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0, 0xA3,
-       0xF0, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01,
-       0x70, 0x19, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x13,
-       0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C,
-       0x74, 0x02, 0x12, 0x4F, 0xF4, 0x90, 0x01, 0x57,
-       0x74, 0x05, 0xF0, 0x22, 0x90, 0x80, 0xDE, 0xE0,
-       0x64, 0x01, 0x70, 0x26, 0x90, 0x81, 0x27, 0xE0,
-       0x60, 0x20, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90,
-       0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x81, 0x2B, 0xE0,
-       0x54, 0xFD, 0xF0, 0x54, 0x07, 0x70, 0x03, 0x12,
-       0x47, 0x2A, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0xB4,
-       0x01, 0x14, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x0E,
-       0x90, 0x81, 0x26, 0xE0, 0x54, 0x0F, 0x64, 0x02,
-       0x60, 0x02, 0x80, 0x03, 0xD1, 0x7F, 0x22, 0x90,
-       0x04, 0x1D, 0xE0, 0x70, 0x13, 0x90, 0x80, 0x3E,
-       0xE0, 0xFF, 0xE4, 0xFD, 0xB1, 0x69, 0x8E, 0x4E,
-       0x8F, 0x4F, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0,
-       0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
-       0x90, 0x82, 0x0E, 0xED, 0xF0, 0x90, 0x82, 0x0D,
-       0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0xF1, 0x37, 0x7C,
-       0x00, 0xAD, 0x07, 0x90, 0x82, 0x0D, 0xE0, 0x90,
-       0x04, 0x25, 0xF0, 0x90, 0x82, 0x0E, 0xE0, 0x60,
-       0x0E, 0x74, 0x0F, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF,
-       0x05, 0x74, 0x08, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
-       0x54, 0xF0, 0xF0, 0x74, 0x21, 0x2D, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xF7,
-       0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92,
-       0xAF, 0x22, 0x8F, 0x4E, 0xF1, 0x4B, 0xBF, 0x01,
-       0x18, 0x90, 0x80, 0x40, 0xE0, 0xFF, 0x7D, 0x01,
-       0xB1, 0x69, 0xAD, 0x07, 0xAC, 0x06, 0xAF, 0x4E,
-       0x12, 0x4F, 0x82, 0x90, 0x04, 0x1F, 0x74, 0x20,
-       0xF0, 0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x81,
-       0x4C, 0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x09,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x80,
-       0x72, 0xED, 0x30, 0xE6, 0x4B, 0x90, 0x81, 0x27,
-       0xE0, 0x64, 0x02, 0x70, 0x2A, 0x90, 0x81, 0x24,
-       0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, 0x09, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x28,
-       0x90, 0x81, 0x26, 0xE0, 0x54, 0x0F, 0x64, 0x01,
-       0x70, 0x2D, 0x90, 0x81, 0x2B, 0xE0, 0x44, 0x04,
-       0xF0, 0x7F, 0x01, 0xB1, 0xD2, 0x80, 0x20, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81,
-       0x26, 0xE0, 0x54, 0x0F, 0x64, 0x02, 0x60, 0x04,
-       0xB1, 0x4F, 0x80, 0x0B, 0xD1, 0x7F, 0x80, 0x07,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
-       0x81, 0x4C, 0xE0, 0x90, 0x81, 0x2B, 0x30, 0xE7,
-       0x11, 0x12, 0x4F, 0xF1, 0x90, 0x01, 0x57, 0x74,
-       0x05, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0x44, 0x04,
-       0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90,
-       0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
-       0x08, 0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x50,
-       0x05, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90,
-       0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81, 0x2A, 0xE0,
-       0x64, 0x0C, 0x60, 0x0C, 0xE4, 0xFD, 0x7F, 0x0C,
-       0x12, 0x47, 0x3D, 0xE4, 0xFF, 0x12, 0x4F, 0x0D,
-       0x22, 0xE4, 0x90, 0x81, 0x4C, 0xF0, 0x90, 0x06,
-       0xA9, 0xE0, 0x90, 0x81, 0x4C, 0xF0, 0xE0, 0x54,
-       0xC0, 0x70, 0x0D, 0x90, 0x81, 0x2B, 0xE0, 0x54,
-       0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x02, 0x47, 0x2A,
-       0x90, 0x81, 0x4C, 0xE0, 0x30, 0xE6, 0x21, 0x90,
-       0x81, 0x27, 0xE0, 0x64, 0x01, 0x70, 0x20, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81,
-       0x26, 0xE0, 0x54, 0x0F, 0x64, 0x02, 0x60, 0x04,
-       0xB1, 0x4F, 0x80, 0x0B, 0xD1, 0x7F, 0x80, 0x07,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
-       0x81, 0x4C, 0xE0, 0x90, 0x81, 0x2B, 0x30, 0xE7,
-       0x11, 0x12, 0x4F, 0xF1, 0x90, 0x01, 0x57, 0x74,
-       0x05, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0x44, 0x04,
-       0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0xE4,
-       0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30, 0xE0,
-       0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED, 0xF0,
-       0xAF, 0x06, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
-       0xC0, 0xD0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A,
-       0x90, 0x05, 0x22, 0xE0, 0x54, 0x90, 0x60, 0x07,
-       0x90, 0x01, 0xC0, 0xE0, 0x44, 0x08, 0xF0, 0x90,
-       0x01, 0xC6, 0xE0, 0x30, 0xE1, 0xE4, 0x7F, 0x00,
-       0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x03, 0x12,
-       0x73, 0xE1, 0x90, 0x81, 0x3F, 0xE0, 0x30, 0xE0,
-       0x03, 0x12, 0x49, 0xDD, 0x22, 0x90, 0x81, 0x27,
-       0xE0, 0x60, 0x35, 0x90, 0x06, 0x92, 0xE0, 0x30,
-       0xE1, 0x24, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x50,
-       0x05, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90,
-       0x06, 0x92, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x81,
-       0x24, 0xE0, 0x54, 0xEF, 0xF0, 0x12, 0x47, 0x2A,
-       0x22, 0x12, 0x71, 0x48, 0x90, 0x81, 0x4D, 0xEF,
-       0xF0, 0x90, 0x81, 0x24, 0x30, 0xE0, 0x06, 0xE0,
-       0x44, 0x01, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFE,
-       0xF0, 0x90, 0x81, 0x4D, 0xE0, 0x30, 0xE6, 0x11,
-       0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4,
-       0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80,
-       0xF0, 0x90, 0x81, 0x24, 0xE0, 0x30, 0xE0, 0x1A,
-       0x90, 0x81, 0x32, 0xE4, 0xF0, 0xA3, 0x74, 0x07,
-       0xF0, 0x90, 0x81, 0x32, 0xA3, 0xE0, 0x90, 0x05,
-       0x58, 0xF0, 0x90, 0x04, 0xEC, 0xE0, 0x54, 0xDD,
-       0xF0, 0x22, 0x90, 0x04, 0xEC, 0xE0, 0x44, 0x22,
-       0xF0, 0x22, 0x90, 0x81, 0x4A, 0xE0, 0x60, 0x0F,
-       0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x01,
-       0xF0, 0x90, 0x05, 0xFD, 0xE0, 0x04, 0xF0, 0x22,
-       0x90, 0x81, 0x24, 0xE0, 0xFF, 0xC4, 0x13, 0x13,
-       0x54, 0x03, 0x30, 0xE0, 0x27, 0xEF, 0x54, 0xBF,
-       0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x81, 0x25,
-       0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80,
-       0x10, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x01, 0xB9,
-       0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x04,
-       0xF0, 0x12, 0x47, 0x2A, 0xE4, 0xFF, 0x90, 0x81,
-       0x45, 0xE0, 0x30, 0xE0, 0x48, 0x90, 0x81, 0x49,
-       0xE0, 0xFD, 0x60, 0x41, 0x74, 0x01, 0x7E, 0x00,
-       0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE,
-       0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x04, 0xE0,
-       0xE0, 0xFB, 0xEF, 0x5B, 0x60, 0x06, 0xE4, 0x90,
-       0x81, 0x49, 0xF0, 0x22, 0x90, 0x81, 0x47, 0xE0,
-       0xD3, 0x9D, 0x50, 0x10, 0x90, 0x01, 0xC7, 0x74,
-       0x10, 0xF0, 0x11, 0xBE, 0x90, 0x81, 0x45, 0xE0,
-       0x54, 0xFE, 0xF0, 0x22, 0x12, 0x4F, 0x0B, 0x90,
-       0x81, 0x49, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x80,
-       0x3C, 0xE0, 0x64, 0x02, 0x60, 0x07, 0x90, 0x06,
-       0x90, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x81,
-       0x24, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x13, 0x54,
-       0x01, 0x30, 0xE0, 0x2C, 0xEF, 0x54, 0x7F, 0xF0,
-       0x90, 0x04, 0xE0, 0xE0, 0x90, 0x81, 0x25, 0x30,
-       0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x0F,
-       0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x01, 0xB9, 0x74,
-       0x01, 0xF0, 0x90, 0x01, 0xB8, 0x04, 0xF0, 0x90,
-       0x81, 0x27, 0xE0, 0x60, 0x03, 0x12, 0x47, 0x2A,
-       0x7F, 0x01, 0x01, 0x6E, 0xC3, 0xEE, 0x94, 0x01,
-       0x40, 0x0A, 0x0D, 0xED, 0x13, 0x90, 0xFD, 0x10,
-       0xF0, 0xE4, 0x2F, 0xFF, 0x22, 0xC3, 0xEE, 0x94,
-       0x01, 0x40, 0x24, 0x90, 0xFD, 0x11, 0xE0, 0x6D,
-       0x70, 0x1A, 0x90, 0x01, 0x17, 0xE0, 0xB5, 0x05,
-       0x0D, 0x90, 0x01, 0xE4, 0x74, 0x77, 0xF0, 0x90,
-       0xFD, 0x11, 0xE4, 0xF0, 0x80, 0x06, 0xED, 0x04,
-       0x90, 0xFD, 0x11, 0xF0, 0xE4, 0x2F, 0xFF, 0x22,
-       0xE4, 0x90, 0x81, 0x4E, 0xF0, 0xA3, 0xF0, 0xA3,
-       0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90, 0x81, 0x4E,
-       0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE, 0x90, 0x81,
-       0x4E, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3,
-       0x90, 0x81, 0x50, 0xE0, 0x94, 0x64, 0x90, 0x81,
-       0x4F, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x01,
-       0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x81, 0x4E,
-       0xE0, 0xFF, 0x22, 0x90, 0x81, 0x4F, 0xE4, 0x75,
-       0xF0, 0x01, 0x12, 0x44, 0xA9, 0x80, 0xC2, 0x74,
-       0x45, 0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E,
-       0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4,
-       0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82,
-       0x12, 0xED, 0xF0, 0x90, 0x82, 0x11, 0xEF, 0xF0,
-       0xD3, 0x94, 0x07, 0x50, 0x70, 0xE0, 0xFF, 0x74,
-       0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33,
-       0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47, 0xE0,
-       0x5F, 0xFD, 0x7F, 0x47, 0x12, 0x32, 0x1E, 0x90,
-       0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07,
-       0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF,
-       0x90, 0x00, 0x46, 0xE0, 0x4F, 0xFD, 0x7F, 0x46,
-       0x12, 0x32, 0x1E, 0x90, 0x82, 0x12, 0xE0, 0x60,
-       0x18, 0x90, 0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01,
-       0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xFF, 0x90, 0x00, 0x45, 0xE0, 0x4F, 0x80,
-       0x17, 0x90, 0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01,
-       0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x45, 0xE0, 0x5F,
-       0xFD, 0x7F, 0x45, 0x80, 0x7E, 0x90, 0x82, 0x11,
-       0xE0, 0x24, 0xF8, 0xF0, 0xE0, 0x24, 0x04, 0xFF,
-       0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3,
-       0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43,
-       0xE0, 0x5F, 0xFD, 0x7F, 0x43, 0x12, 0x32, 0x1E,
-       0x90, 0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01, 0xA8,
-       0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
-       0xFF, 0x90, 0x00, 0x43, 0xE0, 0x4F, 0xFD, 0x7F,
-       0x43, 0x12, 0x32, 0x1E, 0x90, 0x82, 0x12, 0xE0,
-       0x60, 0x1D, 0x90, 0x82, 0x11, 0xE0, 0x24, 0x04,
-       0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02,
-       0xC3, 0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x42,
-       0xE0, 0x4F, 0xFD, 0x7F, 0x42, 0x80, 0x1C, 0x90,
-       0x82, 0x11, 0xE0, 0x24, 0x04, 0xFF, 0x74, 0x01,
-       0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x42, 0xE0, 0x5F,
-       0xFD, 0x7F, 0x42, 0x12, 0x32, 0x1E, 0xD0, 0xD0,
-       0x92, 0xAF, 0x22, 0x90, 0x81, 0x24, 0xE0, 0x54,
-       0xFB, 0xF0, 0xE4, 0x90, 0x81, 0x30, 0xF0, 0x90,
-       0x81, 0x2B, 0xF0, 0x22, 0xEF, 0x24, 0xFE, 0x60,
-       0x0C, 0x04, 0x70, 0x28, 0x90, 0x81, 0x2D, 0x74,
-       0x01, 0xF0, 0xA3, 0xF0, 0x22, 0xED, 0x70, 0x0A,
-       0x90, 0x81, 0x3B, 0xE0, 0x90, 0x81, 0x2D, 0xF0,
-       0x80, 0x05, 0x90, 0x81, 0x2D, 0xED, 0xF0, 0x90,
-       0x81, 0x2D, 0xE0, 0xA3, 0xF0, 0x90, 0x81, 0x25,
-       0xE0, 0x44, 0x08, 0xF0, 0x22, 0x12, 0x4E, 0xAB,
-       0xEF, 0x64, 0x01, 0x60, 0x08, 0x90, 0x01, 0xB8,
-       0x74, 0x01, 0xF0, 0x80, 0x67, 0x90, 0x81, 0x2B,
-       0xE0, 0xFF, 0x54, 0x03, 0x60, 0x08, 0x90, 0x01,
-       0xB8, 0x74, 0x02, 0xF0, 0x80, 0x56, 0x90, 0x81,
-       0x29, 0xE0, 0xFE, 0xE4, 0xC3, 0x9E, 0x50, 0x08,
-       0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x80, 0x44,
-       0xEF, 0x30, 0xE2, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x08, 0xF0, 0x80, 0x38, 0x90, 0x81, 0x2B, 0xE0,
-       0x30, 0xE4, 0x08, 0x90, 0x01, 0xB8, 0x74, 0x10,
-       0xF0, 0x80, 0x29, 0x90, 0x81, 0x25, 0xE0, 0x13,
-       0x13, 0x54, 0x3F, 0x20, 0xE0, 0x08, 0x90, 0x01,
-       0xB8, 0x74, 0x20, 0xF0, 0x80, 0x16, 0x90, 0x81,
-       0x3E, 0xE0, 0x60, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x80, 0xF0, 0x80, 0x08, 0x90, 0x01, 0xB8, 0xE4,
-       0xF0, 0x7F, 0x01, 0x22, 0x90, 0x01, 0xB9, 0x74,
-       0x04, 0xF0, 0x7F, 0x00, 0x22, 0xEF, 0x60, 0x42,
-       0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01, 0x70, 0x3A,
-       0x90, 0x81, 0x25, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
-       0x05, 0x22, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x04,
-       0xE0, 0x54, 0xBF, 0xF0, 0xE4, 0xFF, 0x12, 0x4F,
-       0x0D, 0xBF, 0x01, 0x12, 0x90, 0x81, 0x24, 0xE0,
-       0x44, 0x40, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x06,
-       0xF0, 0x90, 0x81, 0x23, 0xF0, 0x22, 0x90, 0x01,
-       0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x74,
-       0x08, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F,
-       0xF0, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
-       0x90, 0x81, 0x2A, 0x74, 0x02, 0xF0, 0x90, 0x81,
-       0x23, 0xF0, 0x22, 0x12, 0x54, 0x65, 0x90, 0x81,
-       0x2A, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x23, 0xF0,
-       0x22, 0x90, 0x81, 0x24, 0xE0, 0xFF, 0x13, 0x13,
-       0x54, 0x3F, 0x30, 0xE0, 0x11, 0xEF, 0x54, 0xFB,
-       0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD, 0xF0,
-       0x54, 0x07, 0x70, 0x42, 0x80, 0x3D, 0x90, 0x81,
-       0x30, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x2B, 0xE0,
-       0x54, 0xEF, 0xF0, 0x90, 0x81, 0x30, 0xE0, 0xFF,
-       0xB4, 0x01, 0x02, 0x80, 0x04, 0xEF, 0xB4, 0x02,
-       0x06, 0x90, 0x05, 0x58, 0xE0, 0x04, 0xF0, 0x90,
-       0x81, 0x38, 0xE0, 0xFF, 0x90, 0x81, 0x30, 0xE0,
-       0xD3, 0x9F, 0x40, 0x0F, 0x90, 0x80, 0xDE, 0xE0,
-       0xB4, 0x01, 0x0B, 0x90, 0x81, 0x25, 0xE0, 0x54,
-       0xFB, 0xF0, 0x22, 0x12, 0x47, 0x2A, 0x22, 0x22,
-       0x90, 0x05, 0x2B, 0xE0, 0x7F, 0x00, 0x30, 0xE7,
-       0x02, 0x7F, 0x01, 0x22, 0x90, 0x05, 0x22, 0x74,
-       0xFF, 0xF0, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40,
-       0xF0, 0x90, 0x81, 0x22, 0x74, 0x03, 0xF0, 0x22,
-       0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x12,
-       0x49, 0xDD, 0x90, 0x81, 0x22, 0x74, 0x02, 0xF0,
-       0x22, 0x12, 0x49, 0xE3, 0x90, 0x81, 0x22, 0x74,
-       0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F,
-       0xF0, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
-       0x90, 0x81, 0x22, 0x74, 0x04, 0xF0, 0x22, 0xAE,
-       0x07, 0x12, 0x51, 0x73, 0xBF, 0x01, 0x12, 0x90,
-       0x81, 0x23, 0xE0, 0x64, 0x02, 0x60, 0x0A, 0xAF,
-       0x06, 0x7D, 0x01, 0x12, 0x47, 0x3D, 0x7F, 0x01,
-       0x22, 0x7F, 0x00, 0x22, 0x90, 0x01, 0x57, 0xE0,
-       0x60, 0x48, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
-       0x02, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0xFF, 0x13,
-       0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0C, 0xEF, 0x54,
-       0xFB, 0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD,
-       0xF0, 0x22, 0x90, 0x81, 0x30, 0xE0, 0x04, 0xF0,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xEF, 0xF0, 0x90,
-       0x81, 0x38, 0xE0, 0xFF, 0x90, 0x81, 0x30, 0xE0,
-       0xD3, 0x9F, 0x40, 0x0E, 0x90, 0x80, 0xDE, 0xE0,
-       0xB4, 0x01, 0x07, 0x90, 0x81, 0x25, 0xE0, 0x54,
-       0xFB, 0xF0, 0x22, 0x90, 0x80, 0x3F, 0xE0, 0xFF,
-       0x7D, 0x01, 0x12, 0x6D, 0x69, 0x8E, 0x54, 0x8F,
-       0x55, 0xAD, 0x55, 0xAC, 0x54, 0xAF, 0x53, 0x12,
-       0x4F, 0x82, 0xAF, 0x55, 0xAE, 0x54, 0x90, 0x04,
-       0x80, 0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07, 0x74,
-       0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
-       0x83, 0xE0, 0x44, 0x01, 0xF0, 0x74, 0x11, 0x2C,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
-       0x54, 0xFB, 0xF0, 0xAC, 0x07, 0x74, 0x16, 0x2C,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
-       0x44, 0xFA, 0xF0, 0x74, 0x15, 0x2C, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F,
-       0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F,
-       0xF0, 0x90, 0x04, 0x53, 0xE4, 0xF0, 0x90, 0x04,
-       0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0,
-       0x90, 0x04, 0x50, 0x74, 0xFD, 0xF0, 0x74, 0x14,
-       0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
-       0xE0, 0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xED,
-       0xF0, 0x22, 0xAB, 0x07, 0xAA, 0x06, 0xED, 0x2B,
-       0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0x90, 0x80, 0xDB,
-       0xE0, 0x9B, 0x90, 0x80, 0xDA, 0xE0, 0x9A, 0x50,
-       0x13, 0xA3, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x80,
-       0xDA, 0xE0, 0x34, 0x00, 0xFE, 0xC3, 0xEB, 0x9F,
-       0xFB, 0xEA, 0x9E, 0xFA, 0xEA, 0x90, 0xFD, 0x11,
-       0xF0, 0xAF, 0x03, 0x74, 0x00, 0x2F, 0xF5, 0x82,
-       0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0xFF, 0x22,
-       0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x90,
-       0x81, 0x42, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0xEF,
-       0xC3, 0x13, 0x30, 0xE0, 0x0A, 0x90, 0x00, 0x01,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x43, 0xF0, 0x22,
-       0x90, 0x81, 0x45, 0xE0, 0x30, 0xE0, 0x2D, 0x90,
-       0x81, 0x48, 0xE0, 0x04, 0xF0, 0xE0, 0xFF, 0x90,
-       0x81, 0x46, 0xE0, 0xB5, 0x07, 0x1E, 0x90, 0x06,
-       0x92, 0xE0, 0x54, 0x1C, 0x70, 0x0B, 0x12, 0x4F,
-       0x0B, 0x90, 0x81, 0x49, 0xE0, 0x04, 0xF0, 0x80,
-       0x06, 0x90, 0x06, 0x92, 0x74, 0x1C, 0xF0, 0xE4,
-       0x90, 0x81, 0x48, 0xF0, 0x22, 0x00, 0xBB, 0x8E,
-};
index e4f20da91b433de32c29ec5d21343cc464b7d3a6..8a7947d8de7fe2678a48d9c72cde9fc6f47def36 100644 (file)
@@ -819,7 +819,7 @@ void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup
        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
        struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
 
-       if (ODM_CheckPowerStatus(adapt) == false)
+       if (!ODM_CheckPowerStatus(adapt))
                return;
 
        ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save ADDA parameters.\n"));
@@ -888,7 +888,7 @@ _PHY_PathADDAOn(
        ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("ADDA ON.\n"));
 
        pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4;
-       if (false == is2t) {
+       if (!is2t) {
                pathOn = 0x0bdb25a0;
                ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, 0x0b1b25a0);
        } else {
@@ -1276,407 +1276,6 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
        }
 }
 
-/* Analog Pre-distortion calibration */
-#define                APK_BB_REG_NUM  8
-#define                APK_CURVE_REG_NUM 4
-#define                PATH_NUM                2
-
-static void phy_APCalibrate_8188E(struct adapter *adapt, s8 delta, bool is2t)
-{
-       struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-       u32 regD[PATH_NUM];
-       u32 tmpreg, index, offset,  apkbound;
-       u8 path, i, pathbound = PATH_NUM;
-       u32 BB_backup[APK_BB_REG_NUM];
-       u32 BB_REG[APK_BB_REG_NUM] = {
-               rFPGA1_TxBlock,         rOFDM0_TRxPathEnable,
-               rFPGA0_RFMOD, rOFDM0_TRMuxPar,
-               rFPGA0_XCD_RFInterfaceSW, rFPGA0_XAB_RFInterfaceSW,
-               rFPGA0_XA_RFInterfaceOE, rFPGA0_XB_RFInterfaceOE        };
-       u32 BB_AP_MODE[APK_BB_REG_NUM] = {
-               0x00000020, 0x00a05430, 0x02040000,
-               0x000800e4, 0x00204000 };
-       u32 BB_normal_AP_MODE[APK_BB_REG_NUM] = {
-               0x00000020, 0x00a05430, 0x02040000,
-               0x000800e4, 0x22204000 };
-
-       u32 AFE_backup[IQK_ADDA_REG_NUM];
-       u32 AFE_REG[IQK_ADDA_REG_NUM] = {
-               rFPGA0_XCD_SwitchControl, rBlue_Tooth,
-               rRx_Wait_CCA,   rTx_CCK_RFON,
-               rTx_CCK_BBON, rTx_OFDM_RFON,
-               rTx_OFDM_BBON, rTx_To_Rx,
-               rTx_To_Tx,      rRx_CCK,
-               rRx_OFDM,       rRx_Wait_RIFS,
-               rRx_TO_Rx,      rStandby,
-               rSleep,                         rPMPD_ANAEN };
-
-       u32 MAC_backup[IQK_MAC_REG_NUM];
-       u32 MAC_REG[IQK_MAC_REG_NUM] = {
-               REG_TXPAUSE,    REG_BCN_CTRL,
-               REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
-
-       u32 APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
-               {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
-       };
-
-       u32 APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, /* path settings equal to path b settings */
-               {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
-       };
-
-       u32 APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
-               {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
-       };
-
-       u32 APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, /* path settings equal to path b settings */
-               {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
-       };
-
-       u32 AFE_on_off[PATH_NUM] = {
-               0x04db25a4, 0x0b1b25a4};        /* path A on path B off / path A off path B on */
-
-       u32 APK_offset[PATH_NUM] = {
-               rConfig_AntA, rConfig_AntB};
-
-       u32 APK_normal_offset[PATH_NUM] = {
-               rConfig_Pmpd_AntA, rConfig_Pmpd_AntB};
-
-       u32 APK_value[PATH_NUM] = {
-               0x92fc0000, 0x12fc0000};
-
-       u32 APK_normal_value[PATH_NUM] = {
-               0x92680000, 0x12680000};
-
-       s8 APK_delta_mapping[APK_BB_REG_NUM][13] = {
-               {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
-       };
-
-       u32 APK_normal_setting_value_1[13] = {
-               0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
-               0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
-               0x12680000, 0x00880000, 0x00880000
-       };
-
-       u32 APK_normal_setting_value_2[16] = {
-               0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
-               0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
-               0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
-               0x00050006
-       };
-
-       u32 APK_result[PATH_NUM][APK_BB_REG_NUM];       /* val_1_1a, val_1_2a, val_2a, val_3a, val_4a */
-       s32 BB_offset, delta_V, delta_offset;
-
-       if (*(dm_odm->mp_mode) == 1) {
-               struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
-               pMptCtx->APK_bound[0] = 45;
-               pMptCtx->APK_bound[1] = 52;
-       }
-
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("==>phy_APCalibrate_8188E() delta %d\n", delta));
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("AP Calibration for %s\n", (is2t ? "2T2R" : "1T1R")));
-       if (!is2t)
-               pathbound = 1;
-
-       /* 2 FOR NORMAL CHIP SETTINGS */
-
-/*  Temporarily do not allow normal driver to do the following settings
- *  because these offset and value will cause RF internal PA to be
- *  unpredictably disabled by HW, such that RF Tx signal  will disappear
- *  after disable/enable card many times on 88CU. RF SD and DD have not
- *  find the root cause, so we remove these actions temporarily.
- */
-       if (*(dm_odm->mp_mode) != 1)
-               return;
-       /* settings adjust for normal chip */
-       for (index = 0; index < PATH_NUM; index++) {
-               APK_offset[index] = APK_normal_offset[index];
-               APK_value[index] = APK_normal_value[index];
-               AFE_on_off[index] = 0x6fdb25a4;
-       }
-
-       for (index = 0; index < APK_BB_REG_NUM; index++) {
-               for (path = 0; path < pathbound; path++) {
-                       APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index];
-                       APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index];
-               }
-               BB_AP_MODE[index] = BB_normal_AP_MODE[index];
-       }
-
-       apkbound = 6;
-
-       /* save BB default value */
-       for (index = 0; index < APK_BB_REG_NUM; index++) {
-               if (index == 0)         /* skip */
-                       continue;
-               BB_backup[index] = ODM_GetBBReg(dm_odm, BB_REG[index], bMaskDWord);
-       }
-
-       /* save MAC default value */
-       _PHY_SaveMACRegisters(adapt, MAC_REG, MAC_backup);
-
-       /* save AFE default value */
-       _PHY_SaveADDARegisters(adapt, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
-
-       for (path = 0; path < pathbound; path++) {
-               if (path == RF_PATH_A) {
-                       /* path A APK */
-                       /* load APK setting */
-                       /* path-A */
-                       offset = rPdp_AntA;
-                       for (index = 0; index < 11; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-                               offset += 0x04;
-                       }
-
-                       ODM_SetBBReg(dm_odm, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000);
-
-                       offset = rConfig_AntA;
-                       for (; index < 13; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-                               offset += 0x04;
-                       }
-
-                       /* page-B1 */
-                       ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x40000000);
-
-                       /* path A */
-                       offset = rPdp_AntA;
-                       for (index = 0; index < 16; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_2[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-
-                               offset += 0x04;
-                       }
-                       ODM_SetBBReg(dm_odm,  rFPGA0_IQK, bMaskDWord, 0x00000000);
-               } else if (path == RF_PATH_B) {
-                       /* path B APK */
-                       /* load APK setting */
-                       /* path-B */
-                       offset = rPdp_AntB;
-                       for (index = 0; index < 10; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-
-                               offset += 0x04;
-                       }
-                       ODM_SetBBReg(dm_odm, rConfig_Pmpd_AntA, bMaskDWord, 0x12680000);
-                       PHY_SetBBReg(adapt, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000);
-
-                       offset = rConfig_AntA;
-                       index = 11;
-                       for (; index < 13; index++) { /* offset 0xb68, 0xb6c */
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-                               offset += 0x04;
-                       }
-
-                       /* page-B1 */
-                       ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x40000000);
-
-                       /* path B */
-                       offset = 0xb60;
-                       for (index = 0; index < 16; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_2[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-
-                               offset += 0x04;
-                       }
-                       ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0);
-               }
-
-               /* save RF default value */
-               regD[path] = PHY_QueryRFReg(adapt, path, RF_TXBIAS_A, bMaskDWord);
-
-               /* Path A AFE all on, path B AFE All off or vise versa */
-               for (index = 0; index < IQK_ADDA_REG_NUM; index++)
-                       ODM_SetBBReg(dm_odm, AFE_REG[index], bMaskDWord, AFE_on_off[path]);
-               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                            ("phy_APCalibrate_8188E() offset 0xe70 %x\n",
-                            ODM_GetBBReg(dm_odm, rRx_Wait_CCA, bMaskDWord)));
-
-               /* BB to AP mode */
-               if (path == 0) {
-                       for (index = 0; index < APK_BB_REG_NUM; index++) {
-                               if (index == 0)         /* skip */
-                                       continue;
-                               else if (index < 5)
-                               ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_AP_MODE[index]);
-                               else if (BB_REG[index] == 0x870)
-                                       ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_backup[index]|BIT10|BIT26);
-                               else
-                                       ODM_SetBBReg(dm_odm, BB_REG[index], BIT10, 0x0);
-                       }
-
-                       ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
-                       ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
-               } else {
-                       /* path B */
-                       ODM_SetBBReg(dm_odm, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00);
-                       ODM_SetBBReg(dm_odm, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00);
-               }
-
-               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                            ("phy_APCalibrate_8188E() offset 0x800 %x\n",
-                            ODM_GetBBReg(dm_odm, 0x800, bMaskDWord)));
-
-               /* MAC settings */
-               _PHY_MACSettingCalibration(adapt, MAC_REG, MAC_backup);
-
-               if (path == RF_PATH_A) {
-                       /* Path B to standby mode */
-                       ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMaskDWord, 0x10000);
-               } else {
-                       /* Path A to standby mode */
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMaskDWord, 0x10000);
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f);
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE2, bMaskDWord, 0x20103);
-               }
-
-               delta_offset = ((delta+14)/2);
-               if (delta_offset < 0)
-                       delta_offset = 0;
-               else if (delta_offset > 12)
-                       delta_offset = 12;
-
-               /* AP calibration */
-               for (index = 0; index < APK_BB_REG_NUM; index++) {
-                       if (index != 1) /* only DO PA11+PAD01001, AP RF setting */
-                               continue;
-
-                       tmpreg = APK_RF_init_value[path][index];
-                       if (!dm_odm->RFCalibrateInfo.bAPKThermalMeterIgnore) {
-                               BB_offset = (tmpreg & 0xF0000) >> 16;
-
-                               if (!(tmpreg & BIT15)) /* sign bit 0 */
-                                       BB_offset = -BB_offset;
-
-                               delta_V = APK_delta_mapping[index][delta_offset];
-
-                               BB_offset += delta_V;
-
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() APK index %d tmpreg 0x%x delta_V %d delta_offset %d\n",
-                                            index, tmpreg, delta_V, delta_offset));
-
-                               if (BB_offset < 0) {
-                                       tmpreg = tmpreg & (~BIT15);
-                                       BB_offset = -BB_offset;
-                               } else {
-                                       tmpreg = tmpreg | BIT15;
-                               }
-                               tmpreg = (tmpreg & 0xFFF0FFFF) | (BB_offset << 16);
-                       }
-
-                       ODM_SetRFReg(dm_odm, path, RF_IPA_A, bMaskDWord, 0x8992e);
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xc %x\n", PHY_QueryRFReg(adapt, path, RF_IPA_A, bMaskDWord)));
-                       ODM_SetRFReg(dm_odm, path, RF_AC, bMaskDWord, APK_RF_value_0[path][index]);
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("phy_APCalibrate_8188E() offset 0x0 %x\n", PHY_QueryRFReg(adapt, path, RF_AC, bMaskDWord)));
-                       ODM_SetRFReg(dm_odm, path, RF_TXBIAS_A, bMaskDWord, tmpreg);
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xd %x\n", PHY_QueryRFReg(adapt, path, RF_TXBIAS_A, bMaskDWord)));
-                       /*  PA11+PAD01111, one shot */
-                       i = 0;
-                       do {
-                               ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80000000);
-                               ODM_SetBBReg(dm_odm, APK_offset[path], bMaskDWord, APK_value[0]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(dm_odm, APK_offset[path], bMaskDWord)));
-                               ODM_delay_ms(3);
-                               ODM_SetBBReg(dm_odm, APK_offset[path], bMaskDWord, APK_value[1]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(dm_odm, APK_offset[path], bMaskDWord)));
-
-                               ODM_delay_ms(20);
-                               ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
-
-                               if (path == RF_PATH_A)
-                                       tmpreg = ODM_GetBBReg(dm_odm, rAPK, 0x03E00000);
-                               else
-                                       tmpreg = ODM_GetBBReg(dm_odm, rAPK, 0xF8000000);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xbd8[25:21] %x\n", tmpreg));
-
-                               i++;
-                       } while (tmpreg > apkbound && i < 4);
-
-                       APK_result[path][index] = tmpreg;
-               }
-       }
-
-       /* reload MAC default value */
-       _PHY_ReloadMACRegisters(adapt, MAC_REG, MAC_backup);
-
-       /* reload BB default value */
-       for (index = 0; index < APK_BB_REG_NUM; index++) {
-               if (index == 0)         /* skip */
-                       continue;
-               ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_backup[index]);
-       }
-
-       /* reload AFE default value */
-       reload_adda_reg(adapt, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
-
-       /* reload RF path default value */
-       for (path = 0; path < pathbound; path++) {
-               ODM_SetRFReg(dm_odm, path, 0xd, bMaskDWord, regD[path]);
-               if (path == RF_PATH_B) {
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f);
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE2, bMaskDWord, 0x20101);
-               }
-
-               /* note no index == 0 */
-               if (APK_result[path][1] > 6)
-                       APK_result[path][1] = 6;
-               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1]));
-       }
-
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\n"));
-
-       for (path = 0; path < pathbound; path++) {
-               ODM_SetRFReg(dm_odm, path, 0x3, bMaskDWord,
-                            ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1]));
-               if (path == RF_PATH_A)
-                       ODM_SetRFReg(dm_odm, path, 0x4, bMaskDWord,
-                                    ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05));
-               else
-                       ODM_SetRFReg(dm_odm, path, 0x4, bMaskDWord,
-                                    ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05));
-               ODM_SetRFReg(dm_odm, path, RF_BS_PA_APSET_G9_G11, bMaskDWord,
-                            ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08));
-       }
-
-       dm_odm->RFCalibrateInfo.bAPKdone = true;
-
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("<==phy_APCalibrate_8188E()\n"));
-}
-
-#define                DP_BB_REG_NUM           7
-#define                DP_RF_REG_NUM           1
-#define                DP_RETRY_LIMIT          10
-#define                DP_PATH_NUM             2
-#define                DP_DPK_NUM                      3
-#define                DP_DPK_VALUE_NUM        2
-
 void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
 {
        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
@@ -1697,7 +1296,7 @@ void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
        bool is2t;
 
        is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
-       if (ODM_CheckPowerStatus(adapt) == false)
+       if (!ODM_CheckPowerStatus(adapt))
                return;
 
        if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
@@ -1867,28 +1466,6 @@ void PHY_LCCalibrate_8188E(struct adapter *adapt)
                     ("LCK:Finish!!!interface %d\n", dm_odm->InterfaceIndex));
 }
 
-void PHY_APCalibrate_8188E(struct adapter *adapt, s8 delta)
-{
-       struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-
-       return;
-       if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
-               return;
-
-#if FOR_BRAZIL_PRETEST != 1
-       if (dm_odm->RFCalibrateInfo.bAPKdone)
-#endif
-               return;
-
-       if (dm_odm->RFType == ODM_2T2R) {
-               phy_APCalibrate_8188E(adapt, delta, true);
-       } else {
-               /*  For 88C 1T1R */
-               phy_APCalibrate_8188E(adapt, delta, false);
-       }
-}
-
 static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t)
 {
        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
index e913a22a6426af43c0332aea1835b775e0af5988..5700dbce5b8c54d00bafdb9839c7615b698bc157 100644 (file)
@@ -85,7 +85,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
                                value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
                                value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
 
-                               /*  Write the value back to sytem register */
+                               /*  Write the value back to system register */
                                rtw_write8(padapter, offset, value);
                                break;
                        case PWR_CMD_POLLING:
index 8c8587754517f0ceda6249dd52bfe1a48e2a3798..8be2ad7217d4bc398922c43a7b937d34b71f84d1 100644 (file)
@@ -273,7 +273,7 @@ void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt)
 static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
 {
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       u16 *fctrl;
+       __le16 *fctrl;
        u32 rate_len, pktlen;
        struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -360,7 +360,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
        struct rtw_ieee80211_hdr        *pwlanhdr;
        struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
-       u16 *fctrl;
+       __le16 *fctrl;
 
        pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
 
@@ -391,7 +391,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
        u8 bForcePowerSave)
 {
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       u16 *fctrl;
+       __le16 *fctrl;
        u32 pktlen;
        struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
        struct wlan_network             *cur_network = &pmlmepriv->cur_network;
@@ -450,7 +450,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
 static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID)
 {
        struct rtw_ieee80211_hdr        *pwlanhdr;
-       u16 *fctrl;
+       __le16 *fctrl;
        u8 *mac, *bssid;
        u32 pktlen;
        struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
@@ -484,7 +484,7 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u
        *pLength = pktlen;
 }
 
-/*  To check if reserved page content is destroyed by beacon beacuse beacon is too large. */
+/*  To check if reserved page content is destroyed by beacon because beacon is too large. */
 /*  2010.06.23. Added by tynli. */
 void CheckFwRsvdPageContent(struct adapter *Adapter)
 {
@@ -496,9 +496,9 @@ void CheckFwRsvdPageContent(struct adapter *Adapter)
 /*                     (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */
 /*     Input: */
 /*         bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */
-/*                                             so we need to set the packet length to total lengh. */
+/*                                             so we need to set the packet length to total length. */
 /*                           true: At the second time, we should send the first packet (default:beacon) */
-/*                                             to Hw again and set the lengh in descriptor to the real beacon lengh. */
+/*                                             to Hw again and set the length in descriptor to the real beacon length. */
 /*  2009.10.15 by tynli. */
 static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 {
@@ -671,7 +671,7 @@ _func_enter_;
                        DBG_88E("%s: 1 Download RSVD success! DLBcnCount:%u, poll:%u\n", __func__, DLBcnCount, poll);
                /*  */
                /*  We just can send the reserved page twice during the time that Tx thread is stopped (e.g. pnpsetpower) */
-               /*  becuase we need to free the Tx BCN Desc which is used by the first reserved page packet. */
+               /*  because we need to free the Tx BCN Desc which is used by the first reserved page packet. */
                /*  At run time, we cannot get the Tx Desc until it is released in TxHandleInterrupt() so we will return */
                /*  the beacon TCB in the following code. 2011.11.23. by tynli. */
                /*  */
index 292ba62d722f6235298bb5e54bd2253668b09b5b..52b3fba0fae147590b350f22a93f2690ace4715f 100644 (file)
@@ -19,6 +19,7 @@
  ******************************************************************************/
 #define _HAL_INIT_C_
 
+#include <linux/firmware.h>
 #include <drv_types.h>
 #include <rtw_efuse.h>
 
@@ -588,13 +589,15 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
        u8 writeFW_retry = 0;
        u32 fwdl_start_time;
        struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
-
-       u8 *FwImage;
-       u32                     FwImageLen;
+       struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+       struct device *device = dvobj_to_dev(dvobj);
        struct rt_firmware *pFirmware = NULL;
+       const struct firmware *fw;
        struct rt_firmware_hdr *pFwHdr = NULL;
        u8 *pFirmwareBuf;
-       u32                     FirmwareLen;
+       u32 FirmwareLen;
+       char fw_name[] = "rtlwifi/rtl8188eufw.bin";
+       static int log_version;
 
        RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
        pFirmware = (struct rt_firmware *)rtw_zmalloc(sizeof(struct rt_firmware));
@@ -603,27 +606,32 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
                goto Exit;
        }
 
-       FwImage = (u8 *)Rtl8188E_FwImageArray;
-       FwImageLen = Rtl8188E_FWImgArrayLength;
-
-       pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
-
-       switch (pFirmware->eFWSource) {
-       case FW_SOURCE_IMG_FILE:
-               break;
-       case FW_SOURCE_HEADER_FILE:
-               if (FwImageLen > FW_8188E_SIZE) {
-                       rtStatus = _FAIL;
-                       RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE));
-                       goto Exit;
-               }
+       if (request_firmware(&fw, fw_name, device)) {
+               rtStatus = _FAIL;
+               goto Exit;
+       }
+       if (!fw) {
+               pr_err("Firmware %s not available\n", fw_name);
+               rtStatus = _FAIL;
+               goto Exit;
+       }
+       if (fw->size > FW_8188E_SIZE) {
+               rtStatus = _FAIL;
+               RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE));
+               goto Exit;
+       }
 
-               pFirmware->szFwBuffer = FwImage;
-               pFirmware->ulFwLength = FwImageLen;
-               break;
+       pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL);
+       if (!pFirmware->szFwBuffer) {
+               rtStatus = _FAIL;
+               goto Exit;
        }
+       memcpy(pFirmware->szFwBuffer, fw->data, fw->size);
+       pFirmware->ulFwLength = fw->size;
        pFirmwareBuf = pFirmware->szFwBuffer;
        FirmwareLen = pFirmware->ulFwLength;
+       release_firmware(fw);
+
        DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, FirmwareLen);
 
        /*  To Check Fw header. Added by tynli. 2009.12.04. */
@@ -633,8 +641,10 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
        pHalData->FirmwareSubVersion = pFwHdr->Subversion;
        pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
 
-       DBG_88E("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n",
-               __func__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
+       if (!log_version++)
+               pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n",
+                       DRIVER_PREFIX, pHalData->FirmwareVersion,
+                       pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
 
        if (IS_FW_HEADER_EXIST(pFwHdr)) {
                /*  Shift 32 bytes for FW header */
@@ -677,7 +687,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
                goto Exit;
        }
        RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n"));
-
+       kfree(pFirmware->szFwBuffer);
 Exit:
 
        kfree(pFirmware);
@@ -1479,7 +1489,6 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse
 
 static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
 {
-       bool bRet = false;
        u16     efuse_addr = *pAddr;
        u8 badworden = 0;
        u32     PgWriteSuccess = 0;
@@ -1497,7 +1506,6 @@ static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u
                else
                        return true;
        }
-       return bRet;
 }
 
 static bool
@@ -1653,7 +1661,7 @@ hal_EfusePgCheckAvailableAddr(
 {
        u16     efuse_max_available_len = 0;
 
-       /* Change to check TYPE_EFUSE_MAP_LEN , beacuse 8188E raw 256, logic map over 256. */
+       /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */
        EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false);
 
        if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len)
@@ -2100,7 +2108,7 @@ static u8 Hal_GetChnlGroup88E(u8 chnl, u8 *pGroup)
        if (chnl <= 14) {
                bIn24G = true;
 
-               if (chnl < 3)                   /*  Chanel 1-2 */
+               if (chnl < 3)                   /*  Channel 1-2 */
                        *pGroup = 0;
                else if (chnl < 6)              /*  Channel 3-5 */
                        *pGroup = 1;
@@ -2182,7 +2190,7 @@ void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool Auto
                pHalData->bTXPowerDataReadFromEEPORM = true;
 
        for (rfPath = 0; rfPath < pHalData->NumTotalRFPath; rfPath++) {
-               for (ch = 0; ch <= CHANNEL_MAX_NUMBER; ch++) {
+               for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
                        bIn24G = Hal_GetChnlGroup88E(ch, &group);
                        if (bIn24G) {
                                pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
index ff468a68e327b2123125512752991c97e7786d71..68bb96d83c8196f099f15e9832a535c311d7758b 100644 (file)
@@ -559,7 +559,7 @@ static      int phy_BB8188E_Config_ParaFile(struct adapter *Adapter)
 
        /*  */
        /*  1. Read PHY_REG.TXT BB INIT!! */
-       /*  We will seperate as 88C / 92C according to chip version */
+       /*  We will separate as 88C / 92C according to chip version */
        /*  */
        if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG))
                rtStatus = _FAIL;
@@ -685,7 +685,7 @@ static      u8 phy_DbmToTxPwrIdx(struct adapter *Adapter, enum wireless_mode Wireless
 
        /*  */
        /*  Tested by MP, we found that CCK Index 0 equals to 8dbm, OFDM legacy equals to */
-       /*  3dbm, and OFDM HT equals to 0dbm repectively. */
+       /*  3dbm, and OFDM HT equals to 0dbm respectively. */
        /*  Note: */
        /*      The mapping may be different by different NICs. Do not use this formula for what needs accurate result. */
        /*  By Bruce, 2008-01-29. */
@@ -1006,12 +1006,12 @@ _PHY_SetBWMode92C(
        switch (pHalData->CurrentChannelBW) {
        case HT_CHANNEL_WIDTH_20:
                regBwOpMode |= BW_OPMODE_20MHZ;
-               /*  2007/02/07 Mark by Emily becasue we have not verify whether this register works */
+               /*  2007/02/07 Mark by Emily because we have not verify whether this register works */
                rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
                break;
        case HT_CHANNEL_WIDTH_40:
                regBwOpMode &= ~BW_OPMODE_20MHZ;
-               /*  2007/02/07 Mark by Emily becasue we have not verify whether this register works */
+               /*  2007/02/07 Mark by Emily because we have not verify whether this register works */
                rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
                regRRSR_RSC = (regRRSR_RSC&0x90) | (pHalData->nCur40MhzPrimeSC<<5);
                rtw_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
index bfdf9b3ce77fefc82ab90bab8930258a59de9a3e..299e03e3daf6bc6e2209c2768232547a2c89d2b5 100644 (file)
@@ -181,7 +181,7 @@ i            *  Currently, we cannot fully disable driver dynamic
                 * tx power mechanism because it is referenced by BT
                 * coexist mechanism.
                 * In the future, two mechanism shall be separated from
-                * each other and maintained independantly. */
+                * each other and maintained independently. */
                if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) {
                        TxAGC[RF_PATH_A] = 0x10101010;
                        TxAGC[RF_PATH_B] = 0x10101010;
@@ -216,11 +216,11 @@ i          *  Currently, we cannot fully disable driver dynamic
        ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 1, &direction, &pwrtrac_value);
 
        if (direction == 1) {
-               /*  Increase TX pwoer */
+               /*  Increase TX power */
                TxAGC[0] += pwrtrac_value;
                TxAGC[1] += pwrtrac_value;
        } else if (direction == 2) {
-               /*  Decrease TX pwoer */
+               /*  Decrease TX power */
                TxAGC[0] -=  pwrtrac_value;
                TxAGC[1] -=  pwrtrac_value;
        }
@@ -292,7 +292,7 @@ static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel,
                        if (pHalData->pwrGroupCnt == 1)
                                chnlGroup = 0;
                        if (pHalData->pwrGroupCnt >= pHalData->PGMaxGroup) {
-                               if (Channel < 3)                        /*  Chanel 1-2 */
+                               if (Channel < 3)                        /*  Channel 1-2 */
                                        chnlGroup = 0;
                                else if (Channel < 6)           /*  Channel 3-5 */
                                        chnlGroup = 1;
@@ -349,7 +349,7 @@ static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel,
                }
 /*  20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */
 /*  Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */
-/*  In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. */
+/*  In the future, two mechanism shall be separated from each other and maintained independently. Thanks for Lanhsin's reminder. */
                /* 92d do not need this */
                if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1)
                        writeVal = 0x14141414;
index bd8a9ae5d0770181c2ca0802492224b5f844f6f7..8f43f4966f223d89de22d898c7c716bd7682587f 100644 (file)
@@ -332,7 +332,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
 
        /*  2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
        /*  (1) The sequence number of each non-Qos frame / broadcast / multicast / */
-       /*  mgnt frame should be controled by Hw because Fw will also send null data */
+       /*  mgnt frame should be controlled by Hw because Fw will also send null data */
        /*  which we cannot control when Fw LPS enable. */
        /*  --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
        /*  (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
index 5e656ce4540702648067333bd4dbc80651e0f419..cca973211b2fe33824eb223674e89074bf62c1eb 100644 (file)
@@ -464,7 +464,7 @@ static void _InitRetryFunction(struct adapter *Adapter)
 /*-----------------------------------------------------------------------------
  * Function:   usb_AggSettingTxUpdate()
  *
- * Overview:   Seperate TX/RX parameters update independent for TP detection and
+ * Overview:   Separate TX/RX parameters update independent for TP detection and
  *                     dynamic TX/RX aggreagtion parameters update.
  *
  * Input:                      struct adapter *
@@ -473,7 +473,7 @@ static void _InitRetryFunction(struct adapter *Adapter)
  *
  * Revised History:
  *     When            Who             Remark
- *     12/10/2010      MHC             Seperate to smaller function.
+ *     12/10/2010      MHC             Separate to smaller function.
  *
  *---------------------------------------------------------------------------*/
 static void usb_AggSettingTxUpdate(struct adapter *Adapter)
@@ -496,7 +496,7 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
 /*-----------------------------------------------------------------------------
  * Function:   usb_AggSettingRxUpdate()
  *
- * Overview:   Seperate TX/RX parameters update independent for TP detection and
+ * Overview:   Separate TX/RX parameters update independent for TP detection and
  *                     dynamic TX/RX aggreagtion parameters update.
  *
  * Input:                      struct adapter *
@@ -505,7 +505,7 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
  *
  * Revised History:
  *     When            Who             Remark
- *     12/10/2010      MHC             Seperate to smaller function.
+ *     12/10/2010      MHC             Separate to smaller function.
  *
  *---------------------------------------------------------------------------*/
 static void
@@ -847,7 +847,7 @@ _func_enter_;
 
        /*  */
        /*  Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */
-       /*  Hw bug which Hw initials RxFF boundry size to a value which is larger than the real Rx buffer size in 88E. */
+       /*  Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
        /*  */
        /*  Enable MACTXEN/MACRXEN block */
        value16 = rtw_read16(Adapter, REG_CR);
index bc564169b2f0560b155a519d2421fc5ae7f71a56..787763ef74c6707d832c34edf0e8ed443cdb3543 100644 (file)
@@ -547,6 +547,8 @@ static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
                RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete : purb->status(%d) != 0\n", purb->status));
 
                DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
+               skb_put(precvbuf->pskb, purb->actual_length);
+               precvbuf->pskb = NULL;
 
                if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt)))
                        adapt->bSurpriseRemoved = true;
@@ -605,68 +607,68 @@ _func_enter_;
                return _FAIL;
        }
 
+       if (!precvbuf) {
+               RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+                        ("usb_read_port:precvbuf==NULL\n"));
+               return _FAIL;
+       }
+
        if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
                precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
                if (NULL != precvbuf->pskb)
                        precvbuf->reuse = true;
        }
 
-       if (precvbuf != NULL) {
-               rtl8188eu_init_recvbuf(adapter, precvbuf);
-
-               /* re-assign for linux based on skb */
-               if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
-                       precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
-                       if (precvbuf->pskb == NULL) {
-                               RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
-                               DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
-                               return _FAIL;
-                       }
-
-                       tmpaddr = (size_t)precvbuf->pskb->data;
-                       alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
-                       skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
-
-                       precvbuf->phead = precvbuf->pskb->head;
-                       precvbuf->pdata = precvbuf->pskb->data;
-                       precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
-                       precvbuf->pend = skb_end_pointer(precvbuf->pskb);
-                       precvbuf->pbuf = precvbuf->pskb->data;
-               } else { /* reuse skb */
-                       precvbuf->phead = precvbuf->pskb->head;
-                       precvbuf->pdata = precvbuf->pskb->data;
-                       precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
-                       precvbuf->pend = skb_end_pointer(precvbuf->pskb);
-                       precvbuf->pbuf = precvbuf->pskb->data;
+       rtl8188eu_init_recvbuf(adapter, precvbuf);
 
-                       precvbuf->reuse = false;
+       /* re-assign for linux based on skb */
+       if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
+               precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+               if (precvbuf->pskb == NULL) {
+                       RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
+                       DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
+                       return _FAIL;
                }
 
-               precvpriv->rx_pending_cnt++;
+               tmpaddr = (size_t)precvbuf->pskb->data;
+               alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+               skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+
+               precvbuf->phead = precvbuf->pskb->head;
+               precvbuf->pdata = precvbuf->pskb->data;
+               precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+               precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+               precvbuf->pbuf = precvbuf->pskb->data;
+       } else { /* reuse skb */
+               precvbuf->phead = precvbuf->pskb->head;
+               precvbuf->pdata = precvbuf->pskb->data;
+               precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+               precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+               precvbuf->pbuf = precvbuf->pskb->data;
+
+               precvbuf->reuse = false;
+       }
 
-               purb = precvbuf->purb;
+       precvpriv->rx_pending_cnt++;
 
-               /* translate DMA FIFO addr to pipehandle */
-               pipe = ffaddr2pipehdl(pdvobj, addr);
+       purb = precvbuf->purb;
 
-               usb_fill_bulk_urb(purb, pusbd, pipe,
-                                 precvbuf->pbuf,
-                                 MAX_RECVBUF_SZ,
-                                 usb_read_port_complete,
-                                 precvbuf);/* context is precvbuf */
+       /* translate DMA FIFO addr to pipehandle */
+       pipe = ffaddr2pipehdl(pdvobj, addr);
 
-               err = usb_submit_urb(purb, GFP_ATOMIC);
-               if ((err) && (err != (-EPERM))) {
-                       RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
-                                ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
-                                err, purb->status));
-                       DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
-                               err, purb->status);
-                       ret = _FAIL;
-               }
-       } else {
+       usb_fill_bulk_urb(purb, pusbd, pipe,
+                         precvbuf->pbuf,
+                         MAX_RECVBUF_SZ,
+                         usb_read_port_complete,
+                         precvbuf);/* context is precvbuf */
+
+       err = usb_submit_urb(purb, GFP_ATOMIC);
+       if ((err) && (err != (-EPERM))) {
                RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
-                        ("usb_read_port:precvbuf ==NULL\n"));
+                        ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
+                        err, purb->status));
+               DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
+                       err, purb->status);
                ret = _FAIL;
        }
 
diff --git a/drivers/staging/rtl8188eu/include/Hal8188EFWImg_CE.h b/drivers/staging/rtl8188eu/include/Hal8188EFWImg_CE.h
deleted file mode 100644 (file)
index 949c33b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. 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 Street, Fifth Floor, Boston, MA 02110, USA
-*
-*
-******************************************************************************/
-#ifndef __INC_HAL8188E_FW_IMG_H
-#define __INC_HAL8188E_FW_IMG_H
-
-/* V10(1641) */
-#define Rtl8188EFWImgArrayLength 13904
-
-extern const u8 Rtl8188EFwImgArray[Rtl8188EFWImgArrayLength];
-
-#endif /* __INC_HAL8188E_FW_IMG_H */
index c4769e20a5c371149c6c07f8cce71bf6868ced05..25cae8147e732a1519761de9b8bf48379d598b1e 100644 (file)
@@ -75,7 +75,7 @@ enum rf_radio_path {
 
 #define MAX_PG_GROUP 13
 
-#define        RF_PATH_MAX                     2
+#define        RF_PATH_MAX                     3
 #define                MAX_RF_PATH             RF_PATH_MAX
 #define                MAX_TX_COUNT            4 /* path numbers */
 
index 0e06d29b2d2a812622677acb24c41c66ee6bf0b6..9f2969bf8355f1420022174904a3d202e27adf10 100644 (file)
@@ -26,7 +26,7 @@
 /*  2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */
 /*  3. RF register 0x00-2E */
 /*  4. Bit Mask for BB/RF register */
-/*  5. Other defintion for BB/RF R/W */
+/*  5. Other definition for BB/RF R/W */
 /*  */
 
 
index fa583f2483201d587814454ddc79e8e86406b6a9..287e9f9eae4a0b601eac7883149c540236e37963 100644 (file)
@@ -45,8 +45,6 @@ void PHY_IQCalibrate_8188E(struct adapter *Adapter, bool ReCovery);
 void PHY_LCCalibrate_8188E(struct adapter *pAdapter);
 
 /*  AP calibrate */
-void PHY_APCalibrate_8188E(struct adapter *pAdapter, s8 delta);
-
 void PHY_DigitalPredistortion_8188E(struct adapter *pAdapter);
 
 void _PHY_SaveADDARegisters(struct adapter *pAdapter, u32 *ADDAReg,
index cd37ea4df4cbe999f7857ae1e7d5b731e778e797..c4d38d14abf1eb423d68ee2f12b26b080ce73f95 100644 (file)
@@ -306,8 +306,8 @@ struct ieee_ibss_seq {
 };
 
 struct rtw_ieee80211_hdr {
-       u16 frame_ctl;
-       u16 duration_id;
+       __le16 frame_ctl;
+       __le16 duration_id;
        u8 addr1[ETH_ALEN];
        u8 addr2[ETH_ALEN];
        u8 addr3[ETH_ALEN];
@@ -316,8 +316,8 @@ struct rtw_ieee80211_hdr {
 } __packed;
 
 struct rtw_ieee80211_hdr_3addr {
-       u16 frame_ctl;
-       u16 duration_id;
+       __le16 frame_ctl;
+       __le16 duration_id;
        u8 addr1[ETH_ALEN];
        u8 addr2[ETH_ALEN];
        u8 addr3[ETH_ALEN];
@@ -325,8 +325,8 @@ struct rtw_ieee80211_hdr_3addr {
 } __packed;
 
 struct rtw_ieee80211_hdr_qos {
-       u16 frame_ctl;
-       u16 duration_id;
+       __le16 frame_ctl;
+       __le16 duration_id;
        u8 addr1[ETH_ALEN];
        u8 addr2[ETH_ALEN];
        u8 addr3[ETH_ALEN];
@@ -336,8 +336,8 @@ struct rtw_ieee80211_hdr_qos {
 }  __packed;
 
 struct rtw_ieee80211_hdr_3addr_qos {
-       u16 frame_ctl;
-       u16 duration_id;
+       __le16 frame_ctl;
+       __le16 duration_id;
        u8 addr1[ETH_ALEN];
        u8 addr2[ETH_ALEN];
        u8 addr3[ETH_ALEN];
index 4787bacdcad892da62bf66c05cadb851e090e09d..eaa4bc1b2255b136731e4dcda62e86f196206885 100644 (file)
@@ -283,8 +283,6 @@ struct odm_rate_adapt {
 
 /*  Declare for common info */
 
-#define MAX_PATH_NUM_92CS      2
-
 struct odm_phy_status_info {
        u8      RxPWDBAll;
        u8      SignalQuality;   /*  in 0-100 index. */
@@ -950,7 +948,7 @@ struct odm_dm_struct {
        struct timer_list FastAntTrainingTimer;
 };             /*  DM_Dynamic_Mechanism_Structure */
 
-#define ODM_RF_PATH_MAX 2
+#define ODM_RF_PATH_MAX 3
 
 enum ODM_RF_RADIO_PATH {
        ODM_RF_PATH_A = 0,   /* Radio Path A */
index 63779f5b2a3c142f992593eb1f91ccfb93c4e348..df5272221bad976bbb133b991eddb440749d883c 100644 (file)
@@ -69,7 +69,7 @@ struct phy_rx_agc_info {
 };
 
 struct phy_status_rpt {
-       struct phy_rx_agc_info path_agc[2];
+       struct phy_rx_agc_info path_agc[3];
        u8      ch_corr[2];
        u8      cck_sig_qual_ofdm_pwdb_all;
        u8      cck_agc_rpt_ofdm_cfosho_a;
@@ -79,7 +79,7 @@ struct phy_status_rpt {
        u8      path_cfotail[2];
        u8      pcts_mask[2];
        s8      stream_rxevm[2];
-       u8      path_rxsnr[2];
+       u8      path_rxsnr[3];
        u8      noise_power_db_lsb;
        u8      rsvd_2[3];
        u8      stream_csi[2];
index a9ba6df26b9dc1bbda9211c3e52b389f634af0af..622f4c1418b4759453a73a6c2affbcd03d414b31 100644 (file)
@@ -27,7 +27,7 @@
 /*     Define the debug levels */
 /*  */
 /*     1. DBG_TRACE and DBG_LOUD are used for normal cases. */
-/*     They can help SW engineer to develope or trace states changed */
+/*     They can help SW engineer to develop or trace states changed */
 /*     and also help HW enginner to trace every operation to and from HW, */
 /*     e.g IO, Tx, Rx. */
 /*  */
index 520cbbaac35f8639c3fe8f67e52bcfc3ac8c5870..d1d95f4b87a8208aaf5c3aeaf4eecf32c700f492 100644 (file)
 #include <drv_types.h>
 #include <hal_intf.h>
 
-/* 2 Hardware Parameter Files */
-
-#include "Hal8188EFWImg_CE.h"
-
-
 /* 2 OutSrc Header Files */
 
 #include "odm.h"
index 819285b9a78145eb746660b64d1216cdff82283a..8cafd7adfdcd9dea545c959ce4f40ae67da25f57 100644 (file)
@@ -745,7 +745,7 @@ struct TDLSoption_param
 
 Result:
 0x00: success
-0x01: sucess, and check Response.
+0x01: success, and check Response.
 0x02: cmd ignored due to duplicated sequcne number
 0x03: cmd dropped due to invalid cmd code
 0x04: reserved.
index 2e618043d353ef88459695f59d39f7320b4e36ef..d0da4fd40d18415206876cfe6e179e6a0ef5e5c0 100644 (file)
@@ -163,14 +163,14 @@ enum LED_STRATEGY_871x {
 void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE      LedAction);
 
 struct led_priv{
-       /* add for led controll */
+       /* add for led control */
        struct LED_871x                 SwLed0;
        struct LED_871x                 SwLed1;
        enum LED_STRATEGY_871x  LedStrategy;
        u8      bRegUseLed;
        void (*LedControlHandler)(struct adapter *padapter,
                                  enum LED_CTL_MODE LedAction);
-       /* add for led controll */
+       /* add for led control */
 };
 
 #define rtw_led_control(adapt, action) \
index 22538e61695a12dd0e6ed34dac3e6480f38c13a3..4a7143e0eed0e64f484905b15142654ad3443778 100644 (file)
 #define        WIFI_SITE_MONITOR               0x00000800      /* to indicate the station is under site surveying */
 
 #define        WIFI_MP_STATE                   0x00010000
-#define        WIFI_MP_CTX_BACKGROUND          0x00020000      /*  in continous tx background */
-#define        WIFI_MP_CTX_ST                  0x00040000      /*  in continous tx with single-tone */
-#define        WIFI_MP_CTX_BACKGROUND_PENDING  0x00080000      /*  pending in continous tx background due to out of skb */
-#define        WIFI_MP_CTX_CCK_HW              0x00100000      /*  in continous tx */
-#define        WIFI_MP_CTX_CCK_CS              0x00200000      /*  in continous tx with carrier suppression */
+#define        WIFI_MP_CTX_BACKGROUND          0x00020000      /*  in continuous tx background */
+#define        WIFI_MP_CTX_ST                  0x00040000      /*  in continuous tx with single-tone */
+#define        WIFI_MP_CTX_BACKGROUND_PENDING  0x00080000      /*  pending in continuous tx background due to out of skb */
+#define        WIFI_MP_CTX_CCK_HW              0x00100000      /*  in continuous tx */
+#define        WIFI_MP_CTX_CCK_CS              0x00200000      /*  in continuous tx with carrier suppression */
 #define WIFI_MP_LPBK_STATE             0x00400000
 
 #define _FW_UNDER_LINKING      WIFI_UNDER_LINKING
@@ -239,7 +239,7 @@ struct wifidirect_info {
        u8 profileindex; /* Used to point to the index of profileinfo array */
        u8 peer_operating_ch;
        u8 find_phase_state_exchange_cnt;
-       /* The device password ID for group negotation */
+       /* The device password ID for group negotiation */
        u16 device_password_id_for_nego;
        u8 negotiation_dialog_token;
        /* SSID information for group negotitation */
index 853ab80a2b860a0a95bfab8d85ba064ca4eef982..b1bfa2e30fdbf7c38268a8d8d001940478c30e50 100644 (file)
@@ -107,7 +107,7 @@ extern unsigned char WMM_PARA_OUI[];
 /*  Note: */
 /*     We just add new channel plan when the new channel plan is different
  *      from any of the following channel plan. */
-/*     If you just wnat to customize the acitions(scan period or join actions)
+/*     If you just want to customize the actions(scan period or join actions)
  *      about one of the channel plan, */
 /*     customize them in struct rt_channel_info in the RT_CHANNEL_LIST. */
 enum RT_CHANNEL_DOMAIN {
index 3ad22076de3fc3085bb87d2186b8aa9094496eaf..30fd17f23bf14a326b0138ce8c7b74bae3f8f6df 100644 (file)
@@ -56,7 +56,7 @@
 /*  2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */
 /*  3. RF register 0x00-2E */
 /*  4. Bit Mask for BB/RF register */
-/*  5. Other defintion for BB/RF R/W */
+/*  5. Other definition for BB/RF R/W */
 /*  */
 
 
index bae8885c57f92c464e9a61b1f14db6b5b70a1b55..be9c30c574198afceab9d01365d743939efdba3a 100644 (file)
@@ -83,7 +83,7 @@ struct signal_stat {
        u32     total_num;              /* num of valid elements */
        u32     total_val;              /* sum of valid elements */
 };
-#define MAX_PATH_NUM_92CS              2
+#define MAX_PATH_NUM_92CS              3
 struct phy_info {
        u8      RxPWDBAll;
        u8      SignalQuality;   /*  in 0-100 index. */
index 089ecee6c1f9e82af842b8552c36a4310f409031..2df88370de59d84a917f9cf59114139b364796f6 100644 (file)
@@ -119,7 +119,7 @@ enum ht_channel_width {
 };
 
 /*  */
-/*  Represent Extention Channel Offset in HT Capabilities */
+/*  Represent Extension Channel Offset in HT Capabilities */
 /*  This is available only in 40Mhz mode. */
 /*  */
 enum ht_extchnl_offset {
index 3ed2a39741adb0c83a61c6a6244847b664e8c6ee..3e909db1d41a84deb8388e10e069aefaac99bfc5 100644 (file)
@@ -338,7 +338,7 @@ struct      sta_priv {
         */
        struct sta_info *sta_aid[NUM_STA];
 
-       u16 sta_dz_bitmap;/* only support 15 stations, staion aid bitmap
+       u16 sta_dz_bitmap;/* only support 15 stations, station aid bitmap
                           * for sleeping sta. */
        u16 tim_bitmap; /* only support 15 stations, aid=0~15 mapping
                         * bit0~bit15 */
index a615659f947171aafee25de62c90116ac27446cb..84e519974199cb3a9c2df3f0742364f185e54f49 100644 (file)
@@ -984,7 +984,7 @@ enum ht_cap_ampdu_factor {
 #define        P2P_PROVISION_TIMEOUT           5000
 /* 3 seconds timeout for sending the prov disc request concurrent mode */
 #define        P2P_CONCURRENT_PROVISION_TIME   3000
-/* 5 seconds timeout for receiving the group negotation response */
+/* 5 seconds timeout for receiving the group negotiation response */
 #define        P2P_GO_NEGO_TIMEOUT             5000
 /* 3 seconds timeout for sending the negotiation request under concurrent mode */
 #define        P2P_CONCURRENT_GO_NEGO_TIME     3000
index 95953ebc027922e66ffd3168a965dee33f6a30be..ae545877023428b103df7af913ca9e10753ed939 100644 (file)
@@ -938,7 +938,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
        memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
        if (pPMK->cmd == IW_PMKSA_ADD) {
                DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
-               if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == true)
+               if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
                        return ret;
                else
                        ret = true;
@@ -1039,7 +1039,7 @@ static int rtw_wx_get_range(struct net_device *dev,
 
        range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
        /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
-       range->avg_qual.level = 20 + -98;
+       range->avg_qual.level = 178; /* -78 dBm */
        range->avg_qual.noise = 0;
        range->avg_qual.updated = 7; /* Updated all three */
 
@@ -1074,7 +1074,7 @@ static int rtw_wx_get_range(struct net_device *dev,
 
 /*  The following code will proivde the security capability to network manager. */
 /*  If the driver doesn't provide this capability to network manager, */
-/*  the WPA/WPA2 routers can't be choosen in the network manager. */
+/*  the WPA/WPA2 routers can't be chosen in the network manager. */
 
 /*
 #define IW_SCAN_CAPA_NONE              0x00
@@ -1373,7 +1373,7 @@ _func_enter_;
                                }
                        }
 
-                       /* it has still some scan paramater to parse, we only do this now... */
+                       /* it has still some scan parameter to parse, we only do this now... */
                        _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
                } else {
                        _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
@@ -2626,7 +2626,7 @@ static int rtw_get_ap_info(struct net_device *dev,
                        return -EINVAL;
                }
 
-               if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == true) {
+               if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
                        /* BSSID match, then check if supporting wpa/wpa2 */
                        DBG_88E("BSSID:%pM\n", (bssid));
 
@@ -2961,7 +2961,7 @@ static int rtw_p2p_get_status(struct net_device *dev,
 
 /*     Commented by Albert 20110520 */
 /*     This function will return the config method description */
-/*     This config method description will show us which config method the remote P2P device is intented to use */
+/*     This config method description will show us which config method the remote P2P device is intended to use */
 /*     by sending the provisioning discovery request frame. */
 
 static int rtw_p2p_get_req_cm(struct net_device *dev,
@@ -3413,7 +3413,7 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
        /*  +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */
 
        /*      Commented by Ouden 20121226 */
-       /*      The application wants to know P2P initation procedure is support or not. */
+       /*      The application wants to know P2P initiation procedure is supported or not. */
        /*      Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */
 
        DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
@@ -4040,7 +4040,7 @@ static int rtw_rereg_nd_name(struct net_device *dev,
        if (0 != ret)
                goto exit;
 
-       if (!memcmp(rereg_priv->old_ifname, "disable%d", 9) == true) {
+       if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
                padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
                rtw_hal_sw_led_init(padapter);
                rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
@@ -4049,7 +4049,7 @@ static int rtw_rereg_nd_name(struct net_device *dev,
        strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
        rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
 
-       if (!memcmp(new_ifname, "disable%d", 9) == true) {
+       if (!memcmp(new_ifname, "disable%d", 9)) {
                DBG_88E("%s disable\n", __func__);
                /*  free network queue for Android's timming issue */
                rtw_free_network_queue(padapter, true);
@@ -4884,7 +4884,6 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
        case _TKIP_:
        case _TKIP_WTMIC_:
        case _AES_:
-               keylen = 16;
        default:
                keylen = 16;
        }
@@ -6146,7 +6145,7 @@ static int rtw_mp_efuse_set(struct net_device *dev,
 
                for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
                        setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
-               /* Change to check TYPE_EFUSE_MAP_LEN, beacuse 8188E raw 256, logic map over 256. */
+               /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
                EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
                if ((addr+cnts) > max_available_size) {
                        DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
@@ -6221,7 +6220,7 @@ static int rtw_mp_efuse_set(struct net_device *dev,
 
                for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
                        setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
-               /* Change to check TYPE_EFUSE_MAP_LEN, beacuse 8188E raw 256, logic map over 256. */
+               /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
                EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
                if ((addr+cnts) > max_available_size) {
                        DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
index 63bc913eba6d8a44f83601c8bd385aab6046aba3..17659bb04befc24fabded5439be74aba9fdcb5d1 100644 (file)
@@ -85,7 +85,7 @@ static int rtw_uapsd_acvi_en;
 static int rtw_uapsd_acvo_en;
 
 int rtw_ht_enable = 1;
-int rtw_cbw40_enable = 3; /*  0 :diable, bit(0): enable 2.4g, bit(1): enable 5g */
+int rtw_cbw40_enable = 3; /*  0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */
 int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
 static int rtw_rx_stbc = 1;/*  0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
 static int rtw_ampdu_amsdu;/*  0: disabled, 1:enabled, 2:auto */
@@ -707,6 +707,10 @@ int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname)
        return 0;
 }
 
+static const struct device_type wlan_type = {
+       .name = "wlan",
+};
+
 struct net_device *rtw_init_netdev(struct adapter *old_padapter)
 {
        struct adapter *padapter;
@@ -722,6 +726,7 @@ struct net_device *rtw_init_netdev(struct adapter *old_padapter)
        if (!pnetdev)
                return NULL;
 
+       pnetdev->dev.type = &wlan_type;
        padapter = rtw_netdev_priv(pnetdev);
        padapter->pnetdev = pnetdev;
        DBG_88E("register rtw_netdev_ops to netdev_ops\n");
index 4e0bfb7e153b811b75227b9d864b96d49f48676c..5a9e9e4558aa6b60398a00faeb787bafa225e670 100644 (file)
@@ -627,13 +627,14 @@ RETURN:
 int rtw_change_ifname(struct adapter *padapter, const char *ifname)
 {
        struct net_device *pnetdev;
-       struct net_device *cur_pnetdev = padapter->pnetdev;
+       struct net_device *cur_pnetdev;
        struct rereg_nd_name_data *rereg_priv;
        int ret;
 
        if (!padapter)
                goto error;
 
+       cur_pnetdev = padapter->pnetdev;
        rereg_priv = &padapter->rereg_nd_name_priv;
 
        /* free the old_pnetdev */
@@ -794,7 +795,7 @@ void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
 }
 
 /**
- * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
+ * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
  * @size: size of pointer
  *
  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
index e2f4e7d7717041621acfc29299d81cfe56ee66b5..3852ff43810ddde4944f7f615ba44e503652097f 100644 (file)
@@ -77,8 +77,7 @@ int rtw_os_recvbuf_resource_alloc(struct adapter *padapter,
 int rtw_os_recvbuf_resource_free(struct adapter *padapter,
                                 struct recv_buf *precvbuf)
 {
-       if (precvbuf->purb)
-               usb_free_urb(precvbuf->purb);
+       usb_free_urb(precvbuf->purb);
        return _SUCCESS;
 }
 
@@ -224,8 +223,7 @@ _func_exit_;
 _recv_indicatepkt_drop:
 
         /* enqueue back to free_recv_queue */
-       if (precv_frame)
-               rtw_free_recvframe(precv_frame, pfree_recv_queue);
+       rtw_free_recvframe(precv_frame, pfree_recv_queue);
 
 _func_exit_;
         return _FAIL;
index 9ca3180ebaa0e70fbb188c84748971fd4f34922d..7d14779310d370f7a70b35b56a00ef261bd671af 100644 (file)
@@ -737,7 +737,7 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
        status = _SUCCESS;
 
 free_hal_data:
-       if (status != _SUCCESS && padapter->HalData)
+       if (status != _SUCCESS)
                kfree(padapter->HalData);
 handle_dualmac:
        if (status != _SUCCESS)
index f7b14f8b7b8382d4beafb99cc49f28579dae86f4..1260f10944ef07a5c1707f63c74047f8fe9b9687 100644 (file)
@@ -151,7 +151,7 @@ void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
                        MaxChnlNum = pTriple->FirstChnl + j;
                }
 
-               pTriple = (struct chnl_txpow_triple *)((u8*)pTriple + 3);
+               pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3);
        }
 
        UPDATE_CIE_SRC(dev, pTaddr);
index 71f4549a378f636019dbac24493adb7b1521c4d0..fb7683fa5ffd93d3bcaee6741e7e6a79bae5828a 100644 (file)
@@ -38,7 +38,7 @@ enum dot11d_state {
 /**
  * struct rt_dot11d_info * @CountryIeLen: value greater than 0 if @CountryIeBuf contains
  *               valid country information element.
- * @chanell_map: holds channel values
+ * @channel_map: holds channel values
  *             0 - invalid,
  *             1 - valid (active scan),
  *             2 - valid (passive scan)
index 0da56c80f08839f3b8e88623e850a616281a9b23..5af1c19142de6f462cf039c070e3849277988110 100644 (file)
@@ -140,7 +140,7 @@ bool phy_RF8256_Config_ParaFile(struct net_device *dev)
 
                rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF,
                                                (enum rf90_radio_path)eRFPath);
-               if (rtStatus != true) {
+               if (!rtStatus) {
                        RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check "
                                 "Radio[%d] Fail!!\n", eRFPath);
                        goto phy_RF8256_Config_ParaFile_Fail;
@@ -245,7 +245,7 @@ void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8     powerlevel)
        struct r8192_priv *priv = rtllib_priv(dev);
 
        TxAGC = powerlevel;
-       if (priv->bDynamicTxLowPower == true) {
+       if (priv->bDynamicTxLowPower) {
                if (priv->CustomerID == RT_CID_819x_Netcore)
                        TxAGC = 0x22;
                else
@@ -294,7 +294,7 @@ void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel)
                        priv->Pwr_Track = writeVal_tmp;
                }
 
-               if (priv->bDynamicTxHighPower == true)
+               if (priv->bDynamicTxHighPower)
                        writeVal = 0x03030303;
                else
                        writeVal = (byte3 << 24) | (byte2 << 16) |
index 74fbd70d583886f3696b8968c77f8b0bdec683ac..2cace9a4525aac87d44f6ce5b838aff929097e53 100644 (file)
@@ -720,7 +720,7 @@ start:
        }
        priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
 
-       if (priv->RegRfOff == true)
+       if (priv->RegRfOff)
                priv->rtllib->eRFPowerState = eRfOff;
 
        ulRegRead = read_nic_dword(dev, CPU_GEN);
@@ -745,7 +745,7 @@ start:
        }
        RT_TRACE(COMP_INIT, "BB Config Start!\n");
        rtStatus = rtl8192_BBConfig(dev);
-       if (rtStatus != true) {
+       if (!rtStatus) {
                RT_TRACE(COMP_ERR, "BB Config failed\n");
                return rtStatus;
        }
@@ -856,7 +856,7 @@ start:
        if (priv->ResetProgress == RESET_TYPE_NORESET) {
                RT_TRACE(COMP_INIT, "RF Config Started!\n");
                rtStatus = rtl8192_phy_RFConfig(dev);
-               if (rtStatus != true) {
+               if (!rtStatus) {
                        RT_TRACE(COMP_ERR, "RF Config failed\n");
                        return rtStatus;
                }
@@ -869,7 +869,7 @@ start:
 
        write_nic_byte(dev, 0x87, 0x0);
 
-       if (priv->RegRfOff == true) {
+       if (priv->RegRfOff) {
                RT_TRACE((COMP_INIT | COMP_RF | COMP_POWER),
                          "%s(): Turn off RF for RegRfOff ----------\n",
                          __func__);
@@ -1184,7 +1184,7 @@ void  rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc,
                                                cb_desc);
 
        if (pci_dma_mapping_error(priv->pdev, mapping))
-               RT_TRACE(COMP_ERR, "DMA Mapping error\n");;
+               RT_TRACE(COMP_ERR, "DMA Mapping error\n");
        if (cb_desc->bAMPDUEnable) {
                pTxFwInfo->AllowAggregation = 1;
                pTxFwInfo->RxMF = cb_desc->ampdu_factor;
@@ -1283,7 +1283,7 @@ void  rtl8192_tx_fill_cmd_desc(struct net_device *dev,
                         PCI_DMA_TODEVICE);
 
        if (pci_dma_mapping_error(priv->pdev, mapping))
-               RT_TRACE(COMP_ERR, "DMA Mapping error\n");;
+               RT_TRACE(COMP_ERR, "DMA Mapping error\n");
        memset(entry, 0, 12);
        entry->LINIP = cb_desc->bLastIniPkt;
        entry->FirstSeg = 1;
@@ -1866,15 +1866,15 @@ static void rtl8192_TranslateRxSignalStuff(struct net_device *dev,
        type = WLAN_FC_GET_TYPE(fc);
        praddr = hdr->addr1;
 
-       bpacket_match_bssid = ((RTLLIB_FTYPE_CTL != type) &&
-                       (!compare_ether_addr(priv->rtllib->
-                       current_network.bssid,
-                          (fc & RTLLIB_FCTL_TODS) ? hdr->addr1 :
-                          (fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
-               && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
-       bpacket_toself =  bpacket_match_bssid &&        /* check this */
-                         (!compare_ether_addr(praddr,
-                         priv->rtllib->dev->dev_addr));
+       bpacket_match_bssid =
+               ((RTLLIB_FTYPE_CTL != type) &&
+                ether_addr_equal(priv->rtllib->current_network.bssid,
+                                 (fc & RTLLIB_FCTL_TODS) ? hdr->addr1 :
+                                 (fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 :
+                                 hdr->addr3) &&
+                (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
+       bpacket_toself = bpacket_match_bssid &&         /* check this */
+                        ether_addr_equal(praddr, priv->rtllib->dev->dev_addr);
        if (WLAN_FC_GET_FRAMETYPE(fc) == RTLLIB_STYPE_BEACON)
                bPacketBeacon = true;
        if (bpacket_match_bssid)
@@ -2213,7 +2213,7 @@ rtl8192_InitializeVariables(struct net_device  *dev)
        priv->MidHighPwrTHR_L2 = 0x40;
        priv->PwrDomainProtect = false;
 
-       priv->bfirst_after_down = 0;
+       priv->bfirst_after_down = false;
 }
 
 void rtl8192_EnableInterrupt(struct net_device *dev)
index dd2a96bfcc0c00126d0b2bab5e6e797859f8dcbe..abcd22f8fdda576e55854869b3e93e9731639825 100644 (file)
@@ -329,7 +329,7 @@ bool init_firmware(struct net_device *dev)
                }
 
                rt_status = fw_download_code(dev, mapped_file, file_length);
-               if (rt_status != true) {
+               if (!rt_status) {
                        goto download_firmware_fail;
                }
 
index 9676c591c8597574413bd4463d79263b0a63447d..21e6ddde68a2bb4ac389184d3eae7b7628874c65 100644 (file)
@@ -567,7 +567,7 @@ static bool rtl8192_BB_Config_ParaFile(struct net_device *dev)
                rtStatus  = rtl8192_phy_checkBBAndRF(dev,
                                         (enum hw90_block)eCheckItem,
                                         (enum rf90_radio_path)0);
-               if (rtStatus != true) {
+               if (!rtStatus) {
                        RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():"
                                 "Check PHY%d Fail!!\n", eCheckItem-1);
                        return rtStatus;
@@ -1425,7 +1425,7 @@ static bool SetRFPowerState8190(struct net_device *dev,
        u8      i = 0, QueueID = 0;
        struct rtl8192_tx_ring  *ring = NULL;
 
-       if (priv->SetRFPowerStateInProgress == true)
+       if (priv->SetRFPowerStateInProgress)
                return false;
        RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n");
        priv->SetRFPowerStateInProgress = true;
@@ -1443,10 +1443,9 @@ static bool SetRFPowerState8190(struct net_device *dev,
                                        InitilizeCount--;
                                        priv->RegRfOff = false;
                                        rtstatus = NicIFEnableNIC(dev);
-                               } while ((rtstatus != true) &&
-                                        (InitilizeCount > 0));
+                               } while (!rtstatus && (InitilizeCount > 0));
 
-                               if (rtstatus != true) {
+                               if (!rtstatus) {
                                        RT_TRACE(COMP_ERR, "%s():Initialize Ada"
                                                 "pter fail,return\n",
                                                 __func__);
index e0684435555197a395cebe98e29e5fda9f104bef..d93caca9657d2ea8bf50c633425128802649b5e7 100644 (file)
@@ -370,8 +370,7 @@ bool MgntActSet_RF_State(struct net_device *dev,
        case eRfOn:
                priv->rtllib->RfOffReason &= (~ChangeSource);
 
-               if ((ChangeSource == RF_CHANGE_BY_HW) &&
-                   (priv->bHwRadioOff == true))
+               if ((ChangeSource == RF_CHANGE_BY_HW) && priv->bHwRadioOff)
                        priv->bHwRadioOff = false;
 
                if (!priv->rtllib->RfOffReason) {
@@ -405,8 +404,7 @@ bool MgntActSet_RF_State(struct net_device *dev,
                                                      disas_lv_ss);
                        }
                }
-               if ((ChangeSource == RF_CHANGE_BY_HW) &&
-                    (priv->bHwRadioOff == false))
+               if ((ChangeSource == RF_CHANGE_BY_HW) && !priv->bHwRadioOff)
                        priv->bHwRadioOff = true;
                priv->rtllib->RfOffReason |= ChangeSource;
                bActionAllowed = true;
@@ -428,7 +426,7 @@ bool MgntActSet_RF_State(struct net_device *dev,
                PHY_SetRFPowerState(dev, StateToSet);
                if (StateToSet == eRfOn) {
 
-                       if (bConnectBySSID && (priv->blinked_ingpio == true)) {
+                       if (bConnectBySSID && priv->blinked_ingpio) {
                                queue_delayed_work_rsl(ieee->wq,
                                         &ieee->associate_procedure_wq, 0);
                                priv->blinked_ingpio = false;
@@ -955,7 +953,7 @@ static int _rtl8192_sta_up(struct net_device *dev, bool is_silent_reset)
        RT_TRACE(COMP_INIT, "Bringing up iface");
        priv->bfirst_init = true;
        init_status = priv->ops->initialize_adapter(dev);
-       if (init_status != true) {
+       if (!init_status) {
                RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n",
                         __func__);
                priv->bfirst_init = false;
@@ -1000,7 +998,7 @@ static int rtl8192_sta_down(struct net_device *dev, bool shutdownrf)
        priv->bDriverIsGoingToUnload = true;
        priv->up = 0;
        priv->rtllib->ieee_up = 0;
-       priv->bfirst_after_down = 1;
+       priv->bfirst_after_down = true;
        RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__);
        if (!netif_queue_stopped(dev))
                netif_stop_queue(dev);
@@ -1119,8 +1117,8 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
        priv->rtllib->hwscan_sem_up = 1;
        priv->rtllib->status = 0;
        priv->H2CTxCmdSeq = 0;
-       priv->bDisableFrameBursting = 0;
-       priv->bDMInitialGainEnable = 1;
+       priv->bDisableFrameBursting = false;
+       priv->bDMInitialGainEnable = true;
        priv->polling_timer_on = 0;
        priv->up_first_time = 1;
        priv->blinked_ingpio = false;
@@ -1162,7 +1160,7 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
        priv->CckPwEnl = 6;
        priv->ScanDelay = 50;
        priv->ResetProgress = RESET_TYPE_NORESET;
-       priv->bForcedSilentReset = 0;
+       priv->bForcedSilentReset = false;
        priv->bDisableNormalResetCheck = false;
        priv->force_reset = false;
        memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
@@ -1171,7 +1169,7 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
        priv->RxCounter = 0;
        priv->rtllib->wx_set_enc = 0;
        priv->bHwRadioOff = false;
-       priv->RegRfOff = 0;
+       priv->RegRfOff = false;
        priv->isRFOff = false;
        priv->bInPowerSaveMode = false;
        priv->rtllib->RfOffReason = 0;
@@ -1647,7 +1645,7 @@ void      rtl819x_watchdog_wqcallback(void *data)
        bool    bHigherBusyRxTraffic = false;
        bool bEnterPS = false;
 
-       if (IS_NIC_DOWN(priv) || (priv->bHwRadioOff == true))
+       if (IS_NIC_DOWN(priv) || priv->bHwRadioOff)
                return;
 
        if (priv->rtllib->state >= RTLLIB_LINKED) {
@@ -1888,9 +1886,8 @@ void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
        memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
        skb_push(skb, priv->rtllib->tx_headroom);
        ret = rtl8192_tx(dev, skb);
-       if (ret != 0) {
+       if (ret != 0)
                kfree_skb(skb);
-       };
 
        if (queue_index != MGNT_QUEUE) {
                priv->rtllib->stats.tx_bytes += (skb->len -
@@ -1898,7 +1895,6 @@ void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
                priv->rtllib->stats.tx_packets++;
        }
 
-
        return;
 }
 
@@ -1930,15 +1926,11 @@ int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                tcb_desc->bTxEnableFwCalcDur = 1;
                skb_push(skb, priv->rtllib->tx_headroom);
                ret = rtl8192_tx(dev, skb);
-               if (ret != 0) {
+               if (ret != 0)
                        kfree_skb(skb);
-               };
        }
 
-
-
        return ret;
-
 }
 
 static void rtl8192_tx_isr(struct net_device *dev, int prio)
@@ -2601,14 +2593,9 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                        goto out;
                }
 
-               ipw = kmalloc(p->length, GFP_KERNEL);
-               if (ipw == NULL) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               if (copy_from_user(ipw, p->pointer, p->length)) {
-                       kfree(ipw);
-                       ret = -EFAULT;
+               ipw = memdup_user(p->pointer, p->length);
+               if (IS_ERR(ipw)) {
+                       ret = PTR_ERR(ipw);
                        goto out;
                }
 
@@ -2982,7 +2969,6 @@ err_rel_rtllib:
        free_rtllib(dev);
 
        DMESG("wlan driver load failed\n");
-       pci_set_drvdata(pdev, NULL);
 err_pci_disable:
        pci_disable_device(pdev);
        return err;
@@ -3052,7 +3038,7 @@ bool NicIFEnableNIC(struct net_device *dev)
        RT_TRACE(COMP_PS, "===========>%s()\n", __func__);
        priv->bfirst_init = true;
        init_status = priv->ops->initialize_adapter(dev);
-       if (init_status != true) {
+       if (!init_status) {
                RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n",
                         __func__);
                priv->bdisable_nic = false;
index 1853665764a019d9777a615e3ae10d7683ec9c5d..2297fc20fd4e25ccfa999641554c1ad5ccfc9b61 100644 (file)
@@ -535,7 +535,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                                }
                        }
 
-                       if (viviflag == true) {
+                       if (viviflag) {
                                write_nic_byte(dev, Pw_Track_Flag, 0);
                                viviflag = false;
                                RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
@@ -2265,7 +2265,7 @@ void dm_CheckRfCtrlGPIO(void *data)
                return;
 
        if (priv->bfirst_after_down) {
-               priv->bfirst_after_down = 1;
+               priv->bfirst_after_down = true;
                return;
        }
 
@@ -2273,12 +2273,12 @@ void dm_CheckRfCtrlGPIO(void *data)
 
        eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
 
-       if ((priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)) {
+       if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
                RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
                printk(KERN_INFO "gpiochangeRF  - HW Radio ON\n");
                priv->bHwRadioOff = false;
                bActuallySet = true;
-       } else if ((priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)) {
+       } else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) {
                RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
                printk(KERN_INFO "gpiochangeRF  - HW Radio OFF\n");
                priv->bHwRadioOff = true;
@@ -2289,7 +2289,7 @@ void dm_CheckRfCtrlGPIO(void *data)
                mdelay(1000);
                priv->bHwRfOffAction = 1;
                MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, true);
-               if (priv->bHwRadioOff == true)
+               if (priv->bHwRadioOff)
                        argv[1] = "RFOFF";
                else
                        argv[1] = "RFON";
@@ -2312,9 +2312,9 @@ void      dm_rf_pathcheck_workitemcallback(void *data)
 
        for (i = 0; i < RF90_PATH_MAX; i++) {
                if (rfpath & (0x01<<i))
-                       priv->brfpath_rxenable[i] = 1;
+                       priv->brfpath_rxenable[i] = true;
                else
-                       priv->brfpath_rxenable[i] = 0;
+                       priv->brfpath_rxenable[i] = false;
        }
        if (!DM_RxPathSelTable.Enable)
                return;
@@ -2946,8 +2946,7 @@ static void dm_dynamic_txpower(struct net_device *dev)
                        priv->bDynamicTxLowPower = false;
                } else {
                        if (priv->undecorated_smoothed_pwdb <
-                           txlowpower_threshold &&
-                           priv->bDynamicTxHighPower == true)
+                           txlowpower_threshold && priv->bDynamicTxHighPower)
                                priv->bDynamicTxHighPower = false;
                        if (priv->undecorated_smoothed_pwdb < 35)
                                priv->bDynamicTxLowPower = true;
index 658e875232aa7948f56146770c9b848b6b70420b..29608e5488a44dd6c45346a76d169f9b2d4cddb1 100644 (file)
@@ -264,7 +264,7 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
                psearch_list = &ieee->Rx_TS_Admit_List;
 
        for (dir = 0; dir <= DIR_BI_DIR; dir++) {
-               if (search_dir[dir] == false)
+               if (!search_dir[dir])
                        continue;
                list_for_each_entry(pRet, psearch_list, List) {
                        if (memcmp(pRet->Addr, Addr, 6) == 0)
@@ -348,7 +348,7 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
        if (*ppTS != NULL) {
                return true;
        } else {
-               if (bAddNewTs == false) {
+               if (!bAddNewTs) {
                        RTLLIB_DEBUG(RTLLIB_DL_TS, "add new TS failed"
                                     "(tid:%d)\n", UP);
                        return false;
index 8aeaed5a987d62468022124db2b2deeff92c9afd..1a011b9b9da61840789103ef5c9dd4631806a202 100644 (file)
@@ -873,11 +873,11 @@ static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee,
                if (net_ratelimit())
                        printk(KERN_INFO "%s: find HTCControl!\n", __func__);
                hdrlen += 4;
-               rx_stats->bContainHTC = 1;
+               rx_stats->bContainHTC = true;
        }
 
         if (RTLLIB_QOS_HAS_SEQ(fc))
-               rx_stats->bIsQosData = 1;
+               rx_stats->bIsQosData = true;
 
        return hdrlen;
 }
@@ -957,16 +957,15 @@ static void rtllib_rx_extract_addr(struct rtllib_device *ieee,
 static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc,
                                 u8 *dst, u8 *src, u8 *bssid, u8 *addr2)
 {
-       u8 zero_addr[ETH_ALEN] = {0};
        u8 type, stype;
 
        type = WLAN_FC_GET_TYPE(fc);
        stype = WLAN_FC_GET_STYPE(fc);
 
        /* Filter frames from different BSS */
-       if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS)
-               && (compare_ether_addr(ieee->current_network.bssid, bssid) != 0)
-               && memcmp(ieee->current_network.bssid, zero_addr, ETH_ALEN)) {
+       if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS) &&
+           !ether_addr_equal(ieee->current_network.bssid, bssid) &&
+           !is_zero_ether_addr(ieee->current_network.bssid)) {
                return -1;
        }
 
@@ -974,8 +973,8 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc,
        if (ieee->IntelPromiscuousModeInfo.bPromiscuousOn  &&
                ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame) {
                if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) &&
-                       (compare_ether_addr(dst, ieee->current_network.bssid) != 0) &&
-                       (compare_ether_addr(bssid, ieee->current_network.bssid) == 0)) {
+                   !ether_addr_equal(dst, ieee->current_network.bssid) &&
+                   ether_addr_equal(bssid, ieee->current_network.bssid)) {
                        return -1;
                }
        }
@@ -1275,7 +1274,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb,
        /*Filter pkt not to me*/
        multicast = is_multicast_ether_addr(hdr->addr1);
        unicast = !multicast;
-       if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) {
+       if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1)) {
                if (ieee->bNetPromiscuousMode)
                        bToOtherSTA = true;
                else
@@ -1730,7 +1729,7 @@ static inline void rtllib_extract_country_ie(
                        network->CountryIeLen = info_element->len;
 
                        if (!IS_COUNTRY_IE_VALID(ieee)) {
-                               if ((rtllib_act_scanning(ieee, false) == true) && (ieee->FirstIe_InScan == 1))
+                               if (rtllib_act_scanning(ieee, false) && ieee->FirstIe_InScan)
                                        printk(KERN_INFO "Received beacon ContryIE, SSID: <%s>\n", network->ssid);
                                Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
                        }
index 0cbf6f5593a394d99ed58b6a95e7df88cfbe1625..933bd6deaca123035dd271dfd0ddf67bbc290e57 100644 (file)
@@ -604,7 +604,7 @@ static void rtllib_softmac_scan_wq(void *data)
 
        if (!ieee->ieee_up)
                return;
-       if (rtllib_act_scanning(ieee, true) == true)
+       if (rtllib_act_scanning(ieee, true))
                return;
 
        down(&ieee->scan_sem);
@@ -705,7 +705,7 @@ static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
        ieee->scan_watch_dog = 0;
        if (ieee->scanning_continue == 1) {
                ieee->scanning_continue = 0;
-               ieee->actscanning = 0;
+               ieee->actscanning = false;
 
                cancel_delayed_work(&ieee->softmac_scan_wq);
        }
@@ -1202,7 +1202,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon,
 
        if ((ieee->rtllib_ap_sec_type &&
            (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) ||
-           (ieee->bForcedBgMode == true)) {
+           ieee->bForcedBgMode) {
                ieee->pHTInfo->bEnableHT = 0;
                ieee->mode = WIRELESS_MODE_G;
        }
@@ -1535,7 +1535,7 @@ static void rtllib_associate_complete_wq(void *data)
        struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
                                        (&(ieee->PowerSaveControl));
        printk(KERN_INFO "Associated successfully\n");
-       if (ieee->is_silent_reset == 0) {
+       if (!ieee->is_silent_reset) {
                printk(KERN_INFO "normal associate\n");
                notify_wx_assoc_event(ieee);
        }
@@ -1572,9 +1572,9 @@ static void rtllib_associate_complete_wq(void *data)
        pPSC->LpsIdleCount = 0;
        ieee->link_change(ieee->dev);
 
-       if (ieee->is_silent_reset == 1) {
+       if (ieee->is_silent_reset) {
                printk(KERN_INFO "silent reset associate\n");
-               ieee->is_silent_reset = 0;
+               ieee->is_silent_reset = false;
        }
 
        if (ieee->data_hard_resume)
@@ -2005,7 +2005,7 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time)
                return 0;
 
        if (time) {
-               if (ieee->bAwakePktSent == true) {
+               if (ieee->bAwakePktSent) {
                        pPSC->LPSAwakeIntvl = 1;
                } else {
                        u8              MaxPeriod = 1;
@@ -2338,8 +2338,7 @@ inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
                                        }
 
                                        if (ieee->current_network.mode ==
-                                           IEEE_N_24G &&
-                                           bHalfSupportNmode == true) {
+                                           IEEE_N_24G && bHalfSupportNmode) {
                                                printk(KERN_INFO "======>enter "
                                                       "half N mode\n");
                                                ieee->bHalfWirelessN24GMode =
@@ -3098,7 +3097,7 @@ void rtllib_softmac_init(struct rtllib_device *ieee)
        ieee->sta_edca_param[2] = 0x005E4342;
        ieee->sta_edca_param[3] = 0x002F3262;
        ieee->aggregation = true;
-       ieee->enable_rx_imm_BA = 1;
+       ieee->enable_rx_imm_BA = true;
        ieee->tx_pending.txb = NULL;
 
        _setup_timer(&ieee->associate_timer,
@@ -3591,14 +3590,9 @@ int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, struct iw_point *p,
                goto out;
        }
 
-       param = kmalloc(p->length, GFP_KERNEL);
-       if (param == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       if (copy_from_user(param, p->pointer, p->length)) {
-               kfree(param);
-               ret = -EFAULT;
+       param = memdup_user(p->pointer, p->length);
+       if (IS_ERR(param)) {
+               ret = PTR_ERR(param);
                goto out;
        }
 
index 1cc6a9d5e8a3da3e42c520a76411a8217c25fb37..3183627823fb58fb3def9fb89090f98281732ec4 100644 (file)
@@ -908,7 +908,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
                                tcb_desc->data_rate = CURRENT_RATE(ieee->mode,
                                        ieee->rate, ieee->HTCurrentOperaRate);
 
-                       if (bdhcp == true) {
+                       if (bdhcp) {
                                if (ieee->pHTInfo->IOTAction &
                                    HT_IOT_ACT_WA_IOT_Broadcom) {
                                        tcb_desc->data_rate =
index c7e8d4d8ec2b8fc2b8e766f7c776237dee130b94..13af43b90fc00de2ecf473500590c94d1899c9e7 100644 (file)
@@ -753,7 +753,7 @@ int rtllib_wx_set_mlme(struct rtllib_device *ieee,
                /* leave break out intentionly */
 
        case IW_MLME_DISASSOC:
-               if (deauth == true)
+               if (deauth)
                        printk(KERN_INFO "disauth packet !\n");
                else
                        printk(KERN_INFO "dis associate packet!\n");
diff --git a/drivers/staging/rtl8192u/dot11d.h b/drivers/staging/rtl8192u/dot11d.h
deleted file mode 100644 (file)
index 92e7a00..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211/ieee80211.h"
-
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
-       u8 FirstChnl;
-       u8  NumChnls;
-       u8  MaxTxPowerInDbm;
-} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
-       DOT11D_STATE_NONE = 0,
-       DOT11D_STATE_LEARNED,
-       DOT11D_STATE_DONE,
-} DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
-       /* DECLARE_RT_OBJECT(RT_DOT11D_INFO); */
-
-       bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
-
-       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  CountryIeWatchdog;
-
-       u8  channel_map[MAX_CHANNEL_NUMBER+1];  /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
-       u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
-       DOT11D_STATE State;
-} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a, b)                (((a)[0] == (b)[0] && \
-       (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && \
-       (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
-#define cpMacAddr(des, src)          ((des)[0] = (src)[0], \
-       (des)[1] = (src)[1], (des)[2] = (src)[2], \
-       (des)[3] = (src)[3], (des)[4] = (src)[4], \
-       (des)[5] = (src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled)
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
-       (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
-       FALSE : \
-       (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#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
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
-
-#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
-);
-#endif /* #ifndef __INC_DOT11D_H */
index 6aa8c15eba39a09d98e4c963af2dcbfd05dc4b73..bd75e29adc2c41bfccb211e40130c64ae65185a4 100644 (file)
@@ -4,42 +4,43 @@
 #include "ieee80211.h"
 
 
-//#define DOT11D_MAX_CHNL_NUM 83
-
 typedef struct _CHNL_TXPOWER_TRIPLE {
        u8 FirstChnl;
        u8  NumChnls;
        u8  MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
 
 typedef enum _DOT11D_STATE {
        DOT11D_STATE_NONE = 0,
        DOT11D_STATE_LEARNED,
        DOT11D_STATE_DONE,
-}DOT11D_STATE;
+} DOT11D_STATE;
 
 typedef struct _RT_DOT11D_INFO {
-       //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+       /* DECLARE_RT_OBJECT(RT_DOT11D_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  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
 
        DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b)         ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src)           ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a, b)                (((a)[0] == (b)[0] && \
+       (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && \
+       (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
+#define cpMacAddr(des, src)          ((des)[0] = (src)[0], \
+       (des)[1] = (src)[1], (des)[2] = (src)[2], \
+       (des)[3] = (src)[3], (des)[4] = (src)[4], \
+       (des)[5] = (src)[5])
 #define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
 
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled)
 #define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
 
 #define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
@@ -51,9 +52,9 @@ typedef struct _RT_DOT11D_INFO {
        (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
 
 #define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog)
 #define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
 
 #define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
 
@@ -72,7 +73,7 @@ void
 Dot11d_UpdateCountryIe(
        struct ieee80211_device *dev,
        u8 *pTaddr,
-       u16     CoutryIeLen,
+       u16 CoutryIeLen,
        u8 *pCoutryIe
        );
 
@@ -96,4 +97,4 @@ int ToLegalChannel(
        struct ieee80211_device *dev,
        u8 channel
 );
-#endif // #ifndef __INC_DOT11D_H
+#endif /* #ifndef __INC_DOT11D_H */
index 434c431271834f9e28a36e19108392c5ffaa65ae..4b036a8db5a18ca14bc66ad8215e412f1ef68dd0 100644 (file)
@@ -241,7 +241,7 @@ static int debug = \
                            //IEEE80211_DL_DATA |
                            IEEE80211_DL_ERR      //awayls open this flags to show error out
                            ;
-struct proc_dir_entry *ieee80211_proc;
+static struct proc_dir_entry *ieee80211_proc;
 
 static int show_debug_level(struct seq_file *m, void *v)
 {
index 59900bfa1c18f250edbbefb732c5828760e888e3..e730ed64c0fe3775d4567cdd01036d72d0bb8fdf 100644 (file)
@@ -2166,7 +2166,8 @@ static inline u8 ieee80211_SignalStrengthTranslate(
        return RetSS;
 }
 
-long ieee80211_translate_todbm(u8 signal_strength_index        )// 0-100 index.
+/* 0-100 index */
+static long ieee80211_translate_todbm(u8 signal_strength_index)
 {
        long    signal_power; // in dBm.
 
index 5fd696926ee3c2afeb83e81ccfa545df81a3e574..662c7e41cd5cec78a9ade7c7ae1703c7db01c262 100644 (file)
@@ -3150,14 +3150,9 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin
                goto out;
        }
 
-       param = kmalloc(p->length, GFP_KERNEL);
-       if (param == NULL){
-               ret = -ENOMEM;
-               goto out;
-       }
-       if (copy_from_user(param, p->pointer, p->length)) {
-               kfree(param);
-               ret = -EFAULT;
+       param = memdup_user(p->pointer, p->length);
+       if (IS_ERR(param)) {
+               ret = PTR_ERR(param);
                goto out;
        }
 
index a7bcc64ff2263684717ce87c39980522a37854a9..157b2d7466e5f606f107442ab44ca0c9647d4a1d 100644 (file)
@@ -237,8 +237,8 @@ void ieee80211_txb_free(struct ieee80211_txb *txb) {
        kfree(txb);
 }
 
-struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
-                                         int gfp_mask)
+static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+                                                gfp_t gfp_mask)
 {
        struct ieee80211_txb *txb;
        int i;
@@ -303,7 +303,8 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 }
 
 #define SN_LESS(a, b)          (((a-b)&0x800)!=0)
-void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, struct sk_buff *skb, cb_desc *tcb_desc)
+static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee,
+                                      struct sk_buff *skb, cb_desc *tcb_desc)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
        PTX_TS_RECORD                   pTxTs = NULL;
@@ -412,7 +413,8 @@ ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
                tcb_desc->bUseShortGI = true;
 }
 
-void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee,
+                                         cb_desc *tcb_desc)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 
@@ -432,7 +434,9 @@ void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, cb_desc *tcb_d
        return;
 }
 
-void ieee80211_query_protectionmode(struct ieee80211_device *ieee, cb_desc *tcb_desc, struct sk_buff *skb)
+static void ieee80211_query_protectionmode(struct ieee80211_device *ieee,
+                                          cb_desc *tcb_desc,
+                                          struct sk_buff *skb)
 {
        // Common Settings
        tcb_desc->bRTSSTBC                      = false;
@@ -543,7 +547,8 @@ NO_PROTECTION:
 }
 
 
-void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee,
+                                       cb_desc *tcb_desc)
 {
 #ifdef TO_DO_LIST
        if(!IsDataFrame(pFrame))
@@ -573,7 +578,8 @@ void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, cb_desc *tcb_des
        }
 }
 
-void ieee80211_query_seqnum(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *dst)
+static void ieee80211_query_seqnum(struct ieee80211_device *ieee,
+                                  struct sk_buff *skb, u8 *dst)
 {
        if (is_multicast_ether_addr(dst))
                return;
index db0db9347487db1b1ca16e26f46d2bf305eaf728..3684da340bd48d32633fcb1d7a6dd14b4155390f 100644 (file)
@@ -251,7 +251,8 @@ static struct sk_buff *ieee80211_DELBA(
  *  output:  none
  *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
 ********************************************************************************************************************/
-void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD        pBA)
+static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee,
+                                   u8 *dst, PBA_RECORD pBA)
 {
        struct sk_buff *skb = NULL;
        skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
@@ -278,7 +279,8 @@ void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD
  *  output:  none
  *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
 ********************************************************************************************************************/
-void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD pBA, u16 StatusCode)
+static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst,
+                                   PBA_RECORD pBA, u16 StatusCode)
 {
        struct sk_buff *skb = NULL;
        skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
diff --git a/drivers/staging/rtl8192u/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211_crypt.h
deleted file mode 100644 (file)
index 0b4ea43..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- * 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 README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
-       const char *name;
-
-       /* init new crypto context (e.g., allocate private data space,
-        * select IV, etc.); returns NULL on failure or pointer to allocated
-        * private data on success */
-       void * (*init)(int keyidx);
-
-       /* deinitialize crypto context and free allocated private data */
-       void (*deinit)(void *priv);
-
-       /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
-        * value from decrypt_mpdu is passed as the keyidx value for
-        * decrypt_msdu. skb must have enough head and tail room for the
-        * encryption; if not, error will be returned; these functions are
-        * called for all MPDUs (i.e., fragments).
-        */
-       int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-       int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
-       /* These functions are called for full MSDUs, i.e. full frames.
-        * These can be NULL if full MSDU operations are not needed. */
-       int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-       int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-                           void *priv);
-
-       int (*set_key)(void *key, int len, u8 *seq, void *priv);
-       int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
-       /* procfs handler for printing out key information and possible
-        * statistics */
-       char * (*print_stats)(char *p, void *priv);
-
-       /* maximum number of bytes added by encryption; encrypt buf is
-        * allocated with extra_prefix_len bytes, copy of in_buf, and
-        * extra_postfix_len; encrypt need not use all this space, but
-        * the result must start at the beginning of the buffer and correct
-        * length must be returned */
-       int extra_prefix_len, extra_postfix_len;
-
-       struct module *owner;
-};
-
-struct ieee80211_crypt_data {
-       struct list_head list; /* delayed deletion list */
-       struct ieee80211_crypto_ops *ops;
-       void *priv;
-       atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
-                                   struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8192u/r8180_pm.c b/drivers/staging/rtl8192u/r8180_pm.c
deleted file mode 100644 (file)
index 999968d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-   Power management interface routines.
-   Written by Mariusz Matuszek.
-   This code is currently just a placeholder for later work and
-   does not do anything useful.
-
-   This is part of rtl8180 OpenSource driver.
-   Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
-   Released under the terms of GPL (General Public Licence)
-*/
-
-#ifdef CONFIG_RTL8180_PM
-
-
-#include "r8180_hw.h"
-#include "r8180_pm.h"
-
-int rtl8180_save_state (struct pci_dev *dev, u32 state)
-{
-       printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
-       return(-EAGAIN);
-}
-
-
-int rtl8180_suspend (struct pci_dev *dev, u32 state)
-{
-       printk(KERN_NOTICE "r8180 suspend call (state %u).\n", state);
-       return(-EAGAIN);
-}
-
-
-int rtl8180_resume (struct pci_dev *dev)
-{
-       printk(KERN_NOTICE "r8180 resume call.\n");
-       return(-EAGAIN);
-}
-
-
-int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
-{
-       printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
-              state, enable);
-       return(-EAGAIN);
-}
-
-
-
-#endif //CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8192u/r8180_pm.h b/drivers/staging/rtl8192u/r8180_pm.h
deleted file mode 100644 (file)
index 4be63da..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-       Power management interface routines.
-       Written by Mariusz Matuszek.
-       This code is currently just a placeholder for later work and
-       does not do anything useful.
-
-       This is part of rtl8180 OpenSource driver.
-       Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
-       Released under the terms of GPL (General Public Licence)
-
-*/
-
-#ifdef CONFIG_RTL8180_PM
-
-#ifndef R8180_PM_H
-#define R8180_PM_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-int rtl8180_save_state (struct pci_dev *dev, u32 state);
-int rtl8180_suspend (struct pci_dev *dev, u32 state);
-int rtl8180_resume (struct pci_dev *dev);
-int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
-
-#endif //R8180_PM_H
-
-#endif // CONFIG_RTL8180_PM
index 592e7807fa4288edc63cbd14076c62e663df161d..fa6dd37d85e6680d76aaa5909f9f9040d7930d7a 100644 (file)
 #ifndef RTL8225H
 #define RTL8225H
 
-#ifdef RTL8190P
-#define RTL819X_TOTAL_RF_PATH 4 //for 90P
-#else
 #define RTL819X_TOTAL_RF_PATH 2 //for 8192U
-#endif
 extern void PHY_SetRF8256Bandwidth(struct net_device *dev , HT_CHANNEL_WIDTH Bandwidth);
 extern void PHY_RF8256_Config(struct net_device *dev);
 extern void phy_RF8256_Config_ParaFile(struct net_device *dev);
index b484ee128c13fd1227f686a2bee544c8a54f192a..ad3bc567d35a18ac0dbe2cd0026085b37db67f05 100644 (file)
@@ -409,15 +409,11 @@ typedef struct rx_drvinfo_819x_usb {
 #define        USB_HWDESC_HEADER_LEN           sizeof(tx_desc_819x_usb)
 #define TX_PACKET_SHIFT_BYTES          (USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
 #define MAX_FRAGMENT_COUNT             8
-#ifdef RTL8192U
 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
 #define MAX_TRANSMIT_BUFFER_SIZE                       32000
 #else
 #define MAX_TRANSMIT_BUFFER_SIZE                       8000
 #endif
-#else
-#define MAX_TRANSMIT_BUFFER_SIZE       (1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT)
-#endif
 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
 #define TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES (sizeof(tx_desc_819x_usb_aggr_subframe) + sizeof(tx_fwinfo_819x_usb))
 #endif
@@ -1158,14 +1154,6 @@ typedef enum {
        NIC_8192E = 3,
 } nic_t;
 
-
-#ifdef JOHN_HWSEC
-struct ssid_thread {
-       struct net_device *dev;
-       u8 name[IW_ESSID_MAX_SIZE + 1];
-};
-#endif
-
 bool init_firmware(struct net_device *dev);
 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192_tx(struct net_device *dev, struct sk_buff *skb);
index cd0946db025c3c51fd7d98ae46f88f0675606b5c..c2bcbe230ed324171846df82e7883f3412c93401 100644 (file)
@@ -392,7 +392,7 @@ int read_nic_word(struct net_device *dev, int indx, u16 *data)
        return 0;
 }
 
-int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
+static int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
 {
        int status;
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -585,7 +585,7 @@ static int proc_get_stats_rx(struct seq_file *m, void *v)
        return 0;
 }
 
-void rtl8192_proc_module_init(void)
+static void rtl8192_proc_module_init(void)
 {
        RT_TRACE(COMP_INIT, "Initializing proc filesystem");
        rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
@@ -631,7 +631,7 @@ static const struct rtl8192_proc_file rtl8192_proc_files[] = {
        { "" }
 };
 
-void rtl8192_proc_init_one(struct net_device *dev)
+static void rtl8192_proc_init_one(struct net_device *dev)
 {
        const struct rtl8192_proc_file *f;
        struct proc_dir_entry *dir;
@@ -656,7 +656,7 @@ void rtl8192_proc_init_one(struct net_device *dev)
        }
 }
 
-void rtl8192_proc_remove_one(struct net_device *dev)
+static void rtl8192_proc_remove_one(struct net_device *dev)
 {
        remove_proc_subtree(dev->name, rtl8192_proc);
 }
@@ -755,7 +755,7 @@ void rtl8192_set_chan(struct net_device *dev, short ch)
 
 static void rtl8192_rx_isr(struct urb *urb);
 
-u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
+static u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
 {
 
 #ifdef USB_RX_AGGREGATION_SUPPORT
@@ -998,8 +998,8 @@ static void rtl8192_rx_isr(struct urb *urb)
                netdev_err(dev, "can not submit rxurb, err is %x, URB status is %x\n", err, urb->status);
 }
 
-u32 rtl819xusb_rx_command_packet(struct net_device *dev,
-                                struct ieee80211_rx_stats *pstats)
+static u32 rtl819xusb_rx_command_packet(struct net_device *dev,
+                                       struct ieee80211_rx_stats *pstats)
 {
        u32     status;
 
@@ -1608,13 +1608,6 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
        idx_pipe = txqueue2outpipe(priv, queue_index);
 #else
        idx_pipe = 0x04;
-#endif
-#ifdef JOHN_DUMP_TXDESC
-       int i;
-       printk("<Tx descriptor>--rate %x---", rate);
-       for (i = 0; i < 8; i++)
-               printk("%8x ", tx[i]);
-       printk("\n");
 #endif
        usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe),
                          skb->data, skb->len, rtl8192_tx_isr, skb);
@@ -1636,7 +1629,7 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
  *
  * \param QUEUEID       Software Queue
 */
-u8 MapHwQueueToFirmwareQueue(u8 QueueID)
+static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
 {
        u8 QueueSelect = 0x0;       //defualt set to
 
@@ -1723,7 +1716,7 @@ u8 MRateToHwRate8190Pci(u8 rate)
 }
 
 
-u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
+static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
 {
        u8   tmp_Short;
 
@@ -1934,7 +1927,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
        }
 }
 
-short rtl8192_usb_initendpoints(struct net_device *dev)
+static short rtl8192_usb_initendpoints(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
 
@@ -1992,7 +1985,7 @@ short rtl8192_usb_initendpoints(struct net_device *dev)
 
 }
 #ifdef THOMAS_BEACON
-void rtl8192_usb_deleteendpoints(struct net_device *dev)
+static void rtl8192_usb_deleteendpoints(struct net_device *dev)
 {
        int i;
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -2009,7 +2002,7 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev)
        priv->oldaddr = NULL;
        if (priv->pp_rxskb) {
                kfree(priv->pp_rxskb);
-               priv->pp_rxskb = 0;
+               priv->pp_rxskb = NULL;
        }
 }
 #else
@@ -2292,7 +2285,7 @@ void rtl8192_update_ratr_table(struct net_device *dev)
 
 static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
-bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
+static bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee80211;
@@ -3167,7 +3160,7 @@ static struct net_device_stats *rtl8192_stats(struct net_device *dev)
        return &priv->ieee80211->stats;
 }
 
-bool HalTxCheckStuck819xUsb(struct net_device *dev)
+static bool HalTxCheckStuck819xUsb(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        u16             RegTxCounter;
@@ -3217,7 +3210,7 @@ RESET_TYPE TxCheckStuck(struct net_device *dev)
        return RESET_TYPE_NORESET;
 }
 
-bool HalRxCheckStuck819xUsb(struct net_device *dev)
+static bool HalRxCheckStuck819xUsb(struct net_device *dev)
 {
        u16     RegRxCounter;
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -3259,7 +3252,7 @@ bool HalRxCheckStuck819xUsb(struct net_device *dev)
        return bStuck;
 }
 
-RESET_TYPE RxCheckStuck(struct net_device *dev)
+static RESET_TYPE RxCheckStuck(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        bool        bRxCheck = FALSE;
@@ -3796,14 +3789,9 @@ int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                goto out;
        }
 
-       ipw = kmalloc(p->length, GFP_KERNEL);
-       if (ipw == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       if (copy_from_user(ipw, p->pointer, p->length)) {
-               kfree(ipw);
-               ret = -EFAULT;
+       ipw = memdup_user(p->pointer, p->length);
+       if (IS_ERR(ipw)) {
+               ret = PTR_ERR(ipw);
                goto out;
        }
 
@@ -3859,15 +3847,6 @@ int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                                }
                        }
                }
-#ifdef JOHN_HWSEC_DEBUG
-               //john's test 0711
-               printk("@@ wrq->u pointer = ");
-               for (i = 0; i < wrq->u.data.length; i++) {
-                       if (i%10 == 0) printk("\n");
-                       printk("%8x|", ((u32 *)wrq->u.data.pointer)[i]);
-               }
-               printk("\n");
-#endif /*JOHN_HWSEC_DEBUG*/
                ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
                break;
 
@@ -3952,7 +3931,8 @@ u8 HwRateToMRate90(bool bIsHT, u8 rate)
  * Return:
  *               None
  */
-void UpdateRxPktTimeStamp8190(struct net_device *dev, struct ieee80211_rx_stats *stats)
+static void UpdateRxPktTimeStamp8190(struct net_device *dev,
+                                    struct ieee80211_rx_stats *stats)
 {
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 
@@ -4209,7 +4189,7 @@ static u8 rtl819x_evm_dbtopercentage(char value)
 //     We want good-looking for signal strength/quality
 //     2007/7/19 01:09, by cosa.
 //
-long rtl819x_signal_scale_mapping(long currsig)
+static long rtl819x_signal_scale_mapping(long currsig)
 {
        long retsig;
 
@@ -4478,9 +4458,9 @@ void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats,
 }
 
 
-void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
-                                  struct ieee80211_rx_stats *pstats,
-                                  rx_drvinfo_819x_usb  *pdrvinfo)
+static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
+                                         struct ieee80211_rx_stats *pstats,
+                                         rx_drvinfo_819x_usb  *pdrvinfo)
 {
        // TODO: We must only check packet for current MAC address. Not finish
        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
@@ -4549,8 +4529,9 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
 * Return:
 *              None
 */
-void UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
-                                              struct ieee80211_rx_stats *stats)
+static void
+UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
+                                         struct ieee80211_rx_stats *stats)
 {
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
        u32 rcvType = 1;   //0: Total, 1:OK, 2:CRC, 3:ICV
@@ -4614,7 +4595,9 @@ void UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
 }
 
 
-void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
+static void query_rxdesc_status(struct sk_buff *skb,
+                               struct ieee80211_rx_stats *stats,
+                               bool bIsRxAggrSubframe)
 {
        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
        struct net_device *dev = info->dev;
@@ -4930,7 +4913,8 @@ void rtl819xusb_process_received_packet(struct net_device *dev,
 
 }
 
-void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
+static void query_rx_cmdpkt_desc_status(struct sk_buff *skb,
+                                       struct ieee80211_rx_stats *stats)
 {
        rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
 
index a6e4c37d9c78e2d2fc305e1fd0e7862ca9d07c78..41fb67b7337d876985d9e25dcc50f73949f8cf8f 100644 (file)
@@ -100,14 +100,6 @@ static     void    dm_check_txpower_tracking(struct net_device *dev);
 //static       void    dm_txpower_reset_recovery(struct net_device *dev);
 
 
-// DM --> BB init gain restore
-#ifndef RTL8192U
-static void    dm_bb_initialgain_restore(struct net_device *dev);
-
-
-// DM --> BB init gain backup
-static void    dm_bb_initialgain_backup(struct net_device *dev);
-#endif
 // DM --> Dynamic Init Gain by RSSI
 static void    dm_dig_init(struct net_device *dev);
 static void    dm_ctrl_initgain_byrssi(struct net_device *dev);
@@ -122,12 +114,7 @@ static     void dm_init_ctstoself(struct net_device *dev);
 // DM --> EDCA turbo mode control
 static void    dm_check_edca_turbo(struct net_device *dev);
 
-// DM --> HW RF control
-static void    dm_check_rfctrl_gpio(struct net_device *dev);
-
-#ifndef RTL8190P
 //static       void    dm_gpio_change_rf(struct net_device *dev);
-#endif
 // DM --> Check PBC
 static void dm_check_pbc_gpio(struct net_device *dev);
 
@@ -269,7 +256,6 @@ extern  void    hal_dm_watchdog(struct net_device *dev)
        dm_ctrl_initgain_byrssi(dev);
        dm_check_edca_turbo(dev);
        dm_bandwidth_autoswitch(dev);
-       dm_check_rfctrl_gpio(dev);
        dm_check_rx_path_selection(dev);
        dm_check_fsync(dev);
 
@@ -620,16 +606,11 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
        tx_cmd.Op               = TXCMD_SET_TX_PWR_TRACKING;
        tx_cmd.Length   = 4;
        tx_cmd.Value            = Value;
-#ifdef RTL8192U
        rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
        if (rtStatus == RT_STATUS_FAILURE)
        {
                RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
        }
-#else
-       cmpk_message_handle_tx(dev, (u8 *)&tx_cmd,
-                                                               DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
-#endif
        mdelay(1);
        //DbgPrint("hi, vivi, strange\n");
        for(i = 0;i <= 30; i++)
@@ -641,11 +622,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                        mdelay(1);
                        continue;
                }
-#ifdef RTL8190P
-               read_nic_word(dev, 0x1bc, &Avg_TSSI_Meas);
-#else
                read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
-#endif
                if(Avg_TSSI_Meas == 0)
                {
                        write_nic_byte(dev, 0x1ba, 0);
@@ -654,14 +631,10 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
 
                for(k = 0;k < 5; k++)
                {
-#ifdef RTL8190P
-                       read_nic_byte(dev, 0x1d8+k, &tmp_report[k]);
-#else
                        if(k !=4)
                                read_nic_byte(dev, 0x134+k, &tmp_report[k]);
                        else
                                read_nic_byte(dev, 0x13e, &tmp_report[k]);
-#endif
                        RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
                }
 
@@ -708,10 +681,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                        RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-#ifdef RTL8190P
-                       RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
-                       RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
-#endif
                        RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
                        RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
                        return;
@@ -720,11 +689,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                {
                        if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
                        {
-                               if((priv->rfa_txpowertrackingindex > 0)
-#ifdef RTL8190P
-                                       &&(priv->rfc_txpowertrackingindex > 0)
-#endif
-                               )
+                               if (priv->rfa_txpowertrackingindex > 0)
                                {
                                        priv->rfa_txpowertrackingindex--;
                                        if(priv->rfa_txpowertrackingindex_real > 4)
@@ -732,33 +697,16 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                                                priv->rfa_txpowertrackingindex_real--;
                                                rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
                                        }
-#ifdef RTL8190P
-                                       priv->rfc_txpowertrackingindex--;
-                                       if(priv->rfc_txpowertrackingindex_real > 4)
-                                       {
-                                               priv->rfc_txpowertrackingindex_real--;
-                                               rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
-                                       }
-#endif
                                }
                        }
                        else
                        {
-                               if((priv->rfa_txpowertrackingindex < 36)
-#ifdef RTL8190P
-                                       &&(priv->rfc_txpowertrackingindex < 36)
-#endif
-                                       )
+                               if (priv->rfa_txpowertrackingindex < 36)
                                {
                                        priv->rfa_txpowertrackingindex++;
                                        priv->rfa_txpowertrackingindex_real++;
                                        rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
 
-#ifdef RTL8190P
-                                       priv->rfc_txpowertrackingindex++;
-                                       priv->rfc_txpowertrackingindex_real++;
-                                       rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
-#endif
                                }
                        }
                        priv->cck_present_attentuation_difference
@@ -788,10 +736,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                        }
                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-#ifdef RTL8190P
-               RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
-               RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
-#endif
                RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
                RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
 
@@ -937,14 +881,10 @@ extern    void    dm_txpower_trackingcallback(struct work_struct *work)
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
        struct net_device *dev = priv->ieee80211->dev;
 
-#ifdef RTL8190P
-       dm_TXPowerTrackingCallback_TSSI(dev);
-#else
        if(priv->bDcut == TRUE)
                dm_TXPowerTrackingCallback_TSSI(dev);
        else
                dm_TXPowerTrackingCallback_ThermalMeter(dev);
-#endif
 }
 
 
@@ -1472,14 +1412,10 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
 void dm_initialize_txpower_tracking(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef RTL8190P
-       dm_InitializeTXPowerTracking_TSSI(dev);
-#else
        if(priv->bDcut == TRUE)
                dm_InitializeTXPowerTracking_TSSI(dev);
        else
                dm_InitializeTXPowerTracking_ThermalMeter(dev);
-#endif
 }// dm_InitializeTXPowerTracking
 
 
@@ -1677,14 +1613,10 @@ extern void dm_cck_txpower_adjust(
 {      // dm_CCKTxPowerAdjust
 
        struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef RTL8190P
-       dm_CCKTxPowerAdjust_TSSI(dev, binch14);
-#else
        if(priv->bDcut == TRUE)
                dm_CCKTxPowerAdjust_TSSI(dev, binch14);
        else
                dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
-#endif
 }
 
 
@@ -2194,11 +2126,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
                {
                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
-                       #else
-                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
-                       #endif
+                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
                        */
@@ -2265,11 +2193,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
                {
                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-                       #else
-                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
-                       #endif
+                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
                        /*
                        else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
@@ -2342,11 +2266,7 @@ static void dm_ctrl_initgain_byrssi_highpwr(
                // 3.1 Higher PD_TH for OFDM for high power state.
                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
                {
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
-                       #else
-                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
-                       #endif
+                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
 
                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
@@ -2370,11 +2290,7 @@ static void dm_ctrl_initgain_byrssi_highpwr(
                        // 3.2 Recover PD_TH for OFDM for normal power region.
                        if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
                        {
-                               #ifdef RTL8190P
-                                       write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-                               #else
-                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
-                               #endif
+                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
                                /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
                                */
@@ -2516,11 +2432,7 @@ static void dm_pd_th(
                                {
                                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                                       #ifdef RTL8190P
-                                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
-                                       #else
-                                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
-                                       #endif
+                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
                                        */
@@ -2535,11 +2447,7 @@ static void dm_pd_th(
                                {
                                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                                       #ifdef RTL8190P
-                                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-                                       #else
-                                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
-                                       #endif
+                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
                                        */
@@ -2552,11 +2460,7 @@ static void dm_pd_th(
                                // Higher PD_TH for OFDM for high power state.
                                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
                                {
-                                       #ifdef RTL8190P
-                                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
-                                       #else
-                                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
-                                       #endif
+                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
                                        */
@@ -2823,44 +2727,6 @@ static void dm_ctstoself(struct net_device *dev)
        }
 }
 
-
-/*-----------------------------------------------------------------------------
- * Function:   dm_check_rfctrl_gpio()
- *
- * Overview:   Copy 8187B template for 9xseries.
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     05/28/2008      amy             Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_check_rfctrl_gpio(struct net_device *dev)
-{
-       //struct r8192_priv *priv = ieee80211_priv(dev);
-
-       // Work around for DTM test, we will not enable HW - radio on/off because r/w
-       // page 1 register before extra bus is enabled causing system failures when resuming
-       // from S4. 20080218, Emily
-
-       // Stop to execute workitem to prevent S3/S4 bug.
-#ifdef RTL8190P
-       return;
-#endif
-#ifdef RTL8192U
-       return;
-#endif
-#ifdef RTL8192E
-               queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
-#endif
-
-}      /* dm_CheckRfCtrlGPIO */
-
 /*-----------------------------------------------------------------------------
  * Function:   dm_check_pbc_gpio()
  *
@@ -2879,7 +2745,6 @@ static void dm_check_rfctrl_gpio(struct net_device *dev)
  *---------------------------------------------------------------------------*/
 static void    dm_check_pbc_gpio(struct net_device *dev)
 {
-#ifdef RTL8192U
        struct r8192_priv *priv = ieee80211_priv(dev);
        u8 tmp1byte;
 
@@ -2895,83 +2760,9 @@ static   void    dm_check_pbc_gpio(struct net_device *dev)
                RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
                priv->bpbc_pressed = true;
        }
-#endif
 
 }
 
-#ifdef RTL8192E
-
-/*-----------------------------------------------------------------------------
- * Function:   dm_GPIOChangeRF
- * Overview:   PCI will not support workitem call back HW radio on-off control.
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     02/21/2008      MHC             Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void    dm_gpio_change_rf_callback(struct work_struct *work)
-{
-       struct delayed_work *dwork = container_of(work,struct delayed_work,work);
-       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
-       struct net_device *dev = priv->ieee80211->dev;
-       u8 tmp1byte;
-       RT_RF_POWER_STATE       eRfPowerStateToSet;
-       bool bActuallySet = false;
-
-       do{
-               bActuallySet=false;
-
-               if(!priv->up)
-               {
-                       RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
-               }
-               else
-               {
-                       // 0x108 GPIO input register is read only
-                       //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
-                       read_nic_byte(dev, GPI, &tmp1byte);
-
-                       eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
-
-                       if((priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
-                       {
-                               RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
-
-                               priv->bHwRadioOff = false;
-                               bActuallySet = true;
-                       }
-                       else if ((priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
-                       {
-                               RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
-                               priv->bHwRadioOff = true;
-                               bActuallySet = true;
-                       }
-
-                       if(bActuallySet)
-                       {
-                               #ifdef TO_DO
-                               MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-                               //DrvIFIndicateCurrentPhyStatus(pAdapter);
-                               #endif
-                       }
-                       else
-                       {
-                               msleep(2000);
-                       }
-
-               }
-       }while(TRUE)
-
-}      /* dm_GPIOChangeRF */
-
-#endif
 /*-----------------------------------------------------------------------------
  * Function:   DM_RFPathCheckWorkItemCallBack()
  *
@@ -3329,11 +3120,7 @@ static void dm_init_fsync (struct net_device *dev)
        priv->ieee80211->fsync_time_interval = 500;
        priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
        priv->ieee80211->fsync_rssi_threshold = 30;
-#ifdef RTL8190P
-       priv->ieee80211->bfsync_enable = true;
-#else
        priv->ieee80211->bfsync_enable = false;
-#endif
        priv->ieee80211->fsync_multiple_timeinterval = 3;
        priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
        priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
@@ -3416,20 +3203,12 @@ extern void dm_fsync_timer_callback(unsigned long data)
                        priv->bswitch_fsync = !priv->bswitch_fsync;
                        if(priv->bswitch_fsync)
                        {
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, 0xC36, 0x00);
-                       #else
                                write_nic_byte(dev,0xC36, 0x1c);
-                       #endif
                                write_nic_byte(dev, 0xC3e, 0x90);
                        }
                        else
                        {
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, 0xC36, 0x40);
-                       #else
                                write_nic_byte(dev, 0xC36, 0x5c);
-                       #endif
                                write_nic_byte(dev, 0xC3e, 0x96);
                        }
                }
@@ -3438,11 +3217,7 @@ extern void dm_fsync_timer_callback(unsigned long data)
                        if(priv->bswitch_fsync)
                        {
                                priv->bswitch_fsync  = false;
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, 0xC36, 0x40);
-                       #else
                                write_nic_byte(dev, 0xC36, 0x5c);
-                       #endif
                                write_nic_byte(dev, 0xC3e, 0x96);
                        }
                }
@@ -3465,19 +3240,11 @@ extern void dm_fsync_timer_callback(unsigned long data)
                if(priv->bswitch_fsync)
                {
                        priv->bswitch_fsync  = false;
-               #ifdef RTL8190P
-                       write_nic_byte(dev, 0xC36, 0x40);
-               #else
                        write_nic_byte(dev, 0xC36, 0x5c);
-               #endif
                        write_nic_byte(dev, 0xC3e, 0x96);
                }
                priv->ContinueDiffCount = 0;
-       #ifdef RTL8190P
-               write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
-       #else
                write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
-       #endif
        }
        RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
        RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
@@ -3502,19 +3269,13 @@ static void dm_EndSWFsync(struct net_device *dev)
        {
                priv->bswitch_fsync  = false;
 
-               #ifdef RTL8190P
-                       write_nic_byte(dev, 0xC36, 0x40);
-               #else
-                       write_nic_byte(dev, 0xC36, 0x5c);
-               #endif
+               write_nic_byte(dev, 0xC36, 0x5c);
 
                write_nic_byte(dev, 0xC3e, 0x96);
        }
 
        priv->ContinueDiffCount = 0;
-#ifndef RTL8190P
        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
-#endif
 
 }
 
@@ -3553,9 +3314,7 @@ static void dm_StartSWFsync(struct net_device *dev)
        priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
        add_timer(&priv->fsync_timer);
 
-#ifndef RTL8190P
        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
-#endif
 
 }
 
@@ -3624,11 +3383,7 @@ void dm_check_fsync(struct net_device *dev)
                {
                        if(reg_c38_State != RegC38_Fsync_AP_BCM)
                        {       //For broadcom AP we write different default value
-                               #ifdef RTL8190P
-                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
-                               #else
-                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
-                               #endif
+                               write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
 
                                reg_c38_State = RegC38_Fsync_AP_BCM;
                        }
@@ -3659,11 +3414,7 @@ void dm_check_fsync(struct net_device *dev)
                                {
                                        if(reg_c38_State != RegC38_NonFsync_Other_AP)
                                        {
-                                               #ifdef RTL8190P
-                                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
-                                               #else
-                                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
-                                               #endif
+                                               write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
 
                                                reg_c38_State = RegC38_NonFsync_Other_AP;
                                        }
@@ -3845,10 +3596,8 @@ static void dm_dynamic_txpower(struct net_device *dev)
                SetTxPowerLevel8190(Adapter,pHalData->CurrentChannel);
 #endif
 
-#ifdef RTL8192U
                rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
                //pHalData->bStartTxCtrlByTPCNFR = FALSE;    //Clear th flag of Set TX Power from Sitesurvey
-#endif
        }
        priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
        priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
@@ -3885,9 +3634,6 @@ static void dm_send_rssi_tofw(struct net_device *dev)
        tx_cmd.Op               = TXCMD_SET_RX_RSSI;
        tx_cmd.Length   = 4;
        tx_cmd.Value            = priv->undecorated_smoothed_pwdb;
-
-       cmpk_message_handle_tx(dev, (u8 *)&tx_cmd,
-                                                               DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
 }
 
 /*---------------------------Define function prototype------------------------*/
index 61f6620213e2e99881f76835eb51ea3bc6709b15..c70af014a31670428b67205763be1f2a786f42a0 100644 (file)
@@ -127,156 +127,6 @@ static int r8192_wx_get_power(struct net_device *dev,
        return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
 }
 
-#ifdef JOHN_IOCTL
-u16 read_rtl8225(struct net_device *dev, u8 addr);
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-u32 john_read_rtl8225(struct net_device *dev, u8 adr);
-void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-
-static int r8192_wx_read_regs(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 addr;
-       u16 data1;
-
-       down(&priv->wx_sem);
-
-
-       get_user(addr,(u8 *)wrqu->data.pointer);
-       data1 = read_rtl8225(dev, addr);
-       wrqu->data.length = data1;
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-static int r8192_wx_write_regs(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 addr;
-
-       down(&priv->wx_sem);
-
-       get_user(addr, (u8 *)wrqu->data.pointer);
-       write_rtl8225(dev, addr, wrqu->data.length);
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
-
-static int r8192_wx_read_bb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 databb;
-
-       down(&priv->wx_sem);
-
-       databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
-       wrqu->data.length = databb;
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-static int r8192_wx_write_bb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 databb;
-
-       down(&priv->wx_sem);
-
-       get_user(databb, (u8 *)wrqu->data.pointer);
-       rtl8187_write_phy(dev, wrqu->data.length, databb);
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-
-static int r8192_wx_write_nicb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u32 addr;
-
-       down(&priv->wx_sem);
-
-       get_user(addr, (u32 *)wrqu->data.pointer);
-       write_nic_byte(dev, addr, wrqu->data.length);
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-static int r8192_wx_read_nicb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u32 addr;
-       u16 data1;
-
-       down(&priv->wx_sem);
-
-       get_user(addr,(u32 *)wrqu->data.pointer);
-       read_nic_byte(dev, addr, &data1);
-       wrqu->data.length = data1;
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-static int r8192_wx_get_ap_status(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee80211;
-       struct ieee80211_network *target;
-       int name_len;
-
-       down(&priv->wx_sem);
-
-       //count the length of input ssid
-       for(name_len=0 ; ((char *)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
-
-       //search for the corresponding info which is received
-       list_for_each_entry(target, &ieee->network_list, list) {
-               if ( (target->ssid_len == name_len) &&
-                    (strncmp(target->ssid, (char *)wrqu->data.pointer, name_len)==0)){
-                       if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
-                               //set flags=1 to indicate this ap is WPA
-                               wrqu->data.flags = 1;
-                       else wrqu->data.flags = 0;
-
-
-               break;
-               }
-       }
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-
-
-#endif
 static int r8192_wx_force_reset(struct net_device *dev,
                struct iw_request_info *info,
                union iwreq_data *wrqu, char *extra)
@@ -1106,46 +956,7 @@ static const struct iw_priv_args r8192_private_args[] = {
        {
                SIOCIWFIRSTPRIV + 0x2,
                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
-       }
-#ifdef JOHN_IOCTL
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x3,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x4,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x5,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x6,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x7,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x8,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x9,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
-       }
-
-#endif
-       ,
+       },
        {
                SIOCIWFIRSTPRIV + 0x3,
                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
@@ -1163,15 +974,6 @@ static iw_handler r8192_private_handler[] = {
 //     r8192_wx_set_monitor_type,
        r8192_wx_set_scan_type,
        r8192_wx_set_rawtx,
-#ifdef JOHN_IOCTL
-       r8192_wx_read_regs,
-       r8192_wx_write_regs,
-       r8192_wx_read_bb,
-       r8192_wx_write_bb,
-       r8192_wx_read_nicb,
-       r8192_wx_write_nicb,
-       r8192_wx_get_ap_status,
-#endif
        //r8192_wx_null,
        r8192_wx_force_reset,
 };
index 19a7bdd1973ad3bdc02c61657cb891362141dbec..2cbb8e6584f893fb6ab714a8ad57dd4ef356e7cb 100644 (file)
@@ -2,41 +2,36 @@
 #define _R819XU_HTTYPE_H_
 
 
-//------------------------------------------------------------
-// The HT Capability element is present in beacons, association request,
-//     reassociation request and probe response frames
-//------------------------------------------------------------
-
-//
-// Operation mode value
-//
+/*----------------------------------------------------------------------
+ * The HT Capability element is present in beacons, association request,
+ * reassociation request and probe response frames
+ *----------------------------------------------------------------------*/
+
+/* Operation mode value */
 #define HT_OPMODE_NO_PROTECT           0
 #define HT_OPMODE_OPTIONAL             1
-#define HT_OPMODE_40MHZ_PROTECT        2
+#define HT_OPMODE_40MHZ_PROTECT                2
 #define HT_OPMODE_MIXED                        3
 
-//
-// MIMO Power Save Settings
-//
-#define MIMO_PS_STATIC                         0
+/* MIMO Power Save Settings */
+#define MIMO_PS_STATIC                 0
 #define MIMO_PS_DYNAMIC                        1
 #define MIMO_PS_NOLIMIT                        3
 
 
-//
-//     There should be 128 bits to cover all of the MCS rates. However, since
-//     8190 does not support too much rates, one integer is quite enough.
-//
+/* There should be 128 bits to cover all of the MCS rates. However, since
+ * 8190 does not support too much rates, one integer is quite enough. */
 
-#define sHTCLng        4
+#define sHTCLng                                4
 
 
-#define HT_SUPPORTED_MCS_1SS_BITMAP                                    0x000000ff
-#define HT_SUPPORTED_MCS_2SS_BITMAP                                    0x0000ff00
-#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP                        HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+#define HT_SUPPORTED_MCS_1SS_BITMAP    0x000000ff
+#define HT_SUPPORTED_MCS_2SS_BITMAP    0x0000ff00
+#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP        \
+               (HT_MCS_1SS_BITMAP | HT_MCS_1SS_2SS_BITMAP)
 
 
-typedef enum _HT_MCS_RATE{
+typedef enum _HT_MCS_RATE {
        HT_MCS0   = 0x00000001,
        HT_MCS1   = 0x00000002,
        HT_MCS2   = 0x00000004,
@@ -47,71 +42,67 @@ typedef enum _HT_MCS_RATE{
        HT_MCS7   = 0x00000080,
        HT_MCS8   = 0x00000100,
        HT_MCS9   = 0x00000200,
-       HT_MCS10 = 0x00000400,
-       HT_MCS11 = 0x00000800,
-       HT_MCS12 = 0x00001000,
-       HT_MCS13 = 0x00002000,
-       HT_MCS14 = 0x00004000,
-       HT_MCS15 = 0x00008000,
-       // Do not define MCS32 here although 8190 support MCS32
-}HT_MCS_RATE,*PHT_MCS_RATE;
-
-//
-// Represent Channel Width in HT Capabilities
-//
-typedef enum _HT_CHANNEL_WIDTH{
-       HT_CHANNEL_WIDTH_20 = 0,
+       HT_MCS10  = 0x00000400,
+       HT_MCS11  = 0x00000800,
+       HT_MCS12  = 0x00001000,
+       HT_MCS13  = 0x00002000,
+       HT_MCS14  = 0x00004000,
+       HT_MCS15  = 0x00008000,
+       /* Do not define MCS32 here although 8190 support MCS32 */
+} HT_MCS_RATE, *PHT_MCS_RATE;
+
+/* Represent Channel Width in HT Capabilities */
+typedef enum _HT_CHANNEL_WIDTH {
+       HT_CHANNEL_WIDTH_20    = 0,
        HT_CHANNEL_WIDTH_20_40 = 1,
-}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
+} HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
 
-//
-// Represent Extension Channel Offset in HT Capabilities
-// This is available only in 40Mhz mode.
-//
-typedef enum _HT_EXTCHNL_OFFSET{
+/* Represent Extension Channel Offset in HT Capabilities
+ * This is available only in 40Mhz mode. */
+typedef enum _HT_EXTCHNL_OFFSET {
        HT_EXTCHNL_OFFSET_NO_EXT = 0,
-       HT_EXTCHNL_OFFSET_UPPER = 1,
+       HT_EXTCHNL_OFFSET_UPPER  = 1,
        HT_EXTCHNL_OFFSET_NO_DEF = 2,
-       HT_EXTCHNL_OFFSET_LOWER = 3,
-}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
-
-typedef enum _CHNLOP{
-       CHNLOP_NONE = 0, // No Action now
-       CHNLOP_SCAN = 1, // Scan in progress
-       CHNLOP_SWBW = 2, // Bandwidth switching in progress
-       CHNLOP_SWCHNL = 3, // Software Channel switching in progress
+       HT_EXTCHNL_OFFSET_LOWER  = 3,
+} HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
+
+typedef enum _CHNLOP {
+       CHNLOP_NONE   = 0,      /* No Action now */
+       CHNLOP_SCAN   = 1,      /* Scan in progress */
+       CHNLOP_SWBW   = 2,      /* Bandwidth switching in progress */
+       CHNLOP_SWCHNL = 3,      /* Software Channel switching in progress */
 } CHNLOP, *PCHNLOP;
 
-// Determine if the Channel Operation is in progress
+/* Determine if the Channel Operation is in progress */
 #define CHHLOP_IN_PROGRESS(_pHTInfo)   \
-               ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
+               (((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE)
 
 
-typedef enum _HT_ACTION{
+typedef enum _HT_ACTION {
        ACT_RECOMMAND_WIDTH             = 0,
        ACT_MIMO_PWR_SAVE               = 1,
-       ACT_PSMP                                        = 2,
+       ACT_PSMP                        = 2,
        ACT_SET_PCO_PHASE               = 3,
-       ACT_MIMO_CHL_MEASURE    = 4,
-       ACT_RECIPROCITY_CORRECT = 5,
+       ACT_MIMO_CHL_MEASURE            = 4,
+       ACT_RECIPROCITY_CORRECT         = 5,
        ACT_MIMO_CSI_MATRICS            = 6,
-       ACT_MIMO_NOCOMPR_STEER  = 7,
+       ACT_MIMO_NOCOMPR_STEER          = 7,
        ACT_MIMO_COMPR_STEER            = 8,
        ACT_ANTENNA_SELECT              = 9,
 } HT_ACTION, *PHT_ACTION;
 
 
-/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
-typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
+/* Define sub-carrier mode for 40MHZ. */
+typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier {
        SC_MODE_DUPLICATE = 0,
-       SC_MODE_LOWER = 1,
-       SC_MODE_UPPER = 2,
+       SC_MODE_LOWER     = 1,
+       SC_MODE_UPPER     = 2,
        SC_MODE_FULL40MHZ = 3,
-}HT_BW40_SC_E;
+} HT_BW40_SC_E;
 
-typedef        struct _HT_CAPABILITY_ELE{
+typedef        struct _HT_CAPABILITY_ELE {
 
-       //HT capability info
+       /* HT capability info */
        u8      AdvCoding:1;
        u8      ChlWidth:1;
        u8      MimoPwrSave:2;
@@ -127,32 +118,32 @@ typedef   struct _HT_CAPABILITY_ELE{
        u8      Rsvd1:1;
        u8      LSigTxopProtect:1;
 
-       //MAC HT parameters info
+       /* MAC HT parameters info */
        u8      MaxRxAMPDUFactor:2;
        u8      MPDUDensity:3;
        u8      Rsvd2:3;
 
-       //Supported MCS set
+       /* Supported MCS set */
        u8      MCS[16];
 
 
-       //Extended HT Capability Info
+       /* Extended HT Capability Info */
        u16     ExtHTCapInfo;
 
-       //TXBF Capabilities
+       /* TXBF Capabilities */
        u8      TxBFCap[4];
 
-       //Antenna Selection Capabilities
+       /* Antenna Selection Capabilities */
        u8      ASCap;
 
-}__attribute__((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
+} __packed HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
 
-//------------------------------------------------------------
-// The HT Information element is present in beacons
-// Only AP is required to include this element
-//------------------------------------------------------------
+/*------------------------------------------------------------
+ * The HT Information element is present in beacons
+ * Only AP is required to include this element
+ *------------------------------------------------------------*/
 
-typedef struct _HT_INFORMATION_ELE{
+typedef struct _HT_INFORMATION_ELE {
        u8      ControlChl;
 
        u8      ExtChlOffset:2;
@@ -177,146 +168,146 @@ typedef struct _HT_INFORMATION_ELE{
        u8      Rsvd4:4;
 
        u8      BasicMSC[16];
-}__attribute__((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
+} __packed HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
 
-//
-// MIMO Power Save control field.
-// This is appear in MIMO Power Save Action Frame
-//
-typedef struct _MIMOPS_CTRL{
+/* MIMO Power Save control field.
+ * This is appear in MIMO Power Save Action Frame */
+typedef struct _MIMOPS_CTRL {
        u8      MimoPsEnable:1;
        u8      MimoPsMode:1;
        u8      Reserved:6;
 } MIMOPS_CTRL, *PMIMOPS_CTRL;
 
-typedef enum _HT_SPEC_VER{
+typedef enum _HT_SPEC_VER {
        HT_SPEC_VER_IEEE = 0,
        HT_SPEC_VER_EWC = 1,
-}HT_SPEC_VER, *PHT_SPEC_VER;
+} HT_SPEC_VER, *PHT_SPEC_VER;
 
-typedef enum _HT_AGGRE_MODE_E{
+typedef enum _HT_AGGRE_MODE_E {
        HT_AGG_AUTO = 0,
        HT_AGG_FORCE_ENABLE = 1,
        HT_AGG_FORCE_DISABLE = 2,
-}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
-
-//------------------------------------------------------------
-//  The Data structure is used to keep HT related variables when card is
-//  configured as non-AP STA mode.  **Note**  Current_xxx should be set
-//     to default value in HTInitializeHTInfo()
-//------------------------------------------------------------
-
-typedef struct _RT_HIGH_THROUGHPUT{
-//     DECLARE_RT_OBJECT(_RT_HIGH_THROUGHPUT);
-       u8                              bEnableHT;
-       u8                              bCurrentHTSupport;
-
-       u8                              bRegBW40MHz;                            // Tx 40MHz channel capability
-       u8                              bCurBW40MHz;                            // Tx 40MHz channel capability
-
-       u8                              bRegShortGI40MHz;                       // Tx Short GI for 40Mhz
-       u8                              bCurShortGI40MHz;                       // Tx Short GI for 40MHz
-
-       u8                              bRegShortGI20MHz;                       // Tx Short GI for 20MHz
-       u8                              bCurShortGI20MHz;                       // Tx Short GI for 20MHz
-
-       u8                              bRegSuppCCK;                            // Tx CCK rate capability
-       u8                              bCurSuppCCK;                            // Tx CCK rate capability
-
-       // 802.11n spec version for "peer"
-       HT_SPEC_VER                     ePeerHTSpecVer;
-
+} HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
 
-       // HT related information for "Self"
-       HT_CAPABILITY_ELE       SelfHTCap;                                      // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
-       HT_INFORMATION_ELE      SelfHTInfo;                                     // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
+/*----------------------------------------------------------------------------
+ *  The Data structure is used to keep HT related variables when card is
+ *  configured as non-AP STA mode.
+ *  **Note** Current_xxx should be set to default value in HTInitializeHTInfo()
+ *----------------------------------------------------------------------------*/
 
-       // HT related information for "Peer"
-       u8                              PeerHTCapBuf[32];
-       u8                              PeerHTInfoBuf[32];
-
-
-       // A-MSDU related
-       u8                              bAMSDU_Support;                 // This indicates Tx A-MSDU capability
-       u16                             nAMSDU_MaxSize;                 // This indicates Tx A-MSDU capability
-       u8                              bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
-       u16                             nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
-
-
-       // AMPDU  related <2006.08.10 Emily>
-       u8                              bAMPDUEnable;                           // This indicate Tx A-MPDU capability
-       u8                              bCurrentAMPDUEnable;            // This indicate Tx A-MPDU capability
-       u8                              AMPDU_Factor;                           // This indicate Tx A-MPDU capability
-       u8                              CurrentAMPDUFactor;             // This indicate Tx A-MPDU capability
-       u8                              MPDU_Density;                           // This indicate Tx A-MPDU capability
-       u8                              CurrentMPDUDensity;                     // This indicate Tx A-MPDU capability
+typedef struct _RT_HIGH_THROUGHPUT {
+       u8                      bEnableHT;
+       u8                      bCurrentHTSupport;
+       /* Tx 40MHz channel capability */
+       u8                      bRegBW40MHz;
+       u8                      bCurBW40MHz;
+       /* Tx Short GI for 40Mhz */
+       u8                      bRegShortGI40MHz;
+       u8                      bCurShortGI40MHz;
+       /* Tx Short GI for 20MHz */
+       u8                      bRegShortGI20MHz;
+       u8                      bCurShortGI20MHz;
+       /* Tx CCK rate capability */
+       u8                      bRegSuppCCK;
+       u8                      bCurSuppCCK;
+
+       /* 802.11n spec version for "peer" */
+       HT_SPEC_VER             ePeerHTSpecVer;
+
+
+       /* HT related information for "Self" */
+       /* This is HT cap element sent to peer STA, which also indicate
+        * HT Rx capabilities. */
+       HT_CAPABILITY_ELE       SelfHTCap;
+       HT_INFORMATION_ELE      SelfHTInfo;
+
+       /* HT related information for "Peer" */
+       u8                      PeerHTCapBuf[32];
+       u8                      PeerHTInfoBuf[32];
+
+
+       /* A-MSDU related */
+       /* This indicates Tx A-MSDU capability */
+       u8                      bAMSDU_Support;
+       u16                     nAMSDU_MaxSize;
+       u8                      bCurrent_AMSDU_Support;
+       u16                     nCurrent_AMSDU_MaxSize;
+
+
+       /* A-MPDU related */
+       /* This indicate Tx A-MPDU capability */
+       u8                      bAMPDUEnable;
+       u8                      bCurrentAMPDUEnable;
+       u8                      AMPDU_Factor;
+       u8                      CurrentAMPDUFactor;
+       u8                      MPDU_Density;
+       u8                      CurrentMPDUDensity;
 
-       // Forced A-MPDU enable
-       HT_AGGRE_MODE_E ForcedAMPDUMode;
-       u8                              ForcedAMPDUFactor;
-       u8                              ForcedMPDUDensity;
+       /* Forced A-MPDU enable */
+       HT_AGGRE_MODE_E         ForcedAMPDUMode;
+       u8                      ForcedAMPDUFactor;
+       u8                      ForcedMPDUDensity;
 
-       // Forced A-MSDU enable
-       HT_AGGRE_MODE_E ForcedAMSDUMode;
-       u16                             ForcedAMSDUMaxSize;
+       /* Forced A-MSDU enable */
+       HT_AGGRE_MODE_E         ForcedAMSDUMode;
+       u16                     ForcedAMSDUMaxSize;
 
-       u8                              bForcedShortGI;
+       u8                      bForcedShortGI;
 
-       u8                              CurrentOpMode;
+       u8                      CurrentOpMode;
 
-       // MIMO PS related
-       u8                              SelfMimoPs;
-       u8                              PeerMimoPs;
+       /* MIMO PS related */
+       u8                      SelfMimoPs;
+       u8                      PeerMimoPs;
 
-       // 40MHz Channel Offset settings.
+       /* 40MHz Channel Offset settings. */
        HT_EXTCHNL_OFFSET       CurSTAExtChnlOffset;
-       u8                              bCurTxBW40MHz;  // If we use 40 MHz to Tx
-       u8                              PeerBandwidth;
-
-       // For Bandwidth Switching
-       u8                              bSwBwInProgress;
-       CHNLOP                          ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
-       u8                              SwBwStep;
-       //RT_TIMER                      SwBwTimer;
-       struct timer_list               SwBwTimer;
-
-       // For Realtek proprietary A-MPDU factor for aggregation
-       u8                              bRegRT2RTAggregation;
-       u8                              bCurrentRT2RTAggregation;
-       u8                              bCurrentRT2RTLongSlotTime;
-       u8                              szRT2RTAggBuffer[10];
-
-       // Rx Reorder control
-       u8                              bRegRxReorderEnable;
-       u8                              bCurRxReorderEnable;
-       u8                              RxReorderWinSize;
-       u8                              RxReorderPendingTime;
-       u16                             RxReorderDropCounter;
+       u8                      bCurTxBW40MHz;  /* If we use 40 MHz to Tx */
+       u8                      PeerBandwidth;
+
+       /* For Bandwidth Switching */
+       u8                      bSwBwInProgress;
+       CHNLOP                  ChnlOp; /* sw switching channel in progress. */
+       u8                      SwBwStep;
+       struct timer_list       SwBwTimer;
+
+       /* For Realtek proprietary A-MPDU factor for aggregation */
+       u8                      bRegRT2RTAggregation;
+       u8                      bCurrentRT2RTAggregation;
+       u8                      bCurrentRT2RTLongSlotTime;
+       u8                      szRT2RTAggBuffer[10];
+
+       /* Rx Reorder control */
+       u8                      bRegRxReorderEnable;
+       u8                      bCurRxReorderEnable;
+       u8                      RxReorderWinSize;
+       u8                      RxReorderPendingTime;
+       u16                     RxReorderDropCounter;
 
 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-       u8                              UsbTxAggrNum;
+       u8                      UsbTxAggrNum;
 #endif
 #ifdef USB_RX_AGGREGATION_SUPPORT
-       u8                              UsbRxFwAggrEn;
-       u8                              UsbRxFwAggrPageNum;
-       u8                              UsbRxFwAggrPacketNum;
-       u8                              UsbRxFwAggrTimeout;
+       u8                      UsbRxFwAggrEn;
+       u8                      UsbRxFwAggrPageNum;
+       u8                      UsbRxFwAggrPacketNum;
+       u8                      UsbRxFwAggrTimeout;
 #endif
 
-       // Add for Broadcom(Linksys) IOT. Joseph
-       u8                              bIsPeerBcm;
+       /* Add for Broadcom(Linksys) IOT. */
+       u8                      bIsPeerBcm;
 
-       // For IOT issue.
-       u32                                     IOTAction;
-}RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
+       /* For IOT issue. */
+       u32                     IOTAction;
+} RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
 
 
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each Sta"
-// when card is configured as "AP mode"
-//------------------------------------------------------------
+/*----------------------------------------------------------------------
+ * The Data structure is used to keep HT related variable for "each Sta"
+ * when card is configured as "AP mode"
+ *----------------------------------------------------------------------*/
 
-typedef struct _RT_HTINFO_STA_ENTRY{
+typedef struct _RT_HTINFO_STA_ENTRY {
        u8                      bEnableHT;
 
        u8                      bSupportCck;
@@ -335,56 +326,54 @@ typedef struct _RT_HTINFO_STA_ENTRY{
        u8                      McsRateSet[16];
 
 
-}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
+} RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
 
 
 
 
 
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each AP"
-// when card is configured as "STA mode"
-//------------------------------------------------------------
+/*---------------------------------------------------------------------
+ * The Data structure is used to keep HT related variable for "each AP"
+ * when card is configured as "STA mode"
+ *---------------------------------------------------------------------*/
 
-typedef struct _BSS_HT{
+typedef struct _BSS_HT {
 
        u8                              bdSupportHT;
 
-       // HT related elements
-       u8                                      bdHTCapBuf[32];
-       u16                                     bdHTCapLen;
-       u8                                      bdHTInfoBuf[32];
-       u16                                     bdHTInfoLen;
+       /* HT related elements */
+       u8                              bdHTCapBuf[32];
+       u16                             bdHTCapLen;
+       u8                              bdHTInfoBuf[32];
+       u16                             bdHTInfoLen;
 
-       HT_SPEC_VER                             bdHTSpecVer;
-       //HT_CAPABILITY_ELE                     bdHTCapEle;
-       //HT_INFORMATION_ELE            bdHTInfoEle;
+       HT_SPEC_VER                     bdHTSpecVer;
 
-       u8                                      bdRT2RTAggregation;
-       u8                                      bdRT2RTLongSlotTime;
-}BSS_HT, *PBSS_HT;
+       u8                              bdRT2RTAggregation;
+       u8                              bdRT2RTLongSlotTime;
+} BSS_HT, *PBSS_HT;
 
-typedef struct _MIMO_RSSI{
+typedef struct _MIMO_RSSI {
        u32     EnableAntenna;
        u32     AntennaA;
        u32     AntennaB;
        u32     AntennaC;
        u32     AntennaD;
        u32     Average;
-}MIMO_RSSI, *PMIMO_RSSI;
+} MIMO_RSSI, *PMIMO_RSSI;
 
-typedef struct _MIMO_EVM{
+typedef struct _MIMO_EVM {
        u32     EVM1;
-       u32    EVM2;
-}MIMO_EVM, *PMIMO_EVM;
+       u32     EVM2;
+} MIMO_EVM, *PMIMO_EVM;
 
-typedef struct _FALSE_ALARM_STATISTICS{
+typedef struct _FALSE_ALARM_STATISTICS {
        u32     Cnt_Parity_Fail;
-       u32    Cnt_Rate_Illegal;
+       u32     Cnt_Rate_Illegal;
        u32     Cnt_Crc8_fail;
        u32     Cnt_all;
-}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
+} FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
 
 
 
-#endif //__INC_HTTYPE_H
+#endif
index 56144014b7c9ba15126f97b073fb6eea4777937a..7bdcbd39a3b25a3fb8c4d7eaaf6e95ac59b64ad9 100644 (file)
@@ -61,105 +61,6 @@ rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
        return rtStatus;
 }
 
-/*-----------------------------------------------------------------------------
- * Function:   cmpk_message_handle_tx()
- *
- * Overview:   Driver internal module can call the API to send message to
- *             firmware side. For example, you can send a debug command packet.
- *             Or you can send a request for FW to modify RLX4181 LBUS HW bank.
- *             Otherwise, you can change MAC/PHT/RF register by firmware at
- *             run time. We do not support message more than one segment now.
- *
- * Input:      NONE
- *
- * Output:     NONE
- *
- * Return:     NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     05/06/2008      amy             porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-extern rt_status cmpk_message_handle_tx(struct net_device *dev,
-                                       u8 *codevirtualaddress,
-                                       u32 packettype, u32 buffer_len)
-{
-
-       bool        rt_status = true;
-#ifdef RTL8192U
-       return rt_status;
-#else
-       struct r8192_priv   *priv = ieee80211_priv(dev);
-       u16                 frag_threshold;
-       u16                 frag_length, frag_offset = 0;
-
-       rt_firmware         *pfirmware = priv->pFirmware;
-       struct sk_buff      *skb;
-       unsigned char       *seg_ptr;
-       cb_desc             *tcb_desc;
-       u8                  bLastIniPkt;
-
-       firmware_init_param(dev);
-       /* Fragmentation might be required */
-       frag_threshold = pfirmware->cmdpacket_frag_thresold;
-       do {
-               if ((buffer_len - frag_offset) > frag_threshold) {
-                       frag_length = frag_threshold;
-                       bLastIniPkt = 0;
-
-               } else {
-                       frag_length = buffer_len - frag_offset;
-                       bLastIniPkt = 1;
-
-               }
-
-               /* Allocate skb buffer to contain firmware info and tx
-                  descriptor info add 4 to avoid packet appending overflow. */
-#ifdef RTL8192U
-               skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-#else
-               skb  = dev_alloc_skb(frag_length + 4);
-#endif
-               memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
-               tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-               tcb_desc->queue_index = TXCMD_QUEUE;
-               tcb_desc->bCmdOrInit = packettype;
-               tcb_desc->bLastIniPkt = bLastIniPkt;
-
-#ifdef RTL8192U
-               skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-#endif
-
-               seg_ptr = skb_put(skb, buffer_len);
-               /*
-                * Transform from little endian to big endian
-                * and pending zero
-                */
-               memcpy(seg_ptr, codevirtualaddress, buffer_len);
-               tcb_desc->txbuf_size = (u16)buffer_len;
-
-
-               if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
-                   (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
-                   (priv->ieee80211->queue_stop)) {
-                       RT_TRACE(COMP_FIRMWARE, "======> tx full!\n");
-                       skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-               } else {
-                       priv->ieee80211->softmac_hard_start_xmit(skb, dev);
-               }
-
-               codevirtualaddress += frag_length;
-               frag_offset += frag_length;
-
-       } while (frag_offset < buffer_len);
-
-       return rt_status;
-
-
-#endif
-}
-
 /*-----------------------------------------------------------------------------
  * Function:    cmpk_counttxstatistic()
  *
@@ -593,8 +494,8 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg)
  *  05/06/2008         amy     Create Version 0 porting from windows code.
  *
  *---------------------------------------------------------------------------*/
-extern u32 cmpk_message_handle_rx(struct net_device *dev,
-                                 struct ieee80211_rx_stats *pstats)
+u32 cmpk_message_handle_rx(struct net_device *dev,
+                          struct ieee80211_rx_stats *pstats)
 {
        int                     total_length;
        u8                      cmd_length, exe_cnt = 0;
index ebe403270a5bb5ee7b7efc8c04e50d9a07995ea4..52cd437ef7bb52d058c652ac9594de1e9666b20c 100644 (file)
@@ -1,17 +1,17 @@
 #ifndef R819XUSB_CMDPKT_H
 #define R819XUSB_CMDPKT_H
 /* Different command packet have dedicated message length and definition. */
-#define                CMPK_RX_TX_FB_SIZE                                      sizeof(cmpk_txfb_t)             //20
-#define                CMPK_TX_SET_CONFIG_SIZE                         sizeof(cmpk_set_cfg_t)  //16
-#define                CMPK_BOTH_QUERY_CONFIG_SIZE                     sizeof(cmpk_set_cfg_t)  //16
-#define                CMPK_RX_TX_STS_SIZE                                     sizeof(cmpk_tx_status_t)//
-#define                CMPK_RX_DBG_MSG_SIZE                    sizeof(cmpk_rx_dbginfo_t)//
-#define                CMPK_TX_RAHIS_SIZE                      sizeof(cmpk_tx_rahis_t)
+#define                CMPK_RX_TX_FB_SIZE              sizeof(cmpk_txfb_t)     /* 20 */
+#define                CMPK_TX_SET_CONFIG_SIZE         sizeof(cmpk_set_cfg_t)  /* 16 */
+#define                CMPK_BOTH_QUERY_CONFIG_SIZE     sizeof(cmpk_set_cfg_t)  /* 16 */
+#define                CMPK_RX_TX_STS_SIZE             sizeof(cmpk_tx_status_t)
+#define                CMPK_RX_DBG_MSG_SIZE            sizeof(cmpk_rx_dbginfo_t)
+#define                CMPK_TX_RAHIS_SIZE              sizeof(cmpk_tx_rahis_t)
 
 /* 2008/05/08 amy For USB constant. */
-#define ISR_TxBcnOk                                    BIT27                   // Transmit Beacon OK
-#define ISR_TxBcnErr                           BIT26                   // Transmit Beacon Error
-#define ISR_BcnTimerIntr                       BIT13                   // Beacon Timer Interrupt
+#define ISR_TxBcnOk            BIT27           /* Transmit Beacon OK */
+#define ISR_TxBcnErr           BIT26           /* Transmit Beacon Error */
+#define ISR_BcnTimerIntr       BIT13           /* Beacon Timer Interrupt */
 
 
 /* Define element ID of command packet. */
 /* Define different command packet structure. */
 /* 1. RX side: TX feedback packet. */
 typedef struct tag_cmd_pkt_tx_feedback {
-       // DWORD 0
+       /* DWORD 0 */
        u8      element_id;                     /* Command packet type. */
        u8      length;                         /* Command packet length. */
-       /* 2007/07/05 MH Change tx feedback info field. */
+       /* Change tx feedback info field. */
        /*------TX Feedback Info Field */
-       u8      TID:4;                          /* */
-       u8      fail_reason:3;          /* */
+       u8      TID:4;
+       u8      fail_reason:3;
        u8      tok:1;                          /* Transmit ok. */
-       u8      reserve1:4;                     /* */
-       u8      pkt_type:2;             /* */
-       u8      bandwidth:1;            /* */
-       u8      qos_pkt:1;                      /* */
+       u8      reserve1:4;
+       u8      pkt_type:2;
+       u8      bandwidth:1;
+       u8      qos_pkt:1;
 
-       // DWORD 1
-       u8      reserve2;                       /* */
+       /* DWORD 1 */
+       u8      reserve2;
        /*------TX Feedback Info Field */
-       u8      retry_cnt;                      /* */
-       u16     pkt_id;                         /* */
+       u8      retry_cnt;
+       u16     pkt_id;
 
-       // DWORD 3
-       u16     seq_num;                        /* */
+       /* DWORD 3 */
+       u16     seq_num;
        u8      s_rate;                         /* Start rate. */
        u8      f_rate;                         /* Final rate. */
 
-       // DWORD 4
-       u8      s_rts_rate;                     /* */
-       u8      f_rts_rate;                     /* */
-       u16     pkt_length;                     /* */
+       /* DWORD 4 */
+       u8      s_rts_rate;
+       u8      f_rts_rate;
+       u16     pkt_length;
 
-       // DWORD 5
-       u16     reserve3;                       /* */
-       u16     duration;                       /* */
-}cmpk_txfb_t;
+       /* DWORD 5 */
+       u16     reserve3;
+       u16     duration;
+} cmpk_txfb_t;
 
 /* 2. RX side: Interrupt status packet. It includes Beacon State,
        Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */
* Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */
 typedef struct tag_cmd_pkt_interrupt_status {
        u8      element_id;                     /* Command packet type. */
        u8      length;                         /* Command packet length. */
        u16     reserve;
-       u32     interrupt_status;                               /* Interrupt Status. */
-}cmpk_intr_sta_t;
+       u32     interrupt_status;               /* Interrupt Status. */
+} cmpk_intr_sta_t;
 
 
 /* 3. TX side: Set configuration packet. */
 typedef struct tag_cmd_pkt_set_configuration {
        u8      element_id;                     /* Command packet type. */
        u8      length;                         /* Command packet length. */
-       u16     reserve1;                       /* */
+       u16     reserve1;
+       /* Configuration info. */
        u8      cfg_reserve1:3;
-       u8      cfg_size:2;                     /* Configuration info. */
-       u8      cfg_type:2;                     /* Configuration info. */
-       u8      cfg_action:1;           /* Configuration info. */
-       u8      cfg_reserve2;           /* Configuration info. */
-       u8      cfg_page:4;                     /* Configuration info. */
-       u8      cfg_reserve3:4;         /* Configuration info. */
-       u8      cfg_offset;                     /* Configuration info. */
-       u32     value;                          /* */
-       u32     mask;                           /* */
-}cmpk_set_cfg_t;
+       u8      cfg_size:2;
+       u8      cfg_type:2;
+       u8      cfg_action:1;
+       u8      cfg_reserve2;
+       u8      cfg_page:4;
+       u8      cfg_reserve3:4;
+       u8      cfg_offset;
+       u32     value;
+       u32     mask;
+} cmpk_set_cfg_t;
 
 /* 4. Both side : TX/RX query configuraton packet. The query structure is the
       same as set configuration. */
 #define                cmpk_query_cfg_t        cmpk_set_cfg_t
 
 /* 5. Multi packet feedback status. */
-typedef struct tag_tx_stats_feedback { // PJ quick rxcmd 09042007
-       // For endian transfer --> Driver will not the same as firmware structure.
-       // DW 0
+typedef struct tag_tx_stats_feedback {
+       /* For endian transfer --> Driver will not the same as
+          firmware structure. */
+       /* DW 0 */
        u16     reserve1;
-       u8      length;                         // Command packet length
-       u8      element_id;                     // Command packet type
+       u8      length;                         /* Command packet length */
+       u8      element_id;                     /* Command packet type */
 
-       // DW 1
-       u16     txfail;                         // Tx Fail count
-       u16     txok;                           // Tx ok count
+       /* DW 1 */
+       u16     txfail;                         /* Tx fail count */
+       u16     txok;                           /* Tx ok count */
 
-       // DW 2
-       u16     txmcok;                         // tx multicast
-       u16     txretry;                        // Tx Retry count
+       /* DW 2 */
+       u16     txmcok;                         /* Tx multicast */
+       u16     txretry;                        /* Tx retry count */
 
-       // DW 3
-       u16  txucok;                            // tx unicast
-       u16     txbcok;                         // tx broadcast
+       /* DW 3 */
+       u16     txucok;                         /* Tx unicast */
+       u16     txbcok;                         /* Tx broadcast */
 
-       // DW 4
-       u16     txbcfail;                       //
-       u16     txmcfail;                       //
+       /* DW 4 */
+       u16     txbcfail;
+       u16     txmcfail;
 
-       // DW 5
-       u16     reserve2;                       //
-       u16     txucfail;                       //
+       /* DW 5 */
+       u16     reserve2;
+       u16     txucfail;
 
-       // DW 6-8
+       /* DW 6-8 */
        u32     txmclength;
        u32     txbclength;
        u32     txuclength;
 
-       // DW 9
+       /* DW 9 */
        u16     reserve3_23;
        u8      reserve3_1;
        u8      rate;
-}__attribute__((packed)) cmpk_tx_status_t;
+} __packed cmpk_tx_status_t;
 
 /* 6. Debug feedback message. */
-/* 2007/10/23 MH Define RX debug message  */
+/* Define RX debug message  */
 typedef struct tag_rx_debug_message_feedback {
-       // For endian transfer --> for driver
-       // DW 0
+       /* For endian transfer --> for driver */
+       /* DW 0 */
        u16     reserve1;
-       u8      length;                         // Command packet length
-       u8      element_id;                     // Command packet type
+       u8      length;                         /* Command packet length */
+       u8      element_id;                     /* Command packet type */
 
-       // DW 1-??
-       // Variable debug message.
+       /* DW 1-?? */
+       /* Variable debug message. */
 
-}cmpk_rx_dbginfo_t;
+} cmpk_rx_dbginfo_t;
 
-/* 2008/03/20 MH Define transmit rate history. For big endian format. */
+/* Define transmit rate history. For big endian format. */
 typedef struct tag_tx_rate_history {
-       // For endian transfer --> for driver
-       // DW 0
-       u8      element_id;                     // Command packet type
-       u8      length;                         // Command packet length
+       /* For endian transfer --> for driver */
+       /* DW 0 */
+       u8      element_id;                     /* Command packet type */
+       u8      length;                         /* Command packet length */
        u16     reserved1;
 
-       // DW 1-2       CCK rate counter
+       /* DW 1-2       CCK rate counter */
        u16     cck[4];
 
-       // DW 3-6
+       /* DW 3-6 */
        u16     ofdm[8];
 
-       // DW 7-14
-       //UINT16        MCS_BW0_SG0[16];
-
-       // DW 15-22
-       //UINT16        MCS_BW1_SG0[16];
-
-       // DW 23-30
-       //UINT16        MCS_BW0_SG1[16];
-
-       // DW 31-38
-       //UINT16        MCS_BW1_SG1[16];
-
-       // DW 7-14      BW=0 SG=0
-       // DW 15-22     BW=1 SG=0
-       // DW 23-30     BW=0 SG=1
-       // DW 31-38     BW=1 SG=1
+       /* DW 7-14      BW=0 SG=0
+        * DW 15-22     BW=1 SG=0
+        * DW 23-30     BW=0 SG=1
+        * DW 31-38     BW=1 SG=1
+        */
        u16     ht_mcs[4][16];
 
-}__attribute__((packed)) cmpk_tx_rahis_t;
-
-typedef enum tag_command_packet_directories
-{
-    RX_TX_FEEDBACK = 0,
-    RX_INTERRUPT_STATUS                = 1,
-    TX_SET_CONFIG                              = 2,
-    BOTH_QUERY_CONFIG                  = 3,
-    RX_TX_STATUS                               = 4,
-    RX_DBGINFO_FEEDBACK                = 5,
-    RX_TX_PER_PKT_FEEDBACK             = 6,
-    RX_TX_RATE_HISTORY         = 7,
-    RX_CMD_ELE_MAX
-}cmpk_element_e;
-
-typedef enum _rt_status{
+} __packed cmpk_tx_rahis_t;
+
+typedef enum tag_command_packet_directories {
+       RX_TX_FEEDBACK                  = 0,
+       RX_INTERRUPT_STATUS             = 1,
+       TX_SET_CONFIG                   = 2,
+       BOTH_QUERY_CONFIG               = 3,
+       RX_TX_STATUS                    = 4,
+       RX_DBGINFO_FEEDBACK             = 5,
+       RX_TX_PER_PKT_FEEDBACK          = 6,
+       RX_TX_RATE_HISTORY              = 7,
+       RX_CMD_ELE_MAX
+} cmpk_element_e;
+
+typedef enum _rt_status {
        RT_STATUS_SUCCESS,
        RT_STATUS_FAILURE,
        RT_STATUS_PENDING,
        RT_STATUS_RESOURCE
-}rt_status,*prt_status;
-
-extern rt_status cmpk_message_handle_tx(struct net_device *dev, u8 *codevirtualaddress, u32 packettype, u32 buffer_len);
+} rt_status, *prt_status;
 
-extern  u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats);
-extern rt_status SendTxCommandPacket( struct net_device *dev, void *pData, u32 DataLen);
+extern u32 cmpk_message_handle_rx(struct net_device *dev,
+               struct ieee80211_rx_stats *pstats);
+extern rt_status SendTxCommandPacket(struct net_device *dev,
+               void *pData, u32 DataLen);
 
 
 #endif
index bb924ac97e471d9e5613666a18b6f8acb6c0a151..d6a6de3a64f5d6cfd4869f4879293d710ddabf2b 100644 (file)
@@ -61,20 +61,16 @@ bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buff
                /* Allocate skb buffer to contain firmware info and tx descriptor info
                 * add 4 to avoid packet appending overflow.
                 * */
-               #ifdef RTL8192U
                skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-               #else
-               skb  = dev_alloc_skb(frag_length + 4);
-               #endif
+               if (!skb)
+                       return false;
                memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
                tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
                tcb_desc->queue_index = TXCMD_QUEUE;
                tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
                tcb_desc->bLastIniPkt = bLastIniPkt;
 
-               #ifdef RTL8192U
                skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-               #endif
                seg_ptr = skb->data;
                /*
                 * Transform from little endian to big endian
@@ -299,16 +295,10 @@ bool init_firmware(struct net_device *dev)
                                mapped_file = pfirmware->firmware_buf;
                                file_length = fw_entry->size;
                        } else {
-#ifdef RTL8190P
-                               memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size);
-                               mapped_file = pfirmware->firmware_buf;
-                               file_length = fw_entry->size;
-#else
                                memset(pfirmware->firmware_buf,0,128);
                                memcpy(&pfirmware->firmware_buf[128],fw_entry->data,fw_entry->size);
                                mapped_file = pfirmware->firmware_buf;
                                file_length = fw_entry->size + 128;
-#endif
                        }
                        pfirmware->firmware_buf_size = file_length;
                }else if (rst_opt == OPT_FIRMWARE_RESET ) {
@@ -340,15 +330,6 @@ bool init_firmware(struct net_device *dev)
                         * will set polling bit when firmware code is also configured
                         */
                        pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
-#ifdef RTL8190P
-                       // To initialize IMEM, CPU move code  from 0x80000080, hence, we send 0x80 byte packet
-                       rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET);
-                       if (rt_status != true)
-                       {
-                               RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n");
-                               goto  download_firmware_fail;
-                       }
-#endif
                        //mdelay(1000);
                        /*
                         * To initialize IMEM, CPU move code  from 0x80000080,
index a6fac081e42c121accca043899bee3a033b772a5..39cd426bc5e5e92adf49c21ff8b7de004bb3b9ad 100644 (file)
@@ -1713,7 +1713,7 @@ void InitialGain819xUsb(struct net_device *dev,   u8 Operation)
                queue_delayed_work(priv->priv_wq, &priv->initialgain_operate_wq, 0);
 }
 
-extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
+void InitialGainOperateWorkItemCallBack(struct work_struct *work)
 {
        struct delayed_work *dwork = container_of(work, struct delayed_work,
                                                  work);
@@ -1799,12 +1799,6 @@ extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
                RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",
                         priv->initgain_backup.cca);
 
-#ifdef RTL8190P
-               SetTxPowerLevel8190(Adapter, priv->CurrentChannel);
-#endif
-#ifdef RTL8192E
-               SetTxPowerLevel8190(Adapter, priv->CurrentChannel);
-#endif
                rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
 
                if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
index f3c352a10fe06965a5281e0c12268fea5c172621..66cbe3f9cafd9116e42ea7a47be0fc16637288f0 100644 (file)
@@ -23,7 +23,7 @@ typedef struct _SwChnlCmd {
        u32             Para1;
        u32             Para2;
        u32             msDelay;
-} __attribute__ ((packed)) SwChnlCmd;
+} __packed SwChnlCmd;
 
 extern u32 rtl819XMACPHY_Array_PG[];
 extern u32 rtl819XPHY_REG_1T2RArray[];
index 6e81ba0eaf1e5542346c7a04121333d4193aedc4..82a77b45fb50901df1bfb0aba005da9375313517 100644 (file)
@@ -141,7 +141,7 @@ static uint loadparam(struct _adapter *padapter, struct  net_device *pnetdev)
        registry_par->ssid.SsidLength = 3;
        registry_par->channel = (u8)channel;
        registry_par->wireless_mode = (u8)wireless_mode;
-       registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense ;
+       registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense;
        registry_par->vcs_type = (u8)vcs_type;
        registry_par->frag_thresh = (u16)frag_thresh;
        registry_par->preamble = (u8)preamble;
index 088647cdca9953cd47783c4ac41cdbfed9cac512..5b6a96e3bd7b15db5f8c2a34fc9dc592a61fd2cd 100644 (file)
@@ -62,7 +62,7 @@ static void check_hw_pbc(struct _adapter *padapter)
        r8712_write8(padapter, GPIO_IO_SEL, tmp1byte);
        tmp1byte = r8712_read8(padapter, GPIO_CTRL);
        if (tmp1byte == 0xff)
-               return ;
+               return;
        if (tmp1byte&HAL_8192S_HW_GPIO_WPS_BIT) {
                /* Here we only set bPbcPressed to true
                 * After trigger PBC, the variable will be set to false */
@@ -381,7 +381,7 @@ _next:
                        *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) |
                                               (pcmd->cmdcode << 16) |
                                               (pcmdpriv->cmd_seq << 24));
-                       pcmdbuf += 2 ; /* 8 bytes alignment */
+                       pcmdbuf += 2; /* 8 bytes alignment */
                        memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
                        while (check_cmd_fifo(padapter, wr_sz) == _FAIL) {
                                if ((padapter->bDriverStopped == true) ||
@@ -471,11 +471,9 @@ void r8712_event_handle(struct _adapter *padapter, uint *peventbuf)
        if (pevt_priv->event_seq > 127)
                pevt_priv->event_seq = 0;
        peventbuf = peventbuf + 2; /* move to event content, 8 bytes alignment */
-       if (peventbuf) {
-               event_callback = wlanevents[evt_code].event_callback;
-               if (event_callback)
-                       event_callback(padapter, (u8 *)peventbuf);
-       }
+       event_callback = wlanevents[evt_code].event_callback;
+       if (event_callback)
+               event_callback(padapter, (u8 *)peventbuf);
        pevt_priv->evt_done_cnt++;
 _abort_event_:
        return;
index 377fca905801aa974749ac9943d13efee51d5bec..c9eeb4270ab9d84e4a8619d8f4d9270bfe9ba085 100644 (file)
@@ -231,7 +231,7 @@ u16 r8712_efuse_get_current_size(struct _adapter *padapter)
                        /* read next header */
                        efuse_addr = efuse_addr + (word_cnts * 2) + 1;
                } else
-                       bContinual = false ;
+                       bContinual = false;
        }
        return efuse_addr;
 }
index d59a74aa30489f2bf70c9f6b8a450d8ddaf4b484..ea965370d1ac9ed0bc5520721532b8d15419adfd 100644 (file)
@@ -108,7 +108,7 @@ void r8712_free_recv_priv(struct recv_priv *precvpriv)
        struct _adapter *padapter = precvpriv->adapter;
 
        precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-       for (i = 0; i < NR_RECVBUFF ; i++) {
+       for (i = 0; i < NR_RECVBUFF; i++) {
                r8712_os_recvbuf_resource_free(padapter, precvbuf);
                precvbuf++;
        }
@@ -268,7 +268,7 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
        u8   *psta_addr;
        struct recv_frame_hdr *pfhdr;
        struct sta_info *psta;
-       struct  sta_priv *pstapriv ;
+       struct  sta_priv *pstapriv;
        struct list_head *phead;
        union recv_frame *prtnframe = NULL;
        struct  __queue *pfree_recv_queue, *pdefrag_q;
@@ -849,7 +849,7 @@ static void query_rx_phy_status(struct _adapter *padapter,
        } else {
                /* (1)Get RSSI for HT rate */
                for (i = 0; i < ((padapter->registrypriv.rf_config) &
-                           0x0f) ; i++) {
+                           0x0f); i++) {
                        rf_rx_num++;
                        rx_pwr[i] = ((pphy_head[PHY_STAT_GAIN_TRSW_SHT + i]
                                    & 0x3F) * 2) - 110;
index f16307f5d827e72707996c1299c8636e3448e000..7e324315e6ad30846166b9ea9a5bd0f2662e349a 100644 (file)
@@ -965,7 +965,7 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter,
                        psta = r8712_alloc_stainfo(&padapter->stapriv,
                                                   pnetwork->MacAddress);
                        if (psta == NULL)
-                               goto createbss_cmd_fail ;
+                               goto createbss_cmd_fail;
                }
                r8712_indicate_connect(padapter);
        } else {
index d58aa7e3b15cef799726d8bb4f4e656ddfaf7c91..9fec6eda8731c91612f038b370d5258b7adc6c3c 100644 (file)
@@ -820,7 +820,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev,
                        intReturn = true;
                blInserted = false;
                /* overwrite PMKID */
-               for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
+               for (j = 0; j < NUM_PMKID_CACHE; j++) {
                        if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
                            strIssueBssid, ETH_ALEN)) {
                                /* BSSID is matched, the same AP => rewrite
@@ -845,7 +845,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev,
                                PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
                        psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
                                bUsed = true;
-                       psecuritypriv->PMKIDIndex++ ;
+                       psecuritypriv->PMKIDIndex++;
                        if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
                                psecuritypriv->PMKIDIndex = 0;
                }
@@ -1598,7 +1598,7 @@ static int r8711_wx_set_enc(struct net_device *dev,
                wep.Length = wep.KeyLength +
                             FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
        } else {
-               wep.KeyLength = 0 ;
+               wep.KeyLength = 0;
                if (keyindex_provided == 1) { /* set key_id only, no given
                                               * KeyMaterial(erq->length==0).*/
                        padapter->securitypriv.PrivacyKeyIndex = key;
@@ -1880,7 +1880,7 @@ static int r8711_wx_write32(struct net_device *dev,
        u32 data32;
 
        get_user(addr, (u32 __user *)wrqu->data.pointer);
-       data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
+       data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags;
        r8712_write32(padapter, addr, data32);
        return 0;
 }
index 5d6d55e7b38909d316b4ffa4528b5037170072ed..ac0baff7f090e5f12e9d552fb8162ec4d398e2f2 100644 (file)
@@ -153,7 +153,7 @@ uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
                                         padapter->recvpriv.rx_icv_err;
                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
        } else
-               return RNDIS_STATUS_INVALID_LENGTH ;
+               return RNDIS_STATUS_INVALID_LENGTH;
        return RNDIS_STATUS_SUCCESS;
 }
 
@@ -169,7 +169,7 @@ uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
 {
        struct _adapter *padapter = (struct _adapter *)
                                    (poid_par_priv->adapter_context);
-       u32 preamblemode = 0 ;
+       u32 preamblemode = 0;
 
        if (poid_par_priv->type_of_oid != QUERY_OID)
                return RNDIS_STATUS_NOT_ACCEPTED;
@@ -522,7 +522,7 @@ uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
        else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
                ulInfo = ADHOCMODE;
        else
-               ulInfo = NOTASSOCIATED ;
+               ulInfo = NOTASSOCIATED;
        *(u32 *)poid_par_priv->information_buf = ulInfo;
        *poid_par_priv->bytes_rw =  poid_par_priv->information_buf_len;
        return RNDIS_STATUS_SUCCESS;
index 659615481f6f4c1b8d387c572cc063a11cd9492c..8fa0f9d49a8aedb6800d25e07b004a61c4a18531 100644 (file)
@@ -1641,7 +1641,7 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
        struct wlan_network     *cur_network = &adapter->mlmepriv.cur_network;
 
        pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
-                                           > 0 ? 1 : 0) ; /* adhoc no 802.1x */
+                                           > 0 ? 1 : 0); /* adhoc no 802.1x */
        pdev_network->Rssi = 0;
        switch (pregistrypriv->wireless_mode) {
        case WIRELESS_11B:
@@ -1786,7 +1786,7 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
        psta = r8712_get_stainfo(&padapter->stapriv,
                                 pcur_network->network.MacAddress);
        if (psta) {
-               for (i = 0; i < 16 ; i++) {
+               for (i = 0; i < 16; i++) {
                        preorder_ctrl = &psta->recvreorder_ctrl[i];
                        preorder_ctrl->indicate_seq = 0xffff;
                        preorder_ctrl->wend_b = 0xffff;
index 5638d5e065ff7a05c919712040abb9300adcb16f..0563318a19ff40962984dd8b3094f34c3680ec29 100644 (file)
@@ -110,7 +110,7 @@ static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd)
        u16 iocmd_value = iocmd.value;
        u8 iocmd_idx    = iocmd.index;
 
-       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx;
        if (r8712_fw_cmd(pAdapter, cmd32))
                r8712_fw_cmd_data(pAdapter, &val32, 1);
        else
@@ -128,7 +128,7 @@ static u8 fw_iocmd_write(struct _adapter *pAdapter,
 
        r8712_fw_cmd_data(pAdapter, &value, 0);
        msleep(100);
-       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx;
        return r8712_fw_cmd(pAdapter, cmd32);
 }
 
@@ -189,8 +189,8 @@ u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset)
        u32 rf_data;
        struct IOCMD_STRUCT iocmd;
 
-       iocmd.cmdclass  = IOCMD_CLASS_BB_RF ;
-       iocmd.value     = rf_addr ;
+       iocmd.cmdclass  = IOCMD_CLASS_BB_RF;
+       iocmd.value     = rf_addr;
        iocmd.index     = IOCMD_RF_READ_IDX;
        rf_data = fw_iocmd_read(pAdapter, iocmd);
        return rf_data;
index e33fd6db246d9e80bd43aa732a2c86c23f2e1444..5349669707c04d7785564cfd1e153a90ff6e8578 100644 (file)
@@ -835,7 +835,7 @@ static void mix_column(u8 *in, u8 *out)
        u8 temp[4];
        u8 tempb[4];
 
-       for (i = 0 ; i < 4; i++) {
+       for (i = 0; i < 4; i++) {
                if ((in[i] & 0x80) == 0x80)
                        add1b[i] = 0x1b;
                else
@@ -1187,7 +1187,7 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe)
                                        length = pxmitpriv->frag_len -
                                                 pattrib->hdrlen -
                                                 pattrib->iv_len -
-                                                pattrib->icv_len ;
+                                                pattrib->icv_len;
                                        aes_cipher(prwskey, pattrib->
                                                   hdrlen, pframe, length);
                                        pframe += pxmitpriv->frag_len;
@@ -1315,7 +1315,7 @@ static sint aes_decipher(u8 *key, uint    hdrlen,
                bitwise_xor(aes_out, padded_buffer, chain_buffer);
                aes128k128d(key, chain_buffer, aes_out);
        }
-       for (j = 0 ; j < 8; j++)
+       for (j = 0; j < 8; j++)
                mic[j] = aes_out[j];
        /* Insert MIC into payload */
        for (j = 0; j < 8; j++)
index 1247b3d9719db5f279e770bbf8cd2234d38cc7be..8db6849d4b24a0f35e438a0bf369dd9c69833465 100644 (file)
@@ -138,7 +138,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
                }
                phash_list = &(pstapriv->sta_hash[index]);
                list_insert_tail(&psta->hash_list, phash_list);
-               pstapriv->asoc_sta_count++ ;
+               pstapriv->asoc_sta_count++;
 
 /* For the SMC router, the sequence number of first packet of WPS handshake
  * will be 0. In this case, this packet will be dropped by recv_decache function
@@ -149,7 +149,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
                        memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
                                &wRxSeqInitialValue, 2);
                /* for A-MPDU Rx reordering buffer control */
-               for (i = 0; i < 16 ; i++) {
+               for (i = 0; i < 16; i++) {
                        preorder_ctrl = &psta->recvreorder_ctrl[i];
                        preorder_ctrl->padapter = pstapriv->padapter;
                        preorder_ctrl->indicate_seq = 0xffff;
index c812d6c7dc31d48b8c9fc320ce59fba2d735f89a..dbefa43e4c2c50211cf4aa866896d875068b8147 100644 (file)
@@ -353,11 +353,6 @@ static void disable_ht_for_spec_devid(const struct usb_device_id *pdid,
        }
 }
 
-static u8 key_2char2num(u8 hch, u8 lch)
-{
-       return (hex_to_bin(hch) << 4) | hex_to_bin(lch);
-}
-
 /*
  * drv_init() - a device potentially for us
  *
@@ -465,16 +460,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
                                r8712_efuse_pg_packet_read(padapter, offset,
                                                     &pdata[i]);
 
-                       if (r8712_initmac) {
-                               /* Users specify the mac address */
-                               int jj, kk;
-
-                               for (jj = 0, kk = 0; jj < ETH_ALEN;
-                                    jj++, kk += 3)
-                                       mac[jj] =
-                                          key_2char2num(r8712_initmac[kk],
-                                          r8712_initmac[kk + 1]);
-                       } else {
+                       if (!r8712_initmac || !mac_pton(r8712_initmac, mac)) {
                                /* Use the mac address stored in the Efuse
                                 * offset = 0x12 for usb in efuse
                                 */
index 4d22bb7008f8456e378c3568d3252be7ede9a79f..0ac9130faf6cad9cb298e8b8a44e9863a81328cf 100644 (file)
@@ -51,7 +51,7 @@ void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile)
        pfile->pkt = pktptr;
        pfile->cur_addr = pfile->buf_start = pktptr->data;
        pfile->pkt_len = pfile->buf_len = pktptr->len;
-       pfile->cur_buffer = pfile->buf_start ;
+       pfile->cur_buffer = pfile->buf_start;
 }
 
 uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen)
index 61087054640676ba8b734dda3aa5570f81ae61bb..a474eede70a32bf05cc2152fa64b0f107b707a1b 100644 (file)
@@ -973,7 +973,7 @@ static int get_dev_status(struct scsi_cmnd *srb, struct rts51x_chip *chip)
 
        rts51x_pp_status(chip, lun, status, 32);
 
-       buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(status));
+       buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(status));
        rts51x_set_xfer_buf(status, buf_len, srb);
        scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
 
@@ -988,7 +988,7 @@ static int read_status(struct scsi_cmnd *srb, struct rts51x_chip *chip)
 
        rts51x_read_status(chip, lun, rts51x_status, 16);
 
-       buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rts51x_status));
+       buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(rts51x_status));
        rts51x_set_xfer_buf(rts51x_status, buf_len, srb);
        scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
 
index 304e1bcd1e3b2c78f89704ee2e65c2da353163ee..16de497415eebaf70728eac603490c9ccdd2ee5a 100644 (file)
@@ -15,8 +15,8 @@
 #ifndef UART_SB105X_H
 #define UART_SB105X_H
 
-/* 
- * option register 
+/*
+ * option register
  */
 
 /* Device Information Register */
index a10cdb17038bf9717bbb20f979fb104dda9ccb27..5cd3efff97d3b3a029c328fef330aa05348eff5c 100644 (file)
@@ -543,14 +543,14 @@ static int mp_startup(struct sb_uart_state *state, int init_hw)
                if (init_hw) {
                        mp_change_speed(state, NULL);
 
-                       if (info->tty->termios.c_cflag & CBAUD)
+                       if (info->tty && (info->tty->termios.c_cflag & CBAUD))
                                uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
                }
 
                info->flags |= UIF_INITIALIZED;
 
-
-               clear_bit(TTY_IO_ERROR, &info->tty->flags);
+               if (info->tty)
+                       clear_bit(TTY_IO_ERROR, &info->tty->flags);
        }
 
        if (retval && capable(CAP_SYS_ADMIN))
@@ -1216,7 +1216,7 @@ static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
                                return (inb(mp_devs[arg].option_reg_addr+MP_OPTR_IIR0+(state->port->line/8)));
                        }
                case TIOCGGETPORTTYPE:
-                       ret = get_device_type(arg);;
+                       ret = get_device_type(arg);
                        return ret;
                case TIOCSMULTIECHO: /* set to multi-drop mode(RS422) or echo mode(RS485)*/
                        outb( ( inb(info->interface_config_addr) & ~0x03 ) | 0x01 ,  
@@ -1808,10 +1808,7 @@ void mp_unregister_driver(struct uart_driver *drv)
     drv->tty_driver = NULL;
 
 
-    if (drv->state)
-    {
-        kfree(drv->state);
-    }
+    kfree(drv->state);
 
 }
 
index 27365f9bc0b035a6b894e2317dd7da4d6385b001..c6370d3d637f9d26884086db5e4ddc3ff7e9a80a 100644 (file)
@@ -240,7 +240,7 @@ void cpld_select_panel(struct channel *sc, u32 panel)
 }
 
 
-extern void cpld_set_clock(struct channel *sc, u32 mode)
+void cpld_set_clock(struct channel *sc, u32 mode)
 {
        if (sc->p.clock_source == mode)
                return;
index 490a31e0fd4345369028380ef4f94ac3d40b481a..b9262a78dd6edd2e24f6894b5909030262741543 100644 (file)
@@ -1134,7 +1134,7 @@ static int sep_crypto_block_data(struct ablkcipher_request *req)
 
        if (int_error < 0) {
                dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page error\n");
-               return -ENOMEM;
+               return int_error;
        } else if (int_error == 1) {
                ta_ctx->src_sg = new_sg;
                ta_ctx->src_sg_hold = new_sg;
@@ -1149,7 +1149,7 @@ static int sep_crypto_block_data(struct ablkcipher_request *req)
        if (int_error < 0) {
                dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
                        int_error);
-               return -ENOMEM;
+               return int_error;
        } else if (int_error == 1) {
                ta_ctx->dst_sg = new_sg;
                ta_ctx->dst_sg_hold = new_sg;
index 6a98a208bbf2895b0a978cd10658edf7e7f51ae0..1e80a4013b8c1f4e2947280bd5a2ea0448921ccf 100644 (file)
@@ -493,8 +493,7 @@ int sep_free_dma_table_data_handler(struct sep_device *sep,
                 * then we skip this step altogether as restricted
                 * memory is not available to the o/s at all.
                 */
-               if (((*dma_ctx)->secure_dma == false) &&
-                       (dma->out_map_array)) {
+               if (!(*dma_ctx)->secure_dma && dma->out_map_array) {
 
                        for (count = 0; count < dma->out_num_pages; count++) {
                                dma_unmap_page(&sep->pdev->dev,
@@ -515,8 +514,7 @@ int sep_free_dma_table_data_handler(struct sep_device *sep,
                }
 
                /* Again, we do this only for non secure dma */
-               if (((*dma_ctx)->secure_dma == false) &&
-                       (dma->out_page_array)) {
+               if (!(*dma_ctx)->secure_dma && dma->out_page_array) {
 
                        for (count = 0; count < dma->out_num_pages; count++) {
                                if (!PageReserved(dma->out_page_array[count]))
@@ -1263,13 +1261,8 @@ static int sep_lock_user_pages(struct sep_device *sep,
        }
 
        /* Convert the application virtual address into a set of physical */
-       down_read(&current->mm->mmap_sem);
-       result = get_user_pages(current, current->mm, app_virt_addr,
-               num_pages,
-               ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1),
-               0, page_array, NULL);
-
-       up_read(&current->mm->mmap_sem);
+       result = get_user_pages_fast(app_virt_addr, num_pages,
+               ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), page_array);
 
        /* Check the number of pages locked - if not all then exit with error */
        if (result != num_pages) {
@@ -1952,7 +1945,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep,
        }
 
        /* Check if the pages are in Kernel Virtual Address layout */
-       if (is_kva == true)
+       if (is_kva)
                error = sep_lock_kernel_pages(sep, app_virt_addr,
                        data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG,
                        dma_ctx);
@@ -2446,7 +2439,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep,
        dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
 
        /* Lock the pages of the buffer and translate them to pages */
-       if (is_kva == true) {
+       if (is_kva) {
                dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel input pages\n",
                                                current->pid);
                error = sep_lock_kernel_pages(sep, app_virt_in_addr,
@@ -2490,7 +2483,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep,
                        goto end_function;
                }
 
-               if (dma_ctx->secure_dma == true) {
+               if (dma_ctx->secure_dma) {
                        /* secure_dma requires use of non accessible memory */
                        dev_dbg(&sep->pdev->dev, "[PID%d] in secure_dma\n",
                                current->pid);
@@ -2727,11 +2720,11 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
        dcb_table_ptr->tail_data_size = 0;
        dcb_table_ptr->out_vr_tail_pt = 0;
 
-       if (isapplet == true) {
+       if (isapplet) {
 
                /* Check if there is enough data for DMA operation */
                if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) {
-                       if (is_kva == true) {
+                       if (is_kva) {
                                error = -ENODEV;
                                goto end_function_error;
                        } else {
@@ -2772,7 +2765,7 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
                if (tail_size) {
                        if (tail_size > sizeof(dcb_table_ptr->tail_data))
                                return -EINVAL;
-                       if (is_kva == true) {
+                       if (is_kva) {
                                error = -ENODEV;
                                goto end_function_error;
                        } else {
@@ -2883,7 +2876,7 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet,
        if (!dma_ctx || !*dma_ctx) /* nothing to be done here*/
                return 0;
 
-       if (((*dma_ctx)->secure_dma == false) && (isapplet == true)) {
+       if (!(*dma_ctx)->secure_dma && isapplet) {
                dev_dbg(&sep->pdev->dev, "[PID%d] handling applet\n",
                        current->pid);
 
@@ -2902,7 +2895,7 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet,
                                pt_hold = (unsigned long)dcb_table_ptr->
                                        out_vr_tail_pt;
                                tail_pt = (void *)pt_hold;
-                               if (is_kva == true) {
+                               if (is_kva) {
                                        error = -ENODEV;
                                        break;
                                } else {
@@ -4080,6 +4073,7 @@ static int sep_register_driver_with_fs(struct sep_device *sep)
        if (ret_val) {
                dev_warn(&sep->pdev->dev, "sysfs attribute1 fails for SEP %x\n",
                        ret_val);
+               misc_deregister(&sep->miscdev_sep);
                return ret_val;
        }
 
index cfa1f43fa4af08a6ffaa4d09a0d9202458c15ece..8154a7bf050fe7a1d7607e80bdbc889669b3b972 100644 (file)
@@ -22,7 +22,7 @@ do {                                          \
        int  i;                                 \
        if (1) {                                \
                for (i = 0; i < 1000; i++) {    \
-                       udelay(x) ;             \
+                       udelay(x)             \
                }                               \
        } else {                                \
                msleep(x);                      \
index 495272d0134859bf36f080bd7a5c53bc5e0ae708..39dc92a271aba2a1f341a224bd59089fa2ba3870 100644 (file)
@@ -1,11 +1,11 @@
 /******************************************************************************/
 /*                                                                            */
-/* Bypass Control utility, Copyright (c) 2005-20011 Silicom                   */
+/* Bypass Control utility, Copyright (c) 2005-2011 Silicom                    */
 /*                                                                            */
 /* 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, located in the file LICENSE.                 */
-/*  Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.          */
+/* Copyright(c) 2007 - 2009, 2013 Intel Corporation. All rights reserved.     */
 /*                                                                            */
 /*                                                                            */
 /******************************************************************************/
@@ -124,80 +124,60 @@ int bp_proc_create(void);
 int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
 int get_dev_idx_bsf(int bus, int slot, int func);
 
-static unsigned long str_to_hex(char *p);
+static int bp_get_dev_idx_bsf(struct net_device *dev, int *index)
+{
+       struct ethtool_drvinfo drvinfo = {0};
+       char *buf;
+       int bus, slot, func;
+
+       if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
+               dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
+       else
+               return -EOPNOTSUPP;
+
+       if (!drvinfo.bus_info)
+               return -ENODATA;
+       if (!strcmp(drvinfo.bus_info, "N/A"))
+               return -ENODATA;
+
+       buf = strchr(drvinfo.bus_info, ':');
+       if (!buf)
+               return -EINVAL;
+       buf++;
+       if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3)
+               return -EINVAL;
+
+       *index = get_dev_idx_bsf(bus, slot, func);
+       return 0;
+}
+
 static int bp_device_event(struct notifier_block *unused,
                           unsigned long event, void *ptr)
 {
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        static struct bpctl_dev *pbpctl_dev, *pbpctl_dev_m;
        int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;
+
        /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
        /* return NOTIFY_DONE; */
        if (!dev)
                return NOTIFY_DONE;
-       if (event == NETDEV_REGISTER) {
-               {
-                       struct ethtool_drvinfo drvinfo;
-                       char cbuf[32];
-                       char *buf = NULL;
-                       char res[10];
-                       int i = 0, ifindex, idx_dev = 0;
-                       int bus = 0, slot = 0, func = 0;
-                       ifindex = dev->ifindex;
-
-                       memset(res, 0, 10);
-                       memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
-
-                       if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
-                               memset(&drvinfo, 0, sizeof(drvinfo));
-                               dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
-                       } else
-                               return NOTIFY_DONE;
-                       if (!drvinfo.bus_info)
-                               return NOTIFY_DONE;
-                       if (!strcmp(drvinfo.bus_info, "N/A"))
-                               return NOTIFY_DONE;
-                       memcpy(&cbuf, drvinfo.bus_info, 32);
-                       buf = &cbuf[0];
 
-                       while (*buf++ != ':')
-                               ;
-                       for (i = 0; i < 10; i++, buf++) {
-                               if (*buf == ':')
-                                       break;
-                               res[i] = *buf;
-
-                       }
-                       buf++;
-                       bus = str_to_hex(res);
-                       memset(res, 0, 10);
-
-                       for (i = 0; i < 10; i++, buf++) {
-                               if (*buf == '.')
-                                       break;
-                               res[i] = *buf;
-
-                       }
-                       buf++;
-                       slot = str_to_hex(res);
-                       func = str_to_hex(buf);
-                       idx_dev = get_dev_idx_bsf(bus, slot, func);
-
-                       if (idx_dev != -1) {
+       if (event == NETDEV_REGISTER) {
+               int idx_dev;
 
-                               bpctl_dev_arr[idx_dev].ifindex = ifindex;
-                               bpctl_dev_arr[idx_dev].ndev = dev;
+               if (bp_get_dev_idx_bsf(dev, &idx_dev))
+                       return NOTIFY_DONE;
 
-                               bypass_proc_remove_dev_sd(&bpctl_dev_arr
-                                                         [idx_dev]);
-                               bypass_proc_create_dev_sd(&bpctl_dev_arr
-                                                         [idx_dev]);
+               if (idx_dev == -1)
+                       return NOTIFY_DONE;
 
-                       }
+               bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
+               bpctl_dev_arr[idx_dev].ndev = dev;
 
-               }
+               bypass_proc_remove_dev_sd(&bpctl_dev_arr[idx_dev]);
+               bypass_proc_create_dev_sd(&bpctl_dev_arr[idx_dev]);
                return NOTIFY_DONE;
-
        }
        if (event == NETDEV_UNREGISTER) {
                int idx_dev = 0;
@@ -5269,36 +5249,6 @@ int get_dev_idx_bsf(int bus, int slot, int func)
        return -1;
 }
 
-static void str_low(char *str)
-{
-       int i;
-
-       for (i = 0; i < strlen(str); i++)
-               if ((str[i] >= 65) && (str[i] <= 90))
-                       str[i] += 32;
-}
-
-static unsigned long str_to_hex(char *p)
-{
-       unsigned long hex = 0;
-       unsigned long length = strlen(p), shift = 0;
-       unsigned char dig = 0;
-
-       str_low(p);
-       length = strlen(p);
-
-       if (length == 0)
-               return 0;
-
-       do {
-               dig = p[--length];
-               dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa);
-               hex |= (dig << shift);
-               shift += 4;
-       } while (length);
-       return hex;
-}
-
 static int get_dev_idx(int ifindex)
 {
        int idx_dev = 0;
@@ -5329,70 +5279,26 @@ static struct bpctl_dev *get_dev_idx_p(int ifindex)
 
 static void if_scan_init(void)
 {
-       int idx_dev = 0;
        struct net_device *dev;
-       int ifindex;
+
        /* rcu_read_lock(); */
        /* rtnl_lock();     */
        /* rcu_read_lock(); */
 
        for_each_netdev(&init_net, dev) {
+               int idx_dev;
 
-               struct ethtool_drvinfo drvinfo;
-               char cbuf[32];
-               char *buf = NULL;
-               char res[10];
-               int i = 0;
-               int bus = 0, slot = 0, func = 0;
-               ifindex = dev->ifindex;
-
-               memset(res, 0, 10);
-               memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
-
-               if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
-                       memset(&drvinfo, 0, sizeof(drvinfo));
-                       dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
-               } else
+               if (bp_get_dev_idx_bsf(dev, &idx_dev))
                        continue;
-               if (!strcmp(drvinfo.bus_info, "N/A"))
-                       continue;
-               memcpy(&cbuf, drvinfo.bus_info, 32);
-               buf = &cbuf[0];
 
-               while (*buf++ != ':')
-                       ;
-               for (i = 0; i < 10; i++, buf++) {
-                       if (*buf == ':')
-                               break;
-                       res[i] = *buf;
-
-               }
-               buf++;
-               bus = str_to_hex(res);
-               memset(res, 0, 10);
-
-               for (i = 0; i < 10; i++, buf++) {
-                       if (*buf == '.')
-                               break;
-                       res[i] = *buf;
-
-               }
-               buf++;
-               slot = str_to_hex(res);
-               func = str_to_hex(buf);
-               idx_dev = get_dev_idx_bsf(bus, slot, func);
-
-               if (idx_dev != -1) {
-
-                       bpctl_dev_arr[idx_dev].ifindex = ifindex;
-                       bpctl_dev_arr[idx_dev].ndev = dev;
-
-               }
+               if (idx_dev == -1)
+                       continue;
 
+               bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
+               bpctl_dev_arr[idx_dev].ndev = dev;
        }
        /* rtnl_unlock();     */
        /* rcu_read_unlock(); */
-
 }
 
 static long device_ioctl(struct file *file,    /* see include/linux/fs.h */
index 869dcd3b385accb8606d8f53c73b298986c4712c..652272b96a56c68a51d1031cc60c315add73cb08 100644 (file)
@@ -62,6 +62,7 @@
 #define SLIC_OFFLOAD_IP_CHECKSUM               1
 #define STATS_TIMER_INTERVAL                   2
 #define PING_TIMER_INTERVAL                        1
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -791,8 +792,8 @@ static bool slic_mac_filter(struct adapter *adapter,
                        struct mcast_address *mcaddr = adapter->mcastaddrs;
 
                        while (mcaddr) {
-                               if (!compare_ether_addr(mcaddr->address,
-                                                       ether_frame->ether_dhost)) {
+                               if (ether_addr_equal(mcaddr->address,
+                                                    ether_frame->ether_dhost)) {
                                        adapter->rcv_multicasts++;
                                        netdev->stats.multicast++;
                                        return true;
@@ -1834,7 +1835,7 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
 #endif
 
        seq_printf(seq, "driver_version           : %s\n", slic_proc_version);
-       seq_printf(seq, "Microcode versions:           \n");
+       seq_puts(seq, "Microcode versions:           \n");
        seq_printf(seq, "    Gigabit (gb)         : %s %s\n",
                    MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
        seq_printf(seq, "    Gigabit Receiver     : %s %s\n",
@@ -1865,8 +1866,8 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
                           config->macinfo[i].macaddrA[4],
                           config->macinfo[i].macaddrA[5]);
        }
-       seq_printf(seq, "     IF  Init State Duplex/Speed irq\n");
-       seq_printf(seq, "     -------------------------------\n");
+       seq_puts(seq, "     IF  Init State Duplex/Speed irq\n");
+       seq_puts(seq, "     -------------------------------\n");
        for (i = 0; i < card->adapters_allocated; i++) {
                struct adapter *adapter;
 
@@ -1909,7 +1910,7 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
        switch (config->FruFormat) {
        case ATK_FRU_FORMAT:
                {
-                       seq_printf(seq,
+                       seq_puts(seq,
                            "Vendor                   : Alacritech, Inc.\n");
                        seq_printf(seq,
                            "Assembly #               : %c%c%c%c%c%c\n",
@@ -1942,9 +1943,9 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
 
        default:
                {
-                       seq_printf(seq,
+                       seq_puts(seq,
                            "Vendor                   : Alacritech, Inc.\n");
-                       seq_printf(seq,
+                       seq_puts(seq,
                            "Serial   #               : Empty FRU\n");
                        break;
                }
@@ -1953,7 +1954,7 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
        switch (config->OEMFruFormat) {
        case VENDOR1_FRU_FORMAT:
                {
-                       seq_printf(seq, "FRU Information:\n");
+                       seq_puts(seq, "FRU Information:\n");
                        seq_printf(seq, "    Commodity #          : %c\n",
                                    oemfru[0]);
                        seq_printf(seq,
@@ -1976,7 +1977,7 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
 
        case VENDOR2_FRU_FORMAT:
                {
-                       seq_printf(seq, "FRU Information:\n");
+                       seq_puts(seq, "FRU Information:\n");
                        seq_printf(seq,
                                    "    Part     #           : "
                                    "%c%c%c%c%c%c%c%c\n",
@@ -1999,12 +2000,12 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
 
        case VENDOR3_FRU_FORMAT:
                {
-                       seq_printf(seq, "FRU Information:\n");
+                       seq_puts(seq, "FRU Information:\n");
                }
 
        case VENDOR4_FRU_FORMAT:
                {
-                       seq_printf(seq, "FRU Information:\n");
+                       seq_puts(seq, "FRU Information:\n");
                        seq_printf(seq,
                                    "    FRU Number           : "
                                    "%c%c%c%c%c%c%c%c\n",
@@ -2231,14 +2232,8 @@ static void slic_debug_card_destroy(struct sliccard *card)
                if (adapter)
                        slic_debug_adapter_destroy(adapter);
        }
-       if (card->debugfs_cardinfo) {
-               debugfs_remove(card->debugfs_cardinfo);
-               card->debugfs_cardinfo = NULL;
-       }
-       if (card->debugfs_dir) {
-               debugfs_remove(card->debugfs_dir);
-               card->debugfs_dir = NULL;
-       }
+       debugfs_remove(card->debugfs_cardinfo);
+       debugfs_remove(card->debugfs_dir);
 }
 
 static void slic_debug_init(void)
@@ -2256,10 +2251,7 @@ static void slic_debug_init(void)
 
 static void slic_debug_cleanup(void)
 {
-       if (slic_debugfs) {
-               debugfs_remove(slic_debugfs);
-               slic_debugfs = NULL;
-       }
+       debugfs_remove(slic_debugfs);
 }
 
 /*
@@ -2333,7 +2325,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address)
        /* Check to see if it already exists */
        mlist = adapter->mcastaddrs;
        while (mlist) {
-               if (!compare_ether_addr(mlist->address, address))
+               if (ether_addr_equal(mlist->address, address))
                        return 0;
                mlist = mlist->next;
        }
@@ -2627,6 +2619,67 @@ static void slic_xmit_complete(struct adapter *adapter)
        adapter->max_isr_xmits = max(adapter->max_isr_xmits, frames);
 }
 
+static void slic_interrupt_card_up(u32 isr, struct adapter *adapter,
+                       struct net_device *dev)
+{
+       if (isr & ~ISR_IO) {
+               if (isr & ISR_ERR) {
+                       adapter->error_interrupts++;
+                       if (isr & ISR_RMISS) {
+                               int count;
+                               int pre_count;
+                               int errors;
+
+                               struct slic_rcvqueue *rcvq =
+                                       &adapter->rcvqueue;
+
+                               adapter->error_rmiss_interrupts++;
+
+                               if (!rcvq->errors)
+                                       rcv_count = rcvq->count;
+                               pre_count = rcvq->count;
+                               errors = rcvq->errors;
+
+                               while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
+                                       count = slic_rcvqueue_fill(adapter);
+                                       if (!count)
+                                               break;
+                               }
+                       } else if (isr & ISR_XDROP) {
+                               dev_err(&dev->dev,
+                                               "isr & ISR_ERR [%x] "
+                                               "ISR_XDROP \n", isr);
+                       } else {
+                               dev_err(&dev->dev,
+                                               "isr & ISR_ERR [%x]\n",
+                                               isr);
+                       }
+               }
+
+               if (isr & ISR_LEVENT) {
+                       adapter->linkevent_interrupts++;
+                       slic_link_event_handler(adapter);
+               }
+
+               if ((isr & ISR_UPC) || (isr & ISR_UPCERR) ||
+                   (isr & ISR_UPCBSY)) {
+                       adapter->upr_interrupts++;
+                       slic_upr_request_complete(adapter, isr);
+               }
+       }
+
+       if (isr & ISR_RCV) {
+               adapter->rcv_interrupts++;
+               slic_rcv_handler(adapter);
+       }
+
+       if (isr & ISR_CMD) {
+               adapter->xmit_interrupts++;
+               slic_xmit_complete(adapter);
+       }
+}
+
+
 static irqreturn_t slic_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
@@ -2641,64 +2694,7 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
                adapter->num_isrs++;
                switch (adapter->card->state) {
                case CARD_UP:
-                       if (isr & ~ISR_IO) {
-                               if (isr & ISR_ERR) {
-                                       adapter->error_interrupts++;
-                                       if (isr & ISR_RMISS) {
-                                               int count;
-                                               int pre_count;
-                                               int errors;
-
-                                               struct slic_rcvqueue *rcvq =
-                                                   &adapter->rcvqueue;
-
-                                               adapter->
-                                                   error_rmiss_interrupts++;
-                                               if (!rcvq->errors)
-                                                       rcv_count = rcvq->count;
-                                               pre_count = rcvq->count;
-                                               errors = rcvq->errors;
-
-                                               while (rcvq->count <
-                                                      SLIC_RCVQ_FILLTHRESH) {
-                                                       count =
-                                                           slic_rcvqueue_fill
-                                                           (adapter);
-                                                       if (!count)
-                                                               break;
-                                               }
-                                       } else if (isr & ISR_XDROP) {
-                                               dev_err(&dev->dev,
-                                                       "isr & ISR_ERR [%x] "
-                                                       "ISR_XDROP \n", isr);
-                                       } else {
-                                               dev_err(&dev->dev,
-                                                       "isr & ISR_ERR [%x]\n",
-                                                       isr);
-                                       }
-                               }
-
-                               if (isr & ISR_LEVENT) {
-                                       adapter->linkevent_interrupts++;
-                                       slic_link_event_handler(adapter);
-                               }
-
-                               if ((isr & ISR_UPC) ||
-                                   (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
-                                       adapter->upr_interrupts++;
-                                       slic_upr_request_complete(adapter, isr);
-                               }
-                       }
-
-                       if (isr & ISR_RCV) {
-                               adapter->rcv_interrupts++;
-                               slic_rcv_handler(adapter);
-                       }
-
-                       if (isr & ISR_CMD) {
-                               adapter->xmit_interrupts++;
-                               slic_xmit_complete(adapter);
-                       }
+                       slic_interrupt_card_up(isr, adapter, dev);
                        break;
 
                case CARD_DOWN:
@@ -3645,16 +3641,15 @@ static int slic_entry_probe(struct pci_dev *pcidev,
                return err;
 
        if (slic_debug > 0 && did_version++ == 0) {
-               printk(KERN_DEBUG "%s\n", slic_banner);
-               printk(KERN_DEBUG "%s\n", slic_proc_version);
+               dev_dbg(&pcidev->dev, "%s\n", slic_banner);
+               dev_dbg(&pcidev->dev, "%s\n", slic_proc_version);
        }
 
        if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
                pci_using_dac = 1;
                err = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
                if (err) {
-                       dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
-                                       "consistent allocations\n");
+                       dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for consistent allocations\n");
                        goto err_out_disable_pci;
                }
        } else {
@@ -3776,8 +3771,7 @@ static int __init slic_module_init(void)
        slic_init_driver();
 
        if (debug >= 0 && slic_debug != debug)
-               printk(KERN_DEBUG KBUILD_MODNAME ": debug level is %d.\n",
-                      debug);
+               pr_debug("debug level is %d.\n", debug);
        if (debug >= 0)
                slic_debug = debug;
 
index 8add64b1cb0940f69d783083588d65994c5c0e5c..ba199ffff1783cbf08a8892960f3a44c8bbd68cf 100644 (file)
@@ -130,7 +130,8 @@ static int __init sm7xx_vga_setup(char *options)
        for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) {
                if (strstr(options, vesa_mode_table[i].index)) {
                        smtc_scr_info.lfb_width  = vesa_mode_table[i].lfb_width;
-                       smtc_scr_info.lfb_height = vesa_mode_table[i].lfb_height;
+                       smtc_scr_info.lfb_height =
+                                               vesa_mode_table[i].lfb_height;
                        smtc_scr_info.lfb_depth  = vesa_mode_table[i].lfb_depth;
                        return 0;
                }
@@ -259,8 +260,7 @@ static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
                        if (sfb->fb.var.bits_per_pixel == 16) {
                                u32 *pal = sfb->fb.pseudo_palette;
                                val = chan_to_field(red, &sfb->fb.var.red);
-                               val |= chan_to_field(green, \
-                                               &sfb->fb.var.green);
+                               val |= chan_to_field(green, &sfb->fb.var.green);
                                val |= chan_to_field(blue, &sfb->fb.var.blue);
 #ifdef __BIG_ENDIAN
                                pal[regno] =
@@ -274,8 +274,7 @@ static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
                        } else {
                                u32 *pal = sfb->fb.pseudo_palette;
                                val = chan_to_field(red, &sfb->fb.var.red);
-                               val |= chan_to_field(green, \
-                                               &sfb->fb.var.green);
+                               val |= chan_to_field(green, &sfb->fb.var.green);
                                val |= chan_to_field(blue, &sfb->fb.var.blue);
 #ifdef __BIG_ENDIAN
                                val =
@@ -508,9 +507,9 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)
 
                        /* init SEQ register SR30 - SR75 */
                        for (i = 0; i < SIZE_SR30_SR75; i++)
-                               if (((i + 0x30) != 0x62) \
-                                       && ((i + 0x30) != 0x6a) \
-                                       && ((i + 0x30) != 0x6b))
+                               if ((i + 0x30) != 0x62 &&
+                                   (i + 0x30) != 0x6a &&
+                                   (i + 0x30) != 0x6b)
                                        smtc_seqw(i + 0x30,
                                                VGAMode[j].Init_SR30_SR75[i]);
 
@@ -933,7 +932,6 @@ static void smtcfb_pci_remove(struct pci_dev *pdev)
        struct smtcfb_info *sfb;
 
        sfb = pci_get_drvdata(pdev);
-       pci_set_drvdata(pdev, NULL);
        smtc_unmap_smem(sfb);
        smtc_unmap_mmio(sfb);
        unregister_framebuffer(&sfb->fb);
index 8c3e7a60a9be380888cc6450353cbf0c9889880c..efd6f4560d3e55ceeab571fdc1d0ebc242a38df2 100644 (file)
@@ -51,6 +51,7 @@ config SPEAKUP_SYNTH_ACNTSA
 
 config SPEAKUP_SYNTH_ACNTPC
        tristate "Accent PC synthesizer support"
+       depends on ISA || COMPILE_TEST
        ---help---
                This is the Speakup driver for the accent pc
                synthesizer.  You can say y to build it into the kernel,
@@ -102,6 +103,7 @@ config SPEAKUP_SYNTH_DECEXT
 
 config SPEAKUP_SYNTH_DECPC
        depends on m
+       depends on ISA || COMPILE_TEST
        tristate "DECtalk PC (big ISA card) synthesizer support"
        ---help---
 
@@ -124,6 +126,7 @@ config SPEAKUP_SYNTH_DECPC
 
 config SPEAKUP_SYNTH_DTLK
        tristate "DoubleTalk PC synthesizer support"
+       depends on ISA || COMPILE_TEST
        ---help---
 
                This is the Speakup driver for the internal DoubleTalk
@@ -134,6 +137,7 @@ config SPEAKUP_SYNTH_DTLK
 
 config SPEAKUP_SYNTH_KEYPC
        tristate "Keynote Gold PC synthesizer support"
+       depends on ISA || COMPILE_TEST
        ---help---
 
                This is the Speakup driver for the Keynote Gold
index 51bdea3a5beada9a6de419abc9dad9b658355ad3..e2f597ee6261cb143e0f02ef05558734d24e2631 100644 (file)
@@ -585,6 +585,25 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
 }
 EXPORT_SYMBOL_GPL(spk_var_show);
 
+/*
+ * Used to reset either default_pitch or default_vol.
+ */
+static inline void spk_reset_default_value(char *header_name,
+                                       int *synth_default_value, int idx)
+{
+       struct st_var_header *param;
+
+       if (synth && synth_default_value) {
+               param = spk_var_header_by_name(header_name);
+               if (param)  {
+                       spk_set_num_var(synth_default_value[idx],
+                                       param, E_NEW_DEFAULT);
+                       spk_set_num_var(0, param, E_DEFAULT);
+                       pr_info("%s reset to default value\n", param->name);
+               }
+       }
+}
+
 /*
  * This function is called when a user echos a value to one of the
  * variable parameters.
@@ -597,7 +616,7 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
        int len;
        char *cp;
        struct var_t *var_data;
-       int value;
+       long value;
        unsigned long flags;
 
        param = spk_var_header_by_name(attr->attr.name);
@@ -619,61 +638,54 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
                        len = E_INC;
                else
                        len = E_SET;
-               value = simple_strtol(cp, NULL, 10);
-               ret = spk_set_num_var(value, param, len);
+               if (kstrtol(cp, 10, &value) == 0)
+                       ret = spk_set_num_var(value, param, len);
+               else
+                       pr_warn("overflow or parsing error has occured");
                if (ret == -ERANGE) {
                        var_data = param->data;
                        pr_warn("value for %s out of range, expect %d to %d\n",
-                               attr->attr.name,
+                               param->name,
                                var_data->u.n.low, var_data->u.n.high);
                }
+
+              /*
+               * If voice was just changed, we might need to reset our default
+               * pitch and volume.
+               */
+               if (param->var_id == VOICE && synth &&
+                   (ret == 0 || ret == -ERESTART)) {
+                       var_data = param->data;
+                       value = var_data->u.n.value;
+                       spk_reset_default_value("pitch", synth->default_pitch,
+                               value);
+                       spk_reset_default_value("vol", synth->default_vol,
+                               value);
+               }
                break;
        case VAR_STRING:
-               len = strlen(buf);
-               if ((len >= 1) && (buf[len - 1] == '\n'))
+               len = strlen(cp);
+               if ((len >= 1) && (cp[len - 1] == '\n'))
                        --len;
-               if ((len >= 2) && (buf[0] == '"') && (buf[len - 1] == '"')) {
-                       ++buf;
+               if ((len >= 2) && (cp[0] == '"') && (cp[len - 1] == '"')) {
+                       ++cp;
                        len -= 2;
                }
-               cp = (char *) buf;
                cp[len] = '\0';
-               ret = spk_set_string_var(buf, param, len);
+               ret = spk_set_string_var(cp, param, len);
                if (ret == -E2BIG)
                        pr_warn("value too long for %s\n",
-                                       attr->attr.name);
+                                       param->name);
                break;
        default:
                pr_warn("%s unknown type %d\n",
                        param->name, (int)param->var_type);
        break;
        }
-       /*
-        * If voice was just changed, we might need to reset our default
-        * pitch and volume.
-        */
-       if (strcmp(attr->attr.name, "voice") == 0) {
-               if (synth && synth->default_pitch) {
-                       param = spk_var_header_by_name("pitch");
-                       if (param)  {
-                               spk_set_num_var(synth->default_pitch[value],
-                                               param, E_NEW_DEFAULT);
-                               spk_set_num_var(0, param, E_DEFAULT);
-                       }
-               }
-               if (synth && synth->default_vol) {
-                       param = spk_var_header_by_name("vol");
-                       if (param)  {
-                               spk_set_num_var(synth->default_vol[value],
-                                               param, E_NEW_DEFAULT);
-                               spk_set_num_var(0, param, E_DEFAULT);
-                       }
-               }
-       }
        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
 
        if (ret == -ERESTART)
-               pr_info("%s reset to default value\n", attr->attr.name);
+               pr_info("%s reset to default value\n", param->name);
        return count;
 }
 EXPORT_SYMBOL_GPL(spk_var_store);
index 14079c4949a8038e801474a2842f09e38e5bd403..47502fa5f3f60a50db71b21a90be9dc9ce9c54ba 100644 (file)
@@ -90,7 +90,7 @@ const struct st_bits_data spk_punc_info[] = {
        {"repeats", "()", CH_RPT},
        {"extended numeric", "", B_EXNUM},
        {"symbols", "", B_SYM},
-       {0, 0}
+       {NULL, NULL}
 };
 
 static char mark_cut_flag;
index 80141aca712f99039a7584d7b15f0201ce5c953c..1c8a7f4a0ef52035e8954197db31024815974811 100644 (file)
@@ -223,7 +223,7 @@ static void do_catch_up(struct spk_synth *synth)
                if (ch == '\n')
                        ch = PROCSPEECH;
                outb_p(ch, speakup_info.port_tts);
-               if (jiffies >= jiff_max && ch == SPACE) {
+               if (time_after_eq(jiffies, jiff_max) && ch == SPACE) {
                        timeout = SPK_XMITR_TIMEOUT;
                        while (synth_writable()) {
                                if (!--timeout)
index 95d3132f0a35717a2451070f140f2e237260f1bf..70cf1591676a2c2acb0f33bec628e83d719cbc30 100644 (file)
@@ -179,7 +179,7 @@ static void do_catch_up(struct spk_synth *synth)
                        schedule_timeout(msecs_to_jiffies(full_time_val));
                        continue;
                }
-               if ((jiffies >= jiff_max) && (ch == SPACE)) {
+               if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) {
                        spin_lock_irqsave(&speakup_info.spinlock, flags);
                        jiffy_delta_val = jiffy_delta->u.n.value;
                        full_time_val = full_time->u.n.value;
index 3508aee98ab0651e06b831c22d8e3dd80f975ce3..61a3ceeb0d3ae081258400749cfa68110d24e7a2 100644 (file)
@@ -39,7 +39,7 @@ static struct var_t vars[] = {
        { RATE, .u.n = {"\x05[r%d]", 10, 0, 20, 100, -10, NULL } },
        { PITCH, .u.n = {"\x05[f%d]", 80, 39, 4500, 0, 0, NULL } },
        { VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL } },
-       { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, 0 } },
+       { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, NULL } },
        { PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" } },
        { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } },
        V_LAST_VAR
index 9aa2a78cd71cd87dfad5785a9fab9d2f26e497e2..445a3fda380e7b456d49599be9703acadf227e3a 100644 (file)
@@ -46,7 +46,7 @@ static struct st_var_header var_headers[] = {
        { "direct", DIRECT, VAR_NUM, NULL, NULL },
 };
 
-static struct st_var_header *var_ptrs[MAXVARS] = { 0, 0, 0 };
+static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };
 
 static struct punc_var_t punc_vars[] = {
        { PUNC_SOME, 1 },
@@ -280,7 +280,7 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
        if (!cp)
                cp = spk_punc_info[which].value;
        else {
-               for ( ; *cp; cp++) {
+               for (; *cp; cp++) {
                        if (*cp < SPACE)
                                break;
                        if (mask < PUNC) {
@@ -294,11 +294,11 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
                cp = (u_char *)input;
        }
        if (how&2) {
-               for ( ; *cp; cp++)
+               for (; *cp; cp++)
                        if (*cp > SPACE)
                                spk_chartab[*cp] |= mask;
        } else {
-               for ( ; *cp; cp++)
+               for (; *cp; cp++)
                        if (*cp > SPACE)
                                spk_chartab[*cp] &= ~mask;
        }
index 386362c9964ff1e8856adcaa14fa000aa82686f5..28b393071026318eea30591a81e7d66ce250ded7 100644 (file)
@@ -911,8 +911,6 @@ static int synaptics_rmi4_probe
 
        rmi4_data->input_dev = input_allocate_device();
        if (rmi4_data->input_dev == NULL) {
-               dev_err(&client->dev, "%s:input device alloc failed\n",
-                                               __func__);
                retval = -ENOMEM;
                goto err_input;
        }
index d460f5823c6b9a645c465db6d8cafe65223981de..012e4a38d2db70fd4d8df83eb7e770656335ce49 100644 (file)
@@ -36,7 +36,7 @@
 
 /*
  *  ======== dsp_init ========
- *     Allocates bridge resources. Loads a base image onto DSP, if specified.
+ *  Allocates bridge resources. Loads a base image onto DSP, if specified.
  */
 u32 dsp_init(u32 *init_status)
 {
@@ -106,7 +106,7 @@ func_cont:
 
 /*
  *  ======== dsp_deinit ========
- *     Frees the resources allocated for bridge.
+ *  Frees the resources allocated for bridge.
  */
 bool dsp_deinit(u32 device_context)
 {
index d8957a55662642ea248a6cbacbae23924f6122c4..76a1ff0e6275d9c50c1ff37191ef22e1fa38b81e 100644 (file)
@@ -357,8 +357,9 @@ static int stub_probe(struct usb_interface *interface,
        busid_priv = get_busid_priv(udev_busid);
        if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
            (busid_priv->status == STUB_BUSID_OTHER)) {
-               dev_info(&interface->dev, "%s is not in match_busid table... "
-                        "skip!\n", udev_busid);
+               dev_info(&interface->dev,
+                       "%s is not in match_busid table... skip!\n",
+                       udev_busid);
 
                /*
                 * Return value should be ENODEV or ENOXIO to continue trying
@@ -375,8 +376,10 @@ static int stub_probe(struct usb_interface *interface,
        }
 
        if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-               dev_dbg(&udev->dev, "%s is attached on vhci_hcd... skip!\n",
-                        udev_busid);
+               dev_dbg(&udev->dev,
+                       "%s is attached on vhci_hcd... skip!\n",
+                       udev_busid);
+
                return -ENODEV;
        }
 
@@ -386,10 +389,10 @@ static int stub_probe(struct usb_interface *interface,
                        return -ENODEV;
 
                busid_priv->interf_count++;
-               dev_info(&interface->dev, "usbip-host: register new interface "
-                        "(bus %u dev %u ifn %u)\n",
-                        udev->bus->busnum, udev->devnum,
-                        interface->cur_altsetting->desc.bInterfaceNumber);
+               dev_info(&interface->dev,
+                       "usbip-host: register new interface (bus %u dev %u ifn %u)\n",
+                       udev->bus->busnum, udev->devnum,
+                       interface->cur_altsetting->desc.bInterfaceNumber);
 
                /* set private data to usb_interface */
                usb_set_intfdata(interface, sdev);
@@ -412,9 +415,10 @@ static int stub_probe(struct usb_interface *interface,
        if (!sdev)
                return -ENOMEM;
 
-       dev_info(&interface->dev, "usbip-host: register new device "
-                "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
-                interface->cur_altsetting->desc.bInterfaceNumber);
+       dev_info(&interface->dev,
+               "usbip-host: register new device (bus %u dev %u ifn %u)\n",
+               udev->bus->busnum, udev->devnum,
+               interface->cur_altsetting->desc.bInterfaceNumber);
 
        busid_priv->interf_count = 0;
        busid_priv->shutdown_busid = 0;
index 33027cce6700506e6abaca6db07d5f8cf594a6cd..baf857f7cc88ac7873e8acaf790a9cb8de9b5aa3 100644 (file)
@@ -255,14 +255,14 @@ static int __init usbip_host_init(void)
        }
 
        ret = usb_register(&stub_driver);
-       if (ret < 0) {
+       if (ret) {
                pr_err("usb_register failed %d\n", ret);
                goto err_usb_register;
        }
 
        ret = driver_create_file(&stub_driver.drvwrap.driver,
                                 &driver_attr_match_busid);
-       if (ret < 0) {
+       if (ret) {
                pr_err("driver_create_file failed\n");
                goto err_create_file;
        }
index 2be4060f90363a693ffe635955ab462acef98eb8..0ee5d92639962ac65f13c1704e54bcb4dafb53de 100644 (file)
@@ -70,7 +70,6 @@ AC_ARG_WITH([tcp-wrappers],
                       [AC_MSG_RESULT([not found]); exit 1])
             else
                     AC_MSG_RESULT([no]);
-                    LIBS="$saved_LIBS"
             fi],
            dnl [ACTION-IF-NOT-GIVEN]
            [AC_MSG_RESULT([(default)])
index ccdadc87c47824fd56bd2a3a822c1909446961eb..a6097be25d28f6624ff373032e1fcc219490abc6 100644 (file)
@@ -3,7 +3,7 @@
 usbip \- manage USB/IP devices
 .SH SYNOPSIS
 .B usbip
-[\foptions\R] <\fIcommand\fR> <\fIargs\fR>
+[\fIoptions\fR] <\fIcommand\fR> <\fIargs\fR>
 
 .SH DESCRIPTION
 On a USB/IP server, devices can be listed, bound, and unbound using
@@ -23,6 +23,12 @@ Print debugging information.
 Log to syslog.
 .PP
 
+.HP
+\fB\-\-tcp-port PORT\fR
+.IP
+Connect to PORT on remote host (used for attach and list --remote).
+.PP
+
 .SH COMMANDS
 .HP
 \fBversion\fR
index d896936f1780765a7e4306462fc2b461e99e8a42..ac4635db3f0368ded92f66a4c1a815d58057c9e2 100644 (file)
@@ -14,9 +14,21 @@ Devices have to explicitly be exported using
 before usbipd makes them available to other hosts.
 
 The daemon accepts connections from USB/IP clients
-on TCP port 3240.
+on TCP port 3240 by default.
 
 .SH OPTIONS
+.HP
+\fB\-4\fR, \fB\-\-ipv4\fR
+.IP
+Bind to IPv4. Default is both.
+.PP
+
+.HP
+\fB\-6\fR, \fB\-\-ipv6\fR
+.IP
+Bind to IPv6. Default is both.
+.PP
+
 .HP
 \fB\-D\fR, \fB\-\-daemon\fR
 .IP
@@ -29,6 +41,19 @@ Run as a daemon process.
 Print debugging information.
 .PP
 
+.HP
+\fB\-PFILE\fR, \fB\-\-pid FILE\fR
+.IP
+Write process id to FILE.
+.br
+If no FILE specified, use /var/run/usbipd.pid
+.PP
+
+\fB\-tPORT\fR, \fB\-\-tcp\-port PORT\fR
+.IP
+Listen on TCP/IP port PORT.
+.PP
+
 \fB\-h\fR, \fB\-\-help\fR
 .IP
 Print the program help message and exit.
index c39a07f1d38cd0b122bebf572313d46c79d75cac..b4c37e76a6e08f7973bcf324dd87a612d621546d 100644 (file)
 #include <netinet/tcp.h>
 #include <unistd.h>
 
+#ifdef HAVE_LIBWRAP
+#include <tcpd.h>
+#endif
+
 #include "usbip_common.h"
 #include "usbip_network.h"
 
@@ -239,6 +243,18 @@ int usbip_net_set_keepalive(int sockfd)
        return ret;
 }
 
+int usbip_net_set_v6only(int sockfd)
+{
+       const int val = 1;
+       int ret;
+
+       ret = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
+       if (ret < 0)
+               dbg("setsockopt: IPV6_V6ONLY");
+
+       return ret;
+}
+
 /*
  * IPv6 Ready
  */
index 2d0e4277b62be808fa9dc9d87d6339e223e58ea7..f19ae19799b4e13e9740fdcad6d01f0cf306c9bd 100644 (file)
@@ -180,6 +180,7 @@ int usbip_net_recv_op_common(int sockfd, uint16_t *code);
 int usbip_net_set_reuseaddr(int sockfd);
 int usbip_net_set_nodelay(int sockfd);
 int usbip_net_set_keepalive(int sockfd);
+int usbip_net_set_v6only(int sockfd);
 int usbip_net_tcp_connect(char *hostname, char *port);
 
 #endif /* __USBIP_NETWORK_H */
index 1c76cfd274d05e938bb2ce558b995ddeb61916b0..7980f8b5517b4b711f78691607a6970964c29def 100644 (file)
@@ -56,6 +56,13 @@ static const char usbip_version_string[] = PACKAGE_STRING;
 
 static const char usbipd_help_string[] =
        "usage: usbipd [options]\n"
+       "\n"
+       "       -4, --ipv4\n"
+       "               Bind to IPv4. Default is both.\n"
+       "\n"
+       "       -6, --ipv6\n"
+       "               Bind to IPv6. Default is both.\n"
+       "\n"
        "       -D, --daemon\n"
        "               Run as a daemon process.\n"
        "\n"
@@ -354,14 +361,15 @@ static void addrinfo_to_text(struct addrinfo *ai, char buf[],
        snprintf(buf, buf_size, "%s:%s", hbuf, sbuf);
 }
 
-static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
+static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[],
+                            int maxsockfd)
 {
        struct addrinfo *ai;
        int ret, nsockfd = 0;
        const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2;
        char ai_buf[ai_buf_size];
 
-       for (ai = ai_head; ai && nsockfd < MAXSOCKFD; ai = ai->ai_next) {
+       for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) {
                int sock;
                addrinfo_to_text(ai, ai_buf, ai_buf_size);
                dbg("opening %s", ai_buf);
@@ -374,6 +382,9 @@ static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
 
                usbip_net_set_reuseaddr(sock);
                usbip_net_set_nodelay(sock);
+               /* We use seperate sockets for IPv4 and IPv6
+                * (see do_standalone_mode()) */
+               usbip_net_set_v6only(sock);
 
                if (sock >= FD_SETSIZE) {
                        err("FD_SETSIZE: %s: sock=%d, max=%d",
@@ -402,11 +413,6 @@ static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
                sockfdlist[nsockfd++] = sock;
        }
 
-       if (nsockfd == 0)
-               return -1;
-
-       dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
-
        return nsockfd;
 }
 
@@ -473,11 +479,11 @@ static void remove_pid_file()
        }
 }
 
-static int do_standalone_mode(int daemonize)
+static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 {
        struct addrinfo *ai_head;
        int sockfdlist[MAXSOCKFD];
-       int nsockfd;
+       int nsockfd, family;
        int i, terminate;
        struct pollfd *fds;
        struct timespec timeout;
@@ -501,21 +507,36 @@ static int do_standalone_mode(int daemonize)
        set_signal();
        write_pid_file();
 
-       ai_head = do_getaddrinfo(NULL, PF_UNSPEC);
+       info("starting " PROGNAME " (%s)", usbip_version_string);
+
+       /*
+        * To suppress warnings on systems with bindv6only disabled
+        * (default), we use seperate sockets for IPv6 and IPv4 and set
+        * IPV6_V6ONLY on the IPv6 sockets.
+        */
+       if (ipv4 && ipv6)
+               family = AF_UNSPEC;
+       else if (ipv4)
+               family = AF_INET;
+       else
+               family = AF_INET6;
+
+       ai_head = do_getaddrinfo(NULL, family);
        if (!ai_head) {
                usbip_host_driver_close();
                return -1;
        }
-
-       info("starting " PROGNAME " (%s)", usbip_version_string);
-
-       nsockfd = listen_all_addrinfo(ai_head, sockfdlist);
+       nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
+               sizeof(sockfdlist) / sizeof(*sockfdlist));
+       freeaddrinfo(ai_head);
        if (nsockfd <= 0) {
                err("failed to open a listening socket");
-               freeaddrinfo(ai_head);
                usbip_host_driver_close();
                return -1;
        }
+
+       dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
+
        fds = calloc(nsockfd, sizeof(struct pollfd));
        for (i = 0; i < nsockfd; i++) {
                fds[i].fd = sockfdlist[i];
@@ -551,7 +572,6 @@ static int do_standalone_mode(int daemonize)
 
        info("shutting down " PROGNAME);
        free(fds);
-       freeaddrinfo(ai_head);
        usbip_host_driver_close();
 
        return 0;
@@ -560,6 +580,9 @@ static int do_standalone_mode(int daemonize)
 int main(int argc, char *argv[])
 {
        static const struct option longopts[] = {
+               { "ipv4",     no_argument,       NULL, '4' },
+               { "ipv6",     no_argument,       NULL, '6' },
+               { "daemon",   no_argument,       NULL, 'D' },
                { "daemon",   no_argument,       NULL, 'D' },
                { "debug",    no_argument,       NULL, 'd' },
                { "pid",      optional_argument, NULL, 'P' },
@@ -576,6 +599,7 @@ int main(int argc, char *argv[])
        } cmd;
 
        int daemonize = 0;
+       int ipv4 = 0, ipv6 = 0;
        int opt, rc = -1;
        pid_file = NULL;
 
@@ -587,12 +611,18 @@ int main(int argc, char *argv[])
 
        cmd = cmd_standalone_mode;
        for (;;) {
-               opt = getopt_long(argc, argv, "DdP::t:hv", longopts, NULL);
+               opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL);
 
                if (opt == -1)
                        break;
 
                switch (opt) {
+               case '4':
+                       ipv4 = 1;
+                       break;
+               case '6':
+                       ipv6 = 1;
+                       break;
                case 'D':
                        daemonize = 1;
                        break;
@@ -618,9 +648,12 @@ int main(int argc, char *argv[])
                }
        }
 
+       if (!ipv4 && !ipv6)
+               ipv4 = ipv6 = 1;
+
        switch (cmd) {
        case cmd_standalone_mode:
-               rc = do_standalone_mode(daemonize);
+               rc = do_standalone_mode(daemonize, ipv4, ipv6);
                remove_pid_file();
                break;
        case cmd_version:
index d7974cb2cc6f7f499cac46297e41e8f43240f8af..e810ad53e2acfe519a448eedc84830fcc547afae 100644 (file)
@@ -999,12 +999,6 @@ static int vhci_hcd_probe(struct platform_device *pdev)
 
        usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
 
-       /* will be removed */
-       if (pdev->dev.dma_mask) {
-               dev_info(&pdev->dev, "vhci_hcd DMA not supported\n");
-               return -EINVAL;
-       }
-
        /*
         * Allocate and initialize hcd.
         * Our private data is also allocated automatically.
@@ -1146,11 +1140,11 @@ static int __init vhci_hcd_init(void)
                return -ENODEV;
 
        ret = platform_driver_register(&vhci_driver);
-       if (ret < 0)
+       if (ret)
                goto err_driver_register;
 
        ret = platform_device_register(&the_pdev);
-       if (ret < 0)
+       if (ret)
                goto err_platform_device_register;
 
        pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
index 76c8490b0734d212297e8fb00583c73bbaa5716b..7949d58ad7d153e8508556db9f4ef10f349e1c38 100644 (file)
@@ -165,9 +165,8 @@ vMgrDecodeBeacon(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -382,9 +381,8 @@ vMgrDecodeAssocRequest(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -556,9 +554,8 @@ vMgrDecodeReassocRequest(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -742,9 +739,8 @@ vMgrDecodeProbeResponse(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -858,9 +854,9 @@ vMgrDecodeAuthen(
        pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                           + WLAN_AUTHEN_OFF_CHALLENGE);
 
-       if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
+       if (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) &&
+           pItem->byElementID == WLAN_EID_CHALLENGE)
                pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
-       }
 
        return;
 }
index fc056fc6199516cfe7d7f63fdecd5548e9f2e72f..82b0bd1c056a0e9e3cc4e98f600b6242b4769231 100644 (file)
@@ -46,7 +46,7 @@
  * SBOX Table
  */
 
-unsigned char sbox_table[256] =
+static unsigned char 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,
@@ -66,7 +66,7 @@ unsigned char sbox_table[256] =
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 };
 
-unsigned char dot2_table[256] = {
+static unsigned char 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,
@@ -85,7 +85,7 @@ unsigned char dot2_table[256] = {
        0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
 };
 
-unsigned char dot3_table[256] = {
+static unsigned char 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,
@@ -110,7 +110,7 @@ unsigned char dot3_table[256] = {
 
 /*---------------------  Export Functions  --------------------------*/
 
-void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
+static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
 {
        unsigned long *dwPtrA = (unsigned long *)a;
        unsigned long *dwPtrB = (unsigned long *)b;
@@ -122,7 +122,7 @@ void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
 
-void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
+static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
 {
        unsigned long *dwPtrA = (unsigned long *)a;
        unsigned long *dwPtrB = (unsigned long *)b;
@@ -131,7 +131,7 @@ void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
 
-void AddRoundKey(unsigned char *key, int round)
+static void AddRoundKey(unsigned char *key, int round)
 {
        unsigned char sbox_key[4];
        unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
@@ -149,7 +149,7 @@ void AddRoundKey(unsigned char *key, int round)
        xor_32(&key[12], &key[8], &key[12]);
 }
 
-void SubBytes(unsigned char *in, unsigned char *out)
+static void SubBytes(unsigned char *in, unsigned char *out)
 {
        int i;
 
@@ -158,7 +158,7 @@ void SubBytes(unsigned char *in, unsigned char *out)
        }
 }
 
-void ShiftRows(unsigned char *in, unsigned char *out)
+static void ShiftRows(unsigned char *in, unsigned char *out)
 {
        out[0]  = in[0];
        out[1]  = in[5];
@@ -178,7 +178,7 @@ void ShiftRows(unsigned char *in, unsigned char *out)
        out[15] = in[11];
 }
 
-void MixColumns(unsigned char *in, unsigned char *out)
+static void MixColumns(unsigned char *in, unsigned char *out)
 {
        out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
        out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
@@ -186,7 +186,7 @@ void MixColumns(unsigned char *in, unsigned char *out)
        out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
 }
 
-void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
 {
        int  i;
        int  round;
index c26418d806fb335851bb7a688ad1294094cc8a6d..959568a1eb6a03da7260685acec030f8ccebeebf 100644 (file)
@@ -2434,13 +2434,12 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData)
 
        BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10
        // patch for 3253B0 Baseband with Cardbus module
-       if (byData == pDevice->abyBBVGA[0]) {
+       if (byData == pDevice->abyBBVGA[0])
                byBBRxConf |= 0x20;//0010 0000
-       } else if (pDevice->bShortSlotTime) {
+       else if (pDevice->bShortSlotTime)
                byBBRxConf &= 0xDF;//1101 1111
-       } else {
+       else
                byBBRxConf |= 0x20;//0010 0000
-       }
        pDevice->byBBVGACurrent = byData;
        BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10
 }
index f983915168b7883c30a435c4561b8571abb77f75..a23b591eeac3d7432a73e78990342ef0ce65c15d 100644 (file)
@@ -148,7 +148,8 @@ BSSpSearchBSSList(
                        if (pDevice->bLinkPass == false) pCurrBSS->bSelected = false;
                        if ((pCurrBSS->bActive) &&
                            (pCurrBSS->bSelected == false)) {
-                               if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
+                               if (ether_addr_equal(pCurrBSS->abyBSSID,
+                                                    pbyBSSID)) {
                                        if (pSSID != NULL) {
                                                // compare ssid
                                                if (!memcmp(pSSID->abySSID,
@@ -275,7 +276,8 @@ BSSvClearBSSList(
        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                if (bKeepCurrBSSID) {
                        if (pMgmt->sBSSList[ii].bActive &&
-                           !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
+                           ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                            pMgmt->abyCurrBSSID)) {
                                // bKeepCurrBSSID = false;
                                continue;
                        }
@@ -318,7 +320,7 @@ BSSpAddrIsInBSSList(
        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                pBSSList = &(pMgmt->sBSSList[ii]);
                if (pBSSList->bActive) {
-                       if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
+                       if (ether_addr_equal(pBSSList->abyBSSID, abyBSSID)) {
                                if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len) {
                                        if (memcmp(pSSID->abySSID,
                                                   ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
@@ -733,7 +735,8 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr,
        // Index = 0 reserved for AP Node
        for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
                if (pMgmt->sNodeDBTable[ii].bActive) {
-                       if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+                       if (ether_addr_equal(abyDstAddr,
+                                            pMgmt->sNodeDBTable[ii].abyMACAddr)) {
                                *puNodeIndex = ii;
                                return true;
                        }
index 7f36a7103c3ef3812c20963d9f6ab6a51757069b..e93fdc88d84456ed52a8cb6cdaf9c02289c695c2 100644 (file)
@@ -1153,10 +1153,6 @@ static void device_free_info(PSDevice pDevice) {
                pci_release_regions(pDevice->pcid);
        if (dev)
                free_netdev(dev);
-
-       if (pDevice->pcid) {
-               pci_set_drvdata(pDevice->pcid, NULL);
-       }
 }
 
 static bool device_init_rings(PSDevice pDevice) {
index a9533f3f25299cc77e9158712d218347dada3cb3..0ff51cb4a207eeb045720a3884be0eebefc11823 100644 (file)
@@ -172,9 +172,9 @@ s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
        };
 
        pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
-       if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+       if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
                cbHeaderSize += 6;
-       } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+       } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
                cbHeaderSize += 6;
                pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
                if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
@@ -420,7 +420,8 @@ device_receive_frame(
        s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
 
        // filter packet send from myself
-       if (!compare_ether_addr((unsigned char *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
+       if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr,
+                            pDevice->abyCurrentNetAddr))
                return false;
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
index 8acff44a9e753f38481a8b74c6c20a3b62d7f452..aab0012bba92909611659b78ef982d48aec82cfb 100644 (file)
@@ -720,7 +720,6 @@ static int hostap_get_encryption(PSDevice pDevice,
  * Return Value:
  *
  */
-
 int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
 {
        struct viawget_hostapd_param *param;
@@ -731,7 +730,7 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
            p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
                return -EINVAL;
 
-       param = kmalloc((int)p->length, (int)GFP_KERNEL);
+       param = kmalloc((int)p->length, GFP_KERNEL);
        if (param == NULL)
                return -ENOMEM;
 
@@ -755,8 +754,8 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
                break;
        case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
-               return -EOPNOTSUPP;
-               break;
+               ret = -EOPNOTSUPP;
+               goto out;
        case VIAWGET_HOSTAPD_FLUSH:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
                spin_lock_irq(&pDevice->lock);
@@ -790,40 +789,36 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
                ret = hostap_set_flags_sta(pDevice, param);
                break;
-
        case VIAWGET_HOSTAPD_MLME:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
-               return -EOPNOTSUPP;
-
+               ret = -EOPNOTSUPP;
+               goto out;
        case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
                ret = hostap_set_generic_element(pDevice, param);
                break;
-
        case VIAWGET_HOSTAPD_SCAN_REQ:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
-               return -EOPNOTSUPP;
-
+               ret = -EOPNOTSUPP;
+               goto out;
        case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
-               return -EOPNOTSUPP;
-
+               ret = -EOPNOTSUPP;
+               goto out;
        default:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n",
                        (int)param->cmd);
-               return -EOPNOTSUPP;
-               break;
+               ret = -EOPNOTSUPP;
+               goto out;
        }
 
        if ((ret == 0) && ap_ioctl) {
                if (copy_to_user(p->pointer, param, p->length)) {
                        ret = -EFAULT;
-                       goto out;
                }
        }
 
 out:
        kfree(param);
-
        return ret;
 }
index 9de698ef25f5de0511b2f3ebc98c197c4f6566f8..4bff8aa96be71689c707f858f4aed6f20d1acb17 100644 (file)
@@ -663,7 +663,8 @@ int iwctl_siwap(struct net_device *dev,
                        unsigned int ii, uSameBssidNum = 0;
                        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                if (pMgmt->sBSSList[ii].bActive &&
-                                   !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyDesireBSSID)) {
+                                   ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                    pMgmt->abyDesireBSSID)) {
                                        uSameBssidNum++;
                                }
                        }
@@ -840,7 +841,8 @@ int iwctl_siwessid(struct net_device *dev,
                                        //         by means of judging if there are two same BSSID exist in list ?
                                        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                                if (pMgmt->sBSSList[ii].bActive &&
-                                                   !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+                                                   ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                                    pCurr->abyBSSID)) {
                                                        uSameBssidNum++;
                                                }
                                        }
index 92b84b5ea115cd0ee465e097078bbd4bd9866500..04c1304d16e59105b9616029bc6da2a2db0f8abc 100644 (file)
@@ -141,7 +141,7 @@ bool KeybGetKey(
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if (dwKeyIndex == 0xFFFFFFFF) {
                                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
@@ -208,7 +208,7 @@ bool KeybSetKey(
                        j = i;
                }
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        // found table already exist
                        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                                // Pairwise key
@@ -385,7 +385,7 @@ bool KeybRemoveKey(
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                                pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
                                s_vCheckKeyTableValid(pTable, dwIoBase);
@@ -429,7 +429,7 @@ bool KeybRemoveAllKey(
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
                        for (u = 0; u < MAX_GROUP_KEY; u++) {
                                pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
@@ -512,7 +512,7 @@ bool KeybGetTransmitKey(
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if (dwKeyType == PAIRWISE_KEY) {
                                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
index 0828d18ad528ae9ec6ba74f125b7e126052fc4fb..387d20623aa3972d26c3ba1ec0eca2c466b378cd 100644 (file)
@@ -39,18 +39,18 @@ void MIC_vInit(unsigned long dwK0, unsigned long dwK1);
 
 void MIC_vUnInit(void);
 
-// Append bytes to the message to be MICed
+/* Append bytes to the message to be MICed */
 void MIC_vAppend(unsigned char *src, unsigned int nBytes);
 
-// Get the MIC result. Destination should accept 8 bytes of result.
-// This also resets the message to empty.
+/* Get the MIC result. Destination should accept 8 bytes of result. */
+/* This also resets the message to empty. */
 void MIC_vGetMIC(unsigned long *pdwL, unsigned long *pdwR);
 
 /*---------------------  Export Macros ------------------------------*/
 
-// Rotation functions on 32 bit values
+/* Rotation functions on 32 bit values */
 #define ROL32(A, n)                                                    \
        (((A) << (n)) | (((A)>>(32-(n)))  & ((1UL << (n)) - 1)))
 #define ROR32(A, n) ROL32((A), 32-(n))
 
-#endif //__MICHAEL_H__
+#endif /*__MICHAEL_H__ */
index 6948984a25ab0b6295449e5c6b56503179faa240..ce173cc16c192544da18dc3d0dddf09be1ed553a 100644 (file)
@@ -55,7 +55,7 @@
 
 /*---------------------  Static Variables  --------------------------*/
 
-const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
+static const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
        0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
        0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
        0x01A00200+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
@@ -73,7 +73,7 @@ const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
        0x00580F00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
 };
 
-const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
        0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
        0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
        0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -90,7 +90,7 @@ const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
        0x03E7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
 };
 
-const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
        0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
        0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
        0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -107,7 +107,7 @@ const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
        0x06666100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
 };
 
-unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
+static unsigned long dwAL2230PowerTable[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,
@@ -177,7 +177,7 @@ unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
 //{{ RobertYu:20050104
 // 40MHz reference frequency
 // Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
-const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
+static const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
        0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
        0x841FF200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 451FE2
@@ -200,7 +200,7 @@ const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
        0x1ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11a: 12BACF
 };
 
-const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
+static const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
        0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
        0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
        0x451FE200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
@@ -219,7 +219,7 @@ const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
        0x12BACF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11b/g
 };
 
-const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -285,7 +285,7 @@ const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
        0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
 };
 
-const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
        0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
        0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
        0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -349,7 +349,7 @@ const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
        0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
 };
 
-const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
        0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
        0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
        0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -428,7 +428,7 @@ const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool s_bAL7230Init(unsigned long dwIoBase)
+static bool s_bAL7230Init(unsigned long dwIoBase)
 {
        int     ii;
        bool bResult;
@@ -471,7 +471,7 @@ bool s_bAL7230Init(unsigned long dwIoBase)
 }
 
 // Need to Pull PLLON low when writing channel registers through 3-wire interface
-bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
+static bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
 {
        bool bResult;
 
@@ -631,7 +631,7 @@ bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData)
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool RFbAL2230Init(unsigned long dwIoBase)
+static bool RFbAL2230Init(unsigned long dwIoBase)
 {
        int     ii;
        bool bResult;
@@ -678,7 +678,7 @@ bool RFbAL2230Init(unsigned long dwIoBase)
        return bResult;
 }
 
-bool RFbAL2230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
+static bool RFbAL2230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
 {
        bool bResult;
 
@@ -775,36 +775,6 @@ bool RFbInit(
        return bResult;
 }
 
-/*
- * Description: RF ShutDown function
- *
- * Parameters:
- *  In:
- *      byBBType
- *      byRFType
- *  Out:
- *      none
- *
- * Return Value: true if succeeded; false if failed.
- *
- */
-bool RFbShutDown(
-       PSDevice  pDevice
-)
-{
-       bool bResult = true;
-
-       switch (pDevice->byRFType) {
-       case RF_AIROHA7230:
-               bResult = IFRFbWriteEmbedded(pDevice->PortOffset, 0x1ABAEF00 + (BY_AL7230_REG_LEN << 3) + IFREGCTL_REGW);
-               break;
-       default:
-               bResult = true;
-               break;
-       }
-       return bResult;
-}
-
 /*
  * Description: Select channel
  *
index b3e087e19034f31d5aca3494add801586fad3b2e..e7c17c6f7ea56e8bff901a399a2fbfeb2b8f4f07 100644 (file)
@@ -55,7 +55,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 unsigned char TKIP_Sbox_Lower[256] = {
+static const unsigned char 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,
@@ -90,7 +90,7 @@ const unsigned char TKIP_Sbox_Lower[256] = {
        0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A
 };
 
-const unsigned char TKIP_Sbox_Upper[256] = {
+static const unsigned char 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 d8f4f8e7d05eba72281375483ca35fe09f7fbd46..d2bdb71fe62d37a914e5d9fc0c43fff570425320 100644 (file)
@@ -752,25 +752,3 @@ VNTWIFIbChannelSwitch(
        //spin_unlock_irq(&pDevice->lock);
        return true;
 }
-
-/*
-  bool
-  VNTWIFIbRadarPresent(
-  void *pMgmtObject,
-  unsigned char byChannel
-) {
-  PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
-  if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
-  (byChannel == (unsigned char) pMgmt->uCurrChannel) &&
-  (pMgmt->bSwitchChannel != true) &&
-  (pMgmt->b11hEnable == true)) {
-  if (!compare_ether_addr(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) {
-  pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(unsigned char) pMgmt->uCurrChannel);
-  pMgmt->bSwitchChannel = true;
-  }
-  BEACONbSendBeacon(pMgmt);
-  CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10);
-  }
-  return true;
-  }
-*/
index d551653537b4a305c4045b65feadd5714ad84237..9c57eefe78fb12c9109a6aa2930046f3cf03c41b 100644 (file)
@@ -233,7 +233,7 @@ s_vProbeChannel(
  *
  *
  * Return Value:
- *    A ptr to Tx frame or NULL on allocation failue
+ *    A ptr to Tx frame or NULL on allocation failure
  *
  -*/
 
index 9eb81b4eee806b3ccda7331c4a0245182a22ec4d..f05f9f55398bf7a390068495b60ace381a978bc7 100644 (file)
@@ -75,8 +75,8 @@ bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader)
                for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
                        pCacheEntry = &(pCache->asCacheEntry[uIndex]);
                        if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) &&
-                           (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
-) {
+                           ether_addr_equal(pCacheEntry->abyAddr2,
+                                            pMACHeader->abyAddr2)) {
                                /* Duplicate match */
                                return true;
                        }
@@ -111,8 +111,8 @@ unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader)
 
        for (ii = 0; ii < pDevice->cbDFCB; ii++) {
                if ((pDevice->sRxDFCB[ii].bInUse == true) &&
-                   (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
-) {
+                   ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2,
+                                    pMACHeader->abyAddr2)) {
                        //
                        return ii;
                }
index 9938813f997a276227d1cdaae10fc245e97f886b..ed4b32b6d9cee7c4fdf8e1ca6c33ea61b06f928c 100644 (file)
@@ -1680,7 +1680,8 @@ s_vMgrRxDeauthentication(
                        vMgrDecodeDeauthen(&sFrame);
                        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
                        // TODO: update BSS list for specific BSSID if pre-authentication case
-                       if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
+                       if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
+                                            pMgmt->abyCurrBSSID)) {
                                if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
                                        pMgmt->sNodeDBTable[0].bActive = false;
                                        pMgmt->eCurrMode = WMAC_MODE_STANDBY;
index c5293bbcdab5012574ab5d77bbf1f6f8cafe1af2..b697fa6c3b16af995f1af746529b478c6e0df7bf 100644 (file)
 /*---------------------  Static Variables  --------------------------*/
 static int msglevel = MSG_LEVEL_INFO;
 
-const unsigned char abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
-const unsigned char abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
-const unsigned char abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
-const unsigned char abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
-const unsigned char abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
-const unsigned char abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
+static const unsigned char abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
+static const unsigned char abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
+static const unsigned char abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
+static const unsigned char abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
+static const unsigned char abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
+static const unsigned char abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
 
 /*+
  *
index e8d9ecd2913aa32d512e94ddc3ef0fb522904fa2..044368a46c53f332d45f9387722563143139c468 100644 (file)
@@ -394,7 +394,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
 
                } else {
                        // Key Table Full
-                       if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
+                       if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
                                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                                //spin_unlock_irq(&pDevice->lock);
                                return -EINVAL;
index b61328fbee87d41b68789e909c85d360e27577a7..85302c5e2bac41ff6e93ecc439dd4efd78eb7bf5 100644 (file)
@@ -179,7 +179,7 @@ bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uData
                pHeadTD = pHeadTD->next;
        }
 
-       pLastTD->pTDInfo->skb = 0;
+       pLastTD->pTDInfo->skb = NULL;
        pLastTD->pTDInfo->byFlags = 0;
 
        pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
index 5ecc190ae775581e41224cedcfc48fa5876b3b4e..3abc1d36f89dedab58e9e8840c30722b7ae979f7 100644 (file)
@@ -41,4 +41,4 @@
 
 bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex);
 
-#endif // __WROUTE_H__
+#endif /* __WROUTE_H__ */
index 28a4c4c30416cc7fb699a6d593216d3d1a3a8839..6c7693911cd614d829fd1ffaa5176e43b104750f 100644 (file)
@@ -96,9 +96,9 @@ u8 dot3_table[256] = {
 
 static void xor_128(u8 *a, u8 *b, u8 *out)
 {
-       u32 * dwPtrA = (u32 *) a;
-       u32 * dwPtrB = (u32 *) b;
-       u32 * dwPtrOut = (u32 *) out;
+       u32 *dwPtrA = (u32 *) a;
+       u32 *dwPtrB = (u32 *) b;
+       u32 *dwPtrOut = (u32 *) out;
 
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
@@ -108,9 +108,9 @@ static void xor_128(u8 *a, u8 *b, u8 *out)
 
 static void xor_32(u8 *a, u8 *b, u8 *out)
 {
-       u32 * dwPtrA = (u32 *) a;
-       u32 * dwPtrB = (u32 *) b;
-       u32 * dwPtrOut = (u32 *) out;
+       u32 *dwPtrA = (u32 *) a;
+       u32 *dwPtrB = (u32 *) b;
+       u32 *dwPtrOut = (u32 *) out;
 
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
@@ -218,7 +218,7 @@ void AESv128(u8 *key, u8 *data, u8 *ciphertext)
  *
  */
 
-bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, u16 wFrameSize)
+bool AESbGenCCMP(u8 *pbyRxKey, u8 *pbyFrame, u16 wFrameSize)
 {
        u8            abyNonce[13];
        u8            MIC_IV[16];
@@ -231,8 +231,8 @@ bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, u16 wFrameSize)
        u8            abyLastCipher[16];
 
        struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *) pbyFrame;
-       u8 *           pbyIV;
-       u8 *           pbyPayload;
+       u8 *pbyIV;
+       u8 *pbyPayload;
        u16            wHLen = 22;
        /* 8 is IV, 8 is MIC, 4 is CRC */
        u16            wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;
index ee79bbdf1a06ad0e48c23a24ba48f40be1d2778e..dad3f8c78e21d196540c62741af4fbbbe305819b 100644 (file)
@@ -57,6 +57,7 @@
 #include "control.h"
 #include "rndis.h"
 #include "iowpa.h"
+#include "power.h"
 
 static int          msglevel                =MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
@@ -126,7 +127,7 @@ PKnownBSS BSSpSearchBSSList(struct vnt_private *pDevice,
 
             if ((pCurrBSS->bActive) &&
                 (pCurrBSS->bSelected == false)) {
-                   if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
+                   if (ether_addr_equal(pCurrBSS->abyBSSID, pbyBSSID)) {
                     if (pSSID != NULL) {
                         // compare ssid
                         if ( !memcmp(pSSID->abySSID,
@@ -242,8 +243,8 @@ void BSSvClearBSSList(struct vnt_private *pDevice, int bKeepCurrBSSID)
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         if (bKeepCurrBSSID) {
             if (pMgmt->sBSSList[ii].bActive &&
-               !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
-                                   pMgmt->abyCurrBSSID)) {
+               ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                pMgmt->abyCurrBSSID)) {
  //mike mark: there are two BSSID's in list. If that AP is in hidden ssid mode, one SSID is null,
  //                 but other's might not be obvious, so if it associate's with your STA,
  //                 you must keep the two of them!!
@@ -277,7 +278,7 @@ PKnownBSS BSSpAddrIsInBSSList(struct vnt_private *pDevice,
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         pBSSList = &(pMgmt->sBSSList[ii]);
         if (pBSSList->bActive) {
-               if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
+               if (ether_addr_equal(pBSSList->abyBSSID, abyBSSID)) {
                 if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
                     if (memcmp(pSSID->abySSID,
                             ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
@@ -623,8 +624,8 @@ int BSSbIsSTAInNodeDB(struct vnt_private *pDevice,
     // Index = 0 reserved for AP Node
     for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
         if (pMgmt->sNodeDBTable[ii].bActive) {
-               if (!compare_ether_addr(abyDstAddr,
-                                       pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+               if (ether_addr_equal(abyDstAddr,
+                                    pMgmt->sNodeDBTable[ii].abyMACAddr)) {
                 *puNodeIndex = ii;
                 return true;
             }
@@ -813,8 +814,10 @@ void BSSvAddMulticastNode(struct vnt_private *pDevice)
  *
 -*/
 
-void BSSvSecondCallBack(struct vnt_private *pDevice)
+void BSSvSecondCallBack(struct work_struct *work)
 {
+       struct vnt_private *pDevice = container_of(work,
+                       struct vnt_private, second_callback_work.work);
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        int ii;
        PWLAN_IE_SSID pItemSSID, pCurrSSID;
@@ -822,6 +825,9 @@ void BSSvSecondCallBack(struct vnt_private *pDevice)
        u32 uNonShortSlotSTACnt = 0;
        u32 uLongPreambleSTACnt = 0;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     spin_lock_irq(&pDevice->lock);
 
     pDevice->uAssocCount = 0;
@@ -1119,15 +1125,26 @@ else {
         }
     }
 
-    if (pDevice->bLinkPass == true) {
-        if (netif_queue_stopped(pDevice->dev))
-            netif_wake_queue(pDevice->dev);
-    }
+       if (pDevice->bLinkPass == true) {
+               if (pMgmt->eAuthenMode < WMAC_AUTH_WPA ||
+                       pDevice->fWPA_Authened == true) {
+                       if (++pDevice->tx_data_time_out > 40) {
+                               pDevice->tx_trigger = true;
+
+                               PSbSendNullPacket(pDevice);
+
+                               pDevice->tx_trigger = false;
+                               pDevice->tx_data_time_out = 0;
+                       }
+               }
+
+               if (netif_queue_stopped(pDevice->dev))
+                       netif_wake_queue(pDevice->dev);
+       }
 
     spin_unlock_irq(&pDevice->lock);
 
-    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
-    add_timer(&pMgmt->sTimerSecondCallback);
+       schedule_delayed_work(&pDevice->second_callback_work, HZ);
 }
 
 /*+
index bce3b46541656f71a603ad6d402db19813f7e2c3..fc418555bc4d983dcc98a3776440ea86374dabe1 100644 (file)
@@ -262,7 +262,7 @@ void BSSvCreateOneNode(struct vnt_private *, u32 *puNodeIndex);
 void BSSvUpdateAPNode(struct vnt_private *, u16 *pwCapInfo,
        PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pExtSuppRates);
 
-void BSSvSecondCallBack(struct vnt_private *);
+void BSSvSecondCallBack(struct work_struct *work);
 
 void BSSvUpdateNodeTxCounter(struct vnt_private *, PSStatCounter pStatistic,
        u8 byTSR, u8 byPktNO);
index 5158ff4b346a135db1dda3cc225f1e4405cc5edd..e430b35463b6b3595aa52a7fa8bb4962c9aff0f0 100644 (file)
@@ -403,7 +403,7 @@ exit:
 
 void CHvInitChannelTable(struct vnt_private *pDevice)
 {
-       int bMultiBand = false;
+       bool bMultiBand = false;
        int ii;
 
     for (ii = 1; ii <= CB_MAX_CHANNEL; ii++)
index 17fbc35ebcbfe4022fbfe40afbac8faf2c89eb54..af9eab0c00a317d0513b84f52e5ba98cc995d083 100644 (file)
@@ -44,9 +44,9 @@
 #include "rf.h"
 
 /* static int msglevel = MSG_LEVEL_DEBUG; */
-static int          msglevel                =MSG_LEVEL_INFO;
-const u8 acbyIERate[MAX_RATE] =
-{0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+static int msglevel = MSG_LEVEL_INFO;
+const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18,
+       0x24, 0x30, 0x48, 0x60, 0x6C};
 
 #define AUTORATE_TXOK_CNT       0x0400
 #define AUTORATE_TXFAIL_CNT     0x0064
@@ -56,13 +56,13 @@ void s_vResetCounter(PKnownNodeDB psNodeDBTable);
 
 void s_vResetCounter(PKnownNodeDB psNodeDBTable)
 {
-    u8            ii;
+       u8 ii;
 
-    /* clear statistics counter for auto_rate */
-    for (ii = 0; ii <= MAX_RATE; ii++) {
-        psNodeDBTable->uTxOk[ii] = 0;
-        psNodeDBTable->uTxFail[ii] = 0;
-    }
+       /* clear statistics counter for auto_rate */
+       for (ii = 0; ii <= MAX_RATE; ii++) {
+               psNodeDBTable->uTxOk[ii] = 0;
+               psNodeDBTable->uTxFail[ii] = 0;
+       }
 }
 
 /*+
@@ -97,21 +97,18 @@ void s_vResetCounter(PKnownNodeDB psNodeDBTable)
  * Return Value: RateIdx
  *
 -*/
-u16
-RATEwGetRateIdx(
-     u8 byRate
-    )
+u16 RATEwGetRateIdx(u8 byRate)
 {
-    u16    ii;
+       u16 ii;
 
-    /* erase BasicRate flag */
-    byRate = byRate & 0x7F;
+       /* erase BasicRate flag */
+       byRate = byRate & 0x7F;
 
-    for (ii = 0; ii < MAX_RATE; ii ++) {
-        if (acbyIERate[ii] == byRate)
-            return ii;
-    }
-    return 0;
+       for (ii = 0; ii < MAX_RATE; ii++) {
+               if (acbyIERate[ii] == byRate)
+                       return ii;
+       }
+       return 0;
 }
 
 /*+
@@ -139,7 +136,7 @@ void RATEvParseMaxRate(struct vnt_private *pDevice,
        int bUpdateBasicRate, u16 *pwMaxBasicRate, u16 *pwMaxSuppRate,
        u16 *pwSuppRate, u8 *pbyTopCCKRate, u8 *pbyTopOFDMRate)
 {
-       int  ii;
+       int ii;
        u8 byHighSuppRate = 0, byRate = 0;
        u16 wOldBasicRate = pDevice->wBasicRate;
        u32 uRateLen;
@@ -147,83 +144,88 @@ void RATEvParseMaxRate(struct vnt_private *pDevice,
        if (pItemRates == NULL)
                return;
 
-    *pwSuppRate = 0;
-    uRateLen = pItemRates->len;
-
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
-    if (pDevice->byBBType != BB_TYPE_11B) {
-        if (uRateLen > WLAN_RATES_MAXLEN)
-            uRateLen = WLAN_RATES_MAXLEN;
-    } else {
-        if (uRateLen > WLAN_RATES_MAXLEN_11B)
-            uRateLen = WLAN_RATES_MAXLEN_11B;
-    }
-
-    for (ii = 0; ii < uRateLen; ii++) {
-       byRate = (u8)(pItemRates->abyRates[ii]);
-        if (WLAN_MGMT_IS_BASICRATE(byRate) &&
-            (bUpdateBasicRate == true))  {
-         /*
-          * add to basic rate set, update pDevice->byTopCCKBasicRate and
-          * pDevice->byTopOFDMBasicRate
-          */
-               CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
-        }
-        byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
-        if (byHighSuppRate == 0)
-            byHighSuppRate = byRate;
-        if (byRate > byHighSuppRate)
-            byHighSuppRate = byRate;
-        *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
-    }
-    if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
-        (pDevice->byBBType != BB_TYPE_11B)) {
-
-       unsigned int uExtRateLen = pItemExtRates->len;
-
-        if (uExtRateLen > WLAN_RATES_MAXLEN)
-            uExtRateLen = WLAN_RATES_MAXLEN;
-
-        for (ii = 0; ii < uExtRateLen ; ii++) {
-            byRate = (u8)(pItemExtRates->abyRates[ii]);
-           /* select highest basic rate */
-            if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
-             /*
-              * add to basic rate set, update pDevice->byTopCCKBasicRate and
-              * pDevice->byTopOFDMBasicRate
-              */
-                   CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
-            }
-            byRate = (u8)(pItemExtRates->abyRates[ii]&0x7F);
-            if (byHighSuppRate == 0)
-                byHighSuppRate = byRate;
-            if (byRate > byHighSuppRate)
-                byHighSuppRate = byRate;
-            *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
-
-           /* DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n",
-              RATEwGetRateIdx(byRate), byRate)); */
-        }
-    }
-
-    if ((pDevice->byPacketType == PK_TYPE_11GB)
-       && CARDbIsOFDMinBasicRate((void *)pDevice)) {
-        pDevice->byPacketType = PK_TYPE_11GA;
-    }
-
-    *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
-    *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
-    *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
-    if ((pDevice->byPacketType==PK_TYPE_11B) || (pDevice->byPacketType==PK_TYPE_11GB))
-       *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
-    else
-       *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
-    if (wOldBasicRate != pDevice->wBasicRate)
-       CARDvSetRSPINF((void *)pDevice, pDevice->byBBType);
-
-     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
+       *pwSuppRate = 0;
+       uRateLen = pItemRates->len;
+
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
+       if (pDevice->byBBType != BB_TYPE_11B) {
+               if (uRateLen > WLAN_RATES_MAXLEN)
+                       uRateLen = WLAN_RATES_MAXLEN;
+       } else {
+               if (uRateLen > WLAN_RATES_MAXLEN_11B)
+                       uRateLen = WLAN_RATES_MAXLEN_11B;
+       }
+
+       for (ii = 0; ii < uRateLen; ii++) {
+               byRate = (u8)(pItemRates->abyRates[ii]);
+               if (WLAN_MGMT_IS_BASICRATE(byRate) &&
+                               (bUpdateBasicRate == true)) {
+                       /*
+                        * add to basic rate set, update pDevice->byTopCCKBasicRate and
+                        * pDevice->byTopOFDMBasicRate
+                        */
+                       CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
+                       DBG_PRT(MSG_LEVEL_DEBUG,
+                               KERN_INFO"ParseMaxRate AddBasicRate: %d\n",
+                               RATEwGetRateIdx(byRate));
+               }
+               byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
+               if (byHighSuppRate == 0)
+                       byHighSuppRate = byRate;
+               if (byRate > byHighSuppRate)
+                       byHighSuppRate = byRate;
+               *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+       }
+       if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
+                       (pDevice->byBBType != BB_TYPE_11B)) {
+
+               unsigned int uExtRateLen = pItemExtRates->len;
+
+               if (uExtRateLen > WLAN_RATES_MAXLEN)
+                       uExtRateLen = WLAN_RATES_MAXLEN;
+
+               for (ii = 0; ii < uExtRateLen; ii++) {
+                       byRate = (u8)(pItemExtRates->abyRates[ii]);
+                       /* select highest basic rate */
+                       if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
+                               /*
+                                * add to basic rate set, update pDevice->byTopCCKBasicRate and
+                                * pDevice->byTopOFDMBasicRate
+                                */
+                               CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
+                               DBG_PRT(MSG_LEVEL_DEBUG,
+                                               KERN_INFO"ParseMaxRate AddBasicRate: %d\n",
+                                               RATEwGetRateIdx(byRate));
+                       }
+                       byRate = (u8)(pItemExtRates->abyRates[ii]&0x7F);
+                       if (byHighSuppRate == 0)
+                               byHighSuppRate = byRate;
+                       if (byRate > byHighSuppRate)
+                               byHighSuppRate = byRate;
+                       *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+
+                       /* DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n",
+                        * RATEwGetRateIdx(byRate), byRate));
+                        */
+               }
+       }
+
+       if ((pDevice->byPacketType == PK_TYPE_11GB)
+                       && CARDbIsOFDMinBasicRate((void *)pDevice)) {
+               pDevice->byPacketType = PK_TYPE_11GA;
+       }
+
+       *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
+       *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
+       *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
+       if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB))
+               *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
+       else
+               *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
+       if (wOldBasicRate != pDevice->wBasicRate)
+               CARDvSetRSPINF((void *)pDevice, pDevice->byBBType);
+
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
 }
 
 /*+
@@ -263,71 +265,68 @@ void RATEvTxRateFallBack(struct vnt_private *pDevice,
 
        psNodeDBTable->uTimeCount++;
 
-    if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
-        dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
-
-    if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
-        (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
-        (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
-        return;
-    }
-
-    if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) {
-        psNodeDBTable->uTimeCount = 0;
-    }
-
-    for (ii = 0; ii < MAX_RATE; ii++) {
-        if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
-            if (bAutoRate[ii] == true) {
-                wIdxUpRate = (u16) ii;
-            }
-        } else {
-            bAutoRate[ii] = false;
-        }
-    }
-
-    for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
-        if ( (psNodeDBTable->uTxOk[ii] != 0) ||
-             (psNodeDBTable->uTxFail[ii] != 0) ) {
-            dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
-            if (ii < RATE_11M) {
-                psNodeDBTable->uTxFail[ii] *= 4;
-            }
-            dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
-        }
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
-                       ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
-    }
-    dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
-
-    wIdxDownRate = psNodeDBTable->wTxDataRate;
-    for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
-        ii--;
-        if ( (dwThroughputTbl[ii] > dwThroughput) &&
-             (bAutoRate[ii]==true) ) {
-            dwThroughput = dwThroughputTbl[ii];
-            wIdxDownRate = (u16) ii;
-        }
-    }
-    psNodeDBTable->wTxDataRate = wIdxDownRate;
-    if (psNodeDBTable->uTxOk[MAX_RATE]) {
-        if (psNodeDBTable->uTxOk[MAX_RATE] >
-           (psNodeDBTable->uTxFail[MAX_RATE] * 4) ) {
-            psNodeDBTable->wTxDataRate = wIdxUpRate;
-        }
-    } else { /* adhoc, if uTxOk(total) == 0 & uTxFail(total) == 0 */
-        if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
-            psNodeDBTable->wTxDataRate = wIdxUpRate;
-    }
-
-    if (pDevice->byBBType == BB_TYPE_11A) {
-        if (psNodeDBTable->wTxDataRate <= RATE_11M)
-            psNodeDBTable->wTxDataRate = RATE_6M;
-    }
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n",(int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
-    s_vResetCounter(psNodeDBTable);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
-    return;
+       if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
+               dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
+
+       if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
+                       (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
+                       (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
+               return;
+       }
+
+       if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT)
+               psNodeDBTable->uTimeCount = 0;
+
+       for (ii = 0; ii < MAX_RATE; ii++) {
+               if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
+                       if (bAutoRate[ii] == true)
+                               wIdxUpRate = (u16) ii;
+               } else {
+                       bAutoRate[ii] = false;
+               }
+       }
+
+       for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
+               if ((psNodeDBTable->uTxOk[ii] != 0) ||
+                               (psNodeDBTable->uTxFail[ii] != 0)) {
+                       dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
+                       if (ii < RATE_11M)
+                               psNodeDBTable->uTxFail[ii] *= 4;
+                       dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
+               }
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
+                               ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
+       }
+       dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
+
+       wIdxDownRate = psNodeDBTable->wTxDataRate;
+       for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
+               ii--;
+               if ((dwThroughputTbl[ii] > dwThroughput) &&
+                               (bAutoRate[ii] == true)) {
+                       dwThroughput = dwThroughputTbl[ii];
+                       wIdxDownRate = (u16) ii;
+               }
+       }
+       psNodeDBTable->wTxDataRate = wIdxDownRate;
+       if (psNodeDBTable->uTxOk[MAX_RATE]) {
+               if (psNodeDBTable->uTxOk[MAX_RATE] >
+                               (psNodeDBTable->uTxFail[MAX_RATE] * 4)) {
+                       psNodeDBTable->wTxDataRate = wIdxUpRate;
+               }
+       } else { /* adhoc, if uTxOk(total) == 0 & uTxFail(total) == 0 */
+               if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
+                       psNodeDBTable->wTxDataRate = wIdxUpRate;
+       }
+
+       if (pDevice->byBBType == BB_TYPE_11A) {
+               if (psNodeDBTable->wTxDataRate <= RATE_11M)
+                       psNodeDBTable->wTxDataRate = RATE_6M;
+       }
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n", (int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
+       s_vResetCounter(psNodeDBTable);
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
+       return;
 }
 
 /*+
@@ -343,29 +342,24 @@ void RATEvTxRateFallBack(struct vnt_private *pDevice,
  * Return Value: None
  *
 -*/
-u8
-RATEuSetIE (
-     PWLAN_IE_SUPP_RATES pSrcRates,
-     PWLAN_IE_SUPP_RATES pDstRates,
-     unsigned int                uRateLen
-    )
+u8 RATEuSetIE(PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates,
+               unsigned int uRateLen)
 {
-    unsigned int ii, uu, uRateCnt = 0;
-
-    if ((pSrcRates == NULL) || (pDstRates == NULL))
-        return 0;
-
-    if (pSrcRates->len == 0)
-        return 0;
-
-    for (ii = 0; ii < uRateLen; ii++) {
-        for (uu = 0; uu < pSrcRates->len; uu++) {
-            if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
-                pDstRates->abyRates[uRateCnt ++] = pSrcRates->abyRates[uu];
-                break;
-            }
-        }
-    }
-    return (u8)uRateCnt;
+       unsigned int ii, uu, uRateCnt = 0;
+
+       if ((pSrcRates == NULL) || (pDstRates == NULL))
+               return 0;
+
+       if (pSrcRates->len == 0)
+               return 0;
+
+       for (ii = 0; ii < uRateLen; ii++) {
+               for (uu = 0; uu < pSrcRates->len; uu++) {
+                       if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
+                               pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu];
+                               break;
+                       }
+               }
+       }
+       return (u8)uRateCnt;
 }
-
index 4675135aa2583c67c80693889eeffd0e23339440..afe7074c3037e37614121f12077b277fa86cecde 100644 (file)
 /*
  * TX FIFO header
  */
-typedef struct tagSTxBufHead {
-       u32 adwTxKey[4];
-    u16    wFIFOCtl;
-    u16    wTimeStamp;
-    u16    wFragCtl;
-    u16    wReserved;
-} __attribute__ ((__packed__))
-STxBufHead, *PSTxBufHead;
-typedef const STxBufHead *PCSTxBufHead;
 
 typedef struct tagSTxShortBufHead {
     u16    wFIFOCtl;
index 8e396341c5e84aad180e15acbf4d06e74d6a276d..62b7de19b371d2cc7635de9fa339b2b7b78a0143 100644 (file)
@@ -384,8 +384,8 @@ struct vnt_private {
 
        struct tasklet_struct CmdWorkItem;
        struct tasklet_struct EventWorkItem;
-       struct tasklet_struct ReadWorkItem;
-       struct tasklet_struct RxMngWorkItem;
+       struct work_struct read_work_item;
+       struct work_struct rx_mng_work_item;
 
        u32 rx_buf_sz;
        int multicast_limit;
@@ -579,6 +579,9 @@ struct vnt_private {
        u8 abyOFDMAPwrTbl[42];
 
        u16 wCurrentRate;
+       u16 tx_rate_fb0;
+       u16 tx_rate_fb1;
+
        u16 wRTSThreshold;
        u16 wFragmentationThreshold;
        u8 byShortRetryLimit;
@@ -707,13 +710,12 @@ struct vnt_private {
        u8 byBBCR09;
 
        /* command timer */
-       struct timer_list sTimerCommand;
-
-       struct timer_list sTimerTxData;
-       unsigned long nTxDataTimeCout;
-       int fTxDataInSleep;
-       int IsTxDataTrigger;
+       struct delayed_work run_command_work;
+       /* One second callback */
+       struct delayed_work second_callback_work;
 
+       u8 tx_data_time_out;
+       bool tx_trigger;
        int fWPA_Authened; /*is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? */
        u8 byReAssocCount;
        u8 byLinkWaitCount;
index ea7d443b11d067c22f07f41c5c8ac7d2f6fecb03..75dc92d64056a3c30ef25698196fa1c3e4ce326f 100644 (file)
@@ -136,9 +136,9 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
     };
 
     pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
-    if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+    if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
         cbHeaderSize += 6;
-    } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+    } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
         cbHeaderSize += 6;
         pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
        if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||
@@ -361,7 +361,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
     if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
        if (pMgmt->sNodeDBTable[0].bActive) {
-        if (!compare_ether_addr(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
+        if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
            if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
                   pMgmt->sNodeDBTable[0].uInActiveCount = 0;
            }
@@ -374,8 +374,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
             return false;
         }
 
-       if (compare_ether_addr(pDevice->abyCurrentNetAddr,
-                              pMACHeader->addr1)) {
+       if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) {
                return false;
         }
     }
@@ -383,8 +382,8 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
     // Use for TKIP MIC
     s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
 
-    if (!compare_ether_addr((u8 *)&(pDevice->sRxEthHeader.h_source[0]),
-                           pDevice->abyCurrentNetAddr))
+    if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source,
+                        pDevice->abyCurrentNetAddr))
         return false;
 
     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
@@ -560,7 +559,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
             }
             if (pDevice->bIsRxMngWorkItemQueued == false) {
                 pDevice->bIsRxMngWorkItemQueued = true;
-                tasklet_schedule(&pDevice->RxMngWorkItem);
+               schedule_work(&pDevice->rx_mng_work_item);
             }
 
         }
@@ -1333,11 +1332,16 @@ static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb,
     return true;
 }
 
-void RXvWorkItem(struct vnt_private *pDevice)
+void RXvWorkItem(struct work_struct *work)
 {
+       struct vnt_private *pDevice =
+               container_of(work, struct vnt_private, read_work_item);
        int ntStatus;
        struct vnt_rcb *pRCB = NULL;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
     spin_lock_irq(&pDevice->lock);
 
@@ -1384,17 +1388,22 @@ void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb)
         (pDevice->bIsRxWorkItemQueued == false) ) {
 
         pDevice->bIsRxWorkItemQueued = true;
-        tasklet_schedule(&pDevice->ReadWorkItem);
+       schedule_work(&pDevice->read_work_item);
     }
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
 }
 
-void RXvMngWorkItem(struct vnt_private *pDevice)
+void RXvMngWorkItem(struct work_struct *work)
 {
+       struct vnt_private *pDevice =
+               container_of(work, struct vnt_private, rx_mng_work_item);
        struct vnt_rcb *pRCB = NULL;
        struct vnt_rx_mgmt *pRxPacket;
        int bReAllocSkb = false;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
 
     spin_lock_irq(&pDevice->lock);
index 95388dc03ee3993731818fde811342d4f5fbb473..8d524345dfdb943a79df7e027b70f54df6ca9a30 100644 (file)
@@ -32,9 +32,9 @@
 #include "device.h"
 #include "wcmd.h"
 
-void RXvWorkItem(void *Context);
+void RXvWorkItem(struct work_struct *work);
 
-void RXvMngWorkItem(void *Context);
+void RXvMngWorkItem(struct work_struct *work);
 
 void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb);
 
index a1dc3a4cfd9c1e6a47583ea425cfb42ab7d59404..cd2ea76c8b1e1ee70eda84d70cdcce6117978dce 100644 (file)
@@ -35,8 +35,8 @@
 #include "control.h"
 #include "rndis.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; */
 
 #define FIRMWARE_VERSION       0x133           /* version 1.51 */
 #define FIRMWARE_NAME          "vntwusb.fw"
@@ -72,18 +72,17 @@ int FIRMWAREbDownload(struct vnt_private *pDevice)
                memcpy(pBuffer, fw->data + ii, wLength);
 
                NdisStatus = CONTROLnsRequestOutAsyn(pDevice,
-                                            0,
-                                            0x1200+ii,
-                                            0x0000,
-                                            wLength,
-                                            pBuffer
-                                            );
+                                               0,
+                                               0x1200+ii,
+                                               0x0000,
+                                               wLength,
+                                               pBuffer);
 
                DBG_PRT(MSG_LEVEL_DEBUG,
                        KERN_INFO"Download firmware...%d %zu\n", ii, fw->size);
                if (NdisStatus != STATUS_SUCCESS)
                        goto free_fw;
-        }
+       }
 
        result = true;
 free_fw:
@@ -101,48 +100,47 @@ int FIRMWAREbBrach2Sram(struct vnt_private *pDevice)
 {
        int NdisStatus;
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
-
-    NdisStatus = CONTROLnsRequestOut(pDevice,
-                                    1,
-                                    0x1200,
-                                    0x0000,
-                                    0,
-                                    NULL
-                                    );
-
-    if (NdisStatus != STATUS_SUCCESS) {
-        return (false);
-    } else {
-        return (true);
-    }
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
+
+       NdisStatus = CONTROLnsRequestOut(pDevice,
+                                       1,
+                                       0x1200,
+                                       0x0000,
+                                       0,
+                                       NULL);
+       if (NdisStatus != STATUS_SUCCESS)
+               return false;
+       else
+               return true;
 }
 
 int FIRMWAREbCheckVersion(struct vnt_private *pDevice)
 {
        int ntStatus;
 
-    ntStatus = CONTROLnsRequestIn(pDevice,
-                                    MESSAGE_TYPE_READ,
-                                    0,
-                                    MESSAGE_REQUEST_VERSION,
-                                    2,
-                                    (u8 *) &(pDevice->wFirmwareVersion));
-
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
-    if (ntStatus != STATUS_SUCCESS) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
-        return false;
-    }
-    if (pDevice->wFirmwareVersion == 0xFFFF) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
-        return false;
-    }
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
-    if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) {
-        // branch to loader for download new firmware
-        FIRMWAREbBrach2Sram(pDevice);
-        return false;
-    }
-    return true;
+       ntStatus = CONTROLnsRequestIn(pDevice,
+                                       MESSAGE_TYPE_READ,
+                                       0,
+                                       MESSAGE_REQUEST_VERSION,
+                                       2,
+                                       (u8 *) &(pDevice->wFirmwareVersion));
+
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n",
+                                               pDevice->wFirmwareVersion);
+       if (ntStatus != STATUS_SUCCESS) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
+               return false;
+       }
+       if (pDevice->wFirmwareVersion == 0xFFFF) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
+               return false;
+       }
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n",
+                                               pDevice->wFirmwareVersion);
+       if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) {
+               /* branch to loader for download new firmware */
+               FIRMWAREbBrach2Sram(pDevice);
+               return false;
+       }
+       return true;
 }
index c699a3058b39920a34daf1a6f63524be990e29cb..ae1676d190c5b318fcaa43466f58539d39fed095 100644 (file)
@@ -414,7 +414,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice,
        int ret = 0;
        s32 iNodeIndex = -1;
        int ii;
-       int bKeyTableFull = false;
+       bool bKeyTableFull = false;
        u16 wKeyCtl = 0;
 
        param->u.crypt.err = 0;
@@ -685,7 +685,7 @@ int vt6656_hostap_ioctl(struct vnt_private *pDevice, struct iw_point *p)
            p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
                return -EINVAL;
 
-       param = kmalloc((int)p->length, (int)GFP_KERNEL);
+       param = kmalloc((int)p->length, GFP_KERNEL);
        if (param == NULL)
                return -ENOMEM;
 
index 8872e0f84f40e825efec5dd7f7614f6c22f43562..63917abbbd006b8672c4ec8e5124fd9e85ffea63 100644 (file)
@@ -60,7 +60,7 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
        pDevice->wstats.status = pDevice->eOPMode;
        if (pDevice->scStatistic.LinkQuality > 100)
                pDevice->scStatistic.LinkQuality = 100;
-       pDevice->wstats.qual.qual =(u8)pDevice->scStatistic.LinkQuality;
+       pDevice->wstats.qual.qual = (u8)pDevice->scStatistic.LinkQuality;
        RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
        pDevice->wstats.qual.level = ldBm;
        pDevice->wstats.qual.noise = 0;
@@ -190,7 +190,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
                return -EAGAIN;
        }
        pBSS = &(pMgmt->sBSSList[0]);
-       for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+       for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) {
                if (current_ev >= end_buf)
                        break;
                pBSS = &(pMgmt->sBSSList[jj]);
@@ -225,7 +225,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
                        iwe.u.freq.m = pBSS->uChannel;
                        iwe.u.freq.e = 0;
                        iwe.u.freq.i = 0;
-                       current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+                       current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
                        {
                                int f = (int)pBSS->uChannel - 1;
                                if (f < 0)
@@ -400,7 +400,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->flags & DEVICE_FLAGS_OPENED)
                                pDevice->bCommit = true;
                }
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc\n");
                break;
        case IW_MODE_AUTO:
        case IW_MODE_INFRA:
@@ -409,7 +409,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->flags & DEVICE_FLAGS_OPENED)
                                pDevice->bCommit = true;
                }
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure\n");
                break;
        case IW_MODE_MASTER:
 
@@ -422,7 +422,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->flags & DEVICE_FLAGS_OPENED)
                                pDevice->bCommit = true;
                }
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point\n");
                break;
 
        case IW_MODE_REPEAT:
@@ -657,8 +657,8 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
                        unsigned uSameBssidNum = 0;
                        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                if (pMgmt->sBSSList[ii].bActive &&
-                                       !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
-                                                       pMgmt->abyDesireBSSID)) {
+                                       ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                        pMgmt->abyDesireBSSID)) {
                                        uSameBssidNum++;
                                }
                        }
@@ -786,8 +786,8 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
        if (wrq->flags == 0) {
                // Just send an empty SSID list
                memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-               memset(pMgmt->abyDesireBSSID, 0xFF,6);
-               PRINT_K("set essid to 'any' \n");
+               memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+               PRINT_K("set essid to 'any'\n");
                // Unknown desired AP, so here need not associate??
                return 0;
        } else {
@@ -798,15 +798,15 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
 
                memcpy(pItemSSID->abySSID, extra, wrq->length);
                if (pItemSSID->abySSID[wrq->length] == '\0') {
-                       if (wrq->length>0)
+                       if (wrq->length > 0)
                                pItemSSID->len = wrq->length;
                } else {
                        pItemSSID->len = wrq->length;
                }
-               PRINT_K("set essid to %s \n", pItemSSID->abySSID);
+               PRINT_K("set essid to %s\n", pItemSSID->abySSID);
 
                // mike: need clear desiredBSSID
-               if (pItemSSID->len==0) {
+               if (pItemSSID->len == 0) {
                        memset(pMgmt->abyDesireBSSID, 0xFF, 6);
                        return 0;
                }
@@ -840,8 +840,8 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
                                // are two same BSSID exist in list ?
                                for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                        if (pMgmt->sBSSList[ii].bActive &&
-                                               !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
-                                                               pCurr->abyBSSID)) {
+                                               ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                                pCurr->abyBSSID)) {
                                                uSameBssidNum++;
                                        }
                                }
@@ -860,7 +860,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
                        return 0;
                }
 
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID);
        }
 
        if (pDevice->flags & DEVICE_FLAGS_OPENED)
@@ -893,7 +893,7 @@ int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
        memcpy(extra, pItemSSID->abySSID, pItemSSID->len);
        extra[pItemSSID->len] = '\0';
 
-        wrq->length = pItemSSID->len;
+       wrq->length = pItemSSID->len;
        wrq->flags = 1; // active
 
        return 0;
@@ -915,7 +915,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
                0x60, 0x6C, 0x90
        };
 
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n");
        if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
                rc = -EINVAL;
                return rc;
@@ -953,7 +953,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
        }
        // Check that it is valid
        // brate is index of abySupportedRates[]
-       if (brate > 13 ) {
+       if (brate > 13) {
                rc = -EINVAL;
                return rc;
        }
@@ -967,7 +967,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
                        pDevice->uConnectionRate = 3;
                } else {
                        pDevice->uConnectionRate = brate;
-                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate);
                }
        } else {
                pDevice->bFixRate = false;
@@ -1017,7 +1017,7 @@ int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->byBBType == BB_TYPE_11A)
                                brate = 0x6C;
                }
-               if (pDevice->uConnectionRate == 13)
+               if (pDevice->uConnectionRate == 13)
                        brate = abySupportedRates[pDevice->wCurrentRate];
                wrq->value = brate * 500000;
                // If more than one rate, set auto
@@ -1286,7 +1286,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
        if (index < 1) { // get default key
                if (pDevice->byKeyIndex < WLAN_WEP_NKEYS)
                        index = pDevice->byKeyIndex;
-               else
+               else
                        index = 0;
        } else {
                index--;
@@ -1366,14 +1366,14 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
 
        switch (wrq->flags & IW_POWER_MODE) {
        case IW_POWER_UNICAST_R:
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n");
                rc = -EINVAL;
                break;
        case IW_POWER_ALL_R:
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n");
                rc = -EINVAL;
        case IW_POWER_ON:
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n");
                break;
        default:
                rc = -EINVAL;
@@ -1465,7 +1465,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
        case IW_AUTH_CIPHER_PAIRWISE:
                pairwise = wrq->value;
                PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
-               if (pairwise == IW_AUTH_CIPHER_CCMP){
+               if (pairwise == IW_AUTH_CIPHER_CCMP) {
                        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
                } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
                        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
@@ -1490,13 +1490,13 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
                }
                break;
        case IW_AUTH_KEY_MGMT:
-               PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version,wrq->value);
-               if (wpa_version == IW_AUTH_WPA_VERSION_WPA2){
+               PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version, wrq->value);
+               if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) {
                        if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
                                pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
                        else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
                } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
-                       if (wrq->value == 0){
+                       if (wrq->value == 0) {
                                pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
                        } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
                                pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
@@ -1558,17 +1558,17 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
        if (pMgmt == NULL)
                return -EFAULT;
 
-       if (wrq->length){
+       if (wrq->length) {
                if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
                        ret = -EINVAL;
                        goto out;
                }
-               if (wrq->length > MAX_WPA_IE_LEN){
+               if (wrq->length > MAX_WPA_IE_LEN) {
                        ret = -ENOMEM;
                        goto out;
                }
                memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
-               if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
+               if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)) {
                        ret = -EFAULT;
                        goto out;
                }
@@ -1615,7 +1615,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        struct iw_point *wrq = &wrqu->encoding;
        struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
-       struct viawget_wpa_param *param=NULL;
+       struct viawget_wpa_param *param = NULL;
 // original member
        wpa_alg alg_name;
        u8 addr[6];
@@ -1658,8 +1658,8 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
                alg_name = WPA_ALG_CCMP;
                break;
        default:
-               PRINT_K("Unknown alg = %d\n",ext->alg);
-               ret= -ENOMEM;
+               PRINT_K("Unknown alg = %d\n", ext->alg);
+               ret = -ENOMEM;
                goto error;
        }
 // recover addr
@@ -1671,7 +1671,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
                set_tx = 1;
 // recover seq,seq_len
        if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
-               seq_len=IW_ENCODE_SEQ_MAX_SIZE;
+               seq_len = IW_ENCODE_SEQ_MAX_SIZE;
                memcpy(seq, ext->rx_seq, seq_len);
        }
 // recover key,key_len
@@ -1702,7 +1702,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
 /****set if current action is Network Manager count?? */
 /****this method is so foolish,but there is no other way??? */
        if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
-               if (param->u.wpa_key.key_index ==0) {
+               if (param->u.wpa_key.key_index == 0) {
                        pDevice->bwextstep0 = true;
                }
                if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
@@ -1761,7 +1761,7 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
                ret = -EINVAL;
                return ret;
        }
-       switch (mlme->cmd){
+       switch (mlme->cmd) {
        case IW_MLME_DEAUTH:
        case IW_MLME_DISASSOC:
                if (pDevice->bLinkPass == true) {
@@ -1815,7 +1815,6 @@ static const iw_handler iwctl_handler[] = {
        IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
        IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
        IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
-       IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
        IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
        IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
        IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
index 205590b0e9c839018a390cd79a0c23fe97d341ec..be92c048a12e93bbd6169e0b2d54fb1c6c0503f9 100644 (file)
@@ -151,7 +151,7 @@ int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             if (dwKeyIndex == 0xFFFFFFFF) {
                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
@@ -213,7 +213,7 @@ int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable,
             j = i;
         }
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             // found table already exist
             if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                 // Pairwise key
@@ -395,7 +395,7 @@ int KeybRemoveKey(struct vnt_private *pDevice, PSKeyManagement pTable,
     } else {
         for (i=0;i<MAX_KEY_TABLE;i++) {
             if ( (pTable->KeyTable[i].bInUse == true) &&
-                !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
                 if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                     pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
@@ -445,7 +445,7 @@ int KeybRemoveAllKey(struct vnt_private *pDevice, PSKeyManagement pTable,
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
            for (u = 0; u < MAX_GROUP_KEY; u++)
                pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
@@ -480,7 +480,7 @@ int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
 
     for (i = 0; i < MAX_KEY_TABLE; i++) {
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
             if (dwKeyType == PAIRWISE_KEY) {
 
index 6f9d28182445ce99b2d37bcd37aaae3c3d2bdc03..aae228c533effe3a0a7f0f0460ec9ab8c9cb90e5 100644 (file)
@@ -702,6 +702,16 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        device_set_options(pDevice);
        spin_lock_init(&pDevice->lock);
+       INIT_DELAYED_WORK(&pDevice->run_command_work, vRunCommand);
+       INIT_DELAYED_WORK(&pDevice->second_callback_work, BSSvSecondCallBack);
+       INIT_WORK(&pDevice->read_work_item, RXvWorkItem);
+       INIT_WORK(&pDevice->rx_mng_work_item, RXvMngWorkItem);
+
+       pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!pDevice->pControlURB) {
+               DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc control urb\n");
+               goto err_netdev;
+       }
 
        pDevice->tx_80211 = device_dma0_tx_80211;
        pDevice->vnt_mgmt.pAdapter = (void *) pDevice;
@@ -713,14 +723,15 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
        usb_set_intfdata(intf, pDevice);
        SET_NETDEV_DEV(netdev, &intf->dev);
        memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
+
+       usb_device_reset(pDevice);
+
        rc = register_netdev(netdev);
        if (rc) {
                printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
                goto err_netdev;
        }
 
-       usb_device_reset(pDevice);
-
        return 0;
 
 err_netdev:
@@ -849,23 +860,15 @@ static bool device_alloc_bufs(struct vnt_private *pDevice)
         pRCB++;
     }
 
-       pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
-       if (pDevice->pControlURB == NULL) {
-           DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
-           goto free_rx_tx;
-       }
-
        pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
        if (pDevice->pInterruptURB == NULL) {
            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
-           usb_free_urb(pDevice->pControlURB);
            goto free_rx_tx;
        }
 
     pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
        if (pDevice->intBuf.pDataBuf == NULL) {
            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
-           usb_free_urb(pDevice->pControlURB);
            usb_free_urb(pDevice->pInterruptURB);
            goto free_rx_tx;
        }
@@ -981,10 +984,11 @@ static int  device_open(struct net_device *dev)
     }
 
     vMgrObjectInit(pDevice);
-    tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
-    tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
+
     tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
-       add_timer(&pDevice->vnt_mgmt.sTimerSecondCallback);
+
+       schedule_delayed_work(&pDevice->second_callback_work, HZ);
+
        pDevice->int_interval = 100;  /* max 100 microframes */
     pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
 
@@ -1000,7 +1004,7 @@ static int  device_open(struct net_device *dev)
      pDevice->bWPASuppWextEnabled = false;
     pDevice->byReAssocCount = 0;
 
-    RXvWorkItem(pDevice);
+       schedule_work(&pDevice->read_work_item);
     INTvWorkItem(pDevice);
 
     /* if WEP key already set by iwconfig but device not yet open */
@@ -1035,9 +1039,7 @@ free_rx_tx:
     device_free_rx_bufs(pDevice);
     device_free_tx_bufs(pDevice);
     device_free_int_bufs(pDevice);
-       usb_kill_urb(pDevice->pControlURB);
        usb_kill_urb(pDevice->pInterruptURB);
-    usb_free_urb(pDevice->pControlURB);
     usb_free_urb(pDevice->pInterruptURB);
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
@@ -1076,18 +1078,19 @@ static int device_close(struct net_device *dev)
     MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
     MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
     pDevice->fKillEventPollingThread = true;
-    del_timer(&pDevice->sTimerCommand);
-    del_timer(&pMgmt->sTimerSecondCallback);
 
-    del_timer(&pDevice->sTimerTxData);
+       cancel_delayed_work_sync(&pDevice->run_command_work);
+       cancel_delayed_work_sync(&pDevice->second_callback_work);
 
     if (pDevice->bDiversityRegCtlON) {
         del_timer(&pDevice->TimerSQ3Tmax1);
         del_timer(&pDevice->TimerSQ3Tmax2);
         del_timer(&pDevice->TimerSQ3Tmax3);
     }
-    tasklet_kill(&pDevice->RxMngWorkItem);
-    tasklet_kill(&pDevice->ReadWorkItem);
+
+       cancel_work_sync(&pDevice->rx_mng_work_item);
+       cancel_work_sync(&pDevice->read_work_item);
+
     tasklet_kill(&pDevice->EventWorkItem);
 
    pDevice->bRoaming = false;
@@ -1105,9 +1108,7 @@ static int device_close(struct net_device *dev)
     device_free_int_bufs(pDevice);
     device_free_frag_bufs(pDevice);
 
-       usb_kill_urb(pDevice->pControlURB);
        usb_kill_urb(pDevice->pInterruptURB);
-    usb_free_urb(pDevice->pControlURB);
     usb_free_urb(pDevice->pInterruptURB);
 
     BSSvClearNodeDBTable(pDevice, 0);
@@ -1131,9 +1132,12 @@ static void vt6656_disconnect(struct usb_interface *intf)
 
        if (device->dev) {
                unregister_netdev(device->dev);
+
+               usb_kill_urb(device->pControlURB);
+               usb_free_urb(device->pControlURB);
+
                free_netdev(device->dev);
        }
-
 }
 
 static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
index edc8975b2e2a0ceae17aabea15813285cd8c3846..e7d5487d1041ca4f2b284268e6274378df291941 100644 (file)
@@ -233,9 +233,8 @@ void PSvSendPSPOLL(struct vnt_private *pDevice)
        pTxPacket->cbPayloadLen = 0;
 
        /* log failure if sending failed */
-       if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+       if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
-       }
 }
 
 /*
@@ -257,10 +256,8 @@ int PSbSendNullPacket(struct vnt_private *pDevice)
        if (pDevice->bLinkPass == false)
                return false;
 
-       if ((pDevice->bEnablePSMode == false) &&
-               (pDevice->fTxDataInSleep == false)) {
-                       return false;
-       }
+       if (pDevice->bEnablePSMode == false && pDevice->tx_trigger == false)
+               return false;
 
        memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt)
                + WLAN_NULLDATA_FR_MAXLEN);
@@ -269,7 +266,7 @@ int PSbSendNullPacket(struct vnt_private *pDevice)
                + sizeof(struct vnt_tx_mgmt));
 
        flags = WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
-                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL);
+                       WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL);
 
        if (pDevice->bEnablePSMode)
                flags |= WLAN_SET_FC_PWRMGT(1);
index 14f3e852215da5fb27702b4b91687047b9a290c2..35a3ddb41a6a2f4ac7ee36ad55a55549ee7569e0 100644 (file)
@@ -98,21 +98,18 @@ static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
 
 static void *s_vGetFreeContext(struct vnt_private *pDevice);
 
-static void s_vGenerateTxParameter(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
-       void *rts_cts, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
-       struct ethhdr *psEthHeader, bool need_rts);
-
-static u32 s_uFillDataHead(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
-       u32 uDMAIdx, int bNeedAck, u8 byFBOption);
+static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
+       u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
+       struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
+       int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts);
 
 static void s_vGenerateMACHeader(struct vnt_private *pDevice,
        u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
        int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
 
-static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
-       u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
+static void s_vFillTxKey(struct vnt_private *pDevice,
+       struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
+       PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
        struct vnt_mic_hdr *mic_hdr);
 
 static void s_vSWencryption(struct vnt_private *pDevice,
@@ -124,11 +121,11 @@ static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
 static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
        u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
 
-static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
        u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
        int bNeedAck, u16 wCurrentRate, u8 byFBOption);
 
-static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
        struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
 
@@ -183,10 +180,12 @@ static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
           ETH_ALEN);
 }
 
-static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
-       u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
-       u16 wPayloadLen, struct vnt_mic_hdr *mic_hdr)
+static void s_vFillTxKey(struct vnt_private *pDevice,
+       struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
+       PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
+       struct vnt_mic_hdr *mic_hdr)
 {
+       u8 *pbyBuf = (u8 *)&fifo_head->adwTxKey[0];
        u32 *pdwIV = (u32 *)pbyIVHead;
        u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
        struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
@@ -431,185 +430,114 @@ static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
 {
        u32 uCTSTime = 0, uDurTime = 0;
 
-    switch (byDurType) {
+       switch (byDurType) {
+       case RTSDUR_BB:
+       case RTSDUR_BA:
+       case RTSDUR_BA_F0:
+       case RTSDUR_BA_F1:
+               uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
+                       14, pDevice->byTopCCKBasicRate);
+               uDurTime = uCTSTime + 2 * pDevice->uSIFS +
+                       s_uGetTxRsvTime(pDevice, byPktType,
+                                               cbFrameLength, wRate, bNeedAck);
+               break;
 
-    case RTSDUR_BB:    //RTSDuration_bb
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       case RTSDUR_AA:
+       case RTSDUR_AA_F0:
+       case RTSDUR_AA_F1:
+               uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
+                       14, pDevice->byTopOFDMBasicRate);
+               uDurTime = uCTSTime + 2 * pDevice->uSIFS +
+                       s_uGetTxRsvTime(pDevice, byPktType,
+                                               cbFrameLength, wRate, bNeedAck);
+               break;
 
-    case RTSDUR_BA:    //RTSDuration_ba
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       case CTSDUR_BA:
+       case CTSDUR_BA_F0:
+       case CTSDUR_BA_F1:
+               uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice,
+                               byPktType, cbFrameLength, wRate, bNeedAck);
+               break;
 
-    case RTSDUR_AA:    //RTSDuration_aa
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       default:
+               break;
+       }
 
-    case CTSDUR_BA:    //CTSDuration_ba
-        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       return cpu_to_le16((u16)uDurTime);
+}
 
-    case RTSDUR_BA_F0: //RTSDuration_ba_f0
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        }
-        break;
-
-    case RTSDUR_AA_F0: //RTSDuration_aa_f0
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+static u16 vnt_rxtx_datahead_g(struct vnt_private *priv, u8 pkt_type, u16 rate,
+               struct vnt_tx_datahead_g *buf, u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+       BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+                                                       PK_TYPE_11B, &buf->b);
 
-    case RTSDUR_BA_F1: //RTSDuration_ba_f1
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        }
-        break;
-
-    case RTSDUR_AA_F1: //RTSDuration_aa_f1
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+       /* Get Duration and TimeStamp */
+       buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
 
-    case CTSDUR_BA_F0: //CTSDuration_ba_f0
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+       buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
+       buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
+                                       priv->byTopCCKBasicRate);
 
-    case CTSDUR_BA_F1: //CTSDuration_ba_f1
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+       return buf->wDuration_a;
+}
 
-    default:
-        break;
-    }
+static u16 vnt_rxtx_datahead_g_fb(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_g_fb *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
 
-       return cpu_to_le16((u16)uDurTime);
+       BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+                                               PK_TYPE_11B, &buf->b);
+
+       /* Get Duration and TimeStamp */
+       buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
+
+       buf->wDuration_a_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_a_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
+       buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
+                                               priv->byTopCCKBasicRate);
+
+       return buf->wDuration_a;
 }
 
-static u32 s_uFillDataHead(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
-       u32 uDMAIdx, int bNeedAck, u8 byFBOption)
+static u16 vnt_rxtx_datahead_a_fb(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_a_fb *buf,
+               u32 frame_len, int need_ack)
 {
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+       /* Get Duration and TimeStampOff */
+       buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
 
-    if (pTxDataHead == NULL) {
-        return 0;
-    }
+       buf->wDuration_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
 
-    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-            if (byFBOption == AUTO_FB_NONE) {
-               struct vnt_tx_datahead_g *pBuf =
-                               (struct vnt_tx_datahead_g *)pTxDataHead;
-                //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-               BBvCalculateParameter(pDevice, cbFrameLength,
-                       pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
-                //Get Duration and TimeStamp
-               pBuf->wDuration_a = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_b = s_uGetDataDuration(pDevice,
-                                                       PK_TYPE_11B, bNeedAck);
-
-               pBuf->wTimeStampOff_a = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-               pBuf->wTimeStampOff_b = vnt_time_stamp_off(pDevice,
-                                               pDevice->byTopCCKBasicRate);
-                return (pBuf->wDuration_a);
-             } else {
-                // Auto Fallback
-               struct vnt_tx_datahead_g_fb *pBuf =
-                       (struct vnt_tx_datahead_g_fb *)pTxDataHead;
-                //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-               BBvCalculateParameter(pDevice, cbFrameLength,
-                       pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
-                //Get Duration and TimeStamp
-               pBuf->wDuration_a = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_b = s_uGetDataDuration(pDevice,
-                                                       PK_TYPE_11B, bNeedAck);
-               pBuf->wDuration_a_f0 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_a_f1 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wTimeStampOff_a = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-               pBuf->wTimeStampOff_b = vnt_time_stamp_off(pDevice,
-                                               pDevice->byTopCCKBasicRate);
-                return (pBuf->wDuration_a);
-            } //if (byFBOption == AUTO_FB_NONE)
-    }
-    else if (byPktType == PK_TYPE_11A) {
-       if (byFBOption != AUTO_FB_NONE) {
-               struct vnt_tx_datahead_a_fb *pBuf =
-                       (struct vnt_tx_datahead_a_fb *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                                       byPktType, bNeedAck);
-               pBuf->wDuration_f0 = s_uGetDataDuration(pDevice,
-                                       byPktType, bNeedAck);
-               pBuf->wDuration_f1 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-        } else {
-               struct vnt_tx_datahead_ab *pBuf =
-                       (struct vnt_tx_datahead_ab *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->ab);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                               byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-        }
-    }
-    else if (byPktType == PK_TYPE_11B) {
-               struct vnt_tx_datahead_ab *pBuf =
-                       (struct vnt_tx_datahead_ab *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->ab);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                               byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-    }
-    return 0;
+       buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
+
+       return buf->wDuration;
+}
+
+static u16 vnt_rxtx_datahead_ab(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_ab *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->ab);
+       /* Get Duration and TimeStampOff */
+       buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
+
+       return buf->wDuration;
 }
 
 static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
@@ -632,7 +560,7 @@ static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
        return 0;
 }
 
-static int vnt_rxtx_rts_g_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_g_head(struct vnt_private *priv,
        struct vnt_rts_g *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -653,10 +581,11 @@ static int vnt_rxtx_rts_g_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
 
-       return 0;
+       return vnt_rxtx_datahead_g(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
        struct vnt_rts_g_fb *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -678,20 +607,21 @@ static int vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
 
 
        buf->wRTSDuration_ba_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F0,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
        buf->wRTSDuration_aa_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
        buf->wRTSDuration_ba_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F1,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
        buf->wRTSDuration_aa_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
 
-       return 0;
+       return vnt_rxtx_datahead_g_fb(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_ab_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_ab_head(struct vnt_private *priv,
        struct vnt_rts_ab *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -706,10 +636,11 @@ static int vnt_rxtx_rts_ab_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
 
-       return 0;
+       return vnt_rxtx_datahead_ab(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
        struct vnt_rts_a_fb *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -723,23 +654,24 @@ static int vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
                pkt_type, current_rate, need_ack, fb_option);
 
        buf->wRTSDuration_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
 
        buf->wRTSDuration_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
 
-       return 0;
+       return vnt_rxtx_datahead_a_fb(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
        struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
 {
 
        if (!head)
-               return;
+               return 0;
 
        /* Note: So far RTSHead doesn't appear in ATIM
        *       & Beacom DMA, so we don't need to take them
@@ -750,36 +682,38 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        case PK_TYPE_11GB:
        case PK_TYPE_11GA:
                if (byFBOption == AUTO_FB_NONE)
-                       vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
+                       return vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                else
-                       vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
+                       return vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                break;
        case PK_TYPE_11A:
                if (byFBOption) {
-                       vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
+                       return vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                        break;
                }
        case PK_TYPE_11B:
-               vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
+               return vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
                        psEthHeader, byPktType, cbFrameLength,
                        bNeedAck, wCurrentRate, byFBOption);
        }
+
+       return 0;
 }
 
-static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
        u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
        int bNeedAck, u16 wCurrentRate, u8 byFBOption)
 {
        u32 uCTSFrameLen = 14;
 
        if (!head)
-               return;
+               return 0;
 
        if (byFBOption != AUTO_FB_NONE) {
                /* Auto Fall back */
@@ -792,16 +726,19 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
                        wCurrentRate, bNeedAck, byFBOption);
                /* Get CTSDuration_ba_f0 */
                pBuf->wCTSDuration_ba_f0 = s_uGetRTSCTSDuration(pDevice,
-                       CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate,
-                       bNeedAck, byFBOption);
+                       CTSDUR_BA_F0, cbFrameLength, byPktType,
+                       pDevice->tx_rate_fb0, bNeedAck, byFBOption);
                /* Get CTSDuration_ba_f1 */
                pBuf->wCTSDuration_ba_f1 = s_uGetRTSCTSDuration(pDevice,
-                       CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate,
-                       bNeedAck, byFBOption);
+                       CTSDUR_BA_F1, cbFrameLength, byPktType,
+                       pDevice->tx_rate_fb1, bNeedAck, byFBOption);
                /* Get CTS Frame body */
                pBuf->data.duration = pBuf->wDuration_ba;
                pBuf->data.frame_control = TYPE_CTL_CTS;
                memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+
+               return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate,
+                               &pBuf->data_head, cbFrameLength, bNeedAck);
        } else {
                struct vnt_cts *pBuf = &head->cts_g;
                /* Get SignalField,ServiceField,Length */
@@ -815,7 +752,12 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
                pBuf->data.duration = pBuf->wDuration_ba;
                pBuf->data.frame_control = TYPE_CTL_CTS;
                memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+
+               return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate,
+                               &pBuf->data_head, cbFrameLength, bNeedAck);
         }
+
+       return 0;
 }
 
 /*+
@@ -841,112 +783,160 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
  *
 -*/
 
-static void s_vGenerateTxParameter(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
-       void *rts_cts, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
-       struct ethhdr *psEthHeader, bool need_rts)
+static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
+       u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
+       struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
+       int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts)
 {
-       union vnt_tx_data_head *head = rts_cts;
+       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;
 
-    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
-    PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
-    pFifoHead->wReserved = wCurrentRate;
-    wFifoCtl = pFifoHead->wFIFOCtl;
+       pFifoHead->wReserved = wCurrentRate;
+       wFifoCtl = pFifoHead->wFIFOCtl;
 
-    if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
-        byFBOption = AUTO_FB_0;
-    }
-    else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
-        byFBOption = AUTO_FB_1;
-    }
+       if (wFifoCtl & FIFOCTL_AUTO_FB_0)
+               byFBOption = AUTO_FB_0;
+       else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
+               byFBOption = AUTO_FB_1;
 
-       if (!pvRrvTime)
-               return;
+       if (!pFifoHead)
+               return 0;
 
-    if (pDevice->bLongHeader)
-        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+       if (pDevice->bLongHeader)
+               cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
 
-    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-       if (need_rts) {
-            //Fill RsvTime
-               struct vnt_rrv_time_rts *pBuf =
-                       (struct vnt_rrv_time_rts *)pvRrvTime;
-               pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
-                               byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wRTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 1,
-                               byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wRTSTxRrvTime_bb = s_uGetRTSCTSRsvTime(pDevice, 0,
-                               byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
-                       byPktType, cbFrameSize, wCurrentRate, bNeedACK);
-               pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
-                       PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate,
-                               bNeedACK);
-               /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
-                       bNeedACK, psEthHeader, wCurrentRate, byFBOption);
-        }
-        else {//RTS_needless, PCF mode
-            //Fill RsvTime
-               struct vnt_rrv_time_cts *pBuf =
-                               (struct vnt_rrv_time_cts *)pvRrvTime;
-               pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
-                       cbFrameSize, wCurrentRate, bNeedACK);
-               pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
-                       PK_TYPE_11B, cbFrameSize,
-                       pDevice->byTopCCKBasicRate, bNeedACK);
-               pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
+       if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+               if (need_rts) {
+                       struct vnt_rrv_time_rts *pBuf =
+                                       &tx_buffer->tx_head.tx_rts.rts;
+
+                       pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
+                                       byPktType, cbFrameSize, wCurrentRate);
+                       pBuf->wRTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 1,
+                                       byPktType, cbFrameSize, wCurrentRate);
+                       pBuf->wRTSTxRrvTime_bb = s_uGetRTSCTSRsvTime(pDevice, 0,
                                byPktType, cbFrameSize, wCurrentRate);
-               /* Fill CTS */
-               s_vFillCTSHead(pDevice, uDMAIdx, byPktType, head,
-                       cbFrameSize, bNeedACK, wCurrentRate, byFBOption);
-        }
-    }
-    else if (byPktType == PK_TYPE_11A) {
-       if (need_rts) {
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
+
+                       pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
+                               byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+                       pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
+                                       PK_TYPE_11B, cbFrameSize,
+                                       pDevice->byTopCCKBasicRate, bNeedACK);
+
+                       if (need_mic) {
+                               *mic_hdr = &tx_buffer->
+                                               tx_head.tx_rts.tx.mic.hdr;
+                               head = &tx_buffer->tx_head.tx_rts.tx.mic.head;
+                       } else {
+                               head = &tx_buffer->tx_head.tx_rts.tx.head;
+                       }
+
+                       /* Fill RTS */
+                       return s_vFillRTSHead(pDevice, byPktType, head,
+                                       cbFrameSize, bNeedACK, psEthHeader,
+                                               wCurrentRate, byFBOption);
+
+               } else {
+                       struct vnt_rrv_time_cts *pBuf = &tx_buffer->
+                                                       tx_head.tx_cts.cts;
+
+                       pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
+                               byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+                       pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11B, cbFrameSize,
+                                       pDevice->byTopCCKBasicRate, bNeedACK);
+
+                       pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
+                                       byPktType, cbFrameSize, wCurrentRate);
+
+                       if (need_mic) {
+                               *mic_hdr = &tx_buffer->
+                                               tx_head.tx_cts.tx.mic.hdr;
+                               head = &tx_buffer->tx_head.tx_cts.tx.mic.head;
+                       } else {
+                               head = &tx_buffer->tx_head.tx_cts.tx.head;
+                       }
+
+                       /* Fill CTS */
+                       return s_vFillCTSHead(pDevice, uDMAIdx, byPktType,
+                               head, cbFrameSize, bNeedACK, wCurrentRate,
+                                       byFBOption);
+               }
+       } else if (byPktType == PK_TYPE_11A) {
+               if (need_mic) {
+                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+                       head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
+               } else {
+                       head = &tx_buffer->tx_head.tx_ab.tx.head;
+               }
+
+               if (need_rts) {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
                                byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
-                               cbFrameSize, wCurrentRate, bNeedACK);
-               /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
-                       bNeedACK, psEthHeader, wCurrentRate, byFBOption);
-       } else {
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A,
-                       cbFrameSize, wCurrentRate, bNeedACK);
-        }
-    }
-    else if (byPktType == PK_TYPE_11B) {
-       if (need_rts) {
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+
+                       /* Fill RTS */
+                       return s_vFillRTSHead(pDevice, byPktType, head,
+                               cbFrameSize, bNeedACK, psEthHeader,
+                                       wCurrentRate, byFBOption);
+               } else {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11A, cbFrameSize,
+                                       wCurrentRate, bNeedACK);
+
+                       return vnt_rxtx_datahead_a_fb(pDevice, byPktType,
+                               wCurrentRate, &head->data_head_a_fb,
+                                               cbFrameSize, bNeedACK);
+               }
+       } else if (byPktType == PK_TYPE_11B) {
+               if (need_mic) {
+                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+                       head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
+               } else {
+                       head = &tx_buffer->tx_head.tx_ab.tx.head;
+               }
+
+               if (need_rts) {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
                                byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
-                               cbFrameSize, wCurrentRate, bNeedACK);
-               /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11B, cbFrameSize, wCurrentRate,
+                                                               bNeedACK);
+
+                       /* Fill RTS */
+                       return s_vFillRTSHead(pDevice, byPktType, head,
+                               cbFrameSize,
                        bNeedACK, psEthHeader, wCurrentRate, byFBOption);
-        }
-        else { //RTS_needless, non PCF mode
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
-                       cbFrameSize, wCurrentRate, bNeedACK);
-        }
-    }
-    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+               } else {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11B, cbFrameSize,
+                                       wCurrentRate, bNeedACK);
+
+                       return vnt_rxtx_datahead_ab(pDevice, byPktType,
+                               wCurrentRate, &head->data_head_ab,
+                                       cbFrameSize, bNeedACK);
+               }
+       }
+
+       return 0;
 }
 /*
     u8 * pbyBuffer,//point to pTxBufHead
@@ -955,11 +945,12 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 */
 
 static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
-       struct vnt_tx_buffer *pTxBufHead, int bNeedEncryption,
+       struct vnt_tx_buffer *tx_buffer, int bNeedEncryption,
        u32 uSkbPacketLen, u32 uDMAIdx, struct ethhdr *psEthHeader,
        u8 *pPacket, PSKeyItem pTransmitKey, u32 uNodeIndex, u16 wCurrentRate,
        u32 *pcbHeaderLen, u32 *pcbTotalLen)
 {
+       struct vnt_tx_fifo_head *pTxBufHead = &tx_buffer->fifo_head;
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        u32 cbFrameSize, cbFrameBodySize;
        u32 cb802_1_H_len;
@@ -973,17 +964,14 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
                = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
        u32 uDuration;
        u32 cbHeaderLength = 0, uPadding = 0;
-       void *pvRrvTime;
        struct vnt_mic_hdr *pMICHDR;
-       void *rts_cts = NULL;
-       void *pvTxDataHd;
        u8 byFBOption = AUTO_FB_NONE, byFragType;
        u16 wTxBufSize;
        u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
        u32 *pdwMIC_L, *pdwMIC_R;
        int bSoftWEP = false;
 
-       pvRrvTime = pMICHDR = pvTxDataHd = NULL;
+       pMICHDR = NULL;
 
        if (bNeedEncryption && pTransmitKey->pvKeyTable) {
                if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
@@ -1047,16 +1035,27 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
         pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
     }
 
-    //Set Auto Fallback Ctl
-    if (wCurrentRate >= RATE_18M) {
-        if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
-            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
-            byFBOption = AUTO_FB_0;
-        } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
-            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
-            byFBOption = AUTO_FB_1;
-        }
-    }
+       /* Set Auto Fallback Ctl */
+       if (wCurrentRate >= RATE_18M) {
+               if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
+                       pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+
+                       pDevice->tx_rate_fb0 =
+                               wFB_Opt0[FB_RATE0][wCurrentRate - RATE_18M];
+                       pDevice->tx_rate_fb1 =
+                               wFB_Opt0[FB_RATE1][wCurrentRate - RATE_18M];
+
+                       byFBOption = AUTO_FB_0;
+               } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
+                       pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
+                       pDevice->tx_rate_fb0 =
+                               wFB_Opt1[FB_RATE0][wCurrentRate - RATE_18M];
+                       pDevice->tx_rate_fb1 =
+                               wFB_Opt1[FB_RATE1][wCurrentRate - RATE_18M];
+
+                       byFBOption = AUTO_FB_1;
+               }
+       }
 
     if (bSoftWEP != true) {
         if ((bNeedEncryption) && (pTransmitKey != NULL))  { //WEP enabled
@@ -1105,118 +1104,47 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     }
 
     pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
-    wTxBufSize = sizeof(STxBufHead);
+       wTxBufSize = sizeof(struct vnt_tx_fifo_head);
+
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_rts *)
-                                       (pbyTxBufferAddr + wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_rts));
-               rts_cts = (struct vnt_rts_g *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                               cbMICHDR + sizeof(struct vnt_rts_g));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                       cbMICHDR + sizeof(struct vnt_rts_g) +
-                               sizeof(struct vnt_tx_datahead_g);
+                       cbMICHDR + sizeof(struct vnt_rts_g);
             }
             else { //RTS_needless
-               pvRrvTime = (struct vnt_rrv_time_cts *)
-                               (pbyTxBufferAddr + wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_cts));
-               rts_cts = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                       cbMICHDR + sizeof(struct vnt_cts) +
-                               sizeof(struct vnt_tx_datahead_g);
+                       cbMICHDR + sizeof(struct vnt_cts);
             }
         } else {
             // Auto Fall Back
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_rts *)(pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_rts));
-               rts_cts = (struct vnt_rts_g_fb *)(pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                               cbMICHDR + sizeof(struct vnt_rts_g_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                       cbMICHDR + sizeof(struct vnt_rts_g_fb) +
-                               sizeof(struct vnt_tx_datahead_g_fb);
+                       cbMICHDR + sizeof(struct vnt_rts_g_fb);
             }
             else if (bRTS == false) { //RTS_needless
-               pvRrvTime = (struct vnt_rrv_time_cts *)
-                               (pbyTxBufferAddr + wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_cts));
-               rts_cts = (struct vnt_cts_fb *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts_fb) +
-                                       sizeof(struct vnt_tx_datahead_g_fb);
+                               cbMICHDR + sizeof(struct vnt_cts_fb);
             }
         } // Auto Fall Back
     }
     else {//802.11a/b packet
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
-                                               sizeof(struct vnt_rrv_time_ab));
-               rts_cts = (struct vnt_rts_ab *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-                                               sizeof(struct vnt_rts_ab));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-                       cbMICHDR + sizeof(struct vnt_rts_ab) +
-                               sizeof(struct vnt_tx_datahead_ab);
+                       cbMICHDR + sizeof(struct vnt_rts_ab);
             }
             else if (bRTS == false) { //RTS_needless, no MICHDR
-               pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                                               sizeof(struct vnt_rrv_time_ab));
-               pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                                cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
             }
         } else {
             // Auto Fall Back
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
-                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_ab));
-               rts_cts = (struct vnt_rts_a_fb *)(pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-                                       sizeof(struct vnt_rts_a_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-                       cbMICHDR + sizeof(struct vnt_rts_a_fb) +
-                                       sizeof(struct vnt_tx_datahead_a_fb);
+                       cbMICHDR + sizeof(struct vnt_rts_a_fb);
             }
             else if (bRTS == false) { //RTS_needless
-               pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
-                                               sizeof(struct vnt_rrv_time_ab));
-               pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                        cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
             }
@@ -1235,20 +1163,18 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     //uDMAIdx = TYPE_AC0DMA;
     //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
 
-    //Fill FIFO,RrvTime,RTS,and CTS
-    s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               (void *)pbyTxBufferAddr, pvRrvTime, rts_cts,
-               cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
-                               byFBOption);
+       /* Fill FIFO, RrvTime, RTS and CTS */
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+                       tx_buffer, &pMICHDR, cbMICHDR,
+                       cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
+
     // Generate TX MAC Header
     s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
                            byFragType, uDMAIdx, 0);
 
     if (bNeedEncryption == true) {
         //Fill TXKEY
-        s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+       s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
                pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
 
         if (pDevice->bEnableHostWEP) {
@@ -1469,13 +1395,12 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
 {
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        struct vnt_tx_buffer *pTX_Buffer;
-       PSTxBufHead pTxBufHead;
        struct vnt_usb_send_context *pContext;
+       struct vnt_tx_fifo_head *pTxBufHead;
        struct ieee80211_hdr *pMACHeader;
        struct ethhdr sEthHeader;
        u8 byPktType, *pbyTxBufferAddr;
-       void *rts_cts = NULL;
-       void *pvTxDataHd, *pvRrvTime, *pMICHDR;
+       struct vnt_mic_hdr *pMICHDR = NULL;
        u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
        int bNeedACK, bIsPSPOLL = false;
        u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
@@ -1492,10 +1417,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     }
 
        pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
-    pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
     cbFrameBodySize = pPacket->cbPayloadLen;
-    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
-    wTxBufSize = sizeof(STxBufHead);
+       pTxBufHead = &pTX_Buffer->fifo_head;
+       pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
+       wTxBufSize = sizeof(struct vnt_tx_fifo_head);
 
     if (pDevice->byBBType == BB_TYPE_11A) {
         wCurrentRate = RATE_6M;
@@ -1607,21 +1532,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
 
     //Set RrvTime/RTS/CTS Buffer
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
-
-       pvRrvTime = (struct vnt_rrv_time_cts *) (pbyTxBufferAddr + wTxBufSize);
-        pMICHDR = NULL;
-       rts_cts = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_cts));
-       pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr + wTxBufSize +
-               sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-               sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+               sizeof(struct vnt_cts);
     }
     else { // 802.11a/b packet
-       pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
-        pMICHDR = NULL;
-       pvTxDataHd = (struct vnt_tx_datahead_ab *) (pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_ab));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                sizeof(struct vnt_tx_datahead_ab);
     }
@@ -1638,14 +1552,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
 
        /* Fill FIFO,RrvTime,RTS,and CTS */
-       s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               pbyTxBufferAddr, pvRrvTime, rts_cts,
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+               pTX_Buffer, &pMICHDR, 0,
                cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
 
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
-                               AUTO_FB_NONE);
-
     pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
@@ -1684,7 +1594,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
             }
         } while(false);
         //Fill TXKEY
-        s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+       s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
                      (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
 
         memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
@@ -1708,12 +1618,16 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+               struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
+                                               tx_cts.tx.head.cts_g.data_head;
+               data_head->wDuration_a =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+               data_head->wDuration_b =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
        } else {
-               ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+               struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
+                                       tx_ab.tx.head.data_head_ab;
+               data_head->wDuration =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
        }
     }
@@ -1727,10 +1641,14 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     pContext->uBufLen = (u16)cbReqCount + 4;  //USB header
 
     if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr1[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
     else {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr3[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
 
     PIPEnsSendBulkOut(pDevice,pContext);
@@ -1825,15 +1743,13 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
 {
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        struct vnt_tx_buffer *pTX_Buffer;
+       struct vnt_tx_fifo_head *pTxBufHead;
        u8 byPktType;
        u8 *pbyTxBufferAddr;
-       void *rts_cts = NULL;
-       void *pvTxDataHd;
        u32 uDuration, cbReqCount;
        struct ieee80211_hdr *pMACHeader;
        u32 cbHeaderSize, cbFrameBodySize;
        int bNeedACK, bIsPSPOLL = false;
-       PSTxBufHead pTxBufHead;
        u32 cbFrameSize;
        u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
        u32 uPadding = 0;
@@ -1844,7 +1760,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
        u16 wTxBufSize;
        u32 cbMacHdLen;
        struct ethhdr sEthHeader;
-       void *pvRrvTime, *pMICHDR;
+       struct vnt_mic_hdr *pMICHDR;
        u32 wCurrentRate = RATE_1M;
        PUWLAN_80211HDR  p80211Header;
        u32 uNodeIndex = 0;
@@ -1855,7 +1771,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
        u32 cbExtSuppRate = 0;
        struct vnt_usb_send_context *pContext;
 
-       pvRrvTime = pMICHDR = pvTxDataHd = NULL;
+       pMICHDR = NULL;
 
     if(skb->len <= WLAN_HDR_ADDR3_LEN) {
        cbFrameBodySize = 0;
@@ -1874,9 +1790,9 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     }
 
        pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
-    pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
-    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
-    wTxBufSize = sizeof(STxBufHead);
+       pTxBufHead = &pTX_Buffer->fifo_head;
+       pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
+       wTxBufSize = sizeof(struct vnt_tx_fifo_head);
 
     if (pDevice->byBBType == BB_TYPE_11A) {
         wCurrentRate = RATE_6M;
@@ -2014,25 +1930,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
 
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
-       pvRrvTime = (struct vnt_rrv_time_cts *) (pbyTxBufferAddr + wTxBufSize);
-       pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_cts));
-       rts_cts = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-       pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-                                       sizeof(struct vnt_cts));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-               sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+               sizeof(struct vnt_cts);
 
     }
     else {//802.11a/b packet
-
-       pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
-       pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-               sizeof(struct vnt_rrv_time_ab));
-       pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
                                        sizeof(struct vnt_tx_datahead_ab);
     }
@@ -2048,15 +1950,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
 
        /* Fill FIFO,RrvTime,RTS,and CTS */
-       s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               pbyTxBufferAddr, pvRrvTime, rts_cts,
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+               pTX_Buffer, &pMICHDR, cbMICHDR,
                cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
 
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
-                               AUTO_FB_NONE);
-
-    pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
+       pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
 
@@ -2139,7 +2037,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
 
         }
 
-        s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+       s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
                pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
 
         if (pDevice->bEnableHostWEP) {
@@ -2164,12 +2062,16 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+               struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
+                                               tx_cts.tx.head.cts_g.data_head;
+               data_head->wDuration_a =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+               data_head->wDuration_b =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
        } else {
-               ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+               struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
+                                       tx_ab.tx.head.data_head_ab;
+               data_head->wDuration =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
        }
     }
@@ -2183,10 +2085,14 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     pContext->uBufLen = (u16)cbReqCount + 4;  //USB header
 
     if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr1[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
     else {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr3[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
     PIPEnsSendBulkOut(pDevice,pContext);
     return ;
@@ -2568,7 +2474,10 @@ int nsDMA_tx_packet(struct vnt_private *pDevice,
     pContext->Type = CONTEXT_DATA_PACKET;
     pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
 
-    s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
+    s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pContext->sEthHeader.h_dest[0],
+                       (u16)(BytesToWrite-uHeaderLen),
+                       pTX_Buffer->fifo_head.wFIFOCtl);
 
     status = PIPEnsSendBulkOut(pDevice,pContext);
 
@@ -2719,7 +2628,10 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
     pContext->Type = CONTEXT_DATA_PACKET;
     pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
 
-    s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
+    s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+               &pContext->sEthHeader.h_dest[0],
+               (u16)(BytesToWrite - uHeaderLen),
+               pTX_Buffer->fifo_head.wFIFOCtl);
 
     status = PIPEnsSendBulkOut(pDevice,pContext);
 
index 4bbee1c2fcacef62a866c7b222605210ee2674ec..eecbe890027e50976461925022ac87e8dac9dfc8 100644 (file)
@@ -117,6 +117,7 @@ struct vnt_rts_g {
        u16 wDuration_bb;
        u16 wReserved;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_g data_head;
 } __packed;
 
 struct vnt_rts_g_fb {
@@ -131,6 +132,7 @@ struct vnt_rts_g_fb {
        u16 wRTSDuration_ba_f1;
        u16 wRTSDuration_aa_f1;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_g_fb data_head;
 } __packed;
 
 struct vnt_rts_ab {
@@ -138,6 +140,7 @@ struct vnt_rts_ab {
        u16 wDuration;
        u16 wReserved;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_ab data_head;
 } __packed;
 
 struct vnt_rts_a_fb {
@@ -147,6 +150,7 @@ struct vnt_rts_a_fb {
        u16 wRTSDuration_f0;
        u16 wRTSDuration_f1;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_a_fb data_head;
 } __packed;
 
 /* CTS buffer header */
@@ -156,6 +160,7 @@ struct vnt_cts {
        u16 wReserved;
        struct ieee80211_cts data;
        u16 reserved2;
+       struct vnt_tx_datahead_g data_head;
 } __packed;
 
 struct vnt_cts_fb {
@@ -166,6 +171,7 @@ struct vnt_cts_fb {
        u16 wCTSDuration_ba_f1;
        struct ieee80211_cts data;
        u16 reserved2;
+       struct vnt_tx_datahead_g_fb data_head;
 } __packed;
 
 union vnt_tx_data_head {
@@ -178,12 +184,37 @@ union vnt_tx_data_head {
        /* cts g */
        struct vnt_cts cts_g;
        struct vnt_cts_fb cts_g_fb;
+       /* no rts/cts */
+       struct vnt_tx_datahead_a_fb data_head_a_fb;
+       struct vnt_tx_datahead_ab data_head_ab;
 };
 
-struct vnt_tx_buffer {
-       u8 byType;
-       u8 byPKTNO;
-       u16 wTxByteCount;
+struct vnt_tx_mic_hdr {
+       struct vnt_mic_hdr hdr;
+       union vnt_tx_data_head head;
+} __packed;
+
+union vnt_tx {
+       struct vnt_tx_mic_hdr mic;
+       union vnt_tx_data_head head;
+};
+
+union vnt_tx_head {
+       struct {
+               struct vnt_rrv_time_rts rts;
+               union vnt_tx tx;
+       } __packed tx_rts;
+       struct {
+               struct vnt_rrv_time_cts cts;
+               union vnt_tx tx;
+       } __packed tx_cts;
+       struct {
+               struct vnt_rrv_time_ab ab;
+               union vnt_tx tx;
+       } __packed tx_ab;
+};
+
+struct vnt_tx_fifo_head {
        u32 adwTxKey[4];
        u16 wFIFOCtl;
        u16 wTimeStamp;
@@ -191,6 +222,14 @@ struct vnt_tx_buffer {
        u16 wReserved;
 } __packed;
 
+struct vnt_tx_buffer {
+       u8 byType;
+       u8 byPKTNO;
+       u16 wTxByteCount;
+       struct vnt_tx_fifo_head fifo_head;
+       union vnt_tx_head tx_head;
+} __packed;
+
 struct vnt_beacon_buffer {
        u8 byType;
        u8 byPKTNO;
index 3a03f1d5b6856c3c948b33253dfc4e06d5f2928a..5fc18ad822d3046f65cf4205c4484dccbf85e16b 100644 (file)
@@ -118,6 +118,9 @@ int PIPEnsControlOut(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
        if (pDevice->Flags & fMP_CONTROL_READS)
                return STATUS_FAILURE;
 
+       if (pDevice->pControlURB->hcpriv)
+               return STATUS_FAILURE;
+
        MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
 
        pDevice->sUsbCtlRequest.bRequestType = 0x40;
@@ -177,6 +180,9 @@ int PIPEnsControlIn(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
        if (pDevice->Flags & fMP_CONTROL_WRITES)
                return STATUS_FAILURE;
 
+       if (pDevice->pControlURB->hcpriv)
+               return STATUS_FAILURE;
+
        MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
 
        pDevice->sUsbCtlRequest.bRequestType = 0xC0;
@@ -656,8 +662,6 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
         pDevice->ulBulkOutBytesWrite += ulBufLen;
         pDevice->ulBulkOutContCRCError = 0;
-       pDevice->nTxDataTimeCout = 0;
-
     } else {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
         pDevice->ulBulkOutError++;
index 0013cb73d83bcc94dfdadb5e5f3c0aadfdfe9236..2f8e2a87533182a8f9bfa4fd3f62857067d8a731 100644 (file)
@@ -268,20 +268,14 @@ struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
 
 void vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond)
 {
-
-       init_timer(&pDevice->sTimerCommand);
-
-       pDevice->sTimerCommand.data = (unsigned long)pDevice;
-       pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
-       pDevice->sTimerCommand.expires = RUN_AT((MSecond * HZ) / 1000);
-
-       add_timer(&pDevice->sTimerCommand);
-
-       return;
+       schedule_delayed_work(&pDevice->run_command_work,
+                                               msecs_to_jiffies(MSecond));
 }
 
-void vRunCommand(struct vnt_private *pDevice)
+void vRunCommand(struct work_struct *work)
 {
+       struct vnt_private *pDevice =
+               container_of(work, struct vnt_private, run_command_work.work);
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        PWLAN_IE_SSID pItemSSID;
        PWLAN_IE_SSID pItemSSIDCurr;
@@ -292,6 +286,9 @@ void vRunCommand(struct vnt_private *pDevice)
        u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
        u8 byData;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     if (pDevice->dwDiagRefCount != 0)
         return;
     if (pDevice->bCmdRunning != true)
@@ -660,22 +657,6 @@ void vRunCommand(struct vnt_private *pDevice)
                     netif_wake_queue(pDevice->dev);
                 }
 
-                if(pDevice->IsTxDataTrigger != false)   {    //TxDataTimer is not triggered at the first time
-                     // printk("Re-initial TxDataTimer****\n");
-                   del_timer(&pDevice->sTimerTxData);
-                      init_timer(&pDevice->sTimerTxData);
-                       pDevice->sTimerTxData.data = (unsigned long) pDevice;
-                      pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
-                      pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
-                      pDevice->fTxDataInSleep = false;
-                      pDevice->nTxDataTimeCout = 0;
-                }
-                else {
-                  // printk("mike:-->First time trigger TimerTxData InSleep\n");
-                }
-               pDevice->IsTxDataTrigger = true;
-                add_timer(&pDevice->sTimerTxData);
-
             }
           else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
                printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
@@ -687,7 +668,6 @@ void vRunCommand(struct vnt_private *pDevice)
               vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2);
               return;
           }
-                 pDevice->byLinkWaitCount = 0;
 
             s_bCommandComplete(pDevice);
             break;
@@ -696,7 +676,7 @@ void vRunCommand(struct vnt_private *pDevice)
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
 
             if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
-                del_timer(&pMgmt->sTimerSecondCallback);
+               cancel_delayed_work_sync(&pDevice->second_callback_work);
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                 pDevice->bLinkPass = false;
@@ -724,7 +704,7 @@ void vRunCommand(struct vnt_private *pDevice)
                 }
                 pDevice->bLinkPass = true;
                 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
-                add_timer(&pMgmt->sTimerSecondCallback);
+               schedule_delayed_work(&pDevice->second_callback_work, HZ);
             }
             s_bCommandComplete(pDevice);
             break;
@@ -1156,14 +1136,8 @@ static int s_bClearBSSID_SCAN(struct vnt_private *pDevice)
 //mike add:reset command timer
 void vResetCommandTimer(struct vnt_private *pDevice)
 {
+       cancel_delayed_work_sync(&pDevice->run_command_work);
 
-       //delete timer
-       del_timer(&pDevice->sTimerCommand);
-       //init timer
-       init_timer(&pDevice->sTimerCommand);
-       pDevice->sTimerCommand.data = (unsigned long)pDevice;
-       pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
-       pDevice->sTimerCommand.expires = RUN_AT(HZ);
        pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
        pDevice->uCmdDequeueIdx = 0;
        pDevice->uCmdEnqueueIdx = 0;
@@ -1171,33 +1145,3 @@ void vResetCommandTimer(struct vnt_private *pDevice)
        pDevice->bCmdRunning = false;
        pDevice->bCmdClear = false;
 }
-
-void BSSvSecondTxData(struct vnt_private *pDevice)
-{
-       struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
-       pDevice->nTxDataTimeCout++;
-
-       if (pDevice->nTxDataTimeCout < 4) {   //don't tx data if timer less than 40s
-               // printk("mike:%s-->no data Tx not exceed the desired Time as %d\n",__FUNCTION__,
-               //      (int)pDevice->nTxDataTimeCout);
-               pDevice->sTimerTxData.expires = RUN_AT(10 * HZ);      //10s callback
-               add_timer(&pDevice->sTimerTxData);
-               return;
-       }
-
-       spin_lock_irq(&pDevice->lock);
-       //is wap_supplicant running successful OR only open && sharekey mode!
-       if (((pDevice->bLinkPass == true) &&
-               (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
-               (pDevice->fWPA_Authened == true)) {   //wpa linking
-               //   printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__);
-               pDevice->fTxDataInSleep = true;
-               PSbSendNullPacket(pDevice);      //send null packet
-               pDevice->fTxDataInSleep = false;
-       }
-       spin_unlock_irq(&pDevice->lock);
-
-       pDevice->sTimerTxData.expires = RUN_AT(10 * HZ);      //10s callback
-       add_timer(&pDevice->sTimerTxData);
-}
index db8b4cf7fd601ff4f29832658481abbb2c8c3708..caf2684ce9151f34961d5d203e4e7949c5d5b9da 100644 (file)
@@ -105,15 +105,6 @@ void vResetCommandTimer(struct vnt_private *);
 
 int bScheduleCommand(struct vnt_private *, CMD_CODE eCommand, u8 *pbyItem0);
 
-void vRunCommand(struct vnt_private *);
-
-/*
-void
-WCMDvCommandThread(
-    void * Context
-    );
-*/
-
-void BSSvSecondTxData(struct vnt_private *);
+void vRunCommand(struct work_struct *work);
 
 #endif /* __WCMD_H__ */
index 47a655db51efe7491af61f9243691e3660ea7ff4..814342cd948ed9509d175d8ece30734b05d9f69a 100644 (file)
@@ -69,8 +69,7 @@ bool WCTLbIsDuplicate (PSCache pCache, struct ieee80211_hdr *pMACHeader)
         for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
             pCacheEntry = &(pCache->asCacheEntry[uIndex]);
             if ((pCacheEntry->wFmSequence == pMACHeader->seq_ctrl) &&
-               (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]),
-                                    &(pMACHeader->addr2[0]))) &&
+               ether_addr_equal(pCacheEntry->abyAddr2, pMACHeader->addr2) &&
                 (LOBYTE(pCacheEntry->wFrameCtl) == LOBYTE(pMACHeader->frame_control))
                 ) {
                 /* Duplicate match */
@@ -110,8 +109,8 @@ unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice,
 
        for (ii = 0; ii < pDevice->cbDFCB; ii++) {
                if ((pDevice->sRxDFCB[ii].bInUse == true) &&
-                   (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]),
-                                         &(pMACHeader->addr2[0])))) {
+                   ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2,
+                                    pMACHeader->addr2)) {
                        return ii;
                }
        }
index b6cbd138a2b46c615b0870c2c8dca58d094372b5..e26c41519b156dbc04bef2d3ae6e91b0cf0bc017 100644 (file)
@@ -81,7 +81,7 @@
 #include "control.h"
 #include "rndis.h"
 
-static int          msglevel                =MSG_LEVEL_INFO;
+static int msglevel = MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 
 static int ChannelExceedZoneType(struct vnt_private *, u8 byCurrChannel);
@@ -213,24 +213,6 @@ void vMgrObjectInit(struct vnt_private *pDevice)
     pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
     BSSvClearBSSList((void *) pDevice, false);
 
-    init_timer(&pMgmt->sTimerSecondCallback);
-    pMgmt->sTimerSecondCallback.data = (unsigned long)pDevice;
-    pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
-    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
-
-    init_timer(&pDevice->sTimerCommand);
-    pDevice->sTimerCommand.data = (unsigned long)pDevice;
-    pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
-    pDevice->sTimerCommand.expires = RUN_AT(HZ);
-
-    init_timer(&pDevice->sTimerTxData);
-    pDevice->sTimerTxData.data = (unsigned long)pDevice;
-    pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
-    pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
-    pDevice->fTxDataInSleep = false;
-    pDevice->IsTxDataTrigger = false;
-    pDevice->nTxDataTimeCout = 0;
-
     pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
     pDevice->uCmdDequeueIdx = 0;
     pDevice->uCmdEnqueueIdx = 0;
@@ -844,8 +826,8 @@ static void s_vMgrRxAssocResponse(struct vnt_private *pDevice,
               pDevice->bwextstep3 = false;
               pDevice->bWPASuppWextEnabled = false;
 
-if(pMgmt->eCurrState == WMAC_STATE_ASSOC)
-      timer_expire(pDevice->sTimerCommand, 0);
+       if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
+               schedule_delayed_work(&pDevice->run_command_work, 0);
 
     return;
 }
@@ -1127,7 +1109,7 @@ static void s_vMgrRxAuthenSequence_2(struct vnt_private *pDevice,
             if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
                 pMgmt->eCurrState = WMAC_STATE_AUTH;
-              timer_expire(pDevice->sTimerCommand, 0);
+               schedule_delayed_work(&pDevice->run_command_work, 0);
             }
             else {
                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
@@ -1302,7 +1284,7 @@ static void s_vMgrRxAuthenSequence_4(struct vnt_private *pDevice,
     if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
         pMgmt->eCurrState = WMAC_STATE_AUTH;
-        timer_expire(pDevice->sTimerCommand, 0);
+       schedule_delayed_work(&pDevice->run_command_work, 0);
     }
     else{
         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
@@ -1422,8 +1404,8 @@ static void s_vMgrRxDeauthentication(struct vnt_private *pDevice,
           pDevice->fWPA_Authened = false;
             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
             // TODO: update BSS list for specific BSSID if pre-authentication case
-           if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3,
-                                   pMgmt->abyCurrBSSID)) {
+           if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
+                                pMgmt->abyCurrBSSID)) {
                 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
                     pMgmt->sNodeDBTable[0].bActive = false;
                     pMgmt->eCurrMode = WMAC_MODE_STANDBY;
@@ -3095,7 +3077,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
  *
  *
  * Return Value:
- *    A ptr to frame or NULL on allocation failue
+ *    A ptr to frame or NULL on allocation failure
  *
 -*/
 
index 5424c7f820ade84f57ac0a1af70fcc195b246cea..26ba47da467b0cc81164e534ac4babf4857dd686 100644 (file)
@@ -310,9 +310,6 @@ struct vnt_manager {
        u8 byMgmtPacketPool[sizeof(struct vnt_tx_mgmt)
                + WLAN_A3FR_MAXLEN];
 
-       /* One second callback timer */
-       struct timer_list sTimerSecondCallback;
-
        /* Temporarily Rx Mgmt Packet Descriptor */
        struct vnt_rx_mgmt sRxPacket;
 
index 9f1b413ce86f7534cf7ccc30bb2de26cc0c7ded0..003bd7c614e5f726b9e94109ebef08391dec260c 100644 (file)
@@ -227,7 +227,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx)
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
                } else {
                        // Key Table Full
-                       if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
+                       if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
                                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                                return -EINVAL;
                        } else {
index 6160b2fab833fe700e5478aa0a5c2f71484e0282..fc0ef24fad3b10f3ffc732957e89f9c8eddf9ba3 100644 (file)
@@ -18,8 +18,8 @@
 struct mlme_frame {
        s8              *pMMPDU;
        u16             len;
-       u8              DataType;
-       u8              IsInUsed;
+       u8              data_type;
+       u8              is_in_used;
 
        u8              TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE];
        u8              TxMMPDUInUse[(MAX_NUM_TX_MMPDU + 3) & ~0x03];
@@ -52,13 +52,9 @@ struct wbsoft_priv {
        struct hw_data sHwData; /*For HAL */
        struct wb35_mds Mds;
 
-       atomic_t ThreadCount;
-
        u32 RxByteCount;
        u32 TxByteCount;
 
-       u8 LinkName[WB_MAX_LINK_NAME_LEN];
-
        bool enabled;
 };
 
index fcc3d2165ba9e719cac072f6f0846437ef80a65e..cac7720bef2b26922039606ef993c33b24e6e4c8 100644 (file)
@@ -412,7 +412,7 @@ static void MLME_GetNextPacket(struct wbsoft_priv *adapter,
        desc->buffer_size[desc->InternalUsed] = adapter->sMlmeFrame.len;
        desc->buffer_total_size += adapter->sMlmeFrame.len;
        desc->buffer_number++;
-       desc->Type = adapter->sMlmeFrame.DataType;
+       desc->Type = adapter->sMlmeFrame.data_type;
 }
 
 static void MLMEfreeMMPDUBuffer(struct wbsoft_priv *adapter, s8 *pData)
@@ -440,7 +440,7 @@ static void MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID,
        MLMEfreeMMPDUBuffer(adapter, adapter->sMlmeFrame.pMMPDU);
 
        /* Return resource */
-       adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE;
+       adapter->sMlmeFrame.is_in_used = PACKET_FREE_TO_USE;
 }
 
 void
index 560c0ab617d1e2b981555a9aa811857e32e65e33..b031ecd4f3c0302cea95a7cbed6455d123f23173 100644 (file)
@@ -21,6 +21,7 @@
 #include "wbhal.h"
 #include "wb35reg_f.h"
 #include "core.h"
+#include "mto.h"
 
 /* Declare SQ3 to rate and fragmentation threshold table */
 /* Declare fragmentation threshold table */
@@ -45,12 +46,6 @@ static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];
 
 static u8 boSparseTxTraffic;
 
-void MTO_Init(struct wbsoft_priv *adapter);
-void TxRateReductionCtrl(struct wbsoft_priv *adapter);
-void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
-void MTO_TxFailed(struct wbsoft_priv *adapter);
-void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer);
-
 /*
  * ===========================================================================
  * MTO_Init --
index a0f659cf99ffc84d47d4fb86dc9ab78d105ea7fd..8d41eeda45bf39e612bbfdb21c086434b499ad8a 100644 (file)
@@ -127,12 +127,8 @@ extern u16 MTO_Frag_Th_Tbl[];
 #define MTO_DATA_RATE()                        MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
 #define MTO_FRAG_TH()                  MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
 
-extern void MTO_Init(struct wbsoft_priv *);
-extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
-extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
-extern u8 MTO_GetTxRate(struct wbsoft_priv *adapter, u32 fpdu_len);
-extern u8 MTO_GetTxFallbackRate(struct wbsoft_priv *adapter);
-extern void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+void MTO_Init(struct wbsoft_priv *);
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
 
 #endif /* __MTO_H__ */
 
index cfbfbbb53866cbfd08f31592fc1c78d3c2db6a6a..8aecced62ddeeae9d03b7688b462800a4a42e25f 100644 (file)
 #define DEG2RAD(X)      (0.017453 * (X))
 
 static const s32 Angles[] = {
-       FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
-       FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
-       FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
-       FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
+       FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),
+       FIXED(DEG2RAD(14.0362)),  FIXED(DEG2RAD(7.12502)),
+       FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
+       FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)),
+       FIXED(DEG2RAD(0.223811)), FIXED(DEG2RAD(0.111906)),
+       FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
 };
 
 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
@@ -42,7 +44,7 @@ static const s32 Angles[] = {
 
 /****************** FUNCTION DEFINITION SECTION *****************************/
 
-s32 _s13_to_s32(u32 data)
+static s32 _s13_to_s32(u32 data)
 {
        u32     val;
 
@@ -54,22 +56,8 @@ s32 _s13_to_s32(u32 data)
        return (s32) val;
 }
 
-u32 _s32_to_s13(s32 data)
-{
-       u32     val;
-
-       if (data > 4095)
-               data = 4095;
-       else if (data < -4096)
-               data = -4096;
-
-       val = data & 0x1FFF;
-
-       return val;
-}
-
 /****************************************************************************/
-s32 _s4_to_s32(u32 data)
+static s32 _s4_to_s32(u32 data)
 {
        s32     val;
 
@@ -81,7 +69,7 @@ s32 _s4_to_s32(u32 data)
        return val;
 }
 
-u32 _s32_to_s4(s32 data)
+static u32 _s32_to_s4(s32 data)
 {
        u32     val;
 
@@ -96,7 +84,7 @@ u32 _s32_to_s4(s32 data)
 }
 
 /****************************************************************************/
-s32 _s5_to_s32(u32 data)
+static s32 _s5_to_s32(u32 data)
 {
        s32     val;
 
@@ -108,7 +96,7 @@ s32 _s5_to_s32(u32 data)
        return val;
 }
 
-u32 _s32_to_s5(s32 data)
+static u32 _s32_to_s5(s32 data)
 {
        u32     val;
 
@@ -123,7 +111,7 @@ u32 _s32_to_s5(s32 data)
 }
 
 /****************************************************************************/
-s32 _s6_to_s32(u32 data)
+static s32 _s6_to_s32(u32 data)
 {
        s32     val;
 
@@ -135,7 +123,7 @@ s32 _s6_to_s32(u32 data)
        return val;
 }
 
-u32 _s32_to_s6(s32 data)
+static u32 _s32_to_s6(s32 data)
 {
        u32     val;
 
@@ -150,34 +138,7 @@ u32 _s32_to_s6(s32 data)
 }
 
 /****************************************************************************/
-s32 _s9_to_s32(u32 data)
-{
-       s32     val;
-
-       val = data & 0x00FF;
-
-       if ((data & BIT(8)) != 0)
-               val |= 0xFFFFFF00;
-
-       return val;
-}
-
-u32 _s32_to_s9(s32 data)
-{
-       u32     val;
-
-       if (data > 255)
-               data = 255;
-       else if (data < -256)
-               data = -256;
-
-       val = data & 0x01FF;
-
-       return val;
-}
-
-/****************************************************************************/
-s32 _floor(s32 n)
+static s32 _floor(s32 n)
 {
        if (n > 0)
                n += 5;
@@ -193,7 +154,7 @@ s32 _floor(s32 n)
  * sqsum is the input and the output is sq_rt;
  * The maximum of sqsum = 2^27 -1;
  */
-u32 _sqrt(u32 sqsum)
+static u32 _sqrt(u32 sqsum)
 {
        u32     sq_rt;
 
@@ -261,7 +222,7 @@ u32 _sqrt(u32 sqsum)
 }
 
 /****************************************************************************/
-void _sin_cos(s32 angle, s32 *sin, s32 *cos)
+static void _sin_cos(s32 angle, s32 *sin, s32 *cos)
 {
        s32 X, Y, TargetAngle, CurrAngle;
        unsigned    Step;
@@ -296,7 +257,8 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos)
        }
 }
 
-static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 *pValue)
+static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number,
+                                    u32 *pValue)
 {
        if (number < 0x1000)
                number += 0x1000;
@@ -304,7 +266,8 @@ static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 *p
 }
 #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
 
-static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
+static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number,
+                                    u32 value)
 {
        unsigned char ret;
 
@@ -316,7 +279,7 @@ static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 va
 #define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
 
 
-void _reset_rx_cal(struct hw_data *phw_data)
+static void _reset_rx_cal(struct hw_data *phw_data)
 {
        u32     val;
 
@@ -336,7 +299,7 @@ void _reset_rx_cal(struct hw_data *phw_data)
 
 
 /**********************************************/
-void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
+static void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
 {
        u32     reg_agc_ctrl3;
        u32     reg_a_acq_ctrl;
@@ -407,7 +370,8 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        PHY_DEBUG(("[CAL]    ** adc_dc_cal_i = %d (0x%04X)\n",
                           _s9_to_s32(val&0x000001FF), val&0x000001FF));
        PHY_DEBUG(("[CAL]    ** adc_dc_cal_q = %d (0x%04X)\n",
-                          _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
+                          _s9_to_s32((val&0x0003FE00)>>9),
+                          (val&0x0003FE00)>>9));
 #endif
 
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
@@ -430,249 +394,8 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
 }
 
-/****************************************************************/
-void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
-{
-       u32     reg_agc_ctrl3;
-       u32     reg_mode_ctrl;
-       u32     reg_dc_cancel;
-       s32     iqcal_image_i;
-       s32     iqcal_image_q;
-       u32     sqsum;
-       s32     mag_0;
-       s32     mag_1;
-       s32     fix_cancel_dc_i = 0;
-       u32     val;
-       int     loop;
-
-       PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
-
-       /* a. Set to "TX calibration mode" */
-
-       /* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
-       phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
-       /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
-       phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
-       /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
-       phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
-       /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
-       phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
-       /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
-       phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
-
-       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
-
-       /* a. Disable AGC */
-       hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
-       reg_agc_ctrl3 &= ~BIT(2);
-       reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
-       hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
-
-       hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
-       val |= MASK_AGC_FIX_GAIN;
-       hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
-
-       /* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */
-       hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
-
-       PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
-       reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
-
-       /* mode=2, tone=0 */
-       /* reg_mode_ctrl |= (MASK_CALIB_START|2); */
-
-       /* mode=2, tone=1 */
-       /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
-
-       /* mode=2, tone=2 */
-       reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
-       hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
-       PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
-       hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
-       PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
-
-       for (loop = 0; loop < LOOP_TIMES; loop++) {
-               PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
-
-               /* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
-               reg_dc_cancel &= ~(0x03FF);
-               PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
-               hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
-
-               hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
-               PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
-
-               iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
-               iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
-               sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
-               mag_0 = (s32) _sqrt(sqsum);
-               PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
-                                  mag_0, iqcal_image_i, iqcal_image_q));
-
-               /* d. */
-               reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
-               PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
-               hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
-
-               hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
-               PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
-
-               iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
-               iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
-               sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
-               mag_1 = (s32) _sqrt(sqsum);
-               PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
-                                  mag_1, iqcal_image_i, iqcal_image_q));
-
-               /* e. Calculate the correct DC offset cancellation value for I */
-               if (mag_0 != mag_1)
-                       fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
-               else {
-                       if (mag_0 == mag_1)
-                               PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
-                       fix_cancel_dc_i = 0;
-               }
-
-               PHY_DEBUG(("[CAL]    ** fix_cancel_dc_i = %d (0x%04X)\n",
-                                  fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
-
-               if ((abs(mag_1-mag_0)*6) > mag_0)
-                       break;
-       }
-
-       if (loop >= 19)
-               fix_cancel_dc_i = 0;
-
-       reg_dc_cancel &= ~(0x03FF);
-       reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
-       hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
-       PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
-
-       /* g. */
-       reg_mode_ctrl &= ~MASK_CALIB_START;
-       hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
-       PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-}
-
-/*****************************************************/
-void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
-{
-       u32     reg_agc_ctrl3;
-       u32     reg_mode_ctrl;
-       u32     reg_dc_cancel;
-       s32     iqcal_image_i;
-       s32     iqcal_image_q;
-       u32     sqsum;
-       s32     mag_0;
-       s32     mag_1;
-       s32     fix_cancel_dc_q = 0;
-       u32     val;
-       int     loop;
-
-       PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
-       /*0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
-       phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
-       /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
-       phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
-       /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
-       phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
-       /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
-       phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
-       /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
-       phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
-
-       hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
-
-       /* a. Disable AGC */
-       hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
-       reg_agc_ctrl3 &= ~BIT(2);
-       reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
-       hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
-
-       hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
-       val |= MASK_AGC_FIX_GAIN;
-       hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
-
-       /* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */
-       hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
-       PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
-
-       /* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */
-       reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
-       reg_mode_ctrl |= (MASK_CALIB_START|3);
-       hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
-       PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
-       hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
-       PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
-
-       for (loop = 0; loop < LOOP_TIMES; loop++) {
-               PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
-
-               /* b. reset cancel_dc_q[4:0] in register DC_Cancel */
-               reg_dc_cancel &= ~(0x001F);
-               PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
-               hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
-
-               hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
-               PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
-
-               iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
-               iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
-               sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
-               mag_0 = _sqrt(sqsum);
-               PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
-                                  mag_0, iqcal_image_i, iqcal_image_q));
-
-               /* c. */
-               reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
-               PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
-               hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
-
-               hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
-               PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
-
-               iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
-               iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
-               sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
-               mag_1 = _sqrt(sqsum);
-               PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
-                                  mag_1, iqcal_image_i, iqcal_image_q));
-
-               /* d. Calculate the correct DC offset cancellation value for I */
-               if (mag_0 != mag_1)
-                       fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
-               else {
-                       if (mag_0 == mag_1)
-                               PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
-                       fix_cancel_dc_q = 0;
-               }
-
-               PHY_DEBUG(("[CAL]    ** fix_cancel_dc_q = %d (0x%04X)\n",
-                                  fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
-
-               if ((abs(mag_1-mag_0)*6) > mag_0)
-                       break;
-       }
-
-       if (loop >= 19)
-               fix_cancel_dc_q = 0;
-
-       reg_dc_cancel &= ~(0x001F);
-       reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
-       hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
-       PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
-
-
-       /* f. */
-       reg_mode_ctrl &= ~MASK_CALIB_START;
-       hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
-       PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-}
-
 /* 20060612.1.a 20060718.1 Modify */
-u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
+static u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                                                   s32 a_2_threshold,
                                                   s32 b_2_threshold)
 {
@@ -711,7 +434,8 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
        loop = LOOP_TIMES;
 
        while (loop > 0) {
-               PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
+               PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n",
+                                  (LOOP_TIMES-loop+1)));
 
                iqcal_tone_i_avg = 0;
                iqcal_tone_q_avg = 0;
@@ -719,8 +443,8 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        return 0;
                for (capture_time = 0; capture_time < 10; capture_time++) {
                        /*
-                        * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
-                        *    enable "IQ calibration Mode II"
+                        * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start"
+                        *    to 0x1 to enable "IQ calibration Mode II"
                         */
                        reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
                        reg_mode_ctrl &= ~MASK_IQCAL_MODE;
@@ -749,8 +473,8 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
                        /*
-                        * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
-                        *    enable "IQ calibration Mode II"
+                        * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start"
+                        *    to 0x1 to enable "IQ calibration Mode II"
                         */
                        /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
                        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
@@ -766,7 +490,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
                        iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
                        PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
-                       iqcal_tone_i, iqcal_tone_q));
+                                          iqcal_tone_i, iqcal_tone_q));
                        if (capture_time == 0)
                                continue;
                        else {
@@ -955,7 +679,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
        return 1;
 }
 
-void _tx_iq_calibration_winbond(struct hw_data *phw_data)
+static void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 {
        u32     reg_agc_ctrl3;
 #ifdef _DEBUG
@@ -1101,7 +825,7 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 }
 
 /*****************************************************/
-u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
+static u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
 {
        u32     reg_mode_ctrl;
        s32     iqcal_tone_i;
@@ -1146,7 +870,8 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
        /* for (loop = 0; loop < LOOP_TIMES; loop++) */
        loop = LOOP_TIMES;
        while (loop > 0) {
-               PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
+               PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n",
+                                  (LOOP_TIMES-loop+1)));
                iqcal_tone_i_avg = 0;
                iqcal_tone_q_avg = 0;
                iqcal_image_i_avg = 0;
@@ -1199,13 +924,13 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
 
                /* d. */
                rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
-                                               iqcal_tone_q * iqcal_tone_q) / 1024;
+                                       iqcal_tone_q * iqcal_tone_q) / 1024;
                rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
-                                               iqcal_tone_q * iqcal_tone_i) / 1024;
+                                       iqcal_tone_q * iqcal_tone_i) / 1024;
                rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
-                                                iqcal_image_q * iqcal_tone_q) / 1024;
+                                       iqcal_image_q * iqcal_tone_q) / 1024;
                rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
-                                                iqcal_image_q * iqcal_tone_i) / 1024;
+                                       iqcal_image_q * iqcal_tone_i) / 1024;
 
                PHY_DEBUG(("[CAL]    ** rot_tone_i_b  = %d\n", rot_tone_i_b));
                PHY_DEBUG(("[CAL]    ** rot_tone_q_b  = %d\n", rot_tone_q_b));
@@ -1225,8 +950,10 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
                        phw_data->iq_rsdl_phase_tx_d2;
 
-               PHY_DEBUG(("[CAL]    ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
-               PHY_DEBUG(("[CAL]    ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
+               PHY_DEBUG(("[CAL]    ** iq_rsdl_gain_tx_d2 = %d\n",
+                          phw_data->iq_rsdl_gain_tx_d2));
+               PHY_DEBUG(("[CAL]    ** iq_rsdl_phase_tx_d2= %d\n",
+                          phw_data->iq_rsdl_phase_tx_d2));
                PHY_DEBUG(("[CAL]    ***** EPSILON/2 = %d\n", a_2));
                PHY_DEBUG(("[CAL]    ***** THETA/2   = %d\n", b_2));
 
@@ -1272,7 +999,8 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
 
                /* e. */
                pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
-               pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
+               pwr_image = (iqcal_image_i*iqcal_image_i +
+                            iqcal_image_q*iqcal_image_q)*factor;
 
                PHY_DEBUG(("[CAL]    ** pwr_tone  = %d\n", pwr_tone));
                PHY_DEBUG(("[CAL]    ** pwr_image  = %d\n", pwr_image));
@@ -1371,7 +1099,7 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
 /*************************************************/
 
 /***************************************************************/
-void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
+static void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 {
 /* figo 20050523 marked this flag for can't compile for release */
 #ifdef _DEBUG
@@ -1569,7 +1297,8 @@ unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
 
                sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
                iq_mag_0_tx = (s32) _sqrt(sqsum);
-               PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
+               PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n",
+                          iq_mag_0_tx));
 
                if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
                        break;
index 75b775252af1ee4364e32939856216a4dcfd6175..5fd4c4a72eeeca400be29977171a7ae8b067ac10 100644 (file)
@@ -43,7 +43,7 @@
  */
 
 /* MAX2825 (pure b/g) */
-u32 max2825_rf_data[] = {
+static u32 max2825_rf_data[] = {
        (0x00<<18) | 0x000a2,
        (0x01<<18) | 0x21cc0,
        (0x02<<18) | 0x13806,
@@ -59,7 +59,7 @@ u32 max2825_rf_data[] = {
        (0x0C<<18) | 0x0c100   /* 11a: 0x0c300, 11g: 0x0c100 */
 };
 
-u32 max2825_channel_data_24[][3] = {
+static u32 max2825_channel_data_24[][3] = {
        {(0x03 << 18) | 0x30142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 01 */
        {(0x03 << 18) | 0x32141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channel 02 */
        {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channel 03 */
@@ -76,11 +76,11 @@ u32 max2825_channel_data_24[][3] = {
        {(0x03 << 18) | 0x32941, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6}  /* channel 14 (2484MHz) */
 };
 
-u32 max2825_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
+static u32 max2825_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
 
 /* ========================================== */
 /* MAX2827 (a/b/g) */
-u32 max2827_rf_data[] = {
+static u32 max2827_rf_data[] = {
        (0x00 << 18) | 0x000a2,
        (0x01 << 18) | 0x21cc0,
        (0x02 << 18) | 0x13806,
@@ -96,7 +96,7 @@ u32 max2827_rf_data[] = {
        (0x0C << 18) | 0x0c100   /* 11a: 0x0c300, 11g: 0x0c100 */
 };
 
-u32 max2827_channel_data_24[][3] = {
+static u32 max2827_channel_data_24[][3] = {
        {(0x03 << 18) | 0x30142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 01 */
        {(0x03 << 18) | 0x32141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 02 */
        {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 03 */
@@ -113,7 +113,7 @@ u32 max2827_channel_data_24[][3] = {
        {(0x03 << 18) | 0x32941, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6}  /* channel 14 (2484MHz) */
 };
 
-u32 max2827_channel_data_50[][3] = {
+static u32 max2827_channel_data_50[][3] = {
        {(0x03 << 18) | 0x33cc3, (0x04 << 18) | 0x08ccc, (0x05 << 18) | 0x2A9A6}, /* channel 36 */
        {(0x03 << 18) | 0x302c0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2A9A6}, /* channel 40 */
        {(0x03 << 18) | 0x302c2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2A9A6}, /* channel 44 */
@@ -124,12 +124,12 @@ u32 max2827_channel_data_50[][3] = {
        {(0x03 << 18) | 0x30ac2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2A9A6}  /* channel 64 */
 };
 
-u32 max2827_power_data_24[] = {(0x0C << 18) | 0x0C000, (0x0C << 18) | 0x0D600, (0x0C << 18) | 0x0C100};
-u32 max2827_power_data_50[] = {(0x0C << 18) | 0x0C400, (0x0C << 18) | 0x0D500, (0x0C << 18) | 0x0C300};
+static u32 max2827_power_data_24[] = {(0x0C << 18) | 0x0C000, (0x0C << 18) | 0x0D600, (0x0C << 18) | 0x0C100};
+static u32 max2827_power_data_50[] = {(0x0C << 18) | 0x0C400, (0x0C << 18) | 0x0D500, (0x0C << 18) | 0x0C300};
 
 /* ======================================================= */
 /* MAX2828 (a/b/g) */
-u32 max2828_rf_data[] = {
+static u32 max2828_rf_data[] = {
        (0x00 << 18) | 0x000a2,
        (0x01 << 18) | 0x21cc0,
        (0x02 << 18) | 0x13806,
@@ -145,7 +145,7 @@ u32 max2828_rf_data[] = {
        (0x0C << 18) | 0x0c100   /* 11a: 0x0c300, 11g: 0x0c100 */
 };
 
-u32 max2828_channel_data_24[][3] = {
+static u32 max2828_channel_data_24[][3] = {
        {(0x03 << 18) | 0x30142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 01 */
        {(0x03 << 18) | 0x32141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 02 */
        {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 03 */
@@ -162,7 +162,7 @@ u32 max2828_channel_data_24[][3] = {
        {(0x03 << 18) | 0x32941, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6}  /* channel 14 (2484MHz) */
 };
 
-u32 max2828_channel_data_50[][3] = {
+static u32 max2828_channel_data_50[][3] = {
        {(0x03 << 18) | 0x33cc3, (0x04 << 18) | 0x08ccc, (0x05 << 18) | 0x289A6}, /* channel 36 */
        {(0x03 << 18) | 0x302c0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x289A6}, /* channel 40 */
        {(0x03 << 18) | 0x302c2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 44 */
@@ -173,12 +173,12 @@ u32 max2828_channel_data_50[][3] = {
        {(0x03 << 18) | 0x30ac2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}  /* channel 64 */
 };
 
-u32 max2828_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
-u32 max2828_power_data_50[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
+static u32 max2828_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
+static u32 max2828_power_data_50[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
 
 /* ========================================================== */
 /* MAX2829 (a/b/g) */
-u32 max2829_rf_data[] = {
+static u32 max2829_rf_data[] = {
        (0x00 << 18) | 0x000a2,
        (0x01 << 18) | 0x23520,
        (0x02 << 18) | 0x13802,
@@ -194,7 +194,7 @@ u32 max2829_rf_data[] = {
        (0x0C << 18) | 0x0F300 /* TXVGA=51, (MAX-6 dB) */
 };
 
-u32 max2829_channel_data_24[][3] = {
+static u32 max2829_channel_data_24[][3] = {
        {(3 << 18) | 0x30142, (4 << 18) | 0x0b333, (5 << 18) | 0x289C6},  /* 01 (2412MHz) */
        {(3 << 18) | 0x32141, (4 << 18) | 0x08444, (5 << 18) | 0x289C6},  /* 02 (2417MHz) */
        {(3 << 18) | 0x32143, (4 << 18) | 0x0aeee, (5 << 18) | 0x289C6},  /* 03 (2422MHz) */
@@ -211,7 +211,7 @@ u32 max2829_channel_data_24[][3] = {
        {(3 << 18) | 0x32941, (4 << 18) | 0x09999, (5 << 18) | 0x289C6},  /* 14 (2484MHz) */
 };
 
-u32 max2829_channel_data_50[][4] = {
+static u32 max2829_channel_data_50[][4] = {
        {36, (3 << 18) | 0x33cc3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A946}, /* 36 (5.180GHz) */
        {40, (3 << 18) | 0x302c0, (4 << 18) | 0x08000, (5 << 18) | 0x2A946}, /* 40 (5.200GHz) */
        {44, (3 << 18) | 0x302c2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A946}, /* 44 (5.220GHz) */
@@ -296,51 +296,6 @@ u32 max2829_channel_data_50[][4] = {
  * 0x0c 0x0c000
  * ====================================================================
  */
-u32 maxim_317_rf_data[] = {
-       (0x00 << 18) | 0x000a2,
-       (0x01 << 18) | 0x214c0,
-       (0x02 << 18) | 0x13802,
-       (0x03 << 18) | 0x30143,
-       (0x04 << 18) | 0x0accc,
-       (0x05 << 18) | 0x28986,
-       (0x06 << 18) | 0x18008,
-       (0x07 << 18) | 0x38400,
-       (0x08 << 18) | 0x05108,
-       (0x09 << 18) | 0x27ff8,
-       (0x0A << 18) | 0x14000,
-       (0x0B << 18) | 0x37f99,
-       (0x0C << 18) | 0x0c000
-};
-
-u32 maxim_317_channel_data_24[][3] = {
-       {(0x03 << 18) | 0x30143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 01 */
-       {(0x03 << 18) | 0x32140, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 02 */
-       {(0x03 << 18) | 0x32142, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 03 */
-       {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 04 */
-       {(0x03 << 18) | 0x31140, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 05 */
-       {(0x03 << 18) | 0x31142, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 06 */
-       {(0x03 << 18) | 0x31143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 07 */
-       {(0x03 << 18) | 0x33140, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 08 */
-       {(0x03 << 18) | 0x33142, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 09 */
-       {(0x03 << 18) | 0x33143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 10 */
-       {(0x03 << 18) | 0x30940, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 11 */
-       {(0x03 << 18) | 0x30942, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 12 */
-       {(0x03 << 18) | 0x30943, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}  /* channe1 13 */
-};
-
-u32 maxim_317_channel_data_50[][3] = {
-       {(0x03 << 18) | 0x33cc0, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2a986}, /* channel 36 */
-       {(0x03 << 18) | 0x302c0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2a986}, /* channel 40 */
-       {(0x03 << 18) | 0x302c3, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x2a986}, /* channel 44 */
-       {(0x03 << 18) | 0x322c1, (0x04 << 18) | 0x09666, (0x05 << 18) | 0x2a986}, /* channel 48 */
-       {(0x03 << 18) | 0x312c2, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x2a986}, /* channel 52 */
-       {(0x03 << 18) | 0x332c0, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2a99e}, /* channel 56 */
-       {(0x03 << 18) | 0x30ac0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2a99e}, /* channel 60 */
-       {(0x03 << 18) | 0x30ac3, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x2a99e}  /* channel 64 */
-};
-
-u32 maxim_317_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
-u32 maxim_317_power_data_50[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100};
 
 /*
  * ===================================================================
@@ -388,7 +343,7 @@ u32 maxim_317_power_data_50[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100}
  * 0x0f 0xf00a0 ; Restore Initial Setting
  * ==================================================================
  */
-u32 al2230_rf_data[] = {
+static u32 al2230_rf_data[] = {
        (0x00 << 20) | 0x09EFC,
        (0x01 << 20) | 0x8CCCC,
        (0x02 << 20) | 0x40058,
@@ -406,7 +361,7 @@ u32 al2230_rf_data[] = {
        (0x0F << 20) | 0xF01A0
 };
 
-u32 al2230s_rf_data[] = {
+static u32 al2230s_rf_data[] = {
        (0x00 << 20) | 0x09EFC,
        (0x01 << 20) | 0x8CCCC,
        (0x02 << 20) | 0x40058,
@@ -424,7 +379,7 @@ u32 al2230s_rf_data[] = {
        (0x0F << 20) | 0xF01A0
 };
 
-u32 al2230_channel_data_24[][2] = {
+static u32 al2230_channel_data_24[][2] = {
        {(0x00 << 20) | 0x09EFC, (0x01 << 20) | 0x8CCCC}, /* channe1 01 */
        {(0x00 << 20) | 0x09EFC, (0x01 << 20) | 0x8CCCD}, /* channe1 02 */
        {(0x00 << 20) | 0x09E7C, (0x01 << 20) | 0x8CCCC}, /* channe1 03 */
@@ -446,7 +401,7 @@ u32 al2230_channel_data_24[][2] = {
 #define AIROHA_TXVGA_MIDDLE_INDEX      12      /* Index for 0x96602 */
 #define AIROHA_TXVGA_HIGH_INDEX                8       /* Index for 0x97602 1.0.24.0 1.0.28.0 */
 
-u32 al2230_txvga_data[][2] = {
+static u32 al2230_txvga_data[][2] = {
        /* value , index */
        {0x090202, 0},
        {0x094202, 2},
@@ -497,7 +452,7 @@ u32 al2230_txvga_data[][2] = {
  */
 
 /* channel independent registers: */
-u32 al7230_rf_data_24[]        = {
+static u32 al7230_rf_data_24[] = {
        (0x00 << 24) | 0x003790,
        (0x01 << 24) | 0x133331,
        (0x02 << 24) | 0x841FF2,
@@ -516,7 +471,7 @@ u32 al7230_rf_data_24[]     = {
        (0x0F << 24) | 0x1ABA8F
 };
 
-u32 al7230_channel_data_24[][2] = {
+static u32 al7230_channel_data_24[][2] = {
        {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x133331}, /* channe1 01 */
        {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x1B3331}, /* channe1 02 */
        {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x033331}, /* channe1 03 */
@@ -534,7 +489,7 @@ u32 al7230_channel_data_24[][2] = {
 };
 
 /* channel independent registers: */
-u32 al7230_rf_data_50[]        = {
+static u32 al7230_rf_data_50[] = {
        (0x00 << 24) | 0x0FF520,
        (0x01 << 24) | 0x000001,
        (0x02 << 24) | 0x451FE2,
@@ -553,7 +508,7 @@ u32 al7230_rf_data_50[]     = {
        (0x0F << 24) | 0x12BACF  /* 5Ghz default state */
 };
 
-u32 al7230_channel_data_5[][4] = {
+static u32 al7230_channel_data_5[][4] = {
        /* channel dependent registers: 0x00, 0x01 and 0x04 */
        /* 11J =========== */
        {184, (0x00 << 24) | 0x0FF520, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 184 */
@@ -603,7 +558,7 @@ u32 al7230_channel_data_5[][4] = {
  */
 
 /* TXVGA Mapping Table <=== Register 0x0B */
-u32 al7230_txvga_data[][2] = {
+static u32 al7230_txvga_data[][2] = {
        {0x08040B, 0}, /* TXVGA = 0; */
        {0x08041B, 1}, /* TXVGA = 1; */
        {0x08042B, 2}, /* TXVGA = 2; */
@@ -675,7 +630,7 @@ u32 al7230_txvga_data[][2] = {
  * W89RF242 RFIC SPI programming initial data
  * Winbond WLAN 11g RFIC BB-SPI register -- version FA5976A rev 1.3b
  */
-u32 w89rf242_rf_data[] = {
+static u32 w89rf242_rf_data[] = {
        (0x00 << 24) | 0xF86100, /* 3E184; MODA  (0x00) -- Normal mode ; calibration off */
        (0x01 << 24) | 0xEFFFC2, /* 3BFFF; MODB  (0x01) -- turn off RSSI, and other circuits are turned on */
        (0x02 << 24) | 0x102504, /* 04094; FSET  (0x02) -- default 20MHz crystal ; Icmp=1.5mA */
@@ -696,7 +651,7 @@ u32 w89rf242_rf_data[] = {
        (0x12 << 24) | 0x000024  /* TMODC (0x12) -- Turn OFF Temperature sensor */
 };
 
-u32 w89rf242_channel_data_24[][2] = {
+static u32 w89rf242_channel_data_24[][2] = {
        {(0x03 << 24) | 0x025B06, (0x04 << 24) | 0x080408}, /* channe1 01 */
        {(0x03 << 24) | 0x025C46, (0x04 << 24) | 0x080408}, /* channe1 02 */
        {(0x03 << 24) | 0x025D86, (0x04 << 24) | 0x080408}, /* channe1 03 */
@@ -713,9 +668,7 @@ u32 w89rf242_channel_data_24[][2] = {
        {(0x03 << 24) | 0x026D06, (0x04 << 24) | 0x080408}  /* channe1 14 */
 };
 
-u32 w89rf242_power_data_24[] = {(0x05 << 24) | 0x24C48A, (0x05 << 24) | 0x24C48A, (0x05 << 24) | 0x24C48A};
-
-u32 w89rf242_txvga_old_mapping[][2] = {
+static u32 w89rf242_txvga_old_mapping[][2] = {
        {0, 0} , /* New <-> Old */
        {1, 1} ,
        {2, 2} ,
@@ -738,7 +691,7 @@ u32 w89rf242_txvga_old_mapping[][2] = {
        {34, 19},
 };
 
-u32 w89rf242_txvga_data[][5] = {
+static u32 w89rf242_txvga_data[][5] = {
        /* low gain mode */
        {(0x05 << 24) | 0x24C00A, 0, 0x00292315, 0x0800FEFF, 0x52523131}, /* min gain */
        {(0x05 << 24) | 0x24C80A, 1, 0x00292315, 0x0800FEFF, 0x52523131},
@@ -920,7 +873,7 @@ void Uxx_power_on_procedure(struct hw_data *pHwData)
        Wb35Reg_WriteSync(pHwData, 0x03f8, 0x7ff);
 }
 
-static void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp, 
+static void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp,
                                        char number)
 {
        u8      i;
@@ -930,7 +883,7 @@ static void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp,
        }
 }
 
-static void Set_ChanIndep_RfData_al7230_50(struct hw_data *pHwData, u32 *pltmp, 
+static void Set_ChanIndep_RfData_al7230_50(struct hw_data *pHwData, u32 *pltmp,
                                        char number)
 {
        u8      i;
@@ -1088,7 +1041,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData)
                msleep(5);
 
                ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x0F << 20) | 0xF01A0, 20);
-               Wb35Reg_WriteSync(pHwData, 0x0864, ltmp) ;
+               Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
 
                Wb35Reg_WriteSync(pHwData, 0x105c, pHwData->reg.BB5C);
                pHwData->reg.BB50 &= ~0x13; /* (MASK_IQCAL_MODE|MASK_CALIB_START); */
@@ -1620,13 +1573,13 @@ void BBProcessor_initial(struct hw_data *pHwData)
                reg->SQ3_filter[i] = 0x2f; /* half of Bit 0 ~ 6 */
 }
 
-static inline void set_tx_power_per_channel_max2829(struct hw_data *pHwData,  
+static inline void set_tx_power_per_channel_max2829(struct hw_data *pHwData,
                                                struct chan_info Channel)
 {
        RFSynthesizer_SetPowerIndex(pHwData, 100);
 }
 
-static void set_tx_power_per_channel_al2230(struct hw_data *pHwData,  
+static void set_tx_power_per_channel_al2230(struct hw_data *pHwData,
                                        struct chan_info Channel)
 {
        u8      index = 100;
@@ -1636,7 +1589,7 @@ static void set_tx_power_per_channel_al2230(struct hw_data *pHwData,
        RFSynthesizer_SetPowerIndex(pHwData, index);
 }
 
-static void set_tx_power_per_channel_al7230(struct hw_data *pHwData,  
+static void set_tx_power_per_channel_al7230(struct hw_data *pHwData,
                                        struct chan_info Channel)
 {
        u8      i, index = 100;
@@ -1660,7 +1613,7 @@ static void set_tx_power_per_channel_al7230(struct hw_data *pHwData,
        RFSynthesizer_SetPowerIndex(pHwData, index);
 }
 
-static void set_tx_power_per_channel_wb242(struct hw_data *pHwData,  
+static void set_tx_power_per_channel_wb242(struct hw_data *pHwData,
                                        struct chan_info Channel)
 {
        u8      index = 100;
@@ -2096,7 +2049,7 @@ void Mxx_initial(struct hw_data *pHwData)
        pltmp[5] = reg->M38_MacControl;
 
        /* M3C */
-       tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST ;
+       tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST;
        reg->M3C_MacControl = tmp;
        pltmp[6] = tmp;
 
index 30a77ccfe48069d684ce469b5812377f65628655..708c5b05f86c6e929d98fe8e4f9512970a37d525 100644 (file)
@@ -180,7 +180,7 @@ void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount)
 {
        struct hw_data *pHwData = &adapter->sHwData;
        struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
-       unsigned char Trigger = false;
+       bool Trigger = false;
 
        if (pWb35Tx->TxTimer > TimeCount)
                Trigger = true;
index 3fa1ae4d3d769870fad496ef9b8c0044fdf9a953..07891a3e316e6b9e50d0a744f4e7d6a6b854bb40 100644 (file)
@@ -122,16 +122,16 @@ static void wbsoft_tx(struct ieee80211_hw *dev,
 {
        struct wbsoft_priv *priv = dev->priv;
 
-       if (priv->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
+       if (priv->sMlmeFrame.is_in_used != PACKET_FREE_TO_USE) {
                priv->sMlmeFrame.wNumTxMMPDUDiscarded++;
                kfree_skb(skb);
                return;
        }
 
-       priv->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
+       priv->sMlmeFrame.is_in_used = PACKET_COME_FROM_MLME;
 
        priv->sMlmeFrame.pMMPDU         = skb->data;
-       priv->sMlmeFrame.DataType       = FRAME_TYPE_802_11_MANAGEMENT;
+       priv->sMlmeFrame.data_type      = FRAME_TYPE_802_11_MANAGEMENT;
        priv->sMlmeFrame.len            = skb->len;
        priv->sMlmeFrame.wNumTxMMPDU++;
 
index 2abeaa11d8ca3d60d4c01da5fa24afab2f7ac763..71b44653690c4d179b99903c81d9e28280634aa0 100644 (file)
@@ -372,22 +372,22 @@ typedef IFB_STRCT*        IFBP;
 /**********************   W C I    F U N C T I O N S    P R O T O T Y P E S   ******************************/
 /***********************************************************************************************************/
 
-EXTERN_C int            hcf_action                     (IFBP ifbp, hcf_16 cmd );
-EXTERN_C int            hcf_connect            (IFBP ifbp, hcf_io io_base );
-EXTERN_C int            hcf_get_info           (IFBP ifbp, LTVP ltvp );
-EXTERN_C int            hcf_service_nic        (IFBP ifbp, wci_bufp bufp, unsigned int len );
-EXTERN_C int            hcf_cntl                       (IFBP ifbp, hcf_16 cmd );
-EXTERN_C int            hcf_put_info           (IFBP ifbp, LTVP ltvp );
-EXTERN_C int            hcf_rcv_msg            (IFBP ifbp, DESC_STRCT *descp, unsigned int offset );
-EXTERN_C int            hcf_send_msg       (IFBP ifbp, DESC_STRCT *dp, hcf_16 tx_cntl );
+EXTERN_C int hcf_action(IFBP ifbp, hcf_16 cmd);
+EXTERN_C int hcf_connect(IFBP ifbp, hcf_io io_base);
+EXTERN_C int hcf_get_info(IFBP ifbp, LTVP ltvp);
+EXTERN_C int hcf_service_nic(IFBP ifbp, wci_bufp bufp, unsigned int len);
+EXTERN_C int hcf_cntl(IFBP ifbp, hcf_16 cmd);
+EXTERN_C int hcf_put_info(IFBP ifbp, LTVP ltvp);
+EXTERN_C int hcf_rcv_msg(IFBP ifbp, DESC_STRCT *descp, unsigned int offset);
+EXTERN_C int hcf_send_msg(IFBP ifbp, DESC_STRCT *dp, hcf_16 tx_cntl);
 #if HCF_DMA
-EXTERN_C void           hcf_dma_tx_put         (IFBP ifbp, DESC_STRCT *d, hcf_16 tx_cntl );
+EXTERN_C void hcf_dma_tx_put(IFBP ifbp, DESC_STRCT *d, hcf_16 tx_cntl);
 EXTERN_C DESC_STRCT* hcf_dma_tx_get            (IFBP ifbp );
 EXTERN_C DESC_STRCT* hcf_dma_rx_get            (IFBP ifbp );
-EXTERN_C void           hcf_dma_rx_put         (IFBP ifbp, DESC_STRCT *d );
+EXTERN_C void hcf_dma_rx_put(IFBP ifbp, DESC_STRCT *d);
 #endif // HCF_DMA
 #if (HCF_ASSERT) & HCF_ASSERT_LNK_MSF_RTN
-EXTERN_C void           msf_assert                     (unsigned int line_number, hcf_16 trace, hcf_32 qual );
+EXTERN_C void msf_assert(unsigned int line_number, hcf_16 trace, hcf_32 qual);
 #endif // HCF_ASSERT_LNK_MSF_RTN
 
 #endif  // HCF_H
index 19bed819df1e7e6f1ee4b3f68657953d4a31f870..25ac76f7d366ea70468fb7819e84bdfb05cae5bf 100644 (file)
@@ -4472,8 +4472,8 @@ memimage fw_image = {
        "FUPU7D37dhfwci\001C",                  /* signature, <format number>, C/Bin type */
        (CFG_PROG_STRCT *) fw_image_code,
        0x000F368E,
-       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 f1bce18ea828fe4f957705ec342508b16670f99a..a4fd5c4717a880d7c68eefaf939062eabbb4c02a 100644 (file)
@@ -98,10 +98,10 @@ static int prism2_domibset_pstr32(wlandevice_t *wlandev,
 
 
 /* The interface functions, called by the cfg80211 layer */
-int prism2_change_virtual_intf(struct wiphy *wiphy,
-                              struct net_device *dev,
-                              enum nl80211_iftype type, u32 *flags,
-                              struct vif_params *params)
+static int prism2_change_virtual_intf(struct wiphy *wiphy,
+                                     struct net_device *dev,
+                                     enum nl80211_iftype type, u32 *flags,
+                                     struct vif_params *params)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 data;
@@ -122,7 +122,7 @@ int prism2_change_virtual_intf(struct wiphy *wiphy,
                data = 1;
                break;
        default:
-               printk(KERN_WARNING "Operation mode: %d not support\n", type);
+               netdev_warn(dev, "Operation mode: %d not support\n", type);
                return -EOPNOTSUPP;
        }
 
@@ -140,9 +140,9 @@ exit:
        return err;
 }
 
-int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, bool pairwise, const u8 *mac_addr,
-                  struct key_params *params)
+static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
+                         u8 key_index, bool pairwise, const u8 *mac_addr,
+                         struct key_params *params)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 did;
@@ -199,9 +199,10 @@ exit:
        return err;
 }
 
-int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie,
-                  void (*callback)(void *cookie, struct key_params*))
+static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
+                         u8 key_index, bool pairwise,
+                         const u8 *mac_addr, void *cookie,
+                         void (*callback)(void *cookie, struct key_params*))
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct key_params params;
@@ -228,8 +229,8 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, bool pairwise, const u8 *mac_addr)
+static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
+                         u8 key_index, bool pairwise, const u8 *mac_addr)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 did;
@@ -274,8 +275,8 @@ exit:
        return err;
 }
 
-int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
-                          u8 key_index, bool unicast, bool multicast)
+static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
+                                 u8 key_index, bool unicast, bool multicast)
 {
        wlandevice_t *wlandev = dev->ml_priv;
 
@@ -293,8 +294,8 @@ int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
 }
 
 
-int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
-                      u8 *mac, struct station_info *sinfo)
+static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
+                             u8 *mac, struct station_info *sinfo)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct p80211msg_lnxreq_commsquality quality;
@@ -327,7 +328,7 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
        return result;
 }
 
-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);
@@ -352,7 +353,7 @@ int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
                return -EBUSY;
 
        if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
-               printk(KERN_ERR "Can't scan in AP mode\n");
+               netdev_err(dev, "Can't scan in AP mode\n");
                return -EOPNOTSUPP;
        }
 
@@ -436,7 +437,7 @@ exit:
        return err;
 }
 
-int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
@@ -478,8 +479,8 @@ exit:
        return err;
 }
 
-int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
-                  struct cfg80211_connect_params *sme)
+static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
+                         struct cfg80211_connect_params *sme)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct ieee80211_channel *channel = sme->channel;
@@ -510,7 +511,7 @@ int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
                ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
                        msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
        else
-               printk(KERN_WARNING
+               netdev_warn(dev,
                        "Unhandled authorisation type for connect (%d)\n",
                        sme->auth_type);
 
@@ -602,8 +603,8 @@ exit:
        return err;
 }
 
-int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
-                     u16 reason_code)
+static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
+                            u16 reason_code)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct p80211msg_lnxreq_autojoin msg_join;
@@ -626,20 +627,20 @@ int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
 }
 
 
-int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
-                    struct cfg80211_ibss_params *params)
+static int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+                           struct cfg80211_ibss_params *params)
 {
        return -EOPNOTSUPP;
 }
 
-int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+static int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
        return -EOPNOTSUPP;
 }
 
 
-int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
-                       enum nl80211_tx_power_setting type, int mbm)
+static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                              enum nl80211_tx_power_setting type, int mbm)
 {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
@@ -665,8 +666,8 @@ exit:
        return err;
 }
 
-int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
-                       int *dbm)
+static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                              int *dbm)
 {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
index c1a8cb62515445741b914cb8734dcbe0d7b4553a..5b8b094c87261807d49d2b68b3e518033b17a13f 100644 (file)
@@ -355,7 +355,7 @@ static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
 
                /* Check whether we need to reset the RX pipe */
                if (result == -EPIPE) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "%s rx pipe stalled: requesting reset\n",
                               hw->wlandev->netdev->name);
                        if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
@@ -405,7 +405,7 @@ static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
 
                        /* Test whether we need to reset the TX pipe */
                        if (result == -EPIPE) {
-                               printk(KERN_WARNING
+                               netdev_warn(hw->wlandev->netdev,
                                       "%s tx pipe stalled: requesting reset\n",
                                       netdev->name);
                                set_bit(WORK_TX_HALT, &hw->usb_flags);
@@ -454,11 +454,11 @@ static void hfa384x_usb_defer(struct work_struct *data)
 
                ret = usb_clear_halt(hw->usb, hw->endp_in);
                if (ret != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Failed to clear rx pipe for %s: err=%d\n",
                               netdev->name, ret);
                } else {
-                       printk(KERN_INFO "%s rx pipe reset complete.\n",
+                       netdev_info(hw->wlandev->netdev, "%s rx pipe reset complete.\n",
                               netdev->name);
                        clear_bit(WORK_RX_HALT, &hw->usb_flags);
                        set_bit(WORK_RX_RESUME, &hw->usb_flags);
@@ -471,7 +471,7 @@ static void hfa384x_usb_defer(struct work_struct *data)
 
                ret = submit_rx_urb(hw, GFP_KERNEL);
                if (ret != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Failed to resume %s rx pipe.\n", netdev->name);
                } else {
                        clear_bit(WORK_RX_RESUME, &hw->usb_flags);
@@ -485,11 +485,11 @@ static void hfa384x_usb_defer(struct work_struct *data)
                usb_kill_urb(&hw->tx_urb);
                ret = usb_clear_halt(hw->usb, hw->endp_out);
                if (ret != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Failed to clear tx pipe for %s: err=%d\n",
                               netdev->name, ret);
                } else {
-                       printk(KERN_INFO "%s tx pipe reset complete.\n",
+                       netdev_info(hw->wlandev->netdev, "%s tx pipe reset complete.\n",
                               netdev->name);
                        clear_bit(WORK_TX_HALT, &hw->usb_flags);
                        set_bit(WORK_TX_RESUME, &hw->usb_flags);
@@ -1211,7 +1211,7 @@ int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
 
        result = usb_reset_device(hw->usb);
        if (result < 0) {
-               printk(KERN_ERR "usb_reset_device() failed, result=%d.\n",
+               netdev_err(hw->wlandev->netdev, "usb_reset_device() failed, result=%d.\n",
                       result);
        }
 
@@ -1311,7 +1311,7 @@ cleanup:
                if (ctlx->state == CTLX_COMPLETE) {
                        result = completor->complete(completor);
                } else {
-                       printk(KERN_WARNING "CTLX[%d] error: state(%s)\n",
+                       netdev_warn(hw->wlandev->netdev, "CTLX[%d] error: state(%s)\n",
                               le16_to_cpu(ctlx->outbuf.type),
                               ctlxstr(ctlx->state));
                        result = -EIO;
@@ -2018,7 +2018,7 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
        if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
                return -EINVAL;
 
-       printk(KERN_INFO "Download %d bytes to flash @0x%06x\n", len, daddr);
+       netdev_info(hw->wlandev->netdev, "Download %d bytes to flash @0x%06x\n", len, daddr);
 
        /* Convert to flat address for arithmetic */
        /* NOTE: dlbuffer RID stores the address in AUX format */
@@ -2028,7 +2028,7 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
                 hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
 
 #if 0
-       printk(KERN_WARNING "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
+       netdev_warn(hw->wlandev->netdev, "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
               hw->bufinfo.len, hw->dltimeout);
 #endif
        /* Calculations to determine how many fills of the dlbuffer to do
@@ -2055,14 +2055,14 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
                burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
                burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
 
-               printk(KERN_INFO "Writing %d bytes to flash @0x%06x\n",
+               netdev_info(hw->wlandev->netdev, "Writing %d bytes to flash @0x%06x\n",
                       burnlen, burndaddr);
 
                /* Set the download mode */
                result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
                                              burnlo, burnhi, burnlen);
                if (result) {
-                       printk(KERN_ERR "download(NV,lo=%x,hi=%x,len=%x) "
+                       netdev_err(hw->wlandev->netdev, "download(NV,lo=%x,hi=%x,len=%x) "
                               "cmd failed, result=%d. Aborting d/l\n",
                               burnlo, burnhi, burnlen, result);
                        goto exit_proc;
@@ -2094,7 +2094,7 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
                                              HFA384x_PROGMODE_NVWRITE,
                                              0, 0, 0);
                if (result) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "download(NVWRITE,lo=%x,hi=%x,len=%x) "
                               "cmd failed, result=%d. Aborting d/l\n",
                               burnlo, burnhi, burnlen, result);
@@ -2279,7 +2279,7 @@ int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
        /* Check that a port isn't active */
        for (i = 0; i < HFA384x_PORTID_MAX; i++) {
                if (hw->port_enabled[i]) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Can't download with a macport enabled.\n");
                        return -EINVAL;
                }
@@ -2287,7 +2287,7 @@ int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
 
        /* Check that we're not already in a download state */
        if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
-               printk(KERN_ERR "Download state not disabled.\n");
+               netdev_err(hw->wlandev->netdev, "Download state not disabled.\n");
                return -EINVAL;
        }
 
@@ -2352,7 +2352,7 @@ int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
        if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
                return -EINVAL;
 
-       printk(KERN_INFO "Writing %d bytes to ram @0x%06x\n", len, daddr);
+       netdev_info(hw->wlandev->netdev, "Writing %d bytes to ram @0x%06x\n", len, daddr);
 
        /* How many dowmem calls?  */
        nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
@@ -2449,7 +2449,7 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
                                                len);
 
                if (result) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "Read from index %zd failed, continuing\n", i);
                        continue;
                }
@@ -2462,13 +2462,13 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
                        pdrcode = le16_to_cpu(pda[currpdr + 1]);
                        /* Test the record length */
                        if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
-                               printk(KERN_ERR "pdrlen invalid=%d\n", pdrlen);
+                               netdev_err(hw->wlandev->netdev, "pdrlen invalid=%d\n", pdrlen);
                                pdaok = 0;
                                break;
                        }
                        /* Test the code */
                        if (!hfa384x_isgood_pdrcode(pdrcode)) {
-                               printk(KERN_ERR "pdrcode invalid=%d\n",
+                               netdev_err(hw->wlandev->netdev, "pdrcode invalid=%d\n",
                                       pdrcode);
                                pdaok = 0;
                                break;
@@ -2484,7 +2484,7 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
                        }
                }
                if (pdaok) {
-                       printk(KERN_INFO
+                       netdev_info(hw->wlandev->netdev,
                               "PDA Read from 0x%08x in %s space.\n",
                               pdaloc[i].cardaddr,
                               pdaloc[i].auxctl == 0 ? "EXTDS" :
@@ -2564,20 +2564,20 @@ int hfa384x_drvr_start(hfa384x_t *hw)
        result =
            usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
        if (result < 0) {
-               printk(KERN_ERR "Cannot get bulk in endpoint status.\n");
+               netdev_err(hw->wlandev->netdev, "Cannot get bulk in endpoint status.\n");
                goto done;
        }
        if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
-               printk(KERN_ERR "Failed to reset bulk in endpoint.\n");
+               netdev_err(hw->wlandev->netdev, "Failed to reset bulk in endpoint.\n");
 
        result =
            usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
        if (result < 0) {
-               printk(KERN_ERR "Cannot get bulk out endpoint status.\n");
+               netdev_err(hw->wlandev->netdev, "Cannot get bulk out endpoint status.\n");
                goto done;
        }
        if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
-               printk(KERN_ERR "Failed to reset bulk out endpoint.\n");
+               netdev_err(hw->wlandev->netdev, "Failed to reset bulk out endpoint.\n");
 
        /* Synchronous unlink, in case we're trying to restart the driver */
        usb_kill_urb(&hw->rx_urb);
@@ -2585,7 +2585,7 @@ int hfa384x_drvr_start(hfa384x_t *hw)
        /* Post the IN urb */
        result = submit_rx_urb(hw, GFP_KERNEL);
        if (result != 0) {
-               printk(KERN_ERR
+               netdev_err(hw->wlandev->netdev,
                       "Fatal, failed to submit RX URB, result=%d\n", result);
                goto done;
        }
@@ -2605,7 +2605,7 @@ int hfa384x_drvr_start(hfa384x_t *hw)
        result = result2 = hfa384x_cmd_initialize(hw);
        if (result1 != 0) {
                if (result2 != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                                "cmd_initialize() failed on two attempts, results %d and %d\n",
                                result1, result2);
                        usb_kill_urb(&hw->rx_urb);
@@ -2616,9 +2616,9 @@ int hfa384x_drvr_start(hfa384x_t *hw)
                        pr_debug("but second attempt succeeded. All should be ok\n");
                }
        } else if (result2 != 0) {
-               printk(KERN_WARNING "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
+               netdev_warn(hw->wlandev->netdev, "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
                        result2);
-               printk(KERN_WARNING
+               netdev_warn(hw->wlandev->netdev,
                       "Most likely the card will be functional\n");
                goto done;
        }
@@ -2709,7 +2709,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
        char *ptr;
 
        if (hw->tx_urb.status == -EINPROGRESS) {
-               printk(KERN_WARNING "TX URB already in use\n");
+               netdev_warn(hw->wlandev->netdev, "TX URB already in use\n");
                result = 3;
                goto exit;
        }
@@ -2784,7 +2784,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
        result = 1;
        ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
        if (ret != 0) {
-               printk(KERN_ERR "submit_tx_urb() failed, error=%d\n", ret);
+               netdev_err(hw->wlandev->netdev, "submit_tx_urb() failed, error=%d\n", ret);
                result = 3;
        }
 
@@ -3009,7 +3009,7 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
                break;
 
        default:
-               printk(KERN_ERR "CTLX[%d] not in a terminating state(%s)\n",
+               netdev_err(hw->wlandev->netdev, "CTLX[%d] not in a terminating state(%s)\n",
                       le16_to_cpu(ctlx->outbuf.type), ctlxstr(ctlx->state));
                break;
        }                       /* switch */
@@ -3091,7 +3091,7 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
                         * this CTLX back in the "pending" queue
                         * and schedule a reset ...
                         */
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "%s tx pipe stalled: requesting reset\n",
                               hw->wlandev->netdev->name);
                        list_move(&head->list, &hw->ctlxq.pending);
@@ -3101,12 +3101,12 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
                }
 
                if (result == -ESHUTDOWN) {
-                       printk(KERN_WARNING "%s urb shutdown!\n",
+                       netdev_warn(hw->wlandev->netdev, "%s urb shutdown!\n",
                               hw->wlandev->netdev->name);
                        break;
                }
 
-               printk(KERN_ERR "Failed to submit CTLX[%d]: error=%d\n",
+               netdev_err(hw->wlandev->netdev, "Failed to submit CTLX[%d]: error=%d\n",
                       le16_to_cpu(head->outbuf.type), result);
                unlocked_usbctlx_complete(hw, head);
        }                       /* while */
@@ -3173,7 +3173,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
                break;
 
        case -EPIPE:
-               printk(KERN_WARNING "%s rx pipe stalled: requesting reset\n",
+               netdev_warn(hw->wlandev->netdev, "%s rx pipe stalled: requesting reset\n",
                       wlandev->netdev->name);
                if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
                        schedule_work(&hw->usb_work);
@@ -3224,7 +3224,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
                result = submit_rx_urb(hw, GFP_ATOMIC);
 
                if (result != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Fatal, failed to resubmit rx_urb. error=%d\n",
                               result);
                }
@@ -3360,7 +3360,7 @@ retry:
                 * Check that our message is what we're expecting ...
                 */
                if (ctlx->outbuf.type != intype) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "Expected IN[%d], received IN[%d] - ignored.\n",
                               le16_to_cpu(ctlx->outbuf.type),
                               le16_to_cpu(intype));
@@ -3396,7 +3396,7 @@ retry:
                        /*
                         * Throw this CTLX away ...
                         */
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Matched IN URB, CTLX[%d] in invalid state(%s)."
                               " Discarded.\n",
                               le16_to_cpu(ctlx->outbuf.type),
@@ -3534,7 +3534,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
                break;
 
        default:
-               printk(KERN_WARNING "Received frame on unsupported port=%d\n",
+               netdev_warn(hw->wlandev->netdev, "Received frame on unsupported port=%d\n",
                       HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status));
                goto done;
                break;
@@ -3596,7 +3596,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
 
        skb = dev_alloc_skb(skblen);
        if (skb == NULL) {
-               printk(KERN_ERR
+               netdev_err(hw->wlandev->netdev,
                       "alloc_skb failed trying to allocate %d bytes\n",
                       skblen);
                return;
@@ -3714,7 +3714,7 @@ static void hfa384x_usbout_callback(struct urb *urb)
                case -EPIPE:
                        {
                                hfa384x_t *hw = wlandev->priv;
-                               printk(KERN_WARNING
+                               netdev_warn(hw->wlandev->netdev,
                                       "%s tx pipe stalled: requesting reset\n",
                                       wlandev->netdev->name);
                                if (!test_and_set_bit
@@ -3747,7 +3747,7 @@ static void hfa384x_usbout_callback(struct urb *urb)
                        break;
 
                default:
-                       printk(KERN_INFO "unknown urb->status=%d\n",
+                       netdev_info(wlandev->netdev, "unknown urb->status=%d\n",
                               urb->status);
                        ++(wlandev->linux_stats.tx_errors);
                        break;
@@ -3841,7 +3841,7 @@ retry:
 
                default:
                        /* This is NOT a valid CTLX "success" state! */
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                                "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
                                le16_to_cpu(ctlx->outbuf.type),
                                ctlxstr(ctlx->state), urb->status);
@@ -3851,7 +3851,7 @@ retry:
                /* If the pipe has stalled then we need to reset it */
                if ((urb->status == -EPIPE) &&
                    !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "%s tx pipe stalled: requesting reset\n",
                               hw->wlandev->netdev->name);
                        schedule_work(&hw->usb_work);
index 2fecca2302f437a2e368b2a1eed767e76f4b2e5d..2e0bd24f997cd834420fa4125c6e3262e43aaa29 100644 (file)
@@ -138,7 +138,7 @@ typedef struct p80211_frmrx_t {
 } p80211_frmrx_t;
 
 /* called by /proc/net/wireless */
-struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev);
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev);
 /* wireless extensions' ioctls */
 extern struct iw_handler_def p80211wext_handler_def;
 int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
index 77e50a4aa7e9430c1ff59ea3136f5abf9a50b457..c4fabadf5d74c081c70741ce793bc28392851829 100644 (file)
@@ -134,7 +134,7 @@ int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen)
                return -1;
 
 #ifdef WEP_DEBUG
-       printk(KERN_DEBUG "WEP key %d len %d = %*phC\n", keynum, keylen,
+       pr_debug("WEP key %d len %d = %*phC\n", keynum, keylen,
                          8, key);
 #endif
 
@@ -182,7 +182,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
        keylen += 3;            /* add in IV bytes */
 
 #ifdef WEP_DEBUG
-       printk(KERN_DEBUG "D %d: %*ph (%d %d) %*phC\n", len, 3, key,
+       pr_debug("D %d: %*ph (%d %d) %*phC\n", len, 3, key,
                          keyidx, keylen, 5, key + 3);
 #endif
 
@@ -259,7 +259,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
        keylen += 3;            /* add in IV bytes */
 
 #ifdef WEP_DEBUG
-       printk(KERN_DEBUG "E %d (%d/%d %d) %*ph %*phC\n", len,
+       pr_debug("E %d (%d/%d %d) %*ph %*phC\n", len,
                          iv[3], keynum, keylen, 3, key, 5, key + 3);
 #endif
 
index 3b3e17d3f6f58a057cc6c2b014574044f01688a3..b3ff603e6225dec31b2c24cef8832e06365ffcf4 100644 (file)
@@ -2070,7 +2070,6 @@ static void xgifb_remove(struct pci_dev *pdev)
        release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
        pci_disable_device(pdev);
        framebuffer_release(fb_info);
-       pci_set_drvdata(pdev, NULL);
 }
 
 static struct pci_driver xgifb_driver = {
index 46dea3f1088805749a1a6a9b449117fb827fc91d..400c726753fa48170e8a0187568d7025daed2092 100644 (file)
@@ -845,11 +845,10 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeIdIndex,
                        VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
 
                if (pVBInfo->SetFlag & TVSimuMode) {
-                       if (modeflag & Charx8Dot) {
+                       if (modeflag & Charx8Dot)
                                VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK;
-                       } else {
+                       else
                                VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK;
-                       }
                }
 
                /* 301lv */
@@ -5274,9 +5273,8 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
 
        outb(0x00, pVBInfo->P3c8);
 
-       for (i = 0; i < 256 * 3; i++) {
+       for (i = 0; i < 256 * 3; i++)
                outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */
-       }
 
        mdelay(1);
 
@@ -5291,9 +5289,8 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
        /* avoid display something, set BLACK DAC if not restore DAC */
        outb(0x00, pVBInfo->P3c8);
 
-       for (i = 0; i < 256 * 3; i++) {
+       for (i = 0; i < 256 * 3; i++)
                outb(0, (pVBInfo->P3c8 + 1));
-       }
 
        xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
        xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
index 7168eedbd96a1bb471666af8b74a1fa2c08249a0..f17e5b9bd3330c61baa515a18b528c0b26e14393 100644 (file)
@@ -1284,7 +1284,7 @@ static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = {
        {0, 1048,   0, 771}, /* 04 (640x480x60Hz) */
        {0, 1048,   0, 771}, /* 05 (800x600x60Hz) */
        {0, 1048, 805, 770}  /* 06 (1024x768x60Hz) */
-} ;
+};
 
 static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = {
        {1142,  856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
index 8a4181f846a107df9b68b1bf1e8cdc5b94930332..b15f778b4c6815e43a4320cd94862e79dfe4b529 100644 (file)
@@ -16,14 +16,14 @@ if XILLYBUS
 
 config XILLYBUS_PCIE
        tristate "Xillybus over PCIe"
-       depends on XILLYBUS && PCI
+       depends on PCI
        help
          Set to M if you want Xillybus to use PCI Express for communicating
          with the FPGA.
 
 config XILLYBUS_OF
        tristate "Xillybus over Device Tree"
-       depends on XILLYBUS && OF_ADDRESS && OF_IRQ
+       depends on OF_ADDRESS && OF_IRQ
        help
          Set to M if you want Xillybus to find its resources from the
          Open Firmware Flattened Device Tree. If the target is an embedded
index 7db6f03a00540cd8c2a131ab7039fec6251b72cc..2ebaf166038c6e939435f19e1386e752b12bf356 100644 (file)
@@ -101,7 +101,7 @@ static struct workqueue_struct *xillybus_wq;
  * wr_mutex -> rd_mutex -> register_mutex -> wr_spinlock -> rd_spinlock
  */
 
-static void malformed_message(u32 *buf)
+static void malformed_message(struct xilly_endpoint *endpoint, u32 *buf)
 {
        int opcode;
        int msg_channel, msg_bufno, msg_data, msg_dir;
@@ -112,9 +112,9 @@ static void malformed_message(u32 *buf)
        msg_bufno = (buf[0] >> 12) & 0x3ff;
        msg_data = buf[1] & 0xfffffff;
 
-       pr_warn("xillybus: Malformed message (skipping): "
-               "opcode=%d, channel=%03x, dir=%d, bufno=%03x, data=%07x\n",
-               opcode, msg_channel, msg_dir, msg_bufno, msg_data);
+       dev_warn(endpoint->dev,
+                "Malformed message (skipping): opcode=%d, channel=%03x, dir=%d, bufno=%03x, data=%07x\n",
+                opcode, msg_channel, msg_dir, msg_bufno, msg_data);
 }
 
 /*
@@ -152,16 +152,16 @@ irqreturn_t xillybus_isr(int irq, void *data)
 
        for (i = 0; i < buf_size; i += 2)
                if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) {
-                       malformed_message(&buf[i]);
-                       pr_warn("xillybus: Sending a NACK on "
-                               "counter %x (instead of %x) on entry %d\n",
+                       malformed_message(ep, &buf[i]);
+                       dev_warn(ep->dev,
+                                "Sending a NACK on counter %x (instead of %x) on entry %d\n",
                                ((buf[i+1] >> 28) & 0xf),
                                ep->msg_counter,
                                i/2);
 
                        if (++ep->failed_messages > 10)
-                               pr_err("xillybus: Lost sync with "
-                                      "interrupt messages. Stopping.\n");
+                               dev_err(ep->dev,
+                                       "Lost sync with interrupt messages. Stopping.\n");
                        else {
                                ep->ephw->hw_sync_sgl_for_device(
                                        ep,
@@ -177,7 +177,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
                        break;
 
        if (i >= buf_size) {
-               pr_err("xillybus: Bad interrupt message. Stopping.\n");
+               dev_err(ep->dev, "Bad interrupt message. Stopping.\n");
                return IRQ_HANDLED;
        }
 
@@ -196,7 +196,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
 
                        if ((msg_channel > ep->num_channels) ||
                            (msg_channel == 0)) {
-                               malformed_message(&buf[i]);
+                               malformed_message(ep, &buf[i]);
                                break;
                        }
 
@@ -204,7 +204,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
 
                        if (msg_dir) { /* Write channel */
                                if (msg_bufno >= channel->num_wr_buffers) {
-                                       malformed_message(&buf[i]);
+                                       malformed_message(ep, &buf[i]);
                                        break;
                                }
                                spin_lock(&channel->wr_spinlock);
@@ -221,7 +221,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
                                /* Read channel */
 
                                if (msg_bufno >= channel->num_rd_buffers) {
-                                       malformed_message(&buf[i]);
+                                       malformed_message(ep, &buf[i]);
                                        break;
                                }
 
@@ -243,14 +243,14 @@ irqreturn_t xillybus_isr(int irq, void *data)
                        if ((msg_channel > ep->num_channels) ||
                            (msg_channel == 0) || (!msg_dir) ||
                            !ep->channels[msg_channel]->wr_supports_nonempty) {
-                               malformed_message(&buf[i]);
+                               malformed_message(ep, &buf[i]);
                                break;
                        }
 
                        channel = ep->channels[msg_channel];
 
                        if (msg_bufno >= channel->num_wr_buffers) {
-                               malformed_message(&buf[i]);
+                               malformed_message(ep, &buf[i]);
                                break;
                        }
                        spin_lock(&channel->wr_spinlock);
@@ -283,16 +283,11 @@ irqreturn_t xillybus_isr(int irq, void *data)
                case XILLYMSG_OPCODE_FATAL_ERROR:
                        ep->fatal_error = 1;
                        wake_up_interruptible(&ep->ep_wait); /* For select() */
-                       pr_err("xillybus: FPGA reported a fatal "
-                              "error. This means that the low-level "
-                              "communication with the device has failed. "
-                              "This hardware problem is most likely "
-                              "unrelated to xillybus (neither kernel "
-                              "module nor FPGA core), but reports are "
-                              "still welcome. All I/O is aborted.\n");
+                       dev_err(ep->dev,
+                               "FPGA reported a fatal error. This means that the low-level communication with the device has failed. This hardware problem is most likely unrelated to Xillybus (neither kernel module nor FPGA core), but reports are still welcome. All I/O is aborted.\n");
                        break;
                default:
-                       malformed_message(&buf[i]);
+                       malformed_message(ep, &buf[i]);
                        break;
                }
        }
@@ -486,8 +481,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
 
                if ((channelnum > ep->num_channels) ||
                    ((channelnum == 0) && !is_writebuf)) {
-                       pr_err("xillybus: IDT requests channel out "
-                              "of range. Aborting.\n");
+                       dev_err(ep->dev,
+                               "IDT requests channel out of range. Aborting.\n");
                        return -ENODEV;
                }
 
@@ -565,9 +560,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
                                 */
                                if ((left_of_wr_salami < bytebufsize) &&
                                    (left_of_wr_salami > 0)) {
-                                       pr_err("xillybus: "
-                                              "Corrupt buffer allocation "
-                                              "in IDT. Aborting.\n");
+                                       dev_err(ep->dev,
+                                               "Corrupt buffer allocation in IDT. Aborting.\n");
                                        return -ENODEV;
                                }
 
@@ -644,9 +638,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
                                 */
                                if ((left_of_rd_salami < bytebufsize) &&
                                    (left_of_rd_salami > 0)) {
-                                       pr_err("xillybus: "
-                                              "Corrupt buffer allocation "
-                                              "in IDT. Aborting.\n");
+                                       dev_err(ep->dev,
+                                               "Corrupt buffer allocation in IDT. Aborting.\n");
                                        return -ENODEV;
                                }
 
@@ -706,19 +699,19 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
        }
 
        if (!msg_buf_done) {
-               pr_err("xillybus: Corrupt IDT: No message buffer. "
-                      "Aborting.\n");
+               dev_err(ep->dev,
+                       "Corrupt IDT: No message buffer. Aborting.\n");
                return -ENODEV;
        }
 
        return 0;
 
 memfail:
-       pr_err("xillybus: Failed to allocate write buffer memory. "
-              "Aborting.\n");
+       dev_err(ep->dev,
+               "Failed to allocate write buffer memory. Aborting.\n");
        return -ENOMEM;
 dmafail:
-       pr_err("xillybus: Failed to map DMA memory!. Aborting.\n");
+       dev_err(ep->dev, "Failed to map DMA memory!. Aborting.\n");
        return -ENOMEM;
 }
 
@@ -745,8 +738,8 @@ static void xilly_scan_idt(struct xilly_endpoint *endpoint,
        scan++;
 
        if (scan > end_of_idt) {
-               pr_err("xillybus: IDT device name list overflow. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "IDT device name list overflow. Aborting.\n");
                idt_handle->chandesc = NULL;
                return;
        } else
@@ -757,8 +750,8 @@ static void xilly_scan_idt(struct xilly_endpoint *endpoint,
        if (len & 0x03) {
                idt_handle->chandesc = NULL;
 
-               pr_err("xillybus: Corrupt IDT device name list. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Corrupt IDT device name list. Aborting.\n");
        }
 
        idt_handle->entries = len >> 2;
@@ -787,7 +780,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
                                         XILLY_TIMEOUT);
 
        if (channel->wr_sleepy) {
-               pr_err("xillybus: Failed to obtain IDT. Aborting.\n");
+               dev_err(endpoint->dev, "Failed to obtain IDT. Aborting.\n");
 
                if (endpoint->fatal_error)
                        return -EIO;
@@ -803,8 +796,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
                DMA_FROM_DEVICE);
 
        if (channel->wr_buffers[0]->end_offset != endpoint->idtlen) {
-               pr_err("xillybus: IDT length mismatch (%d != %d). "
-                      "Aborting.\n",
+               dev_err(endpoint->dev,
+                       "IDT length mismatch (%d != %d). Aborting.\n",
                       channel->wr_buffers[0]->end_offset, endpoint->idtlen);
                rc = -ENODEV;
                return rc;
@@ -812,7 +805,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
 
        if (crc32_le(~0, channel->wr_buffers[0]->addr,
                     endpoint->idtlen+1) != 0) {
-               pr_err("xillybus: IDT failed CRC check. Aborting.\n");
+               dev_err(endpoint->dev, "IDT failed CRC check. Aborting.\n");
                rc = -ENODEV;
                return rc;
        }
@@ -821,9 +814,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
 
        /* Check version number. Accept anything below 0x82 for now. */
        if (*version > 0x82) {
-               pr_err("xillybus: No support for IDT version 0x%02x. "
-                      "Maybe the xillybus driver needs an upgarde. "
-                      "Aborting.\n",
+               dev_err(endpoint->dev,
+                       "No support for IDT version 0x%02x. Maybe the xillybus driver needs an upgarde. Aborting.\n",
                       (int) *version);
                rc = -ENODEV;
                return rc;
@@ -1312,9 +1304,8 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout)
                                 channel->rd_wait,
                                 (!channel->rd_full),
                                 timeout) == 0) {
-                       pr_warn("xillybus: "
-                               "Timed out while flushing. "
-                               "Output data may be lost.\n");
+                       dev_warn(channel->endpoint->dev,
+                               "Timed out while flushing. Output data may be lost.\n");
 
                        rc = -ETIMEDOUT;
                        break;
@@ -1354,12 +1345,11 @@ static void xillybus_autoflush(struct work_struct *work)
        rc = xillybus_myflush(channel, -1);
 
        if (rc == -EINTR)
-               pr_warn("xillybus: Autoflush failed because "
-                       "work queue thread got a signal.\n");
+               dev_warn(channel->endpoint->dev,
+                        "Autoflush failed because work queue thread got a signal.\n");
        else if (rc)
-               pr_err("xillybus: Autoflush failed under "
-                      "weird circumstances.\n");
-
+               dev_err(channel->endpoint->dev,
+                       "Autoflush failed under weird circumstances.\n");
 }
 
 static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
@@ -1615,8 +1605,8 @@ static int xillybus_open(struct inode *inode, struct file *filp)
        mutex_unlock(&ep_list_lock);
 
        if (!endpoint) {
-               pr_err("xillybus: open() failed to find a device "
-                      "for major=%d and minor=%d\n", major, minor);
+               pr_err("xillybus: open() failed to find a device for major=%d and minor=%d\n",
+                      major, minor);
                return -ENODEV;
        }
 
@@ -1642,15 +1632,15 @@ static int xillybus_open(struct inode *inode, struct file *filp)
        if ((filp->f_mode & FMODE_READ) && (filp->f_flags & O_NONBLOCK) &&
            (channel->wr_synchronous || !channel->wr_allow_partial ||
             !channel->wr_supports_nonempty)) {
-               pr_err("xillybus: open() failed: "
-                      "O_NONBLOCK not allowed for read on this device\n");
+               dev_err(endpoint->dev,
+                       "open() failed: O_NONBLOCK not allowed for read on this device\n");
                return -ENODEV;
        }
 
        if ((filp->f_mode & FMODE_WRITE) && (filp->f_flags & O_NONBLOCK) &&
            (channel->rd_synchronous || !channel->rd_allow_partial)) {
-               pr_err("xillybus: open() failed: "
-                      "O_NONBLOCK not allowed for write on this device\n");
+               dev_err(endpoint->dev,
+                       "open() failed: O_NONBLOCK not allowed for write on this device\n");
                return -ENODEV;
        }
 
@@ -1765,8 +1755,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
                rc = mutex_lock_interruptible(&channel->rd_mutex);
 
                if (rc) {
-                       pr_warn("xillybus: Failed to close file. "
-                               "Hardware left in messy state.\n");
+                       dev_warn(channel->endpoint->dev,
+                                "Failed to close file. Hardware left in messy state.\n");
                        return rc;
                }
 
@@ -1791,8 +1781,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
        if (filp->f_mode & FMODE_READ) {
                rc = mutex_lock_interruptible(&channel->wr_mutex);
                if (rc) {
-                       pr_warn("xillybus: Failed to close file. "
-                               "Hardware left in messy state.\n");
+                       dev_warn(channel->endpoint->dev,
+                                "Failed to close file. Hardware left in messy state.\n");
                        return rc;
                }
 
@@ -1853,10 +1843,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
 
                                if (channel->wr_sleepy) {
                                        mutex_unlock(&channel->wr_mutex);
-                                       pr_warn("xillybus: Hardware failed to "
-                                               "respond to close command, "
-                                               "therefore left in "
-                                               "messy state.\n");
+                                       dev_warn(channel->endpoint->dev,
+                                                "Hardware failed to respond to close command, therefore left in messy state.\n");
                                        return -EINTR;
                                }
                        }
@@ -2022,7 +2010,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint,
                                 xillyname);
 
        if (rc) {
-               pr_warn("xillybus: Failed to obtain major/minors");
+               dev_warn(endpoint->dev, "Failed to obtain major/minors");
                goto error1;
        }
 
@@ -2034,7 +2022,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint,
        rc = cdev_add(&endpoint->cdev, MKDEV(major, minor),
                      endpoint->num_channels);
        if (rc) {
-               pr_warn("xillybus: Failed to add cdev. Aborting.\n");
+               dev_warn(endpoint->dev, "Failed to add cdev. Aborting.\n");
                goto error2;
        }
 
@@ -2057,14 +2045,15 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint,
                                       "%s", devname);
 
                if (IS_ERR(device)) {
-                       pr_warn("xillybus: Failed to create %s "
-                               "device. Aborting.\n", devname);
+                       dev_warn(endpoint->dev,
+                                "Failed to create %s device. Aborting.\n",
+                                devname);
                        goto error3;
                }
        }
 
-       pr_info("xillybus: Created %d device files.\n",
-               endpoint->num_channels);
+       dev_info(endpoint->dev, "Created %d device files.\n",
+                endpoint->num_channels);
        return 0; /* succeed */
 
 error3:
@@ -2093,8 +2082,8 @@ static void xillybus_cleanup_chrdev(struct xilly_endpoint *endpoint)
                                       endpoint->lowest_minor),
                                 endpoint->num_channels);
 
-       pr_info("xillybus: Removed %d device files.\n",
-               endpoint->num_channels);
+       dev_info(endpoint->dev, "Removed %d device files.\n",
+                endpoint->num_channels);
 }
 
 
@@ -2107,7 +2096,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
 
        endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
        if (!endpoint) {
-               pr_err("xillybus: Failed to allocate memory. Aborting.\n");
+               dev_err(dev, "Failed to allocate memory. Aborting.\n");
                return NULL;
        }
 
@@ -2141,8 +2130,8 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint)
                                         XILLY_TIMEOUT);
 
        if (endpoint->idtlen < 0) {
-               pr_err("xillybus: Failed to quiesce the device on "
-                      "exit. Quitting while leaving a mess.\n");
+               dev_err(endpoint->dev,
+                       "Failed to quiesce the device on exit. Quitting while leaving a mess.\n");
                return -ENODEV;
        }
        return 0; /* Success */
@@ -2209,7 +2198,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
                                         XILLY_TIMEOUT);
 
        if (endpoint->idtlen < 0) {
-               pr_err("xillybus: No response from FPGA. Aborting.\n");
+               dev_err(endpoint->dev, "No response from FPGA. Aborting.\n");
                rc = -ENODEV;
                goto failed_quiesce;
        }
@@ -2323,7 +2312,7 @@ static int __init xillybus_init(void)
        xillybus_class = class_create(THIS_MODULE, xillyname);
        if (IS_ERR(xillybus_class)) {
                rc = PTR_ERR(xillybus_class);
-               pr_warn("xillybus: Failed to register class xillybus\n");
+               pr_warn("Failed to register class xillybus\n");
 
                return rc;
        }
index 92c2931f434840435a90327e6d7e66c30dde6ad4..394bfea1af6e308d0118e75adc16d25bc0dc801d 100644 (file)
@@ -117,14 +117,15 @@ static int xilly_drv_probe(struct platform_device *op)
 
        rc = of_address_to_resource(dev->of_node, 0, &endpoint->res);
        if (rc) {
-               pr_warn("xillybus: Failed to obtain device tree "
-                       "resource\n");
+               dev_warn(endpoint->dev,
+                        "Failed to obtain device tree resource\n");
                goto failed_request_regions;
        }
 
        if  (!request_mem_region(endpoint->res.start,
                                 resource_size(&endpoint->res), xillyname)) {
-               pr_err("xillybus: request_mem_region failed. Aborting.\n");
+               dev_err(endpoint->dev,
+                       "request_mem_region failed. Aborting.\n");
                rc = -EBUSY;
                goto failed_request_regions;
        }
@@ -132,7 +133,8 @@ static int xilly_drv_probe(struct platform_device *op)
        endpoint->registers = of_iomap(dev->of_node, 0);
 
        if (!endpoint->registers) {
-               pr_err("xillybus: Failed to map I/O memory. Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to map I/O memory. Aborting.\n");
                goto failed_iomap0;
        }
 
@@ -141,8 +143,8 @@ static int xilly_drv_probe(struct platform_device *op)
        rc = request_irq(irq, xillybus_isr, 0, xillyname, endpoint);
 
        if (rc) {
-               pr_err("xillybus: Failed to register IRQ handler. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to register IRQ handler. Aborting.\n");
                rc = -ENODEV;
                goto failed_register_irq;
        }
@@ -198,15 +200,4 @@ static struct platform_driver xillybus_platform_driver = {
        },
 };
 
-static int __init xillybus_of_init(void)
-{
-       return platform_driver_register(&xillybus_platform_driver);
-}
-
-static void __exit xillybus_of_exit(void)
-{
-       platform_driver_unregister(&xillybus_platform_driver);
-}
-
-module_init(xillybus_of_init);
-module_exit(xillybus_of_exit);
+module_platform_driver(xillybus_platform_driver);
index 67013652358b905039bbfae37791cb721baf7352..1811aa76421384aedf3e47eb62e8e60e0ea6b6b4 100644 (file)
@@ -134,7 +134,7 @@ static int xilly_probe(struct pci_dev *pdev,
        struct xilly_endpoint *endpoint;
        int rc = 0;
 
-       endpoint = xillybus_init_endpoint(pdev, NULL, &pci_hw);
+       endpoint = xillybus_init_endpoint(pdev, &pdev->dev, &pci_hw);
 
        if (!endpoint)
                return -ENOMEM;
@@ -148,29 +148,29 @@ static int xilly_probe(struct pci_dev *pdev,
        pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
 
        if (rc) {
-               pr_err("xillybus: pci_enable_device() failed. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "pci_enable_device() failed. Aborting.\n");
                goto no_enable;
        }
 
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-               pr_err("xillybus: Incorrect BAR configuration. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Incorrect BAR configuration. Aborting.\n");
                rc = -ENODEV;
                goto bad_bar;
        }
 
        rc = pci_request_regions(pdev, xillyname);
        if (rc) {
-               pr_err("xillybus: pci_request_regions() failed. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "pci_request_regions() failed. Aborting.\n");
                goto failed_request_regions;
        }
 
        endpoint->registers = pci_iomap(pdev, 0, 128);
 
        if (!endpoint->registers) {
-               pr_err("xillybus: Failed to map BAR 0. Aborting.\n");
+               dev_err(endpoint->dev, "Failed to map BAR 0. Aborting.\n");
                goto failed_iomap0;
        }
 
@@ -178,16 +178,16 @@ static int xilly_probe(struct pci_dev *pdev,
 
        /* Set up a single MSI interrupt */
        if (pci_enable_msi(pdev)) {
-               pr_err("xillybus: Failed to enable MSI interrupts. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to enable MSI interrupts. Aborting.\n");
                rc = -ENODEV;
                goto failed_enable_msi;
        }
        rc = request_irq(pdev->irq, xillybus_isr, 0, xillyname, endpoint);
 
        if (rc) {
-               pr_err("xillybus: Failed to register MSI handler. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to register MSI handler. Aborting.\n");
                rc = -ENODEV;
                goto failed_register_msi;
        }
@@ -202,8 +202,7 @@ static int xilly_probe(struct pci_dev *pdev,
        if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
                endpoint->dma_using_dac = 0;
        else {
-               pr_err("xillybus: Failed to set DMA mask. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n");
                rc = -ENODEV;
                goto failed_dmamask;
        }
index 2c4ed52ca849d45b385cbeed0d88a545d4a5fa5d..79ce363b2ea9d1dd2cb0b79362b607659ca37345 100644 (file)
@@ -648,6 +648,9 @@ static ssize_t reset_store(struct device *dev,
        zram = dev_to_zram(dev);
        bdev = bdget_disk(zram->disk, 0);
 
+       if (!bdev)
+               return -ENOMEM;
+
        /* Do not reset an active device! */
        if (bdev->bd_holders)
                return -EBUSY;
@@ -660,8 +663,7 @@ static ssize_t reset_store(struct device *dev,
                return -EINVAL;
 
        /* Make sure all pending I/O is finished */
-       if (bdev)
-               fsync_bdev(bdev);
+       fsync_bdev(bdev);
 
        zram_reset_device(zram, true);
        return len;
@@ -896,13 +898,10 @@ static void destroy_device(struct zram *zram)
        sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
                        &zram_disk_attr_group);
 
-       if (zram->disk) {
-               del_gendisk(zram->disk);
-               put_disk(zram->disk);
-       }
+       del_gendisk(zram->disk);
+       put_disk(zram->disk);
 
-       if (zram->queue)
-               blk_cleanup_queue(zram->queue);
+       blk_cleanup_queue(zram->queue);
 }
 
 static int __init zram_init(void)
index 7fab032298f33986cd55b518d3db60eebadb4d9b..0ae13cd0908ed0b25341b812993bea65f681e45f 100644 (file)
@@ -1,5 +1,6 @@
 config ZSMALLOC
        bool "Memory allocator for compressed pages"
+       depends on MMU
        default n
        help
          zsmalloc is a slab-based memory allocator designed to store
index a93a424873faf638a004a3cabbc5f381d381027a..8096fcbe2dc171d4742b561fdcaa0f60e1894547 100644 (file)
@@ -349,7 +349,7 @@ bfin_jc_early_write(struct console *co, const char *buf, unsigned int count)
        bfin_jc_straight_buffer_write(buf, count);
 }
 
-static struct __initdata console bfin_jc_early_console = {
+static struct console bfin_jc_early_console __initdata = {
        .name   = "early_BFJC",
        .write   = bfin_jc_early_write,
        .flags   = CON_ANYTIME | CON_PRINTBUFFER,
index 44fbebab5075f98f337d880288993b01ad9e7271..3502a7bbb69eee716f21b5b5b89c14fd3f9627fb 100644 (file)
@@ -86,6 +86,21 @@ static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
        return i;
 }
 
+static bool hvc_dcc_check(void)
+{
+       unsigned long time = jiffies + (HZ / 10);
+
+       /* Write a test character to check if it is handled */
+       __dcc_putchar('\n');
+
+       while (time_is_after_jiffies(time)) {
+               if (!(__dcc_getstatus() & DCC_STATUS_TX))
+                       return true;
+       }
+
+       return false;
+}
+
 static const struct hv_ops hvc_dcc_get_put_ops = {
        .get_chars = hvc_dcc_get_chars,
        .put_chars = hvc_dcc_put_chars,
@@ -93,6 +108,9 @@ static const struct hv_ops hvc_dcc_get_put_ops = {
 
 static int __init hvc_dcc_console_init(void)
 {
+       if (!hvc_dcc_check())
+               return -ENODEV;
+
        hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
        return 0;
 }
@@ -100,6 +118,9 @@ console_initcall(hvc_dcc_console_init);
 
 static int __init hvc_dcc_init(void)
 {
+       if (!hvc_dcc_check())
+               return -ENODEV;
+
        hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
        return 0;
 }
index fd17a9b804b8ab8608097661b824e27c5bb1cd02..db19a38c8c69b0d33dddac2c1fff95f3f79b80f3 100644 (file)
@@ -1354,8 +1354,7 @@ out_error_memory:
        mempool_destroy(hvc_iucv_mempool);
        kmem_cache_destroy(hvc_iucv_buffer_cache);
 out_error:
-       if (hvc_iucv_filter)
-               kfree(hvc_iucv_filter);
+       kfree(hvc_iucv_filter);
        hvc_iucv_devices = 0; /* ensure that we do not provide any device */
        return rc;
 }
index c791b18cdd086a1fa22b470ba8b9904dd0fc01e3..b594abfbf21e76d58acc1df534a30f603670fb5a 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/prom.h>
 #include <asm/hvsi.h>
 #include <asm/udbg.h>
+#include <asm/machdep.h>
 
 #include "hvc_console.h"
 
@@ -457,7 +458,9 @@ void __init hvc_vio_init_early(void)
        if (hvterm_priv0.proto == HV_PROTOCOL_HVSI)
                goto out;
 #endif
-       add_preferred_console("hvc", 0, NULL);
+       /* Check whether the user has requested a different console. */
+       if (!strstr(cmd_line, "console="))
+               add_preferred_console("hvc", 0, NULL);
        hvc_instantiate(0, 0, ops);
 out:
        of_node_put(stdout_node);
index 7a744b69c3d144516388d3e8a4bc2fc440fd4d34..7cdd1eb9406c11ccb4870560490f0c6036f92032 100644 (file)
@@ -767,7 +767,7 @@ static size_t __process_echoes(struct tty_struct *tty)
         * of echo overrun before the next commit), then discard enough
         * 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_START) {
                        if (echo_buf(ldata, tail) == ECHO_OP_ERASE_TAB)
                                tail += 3;
                        else
@@ -1752,20 +1752,14 @@ int is_ignored(int sig)
 static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
        struct n_tty_data *ldata = tty->disc_data;
-       int canon_change = 1;
 
-       if (old)
-               canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;
-       if (canon_change) {
+       if (!old || (old->c_lflag ^ tty->termios.c_lflag) & ICANON) {
                bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
                ldata->line_start = ldata->canon_head = ldata->read_tail;
                ldata->erasing = 0;
                ldata->lnext = 0;
        }
 
-       if (canon_change && !L_ICANON(tty) && read_cnt(ldata))
-               wake_up_interruptible(&tty->read_wait);
-
        ldata->icanon = (L_ICANON(tty) != 0);
 
        if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
@@ -1820,9 +1814,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
         * Fix tty hang when I_IXON(tty) is cleared, but the tty
         * been stopped by STOP_CHAR(tty) before it.
         */
-       if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
+       if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped)
                start_tty(tty);
-       }
 
        /* The termios change make the tty ready for I/O */
        wake_up_interruptible(&tty->write_wait);
index d6080c3831ef98b72d8269dc3750f58f6d55bfba..cd04293695576aeec9cd25fdce8de91b97f7fd2c 100644 (file)
@@ -959,7 +959,7 @@ static int receive_flow_control(struct nozomi *dc)
                dev_err(&dc->pdev->dev,
                        "ERROR: flow control received for non-existing port\n");
                return 0;
-       };
+       }
 
        DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl),
           *((u16 *)&ctrl_dl));
@@ -1025,7 +1025,7 @@ static enum ctrl_port_type port2ctrl(enum port_type port,
                dev_err(&dc->pdev->dev,
                        "ERROR: send flow control " \
                        "received for non-existing port\n");
-       };
+       }
        return CTRL_ERROR;
 }
 
@@ -1805,7 +1805,7 @@ static int ntty_ioctl(struct tty_struct *tty,
        default:
                DBG1("ERR: 0x%08X, %d", cmd, cmd);
                break;
-       };
+       }
 
        return rval;
 }
index 570df9d2a5d2f46afc72a23d1e373f2c5aa4f3ba..e33d38cb170f97e4055a0a17eb0f4e7bc0b45d0e 100644 (file)
@@ -2322,7 +2322,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
                fcr = uart_config[port->type].fcr;
-               if (baud < 2400 || fifo_bug) {
+               if ((baud < 2400 && !up->dma) || fifo_bug) {
                        fcr &= ~UART_FCR_TRIGGER_MASK;
                        fcr |= UART_FCR_TRIGGER_1;
                }
index daf710f5c3fc68e0197012ea129edf1a41a7ea14..4658e3e0ec4256d9b2e31f890ea72822abf47f93 100644 (file)
 
 
 struct dw8250_data {
-       int             last_lcr;
-       int             last_mcr;
-       int             line;
-       struct clk      *clk;
-       u8              usr_reg;
+       u8                      usr_reg;
+       int                     last_mcr;
+       int                     line;
+       struct clk              *clk;
+       struct uart_8250_dma    dma;
 };
 
 static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
@@ -76,17 +76,33 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
        return value;
 }
 
+static void dw8250_force_idle(struct uart_port *p)
+{
+       serial8250_clear_and_reinit_fifos(container_of
+                                         (p, struct uart_8250_port, port));
+       (void)p->serial_in(p, UART_RX);
+}
+
 static void dw8250_serial_out(struct uart_port *p, int offset, int value)
 {
        struct dw8250_data *d = p->private_data;
 
-       if (offset == UART_LCR)
-               d->last_lcr = value;
-
        if (offset == UART_MCR)
                d->last_mcr = value;
 
        writeb(value, p->membase + (offset << p->regshift));
+
+       /* Make sure LCR write wasn't ignored */
+       if (offset == UART_LCR) {
+               int tries = 1000;
+               while (tries--) {
+                       if (value == p->serial_in(p, UART_LCR))
+                               return;
+                       dw8250_force_idle(p);
+                       writeb(value, p->membase + (UART_LCR << p->regshift));
+               }
+               dev_err(p->dev, "Couldn't set LCR to %d\n", value);
+       }
 }
 
 static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
@@ -107,13 +123,22 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
 {
        struct dw8250_data *d = p->private_data;
 
-       if (offset == UART_LCR)
-               d->last_lcr = value;
-
        if (offset == UART_MCR)
                d->last_mcr = value;
 
        writel(value, p->membase + (offset << p->regshift));
+
+       /* Make sure LCR write wasn't ignored */
+       if (offset == UART_LCR) {
+               int tries = 1000;
+               while (tries--) {
+                       if (value == p->serial_in(p, UART_LCR))
+                               return;
+                       dw8250_force_idle(p);
+                       writel(value, p->membase + (UART_LCR << p->regshift));
+               }
+               dev_err(p->dev, "Couldn't set LCR to %d\n", value);
+       }
 }
 
 static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
@@ -131,9 +156,8 @@ static int dw8250_handle_irq(struct uart_port *p)
        if (serial8250_handle_irq(p, iir)) {
                return 1;
        } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
-               /* Clear the USR and write the LCR again. */
+               /* Clear the USR */
                (void)p->serial_in(p, d->usr_reg);
-               p->serial_out(p, UART_LCR, d->last_lcr);
 
                return 1;
        }
@@ -153,6 +177,14 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
                pm_runtime_put_sync_suspend(port->dev);
 }
 
+static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
+{
+       struct dw8250_data *data = param;
+
+       return chan->chan_id == data->dma.tx_chan_id ||
+              chan->chan_id == data->dma.rx_chan_id;
+}
+
 static void dw8250_setup_port(struct uart_8250_port *up)
 {
        struct uart_port        *p = &up->port;
@@ -241,7 +273,8 @@ static int dw8250_probe_of(struct uart_port *p,
 }
 
 #ifdef CONFIG_ACPI
-static int dw8250_probe_acpi(struct uart_8250_port *up)
+static int dw8250_probe_acpi(struct uart_8250_port *up,
+                            struct dw8250_data *data)
 {
        const struct acpi_device_id *id;
        struct uart_port *p = &up->port;
@@ -260,9 +293,7 @@ static int dw8250_probe_acpi(struct uart_8250_port *up)
        if (!p->uartclk)
                p->uartclk = (unsigned int)id->driver_data;
 
-       up->dma = devm_kzalloc(p->dev, sizeof(*up->dma), GFP_KERNEL);
-       if (!up->dma)
-               return -ENOMEM;
+       up->dma = &data->dma;
 
        up->dma->rxconf.src_maxburst = p->fifosize / 4;
        up->dma->txconf.dst_maxburst = p->fifosize / 4;
@@ -270,7 +301,8 @@ static int dw8250_probe_acpi(struct uart_8250_port *up)
        return 0;
 }
 #else
-static inline int dw8250_probe_acpi(struct uart_8250_port *up)
+static inline int dw8250_probe_acpi(struct uart_8250_port *up,
+                                   struct dw8250_data *data)
 {
        return -ENODEV;
 }
@@ -314,6 +346,12 @@ static int dw8250_probe(struct platform_device *pdev)
                uart.port.uartclk = clk_get_rate(data->clk);
        }
 
+       data->dma.rx_chan_id = -1;
+       data->dma.tx_chan_id = -1;
+       data->dma.rx_param = data;
+       data->dma.tx_param = data;
+       data->dma.fn = dw8250_dma_filter;
+
        uart.port.iotype = UPIO_MEM;
        uart.port.serial_in = dw8250_serial_in;
        uart.port.serial_out = dw8250_serial_out;
@@ -324,7 +362,7 @@ static int dw8250_probe(struct platform_device *pdev)
                if (err)
                        return err;
        } else if (ACPI_HANDLE(&pdev->dev)) {
-               err = dw8250_probe_acpi(&uart);
+               err = dw8250_probe_acpi(&uart, data);
                if (err)
                        return err;
        } else {
index 5f3bba12c159eb4ceaef924495929f19eb5b4247..d1a9078003bd35caa7f6ee0f8a2f6d256751686c 100644 (file)
@@ -122,7 +122,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
        up.port.dev = &pdev->dev;
        up.port.private_data = priv;
 
-       clk_enable(priv->sclk);
+       clk_prepare_enable(priv->sclk);
        up.port.uartclk = clk_get_rate(priv->sclk);
 
        up.port.iotype = UPIO_MEM32;
@@ -134,7 +134,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
        ret = serial8250_register_8250_port(&up);
        if (ret < 0) {
                dev_err(&pdev->dev, "unable to register 8250 port\n");
-               clk_disable(priv->sclk);
+               clk_disable_unprepare(priv->sclk);
                return ret;
        }
 
@@ -148,7 +148,7 @@ static int serial8250_em_remove(struct platform_device *pdev)
        struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
 
        serial8250_unregister_port(priv->line);
-       clk_disable(priv->sclk);
+       clk_disable_unprepare(priv->sclk);
        return 0;
 }
 
index c810da7c7a8843d452ced857d64863993365b464..4697a514b80a6d2cafcd6a2800d8cdc820c6594f 100644 (file)
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License.
  */
+#undef DEBUG
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -27,8 +28,6 @@
 
 #include "8250.h"
 
-#undef SERIAL_DEBUG_PCI
-
 /*
  * init function returns:
  *  > 0 - number of ports
@@ -63,7 +62,7 @@ static int pci_default_setup(struct serial_private*,
 
 static void moan_device(const char *str, struct pci_dev *dev)
 {
-       printk(KERN_WARNING
+       dev_err(&dev->dev,
               "%s: %s\n"
               "Please send the output of lspci -vv, this\n"
               "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
@@ -233,7 +232,7 @@ static int pci_inteli960ni_init(struct pci_dev *dev)
        /* is firmware started? */
        pci_read_config_dword(dev, 0x44, (void *)&oldval);
        if (oldval == 0x00001000L) { /* RESET value */
-               printk(KERN_DEBUG "Local i960 firmware missing");
+               dev_dbg(&dev->dev, "Local i960 firmware missing\n");
                return -ENODEV;
        }
        return 0;
@@ -827,7 +826,7 @@ static int pci_netmos_9900_numports(struct pci_dev *dev)
                if (sub_serports > 0) {
                        return sub_serports;
                } else {
-                       printk(KERN_NOTICE "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
+                       dev_err(&dev->dev, "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
                        return 0;
                }
        }
@@ -931,7 +930,7 @@ static int pci_ite887x_init(struct pci_dev *dev)
        }
 
        if (!inta_addr[i]) {
-               printk(KERN_ERR "ite887x: could not find iobase\n");
+               dev_err(&dev->dev, "ite887x: could not find iobase\n");
                return -ENODEV;
        }
 
@@ -1024,9 +1023,9 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)
        /* Tornado device */
        if (deviceID == 0x07000200) {
                number_uarts = ioread8(p + 4);
-               printk(KERN_DEBUG
+               dev_dbg(&dev->dev,
                        "%d ports detected on Oxford PCI Express device\n",
-                                                               number_uarts);
+                       number_uarts);
        }
        pci_iounmap(dev, p);
        return number_uarts;
@@ -1308,6 +1307,29 @@ static int pci_default_setup(struct serial_private *priv,
        return setup_port(priv, port, bar, offset, board->reg_shift);
 }
 
+static int pci_pericom_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_8250_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset, maxnr;
+
+       bar = FL_GET_BASE(board->flags);
+       if (board->flags & FL_BASE_BARS)
+               bar += idx;
+       else
+               offset += idx * board->uart_offset;
+
+       maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
+               (board->reg_shift + 3);
+
+       if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
+               return 1;
+
+       port->port.uartclk = 14745600;
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
 static int
 ce4100_serial_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
@@ -1324,6 +1346,120 @@ ce4100_serial_setup(struct serial_private *priv,
        return ret;
 }
 
+#define PCI_DEVICE_ID_INTEL_BYT_UART1  0x0f0a
+#define PCI_DEVICE_ID_INTEL_BYT_UART2  0x0f0c
+
+#define BYT_PRV_CLK                    0x800
+#define BYT_PRV_CLK_EN                 (1 << 0)
+#define BYT_PRV_CLK_M_VAL_SHIFT                1
+#define BYT_PRV_CLK_N_VAL_SHIFT                16
+#define BYT_PRV_CLK_UPDATE             (1 << 31)
+
+#define BYT_GENERAL_REG                        0x808
+#define BYT_GENERAL_DIS_RTS_N_OVERRIDE (1 << 3)
+
+#define BYT_TX_OVF_INT                 0x820
+#define BYT_TX_OVF_INT_MASK            (1 << 1)
+
+static void
+byt_set_termios(struct uart_port *p, struct ktermios *termios,
+               struct ktermios *old)
+{
+       unsigned int baud = tty_termios_baud_rate(termios);
+       unsigned int m = 6912;
+       unsigned int n = 15625;
+       u32 reg;
+
+       /* For baud rates 1M, 2M, 3M and 4M the dividers must be adjusted. */
+       if (baud == 1000000 || baud == 2000000 || baud == 4000000) {
+               m = 64;
+               n = 100;
+
+               p->uartclk = 64000000;
+       } else if (baud == 3000000) {
+               m = 48;
+               n = 100;
+
+               p->uartclk = 48000000;
+       } else {
+               p->uartclk = 44236800;
+       }
+
+       /* Reset the clock */
+       reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT);
+       writel(reg, p->membase + BYT_PRV_CLK);
+       reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;
+       writel(reg, p->membase + BYT_PRV_CLK);
+
+       /*
+        * If auto-handshake mechanism is not enabled,
+        * disable rts_n override
+        */
+       reg = readl(p->membase + BYT_GENERAL_REG);
+       reg &= ~BYT_GENERAL_DIS_RTS_N_OVERRIDE;
+       if (termios->c_cflag & CRTSCTS)
+               reg |= BYT_GENERAL_DIS_RTS_N_OVERRIDE;
+       writel(reg, p->membase + BYT_GENERAL_REG);
+
+       serial8250_do_set_termios(p, termios, old);
+}
+
+static bool byt_dma_filter(struct dma_chan *chan, void *param)
+{
+       return chan->chan_id == *(int *)param;
+}
+
+static int
+byt_serial_setup(struct serial_private *priv,
+                const struct pciserial_board *board,
+                struct uart_8250_port *port, int idx)
+{
+       struct uart_8250_dma *dma;
+       int ret;
+
+       dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL);
+       if (!dma)
+               return -ENOMEM;
+
+       switch (priv->dev->device) {
+       case PCI_DEVICE_ID_INTEL_BYT_UART1:
+               dma->rx_chan_id = 3;
+               dma->tx_chan_id = 2;
+               break;
+       case PCI_DEVICE_ID_INTEL_BYT_UART2:
+               dma->rx_chan_id = 5;
+               dma->tx_chan_id = 4;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dma->rxconf.slave_id = dma->rx_chan_id;
+       dma->rxconf.src_maxburst = 16;
+
+       dma->txconf.slave_id = dma->tx_chan_id;
+       dma->txconf.dst_maxburst = 16;
+
+       dma->fn = byt_dma_filter;
+       dma->rx_param = &dma->rx_chan_id;
+       dma->tx_param = &dma->tx_chan_id;
+
+       ret = pci_default_setup(priv, board, port, idx);
+       port->port.iotype = UPIO_MEM;
+       port->port.type = PORT_16550A;
+       port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+       port->port.set_termios = byt_set_termios;
+       port->port.fifosize = 64;
+       port->tx_loadsz = 64;
+       port->dma = dma;
+       port->capabilities = UART_CAP_FIFO | UART_CAP_AFE;
+
+       /* Disable Tx counter interrupts */
+       writel(BYT_TX_OVF_INT_MASK, port->port.membase + BYT_TX_OVF_INT);
+
+       return ret;
+}
+
 static int
 pci_omegapci_setup(struct serial_private *priv,
                      const struct pciserial_board *board,
@@ -1344,17 +1480,80 @@ pci_brcm_trumanage_setup(struct serial_private *priv,
        return ret;
 }
 
+static int pci_fintek_setup(struct serial_private *priv,
+                           const struct pciserial_board *board,
+                           struct uart_8250_port *port, int idx)
+{
+       struct pci_dev *pdev = priv->dev;
+       unsigned long base;
+       unsigned long iobase;
+       unsigned long ciobase = 0;
+       u8 config_base;
+
+       /*
+        * We are supposed to be able to read these from the PCI config space,
+        * but the values there don't seem to match what we need to use, so
+        * just use these hard-coded values for now, as they are correct.
+        */
+       switch (idx) {
+       case 0: iobase = 0xe000; config_base = 0x40; break;
+       case 1: iobase = 0xe008; config_base = 0x48; break;
+       case 2: iobase = 0xe010; config_base = 0x50; break;
+       case 3: iobase = 0xe018; config_base = 0x58; break;
+       case 4: iobase = 0xe020; config_base = 0x60; break;
+       case 5: iobase = 0xe028; config_base = 0x68; break;
+       case 6: iobase = 0xe030; config_base = 0x70; break;
+       case 7: iobase = 0xe038; config_base = 0x78; break;
+       case 8: iobase = 0xe040; config_base = 0x80; break;
+       case 9: iobase = 0xe048; config_base = 0x88; break;
+       case 10: iobase = 0xe050; config_base = 0x90; break;
+       case 11: iobase = 0xe058; config_base = 0x98; break;
+       default:
+               /* Unknown number of ports, get out of here */
+               return -EINVAL;
+       }
+
+       if (idx < 4) {
+               base = pci_resource_start(priv->dev, 3);
+               ciobase = (int)(base + (0x8 * idx));
+       }
+
+       dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n",
+               __func__, idx, iobase, ciobase, config_base);
+
+       /* Enable UART I/O port */
+       pci_write_config_byte(pdev, config_base + 0x00, 0x01);
+
+       /* Select 128-byte FIFO and 8x FIFO threshold */
+       pci_write_config_byte(pdev, config_base + 0x01, 0x33);
+
+       /* LSB UART */
+       pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff));
+
+       /* MSB UART */
+       pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8));
+
+       /* irq number, this usually fails, but the spec says to do it anyway. */
+       pci_write_config_byte(pdev, config_base + 0x06, pdev->irq);
+
+       port->port.iotype = UPIO_PORT;
+       port->port.iobase = iobase;
+       port->port.mapbase = 0;
+       port->port.membase = NULL;
+       port->port.regshift = 0;
+
+       return 0;
+}
+
 static int skip_tx_en_setup(struct serial_private *priv,
                        const struct pciserial_board *board,
                        struct uart_8250_port *port, int idx)
 {
        port->port.flags |= UPF_NO_TXEN_TEST;
-       printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
-                         "[%04x:%04x] subsystem [%04x:%04x]\n",
-                         priv->dev->vendor,
-                         priv->dev->device,
-                         priv->dev->subsystem_vendor,
-                         priv->dev->subsystem_device);
+       dev_dbg(&priv->dev->dev,
+               "serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n",
+               priv->dev->vendor, priv->dev->device,
+               priv->dev->subsystem_vendor, priv->dev->subsystem_device);
 
        return pci_default_setup(priv, board, port, idx);
 }
@@ -1662,6 +1861,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = kt_serial_setup,
        },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_UART1,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = byt_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_UART2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = byt_serial_setup,
+       },
        /*
         * ITE
         */
@@ -1825,6 +2038,31 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .setup          = pci_default_setup,
                .exit           = pci_plx9050_exit,
        },
+       /*
+        * Pericom
+        */
+       {
+               .vendor         = 0x12d8,
+               .device         = 0x7952,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_pericom_setup,
+       },
+       {
+               .vendor         = 0x12d8,
+               .device         = 0x7954,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_pericom_setup,
+       },
+       {
+               .vendor         = 0x12d8,
+               .device         = 0x7958,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_pericom_setup,
+       },
+
        /*
         * PLX
         */
@@ -2255,6 +2493,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_brcm_trumanage_setup,
        },
+       {
+               .vendor         = 0x1c29,
+               .device         = 0x1104,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_fintek_setup,
+       },
+       {
+               .vendor         = 0x1c29,
+               .device         = 0x1108,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_fintek_setup,
+       },
+       {
+               .vendor         = 0x1c29,
+               .device         = 0x1112,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_fintek_setup,
+       },
 
        /*
         * Default "match everything" terminator entry
@@ -2449,9 +2708,13 @@ enum pci_board_num_t {
        pbn_ADDIDATA_PCIe_4_3906250,
        pbn_ADDIDATA_PCIe_8_3906250,
        pbn_ce4100_1_115200,
+       pbn_byt,
        pbn_omegapci,
        pbn_NETMOS9900_2s_115200,
        pbn_brcm_trumanage,
+       pbn_fintek_4,
+       pbn_fintek_8,
+       pbn_fintek_12,
 };
 
 /*
@@ -3185,6 +3448,13 @@ static struct pciserial_board pci_boards[] = {
                .base_baud      = 921600,
                .reg_shift      = 2,
        },
+       [pbn_byt] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 2764800,
+               .uart_offset    = 0x80,
+               .reg_shift      = 2,
+       },
        [pbn_omegapci] = {
                .flags          = FL_BASE0,
                .num_ports      = 8,
@@ -3202,6 +3472,24 @@ static struct pciserial_board pci_boards[] = {
                .reg_shift      = 2,
                .base_baud      = 115200,
        },
+       [pbn_fintek_4] = {
+               .num_ports      = 4,
+               .uart_offset    = 8,
+               .base_baud      = 115200,
+               .first_offset   = 0x40,
+       },
+       [pbn_fintek_8] = {
+               .num_ports      = 8,
+               .uart_offset    = 8,
+               .base_baud      = 115200,
+               .first_offset   = 0x40,
+       },
+       [pbn_fintek_12] = {
+               .num_ports      = 12,
+               .uart_offset    = 8,
+               .base_baud      = 115200,
+               .first_offset   = 0x40,
+       },
 };
 
 static const struct pci_device_id blacklist[] = {
@@ -3362,14 +3650,15 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
                if (quirk->setup(priv, board, &uart, i))
                        break;
 
-#ifdef SERIAL_DEBUG_PCI
-               printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
-                      uart.port.iobase, uart.port.irq, uart.port.iotype);
-#endif
+               dev_dbg(&dev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
+                       uart.port.iobase, uart.port.irq, uart.port.iotype);
 
                priv->line[i] = serial8250_register_8250_port(&uart);
                if (priv->line[i] < 0) {
-                       printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
+                       dev_err(&dev->dev,
+                               "Couldn't register serial port %lx, irq %d, type %d, error %d\n",
+                               uart.port.iobase, uart.port.irq,
+                               uart.port.iotype, priv->line[i]);
                        break;
                }
        }
@@ -3462,7 +3751,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
        }
 
        if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
-               printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
+               dev_err(&dev->dev, "invalid driver_data: %ld\n",
                        ent->driver_data);
                return -EINVAL;
        }
@@ -3520,8 +3809,6 @@ static void pciserial_remove_one(struct pci_dev *dev)
 {
        struct serial_private *priv = pci_get_drvdata(dev);
 
-       pci_set_drvdata(dev, NULL);
-
        pciserial_remove_ports(priv);
 
        pci_disable_device(dev);
@@ -3555,7 +3842,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
                err = pci_enable_device(dev);
                /* FIXME: We cannot simply error out here */
                if (err)
-                       printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n");
+                       dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n");
                pciserial_resume_ports(priv);
        }
        return 0;
@@ -4848,6 +5135,15 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
                PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
                pbn_ce4100_1_115200 },
+       /* Intel BayTrail */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART1,
+               PCI_ANY_ID,  PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+               pbn_byt },
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART2,
+               PCI_ANY_ID,  PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+               pbn_byt },
 
        /*
         * Cronyx Omega PCI
@@ -4918,6 +5214,11 @@ static struct pci_device_id serial_pci_tbl[] = {
                0,
                0, pbn_exar_XR17V358 },
 
+       /* Fintek PCI serial cards */
+       { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 },
+       { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 },
+       { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 },
+
        /*
         * These entries match devices with class COMMUNICATION_SERIAL,
         * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
index febd45cd50273532e99c1a4d790d2690c6ae750d..a3817ab8602fe050e5cf2bf90a79102e73a49dbb 100644 (file)
@@ -709,7 +709,7 @@ config SERIAL_IP22_ZILOG_CONSOLE
 
 config SERIAL_SH_SCI
        tristate "SuperH SCI(F) serial port support"
-       depends on HAVE_CLK && (SUPERH || ARCH_SHMOBILE)
+       depends on HAVE_CLK && (SUPERH || ARM || COMPILE_TEST)
        select SERIAL_CORE
 
 config SERIAL_SH_SCI_NR_UARTS
@@ -1512,6 +1512,7 @@ config SERIAL_FSL_LPUART_CONSOLE
 config SERIAL_ST_ASC
        tristate "ST ASC serial port support"
        select SERIAL_CORE
+       depends on ARM || COMPILE_TEST
        help
          This driver is for the on-chip Asychronous Serial Controller on
          STMicroelectronics STi SoCs.
index 8b90f0b6dfdfe7838c43863350d93f9fccc41dae..33bd8606be6272d93f82e8aa6279cc00f6da87f0 100644 (file)
@@ -728,7 +728,6 @@ static int pl010_probe(struct amba_device *dev, const struct amba_id *id)
        amba_set_drvdata(dev, uap);
        ret = uart_add_one_port(&amba_reg, &uap->port);
        if (ret) {
-               amba_set_drvdata(dev, NULL);
                amba_ports[i] = NULL;
                clk_put(uap->clk);
  unmap:
@@ -745,8 +744,6 @@ static int pl010_remove(struct amba_device *dev)
        struct uart_amba_port *uap = amba_get_drvdata(dev);
        int i;
 
-       amba_set_drvdata(dev, NULL);
-
        uart_remove_one_port(&amba_reg, &uap->port);
 
        for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
index aaa22867e656dc60a65e4249ff231b76fb907c83..7203864992a523509ee0f0f42f47c36714a886aa 100644 (file)
@@ -2147,7 +2147,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
        amba_set_drvdata(dev, uap);
        ret = uart_add_one_port(&amba_reg, &uap->port);
        if (ret) {
-               amba_set_drvdata(dev, NULL);
                amba_ports[i] = NULL;
                pl011_dma_remove(uap);
        }
@@ -2160,8 +2159,6 @@ static int pl011_remove(struct amba_device *dev)
        struct uart_amba_port *uap = amba_get_drvdata(dev);
        int i;
 
-       amba_set_drvdata(dev, NULL);
-
        uart_remove_one_port(&amba_reg, &uap->port);
 
        for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
index 569872f4c9b848fea0f81eab72dd29865b0ded41..c9f5c9dcc15c48e7a15171db06f957bfe7fc6bfd 100644 (file)
@@ -533,7 +533,7 @@ arc_uart_init_one(struct platform_device *pdev, int dev_id)
        unsigned long *plat_data;
        struct arc_uart_port *uart = &arc_uart_ports[dev_id];
 
-       plat_data = (unsigned long *)dev_get_platdata(&pdev->dev);
+       plat_data = dev_get_platdata(&pdev->dev);
        if (!plat_data)
                return -ENODEV;
 
index 6b0f75eac8a26de2c6a3a83eac061ae7a03295cd..c7d99af46a966f1fdc9b9ebf0359756180e90b20 100644 (file)
@@ -99,6 +99,7 @@ static void atmel_stop_rx(struct uart_port *port);
 #define UART_PUT_RTOR(port,v)  __raw_writel(v, (port)->membase + ATMEL_US_RTOR)
 #define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR)
 #define UART_GET_IP_NAME(port) __raw_readl((port)->membase + ATMEL_US_NAME)
+#define UART_GET_IP_VERSION(port) __raw_readl((port)->membase + ATMEL_US_VERSION)
 
  /* PDC registers */
 #define UART_PUT_PTCR(port,v)  __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
@@ -1503,6 +1504,7 @@ static void atmel_get_ip_name(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
        int name = UART_GET_IP_NAME(port);
+       u32 version;
        int usart, uart;
        /* usart and uart ascii */
        usart = 0x55534152;
@@ -1517,7 +1519,22 @@ static void atmel_get_ip_name(struct uart_port *port)
                dev_dbg(port->dev, "This is uart\n");
                atmel_port->is_usart = false;
        } else {
-               dev_err(port->dev, "Not supported ip name, set to uart\n");
+               /* fallback for older SoCs: use version field */
+               version = UART_GET_IP_VERSION(port);
+               switch (version) {
+               case 0x302:
+               case 0x10213:
+                       dev_dbg(port->dev, "This version is usart\n");
+                       atmel_port->is_usart = true;
+                       break;
+               case 0x203:
+               case 0x10202:
+                       dev_dbg(port->dev, "This version is uart\n");
+                       atmel_port->is_usart = false;
+                       break;
+               default:
+                       dev_err(port->dev, "Not supported ip name nor version, set to uart\n");
+               }
        }
 }
 
index 87636cc61a2130db719a4e8d92a277cf2cb52cd3..4f229703328b6e2be09e0cfb111e8e81f8be1c79 100644 (file)
@@ -766,9 +766,8 @@ static int sport_uart_probe(struct platform_device *pdev)
                        return -ENOMEM;
                }
 
-               ret = peripheral_request_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev),
-                       DRV_NAME);
+               ret = peripheral_request_list(dev_get_platdata(&pdev->dev),
+                                               DRV_NAME);
                if (ret) {
                        dev_err(&pdev->dev,
                                "Fail to request SPORT peripherals\n");
@@ -844,8 +843,7 @@ static int sport_uart_probe(struct platform_device *pdev)
 out_error_unmap:
                iounmap(sport->port.membase);
 out_error_free_peripherals:
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
 out_error_free_mem:
                kfree(sport);
                bfin_sport_uart_ports[pdev->id] = NULL;
@@ -864,8 +862,7 @@ static int sport_uart_remove(struct platform_device *pdev)
        if (sport) {
                uart_remove_one_port(&sport_uart_reg, &sport->port);
                iounmap(sport->port.membase);
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
                kfree(sport);
                bfin_sport_uart_ports[pdev->id] = NULL;
        }
index 3c75e8e0402831dc5a94dda760a2b31a9c7fd7da..869ceba2ec57b54f54a2d0a5693640e72e8125bf 100644 (file)
@@ -680,7 +680,7 @@ static int bfin_serial_startup(struct uart_port *port)
                default:
                        uart_dma_ch_rx = uart_dma_ch_tx = 0;
                        break;
-               };
+               }
 
                if (uart_dma_ch_rx &&
                        request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) {
@@ -726,7 +726,7 @@ static int bfin_serial_startup(struct uart_port *port)
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
        if (uart->cts_pin >= 0) {
                if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int,
-                       IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
+                       0, "BFIN_UART_MODEM_STATUS", uart)) {
                        uart->cts_pin = -1;
                        dev_info(port->dev, "Unable to attach BlackFin UART Modem Status interrupt.\n");
                }
@@ -765,7 +765,7 @@ static void bfin_serial_shutdown(struct uart_port *port)
                break;
        default:
                break;
-       };
+       }
 #endif
        free_irq(uart->rx_irq, uart);
        free_irq(uart->tx_irq, uart);
@@ -1240,7 +1240,7 @@ static int bfin_serial_probe(struct platform_device *pdev)
                         */
 #endif
                ret = peripheral_request_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev),
+                       dev_get_platdata(&pdev->dev),
                        DRIVER_NAME);
                if (ret) {
                        dev_err(&pdev->dev,
@@ -1358,8 +1358,7 @@ static int bfin_serial_probe(struct platform_device *pdev)
 out_error_unmap:
                iounmap(uart->port.membase);
 out_error_free_peripherals:
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
 out_error_free_mem:
                kfree(uart);
                bfin_serial_ports[pdev->id] = NULL;
@@ -1377,8 +1376,7 @@ static int bfin_serial_remove(struct platform_device *pdev)
        if (uart) {
                uart_remove_one_port(&bfin_serial_reg, &uart->port);
                iounmap(uart->port.membase);
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
                kfree(uart);
                bfin_serial_ports[pdev->id] = NULL;
        }
@@ -1432,8 +1430,8 @@ static int bfin_earlyprintk_probe(struct platform_device *pdev)
                return -ENOENT;
        }
 
-       ret = peripheral_request_list(
-               (unsigned short *)dev_get_platdata(&pdev->dev), DRIVER_NAME);
+       ret = peripheral_request_list(dev_get_platdata(&pdev->dev),
+                                       DRIVER_NAME);
        if (ret) {
                dev_err(&pdev->dev,
                                "fail to request bfin serial peripherals\n");
@@ -1463,8 +1461,7 @@ static int bfin_earlyprintk_probe(struct platform_device *pdev)
        return 0;
 
 out_error_free_peripherals:
-       peripheral_free_list(
-               (unsigned short *)dev_get_platdata(&pdev->dev));
+       peripheral_free_list(dev_get_platdata(&pdev->dev));
 
        return ret;
 }
index 7e4e4088471cea4cbd6a67c49917b5af2540edc2..8d0b994357c856319b2ffae055d1e605a7a40706 100644 (file)
@@ -459,7 +459,6 @@ static int uart_clps711x_probe(struct platform_device *pdev)
        ret = uart_register_driver(&s->uart);
        if (ret) {
                dev_err(&pdev->dev, "Registering UART driver failed\n");
-               devm_clk_put(&pdev->dev, s->uart_clk);
                return ret;
        }
 
@@ -487,7 +486,6 @@ static int uart_clps711x_remove(struct platform_device *pdev)
        for (i = 0; i < UART_CLPS711X_NR; i++)
                uart_remove_one_port(&s->uart, &s->port[i]);
 
-       devm_clk_put(&pdev->dev, s->uart_clk);
        uart_unregister_driver(&s->uart);
 
        return 0;
index af286e6713eb914ccf30f334b69706a6510b1b97..590390970996b78fb9f274bae440625f433c7a8b 100644 (file)
@@ -1008,7 +1008,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       pl_data = (struct ifx_modem_platform_data *)dev_get_platdata(&spi->dev);
+       pl_data = dev_get_platdata(&spi->dev);
        if (!pl_data) {
                dev_err(&spi->dev, "missing platform data!");
                return -ENODEV;
index 042aa077b5b3e166a8453ac0684da1dd024f6785..b2cfdb661947ec2690fc4840e089688151749a68 100644 (file)
@@ -223,8 +223,7 @@ struct imx_port {
        struct dma_chan         *dma_chan_rx, *dma_chan_tx;
        struct scatterlist      rx_sgl, tx_sgl[2];
        void                    *rx_buf;
-       unsigned int            rx_bytes, tx_bytes;
-       struct work_struct      tsk_dma_rx, tsk_dma_tx;
+       unsigned int            tx_bytes;
        unsigned int            dma_tx_nents;
        wait_queue_head_t       dma_wait;
 };
@@ -505,34 +504,25 @@ static void dma_tx_callback(void *data)
                dev_dbg(sport->port.dev, "exit in %s.\n", __func__);
                return;
        }
-
-       schedule_work(&sport->tsk_dma_tx);
 }
 
-static void dma_tx_work(struct work_struct *w)
+static void imx_dma_tx(struct imx_port *sport)
 {
-       struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_tx);
        struct circ_buf *xmit = &sport->port.state->xmit;
        struct scatterlist *sgl = sport->tx_sgl;
        struct dma_async_tx_descriptor *desc;
        struct dma_chan *chan = sport->dma_chan_tx;
        struct device *dev = sport->port.dev;
        enum dma_status status;
-       unsigned long flags;
        int ret;
 
-       status = chan->device->device_tx_status(chan, (dma_cookie_t)0, NULL);
+       status = dmaengine_tx_status(chan, (dma_cookie_t)0, NULL);
        if (DMA_IN_PROGRESS == status)
                return;
 
-       spin_lock_irqsave(&sport->port.lock, flags);
        sport->tx_bytes = uart_circ_chars_pending(xmit);
-       if (sport->tx_bytes == 0) {
-               spin_unlock_irqrestore(&sport->port.lock, flags);
-               return;
-       }
 
-       if (xmit->tail > xmit->head) {
+       if (xmit->tail > xmit->head && xmit->head > 0) {
                sport->dma_tx_nents = 2;
                sg_init_table(sgl, 2);
                sg_set_buf(sgl, xmit->buf + xmit->tail,
@@ -542,7 +532,6 @@ static void dma_tx_work(struct work_struct *w)
                sport->dma_tx_nents = 1;
                sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
        }
-       spin_unlock_irqrestore(&sport->port.lock, flags);
 
        ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
        if (ret == 0) {
@@ -609,11 +598,7 @@ static void imx_start_tx(struct uart_port *port)
        }
 
        if (sport->dma_is_enabled) {
-               /*
-                * We may in the interrupt context, so arise a work_struct to
-                * do the real job.
-                */
-               schedule_work(&sport->tsk_dma_tx);
+               imx_dma_tx(sport);
                return;
        }
 
@@ -732,6 +717,7 @@ out:
        return IRQ_HANDLED;
 }
 
+static int start_rx_dma(struct imx_port *sport);
 /*
  * If the RXFIFO is filled with some data, and then we
  * arise a DMA operation to receive them.
@@ -750,7 +736,7 @@ static void imx_dma_rxint(struct imx_port *sport)
                writel(temp, sport->port.membase + UCR1);
 
                /* tell the DMA to receive the data. */
-               schedule_work(&sport->tsk_dma_rx);
+               start_rx_dma(sport);
        }
 }
 
@@ -795,8 +781,15 @@ static irqreturn_t imx_int(int irq, void *dev_id)
 static unsigned int imx_tx_empty(struct uart_port *port)
 {
        struct imx_port *sport = (struct imx_port *)port;
+       unsigned int ret;
+
+       ret = (readl(sport->port.membase + USR2) & USR2_TXDC) ?  TIOCSER_TEMT : 0;
 
-       return (readl(sport->port.membase + USR2) & USR2_TXDC) ?  TIOCSER_TEMT : 0;
+       /* If the TX DMA is working, return 0. */
+       if (sport->dma_is_enabled && sport->dma_is_txing)
+               ret = 0;
+
+       return ret;
 }
 
 /*
@@ -865,22 +858,6 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
 }
 
 #define RX_BUF_SIZE    (PAGE_SIZE)
-static int start_rx_dma(struct imx_port *sport);
-static void dma_rx_work(struct work_struct *w)
-{
-       struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_rx);
-       struct tty_port *port = &sport->port.state->port;
-
-       if (sport->rx_bytes) {
-               tty_insert_flip_string(port, sport->rx_buf, sport->rx_bytes);
-               tty_flip_buffer_push(port);
-               sport->rx_bytes = 0;
-       }
-
-       if (sport->dma_is_rxing)
-               start_rx_dma(sport);
-}
-
 static void imx_rx_dma_done(struct imx_port *sport)
 {
        unsigned long temp;
@@ -912,6 +889,7 @@ static void dma_rx_callback(void *data)
        struct imx_port *sport = data;
        struct dma_chan *chan = sport->dma_chan_rx;
        struct scatterlist *sgl = &sport->rx_sgl;
+       struct tty_port *port = &sport->port.state->port;
        struct dma_tx_state state;
        enum dma_status status;
        unsigned int count;
@@ -919,13 +897,15 @@ static void dma_rx_callback(void *data)
        /* unmap it first */
        dma_unmap_sg(sport->port.dev, sgl, 1, DMA_FROM_DEVICE);
 
-       status = chan->device->device_tx_status(chan, (dma_cookie_t)0, &state);
+       status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
        count = RX_BUF_SIZE - state.residue;
        dev_dbg(sport->port.dev, "We get %d bytes.\n", count);
 
        if (count) {
-               sport->rx_bytes = count;
-               schedule_work(&sport->tsk_dma_rx);
+               tty_insert_flip_string(port, sport->rx_buf, count);
+               tty_flip_buffer_push(port);
+
+               start_rx_dma(sport);
        } else
                imx_rx_dma_done(sport);
 }
@@ -1007,7 +987,6 @@ static int imx_uart_dma_init(struct imx_port *sport)
                ret = -ENOMEM;
                goto err;
        }
-       sport->rx_bytes = 0;
 
        /* Prepare for TX : */
        sport->dma_chan_tx = dma_request_slave_channel(dev, "tx");
@@ -1038,11 +1017,7 @@ err:
 static void imx_enable_dma(struct imx_port *sport)
 {
        unsigned long temp;
-       struct tty_port *port = &sport->port.state->port;
 
-       port->low_latency = 1;
-       INIT_WORK(&sport->tsk_dma_tx, dma_tx_work);
-       INIT_WORK(&sport->tsk_dma_rx, dma_rx_work);
        init_waitqueue_head(&sport->dma_wait);
 
        /* set UCR1 */
@@ -1063,7 +1038,6 @@ static void imx_enable_dma(struct imx_port *sport)
 static void imx_disable_dma(struct imx_port *sport)
 {
        unsigned long temp;
-       struct tty_port *port = &sport->port.state->port;
 
        /* clear UCR1 */
        temp = readl(sport->port.membase + UCR1);
@@ -1081,7 +1055,6 @@ static void imx_disable_dma(struct imx_port *sport)
        writel(temp, sport->port.membase + UCR4);
 
        sport->dma_is_enabled = 0;
-       port->low_latency = 0;
 }
 
 /* half the RX buffer size */
@@ -1303,6 +1276,16 @@ static void imx_shutdown(struct uart_port *port)
        clk_disable_unprepare(sport->clk_ipg);
 }
 
+static void imx_flush_buffer(struct uart_port *port)
+{
+       struct imx_port *sport = (struct imx_port *)port;
+
+       if (sport->dma_is_enabled) {
+               sport->tx_bytes = 0;
+               dmaengine_terminate_all(sport->dma_chan_tx);
+       }
+}
+
 static void
 imx_set_termios(struct uart_port *port, struct ktermios *termios,
                   struct ktermios *old)
@@ -1539,7 +1522,7 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
                ret = -EINVAL;
        if (sport->port.uartclk / 16 != ser->baud_base)
                ret = -EINVAL;
-       if ((void *)sport->port.mapbase != ser->iomem_base)
+       if (sport->port.mapbase != (unsigned long)ser->iomem_base)
                ret = -EINVAL;
        if (sport->port.iobase != ser->port)
                ret = -EINVAL;
@@ -1623,6 +1606,7 @@ static struct uart_ops imx_pops = {
        .break_ctl      = imx_break_ctl,
        .startup        = imx_startup,
        .shutdown       = imx_shutdown,
+       .flush_buffer   = imx_flush_buffer,
        .set_termios    = imx_set_termios,
        .type           = imx_type,
        .release_port   = imx_release_port,
index cb3c81eb09964dd6c20a998df74a787717192dcd..1d9420548e169a312e2f6ecacb44948e560c0869 100644 (file)
@@ -832,7 +832,7 @@ ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
                up->curregs[5] |= Tx8;
                up->parity_mask = 0xff;
                break;
-       };
+       }
        up->curregs[4] &= ~0x0c;
        if (cflag & CSTOPB)
                up->curregs[4] |= SB2;
index b2e707aa603a52daeff7762bf81a7e82397fc831..8d71e4047bb300d0e1a12af83f2263297c4a29bc 100644 (file)
@@ -690,7 +690,7 @@ static void max310x_handle_tx(struct uart_port *port)
                        max310x_port_write(port, MAX310X_THR_REG,
                                           xmit->buf[xmit->tail]);
                        xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               };
+               }
        }
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
index d3db042f649eda154bdbe1e7feb81dc5822f8653..52c930fac210c3888cb253387fe7a6ab49327878 100644 (file)
@@ -293,7 +293,7 @@ static void serial_hsu_enable_ms(struct uart_port *port)
        serial_out(up, UART_IER, up->ier);
 }
 
-void hsu_dma_tx(struct uart_hsu_port *up)
+static void hsu_dma_tx(struct uart_hsu_port *up)
 {
        struct circ_buf *xmit = &up->port.state->xmit;
        struct hsu_dma_buffer *dbuf = &up->txbuf;
@@ -340,7 +340,8 @@ void hsu_dma_tx(struct uart_hsu_port *up)
 }
 
 /* The buffer is already cache coherent */
-void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf)
+static void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc,
+                                       struct hsu_dma_buffer *dbuf)
 {
        dbuf->ofs = 0;
 
@@ -386,7 +387,8 @@ static void serial_hsu_stop_tx(struct uart_port *port)
 
 /* This is always called in spinlock protected mode, so
  * modify timeout timer is safe here */
-void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts, unsigned long *flags)
+static void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts,
+                       unsigned long *flags)
 {
        struct hsu_dma_buffer *dbuf = &up->rxbuf;
        struct hsu_dma_chan *chan = up->rxc;
@@ -1183,7 +1185,7 @@ static struct console serial_hsu_console = {
 #define SERIAL_HSU_CONSOLE     NULL
 #endif
 
-struct uart_ops serial_hsu_pops = {
+static struct uart_ops serial_hsu_pops = {
        .tx_empty       = serial_hsu_tx_empty,
        .set_mctrl      = serial_hsu_set_mctrl,
        .get_mctrl      = serial_hsu_get_mctrl,
@@ -1451,7 +1453,6 @@ static void serial_hsu_remove(struct pci_dev *pdev)
                uart_remove_one_port(&serial_hsu_reg, &up->port);
        }
 
-       pci_set_drvdata(pdev, NULL);
        free_irq(pdev->irq, priv);
        pci_disable_device(pdev);
 }
@@ -1504,4 +1505,4 @@ module_init(hsu_pci_init);
 module_exit(hsu_pci_exit);
 
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:medfield-hsu");
+MODULE_DEVICE_TABLE(pci, pci_ids);
index 5be1df39f9f5f6b8fe0671bba23ba8f566e685f4..ec06505e3ae63704d73f44ad23252b3de7bc6656 100644 (file)
@@ -1301,7 +1301,6 @@ static struct uart_ops mpc52xx_uart_ops = {
        .shutdown       = mpc52xx_uart_shutdown,
        .set_termios    = mpc52xx_uart_set_termios,
 /*     .pm             = mpc52xx_uart_pm,              Not supported yet */
-/*     .set_wake       = mpc52xx_uart_set_wake,        Not supported yet */
        .type           = mpc52xx_uart_type,
        .release_port   = mpc52xx_uart_release_port,
        .request_port   = mpc52xx_uart_request_port,
@@ -1766,7 +1765,7 @@ mpc52xx_uart_of_remove(struct platform_device *op)
 static int
 mpc52xx_uart_of_suspend(struct platform_device *op, pm_message_t state)
 {
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(op);
+       struct uart_port *port = platform_get_drvdata(op);
 
        if (port)
                uart_suspend_port(&mpc52xx_uart_driver, port);
@@ -1777,7 +1776,7 @@ mpc52xx_uart_of_suspend(struct platform_device *op, pm_message_t state)
 static int
 mpc52xx_uart_of_resume(struct platform_device *op)
 {
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(op);
+       struct uart_port *port = platform_get_drvdata(op);
 
        if (port)
                uart_resume_port(&mpc52xx_uart_driver, port);
index 8d702677acc5911c002134f85236090eeb793d10..e30a3ca3cea39f8b34765401e1fad569265f7ebb 100644 (file)
@@ -2030,7 +2030,7 @@ static void mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
 {
        struct mpsc_pdata       *pdata;
 
-       pdata = (struct mpsc_pdata *)dev_get_platdata(&pd->dev);
+       pdata = dev_get_platdata(&pd->dev);
 
        pi->port.uartclk = pdata->brg_clk_freq;
        pi->port.iotype = UPIO_MEM;
index a67e7081f0018d640ecef090394be1f828ec04c5..db0448ae59dc85557d7a4b2c16903a602c37f2e5 100644 (file)
@@ -43,6 +43,7 @@
 
 #include <linux/kthread.h>
 #include <linux/spi/spi.h>
+#include <linux/pm.h>
 
 #include "mrst_max3110.h"
 
@@ -61,6 +62,7 @@ struct uart_max3110 {
        struct task_struct *main_thread;
        struct task_struct *read_thread;
        struct mutex thread_mutex;
+       struct mutex io_mutex;
 
        u32 baud;
        u16 cur_conf;
@@ -90,6 +92,7 @@ static int max3110_write_then_read(struct uart_max3110 *max,
        struct spi_transfer     x;
        int ret;
 
+       mutex_lock(&max->io_mutex);
        spi_message_init(&message);
        memset(&x, 0, sizeof x);
        x.len = len;
@@ -104,6 +107,7 @@ static int max3110_write_then_read(struct uart_max3110 *max,
 
        /* Do the i/o */
        ret = spi_sync(spi, &message);
+       mutex_unlock(&max->io_mutex);
        return ret;
 }
 
@@ -491,19 +495,9 @@ static int serial_m3110_startup(struct uart_port *port)
        port->state->port.low_latency = 1;
 
        if (max->irq) {
-               max->read_thread = NULL;
-               ret = request_irq(max->irq, serial_m3110_irq,
-                               IRQ_TYPE_EDGE_FALLING, "max3110", max);
-               if (ret) {
-                       max->irq = 0;
-                       pr_err(PR_FMT "unable to allocate IRQ, polling\n");
-               }  else {
-                       /* Enable RX IRQ only */
-                       config |= WC_RXA_IRQ_ENABLE;
-               }
-       }
-
-       if (max->irq == 0) {
+               /* Enable RX IRQ only */
+               config |= WC_RXA_IRQ_ENABLE;
+       } else {
                /* If IRQ is disabled, start a read thread for input data */
                max->read_thread =
                        kthread_run(max3110_read_thread, max, "max3110_read");
@@ -517,8 +511,6 @@ static int serial_m3110_startup(struct uart_port *port)
 
        ret = max3110_out(max, config);
        if (ret) {
-               if (max->irq)
-                       free_irq(max->irq, max);
                if (max->read_thread)
                        kthread_stop(max->read_thread);
                max->read_thread = NULL;
@@ -540,9 +532,6 @@ static void serial_m3110_shutdown(struct uart_port *port)
                max->read_thread = NULL;
        }
 
-       if (max->irq)
-               free_irq(max->irq, max);
-
        /* Disable interrupts from this port */
        config = WC_TAG | WC_SW_SHDI;
        max3110_out(max, config);
@@ -749,7 +738,8 @@ static int serial_m3110_suspend(struct device *dev)
        struct spi_device *spi = to_spi_device(dev);
        struct uart_max3110 *max = spi_get_drvdata(spi);
 
-       disable_irq(max->irq);
+       if (max->irq > 0)
+               disable_irq(max->irq);
        uart_suspend_port(&serial_m3110_reg, &max->port);
        max3110_out(max, max->cur_conf | WC_SW_SHDI);
        return 0;
@@ -762,7 +752,8 @@ static int serial_m3110_resume(struct device *dev)
 
        max3110_out(max, max->cur_conf);
        uart_resume_port(&serial_m3110_reg, &max->port);
-       enable_irq(max->irq);
+       if (max->irq > 0)
+               enable_irq(max->irq);
        return 0;
 }
 
@@ -803,6 +794,7 @@ static int serial_m3110_probe(struct spi_device *spi)
        max->irq = (u16)spi->irq;
 
        mutex_init(&max->thread_mutex);
+       mutex_init(&max->io_mutex);
 
        max->word_7bits = 0;
        max->parity = 0;
@@ -840,6 +832,16 @@ static int serial_m3110_probe(struct spi_device *spi)
                goto err_kthread;
        }
 
+       if (max->irq) {
+               ret = request_irq(max->irq, serial_m3110_irq,
+                               IRQ_TYPE_EDGE_FALLING, "max3110", max);
+               if (ret) {
+                       max->irq = 0;
+                       dev_warn(&spi->dev,
+                       "unable to allocate IRQ, will use polling method\n");
+               }
+       }
+
        spi_set_drvdata(spi, max);
        pmax = max;
 
@@ -867,6 +869,9 @@ static int serial_m3110_remove(struct spi_device *dev)
 
        free_page((unsigned long)max->con_xmit.buf);
 
+       if (max->irq)
+               free_irq(max->irq, max);
+
        if (max->main_thread)
                kthread_stop(max->main_thread);
 
index 10e9d70b5c4066fced345848f592dc11582c1cfb..d8b6fee77a039220ae8d7d8f08a9ff8e08c7066f 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/cacheflush.h>
 
 #define MXS_AUART_PORTS 5
+#define MXS_AUART_FIFO_SIZE            16
 
 #define AUART_CTRL0                    0x00000000
 #define AUART_CTRL0_SET                        0x00000004
@@ -548,6 +549,9 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s)
        s->flags |= MXS_AUART_DMA_ENABLED;
        dev_dbg(s->dev, "enabled the DMA support.");
 
+       /* The DMA buffer is now the FIFO the TTY subsystem can use */
+       s->port.fifosize = UART_XMIT_SIZE;
+
        return 0;
 
 err_out:
@@ -741,6 +745,9 @@ static int mxs_auart_startup(struct uart_port *u)
        writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
                        u->membase + AUART_INTR);
 
+       /* Reset FIFO size (it could have changed if DMA was enabled) */
+       u->fifosize = MXS_AUART_FIFO_SIZE;
+
        /*
         * Enable fifo so all four bytes of a DMA word are written to
         * output (otherwise, only the LSB is written, ie. 1 in 4 bytes)
@@ -1056,7 +1063,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
        s->port.membase = ioremap(r->start, resource_size(r));
        s->port.ops = &mxs_auart_ops;
        s->port.iotype = UPIO_MEM;
-       s->port.fifosize = 16;
+       s->port.fifosize = MXS_AUART_FIFO_SIZE;
        s->port.uartclk = clk_get_rate(s->clk);
        s->port.type = PORT_IMX;
        s->port.dev = s->dev = &pdev->dev;
index 816d1a23f9d0ef725318afbf01448aa587a3371c..fa511ebab67c67efda853be187ca670e20db4679 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/irq.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_data/serial-omap.h>
@@ -134,6 +135,7 @@ struct uart_omap_port {
        struct uart_port        port;
        struct uart_omap_dma    uart_dma;
        struct device           *dev;
+       int                     wakeirq;
 
        unsigned char           ier;
        unsigned char           lcr;
@@ -175,7 +177,7 @@ struct uart_omap_port {
        bool                    is_suspending;
 };
 
-#define to_uart_omap_port(p)   ((container_of((p), struct uart_omap_port, port)))
+#define to_uart_omap_port(p) ((container_of((p), struct uart_omap_port, port)))
 
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
@@ -214,10 +216,23 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up)
        return pdata->get_context_loss_count(up->dev);
 }
 
+static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up,
+                                      bool enable)
+{
+       if (!up->wakeirq)
+               return;
+
+       if (enable)
+               enable_irq(up->wakeirq);
+       else
+               disable_irq(up->wakeirq);
+}
+
 static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
 {
        struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
 
+       serial_omap_enable_wakeirq(up, enable);
        if (!pdata || !pdata->enable_wakeup)
                return;
 
@@ -242,12 +257,12 @@ serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud)
        unsigned int n16 = port->uartclk / (16 * baud);
        int baudAbsDiff13 = baud - (port->uartclk / (13 * n13));
        int baudAbsDiff16 = baud - (port->uartclk / (16 * n16));
-       if(baudAbsDiff13 < 0)
+       if (baudAbsDiff13 < 0)
                baudAbsDiff13 = -baudAbsDiff13;
-       if(baudAbsDiff16 < 0)
+       if (baudAbsDiff16 < 0)
                baudAbsDiff16 = -baudAbsDiff16;
 
-       return (baudAbsDiff13 > baudAbsDiff16);
+       return (baudAbsDiff13 >= baudAbsDiff16);
 }
 
 /*
@@ -258,13 +273,13 @@ serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud)
 static unsigned int
 serial_omap_get_divisor(struct uart_port *port, unsigned int baud)
 {
-       unsigned int divisor;
+       unsigned int mode;
 
        if (!serial_omap_baud_is_mode16(port, baud))
-               divisor = 13;
+               mode = 13;
        else
-               divisor = 16;
-       return port->uartclk/(baud * divisor);
+               mode = 16;
+       return port->uartclk/(mode * baud);
 }
 
 static void serial_omap_enable_ms(struct uart_port *port)
@@ -283,28 +298,40 @@ static void serial_omap_enable_ms(struct uart_port *port)
 static void serial_omap_stop_tx(struct uart_port *port)
 {
        struct uart_omap_port *up = to_uart_omap_port(port);
-       struct circ_buf *xmit = &up->port.state->xmit;
        int res;
 
        pm_runtime_get_sync(up->dev);
 
-       /* handle rs485 */
+       /* Handle RS-485 */
        if (up->rs485.flags & SER_RS485_ENABLED) {
-               /* do nothing if current tx not yet completed */
-               res = serial_in(up, UART_LSR) & UART_LSR_TEMT;
-               if (!res)
-                       return;
-
-               /* if there's no more data to send, turn off rts */
-               if (uart_circ_empty(xmit)) {
-                       /* if rts not already disabled */
+               if (up->scr & OMAP_UART_SCR_TX_EMPTY) {
+                       /* THR interrupt is fired when both TX FIFO and TX
+                        * shift register are empty. This means there's nothing
+                        * left to transmit now, so make sure the THR interrupt
+                        * is fired when TX FIFO is below the trigger level,
+                        * disable THR interrupts and toggle the RS-485 GPIO
+                        * data direction pin if needed.
+                        */
+                       up->scr &= ~OMAP_UART_SCR_TX_EMPTY;
+                       serial_out(up, UART_OMAP_SCR, up->scr);
                        res = (up->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? 1 : 0;
                        if (gpio_get_value(up->rts_gpio) != res) {
-                               if (up->rs485.delay_rts_after_send > 0) {
+                               if (up->rs485.delay_rts_after_send > 0)
                                        mdelay(up->rs485.delay_rts_after_send);
-                               }
                                gpio_set_value(up->rts_gpio, res);
                        }
+               } else {
+                       /* We're asked to stop, but there's still stuff in the
+                        * UART FIFO, so make sure the THR interrupt is fired
+                        * when both TX FIFO and TX shift register are empty.
+                        * The next THR interrupt (if no transmission is started
+                        * in the meantime) will indicate the end of a
+                        * transmission. Therefore we _don't_ disable THR
+                        * interrupts in this situation.
+                        */
+                       up->scr |= OMAP_UART_SCR_TX_EMPTY;
+                       serial_out(up, UART_OMAP_SCR, up->scr);
+                       return;
                }
        }
 
@@ -384,15 +411,18 @@ static void serial_omap_start_tx(struct uart_port *port)
 
        pm_runtime_get_sync(up->dev);
 
-       /* handle rs485 */
+       /* Handle RS-485 */
        if (up->rs485.flags & SER_RS485_ENABLED) {
+               /* Fire THR interrupts when FIFO is below trigger level */
+               up->scr &= ~OMAP_UART_SCR_TX_EMPTY;
+               serial_out(up, UART_OMAP_SCR, up->scr);
+
                /* if rts not already enabled */
                res = (up->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0;
                if (gpio_get_value(up->rts_gpio) != res) {
                        gpio_set_value(up->rts_gpio, res);
-                       if (up->rs485.delay_rts_before_send > 0) {
+                       if (up->rs485.delay_rts_before_send > 0)
                                mdelay(up->rs485.delay_rts_before_send);
-                       }
                }
        }
 
@@ -699,6 +729,20 @@ static int serial_omap_startup(struct uart_port *port)
        if (retval)
                return retval;
 
+       /* Optional wake-up IRQ */
+       if (up->wakeirq) {
+               retval = request_irq(up->wakeirq, serial_omap_irq,
+                                    up->port.irqflags, up->name, up);
+               if (retval) {
+                       free_irq(up->port.irq, up);
+                       return retval;
+               }
+               disable_irq(up->wakeirq);
+       } else {
+               dev_info(up->port.dev, "no wakeirq for uart%d\n",
+                        up->port.line);
+       }
+
        dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line);
 
        pm_runtime_get_sync(up->dev);
@@ -787,6 +831,8 @@ static void serial_omap_shutdown(struct uart_port *port)
        pm_runtime_mark_last_busy(up->dev);
        pm_runtime_put_autosuspend(up->dev);
        free_irq(up->port.irq, up);
+       if (up->wakeirq)
+               free_irq(up->wakeirq, up);
 }
 
 static void serial_omap_uart_qos_work(struct work_struct *work)
@@ -938,7 +984,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
         */
 
        /* Set receive FIFO threshold to 16 characters and
-        * transmit FIFO threshold to 16 spaces
+        * transmit FIFO threshold to 32 spaces
         */
        up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK;
        up->fcr &= ~OMAP_UART_FCR_TX_FIFO_TRIG_MASK;
@@ -1060,15 +1106,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line);
 }
 
-static int serial_omap_set_wake(struct uart_port *port, unsigned int state)
-{
-       struct uart_omap_port *up = to_uart_omap_port(port);
-
-       serial_omap_enable_wakeup(up, state);
-
-       return 0;
-}
-
 static void
 serial_omap_pm(struct uart_port *port, unsigned int state,
               unsigned int oldstate)
@@ -1353,6 +1390,15 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
        up->ier = mode;
        serial_out(up, UART_IER, up->ier);
 
+       /* If RS-485 is disabled, make sure the THR interrupt is fired when
+        * TX FIFO is below the trigger level.
+        */
+       if (!(up->rs485.flags & SER_RS485_ENABLED) &&
+           (up->scr & OMAP_UART_SCR_TX_EMPTY)) {
+               up->scr &= ~OMAP_UART_SCR_TX_EMPTY;
+               serial_out(up, UART_OMAP_SCR, up->scr);
+       }
+
        spin_unlock_irqrestore(&up->port.lock, flags);
        pm_runtime_mark_last_busy(up->dev);
        pm_runtime_put_autosuspend(up->dev);
@@ -1401,7 +1447,6 @@ static struct uart_ops serial_omap_pops = {
        .shutdown       = serial_omap_shutdown,
        .set_termios    = serial_omap_set_termios,
        .pm             = serial_omap_pm,
-       .set_wake       = serial_omap_set_wake,
        .type           = serial_omap_type,
        .release_port   = serial_omap_release_port,
        .request_port   = serial_omap_request_port,
@@ -1582,11 +1627,23 @@ static int serial_omap_probe(struct platform_device *pdev)
        struct uart_omap_port   *up;
        struct resource         *mem, *irq;
        struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev);
-       int ret;
+       int ret, uartirq = 0, wakeirq = 0;
 
+       /* The optional wakeirq may be specified in the board dts file */
        if (pdev->dev.of_node) {
+               uartirq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+               if (!uartirq)
+                       return -EPROBE_DEFER;
+               wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1);
                omap_up_info = of_get_uart_port_info(&pdev->dev);
                pdev->dev.platform_data = omap_up_info;
+       } else {
+               irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+               if (!irq) {
+                       dev_err(&pdev->dev, "no irq resource?\n");
+                       return -ENODEV;
+               }
+               uartirq = irq->start;
        }
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1595,12 +1652,6 @@ static int serial_omap_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!irq) {
-               dev_err(&pdev->dev, "no irq resource?\n");
-               return -ENODEV;
-       }
-
        if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
                                pdev->dev.driver->name)) {
                dev_err(&pdev->dev, "memory region already claimed\n");
@@ -1634,7 +1685,8 @@ static int serial_omap_probe(struct platform_device *pdev)
        up->port.dev = &pdev->dev;
        up->port.type = PORT_OMAP;
        up->port.iotype = UPIO_MEM;
-       up->port.irq = irq->start;
+       up->port.irq = uartirq;
+       up->wakeirq = wakeirq;
 
        up->port.regshift = 2;
        up->port.fifosize = 64;
@@ -1670,8 +1722,9 @@ static int serial_omap_probe(struct platform_device *pdev)
        up->port.uartclk = omap_up_info->uartclk;
        if (!up->port.uartclk) {
                up->port.uartclk = DEFAULT_CLK_SPEED;
-               dev_warn(&pdev->dev, "No clock speed specified: using default:"
-                                               "%d\n", DEFAULT_CLK_SPEED);
+               dev_warn(&pdev->dev,
+                        "No clock speed specified: using default: %d\n",
+                        DEFAULT_CLK_SPEED);
        }
 
        up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
index 44077c0b7670075625650c9d00cc98a63bb90f5c..0aa2b528ef3d76363c3cd9dcc4ebd96adee850a8 100644 (file)
@@ -1614,7 +1614,6 @@ static struct uart_ops pch_uart_ops = {
        .shutdown = pch_uart_shutdown,
        .set_termios = pch_uart_set_termios,
 /*     .pm             = pch_uart_pm,          Not supported yet */
-/*     .set_wake       = pch_uart_set_wake,    Not supported yet */
        .type = pch_uart_type,
        .release_port = pch_uart_release_port,
        .request_port = pch_uart_request_port,
@@ -1996,6 +1995,8 @@ module_exit(pch_uart_module_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Intel EG20T PCH UART PCI Driver");
+MODULE_DEVICE_TABLE(pci, pch_uart_pci_id);
+
 module_param(default_baud, uint, S_IRUGO);
 MODULE_PARM_DESC(default_baud,
                  "Default BAUD for initial driver state and console (default 9600)");
index f87f1a0c8c6ee577860e37e7a95038e61776e1cb..95917cefe14f53e3a03bf099844d8351647cce31 100644 (file)
@@ -1072,7 +1072,7 @@ static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag,
                uap->curregs[5] |= Tx8;
                uap->parity_mask = 0xff;
                break;
-       };
+       }
        uap->curregs[4] &= ~(SB_MASK);
        if (cflag & CSTOPB)
                uap->curregs[4] |= SB2;
index ba25722a7131ba11246c88a26a800fa7493b69bb..753d4525b36743ab23aaeed37c0205b39fb21788 100644 (file)
@@ -647,7 +647,10 @@ void sa1100_register_uart_fns(struct sa1100_port_fns *fns)
                sa1100_pops.set_mctrl = fns->set_mctrl;
 
        sa1100_pops.pm       = fns->pm;
-       sa1100_pops.set_wake = fns->set_wake;
+       /*
+        * FIXME: fns->set_wake is unused - this should be called from
+        * the suspend() callback if device_may_wakeup(dev)) is set.
+        */
 }
 
 void __init sa1100_register_uart(int idx, int port)
index f3dfa19a1cb86eb4c8dd0b47ea8f23b8bab5f0e8..c1af04d46682657794b4893f3eac571a13acc685 100644 (file)
@@ -407,7 +407,14 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
 
 static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
-       /* todo - possibly remove AFC and do manual CTS */
+       unsigned int umcon = rd_regl(port, S3C2410_UMCON);
+
+       if (mctrl & TIOCM_RTS)
+               umcon |= S3C2410_UMCOM_RTS_LOW;
+       else
+               umcon &= ~S3C2410_UMCOM_RTS_LOW;
+
+       wr_regl(port, S3C2410_UMCON, umcon);
 }
 
 static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
@@ -774,8 +781,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
        if (termios->c_cflag & CSTOPB)
                ulcon |= S3C2410_LCON_STOPB;
 
-       umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;
-
        if (termios->c_cflag & PARENB) {
                if (termios->c_cflag & PARODD)
                        ulcon |= S3C2410_LCON_PODD;
@@ -792,6 +797,15 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
 
        wr_regl(port, S3C2410_ULCON, ulcon);
        wr_regl(port, S3C2410_UBRDIV, quot);
+
+       umcon = rd_regl(port, S3C2410_UMCON);
+       if (termios->c_cflag & CRTSCTS) {
+               umcon |= S3C2410_UMCOM_AFC;
+               /* Disable RTS when RX FIFO contains 63 bytes */
+               umcon &= ~S3C2412_UMCON_AFC_8;
+       } else {
+               umcon &= ~S3C2410_UMCOM_AFC;
+       }
        wr_regl(port, S3C2410_UMCON, umcon);
 
        if (ourport->info->has_divslot)
@@ -1254,7 +1268,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
        ourport->baudclk = ERR_PTR(-EINVAL);
        ourport->info = ourport->drv_data->info;
        ourport->cfg = (dev_get_platdata(&pdev->dev)) ?
-                       (struct s3c2410_uartcfg *)dev_get_platdata(&pdev->dev) :
+                       dev_get_platdata(&pdev->dev) :
                        ourport->drv_data->def_cfg;
 
        ourport->port.fifosize = (ourport->info->fifosize) ?
index aaa617a6c4995e1d978ed88ab33878f232ba8b97..8827e5424cef7d13420114650bdcfa19cad91ea0 100644 (file)
@@ -63,7 +63,7 @@ struct s3c24xx_uart_port {
 
 /* conversion functions */
 
-#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
+#define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
 
 /* register access controls */
 
index 49e9bbfe6cab525454c5b4337b741cbd5fcafcd0..a447f71538ef2c07d77fa92f69247559fa83ebf1 100644 (file)
@@ -986,6 +986,7 @@ static int sccnxp_probe(struct platform_device *pdev)
                return 0;
        }
 
+       uart_unregister_driver(&s->uart);
 err_out:
        if (!IS_ERR(s->regulator))
                return regulator_disable(s->regulator);
index 0489a2bdcdf9a1aff4af5dacd1d7766f9671a523..dfe79ccc4fb3c66f473604c2ac867b181e6e7e00 100644 (file)
@@ -1018,7 +1018,7 @@ static int tegra_uart_startup(struct uart_port *u)
                goto fail_hw_init;
        }
 
-       ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED,
+       ret = request_irq(u->irq, tegra_uart_isr, 0,
                                dev_name(u->dev), tup);
        if (ret < 0) {
                dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq);
index 440a962412da9251c10aa60ee6cf25cf2624474a..90a080b1f9ee13cd78d6647245ee91eb1c710da4 100644 (file)
@@ -1220,8 +1220,6 @@ static void pciserial_txx9_remove_one(struct pci_dev *dev)
 {
        struct uart_txx9_port *up = pci_get_drvdata(dev);
 
-       pci_set_drvdata(dev, NULL);
-
        if (up) {
                serial_txx9_unregister_port(up->port.line);
                pci_disable_device(dev);
index 61c1ad03db5b0159d6b7735838a2a0cb800d7bbd..f186a8fb8887119cd036625a129f515bb57f4210 100644 (file)
@@ -529,7 +529,7 @@ static void sirfsoc_rx_tmo_process_tl(unsigned long param)
        while (sirfport->rx_completed != sirfport->rx_issued) {
                sirfsoc_uart_insert_rx_buf_to_tty(sirfport,
                                        SIRFSOC_RX_DMA_BUF_SIZE);
-               sirfsoc_rx_submit_one_dma_desc(port, sirfport->rx_completed++);
+               sirfport->rx_completed++;
                sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT;
        }
        count = CIRC_CNT(sirfport->rx_dma_items[sirfport->rx_issued].xmit.head,
@@ -706,12 +706,19 @@ static void sirfsoc_uart_rx_dma_complete_tl(unsigned long param)
 {
        struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param;
        struct uart_port *port = &sirfport->port;
+       struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
+       struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
        unsigned long flags;
        spin_lock_irqsave(&sirfport->rx_lock, flags);
        while (sirfport->rx_completed != sirfport->rx_issued) {
                sirfsoc_uart_insert_rx_buf_to_tty(sirfport,
                                        SIRFSOC_RX_DMA_BUF_SIZE);
-               sirfsoc_rx_submit_one_dma_desc(port, sirfport->rx_completed++);
+               if (rd_regl(port, ureg->sirfsoc_int_en_reg) &
+                               uint_en->sirfsoc_rx_timeout_en)
+                       sirfsoc_rx_submit_one_dma_desc(port,
+                                       sirfport->rx_completed++);
+               else
+                       sirfport->rx_completed++;
                sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT;
        }
        spin_unlock_irqrestore(&sirfport->rx_lock, flags);
index fb8d0a0026073f4f6e14b46d56d6be7c834f45b3..b7d679c0881b7ba32567f56a95094a1e4cb98bf1 100644 (file)
@@ -368,15 +368,6 @@ struct sirfsoc_uart_register sirfsoc_uart = {
 #define SIRFSOC_UART_NR                                6
 #define SIRFSOC_PORT_TYPE                      0xa5
 
-/* Baud Rate Calculation */
-#define SIRF_MIN_SAMPLE_DIV                    0xf
-#define SIRF_MAX_SAMPLE_DIV                    0x3f
-#define SIRF_IOCLK_DIV_MAX                     0xffff
-#define SIRF_SAMPLE_DIV_SHIFT                  16
-#define SIRF_IOCLK_DIV_MASK                    0xffff
-#define SIRF_SAMPLE_DIV_MASK                   0x3f0000
-#define SIRF_BAUD_RATE_SUPPORT_NR              18
-
 /* Uart Common Use Macro*/
 #define SIRFSOC_RX_DMA_BUF_SIZE        256
 #define BYTES_TO_ALIGN(dma_addr)       ((unsigned long)(dma_addr) & 0x3)
@@ -453,9 +444,6 @@ struct sirfsoc_uart_port {
        int                             rx_issued;
 };
 
-/* Hardware Flow Control */
-#define SIRFUART_AFC_CTRL_RX_THD       0x70
-
 /* Register Access Control */
 #define portaddr(port, reg)            ((port)->membase + (reg))
 #define rd_regb(port, reg)             (__raw_readb(portaddr(port, reg)))
index 5d6136b2a04a8c488e609696952e5517d5cc412a..380fb5355cb26ae68a472a4e6097c57556d0b8e1 100644 (file)
@@ -894,7 +894,7 @@ static int sunsab_console_setup(struct console *con, char *options)
        case B115200: baud = 115200; break;
        case B230400: baud = 230400; break;
        case B460800: baud = 460800; break;
-       };
+       }
 
        /*
         * Temporary fix.
index 699cc1b5f6aa2c5c39cd89a2bb8ea5b192140015..db79b76f5c8e978e09824b719d585cf470d75d68 100644 (file)
@@ -522,7 +522,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break)
                                serio_interrupt(&up->serio, ch, 0);
 #endif
                                break;
-                       };
+                       }
                }
        } while (serial_in(up, UART_LSR) & UART_LSR_DR);
 }
index 135a1520353260e8f6665538ccce381e3036c562..45a8c6aa583797ba717ec3da79a24929a6eb425f 100644 (file)
@@ -319,7 +319,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
                                serio_interrupt(&up->serio, ch, 0);
 #endif
                        break;
-               };
+               }
        }
 }
 
@@ -897,7 +897,7 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
                up->curregs[R5] |= Tx8;
                up->parity_mask = 0xff;
                break;
-       };
+       }
        up->curregs[R4] &= ~0x0c;
        if (cflag & CSTOPB)
                up->curregs[R4] |= SB2;
@@ -1239,7 +1239,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
        default: case B9600: baud = 9600; break;
        case B19200: baud = 19200; break;
        case B38400: baud = 38400; break;
-       };
+       }
 
        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 
index 88317482b81fce4929dc2556e1b19358c6156017..2fd1e1789811941aea3c2d8de3611e916440e0a7 100644 (file)
@@ -269,7 +269,7 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port)
                        return 1;
 
                bdp++;
-       };
+       }
 }
 
 /*
index 7e4150aa69c65b34c44e526c5633bf456f1abe2f..e46e9f3f19b90d34476b60a2e21aa656fc3c8fae 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Xilinx PS UART driver
  *
- * 2011 (c) Xilinx Inc.
+ * 2011 - 2013 (C) Xilinx Inc.
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General Public
  *
  */
 
+#if defined(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
 #include <linux/platform_device.h>
 #include <linux/serial.h>
+#include <linux/console.h>
 #include <linux/serial_core.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
-#include <linux/console.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #define XUARTPS_MAJOR          0       /* use dynamic node allocation */
 #define XUARTPS_MINOR          0       /* works best with devtmpfs */
 #define XUARTPS_NR_PORTS       2
-#define XUARTPS_FIFO_SIZE      16      /* FIFO size */
+#define XUARTPS_FIFO_SIZE      64      /* FIFO size */
 #define XUARTPS_REGISTER_SPACE 0xFFF
 
 #define xuartps_readl(offset)          ioread32(port->membase + offset)
 #define xuartps_writel(val, offset)    iowrite32(val, port->membase + offset)
 
+/* Rx Trigger level */
+static int rx_trigger_level = 56;
+module_param(rx_trigger_level, uint, S_IRUGO);
+MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
+
+/* Rx Timeout */
+static int rx_timeout = 10;
+module_param(rx_timeout, uint, S_IRUGO);
+MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
+
 /********************************Register Map********************************/
 /** UART
  *
 #define XUARTPS_IXR_RXEMPTY    0x00000002 /* RX FIFO empty interrupt. */
 #define XUARTPS_IXR_MASK       0x00001FFF /* Valid bit mask */
 
+/* Goes in read_status_mask for break detection as the HW doesn't do it*/
+#define XUARTPS_IXR_BRK                0x80000000
+
 /** Channel Status Register
  *
  * The channel status register (CSR) is provided to enable the control logic
 #define XUARTPS_SR_TXFULL      0x00000010 /* TX FIFO full */
 #define XUARTPS_SR_RXTRIG      0x00000001 /* Rx Trigger */
 
+/* baud dividers min/max values */
+#define XUARTPS_BDIV_MIN       4
+#define XUARTPS_BDIV_MAX       255
+#define XUARTPS_CD_MAX         65535
+
 /**
  * struct xuartps - device data
- * @refclk     Reference clock
- * @aperclk    APB clock
+ * @port               Pointer to the UART port
+ * @refclk             Reference clock
+ * @aperclk            APB clock
+ * @baud               Current baud rate
+ * @clk_rate_change_nb Notifier block for clock changes
  */
 struct xuartps {
+       struct uart_port        *port;
        struct clk              *refclk;
        struct clk              *aperclk;
+       unsigned int            baud;
+       struct notifier_block   clk_rate_change_nb;
 };
+#define to_xuartps(_nb) container_of(_nb, struct xuartps, clk_rate_change_nb);
 
 /**
  * xuartps_isr - Interrupt handler
@@ -171,6 +200,23 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
         */
        isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET);
 
+       /*
+        * There is no hardware break detection, so we interpret framing
+        * error with all-zeros data as a break sequence. Most of the time,
+        * there's another non-zero byte at the end of the sequence.
+        */
+
+       if (isrstatus & XUARTPS_IXR_FRAMING) {
+               while (!(xuartps_readl(XUARTPS_SR_OFFSET) &
+                                       XUARTPS_SR_RXEMPTY)) {
+                       if (!xuartps_readl(XUARTPS_FIFO_OFFSET)) {
+                               port->read_status_mask |= XUARTPS_IXR_BRK;
+                               isrstatus &= ~XUARTPS_IXR_FRAMING;
+                       }
+               }
+               xuartps_writel(XUARTPS_IXR_FRAMING, XUARTPS_ISR_OFFSET);
+       }
+
        /* drop byte with parity error if IGNPAR specified */
        if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY)
                isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT);
@@ -184,6 +230,30 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
                while ((xuartps_readl(XUARTPS_SR_OFFSET) &
                        XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) {
                        data = xuartps_readl(XUARTPS_FIFO_OFFSET);
+
+                       /* Non-NULL byte after BREAK is garbage (99%) */
+                       if (data && (port->read_status_mask &
+                                               XUARTPS_IXR_BRK)) {
+                               port->read_status_mask &= ~XUARTPS_IXR_BRK;
+                               port->icount.brk++;
+                               if (uart_handle_break(port))
+                                       continue;
+                       }
+
+                       /*
+                        * uart_handle_sysrq_char() doesn't work if
+                        * spinlocked, for some reason
+                        */
+                        if (port->sysrq) {
+                               spin_unlock(&port->lock);
+                               if (uart_handle_sysrq_char(port,
+                                                       (unsigned char)data)) {
+                                       spin_lock(&port->lock);
+                                       continue;
+                               }
+                               spin_lock(&port->lock);
+                       }
+
                        port->icount.rx++;
 
                        if (isrstatus & XUARTPS_IXR_PARITY) {
@@ -247,63 +317,196 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
 }
 
 /**
- * xuartps_set_baud_rate - Calculate and set the baud rate
- * @port: Handle to the uart port structure
- * @baud: Baud rate to set
- *
+ * xuartps_calc_baud_divs - Calculate baud rate divisors
+ * @clk: UART module input clock
+ * @baud: Desired baud rate
+ * @rbdiv: BDIV value (return value)
+ * @rcd: CD value (return value)
+ * @div8: Value for clk_sel bit in mod (return value)
  * Returns baud rate, requested baud when possible, or actual baud when there
- *     was too much error
- **/
-static unsigned int xuartps_set_baud_rate(struct uart_port *port,
-                                               unsigned int baud)
+ *     was too much error, zero if no valid divisors are found.
+ *
+ * Formula to obtain baud rate is
+ *     baud_tx/rx rate = clk/CD * (BDIV + 1)
+ *     input_clk = (Uart User Defined Clock or Apb Clock)
+ *             depends on UCLKEN in MR Reg
+ *     clk = input_clk or input_clk/8;
+ *             depends on CLKS in MR reg
+ *     CD and BDIV depends on values in
+ *                     baud rate generate register
+ *                     baud rate clock divisor register
+ */
+static unsigned int xuartps_calc_baud_divs(unsigned int clk, unsigned int baud,
+               u32 *rbdiv, u32 *rcd, int *div8)
 {
-       unsigned int sel_clk;
-       unsigned int calc_baud = 0;
-       unsigned int brgr_val, brdiv_val;
+       u32 cd, bdiv;
+       unsigned int calc_baud;
+       unsigned int bestbaud = 0;
        unsigned int bauderror;
+       unsigned int besterror = ~0;
 
-       /* Formula to obtain baud rate is
-        *      baud_tx/rx rate = sel_clk/CD * (BDIV + 1)
-        *      input_clk = (Uart User Defined Clock or Apb Clock)
-        *              depends on UCLKEN in MR Reg
-        *      sel_clk = input_clk or input_clk/8;
-        *              depends on CLKS in MR reg
-        *      CD and BDIV depends on values in
-        *                      baud rate generate register
-        *                      baud rate clock divisor register
-        */
-       sel_clk = port->uartclk;
-       if (xuartps_readl(XUARTPS_MR_OFFSET) & XUARTPS_MR_CLKSEL)
-               sel_clk = sel_clk / 8;
-
-       /* Find the best values for baud generation */
-       for (brdiv_val = 4; brdiv_val < 255; brdiv_val++) {
+       if (baud < clk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX)) {
+               *div8 = 1;
+               clk /= 8;
+       } else {
+               *div8 = 0;
+       }
 
-               brgr_val = sel_clk / (baud * (brdiv_val + 1));
-               if (brgr_val < 2 || brgr_val > 65535)
+       for (bdiv = XUARTPS_BDIV_MIN; bdiv <= XUARTPS_BDIV_MAX; bdiv++) {
+               cd = DIV_ROUND_CLOSEST(clk, baud * (bdiv + 1));
+               if (cd < 1 || cd > XUARTPS_CD_MAX)
                        continue;
 
-               calc_baud = sel_clk / (brgr_val * (brdiv_val + 1));
+               calc_baud = clk / (cd * (bdiv + 1));
 
                if (baud > calc_baud)
                        bauderror = baud - calc_baud;
                else
                        bauderror = calc_baud - baud;
 
-               /* use the values when percent error is acceptable */
-               if (((bauderror * 100) / baud) < 3) {
-                       calc_baud = baud;
-                       break;
+               if (besterror > bauderror) {
+                       *rbdiv = bdiv;
+                       *rcd = cd;
+                       bestbaud = calc_baud;
+                       besterror = bauderror;
                }
        }
+       /* use the values when percent error is acceptable */
+       if (((besterror * 100) / baud) < 3)
+               bestbaud = baud;
+
+       return bestbaud;
+}
 
-       /* Set the values for the new baud rate */
-       xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET);
-       xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET);
+/**
+ * xuartps_set_baud_rate - Calculate and set the baud rate
+ * @port: Handle to the uart port structure
+ * @baud: Baud rate to set
+ * Returns baud rate, requested baud when possible, or actual baud when there
+ *        was too much error, zero if no valid divisors are found.
+ */
+static unsigned int xuartps_set_baud_rate(struct uart_port *port,
+               unsigned int baud)
+{
+       unsigned int calc_baud;
+       u32 cd = 0, bdiv = 0;
+       u32 mreg;
+       int div8;
+       struct xuartps *xuartps = port->private_data;
+
+       calc_baud = xuartps_calc_baud_divs(port->uartclk, baud, &bdiv, &cd,
+                       &div8);
+
+       /* Write new divisors to hardware */
+       mreg = xuartps_readl(XUARTPS_MR_OFFSET);
+       if (div8)
+               mreg |= XUARTPS_MR_CLKSEL;
+       else
+               mreg &= ~XUARTPS_MR_CLKSEL;
+       xuartps_writel(mreg, XUARTPS_MR_OFFSET);
+       xuartps_writel(cd, XUARTPS_BAUDGEN_OFFSET);
+       xuartps_writel(bdiv, XUARTPS_BAUDDIV_OFFSET);
+       xuartps->baud = baud;
 
        return calc_baud;
 }
 
+#ifdef CONFIG_COMMON_CLK
+/**
+ * xuartps_clk_notitifer_cb - Clock notifier callback
+ * @nb:                Notifier block
+ * @event:     Notify event
+ * @data:      Notifier data
+ * Returns NOTIFY_OK on success, NOTIFY_BAD on error.
+ */
+static int xuartps_clk_notifier_cb(struct notifier_block *nb,
+               unsigned long event, void *data)
+{
+       u32 ctrl_reg;
+       struct uart_port *port;
+       int locked = 0;
+       struct clk_notifier_data *ndata = data;
+       unsigned long flags = 0;
+       struct xuartps *xuartps = to_xuartps(nb);
+
+       port = xuartps->port;
+       if (port->suspended)
+               return NOTIFY_OK;
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+       {
+               u32 bdiv;
+               u32 cd;
+               int div8;
+
+               /*
+                * Find out if current baud-rate can be achieved with new clock
+                * frequency.
+                */
+               if (!xuartps_calc_baud_divs(ndata->new_rate, xuartps->baud,
+                                       &bdiv, &cd, &div8))
+                       return NOTIFY_BAD;
+
+               spin_lock_irqsave(&xuartps->port->lock, flags);
+
+               /* Disable the TX and RX to set baud rate */
+               xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+                               (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS),
+                               XUARTPS_CR_OFFSET);
+
+               spin_unlock_irqrestore(&xuartps->port->lock, flags);
+
+               return NOTIFY_OK;
+       }
+       case POST_RATE_CHANGE:
+               /*
+                * Set clk dividers to generate correct baud with new clock
+                * frequency.
+                */
+
+               spin_lock_irqsave(&xuartps->port->lock, flags);
+
+               locked = 1;
+               port->uartclk = ndata->new_rate;
+
+               xuartps->baud = xuartps_set_baud_rate(xuartps->port,
+                               xuartps->baud);
+               /* fall through */
+       case ABORT_RATE_CHANGE:
+               if (!locked)
+                       spin_lock_irqsave(&xuartps->port->lock, flags);
+
+               /* Set TX/RX Reset */
+               xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST),
+                               XUARTPS_CR_OFFSET);
+
+               while (xuartps_readl(XUARTPS_CR_OFFSET) &
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST))
+                       cpu_relax();
+
+               /*
+                * Clear the RX disable and TX disable bits and then set the TX
+                * enable bit and RX enable bit to enable the transmitter and
+                * receiver.
+                */
+               xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
+               ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET);
+               xuartps_writel(
+                       (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) |
+                       (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
+                       XUARTPS_CR_OFFSET);
+
+               spin_unlock_irqrestore(&xuartps->port->lock, flags);
+
+               return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
+#endif
+
 /*----------------------Uart Operations---------------------------*/
 
 /**
@@ -346,7 +549,7 @@ static void xuartps_start_tx(struct uart_port *port)
                port->state->xmit.tail = (port->state->xmit.tail + 1) &
                                        (UART_XMIT_SIZE - 1);
        }
-
+       xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_ISR_OFFSET);
        /* Enable the TX Empty interrupt */
        xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET);
 
@@ -437,7 +640,7 @@ static void xuartps_set_termios(struct uart_port *port,
                                struct ktermios *termios, struct ktermios *old)
 {
        unsigned int cval = 0;
-       unsigned int baud;
+       unsigned int baud, minbaud, maxbaud;
        unsigned long flags;
        unsigned int ctrl_reg, mode_reg;
 
@@ -454,8 +657,14 @@ static void xuartps_set_termios(struct uart_port *port,
                        (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS),
                        XUARTPS_CR_OFFSET);
 
-       /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */
-       baud = uart_get_baud_rate(port, termios, old, 0, 10000000);
+       /*
+        * Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk
+        * min and max baud should be calculated here based on port->uartclk.
+        * this way we get a valid baud and can safely call set_baud()
+        */
+       minbaud = port->uartclk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX * 8);
+       maxbaud = port->uartclk / (XUARTPS_BDIV_MIN + 1);
+       baud = uart_get_baud_rate(port, termios, old, minbaud, maxbaud);
        baud = xuartps_set_baud_rate(port, baud);
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);
@@ -480,7 +689,7 @@ static void xuartps_set_termios(struct uart_port *port,
                        | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
                        XUARTPS_CR_OFFSET);
 
-       xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
+       xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
 
        port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG |
                        XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT;
@@ -531,13 +740,17 @@ static void xuartps_set_termios(struct uart_port *port,
                                cval |= XUARTPS_MR_PARITY_MARK;
                        else
                                cval |= XUARTPS_MR_PARITY_SPACE;
-               } else if (termios->c_cflag & PARODD)
+               } else {
+                       if (termios->c_cflag & PARODD)
                                cval |= XUARTPS_MR_PARITY_ODD;
                        else
                                cval |= XUARTPS_MR_PARITY_EVEN;
-       } else
+               }
+       } else {
                cval |= XUARTPS_MR_PARITY_NONE;
-       xuartps_writel(cval , XUARTPS_MR_OFFSET);
+       }
+       cval |= mode_reg & 1;
+       xuartps_writel(cval, XUARTPS_MR_OFFSET);
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
@@ -583,11 +796,17 @@ static int xuartps_startup(struct uart_port *port)
                | XUARTPS_MR_PARITY_NONE | XUARTPS_MR_CHARLEN_8_BIT,
                 XUARTPS_MR_OFFSET);
 
-       /* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */
-       xuartps_writel(14, XUARTPS_RXWM_OFFSET);
+       /*
+        * Set the RX FIFO Trigger level to use most of the FIFO, but it
+        * can be tuned with a module parameter
+        */
+       xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET);
 
-       /* Receive Timeout register is enabled with value of 10 */
-       xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
+       /*
+        * Receive Timeout register is enabled but it
+        * can be tuned with a module parameter
+        */
+       xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
 
        /* Clear out any pending interrupts before enabling them */
        xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET);
@@ -727,6 +946,54 @@ static void xuartps_enable_ms(struct uart_port *port)
        /* N/A */
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int xuartps_poll_get_char(struct uart_port *port)
+{
+       u32 imr;
+       int c;
+
+       /* Disable all interrupts */
+       imr = xuartps_readl(XUARTPS_IMR_OFFSET);
+       xuartps_writel(imr, XUARTPS_IDR_OFFSET);
+
+       /* Check if FIFO is empty */
+       if (xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY)
+               c = NO_POLL_CHAR;
+       else /* Read a character */
+               c = (unsigned char) xuartps_readl(XUARTPS_FIFO_OFFSET);
+
+       /* Enable interrupts */
+       xuartps_writel(imr, XUARTPS_IER_OFFSET);
+
+       return c;
+}
+
+static void xuartps_poll_put_char(struct uart_port *port, unsigned char c)
+{
+       u32 imr;
+
+       /* Disable all interrupts */
+       imr = xuartps_readl(XUARTPS_IMR_OFFSET);
+       xuartps_writel(imr, XUARTPS_IDR_OFFSET);
+
+       /* Wait until FIFO is empty */
+       while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY))
+               cpu_relax();
+
+       /* Write a character */
+       xuartps_writel(c, XUARTPS_FIFO_OFFSET);
+
+       /* Wait until FIFO is empty */
+       while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY))
+               cpu_relax();
+
+       /* Enable interrupts */
+       xuartps_writel(imr, XUARTPS_IER_OFFSET);
+
+       return;
+}
+#endif
+
 /** The UART operations structure
  */
 static struct uart_ops xuartps_ops = {
@@ -759,6 +1026,10 @@ static struct uart_ops xuartps_ops = {
        .config_port    = xuartps_config_port,  /* Configure when driver
                                                 * adds a xuartps port
                                                 */
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char  = xuartps_poll_get_char,
+       .poll_put_char  = xuartps_poll_put_char,
+#endif
 };
 
 static struct uart_port xuartps_port[2];
@@ -837,7 +1108,7 @@ static void xuartps_console_write(struct console *co, const char *s,
 {
        struct uart_port *port = &xuartps_port[co->index];
        unsigned long flags;
-       unsigned int imr;
+       unsigned int imr, ctrl;
        int locked = 1;
 
        if (oops_in_progress)
@@ -849,9 +1120,19 @@ static void xuartps_console_write(struct console *co, const char *s,
        imr = xuartps_readl(XUARTPS_IMR_OFFSET);
        xuartps_writel(imr, XUARTPS_IDR_OFFSET);
 
+       /*
+        * Make sure that the tx part is enabled. Set the TX enable bit and
+        * clear the TX disable bit to enable the transmitter.
+        */
+       ctrl = xuartps_readl(XUARTPS_CR_OFFSET);
+       xuartps_writel((ctrl & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN,
+               XUARTPS_CR_OFFSET);
+
        uart_console_write(port, s, count, xuartps_console_putchar);
        xuartps_console_wait_tx(port);
 
+       xuartps_writel(ctrl, XUARTPS_CR_OFFSET);
+
        /* restore interrupt state, it seems like there may be a h/w bug
         * in that the interrupt enable register should not need to be
         * written based on the data sheet
@@ -933,6 +1214,119 @@ static struct uart_driver xuartps_uart_driver = {
 #endif
 };
 
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xuartps_suspend - suspend event
+ * @device: Pointer to the device structure
+ *
+ * Returns 0
+ */
+static int xuartps_suspend(struct device *device)
+{
+       struct uart_port *port = dev_get_drvdata(device);
+       struct tty_struct *tty;
+       struct device *tty_dev;
+       int may_wake = 0;
+
+       /* Get the tty which could be NULL so don't assume it's valid */
+       tty = tty_port_tty_get(&port->state->port);
+       if (tty) {
+               tty_dev = tty->dev;
+               may_wake = device_may_wakeup(tty_dev);
+               tty_kref_put(tty);
+       }
+
+       /*
+        * Call the API provided in serial_core.c file which handles
+        * the suspend.
+        */
+       uart_suspend_port(&xuartps_uart_driver, port);
+       if (console_suspend_enabled && !may_wake) {
+               struct xuartps *xuartps = port->private_data;
+
+               clk_disable(xuartps->refclk);
+               clk_disable(xuartps->aperclk);
+       } else {
+               unsigned long flags = 0;
+
+               spin_lock_irqsave(&port->lock, flags);
+               /* Empty the receive FIFO 1st before making changes */
+               while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY))
+                       xuartps_readl(XUARTPS_FIFO_OFFSET);
+               /* set RX trigger level to 1 */
+               xuartps_writel(1, XUARTPS_RXWM_OFFSET);
+               /* disable RX timeout interrups */
+               xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IDR_OFFSET);
+               spin_unlock_irqrestore(&port->lock, flags);
+       }
+
+       return 0;
+}
+
+/**
+ * xuartps_resume - Resume after a previous suspend
+ * @device: Pointer to the device structure
+ *
+ * Returns 0
+ */
+static int xuartps_resume(struct device *device)
+{
+       struct uart_port *port = dev_get_drvdata(device);
+       unsigned long flags = 0;
+       u32 ctrl_reg;
+       struct tty_struct *tty;
+       struct device *tty_dev;
+       int may_wake = 0;
+
+       /* Get the tty which could be NULL so don't assume it's valid */
+       tty = tty_port_tty_get(&port->state->port);
+       if (tty) {
+               tty_dev = tty->dev;
+               may_wake = device_may_wakeup(tty_dev);
+               tty_kref_put(tty);
+       }
+
+       if (console_suspend_enabled && !may_wake) {
+               struct xuartps *xuartps = port->private_data;
+
+               clk_enable(xuartps->aperclk);
+               clk_enable(xuartps->refclk);
+
+               spin_lock_irqsave(&port->lock, flags);
+
+               /* Set TX/RX Reset */
+               xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST),
+                               XUARTPS_CR_OFFSET);
+               while (xuartps_readl(XUARTPS_CR_OFFSET) &
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST))
+                       cpu_relax();
+
+               /* restore rx timeout value */
+               xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
+               /* Enable Tx/Rx */
+               ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET);
+               xuartps_writel(
+                       (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) |
+                       (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
+                       XUARTPS_CR_OFFSET);
+
+               spin_unlock_irqrestore(&port->lock, flags);
+       } else {
+               spin_lock_irqsave(&port->lock, flags);
+               /* restore original rx trigger level */
+               xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET);
+               /* enable RX timeout interrupt */
+               xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET);
+               spin_unlock_irqrestore(&port->lock, flags);
+       }
+
+       return uart_resume_port(&xuartps_uart_driver, port);
+}
+#endif /* ! CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(xuartps_dev_pm_ops, xuartps_suspend, xuartps_resume);
+
 /* ---------------------------------------------------------------------
  * Platform bus binding
  */
@@ -949,27 +1343,26 @@ static int xuartps_probe(struct platform_device *pdev)
        struct resource *res, *res2;
        struct xuartps *xuartps_data;
 
-       xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL);
+       xuartps_data = devm_kzalloc(&pdev->dev, sizeof(*xuartps_data),
+                       GFP_KERNEL);
        if (!xuartps_data)
                return -ENOMEM;
 
-       xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk");
+       xuartps_data->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
        if (IS_ERR(xuartps_data->aperclk)) {
                dev_err(&pdev->dev, "aper_clk clock not found.\n");
-               rc = PTR_ERR(xuartps_data->aperclk);
-               goto err_out_free;
+               return PTR_ERR(xuartps_data->aperclk);
        }
-       xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk");
+       xuartps_data->refclk = devm_clk_get(&pdev->dev, "ref_clk");
        if (IS_ERR(xuartps_data->refclk)) {
                dev_err(&pdev->dev, "ref_clk clock not found.\n");
-               rc = PTR_ERR(xuartps_data->refclk);
-               goto err_out_clk_put_aper;
+               return PTR_ERR(xuartps_data->refclk);
        }
 
        rc = clk_prepare_enable(xuartps_data->aperclk);
        if (rc) {
                dev_err(&pdev->dev, "Unable to enable APER clock.\n");
-               goto err_out_clk_put;
+               return rc;
        }
        rc = clk_prepare_enable(xuartps_data->refclk);
        if (rc) {
@@ -989,13 +1382,21 @@ static int xuartps_probe(struct platform_device *pdev)
                goto err_out_clk_disable;
        }
 
+#ifdef CONFIG_COMMON_CLK
+       xuartps_data->clk_rate_change_nb.notifier_call =
+                       xuartps_clk_notifier_cb;
+       if (clk_notifier_register(xuartps_data->refclk,
+                               &xuartps_data->clk_rate_change_nb))
+               dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+#endif
+
        /* Initialize the port structure */
        port = xuartps_get_port();
 
        if (!port) {
                dev_err(&pdev->dev, "Cannot get uart_port structure\n");
                rc = -ENODEV;
-               goto err_out_clk_disable;
+               goto err_out_notif_unreg;
        } else {
                /* Register the port.
                 * This function also registers this device with the tty layer
@@ -1006,26 +1407,26 @@ static int xuartps_probe(struct platform_device *pdev)
                port->dev = &pdev->dev;
                port->uartclk = clk_get_rate(xuartps_data->refclk);
                port->private_data = xuartps_data;
+               xuartps_data->port = port;
                platform_set_drvdata(pdev, port);
                rc = uart_add_one_port(&xuartps_uart_driver, port);
                if (rc) {
                        dev_err(&pdev->dev,
                                "uart_add_one_port() failed; err=%i\n", rc);
-                       goto err_out_clk_disable;
+                       goto err_out_notif_unreg;
                }
                return 0;
        }
 
+err_out_notif_unreg:
+#ifdef CONFIG_COMMON_CLK
+       clk_notifier_unregister(xuartps_data->refclk,
+                       &xuartps_data->clk_rate_change_nb);
+#endif
 err_out_clk_disable:
        clk_disable_unprepare(xuartps_data->refclk);
 err_out_clk_dis_aper:
        clk_disable_unprepare(xuartps_data->aperclk);
-err_out_clk_put:
-       clk_put(xuartps_data->refclk);
-err_out_clk_put_aper:
-       clk_put(xuartps_data->aperclk);
-err_out_free:
-       kfree(xuartps_data);
 
        return rc;
 }
@@ -1043,13 +1444,14 @@ static int xuartps_remove(struct platform_device *pdev)
        int rc;
 
        /* Remove the xuartps port from the serial core */
+#ifdef CONFIG_COMMON_CLK
+       clk_notifier_unregister(xuartps_data->refclk,
+                       &xuartps_data->clk_rate_change_nb);
+#endif
        rc = uart_remove_one_port(&xuartps_uart_driver, port);
        port->mapbase = 0;
        clk_disable_unprepare(xuartps_data->refclk);
        clk_disable_unprepare(xuartps_data->aperclk);
-       clk_put(xuartps_data->refclk);
-       clk_put(xuartps_data->aperclk);
-       kfree(xuartps_data);
        return rc;
 }
 
@@ -1067,6 +1469,7 @@ static struct platform_driver xuartps_platform_driver = {
                .owner = THIS_MODULE,
                .name = XUARTPS_NAME,           /* Driver name */
                .of_match_table = xuartps_of_match,
+               .pm = &xuartps_dev_pm_ops,
                },
 };
 
index 40a9fe9d3b10f0170af31c4d8845d8cc609e6bb5..ce396ecdf41268b5de64a7ac3f820438c3bdfffb 100644 (file)
@@ -51,7 +51,7 @@
 #include <asm/irq_regs.h>
 
 /* Whether we react on sysrq keys or just ignore them */
-static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
+static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
 static bool __read_mostly sysrq_always_enabled;
 
 unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED };
index f597e88a705d1fa8e65cf36ae98a61f84f20b9a3..c94d2349dd0620dd183645ee37ddced4551e9ccd 100644 (file)
@@ -140,6 +140,10 @@ EXPORT_SYMBOL(tty_port_destroy);
 static void tty_port_destructor(struct kref *kref)
 {
        struct tty_port *port = container_of(kref, struct tty_port, kref);
+
+       /* check if last port ref was dropped before tty release */
+       if (WARN_ON(port->itty))
+               return;
        if (port->xmit_buf)
                free_page((unsigned long)port->xmit_buf);
        tty_port_destroy(port);
@@ -480,8 +484,6 @@ int tty_port_close_start(struct tty_port *port,
 
        if (port->count) {
                spin_unlock_irqrestore(&port->lock, flags);
-               if (port->ops->drop)
-                       port->ops->drop(port);
                return 0;
        }
        set_bit(ASYNCB_CLOSING, &port->flags);
@@ -500,9 +502,7 @@ int tty_port_close_start(struct tty_port *port,
        /* Flush the ldisc buffering */
        tty_ldisc_flush(tty);
 
-       /* Don't call port->drop for the last reference. Callers will want
-          to drop the last active reference in ->shutdown() or the tty
-          shutdown path */
+       /* Report to caller this is the last port reference */
        return 1;
 }
 EXPORT_SYMBOL(tty_port_close_start);
index 9a8e8c5a0c73a93420fc71b85637db4d510ae241..61b1137d7e56d877fad8b2339c368cd09a5419e1 100644 (file)
@@ -1300,21 +1300,30 @@ static void csi_m(struct vc_data *vc)
                        case 27:
                                vc->vc_reverse = 0;
                                break;
-                       case 38: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Enables underscore, white foreground
-                                 * with white underscore (Linux - use
-                                 * default foreground).
+                       case 38:
+                       case 48: /* ITU T.416
+                                 * Higher colour modes.
+                                 * They break the usual properties of SGR codes
+                                 * and thus need to be detected and ignored by
+                                 * hand.  Strictly speaking, that standard also
+                                 * wants : rather than ; as separators, contrary
+                                 * to ECMA-48, but no one produces such codes
+                                 * and almost no one accepts them.
                                  */
-                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               vc->vc_underline = 1;
+                               i++;
+                               if (i > vc->vc_npar)
+                                       break;
+                               if (vc->vc_par[i] == 5)      /* 256 colours */
+                                       i++;                 /* ubiquitous */
+                               else if (vc->vc_par[i] == 2) /* 24 bit colours */
+                                       i += 3;              /* extremely rare */
+                               /* Subcommands 3 (CMY) and 4 (CMYK) are so insane
+                                * that detecting them is not worth the few extra
+                                * bytes of kernel's size.
+                                */
                                break;
-                       case 39: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Disable underline option.
-                                 * Reset colour to default? It did this
-                                 * before...
-                                 */
+                       case 39:
                                vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               vc->vc_underline = 0;
                                break;
                        case 49:
                                vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
index 0e808cf91d97e94b6d973ca4c5937a2939206df8..67beb84449304d987c68a544c02b9c6e428dce1a 100644 (file)
@@ -288,13 +288,13 @@ static int uio_dev_add_attributes(struct uio_device *idev)
                }
                map = kzalloc(sizeof(*map), GFP_KERNEL);
                if (!map)
-                       goto err_map;
+                       goto err_map_kobj;
                kobject_init(&map->kobj, &map_attr_type);
                map->mem = mem;
                mem->map = map;
                ret = kobject_add(&map->kobj, idev->map_dir, "map%d", mi);
                if (ret)
-                       goto err_map;
+                       goto err_map_kobj;
                ret = kobject_uevent(&map->kobj, KOBJ_ADD);
                if (ret)
                        goto err_map;
@@ -313,14 +313,14 @@ static int uio_dev_add_attributes(struct uio_device *idev)
                }
                portio = kzalloc(sizeof(*portio), GFP_KERNEL);
                if (!portio)
-                       goto err_portio;
+                       goto err_portio_kobj;
                kobject_init(&portio->kobj, &portio_attr_type);
                portio->port = port;
                port->portio = portio;
                ret = kobject_add(&portio->kobj, idev->portio_dir,
                                                        "port%d", pi);
                if (ret)
-                       goto err_portio;
+                       goto err_portio_kobj;
                ret = kobject_uevent(&portio->kobj, KOBJ_ADD);
                if (ret)
                        goto err_portio;
@@ -329,14 +329,18 @@ static int uio_dev_add_attributes(struct uio_device *idev)
        return 0;
 
 err_portio:
-       for (pi--; pi >= 0; pi--) {
+       pi--;
+err_portio_kobj:
+       for (; pi >= 0; pi--) {
                port = &idev->info->port[pi];
                portio = port->portio;
                kobject_put(&portio->kobj);
        }
        kobject_put(idev->portio_dir);
 err_map:
-       for (mi--; mi>=0; mi--) {
+       mi--;
+err_map_kobj:
+       for (; mi >= 0; mi--) {
                mem = &idev->info->mem[mi];
                map = mem->map;
                kobject_put(&map->kobj);
@@ -601,6 +605,7 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        struct uio_device *idev = vma->vm_private_data;
        struct page *page;
        unsigned long offset;
+       void *addr;
 
        int mi = uio_find_mem_index(vma);
        if (mi < 0)
@@ -612,10 +617,11 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
         */
        offset = (vmf->pgoff - mi) << PAGE_SHIFT;
 
+       addr = (void *)(unsigned long)idev->info->mem[mi].addr + offset;
        if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
-               page = virt_to_page(idev->info->mem[mi].addr + offset);
+               page = virt_to_page(addr);
        else
-               page = vmalloc_to_page((void *)(unsigned long)idev->info->mem[mi].addr + offset);
+               page = vmalloc_to_page(addr);
        get_page(page);
        vmf->page = page;
        return 0;
@@ -809,10 +815,9 @@ int __uio_register_device(struct module *owner,
 
        info->uio_dev = NULL;
 
-       idev = kzalloc(sizeof(*idev), GFP_KERNEL);
+       idev = devm_kzalloc(parent, sizeof(*idev), GFP_KERNEL);
        if (!idev) {
-               ret = -ENOMEM;
-               goto err_kzalloc;
+               return -ENOMEM;
        }
 
        idev->owner = owner;
@@ -822,7 +827,7 @@ int __uio_register_device(struct module *owner,
 
        ret = uio_get_minor(idev);
        if (ret)
-               goto err_get_minor;
+               return ret;
 
        idev->dev = device_create(&uio_class, parent,
                                  MKDEV(uio_major, idev->minor), idev,
@@ -840,7 +845,7 @@ int __uio_register_device(struct module *owner,
        info->uio_dev = idev;
 
        if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
-               ret = request_irq(info->irq, uio_interrupt,
+               ret = devm_request_irq(parent, info->irq, uio_interrupt,
                                  info->irq_flags, info->name, idev);
                if (ret)
                        goto err_request_irq;
@@ -854,9 +859,6 @@ err_uio_dev_add_attributes:
        device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
 err_device_create:
        uio_free_minor(idev);
-err_get_minor:
-       kfree(idev);
-err_kzalloc:
        return ret;
 }
 EXPORT_SYMBOL_GPL(__uio_register_device);
@@ -877,13 +879,9 @@ void uio_unregister_device(struct uio_info *info)
 
        uio_free_minor(idev);
 
-       if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
-               free_irq(info->irq, idev);
-
        uio_dev_del_attributes(idev);
 
        device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
-       kfree(idev);
 
        return;
 }
index f3611c2d83b681e1903d9bc502347108f50263bc..1549fab633c6a6790dd9aeb2dacdc02ee61f4d9f 100644 (file)
@@ -147,7 +147,6 @@ static void remove(struct pci_dev *pdev)
        uio_unregister_device(info);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
        iounmap(info->priv);
 
        kfree(info);
index 22cdf385ab33159cc99c37fd10946f96bbefdf85..30f533ce37585ed6eb7f82c56c91830442b2809a 100644 (file)
@@ -106,7 +106,6 @@ static void hilscher_pci_remove(struct pci_dev *dev)
        uio_unregister_device(info);
        pci_release_regions(dev);
        pci_disable_device(dev);
-       pci_set_drvdata(dev, NULL);
        iounmap(info->mem[0].internal_addr);
 
        kfree (info);
index a1768b2f449395b1f58220cbb649bc76ee5d42ce..f764adbfe036861dfccbada4ac9f27152e2f88aa 100644 (file)
@@ -42,7 +42,7 @@
 
 enum mf624_interrupt_source {ADC, CTR4, ALL};
 
-void mf624_disable_interrupt(enum mf624_interrupt_source source,
+static void mf624_disable_interrupt(enum mf624_interrupt_source source,
                             struct uio_info *info)
 {
        void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
@@ -70,7 +70,7 @@ void mf624_disable_interrupt(enum mf624_interrupt_source source,
        }
 }
 
-void mf624_enable_interrupt(enum mf624_interrupt_source source,
+static void mf624_enable_interrupt(enum mf624_interrupt_source source,
                            struct uio_info *info)
 {
        void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
@@ -220,7 +220,6 @@ static void mf624_pci_remove(struct pci_dev *dev)
        uio_unregister_device(info);
        pci_release_regions(dev);
        pci_disable_device(dev);
-       pci_set_drvdata(dev, NULL);
 
        iounmap(info->mem[0].internal_addr);
        iounmap(info->mem[1].internal_addr);
index 28a766b9e198af4ded7bc8ddfe2c28181909ddea..4c345db8b016e8adab57c49e2f19992113ec41b8 100644 (file)
@@ -127,7 +127,6 @@ static void netx_pci_remove(struct pci_dev *dev)
        uio_unregister_device(info);
        pci_release_regions(dev);
        pci_disable_device(dev);
-       pci_set_drvdata(dev, NULL);
        iounmap(info->mem[0].internal_addr);
 
        kfree(info);
index 90ff17a0202fb17e090985b7798848213aa2acf6..76669313e9a705679af830b23b2d2d8f48a30e4e 100644 (file)
@@ -112,11 +112,11 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
 
        if (pdev->dev.of_node) {
                /* alloc uioinfo for one device */
-               uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL);
+               uioinfo = devm_kzalloc(&pdev->dev, sizeof(*uioinfo),
+                                      GFP_KERNEL);
                if (!uioinfo) {
-                       ret = -ENOMEM;
                        dev_err(&pdev->dev, "unable to kmalloc\n");
-                       return ret;
+                       return -ENOMEM;
                }
                uioinfo->name = pdev->dev.of_node->name;
                uioinfo->version = "devicetree";
@@ -125,20 +125,19 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
 
        if (!uioinfo || !uioinfo->name || !uioinfo->version) {
                dev_err(&pdev->dev, "missing platform_data\n");
-               goto bad0;
+               return ret;
        }
 
        if (uioinfo->handler || uioinfo->irqcontrol ||
            uioinfo->irq_flags & IRQF_SHARED) {
                dev_err(&pdev->dev, "interrupt configuration error\n");
-               goto bad0;
+               return ret;
        }
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
        if (!priv) {
-               ret = -ENOMEM;
                dev_err(&pdev->dev, "unable to kmalloc\n");
-               goto bad0;
+               return -ENOMEM;
        }
 
        priv->uioinfo = uioinfo;
@@ -153,7 +152,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
                        uioinfo->irq = UIO_IRQ_NONE;
                else if (ret < 0) {
                        dev_err(&pdev->dev, "failed to get IRQ\n");
-                       goto bad1;
+                       return ret;
                }
        }
 
@@ -209,20 +208,12 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
        ret = uio_register_device(&pdev->dev, priv->uioinfo);
        if (ret) {
                dev_err(&pdev->dev, "unable to register uio device\n");
-               goto bad2;
+               pm_runtime_disable(&pdev->dev);
+               return ret;
        }
 
        platform_set_drvdata(pdev, priv);
        return 0;
- bad2:
-       pm_runtime_disable(&pdev->dev);
- bad1:
-       kfree(priv);
- bad0:
-       /* kfree uioinfo for OF */
-       if (pdev->dev.of_node)
-               kfree(uioinfo);
-       return ret;
 }
 
 static int uio_pdrv_genirq_remove(struct platform_device *pdev)
@@ -235,11 +226,6 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev)
        priv->uioinfo->handler = NULL;
        priv->uioinfo->irqcontrol = NULL;
 
-       /* kfree uioinfo for OF */
-       if (pdev->dev.of_node)
-               kfree(priv->uioinfo);
-
-       kfree(priv);
        return 0;
 }
 
index 5419832170856b78b384659f8bc961c3a283f2ee..9cfdfcafa2621de3feab90f003a68854a8b36eca 100644 (file)
@@ -188,7 +188,6 @@ static void sercos3_pci_remove(struct pci_dev *dev)
        uio_unregister_device(info);
        pci_release_regions(dev);
        pci_disable_device(dev);
-       pci_set_drvdata(dev, NULL);
        for (i = 0; i < 5; i++) {
                if (info->mem[i].internal_addr)
                        iounmap(info->mem[i].internal_addr);
index 5651231a74371cc4b97a0b55769e078478158a35..f3eecd967a8a1cb152575828cf45741dfc2bf85d 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/stringify.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
+#include <linux/ratelimit.h>
 
 /*
 #define VERBOSE_DEBUG
        atm_printk(KERN_INFO, instance , format , ## arg)
 #define atm_warn(instance, format, arg...)     \
        atm_printk(KERN_WARNING, instance , format , ## arg)
-#define atm_dbg(instance, format, arg...)              \
-       dynamic_pr_debug("ATM dev %d: " format ,        \
-       (instance)->atm_dev->number , ## arg)
-#define atm_rldbg(instance, format, arg...)            \
-       if (printk_ratelimit())                         \
-               atm_dbg(instance , format , ## arg)
-
+#define atm_dbg(instance, format, ...)                                 \
+       pr_debug("ATM dev %d: " format,                                 \
+                (instance)->atm_dev->number, ##__VA_ARGS__)
+#define atm_rldbg(instance, format, ...)                               \
+       pr_debug_ratelimited("ATM dev %d: " format,                     \
+                            (instance)->atm_dev->number, ##__VA_ARGS__)
 
 /* flags, set by mini-driver in bind() */
 
index 464584c6ccaeaf84d87a888d2e4b8c1382f97e61..a857131656889fa2a2634dc33ed398a5143c373a 100644 (file)
@@ -48,6 +48,7 @@
 #define PORTSC_SUSP           BIT(7)
 #define PORTSC_HSP            BIT(9)
 #define PORTSC_PTC            (0x0FUL << 16)
+#define PORTSC_PHCD(d)       ((d) ? BIT(22) : BIT(23))
 /* PTS and PTW for non lpm version only */
 #define PORTSC_PTS(d)                                          \
        (u32)((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0))
index be822a2c1776cc30c2df5f3ed7840aff68ef10ac..023d3cb6aa0a1bb04e69403f3e4bd825e4ada8d9 100644 (file)
@@ -108,14 +108,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        }
 
        data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
-       if (!IS_ERR(data->phy)) {
-               ret = usb_phy_init(data->phy);
-               if (ret) {
-                       dev_err(&pdev->dev, "unable to init phy: %d\n", ret);
-                       goto err_clk;
-               }
-       } else if (PTR_ERR(data->phy) == -EPROBE_DEFER) {
-               ret = -EPROBE_DEFER;
+       if (IS_ERR(data->phy)) {
+               ret = PTR_ERR(data->phy);
                goto err_clk;
        }
 
@@ -131,7 +125,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
                if (ret) {
                        dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n",
                                        ret);
-                       goto err_phy;
+                       goto err_clk;
                }
        }
 
@@ -143,7 +137,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
                dev_err(&pdev->dev,
                        "Can't register ci_hdrc platform device, err=%d\n",
                        ret);
-               goto err_phy;
+               goto err_clk;
        }
 
        if (data->usbmisc_data) {
@@ -164,9 +158,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 
 disable_device:
        ci_hdrc_remove_device(data->ci_pdev);
-err_phy:
-       if (data->phy)
-               usb_phy_shutdown(data->phy);
 err_clk:
        clk_disable_unprepare(data->clk);
        return ret;
@@ -178,10 +169,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
 
        pm_runtime_disable(&pdev->dev);
        ci_hdrc_remove_device(data->ci_pdev);
-
-       if (data->phy)
-               usb_phy_shutdown(data->phy);
-
        clk_disable_unprepare(data->clk);
 
        return 0;
index 23763dcec069b2e8d1ba6dd140fc9cf644d2ddec..5d8981c5235e50e42776cfb9f672977c11a61ef0 100644 (file)
@@ -172,6 +172,27 @@ u8 hw_port_test_get(struct ci_hdrc *ci)
        return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
 }
 
+/* The PHY enters/leaves low power mode */
+static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
+{
+       enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC;
+       bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm)));
+
+       if (enable && !lpm) {
+               hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
+                               PORTSC_PHCD(ci->hw_bank.lpm));
+       } else  if (!enable && lpm) {
+               hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
+                               0);
+               /* 
+                * The controller needs at least 1ms to reflect
+                * PHY's status, the PHY also needs some time (less
+                * than 1ms) to leave low power mode.
+                */
+               usleep_range(1500, 2000);
+       }
+}
+
 static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
 {
        u32 reg;
@@ -199,6 +220,8 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
        if (ci->hw_ep_max > ENDPT_MAX)
                return -ENODEV;
 
+       ci_hdrc_enter_lpm(ci, false);
+
        /* Disable all interrupts bits */
        hw_write(ci, OP_USBINTR, 0xffffffff, 0);
 
@@ -369,16 +392,28 @@ static irqreturn_t ci_irq(int irq, void *data)
 static int ci_get_platdata(struct device *dev,
                struct ci_hdrc_platform_data *platdata)
 {
-       /* Get the vbus regulator */
-       platdata->reg_vbus = devm_regulator_get(dev, "vbus");
-       if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) {
-               return -EPROBE_DEFER;
-       } else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) {
-               platdata->reg_vbus = NULL; /* no vbus regualator is needed */
-       } else if (IS_ERR(platdata->reg_vbus)) {
-               dev_err(dev, "Getting regulator error: %ld\n",
-                       PTR_ERR(platdata->reg_vbus));
-               return PTR_ERR(platdata->reg_vbus);
+       if (!platdata->phy_mode)
+               platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
+
+       if (!platdata->dr_mode)
+               platdata->dr_mode = of_usb_get_dr_mode(dev->of_node);
+
+       if (platdata->dr_mode == USB_DR_MODE_UNKNOWN)
+               platdata->dr_mode = USB_DR_MODE_OTG;
+
+       if (platdata->dr_mode != USB_DR_MODE_PERIPHERAL) {
+               /* Get the vbus regulator */
+               platdata->reg_vbus = devm_regulator_get(dev, "vbus");
+               if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) {
+                       return -EPROBE_DEFER;
+               } else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) {
+                       /* no vbus regualator is needed */
+                       platdata->reg_vbus = NULL;
+               } else if (IS_ERR(platdata->reg_vbus)) {
+                       dev_err(dev, "Getting regulator error: %ld\n",
+                               PTR_ERR(platdata->reg_vbus));
+                       return PTR_ERR(platdata->reg_vbus);
+               }
        }
 
        return 0;
@@ -465,6 +500,33 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
        }
 }
 
+static int ci_usb_phy_init(struct ci_hdrc *ci)
+{
+       if (ci->platdata->phy) {
+               ci->transceiver = ci->platdata->phy;
+               return usb_phy_init(ci->transceiver);
+       } else {
+               ci->global_phy = true;
+               ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (IS_ERR(ci->transceiver))
+                       ci->transceiver = NULL;
+
+               return 0;
+       }
+}
+
+static void ci_usb_phy_destroy(struct ci_hdrc *ci)
+{
+       if (!ci->transceiver)
+               return;
+
+       otg_set_peripheral(ci->transceiver->otg, NULL);
+       if (ci->global_phy)
+               usb_put_phy(ci->transceiver);
+       else
+               usb_phy_shutdown(ci->transceiver);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
        struct device   *dev = &pdev->dev;
@@ -473,7 +535,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
        void __iomem    *base;
        int             ret;
        enum usb_dr_mode dr_mode;
-       struct device_node *of_node = dev->of_node ?: dev->parent->of_node;
 
        if (!dev->platform_data) {
                dev_err(dev, "platform data missing\n");
@@ -493,10 +554,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
        ci->dev = dev;
        ci->platdata = dev->platform_data;
-       if (ci->platdata->phy)
-               ci->transceiver = ci->platdata->phy;
-       else
-               ci->global_phy = true;
 
        ret = hw_device_init(ci, base);
        if (ret < 0) {
@@ -504,27 +561,25 @@ static int ci_hdrc_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       ret = ci_usb_phy_init(ci);
+       if (ret) {
+               dev_err(dev, "unable to init phy: %d\n", ret);
+               return ret;
+       }
+
        ci->hw_bank.phys = res->start;
 
        ci->irq = platform_get_irq(pdev, 0);
        if (ci->irq < 0) {
                dev_err(dev, "missing IRQ\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto destroy_phy;
        }
 
        ci_get_otg_capable(ci);
 
-       if (!ci->platdata->phy_mode)
-               ci->platdata->phy_mode = of_usb_get_phy_mode(of_node);
-
        hw_phymode_configure(ci);
 
-       if (!ci->platdata->dr_mode)
-               ci->platdata->dr_mode = of_usb_get_dr_mode(of_node);
-
-       if (ci->platdata->dr_mode == USB_DR_MODE_UNKNOWN)
-               ci->platdata->dr_mode = USB_DR_MODE_OTG;
-
        dr_mode = ci->platdata->dr_mode;
        /* initialize role(s) before the interrupt is requested */
        if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
@@ -537,11 +592,23 @@ static int ci_hdrc_probe(struct platform_device *pdev)
                ret = ci_hdrc_gadget_init(ci);
                if (ret)
                        dev_info(dev, "doesn't support gadget\n");
+               if (!ret && ci->transceiver) {
+                       ret = otg_set_peripheral(ci->transceiver->otg,
+                                                       &ci->gadget);
+                       /*
+                        * If we implement all USB functions using chipidea drivers,
+                        * it doesn't need to call above API, meanwhile, if we only
+                        * use gadget function, calling above API is useless.
+                        */
+                       if (ret && ret != -ENOTSUPP)
+                               goto destroy_phy;
+               }
        }
 
        if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
                dev_err(dev, "no supported roles\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto destroy_phy;
        }
 
        if (ci->is_otg) {
@@ -594,6 +661,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
        free_irq(ci->irq, ci);
 stop:
        ci_role_destroy(ci);
+destroy_phy:
+       ci_usb_phy_destroy(ci);
 
        return ret;
 }
@@ -605,6 +674,8 @@ static int ci_hdrc_remove(struct platform_device *pdev)
        dbg_remove_files(ci);
        free_irq(ci->irq, ci);
        ci_role_destroy(ci);
+       ci_hdrc_enter_lpm(ci, true);
+       ci_usb_phy_destroy(ci);
        kfree(ci->hw_bank.regmap);
 
        return 0;
index 64d7a6d9a1adcbd679258661a6b5875bd8bf834a..59e6020ea7539e5e331364ac067c9a16f27855ba 100644 (file)
@@ -103,15 +103,15 @@ static void host_stop(struct ci_hdrc *ci)
        if (hcd) {
                usb_remove_hcd(hcd);
                usb_put_hcd(hcd);
+               if (ci->platdata->reg_vbus)
+                       regulator_disable(ci->platdata->reg_vbus);
        }
-       if (ci->platdata->reg_vbus)
-               regulator_disable(ci->platdata->reg_vbus);
 }
 
 
 void ci_hdrc_host_destroy(struct ci_hdrc *ci)
 {
-       if (ci->role == CI_ROLE_HOST)
+       if (ci->role == CI_ROLE_HOST && ci->hcd)
                host_stop(ci);
 }
 
index 9333083dd1111c047c7016a44402242e2aa87f7d..b34c81969cba672a7e880f405f2445adf36b7e6f 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
-#include <linux/usb/otg.h>
 #include <linux/usb/chipidea.h>
 
 #include "ci.h"
@@ -686,9 +685,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
        usb_ep_fifo_flush(&ci->ep0out->ep);
        usb_ep_fifo_flush(&ci->ep0in->ep);
 
-       if (ci->driver)
-               ci->driver->disconnect(gadget);
-
        /* make sure to disable all endpoints */
        gadget_for_each_ep(ep, gadget) {
                usb_ep_disable(ep);
@@ -718,6 +714,11 @@ __acquires(ci->lock)
        int retval;
 
        spin_unlock(&ci->lock);
+       if (ci->gadget.speed != USB_SPEED_UNKNOWN) {
+               if (ci->driver)
+                       ci->driver->disconnect(&ci->gadget);
+       }
+
        retval = _gadget_stop_activity(&ci->gadget);
        if (retval)
                goto done;
@@ -1461,6 +1462,8 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
                        hw_device_state(ci, ci->ep0out->qh.dma);
                        dev_dbg(ci->dev, "Connected to host\n");
                } else {
+                       if (ci->driver)
+                               ci->driver->disconnect(&ci->gadget);
                        hw_device_state(ci, 0);
                        if (ci->platdata->notify_event)
                                ci->platdata->notify_event(ci,
@@ -1633,23 +1636,22 @@ static int ci_udc_start(struct usb_gadget *gadget,
        retval = usb_ep_enable(&ci->ep0in->ep);
        if (retval)
                return retval;
-       spin_lock_irqsave(&ci->lock, flags);
 
        ci->driver = driver;
        pm_runtime_get_sync(&ci->gadget.dev);
        if (ci->vbus_active) {
+               spin_lock_irqsave(&ci->lock, flags);
                hw_device_reset(ci, USBMODE_CM_DC);
        } else {
                pm_runtime_put_sync(&ci->gadget.dev);
-               goto done;
+               return retval;
        }
 
        retval = hw_device_state(ci, ci->ep0out->qh.dma);
+       spin_unlock_irqrestore(&ci->lock, flags);
        if (retval)
                pm_runtime_put_sync(&ci->gadget.dev);
 
- done:
-       spin_unlock_irqrestore(&ci->lock, flags);
        return retval;
 }
 
@@ -1786,34 +1788,9 @@ static int udc_start(struct ci_hdrc *ci)
 
        ci->gadget.ep0 = &ci->ep0in->ep;
 
-       if (ci->global_phy) {
-               ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
-               if (IS_ERR(ci->transceiver))
-                       ci->transceiver = NULL;
-       }
-
-       if (ci->platdata->flags & CI_HDRC_REQUIRE_TRANSCEIVER) {
-               if (ci->transceiver == NULL) {
-                       retval = -ENODEV;
-                       goto destroy_eps;
-               }
-       }
-
-       if (ci->transceiver) {
-               retval = otg_set_peripheral(ci->transceiver->otg,
-                                               &ci->gadget);
-               /*
-                * If we implement all USB functions using chipidea drivers,
-                * it doesn't need to call above API, meanwhile, if we only
-                * use gadget function, calling above API is useless.
-                */
-               if (retval && retval != -ENOTSUPP)
-                       goto put_transceiver;
-       }
-
        retval = usb_add_gadget_udc(dev, &ci->gadget);
        if (retval)
-               goto remove_trans;
+               goto destroy_eps;
 
        pm_runtime_no_callbacks(&ci->gadget.dev);
        pm_runtime_enable(&ci->gadget.dev);
@@ -1823,17 +1800,6 @@ static int udc_start(struct ci_hdrc *ci)
 
        return retval;
 
-remove_trans:
-       if (ci->transceiver) {
-               otg_set_peripheral(ci->transceiver->otg, NULL);
-               if (ci->global_phy)
-                       usb_put_phy(ci->transceiver);
-       }
-
-       dev_err(dev, "error = %i\n", retval);
-put_transceiver:
-       if (ci->transceiver && ci->global_phy)
-               usb_put_phy(ci->transceiver);
 destroy_eps:
        destroy_eps(ci);
 free_pools:
index d3318a0df8ee503f4f5ee553cda3ff1391298be4..4d387596f3f0a6e531caa1a9049a383d605091b4 100644 (file)
@@ -101,6 +101,7 @@ struct wdm_device {
        struct work_struct      rxwork;
        int                     werr;
        int                     rerr;
+       int                     resp_count;
 
        struct list_head        device_list;
        int                     (*manage_power)(struct usb_interface *, int);
@@ -253,6 +254,10 @@ static void wdm_int_callback(struct urb *urb)
                        "NOTIFY_NETWORK_CONNECTION %s network",
                        dr->wValue ? "connected to" : "disconnected from");
                goto exit;
+       case USB_CDC_NOTIFY_SPEED_CHANGE:
+               dev_dbg(&desc->intf->dev, "SPEED_CHANGE received (len %u)",
+                       urb->actual_length);
+               goto exit;
        default:
                clear_bit(WDM_POLL_RUNNING, &desc->flags);
                dev_err(&desc->intf->dev,
@@ -262,9 +267,9 @@ static void wdm_int_callback(struct urb *urb)
        }
 
        spin_lock(&desc->iuspin);
-       clear_bit(WDM_READ, &desc->flags);
        responding = test_and_set_bit(WDM_RESPONDING, &desc->flags);
-       if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags)
+       if (!desc->resp_count++ && !responding
+               && !test_bit(WDM_DISCONNECTING, &desc->flags)
                && !test_bit(WDM_SUSPENDING, &desc->flags)) {
                rv = usb_submit_urb(desc->response, GFP_ATOMIC);
                dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
@@ -521,10 +526,36 @@ retry:
 
        desc->length -= cntr;
        /* in case we had outstanding data */
-       if (!desc->length)
+       if (!desc->length) {
                clear_bit(WDM_READ, &desc->flags);
 
-       spin_unlock_irq(&desc->iuspin);
+               if (--desc->resp_count) {
+                       set_bit(WDM_RESPONDING, &desc->flags);
+                       spin_unlock_irq(&desc->iuspin);
+
+                       rv = usb_submit_urb(desc->response, GFP_KERNEL);
+                       if (rv) {
+                               dev_err(&desc->intf->dev,
+                                       "%s: usb_submit_urb failed with result %d\n",
+                                       __func__, rv);
+                               spin_lock_irq(&desc->iuspin);
+                               clear_bit(WDM_RESPONDING, &desc->flags);
+                               spin_unlock_irq(&desc->iuspin);
+
+                               if (rv == -ENOMEM) {
+                                       rv = schedule_work(&desc->rxwork);
+                                       if (rv)
+                                               dev_err(&desc->intf->dev, "Cannot schedule work\n");
+                               } else {
+                                       spin_lock_irq(&desc->iuspin);
+                                       desc->resp_count = 0;
+                                       spin_unlock_irq(&desc->iuspin);
+                               }
+                       }
+               } else
+                       spin_unlock_irq(&desc->iuspin);
+       } else
+               spin_unlock_irq(&desc->iuspin);
 
        rv = cntr;
 
@@ -635,6 +666,9 @@ static int wdm_release(struct inode *inode, struct file *file)
                if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
                        dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
                        kill_urbs(desc);
+                       spin_lock_irq(&desc->iuspin);
+                       desc->resp_count = 0;
+                       spin_unlock_irq(&desc->iuspin);
                        desc->manage_power(desc->intf, 0);
                } else {
                        /* must avoid dev_printk here as desc->intf is invalid */
index 71dc5d768fa5cef3edc5ac27c84c032d2a0a0dcf..967152a63bd3c92f86f937a5b2f3c7b1d0805cc2 100644 (file)
@@ -914,10 +914,8 @@ static int proc_control(struct dev_state *ps, void __user *arg)
        snoop(&dev->dev, "control urb: bRequestType=%02x "
                "bRequest=%02x wValue=%04x "
                "wIndex=%04x wLength=%04x\n",
-               ctrl.bRequestType, ctrl.bRequest,
-               __le16_to_cpup(&ctrl.wValue),
-               __le16_to_cpup(&ctrl.wIndex),
-               __le16_to_cpup(&ctrl.wLength));
+               ctrl.bRequestType, ctrl.bRequest, ctrl.wValue,
+               ctrl.wIndex, ctrl.wLength);
        if (ctrl.bRequestType & 0x80) {
                if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,
                                               ctrl.wLength)) {
@@ -1636,32 +1634,32 @@ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
 static int proc_control_compat(struct dev_state *ps,
                                struct usbdevfs_ctrltransfer32 __user *p32)
 {
-        struct usbdevfs_ctrltransfer __user *p;
-        __u32 udata;
-        p = compat_alloc_user_space(sizeof(*p));
-        if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) ||
-            get_user(udata, &p32->data) ||
+       struct usbdevfs_ctrltransfer __user *p;
+       __u32 udata;
+       p = compat_alloc_user_space(sizeof(*p));
+       if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) ||
+           get_user(udata, &p32->data) ||
            put_user(compat_ptr(udata), &p->data))
                return -EFAULT;
-        return proc_control(ps, p);
+       return proc_control(ps, p);
 }
 
 static int proc_bulk_compat(struct dev_state *ps,
                        struct usbdevfs_bulktransfer32 __user *p32)
 {
-        struct usbdevfs_bulktransfer __user *p;
-        compat_uint_t n;
-        compat_caddr_t addr;
+       struct usbdevfs_bulktransfer __user *p;
+       compat_uint_t n;
+       compat_caddr_t addr;
 
-        p = compat_alloc_user_space(sizeof(*p));
+       p = compat_alloc_user_space(sizeof(*p));
 
-        if (get_user(n, &p32->ep) || put_user(n, &p->ep) ||
-            get_user(n, &p32->len) || put_user(n, &p->len) ||
-            get_user(n, &p32->timeout) || put_user(n, &p->timeout) ||
-            get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data))
-                return -EFAULT;
+       if (get_user(n, &p32->ep) || put_user(n, &p->ep) ||
+           get_user(n, &p32->len) || put_user(n, &p->len) ||
+           get_user(n, &p32->timeout) || put_user(n, &p->timeout) ||
+           get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data))
+               return -EFAULT;
 
-        return proc_bulk(ps, p);
+       return proc_bulk(ps, p);
 }
 static int proc_disconnectsignal_compat(struct dev_state *ps, void __user *arg)
 {
index f7841d44feda967f0a78b21bf4e8229556ccd7c5..47aade2a5e741ade190022342590c363316514d7 100644 (file)
@@ -1179,8 +1179,8 @@ static int usb_resume_interface(struct usb_device *udev,
                                                "reset_resume", status);
                } else {
                        intf->needs_binding = 1;
-                       dev_warn(&intf->dev, "no %s for driver %s?\n",
-                                       "reset_resume", driver->name);
+                       dev_dbg(&intf->dev, "no reset_resume for driver %s?\n",
+                                       driver->name);
                }
        } else {
                status = driver->resume(intf);
@@ -1790,6 +1790,9 @@ int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
        struct usb_hcd *hcd = bus_to_hcd(udev->bus);
        int ret = -EPERM;
 
+       if (enable && !udev->usb2_hw_lpm_allowed)
+               return 0;
+
        if (hcd->driver->set_usb2_hw_lpm) {
                ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable);
                if (!ret)
index 7421888087a3b752a3915c0dc70bfcda640d9122..3bdfbf88a0aee73e36989c8d7adfbe3190b2e8ce 100644 (file)
@@ -8,7 +8,7 @@
  * (C) Copyright Deti Fliegl 1999 (new USB architecture)
  * (C) Copyright Randy Dunlap 2000
  * (C) Copyright David Brownell 2000-2001 (kernel hotplug, usb_device_id,
      more docs, etc)
*     more docs, etc)
  * (C) Copyright Yggdrasil Computing, Inc. 2000
  *     (usb_device_id matching changes by Adam J. Richter)
  * (C) Copyright Greg Kroah-Hartman 2002-2003
@@ -27,7 +27,7 @@
 static const struct file_operations *usb_minors[MAX_USB_MINORS];
 static DECLARE_RWSEM(minor_rwsem);
 
-static int usb_open(struct inode * inode, struct file * file)
+static int usb_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
        const struct file_operations *c;
@@ -44,7 +44,7 @@ static int usb_open(struct inode * inode, struct file * file)
        file->f_op = new_fops;
        /* Curiouser and curiouser... NULL ->open() as "no device" ? */
        if (file->f_op->open)
-               err = file->f_op->open(inode,file);
+               err = file->f_op->open(inode, file);
        if (err) {
                fops_put(file->f_op);
                file->f_op = fops_get(old_fops);
@@ -166,7 +166,7 @@ int usb_register_dev(struct usb_interface *intf,
        char *temp;
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
-       /* 
+       /*
         * We don't care what the device tries to start at, we want to start
         * at zero to pack the devices into the smallest available space with
         * no holes in the minor range.
index b9d3c43e38599e67c4cc8c409c686bb4f45fcf8a..dfe9d0f229780653c2bcb505e73ee00f4b372197 100644 (file)
@@ -215,6 +215,9 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
                goto disable_pci;
        }
 
+       hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) &&
+                       driver->flags & (HCD_USB11 | HCD_USB3)) ? 1 : 0;
+
        if (driver->flags & HCD_MEMORY) {
                /* EHCI, OHCI */
                hcd->rsrc_start = pci_resource_start(dev, 0);
index d6a8d23f047ba69c33d836adb8adc9e0741a85c5..6bffb8c87bc9aaee98c2342b0f7a5a3c05c870b0 100644 (file)
@@ -6,7 +6,7 @@
  * (C) Copyright Deti Fliegl 1999
  * (C) Copyright Randy Dunlap 2000
  * (C) Copyright David Brownell 2000-2002
- * 
+ *
  * 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
@@ -40,6 +40,7 @@
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
 #include <linux/pm_runtime.h>
+#include <linux/types.h>
 
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
@@ -92,10 +93,7 @@ EXPORT_SYMBOL_GPL (usb_bus_list);
 
 /* used when allocating bus numbers */
 #define USB_MAXBUS             64
-struct usb_busmap {
-       unsigned long busmap [USB_MAXBUS / (8*sizeof (unsigned long))];
-};
-static struct usb_busmap busmap;
+static DECLARE_BITMAP(busmap, USB_MAXBUS);
 
 /* used when updating list of hcds */
 DEFINE_MUTEX(usb_bus_list_lock);       /* exported only for usbfs */
@@ -171,7 +169,7 @@ static const u8 usb25_rh_dev_descriptor[18] = {
 };
 
 /* usb 2.0 root hub device descriptor */
-static const u8 usb2_rh_dev_descriptor [18] = {
+static const u8 usb2_rh_dev_descriptor[18] = {
        0x12,       /*  __u8  bLength; */
        0x01,       /*  __u8  bDescriptorType; Device */
        0x00, 0x02, /*  __le16 bcdUSB; v2.0 */
@@ -194,7 +192,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {
 /* no usb 2.0 root hub "device qualifier" descriptor: one speed only */
 
 /* usb 1.1 root hub device descriptor */
-static const u8 usb11_rh_dev_descriptor [18] = {
+static const u8 usb11_rh_dev_descriptor[18] = {
        0x12,       /*  __u8  bLength; */
        0x01,       /*  __u8  bDescriptorType; Device */
        0x10, 0x01, /*  __le16 bcdUSB; v1.1 */
@@ -219,7 +217,7 @@ static const u8 usb11_rh_dev_descriptor [18] = {
 
 /* Configuration descriptors for our root hubs */
 
-static const u8 fs_rh_config_descriptor [] = {
+static const u8 fs_rh_config_descriptor[] = {
 
        /* one configuration */
        0x09,       /*  __u8  bLength; */
@@ -228,13 +226,13 @@ static const u8 fs_rh_config_descriptor [] = {
        0x01,       /*  __u8  bNumInterfaces; (1) */
        0x01,       /*  __u8  bConfigurationValue; */
        0x00,       /*  __u8  iConfiguration; */
-       0xc0,       /*  __u8  bmAttributes; 
+       0xc0,       /*  __u8  bmAttributes;
                                 Bit 7: must be set,
                                     6: Self-powered,
                                     5: Remote wakeup,
                                     4..0: resvd */
        0x00,       /*  __u8  MaxPower; */
-      
+
        /* USB 1.1:
         * USB 2.0, single TT organization (mandatory):
         *      one interface, protocol 0
@@ -256,17 +254,17 @@ static const u8 fs_rh_config_descriptor [] = {
        0x00,       /*  __u8  if_bInterfaceSubClass; */
        0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
        0x00,       /*  __u8  if_iInterface; */
-     
+
        /* one endpoint (status change endpoint) */
        0x07,       /*  __u8  ep_bLength; */
        0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
        0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
-       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
-       0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+       0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
        0xff        /*  __u8  ep_bInterval; (255ms -- usb 2.0 spec) */
 };
 
-static const u8 hs_rh_config_descriptor [] = {
+static const u8 hs_rh_config_descriptor[] = {
 
        /* one configuration */
        0x09,       /*  __u8  bLength; */
@@ -275,13 +273,13 @@ static const u8 hs_rh_config_descriptor [] = {
        0x01,       /*  __u8  bNumInterfaces; (1) */
        0x01,       /*  __u8  bConfigurationValue; */
        0x00,       /*  __u8  iConfiguration; */
-       0xc0,       /*  __u8  bmAttributes; 
+       0xc0,       /*  __u8  bmAttributes;
                                 Bit 7: must be set,
                                     6: Self-powered,
                                     5: Remote wakeup,
                                     4..0: resvd */
        0x00,       /*  __u8  MaxPower; */
-      
+
        /* USB 1.1:
         * USB 2.0, single TT organization (mandatory):
         *      one interface, protocol 0
@@ -303,12 +301,12 @@ static const u8 hs_rh_config_descriptor [] = {
        0x00,       /*  __u8  if_bInterfaceSubClass; */
        0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
        0x00,       /*  __u8  if_iInterface; */
-     
+
        /* one endpoint (status change endpoint) */
        0x07,       /*  __u8  ep_bLength; */
        0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
        0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
-       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
                    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
                     * see hub.c:hub_configure() for details. */
        (USB_MAXCHILDREN + 1 + 7) / 8, 0x00,
@@ -428,7 +426,7 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len)
        char const *s;
        static char const langids[4] = {4, USB_DT_STRING, 0x09, 0x04};
 
-       // language ids
+       /* language ids */
        switch (id) {
        case 0:
                /* Array of LANGID codes (0x0409 is MSFT-speak for "en-us") */
@@ -464,7 +462,7 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len)
 static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
 {
        struct usb_ctrlrequest *cmd;
-       u16             typeReq, wValue, wIndex, wLength;
+       u16             typeReq, wValue, wIndex, wLength;
        u8              *ubuf = urb->transfer_buffer;
        unsigned        len = 0;
        int             status;
@@ -526,10 +524,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
         */
 
        case DeviceRequest | USB_REQ_GET_STATUS:
-               tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev)
+               tbuf[0] = (device_may_wakeup(&hcd->self.root_hub->dev)
                                        << USB_DEVICE_REMOTE_WAKEUP)
                                | (1 << USB_DEVICE_SELF_POWERED);
-               tbuf [1] = 0;
+               tbuf[1] = 0;
                len = 2;
                break;
        case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
@@ -546,7 +544,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
                        goto error;
                break;
        case DeviceRequest | USB_REQ_GET_CONFIGURATION:
-               tbuf [0] = 1;
+               tbuf[0] = 1;
                len = 1;
                        /* FALLTHROUGH */
        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
@@ -609,13 +607,13 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
                }
                break;
        case DeviceRequest | USB_REQ_GET_INTERFACE:
-               tbuf [0] = 0;
+               tbuf[0] = 0;
                len = 1;
                        /* FALLTHROUGH */
        case DeviceOutRequest | USB_REQ_SET_INTERFACE:
                break;
        case DeviceOutRequest | USB_REQ_SET_ADDRESS:
-               // wValue == urb->dev->devaddr
+               /* wValue == urb->dev->devaddr */
                dev_dbg (hcd->self.controller, "root hub device address %d\n",
                        wValue);
                break;
@@ -625,9 +623,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
        /* ENDPOINT REQUESTS */
 
        case EndpointRequest | USB_REQ_GET_STATUS:
-               // ENDPOINT_HALT flag
-               tbuf [0] = 0;
-               tbuf [1] = 0;
+               /* ENDPOINT_HALT flag */
+               tbuf[0] = 0;
+               tbuf[1] = 0;
                len = 2;
                        /* FALLTHROUGH */
        case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
@@ -683,7 +681,7 @@ error:
                if (urb->transfer_buffer_length < len)
                        len = urb->transfer_buffer_length;
                urb->actual_length = len;
-               // always USB_DIR_IN, toward host
+               /* always USB_DIR_IN, toward host */
                memcpy (ubuf, bufp, len);
 
                /* report whether RH hardware supports remote wakeup */
@@ -877,11 +875,11 @@ static ssize_t authorized_default_store(struct device *dev,
        usb_hcd = bus_to_hcd(usb_bus);
        result = sscanf(buf, "%u\n", &val);
        if (result == 1) {
-               usb_hcd->authorized_default = val? 1 : 0;
+               usb_hcd->authorized_default = val ? 1 : 0;
                result = size;
-       }
-       else
+       } else {
                result = -EINVAL;
+       }
        return result;
 }
 static DEVICE_ATTR_RW(authorized_default);
@@ -941,12 +939,12 @@ static int usb_register_bus(struct usb_bus *bus)
        int busnum;
 
        mutex_lock(&usb_bus_list_lock);
-       busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
+       busnum = find_next_zero_bit(busmap, USB_MAXBUS, 1);
        if (busnum >= USB_MAXBUS) {
                printk (KERN_ERR "%s: too many buses\n", usbcore_name);
                goto error_find_busnum;
        }
-       set_bit (busnum, busmap.busmap);
+       set_bit(busnum, busmap);
        bus->busnum = busnum;
 
        /* Add it to the local list of buses */
@@ -987,7 +985,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
 
        usb_notify_remove_bus(bus);
 
-       clear_bit (bus->busnum, busmap.busmap);
+       clear_bit(bus->busnum, busmap);
 }
 
 /**
@@ -1033,6 +1031,7 @@ static int register_root_hub(struct usb_hcd *hcd)
                                        dev_name(&usb_dev->dev), retval);
                        return retval;
                }
+               usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
        }
 
        retval = usb_new_device (usb_dev);
@@ -1120,21 +1119,21 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
        case USB_SPEED_LOW:     /* INTR only */
                if (is_input) {
                        tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L;
-                       return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
+                       return 64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp;
                } else {
                        tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L;
-                       return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
+                       return 64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp;
                }
        case USB_SPEED_FULL:    /* ISOC or INTR */
                if (isoc) {
                        tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-                       return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
+                       return ((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp;
                } else {
                        tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-                       return (9107L + BW_HOST_DELAY + tmp);
+                       return 9107L + BW_HOST_DELAY + tmp;
                }
        case USB_SPEED_HIGH:    /* ISOC or INTR */
-               // FIXME adjust for input vs output
+               /* FIXME adjust for input vs output */
                if (isoc)
                        tmp = HS_NSECS_ISO (bytecount);
                else
@@ -1651,6 +1650,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
 static void __usb_hcd_giveback_urb(struct urb *urb)
 {
        struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
+       struct usb_anchor *anchor = urb->anchor;
        int status = urb->unlinked;
        unsigned long flags;
 
@@ -1662,6 +1662,7 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
 
        unmap_urb_for_dma(hcd, urb);
        usbmon_urb_complete(&hcd->self, urb, status);
+       usb_anchor_suspend_wakeups(anchor);
        usb_unanchor_urb(urb);
 
        /* pass ownership to the completion handler */
@@ -1681,6 +1682,7 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
        urb->complete(urb);
        local_irq_restore(flags);
 
+       usb_anchor_resume_wakeups(anchor);
        atomic_dec(&urb->use_count);
        if (unlikely(atomic_read(&urb->reject)))
                wake_up(&usb_kill_urb_queue);
@@ -1703,7 +1705,9 @@ static void usb_giveback_urb_bh(unsigned long param)
 
                urb = list_entry(local_list.next, struct urb, urb_list);
                list_del_init(&urb->urb_list);
+               bh->completing_ep = urb->ep;
                __usb_hcd_giveback_urb(urb);
+               bh->completing_ep = NULL;
        }
 
        /* check if there are new URBs to giveback */
@@ -1812,7 +1816,7 @@ rescan:
                                 case USB_ENDPOINT_XFER_INT:
                                        s = "-intr"; break;
                                 default:
-                                       s = "-iso"; break;
+                                       s = "-iso"; break;
                                };
                                s;
                        }));
@@ -2073,8 +2077,11 @@ EXPORT_SYMBOL_GPL(usb_alloc_streams);
  *
  * Reverts a group of bulk endpoints back to not using stream IDs.
  * Can fail if we are given bad arguments, or HCD is broken.
+ *
+ * Return: On success, the number of allocated streams. On failure, a negative
+ * error code.
  */
-void usb_free_streams(struct usb_interface *interface,
+int usb_free_streams(struct usb_interface *interface,
                struct usb_host_endpoint **eps, unsigned int num_eps,
                gfp_t mem_flags)
 {
@@ -2085,14 +2092,14 @@ void usb_free_streams(struct usb_interface *interface,
        dev = interface_to_usbdev(interface);
        hcd = bus_to_hcd(dev->bus);
        if (dev->speed != USB_SPEED_SUPER)
-               return;
+               return -EINVAL;
 
        /* Streams only apply to bulk endpoints. */
        for (i = 0; i < num_eps; i++)
                if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc))
-                       return;
+                       return -EINVAL;
 
-       hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags);
+       return hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags);
 }
 EXPORT_SYMBOL_GPL(usb_free_streams);
 
@@ -2245,7 +2252,7 @@ static void hcd_resume_work(struct work_struct *work)
 }
 
 /**
- * usb_hcd_resume_root_hub - called by HCD to resume its root hub 
+ * usb_hcd_resume_root_hub - called by HCD to resume its root hub
  * @hcd: host controller for this root hub
  *
  * The USB host controller calls this function when its root hub is
@@ -2324,15 +2331,8 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
 irqreturn_t usb_hcd_irq (int irq, void *__hcd)
 {
        struct usb_hcd          *hcd = __hcd;
-       unsigned long           flags;
        irqreturn_t             rc;
 
-       /* IRQF_DISABLED doesn't work correctly with shared IRQs
-        * when the first handler doesn't use it.  So let's just
-        * assume it's never used.
-        */
-       local_irq_save(flags);
-
        if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
                rc = IRQ_NONE;
        else if (hcd->driver->irq(hcd) == IRQ_NONE)
@@ -2340,7 +2340,6 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
        else
                rc = IRQ_HANDLED;
 
-       local_irq_restore(flags);
        return rc;
 }
 EXPORT_SYMBOL_GPL(usb_hcd_irq);
@@ -2547,13 +2546,6 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd,
 
        if (hcd->driver->irq) {
 
-               /* IRQF_DISABLED doesn't work as advertised when used together
-                * with IRQF_SHARED. As usb_hcd_irq() will always disable
-                * interrupts we can remove it here.
-                */
-               if (irqflags & IRQF_SHARED)
-                       irqflags &= ~IRQF_DISABLED;
-
                snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
                                hcd->driver->description, hcd->self.busnum);
                retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
@@ -2600,7 +2592,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 
        /* Keep old behaviour if authorized_default is not in [0, 1]. */
        if (authorized_default < 0 || authorized_default > 1)
-               hcd->authorized_default = hcd->wireless? 0 : 1;
+               hcd->authorized_default = hcd->wireless ? 0 : 1;
        else
                hcd->authorized_default = authorized_default;
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -2743,7 +2735,7 @@ err_allocate_root_hub:
 err_register_bus:
        hcd_buffer_destroy(hcd);
        return retval;
-} 
+}
 EXPORT_SYMBOL_GPL(usb_add_hcd);
 
 /**
@@ -2818,7 +2810,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
 void
-usb_hcd_platform_shutdown(struct platform_devicedev)
+usb_hcd_platform_shutdown(struct platform_device *dev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(dev);
 
@@ -2840,7 +2832,7 @@ struct usb_mon_operations *mon_ops;
  * Notice that the code is minimally error-proof. Because usbmon needs
  * symbols from usbcore, usbcore gets referenced and cannot be unloaded first.
  */
+
 int usb_mon_register (struct usb_mon_operations *ops)
 {
 
index e6b682c6c236b8152561496b2e00bba22e75e25c..06cec635e703adc3f9859ae8ca53dbb124820cd4 100644 (file)
@@ -120,7 +120,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus)
        if (hub_is_superspeed(hub->hdev))
                return "5.0 Gb/s";
        if (portstatus & USB_PORT_STAT_HIGH_SPEED)
-               return "480 Mb/s";
+               return "480 Mb/s";
        else if (portstatus & USB_PORT_STAT_LOW_SPEED)
                return "1.5 Mb/s";
        else
@@ -135,7 +135,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
        return usb_get_intfdata(hdev->actconfig->interface[0]);
 }
 
-static int usb_device_supports_lpm(struct usb_device *udev)
+int usb_device_supports_lpm(struct usb_device *udev)
 {
        /* USB 2.1 (and greater) devices indicate LPM support through
         * their USB 2.0 Extended Capabilities BOS descriptor.
@@ -156,6 +156,11 @@ static int usb_device_supports_lpm(struct usb_device *udev)
                                "Power management will be impacted.\n");
                return 0;
        }
+
+       /* udev is root hub */
+       if (!udev->parent)
+               return 1;
+
        if (udev->parent->lpm_capable)
                return 1;
 
@@ -310,9 +315,9 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
                return;
 
        udev_u1_del = udev->bos->ss_cap->bU1devExitLat;
-       udev_u2_del = udev->bos->ss_cap->bU2DevExitLat;
+       udev_u2_del = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat);
        hub_u1_del = udev->parent->bos->ss_cap->bU1devExitLat;
-       hub_u2_del = udev->parent->bos->ss_cap->bU2DevExitLat;
+       hub_u2_del = le16_to_cpu(udev->parent->bos->ss_cap->bU2DevExitLat);
 
        usb_set_lpm_mel(udev, &udev->u1_params, udev_u1_del,
                        hub, &udev->parent->u1_params, hub_u1_del);
@@ -433,7 +438,7 @@ static void set_port_led(
                        case HUB_LED_OFF: s = "off"; break;
                        case HUB_LED_AUTO: s = "auto"; break;
                        default: s = "??"; break;
-                       }; s; }),
+                       } s; }),
                        status);
 }
 
@@ -857,7 +862,7 @@ static int hub_hub_status(struct usb_hub *hub,
                                "%s failed (err = %d)\n", __func__, ret);
        } else {
                *status = le16_to_cpu(hub->status->hub.wHubStatus);
-               *change = le16_to_cpu(hub->status->hub.wHubChange); 
+               *change = le16_to_cpu(hub->status->hub.wHubChange);
                ret = 0;
        }
        mutex_unlock(&hub->status_mutex);
@@ -956,7 +961,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
         */
 
        set_bit(port1, hub->change_bits);
-       kick_khubd(hub);
+       kick_khubd(hub);
 }
 
 /**
@@ -1107,16 +1112,13 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                        /*
                         * USB3 protocol ports will automatically transition
                         * to Enabled state when detect an USB3.0 device attach.
-                        * Do not disable USB3 protocol ports.
+                        * Do not disable USB3 protocol ports, just pretend
+                        * power was lost
                         */
-                       if (!hub_is_superspeed(hdev)) {
+                       portstatus &= ~USB_PORT_STAT_ENABLE;
+                       if (!hub_is_superspeed(hdev))
                                usb_clear_port_feature(hdev, port1,
                                                   USB_PORT_FEAT_ENABLE);
-                               portstatus &= ~USB_PORT_STAT_ENABLE;
-                       } else {
-                               /* Pretend that power was lost for USB3 devs */
-                               portstatus &= ~USB_PORT_STAT_ENABLE;
-                       }
                }
 
                /* Clear status-change flags; we'll debounce later */
@@ -1130,6 +1132,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                        usb_clear_port_feature(hub->hdev, port1,
                                        USB_PORT_FEAT_C_ENABLE);
                }
+               if (portchange & USB_PORT_STAT_C_RESET) {
+                       need_debounce_delay = true;
+                       usb_clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_RESET);
+               }
                if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
                                hub_is_superspeed(hub->hdev)) {
                        need_debounce_delay = true;
@@ -1361,7 +1368,7 @@ static int hub_configure(struct usb_hub *hub,
        if ((wHubCharacteristics & HUB_CHAR_COMPOUND) &&
                        !(hub_is_superspeed(hdev))) {
                int     i;
-               char    portstr [USB_MAXCHILDREN + 1];
+               char    portstr[USB_MAXCHILDREN + 1];
 
                for (i = 0; i < hdev->maxchild; i++)
                        portstr[i] = hub->descriptor->u.hs.DeviceRemovable
@@ -1429,32 +1436,32 @@ static int hub_configure(struct usb_hub *hub,
 
        /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
        switch (wHubCharacteristics & HUB_CHAR_TTTT) {
-               case HUB_TTTT_8_BITS:
-                       if (hdev->descriptor.bDeviceProtocol != 0) {
-                               hub->tt.think_time = 666;
-                               dev_dbg(hub_dev, "TT requires at most %d "
-                                               "FS bit times (%d ns)\n",
-                                       8, hub->tt.think_time);
-                       }
-                       break;
-               case HUB_TTTT_16_BITS:
-                       hub->tt.think_time = 666 * 2;
-                       dev_dbg(hub_dev, "TT requires at most %d "
-                                       "FS bit times (%d ns)\n",
-                               16, hub->tt.think_time);
-                       break;
-               case HUB_TTTT_24_BITS:
-                       hub->tt.think_time = 666 * 3;
+       case HUB_TTTT_8_BITS:
+               if (hdev->descriptor.bDeviceProtocol != 0) {
+                       hub->tt.think_time = 666;
                        dev_dbg(hub_dev, "TT requires at most %d "
                                        "FS bit times (%d ns)\n",
-                               24, hub->tt.think_time);
-                       break;
-               case HUB_TTTT_32_BITS:
-                       hub->tt.think_time = 666 * 4;
-                       dev_dbg(hub_dev, "TT requires at most %d "
-                                       "FS bit times (%d ns)\n",
-                               32, hub->tt.think_time);
-                       break;
+                               8, hub->tt.think_time);
+               }
+               break;
+       case HUB_TTTT_16_BITS:
+               hub->tt.think_time = 666 * 2;
+               dev_dbg(hub_dev, "TT requires at most %d "
+                               "FS bit times (%d ns)\n",
+                       16, hub->tt.think_time);
+               break;
+       case HUB_TTTT_24_BITS:
+               hub->tt.think_time = 666 * 3;
+               dev_dbg(hub_dev, "TT requires at most %d "
+                               "FS bit times (%d ns)\n",
+                       24, hub->tt.think_time);
+               break;
+       case HUB_TTTT_32_BITS:
+               hub->tt.think_time = 666 * 4;
+               dev_dbg(hub_dev, "TT requires at most %d "
+                               "FS bit times (%d ns)\n",
+                       32, hub->tt.think_time);
+               break;
        }
 
        /* probe() zeroes hub->indicator[] */
@@ -1560,7 +1567,7 @@ static int hub_configure(struct usb_hub *hub,
 
        /* maybe cycle the hub leds */
        if (hub->has_indicators && blinkenlights)
-               hub->indicator [0] = INDICATOR_CYCLE;
+               hub->indicator[0] = INDICATOR_CYCLE;
 
        for (i = 0; i < hdev->maxchild; i++) {
                ret = usb_hub_create_port_device(hub, i + 1);
@@ -1978,7 +1985,7 @@ static void choose_devnum(struct usb_device *udev)
                if (devnum >= 128)
                        devnum = find_next_zero_bit(bus->devmap.devicemap,
                                                    128, 1);
-               bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
+               bus->devnum_next = (devnum >= 127 ? 1 : devnum + 1);
        }
        if (devnum < 128) {
                set_bit(devnum, bus->devmap.devicemap);
@@ -2018,8 +2025,8 @@ static void hub_free_dev(struct usb_device *udev)
  * Something got disconnected. Get rid of it and all of its children.
  *
  * If *pdev is a normal device then the parent hub must already be locked.
- * If *pdev is a root hub then this routine will acquire the
- * usb_bus_list_lock on behalf of the caller.
+ * If *pdev is a root hub then the caller must hold the usb_bus_list_lock,
+ * which protects the set of root hubs as well as the list of buses.
  *
  * Only hub drivers (including virtual root hub drivers for host
  * controllers) should ever call this.
@@ -2232,8 +2239,7 @@ static int usb_enumerate_device(struct usb_device *udev)
                udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
                udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
                udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-       }
-       else {
+       } else {
                /* read the standard strings and cache them if present */
                udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
                udev->manufacturer = usb_cache_string(udev,
@@ -2489,7 +2495,7 @@ error_device_descriptor:
        usb_autosuspend_device(usb_dev);
 error_autoresume:
 out_authorized:
-       usb_unlock_device(usb_dev);     // complements locktree
+       usb_unlock_device(usb_dev);     /* complements locktree */
        return result;
 }
 
@@ -3108,8 +3114,8 @@ static int finish_port_resume(struct usb_device *udev)
  retry_reset_resume:
                status = usb_reset_and_verify_device(udev);
 
-       /* 10.5.4.5 says be sure devices in the tree are still there.
-        * For now let's assume the device didn't go crazy on resume,
+       /* 10.5.4.5 says be sure devices in the tree are still there.
+        * For now let's assume the device didn't go crazy on resume,
         * and device drivers will know about any resume quirks.
         */
        if (status == 0) {
@@ -3211,7 +3217,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
        if (status == 0 && !port_is_suspended(hub, portstatus))
                goto SuspendCleared;
 
-       // dev_dbg(hub->intfdev, "resume port %d\n", port1);
+       /* dev_dbg(hub->intfdev, "resume port %d\n", port1); */
 
        set_bit(port1, hub->busy_bits);
 
@@ -3855,7 +3861,7 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
  * Between connect detection and reset signaling there must be a delay
  * of 100ms at least for debounce and power-settling.  The corresponding
  * timer shall restart whenever the downstream port detects a disconnect.
- * 
+ *
  * Apparently there are some bluetooth and irda-dongles and a number of
  * low-speed devices for which this debounce period may last over a second.
  * Not covered by the spec - but easy to deal with.
@@ -3949,6 +3955,32 @@ static int hub_set_address(struct usb_device *udev, int devnum)
        return retval;
 }
 
+/*
+ * There are reports of USB 3.0 devices that say they support USB 2.0 Link PM
+ * when they're plugged into a USB 2.0 port, but they don't work when LPM is
+ * enabled.
+ *
+ * Only enable USB 2.0 Link PM if the port is internal (hardwired), or the
+ * device says it supports the new USB 2.0 Link PM errata by setting the BESL
+ * support bit in the BOS descriptor.
+ */
+static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
+{
+       int connect_type;
+
+       if (!udev->usb2_hw_lpm_capable)
+               return;
+
+       connect_type = usb_get_hub_port_connect_type(udev->parent,
+                       udev->portnum);
+
+       if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) ||
+                       connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+               udev->usb2_hw_lpm_allowed = 1;
+               usb_set_usb2_hardware_lpm(udev, 1);
+       }
+}
+
 /* Reset device, (re)assign address, get device descriptor.
  * Device connection must be stable, no more debouncing needed.
  * Returns device in USB_STATE_ADDRESS, except on error.
@@ -4055,7 +4087,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                udev->tt = &hub->tt;
                udev->ttport = port1;
        }
+
        /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
         * Because device hardware and firmware is sometimes buggy in
         * this area, and this is how Linux has done it for ages.
@@ -4130,11 +4162,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
 #undef GET_DESCRIPTOR_BUFSIZE
                }
 
-               /*
-                * If device is WUSB, we already assigned an
-                * unauthorized address in the Connect Ack sequence;
-                * authorization will assign the final address.
-                */
+               /*
+                * If device is WUSB, we already assigned an
+                * unauthorized address in the Connect Ack sequence;
+                * authorization will assign the final address.
+                */
                if (udev->wusb == 0) {
                        for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
                                retval = hub_set_address(udev, devnum);
@@ -4163,7 +4195,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                        msleep(10);
                        if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))
                                break;
-               }
+               }
 
                retval = usb_get_device_descriptor(udev, 8);
                if (retval < 8) {
@@ -4219,7 +4251,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
                usb_ep0_reinit(udev);
        }
-  
+
        retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
        if (retval < (signed)sizeof(udev->descriptor)) {
                if (retval != -ENODEV)
@@ -4242,6 +4274,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        /* notify HCD that we have a device connected and addressed */
        if (hcd->driver->update_device)
                hcd->driver->update_device(hcd, udev);
+       hub_set_initial_usb2_lpm_policy(udev);
 fail:
        if (retval) {
                hub_port_disable(hub, port1, 0);
@@ -4316,7 +4349,7 @@ hub_power_remaining (struct usb_hub *hub)
        }
        if (remaining < 0) {
                dev_warn(hub->intfdev, "%dmA over power budget!\n",
-                       - remaining);
+                       -remaining);
                remaining = 0;
        }
        return remaining;
@@ -4427,7 +4460,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                        set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
 
                if (portstatus & USB_PORT_STAT_ENABLE)
-                       goto done;
+                       goto done;
                return;
        }
        if (hub_is_superspeed(hub->hdev))
@@ -4450,7 +4483,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                }
 
                usb_set_device_state(udev, USB_STATE_POWERED);
-               udev->bus_mA = hub->mA_per_port;
+               udev->bus_mA = hub->mA_per_port;
                udev->level = hdev->level + 1;
                udev->wusb = hub_is_wusb(hub);
 
@@ -4504,7 +4537,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                                goto loop_disable;
                        }
                }
+
                /* check for devices running slower than they could */
                if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
                                && udev->speed == USB_SPEED_FULL
@@ -4564,7 +4597,7 @@ loop:
                        dev_err(hub_dev, "unable to enumerate USB device on port %d\n",
                                        port1);
        }
+
 done:
        hub_port_disable(hub, port1, 1);
        if (hcd->driver->relinquish_port && !hub->hdev->parent)
@@ -4729,7 +4762,7 @@ static void hub_events(void)
                                 * EM interference sometimes causes badly
                                 * shielded USB devices to be shutdown by
                                 * the hub, this hack enables them again.
-                                * Works at least with mouse driver. 
+                                * Works at least with mouse driver.
                                 */
                                if (!(portstatus & USB_PORT_STAT_ENABLE)
                                    && !connect_change
@@ -4841,7 +4874,7 @@ static void hub_events(void)
                                dev_dbg(hub_dev, "over-current change\n");
                                clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
                                msleep(500);    /* Cool down */
-                               hub_power_on(hub, true);
+                               hub_power_on(hub, true);
                                hub_hub_status(hub, &status, &unused);
                                if (status & HUB_STATUS_OVERCURRENT)
                                        dev_err(hub_dev, "over-current "
@@ -4861,7 +4894,7 @@ static void hub_events(void)
                usb_unlock_device(hdev);
                kref_put(&hub->kref, hub_release);
 
-        } /* end while (1) */
+       } /* end while (1) */
 }
 
 static int hub_thread(void *__unused)
@@ -4886,7 +4919,7 @@ static int hub_thread(void *__unused)
 
 static const struct usb_device_id hub_id_table[] = {
     { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
-                  | USB_DEVICE_ID_MATCH_INT_CLASS,
+                       | USB_DEVICE_ID_MATCH_INT_CLASS,
       .idVendor = USB_VENDOR_GENESYS_LOGIC,
       .bInterfaceClass = USB_CLASS_HUB,
       .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
@@ -5086,6 +5119,12 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        }
        parent_hub = usb_hub_to_struct_hub(parent_hdev);
 
+       /* Disable USB2 hardware LPM.
+        * It will be re-enabled by the enumeration process.
+        */
+       if (udev->usb2_hw_lpm_enabled == 1)
+               usb_set_usb2_hardware_lpm(udev, 0);
+
        bos = udev->bos;
        udev->bos = NULL;
 
@@ -5120,13 +5159,13 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
 
        if (ret < 0)
                goto re_enumerate;
+
        /* Device might have changed firmware (DFU or similar) */
        if (descriptors_changed(udev, &descriptor, bos)) {
                dev_info(&udev->dev, "device firmware changed\n");
                udev->descriptor = descriptor;  /* for disconnect() calls */
                goto re_enumerate;
-       }
+       }
 
        /* Restore the device's previous configuration */
        if (!udev->actconfig)
@@ -5151,7 +5190,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                        udev->actconfig->desc.bConfigurationValue, ret);
                mutex_unlock(hcd->bandwidth_mutex);
                goto re_enumerate;
-       }
+       }
        mutex_unlock(hcd->bandwidth_mutex);
        usb_set_device_state(udev, USB_STATE_CONFIGURED);
 
@@ -5193,12 +5232,13 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
 
 done:
        /* Now that the alt settings are re-installed, enable LTM and LPM. */
+       usb_set_usb2_hardware_lpm(udev, 1);
        usb_unlocked_enable_lpm(udev);
        usb_enable_ltm(udev);
        usb_release_bos_descriptor(udev);
        udev->bos = bos;
        return 0;
+
 re_enumerate:
        /* LPM state doesn't matter when we're about to destroy the device. */
        hub_port_logical_disconnect(parent_hub, port1);
index 82927e1ed27d078f513a69727ebf7e55ef885ad8..bb315970e475e3bd90b5985c45a0afc0daf61fd2 100644 (file)
@@ -1182,8 +1182,12 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                        put_device(&dev->actconfig->interface[i]->dev);
                        dev->actconfig->interface[i] = NULL;
                }
+
+               if (dev->usb2_hw_lpm_enabled == 1)
+                       usb_set_usb2_hardware_lpm(dev, 0);
                usb_unlocked_disable_lpm(dev);
                usb_disable_ltm(dev);
+
                dev->actconfig = NULL;
                if (dev->state == USB_STATE_CONFIGURED)
                        usb_set_device_state(dev, USB_STATE_ADDRESS);
index 01fe36273f3b144cb1c1fe3306ebdf16459c605f..12924dbfdc2cb2c6b18319f4c4dec2679e3ae1bc 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/usb.h>
 #include <linux/usb/quirks.h>
+#include <linux/usb/hcd.h>
 #include "usb.h"
 
 /* Lists of quirky USB devices, split in device quirks and interface quirks.
@@ -161,6 +162,21 @@ static const struct usb_device_id usb_interface_quirk_list[] = {
        { }  /* terminating entry must be last */
 };
 
+static const struct usb_device_id usb_amd_resume_quirk_list[] = {
+       /* Lenovo Mouse with Pixart controller */
+       { USB_DEVICE(0x17ef, 0x602e), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Pixart Mouse */
+       { USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
+       { USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
+       { USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Optical Mouse M90/M100 */
+       { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       { }  /* terminating entry must be last */
+};
+
 static bool usb_match_any_interface(struct usb_device *udev,
                                    const struct usb_device_id *id)
 {
@@ -187,6 +203,18 @@ static bool usb_match_any_interface(struct usb_device *udev,
        return false;
 }
 
+static int usb_amd_resume_quirk(struct usb_device *udev)
+{
+       struct usb_hcd *hcd;
+
+       hcd = bus_to_hcd(udev->bus);
+       /* The device should be attached directly to root hub */
+       if (udev->level == 1 && hcd->amd_resume_bug == 1)
+               return 1;
+
+       return 0;
+}
+
 static u32 __usb_detect_quirks(struct usb_device *udev,
                               const struct usb_device_id *id)
 {
@@ -212,6 +240,15 @@ static u32 __usb_detect_quirks(struct usb_device *udev,
 void usb_detect_quirks(struct usb_device *udev)
 {
        udev->quirks = __usb_detect_quirks(udev, usb_quirk_list);
+
+       /*
+        * Pixart-based mice would trigger remote wakeup issue on AMD
+        * Yangtze chipset, so set them as RESET_RESUME flag.
+        */
+       if (usb_amd_resume_quirk(udev))
+               udev->quirks |= __usb_detect_quirks(udev,
+                               usb_amd_resume_quirk_list);
+
        if (udev->quirks)
                dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
                        udev->quirks);
index 6d2c8edb1ffe939e8c31b4a1eeb4585b27be619b..52a97adf02a04dcb39e866a131bfdfa5053efe51 100644 (file)
@@ -23,14 +23,16 @@ static ssize_t field##_show(struct device *dev,                             \
 {                                                                      \
        struct usb_device *udev;                                        \
        struct usb_host_config *actconfig;                              \
+       ssize_t rc = 0;                                                 \
                                                                        \
        udev = to_usb_device(dev);                                      \
+       usb_lock_device(udev);                                          \
        actconfig = udev->actconfig;                                    \
        if (actconfig)                                                  \
-               return sprintf(buf, format_string,                      \
+               rc = sprintf(buf, format_string,                        \
                                actconfig->desc.field);                 \
-       else                                                            \
-               return 0;                                               \
+       usb_unlock_device(udev);                                        \
+       return rc;                                                      \
 }                                                                      \
 
 #define usb_actconfig_attr(field, format_string)               \
@@ -45,12 +47,15 @@ static ssize_t bMaxPower_show(struct device *dev,
 {
        struct usb_device *udev;
        struct usb_host_config *actconfig;
+       ssize_t rc = 0;
 
        udev = to_usb_device(dev);
+       usb_lock_device(udev);
        actconfig = udev->actconfig;
-       if (!actconfig)
-               return 0;
-       return sprintf(buf, "%dmA\n", usb_get_max_power(udev, actconfig));
+       if (actconfig)
+               rc = sprintf(buf, "%dmA\n", usb_get_max_power(udev, actconfig));
+       usb_unlock_device(udev);
+       return rc;
 }
 static DEVICE_ATTR_RO(bMaxPower);
 
@@ -59,12 +64,15 @@ static ssize_t configuration_show(struct device *dev,
 {
        struct usb_device *udev;
        struct usb_host_config *actconfig;
+       ssize_t rc = 0;
 
        udev = to_usb_device(dev);
+       usb_lock_device(udev);
        actconfig = udev->actconfig;
-       if ((!actconfig) || (!actconfig->string))
-               return 0;
-       return sprintf(buf, "%s\n", actconfig->string);
+       if (actconfig && actconfig->string)
+               rc = sprintf(buf, "%s\n", actconfig->string);
+       usb_unlock_device(udev);
+       return rc;
 }
 static DEVICE_ATTR_RO(configuration);
 
@@ -390,7 +398,8 @@ static DEVICE_ATTR_RW(autosuspend);
 static const char on_string[] = "on";
 static const char auto_string[] = "auto";
 
-static void warn_level(void) {
+static void warn_level(void)
+{
        static int level_warned;
 
        if (!level_warned) {
@@ -449,7 +458,7 @@ static ssize_t usb2_hardware_lpm_show(struct device *dev,
        struct usb_device *udev = to_usb_device(dev);
        const char *p;
 
-       if (udev->usb2_hw_lpm_enabled == 1)
+       if (udev->usb2_hw_lpm_allowed == 1)
                p = "enabled";
        else
                p = "disabled";
@@ -469,8 +478,10 @@ static ssize_t usb2_hardware_lpm_store(struct device *dev,
 
        ret = strtobool(buf, &value);
 
-       if (!ret)
+       if (!ret) {
+               udev->usb2_hw_lpm_allowed = value;
                ret = usb_set_usb2_hardware_lpm(udev, value);
+       }
 
        usb_unlock_device(udev);
 
@@ -644,7 +655,7 @@ static ssize_t authorized_store(struct device *dev,
                result = usb_deauthorize_device(usb_dev);
        else
                result = usb_authorize_device(usb_dev);
-       return result < 0? result : size;
+       return result < 0 ? result : size;
 }
 static DEVICE_ATTR_IGNORE_LOCKDEP(authorized, S_IRUGO | S_IWUSR,
                                  authorized_show, authorized_store);
@@ -764,6 +775,7 @@ read_descriptors(struct file *filp, struct kobject *kobj,
         * Following that are the raw descriptor entries for all the
         * configurations (config plus subsidiary descriptors).
         */
+       usb_lock_device(udev);
        for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations &&
                        nleft > 0; ++cfgno) {
                if (cfgno < 0) {
@@ -784,6 +796,7 @@ read_descriptors(struct file *filp, struct kobject *kobj,
                        off -= srclen;
                }
        }
+       usb_unlock_device(udev);
        return count - nleft;
 }
 
@@ -870,9 +883,7 @@ static ssize_t interface_show(struct device *dev, struct device_attribute *attr,
        char *string;
 
        intf = to_usb_interface(dev);
-       string = intf->cur_altsetting->string;
-       barrier();              /* The altsetting might change! */
-
+       string = ACCESS_ONCE(intf->cur_altsetting->string);
        if (!string)
                return 0;
        return sprintf(buf, "%s\n", string);
@@ -888,7 +899,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 
        intf = to_usb_interface(dev);
        udev = interface_to_usbdev(intf);
-       alt = intf->cur_altsetting;
+       alt = ACCESS_ONCE(intf->cur_altsetting);
 
        return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
                        "ic%02Xisc%02Xip%02Xin%02X\n",
@@ -909,23 +920,14 @@ static ssize_t supports_autosuspend_show(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
 {
-       struct usb_interface *intf;
-       struct usb_device *udev;
-       int ret;
+       int s;
 
-       intf = to_usb_interface(dev);
-       udev = interface_to_usbdev(intf);
-
-       usb_lock_device(udev);
+       device_lock(dev);
        /* Devices will be autosuspended even when an interface isn't claimed */
-       if (!intf->dev.driver ||
-                       to_usb_driver(intf->dev.driver)->supports_autosuspend)
-               ret = sprintf(buf, "%u\n", 1);
-       else
-               ret = sprintf(buf, "%u\n", 0);
-       usb_unlock_device(udev);
+       s = (!dev->driver || to_usb_driver(dev->driver)->supports_autosuspend);
+       device_unlock(dev);
 
-       return ret;
+       return sprintf(buf, "%u\n", s);
 }
 static DEVICE_ATTR_RO(supports_autosuspend);
 
index c12bc790a6a702de065087b9d4c07563f3bb54b1..e62208356c8915d6fc565173f4561500cb5261a7 100644 (file)
@@ -138,13 +138,19 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
 }
 EXPORT_SYMBOL_GPL(usb_anchor_urb);
 
+static int usb_anchor_check_wakeup(struct usb_anchor *anchor)
+{
+       return atomic_read(&anchor->suspend_wakeups) == 0 &&
+               list_empty(&anchor->urb_list);
+}
+
 /* Callers must hold anchor->lock */
 static void __usb_unanchor_urb(struct urb *urb, struct usb_anchor *anchor)
 {
        urb->anchor = NULL;
        list_del(&urb->anchor_list);
        usb_put_urb(urb);
-       if (list_empty(&anchor->urb_list))
+       if (usb_anchor_check_wakeup(anchor))
                wake_up(&anchor->wait);
 }
 
@@ -845,6 +851,39 @@ void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
 }
 EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);
 
+/**
+ * usb_anchor_suspend_wakeups
+ * @anchor: the anchor you want to suspend wakeups on
+ *
+ * Call this to stop the last urb being unanchored from waking up any
+ * usb_wait_anchor_empty_timeout waiters. This is used in the hcd urb give-
+ * back path to delay waking up until after the completion handler has run.
+ */
+void usb_anchor_suspend_wakeups(struct usb_anchor *anchor)
+{
+       if (anchor)
+               atomic_inc(&anchor->suspend_wakeups);
+}
+EXPORT_SYMBOL_GPL(usb_anchor_suspend_wakeups);
+
+/**
+ * usb_anchor_resume_wakeups
+ * @anchor: the anchor you want to resume wakeups on
+ *
+ * Allow usb_wait_anchor_empty_timeout waiters to be woken up again, and
+ * wake up any current waiters if the anchor is empty.
+ */
+void usb_anchor_resume_wakeups(struct usb_anchor *anchor)
+{
+       if (!anchor)
+               return;
+
+       atomic_dec(&anchor->suspend_wakeups);
+       if (usb_anchor_check_wakeup(anchor))
+               wake_up(&anchor->wait);
+}
+EXPORT_SYMBOL_GPL(usb_anchor_resume_wakeups);
+
 /**
  * usb_wait_anchor_empty_timeout - wait for an anchor to be unused
  * @anchor: the anchor you want to become unused
@@ -858,7 +897,8 @@ EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);
 int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
                                  unsigned int timeout)
 {
-       return wait_event_timeout(anchor->wait, list_empty(&anchor->urb_list),
+       return wait_event_timeout(anchor->wait,
+                                 usb_anchor_check_wakeup(anchor),
                                  msecs_to_jiffies(timeout));
 }
 EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
index 0a6ee2e70b25afecaae6dfce65a03fe22e40ca04..4d1144990d4c848362c2f86cf8aa1039c3d70923 100644 (file)
@@ -497,7 +497,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
                dev->authorized = 1;
        else {
                dev->authorized = usb_hcd->authorized_default;
-               dev->wusb = usb_bus_is_wusb(bus)? 1 : 0;
+               dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
        }
        return dev;
 }
index 823857767a16f3384730dcf1f90c42f8eedc3588..c49383669cd87ce4dda9b996fd9b3f1caf03bd2b 100644 (file)
@@ -35,6 +35,7 @@ extern int usb_get_device_descriptor(struct usb_device *dev,
                unsigned int size);
 extern int usb_get_bos_descriptor(struct usb_device *dev);
 extern void usb_release_bos_descriptor(struct usb_device *dev);
+extern int usb_device_supports_lpm(struct usb_device *udev);
 extern char *usb_cache_string(struct usb_device *udev, int index);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 extern int usb_choose_configuration(struct usb_device *udev);
index 474162e9d01d2e03bfaf52402a8cfc1b4461c304..74f9cf02da070a6d1c23b643a56f76e3264fb8cd 100644 (file)
@@ -584,7 +584,7 @@ static int dwc3_remove(struct platform_device *pdev)
        usb_phy_set_suspend(dwc->usb2_phy, 1);
        usb_phy_set_suspend(dwc->usb3_phy, 1);
 
-       pm_runtime_put(&pdev->dev);
+       pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        dwc3_debugfs_exit(dwc);
@@ -691,7 +691,6 @@ static int dwc3_resume(struct device *dev)
 
        usb_phy_init(dwc->usb3_phy);
        usb_phy_init(dwc->usb2_phy);
-       msleep(100);
 
        spin_lock_irqsave(&dwc->lock, flags);
 
index 2e252aae51ca0bcc5da41b3251c45cec91cced7d..31443aeedcdbf374a6d663e69087ba18f9c37612 100644 (file)
@@ -165,7 +165,6 @@ static int dwc3_pci_probe(struct pci_dev *pci,
        return 0;
 
 err3:
-       pci_set_drvdata(pci, NULL);
        platform_device_put(dwc3);
 err1:
        pci_disable_device(pci);
@@ -180,7 +179,6 @@ static void dwc3_pci_remove(struct pci_dev *pci)
        platform_device_unregister(glue->dwc3);
        platform_device_unregister(glue->usb2_phy);
        platform_device_unregister(glue->usb3_phy);
-       pci_set_drvdata(pci, NULL);
        pci_disable_device(pci);
 }
 
index 7fa93f4bc507de41782486301760506e18f44a03..95f7649c71a78745692a63bafd1527daacda52e3 100644 (file)
@@ -352,7 +352,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
                break;
        default:
                return -EINVAL;
-       };
+       }
 
        response_pkt = (__le16 *) dwc->setup_buf;
        *response_pkt = cpu_to_le16(usb_status);
@@ -470,7 +470,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
        default:
                return -EINVAL;
-       };
+       }
 
        return 0;
 }
@@ -709,7 +709,7 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
                dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
                ret = dwc3_ep0_delegate_req(dwc, ctrl);
                break;
-       };
+       }
 
        return ret;
 }
index 5e29ddeb4d33d0c65f29116dca2ddbe42ea5407f..8cfc3191be50aee8f9157ba95e84c49446d1ae55 100644 (file)
@@ -568,10 +568,6 @@ try_again:
                dbgp_printk("Could not find attached debug device\n");
                goto err;
        }
-       if (ret < 0) {
-               dbgp_printk("Attached device is not a debug device\n");
-               goto err;
-       }
        dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;
        dbgp_endpoint_in = dbgp_desc.bDebugInEndpoint;
 
index 48cddf3cd6b889b420d45da418e852ecd671d2c5..a91e6422f93021f912042298a99cdde36362b09b 100644 (file)
@@ -58,6 +58,20 @@ config USB_GADGET_DEBUG
           trying to track down.  Never enable these messages for a
           production build.
 
+config USB_GADGET_VERBOSE
+       bool "Verbose debugging Messages (DEVELOPMENT)"
+       depends on USB_GADGET_DEBUG
+       help
+          Many controller and gadget drivers will print verbose debugging
+          messages if you use this option to ask for those messages.
+
+          Avoid enabling these messages, even if you're actively
+          debugging such a driver.  Many drivers will emit so many
+          messages that the driver timings are affected, which will
+          either create new failure modes or remove the one you're
+          trying to track down.  Never enable these messages for a
+          production build.
+
 config USB_GADGET_DEBUG_FILES
        boolean "Debugging information files (DEVELOPMENT)"
        depends on PROC_FS
@@ -525,6 +539,9 @@ config USB_F_SUBSET
 config USB_F_RNDIS
        tristate
 
+config USB_F_MASS_STORAGE
+       tristate
+
 choice
        tristate "USB Gadget Drivers"
        default USB_ETH
@@ -662,6 +679,16 @@ config USB_CONFIGFS_PHONET
        help
          The Phonet protocol implementation for USB device.
 
+config USB_CONFIGFS_MASS_STORAGE
+       boolean "Mass storage"
+       depends on USB_CONFIGFS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+         device (in much the same way as the "loop" device driver),
+         specified as a module parameter or sysfs option.
+
 config USB_ZERO
        tristate "Gadget Zero (DEVELOPMENT)"
        select USB_LIBCOMPOSITE
@@ -878,6 +905,7 @@ config USB_MASS_STORAGE
        tristate "Mass Storage Gadget"
        depends on BLOCK
        select USB_LIBCOMPOSITE
+       select USB_F_MASS_STORAGE
        help
          The Mass Storage Gadget acts as a USB Mass Storage disk drive.
          As its storage repository it can use a regular file or a block
@@ -1001,6 +1029,7 @@ config USB_G_ACM_MS
        select USB_LIBCOMPOSITE
        select USB_U_SERIAL
        select USB_F_ACM
+       select USB_F_MASS_STORAGE
        help
          This driver provides two functions in one configuration:
          a mass storage, and a CDC ACM (serial port) link.
@@ -1015,8 +1044,8 @@ config USB_G_MULTI
        select USB_LIBCOMPOSITE
        select USB_U_SERIAL
        select USB_U_ETHER
-       select USB_U_RNDIS
        select USB_F_ACM
+       select USB_F_MASS_STORAGE
        help
          The Multifunction Composite Gadget provides Ethernet (RNDIS
          and/or CDC Ethernet), mass storage and ACM serial link
@@ -1035,6 +1064,8 @@ config USB_G_MULTI
 config USB_G_MULTI_RNDIS
        bool "RNDIS + CDC Serial + Storage configuration"
        depends on USB_G_MULTI
+       select USB_U_RNDIS
+       select USB_F_RNDIS
        default y
        help
          This option enables a configuration with RNDIS, CDC Serial and
@@ -1048,6 +1079,7 @@ config USB_G_MULTI_CDC
        bool "CDC Ethernet + CDC Serial + Storage configuration"
        depends on USB_G_MULTI
        default n
+       select USB_F_ECM
        help
          This option enables a configuration with CDC Ethernet (ECM), CDC
          Serial and Mass Storage functions available in the Multifunction
index 386db9daf1d9a254528deb6bd2273ef92b981e94..f1af39603d4d2f4132a06e346ab3772bf12999ee 100644 (file)
@@ -1,7 +1,8 @@
 #
 # USB peripheral controller drivers
 #
-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
+ccflags-$(CONFIG_USB_GADGET_DEBUG)     := -DDEBUG
+ccflags-$(CONFIG_USB_GADGET_VERBOSE)   += -DVERBOSE_DEBUG
 
 obj-$(CONFIG_USB_GADGET)       += udc-core.o
 obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o
@@ -60,6 +61,8 @@ usb_f_ecm_subset-y            := f_subset.o
 obj-$(CONFIG_USB_F_SUBSET)     += usb_f_ecm_subset.o
 usb_f_rndis-y                  := f_rndis.o
 obj-$(CONFIG_USB_F_RNDIS)      += usb_f_rndis.o
+usb_f_mass_storage-y           := f_mass_storage.o storage_common.o
+obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 
 #
 # USB gadget drivers
index 4b947bb50f62acdd17bebee987b5b14faa26e253..7bfa134fe0e3bd56e84b8adb16160b4124b20f21 100644 (file)
 #define ACM_MS_VENDOR_NUM      0x1d6b  /* Linux Foundation */
 #define ACM_MS_PRODUCT_NUM     0x0106  /* Composite Gadget: ACM + MS*/
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * Kbuild is not very cooperative with respect to linking separately
- * compiled library objects into one module.  So for now we won't use
- * separate compilation ... ensuring init/exit sections work to shrink
- * the runtime footprint, and giving us at least some parts of what
- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
- */
-#include "f_mass_storage.c"
+#include "f_mass_storage.h"
 
 /*-------------------------------------------------------------------------*/
 USB_GADGET_COMPOSITE_OPTIONS();
@@ -104,18 +95,35 @@ static struct usb_gadget_strings *dev_strings[] = {
 /****************************** Configurations ******************************/
 
 static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
-FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
 
-static struct fsg_common fsg_common;
+static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+
+#else
+
+/*
+ * Number of buffers we will use.
+ * 2 is usually enough for good buffering pipeline
+ */
+#define fsg_num_buffers        CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+
+#endif /* CONFIG_USB_DEBUG */
+
+FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
 
 /*-------------------------------------------------------------------------*/
 static struct usb_function *f_acm;
 static struct usb_function_instance *f_acm_inst;
+
+static struct usb_function_instance *fi_msg;
+static struct usb_function *f_msg;
+
 /*
  * We _always_ have both ACM and mass storage functions.
  */
 static int __init acm_ms_do_config(struct usb_configuration *c)
 {
+       struct fsg_opts *opts;
        int     status;
 
        if (gadget_is_otg(c->cdev->gadget)) {
@@ -123,31 +131,37 @@ static int __init acm_ms_do_config(struct usb_configuration *c)
                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       f_acm_inst = usb_get_function_instance("acm");
-       if (IS_ERR(f_acm_inst))
-               return PTR_ERR(f_acm_inst);
+       opts = fsg_opts_from_func_inst(fi_msg);
 
        f_acm = usb_get_function(f_acm_inst);
-       if (IS_ERR(f_acm)) {
-               status = PTR_ERR(f_acm);
-               goto err_func;
+       if (IS_ERR(f_acm))
+               return PTR_ERR(f_acm);
+
+       f_msg = usb_get_function(fi_msg);
+       if (IS_ERR(f_msg)) {
+               status = PTR_ERR(f_msg);
+               goto put_acm;
        }
 
        status = usb_add_function(c, f_acm);
        if (status < 0)
-               goto err_conf;
+               goto put_msg;
 
-       status = fsg_bind_config(c->cdev, c, &fsg_common);
-       if (status < 0)
-               goto err_fsg;
+       status = fsg_common_run_thread(opts->common);
+       if (status)
+               goto remove_acm;
+
+       status = usb_add_function(c, f_msg);
+       if (status)
+               goto remove_acm;
 
        return 0;
-err_fsg:
+remove_acm:
        usb_remove_function(c, f_acm);
-err_conf:
+put_msg:
+       usb_put_function(f_msg);
+put_acm:
        usb_put_function(f_acm);
-err_func:
-       usb_put_function_instance(f_acm_inst);
        return status;
 }
 
@@ -163,45 +177,82 @@ static struct usb_configuration acm_ms_config_driver = {
 static int __init acm_ms_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget       *gadget = cdev->gadget;
+       struct fsg_opts         *opts;
+       struct fsg_config       config;
        int                     status;
-       void                    *retp;
 
-       /* set up mass storage function */
-       retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
-       if (IS_ERR(retp)) {
-               status = PTR_ERR(retp);
-               return PTR_ERR(retp);
+       f_acm_inst = usb_get_function_instance("acm");
+       if (IS_ERR(f_acm_inst))
+               return PTR_ERR(f_acm_inst);
+
+       fi_msg = usb_get_function_instance("mass_storage");
+       if (IS_ERR(fi_msg)) {
+               status = PTR_ERR(fi_msg);
+               goto fail_get_msg;
        }
 
+       /* set up mass storage function */
+       fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
+       opts = fsg_opts_from_func_inst(fi_msg);
+
+       opts->no_configfs = true;
+       status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
+       if (status)
+               goto fail;
+
+       status = fsg_common_set_nluns(opts->common, config.nluns);
+       if (status)
+               goto fail_set_nluns;
+
+       status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
+       if (status)
+               goto fail_set_cdev;
+
+       fsg_common_set_sysfs(opts->common, true);
+       status = fsg_common_create_luns(opts->common, &config);
+       if (status)
+               goto fail_set_cdev;
+
+       fsg_common_set_inquiry_string(opts->common, config.vendor_name,
+                                     config.product_name);
        /*
         * Allocate string descriptor numbers ... note that string
         * contents can be overridden by the composite_dev glue.
         */
        status = usb_string_ids_tab(cdev, strings_dev);
        if (status < 0)
-               goto fail1;
+               goto fail_string_ids;
        device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
        device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
 
        /* register our configuration */
        status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config);
        if (status < 0)
-               goto fail1;
+               goto fail_string_ids;
 
        usb_composite_overwrite_options(cdev, &coverwrite);
        dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
                        DRIVER_DESC);
-       fsg_common_put(&fsg_common);
        return 0;
 
        /* error recovery */
-fail1:
-       fsg_common_put(&fsg_common);
+fail_string_ids:
+       fsg_common_remove_luns(opts->common);
+fail_set_cdev:
+       fsg_common_free_luns(opts->common);
+fail_set_nluns:
+       fsg_common_free_buffers(opts->common);
+fail:
+       usb_put_function_instance(fi_msg);
+fail_get_msg:
+       usb_put_function_instance(f_acm_inst);
        return status;
 }
 
 static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
 {
+       usb_put_function(f_msg);
+       usb_put_function_instance(fi_msg);
        usb_put_function(f_acm);
        usb_put_function_instance(f_acm_inst);
        return 0;
index a9a4346c83aae221776a297eff8330aab6bb733c..54a1e2954cea9d53384085e04b91d65418fb575e 100644 (file)
@@ -3078,8 +3078,6 @@ static void udc_pci_remove(struct pci_dev *pdev)
        if (dev->active)
                pci_disable_device(pdev);
 
-       pci_set_drvdata(pdev, NULL);
-
        udc_remove(dev);
 }
 
index d4f0f3305759876a2fc1e81cb96e0ade69918eca..3e7ae707f691c4b0cf4b701024d8df0af4a5bb69 100644 (file)
@@ -354,7 +354,7 @@ static u8 encode_bMaxPower(enum usb_device_speed speed,
                return DIV_ROUND_UP(val, 8);
        default:
                return DIV_ROUND_UP(val, 2);
-       };
+       }
 }
 
 static int config_buf(struct usb_configuration *config,
index 8f0d6141e5e6c2b2c1acfb53b769438f32d7907a..25885112fa35b0cc5b0b25733c91d91365606fb8 100644 (file)
@@ -557,7 +557,7 @@ static struct config_group *function_make(
 
        fi = usb_get_function_instance(func_name);
        if (IS_ERR(fi))
-               return ERR_PTR(PTR_ERR(fi));
+               return ERR_CAST(fi);
 
        ret = config_item_set_name(&fi->group.cg_item, name);
        if (ret) {
@@ -991,6 +991,14 @@ static struct configfs_subsystem gadget_subsys = {
        .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex),
 };
 
+void unregister_gadget_item(struct config_item *item)
+{
+       struct gadget_info *gi = to_gadget_info(item);
+
+       unregister_gadget(gi);
+}
+EXPORT_SYMBOL(unregister_gadget_item);
+
 static int __init gadget_cfs_init(void)
 {
        int ret;
diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h
new file mode 100644 (file)
index 0000000..a7b564a
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef USB__GADGET__CONFIGFS__H
+#define USB__GADGET__CONFIGFS__H
+
+void unregister_gadget_item(struct config_item *item);
+
+#endif /*  USB__GADGET__CONFIGFS__H */
index b8a2376971a47aa357794117f74390aaee01a594..8f4dae3109235624e9e60c04a837aab7f6571e4a 100644 (file)
@@ -544,7 +544,7 @@ static int dummy_enable(struct usb_ep *_ep,
                 default:
                         val = "ctrl";
                         break;
-                }; val; }),
+                } val; }),
                max, ep->stream_en ? "enabled" : "disabled");
 
        /* at this point real hardware should be NAKing transfers
@@ -2271,7 +2271,7 @@ static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb)
                default:
                        s = "?";
                        break;
-                }; s; }),
+                } s; }),
                ep, ep ? (usb_pipein(urb->pipe) ? "in" : "out") : "",
                ({ char *s; \
                switch (usb_pipetype(urb->pipe)) { \
@@ -2287,7 +2287,7 @@ static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb)
                default: \
                        s = "-iso"; \
                        break; \
-               }; s; }),
+               } s; }),
                urb->actual_length, urb->transfer_buffer_length);
 }
 
index a01d7d38c01685135a503885342be7f9ec63ebbd..a03ba2c83589ee15f9c1880d17f1aa133eb47f29 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/freezer.h>
+#include <linux/module.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/composite.h>
 
 #include "gadget_chips.h"
+#include "configfs.h"
 
 
 /*------------------------------------------------------------------------*/
 
 static const char fsg_string_interface[] = "Mass Storage";
 
-#include "storage_common.c"
+#include "storage_common.h"
+#include "f_mass_storage.h"
 
+/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+static struct usb_string               fsg_strings[] = {
+       {FSG_STRING_INTERFACE,          fsg_string_interface},
+       {}
+};
+
+static struct usb_gadget_strings       fsg_stringtab = {
+       .language       = 0x0409,               /* en-us */
+       .strings        = fsg_strings,
+};
+
+static struct usb_gadget_strings *fsg_strings_array[] = {
+       &fsg_stringtab,
+       NULL,
+};
 
 /*-------------------------------------------------------------------------*/
 
 struct fsg_dev;
 struct fsg_common;
 
-/* FSF callback functions */
-struct fsg_operations {
-       /*
-        * Callback function to call when thread exits.  If no
-        * callback is set or it returns value lower then zero MSF
-        * will force eject all LUNs it operates on (including those
-        * marked as non-removable or with prevent_medium_removal flag
-        * set).
-        */
-       int (*thread_exits)(struct fsg_common *common);
-};
-
 /* Data shared by all the FSG instances. */
 struct fsg_common {
        struct usb_gadget       *gadget;
@@ -268,13 +274,14 @@ struct fsg_common {
        struct fsg_buffhd       *next_buffhd_to_fill;
        struct fsg_buffhd       *next_buffhd_to_drain;
        struct fsg_buffhd       *buffhds;
+       unsigned int            fsg_num_buffers;
 
        int                     cmnd_size;
        u8                      cmnd[MAX_COMMAND_SIZE];
 
        unsigned int            nluns;
        unsigned int            lun;
-       struct fsg_lun          *luns;
+       struct fsg_lun          **luns;
        struct fsg_lun          *curlun;
 
        unsigned int            bulk_out_maxpacket;
@@ -294,6 +301,7 @@ struct fsg_common {
        unsigned int            short_packet_received:1;
        unsigned int            bad_lun_okay:1;
        unsigned int            running:1;
+       unsigned int            sysfs:1;
 
        int                     thread_wakeup_needed;
        struct completion       thread_notifier;
@@ -313,27 +321,6 @@ struct fsg_common {
        struct kref             ref;
 };
 
-struct fsg_config {
-       unsigned nluns;
-       struct fsg_lun_config {
-               const char *filename;
-               char ro;
-               char removable;
-               char cdrom;
-               char nofua;
-       } luns[FSG_MAX_LUNS];
-
-       /* Callback functions. */
-       const struct fsg_operations     *ops;
-       /* Gadget's private data. */
-       void                    *private_data;
-
-       const char *vendor_name;                /*  8 characters or less */
-       const char *product_name;               /* 16 characters or less */
-
-       char                    can_stall;
-};
-
 struct fsg_dev {
        struct usb_function     function;
        struct usb_gadget       *gadget;        /* Copy of cdev->gadget */
@@ -2172,7 +2159,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                common->data_dir = DATA_DIR_NONE;
        common->lun = cbw->Lun;
        if (common->lun < common->nluns)
-               common->curlun = &common->luns[common->lun];
+               common->curlun = common->luns[common->lun];
        else
                common->curlun = NULL;
        common->tag = cbw->Tag;
@@ -2244,7 +2231,7 @@ reset:
        if (common->fsg) {
                fsg = common->fsg;
 
-               for (i = 0; i < fsg_num_buffers; ++i) {
+               for (i = 0; i < common->fsg_num_buffers; ++i) {
                        struct fsg_buffhd *bh = &common->buffhds[i];
 
                        if (bh->inreq) {
@@ -2303,7 +2290,7 @@ reset:
        clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
 
        /* Allocate the requests */
-       for (i = 0; i < fsg_num_buffers; ++i) {
+       for (i = 0; i < common->fsg_num_buffers; ++i) {
                struct fsg_buffhd       *bh = &common->buffhds[i];
 
                rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
@@ -2320,7 +2307,9 @@ reset:
 
        common->running = 1;
        for (i = 0; i < common->nluns; ++i)
-               common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+               if (common->luns[i])
+                       common->luns[i]->unit_attention_data =
+                               SS_RESET_OCCURRED;
        return rc;
 }
 
@@ -2372,7 +2361,7 @@ static void handle_exception(struct fsg_common *common)
 
        /* Cancel all the pending transfers */
        if (likely(common->fsg)) {
-               for (i = 0; i < fsg_num_buffers; ++i) {
+               for (i = 0; i < common->fsg_num_buffers; ++i) {
                        bh = &common->buffhds[i];
                        if (bh->inreq_busy)
                                usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
@@ -2384,7 +2373,7 @@ static void handle_exception(struct fsg_common *common)
                /* Wait until everything is idle */
                for (;;) {
                        int num_active = 0;
-                       for (i = 0; i < fsg_num_buffers; ++i) {
+                       for (i = 0; i < common->fsg_num_buffers; ++i) {
                                bh = &common->buffhds[i];
                                num_active += bh->inreq_busy + bh->outreq_busy;
                        }
@@ -2407,7 +2396,7 @@ static void handle_exception(struct fsg_common *common)
         */
        spin_lock_irq(&common->lock);
 
-       for (i = 0; i < fsg_num_buffers; ++i) {
+       for (i = 0; i < common->fsg_num_buffers; ++i) {
                bh = &common->buffhds[i];
                bh->state = BUF_STATE_EMPTY;
        }
@@ -2420,7 +2409,9 @@ static void handle_exception(struct fsg_common *common)
                common->state = FSG_STATE_STATUS_PHASE;
        else {
                for (i = 0; i < common->nluns; ++i) {
-                       curlun = &common->luns[i];
+                       curlun = common->luns[i];
+                       if (!curlun)
+                               continue;
                        curlun->prevent_medium_removal = 0;
                        curlun->sense_data = SS_NO_SENSE;
                        curlun->unit_attention_data = SS_NO_SENSE;
@@ -2462,8 +2453,9 @@ static void handle_exception(struct fsg_common *common)
                 * CONFIG_CHANGE cases.
                 */
                /* for (i = 0; i < common->nluns; ++i) */
-               /*      common->luns[i].unit_attention_data = */
-               /*              SS_RESET_OCCURRED;  */
+               /*      if (common->luns[i]) */
+               /*              common->luns[i]->unit_attention_data = */
+               /*                      SS_RESET_OCCURRED;  */
                break;
 
        case FSG_STATE_CONFIG_CHANGE:
@@ -2559,12 +2551,13 @@ static int fsg_main_thread(void *common_)
 
        if (!common->ops || !common->ops->thread_exits
         || common->ops->thread_exits(common) < 0) {
-               struct fsg_lun *curlun = common->luns;
+               struct fsg_lun **curlun_it = common->luns;
                unsigned i = common->nluns;
 
                down_write(&common->filesem);
-               for (; i--; ++curlun) {
-                       if (!fsg_lun_is_open(curlun))
+               for (; i--; ++curlun_it) {
+                       struct fsg_lun *curlun = *curlun_it;
+                       if (!curlun || !fsg_lun_is_open(curlun))
                                continue;
 
                        fsg_lun_close(curlun);
@@ -2580,6 +2573,56 @@ static int fsg_main_thread(void *common_)
 
 /*************************** DEVICE ATTRIBUTES ***************************/
 
+static ssize_t ro_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+
+       return fsg_show_ro(curlun, buf);
+}
+
+static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+
+       return fsg_show_nofua(curlun, buf);
+}
+
+static ssize_t file_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+
+       return fsg_show_file(curlun, filesem, buf);
+}
+
+static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+
+       return fsg_store_ro(curlun, filesem, buf, count);
+}
+
+static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+
+       return fsg_store_nofua(curlun, buf, count);
+}
+
+static ssize_t file_store(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+       struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+
+       return fsg_store_file(curlun, filesem, buf, count);
+}
+
 static DEVICE_ATTR_RW(ro);
 static DEVICE_ATTR_RW(nofua);
 static DEVICE_ATTR_RW(file);
@@ -2597,221 +2640,422 @@ static void fsg_lun_release(struct device *dev)
        /* Nothing needs to be done */
 }
 
-static inline void fsg_common_get(struct fsg_common *common)
+void fsg_common_get(struct fsg_common *common)
 {
        kref_get(&common->ref);
 }
+EXPORT_SYMBOL_GPL(fsg_common_get);
 
-static inline void fsg_common_put(struct fsg_common *common)
+void fsg_common_put(struct fsg_common *common)
 {
        kref_put(&common->ref, fsg_common_release);
 }
+EXPORT_SYMBOL_GPL(fsg_common_put);
 
-static struct fsg_common *fsg_common_init(struct fsg_common *common,
-                                         struct usb_composite_dev *cdev,
-                                         struct fsg_config *cfg)
+/* check if fsg_num_buffers is within a valid range */
+static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
 {
-       struct usb_gadget *gadget = cdev->gadget;
-       struct fsg_buffhd *bh;
-       struct fsg_lun *curlun;
-       struct fsg_lun_config *lcfg;
-       int nluns, i, rc;
-       char *pathbuf;
-
-       rc = fsg_num_buffers_validate();
-       if (rc != 0)
-               return ERR_PTR(rc);
-
-       /* Find out how many LUNs there should be */
-       nluns = cfg->nluns;
-       if (nluns < 1 || nluns > FSG_MAX_LUNS) {
-               dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns);
-               return ERR_PTR(-EINVAL);
-       }
+       if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+               return 0;
+       pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
+              fsg_num_buffers, 2, 4);
+       return -EINVAL;
+}
 
-       /* Allocate? */
+static struct fsg_common *fsg_common_setup(struct fsg_common *common)
+{
        if (!common) {
-               common = kzalloc(sizeof *common, GFP_KERNEL);
+               common = kzalloc(sizeof(*common), GFP_KERNEL);
                if (!common)
                        return ERR_PTR(-ENOMEM);
                common->free_storage_on_release = 1;
        } else {
-               memset(common, 0, sizeof *common);
                common->free_storage_on_release = 0;
        }
+       init_rwsem(&common->filesem);
+       spin_lock_init(&common->lock);
+       kref_init(&common->ref);
+       init_completion(&common->thread_notifier);
+       init_waitqueue_head(&common->fsg_wait);
+       common->state = FSG_STATE_TERMINATED;
 
-       common->buffhds = kcalloc(fsg_num_buffers,
-                                 sizeof *(common->buffhds), GFP_KERNEL);
-       if (!common->buffhds) {
-               if (common->free_storage_on_release)
-                       kfree(common);
-               return ERR_PTR(-ENOMEM);
+       return common;
+}
+
+void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+{
+       common->sysfs = sysfs;
+}
+EXPORT_SYMBOL_GPL(fsg_common_set_sysfs);
+
+static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+{
+       if (buffhds) {
+               struct fsg_buffhd *bh = buffhds;
+               while (n--) {
+                       kfree(bh->buf);
+                       ++bh;
+               }
+               kfree(buffhds);
        }
+}
 
-       common->ops = cfg->ops;
-       common->private_data = cfg->private_data;
+int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n)
+{
+       struct fsg_buffhd *bh, *buffhds;
+       int i, rc;
 
-       common->gadget = gadget;
-       common->ep0 = gadget->ep0;
-       common->ep0req = cdev->req;
-       common->cdev = cdev;
+       rc = fsg_num_buffers_validate(n);
+       if (rc != 0)
+               return rc;
+
+       buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL);
+       if (!buffhds)
+               return -ENOMEM;
 
-       /* Maybe allocate device-global string IDs, and patch descriptors */
-       if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
-               rc = usb_string_id(cdev);
-               if (unlikely(rc < 0))
+       /* Data buffers cyclic list */
+       bh = buffhds;
+       i = n;
+       goto buffhds_first_it;
+       do {
+               bh->next = bh + 1;
+               ++bh;
+buffhds_first_it:
+               bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
+               if (unlikely(!bh->buf))
                        goto error_release;
-               fsg_strings[FSG_STRING_INTERFACE].id = rc;
-               fsg_intf_desc.iInterface = rc;
-       }
+       } while (--i);
+       bh->next = buffhds;
 
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->fsg_num_buffers = n;
+       common->buffhds = buffhds;
+
+       return 0;
+
+error_release:
        /*
-        * Create the LUNs, open their backing files, and register the
-        * LUN devices in sysfs.
+        * "buf"s pointed to by heads after n - i are NULL
+        * so releasing them won't hurt
         */
-       curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
-       if (unlikely(!curlun)) {
-               rc = -ENOMEM;
-               goto error_release;
+       _fsg_common_free_buffers(buffhds, n);
+
+       return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(fsg_common_set_num_buffers);
+
+static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
+{
+       device_remove_file(&lun->dev, &dev_attr_nofua);
+       /*
+        * device_remove_file() =>
+        *
+        * here the attr (e.g. dev_attr_ro) is only used to be passed to:
+        *
+        *      sysfs_remove_file() =>
+        *
+        *      here e.g. both dev_attr_ro_cdrom and dev_attr_ro are in
+        *      the same namespace and
+        *      from here only attr->name is passed to:
+        *
+        *              sysfs_hash_and_remove()
+        *
+        *              attr->name is the same for dev_attr_ro_cdrom and
+        *              dev_attr_ro
+        *              attr->name is the same for dev_attr_file and
+        *              dev_attr_file_nonremovable
+        *
+        * so we don't differentiate between removing e.g. dev_attr_ro_cdrom
+        * and dev_attr_ro
+        */
+       device_remove_file(&lun->dev, &dev_attr_ro);
+       device_remove_file(&lun->dev, &dev_attr_file);
+}
+
+void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+{
+       if (sysfs) {
+               fsg_common_remove_sysfs(lun);
+               device_unregister(&lun->dev);
        }
-       common->luns = curlun;
+       fsg_lun_close(lun);
+       kfree(lun);
+}
+EXPORT_SYMBOL_GPL(fsg_common_remove_lun);
 
-       init_rwsem(&common->filesem);
+static void _fsg_common_remove_luns(struct fsg_common *common, int n)
+{
+       int i;
 
-       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
-               curlun->cdrom = !!lcfg->cdrom;
-               curlun->ro = lcfg->cdrom || lcfg->ro;
-               curlun->initially_ro = curlun->ro;
-               curlun->removable = lcfg->removable;
-               curlun->dev.release = fsg_lun_release;
-               curlun->dev.parent = &gadget->dev;
-               /* curlun->dev.driver = &fsg_driver.driver; XXX */
-               dev_set_drvdata(&curlun->dev, &common->filesem);
-               dev_set_name(&curlun->dev, "lun%d", i);
-
-               rc = device_register(&curlun->dev);
-               if (rc) {
-                       INFO(common, "failed to register LUN%d: %d\n", i, rc);
-                       common->nluns = i;
-                       put_device(&curlun->dev);
-                       goto error_release;
+       for (i = 0; i < n; ++i)
+               if (common->luns[i]) {
+                       fsg_common_remove_lun(common->luns[i], common->sysfs);
+                       common->luns[i] = NULL;
                }
+}
+EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
 
-               rc = device_create_file(&curlun->dev,
-                                       curlun->cdrom
-                                     ? &dev_attr_ro_cdrom
-                                     : &dev_attr_ro);
-               if (rc)
-                       goto error_luns;
-               rc = device_create_file(&curlun->dev,
-                                       curlun->removable
-                                     ? &dev_attr_file
-                                     : &dev_attr_file_nonremovable);
-               if (rc)
-                       goto error_luns;
-               rc = device_create_file(&curlun->dev, &dev_attr_nofua);
-               if (rc)
-                       goto error_luns;
+void fsg_common_remove_luns(struct fsg_common *common)
+{
+       _fsg_common_remove_luns(common, common->nluns);
+}
 
-               if (lcfg->filename) {
-                       rc = fsg_lun_open(curlun, lcfg->filename);
-                       if (rc)
-                               goto error_luns;
-               } else if (!curlun->removable) {
-                       ERROR(common, "no file given for LUN%d\n", i);
-                       rc = -EINVAL;
-                       goto error_luns;
-               }
+void fsg_common_free_luns(struct fsg_common *common)
+{
+       fsg_common_remove_luns(common);
+       kfree(common->luns);
+       common->luns = NULL;
+}
+EXPORT_SYMBOL_GPL(fsg_common_free_luns);
+
+int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+{
+       struct fsg_lun **curlun;
+
+       /* Find out how many LUNs there should be */
+       if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+               pr_err("invalid number of LUNs: %u\n", nluns);
+               return -EINVAL;
        }
+
+       curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
+       if (unlikely(!curlun))
+               return -ENOMEM;
+
+       if (common->luns)
+               fsg_common_free_luns(common);
+
+       common->luns = curlun;
        common->nluns = nluns;
 
-       /* Data buffers cyclic list */
-       bh = common->buffhds;
-       i = fsg_num_buffers;
-       goto buffhds_first_it;
-       do {
-               bh->next = bh + 1;
-               ++bh;
-buffhds_first_it:
-               bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
-               if (unlikely(!bh->buf)) {
-                       rc = -ENOMEM;
-                       goto error_release;
-               }
-       } while (--i);
-       bh->next = common->buffhds;
+       pr_info("Number of LUNs=%d\n", common->nluns);
 
-       /* Prepare inquiryString */
-       i = get_default_bcdDevice();
-       snprintf(common->inquiry_string, sizeof common->inquiry_string,
-                "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
-                /* Assume product name dependent on the first LUN */
-                cfg->product_name ?: (common->luns->cdrom
-                                    ? "File-CD Gadget"
-                                    : "File-Stor Gadget"),
-                i);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
+
+void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops)
+{
+       common->ops = ops;
+}
+EXPORT_SYMBOL_GPL(fsg_common_set_ops);
+
+void fsg_common_free_buffers(struct fsg_common *common)
+{
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->buffhds = NULL;
+}
+EXPORT_SYMBOL_GPL(fsg_common_free_buffers);
+
+int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+{
+       struct usb_string *us;
+
+       common->gadget = cdev->gadget;
+       common->ep0 = cdev->gadget->ep0;
+       common->ep0req = cdev->req;
+       common->cdev = cdev;
+
+       us = usb_gstrings_attach(cdev, fsg_strings_array,
+                                ARRAY_SIZE(fsg_strings));
+       if (IS_ERR(us))
+               return PTR_ERR(us);
+
+       fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
 
        /*
         * Some peripheral controllers are known not to be able to
         * halt bulk endpoints correctly.  If one of them is present,
         * disable stalls.
         */
-       common->can_stall = cfg->can_stall &&
-               !(gadget_is_at91(common->gadget));
+       common->can_stall = can_stall && !(gadget_is_at91(common->gadget));
 
-       spin_lock_init(&common->lock);
-       kref_init(&common->ref);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(fsg_common_set_cdev);
 
-       /* Tell the thread to start working */
-       common->thread_task =
-               kthread_create(fsg_main_thread, common, "file-storage");
-       if (IS_ERR(common->thread_task)) {
-               rc = PTR_ERR(common->thread_task);
-               goto error_release;
+static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+{
+       int rc;
+
+       rc = device_register(&lun->dev);
+       if (rc) {
+               put_device(&lun->dev);
+               return rc;
        }
-       init_completion(&common->thread_notifier);
-       init_waitqueue_head(&common->fsg_wait);
 
-       /* Information */
-       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
-       INFO(common, "Number of LUNs=%d\n", common->nluns);
+       rc = device_create_file(&lun->dev,
+                               lun->cdrom
+                             ? &dev_attr_ro_cdrom
+                             : &dev_attr_ro);
+       if (rc)
+               goto error;
+       rc = device_create_file(&lun->dev,
+                               lun->removable
+                             ? &dev_attr_file
+                             : &dev_attr_file_nonremovable);
+       if (rc)
+               goto error;
+       rc = device_create_file(&lun->dev, &dev_attr_nofua);
+       if (rc)
+               goto error;
+
+       return 0;
+
+error:
+       /* removing nonexistent files is a no-op */
+       fsg_common_remove_sysfs(lun);
+       device_unregister(&lun->dev);
+       return rc;
+}
+
+int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+                         unsigned int id, const char *name,
+                         const char **name_pfx)
+{
+       struct fsg_lun *lun;
+       char *pathbuf, *p;
+       int rc = -ENOMEM;
+
+       if (!common->nluns || !common->luns)
+               return -ENODEV;
+
+       if (common->luns[id])
+               return -EBUSY;
+
+       if (!cfg->filename && !cfg->removable) {
+               pr_err("no file given for LUN%d\n", id);
+               return -EINVAL;
+       }
+
+       lun = kzalloc(sizeof(*lun), GFP_KERNEL);
+       if (!lun)
+               return -ENOMEM;
+
+       lun->name_pfx = name_pfx;
+
+       lun->cdrom = !!cfg->cdrom;
+       lun->ro = cfg->cdrom || cfg->ro;
+       lun->initially_ro = lun->ro;
+       lun->removable = !!cfg->removable;
+
+       if (!common->sysfs) {
+               /* we DON'T own the name!*/
+               lun->name = name;
+       } else {
+               lun->dev.release = fsg_lun_release;
+               lun->dev.parent = &common->gadget->dev;
+               dev_set_drvdata(&lun->dev, &common->filesem);
+               dev_set_name(&lun->dev, "%s", name);
+               lun->name = dev_name(&lun->dev);
+
+               rc = fsg_common_add_sysfs(common, lun);
+               if (rc) {
+                       pr_info("failed to register LUN%d: %d\n", id, rc);
+                       goto error_sysfs;
+               }
+       }
+
+       common->luns[id] = lun;
+
+       if (cfg->filename) {
+               rc = fsg_lun_open(lun, cfg->filename);
+               if (rc)
+                       goto error_lun;
+       }
 
        pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
-       for (i = 0, nluns = common->nluns, curlun = common->luns;
-            i < nluns;
-            ++curlun, ++i) {
-               char *p = "(no medium)";
-               if (fsg_lun_is_open(curlun)) {
-                       p = "(error)";
-                       if (pathbuf) {
-                               p = d_path(&curlun->filp->f_path,
-                                          pathbuf, PATH_MAX);
-                               if (IS_ERR(p))
-                                       p = "(error)";
-                       }
+       p = "(no medium)";
+       if (fsg_lun_is_open(lun)) {
+               p = "(error)";
+               if (pathbuf) {
+                       p = d_path(&lun->filp->f_path, pathbuf, PATH_MAX);
+                       if (IS_ERR(p))
+                               p = "(error)";
                }
-               LINFO(curlun, "LUN: %s%s%sfile: %s\n",
-                     curlun->removable ? "removable " : "",
-                     curlun->ro ? "read only " : "",
-                     curlun->cdrom ? "CD-ROM " : "",
-                     p);
        }
+       pr_info("LUN: %s%s%sfile: %s\n",
+             lun->removable ? "removable " : "",
+             lun->ro ? "read only " : "",
+             lun->cdrom ? "CD-ROM " : "",
+             p);
        kfree(pathbuf);
 
+       return 0;
+
+error_lun:
+       if (common->sysfs) {
+               fsg_common_remove_sysfs(lun);
+               device_unregister(&lun->dev);
+       }
+       fsg_lun_close(lun);
+       common->luns[id] = NULL;
+error_sysfs:
+       kfree(lun);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(fsg_common_create_lun);
+
+int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+{
+       char buf[8]; /* enough for 100000000 different numbers, decimal */
+       int i, rc;
+
+       for (i = 0; i < common->nluns; ++i) {
+               snprintf(buf, sizeof(buf), "lun%d", i);
+               rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
+               if (rc)
+                       goto fail;
+       }
+
+       pr_info("Number of LUNs=%d\n", common->nluns);
+
+       return 0;
+
+fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(fsg_common_create_luns);
+
+void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+{
+       int i;
+
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+       snprintf(common->inquiry_string, sizeof(common->inquiry_string),
+                "%-8s%-16s%04x", vn ?: "Linux",
+                /* Assume product name dependent on the first LUN */
+                pn ?: ((*common->luns)->cdrom
+                    ? "File-CD Gadget"
+                    : "File-Stor Gadget"),
+                i);
+}
+EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string);
+
+int fsg_common_run_thread(struct fsg_common *common)
+{
+       common->state = FSG_STATE_IDLE;
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+       if (IS_ERR(common->thread_task)) {
+               common->state = FSG_STATE_TERMINATED;
+               return PTR_ERR(common->thread_task);
+       }
+
        DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
 
        wake_up_process(common->thread_task);
 
-       return common;
-
-error_luns:
-       common->nluns = i + 1;
-error_release:
-       common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
-       /* Call fsg_common_release() directly, ref might be not initialised. */
-       fsg_common_release(&common->ref);
-       return ERR_PTR(rc);
+       return 0;
 }
+EXPORT_SYMBOL_GPL(fsg_common_run_thread);
 
 static void fsg_common_release(struct kref *ref)
 {
@@ -2824,36 +3068,26 @@ static void fsg_common_release(struct kref *ref)
        }
 
        if (likely(common->luns)) {
-               struct fsg_lun *lun = common->luns;
+               struct fsg_lun **lun_it = common->luns;
                unsigned i = common->nluns;
 
                /* In error recovery common->nluns may be zero. */
-               for (; i; --i, ++lun) {
-                       device_remove_file(&lun->dev, &dev_attr_nofua);
-                       device_remove_file(&lun->dev,
-                                          lun->cdrom
-                                        ? &dev_attr_ro_cdrom
-                                        : &dev_attr_ro);
-                       device_remove_file(&lun->dev,
-                                          lun->removable
-                                        ? &dev_attr_file
-                                        : &dev_attr_file_nonremovable);
+               for (; i; --i, ++lun_it) {
+                       struct fsg_lun *lun = *lun_it;
+                       if (!lun)
+                               continue;
+                       if (common->sysfs)
+                               fsg_common_remove_sysfs(lun);
                        fsg_lun_close(lun);
-                       device_unregister(&lun->dev);
+                       if (common->sysfs)
+                               device_unregister(&lun->dev);
+                       kfree(lun);
                }
 
                kfree(common->luns);
        }
 
-       {
-               struct fsg_buffhd *bh = common->buffhds;
-               unsigned i = fsg_num_buffers;
-               do {
-                       kfree(bh->buf);
-               } while (++bh, --i);
-       }
-
-       kfree(common->buffhds);
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
        if (common->free_storage_on_release)
                kfree(common);
 }
@@ -2861,24 +3095,6 @@ static void fsg_common_release(struct kref *ref)
 
 /*-------------------------------------------------------------------------*/
 
-static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
-{
-       struct fsg_dev          *fsg = fsg_from_func(f);
-       struct fsg_common       *common = fsg->common;
-
-       DBG(fsg, "unbind\n");
-       if (fsg->common->fsg == fsg) {
-               fsg->common->new_fsg = NULL;
-               raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
-               /* FIXME: make interruptible or killable somehow? */
-               wait_event(common->fsg_wait, common->fsg != fsg);
-       }
-
-       fsg_common_put(common);
-       usb_free_all_descriptors(&fsg->function);
-       kfree(fsg);
-}
-
 static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 {
        struct fsg_dev          *fsg = fsg_from_func(f);
@@ -2887,6 +3103,19 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
        struct usb_ep           *ep;
        unsigned                max_burst;
        int                     ret;
+       struct fsg_opts         *opts;
+
+       opts = fsg_opts_from_func_inst(f->fi);
+       if (!opts->no_configfs) {
+               ret = fsg_common_set_cdev(fsg->common, c->cdev,
+                                         fsg->common->can_stall);
+               if (ret)
+                       return ret;
+               fsg_common_set_inquiry_string(fsg->common, 0, 0);
+               ret = fsg_common_run_thread(fsg->common);
+               if (ret)
+                       return ret;
+       }
 
        fsg->gadget = gadget;
 
@@ -2939,95 +3168,472 @@ autoconf_fail:
        return -ENOTSUPP;
 }
 
-/****************************** ADD FUNCTION ******************************/
+/****************************** ALLOCATE FUNCTION *************************/
 
-static struct usb_gadget_strings *fsg_strings_array[] = {
-       &fsg_stringtab,
+static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct fsg_dev          *fsg = fsg_from_func(f);
+       struct fsg_common       *common = fsg->common;
+
+       DBG(fsg, "unbind\n");
+       if (fsg->common->fsg == fsg) {
+               fsg->common->new_fsg = NULL;
+               raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+               /* FIXME: make interruptible or killable somehow? */
+               wait_event(common->fsg_wait, common->fsg != fsg);
+       }
+
+       usb_free_all_descriptors(&fsg->function);
+}
+
+static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct fsg_lun_opts, group);
+}
+
+static inline struct fsg_opts *to_fsg_opts(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct fsg_opts,
+                           func_inst.group);
+}
+
+CONFIGFS_ATTR_STRUCT(fsg_lun_opts);
+CONFIGFS_ATTR_OPS(fsg_lun_opts);
+
+static void fsg_lun_attr_release(struct config_item *item)
+{
+       struct fsg_lun_opts *lun_opts;
+
+       lun_opts = to_fsg_lun_opts(item);
+       kfree(lun_opts);
+}
+
+static struct configfs_item_operations fsg_lun_item_ops = {
+       .release                = fsg_lun_attr_release,
+       .show_attribute         = fsg_lun_opts_attr_show,
+       .store_attribute        = fsg_lun_opts_attr_store,
+};
+
+static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
+{
+       struct fsg_opts *fsg_opts;
+
+       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+
+       return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page);
+}
+
+static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts,
+                                      const char *page, size_t len)
+{
+       struct fsg_opts *fsg_opts;
+
+       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+
+       return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len);
+}
+
+static struct fsg_lun_opts_attribute fsg_lun_opts_file =
+       __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show,
+                       fsg_lun_opts_file_store);
+
+static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page)
+{
+       return fsg_show_ro(opts->lun, page);
+}
+
+static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts,
+                                      const char *page, size_t len)
+{
+       struct fsg_opts *fsg_opts;
+
+       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+
+       return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len);
+}
+
+static struct fsg_lun_opts_attribute fsg_lun_opts_ro =
+       __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show,
+                       fsg_lun_opts_ro_store);
+
+static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts,
+                                          char *page)
+{
+       return fsg_show_removable(opts->lun, page);
+}
+
+static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts,
+                                      const char *page, size_t len)
+{
+       return fsg_store_removable(opts->lun, page, len);
+}
+
+static struct fsg_lun_opts_attribute fsg_lun_opts_removable =
+       __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR,
+                       fsg_lun_opts_removable_show,
+                       fsg_lun_opts_removable_store);
+
+static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
+{
+       return fsg_show_cdrom(opts->lun, page);
+}
+
+static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
+                                      const char *page, size_t len)
+{
+       struct fsg_opts *fsg_opts;
+
+       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+
+       return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page,
+                              len);
+}
+
+static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
+       __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show,
+                       fsg_lun_opts_cdrom_store);
+
+static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page)
+{
+       return fsg_show_nofua(opts->lun, page);
+}
+
+static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts,
+                                      const char *page, size_t len)
+{
+       return fsg_store_nofua(opts->lun, page, len);
+}
+
+static struct fsg_lun_opts_attribute fsg_lun_opts_nofua =
+       __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show,
+                       fsg_lun_opts_nofua_store);
+
+static struct configfs_attribute *fsg_lun_attrs[] = {
+       &fsg_lun_opts_file.attr,
+       &fsg_lun_opts_ro.attr,
+       &fsg_lun_opts_removable.attr,
+       &fsg_lun_opts_cdrom.attr,
+       &fsg_lun_opts_nofua.attr,
        NULL,
 };
 
-static int fsg_bind_config(struct usb_composite_dev *cdev,
-                          struct usb_configuration *c,
-                          struct fsg_common *common)
+static struct config_item_type fsg_lun_type = {
+       .ct_item_ops    = &fsg_lun_item_ops,
+       .ct_attrs       = fsg_lun_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+static struct config_group *fsg_lun_make(struct config_group *group,
+                                        const char *name)
 {
-       struct fsg_dev *fsg;
+       struct fsg_lun_opts *opts;
+       struct fsg_opts *fsg_opts;
+       struct fsg_lun_config config;
+       char *num_str;
+       u8 num;
+       int ret;
+
+       num_str = strchr(name, '.');
+       if (!num_str) {
+               pr_err("Unable to locate . in LUN.NUMBER\n");
+               return ERR_PTR(-EINVAL);
+       }
+       num_str++;
+
+       ret = kstrtou8(num_str, 0, &num);
+       if (ret)
+               return ERR_PTR(ret);
+
+       fsg_opts = to_fsg_opts(&group->cg_item);
+       if (num >= FSG_MAX_LUNS)
+               return ERR_PTR(-ERANGE);
+
+       mutex_lock(&fsg_opts->lock);
+       if (fsg_opts->refcnt || fsg_opts->common->luns[num]) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memset(&config, 0, sizeof(config));
+       config.removable = true;
+
+       ret = fsg_common_create_lun(fsg_opts->common, &config, num, name,
+                                   (const char **)&group->cg_item.ci_name);
+       if (ret) {
+               kfree(opts);
+               goto out;
+       }
+       opts->lun = fsg_opts->common->luns[num];
+       opts->lun_id = num;
+       mutex_unlock(&fsg_opts->lock);
+
+       config_group_init_type_name(&opts->group, name, &fsg_lun_type);
+
+       return &opts->group;
+out:
+       mutex_unlock(&fsg_opts->lock);
+       return ERR_PTR(ret);
+}
+
+static void fsg_lun_drop(struct config_group *group, struct config_item *item)
+{
+       struct fsg_lun_opts *lun_opts;
+       struct fsg_opts *fsg_opts;
+
+       lun_opts = to_fsg_lun_opts(item);
+       fsg_opts = to_fsg_opts(&group->cg_item);
+
+       mutex_lock(&fsg_opts->lock);
+       if (fsg_opts->refcnt) {
+               struct config_item *gadget;
+
+               gadget = group->cg_item.ci_parent->ci_parent;
+               unregister_gadget_item(gadget);
+       }
+
+       fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
+       fsg_opts->common->luns[lun_opts->lun_id] = NULL;
+       lun_opts->lun_id = 0;
+       mutex_unlock(&fsg_opts->lock);
+
+       config_item_put(item);
+}
+
+CONFIGFS_ATTR_STRUCT(fsg_opts);
+CONFIGFS_ATTR_OPS(fsg_opts);
+
+static void fsg_attr_release(struct config_item *item)
+{
+       struct fsg_opts *opts = to_fsg_opts(item);
+
+       usb_put_function_instance(&opts->func_inst);
+}
+
+static struct configfs_item_operations fsg_item_ops = {
+       .release                = fsg_attr_release,
+       .show_attribute         = fsg_opts_attr_show,
+       .store_attribute        = fsg_opts_attr_store,
+};
+
+static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
+{
+       int result;
+
+       mutex_lock(&opts->lock);
+       result = sprintf(page, "%d", opts->common->can_stall);
+       mutex_unlock(&opts->lock);
+
+       return result;
+}
+
+static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
+                                   size_t len)
+{
+       int ret;
+       bool stall;
+
+       mutex_lock(&opts->lock);
+
+       if (opts->refcnt) {
+               mutex_unlock(&opts->lock);
+               return -EBUSY;
+       }
+
+       ret = strtobool(page, &stall);
+       if (!ret) {
+               opts->common->can_stall = stall;
+               ret = len;
+       }
+
+       mutex_unlock(&opts->lock);
+
+       return ret;
+}
+
+static struct fsg_opts_attribute fsg_opts_stall =
+       __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show,
+                       fsg_opts_stall_store);
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
+{
+       int result;
+
+       mutex_lock(&opts->lock);
+       result = sprintf(page, "%d", opts->common->fsg_num_buffers);
+       mutex_unlock(&opts->lock);
+
+       return result;
+}
+
+static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts,
+                                         const char *page, size_t len)
+{
+       int ret;
+       u8 num;
+
+       mutex_lock(&opts->lock);
+       if (opts->refcnt) {
+               ret = -EBUSY;
+               goto end;
+       }
+       ret = kstrtou8(page, 0, &num);
+       if (ret)
+               goto end;
+
+       ret = fsg_num_buffers_validate(num);
+       if (ret)
+               goto end;
+
+       fsg_common_set_num_buffers(opts->common, num);
+       ret = len;
+
+end:
+       mutex_unlock(&opts->lock);
+       return ret;
+}
+
+static struct fsg_opts_attribute fsg_opts_num_buffers =
+       __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR,
+                       fsg_opts_num_buffers_show,
+                       fsg_opts_num_buffers_store);
+
+#endif
+
+static struct configfs_attribute *fsg_attrs[] = {
+       &fsg_opts_stall.attr,
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+       &fsg_opts_num_buffers.attr,
+#endif
+       NULL,
+};
+
+static struct configfs_group_operations fsg_group_ops = {
+       .make_group     = fsg_lun_make,
+       .drop_item      = fsg_lun_drop,
+};
+
+static struct config_item_type fsg_func_type = {
+       .ct_item_ops    = &fsg_item_ops,
+       .ct_group_ops   = &fsg_group_ops,
+       .ct_attrs       = fsg_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+static void fsg_free_inst(struct usb_function_instance *fi)
+{
+       struct fsg_opts *opts;
+
+       opts = fsg_opts_from_func_inst(fi);
+       fsg_common_put(opts->common);
+       kfree(opts);
+}
+
+static struct usb_function_instance *fsg_alloc_inst(void)
+{
+       struct fsg_opts *opts;
+       struct fsg_lun_config config;
        int rc;
 
-       fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = fsg_free_inst;
+       opts->common = fsg_common_setup(opts->common);
+       if (IS_ERR(opts->common)) {
+               rc = PTR_ERR(opts->common);
+               goto release_opts;
+       }
+       rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
+       if (rc)
+               goto release_opts;
+
+       rc = fsg_common_set_num_buffers(opts->common,
+                                       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
+       if (rc)
+               goto release_luns;
+
+       pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+
+       memset(&config, 0, sizeof(config));
+       config.removable = true;
+       rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
+                       (const char **)&opts->func_inst.group.cg_item.ci_name);
+       opts->lun0.lun = opts->common->luns[0];
+       opts->lun0.lun_id = 0;
+       config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
+       opts->default_groups[0] = &opts->lun0.group;
+       opts->func_inst.group.default_groups = opts->default_groups;
+
+       config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type);
+
+       return &opts->func_inst;
+
+release_luns:
+       kfree(opts->common->luns);
+release_opts:
+       kfree(opts);
+       return ERR_PTR(rc);
+}
+
+static void fsg_free(struct usb_function *f)
+{
+       struct fsg_dev *fsg;
+       struct fsg_opts *opts;
+
+       fsg = container_of(f, struct fsg_dev, function);
+       opts = container_of(f->fi, struct fsg_opts, func_inst);
+
+       mutex_lock(&opts->lock);
+       opts->refcnt--;
+       mutex_unlock(&opts->lock);
+
+       kfree(fsg);
+}
+
+static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
+{
+       struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
+       struct fsg_common *common = opts->common;
+       struct fsg_dev *fsg;
+
+       fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
        if (unlikely(!fsg))
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
-       fsg->function.name        = FSG_DRIVER_DESC;
-       fsg->function.strings     = fsg_strings_array;
-       fsg->function.bind        = fsg_bind;
-       fsg->function.unbind      = fsg_unbind;
-       fsg->function.setup       = fsg_setup;
-       fsg->function.set_alt     = fsg_set_alt;
-       fsg->function.disable     = fsg_disable;
+       mutex_lock(&opts->lock);
+       opts->refcnt++;
+       mutex_unlock(&opts->lock);
+       fsg->function.name      = FSG_DRIVER_DESC;
+       fsg->function.bind      = fsg_bind;
+       fsg->function.unbind    = fsg_unbind;
+       fsg->function.setup     = fsg_setup;
+       fsg->function.set_alt   = fsg_set_alt;
+       fsg->function.disable   = fsg_disable;
+       fsg->function.free_func = fsg_free;
 
        fsg->common               = common;
-       /*
-        * Our caller holds a reference to common structure so we
-        * don't have to be worry about it being freed until we return
-        * from this function.  So instead of incrementing counter now
-        * and decrement in error recovery we increment it only when
-        * call to usb_add_function() was successful.
-        */
 
-       rc = usb_add_function(c, &fsg->function);
-       if (unlikely(rc))
-               kfree(fsg);
-       else
-               fsg_common_get(fsg->common);
-       return rc;
+       return &fsg->function;
 }
 
+DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal Nazarewicz");
 
 /************************* Module parameters *************************/
 
-struct fsg_module_parameters {
-       char            *file[FSG_MAX_LUNS];
-       bool            ro[FSG_MAX_LUNS];
-       bool            removable[FSG_MAX_LUNS];
-       bool            cdrom[FSG_MAX_LUNS];
-       bool            nofua[FSG_MAX_LUNS];
-
-       unsigned int    file_count, ro_count, removable_count, cdrom_count;
-       unsigned int    nofua_count;
-       unsigned int    luns;   /* nluns */
-       bool            stall;  /* can_stall */
-};
 
-#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)      \
-       module_param_array_named(prefix ## name, params.name, type,     \
-                                &prefix ## params.name ## _count,      \
-                                S_IRUGO);                              \
-       MODULE_PARM_DESC(prefix ## name, desc)
-
-#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)            \
-       module_param_named(prefix ## name, params.name, type,           \
-                          S_IRUGO);                                    \
-       MODULE_PARM_DESC(prefix ## name, desc)
-
-#define FSG_MODULE_PARAMETERS(prefix, params)                          \
-       _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
-                               "names of backing files or devices");   \
-       _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
-                               "true to force read-only");             \
-       _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
-                               "true to simulate removable media");    \
-       _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
-                               "true to simulate CD-ROM instead of disk"); \
-       _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
-                               "true to ignore SCSI WRITE(10,12) FUA bit"); \
-       _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
-                         "number of LUNs");                            \
-       _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
-                         "false to prevent bulk stalls")
-
-static void
-fsg_config_from_params(struct fsg_config *cfg,
-                      const struct fsg_module_parameters *params)
+void fsg_config_from_params(struct fsg_config *cfg,
+                      const struct fsg_module_parameters *params,
+                      unsigned int fsg_num_buffers)
 {
        struct fsg_lun_config *lun;
        unsigned i;
@@ -3055,19 +3661,7 @@ fsg_config_from_params(struct fsg_config *cfg,
 
        /* Finalise */
        cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
 }
+EXPORT_SYMBOL_GPL(fsg_config_from_params);
 
-static inline struct fsg_common *
-fsg_common_from_params(struct fsg_common *common,
-                      struct usb_composite_dev *cdev,
-                      const struct fsg_module_parameters *params)
-       __attribute__((unused));
-static inline struct fsg_common *
-fsg_common_from_params(struct fsg_common *common,
-                      struct usb_composite_dev *cdev,
-                      const struct fsg_module_parameters *params)
-{
-       struct fsg_config cfg;
-       fsg_config_from_params(&cfg, params);
-       return fsg_common_init(common, cdev, &cfg);
-}
diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
new file mode 100644 (file)
index 0000000..b4866fc
--- /dev/null
@@ -0,0 +1,166 @@
+#ifndef USB_F_MASS_STORAGE_H
+#define USB_F_MASS_STORAGE_H
+
+#include <linux/usb/composite.h>
+#include "storage_common.h"
+
+struct fsg_module_parameters {
+       char            *file[FSG_MAX_LUNS];
+       bool            ro[FSG_MAX_LUNS];
+       bool            removable[FSG_MAX_LUNS];
+       bool            cdrom[FSG_MAX_LUNS];
+       bool            nofua[FSG_MAX_LUNS];
+
+       unsigned int    file_count, ro_count, removable_count, cdrom_count;
+       unsigned int    nofua_count;
+       unsigned int    luns;   /* nluns */
+       bool            stall;  /* can_stall */
+};
+
+#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)      \
+       module_param_array_named(prefix ## name, params.name, type,     \
+                                &prefix ## params.name ## _count,      \
+                                S_IRUGO);                              \
+       MODULE_PARM_DESC(prefix ## name, desc)
+
+#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)            \
+       module_param_named(prefix ## name, params.name, type,           \
+                          S_IRUGO);                                    \
+       MODULE_PARM_DESC(prefix ## name, desc)
+
+#define __FSG_MODULE_PARAMETERS(prefix, params)                                \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+                               "names of backing files or devices");   \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+                               "true to force read-only");             \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
+                               "true to simulate removable media");    \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
+                               "true to simulate CD-ROM instead of disk"); \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
+                               "true to ignore SCSI WRITE(10,12) FUA bit"); \
+       _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
+                         "number of LUNs");                            \
+       _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+                         "false to prevent bulk stalls")
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+
+#define FSG_MODULE_PARAMETERS(prefix, params)                          \
+       __FSG_MODULE_PARAMETERS(prefix, params);                        \
+       module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
+       MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
+#else
+
+#define FSG_MODULE_PARAMETERS(prefix, params)                          \
+       __FSG_MODULE_PARAMETERS(prefix, params)
+
+#endif
+
+struct fsg_common;
+
+/* FSF callback functions */
+struct fsg_operations {
+       /*
+        * Callback function to call when thread exits.  If no
+        * callback is set or it returns value lower then zero MSF
+        * will force eject all LUNs it operates on (including those
+        * marked as non-removable or with prevent_medium_removal flag
+        * set).
+        */
+       int (*thread_exits)(struct fsg_common *common);
+};
+
+struct fsg_lun_opts {
+       struct config_group group;
+       struct fsg_lun *lun;
+       int lun_id;
+};
+
+struct fsg_opts {
+       struct fsg_common *common;
+       struct usb_function_instance func_inst;
+       struct fsg_lun_opts lun0;
+       struct config_group *default_groups[2];
+       bool no_configfs; /* for legacy gadgets */
+
+       /*
+        * Read/write access to configfs attributes is handled by configfs.
+        *
+        * This is to protect the data from concurrent access by read/write
+        * and create symlink/remove symlink.
+        */
+       struct mutex                    lock;
+       int                             refcnt;
+};
+
+struct fsg_lun_config {
+       const char *filename;
+       char ro;
+       char removable;
+       char cdrom;
+       char nofua;
+};
+
+struct fsg_config {
+       unsigned nluns;
+       struct fsg_lun_config luns[FSG_MAX_LUNS];
+
+       /* Callback functions. */
+       const struct fsg_operations     *ops;
+       /* Gadget's private data. */
+       void                    *private_data;
+
+       const char *vendor_name;                /*  8 characters or less */
+       const char *product_name;               /* 16 characters or less */
+
+       char                    can_stall;
+       unsigned int            fsg_num_buffers;
+};
+
+static inline struct fsg_opts *
+fsg_opts_from_func_inst(const struct usb_function_instance *fi)
+{
+       return container_of(fi, struct fsg_opts, func_inst);
+}
+
+void fsg_common_get(struct fsg_common *common);
+
+void fsg_common_put(struct fsg_common *common);
+
+void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+
+int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
+
+void fsg_common_free_buffers(struct fsg_common *common);
+
+int fsg_common_set_cdev(struct fsg_common *common,
+                       struct usb_composite_dev *cdev, bool can_stall);
+
+void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs);
+
+void fsg_common_remove_luns(struct fsg_common *common);
+
+void fsg_common_free_luns(struct fsg_common *common);
+
+int fsg_common_set_nluns(struct fsg_common *common, int nluns);
+
+void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops);
+
+int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+                         unsigned int id, const char *name,
+                         const char **name_pfx);
+
+int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
+
+void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn);
+
+int fsg_common_run_thread(struct fsg_common *common);
+
+void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+
+#endif /* USB_F_MASS_STORAGE_H */
index 5327c82472eda8034a54ca664392baf5875b0a7a..2344efe4f4ce8611e6869605e89e1c18aef7000a 100644 (file)
@@ -76,7 +76,9 @@ struct gfs_ffs_obj {
 
 USB_GADGET_COMPOSITE_OPTIONS();
 
+#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
 USB_ETHERNET_MODULE_PARAMETERS();
+#endif
 
 static struct usb_device_descriptor gfs_dev_desc = {
        .bLength                = sizeof gfs_dev_desc,
index c64deb9e3d62368e073893448dfe9f8b7ec610cc..f82768015715c69ed998e2cb95cc0735dd6a035b 100644 (file)
@@ -1165,7 +1165,7 @@ static int udc_proc_read(struct seq_file *m, void *v)
                                s = "invalid"; break;
                        default:
                                s = "?"; break;
-                       }; s; }),
+                       } s; }),
                        (tmp & EPxSTATUS_TOGGLE) ? "data1" : "data0",
                        (tmp & EPxSTATUS_SUSPEND) ? " suspend" : "",
                        (tmp & EPxSTATUS_FIFO_DISABLE) ? " disable" : "",
@@ -1701,7 +1701,6 @@ static void goku_remove(struct pci_dev *pdev)
        if (dev->enabled)
                pci_disable_device(pdev);
 
-       pci_set_drvdata(pdev, NULL);
        dev->regs = NULL;
 
        INFO(dev, "unbind\n");
index 080e577773d527cb12507b9f20a581c45c452a42..8e27a8c9644470bfa8d5b44fc95a198aeda7214f 100644 (file)
 #define DRIVER_DESC            "Mass Storage Gadget"
 #define DRIVER_VERSION         "2009/09/11"
 
-/*-------------------------------------------------------------------------*/
-
 /*
- * kbuild is not very cooperative with respect to linking separately
- * compiled library objects into one module.  So for now we won't use
- * separate compilation ... ensuring init/exit sections work to shrink
- * the runtime footprint, and giving us at least some parts of what
- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ * Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures.
  */
-#include "f_mass_storage.c"
+#define FSG_VENDOR_ID  0x0525  /* NetChip */
+#define FSG_PRODUCT_ID 0xa4a5  /* Linux-USB File-backed Storage Gadget */
+
+#include "f_mass_storage.h"
 
 /*-------------------------------------------------------------------------*/
 USB_GADGET_COMPOSITE_OPTIONS();
@@ -97,11 +97,28 @@ static struct usb_gadget_strings *dev_strings[] = {
        NULL,
 };
 
+static struct usb_function_instance *fi_msg;
+static struct usb_function *f_msg;
+
 /****************************** Configurations ******************************/
 
 static struct fsg_module_parameters mod_data = {
        .stall = 1
 };
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+
+static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+
+#else
+
+/*
+ * Number of buffers we will use.
+ * 2 is usually enough for good buffering pipeline
+ */
+#define fsg_num_buffers        CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+
+#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+
 FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
 
 static unsigned long msg_registered;
@@ -115,13 +132,7 @@ static int msg_thread_exits(struct fsg_common *common)
 
 static int __init msg_do_config(struct usb_configuration *c)
 {
-       static const struct fsg_operations ops = {
-               .thread_exits = msg_thread_exits,
-       };
-       static struct fsg_common common;
-
-       struct fsg_common *retp;
-       struct fsg_config config;
+       struct fsg_opts *opts;
        int ret;
 
        if (gadget_is_otg(c->cdev->gadget)) {
@@ -129,15 +140,24 @@ static int __init msg_do_config(struct usb_configuration *c)
                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       fsg_config_from_params(&config, &mod_data);
-       config.ops = &ops;
+       opts = fsg_opts_from_func_inst(fi_msg);
+
+       f_msg = usb_get_function(fi_msg);
+       if (IS_ERR(f_msg))
+               return PTR_ERR(f_msg);
+
+       ret = fsg_common_run_thread(opts->common);
+       if (ret)
+               goto put_func;
+
+       ret = usb_add_function(c, f_msg);
+       if (ret)
+               goto put_func;
 
-       retp = fsg_common_init(&common, c->cdev, &config);
-       if (IS_ERR(retp))
-               return PTR_ERR(retp);
+       return 0;
 
-       ret = fsg_bind_config(c->cdev, c, &common);
-       fsg_common_put(&common);
+put_func:
+       usb_put_function(f_msg);
        return ret;
 }
 
@@ -152,23 +172,79 @@ static struct usb_configuration msg_config_driver = {
 
 static int __init msg_bind(struct usb_composite_dev *cdev)
 {
+       static const struct fsg_operations ops = {
+               .thread_exits = msg_thread_exits,
+       };
+       struct fsg_opts *opts;
+       struct fsg_config config;
        int status;
 
+       fi_msg = usb_get_function_instance("mass_storage");
+       if (IS_ERR(fi_msg))
+               return PTR_ERR(fi_msg);
+
+       fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
+       opts = fsg_opts_from_func_inst(fi_msg);
+
+       opts->no_configfs = true;
+       status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
+       if (status)
+               goto fail;
+
+       status = fsg_common_set_nluns(opts->common, config.nluns);
+       if (status)
+               goto fail_set_nluns;
+
+       fsg_common_set_ops(opts->common, &ops);
+
+       status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
+       if (status)
+               goto fail_set_cdev;
+
+       fsg_common_set_sysfs(opts->common, true);
+       status = fsg_common_create_luns(opts->common, &config);
+       if (status)
+               goto fail_set_cdev;
+
+       fsg_common_set_inquiry_string(opts->common, config.vendor_name,
+                                     config.product_name);
+
        status = usb_string_ids_tab(cdev, strings_dev);
        if (status < 0)
-               return status;
+               goto fail_string_ids;
        msg_device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
 
        status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
        if (status < 0)
-               return status;
+               goto fail_string_ids;
+
        usb_composite_overwrite_options(cdev, &coverwrite);
        dev_info(&cdev->gadget->dev,
                 DRIVER_DESC ", version: " DRIVER_VERSION "\n");
        set_bit(0, &msg_registered);
        return 0;
+
+fail_string_ids:
+       fsg_common_remove_luns(opts->common);
+fail_set_cdev:
+       fsg_common_free_luns(opts->common);
+fail_set_nluns:
+       fsg_common_free_buffers(opts->common);
+fail:
+       usb_put_function_instance(fi_msg);
+       return status;
 }
 
+static int msg_unbind(struct usb_composite_dev *cdev)
+{
+       if (!IS_ERR(f_msg))
+               usb_put_function(f_msg);
+
+       if (!IS_ERR(fi_msg))
+               usb_put_function_instance(fi_msg);
+
+       return 0;
+}
 
 /****************************** Some noise ******************************/
 
@@ -179,6 +255,7 @@ static __refdata struct usb_composite_driver msg_driver = {
        .needs_serial   = 1,
        .strings        = dev_strings,
        .bind           = msg_bind,
+       .unbind         = msg_unbind,
 };
 
 MODULE_DESCRIPTION(DRIVER_DESC);
index 23393254a8a35593526062cc09880f50c809dced..4fdaa54a2a2a395a2fa8804cdce9ffab4daa14c5 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/netdevice.h>
 
 #include "u_serial.h"
 #if defined USB_ETH_RNDIS
@@ -32,22 +33,11 @@ MODULE_AUTHOR("Michal Nazarewicz");
 MODULE_LICENSE("GPL");
 
 
-/***************************** All the files... *****************************/
+#include "f_mass_storage.h"
 
-/*
- * kbuild is not very cooperative with respect to linking separately
- * compiled library objects into one module.  So for now we won't use
- * separate compilation ... ensuring init/exit sections work to shrink
- * the runtime footprint, and giving us at least some parts of what
- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
- */
-#include "f_mass_storage.c"
-
-#define USBF_ECM_INCLUDED
-#include "f_ecm.c"
+#include "u_ecm.h"
 #ifdef USB_ETH_RNDIS
-#  define USB_FRNDIS_INCLUDED
-#  include "f_rndis.c"
+#  include "u_rndis.h"
 #  include "rndis.h"
 #endif
 #include "u_ether.h"
@@ -132,22 +122,36 @@ static struct usb_gadget_strings *dev_strings[] = {
 /****************************** Configurations ******************************/
 
 static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
-FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+
+static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
 
-static struct fsg_common fsg_common;
+#else
+
+/*
+ * Number of buffers we will use.
+ * 2 is usually enough for good buffering pipeline
+ */
+#define fsg_num_buffers        CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
 
-static u8 host_mac[ETH_ALEN];
+#endif /* CONFIG_USB_DEBUG */
+
+FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
 
 static struct usb_function_instance *fi_acm;
-static struct eth_dev *the_dev;
+static struct usb_function_instance *fi_msg;
 
 /********** RNDIS **********/
 
 #ifdef USB_ETH_RNDIS
+static struct usb_function_instance *fi_rndis;
 static struct usb_function *f_acm_rndis;
+static struct usb_function *f_rndis;
+static struct usb_function *f_msg_rndis;
 
 static __init int rndis_do_config(struct usb_configuration *c)
 {
+       struct fsg_opts *fsg_opts;
        int ret;
 
        if (gadget_is_otg(c->cdev->gadget)) {
@@ -155,27 +159,50 @@ static __init int rndis_do_config(struct usb_configuration *c)
                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       ret = rndis_bind_config(c, host_mac, the_dev);
+       f_rndis = usb_get_function(fi_rndis);
+       if (IS_ERR(f_rndis))
+               return PTR_ERR(f_rndis);
+
+       ret = usb_add_function(c, f_rndis);
        if (ret < 0)
-               return ret;
+               goto err_func_rndis;
 
        f_acm_rndis = usb_get_function(fi_acm);
-       if (IS_ERR(f_acm_rndis))
-               return PTR_ERR(f_acm_rndis);
+       if (IS_ERR(f_acm_rndis)) {
+               ret = PTR_ERR(f_acm_rndis);
+               goto err_func_acm;
+       }
 
        ret = usb_add_function(c, f_acm_rndis);
        if (ret)
                goto err_conf;
 
-       ret = fsg_bind_config(c->cdev, c, &fsg_common);
-       if (ret < 0)
+       f_msg_rndis = usb_get_function(fi_msg);
+       if (IS_ERR(f_msg_rndis)) {
+               ret = PTR_ERR(f_msg_rndis);
                goto err_fsg;
+       }
+
+       fsg_opts = fsg_opts_from_func_inst(fi_msg);
+       ret = fsg_common_run_thread(fsg_opts->common);
+       if (ret)
+               goto err_run;
+
+       ret = usb_add_function(c, f_msg_rndis);
+       if (ret)
+               goto err_run;
 
        return 0;
+err_run:
+       usb_put_function(f_msg_rndis);
 err_fsg:
        usb_remove_function(c, f_acm_rndis);
 err_conf:
        usb_put_function(f_acm_rndis);
+err_func_acm:
+       usb_remove_function(c, f_rndis);
+err_func_rndis:
+       usb_put_function(f_rndis);
        return ret;
 }
 
@@ -205,10 +232,14 @@ static __ref int rndis_config_register(struct usb_composite_dev *cdev)
 /********** CDC ECM **********/
 
 #ifdef CONFIG_USB_G_MULTI_CDC
+static struct usb_function_instance *fi_ecm;
 static struct usb_function *f_acm_multi;
+static struct usb_function *f_ecm;
+static struct usb_function *f_msg_multi;
 
 static __init int cdc_do_config(struct usb_configuration *c)
 {
+       struct fsg_opts *fsg_opts;
        int ret;
 
        if (gadget_is_otg(c->cdev->gadget)) {
@@ -216,28 +247,51 @@ static __init int cdc_do_config(struct usb_configuration *c)
                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       ret = ecm_bind_config(c, host_mac, the_dev);
+       f_ecm = usb_get_function(fi_ecm);
+       if (IS_ERR(f_ecm))
+               return PTR_ERR(f_ecm);
+
+       ret = usb_add_function(c, f_ecm);
        if (ret < 0)
-               return ret;
+               goto err_func_ecm;
 
        /* implicit port_num is zero */
        f_acm_multi = usb_get_function(fi_acm);
-       if (IS_ERR(f_acm_multi))
-               return PTR_ERR(f_acm_multi);
+       if (IS_ERR(f_acm_multi)) {
+               ret = PTR_ERR(f_acm_multi);
+               goto err_func_acm;
+       }
 
        ret = usb_add_function(c, f_acm_multi);
        if (ret)
                goto err_conf;
 
-       ret = fsg_bind_config(c->cdev, c, &fsg_common);
-       if (ret < 0)
+       f_msg_multi = usb_get_function(fi_msg);
+       if (IS_ERR(f_msg_multi)) {
+               ret = PTR_ERR(f_msg_multi);
                goto err_fsg;
+       }
+
+       fsg_opts = fsg_opts_from_func_inst(fi_msg);
+       ret = fsg_common_run_thread(fsg_opts->common);
+       if (ret)
+               goto err_run;
+
+       ret = usb_add_function(c, f_msg_multi);
+       if (ret)
+               goto err_run;
 
        return 0;
+err_run:
+       usb_put_function(f_msg_multi);
 err_fsg:
        usb_remove_function(c, f_acm_multi);
 err_conf:
        usb_put_function(f_acm_multi);
+err_func_acm:
+       usb_remove_function(c, f_ecm);
+err_func_ecm:
+       usb_put_function(f_ecm);
        return ret;
 }
 
@@ -270,19 +324,67 @@ static __ref int cdc_config_register(struct usb_composite_dev *cdev)
 static int __ref multi_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget *gadget = cdev->gadget;
+#ifdef CONFIG_USB_G_MULTI_CDC
+       struct f_ecm_opts *ecm_opts;
+#endif
+#ifdef USB_ETH_RNDIS
+       struct f_rndis_opts *rndis_opts;
+#endif
+       struct fsg_opts *fsg_opts;
+       struct fsg_config config;
        int status;
 
        if (!can_support_ecm(cdev->gadget)) {
                dev_err(&gadget->dev, "controller '%s' not usable\n",
-                       gadget->name);
+                       gadget->name);
                return -EINVAL;
        }
 
-       /* set up network link layer */
-       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
-                              qmult);
-       if (IS_ERR(the_dev))
-               return PTR_ERR(the_dev);
+#ifdef CONFIG_USB_G_MULTI_CDC
+       fi_ecm = usb_get_function_instance("ecm");
+       if (IS_ERR(fi_ecm))
+               return PTR_ERR(fi_ecm);
+
+       ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
+
+       gether_set_qmult(ecm_opts->net, qmult);
+       if (!gether_set_host_addr(ecm_opts->net, host_addr))
+               pr_info("using host ethernet address: %s", host_addr);
+       if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+               pr_info("using self ethernet address: %s", dev_addr);
+#endif
+
+#ifdef USB_ETH_RNDIS
+       fi_rndis = usb_get_function_instance("rndis");
+       if (IS_ERR(fi_rndis)) {
+               status = PTR_ERR(fi_rndis);
+               goto fail;
+       }
+
+       rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst);
+
+       gether_set_qmult(rndis_opts->net, qmult);
+       if (!gether_set_host_addr(rndis_opts->net, host_addr))
+               pr_info("using host ethernet address: %s", host_addr);
+       if (!gether_set_dev_addr(rndis_opts->net, dev_addr))
+               pr_info("using self ethernet address: %s", dev_addr);
+#endif
+
+#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
+       /*
+        * If both ecm and rndis are selected then:
+        *      1) rndis borrows the net interface from ecm
+        *      2) since the interface is shared it must not be bound
+        *      twice - in ecm's _and_ rndis' binds, so do it here.
+        */
+       gether_set_gadget(ecm_opts->net, cdev->gadget);
+       status = gether_register_netdev(ecm_opts->net);
+       if (status)
+               goto fail0;
+
+       rndis_borrow_net(fi_rndis, ecm_opts->net);
+       ecm_opts->bound = true;
+#endif
 
        /* set up serial link layer */
        fi_acm = usb_get_function_instance("acm");
@@ -292,49 +394,87 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
        }
 
        /* set up mass storage function */
-       {
-               void *retp;
-               retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
-               if (IS_ERR(retp)) {
-                       status = PTR_ERR(retp);
-                       goto fail1;
-               }
+       fi_msg = usb_get_function_instance("mass_storage");
+       if (IS_ERR(fi_msg)) {
+               status = PTR_ERR(fi_msg);
+               goto fail1;
        }
+       fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
+       fsg_opts = fsg_opts_from_func_inst(fi_msg);
+
+       fsg_opts->no_configfs = true;
+       status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
+       if (status)
+               goto fail2;
+
+       status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
+       if (status)
+               goto fail_set_nluns;
+
+       status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
+       if (status)
+               goto fail_set_cdev;
+
+       fsg_common_set_sysfs(fsg_opts->common, true);
+       status = fsg_common_create_luns(fsg_opts->common, &config);
+       if (status)
+               goto fail_set_cdev;
+
+       fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name,
+                                     config.product_name);
 
        /* allocate string IDs */
        status = usb_string_ids_tab(cdev, strings_dev);
        if (unlikely(status < 0))
-               goto fail2;
+               goto fail_string_ids;
        device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
 
        /* register configurations */
        status = rndis_config_register(cdev);
        if (unlikely(status < 0))
-               goto fail2;
+               goto fail_string_ids;
 
        status = cdc_config_register(cdev);
        if (unlikely(status < 0))
-               goto fail2;
+               goto fail_string_ids;
        usb_composite_overwrite_options(cdev, &coverwrite);
 
        /* we're done */
        dev_info(&gadget->dev, DRIVER_DESC "\n");
-       fsg_common_put(&fsg_common);
        return 0;
 
 
        /* error recovery */
+fail_string_ids:
+       fsg_common_remove_luns(fsg_opts->common);
+fail_set_cdev:
+       fsg_common_free_luns(fsg_opts->common);
+fail_set_nluns:
+       fsg_common_free_buffers(fsg_opts->common);
 fail2:
-       fsg_common_put(&fsg_common);
+       usb_put_function_instance(fi_msg);
 fail1:
        usb_put_function_instance(fi_acm);
 fail0:
-       gether_cleanup(the_dev);
+#ifdef USB_ETH_RNDIS
+       usb_put_function_instance(fi_rndis);
+fail:
+#endif
+#ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function_instance(fi_ecm);
+#endif
        return status;
 }
 
 static int __exit multi_unbind(struct usb_composite_dev *cdev)
 {
+#ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_msg_multi);
+#endif
+#ifdef USB_ETH_RNDIS
+       usb_put_function(f_msg_rndis);
+#endif
+       usb_put_function_instance(fi_msg);
 #ifdef CONFIG_USB_G_MULTI_CDC
        usb_put_function(f_acm_multi);
 #endif
@@ -342,7 +482,14 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
        usb_put_function(f_acm_rndis);
 #endif
        usb_put_function_instance(fi_acm);
-       gether_cleanup(the_dev);
+#ifdef USB_ETH_RNDIS
+       usb_put_function(f_rndis);
+       usb_put_function_instance(fi_rndis);
+#endif
+#ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_ecm);
+       usb_put_function_instance(fi_ecm);
+#endif
        return 0;
 }
 
index 561b30efb8ee84de6fc37c33005cdadc6fbcc5ff..234711eabea14be4259eee06e8bf08ef07588b3a 100644 (file)
@@ -310,6 +310,7 @@ static struct mv_u3d_trb *mv_u3d_build_trb_one(struct mv_u3d_req *req,
         */
        trb_hw = dma_pool_alloc(u3d->trb_pool, GFP_ATOMIC, dma);
        if (!trb_hw) {
+               kfree(trb);
                dev_err(u3d->dev,
                        "%s, dma_pool_alloc fail\n", __func__);
                return NULL;
@@ -454,6 +455,7 @@ static int mv_u3d_req_to_trb(struct mv_u3d_req *req)
 
                trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC);
                if (!trb_hw) {
+                       kfree(trb);
                        dev_err(u3d->dev,
                                        "%s, trb_hw alloc fail\n", __func__);
                        return -ENOMEM;
@@ -1936,7 +1938,7 @@ static int mv_u3d_probe(struct platform_device *dev)
        }
        u3d->irq = r->start;
        if (request_irq(u3d->irq, mv_u3d_irq,
-               IRQF_DISABLED | IRQF_SHARED, driver_name, u3d)) {
+               IRQF_SHARED, driver_name, u3d)) {
                u3d->irq = 0;
                dev_err(&dev->dev, "Request irq %d for u3d failed\n",
                        u3d->irq);
index 0781bff70015da3e259106a829d50ad1a507e346..fc852177c08719428d9e445546adb0f53f99a47b 100644 (file)
@@ -129,7 +129,7 @@ static char *type_string (u8 bmAttributes)
        case USB_ENDPOINT_XFER_BULK:    return "bulk";
        case USB_ENDPOINT_XFER_ISOC:    return "iso";
        case USB_ENDPOINT_XFER_INT:     return "intr";
-       };
+       }
        return "control";
 }
 #endif
@@ -1630,7 +1630,7 @@ static ssize_t queues_show(struct device *_dev, struct device_attribute *attr,
                                        val = "intr"; break;
                                 default:
                                        val = "iso"; break;
-                                }; val; }),
+                                } val; }),
                                usb_endpoint_maxp (d) & 0x1fff,
                                ep->dma ? "dma" : "pio", ep->fifo_size
                                );
@@ -2680,7 +2680,6 @@ static void net2280_remove (struct pci_dev *pdev)
        if (dev->enabled)
                pci_disable_device (pdev);
        device_remove_file (&pdev->dev, &dev_attr_registers);
-       pci_set_drvdata (pdev, NULL);
 
        INFO (dev, "unbind\n");
 }
index 24174e1d15642be63c652340c80e81dc61d1bb15..32d5e923750b017a479d394e51ba09c991c8ef4d 100644 (file)
@@ -3080,7 +3080,6 @@ static void pch_udc_remove(struct pci_dev *pdev)
        if (dev->active)
                pci_disable_device(pdev);
        kfree(dev);
-       pci_set_drvdata(pdev, NULL);
 }
 
 #ifdef CONFIG_PM
index 9575085ded8112e05eddda04a60d52231b1f0a02..a3ad732bc812254798a11f4664093008729ba567 100644 (file)
@@ -1068,7 +1068,7 @@ static int rndis_proc_show(struct seq_file *m, void *v)
                                s = "RNDIS_INITIALIZED"; break;
                         case RNDIS_DATA_INITIALIZED:
                                s = "RNDIS_DATA_INITIALIZED"; break;
-                       }; s; }),
+                       } s; }),
                         param->medium,
                         (param->media_state) ? 0 : param->speed*100,
                         (param->media_state) ? "disconnected" : "connected",
index a8a99e4748d522bded4aef1882a7beaafe45603b..9875d9c0823f7c554744a40acb0a70897dde0bc6 100644 (file)
@@ -83,9 +83,12 @@ struct s3c_hsotg_req;
  * @dir_in: Set to true if this endpoint is of the IN direction, which
  *         means that it is sending data to the Host.
  * @index: The index for the endpoint registers.
+ * @mc: Multi Count - number of transactions per microframe
+ * @interval - Interval for periodic endpoints
  * @name: The name array passed to the USB core.
  * @halted: Set if the endpoint has been halted.
  * @periodic: Set if this is a periodic ep, such as Interrupt
+ * @isochronous: Set if this is a isochronous ep
  * @sent_zlp: Set if we've sent a zero-length packet.
  * @total_data: The total number of data bytes done.
  * @fifo_size: The size of the FIFO (for periodic IN endpoints)
@@ -121,9 +124,12 @@ struct s3c_hsotg_ep {
 
        unsigned char           dir_in;
        unsigned char           index;
+       unsigned char           mc;
+       unsigned char           interval;
 
        unsigned int            halted:1;
        unsigned int            periodic:1;
+       unsigned int            isochronous:1;
        unsigned int            sent_zlp:1;
 
        char                    name[10];
@@ -468,6 +474,7 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
        void *data;
        int can_write;
        int pkt_round;
+       int max_transfer;
 
        to_write -= (buf_pos - hs_ep->last_load);
 
@@ -535,8 +542,10 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
                can_write *= 4; /* fifo size is in 32bit quantities. */
        }
 
-       dev_dbg(hsotg->dev, "%s: GNPTXSTS=%08x, can=%d, to=%d, mps %d\n",
-                __func__, gnptxsts, can_write, to_write, hs_ep->ep.maxpacket);
+       max_transfer = hs_ep->ep.maxpacket * hs_ep->mc;
+
+       dev_dbg(hsotg->dev, "%s: GNPTXSTS=%08x, can=%d, to=%d, max_transfer %d\n",
+                __func__, gnptxsts, can_write, to_write, max_transfer);
 
        /*
         * limit to 512 bytes of data, it seems at least on the non-periodic
@@ -551,19 +560,21 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
         * the transfer to return that it did not run out of fifo space
         * doing it.
         */
-       if (to_write > hs_ep->ep.maxpacket) {
-               to_write = hs_ep->ep.maxpacket;
+       if (to_write > max_transfer) {
+               to_write = max_transfer;
 
-               s3c_hsotg_en_gsint(hsotg,
-                                  periodic ? GINTSTS_PTxFEmp :
-                                  GINTSTS_NPTxFEmp);
+               /* it's needed only when we do not use dedicated fifos */
+               if (!hsotg->dedicated_fifos)
+                       s3c_hsotg_en_gsint(hsotg,
+                                          periodic ? GINTSTS_PTxFEmp :
+                                          GINTSTS_NPTxFEmp);
        }
 
        /* see if we can write data */
 
        if (to_write > can_write) {
                to_write = can_write;
-               pkt_round = to_write % hs_ep->ep.maxpacket;
+               pkt_round = to_write % max_transfer;
 
                /*
                 * Round the write down to an
@@ -581,9 +592,11 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
                 * is more room left.
                 */
 
-               s3c_hsotg_en_gsint(hsotg,
-                                  periodic ? GINTSTS_PTxFEmp :
-                                  GINTSTS_NPTxFEmp);
+               /* it's needed only when we do not use dedicated fifos */
+               if (!hsotg->dedicated_fifos)
+                       s3c_hsotg_en_gsint(hsotg,
+                                          periodic ? GINTSTS_PTxFEmp :
+                                          GINTSTS_NPTxFEmp);
        }
 
        dev_dbg(hsotg->dev, "write %d/%d, can_write %d, done %d\n",
@@ -727,8 +740,16 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
        else
                packets = 1;    /* send one packet if length is zero. */
 
+       if (hs_ep->isochronous && length > (hs_ep->mc * hs_ep->ep.maxpacket)) {
+               dev_err(hsotg->dev, "req length > maxpacket*mc\n");
+               return;
+       }
+
        if (dir_in && index != 0)
-               epsize = DxEPTSIZ_MC(1);
+               if (hs_ep->isochronous)
+                       epsize = DxEPTSIZ_MC(packets);
+               else
+                       epsize = DxEPTSIZ_MC(1);
        else
                epsize = 0;
 
@@ -820,6 +841,9 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
 
        dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n",
                __func__, readl(hsotg->regs + epctrl_reg));
+
+       /* enable ep interrupts */
+       s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1);
 }
 
 /**
@@ -1091,6 +1115,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
        bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
        struct s3c_hsotg_ep *ep;
        int ret;
+       bool halted;
 
        dev_dbg(hsotg->dev, "%s: %s_FEATURE\n",
                __func__, set ? "SET" : "CLEAR");
@@ -1105,6 +1130,8 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
 
                switch (le16_to_cpu(ctrl->wValue)) {
                case USB_ENDPOINT_HALT:
+                       halted = ep->halted;
+
                        s3c_hsotg_ep_sethalt(&ep->ep, set);
 
                        ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
@@ -1114,7 +1141,12 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
                                return ret;
                        }
 
-                       if (!set) {
+                       /*
+                        * we have to complete all requests for ep if it was
+                        * halted, and the halt was cleared by CLEAR_FEATURE
+                        */
+
+                       if (!set && halted) {
                                /*
                                 * If we have request in progress,
                                 * then complete it
@@ -1147,6 +1179,8 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
        return 1;
 }
 
+static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
+
 /**
  * s3c_hsotg_process_control - process a control request
  * @hsotg: The device state
@@ -1246,11 +1280,15 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
                 * don't believe we need to anything more to get the EP
                 * to reply with a STALL packet
                 */
+
+                /*
+                 * complete won't be called, so we enqueue
+                 * setup request here
+                 */
+                s3c_hsotg_enqueue_setup(hsotg);
        }
 }
 
-static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
-
 /**
  * s3c_hsotg_complete_setup - completion of a setup transfer
  * @ep: The endpoint the request was on.
@@ -1698,6 +1736,7 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
        struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep];
        void __iomem *regs = hsotg->regs;
        u32 mpsval;
+       u32 mcval;
        u32 reg;
 
        if (ep == 0) {
@@ -1705,15 +1744,19 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
                mpsval = s3c_hsotg_ep0_mps(mps);
                if (mpsval > 3)
                        goto bad_mps;
+               hs_ep->ep.maxpacket = mps;
+               hs_ep->mc = 1;
        } else {
-               if (mps >= DxEPCTL_MPS_LIMIT+1)
+               mpsval = mps & DxEPCTL_MPS_MASK;
+               if (mpsval > 1024)
                        goto bad_mps;
-
-               mpsval = mps;
+               mcval = ((mps >> 11) & 0x3) + 1;
+               hs_ep->mc = mcval;
+               if (mcval > 3)
+                       goto bad_mps;
+               hs_ep->ep.maxpacket = mpsval;
        }
 
-       hs_ep->ep.maxpacket = mps;
-
        /*
         * update both the in and out endpoint controldir_ registers, even
         * if one of the directions may not be in use.
@@ -1782,8 +1825,16 @@ static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg,
 {
        struct s3c_hsotg_req *hs_req = hs_ep->req;
 
-       if (!hs_ep->dir_in || !hs_req)
+       if (!hs_ep->dir_in || !hs_req) {
+               /**
+                * if request is not enqueued, we disable interrupts
+                * for endpoints, excepting ep0
+                */
+               if (hs_ep->index != 0)
+                       s3c_hsotg_ctrl_epint(hsotg, hs_ep->index,
+                                            hs_ep->dir_in, 0);
                return 0;
+       }
 
        if (hs_req->req.actual < hs_req->req.length) {
                dev_dbg(hsotg->dev, "trying to write more for ep%d\n",
@@ -1887,8 +1938,10 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
        u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx);
        u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx);
        u32 ints;
+       u32 ctrl;
 
        ints = readl(hsotg->regs + epint_reg);
+       ctrl = readl(hsotg->regs + epctl_reg);
 
        /* Clear endpoint interrupts */
        writel(ints, hsotg->regs + epint_reg);
@@ -1897,6 +1950,14 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
                __func__, idx, dir_in ? "in" : "out", ints);
 
        if (ints & DxEPINT_XferCompl) {
+               if (hs_ep->isochronous && hs_ep->interval == 1) {
+                       if (ctrl & DxEPCTL_EOFrNum)
+                               ctrl |= DxEPCTL_SetEvenFr;
+                       else
+                               ctrl |= DxEPCTL_SetOddFr;
+                       writel(ctrl, hsotg->regs + epctl_reg);
+               }
+
                dev_dbg(hsotg->dev,
                        "%s: XferCompl: DxEPCTL=0x%08x, DxEPTSIZ=%08x\n",
                        __func__, readl(hsotg->regs + epctl_reg),
@@ -1963,7 +2024,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
        if (ints & DxEPINT_Back2BackSetup)
                dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__);
 
-       if (dir_in) {
+       if (dir_in && !hs_ep->isochronous) {
                /* not sure if this is important, but we'll clear it anyway */
                if (ints & DIEPMSK_INTknTXFEmpMsk) {
                        dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n",
@@ -2092,12 +2153,14 @@ static void kill_all_requests(struct s3c_hsotg *hsotg,
 }
 
 #define call_gadget(_hs, _entry) \
+do { \
        if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \
            (_hs)->driver && (_hs)->driver->_entry) { \
                spin_unlock(&_hs->lock); \
                (_hs)->driver->_entry(&(_hs)->gadget); \
                spin_lock(&_hs->lock); \
-               }
+       } \
+} while (0)
 
 /**
  * s3c_hsotg_disconnect - disconnect service
@@ -2241,15 +2304,19 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
                       GAHBCFG_HBstLen_Incr4,
                       hsotg->regs + GAHBCFG);
        else
-               writel(GAHBCFG_GlblIntrEn, hsotg->regs + GAHBCFG);
+               writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NPTxFEmpLvl |
+                                                   GAHBCFG_PTxFEmpLvl) : 0) |
+                      GAHBCFG_GlblIntrEn,
+                      hsotg->regs + GAHBCFG);
 
        /*
-        * Enabling INTknTXFEmpMsk here seems to be a big mistake, we end
-        * up being flooded with interrupts if the host is polling the
-        * endpoint to try and read data.
+        * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts
+        * when we have no data to transfer. Otherwise we get being flooded by
+        * interrupts.
         */
 
-       writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty : 0) |
+       writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty |
+              DIEPMSK_INTknTXFEmpMsk : 0) |
               DIEPMSK_EPDisbldMsk | DIEPMSK_XferComplMsk |
               DIEPMSK_TimeOUTMsk | DIEPMSK_AHBErrMsk |
               DIEPMSK_INTknEPMisMsk,
@@ -2378,10 +2445,14 @@ irq_retry:
 
        if (gintsts & (GINTSTS_OEPInt | GINTSTS_IEPInt)) {
                u32 daint = readl(hsotg->regs + DAINT);
-               u32 daint_out = daint >> DAINT_OutEP_SHIFT;
-               u32 daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT);
+               u32 daintmsk = readl(hsotg->regs + DAINTMSK);
+               u32 daint_out, daint_in;
                int ep;
 
+               daint &= daintmsk;
+               daint_out = daint >> DAINT_OutEP_SHIFT;
+               daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT);
+
                dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
 
                for (ep = 0; ep < 15 && daint_out; ep++, daint_out >>= 1) {
@@ -2577,16 +2648,25 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        epctrl |= DxEPCTL_SNAK;
 
        /* update the endpoint state */
-       hs_ep->ep.maxpacket = mps;
+       s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps);
 
        /* default, set to non-periodic */
+       hs_ep->isochronous = 0;
        hs_ep->periodic = 0;
+       hs_ep->halted = 0;
+       hs_ep->interval = desc->bInterval;
+
+       if (hs_ep->interval > 1 && hs_ep->mc > 1)
+               dev_err(hsotg->dev, "MC > 1 when interval is not 1\n");
 
        switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
        case USB_ENDPOINT_XFER_ISOC:
-               dev_err(hsotg->dev, "no current ISOC support\n");
-               ret = -EINVAL;
-               goto out;
+               epctrl |= DxEPCTL_EPType_Iso;
+               epctrl |= DxEPCTL_SetEvenFr;
+               hs_ep->isochronous = 1;
+               if (dir_in)
+                       hs_ep->periodic = 1;
+               break;
 
        case USB_ENDPOINT_XFER_BULK:
                epctrl |= DxEPCTL_EPType_Bulk;
@@ -2634,7 +2714,6 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        /* enable the endpoint interrupt */
        s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
 
-out:
        spin_unlock_irqrestore(&hsotg->lock, flags);
        return ret;
 }
@@ -2776,6 +2855,8 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 
        writel(epctl, hs->regs + epreg);
 
+       hs_ep->halted = value;
+
        return 0;
 }
 
@@ -2903,7 +2984,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
        int ret;
 
        if (!hsotg) {
-               printk(KERN_ERR "%s: called with no device\n", __func__);
+               pr_err("%s: called with no device\n", __func__);
                return -ENODEV;
        }
 
@@ -3066,7 +3147,7 @@ static void s3c_hsotg_initep(struct s3c_hsotg *hsotg,
 
        hs_ep->parent = hsotg;
        hs_ep->ep.name = hs_ep->name;
-       hs_ep->ep.maxpacket = epnum ? 512 : EP0_MPS_LIMIT;
+       hs_ep->ep.maxpacket = epnum ? 1024 : EP0_MPS_LIMIT;
        hs_ep->ep.ops = &s3c_hsotg_ep_ops;
 
        /*
@@ -3200,7 +3281,7 @@ static int state_show(struct seq_file *seq, void *v)
                   readl(regs + GNPTXSTS),
                   readl(regs + GRXSTSR));
 
-       seq_printf(seq, "\nEndpoint status:\n");
+       seq_puts(seq, "\nEndpoint status:\n");
 
        for (idx = 0; idx < 15; idx++) {
                u32 in, out;
@@ -3217,7 +3298,7 @@ static int state_show(struct seq_file *seq, void *v)
                seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x",
                           in, out);
 
-               seq_printf(seq, "\n");
+               seq_puts(seq, "\n");
        }
 
        return 0;
@@ -3251,7 +3332,7 @@ static int fifo_show(struct seq_file *seq, void *v)
        u32 val;
        int idx;
 
-       seq_printf(seq, "Non-periodic FIFOs:\n");
+       seq_puts(seq, "Non-periodic FIFOs:\n");
        seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ));
 
        val = readl(regs + GNPTXFSIZ);
@@ -3259,7 +3340,7 @@ static int fifo_show(struct seq_file *seq, void *v)
                   val >> GNPTXFSIZ_NPTxFDep_SHIFT,
                   val & GNPTXFSIZ_NPTxFStAddr_MASK);
 
-       seq_printf(seq, "\nPeriodic TXFIFOs:\n");
+       seq_puts(seq, "\nPeriodic TXFIFOs:\n");
 
        for (idx = 1; idx <= 15; idx++) {
                val = readl(regs + DPTXFSIZn(idx));
@@ -3330,7 +3411,7 @@ static int ep_show(struct seq_file *seq, void *v)
                   readl(regs + DIEPTSIZ(index)),
                   readl(regs + DOEPTSIZ(index)));
 
-       seq_printf(seq, "\n");
+       seq_puts(seq, "\n");
        seq_printf(seq, "mps %d\n", ep->ep.maxpacket);
        seq_printf(seq, "total_data=%ld\n", ep->total_data);
 
@@ -3341,7 +3422,7 @@ static int ep_show(struct seq_file *seq, void *v)
 
        list_for_each_entry(req, &ep->queue, queue) {
                if (--show_limit < 0) {
-                       seq_printf(seq, "not showing more requests...\n");
+                       seq_puts(seq, "not showing more requests...\n");
                        break;
                }
 
index 08a1a3210a2117f43b29f899085a21c547a9e644..ec20a1f50c2d702e56f6e6a79f03485607a36189 100644 (file)
  * The valid range of num_buffers is: num >= 2 && num <= 4.
  */
 
+#include <linux/module.h>
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/usb/composite.h>
 
-#include <linux/usb/storage.h>
-#include <scsi/scsi.h>
-#include <asm/unaligned.h>
-
-
-/*
- * Thanks to NetChip Technologies for donating this product ID.
- *
- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
- * Instead:  allocate your own, using normal USB-IF procedures.
- */
-#define FSG_VENDOR_ID  0x0525  /* NetChip */
-#define FSG_PRODUCT_ID 0xa4a5  /* Linux-USB File-backed Storage Gadget */
-
-
-/*-------------------------------------------------------------------------*/
-
-
-#ifndef DEBUG
-#undef VERBOSE_DEBUG
-#undef DUMP_MSGS
-#endif /* !DEBUG */
-
-#ifdef VERBOSE_DEBUG
-#define VLDBG  LDBG
-#else
-#define VLDBG(lun, fmt, args...) do { } while (0)
-#endif /* VERBOSE_DEBUG */
-
-#define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
-#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
-#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
-#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
-
-
-#ifdef DUMP_MSGS
-
-#  define dump_msg(fsg, /* const char * */ label,                      \
-                  /* const u8 * */ buf, /* unsigned */ length) do {    \
-       if (length < 512) {                                             \
-               DBG(fsg, "%s, length %u:\n", label, length);            \
-               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
-                              16, 1, buf, length, 0);                  \
-       }                                                               \
-} while (0)
-
-#  define dump_cdb(fsg) do { } while (0)
-
-#else
-
-#  define dump_msg(fsg, /* const char * */ label, \
-                  /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
-
-#  ifdef VERBOSE_DEBUG
-
-#    define dump_cdb(fsg)                                              \
-       print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
-                      16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
-
-#  else
-
-#    define dump_cdb(fsg) do { } while (0)
-
-#  endif /* VERBOSE_DEBUG */
-
-#endif /* DUMP_MSGS */
-
-/*-------------------------------------------------------------------------*/
-
-/* Length of a SCSI Command Data Block */
-#define MAX_COMMAND_SIZE       16
-
-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
-#define SS_NO_SENSE                            0
-#define SS_COMMUNICATION_FAILURE               0x040800
-#define SS_INVALID_COMMAND                     0x052000
-#define SS_INVALID_FIELD_IN_CDB                        0x052400
-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE  0x052100
-#define SS_LOGICAL_UNIT_NOT_SUPPORTED          0x052500
-#define SS_MEDIUM_NOT_PRESENT                  0x023a00
-#define SS_MEDIUM_REMOVAL_PREVENTED            0x055302
-#define SS_NOT_READY_TO_READY_TRANSITION       0x062800
-#define SS_RESET_OCCURRED                      0x062900
-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED     0x053900
-#define SS_UNRECOVERED_READ_ERROR              0x031100
-#define SS_WRITE_ERROR                         0x030c02
-#define SS_WRITE_PROTECTED                     0x072700
-
-#define SK(x)          ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
-#define ASC(x)         ((u8) ((x) >> 8))
-#define ASCQ(x)                ((u8) (x))
-
-
-/*-------------------------------------------------------------------------*/
-
-
-struct fsg_lun {
-       struct file     *filp;
-       loff_t          file_length;
-       loff_t          num_sectors;
-
-       unsigned int    initially_ro:1;
-       unsigned int    ro:1;
-       unsigned int    removable:1;
-       unsigned int    cdrom:1;
-       unsigned int    prevent_medium_removal:1;
-       unsigned int    registered:1;
-       unsigned int    info_valid:1;
-       unsigned int    nofua:1;
-
-       u32             sense_data;
-       u32             sense_data_info;
-       u32             unit_attention_data;
-
-       unsigned int    blkbits;        /* Bits of logical block size of bound block device */
-       unsigned int    blksize;        /* logical block size of bound block device */
-       struct device   dev;
-};
-
-static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
-{
-       return curlun->filp != NULL;
-}
-
-static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
-{
-       return container_of(dev, struct fsg_lun, dev);
-}
-
-
-/* Big enough to hold our biggest descriptor */
-#define EP0_BUFSIZE    256
-#define DELAYED_STATUS (EP0_BUFSIZE + 999)     /* An impossibly large value */
-
-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
-
-static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
-module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);
-MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
-
-#else
-
-/*
- * Number of buffers we will use.
- * 2 is usually enough for good buffering pipeline
- */
-#define fsg_num_buffers        CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
-
-#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
-
-/* check if fsg_num_buffers is within a valid range */
-static inline int fsg_num_buffers_validate(void)
-{
-       if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
-               return 0;
-       pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
-              fsg_num_buffers, 2 ,4);
-       return -EINVAL;
-}
-
-/* Default size of buffer length. */
-#define FSG_BUFLEN     ((u32)16384)
-
-/* Maximal number of LUNs supported in mass storage function */
-#define FSG_MAX_LUNS   8
-
-enum fsg_buffer_state {
-       BUF_STATE_EMPTY = 0,
-       BUF_STATE_FULL,
-       BUF_STATE_BUSY
-};
-
-struct fsg_buffhd {
-       void                            *buf;
-       enum fsg_buffer_state           state;
-       struct fsg_buffhd               *next;
-
-       /*
-        * The NetChip 2280 is faster, and handles some protocol faults
-        * better, if we don't submit any short bulk-out read requests.
-        * So we will record the intended request length here.
-        */
-       unsigned int                    bulk_out_intended_length;
-
-       struct usb_request              *inreq;
-       int                             inreq_busy;
-       struct usb_request              *outreq;
-       int                             outreq_busy;
-};
-
-enum fsg_state {
-       /* This one isn't used anywhere */
-       FSG_STATE_COMMAND_PHASE = -10,
-       FSG_STATE_DATA_PHASE,
-       FSG_STATE_STATUS_PHASE,
-
-       FSG_STATE_IDLE = 0,
-       FSG_STATE_ABORT_BULK_OUT,
-       FSG_STATE_RESET,
-       FSG_STATE_INTERFACE_CHANGE,
-       FSG_STATE_CONFIG_CHANGE,
-       FSG_STATE_DISCONNECT,
-       FSG_STATE_EXIT,
-       FSG_STATE_TERMINATED
-};
-
-enum data_direction {
-       DATA_DIR_UNKNOWN = 0,
-       DATA_DIR_FROM_HOST,
-       DATA_DIR_TO_HOST,
-       DATA_DIR_NONE
-};
-
-
-/*-------------------------------------------------------------------------*/
-
-
-static inline u32 get_unaligned_be24(u8 *buf)
-{
-       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-
-enum {
-       FSG_STRING_INTERFACE
-};
-
+#include "storage_common.h"
 
 /* There is only one interface. */
 
-static struct usb_interface_descriptor
-fsg_intf_desc = {
+struct usb_interface_descriptor fsg_intf_desc = {
        .bLength =              sizeof fsg_intf_desc,
        .bDescriptorType =      USB_DT_INTERFACE,
 
@@ -268,14 +43,14 @@ fsg_intf_desc = {
        .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
        .iInterface =           FSG_STRING_INTERFACE,
 };
+EXPORT_SYMBOL(fsg_intf_desc);
 
 /*
  * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
  * interrupt-in.
  */
 
-static struct usb_endpoint_descriptor
-fsg_fs_bulk_in_desc = {
+struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -283,9 +58,9 @@ fsg_fs_bulk_in_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        /* wMaxPacketSize set by autoconfiguration */
 };
+EXPORT_SYMBOL(fsg_fs_bulk_in_desc);
 
-static struct usb_endpoint_descriptor
-fsg_fs_bulk_out_desc = {
+struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -293,13 +68,15 @@ fsg_fs_bulk_out_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        /* wMaxPacketSize set by autoconfiguration */
 };
+EXPORT_SYMBOL(fsg_fs_bulk_out_desc);
 
-static struct usb_descriptor_header *fsg_fs_function[] = {
+struct usb_descriptor_header *fsg_fs_function[] = {
        (struct usb_descriptor_header *) &fsg_intf_desc,
        (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
        (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
        NULL,
 };
+EXPORT_SYMBOL(fsg_fs_function);
 
 
 /*
@@ -310,8 +87,7 @@ static struct usb_descriptor_header *fsg_fs_function[] = {
  * and a "device qualifier" ... plus more construction options
  * for the configuration descriptor.
  */
-static struct usb_endpoint_descriptor
-fsg_hs_bulk_in_desc = {
+struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -319,9 +95,9 @@ fsg_hs_bulk_in_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(512),
 };
+EXPORT_SYMBOL(fsg_hs_bulk_in_desc);
 
-static struct usb_endpoint_descriptor
-fsg_hs_bulk_out_desc = {
+struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -330,17 +106,18 @@ fsg_hs_bulk_out_desc = {
        .wMaxPacketSize =       cpu_to_le16(512),
        .bInterval =            1,      /* NAK every 1 uframe */
 };
+EXPORT_SYMBOL(fsg_hs_bulk_out_desc);
 
 
-static struct usb_descriptor_header *fsg_hs_function[] = {
+struct usb_descriptor_header *fsg_hs_function[] = {
        (struct usb_descriptor_header *) &fsg_intf_desc,
        (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
        (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
        NULL,
 };
+EXPORT_SYMBOL(fsg_hs_function);
 
-static struct usb_endpoint_descriptor
-fsg_ss_bulk_in_desc = {
+struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -348,16 +125,17 @@ fsg_ss_bulk_in_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(1024),
 };
+EXPORT_SYMBOL(fsg_ss_bulk_in_desc);
 
-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
+struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
        .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
 
        /*.bMaxBurst =          DYNAMIC, */
 };
+EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc);
 
-static struct usb_endpoint_descriptor
-fsg_ss_bulk_out_desc = {
+struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -365,15 +143,17 @@ fsg_ss_bulk_out_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(1024),
 };
+EXPORT_SYMBOL(fsg_ss_bulk_out_desc);
 
-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
+struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
        .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
 
        /*.bMaxBurst =          DYNAMIC, */
 };
+EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc);
 
-static struct usb_descriptor_header *fsg_ss_function[] = {
+struct usb_descriptor_header *fsg_ss_function[] = {
        (struct usb_descriptor_header *) &fsg_intf_desc,
        (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
        (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
@@ -381,17 +161,7 @@ static struct usb_descriptor_header *fsg_ss_function[] = {
        (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
        NULL,
 };
-
-/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
-static struct usb_string               fsg_strings[] = {
-       {FSG_STRING_INTERFACE,          fsg_string_interface},
-       {}
-};
-
-static struct usb_gadget_strings       fsg_stringtab = {
-       .language       = 0x0409,               /* en-us */
-       .strings        = fsg_strings,
-};
+EXPORT_SYMBOL(fsg_ss_function);
 
 
  /*-------------------------------------------------------------------------*/
@@ -401,7 +171,7 @@ static struct usb_gadget_strings    fsg_stringtab = {
  * the caller must own fsg->filesem for writing.
  */
 
-static void fsg_lun_close(struct fsg_lun *curlun)
+void fsg_lun_close(struct fsg_lun *curlun)
 {
        if (curlun->filp) {
                LDBG(curlun, "close backing file\n");
@@ -409,9 +179,9 @@ static void fsg_lun_close(struct fsg_lun *curlun)
                curlun->filp = NULL;
        }
 }
+EXPORT_SYMBOL(fsg_lun_close);
 
-
-static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
 {
        int                             ro;
        struct file                     *filp = NULL;
@@ -508,6 +278,7 @@ out:
        fput(filp);
        return rc;
 }
+EXPORT_SYMBOL(fsg_lun_open);
 
 
 /*-------------------------------------------------------------------------*/
@@ -516,7 +287,7 @@ out:
  * Sync the file data, don't bother with the metadata.
  * This code was copied from fs/buffer.c:sys_fdatasync().
  */
-static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+int fsg_lun_fsync_sub(struct fsg_lun *curlun)
 {
        struct file     *filp = curlun->filp;
 
@@ -524,8 +295,9 @@ static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
                return 0;
        return vfs_fsync(filp, 1);
 }
+EXPORT_SYMBOL(fsg_lun_fsync_sub);
 
-static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+void store_cdrom_address(u8 *dest, int msf, u32 addr)
 {
        if (msf) {
                /* Convert to Minutes-Seconds-Frames */
@@ -542,34 +314,28 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr)
                put_unaligned_be32(addr, dest);
        }
 }
-
+EXPORT_SYMBOL(store_cdrom_address);
 
 /*-------------------------------------------------------------------------*/
 
 
-static ssize_t ro_show(struct device *dev, struct device_attribute *attr,
-                      char *buf)
+ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-
        return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
                                  ? curlun->ro
                                  : curlun->initially_ro);
 }
+EXPORT_SYMBOL(fsg_show_ro);
 
-static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
-                         char *buf)
+ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-
        return sprintf(buf, "%u\n", curlun->nofua);
 }
+EXPORT_SYMBOL(fsg_show_nofua);
 
-static ssize_t file_show(struct device *dev, struct device_attribute *attr,
-                        char *buf)
+ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
        char            *p;
        ssize_t         rc;
 
@@ -591,17 +357,44 @@ static ssize_t file_show(struct device *dev, struct device_attribute *attr,
        up_read(filesem);
        return rc;
 }
+EXPORT_SYMBOL(fsg_show_file);
 
+ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf)
+{
+       return sprintf(buf, "%u\n", curlun->cdrom);
+}
+EXPORT_SYMBOL(fsg_show_cdrom);
 
-static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
-                       const char *buf, size_t count)
+ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
+{
+       return sprintf(buf, "%u\n", curlun->removable);
+}
+EXPORT_SYMBOL(fsg_show_removable);
+
+/*
+ * The caller must hold fsg->filesem for reading when calling this function.
+ */
+static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro)
+{
+       if (fsg_lun_is_open(curlun)) {
+               LDBG(curlun, "read-only status change prevented\n");
+               return -EBUSY;
+       }
+
+       curlun->ro = ro;
+       curlun->initially_ro = ro;
+       LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+
+       return 0;
+}
+
+ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count)
 {
        ssize_t         rc;
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
-       unsigned        ro;
+       bool            ro;
 
-       rc = kstrtouint(buf, 2, &ro);
+       rc = strtobool(buf, &ro);
        if (rc)
                return rc;
 
@@ -610,27 +403,21 @@ static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
         * backing file is closed.
         */
        down_read(filesem);
-       if (fsg_lun_is_open(curlun)) {
-               LDBG(curlun, "read-only status change prevented\n");
-               rc = -EBUSY;
-       } else {
-               curlun->ro = ro;
-               curlun->initially_ro = ro;
-               LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+       rc = _fsg_store_ro(curlun, ro);
+       if (!rc)
                rc = count;
-       }
        up_read(filesem);
+
        return rc;
 }
+EXPORT_SYMBOL(fsg_store_ro);
 
-static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
-                          const char *buf, size_t count)
+ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       unsigned        nofua;
+       bool            nofua;
        int             ret;
 
-       ret = kstrtouint(buf, 2, &nofua);
+       ret = strtobool(buf, &nofua);
        if (ret)
                return ret;
 
@@ -642,12 +429,11 @@ static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
 
        return count;
 }
+EXPORT_SYMBOL(fsg_store_nofua);
 
-static ssize_t file_store(struct device *dev, struct device_attribute *attr,
-                         const char *buf, size_t count)
+ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
        int             rc = 0;
 
        if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
@@ -674,3 +460,45 @@ static ssize_t file_store(struct device *dev, struct device_attribute *attr,
        up_write(filesem);
        return (rc < 0 ? rc : count);
 }
+EXPORT_SYMBOL(fsg_store_file);
+
+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                       const char *buf, size_t count)
+{
+       bool            cdrom;
+       int             ret;
+
+       ret = strtobool(buf, &cdrom);
+       if (ret)
+               return ret;
+
+       down_read(filesem);
+       ret = cdrom ? _fsg_store_ro(curlun, true) : 0;
+
+       if (!ret) {
+               curlun->cdrom = cdrom;
+               ret = count;
+       }
+       up_read(filesem);
+
+       return ret;
+}
+EXPORT_SYMBOL(fsg_store_cdrom);
+
+ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+                           size_t count)
+{
+       bool            removable;
+       int             ret;
+
+       ret = strtobool(buf, &removable);
+       if (ret)
+               return ret;
+
+       curlun->removable = removable;
+
+       return count;
+}
+EXPORT_SYMBOL(fsg_store_removable);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
new file mode 100644 (file)
index 0000000..c74c2fd
--- /dev/null
@@ -0,0 +1,229 @@
+#ifndef USB_STORAGE_COMMON_H
+#define USB_STORAGE_COMMON_H
+
+#include <linux/device.h>
+#include <linux/usb/storage.h>
+#include <scsi/scsi.h>
+#include <asm/unaligned.h>
+
+#ifndef DEBUG
+#undef VERBOSE_DEBUG
+#undef DUMP_MSGS
+#endif /* !DEBUG */
+
+#ifdef VERBOSE_DEBUG
+#define VLDBG  LDBG
+#else
+#define VLDBG(lun, fmt, args...) do { } while (0)
+#endif /* VERBOSE_DEBUG */
+
+#define _LMSG(func, lun, fmt, args...)                                 \
+       do {                                                            \
+               if ((lun)->name_pfx && *(lun)->name_pfx)                \
+                       func("%s/%s: " fmt, *(lun)->name_pfx,           \
+                                (lun)->name, ## args);                 \
+               else                                                    \
+                       func("%s: " fmt, (lun)->name, ## args);         \
+       } while (0)
+
+#define LDBG(lun, fmt, args...)                _LMSG(pr_debug, lun, fmt, ## args)
+#define LERROR(lun, fmt, args...)      _LMSG(pr_err, lun, fmt, ## args)
+#define LWARN(lun, fmt, args...)       _LMSG(pr_warn, lun, fmt, ## args)
+#define LINFO(lun, fmt, args...)       _LMSG(pr_info, lun, fmt, ## args)
+
+
+#ifdef DUMP_MSGS
+
+#  define dump_msg(fsg, /* const char * */ label,                      \
+                  /* const u8 * */ buf, /* unsigned */ length)         \
+do {                                                                   \
+       if (length < 512) {                                             \
+               DBG(fsg, "%s, length %u:\n", label, length);            \
+               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
+                              16, 1, buf, length, 0);                  \
+       }                                                               \
+} while (0)
+
+#  define dump_cdb(fsg) do { } while (0)
+
+#else
+
+#  define dump_msg(fsg, /* const char * */ label, \
+                  /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
+
+#  ifdef VERBOSE_DEBUG
+
+#    define dump_cdb(fsg)                                              \
+       print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
+                      16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
+
+#  else
+
+#    define dump_cdb(fsg) do { } while (0)
+
+#  endif /* VERBOSE_DEBUG */
+
+#endif /* DUMP_MSGS */
+
+/* Length of a SCSI Command Data Block */
+#define MAX_COMMAND_SIZE       16
+
+/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+#define SS_NO_SENSE                            0
+#define SS_COMMUNICATION_FAILURE               0x040800
+#define SS_INVALID_COMMAND                     0x052000
+#define SS_INVALID_FIELD_IN_CDB                        0x052400
+#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE  0x052100
+#define SS_LOGICAL_UNIT_NOT_SUPPORTED          0x052500
+#define SS_MEDIUM_NOT_PRESENT                  0x023a00
+#define SS_MEDIUM_REMOVAL_PREVENTED            0x055302
+#define SS_NOT_READY_TO_READY_TRANSITION       0x062800
+#define SS_RESET_OCCURRED                      0x062900
+#define SS_SAVING_PARAMETERS_NOT_SUPPORTED     0x053900
+#define SS_UNRECOVERED_READ_ERROR              0x031100
+#define SS_WRITE_ERROR                         0x030c02
+#define SS_WRITE_PROTECTED                     0x072700
+
+#define SK(x)          ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
+#define ASC(x)         ((u8) ((x) >> 8))
+#define ASCQ(x)                ((u8) (x))
+
+struct fsg_lun {
+       struct file     *filp;
+       loff_t          file_length;
+       loff_t          num_sectors;
+
+       unsigned int    initially_ro:1;
+       unsigned int    ro:1;
+       unsigned int    removable:1;
+       unsigned int    cdrom:1;
+       unsigned int    prevent_medium_removal:1;
+       unsigned int    registered:1;
+       unsigned int    info_valid:1;
+       unsigned int    nofua:1;
+
+       u32             sense_data;
+       u32             sense_data_info;
+       u32             unit_attention_data;
+
+       unsigned int    blkbits; /* Bits of logical block size
+                                                      of bound block device */
+       unsigned int    blksize; /* logical block size of bound block device */
+       struct device   dev;
+       const char      *name;          /* "lun.name" */
+       const char      **name_pfx;     /* "function.name" */
+};
+
+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)
+
+/* Maximal number of LUNs supported in mass storage function */
+#define FSG_MAX_LUNS   8
+
+enum fsg_buffer_state {
+       BUF_STATE_EMPTY = 0,
+       BUF_STATE_FULL,
+       BUF_STATE_BUSY
+};
+
+struct fsg_buffhd {
+       void                            *buf;
+       enum fsg_buffer_state           state;
+       struct fsg_buffhd               *next;
+
+       /*
+        * The NetChip 2280 is faster, and handles some protocol faults
+        * better, if we don't submit any short bulk-out read requests.
+        * So we will record the intended request length here.
+        */
+       unsigned int                    bulk_out_intended_length;
+
+       struct usb_request              *inreq;
+       int                             inreq_busy;
+       struct usb_request              *outreq;
+       int                             outreq_busy;
+};
+
+enum fsg_state {
+       /* This one isn't used anywhere */
+       FSG_STATE_COMMAND_PHASE = -10,
+       FSG_STATE_DATA_PHASE,
+       FSG_STATE_STATUS_PHASE,
+
+       FSG_STATE_IDLE = 0,
+       FSG_STATE_ABORT_BULK_OUT,
+       FSG_STATE_RESET,
+       FSG_STATE_INTERFACE_CHANGE,
+       FSG_STATE_CONFIG_CHANGE,
+       FSG_STATE_DISCONNECT,
+       FSG_STATE_EXIT,
+       FSG_STATE_TERMINATED
+};
+
+enum data_direction {
+       DATA_DIR_UNKNOWN = 0,
+       DATA_DIR_FROM_HOST,
+       DATA_DIR_TO_HOST,
+       DATA_DIR_NONE
+};
+
+static inline u32 get_unaligned_be24(u8 *buf)
+{
+       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+}
+
+static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+{
+       return container_of(dev, struct fsg_lun, dev);
+}
+
+enum {
+       FSG_STRING_INTERFACE
+};
+
+extern struct usb_interface_descriptor fsg_intf_desc;
+
+extern struct usb_endpoint_descriptor fsg_fs_bulk_in_desc;
+extern struct usb_endpoint_descriptor fsg_fs_bulk_out_desc;
+extern struct usb_descriptor_header *fsg_fs_function[];
+
+extern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc;
+extern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc;
+extern struct usb_descriptor_header *fsg_hs_function[];
+
+extern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc;
+extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc;
+extern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc;
+extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc;
+extern struct usb_descriptor_header *fsg_ss_function[];
+
+void fsg_lun_close(struct fsg_lun *curlun);
+int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
+int fsg_lun_fsync_sub(struct fsg_lun *curlun);
+void store_cdrom_address(u8 *dest, int msf, u32 addr);
+ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
+ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
+ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf);
+ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf);
+ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf);
+ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count);
+ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
+ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                       const char *buf, size_t count);
+ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+                           size_t count);
+
+#endif /* USB_STORAGE_COMMON_H */
index 0ff33396eef3ac6e99a78af1db7874d82cff8480..eccea1df702df3afc45c692de31b23febfb52c37 100644 (file)
@@ -472,7 +472,7 @@ static int usbg_bot_setup(struct usb_function *f,
                bot_enqueue_cmd_cbw(fu);
                return 0;
                break;
-       };
+       }
        return -ENOTSUPP;
 }
 
@@ -617,7 +617,7 @@ static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req)
 
        default:
                BUG();
-       };
+       }
        return;
 
 cleanup:
index 59891b1c48fc2e7a04febe488b979b23f3a1cb6f..27768a7d986a7f84e66d510be82cab2c513c7367 100644 (file)
@@ -356,7 +356,8 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
        kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
        return 0;
 err1:
-       dev_err(&udc->dev, "failed to start %s: %d\n",
+       if (ret != -EISNAM)
+               dev_err(&udc->dev, "failed to start %s: %d\n",
                        udc->driver->function, ret);
        udc->driver = NULL;
        udc->dev.driver = NULL;
index 0deb9d6cde26245fd1c52c0b541eecd100aedce6..0dd07ae1555ddf066312e0ff4e8182a02f27a3d6 100644 (file)
@@ -95,6 +95,18 @@ 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;
+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;
+module_param(autoresume_interval_ms, uint, S_IRUGO);
+MODULE_PARM_DESC(autoresume_interval_ms,
+               "milliseconds to increase successive wakeup delays");
+
+static unsigned autoresume_step_ms;
 /*-------------------------------------------------------------------------*/
 
 static struct usb_device_descriptor device_desc = {
@@ -183,8 +195,16 @@ static void zero_suspend(struct usb_composite_dev *cdev)
                return;
 
        if (autoresume) {
-               mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
-               DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
+               if (max_autoresume &&
+                       (autoresume_step_ms > max_autoresume * 1000))
+                               autoresume_step_ms = autoresume * 1000;
+
+               mod_timer(&autoresume_timer, jiffies +
+                       msecs_to_jiffies(autoresume_step_ms));
+               DBG(cdev, "suspend, wakeup in %d milliseconds\n",
+                       autoresume_step_ms);
+
+               autoresume_step_ms += autoresume_interval_ms;
        } else
                DBG(cdev, "%s\n", __func__);
 }
@@ -316,6 +336,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
        if (autoresume) {
                sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
                loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+               autoresume_step_ms = autoresume * 1000;
        }
 
        /* support OTG systems */
index b3f20d7f15dee9554ef9ef96acd735c3e3926064..a9707da7da0bff969c68d6d5a0fa66f2816ef8b7 100644 (file)
@@ -54,7 +54,7 @@ config USB_EHCI_HCD
 
 config USB_EHCI_ROOT_HUB_TT
        bool "Root Hub Transaction Translators"
-       depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST
+       depends on USB_EHCI_HCD
        ---help---
          Some EHCI chips have vendor-specific extensions to integrate
          transaction translators, so that no OHCI or UHCI companion
@@ -66,7 +66,7 @@ config USB_EHCI_ROOT_HUB_TT
 
 config USB_EHCI_TT_NEWSCHED
        bool "Improved Transaction Translator scheduling"
-       depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST
+       depends on USB_EHCI_HCD
        default y
        ---help---
          This changes the periodic scheduling code to fill more of the low
@@ -203,12 +203,11 @@ config USB_EHCI_SH
          Enables support for the on-chip EHCI controller on the SuperH.
          If you use the PCI EHCI controller, this option is not necessary.
 
-config USB_EHCI_S5P
+config USB_EHCI_EXYNOS
        tristate "EHCI support for Samsung S5P/EXYNOS SoC Series"
        depends on PLAT_S5P || ARCH_EXYNOS
        help
-       Enable support for the Samsung S5Pxxxx and Exynos3/4/5 SOC's
-       on-chip EHCI controller.
+       Enable support for the Samsung Exynos SOC's on-chip EHCI controller.
 
 config USB_EHCI_MV
        bool "EHCI support for Marvell PXA/MMP USB controller"
@@ -224,7 +223,7 @@ config USB_EHCI_MV
          on-chip EHCI USB controller" for those.
 
 config USB_W90X900_EHCI
-       bool "W90X900(W90P910) EHCI support"
+       tristate "W90X900(W90P910) EHCI support"
        depends on ARCH_W90X900
        ---help---
                Enables support for the W90X900 USB controller
@@ -367,14 +366,54 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-       bool "OHCI support for OMAP1/2 chips"
+       tristate "OHCI support for OMAP1/2 chips"
        depends on ARCH_OMAP1
        default y
        ---help---
          Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
+config USB_OHCI_HCD_S3C2410
+        tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3C24xx/S3C64xx chips.
+
+config USB_OHCI_HCD_LPC32XX
+       tristate "Support for LPC on-chip OHCI USB controller"
+       depends on USB_OHCI_HCD && ARCH_LPC32XX
+       default y
+       ---help---
+          Enables support for the on-chip OHCI controller on
+          NXP chips.
+
+config USB_OHCI_HCD_PXA27X
+       tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller"
+       depends on USB_OHCI_HCD && (PXA27x || PXA3xx)
+       default y
+       ---help---
+         Enables support for the on-chip OHCI controller on
+         PXA27x/PXA3xx chips.
+
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
-       bool "OHCI support for OMAP3 and later chips"
+       tristate "OHCI support for OMAP3 and later chips"
        depends on (ARCH_OMAP3 || ARCH_OMAP4)
        default y
        ---help---
@@ -454,8 +493,8 @@ config USB_OHCI_SH
          If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-       boolean "OHCI support for Samsung EXYNOS SoC Series"
-       depends on ARCH_EXYNOS
+       tristate "OHCI support for Samsung S5P/EXYNOS SoC Series"
+       depends on PLAT_S5P || ARCH_EXYNOS
        help
         Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
 
index 50b0041c09a95464ed9ff353b090818e39d0112c..01e879ef3654865131eac3523050f2bad636531b 100644 (file)
@@ -34,10 +34,11 @@ obj-$(CONFIG_USB_EHCI_MXC)  += ehci-mxc.o
 obj-$(CONFIG_USB_EHCI_HCD_OMAP)        += ehci-omap.o
 obj-$(CONFIG_USB_EHCI_HCD_ORION)       += ehci-orion.o
 obj-$(CONFIG_USB_EHCI_HCD_SPEAR)       += ehci-spear.o
-obj-$(CONFIG_USB_EHCI_S5P)     += ehci-s5p.o
+obj-$(CONFIG_USB_EHCI_EXYNOS)  += ehci-exynos.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_MSM)     += ehci-msm.o
 obj-$(CONFIG_USB_EHCI_TEGRA)   += ehci-tegra.o
+obj-$(CONFIG_USB_W90X900_EHCI) += ehci-w90x900.o
 
 obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
 obj-$(CONFIG_USB_ISP116X_HCD)  += isp116x-hcd.o
@@ -46,6 +47,14 @@ obj-$(CONFIG_USB_ISP1362_HCD)        += isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)     += ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)    += ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)  += ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)       += ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)       += ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)       += ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)        += ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3C2410)     += ohci-s3c2410.o
+obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)     += ohci-nxp.o
+obj-$(CONFIG_USB_OHCI_HCD_PXA27X)      += ohci-pxa27x.o
 
 obj-$(CONFIG_USB_UHCI_HCD)     += uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)     += fhci.o
index 3b645ff46f7b9f8df67d2d793c1758be26173b21..f417526fb1f405f2fe1d3b4241e7bdac01c9aeaf 100644 (file)
@@ -30,13 +30,17 @@ static const char hcd_name[] = "ehci-atmel";
 static struct hc_driver __read_mostly ehci_atmel_hc_driver;
 
 /* interface and function clocks */
-static struct clk *iclk, *fclk;
+static struct clk *iclk, *fclk, *uclk;
 static int clocked;
 
 /*-------------------------------------------------------------------------*/
 
 static void atmel_start_clock(void)
 {
+       if (IS_ENABLED(CONFIG_COMMON_CLK)) {
+               clk_set_rate(uclk, 48000000);
+               clk_prepare_enable(uclk);
+       }
        clk_prepare_enable(iclk);
        clk_prepare_enable(fclk);
        clocked = 1;
@@ -46,6 +50,8 @@ static void atmel_stop_clock(void)
 {
        clk_disable_unprepare(fclk);
        clk_disable_unprepare(iclk);
+       if (IS_ENABLED(CONFIG_COMMON_CLK))
+               clk_disable_unprepare(uclk);
        clocked = 0;
 }
 
@@ -130,6 +136,14 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
                retval = -ENOENT;
                goto fail_request_resource;
        }
+       if (IS_ENABLED(CONFIG_COMMON_CLK)) {
+               uclk = devm_clk_get(&pdev->dev, "usb_clk");
+               if (IS_ERR(uclk)) {
+                       dev_err(&pdev->dev, "failed to get uclk\n");
+                       retval = PTR_ERR(uclk);
+                       goto fail_request_resource;
+               }
+       }
 
        ehci = hcd_to_ehci(hcd);
        /* registers start at offset 0x0 */
index aa5b603f39336f69ffc2dce8a787f64694fa7d23..4a9c2edbcb2bccf8cdf678aa04266fb5d78560d8 100644 (file)
@@ -334,6 +334,7 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
 /* troubleshooting help: expose state in debugfs */
 
 static int debug_async_open(struct inode *, struct file *);
+static int debug_bandwidth_open(struct inode *, struct file *);
 static int debug_periodic_open(struct inode *, struct file *);
 static int debug_registers_open(struct inode *, struct file *);
 
@@ -347,6 +348,13 @@ static const struct file_operations debug_async_fops = {
        .release        = debug_close,
        .llseek         = default_llseek,
 };
+static const struct file_operations debug_bandwidth_fops = {
+       .owner          = THIS_MODULE,
+       .open           = debug_bandwidth_open,
+       .read           = debug_output,
+       .release        = debug_close,
+       .llseek         = default_llseek,
+};
 static const struct file_operations debug_periodic_fops = {
        .owner          = THIS_MODULE,
        .open           = debug_periodic_open,
@@ -379,7 +387,7 @@ struct debug_buffer {
                case QH_LOW_SPEED:  tmp = 'l'; break; \
                case QH_HIGH_SPEED: tmp = 'h'; break; \
                default: tmp = '?'; break; \
-               }; tmp; })
+               } tmp; })
 
 static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
 {
@@ -525,6 +533,89 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
        return strlen(buf->output_buf);
 }
 
+static ssize_t fill_bandwidth_buffer(struct debug_buffer *buf)
+{
+       struct ehci_hcd         *ehci;
+       struct ehci_tt          *tt;
+       struct ehci_per_sched   *ps;
+       unsigned                temp, size;
+       char                    *next;
+       unsigned                i;
+       u8                      *bw;
+       u16                     *bf;
+       u8                      budget[EHCI_BANDWIDTH_SIZE];
+
+       ehci = hcd_to_ehci(bus_to_hcd(buf->bus));
+       next = buf->output_buf;
+       size = buf->alloc_size;
+
+       *next = 0;
+
+       spin_lock_irq(&ehci->lock);
+
+       /* Dump the HS bandwidth table */
+       temp = scnprintf(next, size,
+                       "HS bandwidth allocation (us per microframe)\n");
+       size -= temp;
+       next += temp;
+       for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
+               bw = &ehci->bandwidth[i];
+               temp = scnprintf(next, size,
+                               "%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
+                               i, bw[0], bw[1], bw[2], bw[3],
+                                       bw[4], bw[5], bw[6], bw[7]);
+               size -= temp;
+               next += temp;
+       }
+
+       /* Dump all the FS/LS tables */
+       list_for_each_entry(tt, &ehci->tt_list, tt_list) {
+               temp = scnprintf(next, size,
+                               "\nTT %s port %d  FS/LS bandwidth allocation (us per frame)\n",
+                               dev_name(&tt->usb_tt->hub->dev),
+                               tt->tt_port + !!tt->usb_tt->multi);
+               size -= temp;
+               next += temp;
+
+               bf = tt->bandwidth;
+               temp = scnprintf(next, size,
+                               "  %5u%5u%5u%5u%5u%5u%5u%5u\n",
+                               bf[0], bf[1], bf[2], bf[3],
+                                       bf[4], bf[5], bf[6], bf[7]);
+               size -= temp;
+               next += temp;
+
+               temp = scnprintf(next, size,
+                               "FS/LS budget (us per microframe)\n");
+               size -= temp;
+               next += temp;
+               compute_tt_budget(budget, tt);
+               for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
+                       bw = &budget[i];
+                       temp = scnprintf(next, size,
+                                       "%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
+                                       i, bw[0], bw[1], bw[2], bw[3],
+                                               bw[4], bw[5], bw[6], bw[7]);
+                       size -= temp;
+                       next += temp;
+               }
+               list_for_each_entry(ps, &tt->ps_list, ps_list) {
+                       temp = scnprintf(next, size,
+                                       "%s ep %02x:  %4u @ %2u.%u+%u mask %04x\n",
+                                       dev_name(&ps->udev->dev),
+                                       ps->ep->desc.bEndpointAddress,
+                                       ps->tt_usecs,
+                                       ps->bw_phase, ps->phase_uf,
+                                       ps->bw_period, ps->cs_mask);
+                       size -= temp;
+                       next += temp;
+               }
+       }
+       spin_unlock_irq(&ehci->lock);
+
+       return next - buf->output_buf;
+}
+
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
@@ -571,7 +662,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
                        case Q_TYPE_QH:
                                hw = p.qh->hw;
                                temp = scnprintf (next, size, " qh%d-%04x/%p",
-                                               p.qh->period,
+                                               p.qh->ps.period,
                                                hc32_to_cpup(ehci,
                                                        &hw->hw_info2)
                                                        /* uframe masks */
@@ -618,7 +709,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
                                                speed_char (scratch),
                                                scratch & 0x007f,
                                                (scratch >> 8) & 0x000f, type,
-                                               p.qh->usecs, p.qh->c_usecs,
+                                               p.qh->ps.usecs,
+                                               p.qh->ps.c_usecs,
                                                temp,
                                                0x7ff & (scratch >> 16));
 
@@ -645,7 +737,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
                        case Q_TYPE_SITD:
                                temp = scnprintf (next, size,
                                        " sitd%d-%04x/%p",
-                                       p.sitd->stream->interval,
+                                       p.sitd->stream->ps.period,
                                        hc32_to_cpup(ehci, &p.sitd->hw_uframe)
                                                & 0x0000ffff,
                                        p.sitd);
@@ -918,6 +1010,7 @@ static int debug_close(struct inode *inode, struct file *file)
 
        return 0;
 }
+
 static int debug_async_open(struct inode *inode, struct file *file)
 {
        file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
@@ -925,6 +1018,14 @@ static int debug_async_open(struct inode *inode, struct file *file)
        return file->private_data ? 0 : -ENOMEM;
 }
 
+static int debug_bandwidth_open(struct inode *inode, struct file *file)
+{
+       file->private_data = alloc_buffer(inode->i_private,
+                       fill_bandwidth_buffer);
+
+       return file->private_data ? 0 : -ENOMEM;
+}
+
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
        struct debug_buffer *buf;
@@ -957,6 +1058,10 @@ static inline void create_debug_files (struct ehci_hcd *ehci)
                                                &debug_async_fops))
                goto file_error;
 
+       if (!debugfs_create_file("bandwidth", S_IRUGO, ehci->debug_dir, bus,
+                                               &debug_bandwidth_fops))
+               goto file_error;
+
        if (!debugfs_create_file("periodic", S_IRUGO, ehci->debug_dir, bus,
                                                &debug_periodic_fops))
                goto file_error;
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
new file mode 100644 (file)
index 0000000..016352e
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * SAMSUNG EXYNOS USB HOST EHCI Controller
+ *
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@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.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI EXYNOS driver"
+
+#define EHCI_INSNREG00(base)                   (base + 0x90)
+#define EHCI_INSNREG00_ENA_INCR16              (0x1 << 25)
+#define EHCI_INSNREG00_ENA_INCR8               (0x1 << 24)
+#define EHCI_INSNREG00_ENA_INCR4               (0x1 << 23)
+#define EHCI_INSNREG00_ENA_INCRX_ALIGN         (0x1 << 22)
+#define EHCI_INSNREG00_ENABLE_DMA_BURST        \
+       (EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 | \
+        EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN)
+
+static const char hcd_name[] = "ehci-exynos";
+static struct hc_driver __read_mostly exynos_ehci_hc_driver;
+
+struct exynos_ehci_hcd {
+       struct clk *clk;
+       struct usb_phy *phy;
+       struct usb_otg *otg;
+};
+
+#define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
+
+static void exynos_setup_vbus_gpio(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       int err;
+       int gpio;
+
+       if (!dev->of_node)
+               return;
+
+       gpio = of_get_named_gpio(dev->of_node, "samsung,vbus-gpio", 0);
+       if (!gpio_is_valid(gpio))
+               return;
+
+       err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_HIGH,
+                                   "ehci_vbus_gpio");
+       if (err)
+               dev_err(dev, "can't request ehci vbus gpio %d", gpio);
+}
+
+static int exynos_ehci_probe(struct platform_device *pdev)
+{
+       struct exynos_ehci_hcd *exynos_ehci;
+       struct usb_hcd *hcd;
+       struct ehci_hcd *ehci;
+       struct resource *res;
+       struct usb_phy *phy;
+       int irq;
+       int err;
+
+       /*
+        * Right now device-tree probed devices don't get dma_mask set.
+        * Since shared usb code relies on it, set it here for now.
+        * Once we move to full device tree support this will vanish off.
+        */
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+       exynos_setup_vbus_gpio(pdev);
+
+       hcd = usb_create_hcd(&exynos_ehci_hc_driver,
+                            &pdev->dev, dev_name(&pdev->dev));
+       if (!hcd) {
+               dev_err(&pdev->dev, "Unable to create HCD\n");
+               return -ENOMEM;
+       }
+       exynos_ehci = to_exynos_ehci(hcd);
+
+       if (of_device_is_compatible(pdev->dev.of_node,
+                                       "samsung,exynos5440-ehci"))
+               goto skip_phy;
+
+       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+       if (IS_ERR(phy)) {
+               usb_put_hcd(hcd);
+               dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
+               return -EPROBE_DEFER;
+       } else {
+               exynos_ehci->phy = phy;
+               exynos_ehci->otg = phy->otg;
+       }
+
+skip_phy:
+
+       exynos_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
+
+       if (IS_ERR(exynos_ehci->clk)) {
+               dev_err(&pdev->dev, "Failed to get usbhost clock\n");
+               err = PTR_ERR(exynos_ehci->clk);
+               goto fail_clk;
+       }
+
+       err = clk_prepare_enable(exynos_ehci->clk);
+       if (err)
+               goto fail_clk;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "Failed to get I/O memory\n");
+               err = -ENXIO;
+               goto fail_io;
+       }
+
+       hcd->rsrc_start = res->start;
+       hcd->rsrc_len = resource_size(res);
+       hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               dev_err(&pdev->dev, "Failed to remap I/O memory\n");
+               err = -ENOMEM;
+               goto fail_io;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (!irq) {
+               dev_err(&pdev->dev, "Failed to get IRQ\n");
+               err = -ENODEV;
+               goto fail_io;
+       }
+
+       if (exynos_ehci->otg)
+               exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
+
+       if (exynos_ehci->phy)
+               usb_phy_init(exynos_ehci->phy);
+
+       ehci = hcd_to_ehci(hcd);
+       ehci->caps = hcd->regs;
+
+       /* DMA burst Enable */
+       writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
+
+       err = usb_add_hcd(hcd, irq, IRQF_SHARED);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to add USB HCD\n");
+               goto fail_add_hcd;
+       }
+
+       platform_set_drvdata(pdev, hcd);
+
+       return 0;
+
+fail_add_hcd:
+       if (exynos_ehci->phy)
+               usb_phy_shutdown(exynos_ehci->phy);
+fail_io:
+       clk_disable_unprepare(exynos_ehci->clk);
+fail_clk:
+       usb_put_hcd(hcd);
+       return err;
+}
+
+static int exynos_ehci_remove(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
+
+       usb_remove_hcd(hcd);
+
+       if (exynos_ehci->otg)
+               exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
+
+       if (exynos_ehci->phy)
+               usb_phy_shutdown(exynos_ehci->phy);
+
+       clk_disable_unprepare(exynos_ehci->clk);
+
+       usb_put_hcd(hcd);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int exynos_ehci_suspend(struct device *dev)
+{
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
+
+       bool do_wakeup = device_may_wakeup(dev);
+       int rc;
+
+       rc = ehci_suspend(hcd, do_wakeup);
+
+       if (exynos_ehci->otg)
+               exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
+
+       if (exynos_ehci->phy)
+               usb_phy_shutdown(exynos_ehci->phy);
+
+       clk_disable_unprepare(exynos_ehci->clk);
+
+       return rc;
+}
+
+static int exynos_ehci_resume(struct device *dev)
+{
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
+
+       clk_prepare_enable(exynos_ehci->clk);
+
+       if (exynos_ehci->otg)
+               exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
+
+       if (exynos_ehci->phy)
+               usb_phy_init(exynos_ehci->phy);
+
+       /* DMA burst Enable */
+       writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
+
+       ehci_resume(hcd, false);
+       return 0;
+}
+#else
+#define exynos_ehci_suspend    NULL
+#define exynos_ehci_resume     NULL
+#endif
+
+static const struct dev_pm_ops exynos_ehci_pm_ops = {
+       .suspend        = exynos_ehci_suspend,
+       .resume         = exynos_ehci_resume,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_ehci_match[] = {
+       { .compatible = "samsung,exynos4210-ehci" },
+       { .compatible = "samsung,exynos5440-ehci" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, exynos_ehci_match);
+#endif
+
+static struct platform_driver exynos_ehci_driver = {
+       .probe          = exynos_ehci_probe,
+       .remove         = exynos_ehci_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
+       .driver = {
+               .name   = "exynos-ehci",
+               .owner  = THIS_MODULE,
+               .pm     = &exynos_ehci_pm_ops,
+               .of_match_table = of_match_ptr(exynos_ehci_match),
+       }
+};
+static const struct ehci_driver_overrides exynos_overrides __initdata = {
+       .extra_priv_size = sizeof(struct exynos_ehci_hcd),
+};
+
+static int __init ehci_exynos_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+       ehci_init_driver(&exynos_ehci_hc_driver, &exynos_overrides);
+       return platform_driver_register(&exynos_ehci_driver);
+}
+module_init(ehci_exynos_init);
+
+static void __exit ehci_exynos_cleanup(void)
+{
+       platform_driver_unregister(&exynos_ehci_driver);
+}
+module_exit(ehci_exynos_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:exynos-ehci");
+MODULE_AUTHOR("Jingoo Han");
+MODULE_AUTHOR("Joonyoung Shim");
+MODULE_LICENSE("GPL v2");
index f2407b2e8a996210aec7f3e7a442119fd6928924..a06d5012201fe6800c0de5c7363bf8bd1cecb58f 100644 (file)
@@ -57,7 +57,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
        pr_debug("initializing FSL-SOC USB Controller\n");
 
        /* Need platform data for setup */
-       pdata = (struct fsl_usb2_platform_data *)dev_get_platdata(&pdev->dev);
+       pdata = dev_get_platdata(&pdev->dev);
        if (!pdata) {
                dev_err(&pdev->dev,
                        "No platform data for %s.\n", dev_name(&pdev->dev));
@@ -664,7 +664,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
         * generic hardware linkage
         */
        .irq = ehci_irq,
-       .flags = HCD_USB2 | HCD_MEMORY,
+       .flags = HCD_USB2 | HCD_MEMORY | HCD_BH,
 
        /*
         * basic lifecycle operations
index 83ab51af250f158e735373760f8c008ce6fe0ad8..b52a66ce92e8592b123239aa24b724dddfd085fa 100644 (file)
@@ -43,7 +43,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
         * generic hardware linkage
         */
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index 86ab9fd9fe9e938fc29cadeac72a935e8c26b8ff..e8ba4c44223a5c360ec552cbbb4137ca2b4ca3b2 100644 (file)
@@ -110,6 +110,9 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
 #include "ehci.h"
 #include "pci-quirks.h"
 
+static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE],
+               struct ehci_tt *tt);
+
 /*
  * The MosChip MCS9990 controller updates its microframe counter
  * a little before the frame counter, and occasionally we will read
@@ -484,6 +487,7 @@ static int ehci_init(struct usb_hcd *hcd)
        INIT_LIST_HEAD(&ehci->intr_qh_list);
        INIT_LIST_HEAD(&ehci->cached_itd_list);
        INIT_LIST_HEAD(&ehci->cached_sitd_list);
+       INIT_LIST_HEAD(&ehci->tt_list);
 
        if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
                /* periodic schedule size can be smaller than default */
@@ -956,6 +960,7 @@ rescan:
                        goto idle_timeout;
 
                /* BUG_ON(!list_empty(&stream->free_list)); */
+               reserve_release_iso_bandwidth(ehci, stream, -1);
                kfree(stream);
                goto done;
        }
@@ -982,6 +987,8 @@ idle_timeout:
                if (qh->clearing_tt)
                        goto idle_timeout;
                if (list_empty (&qh->qtd_list)) {
+                       if (qh->ps.bw_uperiod)
+                               reserve_release_intr_bandwidth(ehci, qh, -1);
                        qh_destroy(ehci, qh);
                        break;
                }
@@ -1022,7 +1029,6 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
         * the toggle bit in the QH.
         */
        if (qh) {
-               usb_settoggle(qh->dev, epnum, is_out, 0);
                if (!list_empty(&qh->qtd_list)) {
                        WARN_ONCE(1, "clear_halt for a busy endpoint\n");
                } else {
@@ -1030,6 +1036,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
                         * while the QH is active.  Unlink it now;
                         * re-linking will call qh_refresh().
                         */
+                       usb_settoggle(qh->ps.udev, epnum, is_out, 0);
                        qh->exception = 1;
                        if (eptype == USB_ENDPOINT_XFER_BULK)
                                start_unlink_async(ehci, qh);
@@ -1048,6 +1055,19 @@ static int ehci_get_frame (struct usb_hcd *hcd)
 
 /*-------------------------------------------------------------------------*/
 
+/* Device addition and removal */
+
+static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev)
+{
+       struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
+
+       spin_lock_irq(&ehci->lock);
+       drop_tt(udev);
+       spin_unlock_irq(&ehci->lock);
+}
+
+/*-------------------------------------------------------------------------*/
+
 #ifdef CONFIG_PM
 
 /* suspend/resume, section 4.3 */
@@ -1075,6 +1095,14 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
        spin_unlock_irq(&ehci->lock);
 
+       synchronize_irq(hcd->irq);
+
+       /* Check for race with a wakeup request */
+       if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) {
+               ehci_resume(hcd, false);
+               return -EBUSY;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(ehci_suspend);
@@ -1158,7 +1186,7 @@ static const struct hc_driver ehci_hc_driver = {
         * generic hardware linkage
         */
        .irq =                  ehci_irq,
-       .flags =                HCD_MEMORY | HCD_USB2,
+       .flags =                HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
@@ -1191,6 +1219,11 @@ static const struct hc_driver ehci_hc_driver = {
        .bus_resume =           ehci_bus_resume,
        .relinquish_port =      ehci_relinquish_port,
        .port_handed_over =     ehci_port_handed_over,
+
+       /*
+        * device support
+        */
+       .free_dev =             ehci_remove_device,
 };
 
 void ehci_init_driver(struct hc_driver *drv,
@@ -1238,11 +1271,6 @@ MODULE_LICENSE ("GPL");
 #define XILINX_OF_PLATFORM_DRIVER      ehci_hcd_xilinx_of_driver
 #endif
 
-#ifdef CONFIG_USB_W90X900_EHCI
-#include "ehci-w90x900.c"
-#define        PLATFORM_DRIVER         ehci_hcd_w90x900_driver
-#endif
-
 #ifdef CONFIG_USB_OCTEON_EHCI
 #include "ehci-octeon.c"
 #define PLATFORM_DRIVER                ehci_octeon_driver
index 52a77734a225fa05a8afc6ede8df5deb4a7089dd..c0fb6a8ae6a3935e367e4a9c386e051acc739338 100644 (file)
@@ -224,11 +224,11 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
                hw->hw_next = EHCI_LIST_END(ehci);
                hw->hw_qtd_next = EHCI_LIST_END(ehci);
                hw->hw_alt_next = EHCI_LIST_END(ehci);
-               hw->hw_token &= ~QTD_STS_ACTIVE;
                ehci->dummy->hw = hw;
 
                for (i = 0; i < ehci->periodic_size; i++)
-                       ehci->periodic[i] = ehci->dummy->qh_dma;
+                       ehci->periodic[i] = cpu_to_hc32(ehci,
+                                       ehci->dummy->qh_dma);
        } else {
                for (i = 0; i < ehci->periodic_size; i++)
                        ehci->periodic[i] = EHCI_LIST_END(ehci);
index 0f717dc688b7276fb75f65a9920bb799facfb164..f341651d6f6ce6e4ae67a2d53ab2cab3aefeb81e 100644 (file)
@@ -42,7 +42,6 @@
 
 static const char hcd_name[] = "ehci-msm";
 static struct hc_driver __read_mostly msm_hc_driver;
-static struct usb_phy *phy;
 
 static int ehci_msm_reset(struct usb_hcd *hcd)
 {
@@ -70,6 +69,7 @@ static int ehci_msm_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
        struct resource *res;
+       struct usb_phy *phy;
        int ret;
 
        dev_dbg(&pdev->dev, "ehci_msm proble\n");
@@ -108,10 +108,14 @@ static int ehci_msm_probe(struct platform_device *pdev)
         * powering up VBUS, mapping of registers address space and power
         * management.
         */
-       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+       if (pdev->dev.of_node)
+               phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
+       else
+               phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+
        if (IS_ERR(phy)) {
                dev_err(&pdev->dev, "unable to find transceiver\n");
-               ret = -ENODEV;
+               ret = -EPROBE_DEFER;
                goto put_hcd;
        }
 
@@ -121,6 +125,7 @@ static int ehci_msm_probe(struct platform_device *pdev)
                goto put_hcd;
        }
 
+       hcd->phy = phy;
        device_init_wakeup(&pdev->dev, 1);
        /*
         * OTG device parent of HCD takes care of putting
@@ -147,7 +152,7 @@ static int ehci_msm_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
 
-       otg_set_host(phy->otg, NULL);
+       otg_set_host(hcd->phy->otg, NULL);
 
        /* FIXME: need to call usb_remove_hcd() here? */
 
@@ -186,12 +191,19 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
        .resume          = ehci_msm_pm_resume,
 };
 
+static struct of_device_id msm_ehci_dt_match[] = {
+       { .compatible = "qcom,ehci-host", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, msm_ehci_dt_match);
+
 static struct platform_driver ehci_msm_driver = {
        .probe  = ehci_msm_probe,
        .remove = ehci_msm_remove,
        .driver = {
                   .name = "msm_hsusb_host",
                   .pm = &ehci_msm_dev_pm_ops,
+                  .of_match_table = msm_ehci_dt_match,
        },
 };
 
index 35cdbd88bbbef62a93a3aa869c12dbfda8183bf2..417c10da945078e37ddf20e7be290e996936074e 100644 (file)
@@ -96,7 +96,7 @@ static const struct hc_driver mv_ehci_hc_driver = {
         * generic hardware linkage
         */
        .irq = ehci_irq,
-       .flags = HCD_MEMORY | HCD_USB2,
+       .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index 45cc00158412ac8a380cda88a28a4bb7536d62fa..ab0397e4d8f3eadae916d07434f4431f3d59def3 100644 (file)
@@ -51,7 +51,7 @@ static const struct hc_driver ehci_octeon_hc_driver = {
         * generic hardware linkage
         */
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index 854c2ec7b699d4effe2c9ca6ae4ab264e1a73cd8..3e86bf4371b3901de76ed7e5db8e8a8de5a72cd3 100644 (file)
@@ -58,8 +58,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
-       struct pci_dev          *p_smbus;
-       u8                      rev;
        u32                     temp;
        int                     retval;
 
@@ -175,22 +173,12 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                /* SB600 and old version of SB700 have a bug in EHCI controller,
                 * which causes usb devices lose response in some cases.
                 */
-               if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
-                       p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
-                                                PCI_DEVICE_ID_ATI_SBX00_SMBUS,
-                                                NULL);
-                       if (!p_smbus)
-                               break;
-                       rev = p_smbus->revision;
-                       if ((pdev->device == 0x4386) || (rev == 0x3a)
-                           || (rev == 0x3b)) {
-                               u8 tmp;
-                               ehci_info(ehci, "applying AMD SB600/SB700 USB "
-                                       "freeze workaround\n");
-                               pci_read_config_byte(pdev, 0x53, &tmp);
-                               pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
-                       }
-                       pci_dev_put(p_smbus);
+               if ((pdev->device == 0x4386 || pdev->device == 0x4396) &&
+                               usb_amd_hang_symptom_quirk()) {
+                       u8 tmp;
+                       ehci_info(ehci, "applying AMD SB600/SB700 USB freeze workaround\n");
+                       pci_read_config_byte(pdev, 0x53, &tmp);
+                       pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
                }
                break;
        case PCI_VENDOR_ID_NETMOS:
index 601e208bd782c07e9d0bb1b60d238ccbb7774758..893b707f0000abf0e323f39b28b6060a3293bcef 100644 (file)
@@ -286,7 +286,7 @@ static const struct hc_driver ehci_msp_hc_driver = {
 #else
        .irq =                  ehci_irq,
 #endif
-       .flags =                HCD_MEMORY | HCD_USB2,
+       .flags =                HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index 932293fa32de657de2e36ba091127e50009a6ff7..6cc5567bf9c87faaa8c4a21dcb4202e8e6e7fb94 100644 (file)
@@ -28,7 +28,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
         * generic hardware linkage
         */
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index fd983771b02559cb56c6210e6813d9b223a80f7a..8188542ba17ea01214a3ab0f269fe07cb6cb1744 100644 (file)
@@ -71,7 +71,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
        .product_desc           = "PS3 EHCI Host Controller",
        .hcd_priv_size          = sizeof(struct ehci_hcd),
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
        .reset                  = ps3_ehci_hc_reset,
        .start                  = ehci_run,
        .stop                   = ehci_stop,
index a7f776a13eb17133459f23ac584b60287e544197..db05bd8ee9d59e4a739720912ee4ca8faaa61eac 100644 (file)
@@ -105,9 +105,9 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
 
                is_out = qh->is_out;
                epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
-               if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
+               if (unlikely(!usb_gettoggle(qh->ps.udev, epnum, is_out))) {
                        hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
-                       usb_settoggle (qh->dev, epnum, is_out, 1);
+                       usb_settoggle(qh->ps.udev, epnum, is_out, 1);
                }
        }
 
@@ -247,8 +247,6 @@ static int qtd_copy_status (
 
 static void
 ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status)
-__releases(ehci->lock)
-__acquires(ehci->lock)
 {
        if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
                /* ... update hc-wide periodic stats */
@@ -274,11 +272,8 @@ __acquires(ehci->lock)
                urb->actual_length, urb->transfer_buffer_length);
 #endif
 
-       /* complete() can reenter this HCD */
        usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
-       spin_unlock (&ehci->lock);
        usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status);
-       spin_lock (&ehci->lock);
 }
 
 static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
@@ -802,26 +797,35 @@ qh_make (
         * For control/bulk requests, the HC or TT handles these.
         */
        if (type == PIPE_INTERRUPT) {
-               qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
+               unsigned        tmp;
+
+               qh->ps.usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
                                is_input, 0,
                                hb_mult(maxp) * max_packet(maxp)));
-               qh->start = NO_FRAME;
+               qh->ps.phase = NO_FRAME;
 
                if (urb->dev->speed == USB_SPEED_HIGH) {
-                       qh->c_usecs = 0;
+                       qh->ps.c_usecs = 0;
                        qh->gap_uf = 0;
 
-                       qh->period = urb->interval >> 3;
-                       if (qh->period == 0 && urb->interval != 1) {
+                       if (urb->interval > 1 && urb->interval < 8) {
                                /* NOTE interval 2 or 4 uframes could work.
                                 * But interval 1 scheduling is simpler, and
                                 * includes high bandwidth.
                                 */
                                urb->interval = 1;
-                       } else if (qh->period > ehci->periodic_size) {
-                               qh->period = ehci->periodic_size;
-                               urb->interval = qh->period << 3;
+                       } else if (urb->interval > ehci->periodic_size << 3) {
+                               urb->interval = ehci->periodic_size << 3;
                        }
+                       qh->ps.period = urb->interval >> 3;
+
+                       /* period for bandwidth allocation */
+                       tmp = min_t(unsigned, EHCI_BANDWIDTH_SIZE,
+                                       1 << (urb->ep->desc.bInterval - 1));
+
+                       /* Allow urb->interval to override */
+                       qh->ps.bw_uperiod = min_t(unsigned, tmp, urb->interval);
+                       qh->ps.bw_period = qh->ps.bw_uperiod >> 3;
                } else {
                        int             think_time;
 
@@ -831,27 +835,35 @@ qh_make (
 
                        /* FIXME this just approximates SPLIT/CSPLIT times */
                        if (is_input) {         // SPLIT, gap, CSPLIT+DATA
-                               qh->c_usecs = qh->usecs + HS_USECS (0);
-                               qh->usecs = HS_USECS (1);
+                               qh->ps.c_usecs = qh->ps.usecs + HS_USECS(0);
+                               qh->ps.usecs = HS_USECS(1);
                        } else {                // SPLIT+DATA, gap, CSPLIT
-                               qh->usecs += HS_USECS (1);
-                               qh->c_usecs = HS_USECS (0);
+                               qh->ps.usecs += HS_USECS(1);
+                               qh->ps.c_usecs = HS_USECS(0);
                        }
 
                        think_time = tt ? tt->think_time : 0;
-                       qh->tt_usecs = NS_TO_US (think_time +
+                       qh->ps.tt_usecs = NS_TO_US(think_time +
                                        usb_calc_bus_time (urb->dev->speed,
                                        is_input, 0, max_packet (maxp)));
-                       qh->period = urb->interval;
-                       if (qh->period > ehci->periodic_size) {
-                               qh->period = ehci->periodic_size;
-                               urb->interval = qh->period;
-                       }
+                       if (urb->interval > ehci->periodic_size)
+                               urb->interval = ehci->periodic_size;
+                       qh->ps.period = urb->interval;
+
+                       /* period for bandwidth allocation */
+                       tmp = min_t(unsigned, EHCI_BANDWIDTH_FRAMES,
+                                       urb->ep->desc.bInterval);
+                       tmp = rounddown_pow_of_two(tmp);
+
+                       /* Allow urb->interval to override */
+                       qh->ps.bw_period = min_t(unsigned, tmp, urb->interval);
+                       qh->ps.bw_uperiod = qh->ps.bw_period << 3;
                }
        }
 
        /* support for tt scheduling, and access to toggles */
-       qh->dev = urb->dev;
+       qh->ps.udev = urb->dev;
+       qh->ps.ep = urb->ep;
 
        /* using TT? */
        switch (urb->dev->speed) {
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
deleted file mode 100644 (file)
index 7c3de95..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * SAMSUNG S5P USB HOST EHCI Controller
- *
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Jingoo Han <jg1.han@samsung.com>
- * Author: Joonyoung Shim <jy0922.shim@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.
- *
- */
-
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/usb-ehci-s5p.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/samsung_usb_phy.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-#include <linux/usb/otg.h>
-
-#include "ehci.h"
-
-#define DRIVER_DESC "EHCI s5p driver"
-
-#define EHCI_INSNREG00(base)                   (base + 0x90)
-#define EHCI_INSNREG00_ENA_INCR16              (0x1 << 25)
-#define EHCI_INSNREG00_ENA_INCR8               (0x1 << 24)
-#define EHCI_INSNREG00_ENA_INCR4               (0x1 << 23)
-#define EHCI_INSNREG00_ENA_INCRX_ALIGN         (0x1 << 22)
-#define EHCI_INSNREG00_ENABLE_DMA_BURST        \
-       (EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 | \
-        EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN)
-
-static const char hcd_name[] = "ehci-s5p";
-static struct hc_driver __read_mostly s5p_ehci_hc_driver;
-
-struct s5p_ehci_hcd {
-       struct clk *clk;
-       struct usb_phy *phy;
-       struct usb_otg *otg;
-       struct s5p_ehci_platdata *pdata;
-};
-
-static struct s5p_ehci_platdata empty_platdata;
-
-#define to_s5p_ehci(hcd)      (struct s5p_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
-
-static void s5p_setup_vbus_gpio(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       int err;
-       int gpio;
-
-       if (!dev->of_node)
-               return;
-
-       gpio = of_get_named_gpio(dev->of_node, "samsung,vbus-gpio", 0);
-       if (!gpio_is_valid(gpio))
-               return;
-
-       err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_HIGH,
-                                   "ehci_vbus_gpio");
-       if (err)
-               dev_err(dev, "can't request ehci vbus gpio %d", gpio);
-}
-
-static int s5p_ehci_probe(struct platform_device *pdev)
-{
-       struct s5p_ehci_platdata *pdata = dev_get_platdata(&pdev->dev);
-       struct s5p_ehci_hcd *s5p_ehci;
-       struct usb_hcd *hcd;
-       struct ehci_hcd *ehci;
-       struct resource *res;
-       struct usb_phy *phy;
-       int irq;
-       int err;
-
-       /*
-        * Right now device-tree probed devices don't get dma_mask set.
-        * Since shared usb code relies on it, set it here for now.
-        * Once we move to full device tree support this will vanish off.
-        */
-       if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-       if (!pdev->dev.coherent_dma_mask)
-               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-
-       s5p_setup_vbus_gpio(pdev);
-
-       hcd = usb_create_hcd(&s5p_ehci_hc_driver,
-                            &pdev->dev, dev_name(&pdev->dev));
-       if (!hcd) {
-               dev_err(&pdev->dev, "Unable to create HCD\n");
-               return -ENOMEM;
-       }
-       s5p_ehci = to_s5p_ehci(hcd);
-
-       if (of_device_is_compatible(pdev->dev.of_node,
-                                       "samsung,exynos5440-ehci")) {
-               s5p_ehci->pdata = &empty_platdata;
-               goto skip_phy;
-       }
-
-       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
-       if (IS_ERR(phy)) {
-               /* Fallback to pdata */
-               if (!pdata) {
-                       usb_put_hcd(hcd);
-                       dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
-                       return -EPROBE_DEFER;
-               } else {
-                       s5p_ehci->pdata = pdata;
-               }
-       } else {
-               s5p_ehci->phy = phy;
-               s5p_ehci->otg = phy->otg;
-       }
-
-skip_phy:
-
-       s5p_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
-
-       if (IS_ERR(s5p_ehci->clk)) {
-               dev_err(&pdev->dev, "Failed to get usbhost clock\n");
-               err = PTR_ERR(s5p_ehci->clk);
-               goto fail_clk;
-       }
-
-       err = clk_prepare_enable(s5p_ehci->clk);
-       if (err)
-               goto fail_clk;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get I/O memory\n");
-               err = -ENXIO;
-               goto fail_io;
-       }
-
-       hcd->rsrc_start = res->start;
-       hcd->rsrc_len = resource_size(res);
-       hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len);
-       if (!hcd->regs) {
-               dev_err(&pdev->dev, "Failed to remap I/O memory\n");
-               err = -ENOMEM;
-               goto fail_io;
-       }
-
-       irq = platform_get_irq(pdev, 0);
-       if (!irq) {
-               dev_err(&pdev->dev, "Failed to get IRQ\n");
-               err = -ENODEV;
-               goto fail_io;
-       }
-
-       if (s5p_ehci->otg)
-               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
-
-       if (s5p_ehci->phy)
-               usb_phy_init(s5p_ehci->phy);
-       else if (s5p_ehci->pdata->phy_init)
-               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
-
-       ehci = hcd_to_ehci(hcd);
-       ehci->caps = hcd->regs;
-
-       /* DMA burst Enable */
-       writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
-
-       err = usb_add_hcd(hcd, irq, IRQF_SHARED);
-       if (err) {
-               dev_err(&pdev->dev, "Failed to add USB HCD\n");
-               goto fail_add_hcd;
-       }
-
-       platform_set_drvdata(pdev, hcd);
-
-       return 0;
-
-fail_add_hcd:
-       if (s5p_ehci->phy)
-               usb_phy_shutdown(s5p_ehci->phy);
-       else if (s5p_ehci->pdata->phy_exit)
-               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
-fail_io:
-       clk_disable_unprepare(s5p_ehci->clk);
-fail_clk:
-       usb_put_hcd(hcd);
-       return err;
-}
-
-static int s5p_ehci_remove(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd = platform_get_drvdata(pdev);
-       struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
-
-       usb_remove_hcd(hcd);
-
-       if (s5p_ehci->otg)
-               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
-
-       if (s5p_ehci->phy)
-               usb_phy_shutdown(s5p_ehci->phy);
-       else if (s5p_ehci->pdata->phy_exit)
-               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
-
-       clk_disable_unprepare(s5p_ehci->clk);
-
-       usb_put_hcd(hcd);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int s5p_ehci_suspend(struct device *dev)
-{
-       struct usb_hcd *hcd = dev_get_drvdata(dev);
-       struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
-       struct platform_device *pdev = to_platform_device(dev);
-
-       bool do_wakeup = device_may_wakeup(dev);
-       int rc;
-
-       rc = ehci_suspend(hcd, do_wakeup);
-
-       if (s5p_ehci->otg)
-               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
-
-       if (s5p_ehci->phy)
-               usb_phy_shutdown(s5p_ehci->phy);
-       else if (s5p_ehci->pdata->phy_exit)
-               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
-
-       clk_disable_unprepare(s5p_ehci->clk);
-
-       return rc;
-}
-
-static int s5p_ehci_resume(struct device *dev)
-{
-       struct usb_hcd *hcd = dev_get_drvdata(dev);
-       struct  s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
-       struct platform_device *pdev = to_platform_device(dev);
-
-       clk_prepare_enable(s5p_ehci->clk);
-
-       if (s5p_ehci->otg)
-               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
-
-       if (s5p_ehci->phy)
-               usb_phy_init(s5p_ehci->phy);
-       else if (s5p_ehci->pdata->phy_init)
-               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
-
-       /* DMA burst Enable */
-       writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
-
-       ehci_resume(hcd, false);
-       return 0;
-}
-#else
-#define s5p_ehci_suspend       NULL
-#define s5p_ehci_resume                NULL
-#endif
-
-static const struct dev_pm_ops s5p_ehci_pm_ops = {
-       .suspend        = s5p_ehci_suspend,
-       .resume         = s5p_ehci_resume,
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id exynos_ehci_match[] = {
-       { .compatible = "samsung,exynos4210-ehci" },
-       { .compatible = "samsung,exynos5440-ehci" },
-       {},
-};
-MODULE_DEVICE_TABLE(of, exynos_ehci_match);
-#endif
-
-static struct platform_driver s5p_ehci_driver = {
-       .probe          = s5p_ehci_probe,
-       .remove         = s5p_ehci_remove,
-       .shutdown       = usb_hcd_platform_shutdown,
-       .driver = {
-               .name   = "s5p-ehci",
-               .owner  = THIS_MODULE,
-               .pm     = &s5p_ehci_pm_ops,
-               .of_match_table = of_match_ptr(exynos_ehci_match),
-       }
-};
-static const struct ehci_driver_overrides s5p_overrides __initdata = {
-       .extra_priv_size = sizeof(struct s5p_ehci_hcd),
-};
-
-static int __init ehci_s5p_init(void)
-{
-       if (usb_disabled())
-               return -ENODEV;
-
-       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
-       ehci_init_driver(&s5p_ehci_hc_driver, &s5p_overrides);
-       return platform_driver_register(&s5p_ehci_driver);
-}
-module_init(ehci_s5p_init);
-
-static void __exit ehci_s5p_cleanup(void)
-{
-       platform_driver_unregister(&s5p_ehci_driver);
-}
-module_exit(ehci_s5p_cleanup);
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_ALIAS("platform:s5p-ehci");
-MODULE_AUTHOR("Jingoo Han");
-MODULE_AUTHOR("Joonyoung Shim");
-MODULE_LICENSE("GPL v2");
index 85dd24ed97a6d6cf6700405797da29d313e76958..e113fd73aeae7148b0cbcd0d424aebb16d84a694 100644 (file)
@@ -103,83 +103,210 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
                *hw_p = *shadow_next_periodic(ehci, &here,
                                Q_NEXT_TYPE(ehci, *hw_p));
        else
-               *hw_p = ehci->dummy->qh_dma;
+               *hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma);
 }
 
-/* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
+/*-------------------------------------------------------------------------*/
+
+/* Bandwidth and TT management */
+
+/* Find the TT data structure for this device; create it if necessary */
+static struct ehci_tt *find_tt(struct usb_device *udev)
 {
-       __hc32                  *hw_p = &ehci->periodic [frame];
-       union ehci_shadow       *q = &ehci->pshadow [frame];
-       unsigned                usecs = 0;
-       struct ehci_qh_hw       *hw;
-
-       while (q->ptr) {
-               switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
-               case Q_TYPE_QH:
-                       hw = q->qh->hw;
-                       /* is it in the S-mask? */
-                       if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
-                               usecs += q->qh->usecs;
-                       /* ... or C-mask? */
-                       if (hw->hw_info2 & cpu_to_hc32(ehci,
-                                       1 << (8 + uframe)))
-                               usecs += q->qh->c_usecs;
-                       hw_p = &hw->hw_next;
-                       q = &q->qh->qh_next;
-                       break;
-               // case Q_TYPE_FSTN:
-               default:
-                       /* for "save place" FSTNs, count the relevant INTR
-                        * bandwidth from the previous frame
-                        */
-                       if (q->fstn->hw_prev != EHCI_LIST_END(ehci)) {
-                               ehci_dbg (ehci, "ignoring FSTN cost ...\n");
-                       }
-                       hw_p = &q->fstn->hw_next;
-                       q = &q->fstn->fstn_next;
-                       break;
-               case Q_TYPE_ITD:
-                       if (q->itd->hw_transaction[uframe])
-                               usecs += q->itd->stream->usecs;
-                       hw_p = &q->itd->hw_next;
-                       q = &q->itd->itd_next;
-                       break;
-               case Q_TYPE_SITD:
-                       /* is it in the S-mask?  (count SPLIT, DATA) */
-                       if (q->sitd->hw_uframe & cpu_to_hc32(ehci,
-                                       1 << uframe)) {
-                               if (q->sitd->hw_fullspeed_ep &
-                                               cpu_to_hc32(ehci, 1<<31))
-                                       usecs += q->sitd->stream->usecs;
-                               else    /* worst case for OUT start-split */
-                                       usecs += HS_USECS_ISO (188);
-                       }
+       struct usb_tt           *utt = udev->tt;
+       struct ehci_tt          *tt, **tt_index, **ptt;
+       unsigned                port;
+       bool                    allocated_index = false;
+
+       if (!utt)
+               return NULL;            /* Not below a TT */
+
+       /*
+        * Find/create our data structure.
+        * For hubs with a single TT, we get it directly.
+        * For hubs with multiple TTs, there's an extra level of pointers.
+        */
+       tt_index = NULL;
+       if (utt->multi) {
+               tt_index = utt->hcpriv;
+               if (!tt_index) {                /* Create the index array */
+                       tt_index = kzalloc(utt->hub->maxchild *
+                                       sizeof(*tt_index), GFP_ATOMIC);
+                       if (!tt_index)
+                               return ERR_PTR(-ENOMEM);
+                       utt->hcpriv = tt_index;
+                       allocated_index = true;
+               }
+               port = udev->ttport - 1;
+               ptt = &tt_index[port];
+       } else {
+               port = 0;
+               ptt = (struct ehci_tt **) &utt->hcpriv;
+       }
+
+       tt = *ptt;
+       if (!tt) {                              /* Create the ehci_tt */
+               struct ehci_hcd         *ehci =
+                               hcd_to_ehci(bus_to_hcd(udev->bus));
 
-                       /* ... C-mask?  (count CSPLIT, DATA) */
-                       if (q->sitd->hw_uframe &
-                                       cpu_to_hc32(ehci, 1 << (8 + uframe))) {
-                               /* worst case for IN complete-split */
-                               usecs += q->sitd->stream->c_usecs;
+               tt = kzalloc(sizeof(*tt), GFP_ATOMIC);
+               if (!tt) {
+                       if (allocated_index) {
+                               utt->hcpriv = NULL;
+                               kfree(tt_index);
                        }
+                       return ERR_PTR(-ENOMEM);
+               }
+               list_add_tail(&tt->tt_list, &ehci->tt_list);
+               INIT_LIST_HEAD(&tt->ps_list);
+               tt->usb_tt = utt;
+               tt->tt_port = port;
+               *ptt = tt;
+       }
 
-                       hw_p = &q->sitd->hw_next;
-                       q = &q->sitd->sitd_next;
-                       break;
+       return tt;
+}
+
+/* Release the TT above udev, if it's not in use */
+static void drop_tt(struct usb_device *udev)
+{
+       struct usb_tt           *utt = udev->tt;
+       struct ehci_tt          *tt, **tt_index, **ptt;
+       int                     cnt, i;
+
+       if (!utt || !utt->hcpriv)
+               return;         /* Not below a TT, or never allocated */
+
+       cnt = 0;
+       if (utt->multi) {
+               tt_index = utt->hcpriv;
+               ptt = &tt_index[udev->ttport - 1];
+
+               /* How many entries are left in tt_index? */
+               for (i = 0; i < utt->hub->maxchild; ++i)
+                       cnt += !!tt_index[i];
+       } else {
+               tt_index = NULL;
+               ptt = (struct ehci_tt **) &utt->hcpriv;
+       }
+
+       tt = *ptt;
+       if (!tt || !list_empty(&tt->ps_list))
+               return;         /* never allocated, or still in use */
+
+       list_del(&tt->tt_list);
+       *ptt = NULL;
+       kfree(tt);
+       if (cnt == 1) {
+               utt->hcpriv = NULL;
+               kfree(tt_index);
+       }
+}
+
+static void bandwidth_dbg(struct ehci_hcd *ehci, int sign, char *type,
+               struct ehci_per_sched *ps)
+{
+       dev_dbg(&ps->udev->dev,
+                       "ep %02x: %s %s @ %u+%u (%u.%u+%u) [%u/%u us] mask %04x\n",
+                       ps->ep->desc.bEndpointAddress,
+                       (sign >= 0 ? "reserve" : "release"), type,
+                       (ps->bw_phase << 3) + ps->phase_uf, ps->bw_uperiod,
+                       ps->phase, ps->phase_uf, ps->period,
+                       ps->usecs, ps->c_usecs, ps->cs_mask);
+}
+
+static void reserve_release_intr_bandwidth(struct ehci_hcd *ehci,
+               struct ehci_qh *qh, int sign)
+{
+       unsigned                start_uf;
+       unsigned                i, j, m;
+       int                     usecs = qh->ps.usecs;
+       int                     c_usecs = qh->ps.c_usecs;
+       int                     tt_usecs = qh->ps.tt_usecs;
+       struct ehci_tt          *tt;
+
+       if (qh->ps.phase == NO_FRAME)   /* Bandwidth wasn't reserved */
+               return;
+       start_uf = qh->ps.bw_phase << 3;
+
+       bandwidth_dbg(ehci, sign, "intr", &qh->ps);
+
+       if (sign < 0) {         /* Release bandwidth */
+               usecs = -usecs;
+               c_usecs = -c_usecs;
+               tt_usecs = -tt_usecs;
+       }
+
+       /* Entire transaction (high speed) or start-split (full/low speed) */
+       for (i = start_uf + qh->ps.phase_uf; i < EHCI_BANDWIDTH_SIZE;
+                       i += qh->ps.bw_uperiod)
+               ehci->bandwidth[i] += usecs;
+
+       /* Complete-split (full/low speed) */
+       if (qh->ps.c_usecs) {
+               /* NOTE: adjustments needed for FSTN */
+               for (i = start_uf; i < EHCI_BANDWIDTH_SIZE;
+                               i += qh->ps.bw_uperiod) {
+                       for ((j = 2, m = 1 << (j+8)); j < 8; (++j, m <<= 1)) {
+                               if (qh->ps.cs_mask & m)
+                                       ehci->bandwidth[i+j] += c_usecs;
+                       }
                }
        }
-#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
-       if (usecs > ehci->uframe_periodic_max)
-               ehci_err (ehci, "uframe %d sched overrun: %d usecs\n",
-                       frame * 8 + uframe, usecs);
-#endif
-       return usecs;
+
+       /* FS/LS bus bandwidth */
+       if (tt_usecs) {
+               tt = find_tt(qh->ps.udev);
+               if (sign > 0)
+                       list_add_tail(&qh->ps.ps_list, &tt->ps_list);
+               else
+                       list_del(&qh->ps.ps_list);
+
+               for (i = start_uf >> 3; i < EHCI_BANDWIDTH_FRAMES;
+                               i += qh->ps.bw_period)
+                       tt->bandwidth[i] += tt_usecs;
+       }
 }
 
 /*-------------------------------------------------------------------------*/
 
-static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
+static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE],
+               struct ehci_tt *tt)
+{
+       struct ehci_per_sched   *ps;
+       unsigned                uframe, uf, x;
+       u8                      *budget_line;
+
+       if (!tt)
+               return;
+       memset(budget_table, 0, EHCI_BANDWIDTH_SIZE);
+
+       /* Add up the contributions from all the endpoints using this TT */
+       list_for_each_entry(ps, &tt->ps_list, ps_list) {
+               for (uframe = ps->bw_phase << 3; uframe < EHCI_BANDWIDTH_SIZE;
+                               uframe += ps->bw_uperiod) {
+                       budget_line = &budget_table[uframe];
+                       x = ps->tt_usecs;
+
+                       /* propagate the time forward */
+                       for (uf = ps->phase_uf; uf < 8; ++uf) {
+                               x += budget_line[uf];
+
+                               /* Each microframe lasts 125 us */
+                               if (x <= 125) {
+                                       budget_line[uf] = x;
+                                       break;
+                               } else {
+                                       budget_line[uf] = 125;
+                                       x -= 125;
+                               }
+                       }
+               }
+       }
+}
+
+static int __maybe_unused same_tt(struct usb_device *dev1,
+               struct usb_device *dev2)
 {
        if (!dev1->tt || !dev2->tt)
                return 0;
@@ -227,68 +354,6 @@ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
        }
 }
 
-/* How many of the tt's periodic downstream 1000 usecs are allocated?
- *
- * While this measures the bandwidth in terms of usecs/uframe,
- * the low/fullspeed bus has no notion of uframes, so any particular
- * low/fullspeed transfer can "carry over" from one uframe to the next,
- * since the TT just performs downstream transfers in sequence.
- *
- * For example two separate 100 usec transfers can start in the same uframe,
- * and the second one would "carry over" 75 usecs into the next uframe.
- */
-static void
-periodic_tt_usecs (
-       struct ehci_hcd *ehci,
-       struct usb_device *dev,
-       unsigned frame,
-       unsigned short tt_usecs[8]
-)
-{
-       __hc32                  *hw_p = &ehci->periodic [frame];
-       union ehci_shadow       *q = &ehci->pshadow [frame];
-       unsigned char           uf;
-
-       memset(tt_usecs, 0, 16);
-
-       while (q->ptr) {
-               switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
-               case Q_TYPE_ITD:
-                       hw_p = &q->itd->hw_next;
-                       q = &q->itd->itd_next;
-                       continue;
-               case Q_TYPE_QH:
-                       if (same_tt(dev, q->qh->dev)) {
-                               uf = tt_start_uframe(ehci, q->qh->hw->hw_info2);
-                               tt_usecs[uf] += q->qh->tt_usecs;
-                       }
-                       hw_p = &q->qh->hw->hw_next;
-                       q = &q->qh->qh_next;
-                       continue;
-               case Q_TYPE_SITD:
-                       if (same_tt(dev, q->sitd->urb->dev)) {
-                               uf = tt_start_uframe(ehci, q->sitd->hw_uframe);
-                               tt_usecs[uf] += q->sitd->stream->tt_usecs;
-                       }
-                       hw_p = &q->sitd->hw_next;
-                       q = &q->sitd->sitd_next;
-                       continue;
-               // case Q_TYPE_FSTN:
-               default:
-                       ehci_dbg(ehci, "ignoring periodic frame %d FSTN\n",
-                                       frame);
-                       hw_p = &q->fstn->hw_next;
-                       q = &q->fstn->fstn_next;
-               }
-       }
-
-       carryover_tt_bandwidth(tt_usecs);
-
-       if (max_tt_usecs[7] < tt_usecs[7])
-               ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n",
-                       frame, tt_usecs[7] - max_tt_usecs[7]);
-}
-
 /*
  * Return true if the device's tt's downstream bus is available for a
  * periodic transfer of the specified length (usecs), starting at the
@@ -312,20 +377,29 @@ periodic_tt_usecs (
  */
 static int tt_available (
        struct ehci_hcd         *ehci,
-       unsigned                period,
-       struct usb_device       *dev,
+       struct ehci_per_sched   *ps,
+       struct ehci_tt          *tt,
        unsigned                frame,
-       unsigned                uframe,
-       u16                     usecs
+       unsigned                uframe
 )
 {
+       unsigned                period = ps->bw_period;
+       unsigned                usecs = ps->tt_usecs;
+
        if ((period == 0) || (uframe >= 7))     /* error */
                return 0;
 
-       for (; frame < ehci->periodic_size; frame += period) {
-               unsigned short tt_usecs[8];
+       for (frame &= period - 1; frame < EHCI_BANDWIDTH_FRAMES;
+                       frame += period) {
+               unsigned        i, uf;
+               unsigned short  tt_usecs[8];
 
-               periodic_tt_usecs (ehci, dev, frame, tt_usecs);
+               if (tt->bandwidth[frame] + usecs > 900)
+                       return 0;
+
+               uf = frame << 3;
+               for (i = 0; i < 8; (++i, ++uf))
+                       tt_usecs[i] = ehci->tt_budget[uf];
 
                if (max_tt_usecs[uframe] <= tt_usecs[uframe])
                        return 0;
@@ -337,7 +411,7 @@ static int tt_available (
                 */
                if (125 < usecs) {
                        int ufs = (usecs / 125);
-                       int i;
+
                        for (i = uframe; i < (uframe + ufs) && i < 8; i++)
                                if (0 < tt_usecs[i])
                                        return 0;
@@ -391,7 +465,7 @@ static int tt_no_collision (
                                continue;
                        case Q_TYPE_QH:
                                hw = here.qh->hw;
-                               if (same_tt (dev, here.qh->dev)) {
+                               if (same_tt(dev, here.qh->ps.udev)) {
                                        u32             mask;
 
                                        mask = hc32_to_cpu(ehci,
@@ -471,19 +545,19 @@ static void disable_periodic(struct ehci_hcd *ehci)
 static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        unsigned        i;
-       unsigned        period = qh->period;
+       unsigned        period = qh->ps.period;
 
-       dev_dbg (&qh->dev->dev,
+       dev_dbg(&qh->ps.udev->dev,
                "link qh%d-%04x/%p start %d [%d/%d us]\n",
                period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
                        & (QH_CMASK | QH_SMASK),
-               qh, qh->start, qh->usecs, qh->c_usecs);
+               qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
 
        /* high bandwidth, or otherwise every microframe */
        if (period == 0)
                period = 1;
 
-       for (i = qh->start; i < ehci->periodic_size; i += period) {
+       for (i = qh->ps.phase; i < ehci->periodic_size; i += period) {
                union ehci_shadow       *prev = &ehci->pshadow[i];
                __hc32                  *hw_p = &ehci->periodic[i];
                union ehci_shadow       here = *prev;
@@ -503,7 +577,7 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
                 * enables sharing interior tree nodes
                 */
                while (here.ptr && qh != here.qh) {
-                       if (qh->period > here.qh->period)
+                       if (qh->ps.period > here.qh->ps.period)
                                break;
                        prev = &here.qh->qh_next;
                        hw_p = &here.qh->hw->hw_next;
@@ -523,10 +597,10 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
        qh->xacterrs = 0;
        qh->exception = 0;
 
-       /* update per-qh bandwidth for usbfs */
-       ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->period
-               ? ((qh->usecs + qh->c_usecs) / qh->period)
-               : (qh->usecs * 8);
+       /* update per-qh bandwidth for debugfs */
+       ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->ps.bw_period
+               ? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.bw_period)
+               : (qh->ps.usecs * 8);
 
        list_add(&qh->intr_node, &ehci->intr_qh_list);
 
@@ -556,22 +630,21 @@ static void qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
         */
 
        /* high bandwidth, or otherwise part of every microframe */
-       if ((period = qh->period) == 0)
-               period = 1;
+       period = qh->ps.period ? : 1;
 
-       for (i = qh->start; i < ehci->periodic_size; i += period)
+       for (i = qh->ps.phase; i < ehci->periodic_size; i += period)
                periodic_unlink (ehci, i, qh);
 
-       /* update per-qh bandwidth for usbfs */
-       ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->period
-               ? ((qh->usecs + qh->c_usecs) / qh->period)
-               : (qh->usecs * 8);
+       /* update per-qh bandwidth for debugfs */
+       ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->ps.bw_period
+               ? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.bw_period)
+               : (qh->ps.usecs * 8);
 
-       dev_dbg (&qh->dev->dev,
+       dev_dbg(&qh->ps.udev->dev,
                "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-               qh->period,
+               qh->ps.period,
                hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
-               qh, qh->start, qh->usecs, qh->c_usecs);
+               qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
 
        /* qh->qh_next still "live" to HC */
        qh->qh_state = QH_STATE_UNLINK;
@@ -694,11 +767,9 @@ static int check_period (
        struct ehci_hcd *ehci,
        unsigned        frame,
        unsigned        uframe,
-       unsigned        period,
+       unsigned        uperiod,
        unsigned        usecs
 ) {
-       int             claimed;
-
        /* complete split running into next frame?
         * given FSTN support, we could sometimes check...
         */
@@ -708,25 +779,10 @@ static int check_period (
        /* convert "usecs we need" to "max already claimed" */
        usecs = ehci->uframe_periodic_max - usecs;
 
-       /* we "know" 2 and 4 uframe intervals were rejected; so
-        * for period 0, check _every_ microframe in the schedule.
-        */
-       if (unlikely (period == 0)) {
-               do {
-                       for (uframe = 0; uframe < 7; uframe++) {
-                               claimed = periodic_usecs (ehci, frame, uframe);
-                               if (claimed > usecs)
-                                       return 0;
-                       }
-               } while ((frame += 1) < ehci->periodic_size);
-
-       /* just check the specified uframe, at that period */
-       } else {
-               do {
-                       claimed = periodic_usecs (ehci, frame, uframe);
-                       if (claimed > usecs)
-                               return 0;
-               } while ((frame += period) < ehci->periodic_size);
+       for (uframe += frame << 3; uframe < EHCI_BANDWIDTH_SIZE;
+                       uframe += uperiod) {
+               if (ehci->bandwidth[uframe] > usecs)
+                       return 0;
        }
 
        // success!
@@ -737,40 +793,40 @@ static int check_intr_schedule (
        struct ehci_hcd         *ehci,
        unsigned                frame,
        unsigned                uframe,
-       const struct ehci_qh    *qh,
-       __hc32                  *c_maskp
+       struct ehci_qh          *qh,
+       unsigned                *c_maskp,
+       struct ehci_tt          *tt
 )
 {
        int             retval = -ENOSPC;
        u8              mask = 0;
 
-       if (qh->c_usecs && uframe >= 6)         /* FSTN territory? */
+       if (qh->ps.c_usecs && uframe >= 6)      /* FSTN territory? */
                goto done;
 
-       if (!check_period (ehci, frame, uframe, qh->period, qh->usecs))
+       if (!check_period(ehci, frame, uframe, qh->ps.bw_uperiod, qh->ps.usecs))
                goto done;
-       if (!qh->c_usecs) {
+       if (!qh->ps.c_usecs) {
                retval = 0;
                *c_maskp = 0;
                goto done;
        }
 
 #ifdef CONFIG_USB_EHCI_TT_NEWSCHED
-       if (tt_available (ehci, qh->period, qh->dev, frame, uframe,
-                               qh->tt_usecs)) {
+       if (tt_available(ehci, &qh->ps, tt, frame, uframe)) {
                unsigned i;
 
                /* TODO : this may need FSTN for SSPLIT in uframe 5. */
-               for (i=uframe+1; i<8 && i<uframe+4; i++)
-                       if (!check_period (ehci, frame, i,
-                                               qh->period, qh->c_usecs))
+               for (i = uframe+2; i < 8 && i <= uframe+4; i++)
+                       if (!check_period(ehci, frame, i,
+                                       qh->ps.bw_uperiod, qh->ps.c_usecs))
                                goto done;
                        else
                                mask |= 1 << i;
 
                retval = 0;
 
-               *c_maskp = cpu_to_hc32(ehci, mask << 8);
+               *c_maskp = mask;
        }
 #else
        /* Make sure this tt's buffer is also available for CSPLITs.
@@ -781,15 +837,15 @@ static int check_intr_schedule (
         * one smart pass...
         */
        mask = 0x03 << (uframe + qh->gap_uf);
-       *c_maskp = cpu_to_hc32(ehci, mask << 8);
+       *c_maskp = mask;
 
        mask |= 1 << uframe;
-       if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
-               if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
-                                       qh->period, qh->c_usecs))
+       if (tt_no_collision(ehci, qh->ps.bw_period, qh->ps.udev, frame, mask)) {
+               if (!check_period(ehci, frame, uframe + qh->gap_uf + 1,
+                               qh->ps.bw_uperiod, qh->ps.c_usecs))
                        goto done;
-               if (!check_period (ehci, frame, uframe + qh->gap_uf,
-                                       qh->period, qh->c_usecs))
+               if (!check_period(ehci, frame, uframe + qh->gap_uf,
+                               qh->ps.bw_uperiod, qh->ps.c_usecs))
                        goto done;
                retval = 0;
        }
@@ -803,62 +859,67 @@ done:
  */
 static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-       int             status;
+       int             status = 0;
        unsigned        uframe;
-       __hc32          c_mask;
-       unsigned        frame;          /* 0..(qh->period - 1), or NO_FRAME */
+       unsigned        c_mask;
        struct ehci_qh_hw       *hw = qh->hw;
+       struct ehci_tt          *tt;
 
        hw->hw_next = EHCI_LIST_END(ehci);
-       frame = qh->start;
 
        /* reuse the previous schedule slots, if we can */
-       if (frame < qh->period) {
-               uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK);
-               status = check_intr_schedule (ehci, frame, --uframe,
-                               qh, &c_mask);
-       } else {
-               uframe = 0;
-               c_mask = 0;
-               status = -ENOSPC;
+       if (qh->ps.phase != NO_FRAME) {
+               ehci_dbg(ehci, "reused qh %p schedule\n", qh);
+               return 0;
+       }
+
+       uframe = 0;
+       c_mask = 0;
+       tt = find_tt(qh->ps.udev);
+       if (IS_ERR(tt)) {
+               status = PTR_ERR(tt);
+               goto done;
        }
+       compute_tt_budget(ehci->tt_budget, tt);
 
        /* else scan the schedule to find a group of slots such that all
         * uframes have enough periodic bandwidth available.
         */
-       if (status) {
-               /* "normal" case, uframing flexible except with splits */
-               if (qh->period) {
-                       int             i;
-
-                       for (i = qh->period; status && i > 0; --i) {
-                               frame = ++ehci->random_frame % qh->period;
-                               for (uframe = 0; uframe < 8; uframe++) {
-                                       status = check_intr_schedule (ehci,
-                                                       frame, uframe, qh,
-                                                       &c_mask);
-                                       if (status == 0)
-                                               break;
-                               }
+       /* "normal" case, uframing flexible except with splits */
+       if (qh->ps.bw_period) {
+               int             i;
+               unsigned        frame;
+
+               for (i = qh->ps.bw_period; i > 0; --i) {
+                       frame = ++ehci->random_frame & (qh->ps.bw_period - 1);
+                       for (uframe = 0; uframe < 8; uframe++) {
+                               status = check_intr_schedule(ehci,
+                                               frame, uframe, qh, &c_mask, tt);
+                               if (status == 0)
+                                       goto got_it;
                        }
-
-               /* qh->period == 0 means every uframe */
-               } else {
-                       frame = 0;
-                       status = check_intr_schedule (ehci, 0, 0, qh, &c_mask);
                }
-               if (status)
-                       goto done;
-               qh->start = frame;
 
-               /* reset S-frame and (maybe) C-frame masks */
-               hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
-               hw->hw_info2 |= qh->period
-                       ? cpu_to_hc32(ehci, 1 << uframe)
-                       : cpu_to_hc32(ehci, QH_SMASK);
-               hw->hw_info2 |= c_mask;
-       } else
-               ehci_dbg (ehci, "reused qh %p schedule\n", qh);
+       /* qh->ps.bw_period == 0 means every uframe */
+       } else {
+               status = check_intr_schedule(ehci, 0, 0, qh, &c_mask, tt);
+       }
+       if (status)
+               goto done;
+
+ got_it:
+       qh->ps.phase = (qh->ps.period ? ehci->random_frame &
+                       (qh->ps.period - 1) : 0);
+       qh->ps.bw_phase = qh->ps.phase & (qh->ps.bw_period - 1);
+       qh->ps.phase_uf = uframe;
+       qh->ps.cs_mask = qh->ps.period ?
+                       (c_mask << 8) | (1 << uframe) :
+                       QH_SMASK;
+
+       /* reset S-frame and (maybe) C-frame masks */
+       hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
+       hw->hw_info2 |= cpu_to_hc32(ehci, qh->ps.cs_mask);
+       reserve_release_intr_bandwidth(ehci, qh, 1);
 
 done:
        return status;
@@ -969,7 +1030,8 @@ iso_stream_alloc (gfp_t mem_flags)
        if (likely (stream != NULL)) {
                INIT_LIST_HEAD(&stream->td_list);
                INIT_LIST_HEAD(&stream->free_list);
-               stream->next_uframe = -1;
+               stream->next_uframe = NO_FRAME;
+               stream->ps.phase = NO_FRAME;
        }
        return stream;
 }
@@ -978,25 +1040,24 @@ static void
 iso_stream_init (
        struct ehci_hcd         *ehci,
        struct ehci_iso_stream  *stream,
-       struct usb_device       *dev,
-       int                     pipe,
-       unsigned                interval
+       struct urb              *urb
 )
 {
        static const u8 smask_out [] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f };
 
+       struct usb_device       *dev = urb->dev;
        u32                     buf1;
        unsigned                epnum, maxp;
        int                     is_input;
-       long                    bandwidth;
+       unsigned                tmp;
 
        /*
         * this might be a "high bandwidth" highspeed endpoint,
         * as encoded in the ep descriptor's wMaxPacket field
         */
-       epnum = usb_pipeendpoint (pipe);
-       is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
-       maxp = usb_maxpacket(dev, pipe, !is_input);
+       epnum = usb_pipeendpoint(urb->pipe);
+       is_input = usb_pipein(urb->pipe) ? USB_DIR_IN : 0;
+       maxp = usb_endpoint_maxp(&urb->ep->desc);
        if (is_input) {
                buf1 = (1 << 11);
        } else {
@@ -1020,9 +1081,19 @@ iso_stream_init (
                /* usbfs wants to report the average usecs per frame tied up
                 * when transfers on this endpoint are scheduled ...
                 */
-               stream->usecs = HS_USECS_ISO (maxp);
-               bandwidth = stream->usecs * 8;
-               bandwidth /= interval;
+               stream->ps.usecs = HS_USECS_ISO(maxp);
+
+               /* period for bandwidth allocation */
+               tmp = min_t(unsigned, EHCI_BANDWIDTH_SIZE,
+                               1 << (urb->ep->desc.bInterval - 1));
+
+               /* Allow urb->interval to override */
+               stream->ps.bw_uperiod = min_t(unsigned, tmp, urb->interval);
+
+               stream->uperiod = urb->interval;
+               stream->ps.period = urb->interval >> 3;
+               stream->bandwidth = stream->ps.usecs * 8 /
+                               stream->ps.bw_uperiod;
 
        } else {
                u32             addr;
@@ -1036,36 +1107,46 @@ iso_stream_init (
                        addr |= dev->tt->hub->devnum << 16;
                addr |= epnum << 8;
                addr |= dev->devnum;
-               stream->usecs = HS_USECS_ISO (maxp);
+               stream->ps.usecs = HS_USECS_ISO(maxp);
                think_time = dev->tt ? dev->tt->think_time : 0;
-               stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
+               stream->ps.tt_usecs = NS_TO_US(think_time + usb_calc_bus_time(
                                dev->speed, is_input, 1, maxp));
                hs_transfers = max (1u, (maxp + 187) / 188);
                if (is_input) {
                        u32     tmp;
 
                        addr |= 1 << 31;
-                       stream->c_usecs = stream->usecs;
-                       stream->usecs = HS_USECS_ISO (1);
-                       stream->raw_mask = 1;
+                       stream->ps.c_usecs = stream->ps.usecs;
+                       stream->ps.usecs = HS_USECS_ISO(1);
+                       stream->ps.cs_mask = 1;
 
                        /* c-mask as specified in USB 2.0 11.18.4 3.c */
                        tmp = (1 << (hs_transfers + 2)) - 1;
-                       stream->raw_mask |= tmp << (8 + 2);
+                       stream->ps.cs_mask |= tmp << (8 + 2);
                } else
-                       stream->raw_mask = smask_out [hs_transfers - 1];
-               bandwidth = stream->usecs + stream->c_usecs;
-               bandwidth /= interval << 3;
+                       stream->ps.cs_mask = smask_out[hs_transfers - 1];
+
+               /* period for bandwidth allocation */
+               tmp = min_t(unsigned, EHCI_BANDWIDTH_FRAMES,
+                               1 << (urb->ep->desc.bInterval - 1));
+
+               /* Allow urb->interval to override */
+               stream->ps.bw_period = min_t(unsigned, tmp, urb->interval);
+               stream->ps.bw_uperiod = stream->ps.bw_period << 3;
 
-               /* stream->splits gets created from raw_mask later */
+               stream->ps.period = urb->interval;
+               stream->uperiod = urb->interval << 3;
+               stream->bandwidth = (stream->ps.usecs + stream->ps.c_usecs) /
+                               stream->ps.bw_period;
+
+               /* stream->splits gets created from cs_mask later */
                stream->address = cpu_to_hc32(ehci, addr);
        }
-       stream->bandwidth = bandwidth;
 
-       stream->udev = dev;
+       stream->ps.udev = dev;
+       stream->ps.ep = urb->ep;
 
        stream->bEndpointAddress = is_input | epnum;
-       stream->interval = interval;
        stream->maxp = maxp;
 }
 
@@ -1090,9 +1171,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
                stream = iso_stream_alloc(GFP_ATOMIC);
                if (likely (stream != NULL)) {
                        ep->hcpriv = stream;
-                       stream->ep = ep;
-                       iso_stream_init(ehci, stream, urb->dev, urb->pipe,
-                                       urb->interval);
+                       iso_stream_init(ehci, stream, urb);
                }
 
        /* if dev->ep [epnum] is a QH, hw is set */
@@ -1137,7 +1216,7 @@ itd_sched_init(
        dma_addr_t      dma = urb->transfer_dma;
 
        /* how many uframes are needed for these transfers */
-       iso_sched->span = urb->number_of_packets * stream->interval;
+       iso_sched->span = urb->number_of_packets * stream->uperiod;
 
        /* figure out per-uframe itd fields that we'll need later
         * when we fit new itds into the schedule.
@@ -1236,7 +1315,7 @@ itd_urb_transaction (
 
                memset (itd, 0, sizeof *itd);
                itd->itd_dma = itd_dma;
-               itd->frame = 9999;              /* an invalid value */
+               itd->frame = NO_FRAME;
                list_add (&itd->itd_list, &sched->td_list);
        }
        spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1249,49 +1328,106 @@ itd_urb_transaction (
 
 /*-------------------------------------------------------------------------*/
 
+static void reserve_release_iso_bandwidth(struct ehci_hcd *ehci,
+               struct ehci_iso_stream *stream, int sign)
+{
+       unsigned                uframe;
+       unsigned                i, j;
+       unsigned                s_mask, c_mask, m;
+       int                     usecs = stream->ps.usecs;
+       int                     c_usecs = stream->ps.c_usecs;
+       int                     tt_usecs = stream->ps.tt_usecs;
+       struct ehci_tt          *tt;
+
+       if (stream->ps.phase == NO_FRAME)       /* Bandwidth wasn't reserved */
+               return;
+       uframe = stream->ps.bw_phase << 3;
+
+       bandwidth_dbg(ehci, sign, "iso", &stream->ps);
+
+       if (sign < 0) {         /* Release bandwidth */
+               usecs = -usecs;
+               c_usecs = -c_usecs;
+               tt_usecs = -tt_usecs;
+       }
+
+       if (!stream->splits) {          /* High speed */
+               for (i = uframe + stream->ps.phase_uf; i < EHCI_BANDWIDTH_SIZE;
+                               i += stream->ps.bw_uperiod)
+                       ehci->bandwidth[i] += usecs;
+
+       } else {                        /* Full speed */
+               s_mask = stream->ps.cs_mask;
+               c_mask = s_mask >> 8;
+
+               /* NOTE: adjustment needed for frame overflow */
+               for (i = uframe; i < EHCI_BANDWIDTH_SIZE;
+                               i += stream->ps.bw_uperiod) {
+                       for ((j = stream->ps.phase_uf, m = 1 << j); j < 8;
+                                       (++j, m <<= 1)) {
+                               if (s_mask & m)
+                                       ehci->bandwidth[i+j] += usecs;
+                               else if (c_mask & m)
+                                       ehci->bandwidth[i+j] += c_usecs;
+                       }
+               }
+
+               tt = find_tt(stream->ps.udev);
+               if (sign > 0)
+                       list_add_tail(&stream->ps.ps_list, &tt->ps_list);
+               else
+                       list_del(&stream->ps.ps_list);
+
+               for (i = uframe >> 3; i < EHCI_BANDWIDTH_FRAMES;
+                               i += stream->ps.bw_period)
+                       tt->bandwidth[i] += tt_usecs;
+       }
+}
+
 static inline int
 itd_slot_ok (
        struct ehci_hcd         *ehci,
-       u32                     mod,
-       u32                     uframe,
-       u8                      usecs,
-       u32                     period
+       struct ehci_iso_stream  *stream,
+       unsigned                uframe
 )
 {
-       uframe %= period;
-       do {
-               /* can't commit more than uframe_periodic_max usec */
-               if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7)
-                               > (ehci->uframe_periodic_max - usecs))
-                       return 0;
+       unsigned                usecs;
+
+       /* convert "usecs we need" to "max already claimed" */
+       usecs = ehci->uframe_periodic_max - stream->ps.usecs;
 
-               /* we know urb->interval is 2^N uframes */
-               uframe += period;
-       } while (uframe < mod);
+       for (uframe &= stream->ps.bw_uperiod - 1; uframe < EHCI_BANDWIDTH_SIZE;
+                       uframe += stream->ps.bw_uperiod) {
+               if (ehci->bandwidth[uframe] > usecs)
+                       return 0;
+       }
        return 1;
 }
 
 static inline int
 sitd_slot_ok (
        struct ehci_hcd         *ehci,
-       u32                     mod,
        struct ehci_iso_stream  *stream,
-       u32                     uframe,
+       unsigned                uframe,
        struct ehci_iso_sched   *sched,
-       u32                     period_uframes
+       struct ehci_tt          *tt
 )
 {
-       u32                     mask, tmp;
-       u32                     frame, uf;
+       unsigned                mask, tmp;
+       unsigned                frame, uf;
+
+       mask = stream->ps.cs_mask << (uframe & 7);
 
-       mask = stream->raw_mask << (uframe & 7);
+       /* for OUT, don't wrap SSPLIT into H-microframe 7 */
+       if (((stream->ps.cs_mask & 0xff) << (uframe & 7)) >= (1 << 7))
+               return 0;
 
        /* for IN, don't wrap CSPLIT into the next frame */
        if (mask & ~0xffff)
                return 0;
 
        /* check bandwidth */
-       uframe %= period_uframes;
+       uframe &= stream->ps.bw_uperiod - 1;
        frame = uframe >> 3;
 
 #ifdef CONFIG_USB_EHCI_TT_NEWSCHED
@@ -1299,54 +1435,48 @@ sitd_slot_ok (
         * tt_available scheduling guarantees 10+% for control/bulk.
         */
        uf = uframe & 7;
-       if (!tt_available(ehci, period_uframes >> 3,
-                       stream->udev, frame, uf, stream->tt_usecs))
+       if (!tt_available(ehci, &stream->ps, tt, frame, uf))
                return 0;
 #else
        /* tt must be idle for start(s), any gap, and csplit.
         * assume scheduling slop leaves 10+% for control/bulk.
         */
-       if (!tt_no_collision(ehci, period_uframes >> 3,
-                       stream->udev, frame, mask))
+       if (!tt_no_collision(ehci, stream->ps.bw_period,
+                       stream->ps.udev, frame, mask))
                return 0;
 #endif
 
-       /* this multi-pass logic is simple, but performance may
-        * suffer when the schedule data isn't cached.
-        */
        do {
-               u32             max_used;
-
-               frame = uframe >> 3;
-               uf = uframe & 7;
+               unsigned        max_used;
+               unsigned        i;
 
                /* check starts (OUT uses more than one) */
-               max_used = ehci->uframe_periodic_max - stream->usecs;
-               for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) {
-                       if (periodic_usecs (ehci, frame, uf) > max_used)
+               uf = uframe;
+               max_used = ehci->uframe_periodic_max - stream->ps.usecs;
+               for (tmp = stream->ps.cs_mask & 0xff; tmp; tmp >>= 1, uf++) {
+                       if (ehci->bandwidth[uf] > max_used)
                                return 0;
                }
 
                /* for IN, check CSPLIT */
-               if (stream->c_usecs) {
-                       uf = uframe & 7;
-                       max_used = ehci->uframe_periodic_max - stream->c_usecs;
-                       do {
-                               tmp = 1 << uf;
-                               tmp <<= 8;
-                               if ((stream->raw_mask & tmp) == 0)
+               if (stream->ps.c_usecs) {
+                       max_used = ehci->uframe_periodic_max -
+                                       stream->ps.c_usecs;
+                       uf = uframe & ~7;
+                       tmp = 1 << (2+8);
+                       for (i = (uframe & 7) + 2; i < 8; (++i, tmp <<= 1)) {
+                               if ((stream->ps.cs_mask & tmp) == 0)
                                        continue;
-                               if (periodic_usecs (ehci, frame, uf)
-                                               > max_used)
+                               if (ehci->bandwidth[uf+i] > max_used)
                                        return 0;
-                       } while (++uf < 8);
+                       }
                }
 
-               /* we know urb->interval is 2^N uframes */
-               uframe += period_uframes;
-       } while (uframe < mod);
+               uframe += stream->ps.bw_uperiod;
+       } while (uframe < EHCI_BANDWIDTH_SIZE);
 
-       stream->splits = cpu_to_hc32(ehci, stream->raw_mask << (uframe & 7));
+       stream->ps.cs_mask <<= uframe & 7;
+       stream->splits = cpu_to_hc32(ehci, stream->ps.cs_mask);
        return 1;
 }
 
@@ -1361,8 +1491,6 @@ sitd_slot_ok (
  * given EHCI_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
 
-#define SCHEDULING_DELAY       40      /* microframes */
-
 static int
 iso_stream_schedule (
        struct ehci_hcd         *ehci,
@@ -1370,134 +1498,184 @@ iso_stream_schedule (
        struct ehci_iso_stream  *stream
 )
 {
-       u32                     now, base, next, start, period, span;
-       int                     status;
+       u32                     now, base, next, start, period, span, now2;
+       u32                     wrap = 0, skip = 0;
+       int                     status = 0;
        unsigned                mod = ehci->periodic_size << 3;
        struct ehci_iso_sched   *sched = urb->hcpriv;
+       bool                    empty = list_empty(&stream->td_list);
+       bool                    new_stream = false;
 
-       period = urb->interval;
+       period = stream->uperiod;
        span = sched->span;
-       if (!stream->highspeed) {
-               period <<= 3;
+       if (!stream->highspeed)
                span <<= 3;
-       }
 
-       now = ehci_read_frame_index(ehci) & (mod - 1);
+       /* Start a new isochronous stream? */
+       if (unlikely(empty && !hcd_periodic_completion_in_progress(
+                       ehci_to_hcd(ehci), urb->ep))) {
 
-       /* Typical case: reuse current schedule, stream is still active.
-        * Hopefully there are no gaps from the host falling behind
-        * (irq delays etc).  If there are, the behavior depends on
-        * whether URB_ISO_ASAP is set.
-        */
-       if (likely (!list_empty (&stream->td_list))) {
+               /* Schedule the endpoint */
+               if (stream->ps.phase == NO_FRAME) {
+                       int             done = 0;
+                       struct ehci_tt  *tt = find_tt(stream->ps.udev);
 
-               /* Take the isochronous scheduling threshold into account */
-               if (ehci->i_thresh)
-                       next = now + ehci->i_thresh;    /* uframe cache */
-               else
-                       next = (now + 2 + 7) & ~0x07;   /* full frame cache */
-
-               /*
-                * Use ehci->last_iso_frame as the base.  There can't be any
-                * TDs scheduled for earlier than that.
-                */
-               base = ehci->last_iso_frame << 3;
-               next = (next - base) & (mod - 1);
-               start = (stream->next_uframe - base) & (mod - 1);
-
-               /* Is the schedule already full? */
-               if (unlikely(start < period)) {
-                       ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n",
-                                       urb, stream->next_uframe, base,
-                                       period, mod);
-                       status = -ENOSPC;
-                       goto fail;
-               }
-
-               /* Behind the scheduling threshold? */
-               if (unlikely(start < next)) {
-                       unsigned now2 = (now - base) & (mod - 1);
+                       if (IS_ERR(tt)) {
+                               status = PTR_ERR(tt);
+                               goto fail;
+                       }
+                       compute_tt_budget(ehci->tt_budget, tt);
 
-                       /* USB_ISO_ASAP: Round up to the first available slot */
-                       if (urb->transfer_flags & URB_ISO_ASAP)
-                               start += (next - start + period - 1) & -period;
+                       start = ((-(++ehci->random_frame)) << 3) & (period - 1);
 
-                       /*
-                        * Not ASAP: Use the next slot in the stream,
-                        * no matter what.
+                       /* find a uframe slot with enough bandwidth.
+                        * Early uframes are more precious because full-speed
+                        * iso IN transfers can't use late uframes,
+                        * and therefore they should be allocated last.
                         */
-                       else if (start + span - period < now2) {
-                               ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n",
-                                               urb, start + base,
-                                               span - period, now2 + base);
+                       next = start;
+                       start += period;
+                       do {
+                               start--;
+                               /* check schedule: enough space? */
+                               if (stream->highspeed) {
+                                       if (itd_slot_ok(ehci, stream, start))
+                                               done = 1;
+                               } else {
+                                       if ((start % 8) >= 6)
+                                               continue;
+                                       if (sitd_slot_ok(ehci, stream, start,
+                                                       sched, tt))
+                                               done = 1;
+                               }
+                       } while (start > next && !done);
+
+                       /* no room in the schedule */
+                       if (!done) {
+                               ehci_dbg(ehci, "iso sched full %p", urb);
+                               status = -ENOSPC;
+                               goto fail;
                        }
+                       stream->ps.phase = (start >> 3) &
+                                       (stream->ps.period - 1);
+                       stream->ps.bw_phase = stream->ps.phase &
+                                       (stream->ps.bw_period - 1);
+                       stream->ps.phase_uf = start & 7;
+                       reserve_release_iso_bandwidth(ehci, stream, 1);
+               }
+
+               /* New stream is already scheduled; use the upcoming slot */
+               else {
+                       start = (stream->ps.phase << 3) + stream->ps.phase_uf;
                }
 
-               start += base;
+               stream->next_uframe = start;
+               new_stream = true;
        }
 
-       /* need to schedule; when's the next (u)frame we could start?
-        * this is bigger than ehci->i_thresh allows; scheduling itself
-        * isn't free, the delay should handle reasonably slow cpus.  it
-        * can also help high bandwidth if the dma and irq loads don't
-        * jump until after the queue is primed.
+       now = ehci_read_frame_index(ehci) & (mod - 1);
+
+       /* Take the isochronous scheduling threshold into account */
+       if (ehci->i_thresh)
+               next = now + ehci->i_thresh;    /* uframe cache */
+       else
+               next = (now + 2 + 7) & ~0x07;   /* full frame cache */
+
+       /*
+        * Use ehci->last_iso_frame as the base.  There can't be any
+        * TDs scheduled for earlier than that.
         */
-       else {
-               int done = 0;
+       base = ehci->last_iso_frame << 3;
+       next = (next - base) & (mod - 1);
+       start = (stream->next_uframe - base) & (mod - 1);
 
-               base = now & ~0x07;
-               start = base + SCHEDULING_DELAY;
+       if (unlikely(new_stream))
+               goto do_ASAP;
 
-               /* find a uframe slot with enough bandwidth.
-                * Early uframes are more precious because full-speed
-                * iso IN transfers can't use late uframes,
-                * and therefore they should be allocated last.
-                */
-               next = start;
-               start += period;
-               do {
-                       start--;
-                       /* check schedule: enough space? */
-                       if (stream->highspeed) {
-                               if (itd_slot_ok(ehci, mod, start,
-                                               stream->usecs, period))
-                                       done = 1;
-                       } else {
-                               if ((start % 8) >= 6)
-                                       continue;
-                               if (sitd_slot_ok(ehci, mod, stream,
-                                               start, sched, period))
-                                       done = 1;
-                       }
-               } while (start > next && !done);
+       /*
+        * Typical case: reuse current schedule, stream may still be active.
+        * Hopefully there are no gaps from the host falling behind
+        * (irq delays etc).  If there are, the behavior depends on
+        * whether URB_ISO_ASAP is set.
+        */
+       now2 = (now - base) & (mod - 1);
+
+       /* Is the schedule already full? */
+       if (unlikely(!empty && start < period)) {
+               ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n",
+                               urb, stream->next_uframe, base, period, mod);
+               status = -ENOSPC;
+               goto fail;
+       }
+
+       /* Is the next packet scheduled after the base time? */
+       if (likely(!empty || start <= now2 + period)) {
+
+               /* URB_ISO_ASAP: make sure that start >= next */
+               if (unlikely(start < next &&
+                               (urb->transfer_flags & URB_ISO_ASAP)))
+                       goto do_ASAP;
+
+               /* Otherwise use start, if it's not in the past */
+               if (likely(start >= now2))
+                       goto use_start;
 
-               /* no room in the schedule */
-               if (!done) {
-                       ehci_dbg(ehci, "iso sched full %p", urb);
-                       status = -ENOSPC;
-                       goto fail;
+       /* Otherwise we got an underrun while the queue was empty */
+       } else {
+               if (urb->transfer_flags & URB_ISO_ASAP)
+                       goto do_ASAP;
+               wrap = mod;
+               now2 += mod;
+       }
+
+       /* How many uframes and packets do we need to skip? */
+       skip = (now2 - start + period - 1) & -period;
+       if (skip >= span) {             /* Entirely in the past? */
+               ehci_dbg(ehci, "iso underrun %p (%u+%u < %u) [%u]\n",
+                               urb, start + base, span - period, now2 + base,
+                               base);
+
+               /* Try to keep the last TD intact for scanning later */
+               skip = span - period;
+
+               /* Will it come before the current scan position? */
+               if (empty) {
+                       skip = span;    /* Skip the entire URB */
+                       status = 1;     /* and give it back immediately */
+                       iso_sched_free(stream, sched);
+                       sched = NULL;
                }
        }
+       urb->error_count = skip / period;
+       if (sched)
+               sched->first_packet = urb->error_count;
+       goto use_start;
 
+ do_ASAP:
+       /* Use the first slot after "next" */
+       start = next + ((start - next) & (period - 1));
+
+ use_start:
        /* Tried to schedule too far into the future? */
-       if (unlikely(start - base + span - period >= mod)) {
+       if (unlikely(start + span - period >= mod + wrap)) {
                ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
-                               urb, start - base, span - period, mod);
+                               urb, start, span - period, mod + wrap);
                status = -EFBIG;
                goto fail;
        }
 
-       stream->next_uframe = start & (mod - 1);
+       start += base;
+       stream->next_uframe = (start + skip) & (mod - 1);
 
        /* report high speed start in uframes; full speed, in frames */
-       urb->start_frame = stream->next_uframe;
+       urb->start_frame = start & (mod - 1);
        if (!stream->highspeed)
                urb->start_frame >>= 3;
 
        /* Make sure scan_isoc() sees these */
        if (ehci->isoc_count == 0)
                ehci->last_iso_frame = now >> 3;
-       return 0;
+       return status;
 
  fail:
        iso_sched_free(stream, sched);
@@ -1610,7 +1788,8 @@ static void itd_link_urb(
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
 
        /* fill iTDs uframe by uframe */
-       for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
+       for (packet = iso_sched->first_packet, itd = NULL;
+                       packet < urb->number_of_packets;) {
                if (itd == NULL) {
                        /* ASSERT:  we have all necessary itds */
                        // BUG_ON (list_empty (&iso_sched->td_list));
@@ -1630,7 +1809,7 @@ static void itd_link_urb(
 
                itd_patch(ehci, itd, iso_sched, packet, uframe);
 
-               next_uframe += stream->interval;
+               next_uframe += stream->uperiod;
                next_uframe &= mod - 1;
                packet++;
 
@@ -1770,9 +1949,9 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
                ehci_dbg (ehci, "can't get iso stream\n");
                return -ENOMEM;
        }
-       if (unlikely (urb->interval != stream->interval)) {
+       if (unlikely(urb->interval != stream->uperiod)) {
                ehci_dbg (ehci, "can't change iso interval %d --> %d\n",
-                       stream->interval, urb->interval);
+                       stream->uperiod, urb->interval);
                goto done;
        }
 
@@ -1804,10 +1983,14 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
        if (unlikely(status))
                goto done_not_linked;
        status = iso_stream_schedule(ehci, urb, stream);
-       if (likely (status == 0))
+       if (likely(status == 0)) {
                itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
-       else
+       } else if (status > 0) {
+               status = 0;
+               ehci_urb_done(ehci, urb, 0);
+       } else {
                usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+       }
  done_not_linked:
        spin_unlock_irqrestore (&ehci->lock, flags);
  done:
@@ -1833,7 +2016,7 @@ sitd_sched_init(
        dma_addr_t      dma = urb->transfer_dma;
 
        /* how many frames are needed for these transfers */
-       iso_sched->span = urb->number_of_packets * stream->interval;
+       iso_sched->span = urb->number_of_packets * stream->ps.period;
 
        /* figure out per-frame sitd fields that we'll need later
         * when we fit new sitds into the schedule.
@@ -1925,7 +2108,7 @@ sitd_urb_transaction (
 
                memset (sitd, 0, sizeof *sitd);
                sitd->sitd_dma = sitd_dma;
-               sitd->frame = 9999;             /* an invalid value */
+               sitd->frame = NO_FRAME;
                list_add (&sitd->sitd_list, &iso_sched->td_list);
        }
 
@@ -2008,7 +2191,7 @@ static void sitd_link_urb(
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
 
        /* fill sITDs frame by frame */
-       for (packet = 0, sitd = NULL;
+       for (packet = sched->first_packet, sitd = NULL;
                        packet < urb->number_of_packets;
                        packet++) {
 
@@ -2027,7 +2210,7 @@ static void sitd_link_urb(
                sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1),
                                sitd);
 
-               next_uframe += stream->interval << 3;
+               next_uframe += stream->uperiod;
        }
        stream->next_uframe = next_uframe & (mod - 1);
 
@@ -2146,9 +2329,9 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
                ehci_dbg (ehci, "can't get iso stream\n");
                return -ENOMEM;
        }
-       if (urb->interval != stream->interval) {
+       if (urb->interval != stream->ps.period) {
                ehci_dbg (ehci, "can't change iso interval %d --> %d\n",
-                       stream->interval, urb->interval);
+                       stream->ps.period, urb->interval);
                goto done;
        }
 
@@ -2178,10 +2361,14 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
        if (unlikely(status))
                goto done_not_linked;
        status = iso_stream_schedule(ehci, urb, stream);
-       if (status == 0)
+       if (likely(status == 0)) {
                sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
-       else
+       } else if (status > 0) {
+               status = 0;
+               ehci_urb_done(ehci, urb, 0);
+       } else {
                usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+       }
  done_not_linked:
        spin_unlock_irqrestore (&ehci->lock, flags);
  done:
@@ -2259,7 +2446,8 @@ restart:
                                    q.itd->hw_next != EHCI_LIST_END(ehci))
                                        *hw_p = q.itd->hw_next;
                                else
-                                       *hw_p = ehci->dummy->qh_dma;
+                                       *hw_p = cpu_to_hc32(ehci,
+                                                       ehci->dummy->qh_dma);
                                type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
                                wmb();
                                modified = itd_complete (ehci, q.itd);
@@ -2294,7 +2482,8 @@ restart:
                                    q.sitd->hw_next != EHCI_LIST_END(ehci))
                                        *hw_p = q.sitd->hw_next;
                                else
-                                       *hw_p = ehci->dummy->qh_dma;
+                                       *hw_p = cpu_to_hc32(ehci,
+                                                       ehci->dummy->qh_dma);
                                type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
                                wmb();
                                modified = sitd_complete (ehci, q.sitd);
index b2de52d3961488f249aeb9d4026efe2d603b72bb..8a734498079bc176938c57a6b132c146e9be00dd 100644 (file)
@@ -55,7 +55,7 @@ const struct hc_driver ehci_sead3_hc_driver = {
         * generic hardware linkage
         */
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index 93e59a13bc1fec919ef81690bbce9f4bdcd3e951..dc899eb2b86183561351d78e8dba1ceffc9cbb18 100644 (file)
@@ -36,7 +36,7 @@ static const struct hc_driver ehci_sh_hc_driver = {
         * generic hardware linkage
         */
        .irq                            = ehci_irq,
-       .flags                          = HCD_USB2 | HCD_MEMORY,
+       .flags                          = HCD_USB2 | HCD_MEMORY | HCD_BH,
 
        /*
         * basic lifecycle operations
index 14ced00ba220abded902fe7832d598fa37eeffb3..f6459dfb6f54fd1a08c2780dd804a906ccca539b 100644 (file)
@@ -97,8 +97,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 {
        struct ehci_hcd         *ehci;
        unsigned                uframe_periodic_max;
-       unsigned                frame, uframe;
-       unsigned short          allocated_max;
+       unsigned                uframe;
        unsigned long           flags;
        ssize_t                 ret;
 
@@ -122,16 +121,14 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 
        /*
         * for request to decrease max periodic bandwidth, we have to check
-        * every microframe in the schedule to see whether the decrease is
-        * possible.
+        * to see whether the decrease is possible.
         */
        if (uframe_periodic_max < ehci->uframe_periodic_max) {
-               allocated_max = 0;
+               u8              allocated_max = 0;
 
-               for (frame = 0; frame < ehci->periodic_size; ++frame)
-                       for (uframe = 0; uframe < 7; ++uframe)
-                               allocated_max = max(allocated_max,
-                                                   periodic_usecs (ehci, frame, uframe));
+               for (uframe = 0; uframe < EHCI_BANDWIDTH_SIZE; ++uframe)
+                       allocated_max = max(allocated_max,
+                                       ehci->bandwidth[uframe]);
 
                if (allocated_max > uframe_periodic_max) {
                        ehci_info(ehci,
index 78fa76da332435a83cc3c55226d33cbeb2e78afe..e6d8e26e48cc935f1d9c71bd29aa344b4e54dd03 100644 (file)
@@ -388,7 +388,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 
        err = clk_prepare_enable(tegra->clk);
        if (err)
-               goto cleanup_clk_get;
+               goto cleanup_hcd_create;
 
        tegra_periph_reset_assert(tegra->clk);
        udelay(1);
@@ -465,8 +465,6 @@ cleanup_phy:
        usb_phy_shutdown(hcd->phy);
 cleanup_clk_en:
        clk_disable_unprepare(tegra->clk);
-cleanup_clk_get:
-       clk_put(tegra->clk);
 cleanup_hcd_create:
        usb_put_hcd(hcd);
        return err;
index cca4be90a864dba009c852f606653fb5fe60d568..67026ffbf9a871c9780a4b0b7f0d6c739c904e73 100644 (file)
@@ -61,7 +61,7 @@ static const struct hc_driver ehci_tilegx_hc_driver = {
         * Generic hardware linkage.
         */
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * Basic lifecycle operations.
index 59e0e24c753febfb76369be8f872cb3731c2f365..cdad8438c02b3171567f5e0084ba46ee480db669 100644 (file)
  *
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ehci.h"
 
 /* enable phy0 and phy1 for w90p910 */
 #define        ENPHY           (0x01<<8)
 #define PHY0_CTR       (0xA4)
 #define PHY1_CTR       (0xA8)
 
+#define DRIVER_DESC "EHCI w90x900 driver"
+
+static const char hcd_name[] = "ehci-w90x900 ";
+
+static struct hc_driver __read_mostly ehci_w90x900_hc_driver;
+
 static int usb_w90x900_probe(const struct hc_driver *driver,
                      struct platform_device *pdev)
 {
@@ -90,8 +105,8 @@ err1:
        return retval;
 }
 
-static
-void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+static void usb_w90x900_remove(struct usb_hcd *hcd,
+                       struct platform_device *pdev)
 {
        usb_remove_hcd(hcd);
        iounmap(hcd->regs);
@@ -99,54 +114,6 @@ void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev)
        usb_put_hcd(hcd);
 }
 
-static const struct hc_driver ehci_w90x900_hc_driver = {
-       .description = hcd_name,
-       .product_desc = "Nuvoton w90x900 EHCI Host Controller",
-       .hcd_priv_size = sizeof(struct ehci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq = ehci_irq,
-       .flags = HCD_USB2|HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset = ehci_setup,
-       .start = ehci_run,
-
-       .stop = ehci_stop,
-       .shutdown = ehci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue = ehci_urb_enqueue,
-       .urb_dequeue = ehci_urb_dequeue,
-       .endpoint_disable = ehci_endpoint_disable,
-       .endpoint_reset = ehci_endpoint_reset,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number = ehci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data = ehci_hub_status_data,
-       .hub_control = ehci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend = ehci_bus_suspend,
-       .bus_resume = ehci_bus_resume,
-#endif
-       .relinquish_port        = ehci_relinquish_port,
-       .port_handed_over       = ehci_port_handed_over,
-
-       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
 static int ehci_w90x900_probe(struct platform_device *pdev)
 {
        if (usb_disabled())
@@ -173,7 +140,25 @@ static struct platform_driver ehci_hcd_w90x900_driver = {
        },
 };
 
+static int __init ehci_w90X900_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+       ehci_init_driver(&ehci_w90x900_hc_driver, NULL);
+       return platform_driver_register(&ehci_hcd_w90x900_driver);
+}
+module_init(ehci_w90X900_init);
+
+static void __exit ehci_w90X900_cleanup(void)
+{
+       platform_driver_unregister(&ehci_hcd_w90x900_driver);
+}
+module_exit(ehci_w90X900_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("w90p910 usb ehci driver!");
-MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:w90p910-ehci");
+MODULE_LICENSE("GPL v2");
index eba962e6ebfbbd8ffdd46a85e0fed5ec9b18b78a..95979f9f4381d8e8e573c7e0fe254d5585d23ab8 100644 (file)
@@ -79,7 +79,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
         * generic hardware linkage
         */
        .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
+       .flags                  = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
        /*
         * basic lifecycle operations
index 291db7d09f220fe24dfa8bf9c21f1528a0d46a59..e8f41c5e771b978ddcd42b49cd1b638fdcc89a57 100644 (file)
@@ -54,6 +54,28 @@ struct ehci_stats {
        unsigned long           unlink;
 };
 
+/*
+ * Scheduling and budgeting information for periodic transfers, for both
+ * high-speed devices and full/low-speed devices lying behind a TT.
+ */
+struct ehci_per_sched {
+       struct usb_device       *udev;          /* access to the TT */
+       struct usb_host_endpoint *ep;
+       struct list_head        ps_list;        /* node on ehci_tt's ps_list */
+       u16                     tt_usecs;       /* time on the FS/LS bus */
+       u16                     cs_mask;        /* C-mask and S-mask bytes */
+       u16                     period;         /* actual period in frames */
+       u16                     phase;          /* actual phase, frame part */
+       u8                      bw_phase;       /* same, for bandwidth
+                                                  reservation */
+       u8                      phase_uf;       /* uframe part of the phase */
+       u8                      usecs, c_usecs; /* times on the HS bus */
+       u8                      bw_uperiod;     /* period in microframes, for
+                                                  bandwidth reservation */
+       u8                      bw_period;      /* same, in frames */
+};
+#define NO_FRAME       29999                   /* frame not assigned yet */
+
 /* ehci_hcd->lock guards shared data against other CPUs:
  *   ehci_hcd: async, unlink, periodic (and shadow), ...
  *   usb_host_endpoint: hcpriv
@@ -230,6 +252,15 @@ struct ehci_hcd {                  /* one per controller */
        struct dentry           *debug_dir;
 #endif
 
+       /* bandwidth usage */
+#define EHCI_BANDWIDTH_SIZE    64
+#define EHCI_BANDWIDTH_FRAMES  (EHCI_BANDWIDTH_SIZE >> 3)
+       u8                      bandwidth[EHCI_BANDWIDTH_SIZE];
+                                               /* us allocated per uframe */
+       u8                      tt_budget[EHCI_BANDWIDTH_SIZE];
+                                               /* us budgeted per uframe */
+       struct list_head        tt_list;
+
        /* platform-specific data -- must come last */
        unsigned long           priv[0] __aligned(sizeof(s64));
 };
@@ -385,6 +416,7 @@ struct ehci_qh {
        struct list_head        intr_node;      /* list of intr QHs */
        struct ehci_qtd         *dummy;
        struct list_head        unlink_node;
+       struct ehci_per_sched   ps;             /* scheduling info */
 
        unsigned                unlink_cycle;
 
@@ -398,16 +430,8 @@ struct ehci_qh {
        u8                      xacterrs;       /* XactErr retry counter */
 #define        QH_XACTERR_MAX          32              /* XactErr retry limit */
 
-       /* periodic schedule info */
-       u8                      usecs;          /* intr bandwidth */
        u8                      gap_uf;         /* uframes split/csplit gap */
-       u8                      c_usecs;        /* ... split completion bw */
-       u16                     tt_usecs;       /* tt downstream bandwidth */
-       unsigned short          period;         /* polling interval */
-       unsigned short          start;          /* where polling starts */
-#define NO_FRAME ((unsigned short)~0)                  /* pick new start */
 
-       struct usb_device       *dev;           /* access to TT */
        unsigned                is_out:1;       /* bulk or intr OUT */
        unsigned                clearing_tt:1;  /* Clear-TT-Buf in progress */
        unsigned                dequeue_during_giveback:1;
@@ -434,6 +458,7 @@ struct ehci_iso_packet {
 struct ehci_iso_sched {
        struct list_head        td_list;
        unsigned                span;
+       unsigned                first_packet;
        struct ehci_iso_packet  packet [0];
 };
 
@@ -449,22 +474,17 @@ struct ehci_iso_stream {
        u8                      highspeed;
        struct list_head        td_list;        /* queued itds/sitds */
        struct list_head        free_list;      /* list of unused itds/sitds */
-       struct usb_device       *udev;
-       struct usb_host_endpoint *ep;
 
        /* output of (re)scheduling */
-       int                     next_uframe;
+       struct ehci_per_sched   ps;             /* scheduling info */
+       unsigned                next_uframe;
        __hc32                  splits;
 
        /* the rest is derived from the endpoint descriptor,
-        * trusting urb->interval == f(epdesc->bInterval) and
         * including the extra info for hw_bufp[0..2]
         */
-       u8                      usecs, c_usecs;
-       u16                     interval;
-       u16                     tt_usecs;
+       u16                     uperiod;        /* period in uframes */
        u16                     maxp;
-       u16                     raw_mask;
        unsigned                bandwidth;
 
        /* This is used to initialize iTD's hw_bufp fields */
@@ -579,6 +599,35 @@ struct ehci_fstn {
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * USB-2.0 Specification Sections 11.14 and 11.18
+ * Scheduling and budgeting split transactions using TTs
+ *
+ * A hub can have a single TT for all its ports, or multiple TTs (one for each
+ * port).  The bandwidth and budgeting information for the full/low-speed bus
+ * below each TT is self-contained and independent of the other TTs or the
+ * high-speed bus.
+ *
+ * "Bandwidth" refers to the number of microseconds on the FS/LS bus allocated
+ * to an interrupt or isochronous endpoint for each frame.  "Budget" refers to
+ * the best-case estimate of the number of full-speed bytes allocated to an
+ * endpoint for each microframe within an allocated frame.
+ *
+ * Removal of an endpoint invalidates a TT's budget.  Instead of trying to
+ * keep an up-to-date record, we recompute the budget when it is needed.
+ */
+
+struct ehci_tt {
+       u16                     bandwidth[EHCI_BANDWIDTH_FRAMES];
+
+       struct list_head        tt_list;        /* List of all ehci_tt's */
+       struct list_head        ps_list;        /* Items using this TT */
+       struct usb_tt           *usb_tt;
+       int                     tt_port;        /* TT port number */
+};
+
+/*-------------------------------------------------------------------------*/
+
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
 #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup)     \
index fce13bcc4a3e69e23eae70d3f49c512101798ed0..55486bd23cf1f7c0917e0a61794a4db3a807e828 100644 (file)
@@ -412,7 +412,7 @@ struct debug_buffer {
                        tmp = 'h'; break; \
                default:                \
                        tmp = '?'; break; \
-               }; tmp; })
+               } tmp; })
 
 static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 {
index 299253c826c7f50db1f3fddca6ebe7e5b86f53e7..e1c6d850a7e1320fa38ffcd518afee2dac46b78b 100644 (file)
@@ -402,7 +402,7 @@ struct debug_buffer {
                case QH_LOW_SPEED:  tmp = 'l'; break; \
                case QH_HIGH_SPEED: tmp = 'h'; break; \
                default: tmp = '?'; break; \
-               }; tmp; })
+               } tmp; })
 
 static inline char token_mark(struct fusbh200_hcd *fusbh200, __hc32 token)
 {
index 5b86ffb88f1cb53205061a08e339c65620293a9f..ada0a52797b183507d724c25bf27f02a0d0e750c 100644 (file)
@@ -199,10 +199,14 @@ static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd)
 {
        struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
        struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
 
-       dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
-               usb_hcd, hwahc);
-       return -ENOSYS;
+       /*
+        * We cannot query the HWA for the WUSB time since that requires sending
+        * a synchronous URB and this function can be called in_interrupt.
+        * Instead, query the USB frame number for our parent and use that.
+        */
+       return usb_get_current_frame_number(wa->usb_dev);
 }
 
 static int hwahc_op_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
@@ -566,14 +570,10 @@ found:
                goto error;
        }
        wa->wa_descr = wa_descr = (struct usb_wa_descriptor *) hdr;
-       /* Make LE fields CPU order */
-       wa_descr->bcdWAVersion = le16_to_cpu(wa_descr->bcdWAVersion);
-       wa_descr->wNumRPipes = le16_to_cpu(wa_descr->wNumRPipes);
-       wa_descr->wRPipeMaxBlock = le16_to_cpu(wa_descr->wRPipeMaxBlock);
-       if (wa_descr->bcdWAVersion > 0x0100)
+       if (le16_to_cpu(wa_descr->bcdWAVersion) > 0x0100)
                dev_warn(dev, "Wire Adapter v%d.%d newer than groked v1.0\n",
-                        wa_descr->bcdWAVersion & 0xff00 >> 8,
-                        wa_descr->bcdWAVersion & 0x00ff);
+                        le16_to_cpu(wa_descr->bcdWAVersion) & 0xff00 >> 8,
+                        le16_to_cpu(wa_descr->bcdWAVersion) & 0x00ff);
        result = 0;
 error:
        return result;
@@ -679,7 +679,8 @@ static void hwahc_security_release(struct hwahc *hwahc)
        /* nothing to do here so far... */
 }
 
-static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface)
+static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface,
+       kernel_ulong_t quirks)
 {
        int result;
        struct device *dev = &iface->dev;
@@ -724,7 +725,7 @@ static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface)
                dev_err(dev, "Can't create WUSB HC structures: %d\n", result);
                goto error_wusbhc_create;
        }
-       result = wa_create(&hwahc->wa, iface);
+       result = wa_create(&hwahc->wa, iface, quirks);
        if (result < 0)
                goto error_wa_create;
        return 0;
@@ -780,7 +781,7 @@ static int hwahc_probe(struct usb_interface *usb_iface,
        wusbhc = usb_hcd_to_wusbhc(usb_hcd);
        hwahc = container_of(wusbhc, struct hwahc, wusbhc);
        hwahc_init(hwahc);
-       result = hwahc_create(hwahc, usb_iface);
+       result = hwahc_create(hwahc, usb_iface, id->driver_info);
        if (result < 0) {
                dev_err(dev, "Cannot initialize internals: %d\n", result);
                goto error_hwahc_create;
@@ -824,6 +825,12 @@ static void hwahc_disconnect(struct usb_interface *usb_iface)
 }
 
 static struct usb_device_id hwahc_id_table[] = {
+       /* Alereon 5310 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01),
+         .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC },
+       /* Alereon 5611 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5611, 0xe0, 0x02, 0x01),
+         .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC },
        /* FIXME: use class labels for this */
        { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), },
        {},
index 6f29abad6815578a6282eb6e6d9cbe3b6469a8d8..935a2dd367a81fb682d820fdf017aa3b7776596f 100644 (file)
@@ -2108,7 +2108,7 @@ static int isp1362_show(struct seq_file *s, void *unused)
                                   default:
                                           s = "?";
                                           break;
-                                  };
+                                  }
                                   s;}), ep->maxpacket) ;
                list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {
                        seq_printf(s, "  urb%p, %d/%d\n", urb,
index caa3764a34075e4735a9aca7d907f8fa693fde83..476b5a5baf251a0781a0843fcead65baab0f83c6 100644 (file)
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)      ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)      \
 
 /* interface, function and usb clocks; sometimes also an AHB clock */
 static struct clk *iclk, *fclk, *uclk, *hclk;
+/* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+                       u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -117,6 +132,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
                        struct platform_device *pdev)
 {
+       struct at91_usbh_data *board;
+       struct ohci_hcd *ohci;
        int retval;
        struct usb_hcd *hcd = NULL;
 
@@ -177,8 +194,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
                }
        }
 
+       board = hcd->self.controller->platform_data;
+       ohci = hcd_to_ohci(hcd);
+       ohci->num_ports = board->ports;
        at91_start_hc(pdev);
-       ohci_hcd_init(hcd_to_ohci(hcd));
 
        retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
        if (retval == 0)
@@ -238,36 +257,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-       struct at91_usbh_data   *board = dev_get_platdata(hcd->self.controller);
-       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
-       int                     ret;
-
-       if ((ret = ohci_init(ohci)) < 0)
-               return ret;
-
-       ohci->num_ports = board->ports;
-       return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
-       int                     ret;
-
-       if ((ret = ohci_run(ohci)) < 0) {
-               dev_err(hcd->self.controller, "can't start %s\n",
-                       hcd->self.bus_name);
-               ohci_stop(hcd);
-               return ret;
-       }
-       return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
        if (!valid_port(port))
@@ -297,8 +286,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
  */
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-       struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
-       int length = ohci_hub_status_data(hcd, buf);
+       struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
+       int length = orig_ohci_hub_status_data(hcd, buf);
        int port;
 
        at91_for_each_port(port) {
@@ -376,7 +365,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                break;
        }
 
-       ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+       ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+                               buf, wLength);
        if (ret)
                goto out;
 
@@ -430,51 +420,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "AT91 OHCI",
-       .hcd_priv_size =        sizeof(struct ohci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  ohci_irq,
-       .flags =                HCD_USB11 | HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset =                ohci_at91_reset,
-       .start =                ohci_at91_start,
-       .stop =                 ohci_stop,
-       .shutdown =             ohci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          ohci_urb_enqueue,
-       .urb_dequeue =          ohci_urb_dequeue,
-       .endpoint_disable =     ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data =      ohci_at91_hub_status_data,
-       .hub_control =          ohci_at91_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend =          ohci_bus_suspend,
-       .bus_resume =           ohci_bus_resume,
-#endif
-       .start_port_reset =     ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
        struct platform_device *pdev = data;
@@ -703,7 +648,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
         * REVISIT: some boards will be able to turn VBUS off...
         */
        if (at91_suspend_entering_slow_clock()) {
-               ohci_usb_reset (ohci);
+               ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+               ohci->hc_control &= OHCI_CTRL_RWC;
+               ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+               ohci->rh_state = OHCI_RH_HALTED;
+
                /* flush the writes */
                (void) ohci_readl (ohci, &ohci->regs->control);
                at91_stop_clock();
@@ -730,8 +679,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
        .probe          = ohci_hcd_at91_drv_probe,
        .remove         = ohci_hcd_at91_drv_remove,
@@ -744,3 +691,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
                .of_match_table = of_match_ptr(at91_ohci_dt_ids),
        },
 };
+
+static int __init ohci_at91_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+       ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+       /*
+        * The Atmel HW has some unusual quirks, which require Atmel-specific
+        * workarounds. We override certain hc_driver functions here to
+        * achieve that. We explicitly do not enhance ohci_driver_overrides to
+        * allow this more easily, since this is an unusual case, and we don't
+        * want to encourage others to override these functions by making it
+        * too easy.
+        */
+
+       orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+       orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+       ohci_at91_hc_driver.hub_status_data     = ohci_at91_hub_status_data;
+       ohci_at91_hc_driver.hub_control         = ohci_at91_hub_control;
+
+       return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+       platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
index 31b81f9eacdc90cff804bcb89d4ecefff9a3a16f..3fca52ec02ac0b2d0859e96699958030938fce06 100644 (file)
@@ -17,7 +17,7 @@
        case PIPE_BULK:         temp = "bulk"; break; \
        case PIPE_INTERRUPT:    temp = "intr"; break; \
        default:                temp = "isoc"; break; \
-       }; temp;})
+       } temp;})
 #define pipestring(pipe) edstring(usb_pipetype(pipe))
 
 /* debug| print the main components of an URB
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
deleted file mode 100644 (file)
index 84a20d5..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- *
- * Bus Glue for ep93xx.
- *
- * Written by Christopher Hoover <ch@hpl.hp.com>
- * Based on fragments of previous driver by Russell King et al.
- *
- * Modified for LH7A404 from ohci-sa1111.c
- *  by Durgesh Pattamatta <pattamattad@sharpsec.com>
- *
- * Modified for pxa27x from ohci-lh7a404.c
- *  by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
- *
- * Modified for ep93xx from ohci-pxa27x.c
- *  by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006
- *  Based on an earlier driver by Ray Lehtiniemi
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/signal.h>
-#include <linux/platform_device.h>
-
-static struct clk *usb_host_clock;
-
-static int ohci_ep93xx_start(struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       int ret;
-
-       if ((ret = ohci_init(ohci)) < 0)
-               return ret;
-
-       if ((ret = ohci_run(ohci)) < 0) {
-               dev_err(hcd->self.controller, "can't start %s\n",
-                       hcd->self.bus_name);
-               ohci_stop(hcd);
-               return ret;
-       }
-
-       return 0;
-}
-
-static struct hc_driver ohci_ep93xx_hc_driver = {
-       .description            = hcd_name,
-       .product_desc           = "EP93xx OHCI",
-       .hcd_priv_size          = sizeof(struct ohci_hcd),
-       .irq                    = ohci_irq,
-       .flags                  = HCD_USB11 | HCD_MEMORY,
-       .start                  = ohci_ep93xx_start,
-       .stop                   = ohci_stop,
-       .shutdown               = ohci_shutdown,
-       .urb_enqueue            = ohci_urb_enqueue,
-       .urb_dequeue            = ohci_urb_dequeue,
-       .endpoint_disable       = ohci_endpoint_disable,
-       .get_frame_number       = ohci_get_frame,
-       .hub_status_data        = ohci_hub_status_data,
-       .hub_control            = ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend            = ohci_bus_suspend,
-       .bus_resume             = ohci_bus_resume,
-#endif
-       .start_port_reset       = ohci_start_port_reset,
-};
-
-static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd;
-       struct resource *res;
-       int irq;
-       int ret;
-
-       if (usb_disabled())
-               return -ENODEV;
-
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0)
-               return irq;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENXIO;
-
-       hcd = usb_create_hcd(&ohci_ep93xx_hc_driver, &pdev->dev, "ep93xx");
-       if (!hcd)
-               return -ENOMEM;
-
-       hcd->rsrc_start = res->start;
-       hcd->rsrc_len = resource_size(res);
-
-       hcd->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(hcd->regs)) {
-               ret = PTR_ERR(hcd->regs);
-               goto err_put_hcd;
-       }
-
-       usb_host_clock = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(usb_host_clock)) {
-               ret = PTR_ERR(usb_host_clock);
-               goto err_put_hcd;
-       }
-
-       clk_enable(usb_host_clock);
-
-       ohci_hcd_init(hcd_to_ohci(hcd));
-
-       ret = usb_add_hcd(hcd, irq, 0);
-       if (ret)
-               goto err_clk_disable;
-
-       return 0;
-
-err_clk_disable:
-       clk_disable(usb_host_clock);
-err_put_hcd:
-       usb_put_hcd(hcd);
-
-       return ret;
-}
-
-static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
-       usb_remove_hcd(hcd);
-       clk_disable(usb_host_clock);
-       usb_put_hcd(hcd);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       struct usb_hcd *hcd = platform_get_drvdata(pdev);
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
-       if (time_before(jiffies, ohci->next_statechange))
-               msleep(5);
-       ohci->next_statechange = jiffies;
-
-       clk_disable(usb_host_clock);
-       return 0;
-}
-
-static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd = platform_get_drvdata(pdev);
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
-       if (time_before(jiffies, ohci->next_statechange))
-               msleep(5);
-       ohci->next_statechange = jiffies;
-
-       clk_enable(usb_host_clock);
-
-       ohci_resume(hcd, false);
-       return 0;
-}
-#endif
-
-
-static struct platform_driver ohci_hcd_ep93xx_driver = {
-       .probe          = ohci_hcd_ep93xx_drv_probe,
-       .remove         = ohci_hcd_ep93xx_drv_remove,
-       .shutdown       = usb_hcd_platform_shutdown,
-#ifdef CONFIG_PM
-       .suspend        = ohci_hcd_ep93xx_drv_suspend,
-       .resume         = ohci_hcd_ep93xx_drv_resume,
-#endif
-       .driver         = {
-               .name   = "ep93xx-ohci",
-               .owner  = THIS_MODULE,
-       },
-};
-
-MODULE_ALIAS("platform:ep93xx-ohci");
index dc6ee9adacf58679305df6baa851167e34e61ed4..a87baedc0aa79555bcb60ed72a27036fc757566f 100644 (file)
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-       struct device *dev;
-       struct usb_hcd *hcd;
        struct clk *clk;
        struct usb_phy *phy;
        struct usb_otg *otg;
-       struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-       struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
        if (exynos_ohci->phy)
                usb_phy_init(exynos_ohci->phy);
-       else if (exynos_ohci->pdata && exynos_ohci->pdata->phy_init)
-               exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-       struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
        if (exynos_ohci->phy)
                usb_phy_shutdown(exynos_ohci->phy);
-       else if (exynos_ohci->pdata && exynos_ohci->pdata->phy_exit)
-               exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
-}
-
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-       return ohci_init(hcd_to_ohci(hcd));
 }
 
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       int ret;
-
-       ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-       ret = ohci_run(ohci);
-       if (ret < 0) {
-               dev_err(hcd->self.controller, "can't start %s\n",
-                       hcd->self.bus_name);
-               ohci_stop(hcd);
-               return ret;
-       }
-
-       return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-       .description            = hcd_name,
-       .product_desc           = "EXYNOS OHCI Host Controller",
-       .hcd_priv_size          = sizeof(struct ohci_hcd),
-
-       .irq                    = ohci_irq,
-       .flags                  = HCD_MEMORY|HCD_USB11,
-
-       .reset                  = ohci_exynos_reset,
-       .start                  = ohci_exynos_start,
-       .stop                   = ohci_stop,
-       .shutdown               = ohci_shutdown,
-
-       .get_frame_number       = ohci_get_frame,
-
-       .urb_enqueue            = ohci_urb_enqueue,
-       .urb_dequeue            = ohci_urb_dequeue,
-       .endpoint_disable       = ohci_endpoint_disable,
-
-       .hub_status_data        = ohci_hub_status_data,
-       .hub_control            = ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend            = ohci_bus_suspend,
-       .bus_resume             = ohci_bus_resume,
-#endif
-       .start_port_reset       = ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
-       struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev);
        struct exynos_ohci_hcd *exynos_ohci;
        struct usb_hcd *hcd;
-       struct ohci_hcd *ohci;
        struct resource *res;
        struct usb_phy *phy;
        int irq;
@@ -119,10 +76,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
        if (!pdev->dev.coherent_dma_mask)
                pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-       exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-                                       GFP_KERNEL);
-       if (!exynos_ohci)
+       hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+                               &pdev->dev, dev_name(&pdev->dev));
+       if (!hcd) {
+               dev_err(&pdev->dev, "Unable to create HCD\n");
                return -ENOMEM;
+       }
+
+       exynos_ohci = to_exynos_ohci(hcd);
 
        if (of_device_is_compatible(pdev->dev.of_node,
                                        "samsung,exynos5440-ohci"))
@@ -130,30 +91,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 
        phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
        if (IS_ERR(phy)) {
-               /* Fallback to pdata */
-               if (!pdata) {
-                       dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
-                       return -EPROBE_DEFER;
-               } else {
-                       exynos_ohci->pdata = pdata;
-               }
+               usb_put_hcd(hcd);
+               dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
+               return -EPROBE_DEFER;
        } else {
                exynos_ohci->phy = phy;
                exynos_ohci->otg = phy->otg;
        }
 
 skip_phy:
-
-       exynos_ohci->dev = &pdev->dev;
-
-       hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-                                       dev_name(&pdev->dev));
-       if (!hcd) {
-               dev_err(&pdev->dev, "Unable to create HCD\n");
-               return -ENOMEM;
-       }
-
-       exynos_ohci->hcd = hcd;
        exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
        if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +136,21 @@ skip_phy:
        }
 
        if (exynos_ohci->otg)
-               exynos_ohci->otg->set_host(exynos_ohci->otg,
-                                       &exynos_ohci->hcd->self);
+               exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-       exynos_ohci_phy_enable(exynos_ohci);
+       platform_set_drvdata(pdev, hcd);
 
-       ohci = hcd_to_ohci(hcd);
-       ohci_hcd_init(ohci);
+       exynos_ohci_phy_enable(pdev);
 
        err = usb_add_hcd(hcd, irq, IRQF_SHARED);
        if (err) {
                dev_err(&pdev->dev, "Failed to add USB HCD\n");
                goto fail_add_hcd;
        }
-
-       platform_set_drvdata(pdev, exynos_ohci);
-
        return 0;
 
 fail_add_hcd:
-       exynos_ohci_phy_disable(exynos_ohci);
+       exynos_ohci_phy_disable(pdev);
 fail_io:
        clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +160,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-       struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-       struct usb_hcd *hcd = exynos_ohci->hcd;
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
        usb_remove_hcd(hcd);
 
        if (exynos_ohci->otg)
-               exynos_ohci->otg->set_host(exynos_ohci->otg,
-                                       &exynos_ohci->hcd->self);
+               exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-       exynos_ohci_phy_disable(exynos_ohci);
+       exynos_ohci_phy_disable(pdev);
 
        clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +179,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-       struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-       struct usb_hcd *hcd = exynos_ohci->hcd;
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
        if (hcd->driver->shutdown)
                hcd->driver->shutdown(hcd);
@@ -249,9 +188,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-       struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-       struct usb_hcd *hcd = exynos_ohci->hcd;
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
        struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       struct platform_device *pdev = to_platform_device(dev);
        unsigned long flags;
        int rc = 0;
 
@@ -271,10 +211,9 @@ static int exynos_ohci_suspend(struct device *dev)
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
        if (exynos_ohci->otg)
-               exynos_ohci->otg->set_host(exynos_ohci->otg,
-                                       &exynos_ohci->hcd->self);
+               exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-       exynos_ohci_phy_disable(exynos_ohci);
+       exynos_ohci_phy_disable(pdev);
 
        clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +225,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-       struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-       struct usb_hcd *hcd = exynos_ohci->hcd;
+       struct usb_hcd *hcd                     = dev_get_drvdata(dev);
+       struct exynos_ohci_hcd *exynos_ohci     = to_exynos_ohci(hcd);
+       struct platform_device *pdev            = to_platform_device(dev);
 
        clk_prepare_enable(exynos_ohci->clk);
 
        if (exynos_ohci->otg)
-               exynos_ohci->otg->set_host(exynos_ohci->otg,
-                                       &exynos_ohci->hcd->self);
+               exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-       exynos_ohci_phy_enable(exynos_ohci);
+       exynos_ohci_phy_enable(pdev);
 
        ohci_resume(hcd, false);
 
@@ -306,6 +245,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume     NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+       .extra_priv_size =      sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
        .suspend        = exynos_ohci_suspend,
        .resume         = exynos_ohci_resume,
@@ -331,6 +274,23 @@ static struct platform_driver exynos_ohci_driver = {
                .of_match_table = of_match_ptr(exynos_ohci_match),
        }
 };
+static int __init ohci_exynos_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+       ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+       return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+       platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
index 604cad1bcf9cd984666aaf0b2b797b48ee6e3382..8ada13f8dde2c7350977cf343987fbb14c2f303b 100644 (file)
@@ -1161,10 +1161,12 @@ void ohci_init_driver(struct hc_driver *drv,
        /* Copy the generic table to drv and then apply the overrides */
        *drv = ohci_hc_driver;
 
-       drv->product_desc = over->product_desc;
-       drv->hcd_priv_size += over->extra_priv_size;
-       if (over->reset)
-               drv->reset = over->reset;
+       if (over) {
+               drv->product_desc = over->product_desc;
+               drv->hcd_priv_size += over->extra_priv_size;
+               if (over->reset)
+                       drv->reset = over->reset;
+       }
 }
 EXPORT_SYMBOL_GPL(ohci_init_driver);
 
@@ -1179,46 +1181,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER          ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER        ohci_hcd_s3c2410_driver
-#endif
-
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER exynos_ohci_driver
-#endif
-
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER  ohci_hcd_omap_driver
-#endif
-
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER  ohci_hcd_omap3_driver
-#endif
-
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#include "ohci-pxa27x.c"
-#define PLATFORM_DRIVER                ohci_hcd_pxa27x_driver
-#endif
-
-#ifdef CONFIG_ARCH_EP93XX
-#include "ohci-ep93xx.c"
-#define EP93XX_PLATFORM_DRIVER ohci_hcd_ep93xx_driver
-#endif
-
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER   ohci_hcd_at91_driver
-#endif
-
-#ifdef CONFIG_ARCH_LPC32XX
-#include "ohci-nxp.c"
-#define NXP_PLATFORM_DRIVER    usb_hcd_nxp_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER        ohci_hcd_da8xx_driver
@@ -1229,11 +1191,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER     ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER  spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_driver
@@ -1296,18 +1253,6 @@ static int __init ohci_hcd_mod_init(void)
                goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-       retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_omap1_platform;
-#endif
-
-#ifdef OMAP3_PLATFORM_DRIVER
-       retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
        retval = platform_driver_register(&OF_PLATFORM_DRIVER);
        if (retval < 0)
@@ -1332,79 +1277,19 @@ static int __init ohci_hcd_mod_init(void)
                goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-       retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_s3c2410;
-#endif
-
-#ifdef EXYNOS_PLATFORM_DRIVER
-       retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_exynos;
-#endif
-
-#ifdef EP93XX_PLATFORM_DRIVER
-       retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_ep93xx;
-#endif
-
-#ifdef AT91_PLATFORM_DRIVER
-       retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_at91;
-#endif
-
-#ifdef NXP_PLATFORM_DRIVER
-       retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_nxp;
-#endif
-
 #ifdef DAVINCI_PLATFORM_DRIVER
        retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER);
        if (retval < 0)
                goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-       retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto error_spear;
-#endif
-
        return retval;
 
        /* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-       platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
        platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
 #endif
-#ifdef NXP_PLATFORM_DRIVER
-       platform_driver_unregister(&NXP_PLATFORM_DRIVER);
- error_nxp:
-#endif
-#ifdef AT91_PLATFORM_DRIVER
-       platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
-#ifdef EP93XX_PLATFORM_DRIVER
-       platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
- error_ep93xx:
-#endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-       platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
-#ifdef S3C2410_PLATFORM_DRIVER
-       platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
        platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1421,14 +1306,6 @@ static int __init ohci_hcd_mod_init(void)
        platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-       platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
-#ifdef OMAP1_PLATFORM_DRIVER
-       platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
        platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1450,27 +1327,9 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-       platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
        platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
-#ifdef NXP_PLATFORM_DRIVER
-       platform_driver_unregister(&NXP_PLATFORM_DRIVER);
-#endif
-#ifdef AT91_PLATFORM_DRIVER
-       platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
-#ifdef EP93XX_PLATFORM_DRIVER
-       platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
-#endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-       platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
-#ifdef S3C2410_PLATFORM_DRIVER
-       platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
        platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
@@ -1483,12 +1342,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
        platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-       platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
-#ifdef OMAP1_PLATFORM_DRIVER
-       platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
        platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
index 2347ab83f046f7c7ce561aaec5562f47399efd59..61705a760e7db5d68fed2df19f94b3bdef96697e 100644 (file)
@@ -212,10 +212,11 @@ __acquires(ohci->lock)
        /* Sometimes PCI D3 suspend trashes frame timings ... */
        periodic_reinit (ohci);
 
-       /* the following code is executed with ohci->lock held and
-        * irqs disabled if and only if autostopped is true
+       /*
+        * The following code is executed with ohci->lock held and
+        * irqs disabled if and only if autostopped is true.  This
+        * will cause sparse to warn about a "context imbalance".
         */
-
 skip_resume:
        /* interrupts might have been disabled */
        ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
@@ -531,7 +532,7 @@ ohci_hub_descriptor (
            temp |= 0x0010;
        else if (rh & RH_A_OCPM)        /* per-port overcurrent reporting? */
            temp |= 0x0008;
-       desc->wHubCharacteristics = (__force __u16)cpu_to_hc16(ohci, temp);
+       desc->wHubCharacteristics = cpu_to_le16(temp);
 
        /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */
        rh = roothub_b (ohci);
index 7d7d507d54e83ef89cdd0695d694f7e3bb4a5e7d..9ab7e24ba65d9f999623a0c65f01021e5bc0d36b 100644 (file)
  * or implied.
  */
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/usb/isp1301.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #define start_int_umask(irq)
 #endif
 
+#define DRIVER_DESC "OHCI NXP driver"
+
+static const char hcd_name[] = "ohci-nxp";
+static struct hc_driver __read_mostly ohci_nxp_hc_driver;
+
 static struct i2c_client *isp1301_i2c_client;
 
 extern int usb_disabled(void);
@@ -132,14 +146,14 @@ static inline void isp1301_vbus_off(void)
                OTG1_VBUS_DRV);
 }
 
-static void nxp_start_hc(void)
+static void ohci_nxp_start_hc(void)
 {
        unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
        __raw_writel(tmp, USB_OTG_STAT_CONTROL);
        isp1301_vbus_on();
 }
 
-static void nxp_stop_hc(void)
+static void ohci_nxp_stop_hc(void)
 {
        unsigned long tmp;
        isp1301_vbus_off();
@@ -147,68 +161,9 @@ static void nxp_stop_hc(void)
        __raw_writel(tmp, USB_OTG_STAT_CONTROL);
 }
 
-static int ohci_nxp_start(struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       int ret;
-
-       if ((ret = ohci_init(ohci)) < 0)
-               return ret;
-
-       if ((ret = ohci_run(ohci)) < 0) {
-               dev_err(hcd->self.controller, "can't start\n");
-               ohci_stop(hcd);
-               return ret;
-       }
-       return 0;
-}
-
-static const struct hc_driver ohci_nxp_hc_driver = {
-       .description = hcd_name,
-       .product_desc =         "nxp OHCI",
-
-       /*
-        * generic hardware linkage
-        */
-       .irq = ohci_irq,
-       .flags = HCD_USB11 | HCD_MEMORY,
-
-       .hcd_priv_size =        sizeof(struct ohci_hcd),
-       /*
-        * basic lifecycle operations
-        */
-       .start = ohci_nxp_start,
-       .stop = ohci_stop,
-       .shutdown = ohci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue = ohci_urb_enqueue,
-       .urb_dequeue = ohci_urb_dequeue,
-       .endpoint_disable = ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number = ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data = ohci_hub_status_data,
-       .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend = ohci_bus_suspend,
-       .bus_resume = ohci_bus_resume,
-#endif
-       .start_port_reset = ohci_start_port_reset,
-};
-
-static int usb_hcd_nxp_probe(struct platform_device *pdev)
+static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = 0;
-       struct ohci_hcd *ohci;
        const struct hc_driver *driver = &ohci_nxp_hc_driver;
        struct resource *res;
        int ret = 0, irq;
@@ -313,17 +268,15 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
                goto fail_resource;
        }
 
-       nxp_start_hc();
+       ohci_nxp_start_hc();
        platform_set_drvdata(pdev, hcd);
-       ohci = hcd_to_ohci(hcd);
-       ohci_hcd_init(ohci);
 
        dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
        ret = usb_add_hcd(hcd, irq, 0);
        if (ret == 0)
                return ret;
 
-       nxp_stop_hc();
+       ohci_nxp_stop_hc();
 fail_resource:
        usb_put_hcd(hcd);
 fail_hcd:
@@ -345,12 +298,12 @@ fail_disable:
        return ret;
 }
 
-static int usb_hcd_nxp_remove(struct platform_device *pdev)
+static int ohci_hcd_nxp_remove(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
        usb_remove_hcd(hcd);
-       nxp_stop_hc();
+       ohci_nxp_stop_hc();
        usb_put_hcd(hcd);
        clk_disable(usb_pll_clk);
        clk_put(usb_pll_clk);
@@ -366,20 +319,40 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)
 MODULE_ALIAS("platform:usb-ohci");
 
 #ifdef CONFIG_OF
-static const struct of_device_id usb_hcd_nxp_match[] = {
+static const struct of_device_id ohci_hcd_nxp_match[] = {
        { .compatible = "nxp,ohci-nxp" },
        {},
 };
-MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match);
+MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);
 #endif
 
-static struct platform_driver usb_hcd_nxp_driver = {
+static struct platform_driver ohci_hcd_nxp_driver = {
        .driver = {
                .name = "usb-ohci",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(usb_hcd_nxp_match),
+               .of_match_table = of_match_ptr(ohci_hcd_nxp_match),
        },
-       .probe = usb_hcd_nxp_probe,
-       .remove = usb_hcd_nxp_remove,
+       .probe = ohci_hcd_nxp_probe,
+       .remove = ohci_hcd_nxp_remove,
 };
 
+static int __init ohci_nxp_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+       ohci_init_driver(&ohci_nxp_hc_driver, NULL);
+       return platform_driver_register(&ohci_hcd_nxp_driver);
+}
+module_init(ohci_nxp_init);
+
+static void __exit ohci_nxp_cleanup(void)
+{
+       platform_driver_unregister(&ohci_hcd_nxp_driver);
+}
+module_exit(ohci_nxp_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
index 31d3a12eb4867e56872f71cbea9f61ef1431dba5..f253214741ba014c35e28fa498894f8c5cac7847 100644 (file)
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
 #define OMAP1510_LB_MMU_RAM_H  0xfffec234
 #define OMAP1510_LB_MMU_RAM_L  0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
        struct ohci_hcd         *ohci = hcd_to_ohci(hcd);
        struct omap_usb_config  *config = dev_get_platdata(hcd->self.controller);
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
        dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
        if (config->otg) {
-               ohci_to_hcd(ohci)->self.otg_port = config->otg;
+               hcd->self.otg_port = config->otg;
                /* default/minimum OTG power budget:  8 mA */
-               ohci_to_hcd(ohci)->power_budget = 8;
+               hcd->power_budget = 8;
        }
 
        /* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
                omap_1510_local_bus_init();
        }
 
-       if ((ret = ohci_init(ohci)) < 0)
+       ret = ohci_setup(hcd);
+       if (ret < 0)
                return ret;
 
+       if (config->otg || config->rwc) {
+               ohci->hc_control = OHCI_CTRL_RWC;
+               writel(OHCI_CTRL_RWC, &ohci->regs->control);
+       }
+
        /* board-specific power switching and overcurrent support */
        if (machine_is_omap_osk() || machine_is_omap_innovator()) {
                u32     rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
        return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-       dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-       ohci_stop(hcd);
-       omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
        int retval, irq;
        struct usb_hcd *hcd = 0;
-       struct ohci_hcd *ohci;
 
        if (pdev->num_resources != 2) {
                printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
                goto err2;
        }
 
-       ohci = hcd_to_ohci(hcd);
-       ohci_hcd_init(ohci);
-
-       host_initialized = 0;
-       host_enabled = 1;
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
        if (retval)
                goto err3;
 
-       host_initialized = 1;
-
-       if (!host_enabled)
-               omap_ohci_clock_power(0);
-
        return 0;
 err3:
        iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+       dev_dbg(hcd->self.controller, "stopping USB Controller\n");
        usb_remove_hcd(hcd);
+       omap_ohci_clock_power(0);
        if (!IS_ERR_OR_NULL(hcd->phy)) {
                (void) otg_set_host(hcd->phy->otg, 0);
                usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-       struct omap_usb_config *config;
-       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ret;
-
-       if (!host_enabled)
-               return 0;
-       config = dev_get_platdata(hcd->self.controller);
-       if (config->otg || config->rwc) {
-               ohci->hc_control = OHCI_CTRL_RWC;
-               writel(OHCI_CTRL_RWC, &ohci->regs->control);
-       }
-
-       if ((ret = ohci_run (ohci)) < 0) {
-               dev_err(hcd->self.controller, "can't start\n");
-               ohci_stop (hcd);
-               return ret;
-       }
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "OMAP OHCI",
-       .hcd_priv_size =        sizeof(struct ohci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  ohci_irq,
-       .flags =                HCD_USB11 | HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset =                ohci_omap_init,
-       .start =                ohci_omap_start,
-       .stop =                 ohci_omap_stop,
-       .shutdown =             ohci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          ohci_urb_enqueue,
-       .urb_dequeue =          ohci_urb_dequeue,
-       .endpoint_disable =     ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data =      ohci_hub_status_data,
-       .hub_control =          ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend =          ohci_bus_suspend,
-       .bus_resume =           ohci_bus_resume,
-#endif
-       .start_port_reset =     ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
        return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -506,16 +431,23 @@ static int ohci_hcd_omap_drv_remove(struct platform_device *dev)
 
 #ifdef CONFIG_PM
 
-static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)
+static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message)
 {
-       struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev));
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       bool do_wakeup = device_may_wakeup(&pdev->dev);
+       int ret;
 
        if (time_before(jiffies, ohci->next_statechange))
                msleep(5);
        ohci->next_statechange = jiffies;
 
+       ret = ohci_suspend(hcd, do_wakeup);
+       if (ret)
+               return ret;
+
        omap_ohci_clock_power(0);
-       return 0;
+       return ret;
 }
 
 static int ohci_omap_resume(struct platform_device *dev)
@@ -553,4 +485,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
        },
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+       .product_desc   = "OMAP OHCI",
+       .reset          = ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+       ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+       return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+       platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
index a09af26f69ed4efdde274e028eb88110231cfc18..408d06a68571f423da0c4d41d0f0ad920bea44fe 100644 (file)
  *     - add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-       dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-       return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       int ret;
-
-       /*
-        * RemoteWakeupConnected has to be set explicitly before
-        * calling ohci_run. The reset value of RWC is 0.
-        */
-       ohci->hc_control = OHCI_CTRL_RWC;
-       writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-       ret = ohci_run(ohci);
-
-       if (ret < 0) {
-               dev_err(hcd->self.controller, "can't start\n");
-               ohci_stop(hcd);
-       }
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-       return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "OMAP3 OHCI Host Controller",
-       .hcd_priv_size =        sizeof(struct ohci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  ohci_irq,
-       .flags =                HCD_USB11 | HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset =                ohci_omap3_init,
-       .start =                ohci_omap3_start,
-       .stop =                 ohci_stop,
-       .shutdown =             ohci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          ohci_urb_enqueue,
-       .urb_dequeue =          ohci_urb_dequeue,
-       .endpoint_disable =     ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data =      ohci_hub_status_data,
-       .hub_control =          ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend =          ohci_bus_suspend,
-       .bus_resume =           ohci_bus_resume,
-#endif
-       .start_port_reset =     ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
        struct device           *dev = &pdev->dev;
+       struct ohci_hcd         *ohci;
        struct usb_hcd          *hcd = NULL;
        void __iomem            *regs = NULL;
        struct resource         *res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
        pm_runtime_enable(dev);
        pm_runtime_get_sync(dev);
 
-       ohci_hcd_init(hcd_to_ohci(hcd));
+       ohci = hcd_to_ohci(hcd);
+       /*
+        * RemoteWakeupConnected has to be set explicitly before
+        * calling ohci_run. The reset value of RWC is 0.
+        */
+       ohci->hc_control = OHCI_CTRL_RWC;
 
        ret = usb_add_hcd(hcd, irq, 0);
        if (ret) {
@@ -248,5 +186,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
        },
 };
 
+static int __init ohci_omap3_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+       ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+       return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+       platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
index ec337c2bd5e0b5294efa467691ef1807742aa1bc..90879e9ccbec302e8c5272d45e4847009b3730c4 100644 (file)
@@ -150,28 +150,16 @@ static int ohci_quirk_nec(struct usb_hcd *hcd)
 static int ohci_quirk_amd700(struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       struct pci_dev *amd_smbus_dev;
-       u8 rev;
 
        if (usb_amd_find_chipset_info())
                ohci->flags |= OHCI_QUIRK_AMD_PLL;
 
-       amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI,
-                       PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
-       if (!amd_smbus_dev)
-               return 0;
-
-       rev = amd_smbus_dev->revision;
-
        /* SB800 needs pre-fetch fix */
-       if ((rev >= 0x40) && (rev <= 0x4f)) {
+       if (usb_amd_prefetch_quirk()) {
                ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;
                ohci_dbg(ohci, "enabled AMD prefetch quirk\n");
        }
 
-       pci_dev_put(amd_smbus_dev);
-       amd_smbus_dev = NULL;
-
        return 0;
 }
 
@@ -323,3 +311,4 @@ module_exit(ohci_pci_cleanup);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
+MODULE_SOFTDEP("pre: ehci_pci");
index a4c6410f0ed494bfb6fb492849d1ed5f3b4fb1d2..f351ff5b171f752f121119cdc1e51d5846d4d6f0 100644 (file)
@@ -139,14 +139,21 @@ static int ohci_platform_remove(struct platform_device *dev)
 
 static int ohci_platform_suspend(struct device *dev)
 {
-       struct usb_ohci_pdata *pdata = dev_get_platdata(dev);
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       struct usb_ohci_pdata *pdata = dev->platform_data;
        struct platform_device *pdev =
                container_of(dev, struct platform_device, dev);
+       bool do_wakeup = device_may_wakeup(dev);
+       int ret;
+
+       ret = ohci_suspend(hcd, do_wakeup);
+       if (ret)
+               return ret;
 
        if (pdata->power_suspend)
                pdata->power_suspend(pdev);
 
-       return 0;
+       return ret;
 }
 
 static int ohci_platform_resume(struct device *dev)
index 93371a235e821fac080068f7522bc5a80576119c..deea5d1d6394f3015de6a8a728061a0d3cfedc5a 100644 (file)
  * This file is licenced under the GPL.
  */
 
-#include <linux/device.h>
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/usb-pxa3xx-ulpi.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI PXA27x/PXA3x driver"
 
 /*
  * UHC: USB Host Controller (OHCI-like) register definitions
 
 #define PXA_UHC_MAX_PORTNUM    3
 
-struct pxa27x_ohci {
-       /* must be 1st member here for hcd_to_ohci() to work */
-       struct ohci_hcd ohci;
+static const char hcd_name[] = "ohci-pxa27x";
+
+static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
 
-       struct device   *dev;
+struct pxa27x_ohci {
        struct clk      *clk;
        void __iomem    *mmio_base;
 };
 
-#define to_pxa27x_ohci(hcd)    (struct pxa27x_ohci *)hcd_to_ohci(hcd)
+#define to_pxa27x_ohci(hcd)    (struct pxa27x_ohci *)(hcd_to_ohci(hcd)->priv)
 
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
@@ -122,10 +133,10 @@ struct pxa27x_ohci {
   PMM_PERPORT_MODE -- PMM per port switching mode
       Ports are powered individually.
  */
-static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
+static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *pxa_ohci, int mode)
 {
-       uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
-       uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB);
+       uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
+       uint32_t uhcrhdb = __raw_readl(pxa_ohci->mmio_base + UHCRHDB);
 
        switch (mode) {
        case PMM_NPS_MODE:
@@ -149,20 +160,18 @@ static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
                uhcrhda |= RH_A_NPS;
        }
 
-       __raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
-       __raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB);
+       __raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
+       __raw_writel(uhcrhdb, pxa_ohci->mmio_base + UHCRHDB);
        return 0;
 }
 
-extern int usb_disabled(void);
-
 /*-------------------------------------------------------------------------*/
 
-static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
+static inline void pxa27x_setup_hc(struct pxa27x_ohci *pxa_ohci,
                                   struct pxaohci_platform_data *inf)
 {
-       uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
-       uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+       uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
+       uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
 
        if (inf->flags & ENABLE_PORT1)
                uhchr &= ~UHCHR_SSEP1;
@@ -194,17 +203,17 @@ static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
                uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
        }
 
-       __raw_writel(uhchr, ohci->mmio_base + UHCHR);
-       __raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+       __raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+       __raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
 }
 
-static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci)
+static inline void pxa27x_reset_hc(struct pxa27x_ohci *pxa_ohci)
 {
-       uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+       uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
 
-       __raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR);
+       __raw_writel(uhchr | UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
        udelay(11);
-       __raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR);
+       __raw_writel(uhchr & ~UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
 }
 
 #ifdef CONFIG_PXA27x
@@ -213,25 +222,26 @@ extern void pxa27x_clear_otgph(void);
 #define pxa27x_clear_otgph()   do {} while (0)
 #endif
 
-static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
+static int pxa27x_start_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
 {
        int retval = 0;
        struct pxaohci_platform_data *inf;
        uint32_t uhchr;
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
 
        inf = dev_get_platdata(dev);
 
-       clk_prepare_enable(ohci->clk);
+       clk_prepare_enable(pxa_ohci->clk);
 
-       pxa27x_reset_hc(ohci);
+       pxa27x_reset_hc(pxa_ohci);
 
-       uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
-       __raw_writel(uhchr, ohci->mmio_base + UHCHR);
+       uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
+       __raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
 
-       while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
+       while (__raw_readl(pxa_ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
                cpu_relax();
 
-       pxa27x_setup_hc(ohci, inf);
+       pxa27x_setup_hc(pxa_ohci, inf);
 
        if (inf->init)
                retval = inf->init(dev);
@@ -240,38 +250,39 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
                return retval;
 
        if (cpu_is_pxa3xx())
-               pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
+               pxa3xx_u2d_start_hc(&hcd->self);
 
-       uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
-       __raw_writel(uhchr, ohci->mmio_base + UHCHR);
-       __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
+       uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
+       __raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+       __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, pxa_ohci->mmio_base + UHCHIE);
 
        /* Clear any OTG Pin Hold */
        pxa27x_clear_otgph();
        return 0;
 }
 
-static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
+static void pxa27x_stop_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
 {
        struct pxaohci_platform_data *inf;
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
        uint32_t uhccoms;
 
        inf = dev_get_platdata(dev);
 
        if (cpu_is_pxa3xx())
-               pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
+               pxa3xx_u2d_stop_hc(&hcd->self);
 
        if (inf->exit)
                inf->exit(dev);
 
-       pxa27x_reset_hc(ohci);
+       pxa27x_reset_hc(pxa_ohci);
 
        /* Host Controller Reset */
-       uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
-       __raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
+       uhccoms = __raw_readl(pxa_ohci->mmio_base + UHCCOMS) | 0x01;
+       __raw_writel(uhccoms, pxa_ohci->mmio_base + UHCCOMS);
        udelay(10);
 
-       clk_disable_unprepare(ohci->clk);
+       clk_disable_unprepare(pxa_ohci->clk);
 }
 
 #ifdef CONFIG_OF
@@ -356,7 +367,8 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
        int retval, irq;
        struct usb_hcd *hcd;
        struct pxaohci_platform_data *inf;
-       struct pxa27x_ohci *ohci;
+       struct pxa27x_ohci *pxa_ohci;
+       struct ohci_hcd *ohci;
        struct resource *r;
        struct clk *usb_clk;
 
@@ -409,29 +421,31 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
        }
 
        /* initialize "struct pxa27x_ohci" */
-       ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
-       ohci->dev = &pdev->dev;
-       ohci->clk = usb_clk;
-       ohci->mmio_base = (void __iomem *)hcd->regs;
+       pxa_ohci = to_pxa27x_ohci(hcd);
+       pxa_ohci->clk = usb_clk;
+       pxa_ohci->mmio_base = (void __iomem *)hcd->regs;
 
-       if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
+       retval = pxa27x_start_hc(pxa_ohci, &pdev->dev);
+       if (retval < 0) {
                pr_debug("pxa27x_start_hc failed");
                goto err3;
        }
 
        /* Select Power Management Mode */
-       pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+       pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
 
        if (inf->power_budget)
                hcd->power_budget = inf->power_budget;
 
-       ohci_hcd_init(hcd_to_ohci(hcd));
+       /* The value of NDP in roothub_a is incorrect on this hardware */
+       ohci = hcd_to_ohci(hcd);
+       ohci->num_ports = 3;
 
        retval = usb_add_hcd(hcd, irq, 0);
        if (retval == 0)
                return retval;
 
-       pxa27x_stop_hc(ohci, &pdev->dev);
+       pxa27x_stop_hc(pxa_ohci, &pdev->dev);
  err3:
        iounmap(hcd->regs);
  err2:
@@ -459,88 +473,18 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
  */
 void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
-       struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+       struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
 
        usb_remove_hcd(hcd);
-       pxa27x_stop_hc(ohci, &pdev->dev);
+       pxa27x_stop_hc(pxa_ohci, &pdev->dev);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       clk_put(pxa_ohci->clk);
        usb_put_hcd(hcd);
-       clk_put(ohci->clk);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pxa27x_start (struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ret;
-
-       ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);
-
-       /* The value of NDP in roothub_a is incorrect on this hardware */
-       ohci->num_ports = 3;
-
-       if ((ret = ohci_init(ohci)) < 0)
-               return ret;
-
-       if ((ret = ohci_run (ohci)) < 0) {
-               dev_err(hcd->self.controller, "can't start %s",
-                       hcd->self.bus_name);
-               ohci_stop (hcd);
-               return ret;
-       }
-
-       return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_pxa27x_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "PXA27x OHCI",
-       .hcd_priv_size =        sizeof(struct pxa27x_ohci),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  ohci_irq,
-       .flags =                HCD_USB11 | HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .start =                ohci_pxa27x_start,
-       .stop =                 ohci_stop,
-       .shutdown =             ohci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          ohci_urb_enqueue,
-       .urb_dequeue =          ohci_urb_dequeue,
-       .endpoint_disable =     ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data =      ohci_hub_status_data,
-       .hub_control =          ohci_hub_control,
-#ifdef  CONFIG_PM
-       .bus_suspend =          ohci_bus_suspend,
-       .bus_resume =           ohci_bus_resume,
-#endif
-       .start_port_reset =     ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
        pr_debug ("In ohci_hcd_pxa27x_drv_probe");
@@ -563,32 +507,42 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
 static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)
 {
        struct usb_hcd *hcd = dev_get_drvdata(dev);
-       struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+       struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       bool do_wakeup = device_may_wakeup(dev);
+       int ret;
+
 
-       if (time_before(jiffies, ohci->ohci.next_statechange))
+       if (time_before(jiffies, ohci->next_statechange))
                msleep(5);
-       ohci->ohci.next_statechange = jiffies;
+       ohci->next_statechange = jiffies;
 
-       pxa27x_stop_hc(ohci, dev);
-       return 0;
+       ret = ohci_suspend(hcd, do_wakeup);
+       if (ret)
+               return ret;
+
+       pxa27x_stop_hc(pxa_ohci, dev);
+       return ret;
 }
 
 static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
 {
        struct usb_hcd *hcd = dev_get_drvdata(dev);
-       struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+       struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
        struct pxaohci_platform_data *inf = dev_get_platdata(dev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
        int status;
 
-       if (time_before(jiffies, ohci->ohci.next_statechange))
+       if (time_before(jiffies, ohci->next_statechange))
                msleep(5);
-       ohci->ohci.next_statechange = jiffies;
+       ohci->next_statechange = jiffies;
 
-       if ((status = pxa27x_start_hc(ohci, dev)) < 0)
+       status = pxa27x_start_hc(pxa_ohci, dev);
+       if (status < 0)
                return status;
 
        /* Select Power Management Mode */
-       pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+       pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
 
        ohci_resume(hcd, false);
        return 0;
@@ -600,9 +554,6 @@ static const struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = {
 };
 #endif
 
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:pxa27x-ohci");
-
 static struct platform_driver ohci_hcd_pxa27x_driver = {
        .probe          = ohci_hcd_pxa27x_drv_probe,
        .remove         = ohci_hcd_pxa27x_drv_remove,
@@ -617,3 +568,27 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {
        },
 };
 
+static const struct ohci_driver_overrides pxa27x_overrides __initconst = {
+       .extra_priv_size =      sizeof(struct pxa27x_ohci),
+};
+
+static int __init ohci_pxa27x_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+       ohci_init_driver(&ohci_pxa27x_hc_driver, &pxa27x_overrides);
+       return platform_driver_register(&ohci_hcd_pxa27x_driver);
+}
+module_init(ohci_pxa27x_init);
+
+static void __exit ohci_pxa27x_cleanup(void)
+{
+       platform_driver_unregister(&ohci_hcd_pxa27x_driver);
+}
+module_exit(ohci_pxa27x_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa27x-ohci");
index 4919afa4125e36eaeed297277da4631cb9cb5c7b..f90101b9cdb98a7b68053281a39e5b4796e56f60 100644 (file)
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3C2410 driver"
+
+static const char hcd_name[] = "ohci-s3c2410";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+                       u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -47,10 +64,10 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)
 
        dev_dbg(&dev->dev, "s3c2410_start_hc:\n");
 
-       clk_enable(usb_clk);
+       clk_prepare_enable(usb_clk);
        mdelay(2);                      /* let the bus clock stabilise */
 
-       clk_enable(clk);
+       clk_prepare_enable(clk);
 
        if (info != NULL) {
                info->hcd       = hcd;
@@ -75,8 +92,8 @@ static void s3c2410_stop_hc(struct platform_device *dev)
                        (info->enable_oc)(info, 0);
        }
 
-       clk_disable(clk);
-       clk_disable(usb_clk);
+       clk_disable_unprepare(clk);
+       clk_disable_unprepare(usb_clk);
 }
 
 /* ohci_s3c2410_hub_status_data
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
        int orig;
        int portno;
 
-       orig  = ohci_hub_status_data(hcd, buf);
+       orig = orig_ohci_hub_status_data(hcd, buf);
 
        if (info == NULL)
                return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
         * process the request straight away and exit */
 
        if (info == NULL) {
-               ret = ohci_hub_control(hcd, typeReq, wValue,
+               ret = orig_ohci_hub_control(hcd, typeReq, wValue,
                                       wIndex, buf, wLength);
                goto out;
        }
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
                break;
        }
 
-       ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+       ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
        if (ret)
                goto out;
 
@@ -374,8 +391,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
        s3c2410_start_hc(dev, hcd);
 
-       ohci_hcd_init(hcd_to_ohci(hcd));
-
        retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
        if (retval != 0)
                goto err_ioremap;
@@ -392,71 +407,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       int ret;
-
-       ret = ohci_init(ohci);
-       if (ret < 0)
-               return ret;
-
-       ret = ohci_run(ohci);
-       if (ret < 0) {
-               dev_err(hcd->self.controller, "can't start %s\n",
-                       hcd->self.bus_name);
-               ohci_stop(hcd);
-               return ret;
-       }
-
-       return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "S3C24XX OHCI",
-       .hcd_priv_size =        sizeof(struct ohci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  ohci_irq,
-       .flags =                HCD_USB11 | HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .start =                ohci_s3c2410_start,
-       .stop =                 ohci_stop,
-       .shutdown =             ohci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          ohci_urb_enqueue,
-       .urb_dequeue =          ohci_urb_dequeue,
-       .endpoint_disable =     ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data =      ohci_s3c2410_hub_status_data,
-       .hub_control =          ohci_s3c2410_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend =          ohci_bus_suspend,
-       .bus_resume =           ohci_bus_resume,
-#endif
-       .start_port_reset =     ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -533,4 +484,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
        },
 };
 
+static int __init ohci_s3c2410_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+       ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+       /*
+        * The Samsung HW has some unusual quirks, which require
+        * Sumsung-specific workarounds. We override certain hc_driver
+        * functions here to achieve that. We explicitly do not enhance
+        * ohci_driver_overrides to allow this more easily, since this
+        * is an unusual case, and we don't want to encourage others to
+        * override these functions by making it too easy.
+        */
+
+       orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+       orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+       ohci_s3c2410_hc_driver.hub_status_data  = ohci_s3c2410_hub_status_data;
+       ohci_s3c2410_hc_driver.hub_control      = ohci_s3c2410_hub_control;
+
+       return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3c2410_init);
+
+static void __exit ohci_s3c2410_cleanup(void)
+{
+       platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3c2410_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
index d479d5ddab8853b9844f29ffa7e15b1ca0beaca7..2a5de5fecd8f5ba3a05a449485dd3f7fae7b39b2 100644 (file)
@@ -216,14 +216,21 @@ static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev)
 static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg)
 {
        struct device *dev = &pdev->dev;
-       struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev));
+       struct usb_hcd  *hcd = platform_get_drvdata(pdev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       bool do_wakeup = device_may_wakeup(dev);
+       int ret;
 
        if (time_before(jiffies, ohci->next_statechange))
                msleep(5);
        ohci->next_statechange = jiffies;
 
+       ret = ohci_suspend(hcd, do_wakeup);
+       if (ret)
+               return ret;
+
        sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0);
-       return 0;
+       return ret;
 }
 
 static int ohci_sm501_resume(struct platform_device *pdev)
index cc9dd9e4f05e69469eeca87233dd0f29bac23992..31ff3fc4e26fd19a66bc26803a9112759a0f2ab7 100644 (file)
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-       struct ohci_hcd ohci;
        struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)     (struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-       clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-       clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       int ret;
-
-       ret = ohci_init(ohci);
-       if (ret < 0)
-               return ret;
-       ohci->regs = hcd->regs;
-
-       ret = ohci_run(ohci);
-       if (ret < 0) {
-               dev_err(hcd->self.controller, "can't start\n");
-               ohci_stop(hcd);
-               return ret;
-       }
-
-       create_debug_files(ohci);
-
-#ifdef DEBUG
-       ohci_dump(ohci, 1);
-#endif
-       return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-       .description            = hcd_name,
-       .product_desc           = "SPEAr OHCI",
-       .hcd_priv_size          = sizeof(struct spear_ohci),
-
-       /* generic hardware linkage */
-       .irq                    = ohci_irq,
-       .flags                  = HCD_USB11 | HCD_MEMORY,
-
-       /* basic lifecycle operations */
-       .start                  = ohci_spear_start,
-       .stop                   = ohci_stop,
-       .shutdown               = ohci_shutdown,
-#ifdef CONFIG_PM
-       .bus_suspend            = ohci_bus_suspend,
-       .bus_resume             = ohci_bus_resume,
-#endif
-
-       /* managing i/o requests and associated device resources */
-       .urb_enqueue            = ohci_urb_enqueue,
-       .urb_dequeue            = ohci_urb_dequeue,
-       .endpoint_disable       = ohci_endpoint_disable,
-
-       /* scheduling support */
-       .get_frame_number       = ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-       /* root hub support */
-       .hub_status_data        = ohci_hub_status_data,
-       .hub_control            = ohci_hub_control,
-
-       .start_port_reset       = ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
        const struct hc_driver *driver = &ohci_spear_hc_driver;
+       struct ohci_hcd *ohci;
        struct usb_hcd *hcd = NULL;
        struct clk *usbh_clk;
-       struct spear_ohci *ohci_p;
+       struct spear_ohci *sohci_p;
        struct resource *res;
        int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
                goto err_put_hcd;
        }
 
-       ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-       ohci_p->clk = usbh_clk;
-       spear_start_ohci(ohci_p);
-       ohci_hcd_init(hcd_to_ohci(hcd));
+       sohci_p = to_spear_ohci(hcd);
+       sohci_p->clk = usbh_clk;
+
+       clk_prepare_enable(sohci_p->clk);
+
+       ohci = hcd_to_ohci(hcd);
 
        retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
        if (retval == 0)
                return retval;
 
-       spear_stop_ohci(ohci_p);
+       clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
        usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
-       struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+       struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
        usb_remove_hcd(hcd);
-       if (ohci_p->clk)
-               spear_stop_ohci(ohci_p);
+       if (sohci_p->clk)
+               clk_disable_unprepare(sohci_p->clk);
 
        usb_put_hcd(hcd);
        return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
        struct usb_hcd *hcd = platform_get_drvdata(dev);
        struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+       struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
        if (time_before(jiffies, ohci->next_statechange))
                msleep(5);
        ohci->next_statechange = jiffies;
 
-       spear_stop_ohci(ohci_p);
+       clk_disable_unprepare(sohci_p->clk);
+
        return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(dev);
        struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-       struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+       struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
        if (time_before(jiffies, ohci->next_statechange))
                msleep(5);
        ohci->next_statechange = jiffies;
 
-       spear_start_ohci(ohci_p);
+       clk_prepare_enable(sohci_p->clk);
        ohci_resume(hcd, false);
        return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
        },
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+       .extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+       ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+       return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+       platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
index 08ef2829a7e2b1c06bbd0af51f308884c8ad9a26..dfbdd3aefe98a8079fd6faf3f5713afd74f97fc6 100644 (file)
 #define USB_INTEL_USB3_PSSEN   0xD8
 #define USB_INTEL_USB3PRM      0xDC
 
+/*
+ * amd_chipset_gen values represent AMD different chipset generations
+ */
+enum amd_chipset_gen {
+       NOT_AMD_CHIPSET = 0,
+       AMD_CHIPSET_SB600,
+       AMD_CHIPSET_SB700,
+       AMD_CHIPSET_SB800,
+       AMD_CHIPSET_HUDSON2,
+       AMD_CHIPSET_BOLTON,
+       AMD_CHIPSET_YANGTZE,
+       AMD_CHIPSET_UNKNOWN,
+};
+
+struct amd_chipset_type {
+       enum amd_chipset_gen gen;
+       u8 rev;
+};
+
 static struct amd_chipset_info {
        struct pci_dev  *nb_dev;
        struct pci_dev  *smbus_dev;
        int nb_type;
-       int sb_type;
+       struct amd_chipset_type sb_type;
        int isoc_reqs;
        int probe_count;
        int probe_result;
@@ -91,6 +110,51 @@ static struct amd_chipset_info {
 
 static DEFINE_SPINLOCK(amd_lock);
 
+/*
+ * amd_chipset_sb_type_init - initialize amd chipset southbridge type
+ *
+ * AMD FCH/SB generation and revision is identified by SMBus controller
+ * vendor, device and revision IDs.
+ *
+ * Returns: 1 if it is an AMD chipset, 0 otherwise.
+ */
+static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
+{
+       u8 rev = 0;
+       pinfo->sb_type.gen = AMD_CHIPSET_UNKNOWN;
+
+       pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI,
+                       PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
+       if (pinfo->smbus_dev) {
+               rev = pinfo->smbus_dev->revision;
+               if (rev >= 0x10 && rev <= 0x1f)
+                       pinfo->sb_type.gen = AMD_CHIPSET_SB600;
+               else if (rev >= 0x30 && rev <= 0x3f)
+                       pinfo->sb_type.gen = AMD_CHIPSET_SB700;
+               else if (rev >= 0x40 && rev <= 0x4f)
+                       pinfo->sb_type.gen = AMD_CHIPSET_SB800;
+       } else {
+               pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
+                               PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
+
+               if (!pinfo->smbus_dev) {
+                       pinfo->sb_type.gen = NOT_AMD_CHIPSET;
+                       return 0;
+               }
+
+               rev = pinfo->smbus_dev->revision;
+               if (rev >= 0x11 && rev <= 0x14)
+                       pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2;
+               else if (rev >= 0x15 && rev <= 0x18)
+                       pinfo->sb_type.gen = AMD_CHIPSET_BOLTON;
+               else if (rev >= 0x39 && rev <= 0x3a)
+                       pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE;
+       }
+
+       pinfo->sb_type.rev = rev;
+       return 1;
+}
+
 void sb800_prefetch(struct device *dev, int on)
 {
        u16 misc;
@@ -106,7 +170,6 @@ EXPORT_SYMBOL_GPL(sb800_prefetch);
 
 int usb_amd_find_chipset_info(void)
 {
-       u8 rev = 0;
        unsigned long flags;
        struct amd_chipset_info info;
        int ret;
@@ -122,27 +185,17 @@ int usb_amd_find_chipset_info(void)
        memset(&info, 0, sizeof(info));
        spin_unlock_irqrestore(&amd_lock, flags);
 
-       info.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL);
-       if (info.smbus_dev) {
-               rev = info.smbus_dev->revision;
-               if (rev >= 0x40)
-                       info.sb_type = 1;
-               else if (rev >= 0x30 && rev <= 0x3b)
-                       info.sb_type = 3;
-       } else {
-               info.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
-                                               0x780b, NULL);
-               if (!info.smbus_dev) {
-                       ret = 0;
-                       goto commit;
-               }
-
-               rev = info.smbus_dev->revision;
-               if (rev >= 0x11 && rev <= 0x18)
-                       info.sb_type = 2;
+       if (!amd_chipset_sb_type_init(&info)) {
+               ret = 0;
+               goto commit;
        }
 
-       if (info.sb_type == 0) {
+       /* Below chipset generations needn't enable AMD PLL quirk */
+       if (info.sb_type.gen == AMD_CHIPSET_UNKNOWN ||
+                       info.sb_type.gen == AMD_CHIPSET_SB600 ||
+                       info.sb_type.gen == AMD_CHIPSET_YANGTZE ||
+                       (info.sb_type.gen == AMD_CHIPSET_SB700 &&
+                       info.sb_type.rev > 0x3b)) {
                if (info.smbus_dev) {
                        pci_dev_put(info.smbus_dev);
                        info.smbus_dev = NULL;
@@ -197,6 +250,39 @@ commit:
 }
 EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info);
 
+int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
+{
+       /* Make sure amd chipset type has already been initialized */
+       usb_amd_find_chipset_info();
+       if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE)
+               return 0;
+
+       dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
+       return 1;
+}
+EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
+
+bool usb_amd_hang_symptom_quirk(void)
+{
+       u8 rev;
+
+       usb_amd_find_chipset_info();
+       rev = amd_chipset.sb_type.rev;
+       /* SB600 and old version of SB700 have hang symptom bug */
+       return amd_chipset.sb_type.gen == AMD_CHIPSET_SB600 ||
+                       (amd_chipset.sb_type.gen == AMD_CHIPSET_SB700 &&
+                        rev >= 0x3a && rev <= 0x3b);
+}
+EXPORT_SYMBOL_GPL(usb_amd_hang_symptom_quirk);
+
+bool usb_amd_prefetch_quirk(void)
+{
+       usb_amd_find_chipset_info();
+       /* SB800 needs pre-fetch fix */
+       return amd_chipset.sb_type.gen == AMD_CHIPSET_SB800;
+}
+EXPORT_SYMBOL_GPL(usb_amd_prefetch_quirk);
+
 /*
  * The hardware normally enables the A-link power management feature, which
  * lets the system lower the power consumption in idle states.
@@ -229,7 +315,9 @@ static void usb_amd_quirk_pll(int disable)
                }
        }
 
-       if (amd_chipset.sb_type == 1 || amd_chipset.sb_type == 2) {
+       if (amd_chipset.sb_type.gen == AMD_CHIPSET_SB800 ||
+                       amd_chipset.sb_type.gen == AMD_CHIPSET_HUDSON2 ||
+                       amd_chipset.sb_type.gen == AMD_CHIPSET_BOLTON) {
                outb_p(AB_REG_BAR_LOW, 0xcd6);
                addr_low = inb_p(0xcd7);
                outb_p(AB_REG_BAR_HIGH, 0xcd6);
@@ -240,7 +328,8 @@ static void usb_amd_quirk_pll(int disable)
                outl_p(0x40, AB_DATA(addr));
                outl_p(0x34, AB_INDX(addr));
                val = inl_p(AB_DATA(addr));
-       } else if (amd_chipset.sb_type == 3) {
+       } else if (amd_chipset.sb_type.gen == AMD_CHIPSET_SB700 &&
+                       amd_chipset.sb_type.rev <= 0x3b) {
                pci_read_config_dword(amd_chipset.smbus_dev,
                                        AB_REG_BAR_SB700, &addr);
                outl(AX_INDXC, AB_INDX(addr));
@@ -353,7 +442,7 @@ void usb_amd_dev_put(void)
        amd_chipset.nb_dev = NULL;
        amd_chipset.smbus_dev = NULL;
        amd_chipset.nb_type = 0;
-       amd_chipset.sb_type = 0;
+       memset(&amd_chipset.sb_type, 0, sizeof(amd_chipset.sb_type));
        amd_chipset.isoc_reqs = 0;
        amd_chipset.probe_result = 0;
 
index ed6700d00fe6fd372f62b575b49075b5ede392f1..638e88f7a28bbce2a3e04df49cee7dedde99229d 100644 (file)
@@ -5,6 +5,8 @@
 void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
 int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
 int usb_amd_find_chipset_info(void);
+bool usb_amd_hang_symptom_quirk(void);
+bool usb_amd_prefetch_quirk(void);
 void usb_amd_dev_put(void);
 void usb_amd_quirk_pll_disable(void);
 void usb_amd_quirk_pll_enable(void);
index 5477bf5df2186549412612dc016e809fa6970124..79620c39217ec182474bf53e2e04386560ea19b7 100644 (file)
@@ -1413,7 +1413,7 @@ static int sl811h_show(struct seq_file *s, void *unused)
                        case SL11H_CTL1MASK_SE0: s = " se0/reset"; break;
                        case SL11H_CTL1MASK_K: s = " k/resume"; break;
                        default: s = "j"; break;
-                       }; s; }),
+                       } s; }),
                        (t & SL11H_CTL1MASK_LSPD) ? " lowspeed" : "",
                        (t & SL11H_CTL1MASK_SUSPEND) ? " suspend" : "");
 
@@ -1446,7 +1446,7 @@ static int sl811h_show(struct seq_file *s, void *unused)
                        case USB_PID_SETUP: s = "setup"; break;
                        case USB_PID_ACK: s = "status"; break;
                        default: s = "?"; break;
-                       }; s;}),
+                       } s;}),
                        ep->maxpacket,
                        ep->nak_count, ep->error_count);
                list_for_each_entry (urb, &ep->hep->urb_list, urb_list) {
index 45573754652534b94c28cc6fa8c85d1a35ac1385..8e239cdd95d51025c8ca806da08899a420a19e09 100644 (file)
@@ -310,14 +310,14 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
        unsigned short portsc1, portsc2;
 
 
-       usbcmd    = uhci_readw(uhci, 0);
-       usbstat   = uhci_readw(uhci, 2);
-       usbint    = uhci_readw(uhci, 4);
-       usbfrnum  = uhci_readw(uhci, 6);
-       flbaseadd = uhci_readl(uhci, 8);
-       sof       = uhci_readb(uhci, 12);
-       portsc1   = uhci_readw(uhci, 16);
-       portsc2   = uhci_readw(uhci, 18);
+       usbcmd    = uhci_readw(uhci, USBCMD);
+       usbstat   = uhci_readw(uhci, USBSTS);
+       usbint    = uhci_readw(uhci, USBINTR);
+       usbfrnum  = uhci_readw(uhci, USBFRNUM);
+       flbaseadd = uhci_readl(uhci, USBFLBASEADD);
+       sof       = uhci_readb(uhci, USBSOF);
+       portsc1   = uhci_readw(uhci, USBPORTSC1);
+       portsc2   = uhci_readw(uhci, USBPORTSC2);
 
        out += sprintf(out, "  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",
                usbcmd,
index 9189bc984c98ce9804d51ec94c4aebe4147b8f3f..93e17b12fb3304b0191f36b3eb2f2b6eef334132 100644 (file)
@@ -75,8 +75,6 @@ static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
        return !!*buf;
 }
 
-#define OK(x)                  len = (x); break
-
 #define CLR_RH_PORTSTAT(x) \
        status = uhci_readw(uhci, port_addr);   \
        status &= ~(RWC_BITS|WZ_BITS); \
@@ -244,7 +242,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        u16 wIndex, char *buf, u16 wLength)
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-       int status, lstatus, retval = 0, len = 0;
+       int status, lstatus, retval = 0;
        unsigned int port = wIndex - 1;
        unsigned long port_addr = USBPORTSC1 + 2 * port;
        u16 wPortChange, wPortStatus;
@@ -258,7 +256,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
        case GetHubStatus:
                *(__le32 *)buf = cpu_to_le32(0);
-               OK(4);          /* hub power */
+               retval = 4; /* hub power */
+               break;
        case GetPortStatus:
                if (port >= uhci->rh_numports)
                        goto err;
@@ -311,13 +310,14 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
                *(__le16 *)buf = cpu_to_le16(wPortStatus);
                *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);
-               OK(4);
+               retval = 4;
+               break;
        case SetHubFeature:             /* We don't implement these */
        case ClearHubFeature:
                switch (wValue) {
                case C_HUB_OVER_CURRENT:
                case C_HUB_LOCAL_POWER:
-                       OK(0);
+                       break;
                default:
                        goto err;
                }
@@ -329,7 +329,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                switch (wValue) {
                case USB_PORT_FEAT_SUSPEND:
                        SET_RH_PORTSTAT(USBPORTSC_SUSP);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_RESET:
                        SET_RH_PORTSTAT(USBPORTSC_PR);
 
@@ -338,10 +338,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
                        /* USB v2.0 7.1.7.5 */
                        uhci->ports_timeout = jiffies + msecs_to_jiffies(50);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_POWER:
                        /* UHCI has no power switching */
-                       OK(0);
+                       break;
                default:
                        goto err;
                }
@@ -356,10 +356,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
                        /* Disable terminates Resume signalling */
                        uhci_finish_suspend(uhci, port, port_addr);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_C_ENABLE:
                        CLR_RH_PORTSTAT(USBPORTSC_PEC);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_SUSPEND:
                        if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) {
 
@@ -382,32 +382,32 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                        uhci->ports_timeout = jiffies +
                                                msecs_to_jiffies(20);
                        }
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_C_SUSPEND:
                        clear_bit(port, &uhci->port_c_suspend);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_POWER:
                        /* UHCI has no power switching */
                        goto err;
                case USB_PORT_FEAT_C_CONNECTION:
                        CLR_RH_PORTSTAT(USBPORTSC_CSC);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_C_OVER_CURRENT:
                        CLR_RH_PORTSTAT(USBPORTSC_OCC);
-                       OK(0);
+                       break;
                case USB_PORT_FEAT_C_RESET:
                        /* this driver won't report these */
-                       OK(0);
+                       break;
                default:
                        goto err;
                }
                break;
        case GetHubDescriptor:
-               len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
-               memcpy(buf, root_hub_hub_des, len);
-               if (len > 2)
+               retval = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
+               memcpy(buf, root_hub_hub_des, retval);
+               if (retval > 2)
                        buf[2] = uhci->rh_numports;
-               OK(len);
+               break;
        default:
 err:
                retval = -EPIPE;
index 0f228c46eedaab97c9351f784b8604d6144bb517..4cd79888804bb679b1ff85f850bb6d2e362d8fd3 100644 (file)
@@ -162,6 +162,8 @@ static void uhci_shutdown(struct pci_dev *pdev)
 
 #ifdef CONFIG_PM
 
+static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated);
+
 static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -174,12 +176,6 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
        if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)
                goto done_okay;         /* Already suspended or dead */
 
-       if (uhci->rh_state > UHCI_RH_SUSPENDED) {
-               dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
-               rc = -EBUSY;
-               goto done;
-       };
-
        /* All PCI host controllers are required to disable IRQ generation
         * at the source, so we must turn off PIRQ.
         */
@@ -195,8 +191,15 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 
 done_okay:
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-done:
        spin_unlock_irq(&uhci->lock);
+
+       synchronize_irq(hcd->irq);
+
+       /* Check for race with a wakeup request */
+       if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) {
+               uhci_pci_resume(hcd, false);
+               rc = -EBUSY;
+       }
        return rc;
 }
 
@@ -299,3 +302,5 @@ static struct pci_driver uhci_pci_driver = {
        },
 #endif
 };
+
+MODULE_SOFTDEP("pre: ehci_pci");
index d033a0ec7f0d02bd3874ae5e7339d43e964d2611..ded842bc65787a9ef74da721fbbfb7bac8fb479c 100644 (file)
@@ -105,8 +105,7 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 
        uhci->regs = hcd->regs;
 
-       ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED |
-                                                               IRQF_SHARED);
+       ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
        if (ret)
                goto err_uhci;
 
index ecc88db804e008ba4b7eacb48f68aa1c6a49ded4..1b0888f8da9a156a4e0ae29597568efe008ddc94 100644 (file)
@@ -134,7 +134,7 @@ static int whc_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
        default:
                ret = asl_urb_enqueue(whc, urb, mem_flags);
                break;
-       };
+       }
 
        return ret;
 }
@@ -160,7 +160,7 @@ static int whc_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb, int status)
        default:
                ret = asl_urb_dequeue(whc, urb, status);
                break;
-       };
+       }
 
        return ret;
 }
index e8b4c56dcf62adf1f5326e8609087cd387fedc2e..805f2348eeba09a3ced3e037a3af82592d7b7c30 100644 (file)
@@ -296,7 +296,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
        /* Wait for last stop endpoint command to finish */
        timeleft = wait_for_completion_interruptible_timeout(
                        cmd->completion,
-                       USB_CTRL_SET_TIMEOUT);
+                       XHCI_CMD_DEFAULT_TIMEOUT);
        if (timeleft <= 0) {
                xhci_warn(xhci, "%s while waiting for stop endpoint command\n",
                                timeleft == 0 ? "Timeout" : "Signal");
@@ -524,7 +524,8 @@ static void xhci_hub_report_usb3_link_state(u32 *status, u32 status_reg)
  * the compliance mode timer is deleted. A port won't enter
  * compliance mode if it has previously entered U0.
  */
-void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex)
+static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status,
+                                   u16 wIndex)
 {
        u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1);
        bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0);
index 83bcd13622c3466e655a00166bf6e8076ae198bc..49b8bd063fab70ab2de943f77c58ac329cdad87f 100644 (file)
@@ -1693,9 +1693,7 @@ void xhci_free_command(struct xhci_hcd *xhci,
 void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
        struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-       struct dev_info *dev_info, *next;
        struct xhci_cd  *cur_cd, *next_cd;
-       unsigned long   flags;
        int size;
        int i, j, num_ports;
 
@@ -1756,13 +1754,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 
        scratchpad_free(xhci);
 
-       spin_lock_irqsave(&xhci->lock, flags);
-       list_for_each_entry_safe(dev_info, next, &xhci->lpm_failed_devs, list) {
-               list_del(&dev_info->list);
-               kfree(dev_info);
-       }
-       spin_unlock_irqrestore(&xhci->lock, flags);
-
        if (!xhci->rh_bw)
                goto no_bw;
 
@@ -2231,7 +2222,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        u32 page_size, temp;
        int i;
 
-       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
        INIT_LIST_HEAD(&xhci->cancel_cmd_list);
 
        page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
index 6bfbd80ec2b9edfa0a079767381d7d733d8c7035..1e2f3f4958436fb120b81d41632ad7e7c76fb5b5 100644 (file)
@@ -178,7 +178,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
                        if (ring->type == TYPE_EVENT &&
                                        last_trb_on_last_seg(xhci, ring,
                                                ring->deq_seg, ring->dequeue)) {
-                               ring->cycle_state = (ring->cycle_state ? 0 : 1);
+                               ring->cycle_state ^= 1;
                        }
                        ring->deq_seg = ring->deq_seg->next;
                        ring->dequeue = ring->deq_seg->trbs;
@@ -726,7 +726,7 @@ static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci,
 
 /* Must be called with xhci->lock held in interrupt context */
 static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
-               struct xhci_td *cur_td, int status, char *adjective)
+               struct xhci_td *cur_td, int status)
 {
        struct usb_hcd *hcd;
        struct urb      *urb;
@@ -765,10 +765,9 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
  *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the chain
  *     bit cleared) so that the HW will skip over them.
  */
-static void handle_stopped_endpoint(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
                union xhci_trb *trb, struct xhci_event_cmd *event)
 {
-       unsigned int slot_id;
        unsigned int ep_index;
        struct xhci_virt_device *virt_dev;
        struct xhci_ring *ep_ring;
@@ -779,10 +778,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
 
        struct xhci_dequeue_state deq_state;
 
-       if (unlikely(TRB_TO_SUSPEND_PORT(
-                            le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])))) {
-               slot_id = TRB_TO_SLOT_ID(
-                       le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]));
+       if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb->generic.field[3])))) {
                virt_dev = xhci->devs[slot_id];
                if (virt_dev)
                        handle_cmd_in_cmd_wait_list(xhci, virt_dev,
@@ -795,7 +791,6 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
        }
 
        memset(&deq_state, 0, sizeof(deq_state));
-       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        ep = &xhci->devs[slot_id]->eps[ep_index];
 
@@ -891,7 +886,7 @@ remove_finished_td:
                /* Doesn't matter what we pass for status, since the core will
                 * just overwrite it (because the URB has been unlinked).
                 */
-               xhci_giveback_urb_in_irq(xhci, cur_td, 0, "cancelled");
+               xhci_giveback_urb_in_irq(xhci, cur_td, 0);
 
                /* Stop processing the cancelled list if the watchdog timer is
                 * running.
@@ -1001,7 +996,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
                                if (!list_empty(&cur_td->cancelled_td_list))
                                        list_del_init(&cur_td->cancelled_td_list);
                                xhci_giveback_urb_in_irq(xhci, cur_td,
-                                               -ESHUTDOWN, "killed");
+                                               -ESHUTDOWN);
                        }
                        while (!list_empty(&temp_ep->cancelled_td_list)) {
                                cur_td = list_first_entry(
@@ -1010,7 +1005,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
                                                cancelled_td_list);
                                list_del_init(&cur_td->cancelled_td_list);
                                xhci_giveback_urb_in_irq(xhci, cur_td,
-                                               -ESHUTDOWN, "killed");
+                                               -ESHUTDOWN);
                        }
                }
        }
@@ -1077,11 +1072,9 @@ static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,
  * endpoint doorbell to restart the ring, but only if there aren't more
  * cancellations pending.
  */
-static void handle_set_deq_completion(struct xhci_hcd *xhci,
-               struct xhci_event_cmd *event,
-               union xhci_trb *trb)
+static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
+               union xhci_trb *trb, u32 cmd_comp_code)
 {
-       unsigned int slot_id;
        unsigned int ep_index;
        unsigned int stream_id;
        struct xhci_ring *ep_ring;
@@ -1089,7 +1082,6 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
        struct xhci_ep_ctx *ep_ctx;
        struct xhci_slot_ctx *slot_ctx;
 
-       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
        dev = xhci->devs[slot_id];
@@ -1107,11 +1099,11 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
        ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
        slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
 
-       if (GET_COMP_CODE(le32_to_cpu(event->status)) != COMP_SUCCESS) {
+       if (cmd_comp_code != COMP_SUCCESS) {
                unsigned int ep_state;
                unsigned int slot_state;
 
-               switch (GET_COMP_CODE(le32_to_cpu(event->status))) {
+               switch (cmd_comp_code) {
                case COMP_TRB_ERR:
                        xhci_warn(xhci, "WARN Set TR Deq Ptr cmd invalid because "
                                        "of stream ID configuration\n");
@@ -1134,7 +1126,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
                default:
                        xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown "
                                        "completion code of %u.\n",
-                                 GET_COMP_CODE(le32_to_cpu(event->status)));
+                                 cmd_comp_code);
                        break;
                }
                /* OK what do we do now?  The endpoint state is hosed, and we
@@ -1171,21 +1163,17 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
        ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
-static void handle_reset_ep_completion(struct xhci_hcd *xhci,
-               struct xhci_event_cmd *event,
-               union xhci_trb *trb)
+static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
+               union xhci_trb *trb, u32 cmd_comp_code)
 {
-       int slot_id;
        unsigned int ep_index;
 
-       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        /* This command will only fail if the endpoint wasn't halted,
         * but we don't care.
         */
        xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
-               "Ignoring reset ep completion code of %u",
-                GET_COMP_CODE(le32_to_cpu(event->status)));
+               "Ignoring reset ep completion code of %u", cmd_comp_code);
 
        /* HW with the reset endpoint quirk needs to have a configure endpoint
         * command complete before the endpoint can be used.  Queue that here
@@ -1386,21 +1374,149 @@ static int handle_stopped_cmd_ring(struct xhci_hcd *xhci,
        return cur_trb_is_good;
 }
 
+static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
+               u32 cmd_comp_code)
+{
+       if (cmd_comp_code == COMP_SUCCESS)
+               xhci->slot_id = slot_id;
+       else
+               xhci->slot_id = 0;
+       complete(&xhci->addr_dev);
+}
+
+static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
+{
+       struct xhci_virt_device *virt_dev;
+
+       virt_dev = xhci->devs[slot_id];
+       if (!virt_dev)
+               return;
+       if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
+               /* Delete default control endpoint resources */
+               xhci_free_device_endpoint_resources(xhci, virt_dev, true);
+       xhci_free_virt_device(xhci, slot_id);
+}
+
+static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
+               struct xhci_event_cmd *event, u32 cmd_comp_code)
+{
+       struct xhci_virt_device *virt_dev;
+       struct xhci_input_control_ctx *ctrl_ctx;
+       unsigned int ep_index;
+       unsigned int ep_state;
+       u32 add_flags, drop_flags;
+
+       virt_dev = xhci->devs[slot_id];
+       if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
+               return;
+       /*
+        * Configure endpoint commands can come from the USB core
+        * configuration or alt setting changes, or because the HW
+        * needed an extra configure endpoint command after a reset
+        * endpoint command or streams were being configured.
+        * If the command was for a halted endpoint, the xHCI driver
+        * is not waiting on the configure endpoint command.
+        */
+       ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+       if (!ctrl_ctx) {
+               xhci_warn(xhci, "Could not get input context, bad type.\n");
+               return;
+       }
+
+       add_flags = le32_to_cpu(ctrl_ctx->add_flags);
+       drop_flags = le32_to_cpu(ctrl_ctx->drop_flags);
+       /* Input ctx add_flags are the endpoint index plus one */
+       ep_index = xhci_last_valid_endpoint(add_flags) - 1;
+
+       /* A usb_set_interface() call directly after clearing a halted
+        * condition may race on this quirky hardware.  Not worth
+        * worrying about, since this is prototype hardware.  Not sure
+        * if this will work for streams, but streams support was
+        * untested on this prototype.
+        */
+       if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
+                       ep_index != (unsigned int) -1 &&
+                       add_flags - SLOT_FLAG == drop_flags) {
+               ep_state = virt_dev->eps[ep_index].ep_state;
+               if (!(ep_state & EP_HALTED))
+                       goto bandwidth_change;
+               xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+                               "Completed config ep cmd - "
+                               "last ep index = %d, state = %d",
+                               ep_index, ep_state);
+               /* Clear internal halted state and restart ring(s) */
+               virt_dev->eps[ep_index].ep_state &= ~EP_HALTED;
+               ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+               return;
+       }
+bandwidth_change:
+       xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
+                       "Completed config ep cmd");
+       virt_dev->cmd_status = cmd_comp_code;
+       complete(&virt_dev->cmd_completion);
+       return;
+}
+
+static void xhci_handle_cmd_eval_ctx(struct xhci_hcd *xhci, int slot_id,
+               struct xhci_event_cmd *event, u32 cmd_comp_code)
+{
+       struct xhci_virt_device *virt_dev;
+
+       virt_dev = xhci->devs[slot_id];
+       if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
+               return;
+       virt_dev->cmd_status = cmd_comp_code;
+       complete(&virt_dev->cmd_completion);
+}
+
+static void xhci_handle_cmd_addr_dev(struct xhci_hcd *xhci, int slot_id,
+               u32 cmd_comp_code)
+{
+       xhci->devs[slot_id]->cmd_status = cmd_comp_code;
+       complete(&xhci->addr_dev);
+}
+
+static void xhci_handle_cmd_reset_dev(struct xhci_hcd *xhci, int slot_id,
+               struct xhci_event_cmd *event)
+{
+       struct xhci_virt_device *virt_dev;
+
+       xhci_dbg(xhci, "Completed reset device command.\n");
+       virt_dev = xhci->devs[slot_id];
+       if (virt_dev)
+               handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
+       else
+               xhci_warn(xhci, "Reset device command completion "
+                               "for disabled slot %u\n", slot_id);
+}
+
+static void xhci_handle_cmd_nec_get_fw(struct xhci_hcd *xhci,
+               struct xhci_event_cmd *event)
+{
+       if (!(xhci->quirks & XHCI_NEC_HOST)) {
+               xhci->error_bitmask |= 1 << 6;
+               return;
+       }
+       xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+                       "NEC firmware version %2x.%02x",
+                       NEC_FW_MAJOR(le32_to_cpu(event->status)),
+                       NEC_FW_MINOR(le32_to_cpu(event->status)));
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
                struct xhci_event_cmd *event)
 {
        int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
        u64 cmd_dma;
        dma_addr_t cmd_dequeue_dma;
-       struct xhci_input_control_ctx *ctrl_ctx;
-       struct xhci_virt_device *virt_dev;
-       unsigned int ep_index;
-       struct xhci_ring *ep_ring;
-       unsigned int ep_state;
+       u32 cmd_comp_code;
+       union xhci_trb *cmd_trb;
+       u32 cmd_type;
 
        cmd_dma = le64_to_cpu(event->cmd_trb);
+       cmd_trb = xhci->cmd_ring->dequeue;
        cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
-                       xhci->cmd_ring->dequeue);
+                       cmd_trb);
        /* Is the command ring deq ptr out of sync with the deq seg ptr? */
        if (cmd_dequeue_dma == 0) {
                xhci->error_bitmask |= 1 << 4;
@@ -1412,19 +1528,17 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
                return;
        }
 
-       trace_xhci_cmd_completion(&xhci->cmd_ring->dequeue->generic,
-                                       (struct xhci_generic_trb *) event);
+       trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
 
-       if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) ||
-               (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) {
+       cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
+       if (cmd_comp_code == COMP_CMD_ABORT || cmd_comp_code == COMP_CMD_STOP) {
                /* If the return value is 0, we think the trb pointed by
                 * command ring dequeue pointer is a good trb. The good
                 * trb means we don't want to cancel the trb, but it have
                 * been stopped by host. So we should handle it normally.
                 * Otherwise, driver should invoke inc_deq() and return.
                 */
-               if (handle_stopped_cmd_ring(xhci,
-                               GET_COMP_CODE(le32_to_cpu(event->status)))) {
+               if (handle_stopped_cmd_ring(xhci, cmd_comp_code)) {
                        inc_deq(xhci, xhci->cmd_ring);
                        return;
                }
@@ -1436,117 +1550,47 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
                        return;
        }
 
-       switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])
-               & TRB_TYPE_BITMASK) {
-       case TRB_TYPE(TRB_ENABLE_SLOT):
-               if (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_SUCCESS)
-                       xhci->slot_id = slot_id;
-               else
-                       xhci->slot_id = 0;
-               complete(&xhci->addr_dev);
+       cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3]));
+       switch (cmd_type) {
+       case TRB_ENABLE_SLOT:
+               xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_DISABLE_SLOT):
-               if (xhci->devs[slot_id]) {
-                       if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
-                               /* Delete default control endpoint resources */
-                               xhci_free_device_endpoint_resources(xhci,
-                                               xhci->devs[slot_id], true);
-                       xhci_free_virt_device(xhci, slot_id);
-               }
+       case TRB_DISABLE_SLOT:
+               xhci_handle_cmd_disable_slot(xhci, slot_id);
                break;
-       case TRB_TYPE(TRB_CONFIG_EP):
-               virt_dev = xhci->devs[slot_id];
-               if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
-                       break;
-               /*
-                * Configure endpoint commands can come from the USB core
-                * configuration or alt setting changes, or because the HW
-                * needed an extra configure endpoint command after a reset
-                * endpoint command or streams were being configured.
-                * If the command was for a halted endpoint, the xHCI driver
-                * is not waiting on the configure endpoint command.
-                */
-               ctrl_ctx = xhci_get_input_control_ctx(xhci,
-                               virt_dev->in_ctx);
-               if (!ctrl_ctx) {
-                       xhci_warn(xhci, "Could not get input context, bad type.\n");
-                       break;
-               }
-               /* Input ctx add_flags are the endpoint index plus one */
-               ep_index = xhci_last_valid_endpoint(le32_to_cpu(ctrl_ctx->add_flags)) - 1;
-               /* A usb_set_interface() call directly after clearing a halted
-                * condition may race on this quirky hardware.  Not worth
-                * worrying about, since this is prototype hardware.  Not sure
-                * if this will work for streams, but streams support was
-                * untested on this prototype.
-                */
-               if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
-                               ep_index != (unsigned int) -1 &&
-                   le32_to_cpu(ctrl_ctx->add_flags) - SLOT_FLAG ==
-                   le32_to_cpu(ctrl_ctx->drop_flags)) {
-                       ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
-                       ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
-                       if (!(ep_state & EP_HALTED))
-                               goto bandwidth_change;
-                       xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
-                                       "Completed config ep cmd - "
-                                       "last ep index = %d, state = %d",
-                                       ep_index, ep_state);
-                       /* Clear internal halted state and restart ring(s) */
-                       xhci->devs[slot_id]->eps[ep_index].ep_state &=
-                               ~EP_HALTED;
-                       ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
-                       break;
-               }
-bandwidth_change:
-               xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
-                               "Completed config ep cmd");
-               xhci->devs[slot_id]->cmd_status =
-                       GET_COMP_CODE(le32_to_cpu(event->status));
-               complete(&xhci->devs[slot_id]->cmd_completion);
+       case TRB_CONFIG_EP:
+               xhci_handle_cmd_config_ep(xhci, slot_id, event, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_EVAL_CONTEXT):
-               virt_dev = xhci->devs[slot_id];
-               if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
-                       break;
-               xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status));
-               complete(&xhci->devs[slot_id]->cmd_completion);
+       case TRB_EVAL_CONTEXT:
+               xhci_handle_cmd_eval_ctx(xhci, slot_id, event, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_ADDR_DEV):
-               xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status));
-               complete(&xhci->addr_dev);
+       case TRB_ADDR_DEV:
+               xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_STOP_RING):
-               handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue, event);
+       case TRB_STOP_RING:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_stop_ep(xhci, slot_id, cmd_trb, event);
                break;
-       case TRB_TYPE(TRB_SET_DEQ):
-               handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue);
+       case TRB_SET_DEQ:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_set_deq(xhci, slot_id, cmd_trb, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_CMD_NOOP):
+       case TRB_CMD_NOOP:
                break;
-       case TRB_TYPE(TRB_RESET_EP):
-               handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue);
+       case TRB_RESET_EP:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_RESET_DEV):
-               xhci_dbg(xhci, "Completed reset device command.\n");
-               slot_id = TRB_TO_SLOT_ID(
-                       le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]));
-               virt_dev = xhci->devs[slot_id];
-               if (virt_dev)
-                       handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
-               else
-                       xhci_warn(xhci, "Reset device command completion "
-                                       "for disabled slot %u\n", slot_id);
+       case TRB_RESET_DEV:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_reset_dev(xhci, slot_id, event);
                break;
-       case TRB_TYPE(TRB_NEC_GET_FW):
-               if (!(xhci->quirks & XHCI_NEC_HOST)) {
-                       xhci->error_bitmask |= 1 << 6;
-                       break;
-               }
-               xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
-                       "NEC firmware version %2x.%02x",
-                        NEC_FW_MAJOR(le32_to_cpu(event->status)),
-                        NEC_FW_MINOR(le32_to_cpu(event->status)));
+       case TRB_NEC_GET_FW:
+               xhci_handle_cmd_nec_get_fw(xhci, event);
                break;
        default:
                /* Skip over unknown commands on the event ring */
index 6e0d886bcce52c19361d321cf68c0abacf5b054c..4265b48856f6a7b0160124964b3b7fc697ecd826 100644 (file)
@@ -3459,7 +3459,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
        /* Wait for the Reset Device command to finish */
        timeleft = wait_for_completion_interruptible_timeout(
                        reset_device_cmd->completion,
-                       USB_CTRL_SET_TIMEOUT);
+                       XHCI_CMD_DEFAULT_TIMEOUT);
        if (timeleft <= 0) {
                xhci_warn(xhci, "%s while waiting for reset device command\n",
                                timeleft == 0 ? "Timeout" : "Signal");
@@ -3583,11 +3583,6 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
                del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
        }
 
-       if (udev->usb2_hw_lpm_enabled) {
-               xhci_set_usb2_hardware_lpm(hcd, udev, 0);
-               udev->usb2_hw_lpm_enabled = 0;
-       }
-
        spin_lock_irqsave(&xhci->lock, flags);
        /* Don't disable the slot if the host controller is dead. */
        state = xhci_readl(xhci, &xhci->op_regs->status);
@@ -3721,9 +3716,6 @@ disable_slot:
  * the device).
  * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so
  * we should only issue and wait on one address command at the same time.
- *
- * We add one to the device address issued by the hardware because the USB core
- * uses address 1 for the root hubs (even though they're not really devices).
  */
 int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
 {
@@ -3868,16 +3860,13 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
        slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
        trace_xhci_address_ctx(xhci, virt_dev->out_ctx,
                                slot_ctx->dev_info >> 27);
-       /* Use kernel assigned address for devices; store xHC assigned
-        * address locally. */
-       virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK)
-               + 1;
        /* Zero the input context control for later use */
        ctrl_ctx->add_flags = 0;
        ctrl_ctx->drop_flags = 0;
 
        xhci_dbg_trace(xhci, trace_xhci_dbg_address,
-                       "Internal device address = %d", virt_dev->address);
+                      "Internal device address = %d",
+                      le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK);
 
        return 0;
 }
@@ -4025,133 +4014,6 @@ static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev)
        return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm);
 }
 
-static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
-                                       struct usb_device *udev)
-{
-       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-       struct dev_info *dev_info;
-       __le32 __iomem  **port_array;
-       __le32 __iomem  *addr, *pm_addr;
-       u32             temp, dev_id;
-       unsigned int    port_num;
-       unsigned long   flags;
-       int             hird;
-       int             ret;
-
-       if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support ||
-                       !udev->lpm_capable)
-               return -EINVAL;
-
-       /* we only support lpm for non-hub device connected to root hub yet */
-       if (!udev->parent || udev->parent->parent ||
-                       udev->descriptor.bDeviceClass == USB_CLASS_HUB)
-               return -EINVAL;
-
-       spin_lock_irqsave(&xhci->lock, flags);
-
-       /* Look for devices in lpm_failed_devs list */
-       dev_id = le16_to_cpu(udev->descriptor.idVendor) << 16 |
-                       le16_to_cpu(udev->descriptor.idProduct);
-       list_for_each_entry(dev_info, &xhci->lpm_failed_devs, list) {
-               if (dev_info->dev_id == dev_id) {
-                       ret = -EINVAL;
-                       goto finish;
-               }
-       }
-
-       port_array = xhci->usb2_ports;
-       port_num = udev->portnum - 1;
-
-       if (port_num > HCS_MAX_PORTS(xhci->hcs_params1)) {
-               xhci_dbg(xhci, "invalid port number %d\n", udev->portnum);
-               ret = -EINVAL;
-               goto finish;
-       }
-
-       /*
-        * Test USB 2.0 software LPM.
-        * FIXME: some xHCI 1.0 hosts may implement a new register to set up
-        * hardware-controlled USB 2.0 LPM. See section 5.4.11 and 4.23.5.1.1.1
-        * in the June 2011 errata release.
-        */
-       xhci_dbg(xhci, "test port %d software LPM\n", port_num);
-       /*
-        * Set L1 Device Slot and HIRD/BESL.
-        * Check device's USB 2.0 extension descriptor to determine whether
-        * HIRD or BESL shoule be used. See USB2.0 LPM errata.
-        */
-       pm_addr = port_array[port_num] + PORTPMSC;
-       hird = xhci_calculate_hird_besl(xhci, udev);
-       temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird);
-       xhci_writel(xhci, temp, pm_addr);
-
-       /* Set port link state to U2(L1) */
-       addr = port_array[port_num];
-       xhci_set_link_state(xhci, port_array, port_num, XDEV_U2);
-
-       /* wait for ACK */
-       spin_unlock_irqrestore(&xhci->lock, flags);
-       msleep(10);
-       spin_lock_irqsave(&xhci->lock, flags);
-
-       /* Check L1 Status */
-       ret = xhci_handshake(xhci, pm_addr,
-                       PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
-       if (ret != -ETIMEDOUT) {
-               /* enter L1 successfully */
-               temp = xhci_readl(xhci, addr);
-               xhci_dbg(xhci, "port %d entered L1 state, port status 0x%x\n",
-                               port_num, temp);
-               ret = 0;
-       } else {
-               temp = xhci_readl(xhci, pm_addr);
-               xhci_dbg(xhci, "port %d software lpm failed, L1 status %d\n",
-                               port_num, temp & PORT_L1S_MASK);
-               ret = -EINVAL;
-       }
-
-       /* Resume the port */
-       xhci_set_link_state(xhci, port_array, port_num, XDEV_U0);
-
-       spin_unlock_irqrestore(&xhci->lock, flags);
-       msleep(10);
-       spin_lock_irqsave(&xhci->lock, flags);
-
-       /* Clear PLC */
-       xhci_test_and_clear_bit(xhci, port_array, port_num, PORT_PLC);
-
-       /* Check PORTSC to make sure the device is in the right state */
-       if (!ret) {
-               temp = xhci_readl(xhci, addr);
-               xhci_dbg(xhci, "resumed port %d status 0x%x\n", port_num, temp);
-               if (!(temp & PORT_CONNECT) || !(temp & PORT_PE) ||
-                               (temp & PORT_PLS_MASK) != XDEV_U0) {
-                       xhci_dbg(xhci, "port L1 resume fail\n");
-                       ret = -EINVAL;
-               }
-       }
-
-       if (ret) {
-               /* Insert dev to lpm_failed_devs list */
-               xhci_warn(xhci, "device LPM test failed, may disconnect and "
-                               "re-enumerate\n");
-               dev_info = kzalloc(sizeof(struct dev_info), GFP_ATOMIC);
-               if (!dev_info) {
-                       ret = -ENOMEM;
-                       goto finish;
-               }
-               dev_info->dev_id = dev_id;
-               INIT_LIST_HEAD(&dev_info->list);
-               list_add(&dev_info->list, &xhci->lpm_failed_devs);
-       } else {
-               xhci_ring_device(xhci, udev->slot_id);
-       }
-
-finish:
-       spin_unlock_irqrestore(&xhci->lock, flags);
-       return ret;
-}
-
 int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
                        struct usb_device *udev, int enable)
 {
@@ -4228,7 +4090,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
                }
 
                pm_val &= ~PORT_HIRD_MASK;
-               pm_val |= PORT_HIRD(hird) | PORT_RWE;
+               pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id);
                xhci_writel(xhci, pm_val, pm_addr);
                pm_val = xhci_readl(xhci, pm_addr);
                pm_val |= PORT_HLE;
@@ -4236,7 +4098,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
                /* flush write */
                xhci_readl(xhci, pm_addr);
        } else {
-               pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK);
+               pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
                xhci_writel(xhci, pm_val, pm_addr);
                /* flush write */
                xhci_readl(xhci, pm_addr);
@@ -4279,24 +4141,26 @@ static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port,
 int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-       int             ret;
        int             portnum = udev->portnum - 1;
 
-       ret = xhci_usb2_software_lpm_test(hcd, udev);
-       if (!ret) {
-               xhci_dbg(xhci, "software LPM test succeed\n");
-               if (xhci->hw_lpm_support == 1 &&
-                   xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) {
-                       udev->usb2_hw_lpm_capable = 1;
-                       udev->l1_params.timeout = XHCI_L1_TIMEOUT;
-                       udev->l1_params.besl = XHCI_DEFAULT_BESL;
-                       if (xhci_check_usb2_port_capability(xhci, portnum,
-                                                           XHCI_BLC))
-                               udev->usb2_hw_lpm_besl_capable = 1;
-                       ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1);
-                       if (!ret)
-                               udev->usb2_hw_lpm_enabled = 1;
-               }
+       if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support ||
+                       !udev->lpm_capable)
+               return 0;
+
+       /* we only support lpm for non-hub device connected to root hub yet */
+       if (!udev->parent || udev->parent->parent ||
+                       udev->descriptor.bDeviceClass == USB_CLASS_HUB)
+               return 0;
+
+       if (xhci->hw_lpm_support == 1 &&
+                       xhci_check_usb2_port_capability(
+                               xhci, portnum, XHCI_HLC)) {
+               udev->usb2_hw_lpm_capable = 1;
+               udev->l1_params.timeout = XHCI_L1_TIMEOUT;
+               udev->l1_params.besl = XHCI_DEFAULT_BESL;
+               if (xhci_check_usb2_port_capability(xhci, portnum,
+                                       XHCI_BLC))
+                       udev->usb2_hw_lpm_besl_capable = 1;
        }
 
        return 0;
index 941d5f59e4dcc254770bac770ba024e36a677bad..03c74b7965f85d767436c8108348f6adf6f87126 100644 (file)
@@ -383,6 +383,7 @@ struct xhci_op_regs {
 #define        PORT_RWE                (1 << 3)
 #define        PORT_HIRD(p)            (((p) & 0xf) << 4)
 #define        PORT_HIRD_MASK          (0xf << 4)
+#define        PORT_L1DS_MASK          (0xff << 8)
 #define        PORT_L1DS(p)            (((p) & 0xff) << 8)
 #define        PORT_HLE                (1 << 16)
 
@@ -934,8 +935,6 @@ struct xhci_virt_device {
        /* Rings saved to ensure old alt settings can be re-instated */
        struct xhci_ring                **ring_cache;
        int                             num_rings_cached;
-       /* Store xHC assigned device address */
-       int                             address;
 #define        XHCI_MAX_RINGS_CACHED   31
        struct xhci_virt_ep             eps[31];
        struct completion               cmd_completion;
index aa28ac8c7607deeb49136340f0def4dd5f6fa05d..b4152820d655f389c9c491b4ead7c6c159e58572 100644 (file)
@@ -120,7 +120,7 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
                        struct usb_host_endpoint        *e;
 
                        e = alt->endpoint + ep;
-                       switch (e->desc.bmAttributes) {
+                       switch (usb_endpoint_type(&e->desc)) {
                        case USB_ENDPOINT_XFER_BULK:
                                break;
                        case USB_ENDPOINT_XFER_ISOC:
@@ -437,7 +437,7 @@ alloc_sglist(int nents, int max, int vary)
        if (max == 0)
                return NULL;
 
-       sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
+       sg = kmalloc_array(nents, sizeof(*sg), GFP_KERNEL);
        if (!sg)
                return NULL;
        sg_init_table(sg, nents);
@@ -573,7 +573,7 @@ static int is_good_config(struct usbtest_dev *tdev, int len)
 {
        struct usb_config_descriptor    *config;
 
-       if (len < sizeof *config)
+       if (len < sizeof(*config))
                return 0;
        config = (struct usb_config_descriptor *) tdev->buf;
 
@@ -606,6 +606,76 @@ static int is_good_config(struct usbtest_dev *tdev, int len)
        return 0;
 }
 
+static int is_good_ext(struct usbtest_dev *tdev, u8 *buf)
+{
+       struct usb_ext_cap_descriptor *ext;
+       u32 attr;
+
+       ext = (struct usb_ext_cap_descriptor *) buf;
+
+       if (ext->bLength != USB_DT_USB_EXT_CAP_SIZE) {
+               ERROR(tdev, "bogus usb 2.0 extension descriptor length\n");
+               return 0;
+       }
+
+       attr = le32_to_cpu(ext->bmAttributes);
+       /* bits[1:4] is used and others are reserved */
+       if (attr & ~0x1e) {     /* reserved == 0 */
+               ERROR(tdev, "reserved bits set\n");
+               return 0;
+       }
+
+       return 1;
+}
+
+static int is_good_ss_cap(struct usbtest_dev *tdev, u8 *buf)
+{
+       struct usb_ss_cap_descriptor *ss;
+
+       ss = (struct usb_ss_cap_descriptor *) buf;
+
+       if (ss->bLength != USB_DT_USB_SS_CAP_SIZE) {
+               ERROR(tdev, "bogus superspeed device capability descriptor length\n");
+               return 0;
+       }
+
+       /*
+        * only bit[1] of bmAttributes is used for LTM and others are
+        * reserved
+        */
+       if (ss->bmAttributes & ~0x02) { /* reserved == 0 */
+               ERROR(tdev, "reserved bits set in bmAttributes\n");
+               return 0;
+       }
+
+       /* bits[0:3] of wSpeedSupported is used and others are reserved */
+       if (le16_to_cpu(ss->wSpeedSupported) & ~0x0f) { /* reserved == 0 */
+               ERROR(tdev, "reserved bits set in wSpeedSupported\n");
+               return 0;
+       }
+
+       return 1;
+}
+
+static int is_good_con_id(struct usbtest_dev *tdev, u8 *buf)
+{
+       struct usb_ss_container_id_descriptor *con_id;
+
+       con_id = (struct usb_ss_container_id_descriptor *) buf;
+
+       if (con_id->bLength != USB_DT_USB_SS_CONTN_ID_SIZE) {
+               ERROR(tdev, "bogus container id descriptor length\n");
+               return 0;
+       }
+
+       if (con_id->bReserved) {        /* reserved == 0 */
+               ERROR(tdev, "reserved bits set\n");
+               return 0;
+       }
+
+       return 1;
+}
+
 /* sanity test for standard requests working with usb_control_mesg() and some
  * of the utility functions which use it.
  *
@@ -683,12 +753,96 @@ static int ch9_postconfig(struct usbtest_dev *dev)
 
        /* there's always [9.4.3] a device descriptor [9.6.1] */
        retval = usb_get_descriptor(udev, USB_DT_DEVICE, 0,
-                       dev->buf, sizeof udev->descriptor);
-       if (retval != sizeof udev->descriptor) {
+                       dev->buf, sizeof(udev->descriptor));
+       if (retval != sizeof(udev->descriptor)) {
                dev_err(&iface->dev, "dev descriptor --> %d\n", retval);
                return (retval < 0) ? retval : -EDOM;
        }
 
+       /*
+        * there's always [9.4.3] a bos device descriptor [9.6.2] in USB
+        * 3.0 spec
+        */
+       if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0300) {
+               struct usb_bos_descriptor *bos = NULL;
+               struct usb_dev_cap_header *header = NULL;
+               unsigned total, num, length;
+               u8 *buf;
+
+               retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
+                               sizeof(*udev->bos->desc));
+               if (retval != sizeof(*udev->bos->desc)) {
+                       dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
+                       return (retval < 0) ? retval : -EDOM;
+               }
+
+               bos = (struct usb_bos_descriptor *)dev->buf;
+               total = le16_to_cpu(bos->wTotalLength);
+               num = bos->bNumDeviceCaps;
+
+               if (total > TBUF_SIZE)
+                       total = TBUF_SIZE;
+
+               /*
+                * get generic device-level capability descriptors [9.6.2]
+                * in USB 3.0 spec
+                */
+               retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
+                               total);
+               if (retval != total) {
+                       dev_err(&iface->dev, "bos descriptor set --> %d\n",
+                                       retval);
+                       return (retval < 0) ? retval : -EDOM;
+               }
+
+               length = sizeof(*udev->bos->desc);
+               buf = dev->buf;
+               for (i = 0; i < num; i++) {
+                       buf += length;
+                       if (buf + sizeof(struct usb_dev_cap_header) >
+                                       dev->buf + total)
+                               break;
+
+                       header = (struct usb_dev_cap_header *)buf;
+                       length = header->bLength;
+
+                       if (header->bDescriptorType !=
+                                       USB_DT_DEVICE_CAPABILITY) {
+                               dev_warn(&udev->dev, "not device capability descriptor, skip\n");
+                               continue;
+                       }
+
+                       switch (header->bDevCapabilityType) {
+                       case USB_CAP_TYPE_EXT:
+                               if (buf + USB_DT_USB_EXT_CAP_SIZE >
+                                               dev->buf + total ||
+                                               !is_good_ext(dev, buf)) {
+                                       dev_err(&iface->dev, "bogus usb 2.0 extension descriptor\n");
+                                       return -EDOM;
+                               }
+                               break;
+                       case USB_SS_CAP_TYPE:
+                               if (buf + USB_DT_USB_SS_CAP_SIZE >
+                                               dev->buf + total ||
+                                               !is_good_ss_cap(dev, buf)) {
+                                       dev_err(&iface->dev, "bogus superspeed device capability descriptor\n");
+                                       return -EDOM;
+                               }
+                               break;
+                       case CONTAINER_ID_TYPE:
+                               if (buf + USB_DT_USB_SS_CONTN_ID_SIZE >
+                                               dev->buf + total ||
+                                               !is_good_con_id(dev, buf)) {
+                                       dev_err(&iface->dev, "bogus container id descriptor\n");
+                                       return -EDOM;
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+
        /* there's always [9.4.3] at least one config descriptor [9.6.3] */
        for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
                retval = usb_get_descriptor(udev, USB_DT_CONFIG, i,
@@ -954,7 +1108,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
                 * device, but some are chosen to trigger protocol stalls
                 * or short reads.
                 */
-               memset(&req, 0, sizeof req);
+               memset(&req, 0, sizeof(req));
                req.bRequest = USB_REQ_GET_DESCRIPTOR;
                req.bRequestType = USB_DIR_IN|USB_RECIP_DEVICE;
 
@@ -1074,7 +1228,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
                if (!u)
                        goto cleanup;
 
-               reqp = kmalloc(sizeof *reqp, GFP_KERNEL);
+               reqp = kmalloc(sizeof(*reqp), GFP_KERNEL);
                if (!reqp)
                        goto cleanup;
                reqp->setup = req;
@@ -1667,13 +1821,13 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
        if (param->sglen > 10)
                return -EDOM;
 
-       memset(&context, 0, sizeof context);
+       memset(&context, 0, sizeof(context));
        context.count = param->iterations * param->sglen;
        context.dev = dev;
        init_completion(&context.done);
        spin_lock_init(&context.lock);
 
-       memset(urbs, 0, sizeof urbs);
+       memset(urbs, 0, sizeof(urbs));
        udev = testdev_to_usbdev(dev);
        dev_info(&dev->intf->dev,
                "... iso period %d %sframes, wMaxPacket %04x\n",
index c258a97ef1b0050f41e02d0a8e08b0052af488e7..57dfc0cedb0055cfb28078b7d4da03d42abb37b0 100644 (file)
@@ -75,6 +75,7 @@ config USB_MUSB_TUSB6010
 config USB_MUSB_OMAP2PLUS
        tristate "OMAP2430 and onwards"
        depends on ARCH_OMAP2PLUS
+       select GENERIC_PHY
 
 config USB_MUSB_AM35X
        tristate "AM35x"
@@ -90,7 +91,7 @@ config USB_MUSB_BLACKFIN
        depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523)
 
 config USB_MUSB_UX500
-       tristate "U8500 and U5500"
+       tristate "Ux500 platforms"
 
 endchoice
 
@@ -112,7 +113,7 @@ choice
          allow using DMA on multiplatform kernels.
 
 config USB_UX500_DMA
-       bool 'ST Ericsson U8500 and U5500'
+       bool 'ST Ericsson Ux500'
        depends on USB_MUSB_UX500
        help
          Enable DMA transfers on UX500 platforms.
index 5c310c664218dec6d1e71874ee8dc84f0232fa19..ca45b39db5b91b62d36e61089916ce3910f7af89 100644 (file)
@@ -89,7 +89,6 @@ struct am35x_glue {
        struct clk              *phy_clk;
        struct clk              *clk;
 };
-#define glue_to_musb(g)                platform_get_drvdata(g->musb)
 
 /*
  * am35x_musb_enable - enable interrupts
@@ -452,14 +451,18 @@ static const struct musb_platform_ops am35x_ops = {
        .set_vbus       = am35x_musb_set_vbus,
 };
 
-static u64 am35x_dmamask = DMA_BIT_MASK(32);
+static const struct platform_device_info am35x_dev_info = {
+       .name           = "musb-hdrc",
+       .id             = PLATFORM_DEVID_AUTO,
+       .dma_mask       = DMA_BIT_MASK(32),
+};
 
 static int am35x_probe(struct platform_device *pdev)
 {
        struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
        struct platform_device          *musb;
        struct am35x_glue               *glue;
-
+       struct platform_device_info     pinfo;
        struct clk                      *phy_clk;
        struct clk                      *clk;
 
@@ -471,12 +474,6 @@ static int am35x_probe(struct platform_device *pdev)
                goto err0;
        }
 
-       musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
-       if (!musb) {
-               dev_err(&pdev->dev, "failed to allocate musb device\n");
-               goto err1;
-       }
-
        phy_clk = clk_get(&pdev->dev, "fck");
        if (IS_ERR(phy_clk)) {
                dev_err(&pdev->dev, "failed to get PHY clock\n");
@@ -503,12 +500,7 @@ static int am35x_probe(struct platform_device *pdev)
                goto err6;
        }
 
-       musb->dev.parent                = &pdev->dev;
-       musb->dev.dma_mask              = &am35x_dmamask;
-       musb->dev.coherent_dma_mask     = am35x_dmamask;
-
        glue->dev                       = &pdev->dev;
-       glue->musb                      = musb;
        glue->phy_clk                   = phy_clk;
        glue->clk                       = clk;
 
@@ -516,22 +508,17 @@ static int am35x_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, glue);
 
-       ret = platform_device_add_resources(musb, pdev->resource,
-                       pdev->num_resources);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add resources\n");
-               goto err7;
-       }
-
-       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform_data\n");
-               goto err7;
-       }
-
-       ret = platform_device_add(musb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register musb device\n");
+       pinfo = am35x_dev_info;
+       pinfo.parent = &pdev->dev;
+       pinfo.res = pdev->resource;
+       pinfo.num_res = pdev->num_resources;
+       pinfo.data = pdata;
+       pinfo.size_data = sizeof(*pdata);
+
+       glue->musb = musb = platform_device_register_full(&pinfo);
+       if (IS_ERR(musb)) {
+               ret = PTR_ERR(musb);
+               dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
                goto err7;
        }
 
@@ -550,9 +537,6 @@ err4:
        clk_put(phy_clk);
 
 err3:
-       platform_device_put(musb);
-
-err1:
        kfree(glue);
 
 err0:
@@ -615,23 +599,16 @@ static int am35x_resume(struct device *dev)
 
        return 0;
 }
-
-static struct dev_pm_ops am35x_pm_ops = {
-       .suspend        = am35x_suspend,
-       .resume         = am35x_resume,
-};
-
-#define DEV_PM_OPS     &am35x_pm_ops
-#else
-#define DEV_PM_OPS     NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume);
+
 static struct platform_driver am35x_driver = {
        .probe          = am35x_probe,
        .remove         = am35x_remove,
        .driver         = {
                .name   = "musb-am35x",
-               .pm     = DEV_PM_OPS,
+               .pm     = &am35x_pm_ops,
        },
 };
 
index 72e2056b6082f4c4872b9a7d94c82f59193e00f4..d9692f78e227ead7e79b28becdafda6c275161d8 100644 (file)
@@ -561,23 +561,16 @@ static int bfin_resume(struct device *dev)
 
        return 0;
 }
-
-static struct dev_pm_ops bfin_pm_ops = {
-       .suspend        = bfin_suspend,
-       .resume         = bfin_resume,
-};
-
-#define DEV_PM_OPS     &bfin_pm_ops
-#else
-#define DEV_PM_OPS     NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume);
+
 static struct platform_driver bfin_driver = {
        .probe          = bfin_probe,
        .remove         = __exit_p(bfin_remove),
        .driver         = {
                .name   = "musb-blackfin",
-               .pm     = DEV_PM_OPS,
+               .pm     = &bfin_pm_ops,
        },
 };
 
index d9ddf4122f37e6ddfd19661eb9cb1448306525b6..2f2c1cb364218833f40468429d1469299a56e406 100644 (file)
@@ -472,7 +472,11 @@ static const struct musb_platform_ops da8xx_ops = {
        .set_vbus       = da8xx_musb_set_vbus,
 };
 
-static u64 da8xx_dmamask = DMA_BIT_MASK(32);
+static const struct platform_device_info da8xx_dev_info = {
+       .name           = "musb-hdrc",
+       .id             = PLATFORM_DEVID_AUTO,
+       .dma_mask       = DMA_BIT_MASK(32),
+};
 
 static int da8xx_probe(struct platform_device *pdev)
 {
@@ -480,7 +484,7 @@ static int da8xx_probe(struct platform_device *pdev)
        struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
        struct platform_device          *musb;
        struct da8xx_glue               *glue;
-
+       struct platform_device_info     pinfo;
        struct clk                      *clk;
 
        int                             ret = -ENOMEM;
@@ -491,12 +495,6 @@ static int da8xx_probe(struct platform_device *pdev)
                goto err0;
        }
 
-       musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
-       if (!musb) {
-               dev_err(&pdev->dev, "failed to allocate musb device\n");
-               goto err1;
-       }
-
        clk = clk_get(&pdev->dev, "usb20");
        if (IS_ERR(clk)) {
                dev_err(&pdev->dev, "failed to get clock\n");
@@ -510,12 +508,7 @@ static int da8xx_probe(struct platform_device *pdev)
                goto err4;
        }
 
-       musb->dev.parent                = &pdev->dev;
-       musb->dev.dma_mask              = &da8xx_dmamask;
-       musb->dev.coherent_dma_mask     = da8xx_dmamask;
-
        glue->dev                       = &pdev->dev;
-       glue->musb                      = musb;
        glue->clk                       = clk;
 
        pdata->platform_ops             = &da8xx_ops;
@@ -535,22 +528,17 @@ static int da8xx_probe(struct platform_device *pdev)
        musb_resources[1].end = pdev->resource[1].end;
        musb_resources[1].flags = pdev->resource[1].flags;
 
-       ret = platform_device_add_resources(musb, musb_resources,
-                       ARRAY_SIZE(musb_resources));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add resources\n");
-               goto err5;
-       }
-
-       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform_data\n");
-               goto err5;
-       }
-
-       ret = platform_device_add(musb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register musb device\n");
+       pinfo = da8xx_dev_info;
+       pinfo.parent = &pdev->dev;
+       pinfo.res = musb_resources;
+       pinfo.num_res = ARRAY_SIZE(musb_resources);
+       pinfo.data = pdata;
+       pinfo.size_data = sizeof(*pdata);
+
+       glue->musb = musb = platform_device_register_full(&pinfo);
+       if (IS_ERR(musb)) {
+               ret = PTR_ERR(musb);
+               dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
                goto err5;
        }
 
@@ -563,9 +551,6 @@ err4:
        clk_put(clk);
 
 err3:
-       platform_device_put(musb);
-
-err1:
        kfree(glue);
 
 err0:
index ed0834e2b72eeaa6c9dbe73bdb77c2f433282b42..1121fd741bf8a81e3c4f7a7fc5598dd1dddb948b 100644 (file)
@@ -505,14 +505,19 @@ static const struct musb_platform_ops davinci_ops = {
        .set_vbus       = davinci_musb_set_vbus,
 };
 
-static u64 davinci_dmamask = DMA_BIT_MASK(32);
+static const struct platform_device_info davinci_dev_info = {
+       .name           = "musb-hdrc",
+       .id             = PLATFORM_DEVID_AUTO,
+       .dma_mask       = DMA_BIT_MASK(32),
+};
 
 static int davinci_probe(struct platform_device *pdev)
 {
-       struct resource musb_resources[2];
+       struct resource                 musb_resources[3];
        struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
        struct platform_device          *musb;
        struct davinci_glue             *glue;
+       struct platform_device_info     pinfo;
        struct clk                      *clk;
 
        int                             ret = -ENOMEM;
@@ -523,12 +528,6 @@ static int davinci_probe(struct platform_device *pdev)
                goto err0;
        }
 
-       musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
-       if (!musb) {
-               dev_err(&pdev->dev, "failed to allocate musb device\n");
-               goto err1;
-       }
-
        clk = clk_get(&pdev->dev, "usb");
        if (IS_ERR(clk)) {
                dev_err(&pdev->dev, "failed to get clock\n");
@@ -542,12 +541,7 @@ static int davinci_probe(struct platform_device *pdev)
                goto err4;
        }
 
-       musb->dev.parent                = &pdev->dev;
-       musb->dev.dma_mask              = &davinci_dmamask;
-       musb->dev.coherent_dma_mask     = davinci_dmamask;
-
        glue->dev                       = &pdev->dev;
-       glue->musb                      = musb;
        glue->clk                       = clk;
 
        pdata->platform_ops             = &davinci_ops;
@@ -567,22 +561,26 @@ static int davinci_probe(struct platform_device *pdev)
        musb_resources[1].end = pdev->resource[1].end;
        musb_resources[1].flags = pdev->resource[1].flags;
 
-       ret = platform_device_add_resources(musb, musb_resources,
-                       ARRAY_SIZE(musb_resources));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add resources\n");
-               goto err5;
-       }
-
-       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform_data\n");
-               goto err5;
-       }
-
-       ret = platform_device_add(musb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register musb device\n");
+       /*
+        * For DM6467 3 resources are passed. A placeholder for the 3rd
+        * resource is always there, so it's safe to always copy it...
+        */
+       musb_resources[2].name = pdev->resource[2].name;
+       musb_resources[2].start = pdev->resource[2].start;
+       musb_resources[2].end = pdev->resource[2].end;
+       musb_resources[2].flags = pdev->resource[2].flags;
+
+       pinfo = davinci_dev_info;
+       pinfo.parent = &pdev->dev;
+       pinfo.res = musb_resources;
+       pinfo.num_res = ARRAY_SIZE(musb_resources);
+       pinfo.data = pdata;
+       pinfo.size_data = sizeof(*pdata);
+
+       glue->musb = musb = platform_device_register_full(&pinfo);
+       if (IS_ERR(musb)) {
+               ret = PTR_ERR(musb);
+               dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
                goto err5;
        }
 
@@ -595,9 +593,6 @@ err4:
        clk_put(clk);
 
 err3:
-       platform_device_put(musb);
-
-err1:
        kfree(glue);
 
 err0:
index 41ac5b5b57ceadfdfa5a796c51c4eed445f0f9f1..8be9b02c3cc2a37dce87eaab685a10c1a58d6632 100644 (file)
@@ -46,7 +46,7 @@ static struct platform_driver am335x_child_driver = {
        .remove         = am335x_child_remove,
        .driver         = {
                .name   = "am335x-usb-childs",
-               .of_match_table = of_match_ptr(am335x_child_of_match),
+               .of_match_table = am335x_child_of_match,
        },
 };
 
index cd70cc8861711015f5443e2b76e969209d9bdb3a..0a43329569d178de72a5c8ee619e7206c360c51c 100644 (file)
@@ -617,7 +617,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
                                /* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */
                                default:
                                        s = "VALID"; break;
-                               }; s; }),
+                               } s; }),
                                VBUSERR_RETRY_COUNT - musb->vbuserr_retry,
                                musb->port1_status);
 
@@ -1809,8 +1809,7 @@ static void musb_free(struct musb *musb)
                        disable_irq_wake(musb->nIrq);
                free_irq(musb->nIrq, musb);
        }
-       if (musb->dma_controller)
-               dma_controller_destroy(musb->dma_controller);
+       cancel_work_sync(&musb->irq_work);
 
        musb_host_free(musb);
 }
@@ -1885,8 +1884,13 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
        pm_runtime_get_sync(musb->controller);
 
-       if (use_dma && dev->dma_mask)
+       if (use_dma && dev->dma_mask) {
                musb->dma_controller = dma_controller_create(musb, musb->mregs);
+               if (IS_ERR(musb->dma_controller)) {
+                       status = PTR_ERR(musb->dma_controller);
+                       goto fail2_5;
+               }
+       }
 
        /* be sure interrupts are disabled before connecting ISR */
        musb_platform_disable(musb);
@@ -1946,6 +1950,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
                if (status < 0)
                        goto fail3;
                status = musb_gadget_setup(musb);
+               if (status)
+                       musb_host_cleanup(musb);
                break;
        default:
                dev_err(dev, "unsupported port mode %d\n", musb->port_mode);
@@ -1972,10 +1978,12 @@ fail5:
 
 fail4:
        musb_gadget_cleanup(musb);
+       musb_host_cleanup(musb);
 
 fail3:
        if (musb->dma_controller)
                dma_controller_destroy(musb->dma_controller);
+fail2_5:
        pm_runtime_put_sync(musb->controller);
 
 fail2:
@@ -2032,6 +2040,9 @@ static int musb_remove(struct platform_device *pdev)
        musb_exit_debugfs(musb);
        musb_shutdown(pdev);
 
+       if (musb->dma_controller)
+               dma_controller_destroy(musb->dma_controller);
+
        musb_free(musb);
        device_init_wakeup(dev, 0);
        return 0;
index 1c5bf75ee8ff8a45a3da1fca7cb1d31920f0eeff..29f7cd7c7964e9bf78607de0031396393e84bd44 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/musb.h>
+#include <linux/phy/phy.h>
 
 struct musb;
 struct musb_hw_ep;
@@ -341,6 +342,7 @@ struct musb {
        u16                     int_tx;
 
        struct usb_phy          *xceiv;
+       struct phy              *phy;
 
        int nIrq;
        unsigned                irq_wake:1;
index ae959746f77f04331a1d8dde9d1da57d90af24b8..ff9d6de2b7465c949d54ae4801108a3800f4be3f 100644 (file)
@@ -484,6 +484,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
                if (ret)
                        goto err;
 
+               ret = -EINVAL;
                if (port > MUSB_DMA_NUM_CHANNELS || !port)
                        goto err;
                if (is_tx)
@@ -503,6 +504,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
                dc = dma_request_slave_channel(dev, str);
                if (!dc) {
                        dev_err(dev, "Falied to request %s.\n", str);
+                       ret = -EPROBE_DEFER;
                        goto err;
                }
                cppi41_channel->dc = dc;
@@ -510,7 +512,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
        return 0;
 err:
        cppi41_release_all_dma_chans(controller);
-       return -EINVAL;
+       return ret;
 }
 
 void dma_controller_destroy(struct dma_controller *c)
@@ -526,7 +528,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
                                        void __iomem *base)
 {
        struct cppi41_dma_controller *controller;
-       int ret;
+       int ret = 0;
 
        if (!musb->controller->of_node) {
                dev_err(musb->controller, "Need DT for the DMA engine.\n");
@@ -553,5 +555,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
 plat_get_fail:
        kfree(controller);
 kzalloc_fail:
+       if (ret == -EPROBE_DEFER)
+               return ERR_PTR(ret);
        return NULL;
 }
index bd4138d80a48f243c9d4cb32527196d0024eb3d1..1901f6fe580749c93862910e322af543dd1eb8c7 100644 (file)
@@ -121,6 +121,43 @@ struct dsps_glue {
        unsigned long last_timer;    /* last timer data for each instance */
 };
 
+static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
+{
+       struct device *dev = musb->controller;
+       struct dsps_glue *glue = dev_get_drvdata(dev->parent);
+
+       if (timeout == 0)
+               timeout = jiffies + msecs_to_jiffies(3);
+
+       /* Never idle if active, or when VBUS timeout is not set as host */
+       if (musb->is_active || (musb->a_wait_bcon == 0 &&
+                               musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
+               dev_dbg(musb->controller, "%s active, deleting timer\n",
+                               usb_otg_state_string(musb->xceiv->state));
+               del_timer(&glue->timer);
+               glue->last_timer = jiffies;
+               return;
+       }
+       if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
+               return;
+
+       if (!musb->g.dev.driver)
+               return;
+
+       if (time_after(glue->last_timer, timeout) &&
+                               timer_pending(&glue->timer)) {
+               dev_dbg(musb->controller,
+                       "Longer idle timer already pending, ignoring...\n");
+               return;
+       }
+       glue->last_timer = timeout;
+
+       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
+               usb_otg_state_string(musb->xceiv->state),
+                       jiffies_to_msecs(timeout - jiffies));
+       mod_timer(&glue->timer, timeout);
+}
+
 /**
  * dsps_musb_enable - enable interrupts
  */
@@ -143,6 +180,7 @@ static void dsps_musb_enable(struct musb *musb)
        /* Force the DRVVBUS IRQ so we can start polling for ID change. */
        dsps_writel(reg_base, wrp->coreintr_set,
                    (1 << wrp->drvvbus) << wrp->usb_shift);
+       dsps_musb_try_idle(musb, 0);
 }
 
 /**
@@ -171,6 +209,7 @@ static void otg_timer(unsigned long _musb)
        const struct dsps_musb_wrapper *wrp = glue->wrp;
        u8 devctl;
        unsigned long flags;
+       int skip_session = 0;
 
        /*
         * We poll because DSPS IP's won't expose several OTG-critical
@@ -183,10 +222,12 @@ static void otg_timer(unsigned long _musb)
        spin_lock_irqsave(&musb->lock, flags);
        switch (musb->xceiv->state) {
        case OTG_STATE_A_WAIT_BCON:
-               devctl &= ~MUSB_DEVCTL_SESSION;
-               dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+               dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
+               skip_session = 1;
+               /* fall */
 
-               devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
+       case OTG_STATE_A_IDLE:
+       case OTG_STATE_B_IDLE:
                if (devctl & MUSB_DEVCTL_BDEVICE) {
                        musb->xceiv->state = OTG_STATE_B_IDLE;
                        MUSB_DEV_MODE(musb);
@@ -194,60 +235,21 @@ static void otg_timer(unsigned long _musb)
                        musb->xceiv->state = OTG_STATE_A_IDLE;
                        MUSB_HST_MODE(musb);
                }
+               if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session)
+                       dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
+               mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
                break;
        case OTG_STATE_A_WAIT_VFALL:
                musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
                dsps_writel(musb->ctrl_base, wrp->coreintr_set,
                            MUSB_INTR_VBUSERROR << wrp->usb_shift);
                break;
-       case OTG_STATE_B_IDLE:
-               devctl = dsps_readb(mregs, MUSB_DEVCTL);
-               if (devctl & MUSB_DEVCTL_BDEVICE)
-                       mod_timer(&glue->timer,
-                                       jiffies + wrp->poll_seconds * HZ);
-               else
-                       musb->xceiv->state = OTG_STATE_A_IDLE;
-               break;
        default:
                break;
        }
        spin_unlock_irqrestore(&musb->lock, flags);
 }
 
-static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
-{
-       struct device *dev = musb->controller;
-       struct dsps_glue *glue = dev_get_drvdata(dev->parent);
-
-       if (timeout == 0)
-               timeout = jiffies + msecs_to_jiffies(3);
-
-       /* Never idle if active, or when VBUS timeout is not set as host */
-       if (musb->is_active || (musb->a_wait_bcon == 0 &&
-                               musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
-               dev_dbg(musb->controller, "%s active, deleting timer\n",
-                               usb_otg_state_string(musb->xceiv->state));
-               del_timer(&glue->timer);
-               glue->last_timer = jiffies;
-               return;
-       }
-       if (musb->port_mode == MUSB_PORT_MODE_HOST)
-               return;
-
-       if (time_after(glue->last_timer, timeout) &&
-                               timer_pending(&glue->timer)) {
-               dev_dbg(musb->controller,
-                       "Longer idle timer already pending, ignoring...\n");
-               return;
-       }
-       glue->last_timer = timeout;
-
-       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
-               usb_otg_state_string(musb->xceiv->state),
-                       jiffies_to_msecs(timeout - jiffies));
-       mod_timer(&glue->timer, timeout);
-}
-
 static irqreturn_t dsps_interrupt(int irq, void *hci)
 {
        struct musb  *musb = hci;
@@ -443,7 +445,7 @@ static int get_musb_port_mode(struct device *dev)
        case USB_DR_MODE_OTG:
        default:
                return MUSB_PORT_MODE_DUAL_ROLE;
-       };
+       }
 }
 
 static int dsps_create_musb_pdev(struct dsps_glue *glue,
@@ -631,7 +633,7 @@ static struct platform_driver dsps_usbss_driver = {
        .remove         = dsps_remove,
        .driver         = {
                .name   = "musb-dsps",
-               .of_match_table = of_match_ptr(musb_dsps_of_match),
+               .of_match_table = musb_dsps_of_match,
        },
 };
 
index 3671898a4535b3cf2de3c0e188f4947485d2760d..d2d3a173b31503b54f9071e9af48f4878567856f 100644 (file)
@@ -1121,7 +1121,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
                        case USB_ENDPOINT_XFER_BULK:    s = "bulk"; break;
                        case USB_ENDPOINT_XFER_INT:     s = "int"; break;
                        default:                        s = "iso"; break;
-                       }; s; }),
+                       } s; }),
                        musb_ep->is_in ? "IN" : "OUT",
                        musb_ep->dma ? "dma, " : "",
                        musb_ep->packet_sz);
index 9a2b8c85f19af4ea05bca5c1e90fe08ac345f22b..6582a20bec05db6be2730f6ffee4f3677e6b2340 100644 (file)
@@ -253,7 +253,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
                        case USB_ENDPOINT_XFER_BULK:    s = "-bulk"; break;
                        case USB_ENDPOINT_XFER_ISOC:    s = "-iso"; break;
                        default:                        s = "-intr"; break;
-                       }; s; }),
+                       } s; }),
                        epnum, buf + offset, len);
 
        /* Configure endpoint */
index d1d6b83aabca61df43dffccf57ccbe7687cbe399..9af6bba5eac964bb7195e78815b22bc1958c6c3c 100644 (file)
@@ -220,6 +220,23 @@ int musb_hub_status_data(struct usb_hcd *hcd, char *buf)
        return retval;
 }
 
+static int musb_has_gadget(struct musb *musb)
+{
+       /*
+        * In host-only mode we start a connection right away. In OTG mode
+        * we have to wait until we loaded a gadget. We don't really need a
+        * gadget if we operate as a host but we should not start a session
+        * as a device without a gadget or else we explode.
+        */
+#ifdef CONFIG_USB_MUSB_HOST
+       return 1;
+#else
+       if (musb->port_mode == MUSB_PORT_MODE_HOST)
+               return 1;
+       return musb->g.dev.driver != NULL;
+#endif
+}
+
 int musb_hub_control(
        struct usb_hcd  *hcd,
        u16             typeReq,
@@ -362,7 +379,7 @@ int musb_hub_control(
                         * initialization logic, e.g. for OTG, or change any
                         * logic relating to VBUS power-up.
                         */
-                       if (!hcd->self.is_b_host)
+                       if (!hcd->self.is_b_host && musb_has_gadget(musb))
                                musb_start(musb);
                        break;
                case USB_PORT_FEAT_RESET:
index 59d2245db1c81ce228d7607aa1176e56bbfb9082..2a408cdaf7b2c7102098faac6d29727505f41c91 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/usb/musb-omap.h>
 #include <linux/usb/omap_control_usb.h>
+#include <linux/of_platform.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
@@ -305,6 +306,9 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
        default:
                dev_dbg(dev, "ID float\n");
        }
+
+       atomic_notifier_call_chain(&musb->xceiv->notifier,
+                       musb->xceiv->last_event, NULL);
 }
 
 
@@ -348,11 +352,21 @@ static int omap2430_musb_init(struct musb *musb)
         * up through ULPI.  TWL4030-family PMICs include one,
         * which needs a driver, drivers aren't always needed.
         */
-       if (dev->parent->of_node)
+       if (dev->parent->of_node) {
+               musb->phy = devm_phy_get(dev->parent, "usb2-phy");
+
+               /* We can't totally remove musb->xceiv as of now because
+                * musb core uses xceiv.state and xceiv.otg. Once we have
+                * a separate state machine to handle otg, these can be moved
+                * out of xceiv and then we can start using the generic PHY
+                * framework
+                */
                musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
                    "usb-phy", 0);
-       else
+       } else {
                musb->xceiv = devm_usb_get_phy_dev(dev, 0);
+               musb->phy = devm_phy_get(dev, "usb");
+       }
 
        if (IS_ERR(musb->xceiv)) {
                status = PTR_ERR(musb->xceiv);
@@ -364,6 +378,10 @@ static int omap2430_musb_init(struct musb *musb)
                return -EPROBE_DEFER;
        }
 
+       if (IS_ERR(musb->phy)) {
+               pr_err("HS USB OTG: no PHY configured\n");
+               return PTR_ERR(musb->phy);
+       }
        musb->isr = omap2430_musb_interrupt;
 
        status = pm_runtime_get_sync(dev);
@@ -397,7 +415,7 @@ static int omap2430_musb_init(struct musb *musb)
        if (glue->status != OMAP_MUSB_UNKNOWN)
                omap_musb_set_mailbox(glue);
 
-       usb_phy_init(musb->xceiv);
+       phy_init(musb->phy);
 
        pm_runtime_put_noidle(musb->controller);
        return 0;
@@ -460,6 +478,7 @@ static int omap2430_musb_exit(struct musb *musb)
        del_timer_sync(&musb_idle_timer);
 
        omap2430_low_level_exit(musb);
+       phy_exit(musb->phy);
 
        return 0;
 }
@@ -509,8 +528,12 @@ static int omap2430_probe(struct platform_device *pdev)
        glue->dev                       = &pdev->dev;
        glue->musb                      = musb;
        glue->status                    = OMAP_MUSB_UNKNOWN;
+       glue->control_otghs = ERR_PTR(-ENODEV);
 
        if (np) {
+               struct device_node *control_node;
+               struct platform_device *control_pdev;
+
                pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
                if (!pdata) {
                        dev_err(&pdev->dev,
@@ -539,22 +562,20 @@ static int omap2430_probe(struct platform_device *pdev)
                of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
                of_property_read_u32(np, "power", (u32 *)&pdata->power);
                config->multipoint = of_property_read_bool(np, "multipoint");
-               pdata->has_mailbox = of_property_read_bool(np,
-                   "ti,has-mailbox");
 
                pdata->board_data       = data;
                pdata->config           = config;
-       }
 
-       if (pdata->has_mailbox) {
-               glue->control_otghs = omap_get_control_dev();
-               if (IS_ERR(glue->control_otghs)) {
-                       dev_vdbg(&pdev->dev, "Failed to get control device\n");
-                       ret = PTR_ERR(glue->control_otghs);
-                       goto err2;
+               control_node = of_parse_phandle(np, "ctrl-module", 0);
+               if (control_node) {
+                       control_pdev = of_find_device_by_node(control_node);
+                       if (!control_pdev) {
+                               dev_err(&pdev->dev, "Failed to get control device\n");
+                               ret = -EINVAL;
+                               goto err2;
+                       }
+                       glue->control_otghs = &control_pdev->dev;
                }
-       } else {
-               glue->control_otghs = ERR_PTR(-ENODEV);
        }
        pdata->platform_ops             = &omap2430_ops;
 
@@ -638,7 +659,7 @@ static int omap2430_runtime_suspend(struct device *dev)
                                OTG_INTERFSEL);
 
                omap2430_low_level_exit(musb);
-               usb_phy_set_suspend(musb->xceiv, 1);
+               phy_power_off(musb->phy);
        }
 
        return 0;
@@ -653,8 +674,7 @@ static int omap2430_runtime_resume(struct device *dev)
                omap2430_low_level_init(musb);
                musb_writel(musb->mregs, OTG_INTERFSEL,
                                musb->context.otg_interfsel);
-
-               usb_phy_set_suspend(musb->xceiv, 0);
+               phy_power_on(musb->phy);
        }
 
        return 0;
index b3b3ed723882ffab75829e7c9bc1b08b42e1605d..4432314d70ee18f1dfe0e092c487dcab224c1742 100644 (file)
@@ -1152,7 +1152,11 @@ static const struct musb_platform_ops tusb_ops = {
        .set_vbus       = tusb_musb_set_vbus,
 };
 
-static u64 tusb_dmamask = DMA_BIT_MASK(32);
+static const struct platform_device_info tusb_dev_info = {
+       .name           = "musb-hdrc",
+       .id             = PLATFORM_DEVID_AUTO,
+       .dma_mask       = DMA_BIT_MASK(32),
+};
 
 static int tusb_probe(struct platform_device *pdev)
 {
@@ -1160,7 +1164,7 @@ static int tusb_probe(struct platform_device *pdev)
        struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
        struct platform_device          *musb;
        struct tusb6010_glue            *glue;
-
+       struct platform_device_info     pinfo;
        int                             ret = -ENOMEM;
 
        glue = kzalloc(sizeof(*glue), GFP_KERNEL);
@@ -1169,18 +1173,7 @@ static int tusb_probe(struct platform_device *pdev)
                goto err0;
        }
 
-       musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
-       if (!musb) {
-               dev_err(&pdev->dev, "failed to allocate musb device\n");
-               goto err1;
-       }
-
-       musb->dev.parent                = &pdev->dev;
-       musb->dev.dma_mask              = &tusb_dmamask;
-       musb->dev.coherent_dma_mask     = tusb_dmamask;
-
        glue->dev                       = &pdev->dev;
-       glue->musb                      = musb;
 
        pdata->platform_ops             = &tusb_ops;
 
@@ -1204,31 +1197,23 @@ static int tusb_probe(struct platform_device *pdev)
        musb_resources[2].end = pdev->resource[2].end;
        musb_resources[2].flags = pdev->resource[2].flags;
 
-       ret = platform_device_add_resources(musb, musb_resources,
-                       ARRAY_SIZE(musb_resources));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add resources\n");
-               goto err3;
-       }
-
-       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform_data\n");
-               goto err3;
-       }
-
-       ret = platform_device_add(musb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register musb device\n");
+       pinfo = tusb_dev_info;
+       pinfo.parent = &pdev->dev;
+       pinfo.res = musb_resources;
+       pinfo.num_res = ARRAY_SIZE(musb_resources);
+       pinfo.data = pdata;
+       pinfo.size_data = sizeof(*pdata);
+
+       glue->musb = musb = platform_device_register_full(&pinfo);
+       if (IS_ERR(musb)) {
+               ret = PTR_ERR(musb);
+               dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
                goto err3;
        }
 
        return 0;
 
 err3:
-       platform_device_put(musb);
-
-err1:
        kfree(glue);
 
 err0:
index 59256b12f7469fe9170ec0fa7db0bee3cbbed6da..122446bf166403fc08523eb6ba7161a17b1a8082 100644 (file)
@@ -259,7 +259,7 @@ static int ux500_probe(struct platform_device *pdev)
                goto err1;
        }
 
-       clk = clk_get(&pdev->dev, "usb");
+       clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(clk)) {
                dev_err(&pdev->dev, "failed to get clock\n");
                ret = PTR_ERR(clk);
@@ -376,17 +376,10 @@ static int ux500_resume(struct device *dev)
 
        return 0;
 }
-
-static const struct dev_pm_ops ux500_pm_ops = {
-       .suspend        = ux500_suspend,
-       .resume         = ux500_resume,
-};
-
-#define DEV_PM_OPS     (&ux500_pm_ops)
-#else
-#define DEV_PM_OPS     NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume);
+
 static const struct of_device_id ux500_match[] = {
         { .compatible = "stericsson,db8500-musb", },
         {}
@@ -397,7 +390,7 @@ static struct platform_driver ux500_driver = {
        .remove         = ux500_remove,
        .driver         = {
                .name   = "musb-ux500",
-               .pm     = DEV_PM_OPS,
+               .pm     = &ux500_pm_ops,
                .of_match_table = ux500_match,
        },
 };
index d5589f9c60a92e3c96757c8a6ba1fd6a171e01b1..08e2f39027ec00ae0a7c5ae07b46fdd1cdbfae8f 100644 (file)
@@ -66,17 +66,6 @@ config OMAP_CONTROL_USB
          power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
          additional register to power on USB3 PHY.
 
-config OMAP_USB2
-       tristate "OMAP USB2 PHY Driver"
-       depends on ARCH_OMAP2PLUS
-       select OMAP_CONTROL_USB
-       select USB_PHY
-       help
-         Enable this to support the transceiver that is part of SOC. This
-         driver takes care of all the PHY functionality apart from comparator.
-         The USB OTG controller communicates with the comparator using this
-         driver.
-
 config OMAP_USB3
        tristate "OMAP USB3 PHY Driver"
        depends on ARCH_OMAP2PLUS || COMPILE_TEST
@@ -93,6 +82,7 @@ config AM335X_CONTROL_USB
 
 config AM335X_PHY_USB
        tristate "AM335x USB PHY Driver"
+       depends on ARM || COMPILE_TEST
        select USB_PHY
        select AM335X_CONTROL_USB
        select NOP_USB_XCEIV
@@ -123,16 +113,6 @@ config SAMSUNG_USB3PHY
          Enable this to support Samsung USB 3.0 (Super Speed) phy controller
          for samsung SoCs.
 
-config TWL4030_USB
-       tristate "TWL4030 USB Transceiver Driver"
-       depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
-       select USB_PHY
-       help
-         Enable this to support the USB OTG transceiver on TWL4030
-         family chips (including the TWL5030 and TPS659x0 devices).
-         This transceiver supports high and full speed devices plus,
-         in host mode, low speed.
-
 config TWL6030_USB
        tristate "TWL6030 USB Transceiver Driver"
        depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
@@ -214,6 +194,19 @@ config USB_RCAR_PHY
          To compile this driver as a module, choose M here: the
          module will be called phy-rcar-usb.
 
+config USB_RCAR_GEN2_PHY
+       tristate "Renesas R-Car Gen2 USB PHY support"
+       depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST
+       select USB_PHY
+       help
+         Say Y here to add support for the Renesas R-Car Gen2 USB PHY driver.
+         It is typically used to control internal USB PHY for USBHS,
+         and to configure shared USB channels 0 and 2.
+         This driver supports R8A7790 and R8A7791.
+
+         To compile this driver as a module, choose M here: the
+         module will be called phy-rcar-gen2-usb.
+
 config USB_ULPI
        bool "Generic ULPI Transceiver Driver"
        depends on ARM
index 2135e85f46eda29f104940467154a789db870683..022c1da7fb786ffb8a1228e6fc890d442941e9ae 100644 (file)
@@ -15,12 +15,10 @@ obj-$(CONFIG_NOP_USB_XCEIV)         += phy-generic.o
 obj-$(CONFIG_OMAP_CONTROL_USB)         += phy-omap-control.o
 obj-$(CONFIG_AM335X_CONTROL_USB)       += phy-am335x-control.o
 obj-$(CONFIG_AM335X_PHY_USB)           += phy-am335x.o
-obj-$(CONFIG_OMAP_USB2)                        += phy-omap-usb2.o
 obj-$(CONFIG_OMAP_USB3)                        += phy-omap-usb3.o
 obj-$(CONFIG_SAMSUNG_USBPHY)           += phy-samsung-usb.o
 obj-$(CONFIG_SAMSUNG_USB2PHY)          += phy-samsung-usb2.o
 obj-$(CONFIG_SAMSUNG_USB3PHY)          += phy-samsung-usb3.o
-obj-$(CONFIG_TWL4030_USB)              += phy-twl4030-usb.o
 obj-$(CONFIG_TWL6030_USB)              += phy-twl6030-usb.o
 obj-$(CONFIG_USB_EHCI_TEGRA)           += phy-tegra-usb.o
 obj-$(CONFIG_USB_GPIO_VBUS)            += phy-gpio-vbus-usb.o
@@ -29,5 +27,6 @@ obj-$(CONFIG_USB_MSM_OTG)             += phy-msm-usb.o
 obj-$(CONFIG_USB_MV_OTG)               += phy-mv-usb.o
 obj-$(CONFIG_USB_MXS_PHY)              += phy-mxs-usb.o
 obj-$(CONFIG_USB_RCAR_PHY)             += phy-rcar-usb.o
+obj-$(CONFIG_USB_RCAR_GEN2_PHY)                += phy-rcar-gen2-usb.o
 obj-$(CONFIG_USB_ULPI)                 += phy-ulpi.o
 obj-$(CONFIG_USB_ULPI_VIEWPORT)                += phy-ulpi-viewport.o
index 22cf07d62e4c68f04378b18a70555eb782ba25ff..634f49acd20e58154d02177c4e49781e51754c8d 100644 (file)
@@ -26,6 +26,41 @@ struct am335x_control_usb {
 #define USBPHY_OTGVDET_EN      (1 << 19)
 #define USBPHY_OTGSESSEND_EN   (1 << 20)
 
+#define AM335X_PHY0_WK_EN      (1 << 0)
+#define AM335X_PHY1_WK_EN      (1 << 8)
+
+static void am335x_phy_wkup(struct  phy_control *phy_ctrl, u32 id, bool on)
+{
+       struct am335x_control_usb *usb_ctrl;
+       u32 val;
+       u32 reg;
+
+       usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl);
+
+       switch (id) {
+       case 0:
+               reg = AM335X_PHY0_WK_EN;
+               break;
+       case 1:
+               reg = AM335X_PHY1_WK_EN;
+               break;
+       default:
+               WARN_ON(1);
+               return;
+       }
+
+       spin_lock(&usb_ctrl->lock);
+       val = readl(usb_ctrl->wkup);
+
+       if (on)
+               val |= reg;
+       else
+               val &= ~reg;
+
+       writel(val, usb_ctrl->wkup);
+       spin_unlock(&usb_ctrl->lock);
+}
+
 static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
 {
        struct am335x_control_usb *usb_ctrl;
@@ -59,6 +94,7 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
 
 static const struct phy_control ctrl_am335x = {
        .phy_power = am335x_phy_power,
+       .phy_wkup = am335x_phy_wkup,
 };
 
 static const struct of_device_id omap_control_usb_id_table[] = {
@@ -117,6 +153,12 @@ static int am335x_control_usb_probe(struct platform_device *pdev)
        ctrl_usb->phy_reg = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(ctrl_usb->phy_reg))
                return PTR_ERR(ctrl_usb->phy_reg);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wakeup");
+       ctrl_usb->wkup = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(ctrl_usb->wkup))
+               return PTR_ERR(ctrl_usb->wkup);
+
        spin_lock_init(&ctrl_usb->lock);
        ctrl_usb->phy_ctrl = *phy_ctrl;
 
@@ -129,7 +171,7 @@ static struct platform_driver am335x_control_driver = {
        .driver         = {
                .name   = "am335x-control-usb",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(omap_control_usb_id_table),
+               .of_match_table = omap_control_usb_id_table,
        },
 };
 
index c4d614d1f17349972d3f629a45949c2e2addef9f..6370e50649d7f732c640fd65879c26d82ec5f994 100644 (file)
@@ -53,21 +53,20 @@ static int am335x_phy_probe(struct platform_device *pdev)
        }
 
        ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen,
-                       USB_PHY_TYPE_USB2, 0, false, false);
+                       USB_PHY_TYPE_USB2, 0, false);
        if (ret)
                return ret;
 
        ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy);
        if (ret)
-               goto err_add;
+               return ret;
        am_phy->usb_phy_gen.phy.init = am335x_init;
        am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown;
 
        platform_set_drvdata(pdev, am_phy);
+
        return 0;
 
-err_add:
-       usb_phy_gen_cleanup_phy(&am_phy->usb_phy_gen);
        return ret;
 }
 
@@ -79,6 +78,40 @@ static int am335x_phy_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
+
+static int am335x_phy_runtime_suspend(struct device *dev)
+{
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct am335x_phy *am_phy = platform_get_drvdata(pdev);
+
+       if (device_may_wakeup(dev))
+               phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true);
+       phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false);
+       return 0;
+}
+
+static int am335x_phy_runtime_resume(struct device *dev)
+{
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct am335x_phy       *am_phy = platform_get_drvdata(pdev);
+
+       phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true);
+       if (device_may_wakeup(dev))
+               phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false);
+       return 0;
+}
+
+static const struct dev_pm_ops am335x_pm_ops = {
+       SET_RUNTIME_PM_OPS(am335x_phy_runtime_suspend,
+                       am335x_phy_runtime_resume, NULL)
+};
+
+#define DEV_PM_OPS     (&am335x_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
 static const struct of_device_id am335x_phy_ids[] = {
        { .compatible = "ti,am335x-usb-phy" },
        { }
@@ -91,7 +124,8 @@ static struct platform_driver am335x_phy_driver = {
        .driver         = {
                .name   = "am335x-phy-driver",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(am335x_phy_ids),
+               .pm = DEV_PM_OPS,
+               .of_match_table = am335x_phy_ids,
        },
 };
 
index fa7c9f9628b599e072b7062ff03270c35714161f..7f3c73b967ce6faf804ee1f29b82acbdde1f59f1 100644 (file)
@@ -134,7 +134,7 @@ int write_ulpi(u8 addr, u8 data)
 /* Operations that will be called from OTG Finite State Machine */
 
 /* Charge vbus for vbus pulsing in SRP */
-void fsl_otg_chrg_vbus(int on)
+void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on)
 {
        u32 tmp;
 
@@ -170,7 +170,7 @@ void fsl_otg_dischrg_vbus(int on)
 }
 
 /* A-device driver vbus, controlled through PP bit in PORTSC */
-void fsl_otg_drv_vbus(int on)
+void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on)
 {
        u32 tmp;
 
@@ -188,7 +188,7 @@ void fsl_otg_drv_vbus(int on)
  * Pull-up D+, signalling connect by periperal. Also used in
  * data-line pulsing in SRP
  */
-void fsl_otg_loc_conn(int on)
+void fsl_otg_loc_conn(struct otg_fsm *fsm, int on)
 {
        u32 tmp;
 
@@ -207,7 +207,7 @@ void fsl_otg_loc_conn(int on)
  * port.  In host mode, controller will automatically send SOF.
  * Suspend will block the data on the port.
  */
-void fsl_otg_loc_sof(int on)
+void fsl_otg_loc_sof(struct otg_fsm *fsm, int on)
 {
        u32 tmp;
 
@@ -222,7 +222,7 @@ void fsl_otg_loc_sof(int on)
 }
 
 /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */
-void fsl_otg_start_pulse(void)
+void fsl_otg_start_pulse(struct otg_fsm *fsm)
 {
        u32 tmp;
 
@@ -235,7 +235,7 @@ void fsl_otg_start_pulse(void)
        fsl_otg_loc_conn(1);
 #endif
 
-       fsl_otg_add_timer(b_data_pulse_tmr);
+       fsl_otg_add_timer(fsm, b_data_pulse_tmr);
 }
 
 void b_data_pulse_end(unsigned long foo)
@@ -252,14 +252,14 @@ void b_data_pulse_end(unsigned long foo)
 void fsl_otg_pulse_vbus(void)
 {
        srp_wait_done = 0;
-       fsl_otg_chrg_vbus(1);
+       fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1);
        /* start the timer to end vbus charge */
-       fsl_otg_add_timer(b_vbus_pulse_tmr);
+       fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr);
 }
 
 void b_vbus_pulse_end(unsigned long foo)
 {
-       fsl_otg_chrg_vbus(0);
+       fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0);
 
        /*
         * As USB3300 using the same a_sess_vld and b_sess_vld voltage
@@ -267,7 +267,7 @@ void b_vbus_pulse_end(unsigned long foo)
         * residual voltage of vbus pulsing and A device pull up
         */
        fsl_otg_dischrg_vbus(1);
-       fsl_otg_add_timer(b_srp_wait_tmr);
+       fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr);
 }
 
 void b_srp_end(unsigned long foo)
@@ -289,7 +289,7 @@ void a_wait_enum(unsigned long foo)
 {
        VDBG("a_wait_enum timeout\n");
        if (!fsl_otg_dev->phy.otg->host->b_hnp_enable)
-               fsl_otg_add_timer(a_wait_enum_tmr);
+               fsl_otg_add_timer(&fsl_otg_dev->fsm, a_wait_enum_tmr);
        else
                otg_statemachine(&fsl_otg_dev->fsm);
 }
@@ -375,8 +375,42 @@ void fsl_otg_uninit_timers(void)
        kfree(b_vbus_pulse_tmr);
 }
 
+static struct fsl_otg_timer *fsl_otg_get_timer(enum otg_fsm_timer t)
+{
+       struct fsl_otg_timer *timer;
+
+       /* REVISIT: use array of pointers to timers instead */
+       switch (t) {
+       case A_WAIT_VRISE:
+               timer = a_wait_vrise_tmr;
+               break;
+       case A_WAIT_BCON:
+               timer = a_wait_vrise_tmr;
+               break;
+       case A_AIDL_BDIS:
+               timer = a_wait_vrise_tmr;
+               break;
+       case B_ASE0_BRST:
+               timer = a_wait_vrise_tmr;
+               break;
+       case B_SE0_SRP:
+               timer = a_wait_vrise_tmr;
+               break;
+       case B_SRP_FAIL:
+               timer = a_wait_vrise_tmr;
+               break;
+       case A_WAIT_ENUM:
+               timer = a_wait_vrise_tmr;
+               break;
+       default:
+               timer = NULL;
+       }
+
+       return timer;
+}
+
 /* Add timer to timer list */
-void fsl_otg_add_timer(void *gtimer)
+void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer)
 {
        struct fsl_otg_timer *timer = gtimer;
        struct fsl_otg_timer *tmp_timer;
@@ -394,8 +428,19 @@ void fsl_otg_add_timer(void *gtimer)
        list_add_tail(&timer->list, &active_timers);
 }
 
+static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
+{
+       struct fsl_otg_timer *timer;
+
+       timer = fsl_otg_get_timer(t);
+       if (!timer)
+               return;
+
+       fsl_otg_add_timer(fsm, timer);
+}
+
 /* Remove timer from the timer list; clear timeout status */
-void fsl_otg_del_timer(void *gtimer)
+void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer)
 {
        struct fsl_otg_timer *timer = gtimer;
        struct fsl_otg_timer *tmp_timer, *del_tmp;
@@ -405,6 +450,17 @@ void fsl_otg_del_timer(void *gtimer)
                        list_del(&timer->list);
 }
 
+static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
+{
+       struct fsl_otg_timer *timer;
+
+       timer = fsl_otg_get_timer(t);
+       if (!timer)
+               return;
+
+       fsl_otg_del_timer(fsm, timer);
+}
+
 /*
  * Reduce timer count by 1, and find timeout conditions.
  * Called by fsl_otg 1ms timer interrupt
@@ -468,7 +524,7 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on)
                                retval = dev->driver->pm->resume(dev);
                                if (fsm->id) {
                                        /* default-b */
-                                       fsl_otg_drv_vbus(1);
+                                       fsl_otg_drv_vbus(fsm, 1);
                                        /*
                                         * Workaround: b_host can't driver
                                         * vbus, but PP in PORTSC needs to
@@ -493,7 +549,7 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on)
                                        retval = dev->driver->pm->suspend(dev);
                                if (fsm->id)
                                        /* default-b */
-                                       fsl_otg_drv_vbus(0);
+                                       fsl_otg_drv_vbus(fsm, 0);
                        }
                        otg_dev->host_working = 0;
                }
@@ -757,8 +813,8 @@ static struct otg_fsm_ops fsl_otg_ops = {
        .loc_sof = fsl_otg_loc_sof,
        .start_pulse = fsl_otg_start_pulse,
 
-       .add_timer = fsl_otg_add_timer,
-       .del_timer = fsl_otg_del_timer,
+       .add_timer = fsl_otg_fsm_add_timer,
+       .del_timer = fsl_otg_fsm_del_timer,
 
        .start_host = fsl_otg_start_host,
        .start_gadget = fsl_otg_start_gadget,
@@ -1011,7 +1067,7 @@ static int show_fsl_usb2_otg_state(struct device *dev,
                        "b_bus_suspend: %d\n"
                        "b_conn: %d\n"
                        "b_se0_srp: %d\n"
-                       "b_sess_end: %d\n"
+                       "b_ssend_srp: %d\n"
                        "b_sess_vld: %d\n"
                        "id: %d\n",
                        fsm->a_bus_req,
@@ -1026,7 +1082,7 @@ static int show_fsl_usb2_otg_state(struct device *dev,
                        fsm->b_bus_suspend,
                        fsm->b_conn,
                        fsm->b_se0_srp,
-                       fsm->b_sess_end,
+                       fsm->b_ssend_srp,
                        fsm->b_sess_vld,
                        fsm->id);
        size -= t;
@@ -1057,7 +1113,7 @@ static long fsl_otg_ioctl(struct file *file, unsigned int cmd,
                break;
 
        case SET_A_SUSPEND_REQ:
-               fsl_otg_dev->fsm.a_suspend_req = arg;
+               fsl_otg_dev->fsm.a_suspend_req_inf = arg;
                break;
 
        case SET_A_BUS_DROP:
index e1859b8ef5679dc5c39a367c7e86979a2cfde5ec..7365170a2f23eb482693762edd1aceac034c1702 100644 (file)
@@ -401,6 +401,6 @@ struct fsl_otg_config {
 #define GET_A_BUS_REQ          _IOR(OTG_IOCTL_MAGIC, 8, int)
 #define GET_B_BUS_REQ          _IOR(OTG_IOCTL_MAGIC, 9, int)
 
-void fsl_otg_add_timer(void *timer);
-void fsl_otg_del_timer(void *timer);
+void fsl_otg_add_timer(struct otg_fsm *fsm, void *timer);
+void fsl_otg_del_timer(struct otg_fsm *fsm, void *timer);
 void fsl_otg_pulse_vbus(void);
index 7f4596606e18b41565ef338598298b6f36c64269..329c2d2f85959963c7828d3d9332315062480623 100644 (file)
@@ -41,17 +41,17 @@ static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
                        fsm->protocol, protocol);
                /* stop old protocol */
                if (fsm->protocol == PROTO_HOST)
-                       ret = fsm->ops->start_host(fsm, 0);
+                       ret = otg_start_host(fsm, 0);
                else if (fsm->protocol == PROTO_GADGET)
-                       ret = fsm->ops->start_gadget(fsm, 0);
+                       ret = otg_start_gadget(fsm, 0);
                if (ret)
                        return ret;
 
                /* start new protocol */
                if (protocol == PROTO_HOST)
-                       ret = fsm->ops->start_host(fsm, 1);
+                       ret = otg_start_host(fsm, 1);
                else if (protocol == PROTO_GADGET)
-                       ret = fsm->ops->start_gadget(fsm, 1);
+                       ret = otg_start_gadget(fsm, 1);
                if (ret)
                        return ret;
 
@@ -69,42 +69,50 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
 {
        switch (old_state) {
        case OTG_STATE_B_IDLE:
-               otg_del_timer(fsm, b_se0_srp_tmr);
+               otg_del_timer(fsm, B_SE0_SRP);
                fsm->b_se0_srp = 0;
+               fsm->adp_sns = 0;
+               fsm->adp_prb = 0;
                break;
        case OTG_STATE_B_SRP_INIT:
+               fsm->data_pulse = 0;
                fsm->b_srp_done = 0;
                break;
        case OTG_STATE_B_PERIPHERAL:
                break;
        case OTG_STATE_B_WAIT_ACON:
-               otg_del_timer(fsm, b_ase0_brst_tmr);
+               otg_del_timer(fsm, B_ASE0_BRST);
                fsm->b_ase0_brst_tmout = 0;
                break;
        case OTG_STATE_B_HOST:
                break;
        case OTG_STATE_A_IDLE:
+               fsm->adp_prb = 0;
                break;
        case OTG_STATE_A_WAIT_VRISE:
-               otg_del_timer(fsm, a_wait_vrise_tmr);
+               otg_del_timer(fsm, A_WAIT_VRISE);
                fsm->a_wait_vrise_tmout = 0;
                break;
        case OTG_STATE_A_WAIT_BCON:
-               otg_del_timer(fsm, a_wait_bcon_tmr);
+               otg_del_timer(fsm, A_WAIT_BCON);
                fsm->a_wait_bcon_tmout = 0;
                break;
        case OTG_STATE_A_HOST:
-               otg_del_timer(fsm, a_wait_enum_tmr);
+               otg_del_timer(fsm, A_WAIT_ENUM);
                break;
        case OTG_STATE_A_SUSPEND:
-               otg_del_timer(fsm, a_aidl_bdis_tmr);
+               otg_del_timer(fsm, A_AIDL_BDIS);
                fsm->a_aidl_bdis_tmout = 0;
-               fsm->a_suspend_req = 0;
+               fsm->a_suspend_req_inf = 0;
                break;
        case OTG_STATE_A_PERIPHERAL:
+               otg_del_timer(fsm, A_BIDL_ADIS);
+               fsm->a_bidl_adis_tmout = 0;
                break;
        case OTG_STATE_A_WAIT_VFALL:
-               otg_del_timer(fsm, a_wait_vrise_tmr);
+               otg_del_timer(fsm, A_WAIT_VFALL);
+               fsm->a_wait_vfall_tmout = 0;
+               otg_del_timer(fsm, A_WAIT_VRISE);
                break;
        case OTG_STATE_A_VBUS_ERR:
                break;
@@ -127,14 +135,19 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                otg_chrg_vbus(fsm, 0);
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
+               /*
+                * Driver is responsible for starting ADP probing
+                * if ADP sensing times out.
+                */
+               otg_start_adp_sns(fsm);
                otg_set_protocol(fsm, PROTO_UNDEF);
-               otg_add_timer(fsm, b_se0_srp_tmr);
+               otg_add_timer(fsm, B_SE0_SRP);
                break;
        case OTG_STATE_B_SRP_INIT:
                otg_start_pulse(fsm);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_UNDEF);
-               otg_add_timer(fsm, b_srp_fail_tmr);
+               otg_add_timer(fsm, B_SRP_FAIL);
                break;
        case OTG_STATE_B_PERIPHERAL:
                otg_chrg_vbus(fsm, 0);
@@ -147,7 +160,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_HOST);
-               otg_add_timer(fsm, b_ase0_brst_tmr);
+               otg_add_timer(fsm, B_ASE0_BRST);
                fsm->a_bus_suspend = 0;
                break;
        case OTG_STATE_B_HOST:
@@ -163,6 +176,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                otg_chrg_vbus(fsm, 0);
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
+               otg_start_adp_prb(fsm);
                otg_set_protocol(fsm, PROTO_HOST);
                break;
        case OTG_STATE_A_WAIT_VRISE:
@@ -170,14 +184,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_HOST);
-               otg_add_timer(fsm, a_wait_vrise_tmr);
+               otg_add_timer(fsm, A_WAIT_VRISE);
                break;
        case OTG_STATE_A_WAIT_BCON:
                otg_drv_vbus(fsm, 1);
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_HOST);
-               otg_add_timer(fsm, a_wait_bcon_tmr);
+               otg_add_timer(fsm, A_WAIT_BCON);
                break;
        case OTG_STATE_A_HOST:
                otg_drv_vbus(fsm, 1);
@@ -188,15 +202,15 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                 * When HNP is triggered while a_bus_req = 0, a_host will
                 * suspend too fast to complete a_set_b_hnp_en
                 */
-               if (!fsm->a_bus_req || fsm->a_suspend_req)
-                       otg_add_timer(fsm, a_wait_enum_tmr);
+               if (!fsm->a_bus_req || fsm->a_suspend_req_inf)
+                       otg_add_timer(fsm, A_WAIT_ENUM);
                break;
        case OTG_STATE_A_SUSPEND:
                otg_drv_vbus(fsm, 1);
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_HOST);
-               otg_add_timer(fsm, a_aidl_bdis_tmr);
+               otg_add_timer(fsm, A_AIDL_BDIS);
 
                break;
        case OTG_STATE_A_PERIPHERAL:
@@ -204,12 +218,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_GADGET);
                otg_drv_vbus(fsm, 1);
+               otg_add_timer(fsm, A_BIDL_ADIS);
                break;
        case OTG_STATE_A_WAIT_VFALL:
                otg_drv_vbus(fsm, 0);
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_HOST);
+               otg_add_timer(fsm, A_WAIT_VFALL);
                break;
        case OTG_STATE_A_VBUS_ERR:
                otg_drv_vbus(fsm, 0);
@@ -250,7 +266,8 @@ int otg_statemachine(struct otg_fsm *fsm)
                        otg_set_state(fsm, OTG_STATE_A_IDLE);
                else if (fsm->b_sess_vld && fsm->otg->gadget)
                        otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
-               else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp)
+               else if ((fsm->b_bus_req || fsm->adp_change || fsm->power_up) &&
+                               fsm->b_ssend_srp && fsm->b_se0_srp)
                        otg_set_state(fsm, OTG_STATE_B_SRP_INIT);
                break;
        case OTG_STATE_B_SRP_INIT:
@@ -277,13 +294,14 @@ int otg_statemachine(struct otg_fsm *fsm)
        case OTG_STATE_B_HOST:
                if (!fsm->id || !fsm->b_sess_vld)
                        otg_set_state(fsm, OTG_STATE_B_IDLE);
-               else if (!fsm->b_bus_req || !fsm->a_conn)
+               else if (!fsm->b_bus_req || !fsm->a_conn || fsm->test_device)
                        otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
                break;
        case OTG_STATE_A_IDLE:
                if (fsm->id)
                        otg_set_state(fsm, OTG_STATE_B_IDLE);
-               else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det))
+               else if (!fsm->a_bus_drop && (fsm->a_bus_req ||
+                         fsm->a_srp_det || fsm->adp_change || fsm->power_up))
                        otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE);
                break;
        case OTG_STATE_A_WAIT_VRISE:
@@ -301,7 +319,7 @@ int otg_statemachine(struct otg_fsm *fsm)
                        otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
                break;
        case OTG_STATE_A_HOST:
-               if ((!fsm->a_bus_req || fsm->a_suspend_req) &&
+               if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) &&
                                fsm->otg->host->b_hnp_enable)
                        otg_set_state(fsm, OTG_STATE_A_SUSPEND);
                else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop)
@@ -324,14 +342,14 @@ int otg_statemachine(struct otg_fsm *fsm)
        case OTG_STATE_A_PERIPHERAL:
                if (fsm->id || fsm->a_bus_drop)
                        otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
-               else if (fsm->b_bus_suspend)
+               else if (fsm->a_bidl_adis_tmout || fsm->b_bus_suspend)
                        otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
                else if (!fsm->a_vbus_vld)
                        otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
                break;
        case OTG_STATE_A_WAIT_VFALL:
-               if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld &&
-                                       !fsm->b_conn))
+               if (fsm->a_wait_vfall_tmout || fsm->id || fsm->a_bus_req ||
+                               (!fsm->a_sess_vld && !fsm->b_conn))
                        otg_set_state(fsm, OTG_STATE_A_IDLE);
                break;
        case OTG_STATE_A_VBUS_ERR:
index fbe586206f33be707bf1bba33340d80a3f0f4437..7441b46a27f1b86ac609b2e6e5c71b8e187cfd1d 100644 (file)
 #define PROTO_HOST     (1)
 #define PROTO_GADGET   (2)
 
+enum otg_fsm_timer {
+       /* Standard OTG timers */
+       A_WAIT_VRISE,
+       A_WAIT_VFALL,
+       A_WAIT_BCON,
+       A_AIDL_BDIS,
+       B_ASE0_BRST,
+       A_BIDL_ADIS,
+
+       /* Auxiliary timers */
+       B_SE0_SRP,
+       B_SRP_FAIL,
+       A_WAIT_ENUM,
+
+       NUM_OTG_FSM_TIMERS,
+};
+
 /* OTG state machine according to the OTG spec */
 struct otg_fsm {
        /* Input */
+       int id;
+       int adp_change;
+       int power_up;
+       int test_device;
+       int a_bus_drop;
+       int a_bus_req;
+       int a_srp_det;
+       int a_vbus_vld;
+       int b_conn;
        int a_bus_resume;
        int a_bus_suspend;
        int a_conn;
+       int b_bus_req;
+       int b_se0_srp;
+       int b_ssend_srp;
+       int b_sess_vld;
+       /* Auxilary inputs */
        int a_sess_vld;
-       int a_srp_det;
-       int a_vbus_vld;
        int b_bus_resume;
        int b_bus_suspend;
-       int b_conn;
-       int b_se0_srp;
-       int b_sess_end;
-       int b_sess_vld;
-       int id;
+
+       /* Output */
+       int data_pulse;
+       int drv_vbus;
+       int loc_conn;
+       int loc_sof;
+       int adp_prb;
+       int adp_sns;
 
        /* Internal variables */
        int a_set_b_hnp_en;
        int b_srp_done;
        int b_hnp_enable;
+       int a_clr_err;
+
+       /* Informative variables */
+       int a_bus_drop_inf;
+       int a_bus_req_inf;
+       int a_clr_err_inf;
+       int b_bus_req_inf;
+       /* Auxilary informative variables */
+       int a_suspend_req_inf;
 
        /* Timeout indicator for timers */
        int a_wait_vrise_tmout;
+       int a_wait_vfall_tmout;
        int a_wait_bcon_tmout;
        int a_aidl_bdis_tmout;
        int b_ase0_brst_tmout;
-
-       /* Informative variables */
-       int a_bus_drop;
-       int a_bus_req;
-       int a_clr_err;
-       int a_suspend_req;
-       int b_bus_req;
-
-       /* Output */
-       int drv_vbus;
-       int loc_conn;
-       int loc_sof;
+       int a_bidl_adis_tmout;
 
        struct otg_fsm_ops *ops;
        struct usb_otg *otg;
@@ -83,65 +114,123 @@ struct otg_fsm {
 };
 
 struct otg_fsm_ops {
-       void    (*chrg_vbus)(int on);
-       void    (*drv_vbus)(int on);
-       void    (*loc_conn)(int on);
-       void    (*loc_sof)(int on);
-       void    (*start_pulse)(void);
-       void    (*add_timer)(void *timer);
-       void    (*del_timer)(void *timer);
+       void    (*chrg_vbus)(struct otg_fsm *fsm, int on);
+       void    (*drv_vbus)(struct otg_fsm *fsm, int on);
+       void    (*loc_conn)(struct otg_fsm *fsm, int on);
+       void    (*loc_sof)(struct otg_fsm *fsm, int on);
+       void    (*start_pulse)(struct otg_fsm *fsm);
+       void    (*start_adp_prb)(struct otg_fsm *fsm);
+       void    (*start_adp_sns)(struct otg_fsm *fsm);
+       void    (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
+       void    (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
        int     (*start_host)(struct otg_fsm *fsm, int on);
        int     (*start_gadget)(struct otg_fsm *fsm, int on);
 };
 
 
-static inline void otg_chrg_vbus(struct otg_fsm *fsm, int on)
+static inline int otg_chrg_vbus(struct otg_fsm *fsm, int on)
 {
-       fsm->ops->chrg_vbus(on);
+       if (!fsm->ops->chrg_vbus)
+               return -EOPNOTSUPP;
+       fsm->ops->chrg_vbus(fsm, on);
+       return 0;
 }
 
-static inline void otg_drv_vbus(struct otg_fsm *fsm, int on)
+static inline int otg_drv_vbus(struct otg_fsm *fsm, int on)
 {
+       if (!fsm->ops->drv_vbus)
+               return -EOPNOTSUPP;
        if (fsm->drv_vbus != on) {
                fsm->drv_vbus = on;
-               fsm->ops->drv_vbus(on);
+               fsm->ops->drv_vbus(fsm, on);
        }
+       return 0;
 }
 
-static inline void otg_loc_conn(struct otg_fsm *fsm, int on)
+static inline int otg_loc_conn(struct otg_fsm *fsm, int on)
 {
+       if (!fsm->ops->loc_conn)
+               return -EOPNOTSUPP;
        if (fsm->loc_conn != on) {
                fsm->loc_conn = on;
-               fsm->ops->loc_conn(on);
+               fsm->ops->loc_conn(fsm, on);
        }
+       return 0;
 }
 
-static inline void otg_loc_sof(struct otg_fsm *fsm, int on)
+static inline int otg_loc_sof(struct otg_fsm *fsm, int on)
 {
+       if (!fsm->ops->loc_sof)
+               return -EOPNOTSUPP;
        if (fsm->loc_sof != on) {
                fsm->loc_sof = on;
-               fsm->ops->loc_sof(on);
+               fsm->ops->loc_sof(fsm, on);
+       }
+       return 0;
+}
+
+static inline int otg_start_pulse(struct otg_fsm *fsm)
+{
+       if (!fsm->ops->start_pulse)
+               return -EOPNOTSUPP;
+       if (!fsm->data_pulse) {
+               fsm->data_pulse = 1;
+               fsm->ops->start_pulse(fsm);
        }
+       return 0;
 }
 
-static inline void otg_start_pulse(struct otg_fsm *fsm)
+static inline int otg_start_adp_prb(struct otg_fsm *fsm)
 {
-       fsm->ops->start_pulse();
+       if (!fsm->ops->start_adp_prb)
+               return -EOPNOTSUPP;
+       if (!fsm->adp_prb) {
+               fsm->adp_sns = 0;
+               fsm->adp_prb = 1;
+               fsm->ops->start_adp_prb(fsm);
+       }
+       return 0;
 }
 
-static inline void otg_add_timer(struct otg_fsm *fsm, void *timer)
+static inline int otg_start_adp_sns(struct otg_fsm *fsm)
 {
-       fsm->ops->add_timer(timer);
+       if (!fsm->ops->start_adp_sns)
+               return -EOPNOTSUPP;
+       if (!fsm->adp_sns) {
+               fsm->adp_sns = 1;
+               fsm->ops->start_adp_sns(fsm);
+       }
+       return 0;
 }
 
-static inline void otg_del_timer(struct otg_fsm *fsm, void *timer)
+static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
 {
-       fsm->ops->del_timer(timer);
+       if (!fsm->ops->add_timer)
+               return -EOPNOTSUPP;
+       fsm->ops->add_timer(fsm, timer);
+       return 0;
 }
 
-int otg_statemachine(struct otg_fsm *fsm);
+static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
+{
+       if (!fsm->ops->del_timer)
+               return -EOPNOTSUPP;
+       fsm->ops->del_timer(fsm, timer);
+       return 0;
+}
 
-/* Defined by device specific driver, for different timer implementation */
-extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr,
-       *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr,
-       *a_wait_enum_tmr;
+static inline int otg_start_host(struct otg_fsm *fsm, int on)
+{
+       if (!fsm->ops->start_host)
+               return -EOPNOTSUPP;
+       return fsm->ops->start_host(fsm, on);
+}
+
+static inline int otg_start_gadget(struct otg_fsm *fsm, int on)
+{
+       if (!fsm->ops->start_gadget)
+               return -EOPNOTSUPP;
+       return fsm->ops->start_gadget(fsm, on);
+}
+
+int otg_statemachine(struct otg_fsm *fsm);
index efe59f3f7fdae946f1d6b5c76b9e6f21a0143be1..fce3a9e9bb5d282ff6b1a64492ad6a55c90e654f 100644 (file)
@@ -35,6 +35,9 @@
 #include <linux/clk.h>
 #include <linux/regulator/consumer.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
 
 #include "phy-generic.h"
 
@@ -64,6 +67,23 @@ static int nop_set_suspend(struct usb_phy *x, int suspend)
        return 0;
 }
 
+static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted)
+{
+       int value;
+
+       if (!gpio_is_valid(nop->gpio_reset))
+               return;
+
+       value = asserted;
+       if (nop->reset_active_low)
+               value = !value;
+
+       gpio_set_value_cansleep(nop->gpio_reset, value);
+
+       if (!asserted)
+               usleep_range(10000, 20000);
+}
+
 int usb_gen_phy_init(struct usb_phy *phy)
 {
        struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
@@ -74,13 +94,10 @@ int usb_gen_phy_init(struct usb_phy *phy)
        }
 
        if (!IS_ERR(nop->clk))
-               clk_enable(nop->clk);
+               clk_prepare_enable(nop->clk);
 
-       if (!IS_ERR(nop->reset)) {
-               /* De-assert RESET */
-               if (regulator_enable(nop->reset))
-                       dev_err(phy->dev, "Failed to de-assert reset\n");
-       }
+       /* De-assert RESET */
+       nop_reset_set(nop, 0);
 
        return 0;
 }
@@ -90,14 +107,11 @@ void usb_gen_phy_shutdown(struct usb_phy *phy)
 {
        struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
 
-       if (!IS_ERR(nop->reset)) {
-               /* Assert RESET */
-               if (regulator_disable(nop->reset))
-                       dev_err(phy->dev, "Failed to assert reset\n");
-       }
+       /* Assert RESET */
+       nop_reset_set(nop, 1);
 
        if (!IS_ERR(nop->clk))
-               clk_disable(nop->clk);
+               clk_disable_unprepare(nop->clk);
 
        if (!IS_ERR(nop->vcc)) {
                if (regulator_disable(nop->vcc))
@@ -136,8 +150,7 @@ 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,
-               bool needs_reset)
+               enum usb_phy_type type, u32 clk_rate, bool needs_vcc)
 {
        int err;
 
@@ -160,14 +173,6 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
                }
        }
 
-       if (!IS_ERR(nop->clk)) {
-               err = clk_prepare(nop->clk);
-               if (err) {
-                       dev_err(dev, "Error preparing clock\n");
-                       return err;
-               }
-       }
-
        nop->vcc = devm_regulator_get(dev, "vcc");
        if (IS_ERR(nop->vcc)) {
                dev_dbg(dev, "Error getting vcc regulator: %ld\n",
@@ -176,12 +181,22 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
                        return -EPROBE_DEFER;
        }
 
-       nop->reset = devm_regulator_get(dev, "reset");
-       if (IS_ERR(nop->reset)) {
-               dev_dbg(dev, "Error getting reset regulator: %ld\n",
-                                       PTR_ERR(nop->reset));
-               if (needs_reset)
-                       return -EPROBE_DEFER;
+       if (gpio_is_valid(nop->gpio_reset)) {
+               unsigned long gpio_flags;
+
+               /* Assert RESET */
+               if (nop->reset_active_low)
+                       gpio_flags = GPIOF_OUT_INIT_LOW;
+               else
+                       gpio_flags = GPIOF_OUT_INIT_HIGH;
+
+               err = devm_gpio_request_one(dev, nop->gpio_reset,
+                                               gpio_flags, dev_name(dev));
+               if (err) {
+                       dev_err(dev, "Error requesting RESET GPIO %d\n",
+                                       nop->gpio_reset);
+                       return err;
+               }
        }
 
        nop->dev                = dev;
@@ -200,13 +215,6 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
 }
 EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy);
 
-void usb_phy_gen_cleanup_phy(struct usb_phy_gen_xceiv *nop)
-{
-       if (!IS_ERR(nop->clk))
-               clk_unprepare(nop->clk);
-}
-EXPORT_SYMBOL_GPL(usb_phy_gen_cleanup_phy);
-
 static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -217,31 +225,36 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
        int err;
        u32 clk_rate = 0;
        bool needs_vcc = false;
-       bool needs_reset = 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");
-               needs_reset = of_property_read_bool(node, "reset-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;
-               needs_reset = pdata->needs_reset;
+               nop->gpio_reset = pdata->gpio_reset;
        }
 
-       nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL);
-       if (!nop)
-               return -ENOMEM;
-
-
-       err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc,
-                       needs_reset);
+       err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc);
        if (err)
                return err;
 
@@ -252,15 +265,13 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
        if (err) {
                dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
                        err);
-               goto err_add;
+               return err;
        }
 
        platform_set_drvdata(pdev, nop);
 
        return 0;
 
-err_add:
-       usb_phy_gen_cleanup_phy(nop);
        return err;
 }
 
@@ -268,7 +279,6 @@ static int usb_phy_gen_xceiv_remove(struct platform_device *pdev)
 {
        struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev);
 
-       usb_phy_gen_cleanup_phy(nop);
        usb_remove_phy(&nop->phy);
 
        return 0;
index 61687d5a965b24ef69729a9cf0c5c38a48a7a2b5..d2a220d81734ad5be296f56c3b416aa321bfb63e 100644 (file)
@@ -6,15 +6,14 @@ struct usb_phy_gen_xceiv {
        struct device *dev;
        struct clk *clk;
        struct regulator *vcc;
-       struct regulator *reset;
+       int gpio_reset;
+       bool reset_active_low;
 };
 
 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,
-               bool needs_reset);
-void usb_phy_gen_cleanup_phy(struct usb_phy_gen_xceiv *nop);
+               enum usb_phy_type type, u32 clk_rate, bool needs_vcc);
 
 #endif
index a4dda8e1256257104cdfdd3d54707af57361ed8f..09c5ace1edd8a987f015508640f7f461508dd0a9 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/usb/omap_control_usb.h>
 
-static struct omap_control_usb *control_usb;
-
-/**
- * omap_get_control_dev - returns the device pointer for this control device
- *
- * This API should be called to get the device pointer for this control
- * module device. This device pointer should be used for called other
- * exported API's in this driver.
- *
- * To be used by PHY driver and glue driver.
- */
-struct device *omap_get_control_dev(void)
-{
-       if (!control_usb)
-               return ERR_PTR(-ENODEV);
-
-       return control_usb->dev;
-}
-EXPORT_SYMBOL_GPL(omap_get_control_dev);
-
 /**
- * omap_control_usb3_phy_power - power on/off the serializer using control
- *     module
+ * omap_control_usb_phy_power - power on/off the phy using control module reg
  * @dev: the control module device
- * @on: 0 to off and 1 to on based on powering on or off the PHY
- *
- * usb3 PHY driver should call this API to power on or off the PHY.
+ * @on: 0 or 1, based on powering on or off the PHY
  */
-void omap_control_usb3_phy_power(struct device *dev, bool on)
+void omap_control_usb_phy_power(struct device *dev, int on)
 {
        u32 val;
        unsigned long rate;
-       struct omap_control_usb *control_usb = dev_get_drvdata(dev);
+       struct omap_control_usb *control_usb;
 
-       if (control_usb->type != OMAP_CTRL_DEV_TYPE2)
+       if (IS_ERR(dev) || !dev) {
+               pr_err("%s: invalid device\n", __func__);
                return;
+       }
 
-       rate = clk_get_rate(control_usb->sys_clk);
-       rate = rate/1000000;
-
-       val = readl(control_usb->phy_power);
-
-       if (on) {
-               val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
-                       OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
-               val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
-                       OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
-               val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
-       } else {
-               val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
-               val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
-                       OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
+       control_usb = dev_get_drvdata(dev);
+       if (!control_usb) {
+               dev_err(dev, "%s: invalid control usb device\n", __func__);
+               return;
        }
 
-       writel(val, control_usb->phy_power);
-}
-EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power);
+       if (control_usb->type == OMAP_CTRL_TYPE_OTGHS)
+               return;
 
-/**
- * omap_control_usb_phy_power - power on/off the phy using control module reg
- * @dev: the control module device
- * @on: 0 or 1, based on powering on or off the PHY
- */
-void omap_control_usb_phy_power(struct device *dev, int on)
-{
-       u32 val;
-       struct omap_control_usb *control_usb = dev_get_drvdata(dev);
+       val = readl(control_usb->power);
 
-       val = readl(control_usb->dev_conf);
+       switch (control_usb->type) {
+       case OMAP_CTRL_TYPE_USB2:
+               if (on)
+                       val &= ~OMAP_CTRL_DEV_PHY_PD;
+               else
+                       val |= OMAP_CTRL_DEV_PHY_PD;
+               break;
 
-       if (on)
-               val &= ~OMAP_CTRL_DEV_PHY_PD;
-       else
-               val |= OMAP_CTRL_DEV_PHY_PD;
+       case OMAP_CTRL_TYPE_PIPE3:
+               rate = clk_get_rate(control_usb->sys_clk);
+               rate = rate/1000000;
+
+               if (on) {
+                       val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
+                                       OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
+                       val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
+                               OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
+                       val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
+               } else {
+                       val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
+                       val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
+                               OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
+               }
+               break;
 
-       writel(val, control_usb->dev_conf);
+       case OMAP_CTRL_TYPE_DRA7USB2:
+               if (on)
+                       val &= ~OMAP_CTRL_USB2_PHY_PD;
+               else
+                       val |= OMAP_CTRL_USB2_PHY_PD;
+               break;
+       default:
+               dev_err(dev, "%s: type %d not recognized\n",
+                                       __func__, control_usb->type);
+               break;
+       }
+
+       writel(val, control_usb->power);
 }
 EXPORT_SYMBOL_GPL(omap_control_usb_phy_power);
 
@@ -172,11 +162,19 @@ void omap_control_usb_set_mode(struct device *dev,
 {
        struct omap_control_usb *ctrl_usb;
 
-       if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1)
+       if (IS_ERR(dev) || !dev)
                return;
 
        ctrl_usb = dev_get_drvdata(dev);
 
+       if (!ctrl_usb) {
+               dev_err(dev, "Invalid control usb device\n");
+               return;
+       }
+
+       if (ctrl_usb->type != OMAP_CTRL_TYPE_OTGHS)
+               return;
+
        switch (mode) {
        case USB_MODE_HOST:
                omap_control_usb_host_mode(ctrl_usb);
@@ -193,12 +191,46 @@ void omap_control_usb_set_mode(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
 
+#ifdef CONFIG_OF
+
+static const enum omap_control_usb_type otghs_data = OMAP_CTRL_TYPE_OTGHS;
+static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2;
+static const enum omap_control_usb_type pipe3_data = OMAP_CTRL_TYPE_PIPE3;
+static const enum omap_control_usb_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2;
+
+static const struct of_device_id omap_control_usb_id_table[] = {
+       {
+               .compatible = "ti,control-phy-otghs",
+               .data = &otghs_data,
+       },
+       {
+               .compatible = "ti,control-phy-usb2",
+               .data = &usb2_data,
+       },
+       {
+               .compatible = "ti,control-phy-pipe3",
+               .data = &pipe3_data,
+       },
+       {
+               .compatible = "ti,control-phy-dra7usb2",
+               .data = &dra7usb2_data,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
+#endif
+
+
 static int omap_control_usb_probe(struct platform_device *pdev)
 {
        struct resource *res;
-       struct device_node *np = pdev->dev.of_node;
-       struct omap_control_usb_platform_data *pdata =
-                       dev_get_platdata(&pdev->dev);
+       const struct of_device_id *of_id;
+       struct omap_control_usb *control_usb;
+
+       of_id = of_match_device(of_match_ptr(omap_control_usb_id_table),
+                                                               &pdev->dev);
+       if (!of_id)
+               return -EINVAL;
 
        control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),
                GFP_KERNEL);
@@ -207,40 +239,27 @@ static int omap_control_usb_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       if (np) {
-               of_property_read_u32(np, "ti,type", &control_usb->type);
-       } else if (pdata) {
-               control_usb->type = pdata->type;
-       } else {
-               dev_err(&pdev->dev, "no pdata present\n");
-               return -EINVAL;
-       }
-
-       control_usb->dev        = &pdev->dev;
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-               "control_dev_conf");
-       control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(control_usb->dev_conf))
-               return PTR_ERR(control_usb->dev_conf);
+       control_usb->dev = &pdev->dev;
+       control_usb->type = *(enum omap_control_usb_type *)of_id->data;
 
-       if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
+       if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                        "otghs_control");
                control_usb->otghs_control = devm_ioremap_resource(
                        &pdev->dev, res);
                if (IS_ERR(control_usb->otghs_control))
                        return PTR_ERR(control_usb->otghs_control);
-       }
-
-       if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
+       } else {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-                       "phy_power_usb");
-               control_usb->phy_power = devm_ioremap_resource(
-                       &pdev->dev, res);
-               if (IS_ERR(control_usb->phy_power))
-                       return PTR_ERR(control_usb->phy_power);
+                               "power");
+               control_usb->power = devm_ioremap_resource(&pdev->dev, res);
+               if (IS_ERR(control_usb->power)) {
+                       dev_err(&pdev->dev, "Couldn't get power register\n");
+                       return PTR_ERR(control_usb->power);
+               }
+       }
 
+       if (control_usb->type == OMAP_CTRL_TYPE_PIPE3) {
                control_usb->sys_clk = devm_clk_get(control_usb->dev,
                        "sys_clkin");
                if (IS_ERR(control_usb->sys_clk)) {
@@ -249,20 +268,11 @@ static int omap_control_usb_probe(struct platform_device *pdev)
                }
        }
 
-
        dev_set_drvdata(control_usb->dev, control_usb);
 
        return 0;
 }
 
-#ifdef CONFIG_OF
-static const struct of_device_id omap_control_usb_id_table[] = {
-       { .compatible = "ti,omap-control-usb" },
-       {}
-};
-MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
-#endif
-
 static struct platform_driver omap_control_usb_driver = {
        .probe          = omap_control_usb_probe,
        .driver         = {
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
deleted file mode 100644 (file)
index d266861..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * omap-usb2.c - USB PHY, talking to musb controller in OMAP.
- *
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.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.
- *
- * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * 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/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/io.h>
-#include <linux/usb/omap_usb.h>
-#include <linux/usb/phy_companion.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/pm_runtime.h>
-#include <linux/delay.h>
-#include <linux/usb/omap_control_usb.h>
-
-/**
- * omap_usb2_set_comparator - links the comparator present in the sytem with
- *     this phy
- * @comparator - the companion phy(comparator) for this phy
- *
- * The phy companion driver should call this API passing the phy_companion
- * filled with set_vbus and start_srp to be used by usb phy.
- *
- * For use by phy companion driver
- */
-int omap_usb2_set_comparator(struct phy_companion *comparator)
-{
-       struct omap_usb *phy;
-       struct usb_phy  *x = usb_get_phy(USB_PHY_TYPE_USB2);
-
-       if (IS_ERR(x))
-               return -ENODEV;
-
-       phy = phy_to_omapusb(x);
-       phy->comparator = comparator;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
-
-static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
-{
-       struct omap_usb *phy = phy_to_omapusb(otg->phy);
-
-       if (!phy->comparator)
-               return -ENODEV;
-
-       return phy->comparator->set_vbus(phy->comparator, enabled);
-}
-
-static int omap_usb_start_srp(struct usb_otg *otg)
-{
-       struct omap_usb *phy = phy_to_omapusb(otg->phy);
-
-       if (!phy->comparator)
-               return -ENODEV;
-
-       return phy->comparator->start_srp(phy->comparator);
-}
-
-static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
-{
-       struct usb_phy  *phy = otg->phy;
-
-       otg->host = host;
-       if (!host)
-               phy->state = OTG_STATE_UNDEFINED;
-
-       return 0;
-}
-
-static int omap_usb_set_peripheral(struct usb_otg *otg,
-               struct usb_gadget *gadget)
-{
-       struct usb_phy  *phy = otg->phy;
-
-       otg->gadget = gadget;
-       if (!gadget)
-               phy->state = OTG_STATE_UNDEFINED;
-
-       return 0;
-}
-
-static int omap_usb2_suspend(struct usb_phy *x, int suspend)
-{
-       struct omap_usb *phy = phy_to_omapusb(x);
-       int ret;
-
-       if (suspend && !phy->is_suspended) {
-               omap_control_usb_phy_power(phy->control_dev, 0);
-               pm_runtime_put_sync(phy->dev);
-               phy->is_suspended = 1;
-       } else if (!suspend && phy->is_suspended) {
-               ret = pm_runtime_get_sync(phy->dev);
-               if (ret < 0) {
-                       dev_err(phy->dev, "get_sync failed with err %d\n", ret);
-                       return ret;
-               }
-               omap_control_usb_phy_power(phy->control_dev, 1);
-               phy->is_suspended = 0;
-       }
-
-       return 0;
-}
-
-static int omap_usb2_probe(struct platform_device *pdev)
-{
-       struct omap_usb                 *phy;
-       struct usb_otg                  *otg;
-
-       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
-       if (!phy) {
-               dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
-               return -ENOMEM;
-       }
-
-       otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
-       if (!otg) {
-               dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
-               return -ENOMEM;
-       }
-
-       phy->dev                = &pdev->dev;
-
-       phy->phy.dev            = phy->dev;
-       phy->phy.label          = "omap-usb2";
-       phy->phy.set_suspend    = omap_usb2_suspend;
-       phy->phy.otg            = otg;
-       phy->phy.type           = USB_PHY_TYPE_USB2;
-
-       phy->control_dev = omap_get_control_dev();
-       if (IS_ERR(phy->control_dev)) {
-               dev_dbg(&pdev->dev, "Failed to get control device\n");
-               return -ENODEV;
-       }
-
-       phy->is_suspended       = 1;
-       omap_control_usb_phy_power(phy->control_dev, 0);
-
-       otg->set_host           = omap_usb_set_host;
-       otg->set_peripheral     = omap_usb_set_peripheral;
-       otg->set_vbus           = omap_usb_set_vbus;
-       otg->start_srp          = omap_usb_start_srp;
-       otg->phy                = &phy->phy;
-
-       phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
-       if (IS_ERR(phy->wkupclk)) {
-               dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
-               return PTR_ERR(phy->wkupclk);
-       }
-       clk_prepare(phy->wkupclk);
-
-       phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m");
-       if (IS_ERR(phy->optclk))
-               dev_vdbg(&pdev->dev, "unable to get refclk960m\n");
-       else
-               clk_prepare(phy->optclk);
-
-       usb_add_phy_dev(&phy->phy);
-
-       platform_set_drvdata(pdev, phy);
-
-       pm_runtime_enable(phy->dev);
-
-       return 0;
-}
-
-static int omap_usb2_remove(struct platform_device *pdev)
-{
-       struct omap_usb *phy = platform_get_drvdata(pdev);
-
-       clk_unprepare(phy->wkupclk);
-       if (!IS_ERR(phy->optclk))
-               clk_unprepare(phy->optclk);
-       usb_remove_phy(&phy->phy);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-
-static int omap_usb2_runtime_suspend(struct device *dev)
-{
-       struct platform_device  *pdev = to_platform_device(dev);
-       struct omap_usb *phy = platform_get_drvdata(pdev);
-
-       clk_disable(phy->wkupclk);
-       if (!IS_ERR(phy->optclk))
-               clk_disable(phy->optclk);
-
-       return 0;
-}
-
-static int omap_usb2_runtime_resume(struct device *dev)
-{
-       struct platform_device  *pdev = to_platform_device(dev);
-       struct omap_usb *phy = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = clk_enable(phy->wkupclk);
-       if (ret < 0) {
-               dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
-               goto err0;
-       }
-
-       if (!IS_ERR(phy->optclk)) {
-               ret = clk_enable(phy->optclk);
-               if (ret < 0) {
-                       dev_err(phy->dev, "Failed to enable optclk %d\n", ret);
-                       goto err1;
-               }
-       }
-
-       return 0;
-
-err1:
-       clk_disable(phy->wkupclk);
-
-err0:
-       return ret;
-}
-
-static const struct dev_pm_ops omap_usb2_pm_ops = {
-       SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume,
-               NULL)
-};
-
-#define DEV_PM_OPS     (&omap_usb2_pm_ops)
-#else
-#define DEV_PM_OPS     NULL
-#endif
-
-#ifdef CONFIG_OF
-static const struct of_device_id omap_usb2_id_table[] = {
-       { .compatible = "ti,omap-usb2" },
-       {}
-};
-MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
-#endif
-
-static struct platform_driver omap_usb2_driver = {
-       .probe          = omap_usb2_probe,
-       .remove         = omap_usb2_remove,
-       .driver         = {
-               .name   = "omap-usb2",
-               .owner  = THIS_MODULE,
-               .pm     = DEV_PM_OPS,
-               .of_match_table = of_match_ptr(omap_usb2_id_table),
-       },
-};
-
-module_platform_driver(omap_usb2_driver);
-
-MODULE_ALIAS("platform: omap_usb2");
-MODULE_AUTHOR("Texas Instruments Inc.");
-MODULE_DESCRIPTION("OMAP USB2 phy driver");
-MODULE_LICENSE("GPL v2");
index 4e8a0405f956c478491a1ed6f18d65a9afc07e9a..0c6ba29bddddc05b7b3c35e2067c026eec13bc2f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/usb/omap_control_usb.h>
+#include <linux/of_platform.h>
 
 #define        PLL_STATUS              0x00000004
 #define        PLL_GO                  0x00000008
@@ -100,7 +101,7 @@ static int omap_usb3_suspend(struct usb_phy *x, int suspend)
                        udelay(1);
                } while (--timeout);
 
-               omap_control_usb3_phy_power(phy->control_dev, 0);
+               omap_control_usb_phy_power(phy->control_dev, 0);
 
                phy->is_suspended       = 1;
        } else if (!suspend && phy->is_suspended) {
@@ -189,15 +190,21 @@ static int omap_usb3_init(struct usb_phy *x)
        if (ret)
                return ret;
 
-       omap_control_usb3_phy_power(phy->control_dev, 1);
+       omap_control_usb_phy_power(phy->control_dev, 1);
 
        return 0;
 }
 
 static int omap_usb3_probe(struct platform_device *pdev)
 {
-       struct omap_usb                 *phy;
-       struct resource                 *res;
+       struct omap_usb *phy;
+       struct resource *res;
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *control_node;
+       struct platform_device *control_pdev;
+
+       if (!node)
+               return -EINVAL;
 
        phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
        if (!phy) {
@@ -239,13 +246,20 @@ static int omap_usb3_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       phy->control_dev = omap_get_control_dev();
-       if (IS_ERR(phy->control_dev)) {
-               dev_dbg(&pdev->dev, "Failed to get control device\n");
-               return -ENODEV;
+       control_node = of_parse_phandle(node, "ctrl-module", 0);
+       if (!control_node) {
+               dev_err(&pdev->dev, "Failed to get control device phandle\n");
+               return -EINVAL;
        }
+       control_pdev = of_find_device_by_node(control_node);
+       if (!control_pdev) {
+               dev_err(&pdev->dev, "Failed to get control device\n");
+               return -EINVAL;
+       }
+
+       phy->control_dev = &control_pdev->dev;
 
-       omap_control_usb3_phy_power(phy->control_dev, 0);
+       omap_control_usb_phy_power(phy->control_dev, 0);
        usb_add_phy_dev(&phy->phy);
 
        platform_set_drvdata(pdev, phy);
diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c b/drivers/usb/phy/phy-rcar-gen2-usb.c
new file mode 100644 (file)
index 0000000..a99a695
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Renesas R-Car Gen2 USB phy driver
+ *
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Cogent Embedded, 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_data/usb-rcar-gen2-phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/usb/otg.h>
+
+struct rcar_gen2_usb_phy_priv {
+       struct usb_phy phy;
+       void __iomem *base;
+       struct clk *clk;
+       spinlock_t lock;
+       int usecount;
+       u32 ugctrl2;
+};
+
+#define usb_phy_to_priv(p) container_of(p, struct rcar_gen2_usb_phy_priv, phy)
+
+/* Low Power Status register */
+#define USBHS_LPSTS_REG                        0x02
+#define USBHS_LPSTS_SUSPM              (1 << 14)
+
+/* USB General control register */
+#define USBHS_UGCTRL_REG               0x80
+#define USBHS_UGCTRL_CONNECT           (1 << 2)
+#define USBHS_UGCTRL_PLLRESET          (1 << 0)
+
+/* USB General control register 2 */
+#define USBHS_UGCTRL2_REG              0x84
+#define USBHS_UGCTRL2_USB0_PCI         (1 << 4)
+#define USBHS_UGCTRL2_USB0_HS          (3 << 4)
+#define USBHS_UGCTRL2_USB2_PCI         (0 << 31)
+#define USBHS_UGCTRL2_USB2_SS          (1 << 31)
+
+/* USB General status register */
+#define USBHS_UGSTS_REG                        0x88
+#define USBHS_UGSTS_LOCK               (3 << 8)
+
+/* Enable USBHS internal phy */
+static int __rcar_gen2_usbhs_phy_enable(void __iomem *base)
+{
+       u32 val;
+       int i;
+
+       /* USBHS PHY power on */
+       val = ioread32(base + USBHS_UGCTRL_REG);
+       val &= ~USBHS_UGCTRL_PLLRESET;
+       iowrite32(val, base + USBHS_UGCTRL_REG);
+
+       val = ioread16(base + USBHS_LPSTS_REG);
+       val |= USBHS_LPSTS_SUSPM;
+       iowrite16(val, base + USBHS_LPSTS_REG);
+
+       for (i = 0; i < 20; i++) {
+               val = ioread32(base + USBHS_UGSTS_REG);
+               if ((val & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) {
+                       val = ioread32(base + USBHS_UGCTRL_REG);
+                       val |= USBHS_UGCTRL_CONNECT;
+                       iowrite32(val, base + USBHS_UGCTRL_REG);
+                       return 0;
+               }
+               udelay(1);
+       }
+
+       /* Timed out waiting for the PLL lock */
+       return -ETIMEDOUT;
+}
+
+/* Disable USBHS internal phy */
+static int __rcar_gen2_usbhs_phy_disable(void __iomem *base)
+{
+       u32 val;
+
+       /* USBHS PHY power off */
+       val = ioread32(base + USBHS_UGCTRL_REG);
+       val &= ~USBHS_UGCTRL_CONNECT;
+       iowrite32(val, base + USBHS_UGCTRL_REG);
+
+       val = ioread16(base + USBHS_LPSTS_REG);
+       val &= ~USBHS_LPSTS_SUSPM;
+       iowrite16(val, base + USBHS_LPSTS_REG);
+
+       val = ioread32(base + USBHS_UGCTRL_REG);
+       val |= USBHS_UGCTRL_PLLRESET;
+       iowrite32(val, base + USBHS_UGCTRL_REG);
+       return 0;
+}
+
+/* Setup USB channels */
+static void __rcar_gen2_usb_phy_init(struct rcar_gen2_usb_phy_priv *priv)
+{
+       u32 val;
+
+       clk_prepare_enable(priv->clk);
+
+       /* Set USB channels in the USBHS UGCTRL2 register */
+       val = ioread32(priv->base);
+       val &= ~(USBHS_UGCTRL2_USB0_HS | USBHS_UGCTRL2_USB2_SS);
+       val |= priv->ugctrl2;
+       iowrite32(val, priv->base);
+}
+
+/* Shutdown USB channels */
+static void __rcar_gen2_usb_phy_shutdown(struct rcar_gen2_usb_phy_priv *priv)
+{
+       __rcar_gen2_usbhs_phy_disable(priv->base);
+       clk_disable_unprepare(priv->clk);
+}
+
+static int rcar_gen2_usb_phy_set_suspend(struct usb_phy *phy, int suspend)
+{
+       struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy);
+       unsigned long flags;
+       int retval;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       retval = suspend ? __rcar_gen2_usbhs_phy_disable(priv->base) :
+                          __rcar_gen2_usbhs_phy_enable(priv->base);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return retval;
+}
+
+static int rcar_gen2_usb_phy_init(struct usb_phy *phy)
+{
+       struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy);
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       /*
+        * Enable the clock and setup USB channels
+        * if it's the first user
+        */
+       if (!priv->usecount++)
+               __rcar_gen2_usb_phy_init(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return 0;
+}
+
+static void rcar_gen2_usb_phy_shutdown(struct usb_phy *phy)
+{
+       struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy);
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (!priv->usecount) {
+               dev_warn(phy->dev, "Trying to disable phy with 0 usecount\n");
+               goto out;
+       }
+
+       /* Disable everything if it's the last user */
+       if (!--priv->usecount)
+               __rcar_gen2_usb_phy_shutdown(priv);
+out:
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int rcar_gen2_usb_phy_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct rcar_gen2_phy_platform_data *pdata;
+       struct rcar_gen2_usb_phy_priv *priv;
+       struct resource *res;
+       void __iomem *base;
+       struct clk *clk;
+       int retval;
+
+       pdata = dev_get_platdata(&pdev->dev);
+       if (!pdata) {
+               dev_err(dev, "No platform data\n");
+               return -EINVAL;
+       }
+
+       clk = devm_clk_get(&pdev->dev, "usbhs");
+       if (IS_ERR(clk)) {
+               dev_err(&pdev->dev, "Can't get the clock\n");
+               return PTR_ERR(clk);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(dev, "Memory allocation failed\n");
+               return -ENOMEM;
+       }
+
+       spin_lock_init(&priv->lock);
+       priv->clk = clk;
+       priv->base = base;
+       priv->ugctrl2 = pdata->chan0_pci ?
+                       USBHS_UGCTRL2_USB0_PCI : USBHS_UGCTRL2_USB0_HS;
+       priv->ugctrl2 |= pdata->chan2_pci ?
+                       USBHS_UGCTRL2_USB2_PCI : USBHS_UGCTRL2_USB2_SS;
+       priv->phy.dev = dev;
+       priv->phy.label = dev_name(dev);
+       priv->phy.init = rcar_gen2_usb_phy_init;
+       priv->phy.shutdown = rcar_gen2_usb_phy_shutdown;
+       priv->phy.set_suspend = rcar_gen2_usb_phy_set_suspend;
+
+       retval = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2);
+       if (retval < 0) {
+               dev_err(dev, "Failed to add USB phy\n");
+               return retval;
+       }
+
+       platform_set_drvdata(pdev, priv);
+
+       return retval;
+}
+
+static int rcar_gen2_usb_phy_remove(struct platform_device *pdev)
+{
+       struct rcar_gen2_usb_phy_priv *priv = platform_get_drvdata(pdev);
+
+       usb_remove_phy(&priv->phy);
+
+       return 0;
+}
+
+static struct platform_driver rcar_gen2_usb_phy_driver = {
+       .driver = {
+               .name = "usb_phy_rcar_gen2",
+       },
+       .probe = rcar_gen2_usb_phy_probe,
+       .remove = rcar_gen2_usb_phy_remove,
+};
+
+module_platform_driver(rcar_gen2_usb_phy_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Renesas R-Car Gen2 USB phy");
+MODULE_AUTHOR("Valentine Barshak <valentine.barshak@cogentembedded.com>");
index ff70e4b19b9705cc4b69b1ea0de7b5c1ecf23959..b3ba86627b7295960e5c0d8701f1b7fd887a98da 100644 (file)
@@ -411,6 +411,7 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
        sphy->drv_data          = drv_data;
        sphy->phy.dev           = sphy->dev;
        sphy->phy.label         = "samsung-usb2phy";
+       sphy->phy.type          = USB_PHY_TYPE_USB2;
        sphy->phy.init          = samsung_usb2phy_init;
        sphy->phy.shutdown      = samsung_usb2phy_shutdown;
 
@@ -426,7 +427,7 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, sphy);
 
-       return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+       return usb_add_phy_dev(&sphy->phy);
 }
 
 static int samsung_usb2phy_remove(struct platform_device *pdev)
index c6eb22213de607c3a5997b7a80a92d814eb371bd..cc0819248acfc6633fbe524f8f0346152bb5d275 100644 (file)
@@ -271,6 +271,7 @@ static int samsung_usb3phy_probe(struct platform_device *pdev)
        sphy->clk               = clk;
        sphy->phy.dev           = sphy->dev;
        sphy->phy.label         = "samsung-usb3phy";
+       sphy->phy.type          = USB_PHY_TYPE_USB3;
        sphy->phy.init          = samsung_usb3phy_init;
        sphy->phy.shutdown      = samsung_usb3phy_shutdown;
        sphy->drv_data          = samsung_usbphy_get_driver_data(pdev);
@@ -283,7 +284,7 @@ static int samsung_usb3phy_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, sphy);
 
-       return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB3);
+       return usb_add_phy_dev(&sphy->phy);
 }
 
 static int samsung_usb3phy_remove(struct platform_device *pdev)
index e9cb1cb8abc7386c7f9e19a5f9c64adcfd271a96..82232acf1ab61b17cfbe9d084c3ed2188d554b18 100644 (file)
@@ -1090,7 +1090,7 @@ static struct platform_driver tegra_usb_phy_driver = {
        .driver         = {
                .name   = "tegra-phy",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(tegra_usb_phy_id_table),
+               .of_match_table = tegra_usb_phy_id_table,
        },
 };
 module_platform_driver(tegra_usb_phy_driver);
diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c
deleted file mode 100644 (file)
index 90730c8..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller
- *
- * Copyright (C) 2004-2007 Texas Instruments
- * Copyright (C) 2008 Nokia Corporation
- * Contact: Felipe Balbi <felipe.balbi@nokia.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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Current status:
- *     - HS USB ULPI mode works.
- *     - 3-pin mode support may be added in future.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/musb-omap.h>
-#include <linux/usb/ulpi.h>
-#include <linux/i2c/twl.h>
-#include <linux/regulator/consumer.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-
-/* Register defines */
-
-#define MCPC_CTRL                      0x30
-#define MCPC_CTRL_RTSOL                        (1 << 7)
-#define MCPC_CTRL_EXTSWR               (1 << 6)
-#define MCPC_CTRL_EXTSWC               (1 << 5)
-#define MCPC_CTRL_VOICESW              (1 << 4)
-#define MCPC_CTRL_OUT64K               (1 << 3)
-#define MCPC_CTRL_RTSCTSSW             (1 << 2)
-#define MCPC_CTRL_HS_UART              (1 << 0)
-
-#define MCPC_IO_CTRL                   0x33
-#define MCPC_IO_CTRL_MICBIASEN         (1 << 5)
-#define MCPC_IO_CTRL_CTS_NPU           (1 << 4)
-#define MCPC_IO_CTRL_RXD_PU            (1 << 3)
-#define MCPC_IO_CTRL_TXDTYP            (1 << 2)
-#define MCPC_IO_CTRL_CTSTYP            (1 << 1)
-#define MCPC_IO_CTRL_RTSTYP            (1 << 0)
-
-#define MCPC_CTRL2                     0x36
-#define MCPC_CTRL2_MCPC_CK_EN          (1 << 0)
-
-#define OTHER_FUNC_CTRL                        0x80
-#define OTHER_FUNC_CTRL_BDIS_ACON_EN   (1 << 4)
-#define OTHER_FUNC_CTRL_FIVEWIRE_MODE  (1 << 2)
-
-#define OTHER_IFC_CTRL                 0x83
-#define OTHER_IFC_CTRL_OE_INT_EN       (1 << 6)
-#define OTHER_IFC_CTRL_CEA2011_MODE    (1 << 5)
-#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN     (1 << 4)
-#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT      (1 << 3)
-#define OTHER_IFC_CTRL_HIZ_ULPI                (1 << 2)
-#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0)
-
-#define OTHER_INT_EN_RISE              0x86
-#define OTHER_INT_EN_FALL              0x89
-#define OTHER_INT_STS                  0x8C
-#define OTHER_INT_LATCH                        0x8D
-#define OTHER_INT_VB_SESS_VLD          (1 << 7)
-#define OTHER_INT_DM_HI                        (1 << 6) /* not valid for "latch" reg */
-#define OTHER_INT_DP_HI                        (1 << 5) /* not valid for "latch" reg */
-#define OTHER_INT_BDIS_ACON            (1 << 3) /* not valid for "fall" regs */
-#define OTHER_INT_MANU                 (1 << 1)
-#define OTHER_INT_ABNORMAL_STRESS      (1 << 0)
-
-#define ID_STATUS                      0x96
-#define ID_RES_FLOAT                   (1 << 4)
-#define ID_RES_440K                    (1 << 3)
-#define ID_RES_200K                    (1 << 2)
-#define ID_RES_102K                    (1 << 1)
-#define ID_RES_GND                     (1 << 0)
-
-#define POWER_CTRL                     0xAC
-#define POWER_CTRL_OTG_ENAB            (1 << 5)
-
-#define OTHER_IFC_CTRL2                        0xAF
-#define OTHER_IFC_CTRL2_ULPI_STP_LOW   (1 << 4)
-#define OTHER_IFC_CTRL2_ULPI_TXEN_POL  (1 << 3)
-#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2)
-#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK    (3 << 0) /* bits 0 and 1 */
-#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N   (0 << 0)
-#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N   (1 << 0)
-
-#define REG_CTRL_EN                    0xB2
-#define REG_CTRL_ERROR                 0xB5
-#define ULPI_I2C_CONFLICT_INTEN                (1 << 0)
-
-#define OTHER_FUNC_CTRL2               0xB8
-#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0)
-
-/* following registers do not have separate _clr and _set registers */
-#define VBUS_DEBOUNCE                  0xC0
-#define ID_DEBOUNCE                    0xC1
-#define VBAT_TIMER                     0xD3
-#define PHY_PWR_CTRL                   0xFD
-#define PHY_PWR_PHYPWD                 (1 << 0)
-#define PHY_CLK_CTRL                   0xFE
-#define PHY_CLK_CTRL_CLOCKGATING_EN    (1 << 2)
-#define PHY_CLK_CTRL_CLK32K_EN         (1 << 1)
-#define REQ_PHY_DPLL_CLK               (1 << 0)
-#define PHY_CLK_CTRL_STS               0xFF
-#define PHY_DPLL_CLK                   (1 << 0)
-
-/* In module TWL_MODULE_PM_MASTER */
-#define STS_HW_CONDITIONS              0x0F
-
-/* In module TWL_MODULE_PM_RECEIVER */
-#define VUSB_DEDICATED1                        0x7D
-#define VUSB_DEDICATED2                        0x7E
-#define VUSB1V5_DEV_GRP                        0x71
-#define VUSB1V5_TYPE                   0x72
-#define VUSB1V5_REMAP                  0x73
-#define VUSB1V8_DEV_GRP                        0x74
-#define VUSB1V8_TYPE                   0x75
-#define VUSB1V8_REMAP                  0x76
-#define VUSB3V1_DEV_GRP                        0x77
-#define VUSB3V1_TYPE                   0x78
-#define VUSB3V1_REMAP                  0x79
-
-/* In module TWL4030_MODULE_INTBR */
-#define PMBR1                          0x0D
-#define GPIO_USB_4PIN_ULPI_2430C       (3 << 0)
-
-struct twl4030_usb {
-       struct usb_phy          phy;
-       struct device           *dev;
-
-       /* TWL4030 internal USB regulator supplies */
-       struct regulator        *usb1v5;
-       struct regulator        *usb1v8;
-       struct regulator        *usb3v1;
-
-       /* for vbus reporting with irqs disabled */
-       spinlock_t              lock;
-
-       /* pin configuration */
-       enum twl4030_usb_mode   usb_mode;
-
-       int                     irq;
-       enum omap_musb_vbus_id_status linkstat;
-       bool                    vbus_supplied;
-       u8                      asleep;
-       bool                    irq_enabled;
-
-       struct delayed_work     id_workaround_work;
-};
-
-/* internal define on top of container_of */
-#define phy_to_twl(x)          container_of((x), struct twl4030_usb, phy)
-
-/*-------------------------------------------------------------------------*/
-
-static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl,
-               u8 module, u8 data, u8 address)
-{
-       u8 check;
-
-       if ((twl_i2c_write_u8(module, data, address) >= 0) &&
-           (twl_i2c_read_u8(module, &check, address) >= 0) &&
-                                               (check == data))
-               return 0;
-       dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n",
-                       1, module, address, check, data);
-
-       /* Failed once: Try again */
-       if ((twl_i2c_write_u8(module, data, address) >= 0) &&
-           (twl_i2c_read_u8(module, &check, address) >= 0) &&
-                                               (check == data))
-               return 0;
-       dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n",
-                       2, module, address, check, data);
-
-       /* Failed again: Return error */
-       return -EBUSY;
-}
-
-#define twl4030_usb_write_verify(twl, address, data)   \
-       twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address))
-
-static inline int twl4030_usb_write(struct twl4030_usb *twl,
-               u8 address, u8 data)
-{
-       int ret = 0;
-
-       ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address);
-       if (ret < 0)
-               dev_dbg(twl->dev,
-                       "TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
-       return ret;
-}
-
-static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address)
-{
-       u8 data;
-       int ret = 0;
-
-       ret = twl_i2c_read_u8(module, &data, address);
-       if (ret >= 0)
-               ret = data;
-       else
-               dev_dbg(twl->dev,
-                       "TWL4030:readb[0x%x,0x%x] Error %d\n",
-                                       module, address, ret);
-
-       return ret;
-}
-
-static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address)
-{
-       return twl4030_readb(twl, TWL_MODULE_USB, address);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline int
-twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
-{
-       return twl4030_usb_write(twl, ULPI_SET(reg), bits);
-}
-
-static inline int
-twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
-{
-       return twl4030_usb_write(twl, ULPI_CLR(reg), bits);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static bool twl4030_is_driving_vbus(struct twl4030_usb *twl)
-{
-       int ret;
-
-       ret = twl4030_usb_read(twl, PHY_CLK_CTRL_STS);
-       if (ret < 0 || !(ret & PHY_DPLL_CLK))
-               /*
-                * if clocks are off, registers are not updated,
-                * but we can assume we don't drive VBUS in this case
-                */
-               return false;
-
-       ret = twl4030_usb_read(twl, ULPI_OTG_CTRL);
-       if (ret < 0)
-               return false;
-
-       return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false;
-}
-
-static enum omap_musb_vbus_id_status
-       twl4030_usb_linkstat(struct twl4030_usb *twl)
-{
-       int     status;
-       enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN;
-
-       twl->vbus_supplied = false;
-
-       /*
-        * For ID/VBUS sensing, see manual section 15.4.8 ...
-        * except when using only battery backup power, two
-        * comparators produce VBUS_PRES and ID_PRES signals,
-        * which don't match docs elsewhere.  But ... BIT(7)
-        * and BIT(2) of STS_HW_CONDITIONS, respectively, do
-        * seem to match up.  If either is true the USB_PRES
-        * signal is active, the OTG module is activated, and
-        * its interrupt may be raised (may wake the system).
-        */
-       status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS);
-       if (status < 0)
-               dev_err(twl->dev, "USB link status err %d\n", status);
-       else if (status & (BIT(7) | BIT(2))) {
-               if (status & BIT(7)) {
-                       if (twl4030_is_driving_vbus(twl))
-                               status &= ~BIT(7);
-                       else
-                               twl->vbus_supplied = true;
-               }
-
-               if (status & BIT(2))
-                       linkstat = OMAP_MUSB_ID_GROUND;
-               else if (status & BIT(7))
-                       linkstat = OMAP_MUSB_VBUS_VALID;
-               else
-                       linkstat = OMAP_MUSB_VBUS_OFF;
-       } else {
-               if (twl->linkstat != OMAP_MUSB_UNKNOWN)
-                       linkstat = OMAP_MUSB_VBUS_OFF;
-       }
-
-       dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
-                       status, status, linkstat);
-
-       /* REVISIT this assumes host and peripheral controllers
-        * are registered, and that both are active...
-        */
-
-       return linkstat;
-}
-
-static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode)
-{
-       twl->usb_mode = mode;
-
-       switch (mode) {
-       case T2_USB_MODE_ULPI:
-               twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL,
-                                       ULPI_IFC_CTRL_CARKITMODE);
-               twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
-               twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL,
-                                       ULPI_FUNC_CTRL_XCVRSEL_MASK |
-                                       ULPI_FUNC_CTRL_OPMODE_MASK);
-               break;
-       case -1:
-               /* FIXME: power on defaults */
-               break;
-       default:
-               dev_err(twl->dev, "unsupported T2 transceiver mode %d\n",
-                               mode);
-               break;
-       };
-}
-
-static void twl4030_i2c_access(struct twl4030_usb *twl, int on)
-{
-       unsigned long timeout;
-       int val = twl4030_usb_read(twl, PHY_CLK_CTRL);
-
-       if (val >= 0) {
-               if (on) {
-                       /* enable DPLL to access PHY registers over I2C */
-                       val |= REQ_PHY_DPLL_CLK;
-                       WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL,
-                                               (u8)val) < 0);
-
-                       timeout = jiffies + HZ;
-                       while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) &
-                                                       PHY_DPLL_CLK)
-                               && time_before(jiffies, timeout))
-                                       udelay(10);
-                       if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) &
-                                                       PHY_DPLL_CLK))
-                               dev_err(twl->dev, "Timeout setting T2 HSUSB "
-                                               "PHY DPLL clock\n");
-               } else {
-                       /* let ULPI control the DPLL clock */
-                       val &= ~REQ_PHY_DPLL_CLK;
-                       WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL,
-                                               (u8)val) < 0);
-               }
-       }
-}
-
-static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
-{
-       u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
-
-       if (on)
-               pwr &= ~PHY_PWR_PHYPWD;
-       else
-               pwr |= PHY_PWR_PHYPWD;
-
-       WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
-}
-
-static void twl4030_phy_power(struct twl4030_usb *twl, int on)
-{
-       int ret;
-
-       if (on) {
-               ret = regulator_enable(twl->usb3v1);
-               if (ret)
-                       dev_err(twl->dev, "Failed to enable usb3v1\n");
-
-               ret = regulator_enable(twl->usb1v8);
-               if (ret)
-                       dev_err(twl->dev, "Failed to enable usb1v8\n");
-
-               /*
-                * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
-                * in twl4030) resets the VUSB_DEDICATED2 register. This reset
-                * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
-                * SLEEP. We work around this by clearing the bit after usv3v1
-                * is re-activated. This ensures that VUSB3V1 is really active.
-                */
-               twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
-
-               ret = regulator_enable(twl->usb1v5);
-               if (ret)
-                       dev_err(twl->dev, "Failed to enable usb1v5\n");
-
-               __twl4030_phy_power(twl, 1);
-               twl4030_usb_write(twl, PHY_CLK_CTRL,
-                                 twl4030_usb_read(twl, PHY_CLK_CTRL) |
-                                       (PHY_CLK_CTRL_CLOCKGATING_EN |
-                                               PHY_CLK_CTRL_CLK32K_EN));
-       } else {
-               __twl4030_phy_power(twl, 0);
-               regulator_disable(twl->usb1v5);
-               regulator_disable(twl->usb1v8);
-               regulator_disable(twl->usb3v1);
-       }
-}
-
-static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off)
-{
-       if (twl->asleep)
-               return;
-
-       twl4030_phy_power(twl, 0);
-       twl->asleep = 1;
-       dev_dbg(twl->dev, "%s\n", __func__);
-}
-
-static void __twl4030_phy_resume(struct twl4030_usb *twl)
-{
-       twl4030_phy_power(twl, 1);
-       twl4030_i2c_access(twl, 1);
-       twl4030_usb_set_mode(twl, twl->usb_mode);
-       if (twl->usb_mode == T2_USB_MODE_ULPI)
-               twl4030_i2c_access(twl, 0);
-}
-
-static void twl4030_phy_resume(struct twl4030_usb *twl)
-{
-       if (!twl->asleep)
-               return;
-       __twl4030_phy_resume(twl);
-       twl->asleep = 0;
-       dev_dbg(twl->dev, "%s\n", __func__);
-
-       /*
-        * XXX When VBUS gets driven after musb goes to A mode,
-        * ID_PRES related interrupts no longer arrive, why?
-        * Register itself is updated fine though, so we must poll.
-        */
-       if (twl->linkstat == OMAP_MUSB_ID_GROUND) {
-               cancel_delayed_work(&twl->id_workaround_work);
-               schedule_delayed_work(&twl->id_workaround_work, HZ);
-       }
-}
-
-static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
-{
-       /* Enable writing to power configuration registers */
-       twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
-                        TWL4030_PM_MASTER_PROTECT_KEY);
-
-       twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
-                        TWL4030_PM_MASTER_PROTECT_KEY);
-
-       /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/
-       /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/
-
-       /* input to VUSB3V1 LDO is from VBAT, not VBUS */
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
-
-       /* Initialize 3.1V regulator */
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
-
-       twl->usb3v1 = devm_regulator_get(twl->dev, "usb3v1");
-       if (IS_ERR(twl->usb3v1))
-               return -ENODEV;
-
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
-
-       /* Initialize 1.5V regulator */
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
-
-       twl->usb1v5 = devm_regulator_get(twl->dev, "usb1v5");
-       if (IS_ERR(twl->usb1v5))
-               return -ENODEV;
-
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
-
-       /* Initialize 1.8V regulator */
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
-
-       twl->usb1v8 = devm_regulator_get(twl->dev, "usb1v8");
-       if (IS_ERR(twl->usb1v8))
-               return -ENODEV;
-
-       twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
-
-       /* disable access to power configuration registers */
-       twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
-                        TWL4030_PM_MASTER_PROTECT_KEY);
-
-       return 0;
-}
-
-static ssize_t twl4030_usb_vbus_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct twl4030_usb *twl = dev_get_drvdata(dev);
-       unsigned long flags;
-       int ret = -EINVAL;
-
-       spin_lock_irqsave(&twl->lock, flags);
-       ret = sprintf(buf, "%s\n",
-                       twl->vbus_supplied ? "on" : "off");
-       spin_unlock_irqrestore(&twl->lock, flags);
-
-       return ret;
-}
-static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
-
-static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
-{
-       struct twl4030_usb *twl = _twl;
-       enum omap_musb_vbus_id_status status;
-       bool status_changed = false;
-
-       status = twl4030_usb_linkstat(twl);
-
-       spin_lock_irq(&twl->lock);
-       if (status >= 0 && status != twl->linkstat) {
-               twl->linkstat = status;
-               status_changed = true;
-       }
-       spin_unlock_irq(&twl->lock);
-
-       if (status_changed) {
-               /* FIXME add a set_power() method so that B-devices can
-                * configure the charger appropriately.  It's not always
-                * correct to consume VBUS power, and how much current to
-                * consume is a function of the USB configuration chosen
-                * by the host.
-                *
-                * REVISIT usb_gadget_vbus_connect(...) as needed, ditto
-                * its disconnect() sibling, when changing to/from the
-                * USB_LINK_VBUS state.  musb_hdrc won't care until it
-                * starts to handle softconnect right.
-                */
-               omap_musb_mailbox(status);
-       }
-       sysfs_notify(&twl->dev->kobj, NULL, "vbus");
-
-       return IRQ_HANDLED;
-}
-
-static void twl4030_id_workaround_work(struct work_struct *work)
-{
-       struct twl4030_usb *twl = container_of(work, struct twl4030_usb,
-               id_workaround_work.work);
-       enum omap_musb_vbus_id_status status;
-       bool status_changed = false;
-
-       status = twl4030_usb_linkstat(twl);
-
-       spin_lock_irq(&twl->lock);
-       if (status >= 0 && status != twl->linkstat) {
-               twl->linkstat = status;
-               status_changed = true;
-       }
-       spin_unlock_irq(&twl->lock);
-
-       if (status_changed) {
-               dev_dbg(twl->dev, "handle missing status change to %d\n",
-                               status);
-               omap_musb_mailbox(status);
-       }
-
-       /* don't schedule during sleep - irq works right then */
-       if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
-               cancel_delayed_work(&twl->id_workaround_work);
-               schedule_delayed_work(&twl->id_workaround_work, HZ);
-       }
-}
-
-static int twl4030_usb_phy_init(struct usb_phy *phy)
-{
-       struct twl4030_usb *twl = phy_to_twl(phy);
-       enum omap_musb_vbus_id_status status;
-
-       /*
-        * Start in sleep state, we'll get called through set_suspend()
-        * callback when musb is runtime resumed and it's time to start.
-        */
-       __twl4030_phy_power(twl, 0);
-       twl->asleep = 1;
-
-       status = twl4030_usb_linkstat(twl);
-       twl->linkstat = status;
-
-       if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)
-               omap_musb_mailbox(twl->linkstat);
-
-       sysfs_notify(&twl->dev->kobj, NULL, "vbus");
-       return 0;
-}
-
-static int twl4030_set_suspend(struct usb_phy *x, int suspend)
-{
-       struct twl4030_usb *twl = phy_to_twl(x);
-
-       if (suspend)
-               twl4030_phy_suspend(twl, 1);
-       else
-               twl4030_phy_resume(twl);
-
-       return 0;
-}
-
-static int twl4030_set_peripheral(struct usb_otg *otg,
-                                       struct usb_gadget *gadget)
-{
-       if (!otg)
-               return -ENODEV;
-
-       otg->gadget = gadget;
-       if (!gadget)
-               otg->phy->state = OTG_STATE_UNDEFINED;
-
-       return 0;
-}
-
-static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host)
-{
-       if (!otg)
-               return -ENODEV;
-
-       otg->host = host;
-       if (!host)
-               otg->phy->state = OTG_STATE_UNDEFINED;
-
-       return 0;
-}
-
-static int twl4030_usb_probe(struct platform_device *pdev)
-{
-       struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
-       struct twl4030_usb      *twl;
-       int                     status, err;
-       struct usb_otg          *otg;
-       struct device_node      *np = pdev->dev.of_node;
-
-       twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
-       if (!twl)
-               return -ENOMEM;
-
-       if (np)
-               of_property_read_u32(np, "usb_mode",
-                               (enum twl4030_usb_mode *)&twl->usb_mode);
-       else if (pdata)
-               twl->usb_mode = pdata->usb_mode;
-       else {
-               dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
-               return -EINVAL;
-       }
-
-       otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL);
-       if (!otg)
-               return -ENOMEM;
-
-       twl->dev                = &pdev->dev;
-       twl->irq                = platform_get_irq(pdev, 0);
-       twl->vbus_supplied      = false;
-       twl->asleep             = 1;
-       twl->linkstat           = OMAP_MUSB_UNKNOWN;
-
-       twl->phy.dev            = twl->dev;
-       twl->phy.label          = "twl4030";
-       twl->phy.otg            = otg;
-       twl->phy.type           = USB_PHY_TYPE_USB2;
-       twl->phy.set_suspend    = twl4030_set_suspend;
-       twl->phy.init           = twl4030_usb_phy_init;
-
-       otg->phy                = &twl->phy;
-       otg->set_host           = twl4030_set_host;
-       otg->set_peripheral     = twl4030_set_peripheral;
-
-       /* init spinlock for workqueue */
-       spin_lock_init(&twl->lock);
-
-       INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work);
-
-       err = twl4030_usb_ldo_init(twl);
-       if (err) {
-               dev_err(&pdev->dev, "ldo init failed\n");
-               return err;
-       }
-       usb_add_phy_dev(&twl->phy);
-
-       platform_set_drvdata(pdev, twl);
-       if (device_create_file(&pdev->dev, &dev_attr_vbus))
-               dev_warn(&pdev->dev, "could not create sysfs file\n");
-
-       /* Our job is to use irqs and status from the power module
-        * to keep the transceiver disabled when nothing's connected.
-        *
-        * FIXME we actually shouldn't start enabling it until the
-        * USB controller drivers have said they're ready, by calling
-        * set_host() and/or set_peripheral() ... OTG_capable boards
-        * need both handles, otherwise just one suffices.
-        */
-       twl->irq_enabled = true;
-       status = devm_request_threaded_irq(twl->dev, twl->irq, NULL,
-                       twl4030_usb_irq, IRQF_TRIGGER_FALLING |
-                       IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl);
-       if (status < 0) {
-               dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
-                       twl->irq, status);
-               return status;
-       }
-
-       dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
-       return 0;
-}
-
-static int twl4030_usb_remove(struct platform_device *pdev)
-{
-       struct twl4030_usb *twl = platform_get_drvdata(pdev);
-       int val;
-
-       cancel_delayed_work(&twl->id_workaround_work);
-       device_remove_file(twl->dev, &dev_attr_vbus);
-
-       /* set transceiver mode to power on defaults */
-       twl4030_usb_set_mode(twl, -1);
-
-       /* autogate 60MHz ULPI clock,
-        * clear dpll clock request for i2c access,
-        * disable 32KHz
-        */
-       val = twl4030_usb_read(twl, PHY_CLK_CTRL);
-       if (val >= 0) {
-               val |= PHY_CLK_CTRL_CLOCKGATING_EN;
-               val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK);
-               twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val);
-       }
-
-       /* disable complete OTG block */
-       twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
-
-       if (!twl->asleep)
-               twl4030_phy_power(twl, 0);
-
-       return 0;
-}
-
-#ifdef CONFIG_OF
-static const struct of_device_id twl4030_usb_id_table[] = {
-       { .compatible = "ti,twl4030-usb" },
-       {}
-};
-MODULE_DEVICE_TABLE(of, twl4030_usb_id_table);
-#endif
-
-static struct platform_driver twl4030_usb_driver = {
-       .probe          = twl4030_usb_probe,
-       .remove         = twl4030_usb_remove,
-       .driver         = {
-               .name   = "twl4030_usb",
-               .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(twl4030_usb_id_table),
-       },
-};
-
-static int __init twl4030_usb_init(void)
-{
-       return platform_driver_register(&twl4030_usb_driver);
-}
-subsys_initcall(twl4030_usb_init);
-
-static void __exit twl4030_usb_exit(void)
-{
-       platform_driver_unregister(&twl4030_usb_driver);
-}
-module_exit(twl4030_usb_exit);
-
-MODULE_ALIAS("platform:twl4030_usb");
-MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation");
-MODULE_DESCRIPTION("TWL4030 USB transceiver driver");
-MODULE_LICENSE("GPL");
index 16dbc93826789dc22d0a2d955bc4c880cf9196c5..30e8a61552d4d0526d999c0b49651593f04a5530 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 
 /* usb register definitions */
 #define USB_VENDOR_ID_LSB              0x00
index 7c22a5390fc34dddf8e6f9987da559d32732a406..18bb8264b5a0565e91f714df9544fa8f27b9b189 100644 (file)
@@ -36,7 +36,7 @@ static int ulpi_viewport_wait(void __iomem *view, u32 mask)
                        return 0;
 
                udelay(1);
-       };
+       }
 
        return -ETIMEDOUT;
 }
index a9984c700d2c428fd2e771a1d175c12009f94475..1b74523e1fee5640bad21035b171ef9cf2c5289b 100644 (file)
@@ -98,7 +98,7 @@ struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type)
 
        ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
        if (!ptr)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        phy = usb_get_phy(type);
        if (!IS_ERR(phy)) {
index 781426230d695a3f34544ab4b0a589a500a0063e..6e1b69d0f5f57da980f439a3643567ada4aec3b6 100644 (file)
@@ -279,7 +279,7 @@ static void cyberjack_read_int_callback(struct urb *urb)
 
                old_rdtodo = priv->rdtodo;
 
-               if (old_rdtodo + size < old_rdtodo) {
+               if (old_rdtodo > SHRT_MAX - size) {
                        dev_dbg(dev, "To many bulk_in urbs to do.\n");
                        spin_unlock(&priv->lock);
                        goto resubmit;
index c45f9c0a1b3493f8f5566c87d6b8702f9fc8116c..9ced8937a8f3a699dad340e1e9ea62c9d706dc69 100644 (file)
@@ -904,6 +904,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
        /* Crucible Devices */
        { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
        { }                                     /* Terminating entry */
 };
 
@@ -1966,8 +1967,16 @@ static int ftdi_process_packet(struct usb_serial_port *port,
                        port->icount.dsr++;
                if (diff_status & FTDI_RS0_RI)
                        port->icount.rng++;
-               if (diff_status & FTDI_RS0_RLSD)
+               if (diff_status & FTDI_RS0_RLSD) {
+                       struct tty_struct *tty;
+
                        port->icount.dcd++;
+                       tty = tty_port_tty_get(&port->port);
+                       if (tty)
+                               usb_serial_handle_dcd_change(port, tty,
+                                               status & FTDI_RS0_RLSD);
+                       tty_kref_put(tty);
+               }
 
                wake_up_interruptible(&port->port.delta_msr_wait);
                priv->prev_status = status;
index 1b8af461b522c65a111983226ba1e704f012ac8c..a7019d1e305814867bb43792ebe55eb00dd7c3fd 100644 (file)
  * Manufacturer: Crucible Technologies
  */
 #define FTDI_CT_COMET_PID      0x8e08
+
+/*
+ * Product: Z3X Box
+ * Manufacturer: Smart GSM Team
+ */
+#define FTDI_Z3X_PID           0x0011
index 1f31e6b4c2518f262a263bbefdddf5fda6ba9cb6..2b01ec8651c296e3f016bf2421040da6f1bbbc98 100644 (file)
@@ -7,7 +7,6 @@
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License version
  *     2 as published by the Free Software Foundation.
- *
  */
 
 #include <linux/kernel.h>
@@ -37,7 +36,6 @@ MODULE_PARM_DESC(product, "User specified USB idProduct");
 
 static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */
 
-/* All of the device info needed for the Generic Serial Converter */
 struct usb_serial_driver usb_serial_generic_device = {
        .driver = {
                .owner =        THIS_MODULE,
@@ -66,7 +64,6 @@ int usb_serial_generic_register(void)
        generic_device_ids[0].match_flags =
                USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
 
-       /* register our generic driver with ourselves */
        retval = usb_serial_register_drivers(serial_drivers,
                        "usbserial_generic", generic_device_ids);
 #endif
@@ -76,7 +73,6 @@ int usb_serial_generic_register(void)
 void usb_serial_generic_deregister(void)
 {
 #ifdef CONFIG_USB_SERIAL_GENERIC
-       /* remove our generic driver */
        usb_serial_deregister_drivers(serial_drivers);
 #endif
 }
@@ -86,13 +82,11 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port
        int result = 0;
        unsigned long flags;
 
-       /* clear the throttle flags */
        spin_lock_irqsave(&port->lock, flags);
        port->throttled = 0;
        port->throttle_req = 0;
        spin_unlock_irqrestore(&port->lock, flags);
 
-       /* if we have a bulk endpoint, start reading from it */
        if (port->bulk_in_size)
                result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
 
@@ -127,12 +121,16 @@ int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
 }
 
 /**
- * usb_serial_generic_write_start - kick off an URB write
- * @port:      Pointer to the &struct usb_serial_port data
+ * usb_serial_generic_write_start - start writing buffered data
+ * @port: usb-serial port
+ * @mem_flags: flags to use for memory allocations
+ *
+ * Serialised using USB_SERIAL_WRITE_BUSY flag.
  *
- * Returns zero on success, or a negative errno value
+ * Return: Zero on success or if busy, otherwise a negative errno value.
  */
-static int usb_serial_generic_write_start(struct usb_serial_port *port)
+int usb_serial_generic_write_start(struct usb_serial_port *port,
+                                                       gfp_t mem_flags)
 {
        struct urb *urb;
        int count, result;
@@ -163,7 +161,7 @@ retry:
        spin_unlock_irqrestore(&port->lock, flags);
 
        clear_bit(i, &port->write_urbs_free);
-       result = usb_submit_urb(urb, GFP_ATOMIC);
+       result = usb_submit_urb(urb, mem_flags);
        if (result) {
                dev_err_console(port, "%s - error submitting urb: %d\n",
                                                __func__, result);
@@ -175,34 +173,34 @@ retry:
                clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags);
                return result;
        }
-
-       /* Try sending off another urb, unless in irq context (in which case
-        * there will be no free urb). */
-       if (!in_irq())
+       /*
+        * 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;
 }
+EXPORT_SYMBOL_GPL(usb_serial_generic_write_start);
 
 /**
- * usb_serial_generic_write - generic write function for serial USB devices
- * @tty:       Pointer to &struct tty_struct for the device
- * @port:      Pointer to the &usb_serial_port structure for the device
- * @buf:       Pointer to the data to write
- * @count:     Number of bytes to write
+ * usb_serial_generic_write - generic write function
+ * @tty: tty for the port
+ * @port: usb-serial port
+ * @buf: data to write
+ * @count: number of bytes to write
  *
- * Returns the number of characters actually written, which may be anything
- * from zero to @count. If an error occurs, it returns the negative errno
- * value.
+ * Return: The number of characters buffered, which may be anything from
+ * zero to @count, or a negative errno value.
  */
 int usb_serial_generic_write(struct tty_struct *tty,
        struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        int result;
 
-       /* only do something if we have a bulk out endpoint */
        if (!port->bulk_out_size)
                return -ENODEV;
 
@@ -210,7 +208,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);
+       result = usb_serial_generic_write_start(port, GFP_KERNEL);
        if (result)
                return result;
 
@@ -337,10 +335,11 @@ void usb_serial_generic_process_read_urb(struct urb *urb)
 
        if (!urb->actual_length)
                return;
-
-       /* The per character mucking around with sysrq path it too slow for
-          stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases
-          where the USB serial is not a console anyway */
+       /*
+        * The per character mucking around with sysrq path it too slow for
+        * stuff like 3G modems, so shortcircuit it in the 99.9999999% of
+        * cases where the USB serial is not a console anyway.
+        */
        if (!port->port.console || !port->sysrq)
                tty_insert_flip_string(&port->port, ch, urb->actual_length);
        else {
@@ -413,7 +412,7 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
                kfifo_reset_out(&port->write_fifo);
                spin_unlock_irqrestore(&port->lock, flags);
        } else {
-               usb_serial_generic_write_start(port);
+               usb_serial_generic_write_start(port, GFP_ATOMIC);
        }
 
        usb_serial_port_softint(port);
@@ -425,8 +424,6 @@ void usb_serial_generic_throttle(struct tty_struct *tty)
        struct usb_serial_port *port = tty->driver_data;
        unsigned long flags;
 
-       /* Set the throttle request flag. It will be picked up
-        * by usb_serial_generic_read_bulk_callback(). */
        spin_lock_irqsave(&port->lock, flags);
        port->throttle_req = 1;
        spin_unlock_irqrestore(&port->lock, flags);
@@ -438,7 +435,6 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
        struct usb_serial_port *port = tty->driver_data;
        int was_throttled;
 
-       /* Clear the throttle flags */
        spin_lock_irq(&port->lock);
        was_throttled = port->throttled;
        port->throttled = port->throttle_req = 0;
@@ -558,10 +554,10 @@ int usb_serial_handle_break(struct usb_serial_port *port)
 EXPORT_SYMBOL_GPL(usb_serial_handle_break);
 
 /**
- *     usb_serial_handle_dcd_change - handle a change of carrier detect state
- *     @port: usb_serial_port structure for the open port
- *     @tty: tty_struct structure for the port
- *     @status: new carrier detect status, nonzero if active
+ * usb_serial_handle_dcd_change - handle a change of carrier detect state
+ * @port: usb-serial port
+ * @tty: tty for the port
+ * @status: new carrier detect status, nonzero if active
  */
 void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
                                struct tty_struct *tty, unsigned int status)
@@ -570,6 +566,16 @@ void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
 
        dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status);
 
+       if (tty) {
+               struct tty_ldisc *ld = tty_ldisc_ref(tty);
+
+               if (ld) {
+                       if (ld->ops->dcd_change)
+                               ld->ops->dcd_change(tty, status);
+                       tty_ldisc_deref(ld);
+               }
+       }
+
        if (status)
                wake_up_interruptible(&port->open_wait);
        else if (tty && !C_CLOCAL(tty))
@@ -595,7 +601,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
                }
 
                if (port->bulk_out_size) {
-                       r = usb_serial_generic_write_start(port);
+                       r = usb_serial_generic_write_start(port, GFP_NOIO);
                        if (r < 0)
                                c++;
                }
index fdf953539c62b4943a5ef1c6f93eab52cd53e463..e5bdd987b9e8f7e260fc95c48b142742026999fa 100644 (file)
@@ -1532,7 +1532,11 @@ static int mos7840_tiocmget(struct tty_struct *tty)
                return -ENODEV;
 
        status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
+       if (status != 1)
+               return -EIO;
        status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
+       if (status != 1)
+               return -EIO;
        result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
            | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
            | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
index acaee066b99aa10e5ecf2a8e75cffd31899b6507..c3d94853b4ab7a2dd13d8f6dea0009f55795ba56 100644 (file)
@@ -1376,6 +1376,23 @@ static const struct usb_device_id option_ids[] = {
                .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff),  /* ZTE MF91 */
                .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1545, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1546, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1547, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1565, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1566, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1567, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1589, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1590, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1591, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1592, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1594, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1596, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1598, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1600, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
          0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
index bedf8e47713be02dfc80b8a2e3512cb24a455a15..1e6de4cd079d6a2c0e3b4b3c7679d6145bcf6f2c 100644 (file)
@@ -4,11 +4,6 @@
  * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
  * Copyright (C) 2003 IBM Corp.
  *
- * Copyright (C) 2009, 2013 Frank Schäfer <fschaefer.oss@googlemail.com>
- *  - fixes, improvements and documentation for the baud rate encoding methods
- * Copyright (C) 2013 Reinhard Max <max@suse.de>
- *  - fixes and improvements for the divisor based baud rate encoding method
- *
  * Original driver for 2.2.x by anonymous
  *
  *     This program is free software; you can redistribute it and/or
@@ -134,18 +129,10 @@ MODULE_DEVICE_TABLE(usb, id_table);
 
 
 enum pl2303_type {
-       type_0,         /* H version ? */
-       type_1,         /* H version ? */
-       HX_TA,          /* HX(A) / X(A) / TA version  */ /* TODO: improve */
-       HXD_EA_RA_SA,   /* HXD / EA / RA / SA version */ /* TODO: improve */
-       TB,             /* TB version */
-       HX_CLONE,       /* Cheap and less functional clone of the HX chip */
+       type_0,         /* don't know the difference between type 0 and */
+       type_1,         /* type 1, until someone from prolific tells us... */
+       HX,             /* HX version of the pl2303 chip */
 };
-/*
- * NOTE: don't know the difference between type 0 and type 1,
- * until someone from Prolific tells us...
- * TODO: distinguish between X/HX, TA and HXD, EA, RA, SA variants
- */
 
 struct pl2303_serial_private {
        enum pl2303_type type;
@@ -185,7 +172,6 @@ static int pl2303_startup(struct usb_serial *serial)
 {
        struct pl2303_serial_private *spriv;
        enum pl2303_type type = type_0;
-       char *type_str = "unknown (treating as type_0)";
        unsigned char *buf;
 
        spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
@@ -198,53 +184,15 @@ static int pl2303_startup(struct usb_serial *serial)
                return -ENOMEM;
        }
 
-       if (serial->dev->descriptor.bDeviceClass == 0x02) {
+       if (serial->dev->descriptor.bDeviceClass == 0x02)
                type = type_0;
-               type_str = "type_0";
-       } else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) {
-               /*
-                * NOTE: The bcdDevice version is the only difference between
-                * the device descriptors of the X/HX, HXD, EA, RA, SA, TA, TB
-                */
-               if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x300) {
-                       /* Check if the device is a clone */
-                       pl2303_vendor_read(0x9494, 0, serial, buf);
-                       /*
-                        * NOTE: Not sure if this read is really needed.
-                        * The HX returns 0x00, the clone 0x02, but the Windows
-                        * driver seems to ignore the value and continues.
-                        */
-                       pl2303_vendor_write(0x0606, 0xaa, serial);
-                       pl2303_vendor_read(0x8686, 0, serial, buf);
-                       if (buf[0] != 0xaa) {
-                               type = HX_CLONE;
-                               type_str = "X/HX clone (limited functionality)";
-                       } else {
-                               type = HX_TA;
-                               type_str = "X/HX/TA";
-                       }
-                       pl2303_vendor_write(0x0606, 0x00, serial);
-               } else if (le16_to_cpu(serial->dev->descriptor.bcdDevice)
-                                                                    == 0x400) {
-                       type = HXD_EA_RA_SA;
-                       type_str = "HXD/EA/RA/SA";
-               } else if (le16_to_cpu(serial->dev->descriptor.bcdDevice)
-                                                                    == 0x500) {
-                       type = TB;
-                       type_str = "TB";
-               } else {
-                       dev_info(&serial->interface->dev,
-                                          "unknown/unsupported device type\n");
-                       kfree(spriv);
-                       kfree(buf);
-                       return -ENODEV;
-               }
-       } else if (serial->dev->descriptor.bDeviceClass == 0x00
-                  || serial->dev->descriptor.bDeviceClass == 0xFF) {
+       else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)
+               type = HX;
+       else if (serial->dev->descriptor.bDeviceClass == 0x00)
                type = type_1;
-               type_str = "type_1";
-       }
-       dev_dbg(&serial->interface->dev, "device type: %s\n", type_str);
+       else if (serial->dev->descriptor.bDeviceClass == 0xFF)
+               type = type_1;
+       dev_dbg(&serial->interface->dev, "device type: %d\n", type);
 
        spriv->type = type;
        usb_set_serial_data(serial, spriv);
@@ -259,10 +207,10 @@ static int pl2303_startup(struct usb_serial *serial)
        pl2303_vendor_read(0x8383, 0, serial, buf);
        pl2303_vendor_write(0, 1, serial);
        pl2303_vendor_write(1, 0, serial);
-       if (type == type_0 || type == type_1)
-               pl2303_vendor_write(2, 0x24, serial);
-       else
+       if (type == HX)
                pl2303_vendor_write(2, 0x44, serial);
+       else
+               pl2303_vendor_write(2, 0x24, serial);
 
        kfree(buf);
        return 0;
@@ -316,174 +264,65 @@ static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value)
        return retval;
 }
 
-static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type,
-                                                                     u8 buf[4])
+static void pl2303_encode_baudrate(struct tty_struct *tty,
+                                       struct usb_serial_port *port,
+                                       u8 buf[4])
 {
-       /*
-        * NOTE: Only the values defined in baud_sup are supported !
-        * => if unsupported values are set, the PL2303 uses 9600 baud instead
-        * => HX clones just don't work at unsupported baud rates < 115200 baud,
-        *    for baud rates > 115200 they run at 115200 baud
-        */
        const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600,
-                                4800, 7200, 9600, 14400, 19200, 28800, 38400,
-                                57600, 115200, 230400, 460800, 614400, 921600,
-                                1228800, 2457600, 3000000, 6000000, 12000000 };
+                                4800, 7200, 9600, 14400, 19200, 28800, 38400,
+                                57600, 115200, 230400, 460800, 500000, 614400,
+                                921600, 1228800, 2457600, 3000000, 6000000 };
+
+       struct usb_serial *serial = port->serial;
+       struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
+       int baud;
+       int i;
+
        /*
-        * NOTE: With the exception of type_0/1 devices, the following
-        * additional baud rates are supported (tested with HX rev. 3A only):
-        * 110*, 56000*, 128000, 134400, 161280, 201600, 256000*, 268800,
-        * 403200, 806400.      (*: not HX and HX clones)
-        *
-        * Maximum values: HXD, TB: 12000000; HX, TA: 6000000;
-        *                 type_0+1: 1228800; RA: 921600; HX clones, SA: 115200
-        *
-        * As long as we are not using this encoding method for anything else
-        * than the type_0+1, HX and HX clone chips, there is no point in
-        * complicating the code to support them.
+        * NOTE: Only the values defined in baud_sup are supported!
+        *       => if unsupported values are set, the PL2303 seems to use
+        *          9600 baud (at least my PL2303X always does)
         */
-       int i;
+       baud = tty_get_baud_rate(tty);
+       dev_dbg(&port->dev, "baud requested = %d\n", baud);
+       if (!baud)
+               return;
 
        /* Set baudrate to nearest supported value */
        for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) {
                if (baud_sup[i] > baud)
                        break;
        }
+
        if (i == ARRAY_SIZE(baud_sup))
                baud = baud_sup[i - 1];
        else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1]))
                baud = baud_sup[i - 1];
        else
                baud = baud_sup[i];
-       /* Respect the chip type specific baud rate limits */
-       /*
-        * FIXME: as long as we don't know how to distinguish between the
-        * HXD, EA, RA, and SA chip variants, allow the max. value of 12M.
-        */
-       if (type == HX_TA)
-               baud = min_t(int, baud, 6000000);
-       else if (type == type_0 || type == type_1)
-               baud = min_t(int, baud, 1228800);
-       else if (type == HX_CLONE)
-               baud = min_t(int, baud, 115200);
-       /* Direct (standard) baud rate encoding method */
-       put_unaligned_le32(baud, buf);
-
-       return baud;
-}
 
-static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type,
-                                                                     u8 buf[4])
-{
-       /*
-        * Divisor based baud rate encoding method
-        *
-        * NOTE: HX clones do NOT support this method.
-        * It's not clear if the type_0/1 chips support it.
-        *
-        * divisor = 12MHz * 32 / baudrate = 2^A * B
-        *
-        * with
-        *
-        * A = buf[1] & 0x0e
-        * B = buf[0]  +  (buf[1] & 0x01) << 8
-        *
-        * Special cases:
-        * => 8 < B < 16: device seems to work not properly
-        * => B <= 8: device uses the max. value B = 512 instead
-        */
-       unsigned int A, B;
+       /* type_0, type_1 only support up to 1228800 baud */
+       if (spriv->type != HX)
+               baud = min_t(int, baud, 1228800);
 
-       /*
-        * NOTE: The Windows driver allows maximum baud rates of 110% of the
-        * specified maximium value.
-        * Quick tests with early (2004) HX (rev. A) chips suggest, that even
-        * higher baud rates (up to the maximum of 24M baud !) are working fine,
-        * but that should really be tested carefully in "real life" scenarios
-        * before removing the upper limit completely.
-        * Baud rates smaller than the specified 75 baud are definitely working
-        * fine.
-        */
-       if (type == type_0 || type == type_1)
-               baud = min_t(int, baud, 1228800 * 1.1);
-       else if (type == HX_TA)
-               baud = min_t(int, baud, 6000000 * 1.1);
-       else if (type == HXD_EA_RA_SA)
-               /* HXD, EA: 12Mbps; RA: 1Mbps; SA: 115200 bps */
-               /*
-                * FIXME: as long as we don't know how to distinguish between
-                * these chip variants, allow the max. of these values
-                */
-               baud = min_t(int, baud, 12000000 * 1.1);
-       else if (type == TB)
-               baud = min_t(int, baud, 12000000 * 1.1);
-       /* Determine factors A and B */
-       A = 0;
-       B = 12000000 * 32 / baud;  /* 12MHz */
-       B <<= 1; /* Add one bit for rounding */
-       while (B > (512 << 1) && A <= 14) {
-               A += 2;
-               B >>= 2;
-       }
-       if (A > 14) { /* max. divisor = min. baudrate reached */
-               A = 14;
-               B = 512;
-               /* => ~45.78 baud */
+       if (baud <= 115200) {
+               put_unaligned_le32(baud, buf);
        } else {
-               B = (B + 1) >> 1; /* Round the last bit */
-       }
-       /* Handle special cases */
-       if (B == 512)
-               B = 0; /* also: 1 to 8 */
-       else if (B < 16)
                /*
-                * NOTE: With the current algorithm this happens
-                * only for A=0 and means that the min. divisor
-                * (respectively: the max. baudrate) is reached.
+                * Apparently the formula for higher speeds is:
+                * baudrate = 12M * 32 / (2^buf[1]) / buf[0]
                 */
-               B = 16;         /* => 24 MBaud */
-       /* Encode the baud rate */
-       buf[3] = 0x80;     /* Select divisor encoding method */
-       buf[2] = 0;
-       buf[1] = (A & 0x0e);            /* A */
-       buf[1] |= ((B & 0x100) >> 8);   /* MSB of B */
-       buf[0] = B & 0xff;              /* 8 LSBs of B */
-       /* Calculate the actual/resulting baud rate */
-       if (B <= 8)
-               B = 512;
-       baud = 12000000 * 32 / ((1 << A) * B);
-
-       return baud;
-}
-
-static void pl2303_encode_baudrate(struct tty_struct *tty,
-                                       struct usb_serial_port *port,
-                                       enum pl2303_type type,
-                                       u8 buf[4])
-{
-       int baud;
+               unsigned tmp = 12000000 * 32 / baud;
+               buf[3] = 0x80;
+               buf[2] = 0;
+               buf[1] = (tmp >= 256);
+               while (tmp >= 256) {
+                       tmp >>= 2;
+                       buf[1] <<= 1;
+               }
+               buf[0] = tmp;
+       }
 
-       baud = tty_get_baud_rate(tty);
-       dev_dbg(&port->dev, "baud requested = %d\n", baud);
-       if (!baud)
-               return;
-       /*
-        * There are two methods for setting/encoding the baud rate
-        * 1) Direct method: encodes the baud rate value directly
-        *    => supported by all chip types
-        * 2) Divisor based method: encodes a divisor to a base value (12MHz*32)
-        *    => not supported by HX clones (and likely type_0/1 chips)
-        *
-        * NOTE: Although the divisor based baud rate encoding method is much
-        * more flexible, some of the standard baud rate values can not be
-        * realized exactly. But the difference is very small (max. 0.2%) and
-        * the device likely uses the same baud rate generator for both methods
-        * so that there is likley no difference.
-        */
-       if (type == type_0 || type == type_1 || type == HX_CLONE)
-               baud = pl2303_baudrate_encode_direct(baud, type, buf);
-       else
-               baud = pl2303_baudrate_encode_divisor(baud, type, buf);
        /* Save resulting baud rate */
        tty_encode_baud_rate(tty, baud, baud);
        dev_dbg(&port->dev, "baud set = %d\n", baud);
@@ -540,8 +379,8 @@ static void pl2303_set_termios(struct tty_struct *tty,
                dev_dbg(&port->dev, "data bits = %d\n", buf[6]);
        }
 
-       /* For reference:   buf[0]:buf[3] baud rate value */
-       pl2303_encode_baudrate(tty, port, spriv->type, buf);
+       /* For reference buf[0]:buf[3] baud rate value */
+       pl2303_encode_baudrate(tty, port, &buf[0]);
 
        /* For reference buf[4]=0 is 1 stop bits */
        /* For reference buf[4]=1 is 1.5 stop bits */
@@ -618,10 +457,10 @@ static void pl2303_set_termios(struct tty_struct *tty,
        dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %7ph\n", i, buf);
 
        if (C_CRTSCTS(tty)) {
-               if (spriv->type == type_0 || spriv->type == type_1)
-                       pl2303_vendor_write(0x0, 0x41, serial);
-               else
+               if (spriv->type == HX)
                        pl2303_vendor_write(0x0, 0x61, serial);
+               else
+                       pl2303_vendor_write(0x0, 0x41, serial);
        } else {
                pl2303_vendor_write(0x0, 0x0, serial);
        }
@@ -658,7 +497,7 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
        struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
        int result;
 
-       if (spriv->type == type_0 || spriv->type == type_1) {
+       if (spriv->type != HX) {
                usb_clear_halt(serial->dev, port->write_urb->pipe);
                usb_clear_halt(serial->dev, port->read_urb->pipe);
        } else {
@@ -833,7 +672,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
        result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                 BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
                                 0, NULL, 0, 100);
-       /* NOTE: HX clones don't support sending breaks, -EPIPE is returned */
        if (result)
                dev_err(&port->dev, "error sending break = %d\n", result);
 }
index 7f78f300f8fbe02674aa7f1f0846d8399c3be0f8..f06ed82e63d139fa2d25efd1ef2ac7cf5545e995 100644 (file)
@@ -208,9 +208,9 @@ static int cbaf_check(struct cbaf *cbaf)
                                ar_name = "ASSOCIATE";
                                ar_assoc = 1;
                                break;
-                       };
+                       }
                        break;
-               };
+               }
 
                dev_dbg(dev, "Association request #%02u: 0x%04x/%04x "
                         "(%zu bytes): %s\n",
@@ -623,6 +623,8 @@ static int cbaf_probe(struct usb_interface *iface,
 
 error_create_group:
 error_check:
+       usb_put_intf(iface);
+       usb_put_dev(cbaf->usb_dev);
        kfree(cbaf->buffer);
 error_kmalloc_buffer:
        kfree(cbaf);
@@ -637,6 +639,7 @@ static void cbaf_disconnect(struct usb_interface *iface)
        sysfs_remove_group(&dev->kobj, &cbaf_dev_attr_group);
        usb_set_intfdata(iface, NULL);
        usb_put_intf(iface);
+       usb_put_dev(cbaf->usb_dev);
        kfree(cbaf->buffer);
        /* paranoia: clean up crypto keys */
        kzfree(cbaf);
index 33a12788f9ca063c8aae13ce28d9b978f27a372c..e538b72c4e3af2d09153614952e12101eac03520 100644 (file)
@@ -973,7 +973,7 @@ int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
        default:
                WARN_ON(1);
                result = NOTIFY_BAD;
-       };
+       }
        return result;
 }
 
index a09b65ebd9bb712d02060e760ff2c349bcdc2e77..368360f9a93ae1283780c3b30e230c6efd630b38 100644 (file)
@@ -33,7 +33,8 @@
  * wa->usb_dev and wa->usb_iface initialized and refcounted,
  * wa->wa_descr initialized.
  */
-int wa_create(struct wahc *wa, struct usb_interface *iface)
+int wa_create(struct wahc *wa, struct usb_interface *iface,
+       kernel_ulong_t quirks)
 {
        int result;
        struct device *dev = &iface->dev;
@@ -41,14 +42,15 @@ int wa_create(struct wahc *wa, struct usb_interface *iface)
        result = wa_rpipes_create(wa);
        if (result < 0)
                goto error_rpipes_create;
+       wa->quirks = quirks;
        /* Fill up Data Transfer EP pointers */
        wa->dti_epd = &iface->cur_altsetting->endpoint[1].desc;
        wa->dto_epd = &iface->cur_altsetting->endpoint[2].desc;
-       wa->xfer_result_size = usb_endpoint_maxp(wa->dti_epd);
-       wa->xfer_result = kmalloc(wa->xfer_result_size, GFP_KERNEL);
-       if (wa->xfer_result == NULL) {
+       wa->dti_buf_size = usb_endpoint_maxp(wa->dti_epd);
+       wa->dti_buf = kmalloc(wa->dti_buf_size, GFP_KERNEL);
+       if (wa->dti_buf == NULL) {
                result = -ENOMEM;
-               goto error_xfer_result_alloc;
+               goto error_dti_buf_alloc;
        }
        result = wa_nep_create(wa, iface);
        if (result < 0) {
@@ -59,8 +61,8 @@ int wa_create(struct wahc *wa, struct usb_interface *iface)
        return 0;
 
 error_nep_create:
-       kfree(wa->xfer_result);
-error_xfer_result_alloc:
+       kfree(wa->dti_buf);
+error_dti_buf_alloc:
        wa_rpipes_destroy(wa);
 error_rpipes_create:
        return result;
@@ -76,7 +78,7 @@ void __wa_destroy(struct wahc *wa)
                usb_kill_urb(wa->buf_in_urb);
                usb_put_urb(wa->buf_in_urb);
        }
-       kfree(wa->xfer_result);
+       kfree(wa->dti_buf);
        wa_nep_destroy(wa);
        wa_rpipes_destroy(wa);
 }
index cf250c21e946bcab938baafc6ca3f48ca2f1a2d3..e614f02f0cf2cef4478f0a4a8aa1fc1ddecb7175 100644 (file)
@@ -117,11 +117,25 @@ struct wa_rpipe {
        struct wahc *wa;
        spinlock_t seg_lock;
        struct list_head seg_list;
+       struct list_head list_node;
        atomic_t segs_available;
        u8 buffer[1];   /* For reads/writes on USB */
 };
 
 
+enum wa_dti_state {
+       WA_DTI_TRANSFER_RESULT_PENDING,
+       WA_DTI_ISOC_PACKET_STATUS_PENDING
+};
+
+enum wa_quirks {
+       /*
+        * The Alereon HWA expects the data frames in isochronous transfer
+        * requests to be concatenated and not sent as separate packets.
+        */
+       WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC      = 0x01,
+};
+
 /**
  * Instance of a HWA Host Controller
  *
@@ -178,14 +192,26 @@ struct wahc {
 
        u16 rpipes;
        unsigned long *rpipe_bm;        /* rpipe usage bitmap */
-       spinlock_t rpipe_bm_lock;       /* protect rpipe_bm */
+       struct list_head rpipe_delayed_list;    /* delayed RPIPES. */
+       spinlock_t rpipe_lock;  /* protect rpipe_bm and delayed list */
        struct mutex rpipe_mutex;       /* assigning resources to endpoints */
 
+       /*
+        * dti_state is used to track the state of the dti_urb.  When dti_state
+        * is WA_DTI_ISOC_PACKET_STATUS_PENDING, dti_isoc_xfer_in_progress and
+        * dti_isoc_xfer_seg identify which xfer the incoming isoc packet status
+        * refers to.
+        */
+       enum wa_dti_state dti_state;
+       u32 dti_isoc_xfer_in_progress;
+       u8  dti_isoc_xfer_seg;
        struct urb *dti_urb;            /* URB for reading xfer results */
        struct urb *buf_in_urb;         /* URB for reading data in */
        struct edc dti_edc;             /* DTI error density counter */
-       struct wa_xfer_result *xfer_result; /* real size = dti_ep maxpktsize */
-       size_t xfer_result_size;
+       void *dti_buf;
+       size_t dti_buf_size;
+
+       unsigned long dto_in_use;       /* protect dto endoint serialization. */
 
        s32 status;                     /* For reading status */
 
@@ -200,10 +226,13 @@ struct wahc {
        struct work_struct xfer_enqueue_work;
        struct work_struct xfer_error_work;
        atomic_t xfer_id_count;
+
+       kernel_ulong_t  quirks;
 };
 
 
-extern int wa_create(struct wahc *wa, struct usb_interface *iface);
+extern int wa_create(struct wahc *wa, struct usb_interface *iface,
+       kernel_ulong_t);
 extern void __wa_destroy(struct wahc *wa);
 void wa_reset_all(struct wahc *wa);
 
@@ -239,7 +268,8 @@ static inline void wa_nep_disarm(struct wahc *wa)
 /* RPipes */
 static inline void wa_rpipe_init(struct wahc *wa)
 {
-       spin_lock_init(&wa->rpipe_bm_lock);
+       INIT_LIST_HEAD(&wa->rpipe_delayed_list);
+       spin_lock_init(&wa->rpipe_lock);
        mutex_init(&wa->rpipe_mutex);
 }
 
@@ -247,6 +277,7 @@ static inline void wa_init(struct wahc *wa)
 {
        edc_init(&wa->nep_edc);
        atomic_set(&wa->notifs_queued, 0);
+       wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
        wa_rpipe_init(wa);
        edc_init(&wa->dti_edc);
        INIT_LIST_HEAD(&wa->xfer_list);
@@ -255,6 +286,7 @@ static inline void wa_init(struct wahc *wa)
        spin_lock_init(&wa->xfer_list_lock);
        INIT_WORK(&wa->xfer_enqueue_work, wa_urb_enqueue_run);
        INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run);
+       wa->dto_in_use = 0;
        atomic_set(&wa->xfer_id_count, 1);
 }
 
index fd4f1ce6256ac7a60fd2a9d5745e88b6f3c98d63..b48e74cc54d71b92e1ef9c0b918ea5cd9404c1e9 100644 (file)
@@ -143,17 +143,18 @@ static void rpipe_init(struct wa_rpipe *rpipe)
        kref_init(&rpipe->refcnt);
        spin_lock_init(&rpipe->seg_lock);
        INIT_LIST_HEAD(&rpipe->seg_list);
+       INIT_LIST_HEAD(&rpipe->list_node);
 }
 
 static unsigned rpipe_get_idx(struct wahc *wa, unsigned rpipe_idx)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
+       spin_lock_irqsave(&wa->rpipe_lock, flags);
        rpipe_idx = find_next_zero_bit(wa->rpipe_bm, wa->rpipes, rpipe_idx);
        if (rpipe_idx < wa->rpipes)
                set_bit(rpipe_idx, wa->rpipe_bm);
-       spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
+       spin_unlock_irqrestore(&wa->rpipe_lock, flags);
 
        return rpipe_idx;
 }
@@ -162,9 +163,9 @@ static void rpipe_put_idx(struct wahc *wa, unsigned rpipe_idx)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
+       spin_lock_irqsave(&wa->rpipe_lock, flags);
        clear_bit(rpipe_idx, wa->rpipe_bm);
-       spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
+       spin_unlock_irqrestore(&wa->rpipe_lock, flags);
 }
 
 void rpipe_destroy(struct kref *_rpipe)
@@ -333,7 +334,10 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
        /* FIXME: compute so seg_size > ep->maxpktsize */
        rpipe->descr.wBlocks = cpu_to_le16(16);         /* given */
        /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */
-       rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize);
+       if (usb_endpoint_xfer_isoc(&ep->desc))
+               rpipe->descr.wMaxPacketSize = epcd->wOverTheAirPacketSize;
+       else
+               rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize;
 
        rpipe->descr.hwa_bMaxBurst = max(min_t(unsigned int,
                                epcd->bMaxBurst, 16U), 1U);
@@ -361,8 +365,10 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
                        epcd->bMaxSequence, 32U), 2U);
        rpipe->descr.bMaxDataSequence = epcd_max_sequence - 1;
        rpipe->descr.bInterval = ep->desc.bInterval;
-       /* FIXME: bOverTheAirInterval */
-       rpipe->descr.bOverTheAirInterval = 0;   /* 0 if not isoc */
+       if (usb_endpoint_xfer_isoc(&ep->desc))
+               rpipe->descr.bOverTheAirInterval = epcd->bOverTheAirInterval;
+       else
+               rpipe->descr.bOverTheAirInterval = 0;   /* 0 if not isoc */
        /* FIXME: xmit power & preamble blah blah */
        rpipe->descr.bmAttribute = (ep->desc.bmAttributes &
                                        USB_ENDPOINT_XFERTYPE_MASK);
@@ -477,7 +483,7 @@ error:
  */
 int wa_rpipes_create(struct wahc *wa)
 {
-       wa->rpipes = wa->wa_descr->wNumRPipes;
+       wa->rpipes = le16_to_cpu(wa->wa_descr->wNumRPipes);
        wa->rpipe_bm = kzalloc(BITS_TO_LONGS(wa->rpipes)*sizeof(unsigned long),
                               GFP_KERNEL);
        if (wa->rpipe_bm == NULL)
index 6ad02f57c366706e85ab4e3d03fa2d6cdc006a79..ed5abe87b0496f1329f3eefada1b636a9151fb70 100644 (file)
@@ -91,7 +91,8 @@
 #include "wusbhc.h"
 
 enum {
-       WA_SEGS_MAX = 255,
+       /* [WUSB] section 8.3.3 allocates 7 bits for the segment index. */
+       WA_SEGS_MAX = 128,
 };
 
 enum wa_seg_status {
@@ -107,6 +108,7 @@ enum wa_seg_status {
 };
 
 static void wa_xfer_delayed_run(struct wa_rpipe *);
+static int __wa_xfer_delayed_run(struct wa_rpipe *rpipe, int *dto_waiting);
 
 /*
  * Life cycle governed by 'struct urb' (the refcount of the struct is
@@ -114,24 +116,27 @@ static void wa_xfer_delayed_run(struct wa_rpipe *);
  * struct).
  */
 struct wa_seg {
-       struct urb urb;
-       struct urb *dto_urb;            /* for data output? */
+       struct urb tr_urb;              /* transfer request urb. */
+       struct urb *isoc_pack_desc_urb; /* for isoc packet descriptor. */
+       struct urb *dto_urb;            /* for data output. */
        struct list_head list_node;     /* for rpipe->req_list */
        struct wa_xfer *xfer;           /* out xfer */
        u8 index;                       /* which segment we are */
+       int isoc_frame_count;   /* number of isoc frames in this segment. */
+       int isoc_frame_offset;  /* starting frame offset in the xfer URB. */
+       int isoc_size;  /* size of all isoc frames sent by this seg. */
        enum wa_seg_status status;
        ssize_t result;                 /* bytes xfered or error */
        struct wa_xfer_hdr xfer_hdr;
-       u8 xfer_extra[];                /* xtra space for xfer_hdr_ctl */
 };
 
 static inline void wa_seg_init(struct wa_seg *seg)
 {
-       usb_init_urb(&seg->urb);
+       usb_init_urb(&seg->tr_urb);
 
        /* set the remaining memory to 0. */
-       memset(((void *)seg) + sizeof(seg->urb), 0,
-               sizeof(*seg) - sizeof(seg->urb));
+       memset(((void *)seg) + sizeof(seg->tr_urb), 0,
+               sizeof(*seg) - sizeof(seg->tr_urb));
 }
 
 /*
@@ -153,12 +158,17 @@ struct wa_xfer {
        unsigned is_dma:1;
        size_t seg_size;
        int result;
+       /* Isoc frame that the current transfer buffer corresponds to. */
+       int dto_isoc_frame_index;
 
        gfp_t gfp;                      /* allocation mask */
 
        struct wusb_dev *wusb_dev;      /* for activity timestamps */
 };
 
+static void __wa_populate_dto_urb_isoc(struct wa_xfer *xfer,
+       struct wa_seg *seg, int curr_iso_frame);
+
 static inline void wa_xfer_init(struct wa_xfer *xfer)
 {
        kref_init(&xfer->refcnt);
@@ -169,7 +179,7 @@ static inline void wa_xfer_init(struct wa_xfer *xfer)
 /*
  * Destroy a transfer structure
  *
- * Note that freeing xfer->seg[cnt]->urb will free the containing
+ * Note that freeing xfer->seg[cnt]->tr_urb will free the containing
  * xfer->seg[cnt] memory that was allocated by __wa_xfer_setup_segs.
  */
 static void wa_xfer_destroy(struct kref *_xfer)
@@ -178,9 +188,17 @@ static void wa_xfer_destroy(struct kref *_xfer)
        if (xfer->seg) {
                unsigned cnt;
                for (cnt = 0; cnt < xfer->segs; cnt++) {
-                       usb_free_urb(xfer->seg[cnt]->dto_urb);
-                       usb_free_urb(&xfer->seg[cnt]->urb);
+                       struct wa_seg *seg = xfer->seg[cnt];
+                       if (seg) {
+                               usb_free_urb(seg->isoc_pack_desc_urb);
+                               if (seg->dto_urb) {
+                                       kfree(seg->dto_urb->sg);
+                                       usb_free_urb(seg->dto_urb);
+                               }
+                               usb_free_urb(&seg->tr_urb);
+                       }
                }
+               kfree(xfer->seg);
        }
        kfree(xfer);
 }
@@ -195,6 +213,59 @@ static void wa_xfer_put(struct wa_xfer *xfer)
        kref_put(&xfer->refcnt, wa_xfer_destroy);
 }
 
+/*
+ * Try to get exclusive access to the DTO endpoint resource.  Return true
+ * if successful.
+ */
+static inline int __wa_dto_try_get(struct wahc *wa)
+{
+       return (test_and_set_bit(0, &wa->dto_in_use) == 0);
+}
+
+/* Release the DTO endpoint resource. */
+static inline void __wa_dto_put(struct wahc *wa)
+{
+       clear_bit_unlock(0, &wa->dto_in_use);
+}
+
+/* Service RPIPEs that are waiting on the DTO resource. */
+static void wa_check_for_delayed_rpipes(struct wahc *wa)
+{
+       unsigned long flags;
+       int dto_waiting = 0;
+       struct wa_rpipe *rpipe;
+
+       spin_lock_irqsave(&wa->rpipe_lock, flags);
+       while (!list_empty(&wa->rpipe_delayed_list) && !dto_waiting) {
+               rpipe = list_first_entry(&wa->rpipe_delayed_list,
+                               struct wa_rpipe, list_node);
+               __wa_xfer_delayed_run(rpipe, &dto_waiting);
+               /* remove this RPIPE from the list if it is not waiting. */
+               if (!dto_waiting) {
+                       pr_debug("%s: RPIPE %d serviced and removed from delayed list.\n",
+                               __func__,
+                               le16_to_cpu(rpipe->descr.wRPipeIndex));
+                       list_del_init(&rpipe->list_node);
+               }
+       }
+       spin_unlock_irqrestore(&wa->rpipe_lock, flags);
+}
+
+/* add this RPIPE to the end of the delayed RPIPE list. */
+static void wa_add_delayed_rpipe(struct wahc *wa, struct wa_rpipe *rpipe)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&wa->rpipe_lock, flags);
+       /* add rpipe to the list if it is not already on it. */
+       if (list_empty(&rpipe->list_node)) {
+               pr_debug("%s: adding RPIPE %d to the delayed list.\n",
+                       __func__, le16_to_cpu(rpipe->descr.wRPipeIndex));
+               list_add_tail(&rpipe->list_node, &wa->rpipe_delayed_list);
+       }
+       spin_unlock_irqrestore(&wa->rpipe_lock, flags);
+}
+
 /*
  * xfer is referenced
  *
@@ -231,6 +302,31 @@ static void wa_xfer_completion(struct wa_xfer *xfer)
        wa_xfer_giveback(xfer);
 }
 
+/*
+ * Initialize a transfer's ID
+ *
+ * We need to use a sequential number; if we use the pointer or the
+ * hash of the pointer, it can repeat over sequential transfers and
+ * then it will confuse the HWA....wonder why in hell they put a 32
+ * bit handle in there then.
+ */
+static void wa_xfer_id_init(struct wa_xfer *xfer)
+{
+       xfer->id = atomic_add_return(1, &xfer->wa->xfer_id_count);
+}
+
+/* Return the xfer's ID. */
+static inline u32 wa_xfer_id(struct wa_xfer *xfer)
+{
+       return xfer->id;
+}
+
+/* Return the xfer's ID in transport format (little endian). */
+static inline __le32 wa_xfer_id_le32(struct wa_xfer *xfer)
+{
+       return cpu_to_le32(xfer->id);
+}
+
 /*
  * If transfer is done, wrap it up and return true
  *
@@ -253,33 +349,37 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
                switch (seg->status) {
                case WA_SEG_DONE:
                        if (found_short && seg->result > 0) {
-                               dev_dbg(dev, "xfer %p#%u: bad short segments (%zu)\n",
-                                       xfer, cnt, seg->result);
+                               dev_dbg(dev, "xfer %p ID %08X#%u: bad short segments (%zu)\n",
+                                       xfer, wa_xfer_id(xfer), cnt,
+                                       seg->result);
                                urb->status = -EINVAL;
                                goto out;
                        }
                        urb->actual_length += seg->result;
-                       if (seg->result < xfer->seg_size
+                       if (!(usb_pipeisoc(xfer->urb->pipe))
+                               && seg->result < xfer->seg_size
                            && cnt != xfer->segs-1)
                                found_short = 1;
-                       dev_dbg(dev, "xfer %p#%u: DONE short %d "
+                       dev_dbg(dev, "xfer %p ID %08X#%u: DONE short %d "
                                "result %zu urb->actual_length %d\n",
-                               xfer, seg->index, found_short, seg->result,
-                               urb->actual_length);
+                               xfer, wa_xfer_id(xfer), seg->index, found_short,
+                               seg->result, urb->actual_length);
                        break;
                case WA_SEG_ERROR:
                        xfer->result = seg->result;
-                       dev_dbg(dev, "xfer %p#%u: ERROR result %zu\n",
-                               xfer, seg->index, seg->result);
+                       dev_dbg(dev, "xfer %p ID %08X#%u: ERROR result %zu(0x%08zX)\n",
+                               xfer, wa_xfer_id(xfer), seg->index, seg->result,
+                               seg->result);
                        goto out;
                case WA_SEG_ABORTED:
-                       dev_dbg(dev, "xfer %p#%u ABORTED: result %d\n",
-                               xfer, seg->index, urb->status);
+                       dev_dbg(dev, "xfer %p ID %08X#%u ABORTED: result %d\n",
+                               xfer, wa_xfer_id(xfer), seg->index,
+                               urb->status);
                        xfer->result = urb->status;
                        goto out;
                default:
-                       dev_warn(dev, "xfer %p#%u: is_done bad state %d\n",
-                                xfer, cnt, seg->status);
+                       dev_warn(dev, "xfer %p ID %08X#%u: is_done bad state %d\n",
+                                xfer, wa_xfer_id(xfer), cnt, seg->status);
                        xfer->result = -EINVAL;
                        goto out;
                }
@@ -289,29 +389,6 @@ out:
        return result;
 }
 
-/*
- * Initialize a transfer's ID
- *
- * We need to use a sequential number; if we use the pointer or the
- * hash of the pointer, it can repeat over sequential transfers and
- * then it will confuse the HWA....wonder why in hell they put a 32
- * bit handle in there then.
- */
-static void wa_xfer_id_init(struct wa_xfer *xfer)
-{
-       xfer->id = atomic_add_return(1, &xfer->wa->xfer_id_count);
-}
-
-/*
- * Return the xfer's ID associated with xfer
- *
- * Need to generate a
- */
-static u32 wa_xfer_id(struct wa_xfer *xfer)
-{
-       return xfer->id;
-}
-
 /*
  * Search for a transfer list ID on the HCD's URB list
  *
@@ -356,15 +433,11 @@ static void __wa_xfer_abort_cb(struct urb *urb)
  *
  * The callback (see above) does nothing but freeing up the data by
  * putting the URB. Because the URB is allocated at the head of the
- * struct, the whole space we allocated is kfreed.
- *
- * We'll get an 'aborted transaction' xfer result on DTI, that'll
- * politely ignore because at this point the transaction has been
- * marked as aborted already.
+ * struct, the whole space we allocated is kfreed. *
  */
-static void __wa_xfer_abort(struct wa_xfer *xfer)
+static int __wa_xfer_abort(struct wa_xfer *xfer)
 {
-       int result;
+       int result = -ENOMEM;
        struct device *dev = &xfer->wa->usb_iface->dev;
        struct wa_xfer_abort_buffer *b;
        struct wa_rpipe *rpipe = xfer->ep->hcpriv;
@@ -375,7 +448,7 @@ static void __wa_xfer_abort(struct wa_xfer *xfer)
        b->cmd.bLength =  sizeof(b->cmd);
        b->cmd.bRequestType = WA_XFER_ABORT;
        b->cmd.wRPipe = rpipe->descr.wRPipeIndex;
-       b->cmd.dwTransferID = wa_xfer_id(xfer);
+       b->cmd.dwTransferID = wa_xfer_id_le32(xfer);
 
        usb_init_urb(&b->urb);
        usb_fill_bulk_urb(&b->urb, xfer->wa->usb_dev,
@@ -385,7 +458,7 @@ static void __wa_xfer_abort(struct wa_xfer *xfer)
        result = usb_submit_urb(&b->urb, GFP_ATOMIC);
        if (result < 0)
                goto error_submit;
-       return;                         /* callback frees! */
+       return result;                          /* callback frees! */
 
 
 error_submit:
@@ -394,10 +467,51 @@ error_submit:
                        xfer, result);
        kfree(b);
 error_kmalloc:
-       return;
+       return result;
 
 }
 
+/*
+ * Calculate the number of isoc frames starting from isoc_frame_offset
+ * that will fit a in transfer segment.
+ */
+static int __wa_seg_calculate_isoc_frame_count(struct wa_xfer *xfer,
+       int isoc_frame_offset, int *total_size)
+{
+       int segment_size = 0, frame_count = 0;
+       int index = isoc_frame_offset;
+       struct usb_iso_packet_descriptor *iso_frame_desc =
+               xfer->urb->iso_frame_desc;
+
+       while ((index < xfer->urb->number_of_packets)
+               && ((segment_size + iso_frame_desc[index].length)
+                               <= xfer->seg_size)) {
+               /*
+                * For Alereon HWA devices, only include an isoc frame in a
+                * segment if it is physically contiguous with the previous
+                * frame.  This is required because those devices expect
+                * the isoc frames to be sent as a single USB transaction as
+                * opposed to one transaction per frame with standard HWA.
+                */
+               if ((xfer->wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC)
+                       && (index > isoc_frame_offset)
+                       && ((iso_frame_desc[index - 1].offset +
+                               iso_frame_desc[index - 1].length) !=
+                               iso_frame_desc[index].offset))
+                       break;
+
+               /* this frame fits. count it. */
+               ++frame_count;
+               segment_size += iso_frame_desc[index].length;
+
+               /* move to the next isoc frame. */
+               ++index;
+       }
+
+       *total_size = segment_size;
+       return frame_count;
+}
+
 /*
  *
  * @returns < 0 on error, transfer segment request size if ok
@@ -422,43 +536,92 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
                result = sizeof(struct wa_xfer_bi);
                break;
        case USB_ENDPOINT_XFER_ISOC:
-               dev_err(dev, "FIXME: ISOC not implemented\n");
-               result = -ENOSYS;
-               goto error;
+               if (usb_pipeout(urb->pipe)) {
+                       *pxfer_type = WA_XFER_TYPE_ISO;
+                       result = sizeof(struct wa_xfer_hwaiso);
+               } else {
+                       dev_err(dev, "FIXME: ISOC IN not implemented\n");
+                       result = -ENOSYS;
+                       goto error;
+               }
+               break;
        default:
                /* never happens */
                BUG();
                result = -EINVAL;       /* shut gcc up */
-       };
+       }
        xfer->is_inbound = urb->pipe & USB_DIR_IN ? 1 : 0;
        xfer->is_dma = urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? 1 : 0;
-       xfer->seg_size = le16_to_cpu(rpipe->descr.wBlocks)
-               * 1 << (xfer->wa->wa_descr->bRPipeBlockSize - 1);
-       /* Compute the segment size and make sure it is a multiple of
-        * the maxpktsize (WUSB1.0[8.3.3.1])...not really too much of
-        * a check (FIXME) */
+
        maxpktsize = le16_to_cpu(rpipe->descr.wMaxPacketSize);
-       if (xfer->seg_size < maxpktsize) {
-               dev_err(dev, "HW BUG? seg_size %zu smaller than maxpktsize "
-                       "%zu\n", xfer->seg_size, maxpktsize);
-               result = -EINVAL;
-               goto error;
+       if ((rpipe->descr.bmAttribute & 0x3) == USB_ENDPOINT_XFER_ISOC) {
+               int index = 0;
+
+               xfer->seg_size = maxpktsize;
+               xfer->segs = 0;
+               /*
+                * loop over urb->number_of_packets to determine how many
+                * xfer segments will be needed to send the isoc frames.
+                */
+               while (index < urb->number_of_packets) {
+                       int seg_size; /* don't care. */
+                       index += __wa_seg_calculate_isoc_frame_count(xfer,
+                                       index, &seg_size);
+                       ++xfer->segs;
+               }
+       } else {
+               xfer->seg_size = le16_to_cpu(rpipe->descr.wBlocks)
+                       * 1 << (xfer->wa->wa_descr->bRPipeBlockSize - 1);
+               /* Compute the segment size and make sure it is a multiple of
+                * the maxpktsize (WUSB1.0[8.3.3.1])...not really too much of
+                * a check (FIXME) */
+               if (xfer->seg_size < maxpktsize) {
+                       dev_err(dev,
+                               "HW BUG? seg_size %zu smaller than maxpktsize %zu\n",
+                               xfer->seg_size, maxpktsize);
+                       result = -EINVAL;
+                       goto error;
+               }
+               xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
+               xfer->segs = DIV_ROUND_UP(urb->transfer_buffer_length,
+                                               xfer->seg_size);
+               if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL)
+                       xfer->segs = 1;
        }
-       xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
-       xfer->segs = DIV_ROUND_UP(urb->transfer_buffer_length, xfer->seg_size);
-       if (xfer->segs >= WA_SEGS_MAX) {
-               dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n",
-                       (int)(urb->transfer_buffer_length / xfer->seg_size),
+
+       if (xfer->segs > WA_SEGS_MAX) {
+               dev_err(dev, "BUG? oops, number of segments %zu bigger than %d\n",
+                       (urb->transfer_buffer_length/xfer->seg_size),
                        WA_SEGS_MAX);
                result = -EINVAL;
                goto error;
        }
-       if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL)
-               xfer->segs = 1;
 error:
        return result;
 }
 
+static void __wa_setup_isoc_packet_descr(
+               struct wa_xfer_packet_info_hwaiso *packet_desc,
+               struct wa_xfer *xfer,
+               struct wa_seg *seg) {
+       struct usb_iso_packet_descriptor *iso_frame_desc =
+               xfer->urb->iso_frame_desc;
+       int frame_index;
+
+       /* populate isoc packet descriptor. */
+       packet_desc->bPacketType = WA_XFER_ISO_PACKET_INFO;
+       packet_desc->wLength = cpu_to_le16(sizeof(*packet_desc) +
+               (sizeof(packet_desc->PacketLength[0]) *
+                       seg->isoc_frame_count));
+       for (frame_index = 0; frame_index < seg->isoc_frame_count;
+               ++frame_index) {
+               int offset_index = frame_index + seg->isoc_frame_offset;
+               packet_desc->PacketLength[frame_index] =
+                       cpu_to_le16(iso_frame_desc[offset_index].length);
+       }
+}
+
+
 /* Fill in the common request header and xfer-type specific data. */
 static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
                                 struct wa_xfer_hdr *xfer_hdr0,
@@ -466,12 +629,13 @@ static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
                                 size_t xfer_hdr_size)
 {
        struct wa_rpipe *rpipe = xfer->ep->hcpriv;
+       struct wa_seg *seg = xfer->seg[0];
 
-       xfer_hdr0 = &xfer->seg[0]->xfer_hdr;
+       xfer_hdr0 = &seg->xfer_hdr;
        xfer_hdr0->bLength = xfer_hdr_size;
        xfer_hdr0->bRequestType = xfer_type;
        xfer_hdr0->wRPipe = rpipe->descr.wRPipeIndex;
-       xfer_hdr0->dwTransferID = wa_xfer_id(xfer);
+       xfer_hdr0->dwTransferID = wa_xfer_id_le32(xfer);
        xfer_hdr0->bTransferSegment = 0;
        switch (xfer_type) {
        case WA_XFER_TYPE_CTL: {
@@ -484,8 +648,18 @@ static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
        }
        case WA_XFER_TYPE_BI:
                break;
-       case WA_XFER_TYPE_ISO:
-               printk(KERN_ERR "FIXME: ISOC not implemented\n");
+       case WA_XFER_TYPE_ISO: {
+               struct wa_xfer_hwaiso *xfer_iso =
+                       container_of(xfer_hdr0, struct wa_xfer_hwaiso, hdr);
+               struct wa_xfer_packet_info_hwaiso *packet_desc =
+                       ((void *)xfer_iso) + xfer_hdr_size;
+
+               /* populate the isoc section of the transfer request. */
+               xfer_iso->dwNumOfPackets = cpu_to_le32(seg->isoc_frame_count);
+               /* populate isoc packet descriptor. */
+               __wa_setup_isoc_packet_descr(packet_desc, xfer, seg);
+               break;
+       }
        default:
                BUG();
        };
@@ -494,16 +668,149 @@ static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
 /*
  * Callback for the OUT data phase of the segment request
  *
- * Check wa_seg_cb(); most comments also apply here because this
+ * Check wa_seg_tr_cb(); most comments also apply here because this
  * function does almost the same thing and they work closely
  * together.
  *
  * If the seg request has failed but this DTO phase has succeeded,
- * wa_seg_cb() has already failed the segment and moved the
+ * wa_seg_tr_cb() has already failed the segment and moved the
  * status to WA_SEG_ERROR, so this will go through 'case 0' and
  * effectively do nothing.
  */
 static void wa_seg_dto_cb(struct urb *urb)
+{
+       struct wa_seg *seg = urb->context;
+       struct wa_xfer *xfer = seg->xfer;
+       struct wahc *wa;
+       struct device *dev;
+       struct wa_rpipe *rpipe;
+       unsigned long flags;
+       unsigned rpipe_ready = 0;
+       int data_send_done = 1, release_dto = 0, holding_dto = 0;
+       u8 done = 0;
+       int result;
+
+       /* free the sg if it was used. */
+       kfree(urb->sg);
+       urb->sg = NULL;
+
+       spin_lock_irqsave(&xfer->lock, flags);
+       wa = xfer->wa;
+       dev = &wa->usb_iface->dev;
+       if (usb_pipeisoc(xfer->urb->pipe)) {
+               /* Alereon HWA sends all isoc frames in a single transfer. */
+               if (wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC)
+                       xfer->dto_isoc_frame_index += seg->isoc_frame_count;
+               else
+                       xfer->dto_isoc_frame_index += 1;
+               if (xfer->dto_isoc_frame_index < seg->isoc_frame_count) {
+                       data_send_done = 0;
+                       holding_dto = 1; /* checked in error cases. */
+                       /*
+                        * if this is the last isoc frame of the segment, we
+                        * can release DTO after sending this frame.
+                        */
+                       if ((xfer->dto_isoc_frame_index + 1) >=
+                               seg->isoc_frame_count)
+                               release_dto = 1;
+               }
+               dev_dbg(dev, "xfer 0x%08X#%u: isoc frame = %d, holding_dto = %d, release_dto = %d.\n",
+                       wa_xfer_id(xfer), seg->index,
+                       xfer->dto_isoc_frame_index, holding_dto, release_dto);
+       }
+       spin_unlock_irqrestore(&xfer->lock, flags);
+
+       switch (urb->status) {
+       case 0:
+               spin_lock_irqsave(&xfer->lock, flags);
+               seg->result += urb->actual_length;
+               if (data_send_done) {
+                       dev_dbg(dev, "xfer 0x%08X#%u: data out done (%zu bytes)\n",
+                               wa_xfer_id(xfer), seg->index, seg->result);
+                       if (seg->status < WA_SEG_PENDING)
+                               seg->status = WA_SEG_PENDING;
+               } else {
+                       /* should only hit this for isoc xfers. */
+                       /*
+                        * Populate the dto URB with the next isoc frame buffer,
+                        * send the URB and release DTO if we no longer need it.
+                        */
+                        __wa_populate_dto_urb_isoc(xfer, seg,
+                               seg->isoc_frame_offset +
+                               xfer->dto_isoc_frame_index);
+
+                       /* resubmit the URB with the next isoc frame. */
+                       result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC);
+                       if (result < 0) {
+                               dev_err(dev, "xfer 0x%08X#%u: DTO submit failed: %d\n",
+                                      wa_xfer_id(xfer), seg->index, result);
+                               spin_unlock_irqrestore(&xfer->lock, flags);
+                               goto error_dto_submit;
+                       }
+               }
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               if (release_dto) {
+                       __wa_dto_put(wa);
+                       wa_check_for_delayed_rpipes(wa);
+               }
+               break;
+       case -ECONNRESET:       /* URB unlinked; no need to do anything */
+       case -ENOENT:           /* as it was done by the who unlinked us */
+               if (holding_dto) {
+                       __wa_dto_put(wa);
+                       wa_check_for_delayed_rpipes(wa);
+               }
+               break;
+       default:                /* Other errors ... */
+               dev_err(dev, "xfer 0x%08X#%u: data out error %d\n",
+                       wa_xfer_id(xfer), seg->index, urb->status);
+               goto error_default;
+       }
+
+       return;
+
+error_dto_submit:
+error_default:
+       spin_lock_irqsave(&xfer->lock, flags);
+       rpipe = xfer->ep->hcpriv;
+       if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
+                   EDC_ERROR_TIMEFRAME)){
+               dev_err(dev, "DTO: URB max acceptable errors exceeded, resetting device\n");
+               wa_reset_all(wa);
+       }
+       if (seg->status != WA_SEG_ERROR) {
+               seg->status = WA_SEG_ERROR;
+               seg->result = urb->status;
+               xfer->segs_done++;
+               __wa_xfer_abort(xfer);
+               rpipe_ready = rpipe_avail_inc(rpipe);
+               done = __wa_xfer_is_done(xfer);
+       }
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       if (holding_dto) {
+               __wa_dto_put(wa);
+               wa_check_for_delayed_rpipes(wa);
+       }
+       if (done)
+               wa_xfer_completion(xfer);
+       if (rpipe_ready)
+               wa_xfer_delayed_run(rpipe);
+
+}
+
+/*
+ * Callback for the isoc packet descriptor phase of the segment request
+ *
+ * Check wa_seg_tr_cb(); most comments also apply here because this
+ * function does almost the same thing and they work closely
+ * together.
+ *
+ * If the seg request has failed but this phase has succeeded,
+ * wa_seg_tr_cb() has already failed the segment and moved the
+ * status to WA_SEG_ERROR, so this will go through 'case 0' and
+ * effectively do nothing.
+ */
+static void wa_seg_iso_pack_desc_cb(struct urb *urb)
 {
        struct wa_seg *seg = urb->context;
        struct wa_xfer *xfer = seg->xfer;
@@ -519,11 +826,10 @@ static void wa_seg_dto_cb(struct urb *urb)
                spin_lock_irqsave(&xfer->lock, flags);
                wa = xfer->wa;
                dev = &wa->usb_iface->dev;
-               dev_dbg(dev, "xfer %p#%u: data out done (%d bytes)\n",
-                       xfer, seg->index, urb->actual_length);
-               if (seg->status < WA_SEG_PENDING)
+               dev_dbg(dev, "iso xfer %08X#%u: packet descriptor done\n",
+                       wa_xfer_id(xfer), seg->index);
+               if (xfer->is_inbound && seg->status < WA_SEG_PENDING)
                        seg->status = WA_SEG_PENDING;
-               seg->result = urb->actual_length;
                spin_unlock_irqrestore(&xfer->lock, flags);
                break;
        case -ECONNRESET:       /* URB unlinked; no need to do anything */
@@ -534,15 +840,15 @@ static void wa_seg_dto_cb(struct urb *urb)
                wa = xfer->wa;
                dev = &wa->usb_iface->dev;
                rpipe = xfer->ep->hcpriv;
-               dev_dbg(dev, "xfer %p#%u: data out error %d\n",
-                       xfer, seg->index, urb->status);
+               pr_err_ratelimited("iso xfer %08X#%u: packet descriptor error %d\n",
+                               wa_xfer_id(xfer), seg->index, urb->status);
                if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
                            EDC_ERROR_TIMEFRAME)){
-                       dev_err(dev, "DTO: URB max acceptable errors "
-                               "exceeded, resetting device\n");
+                       dev_err(dev, "DTO: URB max acceptable errors exceeded, resetting device\n");
                        wa_reset_all(wa);
                }
                if (seg->status != WA_SEG_ERROR) {
+                       usb_unlink_urb(seg->dto_urb);
                        seg->status = WA_SEG_ERROR;
                        seg->result = urb->status;
                        xfer->segs_done++;
@@ -572,11 +878,11 @@ static void wa_seg_dto_cb(struct urb *urb)
  * We have to check before setting the status to WA_SEG_PENDING
  * because sometimes the xfer result callback arrives before this
  * callback (geeeeeeze), so it might happen that we are already in
- * another state. As well, we don't set it if the transfer is inbound,
+ * another state. As well, we don't set it if the transfer is not inbound,
  * as in that case, wa_seg_dto_cb will do it when the OUT data phase
  * finishes.
  */
-static void wa_seg_cb(struct urb *urb)
+static void wa_seg_tr_cb(struct urb *urb)
 {
        struct wa_seg *seg = urb->context;
        struct wa_xfer *xfer = seg->xfer;
@@ -592,8 +898,11 @@ static void wa_seg_cb(struct urb *urb)
                spin_lock_irqsave(&xfer->lock, flags);
                wa = xfer->wa;
                dev = &wa->usb_iface->dev;
-               dev_dbg(dev, "xfer %p#%u: request done\n", xfer, seg->index);
-               if (xfer->is_inbound && seg->status < WA_SEG_PENDING)
+               dev_dbg(dev, "xfer %p ID 0x%08X#%u: request done\n",
+                       xfer, wa_xfer_id(xfer), seg->index);
+               if (xfer->is_inbound &&
+                       seg->status < WA_SEG_PENDING &&
+                       !(usb_pipeisoc(xfer->urb->pipe)))
                        seg->status = WA_SEG_PENDING;
                spin_unlock_irqrestore(&xfer->lock, flags);
                break;
@@ -606,14 +915,16 @@ static void wa_seg_cb(struct urb *urb)
                dev = &wa->usb_iface->dev;
                rpipe = xfer->ep->hcpriv;
                if (printk_ratelimit())
-                       dev_err(dev, "xfer %p#%u: request error %d\n",
-                               xfer, seg->index, urb->status);
+                       dev_err(dev, "xfer %p ID 0x%08X#%u: request error %d\n",
+                               xfer, wa_xfer_id(xfer), seg->index,
+                               urb->status);
                if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
                            EDC_ERROR_TIMEFRAME)){
                        dev_err(dev, "DTO: URB max acceptable errors "
                                "exceeded, resetting device\n");
                        wa_reset_all(wa);
                }
+               usb_unlink_urb(seg->isoc_pack_desc_urb);
                usb_unlink_urb(seg->dto_urb);
                seg->status = WA_SEG_ERROR;
                seg->result = urb->status;
@@ -629,9 +940,11 @@ static void wa_seg_cb(struct urb *urb)
        }
 }
 
-/* allocate an SG list to store bytes_to_transfer bytes and copy the
+/*
+ * Allocate an SG list to store bytes_to_transfer bytes and copy the
  * subset of the in_sg that matches the buffer subset
- * we are about to transfer. */
+ * we are about to transfer.
+ */
 static struct scatterlist *wa_xfer_create_subset_sg(struct scatterlist *in_sg,
        const unsigned int bytes_transferred,
        const unsigned int bytes_to_transfer, unsigned int *out_num_sgs)
@@ -709,6 +1022,75 @@ static struct scatterlist *wa_xfer_create_subset_sg(struct scatterlist *in_sg,
        return out_sg;
 }
 
+/*
+ * Populate DMA buffer info for the isoc dto urb.
+ */
+static void __wa_populate_dto_urb_isoc(struct wa_xfer *xfer,
+       struct wa_seg *seg, int curr_iso_frame)
+{
+       seg->dto_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       seg->dto_urb->sg = NULL;
+       seg->dto_urb->num_sgs = 0;
+       /* dto urb buffer address pulled from iso_frame_desc. */
+       seg->dto_urb->transfer_dma = xfer->urb->transfer_dma +
+               xfer->urb->iso_frame_desc[curr_iso_frame].offset;
+       /* The Alereon HWA sends a single URB with all isoc segs. */
+       if (xfer->wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC)
+               seg->dto_urb->transfer_buffer_length = seg->isoc_size;
+       else
+               seg->dto_urb->transfer_buffer_length =
+                       xfer->urb->iso_frame_desc[curr_iso_frame].length;
+}
+
+/*
+ * Populate buffer ptr and size, DMA buffer or SG list for the dto urb.
+ */
+static int __wa_populate_dto_urb(struct wa_xfer *xfer,
+       struct wa_seg *seg, size_t buf_itr_offset, size_t buf_itr_size)
+{
+       int result = 0;
+
+       if (xfer->is_dma) {
+               seg->dto_urb->transfer_dma =
+                       xfer->urb->transfer_dma + buf_itr_offset;
+               seg->dto_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               seg->dto_urb->sg = NULL;
+               seg->dto_urb->num_sgs = 0;
+       } else {
+               /* do buffer or SG processing. */
+               seg->dto_urb->transfer_flags &=
+                       ~URB_NO_TRANSFER_DMA_MAP;
+               /* this should always be 0 before a resubmit. */
+               seg->dto_urb->num_mapped_sgs = 0;
+
+               if (xfer->urb->transfer_buffer) {
+                       seg->dto_urb->transfer_buffer =
+                               xfer->urb->transfer_buffer +
+                               buf_itr_offset;
+                       seg->dto_urb->sg = NULL;
+                       seg->dto_urb->num_sgs = 0;
+               } else {
+                       seg->dto_urb->transfer_buffer = NULL;
+
+                       /*
+                        * allocate an SG list to store seg_size bytes
+                        * and copy the subset of the xfer->urb->sg that
+                        * matches the buffer subset we are about to
+                        * read.
+                        */
+                       seg->dto_urb->sg = wa_xfer_create_subset_sg(
+                               xfer->urb->sg,
+                               buf_itr_offset, buf_itr_size,
+                               &(seg->dto_urb->num_sgs));
+                       if (!(seg->dto_urb->sg))
+                               result = -ENOMEM;
+               }
+       }
+       seg->dto_urb->transfer_buffer_length = buf_itr_size;
+
+       return result;
+}
+
 /*
  * Allocate the segs array and initialize each of them
  *
@@ -719,13 +1101,14 @@ static struct scatterlist *wa_xfer_create_subset_sg(struct scatterlist *in_sg,
  */
 static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size)
 {
-       int result, cnt;
+       int result, cnt, iso_frame_offset;
        size_t alloc_size = sizeof(*xfer->seg[0])
                - sizeof(xfer->seg[0]->xfer_hdr) + xfer_hdr_size;
        struct usb_device *usb_dev = xfer->wa->usb_dev;
        const struct usb_endpoint_descriptor *dto_epd = xfer->wa->dto_epd;
        struct wa_seg *seg;
        size_t buf_itr, buf_size, buf_itr_size;
+       int xfer_isoc_frame_offset = 0;
 
        result = -ENOMEM;
        xfer->seg = kcalloc(xfer->segs, sizeof(xfer->seg[0]), GFP_ATOMIC);
@@ -733,18 +1116,35 @@ static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size)
                goto error_segs_kzalloc;
        buf_itr = 0;
        buf_size = xfer->urb->transfer_buffer_length;
+       iso_frame_offset = 0;
        for (cnt = 0; cnt < xfer->segs; cnt++) {
-               seg = xfer->seg[cnt] = kmalloc(alloc_size, GFP_ATOMIC);
+               size_t iso_pkt_descr_size = 0;
+               int seg_isoc_frame_count = 0, seg_isoc_size = 0;
+
+               if (usb_pipeisoc(xfer->urb->pipe)) {
+                       seg_isoc_frame_count =
+                               __wa_seg_calculate_isoc_frame_count(xfer,
+                                       xfer_isoc_frame_offset, &seg_isoc_size);
+
+                       iso_pkt_descr_size =
+                               sizeof(struct wa_xfer_packet_info_hwaiso) +
+                               (seg_isoc_frame_count * sizeof(__le16));
+               }
+               seg = xfer->seg[cnt] = kmalloc(alloc_size + iso_pkt_descr_size,
+                                               GFP_ATOMIC);
                if (seg == NULL)
                        goto error_seg_kmalloc;
                wa_seg_init(seg);
                seg->xfer = xfer;
                seg->index = cnt;
-               usb_fill_bulk_urb(&seg->urb, usb_dev,
+               seg->isoc_frame_count = seg_isoc_frame_count;
+               seg->isoc_frame_offset = xfer_isoc_frame_offset;
+               seg->isoc_size = seg_isoc_size;
+               usb_fill_bulk_urb(&seg->tr_urb, usb_dev,
                                  usb_sndbulkpipe(usb_dev,
                                                  dto_epd->bEndpointAddress),
                                  &seg->xfer_hdr, xfer_hdr_size,
-                                 wa_seg_cb, seg);
+                                 wa_seg_tr_cb, seg);
                buf_itr_size = min(buf_size, xfer->seg_size);
                if (xfer->is_inbound == 0 && buf_size > 0) {
                        /* outbound data. */
@@ -756,69 +1156,64 @@ static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size)
                                usb_sndbulkpipe(usb_dev,
                                                dto_epd->bEndpointAddress),
                                NULL, 0, wa_seg_dto_cb, seg);
-                       if (xfer->is_dma) {
-                               seg->dto_urb->transfer_dma =
-                                       xfer->urb->transfer_dma + buf_itr;
-                               seg->dto_urb->transfer_flags |=
-                                       URB_NO_TRANSFER_DMA_MAP;
-                               seg->dto_urb->transfer_buffer = NULL;
-                               seg->dto_urb->sg = NULL;
-                               seg->dto_urb->num_sgs = 0;
+
+                       if (usb_pipeisoc(xfer->urb->pipe)) {
+                               /* iso packet descriptor. */
+                               seg->isoc_pack_desc_urb =
+                                               usb_alloc_urb(0, GFP_ATOMIC);
+                               if (seg->isoc_pack_desc_urb == NULL)
+                                       goto error_iso_pack_desc_alloc;
+                               /*
+                                * The buffer for the isoc packet descriptor
+                                * after the transfer request header in the
+                                * segment object memory buffer.
+                                */
+                               usb_fill_bulk_urb(
+                                       seg->isoc_pack_desc_urb, usb_dev,
+                                       usb_sndbulkpipe(usb_dev,
+                                               dto_epd->bEndpointAddress),
+                                       (void *)(&seg->xfer_hdr) +
+                                               xfer_hdr_size,
+                                       iso_pkt_descr_size,
+                                       wa_seg_iso_pack_desc_cb, seg);
+
+                               /*
+                                * Fill in the xfer buffer information for the
+                                * first isoc frame.  Subsequent frames in this
+                                * segment will be filled in and sent from the
+                                * DTO completion routine, if needed.
+                                */
+                               __wa_populate_dto_urb_isoc(xfer, seg,
+                                       xfer_isoc_frame_offset);
+                               /* adjust starting frame offset for next seg. */
+                               xfer_isoc_frame_offset += seg_isoc_frame_count;
                        } else {
-                               /* do buffer or SG processing. */
-                               seg->dto_urb->transfer_flags &=
-                                       ~URB_NO_TRANSFER_DMA_MAP;
-                               /* this should always be 0 before a resubmit. */
-                               seg->dto_urb->num_mapped_sgs = 0;
-
-                               if (xfer->urb->transfer_buffer) {
-                                       seg->dto_urb->transfer_buffer =
-                                               xfer->urb->transfer_buffer +
-                                               buf_itr;
-                                       seg->dto_urb->sg = NULL;
-                                       seg->dto_urb->num_sgs = 0;
-                               } else {
-                                       /* allocate an SG list to store seg_size
-                                           bytes and copy the subset of the
-                                           xfer->urb->sg that matches the
-                                           buffer subset we are about to read.
-                                       */
-                                       seg->dto_urb->sg =
-                                               wa_xfer_create_subset_sg(
-                                               xfer->urb->sg,
-                                               buf_itr, buf_itr_size,
-                                               &(seg->dto_urb->num_sgs));
-
-                                       if (!(seg->dto_urb->sg)) {
-                                               seg->dto_urb->num_sgs   = 0;
-                                               goto error_sg_alloc;
-                                       }
-
-                                       seg->dto_urb->transfer_buffer = NULL;
-                               }
+                               /* fill in the xfer buffer information. */
+                               result = __wa_populate_dto_urb(xfer, seg,
+                                                       buf_itr, buf_itr_size);
+                               if (result < 0)
+                                       goto error_seg_outbound_populate;
+
+                               buf_itr += buf_itr_size;
+                               buf_size -= buf_itr_size;
                        }
-                       seg->dto_urb->transfer_buffer_length = buf_itr_size;
                }
                seg->status = WA_SEG_READY;
-               buf_itr += buf_itr_size;
-               buf_size -= buf_itr_size;
        }
        return 0;
 
-error_sg_alloc:
+       /*
+        * Free the memory for the current segment which failed to init.
+        * Use the fact that cnt is left at were it failed.  The remaining
+        * segments will be cleaned up by wa_xfer_destroy.
+        */
+error_iso_pack_desc_alloc:
+error_seg_outbound_populate:
        usb_free_urb(xfer->seg[cnt]->dto_urb);
 error_dto_alloc:
        kfree(xfer->seg[cnt]);
-       cnt--;
+       xfer->seg[cnt] = NULL;
 error_seg_kmalloc:
-       /* use the fact that cnt is left at were it failed */
-       for (; cnt >= 0; cnt--) {
-               if (xfer->seg[cnt] && xfer->is_inbound == 0) {
-                       usb_free_urb(xfer->seg[cnt]->dto_urb);
-                       kfree(xfer->seg[cnt]->dto_urb->sg);
-               }
-               kfree(xfer->seg[cnt]);
-       }
 error_segs_kzalloc:
        return result;
 }
@@ -856,21 +1251,45 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb)
        wa_xfer_id_init(xfer);
        __wa_xfer_setup_hdr0(xfer, xfer_hdr0, xfer_type, xfer_hdr_size);
 
-       /* Fill remainig headers */
+       /* Fill remaining headers */
        xfer_hdr = xfer_hdr0;
-       transfer_size = urb->transfer_buffer_length;
-       xfer_hdr0->dwTransferLength = transfer_size > xfer->seg_size ?
-               xfer->seg_size : transfer_size;
-       transfer_size -=  xfer->seg_size;
-       for (cnt = 1; cnt < xfer->segs; cnt++) {
-               xfer_hdr = &xfer->seg[cnt]->xfer_hdr;
-               memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
-               xfer_hdr->bTransferSegment = cnt;
-               xfer_hdr->dwTransferLength = transfer_size > xfer->seg_size ?
-                       cpu_to_le32(xfer->seg_size)
-                       : cpu_to_le32(transfer_size);
-               xfer->seg[cnt]->status = WA_SEG_READY;
+       if (xfer_type == WA_XFER_TYPE_ISO) {
+               xfer_hdr0->dwTransferLength =
+                       cpu_to_le32(xfer->seg[0]->isoc_size);
+               for (cnt = 1; cnt < xfer->segs; cnt++) {
+                       struct wa_xfer_packet_info_hwaiso *packet_desc;
+                       struct wa_seg *seg = xfer->seg[cnt];
+
+                       xfer_hdr = &seg->xfer_hdr;
+                       packet_desc = ((void *)xfer_hdr) + xfer_hdr_size;
+                       /*
+                        * Copy values from the 0th header. Segment specific
+                        * values are set below.
+                        */
+                       memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
+                       xfer_hdr->bTransferSegment = cnt;
+                       xfer_hdr->dwTransferLength =
+                               cpu_to_le32(seg->isoc_size);
+                       __wa_setup_isoc_packet_descr(packet_desc, xfer, seg);
+                       seg->status = WA_SEG_READY;
+               }
+       } else {
+               transfer_size = urb->transfer_buffer_length;
+               xfer_hdr0->dwTransferLength = transfer_size > xfer->seg_size ?
+                       cpu_to_le32(xfer->seg_size) :
+                       cpu_to_le32(transfer_size);
                transfer_size -=  xfer->seg_size;
+               for (cnt = 1; cnt < xfer->segs; cnt++) {
+                       xfer_hdr = &xfer->seg[cnt]->xfer_hdr;
+                       memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
+                       xfer_hdr->bTransferSegment = cnt;
+                       xfer_hdr->dwTransferLength =
+                               transfer_size > xfer->seg_size ?
+                                       cpu_to_le32(xfer->seg_size)
+                                       : cpu_to_le32(transfer_size);
+                       xfer->seg[cnt]->status = WA_SEG_READY;
+                       transfer_size -=  xfer->seg_size;
+               }
        }
        xfer_hdr->bTransferSegment |= 0x80;     /* this is the last segment */
        result = 0;
@@ -885,20 +1304,46 @@ error_setup_sizes:
  * rpipe->seg_lock is held!
  */
 static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer,
-                          struct wa_seg *seg)
+                          struct wa_seg *seg, int *dto_done)
 {
        int result;
-       result = usb_submit_urb(&seg->urb, GFP_ATOMIC);
+
+       /* default to done unless we encounter a multi-frame isoc segment. */
+       *dto_done = 1;
+
+       /* submit the transfer request. */
+       result = usb_submit_urb(&seg->tr_urb, GFP_ATOMIC);
        if (result < 0) {
-               printk(KERN_ERR "xfer %p#%u: REQ submit failed: %d\n",
-                      xfer, seg->index, result);
+               pr_err("%s: xfer %p#%u: REQ submit failed: %d\n",
+                      __func__, xfer, seg->index, result);
                goto error_seg_submit;
        }
+       /* submit the isoc packet descriptor if present. */
+       if (seg->isoc_pack_desc_urb) {
+               struct wahc *wa = xfer->wa;
+
+               result = usb_submit_urb(seg->isoc_pack_desc_urb, GFP_ATOMIC);
+               if (result < 0) {
+                       pr_err("%s: xfer %p#%u: ISO packet descriptor submit failed: %d\n",
+                              __func__, xfer, seg->index, result);
+                       goto error_iso_pack_desc_submit;
+               }
+               xfer->dto_isoc_frame_index = 0;
+               /*
+                * If this segment contains more than one isoc frame, hold
+                * onto the dto resource until we send all frames.
+                * Only applies to non-Alereon devices.
+                */
+               if (((wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC) == 0)
+                       && (seg->isoc_frame_count > 1))
+                       *dto_done = 0;
+       }
+       /* submit the out data if this is an out request. */
        if (seg->dto_urb) {
                result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC);
                if (result < 0) {
-                       printk(KERN_ERR "xfer %p#%u: DTO submit failed: %d\n",
-                              xfer, seg->index, result);
+                       pr_err("%s: xfer %p#%u: DTO submit failed: %d\n",
+                              __func__, xfer, seg->index, result);
                        goto error_dto_submit;
                }
        }
@@ -907,38 +1352,48 @@ static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer,
        return 0;
 
 error_dto_submit:
-       usb_unlink_urb(&seg->urb);
+       usb_unlink_urb(seg->isoc_pack_desc_urb);
+error_iso_pack_desc_submit:
+       usb_unlink_urb(&seg->tr_urb);
 error_seg_submit:
        seg->status = WA_SEG_ERROR;
        seg->result = result;
+       *dto_done = 1;
        return result;
 }
 
 /*
- * Execute more queued request segments until the maximum concurrent allowed
+ * Execute more queued request segments until the maximum concurrent allowed.
+ * Return true if the DTO resource was acquired and released.
  *
  * The ugly unlock/lock sequence on the error path is needed as the
  * xfer->lock normally nests the seg_lock and not viceversa.
- *
  */
-static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
+static int __wa_xfer_delayed_run(struct wa_rpipe *rpipe, int *dto_waiting)
 {
-       int result;
+       int result, dto_acquired = 0, dto_done = 0;
        struct device *dev = &rpipe->wa->usb_iface->dev;
        struct wa_seg *seg;
        struct wa_xfer *xfer;
        unsigned long flags;
 
+       *dto_waiting = 0;
+
        spin_lock_irqsave(&rpipe->seg_lock, flags);
        while (atomic_read(&rpipe->segs_available) > 0
-             && !list_empty(&rpipe->seg_list)) {
+             && !list_empty(&rpipe->seg_list)
+             && (dto_acquired = __wa_dto_try_get(rpipe->wa))) {
                seg = list_first_entry(&(rpipe->seg_list), struct wa_seg,
                                 list_node);
                list_del(&seg->list_node);
                xfer = seg->xfer;
-               result = __wa_seg_submit(rpipe, xfer, seg);
-               dev_dbg(dev, "xfer %p#%u submitted from delayed [%d segments available] %d\n",
-                       xfer, seg->index, atomic_read(&rpipe->segs_available), result);
+               result = __wa_seg_submit(rpipe, xfer, seg, &dto_done);
+               /* release the dto resource if this RPIPE is done with it. */
+               if (dto_done)
+                       __wa_dto_put(rpipe->wa);
+               dev_dbg(dev, "xfer %p ID %08X#%u submitted from delayed [%d segments available] %d\n",
+                       xfer, wa_xfer_id(xfer), seg->index,
+                       atomic_read(&rpipe->segs_available), result);
                if (unlikely(result < 0)) {
                        spin_unlock_irqrestore(&rpipe->seg_lock, flags);
                        spin_lock_irqsave(&xfer->lock, flags);
@@ -948,7 +1403,37 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
                        spin_lock_irqsave(&rpipe->seg_lock, flags);
                }
        }
+       /*
+        * Mark this RPIPE as waiting if dto was not acquired, there are
+        * delayed segs and no active transfers to wake us up later.
+        */
+       if (!dto_acquired && !list_empty(&rpipe->seg_list)
+               && (atomic_read(&rpipe->segs_available) ==
+                       le16_to_cpu(rpipe->descr.wRequests)))
+               *dto_waiting = 1;
+
        spin_unlock_irqrestore(&rpipe->seg_lock, flags);
+
+       return dto_done;
+}
+
+static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
+{
+       int dto_waiting;
+       int dto_done = __wa_xfer_delayed_run(rpipe, &dto_waiting);
+
+       /*
+        * If this RPIPE is waiting on the DTO resource, add it to the tail of
+        * the waiting list.
+        * Otherwise, if the WA DTO resource was acquired and released by
+        *  __wa_xfer_delayed_run, another RPIPE may have attempted to acquire
+        * DTO and failed during that time.  Check the delayed list and process
+        * any waiters.  Start searching from the next RPIPE index.
+        */
+       if (dto_waiting)
+               wa_add_delayed_rpipe(rpipe->wa, rpipe);
+       else if (dto_done)
+               wa_check_for_delayed_rpipes(rpipe->wa);
 }
 
 /*
@@ -960,7 +1445,7 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
  */
 static int __wa_xfer_submit(struct wa_xfer *xfer)
 {
-       int result;
+       int result, dto_acquired = 0, dto_done = 0, dto_waiting = 0;
        struct wahc *wa = xfer->wa;
        struct device *dev = &wa->usb_iface->dev;
        unsigned cnt;
@@ -979,27 +1464,58 @@ static int __wa_xfer_submit(struct wa_xfer *xfer)
        result = 0;
        spin_lock_irqsave(&rpipe->seg_lock, flags);
        for (cnt = 0; cnt < xfer->segs; cnt++) {
+               int delay_seg = 1;
+
                available = atomic_read(&rpipe->segs_available);
                empty = list_empty(&rpipe->seg_list);
                seg = xfer->seg[cnt];
-               dev_dbg(dev, "xfer %p#%u: available %u empty %u (%s)\n",
-                       xfer, cnt, available, empty,
-                       available == 0 || !empty ? "delayed" : "submitted");
-               if (available == 0 || !empty) {
-                       dev_dbg(dev, "xfer %p#%u: delayed\n", xfer, cnt);
+               if (available && empty) {
+                       /*
+                        * Only attempt to acquire DTO if we have a segment
+                        * to send.
+                        */
+                       dto_acquired = __wa_dto_try_get(rpipe->wa);
+                       if (dto_acquired) {
+                               delay_seg = 0;
+                               result = __wa_seg_submit(rpipe, xfer, seg,
+                                                       &dto_done);
+                               dev_dbg(dev, "xfer %p ID 0x%08X#%u: available %u empty %u submitted\n",
+                                       xfer, wa_xfer_id(xfer), cnt, available,
+                                       empty);
+                               if (dto_done)
+                                       __wa_dto_put(rpipe->wa);
+
+                               if (result < 0) {
+                                       __wa_xfer_abort(xfer);
+                                       goto error_seg_submit;
+                               }
+                       }
+               }
+
+               if (delay_seg) {
+                       dev_dbg(dev, "xfer %p ID 0x%08X#%u: available %u empty %u delayed\n",
+                               xfer, wa_xfer_id(xfer), cnt, available,  empty);
                        seg->status = WA_SEG_DELAYED;
                        list_add_tail(&seg->list_node, &rpipe->seg_list);
-               } else {
-                       result = __wa_seg_submit(rpipe, xfer, seg);
-                       if (result < 0) {
-                               __wa_xfer_abort(xfer);
-                               goto error_seg_submit;
-                       }
                }
                xfer->segs_submitted++;
        }
 error_seg_submit:
+       /*
+        * Mark this RPIPE as waiting if dto was not acquired, there are
+        * delayed segs and no active transfers to wake us up later.
+        */
+       if (!dto_acquired && !list_empty(&rpipe->seg_list)
+               && (atomic_read(&rpipe->segs_available) ==
+                       le16_to_cpu(rpipe->descr.wRequests)))
+               dto_waiting = 1;
        spin_unlock_irqrestore(&rpipe->seg_lock, flags);
+
+       if (dto_waiting)
+               wa_add_delayed_rpipe(rpipe->wa, rpipe);
+       else if (dto_done)
+               wa_check_for_delayed_rpipes(rpipe->wa);
+
        return result;
 }
 
@@ -1025,7 +1541,7 @@ error_seg_submit:
  * result never kicks in, the xfer will timeout from the USB code and
  * dequeue() will be called.
  */
-static void wa_urb_enqueue_b(struct wa_xfer *xfer)
+static int wa_urb_enqueue_b(struct wa_xfer *xfer)
 {
        int result;
        unsigned long flags;
@@ -1036,18 +1552,22 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
        unsigned done;
 
        result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp);
-       if (result < 0)
+       if (result < 0) {
+               pr_err("%s: error_rpipe_get\n", __func__);
                goto error_rpipe_get;
+       }
        result = -ENODEV;
        /* FIXME: segmentation broken -- kills DWA */
        mutex_lock(&wusbhc->mutex);             /* get a WUSB dev */
        if (urb->dev == NULL) {
                mutex_unlock(&wusbhc->mutex);
+               pr_err("%s: error usb dev gone\n", __func__);
                goto error_dev_gone;
        }
        wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
        if (wusb_dev == NULL) {
                mutex_unlock(&wusbhc->mutex);
+               pr_err("%s: error wusb dev gone\n", __func__);
                goto error_dev_gone;
        }
        mutex_unlock(&wusbhc->mutex);
@@ -1055,21 +1575,28 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
        spin_lock_irqsave(&xfer->lock, flags);
        xfer->wusb_dev = wusb_dev;
        result = urb->status;
-       if (urb->status != -EINPROGRESS)
+       if (urb->status != -EINPROGRESS) {
+               pr_err("%s: error_dequeued\n", __func__);
                goto error_dequeued;
+       }
 
        result = __wa_xfer_setup(xfer, urb);
-       if (result < 0)
+       if (result < 0) {
+               pr_err("%s: error_xfer_setup\n", __func__);
                goto error_xfer_setup;
+       }
        result = __wa_xfer_submit(xfer);
-       if (result < 0)
+       if (result < 0) {
+               pr_err("%s: error_xfer_submit\n", __func__);
                goto error_xfer_submit;
+       }
        spin_unlock_irqrestore(&xfer->lock, flags);
-       return;
+       return 0;
 
-       /* this is basically wa_xfer_completion() broken up wa_xfer_giveback()
-        * does a wa_xfer_put() that will call wa_xfer_destroy() and clean
-        * upundo setup().
+       /*
+        * this is basically wa_xfer_completion() broken up wa_xfer_giveback()
+        * does a wa_xfer_put() that will call wa_xfer_destroy() and undo
+        * setup().
         */
 error_xfer_setup:
 error_dequeued:
@@ -1081,8 +1608,7 @@ error_dev_gone:
        rpipe_put(xfer->ep->hcpriv);
 error_rpipe_get:
        xfer->result = result;
-       wa_xfer_giveback(xfer);
-       return;
+       return result;
 
 error_xfer_submit:
        done = __wa_xfer_is_done(xfer);
@@ -1090,6 +1616,8 @@ error_xfer_submit:
        spin_unlock_irqrestore(&xfer->lock, flags);
        if (done)
                wa_xfer_completion(xfer);
+       /* return success since the completion routine will run. */
+       return 0;
 }
 
 /*
@@ -1123,7 +1651,8 @@ void wa_urb_enqueue_run(struct work_struct *ws)
                list_del_init(&xfer->list_node);
 
                urb = xfer->urb;
-               wa_urb_enqueue_b(xfer);
+               if (wa_urb_enqueue_b(xfer) < 0)
+                       wa_xfer_giveback(xfer);
                usb_put_urb(urb);       /* taken when queuing */
        }
 }
@@ -1229,7 +1758,19 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
                spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
                queue_work(wusbd, &wa->xfer_enqueue_work);
        } else {
-               wa_urb_enqueue_b(xfer);
+               result = wa_urb_enqueue_b(xfer);
+               if (result < 0) {
+                       /*
+                        * URB submit/enqueue failed.  Clean up, return an
+                        * error and do not run the callback.  This avoids
+                        * an infinite submit/complete loop.
+                        */
+                       dev_err(dev, "%s: URB enqueue failed: %d\n",
+                          __func__, result);
+                       wa_put(xfer->wa);
+                       wa_xfer_put(xfer);
+                       return result;
+               }
        }
        return 0;
 
@@ -1264,7 +1805,7 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
        struct wa_xfer *xfer;
        struct wa_seg *seg;
        struct wa_rpipe *rpipe;
-       unsigned cnt;
+       unsigned cnt, done = 0, xfer_abort_pending;
        unsigned rpipe_ready = 0;
 
        xfer = urb->hcpriv;
@@ -1278,6 +1819,7 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
                goto out;
        }
        spin_lock_irqsave(&xfer->lock, flags);
+       pr_debug("%s: DEQUEUE xfer id 0x%08X\n", __func__, wa_xfer_id(xfer));
        rpipe = xfer->ep->hcpriv;
        if (rpipe == NULL) {
                pr_debug("%s: xfer id 0x%08X has no RPIPE.  %s",
@@ -1293,9 +1835,11 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
        if (xfer->seg == NULL)          /* still hasn't reached */
                goto out_unlock;        /* setup(), enqueue_b() completes */
        /* Ok, the xfer is in flight already, it's been setup and submitted.*/
-       __wa_xfer_abort(xfer);
+       xfer_abort_pending = __wa_xfer_abort(xfer) >= 0;
        for (cnt = 0; cnt < xfer->segs; cnt++) {
                seg = xfer->seg[cnt];
+               pr_debug("%s: xfer id 0x%08X#%d status = %d\n",
+                       __func__, wa_xfer_id(xfer), cnt, seg->status);
                switch (seg->status) {
                case WA_SEG_NOTREADY:
                case WA_SEG_READY:
@@ -1304,42 +1848,50 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
                        WARN_ON(1);
                        break;
                case WA_SEG_DELAYED:
+                       /*
+                        * delete from rpipe delayed list.  If no segments on
+                        * this xfer have been submitted, __wa_xfer_is_done will
+                        * trigger a giveback below.  Otherwise, the submitted
+                        * segments will be completed in the DTI interrupt.
+                        */
                        seg->status = WA_SEG_ABORTED;
                        spin_lock_irqsave(&rpipe->seg_lock, flags2);
                        list_del(&seg->list_node);
                        xfer->segs_done++;
-                       rpipe_ready = rpipe_avail_inc(rpipe);
                        spin_unlock_irqrestore(&rpipe->seg_lock, flags2);
                        break;
-               case WA_SEG_SUBMITTED:
-                       seg->status = WA_SEG_ABORTED;
-                       usb_unlink_urb(&seg->urb);
-                       if (xfer->is_inbound == 0)
-                               usb_unlink_urb(seg->dto_urb);
-                       xfer->segs_done++;
-                       rpipe_ready = rpipe_avail_inc(rpipe);
-                       break;
-               case WA_SEG_PENDING:
-                       seg->status = WA_SEG_ABORTED;
-                       xfer->segs_done++;
-                       rpipe_ready = rpipe_avail_inc(rpipe);
-                       break;
-               case WA_SEG_DTI_PENDING:
-                       usb_unlink_urb(wa->dti_urb);
-                       seg->status = WA_SEG_ABORTED;
-                       xfer->segs_done++;
-                       rpipe_ready = rpipe_avail_inc(rpipe);
-                       break;
                case WA_SEG_DONE:
                case WA_SEG_ERROR:
                case WA_SEG_ABORTED:
                        break;
+                       /*
+                        * In the states below, the HWA device already knows
+                        * about the transfer.  If an abort request was sent,
+                        * allow the HWA to process it and wait for the
+                        * results.  Otherwise, the DTI state and seg completed
+                        * counts can get out of sync.
+                        */
+               case WA_SEG_SUBMITTED:
+               case WA_SEG_PENDING:
+               case WA_SEG_DTI_PENDING:
+                       /*
+                        * Check if the abort was successfully sent.  This could
+                        * be false if the HWA has been removed but we haven't
+                        * gotten the disconnect notification yet.
+                        */
+                       if (!xfer_abort_pending) {
+                               seg->status = WA_SEG_ABORTED;
+                               rpipe_ready = rpipe_avail_inc(rpipe);
+                               xfer->segs_done++;
+                       }
+                       break;
                }
        }
        xfer->result = urb->status;     /* -ENOENT or -ECONNRESET */
-       __wa_xfer_is_done(xfer);
+       done = __wa_xfer_is_done(xfer);
        spin_unlock_irqrestore(&xfer->lock, flags);
-       wa_xfer_completion(xfer);
+       if (done)
+               wa_xfer_completion(xfer);
        if (rpipe_ready)
                wa_xfer_delayed_run(rpipe);
        return 0;
@@ -1409,14 +1961,57 @@ static int wa_xfer_status_to_errno(u8 status)
        return errno;
 }
 
+/*
+ * If a last segment flag and/or a transfer result error is encountered,
+ * no other segment transfer results will be returned from the device.
+ * Mark the remaining submitted or pending xfers as completed so that
+ * the xfer will complete cleanly.
+ */
+static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer,
+               struct wa_seg *incoming_seg)
+{
+       int index;
+       struct wa_rpipe *rpipe = xfer->ep->hcpriv;
+
+       for (index = incoming_seg->index + 1; index < xfer->segs_submitted;
+               index++) {
+               struct wa_seg *current_seg = xfer->seg[index];
+
+               BUG_ON(current_seg == NULL);
+
+               switch (current_seg->status) {
+               case WA_SEG_SUBMITTED:
+               case WA_SEG_PENDING:
+               case WA_SEG_DTI_PENDING:
+                       rpipe_avail_inc(rpipe);
+               /*
+                * do not increment RPIPE avail for the WA_SEG_DELAYED case
+                * since it has not been submitted to the RPIPE.
+                */
+               case WA_SEG_DELAYED:
+                       xfer->segs_done++;
+                       current_seg->status = incoming_seg->status;
+                       break;
+               case WA_SEG_ABORTED:
+                       break;
+               default:
+                       WARN(1, "%s: xfer 0x%08X#%d. bad seg status = %d\n",
+                               __func__, wa_xfer_id(xfer), index,
+                               current_seg->status);
+                       break;
+               }
+       }
+}
+
 /*
  * Process a xfer result completion message
  *
- * inbound transfers: need to schedule a DTI read
+ * inbound transfers: need to schedule a buf_in_urb read
  *
  * FIXME: this function needs to be broken up in parts
  */
-static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
+static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer,
+               struct wa_xfer_result *xfer_result)
 {
        int result;
        struct device *dev = &wa->usb_iface->dev;
@@ -1424,8 +2019,7 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
        u8 seg_idx;
        struct wa_seg *seg;
        struct wa_rpipe *rpipe;
-       struct wa_xfer_result *xfer_result = wa->xfer_result;
-       u8 done = 0;
+       unsigned done = 0;
        u8 usb_status;
        unsigned rpipe_ready = 0;
 
@@ -1436,8 +2030,8 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
        seg = xfer->seg[seg_idx];
        rpipe = xfer->ep->hcpriv;
        usb_status = xfer_result->bTransferStatus;
-       dev_dbg(dev, "xfer %p#%u: bTransferStatus 0x%02x (seg status %u)\n",
-               xfer, seg_idx, usb_status, seg->status);
+       dev_dbg(dev, "xfer %p ID 0x%08X#%u: bTransferStatus 0x%02x (seg status %u)\n",
+               xfer, wa_xfer_id(xfer), seg_idx, usb_status, seg->status);
        if (seg->status == WA_SEG_ABORTED
            || seg->status == WA_SEG_ERROR)     /* already handled */
                goto segment_aborted;
@@ -1453,12 +2047,19 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
                seg->result = wa_xfer_status_to_errno(usb_status);
                dev_err(dev, "DTI: xfer %p#:%08X:%u failed (0x%02x)\n",
                        xfer, xfer->id, seg->index, usb_status);
+               seg->status = ((usb_status & 0x7F) == WA_XFER_STATUS_ABORTED) ?
+                       WA_SEG_ABORTED : WA_SEG_ERROR;
                goto error_complete;
        }
        /* FIXME: we ignore warnings, tally them for stats */
        if (usb_status & 0x40)          /* Warning?... */
                usb_status = 0;         /* ... pass */
-       if (xfer->is_inbound) { /* IN data phase: read to buffer */
+       if (usb_pipeisoc(xfer->urb->pipe)) {
+               /* set up WA state to read the isoc packet status next. */
+               wa->dti_isoc_xfer_in_progress = wa_xfer_id(xfer);
+               wa->dti_isoc_xfer_seg = seg_idx;
+               wa->dti_state = WA_DTI_ISOC_PACKET_STATUS_PENDING;
+       } else if (xfer->is_inbound) {  /* IN data phase: read to buffer */
                seg->status = WA_SEG_DTI_PENDING;
                BUG_ON(wa->buf_in_urb->status == -EINPROGRESS);
                /* this should always be 0 before a resubmit. */
@@ -1535,12 +2136,14 @@ error_submit_buf_in:
                        xfer, seg_idx, result);
        seg->result = result;
        kfree(wa->buf_in_urb->sg);
+       wa->buf_in_urb->sg = NULL;
 error_sg_alloc:
        __wa_xfer_abort(xfer);
-error_complete:
        seg->status = WA_SEG_ERROR;
+error_complete:
        xfer->segs_done++;
        rpipe_ready = rpipe_avail_inc(rpipe);
+       wa_complete_remaining_xfer_segs(xfer, seg);
        done = __wa_xfer_is_done(xfer);
        /*
         * queue work item to clear STALL for control endpoints.
@@ -1552,10 +2155,8 @@ error_complete:
 
                dev_info(dev, "Control EP stall.  Queue delayed work.\n");
                spin_lock_irq(&wa->xfer_list_lock);
-               /* remove xfer from xfer_list. */
-               list_del(&xfer->list_node);
-               /* add xfer to xfer_errored_list. */
-               list_add_tail(&xfer->list_node, &wa->xfer_errored_list);
+               /* move xfer from xfer_list to xfer_errored_list. */
+               list_move_tail(&xfer->list_node, &wa->xfer_errored_list);
                spin_unlock_irq(&wa->xfer_list_lock);
                spin_unlock_irqrestore(&xfer->lock, flags);
                queue_work(wusbd, &wa->xfer_error_work);
@@ -1586,6 +2187,90 @@ segment_aborted:
        spin_unlock_irqrestore(&xfer->lock, flags);
 }
 
+/*
+ * Process a isochronous packet status message
+ *
+ * inbound transfers: need to schedule a buf_in_urb read
+ */
+static void wa_process_iso_packet_status(struct wahc *wa, struct urb *urb)
+{
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_xfer_packet_status_hwaiso *packet_status;
+       struct wa_xfer_packet_status_len_hwaiso *status_array;
+       struct wa_xfer *xfer;
+       unsigned long flags;
+       struct wa_seg *seg;
+       struct wa_rpipe *rpipe;
+       unsigned done = 0;
+       unsigned rpipe_ready = 0, seg_index;
+       int expected_size;
+
+       /* We have a xfer result buffer; check it */
+       dev_dbg(dev, "DTI: isoc packet status %d bytes at %p\n",
+               urb->actual_length, urb->transfer_buffer);
+       packet_status = (struct wa_xfer_packet_status_hwaiso *)(wa->dti_buf);
+       if (packet_status->bPacketType != WA_XFER_ISO_PACKET_STATUS) {
+               dev_err(dev, "DTI Error: isoc packet status--bad type 0x%02x\n",
+                       packet_status->bPacketType);
+               goto error_parse_buffer;
+       }
+       xfer = wa_xfer_get_by_id(wa, wa->dti_isoc_xfer_in_progress);
+       if (xfer == NULL) {
+               dev_err(dev, "DTI Error: isoc packet status--unknown xfer 0x%08x\n",
+                       wa->dti_isoc_xfer_in_progress);
+               goto error_parse_buffer;
+       }
+       spin_lock_irqsave(&xfer->lock, flags);
+       if (unlikely(wa->dti_isoc_xfer_seg >= xfer->segs))
+               goto error_bad_seg;
+       seg = xfer->seg[wa->dti_isoc_xfer_seg];
+       rpipe = xfer->ep->hcpriv;
+       expected_size = sizeof(*packet_status) +
+                       (sizeof(packet_status->PacketStatus[0]) *
+                       seg->isoc_frame_count);
+       if (urb->actual_length != expected_size) {
+               dev_err(dev, "DTI Error: isoc packet status--bad urb length (%d bytes vs %d needed)\n",
+                       urb->actual_length, expected_size);
+               goto error_bad_seg;
+       }
+       if (le16_to_cpu(packet_status->wLength) != expected_size) {
+               dev_err(dev, "DTI Error: isoc packet status--bad length %u\n",
+                       le16_to_cpu(packet_status->wLength));
+               goto error_bad_seg;
+       }
+       /* isoc packet status and lengths back xfer urb. */
+       status_array = packet_status->PacketStatus;
+       for (seg_index = 0; seg_index < seg->isoc_frame_count; ++seg_index) {
+               xfer->urb->iso_frame_desc[seg->index].status =
+                       wa_xfer_status_to_errno(
+                       le16_to_cpu(status_array[seg_index].PacketStatus));
+               xfer->urb->iso_frame_desc[seg->index].actual_length =
+                       le16_to_cpu(status_array[seg_index].PacketLength);
+       }
+
+       if (!xfer->is_inbound) {
+               /* OUT transfer, complete it -- */
+               seg->status = WA_SEG_DONE;
+               xfer->segs_done++;
+               rpipe_ready = rpipe_avail_inc(rpipe);
+               done = __wa_xfer_is_done(xfer);
+       }
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
+       if (done)
+               wa_xfer_completion(xfer);
+       if (rpipe_ready)
+               wa_xfer_delayed_run(rpipe);
+       wa_xfer_put(xfer);
+       return;
+
+error_bad_seg:
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       wa_xfer_put(xfer);
+error_parse_buffer:
+       return;
+}
+
 /*
  * Callback for the IN data phase
  *
@@ -1687,56 +2372,61 @@ static void wa_buf_in_cb(struct urb *urb)
  * We go back to OFF when we detect a ENOENT or ESHUTDOWN (or too many
  * errors) in the URBs.
  */
-static void wa_xfer_result_cb(struct urb *urb)
+static void wa_dti_cb(struct urb *urb)
 {
        int result;
        struct wahc *wa = urb->context;
        struct device *dev = &wa->usb_iface->dev;
-       struct wa_xfer_result *xfer_result;
        u32 xfer_id;
-       struct wa_xfer *xfer;
        u8 usb_status;
 
        BUG_ON(wa->dti_urb != urb);
        switch (wa->dti_urb->status) {
        case 0:
-               /* We have a xfer result buffer; check it */
-               dev_dbg(dev, "DTI: xfer result %d bytes at %p\n",
-                       urb->actual_length, urb->transfer_buffer);
-               if (wa->dti_urb->actual_length != sizeof(*xfer_result)) {
-                       dev_err(dev, "DTI Error: xfer result--bad size "
-                               "xfer result (%d bytes vs %zu needed)\n",
-                               urb->actual_length, sizeof(*xfer_result));
-                       break;
-               }
-               xfer_result = wa->xfer_result;
-               if (xfer_result->hdr.bLength != sizeof(*xfer_result)) {
-                       dev_err(dev, "DTI Error: xfer result--"
-                               "bad header length %u\n",
-                               xfer_result->hdr.bLength);
-                       break;
-               }
-               if (xfer_result->hdr.bNotifyType != WA_XFER_RESULT) {
-                       dev_err(dev, "DTI Error: xfer result--"
-                               "bad header type 0x%02x\n",
-                               xfer_result->hdr.bNotifyType);
-                       break;
-               }
-               usb_status = xfer_result->bTransferStatus & 0x3f;
-               if (usb_status == WA_XFER_STATUS_NOT_FOUND)
-                       /* taken care of already */
-                       break;
-               xfer_id = xfer_result->dwTransferID;
-               xfer = wa_xfer_get_by_id(wa, xfer_id);
-               if (xfer == NULL) {
-                       /* FIXME: transaction might have been cancelled */
-                       dev_err(dev, "DTI Error: xfer result--"
-                               "unknown xfer 0x%08x (status 0x%02x)\n",
-                               xfer_id, usb_status);
-                       break;
+               if (wa->dti_state == WA_DTI_TRANSFER_RESULT_PENDING) {
+                       struct wa_xfer_result *xfer_result;
+                       struct wa_xfer *xfer;
+
+                       /* We have a xfer result buffer; check it */
+                       dev_dbg(dev, "DTI: xfer result %d bytes at %p\n",
+                               urb->actual_length, urb->transfer_buffer);
+                       if (urb->actual_length != sizeof(*xfer_result)) {
+                               dev_err(dev, "DTI Error: xfer result--bad size xfer result (%d bytes vs %zu needed)\n",
+                                       urb->actual_length,
+                                       sizeof(*xfer_result));
+                               break;
+                       }
+                       xfer_result = (struct wa_xfer_result *)(wa->dti_buf);
+                       if (xfer_result->hdr.bLength != sizeof(*xfer_result)) {
+                               dev_err(dev, "DTI Error: xfer result--bad header length %u\n",
+                                       xfer_result->hdr.bLength);
+                               break;
+                       }
+                       if (xfer_result->hdr.bNotifyType != WA_XFER_RESULT) {
+                               dev_err(dev, "DTI Error: xfer result--bad header type 0x%02x\n",
+                                       xfer_result->hdr.bNotifyType);
+                               break;
+                       }
+                       usb_status = xfer_result->bTransferStatus & 0x3f;
+                       if (usb_status == WA_XFER_STATUS_NOT_FOUND)
+                               /* taken care of already */
+                               break;
+                       xfer_id = le32_to_cpu(xfer_result->dwTransferID);
+                       xfer = wa_xfer_get_by_id(wa, xfer_id);
+                       if (xfer == NULL) {
+                               /* FIXME: transaction not found. */
+                               dev_err(dev, "DTI Error: xfer result--unknown xfer 0x%08x (status 0x%02x)\n",
+                                       xfer_id, usb_status);
+                               break;
+                       }
+                       wa_xfer_result_chew(wa, xfer, xfer_result);
+                       wa_xfer_put(xfer);
+               } else if (wa->dti_state == WA_DTI_ISOC_PACKET_STATUS_PENDING) {
+                       wa_process_iso_packet_status(wa, urb);
+               } else {
+                       dev_err(dev, "DTI Error: unexpected EP state = %d\n",
+                               wa->dti_state);
                }
-               wa_xfer_result_chew(wa, xfer);
-               wa_xfer_put(xfer);
                break;
        case -ENOENT:           /* (we killed the URB)...so, no broadcast */
        case -ESHUTDOWN:        /* going away! */
@@ -1777,7 +2467,7 @@ out:
  * don't really set it up and start it until the first xfer complete
  * notification arrives, which is what we do here.
  *
- * Follow up in wa_xfer_result_cb(), as that's where the whole state
+ * Follow up in wa_dti_cb(), as that's where the whole state
  * machine starts.
  *
  * So here we just initialize the DTI URB for reading transfer result
@@ -1813,8 +2503,8 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
        usb_fill_bulk_urb(
                wa->dti_urb, wa->usb_dev,
                usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
-               wa->xfer_result, wa->xfer_result_size,
-               wa_xfer_result_cb, wa);
+               wa->dti_buf, wa->dti_buf_size,
+               wa_dti_cb, wa);
 
        wa->buf_in_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (wa->buf_in_urb == NULL) {
@@ -1836,6 +2526,7 @@ out:
 
 error_dti_urb_submit:
        usb_put_urb(wa->buf_in_urb);
+       wa->buf_in_urb = NULL;
 error_buf_in_urb_alloc:
        usb_put_urb(wa->dti_urb);
        wa->dti_urb = NULL;
index 9209eafc75b1f004e407965c32c3a683abdf5ed2..80079b8fed155c39f109bd65d12e4e5e155a1b3c 100644 (file)
@@ -244,7 +244,7 @@ static ssize_t uwb_dev_RSSI_store(struct device *dev,
 static DEVICE_ATTR(RSSI, S_IRUGO | S_IWUSR, uwb_dev_RSSI_show, uwb_dev_RSSI_store);
 
 
-static struct attribute *dev_attrs[] = {
+static struct attribute *uwb_dev_attrs[] = {
        &dev_attr_EUI_48.attr,
        &dev_attr_DevAddr.attr,
        &dev_attr_BPST.attr,
@@ -253,20 +253,10 @@ static struct attribute *dev_attrs[] = {
        &dev_attr_RSSI.attr,
        NULL,
 };
-
-static struct attribute_group dev_attr_group = {
-       .attrs = dev_attrs,
-};
-
-static const struct attribute_group *groups[] = {
-       &dev_attr_group,
-       NULL,
-};
+ATTRIBUTE_GROUPS(uwb_dev);
 
 /**
  * Device SYSFS registration
- *
- *
  */
 static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev)
 {
@@ -276,7 +266,7 @@ static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev)
        /* Device sysfs files are only useful for neighbor devices not
           local radio controllers. */
        if (&uwb_dev->rc->uwb_dev != uwb_dev)
-               dev->groups = groups;
+               dev->groups = uwb_dev_groups;
        dev->parent = parent_dev;
        dev_set_drvdata(dev, uwb_dev);
 
index 5c5b3fc9088a30d25fd526fca9427006e9f9d23e..e3ed6ff6a48124b5cbdd5b5c4f11dbe07659fcec 100644 (file)
@@ -201,6 +201,7 @@ static ssize_t capability_id_show(struct device *dev, struct device_attribute *a
 
        return sprintf(buf, "0x%02x\n", umc->cap_id);
 }
+static DEVICE_ATTR_RO(capability_id);
 
 static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -208,12 +209,14 @@ static ssize_t version_show(struct device *dev, struct device_attribute *attr, c
 
        return sprintf(buf, "0x%04x\n", umc->version);
 }
+static DEVICE_ATTR_RO(version);
 
-static struct device_attribute umc_dev_attrs[] = {
-       __ATTR_RO(capability_id),
-       __ATTR_RO(version),
-       __ATTR_NULL,
+static struct attribute *umc_dev_attrs[] = {
+       &dev_attr_capability_id.attr,
+       &dev_attr_version.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(umc_dev);
 
 struct bus_type umc_bus_type = {
        .name           = "umc",
@@ -222,7 +225,7 @@ struct bus_type umc_bus_type = {
        .remove         = umc_device_remove,
        .suspend        = umc_device_suspend,
        .resume         = umc_device_resume,
-       .dev_attrs      = umc_dev_attrs,
+       .dev_groups     = umc_dev_groups,
 };
 EXPORT_SYMBOL_GPL(umc_bus_type);
 
index 0393d827dd44bcfa6f472d78c11823892b944af3..f7447f7004fb12babc4141d55ee70698806f8a46 100644 (file)
@@ -118,7 +118,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = {
        .update_status  = atmel_pwm_bl_set_intensity,
 };
 
-static int __init atmel_pwm_bl_probe(struct platform_device *pdev)
+static int atmel_pwm_bl_probe(struct platform_device *pdev)
 {
        struct backlight_properties props;
        const struct atmel_pwm_bl_platform_data *pdata;
@@ -202,7 +202,7 @@ err_free_mem:
        return retval;
 }
 
-static int __exit atmel_pwm_bl_remove(struct platform_device *pdev)
+static int atmel_pwm_bl_remove(struct platform_device *pdev)
 {
        struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
 
@@ -220,10 +220,11 @@ static struct platform_driver atmel_pwm_bl_driver = {
                .name = "atmel-pwm-bl",
        },
        /* REVISIT add suspend() and resume() */
-       .remove = __exit_p(atmel_pwm_bl_remove),
+       .probe = atmel_pwm_bl_probe,
+       .remove = atmel_pwm_bl_remove,
 };
 
-module_platform_driver_probe(atmel_pwm_bl_driver, atmel_pwm_bl_probe);
+module_platform_driver(atmel_pwm_bl_driver);
 
 MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
 MODULE_DESCRIPTION("Atmel PWM backlight driver");
index 35687fd56456a82318b631e4ffc3df81b74759ca..4ad24f2c64727fdbaea36fe76124444aa3e34014 100644 (file)
@@ -3,7 +3,7 @@
  *     core code for console driver using HP's STI firmware
  *
  *     Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *     Copyright (C) 2001-2003 Helge Deller <deller@gmx.de>
+ *     Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>
  *     Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
  * 
  * TODO:
@@ -30,7 +30,7 @@
 
 #include "../sticore.h"
 
-#define STI_DRIVERVERSION "Version 0.9a"
+#define STI_DRIVERVERSION "Version 0.9b"
 
 static struct sti_struct *default_sti __read_mostly;
 
@@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = {
 
 static int sti_init_graph(struct sti_struct *sti)
 {
-       struct sti_init_inptr_ext inptr_ext = { 0, };
-       struct sti_init_inptr inptr = {
-               .text_planes    = 3, /* # of text planes (max 3 for STI) */
-               .ext_ptr        = STI_PTR(&inptr_ext)
-       };
-       struct sti_init_outptr outptr = { 0, };
+       struct sti_init_inptr *inptr = &sti->sti_data->init_inptr;
+       struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext;
+       struct sti_init_outptr *outptr = &sti->sti_data->init_outptr;
        unsigned long flags;
-       int ret;
+       int ret, err;
 
        spin_lock_irqsave(&sti->lock, flags);
 
-       ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
-               &outptr, sti->glob_cfg);
+       memset(inptr, 0, sizeof(*inptr));
+       inptr->text_planes = 3; /* # of text planes (max 3 for STI) */
+       memset(inptr_ext, 0, sizeof(*inptr_ext));
+       inptr->ext_ptr = STI_PTR(inptr_ext);
+       outptr->errno = 0;
+
+       ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr,
+               outptr, sti->glob_cfg);
+
+       if (ret >= 0)
+               sti->text_planes = outptr->text_planes;
+       err = outptr->errno;
 
        spin_unlock_irqrestore(&sti->lock, flags);
 
        if (ret < 0) {
-               printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno);
+               pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);
                return -1;
        }
        
-       sti->text_planes = outptr.text_planes;
        return 0;
 }
 
@@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = {
 
 static void sti_inq_conf(struct sti_struct *sti)
 {
-       struct sti_conf_inptr inptr = { 0, };
+       struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr;
+       struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr;
        unsigned long flags;
        s32 ret;
 
-       sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext);
+       outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);
        
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->inq_conf, &default_conf_flags,
-                       &inptr, &sti->outptr, sti->glob_cfg);
+               memset(inptr, 0, sizeof(*inptr));
+               ret = sti_call(sti, sti->inq_conf, &default_conf_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = {
 void
 sti_putc(struct sti_struct *sti, int c, int y, int x)
 {
-       struct sti_font_inptr inptr = {
+       struct sti_font_inptr *inptr = &sti->sti_data->font_inptr;
+       struct sti_font_inptr inptr_default = {
                .font_start_addr= STI_PTR(sti->font->raw),
                .index          = c_index(sti, c),
                .fg_color       = c_fg(sti, c),
@@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x)
                .dest_x         = x * sti->font_width,
                .dest_y         = y * sti->font_height,
        };
-       struct sti_font_outptr outptr = { 0, };
+       struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;
        s32 ret;
        unsigned long flags;
 
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->font_unpmv, &default_font_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->font_unpmv, &default_font_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -156,7 +166,8 @@ void
 sti_set(struct sti_struct *sti, int src_y, int src_x,
        int height, int width, u8 color)
 {
-       struct sti_blkmv_inptr inptr = {
+       struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
+       struct sti_blkmv_inptr inptr_default = {
                .fg_color       = color,
                .bg_color       = color,
                .src_x          = src_x,
@@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
                .width          = width,
                .height         = height,
        };
-       struct sti_blkmv_outptr outptr = { 0, };
+       struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
        s32 ret;
        unsigned long flags;
        
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -182,7 +194,8 @@ void
 sti_clear(struct sti_struct *sti, int src_y, int src_x,
          int height, int width, int c)
 {
-       struct sti_blkmv_inptr inptr = {
+       struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
+       struct sti_blkmv_inptr inptr_default = {
                .fg_color       = c_fg(sti, c),
                .bg_color       = c_bg(sti, c),
                .src_x          = src_x * sti->font_width,
@@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
                .width          = width * sti->font_width,
                .height         = height* sti->font_height,
        };
-       struct sti_blkmv_outptr outptr = { 0, };
+       struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
        s32 ret;
        unsigned long flags;
 
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -212,7 +226,8 @@ void
 sti_bmove(struct sti_struct *sti, int src_y, int src_x,
          int dst_y, int dst_x, int height, int width)
 {
-       struct sti_blkmv_inptr inptr = {
+       struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
+       struct sti_blkmv_inptr inptr_default = {
                .src_x          = src_x * sti->font_width,
                .src_y          = src_y * sti->font_height,
                .dest_x         = dst_x * sti->font_width,
@@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,
                .width          = width * sti->font_width,
                .height         = height* sti->font_height,
        };
-       struct sti_blkmv_outptr outptr = { 0, };
+       struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
        s32 ret;
        unsigned long flags;
 
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->block_move, &default_blkmv_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->block_move, &default_blkmv_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -284,7 +300,7 @@ __setup("sti=", sti_setup);
 
 
 
-static char *font_name[MAX_STI_ROMS] = { "VGA8x16", };
+static char *font_name[MAX_STI_ROMS];
 static int font_index[MAX_STI_ROMS],
           font_height[MAX_STI_ROMS],
           font_width[MAX_STI_ROMS];
@@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti)
                "%d used bits\n"
                "%d planes\n"
                "attributes %08x\n",
-                sti->outptr.bits_per_pixel,
-                sti->outptr.bits_used,
-                sti->outptr.planes,
-                sti->outptr.attributes));
+                sti->sti_data->inq_outptr.bits_per_pixel,
+                sti->sti_data->inq_outptr.bits_used,
+                sti->sti_data->inq_outptr.planes,
+                sti->sti_data->inq_outptr.attributes));
 }
 
 static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
@@ -402,24 +418,21 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
        struct sti_glob_cfg_ext *glob_cfg_ext;
        void *save_addr;
        void *sti_mem_addr;
-       const int save_addr_size = 1024;        /* XXX */
-       int i;
+       int i, size;
 
-       if (!sti->sti_mem_request)
+       if (sti->sti_mem_request < 256)
                sti->sti_mem_request = 256; /* STI default */
 
-       glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL);
-       glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
-       save_addr = kzalloc(save_addr_size, GFP_KERNEL);
-       sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL);
+       size = sizeof(struct sti_all_data) + sti->sti_mem_request - 256;
 
-       if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) {
-               kfree(glob_cfg);
-               kfree(glob_cfg_ext);
-               kfree(save_addr);
-               kfree(sti_mem_addr);
+       sti->sti_data = kzalloc(size, STI_LOWMEM);
+       if (!sti->sti_data)
                return -ENOMEM;
-       }
+
+       glob_cfg        = &sti->sti_data->glob_cfg;
+       glob_cfg_ext    = &sti->sti_data->glob_cfg_ext;
+       save_addr       = &sti->sti_data->save_addr;
+       sti_mem_addr    = &sti->sti_data->sti_mem_addr;
 
        glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
        glob_cfg->save_addr = STI_PTR(save_addr);
@@ -475,32 +488,31 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
        return 0;
 }
 
-#ifdef CONFIG_FB
+#ifdef CONFIG_FONTS
 static struct sti_cooked_font *
 sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
 {
-       const struct font_desc *fbfont;
+       const struct font_desc *fbfont = NULL;
        unsigned int size, bpc;
        void *dest;
        struct sti_rom_font *nf;
        struct sti_cooked_font *cooked_font;
        
-       if (!fbfont_name || !strlen(fbfont_name))
-               return NULL;
-       fbfont = find_font(fbfont_name);
+       if (fbfont_name && strlen(fbfont_name))
+               fbfont = find_font(fbfont_name);
        if (!fbfont)
                fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
        if (!fbfont)
                return NULL;
 
-       DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n",
-                       fbfont->width, fbfont->height, fbfont->name));
+       pr_info("STI selected %dx%d framebuffer font %s for sticon\n",
+                       fbfont->width, fbfont->height, fbfont->name);
                        
        bpc = ((fbfont->width+7)/8) * fbfont->height; 
        size = bpc * 256;
        size += sizeof(struct sti_rom_font);
 
-       nf = kzalloc(size, GFP_KERNEL);
+       nf = kzalloc(size, STI_LOWMEM);
        if (!nf)
                return NULL;
 
@@ -637,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f)
        unsigned char *n, *p, *q;
        int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
        
-       n = kzalloc (4*size, GFP_KERNEL);
+       n = kzalloc(4*size, STI_LOWMEM);
        if (!n)
                return NULL;
        p = n + 3;
@@ -673,7 +685,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address)
        sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);
 
        size = (size+3) / 4;
-       raw = kmalloc(size, GFP_KERNEL);
+       raw = kmalloc(size, STI_LOWMEM);
        if (raw) {
                sti_bmode_rom_copy(address, size, raw);
                memmove (&raw->res004, &raw->type[0], 0x3c);
@@ -707,7 +719,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address)
        /* read the ROM size directly from the struct in ROM */ 
        size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
 
-       raw = kmalloc(size, GFP_KERNEL);
+       raw = kmalloc(size, STI_LOWMEM);
        if (raw)
                sti_rom_copy(address, size, raw);
 
@@ -743,6 +755,10 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
 
        address = (unsigned long) STI_PTR(raw);
 
+       pr_info("STI ROM supports 32 %sbit firmware functions.\n",
+               raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64
+               ? "and 64 " : "");
+
        sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff);
        sti->block_move = address + (raw->block_move & 0x03ffffff);
        sti->init_graph = address + (raw->init_graph & 0x03ffffff);
@@ -901,7 +917,8 @@ test_rom:
        sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
        sti_dump_outptr(sti);
        
-       printk(KERN_INFO "    graphics card name: %s\n", sti->outptr.dev_name );
+       pr_info("    graphics card name: %s\n",
+               sti->sti_data->inq_outptr.dev_name);
 
        sti_roms[num_sti_roms] = sti;
        num_sti_roms++;
@@ -1073,6 +1090,29 @@ struct sti_struct * sti_get_rom(unsigned int index)
 }
 EXPORT_SYMBOL(sti_get_rom);
 
+
+int sti_call(const struct sti_struct *sti, unsigned long func,
+               const void *flags, void *inptr, void *outptr,
+               struct sti_glob_cfg *glob_cfg)
+{
+       unsigned long _flags = STI_PTR(flags);
+       unsigned long _inptr = STI_PTR(inptr);
+       unsigned long _outptr = STI_PTR(outptr);
+       unsigned long _glob_cfg = STI_PTR(glob_cfg);
+       int ret;
+
+#ifdef CONFIG_64BIT
+       /* Check for overflow when using 32bit STI on 64bit kernel. */
+       if (WARN_ONCE(_flags>>32 || _inptr>>32 || _outptr>>32 || _glob_cfg>>32,
+                       "Out of 32bit-range pointers!"))
+               return -1;
+#endif
+
+       ret = pdc_sti_call(func, _flags, _inptr, _outptr, _glob_cfg);
+
+       return ret;
+}
+
 MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");
 MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");
 MODULE_LICENSE("GPL v2");
index 57886787ead020687d1f05d40230d62c1db096fa..1c446bc48b42fdefca1861de934271840901e61c 100644 (file)
@@ -1641,67 +1641,6 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
        cyber2000fb_set_par(&cfb->fb);
 }
 
-#ifdef CONFIG_ARCH_SHARK
-
-#include <mach/framebuffer.h>
-
-static int cyberpro_vl_probe(void)
-{
-       struct cfb_info *cfb;
-       int err = -ENOMEM;
-
-       if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))
-               return err;
-
-       cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
-       if (!cfb)
-               goto failed_release;
-
-       cfb->irq = -1;
-       cfb->region = ioremap(FB_START, FB_SIZE);
-       if (!cfb->region)
-               goto failed_ioremap;
-
-       cfb->regs = cfb->region + MMIO_OFFSET;
-       cfb->fb.device = NULL;
-       cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;
-       cfb->fb.fix.smem_start = FB_START;
-
-       /*
-        * Bring up the hardware.  This is expected to enable access
-        * to the linear memory region, and allow access to the memory
-        * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be
-        * initialised.
-        */
-       cyber2000fb_writeb(0x18, 0x46e8, cfb);
-       cyber2000fb_writeb(0x01, 0x102, cfb);
-       cyber2000fb_writeb(0x08, 0x46e8, cfb);
-       cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb);
-       cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb);
-
-       cfb->mclk_mult = 0xdb;
-       cfb->mclk_div  = 0x54;
-
-       err = cyberpro_common_probe(cfb);
-       if (err)
-               goto failed;
-
-       if (int_cfb_info == NULL)
-               int_cfb_info = cfb;
-
-       return 0;
-
-failed:
-       iounmap(cfb->region);
-failed_ioremap:
-       cyberpro_free_fb_info(cfb);
-failed_release:
-       release_mem_region(FB_START, FB_SIZE);
-
-       return err;
-}
-#endif /* CONFIG_ARCH_SHARK */
-
 /*
  * PCI specific support.
  */
@@ -1948,28 +1887,19 @@ static int __init cyber2000fb_init(void)
        cyber2000fb_setup(option);
 #endif
 
-#ifdef CONFIG_ARCH_SHARK
-       err = cyberpro_vl_probe();
-       if (!err)
-               ret = 0;
-#endif
-#ifdef CONFIG_PCI
        err = pci_register_driver(&cyberpro_driver);
        if (!err)
                ret = 0;
-#endif
 
        return ret ? err : 0;
 }
 module_init(cyber2000fb_init);
 
-#ifndef CONFIG_ARCH_SHARK
 static void __exit cyberpro_exit(void)
 {
        pci_unregister_driver(&cyberpro_driver);
 }
 module_exit(cyberpro_exit);
-#endif
 
 MODULE_AUTHOR("Russell King");
 MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
index 1b035b2eb6b611a075e633b3cf020e2dbfcb5700..1129d0e9e6403dbb6c68a0478fda17bc2117b7b9 100644 (file)
@@ -16,6 +16,7 @@ if EXYNOS_VIDEO
 config EXYNOS_MIPI_DSI
        bool "EXYNOS MIPI DSI driver support."
        depends on ARCH_S5PV210 || ARCH_EXYNOS
+       select GENERIC_PHY
        help
          This enables support for MIPI-DSI device.
 
@@ -29,7 +30,7 @@ config EXYNOS_LCD_S6E8AX0
 
 config EXYNOS_DP
        bool "EXYNOS DP driver support"
-       depends on ARCH_EXYNOS
+       depends on OF && ARCH_EXYNOS
        default n
        help
          This enables support for DP device.
index 12bbede3b091e68ae0600b7fb55c765052d2f66d..5e1a7158005196572459dbf7bfbf561495210410 100644 (file)
@@ -19,8 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/of.h>
-
-#include <video/exynos_dp.h>
+#include <linux/phy/phy.h>
 
 #include "exynos_dp_core.h"
 
@@ -894,26 +893,17 @@ static void exynos_dp_hotplug(struct work_struct *work)
                dev_err(dp->dev, "unable to config video\n");
 }
 
-#ifdef CONFIG_OF
-static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 {
        struct device_node *dp_node = dev->of_node;
-       struct exynos_dp_platdata *pd;
        struct video_info *dp_video_config;
 
-       pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
-       if (!pd) {
-               dev_err(dev, "memory allocation for pdata failed\n");
-               return ERR_PTR(-ENOMEM);
-       }
        dp_video_config = devm_kzalloc(dev,
                                sizeof(*dp_video_config), GFP_KERNEL);
-
        if (!dp_video_config) {
                dev_err(dev, "memory allocation for video config failed\n");
                return ERR_PTR(-ENOMEM);
        }
-       pd->video_info = dp_video_config;
 
        dp_video_config->h_sync_polarity =
                of_property_read_bool(dp_node, "hsync-active-high");
@@ -960,7 +950,7 @@ static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
                return ERR_PTR(-EINVAL);
        }
 
-       return pd;
+       return dp_video_config;
 }
 
 static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
@@ -971,8 +961,11 @@ static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
 
        dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
        if (!dp_phy_node) {
-               dev_err(dp->dev, "could not find dptx-phy node\n");
-               return -ENODEV;
+               dp->phy = devm_phy_get(dp->dev, "dp");
+               if (IS_ERR(dp->phy))
+                       return PTR_ERR(dp->phy);
+               else
+                       return 0;
        }
 
        if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
@@ -1003,48 +996,34 @@ err:
 
 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
-       u32 reg;
-
-       reg = __raw_readl(dp->phy_addr);
-       reg |= dp->enable_mask;
-       __raw_writel(reg, dp->phy_addr);
-}
-
-static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
-{
-       u32 reg;
-
-       reg = __raw_readl(dp->phy_addr);
-       reg &= ~(dp->enable_mask);
-       __raw_writel(reg, dp->phy_addr);
-}
-#else
-static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
-{
-       return NULL;
-}
-
-static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
-{
-       return -EINVAL;
-}
-
-static void exynos_dp_phy_init(struct exynos_dp_device *dp)
-{
-       return;
+       if (dp->phy) {
+               phy_power_on(dp->phy);
+       } else if (dp->phy_addr) {
+               u32 reg;
+
+               reg = __raw_readl(dp->phy_addr);
+               reg |= dp->enable_mask;
+               __raw_writel(reg, dp->phy_addr);
+       }
 }
 
 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 {
-       return;
+       if (dp->phy) {
+               phy_power_off(dp->phy);
+       } else if (dp->phy_addr) {
+               u32 reg;
+
+               reg = __raw_readl(dp->phy_addr);
+               reg &= ~(dp->enable_mask);
+               __raw_writel(reg, dp->phy_addr);
+       }
 }
-#endif /* CONFIG_OF */
 
 static int exynos_dp_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct exynos_dp_device *dp;
-       struct exynos_dp_platdata *pdata;
 
        int ret = 0;
 
@@ -1057,21 +1036,13 @@ static int exynos_dp_probe(struct platform_device *pdev)
 
        dp->dev = &pdev->dev;
 
-       if (pdev->dev.of_node) {
-               pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
-               if (IS_ERR(pdata))
-                       return PTR_ERR(pdata);
+       dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev);
+       if (IS_ERR(dp->video_info))
+               return PTR_ERR(dp->video_info);
 
-               ret = exynos_dp_dt_parse_phydata(dp);
-               if (ret)
-                       return ret;
-       } else {
-               pdata = pdev->dev.platform_data;
-               if (!pdata) {
-                       dev_err(&pdev->dev, "no platform data\n");
-                       return -EINVAL;
-               }
-       }
+       ret = exynos_dp_dt_parse_phydata(dp);
+       if (ret)
+               return ret;
 
        dp->clock = devm_clk_get(&pdev->dev, "dp");
        if (IS_ERR(dp->clock)) {
@@ -1095,15 +1066,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 
        INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
 
-       dp->video_info = pdata->video_info;
-
-       if (pdev->dev.of_node) {
-               if (dp->phy_addr)
-                       exynos_dp_phy_init(dp);
-       } else {
-               if (pdata->phy_init)
-                       pdata->phy_init();
-       }
+       exynos_dp_phy_init(dp);
 
        exynos_dp_init_dp(dp);
 
@@ -1121,18 +1084,11 @@ static int exynos_dp_probe(struct platform_device *pdev)
 
 static int exynos_dp_remove(struct platform_device *pdev)
 {
-       struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
        struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
        flush_work(&dp->hotplug_work);
 
-       if (pdev->dev.of_node) {
-               if (dp->phy_addr)
-                       exynos_dp_phy_exit(dp);
-       } else {
-               if (pdata->phy_exit)
-                       pdata->phy_exit();
-       }
+       exynos_dp_phy_exit(dp);
 
        clk_disable_unprepare(dp->clock);
 
@@ -1143,20 +1099,13 @@ static int exynos_dp_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int exynos_dp_suspend(struct device *dev)
 {
-       struct exynos_dp_platdata *pdata = dev->platform_data;
        struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
        disable_irq(dp->irq);
 
        flush_work(&dp->hotplug_work);
 
-       if (dev->of_node) {
-               if (dp->phy_addr)
-                       exynos_dp_phy_exit(dp);
-       } else {
-               if (pdata->phy_exit)
-                       pdata->phy_exit();
-       }
+       exynos_dp_phy_exit(dp);
 
        clk_disable_unprepare(dp->clock);
 
@@ -1165,16 +1114,9 @@ static int exynos_dp_suspend(struct device *dev)
 
 static int exynos_dp_resume(struct device *dev)
 {
-       struct exynos_dp_platdata *pdata = dev->platform_data;
        struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-       if (dev->of_node) {
-               if (dp->phy_addr)
-                       exynos_dp_phy_init(dp);
-       } else {
-               if (pdata->phy_init)
-                       pdata->phy_init();
-       }
+       exynos_dp_phy_init(dp);
 
        clk_prepare_enable(dp->clock);
 
@@ -1203,7 +1145,7 @@ static struct platform_driver exynos_dp_driver = {
                .name   = "exynos-dp",
                .owner  = THIS_MODULE,
                .pm     = &exynos_dp_pm_ops,
-               .of_match_table = of_match_ptr(exynos_dp_match),
+               .of_match_table = exynos_dp_match,
        },
 };
 
index 6c567bbf2fb8fcec22f4f7949916e5a515b7b573..607e36d0c147ada6fc2203a7dc657d2490c1a91d 100644 (file)
 #ifndef _EXYNOS_DP_CORE_H
 #define _EXYNOS_DP_CORE_H
 
+#define DP_TIMEOUT_LOOP_COUNT 100
+#define MAX_CR_LOOP 5
+#define MAX_EQ_LOOP 5
+
+enum link_rate_type {
+       LINK_RATE_1_62GBPS = 0x06,
+       LINK_RATE_2_70GBPS = 0x0a
+};
+
+enum link_lane_count_type {
+       LANE_COUNT1 = 1,
+       LANE_COUNT2 = 2,
+       LANE_COUNT4 = 4
+};
+
+enum link_training_state {
+       START,
+       CLOCK_RECOVERY,
+       EQUALIZER_TRAINING,
+       FINISHED,
+       FAILED
+};
+
+enum voltage_swing_level {
+       VOLTAGE_LEVEL_0,
+       VOLTAGE_LEVEL_1,
+       VOLTAGE_LEVEL_2,
+       VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+       PRE_EMPHASIS_LEVEL_0,
+       PRE_EMPHASIS_LEVEL_1,
+       PRE_EMPHASIS_LEVEL_2,
+       PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+       PRBS7,
+       D10_2,
+       TRAINING_PTN1,
+       TRAINING_PTN2,
+       DP_NONE
+};
+
+enum color_space {
+       COLOR_RGB,
+       COLOR_YCBCR422,
+       COLOR_YCBCR444
+};
+
+enum color_depth {
+       COLOR_6,
+       COLOR_8,
+       COLOR_10,
+       COLOR_12
+};
+
+enum color_coefficient {
+       COLOR_YCBCR601,
+       COLOR_YCBCR709
+};
+
+enum dynamic_range {
+       VESA,
+       CEA
+};
+
+enum pll_status {
+       PLL_UNLOCKED,
+       PLL_LOCKED
+};
+
+enum clock_recovery_m_value_type {
+       CALCULATED_M,
+       REGISTER_M
+};
+
+enum video_timing_recognition_type {
+       VIDEO_TIMING_FROM_CAPTURE,
+       VIDEO_TIMING_FROM_REGISTER
+};
+
+enum analog_power_block {
+       AUX_BLOCK,
+       CH0_BLOCK,
+       CH1_BLOCK,
+       CH2_BLOCK,
+       CH3_BLOCK,
+       ANALOG_TOTAL,
+       POWER_ALL
+};
+
 enum dp_irq_type {
        DP_IRQ_TYPE_HP_CABLE_IN,
        DP_IRQ_TYPE_HP_CABLE_OUT,
@@ -20,6 +113,22 @@ enum dp_irq_type {
        DP_IRQ_TYPE_UNKNOWN,
 };
 
+struct video_info {
+       char *name;
+
+       bool h_sync_polarity;
+       bool v_sync_polarity;
+       bool interlaced;
+
+       enum color_space color_space;
+       enum dynamic_range dynamic_range;
+       enum color_coefficient ycbcr_coeff;
+       enum color_depth color_depth;
+
+       enum link_rate_type link_rate;
+       enum link_lane_count_type lane_count;
+};
+
 struct link_train {
        int eq_loop;
        int cr_loop[4];
@@ -42,6 +151,7 @@ struct exynos_dp_device {
        struct video_info       *video_info;
        struct link_train       link_train;
        struct work_struct      hotplug_work;
+       struct phy              *phy;
 };
 
 /* exynos_dp_reg.c */
index 29d9d035c73a76e7313650fcbb6045b7dd0cfa38..b70da5052ff0287233b3668574df40ed5b7e8fb1 100644 (file)
@@ -14,8 +14,6 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 
-#include <video/exynos_dp.h>
-
 #include "exynos_dp_core.h"
 #include "exynos_dp_reg.h"
 
index 32e540600f995b42937653832c3e4d8508012c50..00b3a52c1d68766d42cab3c65a1a9405d4a04617 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
 #include <linux/notifier.h>
+#include <linux/phy/phy.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
@@ -156,8 +157,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
                exynos_mipi_regulator_enable(dsim);
 
                /* enable MIPI-DSI PHY. */
-               if (dsim->pd->phy_enable)
-                       dsim->pd->phy_enable(pdev, true);
+               phy_power_on(dsim->phy);
 
                clk_enable(dsim->clock);
 
@@ -373,6 +373,10 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
                return ret;
        }
 
+       dsim->phy = devm_phy_get(&pdev->dev, "dsim");
+       if (IS_ERR(dsim->phy))
+               return PTR_ERR(dsim->phy);
+
        dsim->clock = devm_clk_get(&pdev->dev, "dsim0");
        if (IS_ERR(dsim->clock)) {
                dev_err(&pdev->dev, "failed to get dsim clock source\n");
@@ -439,8 +443,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
        exynos_mipi_regulator_enable(dsim);
 
        /* enable MIPI-DSI PHY. */
-       if (dsim->pd->phy_enable)
-               dsim->pd->phy_enable(pdev, true);
+       phy_power_on(dsim->phy);
 
        exynos_mipi_update_cfg(dsim);
 
@@ -504,9 +507,8 @@ static int exynos_mipi_dsi_suspend(struct device *dev)
        if (client_drv && client_drv->suspend)
                client_drv->suspend(client_dev);
 
-       /* enable MIPI-DSI PHY. */
-       if (dsim->pd->phy_enable)
-               dsim->pd->phy_enable(pdev, false);
+       /* disable MIPI-DSI PHY. */
+       phy_power_off(dsim->phy);
 
        clk_disable(dsim->clock);
 
@@ -536,8 +538,7 @@ static int exynos_mipi_dsi_resume(struct device *dev)
        exynos_mipi_regulator_enable(dsim);
 
        /* enable MIPI-DSI PHY. */
-       if (dsim->pd->phy_enable)
-               dsim->pd->phy_enable(pdev, true);
+       phy_power_on(dsim->phy);
 
        clk_enable(dsim->clock);
 
index addf7b615ef8d2e88a8130a73ce1f5aac12032db..af1619536ac84f3d2b638c400f7bf674cd087724 100644 (file)
@@ -18,6 +18,9 @@
 #define STI_FONT_HPROMAN8 1
 #define STI_FONT_KANA8 2
 
+#define ALT_CODE_TYPE_UNKNOWN 0x00     /* alt code type values */
+#define ALT_CODE_TYPE_PA_RISC_64 0x01
+
 /* The latency of the STI functions cannot really be reduced by setting
  * this to 0;  STI doesn't seem to be designed to allow calling a different
  * function (or the same function with different arguments) after a
 
 #define STI_PTR(p)     ( virt_to_phys(p) )
 #define PTR_STI(p)     ( phys_to_virt((unsigned long)p) )
-#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
-       ({                                              \
-               pdc_sti_call( func, STI_PTR(flags),     \
-                                  STI_PTR(inptr),      \
-                                  STI_PTR(outptr),     \
-                                  STI_PTR(glob_cfg));  \
-       })
-
 
 #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
 #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
 #define sti_font_x(sti) (PTR_STI(sti->font)->width)
 #define sti_font_y(sti) (PTR_STI(sti->font)->height)
 
+#ifdef CONFIG_64BIT
+#define STI_LOWMEM     (GFP_KERNEL | GFP_DMA)
+#else
+#define STI_LOWMEM     (GFP_KERNEL)
+#endif
+
 
 /* STI function configuration structs */
 
@@ -306,6 +307,34 @@ struct sti_blkmv_outptr {
 };
 
 
+/* sti_all_data is an internal struct which needs to be allocated in
+ * low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */
+
+struct sti_all_data {
+       struct sti_glob_cfg glob_cfg;
+       struct sti_glob_cfg_ext glob_cfg_ext;
+
+       struct sti_conf_inptr           inq_inptr;
+       struct sti_conf_outptr          inq_outptr; /* configuration */
+       struct sti_conf_outptr_ext      inq_outptr_ext;
+
+       struct sti_init_inptr_ext       init_inptr_ext;
+       struct sti_init_inptr           init_inptr;
+       struct sti_init_outptr          init_outptr;
+
+       struct sti_blkmv_inptr          blkmv_inptr;
+       struct sti_blkmv_outptr         blkmv_outptr;
+
+       struct sti_font_inptr           font_inptr;
+       struct sti_font_outptr          font_outptr;
+
+       /* leave as last entries */
+       unsigned long save_addr[1024 / sizeof(unsigned long)];
+          /* min 256 bytes which is STI default, max sti->sti_mem_request */
+       unsigned long sti_mem_addr[256 / sizeof(unsigned long)];
+       /* do not add something below here ! */
+};
+
 /* internal generic STI struct */
 
 struct sti_struct {
@@ -330,11 +359,9 @@ struct sti_struct {
        region_t regions[STI_REGION_MAX];
        unsigned long regions_phys[STI_REGION_MAX];
 
-       struct sti_glob_cfg *glob_cfg;
-       struct sti_cooked_font *font;   /* ptr to selected font (cooked) */
+       struct sti_glob_cfg *glob_cfg;  /* points into sti_all_data */
 
-       struct sti_conf_outptr outptr; /* configuration */
-       struct sti_conf_outptr_ext outptr_ext;
+       struct sti_cooked_font *font;   /* ptr to selected font (cooked) */
 
        struct pci_dev *pd;
 
@@ -343,6 +370,9 @@ struct sti_struct {
 
        /* pointer to the fb_info where this STI device is used */
        struct fb_info *info;
+
+       /* pointer to all internal data */
+       struct sti_all_data *sti_data;
 };
 
 
@@ -350,6 +380,14 @@ struct sti_struct {
 
 struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
 
+
+/* sticore main function to call STI firmware */
+
+int sti_call(const struct sti_struct *sti, unsigned long func,
+               const void *flags, void *inptr, void *outptr,
+               struct sti_glob_cfg *glob_cfg);
+
+
 /* functions to call the STI ROM directly */
 
 void sti_putc(struct sti_struct *sti, int c, int y, int x);
index 876648e15e9d6d7cdd3d423da4401c2252ac3357..019a1feef995adcbfaff37c3e092a002eb190a4b 100644 (file)
@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
        var = &info->var;
 
        fb->sti = sti;
+       dev_name = sti->sti_data->inq_outptr.dev_name;
        /* store upper 32bits of the graphics id */
        fb->id = fb->sti->graphics_id[0];
 
@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                  Since this driver only supports standard mode, we check
                  if the device name contains the string "DX" and tell the
                  user how to reconfigure the card. */
-               if (strstr(sti->outptr.dev_name, "DX")) {
+               if (strstr(dev_name, "DX")) {
                   printk(KERN_WARNING
 "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
 "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
-                       sti->outptr.dev_name);
+                       dev_name);
                   goto out_err0;
                }
                /* fall though */
@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                break;
        default:
                printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
-                       sti->outptr.dev_name, fb->id);
+                       dev_name, fb->id);
                goto out_err0;
        }
        
@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                fb->id = S9000_ID_A1659A;
                break;
        case S9000_ID_TIMBER:   /* HP9000/710 Any (may be a grayscale device) */
-               dev_name = fb->sti->outptr.dev_name;
                if (strstr(dev_name, "GRAYSCALE") || 
                    strstr(dev_name, "Grayscale") ||
                    strstr(dev_name, "grayscale"))
@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                var->xres, 
                var->yres,
                var->bits_per_pixel,
-               sti->outptr.dev_name,
+               dev_name,
                fb->id, 
                fix->mmio_start);
 
index ee59b74768d9555e27802e0256a9d448f599f48d..fed0ce198ae3eacf76d747948f54cb051bda8d57 100644 (file)
@@ -13,18 +13,24 @@ static ssize_t device_show(struct device *_d,
        struct virtio_device *dev = dev_to_virtio(_d);
        return sprintf(buf, "0x%04x\n", dev->id.device);
 }
+static DEVICE_ATTR_RO(device);
+
 static ssize_t vendor_show(struct device *_d,
                           struct device_attribute *attr, char *buf)
 {
        struct virtio_device *dev = dev_to_virtio(_d);
        return sprintf(buf, "0x%04x\n", dev->id.vendor);
 }
+static DEVICE_ATTR_RO(vendor);
+
 static ssize_t status_show(struct device *_d,
                           struct device_attribute *attr, char *buf)
 {
        struct virtio_device *dev = dev_to_virtio(_d);
        return sprintf(buf, "0x%08x\n", dev->config->get_status(dev));
 }
+static DEVICE_ATTR_RO(status);
+
 static ssize_t modalias_show(struct device *_d,
                             struct device_attribute *attr, char *buf)
 {
@@ -32,6 +38,8 @@ static ssize_t modalias_show(struct device *_d,
        return sprintf(buf, "virtio:d%08Xv%08X\n",
                       dev->id.device, dev->id.vendor);
 }
+static DEVICE_ATTR_RO(modalias);
+
 static ssize_t features_show(struct device *_d,
                             struct device_attribute *attr, char *buf)
 {
@@ -47,14 +55,17 @@ static ssize_t features_show(struct device *_d,
        len += sprintf(buf+len, "\n");
        return len;
 }
-static struct device_attribute virtio_dev_attrs[] = {
-       __ATTR_RO(device),
-       __ATTR_RO(vendor),
-       __ATTR_RO(status),
-       __ATTR_RO(modalias),
-       __ATTR_RO(features),
-       __ATTR_NULL
+static DEVICE_ATTR_RO(features);
+
+static struct attribute *virtio_dev_attrs[] = {
+       &dev_attr_device.attr,
+       &dev_attr_vendor.attr,
+       &dev_attr_status.attr,
+       &dev_attr_modalias.attr,
+       &dev_attr_features.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(virtio_dev);
 
 static inline int virtio_id_match(const struct virtio_device *dev,
                                  const struct virtio_device_id *id)
@@ -165,7 +176,7 @@ static int virtio_dev_remove(struct device *_d)
 static struct bus_type virtio_bus = {
        .name  = "virtio",
        .match = virtio_dev_match,
-       .dev_attrs = virtio_dev_attrs,
+       .dev_groups = virtio_dev_groups,
        .uevent = virtio_uevent,
        .probe = virtio_dev_probe,
        .remove = virtio_dev_remove,
index 96cab6ac2b4e6fdda01cff9d5bdb7d185fb1f82f..41613f92a723448c1b4091a7e357fc05b2af9638 100644 (file)
@@ -498,7 +498,7 @@ static int ds1wm_probe(struct platform_device *pdev)
                irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
 
        ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
-                       IRQF_DISABLED | IRQF_SHARED, "ds1wm", ds1wm_data);
+                       IRQF_SHARED, "ds1wm", ds1wm_data);
        if (ret)
                return ret;
 
index 6e94d8dd3d00a31d696fc7e140329d9b4dc72c6b..9900e8ec73939fef918abff3bda6829e6b25b4d3 100644 (file)
@@ -577,8 +577,7 @@ static int omap_hdq_probe(struct platform_device *pdev)
                goto err_irq;
        }
 
-       ret = devm_request_irq(dev, irq, hdq_isr, IRQF_DISABLED,
-                       "omap_hdq", hdq_data);
+       ret = devm_request_irq(dev, irq, hdq_isr, 0, "omap_hdq", hdq_data);
        if (ret < 0) {
                dev_dbg(&pdev->dev, "could not request irq\n");
                goto err_irq;
index f54ece268c982d1dce13224c78efce9434dbffbb..264ad1c583abcc78ad04a8190edfffcfc4aacde5 100644 (file)
@@ -58,6 +58,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
 {
        struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
        struct device_node *np = pdev->dev.of_node;
+       int gpio;
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
@@ -66,7 +67,11 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
        if (of_get_property(np, "linux,open-drain", NULL))
                pdata->is_open_drain = 1;
 
-       pdata->pin = of_get_gpio(np, 0);
+       gpio = of_get_gpio(np, 0);
+       if (gpio < 0)
+               return gpio;
+       pdata->pin = gpio;
+
        pdata->ext_pullup_enable_pin = of_get_gpio(np, 1);
        pdev->dev.platform_data = pdata;
 
@@ -94,25 +99,27 @@ static int w1_gpio_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL);
+       master = devm_kzalloc(&pdev->dev, sizeof(struct w1_bus_master),
+                       GFP_KERNEL);
        if (!master) {
                dev_err(&pdev->dev, "Out of memory\n");
                return -ENOMEM;
        }
 
-       err = gpio_request(pdata->pin, "w1");
+       err = devm_gpio_request(&pdev->dev, pdata->pin, "w1");
        if (err) {
                dev_err(&pdev->dev, "gpio_request (pin) failed\n");
-               goto free_master;
+               return err;
        }
 
        if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
-               err = gpio_request_one(pdata->ext_pullup_enable_pin,
-                                      GPIOF_INIT_LOW, "w1 pullup");
+               err = devm_gpio_request_one(&pdev->dev,
+                               pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW,
+                               "w1 pullup");
                if (err < 0) {
                        dev_err(&pdev->dev, "gpio_request_one "
                                        "(ext_pullup_enable_pin) failed\n");
-                       goto free_gpio;
+                       return err;
                }
        }
 
@@ -130,7 +137,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
        err = w1_add_master_device(master);
        if (err) {
                dev_err(&pdev->dev, "w1_add_master device failed\n");
-               goto free_gpio_ext_pu;
+               return err;
        }
 
        if (pdata->enable_external_pullup)
@@ -142,16 +149,6 @@ static int w1_gpio_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, master);
 
        return 0;
-
- free_gpio_ext_pu:
-       if (gpio_is_valid(pdata->ext_pullup_enable_pin))
-               gpio_free(pdata->ext_pullup_enable_pin);
- free_gpio:
-       gpio_free(pdata->pin);
- free_master:
-       kfree(master);
-
-       return err;
 }
 
 static int w1_gpio_remove(struct platform_device *pdev)
@@ -166,8 +163,6 @@ static int w1_gpio_remove(struct platform_device *pdev)
                gpio_set_value(pdata->ext_pullup_enable_pin, 0);
 
        w1_remove_master_device(master);
-       gpio_free(pdata->pin);
-       kfree(master);
 
        return 0;
 }
index 38e92b770e91f224209dab2fc0e5543e8591bb65..3c0a74b3e9b15af5355c8619294805f59030f75d 100644 (file)
@@ -384,12 +384,14 @@ static ssize_t nodename_show(struct device *dev,
 {
        return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
 }
+static DEVICE_ATTR_RO(nodename);
 
 static ssize_t devtype_show(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
 }
+static DEVICE_ATTR_RO(devtype);
 
 static ssize_t modalias_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
@@ -397,14 +399,24 @@ static ssize_t modalias_show(struct device *dev,
        return sprintf(buf, "%s:%s\n", dev->bus->name,
                       to_xenbus_device(dev)->devicetype);
 }
+static DEVICE_ATTR_RO(modalias);
 
-struct device_attribute xenbus_dev_attrs[] = {
-       __ATTR_RO(nodename),
-       __ATTR_RO(devtype),
-       __ATTR_RO(modalias),
-       __ATTR_NULL
+static struct attribute *xenbus_dev_attrs[] = {
+       &dev_attr_nodename.attr,
+       &dev_attr_devtype.attr,
+       &dev_attr_modalias.attr,
+       NULL,
 };
-EXPORT_SYMBOL_GPL(xenbus_dev_attrs);
+
+static const struct attribute_group xenbus_dev_group = {
+       .attrs = xenbus_dev_attrs,
+};
+
+const struct attribute_group *xenbus_dev_groups[] = {
+       &xenbus_dev_group,
+       NULL,
+};
+EXPORT_SYMBOL_GPL(xenbus_dev_groups);
 
 int xenbus_probe_node(struct xen_bus_type *bus,
                      const char *type,
index 146f857a36f83b5a2f4646424c1251a23abf1b07..1085ec294a1987a5620b24c4a2e120528d13cac0 100644 (file)
@@ -54,7 +54,7 @@ enum xenstore_init {
        XS_LOCAL,
 };
 
-extern struct device_attribute xenbus_dev_attrs[];
+extern const struct attribute_group *xenbus_dev_groups[];
 
 extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
 extern int xenbus_dev_probe(struct device *_dev);
index 998bbbab816be6c59a4a71b8b183a2a39f053aff..5125dce11a6083da92fc5942a09c2aa786f181d8 100644 (file)
@@ -200,7 +200,7 @@ static struct xen_bus_type xenbus_backend = {
                .probe          = xenbus_dev_probe,
                .remove         = xenbus_dev_remove,
                .shutdown       = xenbus_dev_shutdown,
-               .dev_attrs      = xenbus_dev_attrs,
+               .dev_groups     = xenbus_dev_groups,
        },
 };
 
index 34b20bfa4e8c3cf813194a45c4545e01c1d88eb1..129bf84c19ec999f5e239c1b7168089955a29bec 100644 (file)
@@ -154,7 +154,7 @@ static struct xen_bus_type xenbus_frontend = {
                .probe          = xenbus_frontend_dev_probe,
                .remove         = xenbus_dev_remove,
                .shutdown       = xenbus_dev_shutdown,
-               .dev_attrs      = xenbus_dev_attrs,
+               .dev_groups     = xenbus_dev_groups,
 
                .pm             = &xenbus_pm_ops,
        },
index a9ea73d6dcf311b7703af1225fb71698da2a4fc3..2b7a032c37bc7b087e0fdb3129436c0b735ba809 100644 (file)
@@ -90,7 +90,7 @@ void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
 
        v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
                                                &v9fs_cache_session_index_def,
-                                               v9ses);
+                                               v9ses, true);
        p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
                 v9ses, v9ses->fscache);
 }
@@ -204,7 +204,7 @@ void v9fs_cache_inode_get_cookie(struct inode *inode)
        v9ses = v9fs_inode2v9ses(inode);
        v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
                                                  &v9fs_cache_inode_index_def,
-                                                 v9inode);
+                                                 v9inode, true);
 
        p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
                 inode, v9inode->fscache);
@@ -271,7 +271,7 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
        v9ses = v9fs_inode2v9ses(inode);
        v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
                                                  &v9fs_cache_inode_index_def,
-                                                 v9inode);
+                                                 v9inode, true);
        p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
                 inode, old, v9inode->fscache);
 
index 3c090b7555ea8f3a095e0504a69cbd696db13ab5..ca0a3cf93791879578121b842891e97e5b0ffb1e 100644 (file)
@@ -179,7 +179,7 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
        /* put it up for caching (this never returns an error) */
        cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
                                             &afs_cell_cache_index_def,
-                                            cell);
+                                            cell, true);
 #endif
 
        /* add to the cell lists */
index 789bc253b5f63c2d3c9abfdd216e0778b140a765..ce25d755b7aa16d68b131dd4944898e560e0d8e3 100644 (file)
@@ -259,7 +259,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
 #ifdef CONFIG_AFS_FSCACHE
        vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
                                              &afs_vnode_cache_index_def,
-                                             vnode);
+                                             vnode, true);
 #endif
 
        ret = afs_inode_map_status(vnode, key);
index 57bcb1596530892e91ebf39fd12abfee0fe2dead..b6df2e83809f4ac81ed5b3d02f944ac7f32d9de8 100644 (file)
@@ -308,7 +308,8 @@ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl,
        /* see if we have an in-cache copy (will set vl->valid if there is) */
 #ifdef CONFIG_AFS_FSCACHE
        vl->cache = fscache_acquire_cookie(vl->cell->cache,
-                                          &afs_vlocation_cache_index_def, vl);
+                                          &afs_vlocation_cache_index_def, vl,
+                                          true);
 #endif
 
        if (vl->valid) {
index 401eeb21869ff0657b966f4753fd951bc7897333..2b607257820c8ed7b383e486f3a7870052974ae4 100644 (file)
@@ -131,7 +131,7 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
 #ifdef CONFIG_AFS_FSCACHE
        volume->cache = fscache_acquire_cookie(vlocation->cache,
                                               &afs_volume_cache_index_def,
-                                              volume);
+                                              volume, true);
 #endif
        afs_get_vlocation(vlocation);
        volume->vlocation = vlocation;
index 43eb5592cdea83c83df854a489edea79d076cfda..00baf1419989f804ad56f1f27ed633f86d2d6628 100644 (file)
@@ -270,7 +270,7 @@ static void cachefiles_drop_object(struct fscache_object *_object)
 #endif
 
        /* delete retired objects */
-       if (test_bit(FSCACHE_COOKIE_RETIRED, &object->fscache.cookie->flags) &&
+       if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) &&
            _object != cache->cache.fsdef
            ) {
                _debug("- retire object OBJ%x", object->fscache.debug_id);
index 6bfe65e0b03831280b0e66e96d616be9ee55e6b1..7db2e6ca4b8f0b07146c137a80e24567a03d3e43 100644 (file)
@@ -68,7 +68,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
 {
        fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index,
                                              &ceph_fscache_fsid_object_def,
-                                             fsc);
+                                             fsc, true);
 
        if (fsc->fscache == NULL) {
                pr_err("Unable to resgister fsid: %p fscache cookie", fsc);
@@ -204,7 +204,7 @@ void ceph_fscache_register_inode_cookie(struct ceph_fs_client* fsc,
 
        ci->fscache = fscache_acquire_cookie(fsc->fscache,
                                             &ceph_fscache_inode_object_def,
-                                            ci);
+                                            ci, true);
 done:
        mutex_unlock(&inode->i_mutex);
 
index 52b6f6c26bfcbe37d2994ba0fe3fa0b3779016d4..26b1c1dc93f6ef20c8c3d23fc57db320478cc923 100644 (file)
@@ -278,6 +278,8 @@ struct smb_version_operations {
        /* set attributes */
        int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *,
                             const unsigned int);
+       int (*set_compression)(const unsigned int, struct cifs_tcon *,
+                              struct cifsFileInfo *);
        /* check if we can send an echo or nor */
        bool (*can_echo)(struct TCP_Server_Info *);
        /* send echo request */
@@ -620,11 +622,34 @@ set_credits(struct TCP_Server_Info *server, const int val)
 }
 
 static inline __u64
-get_next_mid(struct TCP_Server_Info *server)
+get_next_mid64(struct TCP_Server_Info *server)
 {
        return server->ops->get_next_mid(server);
 }
 
+static inline __le16
+get_next_mid(struct TCP_Server_Info *server)
+{
+       __u16 mid = get_next_mid64(server);
+       /*
+        * The value in the SMB header should be little endian for easy
+        * on-the-wire decoding.
+        */
+       return cpu_to_le16(mid);
+}
+
+static inline __u16
+get_mid(const struct smb_hdr *smb)
+{
+       return le16_to_cpu(smb->Mid);
+}
+
+static inline bool
+compare_mid(__u16 mid, const struct smb_hdr *smb)
+{
+       return mid == le16_to_cpu(smb->Mid);
+}
+
 /*
  * When the server supports very large reads and writes via POSIX extensions,
  * we can allow up to 2^24-1, minus the size of a READ/WRITE_AND_X header, not
@@ -828,6 +853,8 @@ struct cifs_tcon {
        __u32 maximal_access;
        __u32 vol_serial_number;
        __le64 vol_create_time;
+       __u32 ss_flags;         /* sector size flags */
+       __u32 perf_sector_size; /* best sector size for perf */
 #endif /* CONFIG_CIFS_SMB2 */
 #ifdef CONFIG_CIFS_FSCACHE
        u64 resource_id;                /* server resource id */
index 08f9dfb1a894402eec24579717f6c48d4d92f695..9e5ee34de98633b0d894ddadfdf86cd5bd963159 100644 (file)
@@ -428,7 +428,7 @@ struct smb_hdr {
        __u16 Tid;
        __le16 Pid;
        __u16 Uid;
-       __u16 Mid;
+       __le16 Mid;
        __u8 WordCount;
 } __attribute__((packed));
 
@@ -1352,6 +1352,35 @@ typedef struct smb_com_transaction_ioctl_req {
        __u8 Data[1];
 } __attribute__((packed)) TRANSACT_IOCTL_REQ;
 
+typedef struct smb_com_transaction_compr_ioctl_req {
+       struct smb_hdr hdr;     /* wct = 23 */
+       __u8 MaxSetupCount;
+       __u16 Reserved;
+       __le32 TotalParameterCount;
+       __le32 TotalDataCount;
+       __le32 MaxParameterCount;
+       __le32 MaxDataCount;
+       __le32 ParameterCount;
+       __le32 ParameterOffset;
+       __le32 DataCount;
+       __le32 DataOffset;
+       __u8 SetupCount; /* four setup words follow subcommand */
+       /* SNIA spec incorrectly included spurious pad here */
+       __le16 SubCommand; /* 2 = IOCTL/FSCTL */
+       __le32 FunctionCode;
+       __u16 Fid;
+       __u8 IsFsctl;  /* 1 = File System Control 0 = device control (IOCTL) */
+       __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */
+       __le16 ByteCount;
+       __u8 Pad[3];
+       __le16 compression_state;  /* See below for valid flags */
+} __attribute__((packed)) TRANSACT_COMPR_IOCTL_REQ;
+
+/* compression state flags */
+#define COMPRESSION_FORMAT_NONE                0x0000
+#define COMPRESSION_FORMAT_DEFAULT     0x0001
+#define COMPRESSION_FORMAT_LZNT1       0x0002
+
 typedef struct smb_com_transaction_ioctl_rsp {
        struct smb_hdr hdr;     /* wct = 19 */
        __u8 Reserved[3];
@@ -2215,6 +2244,9 @@ typedef struct {
        __le32 DeviceCharacteristics;
 } __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */
 
+/* minimum includes first three fields, and empty FS Name */
+#define MIN_FS_ATTR_INFO_SIZE 12
+
 typedef struct {
        __le32 Attributes;
        __le32 MaxPathNameComponentLength;
index b5ec2a268f560c77424744c55266480f25f3c8bb..aa3397620342d20beba92abc732845273d3663ca 100644 (file)
@@ -360,6 +360,8 @@ extern int CIFSSMBUnixQuerySymLink(const unsigned int xid,
 extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
                               __u16 fid, char **symlinkinfo,
                               const struct nls_table *nls_codepage);
+extern int CIFSSMB_set_compression(const unsigned int xid,
+                                  struct cifs_tcon *tcon, __u16 fid);
 extern int CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
                        const char *fileName, const int disposition,
                        const int access_flags, const int omode,
index ccd31ab815d4b2404d58a0e42f3ad606d35b87f5..93b29474714a0cdba1356c85c049e874dbc195dd 100644 (file)
@@ -3199,6 +3199,60 @@ qreparse_out:
        return rc;
 }
 
+int
+CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+                   __u16 fid)
+{
+       int rc = 0;
+       int bytes_returned;
+       struct smb_com_transaction_compr_ioctl_req *pSMB;
+       struct smb_com_transaction_ioctl_rsp *pSMBr;
+
+       cifs_dbg(FYI, "Set compression for %u\n", fid);
+       rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
+
+       pSMB->TotalParameterCount = 0;
+       pSMB->TotalDataCount = __constant_cpu_to_le32(2);
+       pSMB->MaxParameterCount = 0;
+       pSMB->MaxDataCount = 0;
+       pSMB->MaxSetupCount = 4;
+       pSMB->Reserved = 0;
+       pSMB->ParameterOffset = 0;
+       pSMB->DataCount = __constant_cpu_to_le32(2);
+       pSMB->DataOffset =
+               cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
+                               compression_state) - 4);  /* 84 */
+       pSMB->SetupCount = 4;
+       pSMB->SubCommand = __constant_cpu_to_le16(NT_TRANSACT_IOCTL);
+       pSMB->ParameterCount = 0;
+       pSMB->FunctionCode = __constant_cpu_to_le32(FSCTL_SET_COMPRESSION);
+       pSMB->IsFsctl = 1; /* FSCTL */
+       pSMB->IsRootFlag = 0;
+       pSMB->Fid = fid; /* file handle always le */
+       /* 3 byte pad, followed by 2 byte compress state */
+       pSMB->ByteCount = __constant_cpu_to_le16(5);
+       inc_rfc1001_len(pSMB, 5);
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc)
+               cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
+
+       cifs_buf_release(pSMB);
+
+       /*
+        * Note: On -EAGAIN error only caller can retry on handle based calls
+        * since file handle passed in no longer valid.
+        */
+       return rc;
+}
+
+
 #ifdef CONFIG_CIFS_POSIX
 
 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
index a279ffc0bc29577ed447319467b2e92248f09149..62a55147400a50adcf4c7a37756add3cc5410325 100644 (file)
@@ -2242,6 +2242,8 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
 
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+               if (ses->status == CifsExiting)
+                       continue;
                if (!match_session(ses, vol))
                        continue;
                ++ses->ses_count;
@@ -2255,24 +2257,37 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
 static void
 cifs_put_smb_ses(struct cifs_ses *ses)
 {
-       unsigned int xid;
+       unsigned int rc, xid;
        struct TCP_Server_Info *server = ses->server;
 
        cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
+
        spin_lock(&cifs_tcp_ses_lock);
+       if (ses->status == CifsExiting) {
+               spin_unlock(&cifs_tcp_ses_lock);
+               return;
+       }
        if (--ses->ses_count > 0) {
                spin_unlock(&cifs_tcp_ses_lock);
                return;
        }
-
-       list_del_init(&ses->smb_ses_list);
+       if (ses->status == CifsGood)
+               ses->status = CifsExiting;
        spin_unlock(&cifs_tcp_ses_lock);
 
-       if (ses->status == CifsGood && server->ops->logoff) {
+       if (ses->status == CifsExiting && server->ops->logoff) {
                xid = get_xid();
-               server->ops->logoff(xid, ses);
+               rc = server->ops->logoff(xid, ses);
+               if (rc)
+                       cifs_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
+                               __func__, rc);
                _free_xid(xid);
        }
+
+       spin_lock(&cifs_tcp_ses_lock);
+       list_del_init(&ses->smb_ses_list);
+       spin_unlock(&cifs_tcp_ses_lock);
+
        sesInfoFree(ses);
        cifs_put_tcp_session(server);
 }
index b3258f35e88a5126d61b463bb4d96387e5dcba42..8d4b7bc8ae914edf292b16da534d700f6d870b1e 100644 (file)
@@ -27,7 +27,7 @@ void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
 {
        server->fscache =
                fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
-                               &cifs_fscache_server_index_def, server);
+                               &cifs_fscache_server_index_def, server, true);
        cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
                 __func__, server, server->fscache);
 }
@@ -46,7 +46,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
 
        tcon->fscache =
                fscache_acquire_cookie(server->fscache,
-                               &cifs_fscache_super_index_def, tcon);
+                               &cifs_fscache_super_index_def, tcon, true);
        cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
                 __func__, server->fscache, tcon->fscache);
 }
@@ -69,7 +69,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
                cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
-                               &cifs_fscache_inode_object_def, cifsi);
+                               &cifs_fscache_inode_object_def, cifsi, true);
                cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n",
                         __func__, tcon->fscache, cifsi->fscache);
        }
@@ -119,7 +119,7 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode)
                cifsi->fscache = fscache_acquire_cookie(
                                        cifs_sb_master_tcon(cifs_sb)->fscache,
                                        &cifs_fscache_inode_object_def,
-                                       cifsi);
+                                       cifsi, true);
                cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n",
                         __func__, cifsi->fscache, old);
        }
index 3e0845585853e52c3f6be35c442b55991d71c5c2..ba54bf6ab1165d6db4b587a898554dd8dc388d2d 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with io control
  *
- *   Copyright (C) International Business Machines  Corp., 2005,2007
+ *   Copyright (C) International Business Machines  Corp., 2005,2013
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -34,13 +34,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
        int rc = -ENOTTY; /* strange error - but the precedent */
        unsigned int xid;
        struct cifs_sb_info *cifs_sb;
-#ifdef CONFIG_CIFS_POSIX
        struct cifsFileInfo *pSMBFile = filep->private_data;
        struct cifs_tcon *tcon;
        __u64   ExtAttrBits = 0;
-       __u64   ExtAttrMask = 0;
        __u64   caps;
-#endif /* CONFIG_CIFS_POSIX */
 
        xid = get_xid();
 
@@ -49,13 +46,14 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
        cifs_sb = CIFS_SB(inode->i_sb);
 
        switch (command) {
-#ifdef CONFIG_CIFS_POSIX
                case FS_IOC_GETFLAGS:
                        if (pSMBFile == NULL)
                                break;
                        tcon = tlink_tcon(pSMBFile->tlink);
                        caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
+#ifdef CONFIG_CIFS_POSIX
                        if (CIFS_UNIX_EXTATTR_CAP & caps) {
+                               __u64   ExtAttrMask = 0;
                                rc = CIFSGetExtAttr(xid, tcon,
                                                    pSMBFile->fid.netfid,
                                                    &ExtAttrBits, &ExtAttrMask);
@@ -63,29 +61,50 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                                        rc = put_user(ExtAttrBits &
                                                FS_FL_USER_VISIBLE,
                                                (int __user *)arg);
+                               if (rc != EOPNOTSUPP)
+                                       break;
+                       }
+#endif /* CONFIG_CIFS_POSIX */
+                       rc = 0;
+                       if (CIFS_I(inode)->cifsAttrs & ATTR_COMPRESSED) {
+                               /* add in the compressed bit */
+                               ExtAttrBits = FS_COMPR_FL;
+                               rc = put_user(ExtAttrBits & FS_FL_USER_VISIBLE,
+                                             (int __user *)arg);
                        }
                        break;
-
                case FS_IOC_SETFLAGS:
                        if (pSMBFile == NULL)
                                break;
                        tcon = tlink_tcon(pSMBFile->tlink);
                        caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
-                       if (CIFS_UNIX_EXTATTR_CAP & caps) {
-                               if (get_user(ExtAttrBits, (int __user *)arg)) {
-                                       rc = -EFAULT;
-                                       break;
-                               }
-                               /*
-                                * rc = CIFSGetExtAttr(xid, tcon,
-                                *                     pSMBFile->fid.netfid,
-                                *                     extAttrBits,
-                                *                     &ExtAttrMask);
-                                */
+
+                       if (get_user(ExtAttrBits, (int __user *)arg)) {
+                               rc = -EFAULT;
+                               break;
+                       }
+
+                       /*
+                        * if (CIFS_UNIX_EXTATTR_CAP & caps)
+                        *      rc = CIFSSetExtAttr(xid, tcon,
+                        *                     pSMBFile->fid.netfid,
+                        *                     extAttrBits,
+                        *                     &ExtAttrMask);
+                        * if (rc != EOPNOTSUPP)
+                        *      break;
+                        */
+
+                       /* Currently only flag we can set is compressed flag */
+                       if ((ExtAttrBits & FS_COMPR_FL) == 0)
+                               break;
+
+                       /* Try to set compress flag */
+                       if (tcon->ses->server->ops->set_compression) {
+                               rc = tcon->ses->server->ops->set_compression(
+                                                       xid, tcon, pSMBFile);
+                               cifs_dbg(FYI, "set compress flag rc %d\n", rc);
                        }
-                       cifs_dbg(FYI, "set flags not implemented yet\n");
                        break;
-#endif /* CONFIG_CIFS_POSIX */
                default:
                        cifs_dbg(FYI, "unsupported ioctl\n");
                        break;
index 138a011633fe8ae4feabb965530c99eda25e1226..2f9f3790679d9137cddc89d141b0be434716a42a 100644 (file)
@@ -278,7 +278,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
 }
 
 static int
-check_smb_hdr(struct smb_hdr *smb, __u16 mid)
+check_smb_hdr(struct smb_hdr *smb)
 {
        /* does it have the right SMB "signature" ? */
        if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) {
@@ -287,13 +287,6 @@ check_smb_hdr(struct smb_hdr *smb, __u16 mid)
                return 1;
        }
 
-       /* Make sure that message ids match */
-       if (mid != smb->Mid) {
-               cifs_dbg(VFS, "Mids do not match. received=%u expected=%u\n",
-                        smb->Mid, mid);
-               return 1;
-       }
-
        /* if it's a response then accept */
        if (smb->Flags & SMBFLG_RESPONSE)
                return 0;
@@ -302,7 +295,8 @@ check_smb_hdr(struct smb_hdr *smb, __u16 mid)
        if (smb->Command == SMB_COM_LOCKING_ANDX)
                return 0;
 
-       cifs_dbg(VFS, "Server sent request, not response. mid=%u\n", smb->Mid);
+       cifs_dbg(VFS, "Server sent request, not response. mid=%u\n",
+                get_mid(smb));
        return 1;
 }
 
@@ -310,7 +304,6 @@ int
 checkSMB(char *buf, unsigned int total_read)
 {
        struct smb_hdr *smb = (struct smb_hdr *)buf;
-       __u16 mid = smb->Mid;
        __u32 rfclen = be32_to_cpu(smb->smb_buf_length);
        __u32 clc_len;  /* calculated length */
        cifs_dbg(FYI, "checkSMB Length: 0x%x, smb_buf_length: 0x%x\n",
@@ -348,7 +341,7 @@ checkSMB(char *buf, unsigned int total_read)
        }
 
        /* otherwise, there is enough to get to the BCC */
-       if (check_smb_hdr(smb, mid))
+       if (check_smb_hdr(smb))
                return -EIO;
        clc_len = smbCalcSize(smb);
 
@@ -359,6 +352,7 @@ checkSMB(char *buf, unsigned int total_read)
        }
 
        if (4 + rfclen != clc_len) {
+               __u16 mid = get_mid(smb);
                /* check if bcc wrapped around for large read responses */
                if ((rfclen > 64 * 1024) && (rfclen > clc_len)) {
                        /* check if lengths match mod 64K */
@@ -366,11 +360,11 @@ checkSMB(char *buf, unsigned int total_read)
                                return 0; /* bcc wrapped */
                }
                cifs_dbg(FYI, "Calculated size %u vs length %u mismatch for mid=%u\n",
-                        clc_len, 4 + rfclen, smb->Mid);
+                        clc_len, 4 + rfclen, mid);
 
                if (4 + rfclen < clc_len) {
                        cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n",
-                                rfclen, smb->Mid);
+                                rfclen, mid);
                        return -EIO;
                } else if (rfclen > clc_len + 512) {
                        /*
@@ -383,7 +377,7 @@ checkSMB(char *buf, unsigned int total_read)
                         * data to 512 bytes.
                         */
                        cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for mid=%u\n",
-                                rfclen, smb->Mid);
+                                rfclen, mid);
                        return -EIO;
                }
        }
index 8233b174de3d62c6e5a3223919e83db8f7c57016..384cffe42850cdbdb4365e0ff6d6e8eb1a1fbb87 100644 (file)
@@ -67,7 +67,7 @@ send_nt_cancel(struct TCP_Server_Info *server, void *buf,
        mutex_unlock(&server->srv_mutex);
 
        cifs_dbg(FYI, "issued NT_CANCEL for mid %u, rc = %d\n",
-                in_buf->Mid, rc);
+                get_mid(in_buf), rc);
 
        return rc;
 }
@@ -101,7 +101,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
 
        spin_lock(&GlobalMid_Lock);
        list_for_each_entry(mid, &server->pending_mid_q, qhead) {
-               if (mid->mid == buf->Mid &&
+               if (compare_mid(mid->mid, buf) &&
                    mid->mid_state == MID_REQUEST_SUBMITTED &&
                    le16_to_cpu(mid->command) == buf->Command) {
                        spin_unlock(&GlobalMid_Lock);
@@ -806,6 +806,13 @@ out:
        return rc;
 }
 
+static int
+cifs_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+                  struct cifsFileInfo *cfile)
+{
+       return CIFSSMB_set_compression(xid, tcon, cfile->fid.netfid);
+}
+
 static int
 cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
                     const char *path, struct cifs_sb_info *cifs_sb,
@@ -956,6 +963,7 @@ struct smb_version_operations smb1_operations = {
        .set_path_size = CIFSSMBSetEOF,
        .set_file_size = CIFSSMBSetFileSize,
        .set_file_info = smb_set_file_info,
+       .set_compression = cifs_set_compression,
        .echo = CIFSSMBEcho,
        .mkdir = CIFSSMBMkDir,
        .mkdir_setinfo = cifs_mkdir_setinfo,
index 861b332141440c35c3a1b56ec1587b0166399006..c571be8cb76ef418ffcca63634fde5e3d39294f5 100644 (file)
@@ -209,6 +209,94 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        return rsize;
 }
 
+#ifdef CONFIG_CIFS_STATS2
+static int
+SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
+{
+       int rc;
+       unsigned int ret_data_len = 0;
+       struct network_interface_info_ioctl_rsp *out_buf;
+
+       rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
+                       FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */,
+                       NULL /* no data input */, 0 /* no data input */,
+                       (char **)&out_buf, &ret_data_len);
+
+       if ((rc == 0)  && (ret_data_len > 0)) {
+               /* Dump info on first interface */
+               cifs_dbg(FYI, "Adapter Capability 0x%x\t",
+                       le32_to_cpu(out_buf->Capability));
+               cifs_dbg(FYI, "Link Speed %lld\n",
+                       le64_to_cpu(out_buf->LinkSpeed));
+       } else
+               cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
+
+       return rc;
+}
+#endif /* STATS2 */
+
+static void
+smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
+{
+       int rc;
+       __le16 srch_path = 0; /* Null - open root of share */
+       u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+       struct cifs_open_parms oparms;
+       struct cifs_fid fid;
+
+       oparms.tcon = tcon;
+       oparms.desired_access = FILE_READ_ATTRIBUTES;
+       oparms.disposition = FILE_OPEN;
+       oparms.create_options = 0;
+       oparms.fid = &fid;
+       oparms.reconnect = false;
+
+       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
+       if (rc)
+               return;
+
+#ifdef CONFIG_CIFS_STATS2
+       SMB3_request_interfaces(xid, tcon);
+#endif /* STATS2 */
+
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_ATTRIBUTE_INFORMATION);
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_DEVICE_INFORMATION);
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
+       SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+       return;
+}
+
+static void
+smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
+{
+       int rc;
+       __le16 srch_path = 0; /* Null - open root of share */
+       u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+       struct cifs_open_parms oparms;
+       struct cifs_fid fid;
+
+       oparms.tcon = tcon;
+       oparms.desired_access = FILE_READ_ATTRIBUTES;
+       oparms.disposition = FILE_OPEN;
+       oparms.create_options = 0;
+       oparms.fid = &fid;
+       oparms.reconnect = false;
+
+       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
+       if (rc)
+               return;
+
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_ATTRIBUTE_INFORMATION);
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_DEVICE_INFORMATION);
+       SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+       return;
+}
+
 static int
 smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
                        struct cifs_sb_info *cifs_sb, const char *full_path)
@@ -304,7 +392,19 @@ smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
                seq_puts(m, " ASYMMETRIC,");
        if (tcon->capabilities == 0)
                seq_puts(m, " None");
+       if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE)
+               seq_puts(m, " Aligned,");
+       if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE)
+               seq_puts(m, " Partition Aligned,");
+       if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY)
+               seq_puts(m, " SSD,");
+       if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED)
+               seq_puts(m, " TRIM-support,");
+
        seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
+       if (tcon->perf_sector_size)
+               seq_printf(m, "\tOptimal sector size: 0x%x",
+                          tcon->perf_sector_size);
 }
 
 static void
@@ -445,6 +545,14 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
                            cfile->fid.volatile_fid, cfile->pid, &eof);
 }
 
+static int
+smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+                  struct cifsFileInfo *cfile)
+{
+       return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid,
+                           cfile->fid.volatile_fid);
+}
+
 static int
 smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
                     const char *path, struct cifs_sb_info *cifs_sb,
@@ -865,6 +973,7 @@ struct smb_version_operations smb20_operations = {
        .logoff = SMB2_logoff,
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
+       .qfs_tcon = smb2_qfs_tcon,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
@@ -874,6 +983,7 @@ struct smb_version_operations smb20_operations = {
        .set_path_size = smb2_set_path_size,
        .set_file_size = smb2_set_file_size,
        .set_file_info = smb2_set_file_info,
+       .set_compression = smb2_set_compression,
        .mkdir = smb2_mkdir,
        .mkdir_setinfo = smb2_mkdir_setinfo,
        .rmdir = smb2_rmdir,
@@ -936,6 +1046,7 @@ struct smb_version_operations smb21_operations = {
        .logoff = SMB2_logoff,
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
+       .qfs_tcon = smb2_qfs_tcon,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
@@ -945,6 +1056,7 @@ struct smb_version_operations smb21_operations = {
        .set_path_size = smb2_set_path_size,
        .set_file_size = smb2_set_file_size,
        .set_file_info = smb2_set_file_info,
+       .set_compression = smb2_set_compression,
        .mkdir = smb2_mkdir,
        .mkdir_setinfo = smb2_mkdir_setinfo,
        .rmdir = smb2_rmdir,
@@ -1008,6 +1120,7 @@ struct smb_version_operations smb30_operations = {
        .logoff = SMB2_logoff,
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
+       .qfs_tcon = smb3_qfs_tcon,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
@@ -1017,6 +1130,7 @@ struct smb_version_operations smb30_operations = {
        .set_path_size = smb2_set_path_size,
        .set_file_size = smb2_set_file_size,
        .set_file_info = smb2_set_file_info,
+       .set_compression = smb2_set_compression,
        .mkdir = smb2_mkdir,
        .mkdir_setinfo = smb2_mkdir_setinfo,
        .rmdir = smb2_rmdir,
index edccb5252462b6b465d3d71cb7d3de20e8d2be9a..8ab05b0d6778f99343d5740ff037ccbfad7bbef8 100644 (file)
@@ -1137,6 +1137,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 
        cifs_dbg(FYI, "SMB2 IOCTL\n");
 
+       *out_data = NULL;
        /* zero out returned data len, in case of error */
        if (plen)
                *plen = 0;
@@ -1182,11 +1183,23 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
                req->Flags = 0;
 
        iov[0].iov_base = (char *)req;
-       /* 4 for rfc1002 length field */
-       iov[0].iov_len = get_rfc1002_length(req) + 4;
 
-       if (indatalen)
-               inc_rfc1001_len(req, indatalen);
+       /*
+        * If no input data, the size of ioctl struct in
+        * protocol spec still includes a 1 byte data buffer,
+        * but if input data passed to ioctl, we do not
+        * want to double count this, so we do not send
+        * the dummy one byte of data in iovec[0] if sending
+        * input data (in iovec[1]). We also must add 4 bytes
+        * in first iovec to allow for rfc1002 length field.
+        */
+
+       if (indatalen) {
+               iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
+               inc_rfc1001_len(req, indatalen - 1);
+       } else
+               iov[0].iov_len = get_rfc1002_length(req) + 4;
+
 
        rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
        rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
@@ -1234,6 +1247,33 @@ ioctl_exit:
        return rc;
 }
 
+/*
+ *   Individual callers to ioctl worker function follow
+ */
+
+int
+SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+                    u64 persistent_fid, u64 volatile_fid)
+{
+       int rc;
+       char *res_key = NULL;
+       struct  compress_ioctl fsctl_input;
+       char *ret_data = NULL;
+
+       fsctl_input.CompressionState =
+                       __constant_cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
+
+       rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
+                       FSCTL_SET_COMPRESSION, true /* is_fsctl */,
+                       (char *)&fsctl_input /* data input */,
+                       2 /* in data len */, &ret_data /* out data */, NULL);
+
+       cifs_dbg(FYI, "set compression rc %d\n", rc);
+       kfree(res_key);
+
+       return rc;
+}
+
 int
 SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
           u64 persistent_fid, u64 volatile_fid)
@@ -2299,7 +2339,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
        rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0);
        if (rc) {
                cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
-               goto qinf_exit;
+               goto qfsinf_exit;
        }
        rsp = (struct smb2_query_info_rsp *)iov.iov_base;
 
@@ -2311,7 +2351,70 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
        if (!rc)
                copy_fs_info_to_kstatfs(info, fsdata);
 
-qinf_exit:
+qfsinf_exit:
+       free_rsp_buf(resp_buftype, iov.iov_base);
+       return rc;
+}
+
+int
+SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
+             u64 persistent_fid, u64 volatile_fid, int level)
+{
+       struct smb2_query_info_rsp *rsp = NULL;
+       struct kvec iov;
+       int rc = 0;
+       int resp_buftype, max_len, min_len;
+       struct cifs_ses *ses = tcon->ses;
+       unsigned int rsp_len, offset;
+
+       if (level == FS_DEVICE_INFORMATION) {
+               max_len = sizeof(FILE_SYSTEM_DEVICE_INFO);
+               min_len = sizeof(FILE_SYSTEM_DEVICE_INFO);
+       } else if (level == FS_ATTRIBUTE_INFORMATION) {
+               max_len = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO);
+               min_len = MIN_FS_ATTR_INFO_SIZE;
+       } else if (level == FS_SECTOR_SIZE_INFORMATION) {
+               max_len = sizeof(struct smb3_fs_ss_info);
+               min_len = sizeof(struct smb3_fs_ss_info);
+       } else {
+               cifs_dbg(FYI, "Invalid qfsinfo level %d\n", level);
+               return -EINVAL;
+       }
+
+       rc = build_qfs_info_req(&iov, tcon, level, max_len,
+                               persistent_fid, volatile_fid);
+       if (rc)
+               return rc;
+
+       rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0);
+       if (rc) {
+               cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
+               goto qfsattr_exit;
+       }
+       rsp = (struct smb2_query_info_rsp *)iov.iov_base;
+
+       rsp_len = le32_to_cpu(rsp->OutputBufferLength);
+       offset = le16_to_cpu(rsp->OutputBufferOffset);
+       rc = validate_buf(offset, rsp_len, &rsp->hdr, min_len);
+       if (rc)
+               goto qfsattr_exit;
+
+       if (level == FS_ATTRIBUTE_INFORMATION)
+               memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset
+                       + (char *)&rsp->hdr, min_t(unsigned int,
+                       rsp_len, max_len));
+       else if (level == FS_DEVICE_INFORMATION)
+               memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset
+                       + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO));
+       else if (level == FS_SECTOR_SIZE_INFORMATION) {
+               struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *)
+                       (4 /* RFC1001 len */ + offset + (char *)&rsp->hdr);
+               tcon->ss_flags = le32_to_cpu(ss_info->Flags);
+               tcon->perf_sector_size =
+                       le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf);
+       }
+
+qfsattr_exit:
        free_rsp_buf(resp_buftype, iov.iov_base);
        return rc;
 }
index b83d0118a7577256ee4084d8a3abce4666e90bb7..6183b1b7550f068a7f0628e7dab6e701e9ad0d2f 100644 (file)
@@ -569,6 +569,10 @@ struct network_interface_info_ioctl_rsp {
 
 #define NO_FILE_ID 0xFFFFFFFFFFFFFFFFULL /* general ioctls to srv not to file */
 
+struct compress_ioctl {
+       __le16 CompressionState; /* See cifspdu.h for possible flag values */
+} __packed;
+
 struct smb2_ioctl_req {
        struct smb2_hdr hdr;
        __le16 StructureSize;   /* Must be 57 */
@@ -584,7 +588,7 @@ struct smb2_ioctl_req {
        __le32 MaxOutputResponse;
        __le32 Flags;
        __u32  Reserved2;
-       char   Buffer[0];
+       __u8   Buffer[0];
 } __packed;
 
 struct smb2_ioctl_rsp {
@@ -870,14 +874,16 @@ struct smb2_lease_ack {
 
 /* File System Information Classes */
 #define FS_VOLUME_INFORMATION          1 /* Query */
-#define FS_LABEL_INFORMATION           2 /* Set */
+#define FS_LABEL_INFORMATION           2 /* Local only */
 #define FS_SIZE_INFORMATION            3 /* Query */
 #define FS_DEVICE_INFORMATION          4 /* Query */
 #define FS_ATTRIBUTE_INFORMATION       5 /* Query */
 #define FS_CONTROL_INFORMATION         6 /* Query, Set */
 #define FS_FULL_SIZE_INFORMATION       7 /* Query */
 #define FS_OBJECT_ID_INFORMATION       8 /* Query, Set */
-#define FS_DRIVER_PATH_INFORMATION     9 /* Query */
+#define FS_DRIVER_PATH_INFORMATION     9 /* Local only */
+#define FS_VOLUME_FLAGS_INFORMATION    10 /* Local only */
+#define FS_SECTOR_SIZE_INFORMATION     11 /* SMB3 or later. Query */
 
 struct smb2_fs_full_size_info {
        __le64 TotalAllocationUnits;
@@ -887,6 +893,22 @@ struct smb2_fs_full_size_info {
        __le32 BytesPerSector;
 } __packed;
 
+#define SSINFO_FLAGS_ALIGNED_DEVICE            0x00000001
+#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002
+#define SSINFO_FLAGS_NO_SEEK_PENALTY           0x00000004
+#define SSINFO_FLAGS_TRIM_ENABLED              0x00000008
+
+/* sector size info struct */
+struct smb3_fs_ss_info {
+       __le32 LogicalBytesPerSector;
+       __le32 PhysicalBytesPerSectorForAtomicity;
+       __le32 PhysicalBytesPerSectorForPerf;
+       __le32 FileSystemEffectivePhysicalBytesPerSectorForAtomicity;
+       __le32 Flags;
+       __le32 ByteOffsetForSectorAlignment;
+       __le32 ByteOffsetForPartitionAlignment;
+} __packed;
+
 /* partial list of QUERY INFO levels */
 #define FILE_DIRECTORY_INFORMATION     1
 #define FILE_FULL_DIRECTORY_INFORMATION 2
index e3fb4801ee969295484fd8324bec855fc9600e0b..313813e4c19b300357bfc5f6db225a3be85d1121 100644 (file)
@@ -142,12 +142,16 @@ extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon,
 extern int SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon,
                         u64 persistent_fid, u64 volatile_fid,
                         FILE_BASIC_INFO *buf);
+extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+                               u64 persistent_fid, u64 volatile_fid);
 extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
                             const u64 persistent_fid, const u64 volatile_fid,
                             const __u8 oplock_level);
 extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
                         u64 persistent_file_id, u64 volatile_file_id,
                         struct kstatfs *FSData);
+extern int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
+                        u64 persistent_file_id, u64 volatile_file_id, int lvl);
 extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
                     const __u64 persist_fid, const __u64 volatile_fid,
                     const __u32 pid, const __u64 length, const __u64 offset,
index 340abca3aa522f31490d0c483e76b60aa08d582a..59c748ce872f9bb190bf683c8fd49a38926e3b4d 100644 (file)
@@ -466,7 +466,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 static inline void
 smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr)
 {
-       hdr->MessageId = get_next_mid(server);
+       hdr->MessageId = get_next_mid64(server);
 }
 
 static struct mid_q_entry *
@@ -516,13 +516,19 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf,
                return -EAGAIN;
        }
 
-       if (ses->status != CifsGood) {
-               /* check if SMB2 session is bad because we are setting it up */
+       if (ses->status == CifsNew) {
                if ((buf->Command != SMB2_SESSION_SETUP) &&
                    (buf->Command != SMB2_NEGOTIATE))
                        return -EAGAIN;
                /* else ok - we are setting up session */
        }
+
+       if (ses->status == CifsExiting) {
+               if (buf->Command != SMB2_LOGOFF)
+                       return -EAGAIN;
+               /* else ok - we are shutting down the session */
+       }
+
        *mid = smb2_mid_entry_alloc(buf, ses->server);
        if (*mid == NULL)
                return -ENOMEM;
index 800b938e4061768f5f55ee414b45afa56e6d6aa2..b375709528467b5a1a74e078fae2aeb7813e1a1e 100644 (file)
@@ -58,7 +58,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
                return temp;
        else {
                memset(temp, 0, sizeof(struct mid_q_entry));
-               temp->mid = smb_buffer->Mid;    /* always LE */
+               temp->mid = get_mid(smb_buffer);
                temp->pid = current->pid;
                temp->command = cpu_to_le16(smb_buffer->Command);
                cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command);
@@ -431,13 +431,20 @@ static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
                return -EAGAIN;
        }
 
-       if (ses->status != CifsGood) {
-               /* check if SMB session is bad because we are setting it up */
+       if (ses->status == CifsNew) {
                if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
                        (in_buf->Command != SMB_COM_NEGOTIATE))
                        return -EAGAIN;
                /* else ok - we are setting up session */
        }
+
+       if (ses->status == CifsExiting) {
+               /* check if SMB session is bad because we are setting it up */
+               if (in_buf->Command != SMB_COM_LOGOFF_ANDX)
+                       return -EAGAIN;
+               /* else ok - we are shutting down session */
+       }
+
        *ppmidQ = AllocMidQEntry(in_buf, ses->server);
        if (*ppmidQ == NULL)
                return -ENOMEM;
index 20532cb0b06e7ebfc6887e87fd3781e65eb41999..ae6ebb88ceff15ccef25f26804532d8b89cbe45a 100644 (file)
@@ -542,7 +542,7 @@ EXPORT_SYMBOL(d_drop);
  * If ref is non-zero, then decrement the refcount too.
  * Returns dentry requiring refcount drop, or NULL if we're done.
  */
-static inline struct dentry *
+static struct dentry *
 dentry_kill(struct dentry *dentry, int unlock_on_failure)
        __releases(dentry->d_lock)
 {
@@ -630,7 +630,8 @@ repeat:
                        goto kill_it;
        }
 
-       dentry->d_flags |= DCACHE_REFERENCED;
+       if (!(dentry->d_flags & DCACHE_REFERENCED))
+               dentry->d_flags |= DCACHE_REFERENCED;
        dentry_lru_add(dentry);
 
        dentry->d_lockref.count--;
index b2a86e324aac05f7bf64b7ce0d0e2c30d91f3d68..29d7feb62cf7a5784a3828d9e6b19db4c30ceb01 100644 (file)
@@ -58,15 +58,16 @@ void fscache_cookie_init_once(void *_cookie)
 struct fscache_cookie *__fscache_acquire_cookie(
        struct fscache_cookie *parent,
        const struct fscache_cookie_def *def,
-       void *netfs_data)
+       void *netfs_data,
+       bool enable)
 {
        struct fscache_cookie *cookie;
 
        BUG_ON(!def);
 
-       _enter("{%s},{%s},%p",
+       _enter("{%s},{%s},%p,%u",
               parent ? (char *) parent->def->name : "<no-parent>",
-              def->name, netfs_data);
+              def->name, netfs_data, enable);
 
        fscache_stat(&fscache_n_acquires);
 
@@ -106,7 +107,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
        cookie->def             = def;
        cookie->parent          = parent;
        cookie->netfs_data      = netfs_data;
-       cookie->flags           = 0;
+       cookie->flags           = (1 << FSCACHE_COOKIE_NO_DATA_YET);
 
        /* radix tree insertion won't use the preallocation pool unless it's
         * told it may not wait */
@@ -124,16 +125,22 @@ struct fscache_cookie *__fscache_acquire_cookie(
                break;
        }
 
-       /* if the object is an index then we need do nothing more here - we
-        * create indices on disk when we need them as an index may exist in
-        * multiple caches */
-       if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
-               if (fscache_acquire_non_index_cookie(cookie) < 0) {
-                       atomic_dec(&parent->n_children);
-                       __fscache_cookie_put(cookie);
-                       fscache_stat(&fscache_n_acquires_nobufs);
-                       _leave(" = NULL");
-                       return NULL;
+       if (enable) {
+               /* if the object is an index then we need do nothing more here
+                * - we create indices on disk when we need them as an index
+                * may exist in multiple caches */
+               if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+                       if (fscache_acquire_non_index_cookie(cookie) == 0) {
+                               set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
+                       } else {
+                               atomic_dec(&parent->n_children);
+                               __fscache_cookie_put(cookie);
+                               fscache_stat(&fscache_n_acquires_nobufs);
+                               _leave(" = NULL");
+                               return NULL;
+                       }
+               } else {
+                       set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
                }
        }
 
@@ -143,6 +150,39 @@ struct fscache_cookie *__fscache_acquire_cookie(
 }
 EXPORT_SYMBOL(__fscache_acquire_cookie);
 
+/*
+ * Enable a cookie to permit it to accept new operations.
+ */
+void __fscache_enable_cookie(struct fscache_cookie *cookie,
+                            bool (*can_enable)(void *data),
+                            void *data)
+{
+       _enter("%p", cookie);
+
+       wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
+                        fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+
+       if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
+               goto out_unlock;
+
+       if (can_enable && !can_enable(data)) {
+               /* The netfs decided it didn't want to enable after all */
+       } else if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+               /* Wait for outstanding disablement to complete */
+               __fscache_wait_on_invalidate(cookie);
+
+               if (fscache_acquire_non_index_cookie(cookie) == 0)
+                       set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
+       } else {
+               set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
+       }
+
+out_unlock:
+       clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
+       wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
+}
+EXPORT_SYMBOL(__fscache_enable_cookie);
+
 /*
  * acquire a non-index cookie
  * - this must make sure the index chain is instantiated and instantiate the
@@ -157,7 +197,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
 
        _enter("");
 
-       cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE;
+       set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
 
        /* now we need to see whether the backing objects for this cookie yet
         * exist, if not there'll be nothing to search */
@@ -180,9 +220,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
 
        _debug("cache %s", cache->tag->name);
 
-       cookie->flags =
-               (1 << FSCACHE_COOKIE_LOOKING_UP) |
-               (1 << FSCACHE_COOKIE_NO_DATA_YET);
+       set_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
 
        /* ask the cache to allocate objects for this cookie and its parent
         * chain */
@@ -398,7 +436,8 @@ void __fscache_invalidate(struct fscache_cookie *cookie)
        if (!hlist_empty(&cookie->backing_objects)) {
                spin_lock(&cookie->lock);
 
-               if (!hlist_empty(&cookie->backing_objects) &&
+               if (fscache_cookie_enabled(cookie) &&
+                   !hlist_empty(&cookie->backing_objects) &&
                    !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING,
                                      &cookie->flags)) {
                        object = hlist_entry(cookie->backing_objects.first,
@@ -452,10 +491,14 @@ void __fscache_update_cookie(struct fscache_cookie *cookie)
 
        spin_lock(&cookie->lock);
 
-       /* update the index entry on disk in each cache backing this cookie */
-       hlist_for_each_entry(object,
-                            &cookie->backing_objects, cookie_link) {
-               fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
+       if (fscache_cookie_enabled(cookie)) {
+               /* update the index entry on disk in each cache backing this
+                * cookie.
+                */
+               hlist_for_each_entry(object,
+                                    &cookie->backing_objects, cookie_link) {
+                       fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
+               }
        }
 
        spin_unlock(&cookie->lock);
@@ -464,28 +507,14 @@ void __fscache_update_cookie(struct fscache_cookie *cookie)
 EXPORT_SYMBOL(__fscache_update_cookie);
 
 /*
- * release a cookie back to the cache
- * - the object will be marked as recyclable on disk if retire is true
- * - all dependents of this cookie must have already been unregistered
- *   (indices/files/pages)
+ * Disable a cookie to stop it from accepting new requests from the netfs.
  */
-void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
 {
        struct fscache_object *object;
+       bool awaken = false;
 
-       fscache_stat(&fscache_n_relinquishes);
-       if (retire)
-               fscache_stat(&fscache_n_relinquishes_retire);
-
-       if (!cookie) {
-               fscache_stat(&fscache_n_relinquishes_null);
-               _leave(" [no cookie]");
-               return;
-       }
-
-       _enter("%p{%s,%p,%d},%d",
-              cookie, cookie->def->name, cookie->netfs_data,
-              atomic_read(&cookie->n_active), retire);
+       _enter("%p,%u", cookie, invalidate);
 
        ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
 
@@ -495,24 +524,82 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
                BUG();
        }
 
-       /* No further netfs-accessing operations on this cookie permitted */
-       set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags);
-       if (retire)
-               set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags);
+       wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
+                        fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+       if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
+               goto out_unlock_enable;
+
+       /* If the cookie is being invalidated, wait for that to complete first
+        * so that we can reuse the flag.
+        */
+       __fscache_wait_on_invalidate(cookie);
+
+       /* Dispose of the backing objects */
+       set_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags);
 
        spin_lock(&cookie->lock);
-       hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) {
-               fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
+       if (!hlist_empty(&cookie->backing_objects)) {
+               hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) {
+                       if (invalidate)
+                               set_bit(FSCACHE_OBJECT_RETIRED, &object->flags);
+                       fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
+               }
+       } else {
+               if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
+                       awaken = true;
        }
        spin_unlock(&cookie->lock);
+       if (awaken)
+               wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
 
        /* Wait for cessation of activity requiring access to the netfs (when
-        * n_active reaches 0).
+        * n_active reaches 0).  This makes sure outstanding reads and writes
+        * have completed.
         */
        if (!atomic_dec_and_test(&cookie->n_active))
                wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t,
                                 TASK_UNINTERRUPTIBLE);
 
+       /* Reset the cookie state if it wasn't relinquished */
+       if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) {
+               atomic_inc(&cookie->n_active);
+               set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+       }
+
+out_unlock_enable:
+       clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
+       wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
+       _leave("");
+}
+EXPORT_SYMBOL(__fscache_disable_cookie);
+
+/*
+ * release a cookie back to the cache
+ * - the object will be marked as recyclable on disk if retire is true
+ * - all dependents of this cookie must have already been unregistered
+ *   (indices/files/pages)
+ */
+void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
+{
+       fscache_stat(&fscache_n_relinquishes);
+       if (retire)
+               fscache_stat(&fscache_n_relinquishes_retire);
+
+       if (!cookie) {
+               fscache_stat(&fscache_n_relinquishes_null);
+               _leave(" [no cookie]");
+               return;
+       }
+
+       _enter("%p{%s,%p,%d},%d",
+              cookie, cookie->def->name, cookie->netfs_data,
+              atomic_read(&cookie->n_active), retire);
+
+       /* No further netfs-accessing operations on this cookie permitted */
+       set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags);
+
+       __fscache_disable_cookie(cookie, retire);
+
        /* Clear pointers back to the netfs */
        cookie->netfs_data      = NULL;
        cookie->def             = NULL;
@@ -568,6 +655,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
 {
        struct fscache_operation *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,", cookie);
@@ -591,7 +679,8 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto inconsistent;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
@@ -600,7 +689,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
 
        op->debug_id = atomic_inc_return(&fscache_op_debug_id);
 
-       atomic_inc(&cookie->n_active);
+       __fscache_use_cookie(cookie);
        if (fscache_submit_op(object, op) < 0)
                goto submit_failed;
 
@@ -622,9 +711,11 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
        return ret;
 
 submit_failed:
-       atomic_dec(&cookie->n_active);
+       wake_cookie = __fscache_unuse_cookie(cookie);
 inconsistent:
        spin_unlock(&cookie->lock);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        kfree(op);
        _leave(" = -ESTALE");
        return -ESTALE;
index 10a2ade0bdf8c1ff390be0e82c5dd2e161732054..5a117df2a9ef7e51f89a55d1bc40bdac81b79393 100644 (file)
@@ -59,6 +59,7 @@ struct fscache_cookie fscache_fsdef_index = {
        .lock           = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock),
        .backing_objects = HLIST_HEAD_INIT,
        .def            = &fscache_fsdef_index_def,
+       .flags          = 1 << FSCACHE_COOKIE_ENABLED,
 };
 EXPORT_SYMBOL(fscache_fsdef_index);
 
index b1bb6117473a25a292ccf326dcd607fcf4a4f354..989f394015472bafe7758c19e006a16c57a59e4c 100644 (file)
@@ -45,6 +45,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
        netfs->primary_index->def               = &fscache_fsdef_netfs_def;
        netfs->primary_index->parent            = &fscache_fsdef_index;
        netfs->primary_index->netfs_data        = netfs;
+       netfs->primary_index->flags             = 1 << FSCACHE_COOKIE_ENABLED;
 
        atomic_inc(&netfs->primary_index->parent->usage);
        atomic_inc(&netfs->primary_index->parent->n_children);
index 86d75a60b20c85543bd445869d9a57f37d42e920..dcb8216177747d033731bfd6b4a42ff903af44c5 100644 (file)
@@ -495,6 +495,7 @@ void fscache_object_lookup_negative(struct fscache_object *object)
                 * returning ENODATA.
                 */
                set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+               clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
 
                _debug("wake up lookup %p", &cookie->flags);
                clear_bit_unlock(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
@@ -527,6 +528,7 @@ void fscache_obtained_object(struct fscache_object *object)
 
                /* We do (presumably) have data */
                clear_bit_unlock(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+               clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
 
                /* Allow write requests to begin stacking up and read requests
                 * to begin shovelling data.
@@ -679,7 +681,8 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
         */
        spin_lock(&cookie->lock);
        hlist_del_init(&object->cookie_link);
-       if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
+       if (hlist_empty(&cookie->backing_objects) &&
+           test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
                awaken = true;
        spin_unlock(&cookie->lock);
 
@@ -927,7 +930,7 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj
         */
        if (!fscache_use_cookie(object)) {
                ASSERT(object->cookie->stores.rnode == NULL);
-               set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags);
+               set_bit(FSCACHE_OBJECT_RETIRED, &object->flags);
                _leave(" [no cookie]");
                return transit_to(KILL_OBJECT);
        }
index 73899c1c34494555d73dd5714ecb21eb74c0296d..7f5c658af755f9b43296c1dacfab5def788c4a1c 100644 (file)
@@ -163,12 +163,10 @@ static void fscache_attr_changed_op(struct fscache_operation *op)
 
        fscache_stat(&fscache_n_attr_changed_calls);
 
-       if (fscache_object_is_active(object) &&
-           fscache_use_cookie(object)) {
+       if (fscache_object_is_active(object)) {
                fscache_stat(&fscache_n_cop_attr_changed);
                ret = object->cache->ops->attr_changed(object);
                fscache_stat_d(&fscache_n_cop_attr_changed);
-               fscache_unuse_cookie(object);
                if (ret < 0)
                        fscache_abort_object(object);
        }
@@ -184,6 +182,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
 {
        struct fscache_operation *op;
        struct fscache_object *object;
+       bool wake_cookie;
 
        _enter("%p", cookie);
 
@@ -199,15 +198,19 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
        }
 
        fscache_operation_init(op, fscache_attr_changed_op, NULL);
-       op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE);
+       op->flags = FSCACHE_OP_ASYNC |
+               (1 << FSCACHE_OP_EXCLUSIVE) |
+               (1 << FSCACHE_OP_UNUSE_COOKIE);
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       __fscache_use_cookie(cookie);
        if (fscache_submit_exclusive_op(object, op) < 0)
                goto nobufs;
        spin_unlock(&cookie->lock);
@@ -217,8 +220,11 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
        return 0;
 
 nobufs:
+       wake_cookie = __fscache_unuse_cookie(cookie);
        spin_unlock(&cookie->lock);
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        fscache_stat(&fscache_n_attr_changed_nobufs);
        _leave(" = %d", -ENOBUFS);
        return -ENOBUFS;
@@ -263,7 +269,6 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
        }
 
        fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op);
-       atomic_inc(&cookie->n_active);
        op->op.flags    = FSCACHE_OP_MYTHREAD |
                (1UL << FSCACHE_OP_WAITING) |
                (1UL << FSCACHE_OP_UNUSE_COOKIE);
@@ -384,6 +389,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 {
        struct fscache_retrieval *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,%p,,,", cookie, page);
@@ -405,7 +411,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
                return -ERESTARTSYS;
 
        op = fscache_alloc_retrieval(cookie, page->mapping,
-                                    end_io_func,context);
+                                    end_io_func, context);
        if (!op) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
@@ -414,13 +420,15 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs_unlock;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
        ASSERT(test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags));
 
+       __fscache_use_cookie(cookie);
        atomic_inc(&object->n_reads);
        __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
 
@@ -475,9 +483,11 @@ error:
 
 nobufs_unlock_dec:
        atomic_dec(&object->n_reads);
+       wake_cookie = __fscache_unuse_cookie(cookie);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
-       atomic_dec(&cookie->n_active);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        kfree(op);
 nobufs:
        fscache_stat(&fscache_n_retrievals_nobufs);
@@ -514,6 +524,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 {
        struct fscache_retrieval *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,,%d,,,", cookie, *nr_pages);
@@ -542,11 +553,13 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs_unlock;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       __fscache_use_cookie(cookie);
        atomic_inc(&object->n_reads);
        __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
 
@@ -601,10 +614,12 @@ error:
 
 nobufs_unlock_dec:
        atomic_dec(&object->n_reads);
+       wake_cookie = __fscache_unuse_cookie(cookie);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
-       atomic_dec(&cookie->n_active);
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
 nobufs:
        fscache_stat(&fscache_n_retrievals_nobufs);
        _leave(" = -ENOBUFS");
@@ -626,6 +641,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
 {
        struct fscache_retrieval *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,%p,,,", cookie, page);
@@ -653,13 +669,15 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs_unlock;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       __fscache_use_cookie(cookie);
        if (fscache_submit_op(object, &op->op) < 0)
-               goto nobufs_unlock;
+               goto nobufs_unlock_dec;
        spin_unlock(&cookie->lock);
 
        fscache_stat(&fscache_n_alloc_ops);
@@ -689,10 +707,13 @@ error:
        _leave(" = %d", ret);
        return ret;
 
+nobufs_unlock_dec:
+       wake_cookie = __fscache_unuse_cookie(cookie);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
-       atomic_dec(&cookie->n_active);
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
 nobufs:
        fscache_stat(&fscache_n_allocs_nobufs);
        _leave(" = -ENOBUFS");
@@ -889,6 +910,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
 {
        struct fscache_storage *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,%x,", cookie, (u32) page->flags);
@@ -920,7 +942,8 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        ret = -ENOBUFS;
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
@@ -957,7 +980,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
        op->store_limit = object->store_limit;
 
-       atomic_inc(&cookie->n_active);
+       __fscache_use_cookie(cookie);
        if (fscache_submit_op(object, &op->op) < 0)
                goto submit_failed;
 
@@ -984,10 +1007,10 @@ already_pending:
        return 0;
 
 submit_failed:
-       atomic_dec(&cookie->n_active);
        spin_lock(&cookie->stores_lock);
        radix_tree_delete(&cookie->stores, page->index);
        spin_unlock(&cookie->stores_lock);
+       wake_cookie = __fscache_unuse_cookie(cookie);
        page_cache_release(page);
        ret = -ENOBUFS;
        goto nobufs;
@@ -999,6 +1022,8 @@ nobufs:
        spin_unlock(&cookie->lock);
        radix_tree_preload_end();
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        fscache_stat(&fscache_n_stores_nobufs);
        _leave(" = -ENOBUFS");
        return -ENOBUFS;
index 1f7d8057ea68d1c7214d3db0a6446aa248888eea..b7fc035a6943cc40f649f1cca7be5858fbcf1cbc 100644 (file)
@@ -611,12 +611,14 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
                gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
 
        if (alloc_required) {
+               struct gfs2_alloc_parms ap = { .aflags = 0, };
                error = gfs2_quota_lock_check(ip);
                if (error)
                        goto out_unlock;
 
                requested = data_blocks + ind_blocks;
-               error = gfs2_inplace_reserve(ip, requested, 0);
+               ap.target = requested;
+               error = gfs2_inplace_reserve(ip, &ap);
                if (error)
                        goto out_qunlock;
        }
index 62a65fc448dcedf5009f85a233cb43ad7cd4b442..fe0500c0af7aab88ca4276234df6894cca7290b3 100644 (file)
@@ -1216,6 +1216,7 @@ static int do_grow(struct inode *inode, u64 size)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
+       struct gfs2_alloc_parms ap = { .target = 1, };
        struct buffer_head *dibh;
        int error;
        int unstuff = 0;
@@ -1226,7 +1227,7 @@ static int do_grow(struct inode *inode, u64 size)
                if (error)
                        return error;
 
-               error = gfs2_inplace_reserve(ip, 1, 0);
+               error = gfs2_inplace_reserve(ip, &ap);
                if (error)
                        goto do_grow_qunlock;
                unstuff = 1;
@@ -1279,6 +1280,7 @@ do_grow_qunlock:
 
 int gfs2_setattr_size(struct inode *inode, u64 newsize)
 {
+       struct gfs2_inode *ip = GFS2_I(inode);
        int ret;
        u64 oldsize;
 
@@ -1294,7 +1296,7 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
 
        inode_dio_wait(inode);
 
-       ret = gfs2_rs_alloc(GFS2_I(inode));
+       ret = gfs2_rs_alloc(ip);
        if (ret)
                goto out;
 
@@ -1304,6 +1306,7 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
                goto out;
        }
 
+       gfs2_rs_deltree(ip->i_res);
        ret = do_shrink(inode, oldsize, newsize);
 out:
        put_write_access(inode);
index 0621b46d474d0e6d82157e6701b3e49449839908..efc078f0ee4ed5464646841a4035b933756b562e 100644 (file)
@@ -383,6 +383,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        struct inode *inode = file_inode(vma->vm_file);
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
+       struct gfs2_alloc_parms ap = { .aflags = 0, };
        unsigned long last_index;
        u64 pos = page->index << PAGE_CACHE_SHIFT;
        unsigned int data_blocks, ind_blocks, rblocks;
@@ -430,7 +431,8 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        if (ret)
                goto out_unlock;
        gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
-       ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks, 0);
+       ap.target = data_blocks + ind_blocks;
+       ret = gfs2_inplace_reserve(ip, &ap);
        if (ret)
                goto out_quota_unlock;
 
@@ -620,7 +622,7 @@ static int gfs2_release(struct inode *inode, struct file *file)
        if (!(file->f_mode & FMODE_WRITE))
                return 0;
 
-       gfs2_rs_delete(ip);
+       gfs2_rs_delete(ip, &inode->i_writecount);
        return 0;
 }
 
@@ -800,6 +802,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
        struct inode *inode = file_inode(file);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_alloc_parms ap = { .aflags = 0, };
        unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
        loff_t bytes, max_bytes;
        int error;
@@ -850,7 +853,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
 retry:
                gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
 
-               error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks, 0);
+               ap.target = data_blocks + ind_blocks;
+               error = gfs2_inplace_reserve(ip, &ap);
                if (error) {
                        if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
                                bytes >>= 1;
index c2f41b4d00b9872ccfb4f5f23f988d46f154df32..e66a8009aff16d66b1179bba0ffc3a266ff923f6 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/bit_spinlock.h>
 #include <linux/percpu.h>
 #include <linux/list_sort.h>
+#include <linux/lockref.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -129,10 +130,10 @@ void gfs2_glock_free(struct gfs2_glock *gl)
  *
  */
 
-void gfs2_glock_hold(struct gfs2_glock *gl)
+static void gfs2_glock_hold(struct gfs2_glock *gl)
 {
-       GLOCK_BUG_ON(gl, atomic_read(&gl->gl_ref) == 0);
-       atomic_inc(&gl->gl_ref);
+       GLOCK_BUG_ON(gl, __lockref_is_dead(&gl->gl_lockref));
+       lockref_get(&gl->gl_lockref);
 }
 
 /**
@@ -186,20 +187,6 @@ static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
        spin_unlock(&lru_lock);
 }
 
-/**
- * gfs2_glock_put_nolock() - Decrement reference count on glock
- * @gl: The glock to put
- *
- * This function should only be used if the caller has its own reference
- * to the glock, in addition to the one it is dropping.
- */
-
-void gfs2_glock_put_nolock(struct gfs2_glock *gl)
-{
-       if (atomic_dec_and_test(&gl->gl_ref))
-               GLOCK_BUG_ON(gl, 1);
-}
-
 /**
  * gfs2_glock_put() - Decrement reference count on glock
  * @gl: The glock to put
@@ -211,17 +198,22 @@ void gfs2_glock_put(struct gfs2_glock *gl)
        struct gfs2_sbd *sdp = gl->gl_sbd;
        struct address_space *mapping = gfs2_glock2aspace(gl);
 
-       if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
-               __gfs2_glock_remove_from_lru(gl);
-               spin_unlock(&lru_lock);
-               spin_lock_bucket(gl->gl_hash);
-               hlist_bl_del_rcu(&gl->gl_list);
-               spin_unlock_bucket(gl->gl_hash);
-               GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
-               GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
-               trace_gfs2_glock_put(gl);
-               sdp->sd_lockstruct.ls_ops->lm_put_lock(gl);
-       }
+       if (lockref_put_or_lock(&gl->gl_lockref))
+               return;
+
+       lockref_mark_dead(&gl->gl_lockref);
+
+       spin_lock(&lru_lock);
+       __gfs2_glock_remove_from_lru(gl);
+       spin_unlock(&lru_lock);
+       spin_unlock(&gl->gl_lockref.lock);
+       spin_lock_bucket(gl->gl_hash);
+       hlist_bl_del_rcu(&gl->gl_list);
+       spin_unlock_bucket(gl->gl_hash);
+       GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
+       GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
+       trace_gfs2_glock_put(gl);
+       sdp->sd_lockstruct.ls_ops->lm_put_lock(gl);
 }
 
 /**
@@ -244,7 +236,7 @@ static struct gfs2_glock *search_bucket(unsigned int hash,
                        continue;
                if (gl->gl_sbd != sdp)
                        continue;
-               if (atomic_inc_not_zero(&gl->gl_ref))
+               if (lockref_get_not_dead(&gl->gl_lockref))
                        return gl;
        }
 
@@ -396,10 +388,11 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state)
        held2 = (new_state != LM_ST_UNLOCKED);
 
        if (held1 != held2) {
+               GLOCK_BUG_ON(gl, __lockref_is_dead(&gl->gl_lockref));
                if (held2)
-                       gfs2_glock_hold(gl);
+                       gl->gl_lockref.count++;
                else
-                       gfs2_glock_put_nolock(gl);
+                       gl->gl_lockref.count--;
        }
        if (held1 && held2 && list_empty(&gl->gl_holders))
                clear_bit(GLF_QUEUED, &gl->gl_flags);
@@ -626,9 +619,9 @@ out:
 out_sched:
        clear_bit(GLF_LOCK, &gl->gl_flags);
        smp_mb__after_clear_bit();
-       gfs2_glock_hold(gl);
+       gl->gl_lockref.count++;
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
-               gfs2_glock_put_nolock(gl);
+               gl->gl_lockref.count--;
        return;
 
 out_unlock:
@@ -754,7 +747,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
        gl->gl_sbd = sdp;
        gl->gl_flags = 0;
        gl->gl_name = name;
-       atomic_set(&gl->gl_ref, 1);
+       gl->gl_lockref.count = 1;
        gl->gl_state = LM_ST_UNLOCKED;
        gl->gl_target = LM_ST_UNLOCKED;
        gl->gl_demote_state = LM_ST_EXCLUSIVE;
@@ -1356,10 +1349,10 @@ void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
                }
        }
 
-       spin_unlock(&gl->gl_spin);
+       gl->gl_lockref.count++;
        set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
-       smp_wmb();
-       gfs2_glock_hold(gl);
+       spin_unlock(&gl->gl_spin);
+
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                gfs2_glock_put(gl);
 }
@@ -1404,15 +1397,19 @@ __acquires(&lru_lock)
        while(!list_empty(list)) {
                gl = list_entry(list->next, struct gfs2_glock, gl_lru);
                list_del_init(&gl->gl_lru);
+               if (!spin_trylock(&gl->gl_spin)) {
+                       list_add(&gl->gl_lru, &lru_list);
+                       atomic_inc(&lru_count);
+                       continue;
+               }
                clear_bit(GLF_LRU, &gl->gl_flags);
-               gfs2_glock_hold(gl);
                spin_unlock(&lru_lock);
-               spin_lock(&gl->gl_spin);
+               gl->gl_lockref.count++;
                if (demote_ok(gl))
                        handle_callback(gl, LM_ST_UNLOCKED, 0, false);
                WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags));
                if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
-                       gfs2_glock_put_nolock(gl);
+                       gl->gl_lockref.count--;
                spin_unlock(&gl->gl_spin);
                spin_lock(&lru_lock);
        }
@@ -1493,7 +1490,7 @@ static void examine_bucket(glock_examiner examiner, const struct gfs2_sbd *sdp,
 
        rcu_read_lock();
        hlist_bl_for_each_entry_rcu(gl, pos, head, gl_list) {
-               if ((gl->gl_sbd == sdp) && atomic_inc_not_zero(&gl->gl_ref))
+               if ((gl->gl_sbd == sdp) && lockref_get_not_dead(&gl->gl_lockref))
                        examiner(gl);
        }
        rcu_read_unlock();
@@ -1746,7 +1743,7 @@ int gfs2_dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
                  state2str(gl->gl_demote_state), dtime,
                  atomic_read(&gl->gl_ail_count),
                  atomic_read(&gl->gl_revokes),
-                 atomic_read(&gl->gl_ref), gl->gl_hold_time);
+                 (int)gl->gl_lockref.count, gl->gl_hold_time);
 
        list_for_each_entry(gh, &gl->gl_holders, gh_list) {
                error = dump_holder(seq, gh);
@@ -1902,7 +1899,7 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
                        gi->nhash = 0;
                }
        /* Skip entries for other sb and dead entries */
-       } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0);
+       } while (gi->sdp != gi->gl->gl_sbd || __lockref_is_dead(&gl->gl_lockref));
 
        return 0;
 }
index 69f66e3d22bf512787b3b9db403e0c8c91babd59..6647d77366ba097c4c98f482bcef1ab980704baa 100644 (file)
@@ -181,8 +181,6 @@ static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
 extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
                          const struct gfs2_glock_operations *glops,
                          int create, struct gfs2_glock **glp);
-extern void gfs2_glock_hold(struct gfs2_glock *gl);
-extern void gfs2_glock_put_nolock(struct gfs2_glock *gl);
 extern void gfs2_glock_put(struct gfs2_glock *gl);
 extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
                             unsigned flags, struct gfs2_holder *gh);
index e2e0a90396e7823da9aa47c44a727d5e75751cc6..db908f697139cfffbca462d3a7528e13139576b5 100644 (file)
@@ -525,9 +525,9 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote)
 
        if (gl->gl_demote_state == LM_ST_UNLOCKED &&
            gl->gl_state == LM_ST_SHARED && ip) {
-               gfs2_glock_hold(gl);
+               gl->gl_lockref.count++;
                if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
-                       gfs2_glock_put_nolock(gl);
+                       gl->gl_lockref.count--;
        }
 }
 
index 26aabd7caba7edfd56c9d611df1732ac6b16a6a1..ba1ea67f4eeb1c99e826f54be8b9b6d8d57909f8 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/rbtree.h>
 #include <linux/ktime.h>
 #include <linux/percpu.h>
+#include <linux/lockref.h>
 
 #define DIO_WAIT       0x00000010
 #define DIO_METADATA   0x00000020
@@ -71,6 +72,7 @@ struct gfs2_bitmap {
        u32 bi_offset;
        u32 bi_start;
        u32 bi_len;
+       u32 bi_blocks;
 };
 
 struct gfs2_rgrpd {
@@ -101,19 +103,25 @@ struct gfs2_rgrpd {
 
 struct gfs2_rbm {
        struct gfs2_rgrpd *rgd;
-       struct gfs2_bitmap *bi; /* Bitmap must belong to the rgd */
        u32 offset;             /* The offset is bitmap relative */
+       int bii;                /* Bitmap index */
 };
 
+static inline struct gfs2_bitmap *rbm_bi(const struct gfs2_rbm *rbm)
+{
+       return rbm->rgd->rd_bits + rbm->bii;
+}
+
 static inline u64 gfs2_rbm_to_block(const struct gfs2_rbm *rbm)
 {
-       return rbm->rgd->rd_data0 + (rbm->bi->bi_start * GFS2_NBBY) + rbm->offset;
+       return rbm->rgd->rd_data0 + (rbm_bi(rbm)->bi_start * GFS2_NBBY) +
+               rbm->offset;
 }
 
 static inline bool gfs2_rbm_eq(const struct gfs2_rbm *rbm1,
                               const struct gfs2_rbm *rbm2)
 {
-       return (rbm1->rgd == rbm2->rgd) && (rbm1->bi == rbm2->bi) && 
+       return (rbm1->rgd == rbm2->rgd) && (rbm1->bii == rbm2->bii) &&
               (rbm1->offset == rbm2->offset);
 }
 
@@ -278,6 +286,20 @@ struct gfs2_blkreserv {
        unsigned int rs_qa_qd_num;
 };
 
+/*
+ * Allocation parameters
+ * @target: The number of blocks we'd ideally like to allocate
+ * @aflags: The flags (e.g. Orlov flag)
+ *
+ * The intent is to gradually expand this structure over time in
+ * order to give more information, e.g. alignment, min extent size
+ * to the allocation code.
+ */
+struct gfs2_alloc_parms {
+       u32 target;
+       u32 aflags;
+};
+
 enum {
        GLF_LOCK                        = 1,
        GLF_DEMOTE                      = 3,
@@ -300,9 +322,9 @@ struct gfs2_glock {
        struct gfs2_sbd *gl_sbd;
        unsigned long gl_flags;         /* GLF_... */
        struct lm_lockname gl_name;
-       atomic_t gl_ref;
 
-       spinlock_t gl_spin;
+       struct lockref gl_lockref;
+#define gl_spin gl_lockref.lock
 
        /* State fields protected by gl_spin */
        unsigned int gl_state:2,        /* Current state */
@@ -398,11 +420,10 @@ enum {
 
 struct gfs2_quota_data {
        struct list_head qd_list;
-       struct list_head qd_reclaim;
-
-       atomic_t qd_count;
-
        struct kqid qd_id;
+       struct lockref qd_lockref;
+       struct list_head qd_lru;
+
        unsigned long qd_flags;         /* QDF_... */
 
        s64 qd_change;
@@ -516,7 +537,6 @@ struct gfs2_tune {
 
        unsigned int gt_logd_secs;
 
-       unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
        unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */
        unsigned int gt_quota_scale_num; /* Numerator */
        unsigned int gt_quota_scale_den; /* Denominator */
@@ -694,6 +714,7 @@ struct gfs2_sbd {
        struct list_head sd_quota_list;
        atomic_t sd_quota_count;
        struct mutex sd_quota_mutex;
+       struct mutex sd_quota_sync_mutex;
        wait_queue_head_t sd_quota_wait;
        struct list_head sd_trunc_list;
        spinlock_t sd_trunc_lock;
index ced3257f06e84bd24b6d96063a4f88f5e2b81525..109ce9325b761211feb2facce8f721a7c8ac155d 100644 (file)
@@ -379,6 +379,7 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip,
 static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       struct gfs2_alloc_parms ap = { .target = RES_DINODE, .aflags = flags, };
        int error;
        int dblocks = 1;
 
@@ -386,7 +387,7 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
        if (error)
                goto out;
 
-       error = gfs2_inplace_reserve(ip, RES_DINODE, flags);
+       error = gfs2_inplace_reserve(ip, &ap);
        if (error)
                goto out_quota;
 
@@ -472,6 +473,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
                       struct gfs2_inode *ip, int arq)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
+       struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
        int error;
 
        if (arq) {
@@ -479,7 +481,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
                if (error)
                        goto fail_quota_locks;
 
-               error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres, 0);
+               error = gfs2_inplace_reserve(dip, &ap);
                if (error)
                        goto fail_quota_locks;
 
@@ -584,17 +586,17 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        if (!IS_ERR(inode)) {
                d = d_splice_alias(inode, dentry);
                error = 0;
-               if (file && !IS_ERR(d)) {
-                       if (d == NULL)
-                               d = dentry;
-                       if (S_ISREG(inode->i_mode))
-                               error = finish_open(file, d, gfs2_open_common, opened);
-                       else
+               if (file) {
+                       if (S_ISREG(inode->i_mode)) {
+                               WARN_ON(d != NULL);
+                               error = finish_open(file, dentry, gfs2_open_common, opened);
+                       } else {
                                error = finish_no_open(file, d);
+                       }
+               } else {
+                       dput(d);
                }
                gfs2_glock_dq_uninit(ghs);
-               if (IS_ERR(d))
-                       return PTR_ERR(d);
                return error;
        } else if (error != -ENOENT) {
                goto fail_gunlock;
@@ -713,7 +715,7 @@ fail_gunlock2:
 fail_free_inode:
        if (ip->i_gl)
                gfs2_glock_put(ip->i_gl);
-       gfs2_rs_delete(ip);
+       gfs2_rs_delete(ip, NULL);
        free_inode_nonrcu(inode);
        inode = NULL;
 fail_gunlock:
@@ -781,8 +783,10 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry,
                error = finish_open(file, dentry, gfs2_open_common, opened);
 
        gfs2_glock_dq_uninit(&gh);
-       if (error)
+       if (error) {
+               dput(d);
                return ERR_PTR(error);
+       }
        return d;
 }
 
@@ -874,11 +878,12 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        error = 0;
 
        if (alloc_required) {
+               struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
                error = gfs2_quota_lock_check(dip);
                if (error)
                        goto out_gunlock;
 
-               error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres, 0);
+               error = gfs2_inplace_reserve(dip, &ap);
                if (error)
                        goto out_gunlock_q;
 
@@ -1163,14 +1168,16 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry,
        d = __gfs2_lookup(dir, dentry, file, opened);
        if (IS_ERR(d))
                return PTR_ERR(d);
-       if (d == NULL)
-               d = dentry;
-       if (d->d_inode) {
+       if (d != NULL)
+               dentry = d;
+       if (dentry->d_inode) {
                if (!(*opened & FILE_OPENED))
-                       return finish_no_open(file, d);
+                       return finish_no_open(file, dentry);
+               dput(d);
                return 0;
        }
 
+       BUG_ON(d != NULL);
        if (!(flags & O_CREAT))
                return -ENOENT;
 
@@ -1385,11 +1392,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                goto out_gunlock;
 
        if (alloc_required) {
+               struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
                error = gfs2_quota_lock_check(ndip);
                if (error)
                        goto out_gunlock;
 
-               error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres, 0);
+               error = gfs2_inplace_reserve(ndip, &ap);
                if (error)
                        goto out_gunlock_q;
 
index 351586e24e3004f59b8bf3c5db022ce07afeaedd..0650db2541ef6ff1739f0321bdf132f084a9f23f 100644 (file)
 
 struct workqueue_struct *gfs2_control_wq;
 
-static struct shrinker qd_shrinker = {
-       .count_objects = gfs2_qd_shrink_count,
-       .scan_objects = gfs2_qd_shrink_scan,
-       .seeks = DEFAULT_SEEKS,
-};
-
 static void gfs2_init_inode_once(void *foo)
 {
        struct gfs2_inode *ip = foo;
@@ -87,6 +81,10 @@ static int __init init_gfs2_fs(void)
        if (error)
                return error;
 
+       error = list_lru_init(&gfs2_qd_lru);
+       if (error)
+               goto fail_lru;
+
        error = gfs2_glock_init();
        if (error)
                goto fail;
@@ -139,7 +137,7 @@ static int __init init_gfs2_fs(void)
        if (!gfs2_rsrv_cachep)
                goto fail;
 
-       register_shrinker(&qd_shrinker);
+       register_shrinker(&gfs2_qd_shrinker);
 
        error = register_filesystem(&gfs2_fs_type);
        if (error)
@@ -179,7 +177,9 @@ fail_wq:
 fail_unregister:
        unregister_filesystem(&gfs2_fs_type);
 fail:
-       unregister_shrinker(&qd_shrinker);
+       list_lru_destroy(&gfs2_qd_lru);
+fail_lru:
+       unregister_shrinker(&gfs2_qd_shrinker);
        gfs2_glock_exit();
 
        if (gfs2_rsrv_cachep)
@@ -214,13 +214,14 @@ fail:
 
 static void __exit exit_gfs2_fs(void)
 {
-       unregister_shrinker(&qd_shrinker);
+       unregister_shrinker(&gfs2_qd_shrinker);
        gfs2_glock_exit();
        gfs2_unregister_debugfs();
        unregister_filesystem(&gfs2_fs_type);
        unregister_filesystem(&gfs2meta_fs_type);
        destroy_workqueue(gfs_recovery_wq);
        destroy_workqueue(gfs2_control_wq);
+       list_lru_destroy(&gfs2_qd_lru);
 
        rcu_barrier();
 
index 19ff5e8c285c4c0764d402a719146f1416d9f35a..82303b4749582cd3c00d402a9f42b9972b1de677 100644 (file)
@@ -51,7 +51,6 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
 {
        spin_lock_init(&gt->gt_spin);
 
-       gt->gt_quota_simul_sync = 64;
        gt->gt_quota_warn_period = 10;
        gt->gt_quota_scale_num = 1;
        gt->gt_quota_scale_den = 1;
@@ -94,6 +93,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
        INIT_LIST_HEAD(&sdp->sd_quota_list);
        mutex_init(&sdp->sd_quota_mutex);
+       mutex_init(&sdp->sd_quota_sync_mutex);
        init_waitqueue_head(&sdp->sd_quota_wait);
        INIT_LIST_HEAD(&sdp->sd_trunc_list);
        spin_lock_init(&sdp->sd_trunc_lock);
index db441359ee8cd2f31fa4a980afe8c54a3f715447..453b50eaddec42f8e8461d9f96965e7d40ba746f 100644 (file)
@@ -50,6 +50,8 @@
 #include <linux/freezer.h>
 #include <linux/quota.h>
 #include <linux/dqblk_xfs.h>
+#include <linux/lockref.h>
+#include <linux/list_lru.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -71,29 +73,25 @@ struct gfs2_quota_change_host {
        struct kqid qc_id;
 };
 
-static LIST_HEAD(qd_lru_list);
-static atomic_t qd_lru_count = ATOMIC_INIT(0);
-static DEFINE_SPINLOCK(qd_lru_lock);
+/* Lock order: qd_lock -> qd->lockref.lock -> lru lock */
+static DEFINE_SPINLOCK(qd_lock);
+struct list_lru gfs2_qd_lru;
 
-unsigned long gfs2_qd_shrink_scan(struct shrinker *shrink,
-                                 struct shrink_control *sc)
+static void gfs2_qd_dispose(struct list_head *list)
 {
        struct gfs2_quota_data *qd;
        struct gfs2_sbd *sdp;
-       int nr_to_scan = sc->nr_to_scan;
-       long freed = 0;
 
-       if (!(sc->gfp_mask & __GFP_FS))
-               return SHRINK_STOP;
-
-       spin_lock(&qd_lru_lock);
-       while (nr_to_scan && !list_empty(&qd_lru_list)) {
-               qd = list_entry(qd_lru_list.next,
-                               struct gfs2_quota_data, qd_reclaim);
+       while (!list_empty(list)) {
+               qd = list_entry(list->next, struct gfs2_quota_data, qd_lru);
                sdp = qd->qd_gl->gl_sbd;
 
+               list_del(&qd->qd_lru);
+
                /* Free from the filesystem-specific list */
+               spin_lock(&qd_lock);
                list_del(&qd->qd_list);
+               spin_unlock(&qd_lock);
 
                gfs2_assert_warn(sdp, !qd->qd_change);
                gfs2_assert_warn(sdp, !qd->qd_slot_count);
@@ -103,24 +101,59 @@ unsigned long gfs2_qd_shrink_scan(struct shrinker *shrink,
                atomic_dec(&sdp->sd_quota_count);
 
                /* Delete it from the common reclaim list */
-               list_del_init(&qd->qd_reclaim);
-               atomic_dec(&qd_lru_count);
-               spin_unlock(&qd_lru_lock);
                kmem_cache_free(gfs2_quotad_cachep, qd);
-               spin_lock(&qd_lru_lock);
-               nr_to_scan--;
-               freed++;
        }
-       spin_unlock(&qd_lru_lock);
+}
+
+
+static enum lru_status gfs2_qd_isolate(struct list_head *item, spinlock_t *lock, void *arg)
+{
+       struct list_head *dispose = arg;
+       struct gfs2_quota_data *qd = list_entry(item, struct gfs2_quota_data, qd_lru);
+
+       if (!spin_trylock(&qd->qd_lockref.lock))
+               return LRU_SKIP;
+
+       if (qd->qd_lockref.count == 0) {
+               lockref_mark_dead(&qd->qd_lockref);
+               list_move(&qd->qd_lru, dispose);
+       }
+
+       spin_unlock(&qd->qd_lockref.lock);
+       return LRU_REMOVED;
+}
+
+static unsigned long gfs2_qd_shrink_scan(struct shrinker *shrink,
+                                        struct shrink_control *sc)
+{
+       LIST_HEAD(dispose);
+       unsigned long freed;
+
+       if (!(sc->gfp_mask & __GFP_FS))
+               return SHRINK_STOP;
+
+       freed = list_lru_walk_node(&gfs2_qd_lru, sc->nid, gfs2_qd_isolate,
+                                  &dispose, &sc->nr_to_scan);
+
+       gfs2_qd_dispose(&dispose);
+
        return freed;
 }
 
-unsigned long gfs2_qd_shrink_count(struct shrinker *shrink,
-                                  struct shrink_control *sc)
+static unsigned long gfs2_qd_shrink_count(struct shrinker *shrink,
+                                         struct shrink_control *sc)
 {
-       return vfs_pressure_ratio(atomic_read(&qd_lru_count));
+       return vfs_pressure_ratio(list_lru_count_node(&gfs2_qd_lru, sc->nid));
 }
 
+struct shrinker gfs2_qd_shrinker = {
+       .count_objects = gfs2_qd_shrink_count,
+       .scan_objects = gfs2_qd_shrink_scan,
+       .seeks = DEFAULT_SEEKS,
+       .flags = SHRINKER_NUMA_AWARE,
+};
+
+
 static u64 qd2index(struct gfs2_quota_data *qd)
 {
        struct kqid qid = qd->qd_id;
@@ -148,10 +181,11 @@ static int qd_alloc(struct gfs2_sbd *sdp, struct kqid qid,
        if (!qd)
                return -ENOMEM;
 
-       atomic_set(&qd->qd_count, 1);
+       qd->qd_lockref.count = 1;
+       spin_lock_init(&qd->qd_lockref.lock);
        qd->qd_id = qid;
        qd->qd_slot = -1;
-       INIT_LIST_HEAD(&qd->qd_reclaim);
+       INIT_LIST_HEAD(&qd->qd_lru);
 
        error = gfs2_glock_get(sdp, qd2index(qd),
                              &gfs2_quota_glops, CREATE, &qd->qd_gl);
@@ -177,16 +211,11 @@ static int qd_get(struct gfs2_sbd *sdp, struct kqid qid,
 
        for (;;) {
                found = 0;
-               spin_lock(&qd_lru_lock);
+               spin_lock(&qd_lock);
                list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
-                       if (qid_eq(qd->qd_id, qid)) {
-                               if (!atomic_read(&qd->qd_count) &&
-                                   !list_empty(&qd->qd_reclaim)) {
-                                       /* Remove it from reclaim list */
-                                       list_del_init(&qd->qd_reclaim);
-                                       atomic_dec(&qd_lru_count);
-                               }
-                               atomic_inc(&qd->qd_count);
+                       if (qid_eq(qd->qd_id, qid) &&
+                           lockref_get_not_dead(&qd->qd_lockref)) {
+                               list_lru_del(&gfs2_qd_lru, &qd->qd_lru);
                                found = 1;
                                break;
                        }
@@ -202,7 +231,7 @@ static int qd_get(struct gfs2_sbd *sdp, struct kqid qid,
                        new_qd = NULL;
                }
 
-               spin_unlock(&qd_lru_lock);
+               spin_unlock(&qd_lock);
 
                if (qd) {
                        if (new_qd) {
@@ -222,18 +251,19 @@ static int qd_get(struct gfs2_sbd *sdp, struct kqid qid,
 static void qd_hold(struct gfs2_quota_data *qd)
 {
        struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
-       gfs2_assert(sdp, atomic_read(&qd->qd_count));
-       atomic_inc(&qd->qd_count);
+       gfs2_assert(sdp, !__lockref_is_dead(&qd->qd_lockref));
+       lockref_get(&qd->qd_lockref);
 }
 
 static void qd_put(struct gfs2_quota_data *qd)
 {
-       if (atomic_dec_and_lock(&qd->qd_count, &qd_lru_lock)) {
-               /* Add to the reclaim list */
-               list_add_tail(&qd->qd_reclaim, &qd_lru_list);
-               atomic_inc(&qd_lru_count);
-               spin_unlock(&qd_lru_lock);
-       }
+       if (lockref_put_or_lock(&qd->qd_lockref))
+               return;
+
+       qd->qd_lockref.count = 0;
+       list_lru_add(&gfs2_qd_lru, &qd->qd_lru);
+       spin_unlock(&qd->qd_lockref.lock);
+
 }
 
 static int slot_get(struct gfs2_quota_data *qd)
@@ -242,10 +272,10 @@ static int slot_get(struct gfs2_quota_data *qd)
        unsigned int c, o = 0, b;
        unsigned char byte = 0;
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
 
        if (qd->qd_slot_count++) {
-               spin_unlock(&qd_lru_lock);
+               spin_unlock(&qd_lock);
                return 0;
        }
 
@@ -269,13 +299,13 @@ found:
 
        sdp->sd_quota_bitmap[c][o] |= 1 << b;
 
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
 
        return 0;
 
 fail:
        qd->qd_slot_count--;
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
        return -ENOSPC;
 }
 
@@ -283,23 +313,43 @@ static void slot_hold(struct gfs2_quota_data *qd)
 {
        struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
        gfs2_assert(sdp, qd->qd_slot_count);
        qd->qd_slot_count++;
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
+}
+
+static void gfs2_icbit_munge(struct gfs2_sbd *sdp, unsigned char **bitmap,
+                            unsigned int bit, int new_value)
+{
+       unsigned int c, o, b = bit;
+       int old_value;
+
+       c = b / (8 * PAGE_SIZE);
+       b %= 8 * PAGE_SIZE;
+       o = b / 8;
+       b %= 8;
+
+       old_value = (bitmap[c][o] & (1 << b));
+       gfs2_assert_withdraw(sdp, !old_value != !new_value);
+
+       if (new_value)
+               bitmap[c][o] |= 1 << b;
+       else
+               bitmap[c][o] &= ~(1 << b);
 }
 
 static void slot_put(struct gfs2_quota_data *qd)
 {
        struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
        gfs2_assert(sdp, qd->qd_slot_count);
        if (!--qd->qd_slot_count) {
                gfs2_icbit_munge(sdp, sdp->sd_quota_bitmap, qd->qd_slot, 0);
                qd->qd_slot = -1;
        }
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
 }
 
 static int bh_get(struct gfs2_quota_data *qd)
@@ -363,6 +413,25 @@ static void bh_put(struct gfs2_quota_data *qd)
        mutex_unlock(&sdp->sd_quota_mutex);
 }
 
+static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd,
+                        u64 *sync_gen)
+{
+       if (test_bit(QDF_LOCKED, &qd->qd_flags) ||
+           !test_bit(QDF_CHANGE, &qd->qd_flags) ||
+           (sync_gen && (qd->qd_sync_gen >= *sync_gen)))
+               return 0;
+
+       if (!lockref_get_not_dead(&qd->qd_lockref))
+               return 0;
+
+       list_move_tail(&qd->qd_list, &sdp->sd_quota_list);
+       set_bit(QDF_LOCKED, &qd->qd_flags);
+       qd->qd_change_sync = qd->qd_change;
+       gfs2_assert_warn(sdp, qd->qd_slot_count);
+       qd->qd_slot_count++;
+       return 1;
+}
+
 static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
 {
        struct gfs2_quota_data *qd = NULL;
@@ -374,31 +443,18 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
        if (sdp->sd_vfs->s_flags & MS_RDONLY)
                return 0;
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
 
        list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
-               if (test_bit(QDF_LOCKED, &qd->qd_flags) ||
-                   !test_bit(QDF_CHANGE, &qd->qd_flags) ||
-                   qd->qd_sync_gen >= sdp->sd_quota_sync_gen)
-                       continue;
-
-               list_move_tail(&qd->qd_list, &sdp->sd_quota_list);
-
-               set_bit(QDF_LOCKED, &qd->qd_flags);
-               gfs2_assert_warn(sdp, atomic_read(&qd->qd_count));
-               atomic_inc(&qd->qd_count);
-               qd->qd_change_sync = qd->qd_change;
-               gfs2_assert_warn(sdp, qd->qd_slot_count);
-               qd->qd_slot_count++;
-               found = 1;
-
-               break;
+               found = qd_check_sync(sdp, qd, &sdp->sd_quota_sync_gen);
+               if (found)
+                       break;
        }
 
        if (!found)
                qd = NULL;
 
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
 
        if (qd) {
                gfs2_assert_warn(sdp, qd->qd_change_sync);
@@ -416,43 +472,6 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
        return 0;
 }
 
-static int qd_trylock(struct gfs2_quota_data *qd)
-{
-       struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
-
-       if (sdp->sd_vfs->s_flags & MS_RDONLY)
-               return 0;
-
-       spin_lock(&qd_lru_lock);
-
-       if (test_bit(QDF_LOCKED, &qd->qd_flags) ||
-           !test_bit(QDF_CHANGE, &qd->qd_flags)) {
-               spin_unlock(&qd_lru_lock);
-               return 0;
-       }
-
-       list_move_tail(&qd->qd_list, &sdp->sd_quota_list);
-
-       set_bit(QDF_LOCKED, &qd->qd_flags);
-       gfs2_assert_warn(sdp, atomic_read(&qd->qd_count));
-       atomic_inc(&qd->qd_count);
-       qd->qd_change_sync = qd->qd_change;
-       gfs2_assert_warn(sdp, qd->qd_slot_count);
-       qd->qd_slot_count++;
-
-       spin_unlock(&qd_lru_lock);
-
-       gfs2_assert_warn(sdp, qd->qd_change_sync);
-       if (bh_get(qd)) {
-               clear_bit(QDF_LOCKED, &qd->qd_flags);
-               slot_put(qd);
-               qd_put(qd);
-               return 0;
-       }
-
-       return 1;
-}
-
 static void qd_unlock(struct gfs2_quota_data *qd)
 {
        gfs2_assert_warn(qd->qd_gl->gl_sbd,
@@ -602,9 +621,9 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
        x = be64_to_cpu(qc->qc_change) + change;
        qc->qc_change = cpu_to_be64(x);
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
        qd->qd_change = x;
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
 
        if (!x) {
                gfs2_assert_warn(sdp, test_bit(QDF_CHANGE, &qd->qd_flags));
@@ -763,6 +782,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
 {
        struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
        struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
+       struct gfs2_alloc_parms ap = { .aflags = 0, };
        unsigned int data_blocks, ind_blocks;
        struct gfs2_holder *ghs, i_gh;
        unsigned int qx, x;
@@ -815,7 +835,8 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
        blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3;
 
        reserved = 1 + (nalloc * (data_blocks + ind_blocks));
-       error = gfs2_inplace_reserve(ip, reserved, 0);
+       ap.target = reserved;
+       error = gfs2_inplace_reserve(ip, &ap);
        if (error)
                goto out_alloc;
 
@@ -974,9 +995,9 @@ static int need_sync(struct gfs2_quota_data *qd)
        if (!qd->qd_qb.qb_limit)
                return 0;
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
        value = qd->qd_change;
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
 
        spin_lock(&gt->gt_spin);
        num = gt->gt_quota_scale_num;
@@ -1001,9 +1022,11 @@ static int need_sync(struct gfs2_quota_data *qd)
 
 void gfs2_quota_unlock(struct gfs2_inode *ip)
 {
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_quota_data *qda[4];
        unsigned int count = 0;
        unsigned int x;
+       int found;
 
        if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags))
                goto out;
@@ -1016,9 +1039,25 @@ void gfs2_quota_unlock(struct gfs2_inode *ip)
                sync = need_sync(qd);
 
                gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]);
+               if (!sync)
+                       continue;
+
+               spin_lock(&qd_lock);
+               found = qd_check_sync(sdp, qd, NULL);
+               spin_unlock(&qd_lock);
+
+               if (!found)
+                       continue;
 
-               if (sync && qd_trylock(qd))
-                       qda[count++] = qd;
+               gfs2_assert_warn(sdp, qd->qd_change_sync);
+               if (bh_get(qd)) {
+                       clear_bit(QDF_LOCKED, &qd->qd_flags);
+                       slot_put(qd);
+                       qd_put(qd);
+                       continue;
+               }
+
+               qda[count++] = qd;
        }
 
        if (count) {
@@ -1067,9 +1106,9 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
                        continue;
 
                value = (s64)be64_to_cpu(qd->qd_qb.qb_value);
-               spin_lock(&qd_lru_lock);
+               spin_lock(&qd_lock);
                value += qd->qd_change;
-               spin_unlock(&qd_lru_lock);
+               spin_unlock(&qd_lock);
 
                if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
                        print_message(qd, "exceeded");
@@ -1118,17 +1157,18 @@ int gfs2_quota_sync(struct super_block *sb, int type)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
        struct gfs2_quota_data **qda;
-       unsigned int max_qd = gfs2_tune_get(sdp, gt_quota_simul_sync);
+       unsigned int max_qd = PAGE_SIZE/sizeof(struct gfs2_holder);
        unsigned int num_qd;
        unsigned int x;
        int error = 0;
 
-       sdp->sd_quota_sync_gen++;
-
        qda = kcalloc(max_qd, sizeof(struct gfs2_quota_data *), GFP_KERNEL);
        if (!qda)
                return -ENOMEM;
 
+       mutex_lock(&sdp->sd_quota_sync_mutex);
+       sdp->sd_quota_sync_gen++;
+
        do {
                num_qd = 0;
 
@@ -1153,6 +1193,7 @@ int gfs2_quota_sync(struct super_block *sb, int type)
                }
        } while (!error && num_qd == max_qd);
 
+       mutex_unlock(&sdp->sd_quota_sync_mutex);
        kfree(qda);
 
        return error;
@@ -1258,11 +1299,11 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
                        qd->qd_slot = slot;
                        qd->qd_slot_count = 1;
 
-                       spin_lock(&qd_lru_lock);
+                       spin_lock(&qd_lock);
                        gfs2_icbit_munge(sdp, sdp->sd_quota_bitmap, slot, 1);
                        list_add(&qd->qd_list, &sdp->sd_quota_list);
                        atomic_inc(&sdp->sd_quota_count);
-                       spin_unlock(&qd_lru_lock);
+                       spin_unlock(&qd_lock);
 
                        found++;
                }
@@ -1288,30 +1329,34 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
        struct gfs2_quota_data *qd;
        unsigned int x;
 
-       spin_lock(&qd_lru_lock);
+       spin_lock(&qd_lock);
        while (!list_empty(head)) {
                qd = list_entry(head->prev, struct gfs2_quota_data, qd_list);
 
-               if (atomic_read(&qd->qd_count) > 1 ||
-                   (atomic_read(&qd->qd_count) &&
-                    !test_bit(QDF_CHANGE, &qd->qd_flags))) {
+               /*
+                * To be removed in due course... we should be able to
+                * ensure that all refs to the qd have done by this point
+                * so that this rather odd test is not required
+                */
+               spin_lock(&qd->qd_lockref.lock);
+               if (qd->qd_lockref.count > 1 ||
+                   (qd->qd_lockref.count && !test_bit(QDF_CHANGE, &qd->qd_flags))) {
+                       spin_unlock(&qd->qd_lockref.lock);
                        list_move(&qd->qd_list, head);
-                       spin_unlock(&qd_lru_lock);
+                       spin_unlock(&qd_lock);
                        schedule();
-                       spin_lock(&qd_lru_lock);
+                       spin_lock(&qd_lock);
                        continue;
                }
+               spin_unlock(&qd->qd_lockref.lock);
 
                list_del(&qd->qd_list);
                /* Also remove if this qd exists in the reclaim list */
-               if (!list_empty(&qd->qd_reclaim)) {
-                       list_del_init(&qd->qd_reclaim);
-                       atomic_dec(&qd_lru_count);
-               }
+               list_lru_del(&gfs2_qd_lru, &qd->qd_lru);
                atomic_dec(&sdp->sd_quota_count);
-               spin_unlock(&qd_lru_lock);
+               spin_unlock(&qd_lock);
 
-               if (!atomic_read(&qd->qd_count)) {
+               if (!qd->qd_lockref.count) {
                        gfs2_assert_warn(sdp, !qd->qd_change);
                        gfs2_assert_warn(sdp, !qd->qd_slot_count);
                } else
@@ -1321,9 +1366,9 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
                gfs2_glock_put(qd->qd_gl);
                kmem_cache_free(gfs2_quotad_cachep, qd);
 
-               spin_lock(&qd_lru_lock);
+               spin_lock(&qd_lock);
        }
-       spin_unlock(&qd_lru_lock);
+       spin_unlock(&qd_lock);
 
        gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_quota_count));
 
@@ -1462,7 +1507,7 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
        }
        fqs->qs_uquota.qfs_nextents = 1; /* unsupported */
        fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */
-       fqs->qs_incoredqs = atomic_read(&qd_lru_count);
+       fqs->qs_incoredqs = list_lru_count(&gfs2_qd_lru);
        return 0;
 }
 
@@ -1573,10 +1618,12 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
        if (gfs2_is_stuffed(ip))
                alloc_required = 1;
        if (alloc_required) {
+               struct gfs2_alloc_parms ap = { .aflags = 0, };
                gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
                                       &data_blocks, &ind_blocks);
                blocks = 1 + data_blocks + ind_blocks;
-               error = gfs2_inplace_reserve(ip, blocks, 0);
+               ap.target = blocks;
+               error = gfs2_inplace_reserve(ip, &ap);
                if (error)
                        goto out_i;
                blocks += gfs2_rg_blocks(ip, blocks);
index 0f64d9deb1b027c892caaf377ec76681dbbfce4f..96e4f34a03b0d8e8eadf13a330e0e48907416bc6 100644 (file)
 #ifndef __QUOTA_DOT_H__
 #define __QUOTA_DOT_H__
 
+#include <linux/list_lru.h>
+
 struct gfs2_inode;
 struct gfs2_sbd;
-struct shrink_control;
 
 #define NO_UID_QUOTA_CHANGE INVALID_UID
 #define NO_GID_QUOTA_CHANGE INVALID_GID
@@ -53,10 +54,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
        return ret;
 }
 
-extern unsigned long gfs2_qd_shrink_count(struct shrinker *shrink,
-                                         struct shrink_control *sc);
-extern unsigned long gfs2_qd_shrink_scan(struct shrinker *shrink,
-                                        struct shrink_control *sc);
 extern const struct quotactl_ops gfs2_quotactl_ops;
+extern struct shrinker gfs2_qd_shrinker;
+extern struct list_lru gfs2_qd_lru;
 
 #endif /* __QUOTA_DOT_H__ */
index 69317435faa723c9288d390407d9343fb6bf1096..4d83abdd5635273b3e0af9589eec83226be249ff 100644 (file)
@@ -81,11 +81,12 @@ static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone,
                               unsigned char new_state)
 {
        unsigned char *byte1, *byte2, *end, cur_state;
-       unsigned int buflen = rbm->bi->bi_len;
+       struct gfs2_bitmap *bi = rbm_bi(rbm);
+       unsigned int buflen = bi->bi_len;
        const unsigned int bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE;
 
-       byte1 = rbm->bi->bi_bh->b_data + rbm->bi->bi_offset + (rbm->offset / GFS2_NBBY);
-       end = rbm->bi->bi_bh->b_data + rbm->bi->bi_offset + buflen;
+       byte1 = bi->bi_bh->b_data + bi->bi_offset + (rbm->offset / GFS2_NBBY);
+       end = bi->bi_bh->b_data + bi->bi_offset + buflen;
 
        BUG_ON(byte1 >= end);
 
@@ -95,18 +96,17 @@ static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone,
                printk(KERN_WARNING "GFS2: buf_blk = 0x%x old_state=%d, "
                       "new_state=%d\n", rbm->offset, cur_state, new_state);
                printk(KERN_WARNING "GFS2: rgrp=0x%llx bi_start=0x%x\n",
-                      (unsigned long long)rbm->rgd->rd_addr,
-                      rbm->bi->bi_start);
+                      (unsigned long long)rbm->rgd->rd_addr, bi->bi_start);
                printk(KERN_WARNING "GFS2: bi_offset=0x%x bi_len=0x%x\n",
-                      rbm->bi->bi_offset, rbm->bi->bi_len);
+                      bi->bi_offset, bi->bi_len);
                dump_stack();
                gfs2_consist_rgrpd(rbm->rgd);
                return;
        }
        *byte1 ^= (cur_state ^ new_state) << bit;
 
-       if (do_clone && rbm->bi->bi_clone) {
-               byte2 = rbm->bi->bi_clone + rbm->bi->bi_offset + (rbm->offset / GFS2_NBBY);
+       if (do_clone && bi->bi_clone) {
+               byte2 = bi->bi_clone + bi->bi_offset + (rbm->offset / GFS2_NBBY);
                cur_state = (*byte2 >> bit) & GFS2_BIT_MASK;
                *byte2 ^= (cur_state ^ new_state) << bit;
        }
@@ -121,7 +121,8 @@ static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone,
 
 static inline u8 gfs2_testbit(const struct gfs2_rbm *rbm)
 {
-       const u8 *buffer = rbm->bi->bi_bh->b_data + rbm->bi->bi_offset;
+       struct gfs2_bitmap *bi = rbm_bi(rbm);
+       const u8 *buffer = bi->bi_bh->b_data + bi->bi_offset;
        const u8 *byte;
        unsigned int bit;
 
@@ -252,28 +253,52 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len,
 static int gfs2_rbm_from_block(struct gfs2_rbm *rbm, u64 block)
 {
        u64 rblock = block - rbm->rgd->rd_data0;
-       u32 x;
 
        if (WARN_ON_ONCE(rblock > UINT_MAX))
                return -EINVAL;
        if (block >= rbm->rgd->rd_data0 + rbm->rgd->rd_data)
                return -E2BIG;
 
-       rbm->bi = rbm->rgd->rd_bits;
+       rbm->bii = 0;
        rbm->offset = (u32)(rblock);
        /* Check if the block is within the first block */
-       if (rbm->offset < (rbm->bi->bi_start + rbm->bi->bi_len) * GFS2_NBBY)
+       if (rbm->offset < rbm_bi(rbm)->bi_blocks)
                return 0;
 
        /* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */
        rbm->offset += (sizeof(struct gfs2_rgrp) -
                        sizeof(struct gfs2_meta_header)) * GFS2_NBBY;
-       x = rbm->offset / rbm->rgd->rd_sbd->sd_blocks_per_bitmap;
-       rbm->offset -= x * rbm->rgd->rd_sbd->sd_blocks_per_bitmap;
-       rbm->bi += x;
+       rbm->bii = rbm->offset / rbm->rgd->rd_sbd->sd_blocks_per_bitmap;
+       rbm->offset -= rbm->bii * rbm->rgd->rd_sbd->sd_blocks_per_bitmap;
        return 0;
 }
 
+/**
+ * gfs2_rbm_incr - increment an rbm structure
+ * @rbm: The rbm with rgd already set correctly
+ *
+ * This function takes an existing rbm structure and increments it to the next
+ * viable block offset.
+ *
+ * Returns: If incrementing the offset would cause the rbm to go past the
+ *          end of the rgrp, true is returned, otherwise false.
+ *
+ */
+
+static bool gfs2_rbm_incr(struct gfs2_rbm *rbm)
+{
+       if (rbm->offset + 1 < rbm_bi(rbm)->bi_blocks) { /* in the same bitmap */
+               rbm->offset++;
+               return false;
+       }
+       if (rbm->bii == rbm->rgd->rd_length - 1) /* at the last bitmap */
+               return true;
+
+       rbm->offset = 0;
+       rbm->bii++;
+       return false;
+}
+
 /**
  * gfs2_unaligned_extlen - Look for free blocks which are not byte aligned
  * @rbm: Position to search (value/result)
@@ -285,7 +310,6 @@ static int gfs2_rbm_from_block(struct gfs2_rbm *rbm, u64 block)
 
 static bool gfs2_unaligned_extlen(struct gfs2_rbm *rbm, u32 n_unaligned, u32 *len)
 {
-       u64 block;
        u32 n;
        u8 res;
 
@@ -296,8 +320,7 @@ static bool gfs2_unaligned_extlen(struct gfs2_rbm *rbm, u32 n_unaligned, u32 *le
                (*len)--;
                if (*len == 0)
                        return true;
-               block = gfs2_rbm_to_block(rbm);
-               if (gfs2_rbm_from_block(rbm, block + 1))
+               if (gfs2_rbm_incr(rbm))
                        return true;
        }
 
@@ -328,6 +351,7 @@ static u32 gfs2_free_extlen(const struct gfs2_rbm *rrbm, u32 len)
        u32 chunk_size;
        u8 *ptr, *start, *end;
        u64 block;
+       struct gfs2_bitmap *bi;
 
        if (n_unaligned &&
            gfs2_unaligned_extlen(&rbm, 4 - n_unaligned, &len))
@@ -336,11 +360,12 @@ static u32 gfs2_free_extlen(const struct gfs2_rbm *rrbm, u32 len)
        n_unaligned = len & 3;
        /* Start is now byte aligned */
        while (len > 3) {
-               start = rbm.bi->bi_bh->b_data;
-               if (rbm.bi->bi_clone)
-                       start = rbm.bi->bi_clone;
-               end = start + rbm.bi->bi_bh->b_size;
-               start += rbm.bi->bi_offset;
+               bi = rbm_bi(&rbm);
+               start = bi->bi_bh->b_data;
+               if (bi->bi_clone)
+                       start = bi->bi_clone;
+               end = start + bi->bi_bh->b_size;
+               start += bi->bi_offset;
                BUG_ON(rbm.offset & 3);
                start += (rbm.offset / GFS2_NBBY);
                bytes = min_t(u32, len / GFS2_NBBY, (end - start));
@@ -605,11 +630,13 @@ static void __rs_deltree(struct gfs2_blkreserv *rs)
        RB_CLEAR_NODE(&rs->rs_node);
 
        if (rs->rs_free) {
+               struct gfs2_bitmap *bi = rbm_bi(&rs->rs_rbm);
+
                /* 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;
                rs->rs_free = 0;
-               clear_bit(GBF_FULL, &rs->rs_rbm.bi->bi_flags);
+               clear_bit(GBF_FULL, &bi->bi_flags);
                smp_mb__after_clear_bit();
        }
 }
@@ -634,14 +661,13 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
 /**
  * gfs2_rs_delete - delete a multi-block reservation
  * @ip: The inode for this reservation
+ * @wcount: The inode's write count, or NULL
  *
  */
-void gfs2_rs_delete(struct gfs2_inode *ip)
+void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount)
 {
-       struct inode *inode = &ip->i_inode;
-
        down_write(&ip->i_rw_mutex);
-       if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
+       if (ip->i_res && ((wcount == NULL) || (atomic_read(wcount) <= 1))) {
                gfs2_rs_deltree(ip->i_res);
                BUG_ON(ip->i_res->rs_free);
                kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
@@ -743,18 +769,21 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
                        bi->bi_offset = sizeof(struct gfs2_rgrp);
                        bi->bi_start = 0;
                        bi->bi_len = bytes;
+                       bi->bi_blocks = bytes * GFS2_NBBY;
                /* header block */
                } else if (x == 0) {
                        bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_rgrp);
                        bi->bi_offset = sizeof(struct gfs2_rgrp);
                        bi->bi_start = 0;
                        bi->bi_len = bytes;
+                       bi->bi_blocks = bytes * GFS2_NBBY;
                /* last block */
                } else if (x + 1 == length) {
                        bytes = bytes_left;
                        bi->bi_offset = sizeof(struct gfs2_meta_header);
                        bi->bi_start = rgd->rd_bitbytes - bytes_left;
                        bi->bi_len = bytes;
+                       bi->bi_blocks = bytes * GFS2_NBBY;
                /* other blocks */
                } else {
                        bytes = sdp->sd_sb.sb_bsize -
@@ -762,6 +791,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
                        bi->bi_offset = sizeof(struct gfs2_meta_header);
                        bi->bi_start = rgd->rd_bitbytes - bytes_left;
                        bi->bi_len = bytes;
+                       bi->bi_blocks = bytes * GFS2_NBBY;
                }
 
                bytes_left -= bytes;
@@ -1392,12 +1422,12 @@ static void rs_insert(struct gfs2_inode *ip)
  * rg_mblk_search - find a group of multiple free blocks to form a reservation
  * @rgd: the resource group descriptor
  * @ip: pointer to the inode for which we're reserving blocks
- * @requested: number of blocks required for this allocation
+ * @ap: the allocation parameters
  *
  */
 
 static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
-                          unsigned requested)
+                          const struct gfs2_alloc_parms *ap)
 {
        struct gfs2_rbm rbm = { .rgd = rgd, };
        u64 goal;
@@ -1410,7 +1440,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
        if (S_ISDIR(inode->i_mode))
                extlen = 1;
        else {
-               extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested);
+               extlen = max_t(u32, atomic_read(&rs->rs_sizehint), ap->target);
                extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
        }
        if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen))
@@ -1554,14 +1584,14 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext,
                         const struct gfs2_inode *ip, bool nowrap)
 {
        struct buffer_head *bh;
-       struct gfs2_bitmap *initial_bi;
+       int initial_bii;
        u32 initial_offset;
        u32 offset;
        u8 *buffer;
-       int index;
        int n = 0;
        int iters = rbm->rgd->rd_length;
        int ret;
+       struct gfs2_bitmap *bi;
 
        /* 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
@@ -1571,52 +1601,53 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext,
                iters++;
 
        while(1) {
-               if (test_bit(GBF_FULL, &rbm->bi->bi_flags) &&
+               bi = rbm_bi(rbm);
+               if (test_bit(GBF_FULL, &bi->bi_flags) &&
                    (state == GFS2_BLKST_FREE))
                        goto next_bitmap;
 
-               bh = rbm->bi->bi_bh;
-               buffer = bh->b_data + rbm->bi->bi_offset;
+               bh = bi->bi_bh;
+               buffer = bh->b_data + bi->bi_offset;
                WARN_ON(!buffer_uptodate(bh));
-               if (state != GFS2_BLKST_UNLINKED && rbm->bi->bi_clone)
-                       buffer = rbm->bi->bi_clone + rbm->bi->bi_offset;
+               if (state != GFS2_BLKST_UNLINKED && bi->bi_clone)
+                       buffer = bi->bi_clone + bi->bi_offset;
                initial_offset = rbm->offset;
-               offset = gfs2_bitfit(buffer, rbm->bi->bi_len, rbm->offset, state);
+               offset = gfs2_bitfit(buffer, bi->bi_len, rbm->offset, state);
                if (offset == BFITNOENT)
                        goto bitmap_full;
                rbm->offset = offset;
                if (ip == NULL)
                        return 0;
 
-               initial_bi = rbm->bi;
+               initial_bii = rbm->bii;
                ret = gfs2_reservation_check_and_update(rbm, ip, minext);
                if (ret == 0)
                        return 0;
                if (ret > 0) {
-                       n += (rbm->bi - initial_bi);
+                       n += (rbm->bii - initial_bii);
                        goto next_iter;
                }
                if (ret == -E2BIG) {
-                       index = 0;
+                       rbm->bii = 0;
                        rbm->offset = 0;
-                       n += (rbm->bi - initial_bi);
+                       n += (rbm->bii - initial_bii);
                        goto res_covered_end_of_rgrp;
                }
                return ret;
 
 bitmap_full:   /* Mark bitmap as full and fall through */
-               if ((state == GFS2_BLKST_FREE) && initial_offset == 0)
-                       set_bit(GBF_FULL, &rbm->bi->bi_flags);
+               if ((state == GFS2_BLKST_FREE) && initial_offset == 0) {
+                       struct gfs2_bitmap *bi = rbm_bi(rbm);
+                       set_bit(GBF_FULL, &bi->bi_flags);
+               }
 
 next_bitmap:   /* Find next bitmap in the rgrp */
                rbm->offset = 0;
-               index = rbm->bi - rbm->rgd->rd_bits;
-               index++;
-               if (index == rbm->rgd->rd_length)
-                       index = 0;
+               rbm->bii++;
+               if (rbm->bii == rbm->rgd->rd_length)
+                       rbm->bii = 0;
 res_covered_end_of_rgrp:
-               rbm->bi = &rbm->rgd->rd_bits[index];
-               if ((index == 0) && nowrap)
+               if ((rbm->bii == 0) && nowrap)
                        break;
                n++;
 next_iter:
@@ -1645,7 +1676,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
        struct gfs2_inode *ip;
        int error;
        int found = 0;
-       struct gfs2_rbm rbm = { .rgd = rgd, .bi = rgd->rd_bits, .offset = 0 };
+       struct gfs2_rbm rbm = { .rgd = rgd, .bii = 0, .offset = 0 };
 
        while (1) {
                down_write(&sdp->sd_log_flush_lock);
@@ -1800,12 +1831,12 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b
 /**
  * gfs2_inplace_reserve - Reserve space in the filesystem
  * @ip: the inode to reserve space for
- * @requested: the number of blocks to be reserved
+ * @ap: the allocation parameters
  *
  * Returns: errno
  */
 
-int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
+int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_rgrpd *begin = NULL;
@@ -1817,17 +1848,16 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
 
        if (sdp->sd_args.ar_rgrplvb)
                flags |= GL_SKIP;
-       if (gfs2_assert_warn(sdp, requested))
+       if (gfs2_assert_warn(sdp, ap->target))
                return -EINVAL;
        if (gfs2_rs_active(rs)) {
                begin = rs->rs_rbm.rgd;
-               flags = 0; /* Yoda: Do or do not. There is no try */
        } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) {
                rs->rs_rbm.rgd = begin = ip->i_rgd;
        } else {
                rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
        }
-       if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV))
+       if (S_ISDIR(ip->i_inode.i_mode) && (ap->aflags & GFS2_AF_ORLOV))
                skip = gfs2_orlov_skip(ip);
        if (rs->rs_rbm.rgd == NULL)
                return -EBADSLT;
@@ -1869,14 +1899,14 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
 
                /* Get a reservation if we don't already have one */
                if (!gfs2_rs_active(rs))
-                       rg_mblk_search(rs->rs_rbm.rgd, ip, requested);
+                       rg_mblk_search(rs->rs_rbm.rgd, ip, ap);
 
                /* Skip rgrps when we can't get a reservation on first pass */
                if (!gfs2_rs_active(rs) && (loops < 1))
                        goto check_rgrp;
 
                /* If rgrp has enough free space, use it */
-               if (rs->rs_rbm.rgd->rd_free_clone >= requested) {
+               if (rs->rs_rbm.rgd->rd_free_clone >= ap->target) {
                        ip->i_rgd = rs->rs_rbm.rgd;
                        return 0;
                }
@@ -1973,14 +2003,14 @@ static void gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode,
 
        *n = 1;
        block = gfs2_rbm_to_block(rbm);
-       gfs2_trans_add_meta(rbm->rgd->rd_gl, rbm->bi->bi_bh);
+       gfs2_trans_add_meta(rbm->rgd->rd_gl, rbm_bi(rbm)->bi_bh);
        gfs2_setbit(rbm, true, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
        block++;
        while (*n < elen) {
                ret = gfs2_rbm_from_block(&pos, block);
                if (ret || gfs2_testbit(&pos) != GFS2_BLKST_FREE)
                        break;
-               gfs2_trans_add_meta(pos.rgd->rd_gl, pos.bi->bi_bh);
+               gfs2_trans_add_meta(pos.rgd->rd_gl, rbm_bi(&pos)->bi_bh);
                gfs2_setbit(&pos, true, GFS2_BLKST_USED);
                (*n)++;
                block++;
@@ -2001,6 +2031,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
                                     u32 blen, unsigned char new_state)
 {
        struct gfs2_rbm rbm;
+       struct gfs2_bitmap *bi;
 
        rbm.rgd = gfs2_blk2rgrpd(sdp, bstart, 1);
        if (!rbm.rgd) {
@@ -2011,15 +2042,15 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
 
        while (blen--) {
                gfs2_rbm_from_block(&rbm, bstart);
+               bi = rbm_bi(&rbm);
                bstart++;
-               if (!rbm.bi->bi_clone) {
-                       rbm.bi->bi_clone = kmalloc(rbm.bi->bi_bh->b_size,
-                                                  GFP_NOFS | __GFP_NOFAIL);
-                       memcpy(rbm.bi->bi_clone + rbm.bi->bi_offset,
-                              rbm.bi->bi_bh->b_data + rbm.bi->bi_offset,
-                              rbm.bi->bi_len);
+               if (!bi->bi_clone) {
+                       bi->bi_clone = kmalloc(bi->bi_bh->b_size,
+                                              GFP_NOFS | __GFP_NOFAIL);
+                       memcpy(bi->bi_clone + bi->bi_offset,
+                              bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
                }
-               gfs2_trans_add_meta(rbm.rgd->rd_gl, rbm.bi->bi_bh);
+               gfs2_trans_add_meta(rbm.rgd->rd_gl, bi->bi_bh);
                gfs2_setbit(&rbm, false, new_state);
        }
 
@@ -2102,6 +2133,35 @@ out:
        spin_unlock(&rgd->rd_rsspin);
 }
 
+/**
+ * gfs2_set_alloc_start - Set starting point for block allocation
+ * @rbm: The rbm which will be set to the required location
+ * @ip: The gfs2 inode
+ * @dinode: Flag to say if allocation includes a new inode
+ *
+ * This sets the starting point from the reservation if one is active
+ * otherwise it falls back to guessing a start point based on the
+ * inode's goal block or the last allocation point in the rgrp.
+ */
+
+static void gfs2_set_alloc_start(struct gfs2_rbm *rbm,
+                                const struct gfs2_inode *ip, bool dinode)
+{
+       u64 goal;
+
+       if (gfs2_rs_active(ip->i_res)) {
+               *rbm = ip->i_res->rs_rbm;
+               return;
+       }
+
+       if (!dinode && rgrp_contains_block(rbm->rgd, ip->i_goal))
+               goal = ip->i_goal;
+       else
+               goal = rbm->rgd->rd_last_alloc + rbm->rgd->rd_data0;
+
+       gfs2_rbm_from_block(rbm, goal);
+}
+
 /**
  * gfs2_alloc_blocks - Allocate one or more blocks of data and/or a dinode
  * @ip: the inode to allocate the block for
@@ -2120,22 +2180,14 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
        struct buffer_head *dibh;
        struct gfs2_rbm rbm = { .rgd = ip->i_rgd, };
        unsigned int ndata;
-       u64 goal;
        u64 block; /* block, within the file system scope */
        int error;
 
-       if (gfs2_rs_active(ip->i_res))
-               goal = gfs2_rbm_to_block(&ip->i_res->rs_rbm);
-       else if (!dinode && rgrp_contains_block(rbm.rgd, ip->i_goal))
-               goal = ip->i_goal;
-       else
-               goal = rbm.rgd->rd_last_alloc + rbm.rgd->rd_data0;
-
-       gfs2_rbm_from_block(&rbm, goal);
+       gfs2_set_alloc_start(&rbm, ip, dinode);
        error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, 0, ip, false);
 
        if (error == -ENOSPC) {
-               gfs2_rbm_from_block(&rbm, goal);
+               gfs2_set_alloc_start(&rbm, ip, dinode);
                error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, 0, NULL, false);
        }
 
index 5b3f4a896e6ca305c7708478d73286b23ea3e3e5..3a10d2ffbbe7b34e93fd37a8dbc68028b8bfa041 100644 (file)
@@ -40,7 +40,7 @@ extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh);
 extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
 
 #define GFS2_AF_ORLOV 1
-extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 flags);
+extern int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *ap);
 extern void gfs2_inplace_release(struct gfs2_inode *ip);
 
 extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
@@ -48,7 +48,7 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
 
 extern int gfs2_rs_alloc(struct gfs2_inode *ip);
 extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs);
-extern void gfs2_rs_delete(struct gfs2_inode *ip);
+extern void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount);
 extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta);
 extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
 extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
index e5639dec66c49dc7361ff0ed79828301031b675d..35da5b19c0deb62b59e4124ab4566f4dc9279ef9 100644 (file)
@@ -1526,7 +1526,7 @@ out_unlock:
 out:
        /* Case 3 starts here */
        truncate_inode_pages(&inode->i_data, 0);
-       gfs2_rs_delete(ip);
+       gfs2_rs_delete(ip, NULL);
        gfs2_ordered_del_inode(ip);
        clear_inode(inode);
        gfs2_dir_hash_inval(ip);
index aa5c48044966697c2365712ab53a20d7bc5d8958..d09f6edda0ff8d55f31ef04dba7f4720852f7a8d 100644 (file)
@@ -587,7 +587,6 @@ TUNE_ATTR(max_readahead, 0);
 TUNE_ATTR(complain_secs, 0);
 TUNE_ATTR(statfs_slow, 0);
 TUNE_ATTR(new_files_jdata, 0);
-TUNE_ATTR(quota_simul_sync, 1);
 TUNE_ATTR(statfs_quantum, 1);
 TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
 
@@ -597,7 +596,6 @@ static struct attribute *tune_attrs[] = {
        &tune_attr_max_readahead.attr,
        &tune_attr_complain_secs.attr,
        &tune_attr_statfs_slow.attr,
-       &tune_attr_quota_simul_sync.attr,
        &tune_attr_statfs_quantum.attr,
        &tune_attr_quota_scale.attr,
        &tune_attr_new_files_jdata.attr,
index 6402fb69d71bd838d943c4d60d1a8879d15f6217..f7109f689e6132d08b7fcfc6a0c69db63dc0c24f 100644 (file)
@@ -268,23 +268,3 @@ int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
        return rv;
 }
 
-void gfs2_icbit_munge(struct gfs2_sbd *sdp, unsigned char **bitmap,
-                     unsigned int bit, int new_value)
-{
-       unsigned int c, o, b = bit;
-       int old_value;
-
-       c = b / (8 * PAGE_SIZE);
-       b %= 8 * PAGE_SIZE;
-       o = b / 8;
-       b %= 8;
-
-       old_value = (bitmap[c][o] & (1 << b));
-       gfs2_assert_withdraw(sdp, !old_value != !new_value);
-
-       if (new_value)
-               bitmap[c][o] |= 1 << b;
-       else
-               bitmap[c][o] &= ~(1 << b);
-}
-
index 80535739ac7b2c5c1f98ac46e9c2cb4faf5d0eb5..b7ffb09b99ea2d231011b92c21fa64a3e0bcfa6d 100644 (file)
@@ -164,8 +164,6 @@ static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
 #define gfs2_tune_get(sdp, field) \
 gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field)
 
-void gfs2_icbit_munge(struct gfs2_sbd *sdp, unsigned char **bitmap,
-                     unsigned int bit, int new_value);
 int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...);
 
 #endif /* __UTIL_DOT_H__ */
index ecd37f30ab91986923c5fa8c0cdf02f1bd3d330b..8c6a6f6bdba978f9c3b37703a79d4c409516557b 100644 (file)
@@ -723,6 +723,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
                             unsigned int blks,
                             ea_skeleton_call_t skeleton_call, void *private)
 {
+       struct gfs2_alloc_parms ap = { .target = blks };
        struct buffer_head *dibh;
        int error;
 
@@ -734,7 +735,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
        if (error)
                return error;
 
-       error = gfs2_inplace_reserve(ip, blks, 0);
+       error = gfs2_inplace_reserve(ip, &ap);
        if (error)
                goto out_gunlock_q;
 
index b5e80b0af315b065954fe42c2a832e85ff57b23f..38c1768b4142e6508a6805aaa1ff1067f8770381 100644 (file)
@@ -140,6 +140,17 @@ config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN
          If the NFS client is unchanged from the upstream kernel, this
          option should be set to the default "kernel.org".
 
+config NFS_V4_1_MIGRATION
+       bool "NFSv4.1 client support for migration"
+       depends on NFS_V4_1
+       default n
+       help
+         This option makes the NFS client advertise to NFSv4.1 servers that
+          it can support NFSv4 migration.
+
+          The NFSv4.1 pieces of the Linux NFSv4 migration implementation are
+          still experimental.  If you are not an NFSv4 developer, say N here.
+
 config NFS_V4_SECURITY_LABEL
        bool
        depends on NFS_V4_2 && SECURITY
index 67cd73213168f3f7fd5f30b8f217fd22fcc7d7f2..073b4cf67ed9d39690626add5517708debeab021 100644 (file)
@@ -164,8 +164,7 @@ nfs41_callback_up(struct svc_serv *serv)
                svc_xprt_put(serv->sv_bc_xprt);
                serv->sv_bc_xprt = NULL;
        }
-       dprintk("--> %s return %ld\n", __func__,
-               IS_ERR(rqstp) ? PTR_ERR(rqstp) : 0);
+       dprintk("--> %s return %d\n", __func__, PTR_ERR_OR_ZERO(rqstp));
        return rqstp;
 }
 
index 2dceee4db07652fd449ef713037a8a268d864f00..1d09289c8f0e370dd3f45a17a7c077246b23d7da 100644 (file)
@@ -590,6 +590,8 @@ int nfs_create_rpc_client(struct nfs_client *clp,
 
        if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
                args.flags |= RPC_CLNT_CREATE_DISCRTRY;
+       if (test_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags))
+               args.flags |= RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT;
        if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
                args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
        if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
@@ -784,8 +786,10 @@ static int nfs_init_server(struct nfs_server *server,
                goto error;
 
        server->port = data->nfs_server.port;
+       server->auth_info = data->auth_info;
 
-       error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
+       error = nfs_init_server_rpcclient(server, &timeparms,
+                                         data->selected_flavor);
        if (error < 0)
                goto error;
 
@@ -926,6 +930,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
        target->acdirmax = source->acdirmax;
        target->caps = source->caps;
        target->options = source->options;
+       target->auth_info = source->auth_info;
 }
 EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
 
@@ -943,7 +948,7 @@ void nfs_server_insert_lists(struct nfs_server *server)
 }
 EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
 
-static void nfs_server_remove_lists(struct nfs_server *server)
+void nfs_server_remove_lists(struct nfs_server *server)
 {
        struct nfs_client *clp = server->nfs_client;
        struct nfs_net *nn;
@@ -960,6 +965,7 @@ static void nfs_server_remove_lists(struct nfs_server *server)
 
        synchronize_rcu();
 }
+EXPORT_SYMBOL_GPL(nfs_server_remove_lists);
 
 /*
  * Allocate and initialise a server record
index 02b0df769e2db23d18d7787e27066ebaa684bbd0..9a8676f33350d2d2fcd67148dd4fec4b0fd1f1f7 100644 (file)
@@ -1139,7 +1139,13 @@ out_zap_parent:
        if (inode && S_ISDIR(inode->i_mode)) {
                /* Purge readdir caches. */
                nfs_zap_caches(inode);
-               if (dentry->d_flags & DCACHE_DISCONNECTED)
+               /*
+                * We can't d_drop the root of a disconnected tree:
+                * its d_hash is on the s_anon list and d_drop() would hide
+                * it from shrink_dcache_for_unmount(), leading to busy
+                * inodes on unmount and further oopses.
+                */
+               if (IS_ROOT(dentry))
                        goto out_valid;
        }
        /* If we have submounts, don't unhash ! */
@@ -1381,7 +1387,7 @@ static struct nfs_open_context *create_nfs_open_context(struct dentry *dentry, i
 
 static int do_open(struct inode *inode, struct file *filp)
 {
-       nfs_fscache_set_inode_cookie(inode, filp);
+       nfs_fscache_open_file(inode, filp);
        return 0;
 }
 
index 24d1d1c5fcaf9e50b7528d7ef2a9eff6fcf9f018..3ef01f0ba0bcafa2bdfe0c6088e367c12dd76668 100644 (file)
@@ -39,7 +39,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp)
        /* create a cache index for looking up filehandles */
        clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
                                              &nfs_fscache_server_index_def,
-                                             clp);
+                                             clp, true);
        dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
                 clp, clp->fscache);
 }
@@ -139,7 +139,7 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
        /* create a cache index for looking up filehandles */
        nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
                                               &nfs_fscache_super_index_def,
-                                              nfss);
+                                              nfss, true);
        dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
                 nfss, nfss->fscache);
        return;
@@ -178,163 +178,79 @@ void nfs_fscache_release_super_cookie(struct super_block *sb)
 /*
  * Initialise the per-inode cache cookie pointer for an NFS inode.
  */
-void nfs_fscache_init_inode_cookie(struct inode *inode)
+void nfs_fscache_init_inode(struct inode *inode)
 {
-       NFS_I(inode)->fscache = NULL;
-       if (S_ISREG(inode->i_mode))
-               set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
-}
-
-/*
- * Get the per-inode cache cookie for an NFS inode.
- */
-static void nfs_fscache_enable_inode_cookie(struct inode *inode)
-{
-       struct super_block *sb = inode->i_sb;
        struct nfs_inode *nfsi = NFS_I(inode);
 
-       if (nfsi->fscache || !NFS_FSCACHE(inode))
+       nfsi->fscache = NULL;
+       if (!S_ISREG(inode->i_mode))
                return;
-
-       if ((NFS_SB(sb)->options & NFS_OPTION_FSCACHE)) {
-               nfsi->fscache = fscache_acquire_cookie(
-                       NFS_SB(sb)->fscache,
-                       &nfs_fscache_inode_object_def,
-                       nfsi);
-
-               dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n",
-                        sb, nfsi, nfsi->fscache);
-       }
+       nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache,
+                                              &nfs_fscache_inode_object_def,
+                                              nfsi, false);
 }
 
 /*
  * Release a per-inode cookie.
  */
-void nfs_fscache_release_inode_cookie(struct inode *inode)
+void nfs_fscache_clear_inode(struct inode *inode)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
+       struct fscache_cookie *cookie = nfs_i_fscache(inode);
 
-       dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n",
-                nfsi, nfsi->fscache);
+       dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie);
 
-       fscache_relinquish_cookie(nfsi->fscache, 0);
+       fscache_relinquish_cookie(cookie, false);
        nfsi->fscache = NULL;
 }
 
-/*
- * Retire a per-inode cookie, destroying the data attached to it.
- */
-void nfs_fscache_zap_inode_cookie(struct inode *inode)
+static bool nfs_fscache_can_enable(void *data)
 {
-       struct nfs_inode *nfsi = NFS_I(inode);
+       struct inode *inode = data;
 
-       dfprintk(FSCACHE, "NFS: zapping cookie (0x%p/0x%p)\n",
-                nfsi, nfsi->fscache);
-
-       fscache_relinquish_cookie(nfsi->fscache, 1);
-       nfsi->fscache = NULL;
+       return !inode_is_open_for_write(inode);
 }
 
 /*
- * Turn off the cache with regard to a per-inode cookie if opened for writing,
- * invalidating all the pages in the page cache relating to the associated
- * inode to clear the per-page caching.
- */
-static void nfs_fscache_disable_inode_cookie(struct inode *inode)
-{
-       clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
-
-       if (NFS_I(inode)->fscache) {
-               dfprintk(FSCACHE,
-                        "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode));
-
-               /* Need to uncache any pages attached to this inode that
-                * fscache knows about before turning off the cache.
-                */
-               fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode);
-               nfs_fscache_zap_inode_cookie(inode);
-       }
-}
-
-/*
- * wait_on_bit() sleep function for uninterruptible waiting
- */
-static int nfs_fscache_wait_bit(void *flags)
-{
-       schedule();
-       return 0;
-}
-
-/*
- * Lock against someone else trying to also acquire or relinquish a cookie
- */
-static inline void nfs_fscache_inode_lock(struct inode *inode)
-{
-       struct nfs_inode *nfsi = NFS_I(inode);
-
-       while (test_and_set_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags))
-               wait_on_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK,
-                           nfs_fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-}
-
-/*
- * Unlock cookie management lock
- */
-static inline void nfs_fscache_inode_unlock(struct inode *inode)
-{
-       struct nfs_inode *nfsi = NFS_I(inode);
-
-       smp_mb__before_clear_bit();
-       clear_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags);
-       smp_mb__after_clear_bit();
-       wake_up_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK);
-}
-
-/*
- * Decide if we should enable or disable local caching for this inode.
- * - For now, with NFS, only regular files that are open read-only will be able
- *   to use the cache.
- * - May be invoked multiple times in parallel by parallel nfs_open() functions.
- */
-void nfs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
-{
-       if (NFS_FSCACHE(inode)) {
-               nfs_fscache_inode_lock(inode);
-               if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
-                       nfs_fscache_disable_inode_cookie(inode);
-               else
-                       nfs_fscache_enable_inode_cookie(inode);
-               nfs_fscache_inode_unlock(inode);
-       }
-}
-EXPORT_SYMBOL_GPL(nfs_fscache_set_inode_cookie);
-
-/*
- * Replace a per-inode cookie due to revalidation detecting a file having
- * changed on the server.
+ * Enable or disable caching for a file that is being opened as appropriate.
+ * The cookie is allocated when the inode is initialised, but is not enabled at
+ * that time.  Enablement is deferred to file-open time to avoid stat() and
+ * access() thrashing the cache.
+ *
+ * For now, with NFS, only regular files that are open read-only will be able
+ * to use the cache.
+ *
+ * We enable the cache for an inode if we open it read-only and it isn't
+ * currently open for writing.  We disable the cache if the inode is open
+ * write-only.
+ *
+ * The caller uses the file struct to pin i_writecount on the inode before
+ * calling us when a file is opened for writing, so we can make use of that.
+ *
+ * Note that this may be invoked multiple times in parallel by parallel
+ * nfs_open() functions.
  */
-void nfs_fscache_reset_inode_cookie(struct inode *inode)
+void nfs_fscache_open_file(struct inode *inode, struct file *filp)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
-       struct nfs_server *nfss = NFS_SERVER(inode);
-       NFS_IFDEBUG(struct fscache_cookie *old = nfsi->fscache);
+       struct fscache_cookie *cookie = nfs_i_fscache(inode);
 
-       nfs_fscache_inode_lock(inode);
-       if (nfsi->fscache) {
-               /* retire the current fscache cache and get a new one */
-               fscache_relinquish_cookie(nfsi->fscache, 1);
-
-               nfsi->fscache = fscache_acquire_cookie(
-                       nfss->nfs_client->fscache,
-                       &nfs_fscache_inode_object_def,
-                       nfsi);
+       if (!fscache_cookie_valid(cookie))
+               return;
 
-               dfprintk(FSCACHE,
-                        "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n",
-                        nfss, nfsi, old, nfsi->fscache);
+       if (inode_is_open_for_write(inode)) {
+               dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi);
+               clear_bit(NFS_INO_FSCACHE, &nfsi->flags);
+               fscache_disable_cookie(cookie, true);
+               fscache_uncache_all_inode_pages(cookie, inode);
+       } else {
+               dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi);
+               fscache_enable_cookie(cookie, nfs_fscache_can_enable, inode);
+               if (fscache_cookie_enabled(cookie))
+                       set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
        }
-       nfs_fscache_inode_unlock(inode);
 }
+EXPORT_SYMBOL_GPL(nfs_fscache_open_file);
 
 /*
  * Release the caching state associated with a page, if the page isn't busy
@@ -344,12 +260,11 @@ void nfs_fscache_reset_inode_cookie(struct inode *inode)
 int nfs_fscache_release_page(struct page *page, gfp_t gfp)
 {
        if (PageFsCache(page)) {
-               struct nfs_inode *nfsi = NFS_I(page->mapping->host);
-               struct fscache_cookie *cookie = nfsi->fscache;
+               struct fscache_cookie *cookie = nfs_i_fscache(page->mapping->host);
 
                BUG_ON(!cookie);
                dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
-                        cookie, page, nfsi);
+                        cookie, page, NFS_I(page->mapping->host));
 
                if (!fscache_maybe_release_page(cookie, page, gfp))
                        return 0;
@@ -367,13 +282,12 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
  */
 void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode)
 {
-       struct nfs_inode *nfsi = NFS_I(inode);
-       struct fscache_cookie *cookie = nfsi->fscache;
+       struct fscache_cookie *cookie = nfs_i_fscache(inode);
 
        BUG_ON(!cookie);
 
        dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n",
-                cookie, page, nfsi);
+                cookie, page, NFS_I(inode));
 
        fscache_wait_on_page_write(cookie, page);
 
@@ -417,9 +331,9 @@ int __nfs_readpage_from_fscache(struct nfs_open_context *ctx,
 
        dfprintk(FSCACHE,
                 "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n",
-                NFS_I(inode)->fscache, page, page->index, page->flags, inode);
+                nfs_i_fscache(inode), page, page->index, page->flags, inode);
 
-       ret = fscache_read_or_alloc_page(NFS_I(inode)->fscache,
+       ret = fscache_read_or_alloc_page(nfs_i_fscache(inode),
                                         page,
                                         nfs_readpage_from_fscache_complete,
                                         ctx,
@@ -459,9 +373,9 @@ int __nfs_readpages_from_fscache(struct nfs_open_context *ctx,
        int ret;
 
        dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
-                NFS_I(inode)->fscache, npages, inode);
+                nfs_i_fscache(inode), npages, inode);
 
-       ret = fscache_read_or_alloc_pages(NFS_I(inode)->fscache,
+       ret = fscache_read_or_alloc_pages(nfs_i_fscache(inode),
                                          mapping, pages, nr_pages,
                                          nfs_readpage_from_fscache_complete,
                                          ctx,
@@ -506,15 +420,15 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
 
        dfprintk(FSCACHE,
                 "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n",
-                NFS_I(inode)->fscache, page, page->index, page->flags, sync);
+                nfs_i_fscache(inode), page, page->index, page->flags, sync);
 
-       ret = fscache_write_page(NFS_I(inode)->fscache, page, GFP_KERNEL);
+       ret = fscache_write_page(nfs_i_fscache(inode), page, GFP_KERNEL);
        dfprintk(FSCACHE,
                 "NFS:     readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n",
                 page, page->index, page->flags, ret);
 
        if (ret != 0) {
-               fscache_uncache_page(NFS_I(inode)->fscache, page);
+               fscache_uncache_page(nfs_i_fscache(inode), page);
                nfs_add_fscache_stats(inode,
                                      NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1);
                nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
index 4ecb76652eba6059402c0d9e7320e4cdc1603b82..d7fe3e799f2fc0ee4c83f226f5dee1cc72ca0cc7 100644 (file)
@@ -76,11 +76,9 @@ extern void nfs_fscache_release_client_cookie(struct nfs_client *);
 extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
 extern void nfs_fscache_release_super_cookie(struct super_block *);
 
-extern void nfs_fscache_init_inode_cookie(struct inode *);
-extern void nfs_fscache_release_inode_cookie(struct inode *);
-extern void nfs_fscache_zap_inode_cookie(struct inode *);
-extern void nfs_fscache_set_inode_cookie(struct inode *, struct file *);
-extern void nfs_fscache_reset_inode_cookie(struct inode *);
+extern void nfs_fscache_init_inode(struct inode *);
+extern void nfs_fscache_clear_inode(struct inode *);
+extern void nfs_fscache_open_file(struct inode *, struct file *);
 
 extern void __nfs_fscache_invalidate_page(struct page *, struct inode *);
 extern int nfs_fscache_release_page(struct page *, gfp_t);
@@ -187,12 +185,10 @@ static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
 
 static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
 
-static inline void nfs_fscache_init_inode_cookie(struct inode *inode) {}
-static inline void nfs_fscache_release_inode_cookie(struct inode *inode) {}
-static inline void nfs_fscache_zap_inode_cookie(struct inode *inode) {}
-static inline void nfs_fscache_set_inode_cookie(struct inode *inode,
-                                               struct file *filp) {}
-static inline void nfs_fscache_reset_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_init_inode(struct inode *inode) {}
+static inline void nfs_fscache_clear_inode(struct inode *inode) {}
+static inline void nfs_fscache_open_file(struct inode *inode,
+                                        struct file *filp) {}
 
 static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
 {
index eda8879171c47e3225ee6891a77aac70e1531af2..18ab2da4eeb65dbf7c8f7d7b578a35fc5251b0b6 100644 (file)
@@ -122,7 +122,7 @@ void nfs_clear_inode(struct inode *inode)
        WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files));
        nfs_zap_acl_cache(inode);
        nfs_access_zap_cache(inode);
-       nfs_fscache_release_inode_cookie(inode);
+       nfs_fscache_clear_inode(inode);
 }
 EXPORT_SYMBOL_GPL(nfs_clear_inode);
 
@@ -274,12 +274,6 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
        if (label == NULL)
                return;
 
-       if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL) == 0)
-               return;
-
-       if (NFS_SERVER(inode)->nfs_client->cl_minorversion < 2)
-               return;
-
        if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) {
                error = security_inode_notifysecctx(inode, label->label,
                                label->len);
@@ -459,7 +453,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                nfsi->attrtimeo_timestamp = now;
                nfsi->access_cache = RB_ROOT;
 
-               nfs_fscache_init_inode_cookie(inode);
+               nfs_fscache_init_inode(inode);
 
                unlock_new_inode(inode);
        } else
@@ -854,7 +848,7 @@ int nfs_open(struct inode *inode, struct file *filp)
                return PTR_ERR(ctx);
        nfs_file_set_open_context(filp, ctx);
        put_nfs_open_context(ctx);
-       nfs_fscache_set_inode_cookie(inode, filp);
+       nfs_fscache_open_file(inode, filp);
        return 0;
 }
 
@@ -923,6 +917,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
                nfs_zap_acl_cache(inode);
 
+       nfs_setsecurity(inode, fattr, label);
+
        dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
                inode->i_sb->s_id,
                (long long)NFS_FILEID(inode));
@@ -1209,6 +1205,7 @@ u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh)
         * not on the result */
        return nfs_fhandle_hash(fh);
 }
+EXPORT_SYMBOL_GPL(_nfs_display_fhandle_hash);
 
 /*
  * _nfs_display_fhandle - display an NFS file handle on the console
@@ -1253,6 +1250,7 @@ void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption)
                }
        }
 }
+EXPORT_SYMBOL_GPL(_nfs_display_fhandle);
 #endif
 
 /**
index 38da8c2b81ac09d526b3b402d1964e0c7c17c2dc..bca6a3e3c49ce58e9cdfa1552e25afce2158584e 100644 (file)
@@ -88,8 +88,8 @@ struct nfs_parsed_mount_data {
        unsigned int            namlen;
        unsigned int            options;
        unsigned int            bsize;
-       unsigned int            auth_flavor_len;
-       rpc_authflavor_t        auth_flavors[1];
+       struct nfs_auth_info    auth_info;
+       rpc_authflavor_t        selected_flavor;
        char                    *client_address;
        unsigned int            version;
        unsigned int            minorversion;
@@ -154,6 +154,7 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *,
                                  rpc_authflavor_t);
 int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
 void nfs_server_insert_lists(struct nfs_server *);
+void nfs_server_remove_lists(struct nfs_server *);
 void nfs_init_timeout_values(struct rpc_timeout *, int, unsigned int, unsigned int);
 int nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t,
                rpc_authflavor_t);
@@ -174,6 +175,8 @@ extern struct nfs_server *nfs4_create_server(
                                        struct nfs_subversion *);
 extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
                                                      struct nfs_fh *);
+extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
+                                       struct sockaddr *sap, size_t salen);
 extern void nfs_free_server(struct nfs_server *server);
 extern struct nfs_server *nfs_clone_server(struct nfs_server *,
                                           struct nfs_fh *,
@@ -323,6 +326,7 @@ extern struct file_system_type nfs_xdev_fs_type;
 extern struct file_system_type nfs4_xdev_fs_type;
 extern struct file_system_type nfs4_referral_fs_type;
 #endif
+bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t);
 struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
                        struct nfs_subversion *);
 void nfs_initialise_sb(struct super_block *);
index 28842abafab45ad8b351e96f0ba06517b6676b28..3ce79b04522eb19b2ecee294c3a59a2b0c49b4b9 100644 (file)
@@ -29,6 +29,8 @@ enum nfs4_client_state {
        NFS4CLNT_SERVER_SCOPE_MISMATCH,
        NFS4CLNT_PURGE_STATE,
        NFS4CLNT_BIND_CONN_TO_SESSION,
+       NFS4CLNT_MOVED,
+       NFS4CLNT_LEASE_MOVED,
 };
 
 #define NFS4_RENEW_TIMEOUT             0x01
@@ -50,6 +52,7 @@ struct nfs4_minor_version_ops {
        const struct nfs4_state_recovery_ops *reboot_recovery_ops;
        const struct nfs4_state_recovery_ops *nograce_recovery_ops;
        const struct nfs4_state_maintenance_ops *state_renewal_ops;
+       const struct nfs4_mig_recovery_ops *mig_recovery_ops;
 };
 
 #define NFS_SEQID_CONFIRMED 1
@@ -203,6 +206,12 @@ struct nfs4_state_maintenance_ops {
        int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
 };
 
+struct nfs4_mig_recovery_ops {
+       int (*get_locations)(struct inode *, struct nfs4_fs_locations *,
+               struct page *, struct rpc_cred *);
+       int (*fsid_present)(struct inode *, struct rpc_cred *);
+};
+
 extern const struct dentry_operations nfs4_dentry_operations;
 
 /* dir.c */
@@ -213,10 +222,11 @@ int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
 extern struct file_system_type nfs4_fs_type;
 
 /* nfs4namespace.c */
-rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
 struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
 struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
                               struct nfs_fh *, struct nfs_fattr *);
+int nfs4_replace_transport(struct nfs_server *server,
+                               const struct nfs4_fs_locations *locations);
 
 /* nfs4proc.c */
 extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
@@ -231,6 +241,9 @@ extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
 extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
                                  struct nfs4_fs_locations *, struct page *);
+extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
+               struct page *page, struct rpc_cred *);
+extern int nfs4_proc_fsid_present(struct inode *, struct rpc_cred *);
 extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *,
                            struct nfs_fh *, struct nfs_fattr *);
 extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
@@ -411,6 +424,8 @@ extern int nfs4_client_recover_expired_lease(struct nfs_client *clp);
 extern void nfs4_schedule_state_manager(struct nfs_client *);
 extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
 extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
+extern int nfs4_schedule_migration_recovery(const struct nfs_server *);
+extern void nfs4_schedule_lease_moved_recovery(struct nfs_client *);
 extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
 extern void nfs41_handle_server_scope(struct nfs_client *,
                                      struct nfs41_server_scope **);
index a860ab566d6e98e5ce2f2f1c42686a15837254bc..b4a160a405ce2b60f64255433c1555a4284c61e9 100644 (file)
@@ -197,6 +197,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
        clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
        clp->cl_minorversion = cl_init->minorversion;
        clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
+       clp->cl_mig_gen = 1;
        return clp;
 
 error:
@@ -368,6 +369,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
        if (clp->cl_minorversion != 0)
                __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
        __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
+       __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
        error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
        if (error == -EINVAL)
                error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX);
@@ -924,7 +926,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
        dprintk("Server FSID: %llx:%llx\n",
                        (unsigned long long) server->fsid.major,
                        (unsigned long long) server->fsid.minor);
-       dprintk("Mount FH: %d\n", mntfh->size);
+       nfs_display_fhandle(mntfh, "Pseudo-fs root FH");
 
        nfs4_session_set_rwsize(server);
 
@@ -947,9 +949,8 @@ out:
  * Create a version 4 volume record
  */
 static int nfs4_init_server(struct nfs_server *server,
-               const struct nfs_parsed_mount_data *data)
+               struct nfs_parsed_mount_data *data)
 {
-       rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX;
        struct rpc_timeout timeparms;
        int error;
 
@@ -961,9 +962,15 @@ static int nfs4_init_server(struct nfs_server *server,
        /* Initialise the client representation from the mount data */
        server->flags = data->flags;
        server->options = data->options;
+       server->auth_info = data->auth_info;
 
-       if (data->auth_flavor_len >= 1)
-               pseudoflavor = data->auth_flavors[0];
+       /* Use the first specified auth flavor. If this flavor isn't
+        * allowed by the server, use the SECINFO path to try the
+        * other specified flavors */
+       if (data->auth_info.flavor_len >= 1)
+               data->selected_flavor = data->auth_info.flavors[0];
+       else
+               data->selected_flavor = RPC_AUTH_UNIX;
 
        /* Get a client record */
        error = nfs4_set_client(server,
@@ -971,7 +978,7 @@ static int nfs4_init_server(struct nfs_server *server,
                        (const struct sockaddr *)&data->nfs_server.address,
                        data->nfs_server.addrlen,
                        data->client_address,
-                       pseudoflavor,
+                       data->selected_flavor,
                        data->nfs_server.protocol,
                        &timeparms,
                        data->minorversion,
@@ -991,7 +998,8 @@ static int nfs4_init_server(struct nfs_server *server,
 
        server->port = data->nfs_server.port;
 
-       error = nfs_init_server_rpcclient(server, &timeparms, pseudoflavor);
+       error = nfs_init_server_rpcclient(server, &timeparms,
+                                         data->selected_flavor);
 
 error:
        /* Done */
@@ -1018,7 +1026,7 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
-       auth_probe = mount_info->parsed->auth_flavor_len < 1;
+       auth_probe = mount_info->parsed->auth_info.flavor_len < 1;
 
        /* set up the general RPC client */
        error = nfs4_init_server(server, mount_info->parsed);
@@ -1046,6 +1054,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 {
        struct nfs_client *parent_client;
        struct nfs_server *server, *parent_server;
+       bool auth_probe;
        int error;
 
        dprintk("--> nfs4_create_referral_server()\n");
@@ -1078,8 +1087,9 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (error < 0)
                goto error;
 
-       error = nfs4_server_common_setup(server, mntfh,
-                       !(parent_server->flags & NFS_MOUNT_SECFLAVOUR));
+       auth_probe = parent_server->auth_info.flavor_len < 1;
+
+       error = nfs4_server_common_setup(server, mntfh, auth_probe);
        if (error < 0)
                goto error;
 
@@ -1091,3 +1101,111 @@ error:
        dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
        return ERR_PTR(error);
 }
+
+/*
+ * Grab the destination's particulars, including lease expiry time.
+ *
+ * Returns zero if probe succeeded and retrieved FSID matches the FSID
+ * we have cached.
+ */
+static int nfs_probe_destination(struct nfs_server *server)
+{
+       struct inode *inode = server->super->s_root->d_inode;
+       struct nfs_fattr *fattr;
+       int error;
+
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               return -ENOMEM;
+
+       /* Sanity: the probe won't work if the destination server
+        * does not recognize the migrated FH. */
+       error = nfs_probe_fsinfo(server, NFS_FH(inode), fattr);
+
+       nfs_free_fattr(fattr);
+       return error;
+}
+
+/**
+ * nfs4_update_server - Move an nfs_server to a different nfs_client
+ *
+ * @server: represents FSID to be moved
+ * @hostname: new end-point's hostname
+ * @sap: new end-point's socket address
+ * @salen: size of "sap"
+ *
+ * The nfs_server must be quiescent before this function is invoked.
+ * Either its session is drained (NFSv4.1+), or its transport is
+ * plugged and drained (NFSv4.0).
+ *
+ * Returns zero on success, or a negative errno value.
+ */
+int nfs4_update_server(struct nfs_server *server, const char *hostname,
+                      struct sockaddr *sap, size_t salen)
+{
+       struct nfs_client *clp = server->nfs_client;
+       struct rpc_clnt *clnt = server->client;
+       struct xprt_create xargs = {
+               .ident          = clp->cl_proto,
+               .net            = &init_net,
+               .dstaddr        = sap,
+               .addrlen        = salen,
+               .servername     = hostname,
+       };
+       char buf[INET6_ADDRSTRLEN + 1];
+       struct sockaddr_storage address;
+       struct sockaddr *localaddr = (struct sockaddr *)&address;
+       int error;
+
+       dprintk("--> %s: move FSID %llx:%llx to \"%s\")\n", __func__,
+                       (unsigned long long)server->fsid.major,
+                       (unsigned long long)server->fsid.minor,
+                       hostname);
+
+       error = rpc_switch_client_transport(clnt, &xargs, clnt->cl_timeout);
+       if (error != 0) {
+               dprintk("<-- %s(): rpc_switch_client_transport returned %d\n",
+                       __func__, error);
+               goto out;
+       }
+
+       error = rpc_localaddr(clnt, localaddr, sizeof(address));
+       if (error != 0) {
+               dprintk("<-- %s(): rpc_localaddr returned %d\n",
+                       __func__, error);
+               goto out;
+       }
+
+       error = -EAFNOSUPPORT;
+       if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0) {
+               dprintk("<-- %s(): rpc_ntop returned %d\n",
+                       __func__, error);
+               goto out;
+       }
+
+       nfs_server_remove_lists(server);
+       error = nfs4_set_client(server, hostname, sap, salen, buf,
+                               clp->cl_rpcclient->cl_auth->au_flavor,
+                               clp->cl_proto, clnt->cl_timeout,
+                               clp->cl_minorversion, clp->cl_net);
+       nfs_put_client(clp);
+       if (error != 0) {
+               nfs_server_insert_lists(server);
+               dprintk("<-- %s(): nfs4_set_client returned %d\n",
+                       __func__, error);
+               goto out;
+       }
+
+       if (server->nfs_client->cl_hostname == NULL)
+               server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
+       nfs_server_insert_lists(server);
+
+       error = nfs_probe_destination(server);
+       if (error < 0)
+               goto out;
+
+       dprintk("<-- %s() succeeded\n", __func__);
+
+out:
+       return error;
+}
index 77efaf15ec9019a2a6ed4527b214a166796497c4..1f01b55692eeb074c621e9225313c1567867bec5 100644 (file)
@@ -75,7 +75,7 @@ nfs4_file_open(struct inode *inode, struct file *filp)
 
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
        nfs_file_set_open_context(filp, ctx);
-       nfs_fscache_set_inode_cookie(inode, filp);
+       nfs_fscache_open_file(inode, filp);
        err = 0;
 
 out_put_ctx:
index 2288cd3c92784305c9669fe5e87682ad3293c843..c08cbf40c59ebd94b048c29649167b9e65d01d38 100644 (file)
@@ -137,6 +137,7 @@ static size_t nfs_parse_server_name(char *string, size_t len,
 
 /**
  * nfs_find_best_sec - Find a security mechanism supported locally
+ * @server: NFS server struct
  * @flavors: List of security tuples returned by SECINFO procedure
  *
  * Return the pseudoflavor of the first security mechanism in
@@ -145,7 +146,8 @@ static size_t nfs_parse_server_name(char *string, size_t len,
  * is searched in the order returned from the server, per RFC 3530
  * recommendation.
  */
-rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
+static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server,
+                                         struct nfs4_secinfo_flavors *flavors)
 {
        rpc_authflavor_t pseudoflavor;
        struct nfs4_secinfo4 *secinfo;
@@ -160,12 +162,19 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
                case RPC_AUTH_GSS:
                        pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor,
                                                        &secinfo->flavor_info);
-                       if (pseudoflavor != RPC_AUTH_MAXFLAVOR)
+                       /* make sure pseudoflavor matches sec= mount opt */
+                       if (pseudoflavor != RPC_AUTH_MAXFLAVOR &&
+                           nfs_auth_info_match(&server->auth_info,
+                                               pseudoflavor))
                                return pseudoflavor;
                        break;
                }
        }
 
+       /* if there were any sec= options then nothing matched */
+       if (server->auth_info.flavor_len > 0)
+               return -EPERM;
+
        return RPC_AUTH_UNIX;
 }
 
@@ -187,7 +196,7 @@ static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr
                goto out;
        }
 
-       flavor = nfs_find_best_sec(flavors);
+       flavor = nfs_find_best_sec(NFS_SERVER(inode), flavors);
 
 out:
        put_page(page);
@@ -390,7 +399,7 @@ struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry,
 
        if (client->cl_auth->au_flavor != flavor)
                flavor = client->cl_auth->au_flavor;
-       else if (!(server->flags & NFS_MOUNT_SECFLAVOUR)) {
+       else {
                rpc_authflavor_t new = nfs4_negotiate_security(dir, name);
                if ((int)new >= 0)
                        flavor = new;
@@ -400,3 +409,104 @@ out:
        rpc_shutdown_client(client);
        return mnt;
 }
+
+/*
+ * Try one location from the fs_locations array.
+ *
+ * Returns zero on success, or a negative errno value.
+ */
+static int nfs4_try_replacing_one_location(struct nfs_server *server,
+               char *page, char *page2,
+               const struct nfs4_fs_location *location)
+{
+       const size_t addr_bufsize = sizeof(struct sockaddr_storage);
+       struct sockaddr *sap;
+       unsigned int s;
+       size_t salen;
+       int error;
+
+       sap = kmalloc(addr_bufsize, GFP_KERNEL);
+       if (sap == NULL)
+               return -ENOMEM;
+
+       error = -ENOENT;
+       for (s = 0; s < location->nservers; s++) {
+               const struct nfs4_string *buf = &location->servers[s];
+               char *hostname;
+
+               if (buf->len <= 0 || buf->len > PAGE_SIZE)
+                       continue;
+
+               if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len) != NULL)
+                       continue;
+
+               salen = nfs_parse_server_name(buf->data, buf->len,
+                                               sap, addr_bufsize, server);
+               if (salen == 0)
+                       continue;
+               rpc_set_port(sap, NFS_PORT);
+
+               error = -ENOMEM;
+               hostname = kstrndup(buf->data, buf->len, GFP_KERNEL);
+               if (hostname == NULL)
+                       break;
+
+               error = nfs4_update_server(server, hostname, sap, salen);
+               kfree(hostname);
+               if (error == 0)
+                       break;
+       }
+
+       kfree(sap);
+       return error;
+}
+
+/**
+ * nfs4_replace_transport - set up transport to destination server
+ *
+ * @server: export being migrated
+ * @locations: fs_locations array
+ *
+ * Returns zero on success, or a negative errno value.
+ *
+ * The client tries all the entries in the "locations" array, in the
+ * order returned by the server, until one works or the end of the
+ * array is reached.
+ */
+int nfs4_replace_transport(struct nfs_server *server,
+                          const struct nfs4_fs_locations *locations)
+{
+       char *page = NULL, *page2 = NULL;
+       int loc, error;
+
+       error = -ENOENT;
+       if (locations == NULL || locations->nlocations <= 0)
+               goto out;
+
+       error = -ENOMEM;
+       page = (char *) __get_free_page(GFP_USER);
+       if (!page)
+               goto out;
+       page2 = (char *) __get_free_page(GFP_USER);
+       if (!page2)
+               goto out;
+
+       for (loc = 0; loc < locations->nlocations; loc++) {
+               const struct nfs4_fs_location *location =
+                                               &locations->locations[loc];
+
+               if (location == NULL || location->nservers <= 0 ||
+                   location->rootpath.ncomponents == 0)
+                       continue;
+
+               error = nfs4_try_replacing_one_location(server, page,
+                                                       page2, location);
+               if (error == 0)
+                       break;
+       }
+
+out:
+       free_page((unsigned long)page);
+       free_page((unsigned long)page2);
+       return error;
+}
index d53d6785cba27f5c6442831e51eded9d04b054f3..5ab33c0792dfc208d9cdb51e0a0208d77ba22712 100644 (file)
@@ -105,9 +105,6 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
        if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
                return NULL;
 
-       if (NFS_SERVER(dir)->nfs_client->cl_minorversion < 2)
-               return NULL;
-
        err = security_dentry_init_security(dentry, sattr->ia_mode,
                                &dentry->d_name, (void **)&label->label, &label->len);
        if (err == 0)
@@ -384,6 +381,14 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
                case -NFS4ERR_STALE_CLIENTID:
                        nfs4_schedule_lease_recovery(clp);
                        goto wait_on_recovery;
+               case -NFS4ERR_MOVED:
+                       ret = nfs4_schedule_migration_recovery(server);
+                       if (ret < 0)
+                               break;
+                       goto wait_on_recovery;
+               case -NFS4ERR_LEASE_MOVED:
+                       nfs4_schedule_lease_moved_recovery(clp);
+                       goto wait_on_recovery;
 #if defined(CONFIG_NFS_V4_1)
                case -NFS4ERR_BADSESSION:
                case -NFS4ERR_BADSLOT:
@@ -431,6 +436,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
        return nfs4_map_errors(ret);
 wait_on_recovery:
        ret = nfs4_wait_clnt_recover(clp);
+       if (test_bit(NFS_MIG_FAILED, &server->mig_status))
+               return -EIO;
        if (ret == 0)
                exception->retry = 1;
        return ret;
@@ -1318,31 +1325,24 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
        int ret;
 
        if (!data->rpc_done) {
-               ret = data->rpc_status;
-               goto err;
+               if (data->rpc_status) {
+                       ret = data->rpc_status;
+                       goto err;
+               }
+               /* cached opens have already been processed */
+               goto update;
        }
 
-       ret = -ESTALE;
-       if (!(data->f_attr.valid & NFS_ATTR_FATTR_TYPE) ||
-           !(data->f_attr.valid & NFS_ATTR_FATTR_FILEID) ||
-           !(data->f_attr.valid & NFS_ATTR_FATTR_CHANGE))
-               goto err;
-
-       ret = -ENOMEM;
-       state = nfs4_get_open_state(inode, data->owner);
-       if (state == NULL)
-               goto err;
-
        ret = nfs_refresh_inode(inode, &data->f_attr);
        if (ret)
                goto err;
 
-       nfs_setsecurity(inode, &data->f_attr, data->f_label);
-
        if (data->o_res.delegation_type != 0)
                nfs4_opendata_check_deleg(data, state);
+update:
        update_open_stateid(state, &data->o_res.stateid, NULL,
                            data->o_arg.fmode);
+       atomic_inc(&state->count);
 
        return state;
 err:
@@ -1575,6 +1575,12 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
                        /* Don't recall a delegation if it was lost */
                        nfs4_schedule_lease_recovery(server->nfs_client);
                        return -EAGAIN;
+               case -NFS4ERR_MOVED:
+                       nfs4_schedule_migration_recovery(server);
+                       return -EAGAIN;
+               case -NFS4ERR_LEASE_MOVED:
+                       nfs4_schedule_lease_moved_recovery(server->nfs_client);
+                       return -EAGAIN;
                case -NFS4ERR_DELEG_REVOKED:
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_BAD_STATEID:
@@ -2697,6 +2703,10 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
                nfs4_close_state(ctx->state, ctx->mode);
 }
 
+#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
+#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
+#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL)
+
 static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
 {
        struct nfs4_server_caps_arg args = {
@@ -2712,12 +2722,25 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 
        status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
        if (status == 0) {
+               /* Sanity check the server answers */
+               switch (server->nfs_client->cl_minorversion) {
+               case 0:
+                       res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK;
+                       res.attr_bitmask[2] = 0;
+                       break;
+               case 1:
+                       res.attr_bitmask[2] &= FATTR4_WORD2_NFS41_MASK;
+                       break;
+               case 2:
+                       res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK;
+               }
                memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
                server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
                                NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
                                NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
                                NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
-                               NFS_CAP_CTIME|NFS_CAP_MTIME);
+                               NFS_CAP_CTIME|NFS_CAP_MTIME|
+                               NFS_CAP_SECURITY_LABEL);
                if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
                        server->caps |= NFS_CAP_ACLS;
                if (res.has_links != 0)
@@ -2746,14 +2769,12 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 #endif
                memcpy(server->attr_bitmask_nl, res.attr_bitmask,
                                sizeof(server->attr_bitmask));
+               server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
 
-               if (server->caps & NFS_CAP_SECURITY_LABEL) {
-                       server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
-                       res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
-               }
                memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
                server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
                server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
+               server->cache_consistency_bitmask[2] = 0;
                server->acl_bitmask = res.acl_bitmask;
                server->fh_expire_type = res.fh_expire_type;
        }
@@ -2864,11 +2885,24 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
        int status = -EPERM;
        size_t i;
 
-       for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
-               status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
-               if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
-                       continue;
-               break;
+       if (server->auth_info.flavor_len > 0) {
+               /* try each flavor specified by user */
+               for (i = 0; i < server->auth_info.flavor_len; i++) {
+                       status = nfs4_lookup_root_sec(server, fhandle, info,
+                                               server->auth_info.flavors[i]);
+                       if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
+                               continue;
+                       break;
+               }
+       } else {
+               /* no flavors specified by user, try default list */
+               for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
+                       status = nfs4_lookup_root_sec(server, fhandle, info,
+                                                     flav_array[i]);
+                       if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
+                               continue;
+                       break;
+               }
        }
 
        /*
@@ -2910,9 +2944,6 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
                status = nfs4_lookup_root(server, fhandle, info);
                if (status != -NFS4ERR_WRONGSEC)
                        break;
-               /* Did user force a 'sec=' mount option? */
-               if (server->flags & NFS_MOUNT_SECFLAVOUR)
-                       break;
        default:
                status = nfs4_do_find_root_sec(server, fhandle, info);
        }
@@ -2981,11 +3012,16 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir,
        status = nfs4_proc_fs_locations(client, dir, name, locations, page);
        if (status != 0)
                goto out;
-       /* Make sure server returned a different fsid for the referral */
+
+       /*
+        * If the fsid didn't change, this is a migration event, not a
+        * referral.  Cause us to drop into the exception handler, which
+        * will kick off migration recovery.
+        */
        if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
                dprintk("%s: server did not return a different fsid for"
                        " a referral at %s\n", __func__, name->name);
-               status = -EIO;
+               status = -NFS4ERR_MOVED;
                goto out;
        }
        /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */
@@ -3165,9 +3201,6 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
                        err = -EPERM;
                        if (client != *clnt)
                                goto out;
-                       /* No security negotiation if the user specified 'sec=' */
-                       if (NFS_SERVER(dir)->flags & NFS_MOUNT_SECFLAVOUR)
-                               goto out;
                        client = nfs4_create_sec_client(client, dir, name);
                        if (IS_ERR(client))
                                return PTR_ERR(client);
@@ -4221,7 +4254,13 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata)
        unsigned long timestamp = data->timestamp;
 
        trace_nfs4_renew_async(clp, task->tk_status);
-       if (task->tk_status < 0) {
+       switch (task->tk_status) {
+       case 0:
+               break;
+       case -NFS4ERR_LEASE_MOVED:
+               nfs4_schedule_lease_moved_recovery(clp);
+               break;
+       default:
                /* Unless we're shutting down, schedule state recovery! */
                if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0)
                        return;
@@ -4575,7 +4614,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
        struct nfs4_label label = {0, 0, buflen, buf};
 
        u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
-       struct nfs4_getattr_arg args = {
+       struct nfs4_getattr_arg arg = {
                .fh             = NFS_FH(inode),
                .bitmask        = bitmask,
        };
@@ -4586,14 +4625,14 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
        };
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_GETATTR],
-               .rpc_argp       = &args,
+               .rpc_argp       = &arg,
                .rpc_resp       = &res,
        };
        int ret;
 
        nfs_fattr_init(&fattr);
 
-       ret = rpc_call_sync(server->client, &msg, 0);
+       ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 0);
        if (ret)
                return ret;
        if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL))
@@ -4630,7 +4669,7 @@ static int _nfs4_do_set_security_label(struct inode *inode,
        struct iattr sattr = {0};
        struct nfs_server *server = NFS_SERVER(inode);
        const u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
-       struct nfs_setattrargs args = {
+       struct nfs_setattrargs arg = {
                .fh             = NFS_FH(inode),
                .iap            = &sattr,
                .server         = server,
@@ -4644,14 +4683,14 @@ static int _nfs4_do_set_security_label(struct inode *inode,
        };
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_SETATTR],
-               .rpc_argp       = &args,
+               .rpc_argp       = &arg,
                .rpc_resp       = &res,
        };
        int status;
 
-       nfs4_stateid_copy(&args.stateid, &zero_stateid);
+       nfs4_stateid_copy(&arg.stateid, &zero_stateid);
 
-       status = rpc_call_sync(server->client, &msg, 0);
+       status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
        if (status)
                dprintk("%s failed: %d\n", __func__, status);
 
@@ -4735,17 +4774,24 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
                        if (state == NULL)
                                break;
                        if (nfs4_schedule_stateid_recovery(server, state) < 0)
-                               goto stateid_invalid;
+                               goto recovery_failed;
                        goto wait_on_recovery;
                case -NFS4ERR_EXPIRED:
                        if (state != NULL) {
                                if (nfs4_schedule_stateid_recovery(server, state) < 0)
-                                       goto stateid_invalid;
+                                       goto recovery_failed;
                        }
                case -NFS4ERR_STALE_STATEID:
                case -NFS4ERR_STALE_CLIENTID:
                        nfs4_schedule_lease_recovery(clp);
                        goto wait_on_recovery;
+               case -NFS4ERR_MOVED:
+                       if (nfs4_schedule_migration_recovery(server) < 0)
+                               goto recovery_failed;
+                       goto wait_on_recovery;
+               case -NFS4ERR_LEASE_MOVED:
+                       nfs4_schedule_lease_moved_recovery(clp);
+                       goto wait_on_recovery;
 #if defined(CONFIG_NFS_V4_1)
                case -NFS4ERR_BADSESSION:
                case -NFS4ERR_BADSLOT:
@@ -4757,29 +4803,28 @@ 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);
-                       task->tk_status = 0;
-                       return -EAGAIN;
+                       goto restart_call;
 #endif /* CONFIG_NFS_V4_1 */
                case -NFS4ERR_DELAY:
                        nfs_inc_server_stats(server, NFSIOS_DELAY);
                case -NFS4ERR_GRACE:
                        rpc_delay(task, NFS4_POLL_RETRY_MAX);
-                       task->tk_status = 0;
-                       return -EAGAIN;
                case -NFS4ERR_RETRY_UNCACHED_REP:
                case -NFS4ERR_OLD_STATEID:
-                       task->tk_status = 0;
-                       return -EAGAIN;
+                       goto restart_call;
        }
        task->tk_status = nfs4_map_errors(task->tk_status);
        return 0;
-stateid_invalid:
+recovery_failed:
        task->tk_status = -EIO;
        return 0;
 wait_on_recovery:
        rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
        if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
                rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
+       if (test_bit(NFS_MIG_FAILED, &server->mig_status))
+               goto recovery_failed;
+restart_call:
        task->tk_status = 0;
        return -EAGAIN;
 }
@@ -5106,6 +5151,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
                        status = 0;
        }
        request->fl_ops->fl_release_private(request);
+       request->fl_ops = NULL;
 out:
        return status;
 }
@@ -5779,6 +5825,7 @@ struct nfs_release_lockowner_data {
        struct nfs_release_lockowner_args args;
        struct nfs4_sequence_args seq_args;
        struct nfs4_sequence_res seq_res;
+       unsigned long timestamp;
 };
 
 static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata)
@@ -5786,12 +5833,27 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata
        struct nfs_release_lockowner_data *data = calldata;
        nfs40_setup_sequence(data->server,
                                &data->seq_args, &data->seq_res, task);
+       data->timestamp = jiffies;
 }
 
 static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata)
 {
        struct nfs_release_lockowner_data *data = calldata;
+       struct nfs_server *server = data->server;
+
        nfs40_sequence_done(task, &data->seq_res);
+
+       switch (task->tk_status) {
+       case 0:
+               renew_lease(server, data->timestamp);
+               break;
+       case -NFS4ERR_STALE_CLIENTID:
+       case -NFS4ERR_EXPIRED:
+       case -NFS4ERR_LEASE_MOVED:
+       case -NFS4ERR_DELAY:
+               if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN)
+                       rpc_restart_call_prepare(task);
+       }
 }
 
 static void nfs4_release_lockowner_release(void *calldata)
@@ -5990,6 +6052,283 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
        return err;
 }
 
+/*
+ * This operation also signals the server that this client is
+ * performing migration recovery.  The server can stop returning
+ * NFS4ERR_LEASE_MOVED to this client.  A RENEW operation is
+ * appended to this compound to identify the client ID which is
+ * performing recovery.
+ */
+static int _nfs40_proc_get_locations(struct inode *inode,
+                                    struct nfs4_fs_locations *locations,
+                                    struct page *page, struct rpc_cred *cred)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct rpc_clnt *clnt = server->client;
+       u32 bitmask[2] = {
+               [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
+       };
+       struct nfs4_fs_locations_arg args = {
+               .clientid       = server->nfs_client->cl_clientid,
+               .fh             = NFS_FH(inode),
+               .page           = page,
+               .bitmask        = bitmask,
+               .migration      = 1,            /* skip LOOKUP */
+               .renew          = 1,            /* append RENEW */
+       };
+       struct nfs4_fs_locations_res res = {
+               .fs_locations   = locations,
+               .migration      = 1,
+               .renew          = 1,
+       };
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
+               .rpc_argp       = &args,
+               .rpc_resp       = &res,
+               .rpc_cred       = cred,
+       };
+       unsigned long now = jiffies;
+       int status;
+
+       nfs_fattr_init(&locations->fattr);
+       locations->server = server;
+       locations->nlocations = 0;
+
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
+       nfs4_set_sequence_privileged(&args.seq_args);
+       status = nfs4_call_sync_sequence(clnt, server, &msg,
+                                       &args.seq_args, &res.seq_res);
+       if (status)
+               return status;
+
+       renew_lease(server, now);
+       return 0;
+}
+
+#ifdef CONFIG_NFS_V4_1
+
+/*
+ * This operation also signals the server that this client is
+ * performing migration recovery.  The server can stop asserting
+ * SEQ4_STATUS_LEASE_MOVED for this client.  The client ID
+ * performing this operation is identified in the SEQUENCE
+ * operation in this compound.
+ *
+ * When the client supports GETATTR(fs_locations_info), it can
+ * be plumbed in here.
+ */
+static int _nfs41_proc_get_locations(struct inode *inode,
+                                    struct nfs4_fs_locations *locations,
+                                    struct page *page, struct rpc_cred *cred)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct rpc_clnt *clnt = server->client;
+       u32 bitmask[2] = {
+               [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
+       };
+       struct nfs4_fs_locations_arg args = {
+               .fh             = NFS_FH(inode),
+               .page           = page,
+               .bitmask        = bitmask,
+               .migration      = 1,            /* skip LOOKUP */
+       };
+       struct nfs4_fs_locations_res res = {
+               .fs_locations   = locations,
+               .migration      = 1,
+       };
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
+               .rpc_argp       = &args,
+               .rpc_resp       = &res,
+               .rpc_cred       = cred,
+       };
+       int status;
+
+       nfs_fattr_init(&locations->fattr);
+       locations->server = server;
+       locations->nlocations = 0;
+
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
+       nfs4_set_sequence_privileged(&args.seq_args);
+       status = nfs4_call_sync_sequence(clnt, server, &msg,
+                                       &args.seq_args, &res.seq_res);
+       if (status == NFS4_OK &&
+           res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED)
+               status = -NFS4ERR_LEASE_MOVED;
+       return status;
+}
+
+#endif /* CONFIG_NFS_V4_1 */
+
+/**
+ * nfs4_proc_get_locations - discover locations for a migrated FSID
+ * @inode: inode on FSID that is migrating
+ * @locations: result of query
+ * @page: buffer
+ * @cred: credential to use for this operation
+ *
+ * Returns NFS4_OK on success, a negative NFS4ERR status code if the
+ * operation failed, or a negative errno if a local error occurred.
+ *
+ * On success, "locations" is filled in, but if the server has
+ * no locations information, NFS_ATTR_FATTR_V4_LOCATIONS is not
+ * asserted.
+ *
+ * -NFS4ERR_LEASE_MOVED is returned if the server still has leases
+ * from this client that require migration recovery.
+ */
+int nfs4_proc_get_locations(struct inode *inode,
+                           struct nfs4_fs_locations *locations,
+                           struct page *page, struct rpc_cred *cred)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs_client *clp = server->nfs_client;
+       const struct nfs4_mig_recovery_ops *ops =
+                                       clp->cl_mvops->mig_recovery_ops;
+       struct nfs4_exception exception = { };
+       int status;
+
+       dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__,
+               (unsigned long long)server->fsid.major,
+               (unsigned long long)server->fsid.minor,
+               clp->cl_hostname);
+       nfs_display_fhandle(NFS_FH(inode), __func__);
+
+       do {
+               status = ops->get_locations(inode, locations, page, cred);
+               if (status != -NFS4ERR_DELAY)
+                       break;
+               nfs4_handle_exception(server, status, &exception);
+       } while (exception.retry);
+       return status;
+}
+
+/*
+ * This operation also signals the server that this client is
+ * performing "lease moved" recovery.  The server can stop
+ * returning NFS4ERR_LEASE_MOVED to this client.  A RENEW operation
+ * is appended to this compound to identify the client ID which is
+ * performing recovery.
+ */
+static int _nfs40_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
+       struct rpc_clnt *clnt = server->client;
+       struct nfs4_fsid_present_arg args = {
+               .fh             = NFS_FH(inode),
+               .clientid       = clp->cl_clientid,
+               .renew          = 1,            /* append RENEW */
+       };
+       struct nfs4_fsid_present_res res = {
+               .renew          = 1,
+       };
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT],
+               .rpc_argp       = &args,
+               .rpc_resp       = &res,
+               .rpc_cred       = cred,
+       };
+       unsigned long now = jiffies;
+       int status;
+
+       res.fh = nfs_alloc_fhandle();
+       if (res.fh == NULL)
+               return -ENOMEM;
+
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
+       nfs4_set_sequence_privileged(&args.seq_args);
+       status = nfs4_call_sync_sequence(clnt, server, &msg,
+                                               &args.seq_args, &res.seq_res);
+       nfs_free_fhandle(res.fh);
+       if (status)
+               return status;
+
+       do_renew_lease(clp, now);
+       return 0;
+}
+
+#ifdef CONFIG_NFS_V4_1
+
+/*
+ * This operation also signals the server that this client is
+ * performing "lease moved" recovery.  The server can stop asserting
+ * SEQ4_STATUS_LEASE_MOVED for this client.  The client ID performing
+ * this operation is identified in the SEQUENCE operation in this
+ * compound.
+ */
+static int _nfs41_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct rpc_clnt *clnt = server->client;
+       struct nfs4_fsid_present_arg args = {
+               .fh             = NFS_FH(inode),
+       };
+       struct nfs4_fsid_present_res res = {
+       };
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT],
+               .rpc_argp       = &args,
+               .rpc_resp       = &res,
+               .rpc_cred       = cred,
+       };
+       int status;
+
+       res.fh = nfs_alloc_fhandle();
+       if (res.fh == NULL)
+               return -ENOMEM;
+
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
+       nfs4_set_sequence_privileged(&args.seq_args);
+       status = nfs4_call_sync_sequence(clnt, server, &msg,
+                                               &args.seq_args, &res.seq_res);
+       nfs_free_fhandle(res.fh);
+       if (status == NFS4_OK &&
+           res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED)
+               status = -NFS4ERR_LEASE_MOVED;
+       return status;
+}
+
+#endif /* CONFIG_NFS_V4_1 */
+
+/**
+ * nfs4_proc_fsid_present - Is this FSID present or absent on server?
+ * @inode: inode on FSID to check
+ * @cred: credential to use for this operation
+ *
+ * Server indicates whether the FSID is present, moved, or not
+ * recognized.  This operation is necessary to clear a LEASE_MOVED
+ * condition for this client ID.
+ *
+ * Returns NFS4_OK if the FSID is present on this server,
+ * -NFS4ERR_MOVED if the FSID is no longer present, a negative
+ *  NFS4ERR code if some error occurred on the server, or a
+ *  negative errno if a local failure occurred.
+ */
+int nfs4_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs_client *clp = server->nfs_client;
+       const struct nfs4_mig_recovery_ops *ops =
+                                       clp->cl_mvops->mig_recovery_ops;
+       struct nfs4_exception exception = { };
+       int status;
+
+       dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__,
+               (unsigned long long)server->fsid.major,
+               (unsigned long long)server->fsid.minor,
+               clp->cl_hostname);
+       nfs_display_fhandle(NFS_FH(inode), __func__);
+
+       do {
+               status = ops->fsid_present(inode, cred);
+               if (status != -NFS4ERR_DELAY)
+                       break;
+               nfs4_handle_exception(server, status, &exception);
+       } while (exception.retry);
+       return status;
+}
+
 /**
  * If 'use_integrity' is true and the state managment nfs_client
  * cl_rpcclient is using krb5i/p, use the integrity protected cl_rpcclient
@@ -6276,8 +6615,14 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
        struct nfs41_exchange_id_args args = {
                .verifier = &verifier,
                .client = clp,
+#ifdef CONFIG_NFS_V4_1_MIGRATION
                .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
-                       EXCHGID4_FLAG_BIND_PRINC_STATEID,
+                        EXCHGID4_FLAG_BIND_PRINC_STATEID |
+                        EXCHGID4_FLAG_SUPP_MOVED_MIGR,
+#else
+               .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
+                        EXCHGID4_FLAG_BIND_PRINC_STATEID,
+#endif
        };
        struct nfs41_exchange_id_res res = {
                0
@@ -7616,6 +7961,9 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
                        break;
                }
 
+               if (!nfs_auth_info_match(&server->auth_info, flavor))
+                       flavor = RPC_AUTH_MAXFLAVOR;
+
                if (flavor != RPC_AUTH_MAXFLAVOR) {
                        err = nfs4_lookup_root_sec(server, fhandle,
                                                   info, flavor);
@@ -7887,6 +8235,18 @@ static const struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
 };
 #endif
 
+static const struct nfs4_mig_recovery_ops nfs40_mig_recovery_ops = {
+       .get_locations = _nfs40_proc_get_locations,
+       .fsid_present = _nfs40_proc_fsid_present,
+};
+
+#if defined(CONFIG_NFS_V4_1)
+static const struct nfs4_mig_recovery_ops nfs41_mig_recovery_ops = {
+       .get_locations = _nfs41_proc_get_locations,
+       .fsid_present = _nfs41_proc_fsid_present,
+};
+#endif /* CONFIG_NFS_V4_1 */
+
 static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
        .minor_version = 0,
        .init_caps = NFS_CAP_READDIRPLUS
@@ -7902,6 +8262,7 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
        .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
        .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
        .state_renewal_ops = &nfs40_state_renewal_ops,
+       .mig_recovery_ops = &nfs40_mig_recovery_ops,
 };
 
 #if defined(CONFIG_NFS_V4_1)
@@ -7922,6 +8283,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
        .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
        .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
        .state_renewal_ops = &nfs41_state_renewal_ops,
+       .mig_recovery_ops = &nfs41_mig_recovery_ops,
 };
 #endif
 
index cc14cbb78b7322637ae74f6ad013c9183e7a996a..c8e729deb4f711fc38349c2b883f29c7ecb6b407 100644 (file)
@@ -239,8 +239,6 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
        }
 }
 
-#if defined(CONFIG_NFS_V4_1)
-
 static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl)
 {
        set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
@@ -270,6 +268,8 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
        return nfs4_drain_slot_tbl(&ses->fc_slot_table);
 }
 
+#if defined(CONFIG_NFS_V4_1)
+
 static int nfs41_setup_state_renewal(struct nfs_client *clp)
 {
        int status;
@@ -1197,20 +1197,74 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
 }
 EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery);
 
+/**
+ * nfs4_schedule_migration_recovery - trigger migration recovery
+ *
+ * @server: FSID that is migrating
+ *
+ * Returns zero if recovery has started, otherwise a negative NFS4ERR
+ * value is returned.
+ */
+int nfs4_schedule_migration_recovery(const struct nfs_server *server)
+{
+       struct nfs_client *clp = server->nfs_client;
+
+       if (server->fh_expire_type != NFS4_FH_PERSISTENT) {
+               pr_err("NFS: volatile file handles not supported (server %s)\n",
+                               clp->cl_hostname);
+               return -NFS4ERR_IO;
+       }
+
+       if (test_bit(NFS_MIG_FAILED, &server->mig_status))
+               return -NFS4ERR_IO;
+
+       dprintk("%s: scheduling migration recovery for (%llx:%llx) on %s\n",
+                       __func__,
+                       (unsigned long long)server->fsid.major,
+                       (unsigned long long)server->fsid.minor,
+                       clp->cl_hostname);
+
+       set_bit(NFS_MIG_IN_TRANSITION,
+                       &((struct nfs_server *)server)->mig_status);
+       set_bit(NFS4CLNT_MOVED, &clp->cl_state);
+
+       nfs4_schedule_state_manager(clp);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(nfs4_schedule_migration_recovery);
+
+/**
+ * nfs4_schedule_lease_moved_recovery - start lease-moved recovery
+ *
+ * @clp: server to check for moved leases
+ *
+ */
+void nfs4_schedule_lease_moved_recovery(struct nfs_client *clp)
+{
+       dprintk("%s: scheduling lease-moved recovery for client ID %llx on %s\n",
+               __func__, clp->cl_clientid, clp->cl_hostname);
+
+       set_bit(NFS4CLNT_LEASE_MOVED, &clp->cl_state);
+       nfs4_schedule_state_manager(clp);
+}
+EXPORT_SYMBOL_GPL(nfs4_schedule_lease_moved_recovery);
+
 int nfs4_wait_clnt_recover(struct nfs_client *clp)
 {
        int res;
 
        might_sleep();
 
+       atomic_inc(&clp->cl_count);
        res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
                        nfs_wait_bit_killable, TASK_KILLABLE);
        if (res)
-               return res;
-
+               goto out;
        if (clp->cl_cons_state < 0)
-               return clp->cl_cons_state;
-       return 0;
+               res = clp->cl_cons_state;
+out:
+       nfs_put_client(clp);
+       return res;
 }
 
 int nfs4_client_recover_expired_lease(struct nfs_client *clp)
@@ -1375,8 +1429,8 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
                        case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
                                goto out;
                        default:
-                               printk(KERN_ERR "NFS: %s: unhandled error %d. "
-                                       "Zeroing state\n", __func__, status);
+                               printk(KERN_ERR "NFS: %s: unhandled error %d\n",
+                                        __func__, status);
                        case -ENOMEM:
                        case -NFS4ERR_DENIED:
                        case -NFS4ERR_RECLAIM_BAD:
@@ -1422,7 +1476,7 @@ restart:
                if (status >= 0) {
                        status = nfs4_reclaim_locks(state, ops);
                        if (status >= 0) {
-                               if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) {
+                               if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {
                                        spin_lock(&state->state_lock);
                                        list_for_each_entry(lock, &state->lock_states, ls_locks) {
                                                if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
@@ -1439,15 +1493,12 @@ restart:
                }
                switch (status) {
                        default:
-                               printk(KERN_ERR "NFS: %s: unhandled error %d. "
-                                       "Zeroing state\n", __func__, status);
+                               printk(KERN_ERR "NFS: %s: unhandled error %d\n",
+                                       __func__, status);
                        case -ENOENT:
                        case -ENOMEM:
                        case -ESTALE:
-                               /*
-                                * Open state on this file cannot be recovered
-                                * All we can do is revert to using the zero stateid.
-                                */
+                               /* Open state on this file cannot be recovered */
                                nfs4_state_mark_recovery_failed(state, status);
                                break;
                        case -EAGAIN:
@@ -1628,7 +1679,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
                        nfs4_state_end_reclaim_reboot(clp);
                        break;
                case -NFS4ERR_STALE_CLIENTID:
-               case -NFS4ERR_LEASE_MOVED:
                        set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
                        nfs4_state_clear_reclaim_reboot(clp);
                        nfs4_state_start_reclaim_reboot(clp);
@@ -1829,6 +1879,168 @@ static int nfs4_purge_lease(struct nfs_client *clp)
        return 0;
 }
 
+/*
+ * Try remote migration of one FSID from a source server to a
+ * destination server.  The source server provides a list of
+ * potential destinations.
+ *
+ * Returns zero or a negative NFS4ERR status code.
+ */
+static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred)
+{
+       struct nfs_client *clp = server->nfs_client;
+       struct nfs4_fs_locations *locations = NULL;
+       struct inode *inode;
+       struct page *page;
+       int status, result;
+
+       dprintk("--> %s: FSID %llx:%llx on \"%s\"\n", __func__,
+                       (unsigned long long)server->fsid.major,
+                       (unsigned long long)server->fsid.minor,
+                       clp->cl_hostname);
+
+       result = 0;
+       page = alloc_page(GFP_KERNEL);
+       locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
+       if (page == NULL || locations == NULL) {
+               dprintk("<-- %s: no memory\n", __func__);
+               goto out;
+       }
+
+       inode = server->super->s_root->d_inode;
+       result = nfs4_proc_get_locations(inode, locations, page, cred);
+       if (result) {
+               dprintk("<-- %s: failed to retrieve fs_locations: %d\n",
+                       __func__, result);
+               goto out;
+       }
+
+       result = -NFS4ERR_NXIO;
+       if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) {
+               dprintk("<-- %s: No fs_locations data, migration skipped\n",
+                       __func__);
+               goto out;
+       }
+
+       nfs4_begin_drain_session(clp);
+
+       status = nfs4_replace_transport(server, locations);
+       if (status != 0) {
+               dprintk("<-- %s: failed to replace transport: %d\n",
+                       __func__, status);
+               goto out;
+       }
+
+       result = 0;
+       dprintk("<-- %s: migration succeeded\n", __func__);
+
+out:
+       if (page != NULL)
+               __free_page(page);
+       kfree(locations);
+       if (result) {
+               pr_err("NFS: migration recovery failed (server %s)\n",
+                               clp->cl_hostname);
+               set_bit(NFS_MIG_FAILED, &server->mig_status);
+       }
+       return result;
+}
+
+/*
+ * Returns zero or a negative NFS4ERR status code.
+ */
+static int nfs4_handle_migration(struct nfs_client *clp)
+{
+       const struct nfs4_state_maintenance_ops *ops =
+                               clp->cl_mvops->state_renewal_ops;
+       struct nfs_server *server;
+       struct rpc_cred *cred;
+
+       dprintk("%s: migration reported on \"%s\"\n", __func__,
+                       clp->cl_hostname);
+
+       spin_lock(&clp->cl_lock);
+       cred = ops->get_state_renewal_cred_locked(clp);
+       spin_unlock(&clp->cl_lock);
+       if (cred == NULL)
+               return -NFS4ERR_NOENT;
+
+       clp->cl_mig_gen++;
+restart:
+       rcu_read_lock();
+       list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
+               int status;
+
+               if (server->mig_gen == clp->cl_mig_gen)
+                       continue;
+               server->mig_gen = clp->cl_mig_gen;
+
+               if (!test_and_clear_bit(NFS_MIG_IN_TRANSITION,
+                                               &server->mig_status))
+                       continue;
+
+               rcu_read_unlock();
+               status = nfs4_try_migration(server, cred);
+               if (status < 0) {
+                       put_rpccred(cred);
+                       return status;
+               }
+               goto restart;
+       }
+       rcu_read_unlock();
+       put_rpccred(cred);
+       return 0;
+}
+
+/*
+ * Test each nfs_server on the clp's cl_superblocks list to see
+ * if it's moved to another server.  Stop when the server no longer
+ * returns NFS4ERR_LEASE_MOVED.
+ */
+static int nfs4_handle_lease_moved(struct nfs_client *clp)
+{
+       const struct nfs4_state_maintenance_ops *ops =
+                               clp->cl_mvops->state_renewal_ops;
+       struct nfs_server *server;
+       struct rpc_cred *cred;
+
+       dprintk("%s: lease moved reported on \"%s\"\n", __func__,
+                       clp->cl_hostname);
+
+       spin_lock(&clp->cl_lock);
+       cred = ops->get_state_renewal_cred_locked(clp);
+       spin_unlock(&clp->cl_lock);
+       if (cred == NULL)
+               return -NFS4ERR_NOENT;
+
+       clp->cl_mig_gen++;
+restart:
+       rcu_read_lock();
+       list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
+               struct inode *inode;
+               int status;
+
+               if (server->mig_gen == clp->cl_mig_gen)
+                       continue;
+               server->mig_gen = clp->cl_mig_gen;
+
+               rcu_read_unlock();
+
+               inode = server->super->s_root->d_inode;
+               status = nfs4_proc_fsid_present(inode, cred);
+               if (status != -NFS4ERR_MOVED)
+                       goto restart;   /* wasn't this one */
+               if (nfs4_try_migration(server, cred) == -NFS4ERR_LEASE_MOVED)
+                       goto restart;   /* there are more */
+               goto out;
+       }
+       rcu_read_unlock();
+
+out:
+       put_rpccred(cred);
+       return 0;
+}
+
 /**
  * nfs4_discover_server_trunking - Detect server IP address trunking
  *
@@ -2017,9 +2229,10 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
                nfs41_handle_server_reboot(clp);
        if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
                            SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
-                           SEQ4_STATUS_ADMIN_STATE_REVOKED |
-                           SEQ4_STATUS_LEASE_MOVED))
+                           SEQ4_STATUS_ADMIN_STATE_REVOKED))
                nfs41_handle_state_revoked(clp);
+       if (flags & SEQ4_STATUS_LEASE_MOVED)
+               nfs4_schedule_lease_moved_recovery(clp);
        if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
                nfs41_handle_recallable_state_revoked(clp);
        if (flags & SEQ4_STATUS_BACKCHANNEL_FAULT)
@@ -2157,7 +2370,20 @@ static void nfs4_state_manager(struct nfs_client *clp)
                        status = nfs4_check_lease(clp);
                        if (status < 0)
                                goto out_error;
-                       continue;
+               }
+
+               if (test_and_clear_bit(NFS4CLNT_MOVED, &clp->cl_state)) {
+                       section = "migration";
+                       status = nfs4_handle_migration(clp);
+                       if (status < 0)
+                               goto out_error;
+               }
+
+               if (test_and_clear_bit(NFS4CLNT_LEASE_MOVED, &clp->cl_state)) {
+                       section = "lease moved";
+                       status = nfs4_handle_lease_moved(clp);
+                       if (status < 0)
+                               goto out_error;
                }
 
                /* First recover reboot state... */
index e26acdd1a6456c2e4dc62410f191a720f18babd7..65ab0a0ca1c47242090bc14dc97e9cf1fcec525a 100644 (file)
@@ -261,9 +261,9 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
 
        res = nfs_follow_remote_path(root_mnt, export_path);
 
-       dfprintk(MOUNT, "<-- nfs4_try_mount() = %ld%s\n",
-                       IS_ERR(res) ? PTR_ERR(res) : 0,
-                       IS_ERR(res) ? " [error]" : "");
+       dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n",
+                PTR_ERR_OR_ZERO(res),
+                IS_ERR(res) ? " [error]" : "");
        return res;
 }
 
@@ -319,9 +319,9 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
        data->mnt_path = export_path;
 
        res = nfs_follow_remote_path(root_mnt, export_path);
-       dprintk("<-- nfs4_referral_mount() = %ld%s\n",
-                       IS_ERR(res) ? PTR_ERR(res) : 0,
-                       IS_ERR(res) ? " [error]" : "");
+       dprintk("<-- nfs4_referral_mount() = %d%s\n",
+               PTR_ERR_OR_ZERO(res),
+               IS_ERR(res) ? " [error]" : "");
        return res;
 }
 
index 79210d23f60770cfc3e7ede9d4156a299f45ee01..5be2868c02f15e63c33eaea848f077e1e7b3d889 100644 (file)
@@ -105,12 +105,8 @@ static int nfs4_stat_to_errno(int);
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
 /* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */
 #define        nfs4_label_maxsz        (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN))
-#define encode_readdir_space 24
-#define encode_readdir_bitmask_sz 3
 #else
 #define        nfs4_label_maxsz        0
-#define encode_readdir_space 20
-#define encode_readdir_bitmask_sz 2
 #endif
 /* We support only one layout type per file system */
 #define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
@@ -595,11 +591,13 @@ static int nfs4_stat_to_errno(int);
 #define NFS4_enc_getattr_sz    (compound_encode_hdr_maxsz + \
                                encode_sequence_maxsz + \
                                encode_putfh_maxsz + \
-                               encode_getattr_maxsz)
+                               encode_getattr_maxsz + \
+                               encode_renew_maxsz)
 #define NFS4_dec_getattr_sz    (compound_decode_hdr_maxsz + \
                                decode_sequence_maxsz + \
                                decode_putfh_maxsz + \
-                               decode_getattr_maxsz)
+                               decode_getattr_maxsz + \
+                               decode_renew_maxsz)
 #define NFS4_enc_lookup_sz     (compound_encode_hdr_maxsz + \
                                encode_sequence_maxsz + \
                                encode_putfh_maxsz + \
@@ -736,13 +734,15 @@ static int nfs4_stat_to_errno(int);
                                 encode_sequence_maxsz + \
                                 encode_putfh_maxsz + \
                                 encode_lookup_maxsz + \
-                                encode_fs_locations_maxsz)
+                                encode_fs_locations_maxsz + \
+                                encode_renew_maxsz)
 #define NFS4_dec_fs_locations_sz \
                                (compound_decode_hdr_maxsz + \
                                 decode_sequence_maxsz + \
                                 decode_putfh_maxsz + \
                                 decode_lookup_maxsz + \
-                                decode_fs_locations_maxsz)
+                                decode_fs_locations_maxsz + \
+                                decode_renew_maxsz)
 #define NFS4_enc_secinfo_sz    (compound_encode_hdr_maxsz + \
                                encode_sequence_maxsz + \
                                encode_putfh_maxsz + \
@@ -751,6 +751,18 @@ static int nfs4_stat_to_errno(int);
                                decode_sequence_maxsz + \
                                decode_putfh_maxsz + \
                                decode_secinfo_maxsz)
+#define NFS4_enc_fsid_present_sz \
+                               (compound_encode_hdr_maxsz + \
+                                encode_sequence_maxsz + \
+                                encode_putfh_maxsz + \
+                                encode_getfh_maxsz + \
+                                encode_renew_maxsz)
+#define NFS4_dec_fsid_present_sz \
+                               (compound_decode_hdr_maxsz + \
+                                decode_sequence_maxsz + \
+                                decode_putfh_maxsz + \
+                                decode_getfh_maxsz + \
+                                decode_renew_maxsz)
 #if defined(CONFIG_NFS_V4_1)
 #define NFS4_enc_bind_conn_to_session_sz \
                                (compound_encode_hdr_maxsz + \
@@ -1565,6 +1577,8 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
        };
        uint32_t dircount = readdir->count >> 1;
        __be32 *p, verf[2];
+       uint32_t attrlen = 0;
+       unsigned int i;
 
        if (readdir->plus) {
                attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
@@ -1573,26 +1587,27 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
                        FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
                        FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
                        FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
+               attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
                dircount >>= 1;
        }
        /* Use mounted_on_fileid only if the server supports it */
        if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
                attrs[0] |= FATTR4_WORD0_FILEID;
+       for (i = 0; i < ARRAY_SIZE(attrs); i++) {
+               attrs[i] &= readdir->bitmask[i];
+               if (attrs[i] != 0)
+                       attrlen = i+1;
+       }
 
        encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr);
        encode_uint64(xdr, readdir->cookie);
        encode_nfs4_verifier(xdr, &readdir->verifier);
-       p = reserve_space(xdr, encode_readdir_space);
+       p = reserve_space(xdr, 12 + (attrlen << 2));
        *p++ = cpu_to_be32(dircount);
        *p++ = cpu_to_be32(readdir->count);
-       *p++ = cpu_to_be32(encode_readdir_bitmask_sz);
-       *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]);
-       *p   = cpu_to_be32(attrs[1] & readdir->bitmask[1]);
-       if (encode_readdir_bitmask_sz > 2) {
-               if (hdr->minorversion > 1)
-                       attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
-               p++, *p++ = cpu_to_be32(attrs[2] & readdir->bitmask[2]);
-       }
+       *p++ = cpu_to_be32(attrlen);
+       for (i = 0; i < attrlen; i++)
+               *p++ = cpu_to_be32(attrs[i]);
        memcpy(verf, readdir->verifier.data, sizeof(verf));
 
        dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n",
@@ -2687,11 +2702,20 @@ static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req,
 
        encode_compound_hdr(xdr, req, &hdr);
        encode_sequence(xdr, &args->seq_args, &hdr);
-       encode_putfh(xdr, args->dir_fh, &hdr);
-       encode_lookup(xdr, args->name, &hdr);
-       replen = hdr.replen;    /* get the attribute into args->page */
-       encode_fs_locations(xdr, args->bitmask, &hdr);
+       if (args->migration) {
+               encode_putfh(xdr, args->fh, &hdr);
+               replen = hdr.replen;
+               encode_fs_locations(xdr, args->bitmask, &hdr);
+               if (args->renew)
+                       encode_renew(xdr, args->clientid, &hdr);
+       } else {
+               encode_putfh(xdr, args->dir_fh, &hdr);
+               encode_lookup(xdr, args->name, &hdr);
+               replen = hdr.replen;
+               encode_fs_locations(xdr, args->bitmask, &hdr);
+       }
 
+       /* Set up reply kvec to capture returned fs_locations array. */
        xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page,
                        0, PAGE_SIZE);
        encode_nops(&hdr);
@@ -2715,6 +2739,26 @@ static void nfs4_xdr_enc_secinfo(struct rpc_rqst *req,
        encode_nops(&hdr);
 }
 
+/*
+ * Encode FSID_PRESENT request
+ */
+static void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req,
+                                     struct xdr_stream *xdr,
+                                     struct nfs4_fsid_present_arg *args)
+{
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->seq_args, &hdr);
+       encode_putfh(xdr, args->fh, &hdr);
+       encode_getfh(xdr, &hdr);
+       if (args->renew)
+               encode_renew(xdr, args->clientid, &hdr);
+       encode_nops(&hdr);
+}
+
 #if defined(CONFIG_NFS_V4_1)
 /*
  * BIND_CONN_TO_SESSION request
@@ -6824,13 +6868,26 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
        status = decode_putfh(xdr);
        if (status)
                goto out;
-       status = decode_lookup(xdr);
-       if (status)
-               goto out;
-       xdr_enter_page(xdr, PAGE_SIZE);
-       status = decode_getfattr_generic(xdr, &res->fs_locations->fattr,
+       if (res->migration) {
+               xdr_enter_page(xdr, PAGE_SIZE);
+               status = decode_getfattr_generic(xdr,
+                                       &res->fs_locations->fattr,
+                                        NULL, res->fs_locations,
+                                        NULL, res->fs_locations->server);
+               if (status)
+                       goto out;
+               if (res->renew)
+                       status = decode_renew(xdr);
+       } else {
+               status = decode_lookup(xdr);
+               if (status)
+                       goto out;
+               xdr_enter_page(xdr, PAGE_SIZE);
+               status = decode_getfattr_generic(xdr,
+                                       &res->fs_locations->fattr,
                                         NULL, res->fs_locations,
                                         NULL, res->fs_locations->server);
+       }
 out:
        return status;
 }
@@ -6859,6 +6916,34 @@ out:
        return status;
 }
 
+/*
+ * Decode FSID_PRESENT response
+ */
+static int nfs4_xdr_dec_fsid_present(struct rpc_rqst *rqstp,
+                                    struct xdr_stream *xdr,
+                                    struct nfs4_fsid_present_res *res)
+{
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->seq_res, rqstp);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+       status = decode_getfh(xdr, res->fh);
+       if (status)
+               goto out;
+       if (res->renew)
+               status = decode_renew(xdr);
+out:
+       return status;
+}
+
 #if defined(CONFIG_NFS_V4_1)
 /*
  * Decode BIND_CONN_TO_SESSION response
@@ -7373,6 +7458,7 @@ struct rpc_procinfo       nfs4_procedures[] = {
        PROC(FS_LOCATIONS,      enc_fs_locations,       dec_fs_locations),
        PROC(RELEASE_LOCKOWNER, enc_release_lockowner,  dec_release_lockowner),
        PROC(SECINFO,           enc_secinfo,            dec_secinfo),
+       PROC(FSID_PRESENT,      enc_fsid_present,       dec_fsid_present),
 #if defined(CONFIG_NFS_V4_1)
        PROC(EXCHANGE_ID,       enc_exchange_id,        dec_exchange_id),
        PROC(CREATE_SESSION,    enc_create_session,     dec_create_session),
index a03b9c6f94895c4bec17b7191aac69a190d3e35f..317d6fc2160ebe787714e0f0ac6cb5288b0527b7 100644 (file)
@@ -497,7 +497,8 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
        static const struct {
                rpc_authflavor_t flavour;
                const char *str;
-       } sec_flavours[] = {
+       } sec_flavours[NFS_AUTH_INFO_MAX_FLAVORS] = {
+               /* update NFS_AUTH_INFO_MAX_FLAVORS when this list changes! */
                { RPC_AUTH_NULL, "null" },
                { RPC_AUTH_UNIX, "sys" },
                { RPC_AUTH_GSS_KRB5, "krb5" },
@@ -923,8 +924,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
                data->mount_server.port = NFS_UNSPEC_PORT;
                data->nfs_server.port   = NFS_UNSPEC_PORT;
                data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
-               data->auth_flavors[0]   = RPC_AUTH_MAXFLAVOR;
-               data->auth_flavor_len   = 0;
+               data->selected_flavor   = RPC_AUTH_MAXFLAVOR;
                data->minorversion      = 0;
                data->need_mount        = true;
                data->net               = current->nsproxy->net_ns;
@@ -1019,12 +1019,51 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
        }
 }
 
-static void nfs_set_auth_parsed_mount_data(struct nfs_parsed_mount_data *data,
-               rpc_authflavor_t pseudoflavor)
+/*
+ * Add 'flavor' to 'auth_info' if not already present.
+ * Returns true if 'flavor' ends up in the list, false otherwise
+ */
+static bool nfs_auth_info_add(struct nfs_auth_info *auth_info,
+                             rpc_authflavor_t flavor)
+{
+       unsigned int i;
+       unsigned int max_flavor_len = (sizeof(auth_info->flavors) /
+                                      sizeof(auth_info->flavors[0]));
+
+       /* make sure this flavor isn't already in the list */
+       for (i = 0; i < auth_info->flavor_len; i++) {
+               if (flavor == auth_info->flavors[i])
+                       return true;
+       }
+
+       if (auth_info->flavor_len + 1 >= max_flavor_len) {
+               dfprintk(MOUNT, "NFS: too many sec= flavors\n");
+               return false;
+       }
+
+       auth_info->flavors[auth_info->flavor_len++] = flavor;
+       return true;
+}
+
+/*
+ * Return true if 'match' is in auth_info or auth_info is empty.
+ * Return false otherwise.
+ */
+bool nfs_auth_info_match(const struct nfs_auth_info *auth_info,
+                        rpc_authflavor_t match)
 {
-       data->auth_flavors[0] = pseudoflavor;
-       data->auth_flavor_len = 1;
+       int i;
+
+       if (!auth_info->flavor_len)
+               return true;
+
+       for (i = 0; i < auth_info->flavor_len; i++) {
+               if (auth_info->flavors[i] == match)
+                       return true;
+       }
+       return false;
 }
+EXPORT_SYMBOL_GPL(nfs_auth_info_match);
 
 /*
  * Parse the value of the 'sec=' option.
@@ -1034,49 +1073,55 @@ static int nfs_parse_security_flavors(char *value,
 {
        substring_t args[MAX_OPT_ARGS];
        rpc_authflavor_t pseudoflavor;
+       char *p;
 
        dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value);
 
-       switch (match_token(value, nfs_secflavor_tokens, args)) {
-       case Opt_sec_none:
-               pseudoflavor = RPC_AUTH_NULL;
-               break;
-       case Opt_sec_sys:
-               pseudoflavor = RPC_AUTH_UNIX;
-               break;
-       case Opt_sec_krb5:
-               pseudoflavor = RPC_AUTH_GSS_KRB5;
-               break;
-       case Opt_sec_krb5i:
-               pseudoflavor = RPC_AUTH_GSS_KRB5I;
-               break;
-       case Opt_sec_krb5p:
-               pseudoflavor = RPC_AUTH_GSS_KRB5P;
-               break;
-       case Opt_sec_lkey:
-               pseudoflavor = RPC_AUTH_GSS_LKEY;
-               break;
-       case Opt_sec_lkeyi:
-               pseudoflavor = RPC_AUTH_GSS_LKEYI;
-               break;
-       case Opt_sec_lkeyp:
-               pseudoflavor = RPC_AUTH_GSS_LKEYP;
-               break;
-       case Opt_sec_spkm:
-               pseudoflavor = RPC_AUTH_GSS_SPKM;
-               break;
-       case Opt_sec_spkmi:
-               pseudoflavor = RPC_AUTH_GSS_SPKMI;
-               break;
-       case Opt_sec_spkmp:
-               pseudoflavor = RPC_AUTH_GSS_SPKMP;
-               break;
-       default:
-               return 0;
+       while ((p = strsep(&value, ":")) != NULL) {
+               switch (match_token(p, nfs_secflavor_tokens, args)) {
+               case Opt_sec_none:
+                       pseudoflavor = RPC_AUTH_NULL;
+                       break;
+               case Opt_sec_sys:
+                       pseudoflavor = RPC_AUTH_UNIX;
+                       break;
+               case Opt_sec_krb5:
+                       pseudoflavor = RPC_AUTH_GSS_KRB5;
+                       break;
+               case Opt_sec_krb5i:
+                       pseudoflavor = RPC_AUTH_GSS_KRB5I;
+                       break;
+               case Opt_sec_krb5p:
+                       pseudoflavor = RPC_AUTH_GSS_KRB5P;
+                       break;
+               case Opt_sec_lkey:
+                       pseudoflavor = RPC_AUTH_GSS_LKEY;
+                       break;
+               case Opt_sec_lkeyi:
+                       pseudoflavor = RPC_AUTH_GSS_LKEYI;
+                       break;
+               case Opt_sec_lkeyp:
+                       pseudoflavor = RPC_AUTH_GSS_LKEYP;
+                       break;
+               case Opt_sec_spkm:
+                       pseudoflavor = RPC_AUTH_GSS_SPKM;
+                       break;
+               case Opt_sec_spkmi:
+                       pseudoflavor = RPC_AUTH_GSS_SPKMI;
+                       break;
+               case Opt_sec_spkmp:
+                       pseudoflavor = RPC_AUTH_GSS_SPKMP;
+                       break;
+               default:
+                       dfprintk(MOUNT,
+                                "NFS: sec= option '%s' not recognized\n", p);
+                       return 0;
+               }
+
+               if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor))
+                       return 0;
        }
 
-       mnt->flags |= NFS_MOUNT_SECFLAVOUR;
-       nfs_set_auth_parsed_mount_data(mnt, pseudoflavor);
        return 1;
 }
 
@@ -1623,12 +1668,14 @@ out_security_failure:
 }
 
 /*
- * Ensure that the specified authtype in args->auth_flavors[0] is supported by
- * the server. Returns 0 if it's ok, and -EACCES if not.
+ * Ensure that a specified authtype in args->auth_info is supported by
+ * the server. Returns 0 and sets args->selected_flavor if it's ok, and
+ * -EACCES if not.
  */
-static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args,
+static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args,
                        rpc_authflavor_t *server_authlist, unsigned int count)
 {
+       rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR;
        unsigned int i;
 
        /*
@@ -1640,17 +1687,20 @@ static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args,
         * can be used.
         */
        for (i = 0; i < count; i++) {
-               if (args->auth_flavors[0] == server_authlist[i] ||
-                   server_authlist[i] == RPC_AUTH_NULL)
+               flavor = server_authlist[i];
+
+               if (nfs_auth_info_match(&args->auth_info, flavor) ||
+                   flavor == RPC_AUTH_NULL)
                        goto out;
        }
 
-       dfprintk(MOUNT, "NFS: auth flavor %u not supported by server\n",
-               args->auth_flavors[0]);
+       dfprintk(MOUNT,
+                "NFS: specified auth flavors not supported by server\n");
        return -EACCES;
 
 out:
-       dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
+       args->selected_flavor = flavor;
+       dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor);
        return 0;
 }
 
@@ -1738,9 +1788,10 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
         * Was a sec= authflavor specified in the options? First, verify
         * whether the server supports it, and then just try to use it if so.
         */
-       if (args->auth_flavor_len > 0) {
-               status = nfs_verify_authflavor(args, authlist, authlist_len);
-               dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
+       if (args->auth_info.flavor_len > 0) {
+               status = nfs_verify_authflavors(args, authlist, authlist_len);
+               dfprintk(MOUNT, "NFS: using auth flavor %u\n",
+                        args->selected_flavor);
                if (status)
                        return ERR_PTR(status);
                return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
@@ -1769,7 +1820,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
                        /* Fallthrough */
                }
                dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
-               nfs_set_auth_parsed_mount_data(args, flavor);
+               args->selected_flavor = flavor;
                server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
                if (!IS_ERR(server))
                        return server;
@@ -1785,7 +1836,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
 
        /* Last chance! Try AUTH_UNIX */
        dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
-       nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
+       args->selected_flavor = RPC_AUTH_UNIX;
        return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
 }
 
@@ -1972,9 +2023,9 @@ static int nfs23_validate_mount_data(void *options,
                args->bsize             = data->bsize;
 
                if (data->flags & NFS_MOUNT_SECFLAVOUR)
-                       nfs_set_auth_parsed_mount_data(args, data->pseudoflavor);
+                       args->selected_flavor = data->pseudoflavor;
                else
-                       nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
+                       args->selected_flavor = RPC_AUTH_UNIX;
                if (!args->nfs_server.hostname)
                        goto out_nomem;
 
@@ -2108,9 +2159,6 @@ static int nfs_validate_text_mount_data(void *options,
 
        nfs_set_port(sap, &args->nfs_server.port, port);
 
-       if (args->auth_flavor_len > 1)
-               goto out_bad_auth;
-
        return nfs_parse_devname(dev_name,
                                   &args->nfs_server.hostname,
                                   max_namelen,
@@ -2130,10 +2178,6 @@ out_invalid_transport_udp:
 out_no_address:
        dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
        return -EINVAL;
-
-out_bad_auth:
-       dfprintk(MOUNT, "NFS: Too many RPC auth flavours specified\n");
-       return -EINVAL;
 }
 
 static int
@@ -2143,8 +2187,10 @@ nfs_compare_remount_data(struct nfs_server *nfss,
        if (data->flags != nfss->flags ||
            data->rsize != nfss->rsize ||
            data->wsize != nfss->wsize ||
+           data->version != nfss->nfs_client->rpc_ops->version ||
+           data->minorversion != nfss->nfs_client->cl_minorversion ||
            data->retrans != nfss->client->cl_timeout->to_retries ||
-           data->auth_flavors[0] != nfss->client->cl_auth->au_flavor ||
+           data->selected_flavor != nfss->client->cl_auth->au_flavor ||
            data->acregmin != nfss->acregmin / HZ ||
            data->acregmax != nfss->acregmax / HZ ||
            data->acdirmin != nfss->acdirmin / HZ ||
@@ -2189,7 +2235,8 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
        data->rsize = nfss->rsize;
        data->wsize = nfss->wsize;
        data->retrans = nfss->client->cl_timeout->to_retries;
-       nfs_set_auth_parsed_mount_data(data, nfss->client->cl_auth->au_flavor);
+       data->selected_flavor = nfss->client->cl_auth->au_flavor;
+       data->auth_info = nfss->auth_info;
        data->acregmin = nfss->acregmin / HZ;
        data->acregmax = nfss->acregmax / HZ;
        data->acdirmin = nfss->acdirmin / HZ;
@@ -2197,12 +2244,14 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
        data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
        data->nfs_server.port = nfss->port;
        data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
+       data->version = nfsvers;
+       data->minorversion = nfss->nfs_client->cl_minorversion;
        memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
                data->nfs_server.addrlen);
 
        /* overwrite those values with any that were specified */
-       error = nfs_parse_mount_options((char *)options, data);
-       if (error < 0)
+       error = -EINVAL;
+       if (!nfs_parse_mount_options((char *)options, data))
                goto out;
 
        /*
@@ -2332,7 +2381,7 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
                goto Ebusy;
        if (a->acdirmax != b->acdirmax)
                goto Ebusy;
-       if (b->flags & NFS_MOUNT_SECFLAVOUR &&
+       if (b->auth_info.flavor_len > 0 &&
           clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
                goto Ebusy;
        return 1;
@@ -2530,6 +2579,7 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
                        mntroot = ERR_PTR(error);
                        goto error_splat_bdi;
                }
+               server->super = s;
        }
 
        if (!s->s_root) {
@@ -2713,9 +2763,9 @@ static int nfs4_validate_mount_data(void *options,
                                           data->auth_flavours,
                                           sizeof(pseudoflavor)))
                                return -EFAULT;
-                       nfs_set_auth_parsed_mount_data(args, pseudoflavor);
+                       args->selected_flavor = pseudoflavor;
                } else
-                       nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
+                       args->selected_flavor = RPC_AUTH_UNIX;
 
                c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
                if (IS_ERR(c))
index bb939edd4c998cb98b7aeb56ae1aa308e4d9009d..0c29b1bb393678819e33d1ef44d1602516157fab 100644 (file)
@@ -493,7 +493,7 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
        unsigned long long fileid;
        struct dentry *sdentry;
        struct rpc_task *task;
-       int            error = -EIO;
+       int            error = -EBUSY;
 
        dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -503,7 +503,6 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
        /*
         * We don't allow a dentry to be silly-renamed twice.
         */
-       error = -EBUSY;
        if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
                goto out;
 
index 7a1ceb946b80968636c201f7bfe618b691571898..8876ac18337319b16f0da09ea40a52f5c642478f 100644 (file)
@@ -2,5 +2,4 @@
 # Makefile for the sysfs virtual filesystem
 #
 
-obj-y          := inode.o file.o dir.o symlink.o mount.o bin.o \
-                  group.o
+obj-y          := inode.o file.o dir.o symlink.o mount.o group.o
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
deleted file mode 100644 (file)
index c590cab..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * fs/sysfs/bin.c - sysfs binary file implementation
- *
- * Copyright (c) 2003 Patrick Mochel
- * Copyright (c) 2003 Matthew Wilcox
- * Copyright (c) 2004 Silicon Graphics, Inc.
- * Copyright (c) 2007 SUSE Linux Products GmbH
- * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
- *
- * This file is released under the GPLv2.
- *
- * Please see Documentation/filesystems/sysfs.txt for more information.
- */
-
-#undef DEBUG
-
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/kobject.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-
-#include "sysfs.h"
-
-/*
- * There's one bin_buffer for each open file.
- *
- * filp->private_data points to bin_buffer and
- * sysfs_dirent->s_bin_attr.buffers points to a the bin_buffer s
- * sysfs_dirent->s_bin_attr.buffers is protected by sysfs_bin_lock
- */
-static DEFINE_MUTEX(sysfs_bin_lock);
-
-struct bin_buffer {
-       struct mutex                    mutex;
-       void                            *buffer;
-       int                             mmapped;
-       const struct vm_operations_struct *vm_ops;
-       struct file                     *file;
-       struct hlist_node               list;
-};
-
-static int
-fill_read(struct file *file, char *buffer, loff_t off, size_t count)
-{
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
-       struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
-       int rc;
-
-       /* need attr_sd for attr, its parent for kobj */
-       if (!sysfs_get_active(attr_sd))
-               return -ENODEV;
-
-       rc = -EIO;
-       if (attr->read)
-               rc = attr->read(file, kobj, attr, buffer, off, count);
-
-       sysfs_put_active(attr_sd);
-
-       return rc;
-}
-
-static ssize_t
-read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
-{
-       struct bin_buffer *bb = file->private_data;
-       int size = file_inode(file)->i_size;
-       loff_t offs = *off;
-       int count = min_t(size_t, bytes, PAGE_SIZE);
-       char *temp;
-
-       if (!bytes)
-               return 0;
-
-       if (size) {
-               if (offs > size)
-                       return 0;
-               if (offs + count > size)
-                       count = size - offs;
-       }
-
-       temp = kmalloc(count, GFP_KERNEL);
-       if (!temp)
-               return -ENOMEM;
-
-       mutex_lock(&bb->mutex);
-
-       count = fill_read(file, bb->buffer, offs, count);
-       if (count < 0) {
-               mutex_unlock(&bb->mutex);
-               goto out_free;
-       }
-
-       memcpy(temp, bb->buffer, count);
-
-       mutex_unlock(&bb->mutex);
-
-       if (copy_to_user(userbuf, temp, count)) {
-               count = -EFAULT;
-               goto out_free;
-       }
-
-       pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
-
-       *off = offs + count;
-
- out_free:
-       kfree(temp);
-       return count;
-}
-
-static int
-flush_write(struct file *file, char *buffer, loff_t offset, size_t count)
-{
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
-       struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
-       int rc;
-
-       /* need attr_sd for attr, its parent for kobj */
-       if (!sysfs_get_active(attr_sd))
-               return -ENODEV;
-
-       rc = -EIO;
-       if (attr->write)
-               rc = attr->write(file, kobj, attr, buffer, offset, count);
-
-       sysfs_put_active(attr_sd);
-
-       return rc;
-}
-
-static ssize_t write(struct file *file, const char __user *userbuf,
-                    size_t bytes, loff_t *off)
-{
-       struct bin_buffer *bb = file->private_data;
-       int size = file_inode(file)->i_size;
-       loff_t offs = *off;
-       int count = min_t(size_t, bytes, PAGE_SIZE);
-       char *temp;
-
-       if (!bytes)
-               return 0;
-
-       if (size) {
-               if (offs > size)
-                       return 0;
-               if (offs + count > size)
-                       count = size - offs;
-       }
-
-       temp = memdup_user(userbuf, count);
-       if (IS_ERR(temp))
-               return PTR_ERR(temp);
-
-       mutex_lock(&bb->mutex);
-
-       memcpy(bb->buffer, temp, count);
-
-       count = flush_write(file, bb->buffer, offs, count);
-       mutex_unlock(&bb->mutex);
-
-       if (count > 0)
-               *off = offs + count;
-
-       kfree(temp);
-       return count;
-}
-
-static void bin_vma_open(struct vm_area_struct *vma)
-{
-       struct file *file = vma->vm_file;
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-
-       if (!bb->vm_ops)
-               return;
-
-       if (!sysfs_get_active(attr_sd))
-               return;
-
-       if (bb->vm_ops->open)
-               bb->vm_ops->open(vma);
-
-       sysfs_put_active(attr_sd);
-}
-
-static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-       struct file *file = vma->vm_file;
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       int ret;
-
-       if (!bb->vm_ops)
-               return VM_FAULT_SIGBUS;
-
-       if (!sysfs_get_active(attr_sd))
-               return VM_FAULT_SIGBUS;
-
-       ret = VM_FAULT_SIGBUS;
-       if (bb->vm_ops->fault)
-               ret = bb->vm_ops->fault(vma, vmf);
-
-       sysfs_put_active(attr_sd);
-       return ret;
-}
-
-static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-       struct file *file = vma->vm_file;
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       int ret;
-
-       if (!bb->vm_ops)
-               return VM_FAULT_SIGBUS;
-
-       if (!sysfs_get_active(attr_sd))
-               return VM_FAULT_SIGBUS;
-
-       ret = 0;
-       if (bb->vm_ops->page_mkwrite)
-               ret = bb->vm_ops->page_mkwrite(vma, vmf);
-       else
-               file_update_time(file);
-
-       sysfs_put_active(attr_sd);
-       return ret;
-}
-
-static int bin_access(struct vm_area_struct *vma, unsigned long addr,
-                 void *buf, int len, int write)
-{
-       struct file *file = vma->vm_file;
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       int ret;
-
-       if (!bb->vm_ops)
-               return -EINVAL;
-
-       if (!sysfs_get_active(attr_sd))
-               return -EINVAL;
-
-       ret = -EINVAL;
-       if (bb->vm_ops->access)
-               ret = bb->vm_ops->access(vma, addr, buf, len, write);
-
-       sysfs_put_active(attr_sd);
-       return ret;
-}
-
-#ifdef CONFIG_NUMA
-static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
-{
-       struct file *file = vma->vm_file;
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       int ret;
-
-       if (!bb->vm_ops)
-               return 0;
-
-       if (!sysfs_get_active(attr_sd))
-               return -EINVAL;
-
-       ret = 0;
-       if (bb->vm_ops->set_policy)
-               ret = bb->vm_ops->set_policy(vma, new);
-
-       sysfs_put_active(attr_sd);
-       return ret;
-}
-
-static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
-                                       unsigned long addr)
-{
-       struct file *file = vma->vm_file;
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       struct mempolicy *pol;
-
-       if (!bb->vm_ops)
-               return vma->vm_policy;
-
-       if (!sysfs_get_active(attr_sd))
-               return vma->vm_policy;
-
-       pol = vma->vm_policy;
-       if (bb->vm_ops->get_policy)
-               pol = bb->vm_ops->get_policy(vma, addr);
-
-       sysfs_put_active(attr_sd);
-       return pol;
-}
-
-static int 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 bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       int ret;
-
-       if (!bb->vm_ops)
-               return 0;
-
-       if (!sysfs_get_active(attr_sd))
-               return 0;
-
-       ret = 0;
-       if (bb->vm_ops->migrate)
-               ret = bb->vm_ops->migrate(vma, from, to, flags);
-
-       sysfs_put_active(attr_sd);
-       return ret;
-}
-#endif
-
-static const struct vm_operations_struct bin_vm_ops = {
-       .open           = bin_vma_open,
-       .fault          = bin_fault,
-       .page_mkwrite   = bin_page_mkwrite,
-       .access         = bin_access,
-#ifdef CONFIG_NUMA
-       .set_policy     = bin_set_policy,
-       .get_policy     = bin_get_policy,
-       .migrate        = bin_migrate,
-#endif
-};
-
-static int mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct bin_buffer *bb = file->private_data;
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
-       struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
-       int rc;
-
-       mutex_lock(&bb->mutex);
-
-       /* need attr_sd for attr, its parent for kobj */
-       rc = -ENODEV;
-       if (!sysfs_get_active(attr_sd))
-               goto out_unlock;
-
-       rc = -EINVAL;
-       if (!attr->mmap)
-               goto out_put;
-
-       rc = attr->mmap(file, kobj, attr, 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 (bb->mmapped && bb->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;
-       bb->mmapped = 1;
-       bb->vm_ops = vma->vm_ops;
-       vma->vm_ops = &bin_vm_ops;
-out_put:
-       sysfs_put_active(attr_sd);
-out_unlock:
-       mutex_unlock(&bb->mutex);
-
-       return rc;
-}
-
-static int open(struct inode *inode, struct file *file)
-{
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
-       struct bin_buffer *bb = NULL;
-       int error;
-
-       /* binary file operations requires both @sd and its parent */
-       if (!sysfs_get_active(attr_sd))
-               return -ENODEV;
-
-       error = -EACCES;
-       if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
-               goto err_out;
-       if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
-               goto err_out;
-
-       error = -ENOMEM;
-       bb = kzalloc(sizeof(*bb), GFP_KERNEL);
-       if (!bb)
-               goto err_out;
-
-       bb->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!bb->buffer)
-               goto err_out;
-
-       mutex_init(&bb->mutex);
-       bb->file = file;
-       file->private_data = bb;
-
-       mutex_lock(&sysfs_bin_lock);
-       hlist_add_head(&bb->list, &attr_sd->s_bin_attr.buffers);
-       mutex_unlock(&sysfs_bin_lock);
-
-       /* open succeeded, put active references */
-       sysfs_put_active(attr_sd);
-       return 0;
-
- err_out:
-       sysfs_put_active(attr_sd);
-       kfree(bb);
-       return error;
-}
-
-static int release(struct inode *inode, struct file *file)
-{
-       struct bin_buffer *bb = file->private_data;
-
-       mutex_lock(&sysfs_bin_lock);
-       hlist_del(&bb->list);
-       mutex_unlock(&sysfs_bin_lock);
-
-       kfree(bb->buffer);
-       kfree(bb);
-       return 0;
-}
-
-const struct file_operations bin_fops = {
-       .read           = read,
-       .write          = write,
-       .mmap           = mmap,
-       .llseek         = generic_file_llseek,
-       .open           = open,
-       .release        = release,
-};
-
-
-void unmap_bin_file(struct sysfs_dirent *attr_sd)
-{
-       struct bin_buffer *bb;
-
-       if (sysfs_type(attr_sd) != SYSFS_KOBJ_BIN_ATTR)
-               return;
-
-       mutex_lock(&sysfs_bin_lock);
-
-       hlist_for_each_entry(bb, &attr_sd->s_bin_attr.buffers, list) {
-               struct inode *inode = file_inode(bb->file);
-
-               unmap_mapping_range(inode->i_mapping, 0, 0, 1);
-       }
-
-       mutex_unlock(&sysfs_bin_lock);
-}
-
-/**
- *     sysfs_create_bin_file - create binary file for object.
- *     @kobj:  object.
- *     @attr:  attribute descriptor.
- */
-int sysfs_create_bin_file(struct kobject *kobj,
-                         const struct bin_attribute *attr)
-{
-       BUG_ON(!kobj || !kobj->sd || !attr);
-
-       return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
-}
-EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
-
-/**
- *     sysfs_remove_bin_file - remove binary file for object.
- *     @kobj:  object.
- *     @attr:  attribute descriptor.
- */
-void sysfs_remove_bin_file(struct kobject *kobj,
-                          const struct bin_attribute *attr)
-{
-       sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name);
-}
-EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
index 4d83cedb9fcb6a98b784bb7e5d67472b9e96e289..5e73d6626e50593ef95eeca259d71d6e8babbb55 100644 (file)
 #include "sysfs.h"
 
 DEFINE_MUTEX(sysfs_mutex);
-DEFINE_SPINLOCK(sysfs_assoc_lock);
+DEFINE_SPINLOCK(sysfs_symlink_target_lock);
 
-#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb);
+#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
- *     @ns:   Namespace tag to 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 void *ns, const char *name)
+static unsigned int sysfs_name_hash(const char *name, const void *ns)
 {
        unsigned long hash = init_name_hash();
        unsigned int len = strlen(name);
@@ -56,8 +56,8 @@ static unsigned int sysfs_name_hash(const void *ns, const char *name)
        return hash;
 }
 
-static int sysfs_name_compare(unsigned int hash, const void *ns,
-       const char *name, const struct sysfs_dirent *sd)
+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;
@@ -69,7 +69,7 @@ static int sysfs_name_compare(unsigned int hash, const void *ns,
 static int sysfs_sd_compare(const struct sysfs_dirent *left,
                            const struct sysfs_dirent *right)
 {
-       return sysfs_name_compare(left->s_hash, left->s_ns, left->s_name,
+       return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns,
                                  right);
 }
 
@@ -132,24 +132,6 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
        rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children);
 }
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-
-/* Test for attributes that want to ignore lockdep for read-locking */
-static bool ignore_lockdep(struct sysfs_dirent *sd)
-{
-       return sysfs_type(sd) == SYSFS_KOBJ_ATTR &&
-                       sd->s_attr.attr->ignore_lockdep;
-}
-
-#else
-
-static inline bool ignore_lockdep(struct sysfs_dirent *sd)
-{
-       return true;
-}
-
-#endif
-
 /**
  *     sysfs_get_active - get an active reference to sysfs_dirent
  *     @sd: sysfs_dirent to get an active reference to
@@ -168,7 +150,7 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
        if (!atomic_inc_unless_negative(&sd->s_active))
                return NULL;
 
-       if (likely(!ignore_lockdep(sd)))
+       if (likely(!sysfs_ignore_lockdep(sd)))
                rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_);
        return sd;
 }
@@ -187,7 +169,7 @@ void sysfs_put_active(struct sysfs_dirent *sd)
        if (unlikely(!sd))
                return;
 
-       if (likely(!ignore_lockdep(sd)))
+       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))
@@ -400,22 +382,19 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
 /**
  *     sysfs_addrm_start - prepare for sysfs_dirent add/remove
  *     @acxt: pointer to sysfs_addrm_cxt to be used
- *     @parent_sd: parent sysfs_dirent
  *
- *     This function is called when the caller is about to add or
- *     remove sysfs_dirent under @parent_sd.  This function acquires
- *     sysfs_mutex.  @acxt is used to keep and pass context to
- *     other addrm functions.
+ *     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,
-                      struct sysfs_dirent *parent_sd)
+void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt)
+       __acquires(sysfs_mutex)
 {
        memset(acxt, 0, sizeof(*acxt));
-       acxt->parent_sd = parent_sd;
 
        mutex_lock(&sysfs_mutex);
 }
@@ -424,10 +403,11 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
  *     __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 @acxt->parent_sd and set sd->s_parent to it and increment
- *     nlink of parent inode if @sd is a directory and link into the
- *     children list of the parent.
+ *     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
@@ -440,27 +420,28 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
  *     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)
+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(acxt->parent_sd) != !!sd->s_ns) {
+       if (!!sysfs_ns_type(parent_sd) != !!sd->s_ns) {
                WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
-                       sysfs_ns_type(acxt->parent_sd) ? "required" : "invalid",
-                       acxt->parent_sd->s_name, sd->s_name);
+                       sysfs_ns_type(parent_sd) ? "required" : "invalid",
+                       parent_sd->s_name, sd->s_name);
                return -EINVAL;
        }
 
-       sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
-       sd->s_parent = sysfs_get(acxt->parent_sd);
+       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 = acxt->parent_sd->s_iattr;
+       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;
@@ -490,14 +471,32 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
        return path;
 }
 
+void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name)
+{
+       char *path;
+
+       path = kzalloc(PATH_MAX, GFP_KERNEL);
+       if (path) {
+               sysfs_pathname(parent, path);
+               strlcat(path, "/", PATH_MAX);
+               strlcat(path, name, PATH_MAX);
+       }
+
+       WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s'\n",
+            path ? path : 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 @acxt->parent_sd and set sd->s_parent to it and increment
- *     nlink of parent inode if @sd is a directory and link into the
- *     children list of the parent.
+ *     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
@@ -510,23 +509,15 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
  *     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)
+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);
-       if (ret == -EEXIST) {
-               char *path = kzalloc(PATH_MAX, GFP_KERNEL);
-               WARN(1, KERN_WARNING
-                    "sysfs: cannot create duplicate filename '%s'\n",
-                    (path == NULL) ? sd->s_name
-                                   : (sysfs_pathname(acxt->parent_sd, path),
-                                      strlcat(path, "/", PATH_MAX),
-                                      strlcat(path, sd->s_name, PATH_MAX),
-                                      path));
-               kfree(path);
-       }
+       ret = __sysfs_add_one(acxt, sd, parent_sd);
 
+       if (ret == -EEXIST)
+               sysfs_warn_dup(parent_sd, sd->s_name);
        return ret;
 }
 
@@ -545,16 +536,22 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
  *     LOCKING:
  *     Determined by sysfs_addrm_start().
  */
-void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
+                            struct sysfs_dirent *sd)
 {
        struct sysfs_inode_attrs *ps_iattr;
 
-       BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED);
+       /*
+        * 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 = acxt->parent_sd->s_iattr;
+       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;
@@ -577,6 +574,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
  *     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);
@@ -588,7 +586,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
                acxt->removed = sd->u.removed_list;
 
                sysfs_deactivate(sd);
-               unmap_bin_file(sd);
+               sysfs_unmap_bin_file(sd);
                sysfs_put(sd);
        }
 }
@@ -597,6 +595,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
  *     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.
  *
@@ -607,8 +606,8 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
  *     Pointer to sysfs_dirent if found, NULL if not.
  */
 struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
-                                      const void *ns,
-                                      const unsigned char *name)
+                                      const unsigned char *name,
+                                      const void *ns)
 {
        struct rb_node *node = parent_sd->s_dir.children.rb_node;
        unsigned int hash;
@@ -620,13 +619,13 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
                return NULL;
        }
 
-       hash = sysfs_name_hash(ns, name);
+       hash = sysfs_name_hash(name, ns);
        while (node) {
                struct sysfs_dirent *sd;
                int result;
 
                sd = to_sysfs_dirent(node);
-               result = sysfs_name_compare(hash, ns, name, sd);
+               result = sysfs_name_compare(hash, name, ns, sd);
                if (result < 0)
                        node = node->rb_left;
                else if (result > 0)
@@ -638,9 +637,10 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
 }
 
 /**
- *     sysfs_get_dirent - find and get sysfs_dirent with the given name
+ *     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.
@@ -651,24 +651,25 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
  *     RETURNS:
  *     Pointer to sysfs_dirent if found, NULL if not.
  */
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
-                                     const void *ns,
-                                     const unsigned char *name)
+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, ns, name);
+       sd = sysfs_find_dirent(parent_sd, name, ns);
        sysfs_get(sd);
        mutex_unlock(&sysfs_mutex);
 
        return sd;
 }
-EXPORT_SYMBOL_GPL(sysfs_get_dirent);
+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 void *ns, const char *name,
-       struct sysfs_dirent **p_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;
@@ -685,8 +686,8 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
        sd->s_dir.kobj = kobj;
 
        /* link in */
-       sysfs_addrm_start(&acxt, parent_sd);
-       rc = sysfs_add_one(&acxt, sd);
+       sysfs_addrm_start(&acxt);
+       rc = sysfs_add_one(&acxt, sd, parent_sd);
        sysfs_addrm_finish(&acxt);
 
        if (rc == 0)
@@ -701,7 +702,7 @@ 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, NULL, name, p_sd);
+                         KOBJ_NS_TYPE_NONE, name, NULL, p_sd);
 }
 
 /**
@@ -730,14 +731,14 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
 }
 
 /**
- *     sysfs_create_dir - create a directory for an object.
- *     @kobj:          object we're creating directory for.
+ * sysfs_create_dir_ns - create a directory for an object with a namespace tag
+ * @kobj: object we're creating directory for
+ * @ns: the namespace tag to use
  */
-int sysfs_create_dir(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;
-       const void *ns = NULL;
        int error = 0;
 
        BUG_ON(!kobj);
@@ -750,11 +751,9 @@ int sysfs_create_dir(struct kobject *kobj)
        if (!parent_sd)
                return -ENOENT;
 
-       if (sysfs_ns_type(parent_sd))
-               ns = kobj->ktype->namespace(kobj);
        type = sysfs_read_ns_type(kobj);
 
-       error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);
+       error = create_dir(kobj, parent_sd, type, kobject_name(kobj), ns, &sd);
        if (!error)
                kobj->sd = sd;
        return error;
@@ -776,7 +775,7 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
        type = sysfs_ns_type(parent_sd);
        ns = sysfs_info(dir->i_sb)->ns[type];
 
-       sd = sysfs_find_dirent(parent_sd, ns, dentry->d_name.name);
+       sd = sysfs_find_dirent(parent_sd, dentry->d_name.name, ns);
 
        /* no such entry */
        if (!sd) {
@@ -807,41 +806,128 @@ const struct inode_operations sysfs_dir_inode_operations = {
        .setxattr       = sysfs_setxattr,
 };
 
-static void remove_dir(struct sysfs_dirent *sd)
+static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos)
 {
-       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent *last;
 
-       sysfs_addrm_start(&acxt, sd->s_parent);
-       sysfs_remove_one(&acxt, sd);
-       sysfs_addrm_finish(&acxt);
+       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;
 }
 
-void sysfs_remove_subdir(struct sysfs_dirent *sd)
+/**
+ * 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)
 {
-       remove_dir(sd);
+       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;
 
-static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
+       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;
-       struct rb_node *pos;
 
-       if (!dir_sd)
-               return;
+       sysfs_addrm_start(&acxt);
+       __sysfs_remove(&acxt, sd);
+       sysfs_addrm_finish(&acxt);
+}
 
-       pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
-       sysfs_addrm_start(&acxt, dir_sd);
-       pos = rb_first(&dir_sd->s_dir.children);
-       while (pos) {
-               struct sysfs_dirent *sd = to_sysfs_dirent(pos);
-               pos = rb_next(pos);
-               if (sysfs_type(sd) != SYSFS_DIR)
-                       sysfs_remove_one(&acxt, sd);
+/**
+ * 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);
 
-       remove_dir(dir_sd);
+       if (sd)
+               return 0;
+       else
+               return -ENOENT;
 }
 
 /**
@@ -852,21 +938,34 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
  *     the directory before we remove the directory, and we've inlined
  *     what used to be sysfs_rmdir() below, instead of calling separately.
  */
-
 void sysfs_remove_dir(struct kobject *kobj)
 {
        struct sysfs_dirent *sd = kobj->sd;
 
-       spin_lock(&sysfs_assoc_lock);
+       /*
+        * In general, kboject owner is responsible for ensuring removal
+        * doesn't race with other operations and sysfs doesn't provide any
+        * protection; however, when @kobj is used as a symlink target, the
+        * symlinking entity usually doesn't own @kobj and thus has no
+        * control over removal.  @kobj->sd may be removed anytime and
+        * symlink code may end up dereferencing an already freed sd.
+        *
+        * sysfs_symlink_target_lock synchronizes @kobj->sd disassociation
+        * against symlink operations so that symlink code can safely
+        * dereference @kobj->sd.
+        */
+       spin_lock(&sysfs_symlink_target_lock);
        kobj->sd = NULL;
-       spin_unlock(&sysfs_assoc_lock);
+       spin_unlock(&sysfs_symlink_target_lock);
 
-       __sysfs_remove_dir(sd);
+       if (sd) {
+               WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR);
+               sysfs_remove(sd);
+       }
 }
 
-int sysfs_rename(struct sysfs_dirent *sd,
-       struct sysfs_dirent *new_parent_sd, const void *new_ns,
-       const char *new_name)
+int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
+                const char *new_name, const void *new_ns)
 {
        int error;
 
@@ -878,7 +977,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
                goto out;       /* nothing to rename */
 
        error = -EEXIST;
-       if (sysfs_find_dirent(new_parent_sd, new_ns, new_name))
+       if (sysfs_find_dirent(new_parent_sd, new_name, new_ns))
                goto out;
 
        /* rename sysfs_dirent */
@@ -899,7 +998,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
        sysfs_get(new_parent_sd);
        sysfs_put(sd->s_parent);
        sd->s_ns = new_ns;
-       sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
+       sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
        sd->s_parent = new_parent_sd;
        sysfs_link_sibling(sd);
 
@@ -909,30 +1008,25 @@ int sysfs_rename(struct sysfs_dirent *sd,
        return error;
 }
 
-int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
+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;
-       const void *new_ns = NULL;
-
-       if (sysfs_ns_type(parent_sd))
-               new_ns = kobj->ktype->namespace(kobj);
 
-       return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name);
+       return sysfs_rename(kobj->sd, parent_sd, new_name, new_ns);
 }
 
-int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
+int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
+                     const void *new_ns)
 {
        struct sysfs_dirent *sd = kobj->sd;
        struct sysfs_dirent *new_parent_sd;
-       const void *new_ns = NULL;
 
        BUG_ON(!sd->s_parent);
-       if (sysfs_ns_type(sd->s_parent))
-               new_ns = kobj->ktype->namespace(kobj);
        new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
                new_parent_kobj->sd : &sysfs_root;
 
-       return sysfs_rename(sd, new_parent_sd, new_ns, sd->s_name);
+       return sysfs_rename(sd, new_parent_sd, sd->s_name, new_ns);
 }
 
 /* Relationship between s_mode and the DT_xxx types */
index 15ef5eb13663f6828b15e619b5e801b4700a3a82..79b5da2acbe184353475f53ccb03793404bd3563 100644 (file)
 #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_buffer for each open file and one
- * sysfs_open_dirent for each sysfs_dirent with one or more open
- * files.
+ * 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.
  *
- * filp->private_data points to sysfs_buffer and
- * sysfs_dirent->s_attr.open points to sysfs_open_dirent.  s_attr.open
- * is protected by sysfs_open_dirent_lock.
+ * 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        buffers; /* goes through sysfs_buffer.list */
+       struct list_head        files; /* goes through sysfs_open_file.list */
 };
 
-struct sysfs_buffer {
-       size_t                  count;
-       loff_t                  pos;
-       char                    *page;
-       const struct sysfs_ops  *ops;
+struct sysfs_open_file {
+       struct sysfs_dirent     *sd;
+       struct file             *file;
        struct mutex            mutex;
-       int                     needs_read_fill;
        int                     event;
        struct list_head        list;
+
+       bool                    mmapped;
+       const struct vm_operations_struct *vm_ops;
 };
 
-/**
- *     fill_read_buffer - allocate and fill buffer from object.
- *     @dentry:        dentry pointer.
- *     @buffer:        data buffer for file.
- *
- *     Allocate @buffer->page, if it hasn't been already, then call the
- *     kobject's show() method to fill the buffer with this attribute's
- *     data.
- *     This is called only once, on the file's first read unless an error
- *     is returned.
+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;
+}
+
+/*
+ * Determine ktype->sysfs_ops for the given sysfs_dirent.  This function
+ * must be called while holding an active reference.
  */
-static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)
+static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd)
 {
-       struct sysfs_dirent *attr_sd = dentry->d_fsdata;
-       struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
-       const struct sysfs_ops *ops = buffer->ops;
-       int ret = 0;
+       struct kobject *kobj = sd->s_parent->s_dir.kobj;
+
+       if (!sysfs_ignore_lockdep(sd))
+               lockdep_assert_held(sd);
+       return kobj->ktype ? kobj->ktype->sysfs_ops : NULL;
+}
+
+/*
+ * Reads on sysfs are handled through seq_file, which takes care of hairy
+ * 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)
+{
+       struct sysfs_open_file *of = sf->private;
+       struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
+       const struct sysfs_ops *ops;
+       char *buf;
        ssize_t count;
 
-       if (!buffer->page)
-               buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
-       if (!buffer->page)
-               return -ENOMEM;
+       /* acquire buffer and ensure that it's >= PAGE_SIZE */
+       count = seq_get_buf(sf, &buf);
+       if (count < PAGE_SIZE) {
+               seq_commit(sf, -1);
+               return 0;
+       }
 
-       /* need attr_sd for attr and ops, its parent for kobj */
-       if (!sysfs_get_active(attr_sd))
+       /*
+        * 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;
+       }
 
-       buffer->event = atomic_read(&attr_sd->s_attr.open->event);
-       count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
+       of->event = atomic_read(&of->sd->s_attr.open->event);
 
-       sysfs_put_active(attr_sd);
+       /*
+        * 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
@@ -96,155 +140,389 @@ static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)
                /* Try to struggle along */
                count = PAGE_SIZE - 1;
        }
-       if (count >= 0) {
-               buffer->needs_read_fill = 0;
-               buffer->count = count;
-       } else {
-               ret = count;
-       }
-       return ret;
+       seq_commit(sf, count);
+       return 0;
 }
 
-/**
- *     sysfs_read_file - read an attribute.
- *     @file:  file pointer.
- *     @buf:   buffer to fill.
- *     @count: number of bytes to read.
- *     @ppos:  starting offset in file.
- *
- *     Userspace wants to read an attribute file. The attribute descriptor
- *     is in the file's ->d_fsdata. The target object is in the directory's
- *     ->d_fsdata.
- *
- *     We call fill_read_buffer() to allocate and fill the buffer from the
- *     object's show() method exactly once (if the read is happening from
- *     the beginning of the file). That should fill the entire buffer with
- *     all the data the object has to offer for that attribute.
- *     We then call flush_read_buffer() to copy the buffer to userspace
- *     in the increments specified.
+/*
+ * 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_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t sysfs_bin_read(struct file *file, char __user *userbuf,
+                             size_t bytes, loff_t *off)
 {
-       struct sysfs_buffer *buffer = file->private_data;
-       ssize_t retval = 0;
+       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;
+
+       if (!bytes)
+               return 0;
 
-       mutex_lock(&buffer->mutex);
-       if (buffer->needs_read_fill || *ppos == 0) {
-               retval = fill_read_buffer(file->f_path.dentry, buffer);
-               if (retval)
-                       goto out;
+       if (size) {
+               if (offs > size)
+                       return 0;
+               if (offs + count > size)
+                       count = size - offs;
        }
-       pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
-                __func__, count, *ppos, buffer->page);
-       retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
-                                        buffer->count);
-out:
-       mutex_unlock(&buffer->mutex);
-       return retval;
-}
 
-/**
- *     fill_write_buffer - copy buffer from userspace.
- *     @buffer:        data buffer for file.
- *     @buf:           data from user.
- *     @count:         number of bytes in @userbuf.
- *
- *     Allocate @buffer->page if it hasn't been already, then
- *     copy the user-supplied buffer into it.
- */
-static int fill_write_buffer(struct sysfs_buffer *buffer,
-                            const char __user *buf, size_t count)
-{
-       int error;
-
-       if (!buffer->page)
-               buffer->page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!buffer->page)
+       buf = kmalloc(count, GFP_KERNEL);
+       if (!buf)
                return -ENOMEM;
 
-       if (count >= PAGE_SIZE)
-               count = PAGE_SIZE - 1;
-       error = copy_from_user(buffer->page, buf, count);
-       buffer->needs_read_fill = 1;
-       /* if buf is assumed to contain a string, terminate it by \0,
-          so e.g. sscanf() can scan the string easily */
-       buffer->page[count] = 0;
-       return error ? -EFAULT : count;
-}
+       /* 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)
+               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;
+}
 
 /**
- *     flush_write_buffer - push buffer to kobject.
- *     @dentry:        dentry to the attribute
- *     @buffer:        data buffer for file.
- *     @count:         number of bytes
+ * 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 the attribute,
- *     passing the buffer that we acquired in fill_write_buffer().
+ * 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 dentry *dentry,
-                             struct sysfs_buffer *buffer, size_t count)
+static int flush_write_buffer(struct sysfs_open_file *of, char *buf, loff_t off,
+                             size_t count)
 {
-       struct sysfs_dirent *attr_sd = dentry->d_fsdata;
-       struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
-       const struct sysfs_ops *ops = buffer->ops;
-       int rc;
+       struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
+       int rc = 0;
 
-       /* need attr_sd for attr and ops, its parent for kobj */
-       if (!sysfs_get_active(attr_sd))
+       /*
+        * 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;
+       }
 
-       rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);
+       if (sysfs_is_bin(of->sd)) {
+               struct bin_attribute *battr = of->sd->s_attr.bin_attr;
 
-       sysfs_put_active(attr_sd);
+               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);
 
        return rc;
 }
 
-
 /**
- *     sysfs_write_file - write an attribute.
- *     @file:  file pointer
- *     @buf:   data to write
- *     @count: number of bytes
- *     @ppos:  starting offset
+ * 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().
  *
- *     Similar to sysfs_read_file(), though working in the opposite direction.
- *     We allocate and fill the data from the user in fill_write_buffer(),
- *     then push it to the kobject in 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.
+ * 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 *buf,
+static ssize_t sysfs_write_file(struct file *file, const char __user *user_buf,
                                size_t count, loff_t *ppos)
 {
-       struct sysfs_buffer *buffer = file->private_data;
-       ssize_t len;
+       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;
+
+       if (sysfs_is_bin(of->sd) && size) {
+               if (size <= *ppos)
+                       return 0;
+               len = min_t(ssize_t, len, size - *ppos);
+       }
 
-       mutex_lock(&buffer->mutex);
-       len = fill_write_buffer(buffer, buf, count);
-       if (len > 0)
-               len = flush_write_buffer(file->f_path.dentry, buffer, len);
+       if (!len)
+               return 0;
+
+       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 */
+
+       len = flush_write_buffer(of, buf, *ppos, len);
        if (len > 0)
                *ppos += len;
-       mutex_unlock(&buffer->mutex);
+out_free:
+       kfree(buf);
        return len;
 }
 
+static void sysfs_bin_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 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;
+
+       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
- *     @buffer: sysfs_buffer for this instance of open
+ *     @of: sysfs_open_file for this instance of open
  *
  *     If @sd->s_attr.open exists, increment its reference count;
- *     otherwise, create one.  @buffer is chained to the buffers
- *     list.
+ *     otherwise, create one.  @of is chained to the files list.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep).
@@ -253,11 +531,12 @@ static ssize_t sysfs_write_file(struct file *file, const char __user *buf,
  *     0 on success, -errno on failure.
  */
 static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
-                                struct sysfs_buffer *buffer)
+                                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) {
@@ -268,10 +547,11 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
        od = sd->s_attr.open;
        if (od) {
                atomic_inc(&od->refcnt);
-               list_add_tail(&buffer->list, &od->buffers);
+               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);
@@ -286,36 +566,40 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
        atomic_set(&new_od->refcnt, 0);
        atomic_set(&new_od->event, 1);
        init_waitqueue_head(&new_od->poll);
-       INIT_LIST_HEAD(&new_od->buffers);
+       INIT_LIST_HEAD(&new_od->files);
        goto retry;
 }
 
 /**
  *     sysfs_put_open_dirent - put sysfs_open_dirent
  *     @sd: target sysfs_dirent
- *     @buffer: associated sysfs_buffer
+ *     @of: associated sysfs_open_file
  *
- *     Put @sd->s_attr.open and unlink @buffer from the buffers list.
- *     If reference count reaches zero, disassociate and free it.
+ *     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_buffer *buffer)
+                                 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);
 
-       list_del(&buffer->list);
+       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);
 }
@@ -324,67 +608,81 @@ 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_buffer *buffer;
-       const struct sysfs_ops *ops;
+       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;
 
-       /* every kobject with an attribute needs a ktype assigned */
-       if (kobj->ktype && kobj->ktype->sysfs_ops)
-               ops = kobj->ktype->sysfs_ops;
-       else {
-               WARN(1, KERN_ERR
-                    "missing sysfs attribute operations for kobject: %s\n",
-                    kobject_name(kobj));
-               goto err_out;
-       }
+       if (sysfs_is_bin(attr_sd)) {
+               struct bin_attribute *battr = attr_sd->s_attr.bin_attr;
 
-       /* File needs write support.
-        * The inode's perms must say it's ok,
-        * and we must have a store method.
-        */
-       if (file->f_mode & FMODE_WRITE) {
-               if (!(inode->i_mode & S_IWUGO) || !ops->store)
-                       goto err_out;
-       }
+               has_read = battr->read || battr->mmap;
+               has_write = battr->write || battr->mmap;
+       } else {
+               const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
 
-       /* File needs read support.
-        * The inode's perms must say it's ok, and we there
-        * must be a show method for it.
-        */
-       if (file->f_mode & FMODE_READ) {
-               if (!(inode->i_mode & S_IRUGO) || !ops->show)
+               /* 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;
        }
 
-       /* No error? Great, allocate a buffer for the file, and store it
-        * it in file->private_data for easy access.
-        */
+       /* 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;
-       buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
-       if (!buffer)
+       of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
+       if (!of)
                goto err_out;
 
-       mutex_init(&buffer->mutex);
-       buffer->needs_read_fill = 1;
-       buffer->ops = ops;
-       file->private_data = buffer;
+       mutex_init(&of->mutex);
+       of->sd = attr_sd;
+       of->file = file;
 
-       /* make sure we have open dirent struct */
-       error = sysfs_get_open_dirent(attr_sd, buffer);
+       /*
+        * 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_free:
-       kfree(buffer);
- err_out:
+err_close:
+       single_release(inode, file);
+err_free:
+       kfree(of);
+err_out:
        sysfs_put_active(attr_sd);
        return error;
 }
@@ -392,17 +690,41 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
 static int sysfs_release(struct inode *inode, struct file *filp)
 {
        struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
-       struct sysfs_buffer *buffer = filp->private_data;
+       struct sysfs_open_file *of = sysfs_of(filp);
 
-       sysfs_put_open_dirent(sd, buffer);
-
-       if (buffer->page)
-               free_page((unsigned long)buffer->page);
-       kfree(buffer);
+       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);
+       }
+       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
@@ -418,7 +740,7 @@ static int sysfs_release(struct inode *inode, struct file *filp)
  */
 static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
 {
-       struct sysfs_buffer *buffer = filp->private_data;
+       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;
 
@@ -430,13 +752,12 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
 
        sysfs_put_active(attr_sd);
 
-       if (buffer->event != atomic_read(&od->event))
+       if (of->event != atomic_read(&od->event))
                goto trigger;
 
        return DEFAULT_POLLMASK;
 
  trigger:
-       buffer->needs_read_fill = 1;
        return DEFAULT_POLLMASK|POLLERR|POLLPRI;
 }
 
@@ -466,9 +787,9 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
        mutex_lock(&sysfs_mutex);
 
        if (sd && dir)
-               sd = sysfs_find_dirent(sd, NULL, dir);
+               sd = sysfs_find_dirent(sd, dir, NULL);
        if (sd && attr)
-               sd = sysfs_find_dirent(sd, NULL, attr);
+               sd = sysfs_find_dirent(sd, attr, NULL);
        if (sd)
                sysfs_notify_dirent(sd);
 
@@ -477,7 +798,7 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
 EXPORT_SYMBOL_GPL(sysfs_notify);
 
 const struct file_operations sysfs_file_operations = {
-       .read           = sysfs_read_file,
+       .read           = seq_read,
        .write          = sysfs_write_file,
        .llseek         = generic_file_llseek,
        .open           = sysfs_open_file,
@@ -485,58 +806,25 @@ const struct file_operations sysfs_file_operations = {
        .poll           = sysfs_poll,
 };
 
-static int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
-                        const void **pns)
-{
-       struct sysfs_dirent *dir_sd = kobj->sd;
-       const struct sysfs_ops *ops;
-       const void *ns = NULL;
-       int err;
-
-       if (!dir_sd) {
-               WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n",
-                       kobject_name(kobj));
-               return -ENOENT;
-       }
-
-       err = 0;
-       if (!sysfs_ns_type(dir_sd))
-               goto out;
-
-       err = -EINVAL;
-       if (!kobj->ktype)
-               goto out;
-       ops = kobj->ktype->sysfs_ops;
-       if (!ops)
-               goto out;
-       if (!ops->namespace)
-               goto out;
-
-       err = 0;
-       ns = ops->namespace(kobj, attr);
-out:
-       if (err) {
-               WARN(1, KERN_ERR
-                    "missing sysfs namespace attribute operation for kobject: %s\n",
-                    kobject_name(kobj));
-       }
-       *pns = ns;
-       return err;
-}
+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,
+};
 
-int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
-                       const struct attribute *attr, int type, umode_t amode)
+int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
+                          const struct attribute *attr, int type,
+                          umode_t amode, const void *ns)
 {
        umode_t mode = (amode & S_IALLUGO) | S_IFREG;
        struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *sd;
-       const void *ns;
        int rc;
 
-       rc = sysfs_attr_ns(dir_sd->s_dir.kobj, attr, &ns);
-       if (rc)
-               return rc;
-
        sd = sysfs_new_dirent(attr->name, mode, type);
        if (!sd)
                return -ENOMEM;
@@ -545,8 +833,8 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
        sd->s_attr.attr = (void *)attr;
        sysfs_dirent_init_lockdep(sd);
 
-       sysfs_addrm_start(&acxt, dir_sd);
-       rc = sysfs_add_one(&acxt, sd);
+       sysfs_addrm_start(&acxt);
+       rc = sysfs_add_one(&acxt, sd, dir_sd);
        sysfs_addrm_finish(&acxt);
 
        if (rc)
@@ -559,23 +847,25 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
 int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
                   int type)
 {
-       return sysfs_add_file_mode(dir_sd, attr, type, attr->mode);
+       return sysfs_add_file_mode_ns(dir_sd, attr, type, attr->mode, NULL);
 }
 
-
 /**
- *     sysfs_create_file - create an attribute file for an object.
- *     @kobj:  object we're creating for.
- *     @attr:  attribute descriptor.
+ * sysfs_create_file_ns - create an attribute file for an object with custom ns
+ * @kobj: object we're creating for
+ * @attr: attribute descriptor
+ * @ns: namespace the new file should belong to
  */
-int sysfs_create_file(struct kobject *kobj, const struct attribute *attr)
+int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
+                        const void *ns)
 {
        BUG_ON(!kobj || !kobj->sd || !attr);
 
-       return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);
+       return sysfs_add_file_mode_ns(kobj->sd, attr, SYSFS_KOBJ_ATTR,
+                                     attr->mode, ns);
 
 }
-EXPORT_SYMBOL_GPL(sysfs_create_file);
+EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
 
 int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
 {
@@ -604,7 +894,7 @@ int sysfs_add_file_to_group(struct kobject *kobj,
        int error;
 
        if (group)
-               dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
+               dir_sd = sysfs_get_dirent(kobj->sd, group);
        else
                dir_sd = sysfs_get(kobj->sd);
 
@@ -630,17 +920,12 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
 {
        struct sysfs_dirent *sd;
        struct iattr newattrs;
-       const void *ns;
        int rc;
 
-       rc = sysfs_attr_ns(kobj, attr, &ns);
-       if (rc)
-               return rc;
-
        mutex_lock(&sysfs_mutex);
 
        rc = -ENOENT;
-       sd = sysfs_find_dirent(kobj->sd, ns, attr->name);
+       sd = sysfs_find_dirent(kobj->sd, attr->name, NULL);
        if (!sd)
                goto out;
 
@@ -655,22 +940,21 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
 /**
- *     sysfs_remove_file - remove an object attribute.
- *     @kobj:  object we're acting for.
- *     @attr:  attribute descriptor.
+ * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
+ * @kobj: object we're acting for
+ * @attr: attribute descriptor
+ * @ns: namespace tag of the file to remove
  *
- *     Hash the attribute name and kill the victim.
+ * Hash the attribute name and namespace tag and kill the victim.
  */
-void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr)
+void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
+                         const void *ns)
 {
-       const void *ns;
-
-       if (sysfs_attr_ns(kobj, attr, &ns))
-               return;
+       struct sysfs_dirent *dir_sd = kobj->sd;
 
-       sysfs_hash_and_remove(kobj->sd, ns, attr->name);
+       sysfs_hash_and_remove(dir_sd, attr->name, ns);
 }
-EXPORT_SYMBOL_GPL(sysfs_remove_file);
+EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
 
 void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
 {
@@ -692,16 +976,42 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
        struct sysfs_dirent *dir_sd;
 
        if (group)
-               dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
+               dir_sd = sysfs_get_dirent(kobj->sd, group);
        else
                dir_sd = sysfs_get(kobj->sd);
        if (dir_sd) {
-               sysfs_hash_and_remove(dir_sd, NULL, attr->name);
+               sysfs_hash_and_remove(dir_sd, attr->name, NULL);
                sysfs_put(dir_sd);
        }
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
 
+/**
+ *     sysfs_create_bin_file - create binary file for object.
+ *     @kobj:  object.
+ *     @attr:  attribute descriptor.
+ */
+int sysfs_create_bin_file(struct kobject *kobj,
+                         const struct bin_attribute *attr)
+{
+       BUG_ON(!kobj || !kobj->sd || !attr);
+
+       return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
+}
+EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
+
+/**
+ *     sysfs_remove_bin_file - remove binary file for object.
+ *     @kobj:  object.
+ *     @attr:  attribute descriptor.
+ */
+void sysfs_remove_bin_file(struct kobject *kobj,
+                          const struct bin_attribute *attr)
+{
+       sysfs_hash_and_remove(kobj->sd, attr->attr.name, NULL);
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
+
 struct sysfs_schedule_callback_struct {
        struct list_head        workq_list;
        struct kobject          *kobj;
index 5f92cd2f61c1fe118168be8978a9d5c9846c5132..1898a10e38ce8ccef26a687882c637f349ac5b29 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, NULL, (*attr)->name);
+                       sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL);
        if (grp->bin_attrs)
                for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++)
                        sysfs_remove_bin_file(kobj, *bin_attr);
@@ -49,16 +49,17 @@ 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, NULL,
-                                                     (*attr)->name);
+                               sysfs_hash_and_remove(dir_sd, (*attr)->name,
+                                                     NULL);
                        if (grp->is_visible) {
                                mode = grp->is_visible(kobj, *attr, i);
                                if (!mode)
                                        continue;
                        }
-                       error = sysfs_add_file_mode(dir_sd, *attr,
-                                                   SYSFS_KOBJ_ATTR,
-                                                   (*attr)->mode | mode);
+                       error = sysfs_add_file_mode_ns(dir_sd, *attr,
+                                                      SYSFS_KOBJ_ATTR,
+                                                      (*attr)->mode | mode,
+                                                      NULL);
                        if (unlikely(error))
                                break;
                }
@@ -110,7 +111,7 @@ static int internal_create_group(struct kobject *kobj, int update,
        error = create_files(sd, kobj, grp, update);
        if (error) {
                if (grp->name)
-                       sysfs_remove_subdir(sd);
+                       sysfs_remove(sd);
        }
        sysfs_put(sd);
        return error;
@@ -206,7 +207,7 @@ void sysfs_remove_group(struct kobject *kobj,
        struct sysfs_dirent *sd;
 
        if (grp->name) {
-               sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
+               sd = sysfs_get_dirent(dir_sd, grp->name);
                if (!sd) {
                        WARN(!sd, KERN_WARNING
                             "sysfs group %p not found for kobject '%s'\n",
@@ -218,7 +219,7 @@ void sysfs_remove_group(struct kobject *kobj,
 
        remove_files(sd, kobj, grp);
        if (grp->name)
-               sysfs_remove_subdir(sd);
+               sysfs_remove(sd);
 
        sysfs_put(sd);
 }
@@ -261,7 +262,7 @@ int sysfs_merge_group(struct kobject *kobj,
        struct attribute *const *attr;
        int i;
 
-       dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
+       dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
        if (!dir_sd)
                return -ENOENT;
 
@@ -269,7 +270,7 @@ int sysfs_merge_group(struct kobject *kobj,
                error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
        if (error) {
                while (--i >= 0)
-                       sysfs_hash_and_remove(dir_sd, NULL, (*--attr)->name);
+                       sysfs_hash_and_remove(dir_sd, (*--attr)->name, NULL);
        }
        sysfs_put(dir_sd);
 
@@ -288,10 +289,10 @@ void sysfs_unmerge_group(struct kobject *kobj,
        struct sysfs_dirent *dir_sd;
        struct attribute *const *attr;
 
-       dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
+       dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
        if (dir_sd) {
                for (attr = grp->attrs; *attr; ++attr)
-                       sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
+                       sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL);
                sysfs_put(dir_sd);
        }
 }
@@ -310,7 +311,7 @@ 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, NULL, group_name);
+       dir_sd = sysfs_get_dirent(kobj->sd, group_name);
        if (!dir_sd)
                return -ENOENT;
 
@@ -332,9 +333,9 @@ 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, NULL, group_name);
+       dir_sd = sysfs_get_dirent(kobj->sd, group_name);
        if (dir_sd) {
-               sysfs_hash_and_remove(dir_sd, NULL, link_name);
+               sysfs_hash_and_remove(dir_sd, link_name, NULL);
                sysfs_put(dir_sd);
        }
 }
index 963f910c8034f84d414e625c092d45d2ca564123..1750f790af3b9a3714580c73705acc3cb21c613b 100644 (file)
@@ -258,9 +258,9 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
                inode->i_fop = &sysfs_file_operations;
                break;
        case SYSFS_KOBJ_BIN_ATTR:
-               bin_attr = sd->s_bin_attr.bin_attr;
+               bin_attr = sd->s_attr.bin_attr;
                inode->i_size = bin_attr->size;
-               inode->i_fop = &bin_fops;
+               inode->i_fop = &sysfs_bin_operations;
                break;
        case SYSFS_KOBJ_LINK:
                inode->i_op = &sysfs_symlink_inode_operations;
@@ -314,32 +314,6 @@ void sysfs_evict_inode(struct inode *inode)
        sysfs_put(sd);
 }
 
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
-                         const char *name)
-{
-       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, dir_sd);
-
-       sd = sysfs_find_dirent(dir_sd, ns, name);
-       if (sd)
-               sysfs_remove_one(&acxt, sd);
-
-       sysfs_addrm_finish(&acxt);
-
-       if (sd)
-               return 0;
-       else
-               return -ENOENT;
-}
-
 int sysfs_permission(struct inode *inode, int mask)
 {
        struct sysfs_dirent *sd;
index 2dd4507d9edd675b78a5c857d337a8abc9cf76cd..3ae3f1bf1a0957075bec9d36d8834550000c3b14 100644 (file)
@@ -33,13 +33,15 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
 
        BUG_ON(!name || !parent_sd);
 
-       /* target->sd can go away beneath us but is protected with
-        * sysfs_assoc_lock.  Fetch target_sd from it.
+       /*
+        * We don't own @target and it may be removed at any time.
+        * Synchronize using sysfs_symlink_target_lock.  See
+        * sysfs_remove_dir() for details.
         */
-       spin_lock(&sysfs_assoc_lock);
+       spin_lock(&sysfs_symlink_target_lock);
        if (target->sd)
                target_sd = sysfs_get(target->sd);
-       spin_unlock(&sysfs_assoc_lock);
+       spin_unlock(&sysfs_symlink_target_lock);
 
        error = -ENOENT;
        if (!target_sd)
@@ -52,18 +54,18 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
 
        ns_type = sysfs_ns_type(parent_sd);
        if (ns_type)
-               sd->s_ns = target->ktype->namespace(target);
+               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, parent_sd);
+       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);
+                       error = sysfs_add_one(&acxt, sd, parent_sd);
                else
-                       error = __sysfs_add_one(&acxt, sd);
+                       error = __sysfs_add_one(&acxt, sd, parent_sd);
        } else {
                error = -EINVAL;
                WARN(1, KERN_WARNING
@@ -155,11 +157,17 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
                        const char *name)
 {
        const void *ns = NULL;
-       spin_lock(&sysfs_assoc_lock);
+
+       /*
+        * We don't own @target and it may be removed at any time.
+        * Synchronize using sysfs_symlink_target_lock.  See
+        * sysfs_remove_dir() for details.
+        */
+       spin_lock(&sysfs_symlink_target_lock);
        if (targ->sd && sysfs_ns_type(kobj->sd))
                ns = targ->sd->s_ns;
-       spin_unlock(&sysfs_assoc_lock);
-       sysfs_hash_and_remove(kobj->sd, ns, name);
+       spin_unlock(&sysfs_symlink_target_lock);
+       sysfs_hash_and_remove(kobj->sd, name, ns);
 }
 
 /**
@@ -176,24 +184,25 @@ void sysfs_remove_link(struct kobject *kobj, const char *name)
        else
                parent_sd = kobj->sd;
 
-       sysfs_hash_and_remove(parent_sd, NULL, name);
+       sysfs_hash_and_remove(parent_sd, name, NULL);
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_link);
 
 /**
- *     sysfs_rename_link - rename symlink in object's directory.
+ *     sysfs_rename_link_ns - rename symlink in object's directory.
  *     @kobj:  object we're acting for.
  *     @targ:  object we're pointing to.
  *     @old:   previous name of the symlink.
  *     @new:   new name of the symlink.
+ *     @new_ns: new namespace of the symlink.
  *
  *     A helper function for the common rename symlink idiom.
  */
-int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
-                       const char *old, const char *new)
+int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ,
+                        const char *old, const char *new, const void *new_ns)
 {
        struct sysfs_dirent *parent_sd, *sd = NULL;
-       const void *old_ns = NULL, *new_ns = NULL;
+       const void *old_ns = NULL;
        int result;
 
        if (!kobj)
@@ -205,7 +214,7 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
                old_ns = targ->sd->s_ns;
 
        result = -ENOENT;
-       sd = sysfs_get_dirent(parent_sd, old_ns, old);
+       sd = sysfs_get_dirent_ns(parent_sd, old, old_ns);
        if (!sd)
                goto out;
 
@@ -215,16 +224,13 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
        if (sd->s_symlink.target_sd->s_dir.kobj != targ)
                goto out;
 
-       if (sysfs_ns_type(parent_sd))
-               new_ns = targ->ktype->namespace(targ);
-
-       result = sysfs_rename(sd, parent_sd, new_ns, new);
+       result = sysfs_rename(sd, parent_sd, new, new_ns);
 
 out:
        sysfs_put(sd);
        return result;
 }
-EXPORT_SYMBOL_GPL(sysfs_rename_link);
+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)
index b6deca3e301d2947c94c5789c8a941a0dfe497fa..0af09fbfb3f6abc112581638bf401b4b562430e8 100644 (file)
@@ -29,15 +29,13 @@ struct sysfs_elem_symlink {
 };
 
 struct sysfs_elem_attr {
-       struct attribute        *attr;
+       union {
+               struct attribute        *attr;
+               struct bin_attribute    *bin_attr;
+       };
        struct sysfs_open_dirent *open;
 };
 
-struct sysfs_elem_bin_attr {
-       struct bin_attribute    *bin_attr;
-       struct hlist_head       buffers;
-};
-
 struct sysfs_inode_attrs {
        struct iattr    ia_iattr;
        void            *ia_secdata;
@@ -74,7 +72,6 @@ struct sysfs_dirent {
                struct sysfs_elem_dir           s_dir;
                struct sysfs_elem_symlink       s_symlink;
                struct sysfs_elem_attr          s_attr;
-               struct sysfs_elem_bin_attr      s_bin_attr;
        };
 
        unsigned short          s_flags;
@@ -115,6 +112,7 @@ static inline enum kobj_ns_type sysfs_ns_type(struct sysfs_dirent *sd)
 }
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
+
 #define sysfs_dirent_init_lockdep(sd)                          \
 do {                                                           \
        struct attribute *attr = sd->s_attr.attr;               \
@@ -124,15 +122,31 @@ do {                                                              \
                                                                \
        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     *parent_sd;
        struct sysfs_dirent     *removed;
 };
 
@@ -156,38 +170,37 @@ extern struct kmem_cache *sysfs_dir_cachep;
  * dir.c
  */
 extern struct mutex sysfs_mutex;
-extern spinlock_t sysfs_assoc_lock;
+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 dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
 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,
-                      struct sysfs_dirent *parent_sd);
-int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
-int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
-void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, 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 void *ns,
-                                      const unsigned char *name);
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
-                                     const void *ns,
-                                     const unsigned char *name);
+                                      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);
-void sysfs_remove_subdir(struct sysfs_dirent *sd);
 
 int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
-                const void *ns, const char *new_name);
+                const char *new_name, const void *new_ns);
 
 static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
 {
@@ -218,25 +231,21 @@ 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_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
-                         const char *name);
 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);
 
-int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
-                       const struct attribute *attr, int type, umode_t amode);
-/*
- * bin.c
- */
-extern const struct file_operations bin_fops;
-void unmap_bin_file(struct sysfs_dirent *attr_sd);
+int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
+                          const struct attribute *attr, int type,
+                          umode_t amode, const void *ns);
+void sysfs_unmap_bin_file(struct sysfs_dirent *sd);
 
 /*
  * symlink.c
diff --git a/include/dt-bindings/mfd/dbx500-prcmu.h b/include/dt-bindings/mfd/dbx500-prcmu.h
new file mode 100644 (file)
index 0000000..552a2d1
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * This header provides constants for the PRCMU bindings.
+ *
+ */
+
+#ifndef _DT_BINDINGS_MFD_PRCMU_H
+#define _DT_BINDINGS_MFD_PRCMU_H
+
+/*
+ * Clock identifiers.
+ */
+#define ARMCLK                 0
+#define PRCMU_ACLK             1
+#define PRCMU_SVAMMCSPCLK      2
+#define PRCMU_SDMMCHCLK        2  /* DBx540 only. */
+#define PRCMU_SIACLK           3
+#define PRCMU_SIAMMDSPCLK      3  /* DBx540 only. */
+#define PRCMU_SGACLK           4
+#define PRCMU_UARTCLK          5
+#define PRCMU_MSP02CLK                 6
+#define PRCMU_MSP1CLK          7
+#define PRCMU_I2CCLK           8
+#define PRCMU_SDMMCCLK                 9
+#define PRCMU_SLIMCLK          10
+#define PRCMU_CAMCLK           10 /* DBx540 only. */
+#define PRCMU_PER1CLK          11
+#define PRCMU_PER2CLK          12
+#define PRCMU_PER3CLK          13
+#define PRCMU_PER5CLK          14
+#define PRCMU_PER6CLK          15
+#define PRCMU_PER7CLK          16
+#define PRCMU_LCDCLK           17
+#define PRCMU_BMLCLK           18
+#define PRCMU_HSITXCLK                 19
+#define PRCMU_HSIRXCLK                 20
+#define PRCMU_HDMICLK          21
+#define PRCMU_APEATCLK                 22
+#define PRCMU_APETRACECLK      23
+#define PRCMU_MCDECLK                  24
+#define PRCMU_IPI2CCLK         25
+#define PRCMU_DSIALTCLK        26
+#define PRCMU_DMACLK           27
+#define PRCMU_B2R2CLK                  28
+#define PRCMU_TVCLK            29
+#define SPARE_UNIPROCLK        30
+#define PRCMU_SSPCLK           31
+#define PRCMU_RNGCLK           32
+#define PRCMU_UICCCLK                  33
+#define PRCMU_G1CLK             34 /* DBx540 only. */
+#define PRCMU_HVACLK            35 /* DBx540 only. */
+#define PRCMU_SPARE1CLK                36
+#define PRCMU_SPARE2CLK                37
+
+#define PRCMU_NUM_REG_CLOCKS   38
+
+#define PRCMU_RTCCLK           PRCMU_NUM_REG_CLOCKS
+#define PRCMU_SYSCLK           39
+#define PRCMU_CDCLK            40
+#define PRCMU_TIMCLK           41
+#define PRCMU_PLLSOC0                  42
+#define PRCMU_PLLSOC1                  43
+#define PRCMU_ARMSS            44
+#define PRCMU_PLLDDR           45
+
+/* DSI Clocks */
+#define PRCMU_PLLDSI           46
+#define PRCMU_DSI0CLK          47
+#define PRCMU_DSI1CLK                  48
+#define PRCMU_DSI0ESCCLK       49
+#define PRCMU_DSI1ESCCLK       50
+#define PRCMU_DSI2ESCCLK       51
+
+/* LCD DSI PLL - Ux540 only */
+#define PRCMU_PLLDSI_LCD        52
+#define PRCMU_DSI0CLK_LCD       53
+#define PRCMU_DSI1CLK_LCD       54
+#define PRCMU_DSI0ESCCLK_LCD    55
+#define PRCMU_DSI1ESCCLK_LCD    56
+#define PRCMU_DSI2ESCCLK_LCD    57
+
+#define PRCMU_NUM_CLKS         58
+
+#endif
diff --git a/include/dt-bindings/pinctrl/am43xx.h b/include/dt-bindings/pinctrl/am43xx.h
new file mode 100644 (file)
index 0000000..eb6c366
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * This header provides constants specific to AM43XX pinctrl bindings.
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_AM43XX_H
+#define _DT_BINDINGS_PINCTRL_AM43XX_H
+
+#define MUX_MODE0      0
+#define MUX_MODE1      1
+#define MUX_MODE2      2
+#define MUX_MODE3      3
+#define MUX_MODE4      4
+#define MUX_MODE5      5
+#define MUX_MODE6      6
+#define MUX_MODE7      7
+
+#define PULL_DISABLE           (1 << 16)
+#define PULL_UP                        (1 << 17)
+#define INPUT_EN               (1 << 18)
+#define SLEWCTRL_FAST          (1 << 19)
+#define DS0_PULL_UP_DOWN_EN    (1 << 27)
+
+#define PIN_OUTPUT             (PULL_DISABLE)
+#define PIN_OUTPUT_PULLUP      (PULL_UP)
+#define PIN_OUTPUT_PULLDOWN    0
+#define PIN_INPUT              (INPUT_EN | PULL_DISABLE)
+#define PIN_INPUT_PULLUP       (INPUT_EN | PULL_UP)
+#define PIN_INPUT_PULLDOWN     (INPUT_EN)
+
+#endif
+
diff --git a/include/dt-bindings/pinctrl/dra.h b/include/dt-bindings/pinctrl/dra.h
new file mode 100644 (file)
index 0000000..002a285
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * This header provides constants for DRA pinctrl bindings.
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Rajendra Nayak <rnayak@ti.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 _DT_BINDINGS_PINCTRL_DRA_H
+#define _DT_BINDINGS_PINCTRL_DRA_H
+
+/* DRA7 mux mode options for each pin. See TRM for options */
+#define MUX_MODE0      0x0
+#define MUX_MODE1      0x1
+#define MUX_MODE2      0x2
+#define MUX_MODE3      0x3
+#define MUX_MODE4      0x4
+#define MUX_MODE5      0x5
+#define MUX_MODE6      0x6
+#define MUX_MODE7      0x7
+#define MUX_MODE8      0x8
+#define MUX_MODE9      0x9
+#define MUX_MODE10     0xa
+#define MUX_MODE11     0xb
+#define MUX_MODE12     0xc
+#define MUX_MODE13     0xd
+#define MUX_MODE14     0xe
+#define MUX_MODE15     0xf
+
+#define PULL_ENA               (1 << 16)
+#define PULL_UP                        (1 << 17)
+#define INPUT_EN               (1 << 18)
+#define SLEWCONTROL            (1 << 19)
+#define WAKEUP_EN              (1 << 24)
+#define WAKEUP_EVENT           (1 << 25)
+
+/* Active pin states */
+#define PIN_OUTPUT             0
+#define PIN_OUTPUT_PULLUP      (PIN_OUTPUT | PULL_ENA | PULL_UP)
+#define PIN_OUTPUT_PULLDOWN    (PIN_OUTPUT | PULL_ENA)
+#define PIN_INPUT              INPUT_EN
+#define PIN_INPUT_SLEW         (INPUT_EN | SLEWCONTROL)
+#define PIN_INPUT_PULLUP       (PULL_ENA | INPUT_EN | PULL_UP)
+#define PIN_INPUT_PULLDOWN     (PULL_ENA | INPUT_EN)
+
+#endif
+
index be201ca2990ce1a0363608b39f2dd210097c57a2..00beddf6be20358ca7cd108b54a45902c4478c8b 100644 (file)
 #define ATMEL_US_IF            0x4c                    /* IrDA Filter Register */
 
 #define ATMEL_US_NAME          0xf0                    /* Ip Name */
+#define ATMEL_US_VERSION       0xfc                    /* Ip Version */
 
 #endif
index 90c30dc3efc773abe3a8bdf9c18620209738b1ba..5138a90e018c981ce5fa8291351a2bb84303fd2e 100644 (file)
@@ -9,8 +9,6 @@
 #ifndef __LINUX_CLK_MXS_H
 #define __LINUX_CLK_MXS_H
 
-int mx23_clocks_init(void);
-int mx28_clocks_init(void);
 int mxs_saif_clkmux_select(unsigned int clkmux);
 
 #endif
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
deleted file mode 100644 (file)
index e074fdd..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2012 Maxime Ripard
- *
- * Maxime Ripard <maxime.ripard@free-electrons.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 __LINUX_CLK_SUNXI_H_
-#define __LINUX_CLK_SUNXI_H_
-
-void __init sunxi_init_clocks(void);
-
-#endif
index 263489d0788d02f2782b6d0a6dd4a504ba4da743..4d0b4d1aa1325256ae428294566257aaed04550a 100644 (file)
@@ -206,6 +206,12 @@ static inline struct dentry *debugfs_create_size_t(const char *name, umode_t mod
        return ERR_PTR(-ENODEV);
 }
 
+static inline struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
+                                    struct dentry *parent, atomic_t *value)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline struct dentry *debugfs_create_bool(const char *name, umode_t mode,
                                                 struct dentry *parent,
                                                 u32 *value)
@@ -227,6 +233,12 @@ static inline struct dentry *debugfs_create_regset32(const char *name,
        return ERR_PTR(-ENODEV);
 }
 
+static inline int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
+                        int nregs, void __iomem *base, char *prefix)
+{
+       return 0;
+}
+
 static inline bool debugfs_initialized(void)
 {
        return false;
index 2a9d6ed5957903009d9ea7eea1050b2463b66b64..b025925df7f75a5b86fa894de93e2e83d0bdf571 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/atomic.h>
 #include <linux/ratelimit.h>
 #include <linux/uidgid.h>
+#include <linux/gfp.h>
 #include <asm/device.h>
 
 struct device;
@@ -63,9 +64,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  * @name:      The name of the bus.
  * @dev_name:  Used for subsystems to enumerate devices like ("foo%u", dev->id).
  * @dev_root:  Default device to use as the parent.
- * @bus_attrs: Default attributes of the bus.
  * @dev_attrs: Default attributes of the devices on the bus.
- * @drv_attrs: Default attributes of the device drivers on the bus.
  * @bus_groups:        Default attributes of the bus.
  * @dev_groups:        Default attributes of the devices on the bus.
  * @drv_groups: Default attributes of the device drivers on the bus.
@@ -106,9 +105,7 @@ struct bus_type {
        const char              *name;
        const char              *dev_name;
        struct device           *dev_root;
-       struct bus_attribute    *bus_attrs;     /* use bus_groups instead */
        struct device_attribute *dev_attrs;     /* use dev_groups instead */
-       struct driver_attribute *drv_attrs;     /* use drv_groups instead */
        const struct attribute_group **bus_groups;
        const struct attribute_group **dev_groups;
        const struct attribute_group **drv_groups;
@@ -329,8 +326,6 @@ int subsys_virtual_register(struct bus_type *subsys,
  * @owner:     The module owner.
  * @class_attrs: Default attributes of this class.
  * @dev_groups:        Default attributes of the devices that belong to the class.
- * @dev_attrs: Default attributes of the devices belong to the class.
- * @dev_bin_attrs: Default binary attributes of the devices belong to the class.
  * @dev_kobj:  The kobject that represents this class and links it into the hierarchy.
  * @dev_uevent:        Called when a device is added, removed from this class, or a
  *             few other things that generate uevents to add the environment
@@ -358,9 +353,7 @@ struct class {
        struct module           *owner;
 
        struct class_attribute          *class_attrs;
-       struct device_attribute         *dev_attrs;     /* use dev_groups instead */
        const struct attribute_group    **dev_groups;
-       struct bin_attribute            *dev_bin_attrs;
        struct kobject                  *dev_kobj;
 
        int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
@@ -427,8 +420,6 @@ struct class_attribute {
                        char *buf);
        ssize_t (*store)(struct class *class, struct class_attribute *attr,
                        const char *buf, size_t count);
-       const void *(*namespace)(struct class *class,
-                                const struct class_attribute *attr);
 };
 
 #define CLASS_ATTR(_name, _mode, _show, _store) \
@@ -438,10 +429,24 @@ struct class_attribute {
 #define CLASS_ATTR_RO(_name) \
        struct class_attribute class_attr_##_name = __ATTR_RO(_name)
 
-extern int __must_check class_create_file(struct class *class,
-                                         const struct class_attribute *attr);
-extern void class_remove_file(struct class *class,
-                             const struct class_attribute *attr);
+extern int __must_check class_create_file_ns(struct class *class,
+                                            const struct class_attribute *attr,
+                                            const void *ns);
+extern void class_remove_file_ns(struct class *class,
+                                const struct class_attribute *attr,
+                                const void *ns);
+
+static inline int __must_check class_create_file(struct class *class,
+                                       const struct class_attribute *attr)
+{
+       return class_create_file_ns(class, attr, NULL);
+}
+
+static inline void class_remove_file(struct class *class,
+                                    const struct class_attribute *attr)
+{
+       return class_remove_file_ns(class, attr, NULL);
+}
 
 /* Simple class attribute that is just a static string */
 struct class_attribute_string {
@@ -602,8 +607,24 @@ extern void devres_close_group(struct device *dev, void *id);
 extern void devres_remove_group(struct device *dev, void *id);
 extern int devres_release_group(struct device *dev, void *id);
 
-/* managed kzalloc/kfree for device drivers, no kmalloc, always use kzalloc */
-extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
+/* managed devm_k.alloc/kfree for device drivers */
+extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp);
+static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
+{
+       return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
+}
+static inline void *devm_kmalloc_array(struct device *dev,
+                                      size_t n, size_t size, gfp_t flags)
+{
+       if (size != 0 && n > SIZE_MAX / size)
+               return NULL;
+       return devm_kmalloc(dev, n * size, flags);
+}
+static inline void *devm_kcalloc(struct device *dev,
+                                size_t n, size_t size, gfp_t flags)
+{
+       return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
+}
 extern void devm_kfree(struct device *dev, void *p);
 
 void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
@@ -1149,16 +1170,15 @@ do {                                                                    \
 #endif
 
 /*
- * dev_WARN*() acts like dev_printk(), but with the key difference
- * of using a WARN/WARN_ON to get the message out, including the
- * file/line information and a backtrace.
+ * dev_WARN*() acts like dev_printk(), but with the key difference of
+ * using WARN/WARN_ONCE to include file/line information and a backtrace.
  */
 #define dev_WARN(dev, format, arg...) \
-       WARN(1, "Device: %s\n" format, dev_driver_string(dev), ## arg);
+       WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
 
 #define dev_WARN_ONCE(dev, condition, format, arg...) \
-       WARN_ONCE(condition, "Device %s\n" format, \
-                       dev_driver_string(dev), ## arg)
+       WARN_ONCE(condition, "%s %s: " format, \
+                       dev_driver_string(dev), dev_name(dev), ## arg)
 
 /* Create alias, so I can be autoloaded. */
 #define MODULE_ALIAS_CHARDEV(major,minor) \
index fcb51c88319f1a2b3d09715f9d74a12dc25cf49a..21c59af1150b57588fbe697c9ef9fe38aacff06f 100644 (file)
 enum extcon_cable_name {
        EXTCON_USB = 0,
        EXTCON_USB_HOST,
-       EXTCON_TA, /* Travel Adaptor */
+       EXTCON_TA,                      /* Travel Adaptor */
        EXTCON_FAST_CHARGER,
        EXTCON_SLOW_CHARGER,
-       EXTCON_CHARGE_DOWNSTREAM, /* Charging an external device */
+       EXTCON_CHARGE_DOWNSTREAM,       /* Charging an external device */
        EXTCON_HDMI,
        EXTCON_MHL,
        EXTCON_DVI,
@@ -76,8 +76,8 @@ struct extcon_cable;
 
 /**
  * struct extcon_dev - An extcon device represents one external connector.
- * @name:      The name of this extcon device. Parent device name is used
- *             if NULL.
+ * @name:              The name of this extcon device. Parent device name is
+ *                     used if NULL.
  * @supported_cable:   Array of supported cable names ending with NULL.
  *                     If supported_cable is NULL, cable name related APIs
  *                     are disabled.
@@ -89,21 +89,21 @@ struct extcon_cable;
  *                     be attached simulataneously. {0x7, 0} is equivalent to
  *                     {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there
  *                     can be no simultaneous connections.
- * @print_name:        An optional callback to override the method to print the
- *             name of the extcon device.
+ * @print_name:                An optional callback to override the method to print the
+ *                     name of the extcon device.
  * @print_state:       An optional callback to override the method to print the
- *             status of the extcon device.
- * @dev:       Device of this extcon. Do not provide at register-time.
- * @state:     Attach/detach state of this extcon. Do not provide at
- *             register-time
- * @nh:        Notifier for the state change events from this extcon
- * @entry:     To support list of extcon devices so that users can search
- *             for extcon devices based on the extcon name.
+ *                     status of the extcon device.
+ * @dev:               Device of this extcon.
+ * @state:             Attach/detach state of this extcon. Do not provide at
+ *                     register-time.
+ * @nh:                        Notifier for the state change events from this extcon
+ * @entry:             To support list of extcon devices so that users can search
+ *                     for extcon devices based on the extcon name.
  * @lock:
  * @max_supported:     Internal value to store the number of cables.
  * @extcon_dev_type:   Device_type struct to provide attribute_groups
  *                     customized for each extcon device.
- * @cables:    Sysfs subdirectories. Each represents one cable.
+ * @cables:            Sysfs subdirectories. Each represents one cable.
  *
  * In most cases, users only need to provide "User initializing data" of
  * this struct when registering an extcon. In some exceptional cases,
@@ -111,26 +111,27 @@ struct extcon_cable;
  * are overwritten by register function.
  */
 struct extcon_dev {
-       /* --- Optional user initializing data --- */
-       const char      *name;
+       /* Optional user initializing data */
+       const char *name;
        const char **supported_cable;
-       const u32       *mutually_exclusive;
+       const u32 *mutually_exclusive;
 
-       /* --- Optional callbacks to override class functions --- */
+       /* Optional callbacks to override class functions */
        ssize_t (*print_name)(struct extcon_dev *edev, char *buf);
        ssize_t (*print_state)(struct extcon_dev *edev, char *buf);
 
-       /* --- Internal data. Please do not set. --- */
-       struct device   *dev;
-       u32             state;
+       /* Internal data. Please do not set. */
+       struct device dev;
        struct raw_notifier_head nh;
        struct list_head entry;
-       spinlock_t lock; /* could be called by irq handler */
        int max_supported;
+       spinlock_t lock;        /* could be called by irq handler */
+       u32 state;
 
        /* /sys/class/extcon/.../cable.n/... */
        struct device_type extcon_dev_type;
        struct extcon_cable *cables;
+
        /* /sys/class/extcon/.../mutually_exclusive/... */
        struct attribute_group attr_g_muex;
        struct attribute **attrs_muex;
@@ -138,13 +139,13 @@ struct extcon_dev {
 };
 
 /**
- * struct extcon_cable - An internal data for each cable of extcon device.
- * @edev:      The extcon device
+ * struct extcon_cable - An internal data for each cable of extcon device.
+ * @edev:              The extcon device
  * @cable_index:       Index of this cable in the edev
- * @attr_g:    Attribute group for the cable
- * @attr_name: "name" sysfs entry
- * @attr_state:        "state" sysfs entry
- * @attrs:     Array pointing to attr_name and attr_state for attr_g
+ * @attr_g:            Attribute group for the cable
+ * @attr_name:         "name" sysfs entry
+ * @attr_state:                "state" sysfs entry
+ * @attrs:             Array pointing to attr_name and attr_state for attr_g
  */
 struct extcon_cable {
        struct extcon_dev *edev;
@@ -159,11 +160,13 @@ struct extcon_cable {
 
 /**
  * struct extcon_specific_cable_nb - An internal data for
- *                             extcon_register_interest().
- * @internal_nb:       a notifier block bridging extcon notifier and cable notifier.
- * @user_nb:   user provided notifier block for events from a specific cable.
+ *                                  extcon_register_interest().
+ * @internal_nb:       A notifier block bridging extcon notifier
+ *                     and cable notifier.
+ * @user_nb:           user provided notifier block for events from
+ *                     a specific cable.
  * @cable_index:       the target cable.
- * @edev:      the target extcon device.
+ * @edev:              the target extcon device.
  * @previous_value:    the saved previous event value.
  */
 struct extcon_specific_cable_nb {
@@ -180,7 +183,7 @@ struct extcon_specific_cable_nb {
  * Following APIs are for notifiers or configurations.
  * Notifiers are the external port and connection devices.
  */
-extern int extcon_dev_register(struct extcon_dev *edev, struct device *dev);
+extern int extcon_dev_register(struct extcon_dev *edev);
 extern void extcon_dev_unregister(struct extcon_dev *edev);
 extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
 
@@ -238,8 +241,7 @@ extern int extcon_register_notifier(struct extcon_dev *edev,
 extern int extcon_unregister_notifier(struct extcon_dev *edev,
                                      struct notifier_block *nb);
 #else /* CONFIG_EXTCON */
-static inline int extcon_dev_register(struct extcon_dev *edev,
-                                     struct device *dev)
+static inline int extcon_dev_register(struct extcon_dev *edev)
 {
        return 0;
 }
index 20e9eef25d4c2d30e33fe4986e6eeb6276647bae..9ca958c4e94c79f9ae7997e47b6c521478930b19 100644 (file)
 
 /**
  * struct adc_jack_cond - condition to use an extcon state
- * @state      - the corresponding extcon state (if 0, this struct denotes
- *             the last adc_jack_cond element among the array)
- * @min_adc    - min adc value for this condition
- * @max_adc    - max adc value for this condition
+ * @state:             the corresponding extcon state (if 0, this struct
+ *                     denotes the last adc_jack_cond element among the array)
+ * @min_adc:           min adc value for this condition
+ * @max_adc:           max adc value for this condition
  *
  * For example, if { .state = 0x3, .min_adc = 100, .max_adc = 200}, it means
  * that if ADC value is between (inclusive) 100 and 200, than the cable 0 and
  * because when no adc_jack_cond is met, state = 0 is automatically chosen.
  */
 struct adc_jack_cond {
-       u32 state; /* extcon state value. 0 if invalid */
+       u32 state;      /* extcon state value. 0 if invalid */
        u32 min_adc;
        u32 max_adc;
 };
 
 /**
  * struct adc_jack_pdata - platform data for adc jack device.
- * @name       - name of the extcon device. If null, "adc-jack" is used.
- * @consumer_channel - Unique name to identify the channel on the consumer
- *                   side. This typically describes the channels used within
- *                   the consumer. E.g. 'battery_voltage'
- * @cable_names        - array of cable names ending with null.
- * @adc_contitions     - array of struct adc_jack_cond conditions ending
- *                     with .state = 0 entry. This describes how to decode
- *                     adc values into extcon state.
- * @irq_flags  - irq flags used for the @irq
- * @handling_delay_ms  - in some devices, we need to read ADC value some
- *                     milli-seconds after the interrupt occurs. You may
- *                     describe such delays with @handling_delay_ms, which
- *                     is rounded-off by jiffies.
+ * @name:              name of the extcon device. If null, "adc-jack" is used.
+ * @consumer_channel Unique name to identify the channel on the consumer
+ *                     side. This typically describes the channels used within
+ *                     the consumer. E.g. 'battery_voltage'
+ * @cable_names:       array of cable names ending with null.
+ * @adc_contitions:    array of struct adc_jack_cond conditions ending
+ *                     with .state = 0 entry. This describes how to decode
+ *                     adc values into extcon state.
+ * @irq_flags:         irq flags used for the @irq
+ * @handling_delay_ms: in some devices, we need to read ADC value some
+ *                     milli-seconds after the interrupt occurs. You may
+ *                     describe such delays with @handling_delay_ms, which
+ *                     is rounded-off by jiffies.
  */
 struct adc_jack_pdata {
        const char *name;
        const char *consumer_channel;
-       /*
-        * The last entry should be NULL
-        */
+
+       /* The last entry should be NULL */
        const char **cable_names;
+
        /* The last entry's state should be 0 */
        struct adc_jack_cond *adc_conditions;
 
index 2d8307f7d67decd0f0729b1f121cf0475e4b04b7..4195810f87fe6a3eda2eaf928b3361cb795626b8 100644 (file)
 
 /**
  * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device.
- * @name       The name of this GPIO extcon device.
- * @gpio       Corresponding GPIO.
- * @debounce   Debounce time for GPIO IRQ in ms.
- * @irq_flags  IRQ Flags (e.g., IRQF_TRIGGER_LOW).
- * @state_on   print_state is overriden with state_on if attached. If Null,
- *             default method of extcon class is used.
- * @state_off  print_state is overriden with state_on if detached. If Null,
- *             default method of extcon class is used.
+ * @name:              The name of this GPIO extcon device.
+ * @gpio:              Corresponding GPIO.
+ * @gpio_active_low:   Boolean describing whether gpio active state is 1 or 0
+ *                     If true, low state of gpio means active.
+ *                     If false, high state of gpio means active.
+ * @debounce:          Debounce time for GPIO IRQ in ms.
+ * @irq_flags:         IRQ Flags (e.g., IRQF_TRIGGER_LOW).
+ * @state_on:          print_state is overriden with state_on if attached.
+ *                     If NULL, default method of extcon class is used.
+ * @state_off:         print_state is overriden with state_on if detached.
+ *                     If NUll, default method of extcon class is used.
  *
  * Note that in order for state_on or state_off to be valid, both state_on
  * and state_off should be not NULL. If at least one of them is NULL,
@@ -41,6 +44,7 @@
 struct gpio_extcon_platform_data {
        const char *name;
        unsigned gpio;
+       bool gpio_active_low;
        unsigned long debounce;
        unsigned long irq_flags;
 
index 3f40547ba1917cd038f085bcdb6c6e577a9d4538..955dff5da56aca683bcbe6e46ca51bf5b39e0f5c 100644 (file)
@@ -2292,6 +2292,11 @@ static inline void allow_write_access(struct file *file)
        if (file)
                atomic_inc(&file_inode(file)->i_writecount);
 }
+static inline bool inode_is_open_for_write(const struct inode *inode)
+{
+       return atomic_read(&inode->i_writecount) > 0;
+}
+
 #ifdef CONFIG_IMA
 static inline void i_readcount_dec(struct inode *inode)
 {
index 7823e9ef995e2beaaa2b8e7a26a3c9619ee2e370..771484993ca7c662e6dc07c115e421050459256a 100644 (file)
@@ -308,36 +308,6 @@ struct fscache_cache_ops {
        void (*dissociate_pages)(struct fscache_cache *cache);
 };
 
-/*
- * data file or index object cookie
- * - a file will only appear in one cache
- * - a request to cache a file may or may not be honoured, subject to
- *   constraints such as disk space
- * - indices are created on disk just-in-time
- */
-struct fscache_cookie {
-       atomic_t                        usage;          /* number of users of this cookie */
-       atomic_t                        n_children;     /* number of children of this cookie */
-       atomic_t                        n_active;       /* number of active users of netfs ptrs */
-       spinlock_t                      lock;
-       spinlock_t                      stores_lock;    /* lock on page store tree */
-       struct hlist_head               backing_objects; /* object(s) backing this file/index */
-       const struct fscache_cookie_def *def;           /* definition */
-       struct fscache_cookie           *parent;        /* parent of this entry */
-       void                            *netfs_data;    /* back pointer to netfs */
-       struct radix_tree_root          stores;         /* pages to be stored on this cookie */
-#define FSCACHE_COOKIE_PENDING_TAG     0               /* pages tag: pending write to cache */
-#define FSCACHE_COOKIE_STORING_TAG     1               /* pages tag: writing to cache */
-
-       unsigned long                   flags;
-#define FSCACHE_COOKIE_LOOKING_UP      0       /* T if non-index cookie being looked up still */
-#define FSCACHE_COOKIE_NO_DATA_YET     1       /* T if new object with no cached data yet */
-#define FSCACHE_COOKIE_UNAVAILABLE     2       /* T if cookie is unavailable (error, etc) */
-#define FSCACHE_COOKIE_INVALIDATING    3       /* T if cookie is being invalidated */
-#define FSCACHE_COOKIE_RELINQUISHED    4       /* T if cookie has been relinquished */
-#define FSCACHE_COOKIE_RETIRED         5       /* T if cookie was retired */
-};
-
 extern struct fscache_cookie fscache_fsdef_index;
 
 /*
@@ -400,6 +370,7 @@ struct fscache_object {
 #define FSCACHE_OBJECT_IS_LIVE         3       /* T if object is not withdrawn or relinquished */
 #define FSCACHE_OBJECT_IS_LOOKED_UP    4       /* T if object has been looked up */
 #define FSCACHE_OBJECT_IS_AVAILABLE    5       /* T if object has become active */
+#define FSCACHE_OBJECT_RETIRED         6       /* T if object was retired on relinquishment */
 
        struct list_head        cache_link;     /* link in cache->object_list */
        struct hlist_node       cookie_link;    /* link in cookie->backing_objects */
@@ -511,6 +482,11 @@ static inline void fscache_end_io(struct fscache_retrieval *op,
        op->end_io_func(page, op->context, error);
 }
 
+static inline void __fscache_use_cookie(struct fscache_cookie *cookie)
+{
+       atomic_inc(&cookie->n_active);
+}
+
 /**
  * fscache_use_cookie - Request usage of cookie attached to an object
  * @object: Object description
@@ -524,6 +500,16 @@ static inline bool fscache_use_cookie(struct fscache_object *object)
        return atomic_inc_not_zero(&cookie->n_active) != 0;
 }
 
+static inline bool __fscache_unuse_cookie(struct fscache_cookie *cookie)
+{
+       return atomic_dec_and_test(&cookie->n_active);
+}
+
+static inline void __fscache_wake_unused_cookie(struct fscache_cookie *cookie)
+{
+       wake_up_atomic_t(&cookie->n_active);
+}
+
 /**
  * fscache_unuse_cookie - Cease usage of cookie attached to an object
  * @object: Object description
@@ -534,8 +520,8 @@ static inline bool fscache_use_cookie(struct fscache_object *object)
 static inline void fscache_unuse_cookie(struct fscache_object *object)
 {
        struct fscache_cookie *cookie = object->cookie;
-       if (atomic_dec_and_test(&cookie->n_active))
-               wake_up_atomic_t(&cookie->n_active);
+       if (__fscache_unuse_cookie(cookie))
+               __fscache_wake_unused_cookie(cookie);
 }
 
 /*
index 19b46458e4e88e3e25e55692a00ace4987897441..115bb81912ccc8759a54d206487cc8936e2a90c7 100644 (file)
@@ -166,6 +166,42 @@ struct fscache_netfs {
        struct list_head                link;           /* internal link */
 };
 
+/*
+ * data file or index object cookie
+ * - a file will only appear in one cache
+ * - a request to cache a file may or may not be honoured, subject to
+ *   constraints such as disk space
+ * - indices are created on disk just-in-time
+ */
+struct fscache_cookie {
+       atomic_t                        usage;          /* number of users of this cookie */
+       atomic_t                        n_children;     /* number of children of this cookie */
+       atomic_t                        n_active;       /* number of active users of netfs ptrs */
+       spinlock_t                      lock;
+       spinlock_t                      stores_lock;    /* lock on page store tree */
+       struct hlist_head               backing_objects; /* object(s) backing this file/index */
+       const struct fscache_cookie_def *def;           /* definition */
+       struct fscache_cookie           *parent;        /* parent of this entry */
+       void                            *netfs_data;    /* back pointer to netfs */
+       struct radix_tree_root          stores;         /* pages to be stored on this cookie */
+#define FSCACHE_COOKIE_PENDING_TAG     0               /* pages tag: pending write to cache */
+#define FSCACHE_COOKIE_STORING_TAG     1               /* pages tag: writing to cache */
+
+       unsigned long                   flags;
+#define FSCACHE_COOKIE_LOOKING_UP      0       /* T if non-index cookie being looked up still */
+#define FSCACHE_COOKIE_NO_DATA_YET     1       /* T if new object with no cached data yet */
+#define FSCACHE_COOKIE_UNAVAILABLE     2       /* T if cookie is unavailable (error, etc) */
+#define FSCACHE_COOKIE_INVALIDATING    3       /* T if cookie is being invalidated */
+#define FSCACHE_COOKIE_RELINQUISHED    4       /* T if cookie has been relinquished */
+#define FSCACHE_COOKIE_ENABLED         5       /* T if cookie is enabled */
+#define FSCACHE_COOKIE_ENABLEMENT_LOCK 6       /* T if cookie is being en/disabled */
+};
+
+static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie)
+{
+       return test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
+}
+
 /*
  * slow-path functions for when there is actually caching available, and the
  * netfs does actually have a valid token
@@ -181,8 +217,8 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *);
 extern struct fscache_cookie *__fscache_acquire_cookie(
        struct fscache_cookie *,
        const struct fscache_cookie_def *,
-       void *);
-extern void __fscache_relinquish_cookie(struct fscache_cookie *, int);
+       void *, bool);
+extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
 extern int __fscache_check_consistency(struct fscache_cookie *);
 extern void __fscache_update_cookie(struct fscache_cookie *);
 extern int __fscache_attr_changed(struct fscache_cookie *);
@@ -211,6 +247,9 @@ extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *,
                                              struct inode *);
 extern void __fscache_readpages_cancel(struct fscache_cookie *cookie,
                                       struct list_head *pages);
+extern void __fscache_disable_cookie(struct fscache_cookie *, bool);
+extern void __fscache_enable_cookie(struct fscache_cookie *,
+                                   bool (*)(void *), void *);
 
 /**
  * fscache_register_netfs - Register a filesystem as desiring caching services
@@ -289,6 +328,7 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag)
  * @def: A description of the cache object, including callback operations
  * @netfs_data: An arbitrary piece of data to be kept in the cookie to
  * represent the cache object to the netfs
+ * @enable: Whether or not to enable a data cookie immediately
  *
  * This function is used to inform FS-Cache about part of an index hierarchy
  * that can be used to locate files.  This is done by requesting a cookie for
@@ -301,10 +341,12 @@ static inline
 struct fscache_cookie *fscache_acquire_cookie(
        struct fscache_cookie *parent,
        const struct fscache_cookie_def *def,
-       void *netfs_data)
+       void *netfs_data,
+       bool enable)
 {
-       if (fscache_cookie_valid(parent))
-               return __fscache_acquire_cookie(parent, def, netfs_data);
+       if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent))
+               return __fscache_acquire_cookie(parent, def, netfs_data,
+                                               enable);
        else
                return NULL;
 }
@@ -322,7 +364,7 @@ struct fscache_cookie *fscache_acquire_cookie(
  * description.
  */
 static inline
-void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
 {
        if (fscache_cookie_valid(cookie))
                __fscache_relinquish_cookie(cookie, retire);
@@ -341,7 +383,7 @@ void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
 static inline
 int fscache_check_consistency(struct fscache_cookie *cookie)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                return __fscache_check_consistency(cookie);
        else
                return 0;
@@ -360,7 +402,7 @@ int fscache_check_consistency(struct fscache_cookie *cookie)
 static inline
 void fscache_update_cookie(struct fscache_cookie *cookie)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                __fscache_update_cookie(cookie);
 }
 
@@ -407,7 +449,7 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie)
 static inline
 int fscache_attr_changed(struct fscache_cookie *cookie)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                return __fscache_attr_changed(cookie);
        else
                return -ENOBUFS;
@@ -429,7 +471,7 @@ int fscache_attr_changed(struct fscache_cookie *cookie)
 static inline
 void fscache_invalidate(struct fscache_cookie *cookie)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                __fscache_invalidate(cookie);
 }
 
@@ -503,7 +545,7 @@ int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
                               void *context,
                               gfp_t gfp)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                return __fscache_read_or_alloc_page(cookie, page, end_io_func,
                                                    context, gfp);
        else
@@ -554,7 +596,7 @@ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
                                void *context,
                                gfp_t gfp)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                return __fscache_read_or_alloc_pages(cookie, mapping, pages,
                                                     nr_pages, end_io_func,
                                                     context, gfp);
@@ -585,7 +627,7 @@ int fscache_alloc_page(struct fscache_cookie *cookie,
                       struct page *page,
                       gfp_t gfp)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                return __fscache_alloc_page(cookie, page, gfp);
        else
                return -ENOBUFS;
@@ -634,7 +676,7 @@ int fscache_write_page(struct fscache_cookie *cookie,
                       struct page *page,
                       gfp_t gfp)
 {
-       if (fscache_cookie_valid(cookie))
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
                return __fscache_write_page(cookie, page, gfp);
        else
                return -ENOBUFS;
@@ -744,4 +786,47 @@ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
                __fscache_uncache_all_inode_pages(cookie, inode);
 }
 
+/**
+ * fscache_disable_cookie - Disable a cookie
+ * @cookie: The cookie representing the cache object
+ * @invalidate: Invalidate the backing object
+ *
+ * Disable a cookie from accepting further alloc, read, write, invalidate,
+ * update or acquire operations.  Outstanding operations can still be waited
+ * upon and pages can still be uncached and the cookie relinquished.
+ *
+ * This will not return until all outstanding operations have completed.
+ *
+ * If @invalidate is set, then the backing object will be invalidated and
+ * detached, otherwise it will just be detached.
+ */
+static inline
+void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
+{
+       if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
+               __fscache_disable_cookie(cookie, invalidate);
+}
+
+/**
+ * fscache_enable_cookie - Reenable a cookie
+ * @cookie: The cookie representing the cache object
+ * @can_enable: A function to permit enablement once lock is held
+ * @data: Data for can_enable()
+ *
+ * Reenable a previously disabled cookie, allowing it to accept further alloc,
+ * read, write, invalidate, update or acquire operations.  An attempt will be
+ * made to immediately reattach the cookie to a backing object.
+ *
+ * The can_enable() function is called (if not NULL) once the enablement lock
+ * is held to rule on whether enablement is still permitted to go ahead.
+ */
+static inline
+void fscache_enable_cookie(struct fscache_cookie *cookie,
+                          bool (*can_enable)(void *data),
+                          void *data)
+{
+       if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie))
+               __fscache_enable_cookie(cookie, can_enable, data);
+}
+
 #endif /* _LINUX_FSCACHE_H */
index 32ba45158d39eaf050adfc411118163f23858b4f..a265af294ea49a28c0384af71aa5ee1a249b3be8 100644 (file)
@@ -47,11 +47,13 @@ struct hid_sensor_hub_attribute_info {
  * @hdev:              Stores the hid instance.
  * @vendor_id:         Vendor id of hub device.
  * @product_id:                Product id of hub device.
+ * @ref_cnt:           Number of MFD clients have opened this device
  */
 struct hid_sensor_hub_device {
        struct hid_device *hdev;
        u32 vendor_id;
        u32 product_id;
+       int ref_cnt;
 };
 
 /**
@@ -74,6 +76,22 @@ struct hid_sensor_hub_callbacks {
                         void *priv);
 };
 
+/**
+* sensor_hub_device_open() - Open hub device
+* @hsdev:      Hub device instance.
+*
+* Used to open hid device for sensor hub.
+*/
+int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev);
+
+/**
+* sensor_hub_device_clode() - Close hub device
+* @hsdev:      Hub device instance.
+*
+* Used to clode hid device for sensor hub.
+*/
+void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev);
+
 /* Registration functions */
 
 /**
index d98503bde7e9bc7ace0e2c3ddc5f2ae019f527ff..15da677478ddc353b151d81362043bcbdfc3d089 100644 (file)
@@ -432,15 +432,6 @@ struct hv_ring_buffer_info {
        u32 ring_data_startoffset;
 };
 
-struct hv_ring_buffer_debug_info {
-       u32 current_interrupt_mask;
-       u32 current_read_index;
-       u32 current_write_index;
-       u32 bytes_avail_toread;
-       u32 bytes_avail_towrite;
-};
-
-
 /*
  *
  * hv_get_ringbuffer_availbytes()
@@ -902,23 +893,6 @@ enum vmbus_channel_state {
        CHANNEL_OPENED_STATE,
 };
 
-struct vmbus_channel_debug_info {
-       u32 relid;
-       enum vmbus_channel_state state;
-       uuid_le interfacetype;
-       uuid_le interface_instance;
-       u32 monitorid;
-       u32 servermonitor_pending;
-       u32 servermonitor_latency;
-       u32 servermonitor_connectionid;
-       u32 clientmonitor_pending;
-       u32 clientmonitor_latency;
-       u32 clientmonitor_connectionid;
-
-       struct hv_ring_buffer_debug_info inbound;
-       struct hv_ring_buffer_debug_info outbound;
-};
-
 /*
  * Represents each channel msg on the vmbus connection This is a
  * variable-size data structure depending on the msg type itself
@@ -1184,19 +1158,8 @@ extern int vmbus_recvpacket_raw(struct vmbus_channel *channel,
                                     u64 *requestid);
 
 
-extern void vmbus_get_debug_info(struct vmbus_channel *channel,
-                                    struct vmbus_channel_debug_info *debug);
-
 extern void vmbus_ontimer(unsigned long data);
 
-struct hv_dev_port_info {
-       u32 int_mask;
-       u32 read_idx;
-       u32 write_idx;
-       u32 bytes_avail_toread;
-       u32 bytes_avail_towrite;
-};
-
 /* Base driver object */
 struct hv_driver {
        const char *name;
index 81cbbdb96aae2bff8969fd68fefc086231de3c4b..673a3ce67f311df6567aa780dfdbf3d7adbe0cf9 100644 (file)
@@ -26,6 +26,7 @@
 #define __TWL_H_
 
 #include <linux/types.h>
+#include <linux/phy/phy.h>
 #include <linux/input/matrix_keypad.h>
 
 /*
@@ -615,6 +616,7 @@ enum twl4030_usb_mode {
 struct twl4030_usb_data {
        enum twl4030_usb_mode   usb_mode;
        unsigned long           features;
+       struct phy_init_data    *init_data;
 
        int             (*phy_init)(struct device *dev);
        int             (*phy_exit)(struct device *dev);
index b17974917dbf4369200901f119f670d14e0faa62..46a14229a162cf2bc5cc5e5b096c10c120766d8d 100644 (file)
@@ -1514,7 +1514,7 @@ static inline void ide_set_max_pio(ide_drive_t *drive)
 
 char *ide_media_string(ide_drive_t *);
 
-extern struct device_attribute ide_dev_attrs[];
+extern const struct attribute_group *ide_dev_groups[];
 extern struct bus_type ide_bus_type;
 extern struct class *ide_port_class;
 
index 2bac0eb8948df6c541d738823aaeb37153b018e0..15607b45221a9b9c03c6fdaade48afd9a4641c9e 100644 (file)
@@ -11,6 +11,7 @@
 #define _IIO_BUFFER_GENERIC_H_
 #include <linux/sysfs.h>
 #include <linux/iio/iio.h>
+#include <linux/kref.h>
 
 #ifdef CONFIG_IIO_BUFFER
 
@@ -26,6 +27,8 @@ struct iio_buffer;
  * @set_bytes_per_datum:set number of bytes per datum
  * @get_length:                get number of datums in buffer
  * @set_length:                set number of datums in buffer
+ * @release:           called when the last reference to the buffer is dropped,
+ *                     should free all resources allocated by the buffer.
  *
  * The purpose of this structure is to make the buffer element
  * modular as event for a given driver, different usecases may require
@@ -36,7 +39,7 @@ struct iio_buffer;
  * any of them not existing.
  **/
 struct iio_buffer_access_funcs {
-       int (*store_to)(struct iio_buffer *buffer, u8 *data);
+       int (*store_to)(struct iio_buffer *buffer, const void *data);
        int (*read_first_n)(struct iio_buffer *buffer,
                            size_t n,
                            char __user *buf);
@@ -47,6 +50,8 @@ struct iio_buffer_access_funcs {
        int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
        int (*get_length)(struct iio_buffer *buffer);
        int (*set_length)(struct iio_buffer *buffer, int length);
+
+       void (*release)(struct iio_buffer *buffer);
 };
 
 /**
@@ -67,6 +72,7 @@ struct iio_buffer_access_funcs {
  * @demux_list:                [INTERN] list of operations required to demux the scan.
  * @demux_bounce:      [INTERN] buffer for doing gather from incoming scan.
  * @buffer_list:       [INTERN] entry in the devices list of current buffers.
+ * @ref:               [INTERN] reference count of the buffer.
  */
 struct iio_buffer {
        int                                     length;
@@ -81,8 +87,9 @@ struct iio_buffer {
        bool                                    stufftoread;
        const struct attribute_group *attrs;
        struct list_head                        demux_list;
-       unsigned char                           *demux_bounce;
+       void                                    *demux_bounce;
        struct list_head                        buffer_list;
+       struct kref                             ref;
 };
 
 /**
@@ -120,7 +127,32 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
  * @indio_dev:         iio_dev structure for device.
  * @data:              Full scan.
  */
-int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data);
+int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data);
+
+/*
+ * iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers
+ * @indio_dev:         iio_dev structure for device.
+ * @data:              sample data
+ * @timestamp:         timestamp for the sample data
+ *
+ * Pushes data to the IIO device's buffers. If timestamps are enabled for the
+ * device the function will store the supplied timestamp as the last element in
+ * the sample data buffer before pushing it to the device buffers. The sample
+ * data buffer needs to be large enough to hold the additional timestamp
+ * (usually the buffer should be indio->scan_bytes bytes large).
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
+       void *data, int64_t timestamp)
+{
+       if (indio_dev->scan_timestamp) {
+               size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1;
+               ((int64_t *)data)[ts_offset] = timestamp;
+       }
+
+       return iio_push_to_buffers(indio_dev, data);
+}
 
 int iio_update_demux(struct iio_dev *indio_dev);
 
@@ -174,11 +206,27 @@ ssize_t iio_buffer_show_enable(struct device *dev,
                                           iio_buffer_show_enable,      \
                                           iio_buffer_store_enable)
 
-int iio_sw_buffer_preenable(struct iio_dev *indio_dev);
-
 bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
        const unsigned long *mask);
 
+struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer);
+void iio_buffer_put(struct iio_buffer *buffer);
+
+/**
+ * iio_device_attach_buffer - Attach a buffer to a IIO device
+ * @indio_dev: The device the buffer should be attached to
+ * @buffer: The buffer to attach to the device
+ *
+ * This function attaches a buffer to a IIO device. The buffer stays attached to
+ * the device until the device is freed. The function should only be called at
+ * most once per device.
+ */
+static inline void iio_device_attach_buffer(struct iio_dev *indio_dev,
+       struct iio_buffer *buffer)
+{
+       indio_dev->buffer = iio_buffer_get(buffer);
+}
+
 #else /* CONFIG_IIO_BUFFER */
 
 static inline int iio_buffer_register(struct iio_dev *indio_dev,
@@ -191,6 +239,9 @@ static inline int iio_buffer_register(struct iio_dev *indio_dev,
 static inline void iio_buffer_unregister(struct iio_dev *indio_dev)
 {}
 
+static inline void iio_buffer_get(struct iio_buffer *buffer) {}
+static inline void iio_buffer_put(struct iio_buffer *buffer) {}
+
 #endif /* CONFIG_IIO_BUFFER */
 
 #endif /* _IIO_BUFFER_GENERIC_H_ */
index e51f65480ea5a895828433444e0d3ec6348ca785..3c005eb3a0a4bab608479bd3ba7cd4d3dc65cd5f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/irqreturn.h>
 #include <linux/iio/trigger.h>
 #include <linux/bitops.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/platform_data/st_sensors_pdata.h>
 
@@ -184,6 +185,7 @@ struct st_sensors {
        u8 wai;
        char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME];
        struct iio_chan_spec *ch;
+       int num_ch;
        struct st_sensor_odr odr;
        struct st_sensor_power pw;
        struct st_sensor_axis enable_axis;
@@ -200,6 +202,8 @@ struct st_sensors {
  * @trig: The trigger in use by the core driver.
  * @sensor: Pointer to the current sensor struct in use.
  * @current_fullscale: Maximum range of measure by the sensor.
+ * @vdd: Pointer to sensor's Vdd power supply
+ * @vdd_io: Pointer to sensor's Vdd-IO power supply
  * @enabled: Status of the sensor (false->off, true->on).
  * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread.
  * @buffer_data: Data used by buffer part.
@@ -215,6 +219,8 @@ struct st_sensor_data {
        struct iio_trigger *trig;
        struct st_sensors *sensor;
        struct st_sensor_fullscale_avl *current_fullscale;
+       struct regulator *vdd;
+       struct regulator *vdd_io;
 
        bool enabled;
        bool multiread_bit;
index 833926c91aa84dff36403b814a046267dd968557..2752b1fd12be3ea8b41c58f64b408d88f1afddaa 100644 (file)
@@ -77,7 +77,7 @@ struct iio_cb_buffer;
  * fail.
  */
 struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
-                                            int (*cb)(u8 *data,
+                                            int (*cb)(const void *data,
                                                       void *private),
                                             void *private);
 /**
index 13ce220c70036f077b7c8ec28134d5d44c9a4eb4..5dab2c41031f059cce67944a0eea559a9e09bede 100644 (file)
@@ -26,20 +26,6 @@ struct iio_event_data {
 
 #define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int)
 
-enum iio_event_type {
-       IIO_EV_TYPE_THRESH,
-       IIO_EV_TYPE_MAG,
-       IIO_EV_TYPE_ROC,
-       IIO_EV_TYPE_THRESH_ADAPTIVE,
-       IIO_EV_TYPE_MAG_ADAPTIVE,
-};
-
-enum iio_event_direction {
-       IIO_EV_DIR_EITHER,
-       IIO_EV_DIR_RISING,
-       IIO_EV_DIR_FALLING,
-};
-
 /**
  * IIO_EVENT_CODE() - create event identifier
  * @chan_type: Type of the channel. Should be one of enum iio_chan_type.
index 2103cc32a5fb9b7d701d428e2f49ac636bbc6376..256a90a1bea681fde6473e2d5d74bc93ea868a87 100644 (file)
@@ -36,6 +36,14 @@ enum iio_chan_info_enum {
        IIO_CHAN_INFO_PHASE,
        IIO_CHAN_INFO_HARDWAREGAIN,
        IIO_CHAN_INFO_HYSTERESIS,
+       IIO_CHAN_INFO_INT_TIME,
+};
+
+enum iio_shared_by {
+       IIO_SEPARATE,
+       IIO_SHARED_BY_TYPE,
+       IIO_SHARED_BY_DIR,
+       IIO_SHARED_BY_ALL
 };
 
 enum iio_endian {
@@ -57,7 +65,7 @@ struct iio_dev;
  */
 struct iio_chan_spec_ext_info {
        const char *name;
-       bool shared;
+       enum iio_shared_by shared;
        ssize_t (*read)(struct iio_dev *, uintptr_t private,
                        struct iio_chan_spec const *, char *buf);
        ssize_t (*write)(struct iio_dev *, uintptr_t private,
@@ -125,11 +133,34 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
 #define IIO_ENUM_AVAILABLE(_name, _e) \
 { \
        .name = (_name "_available"), \
-       .shared = true, \
+       .shared = IIO_SHARED_BY_TYPE, \
        .read = iio_enum_available_read, \
        .private = (uintptr_t)(_e), \
 }
 
+/**
+ * struct iio_event_spec - specification for a channel event
+ * @type:                  Type of the event
+ * @dir:                   Direction of the event
+ * @mask_separate:         Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be registered per channel.
+ * @mask_shared_by_type:    Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be shared by channel type.
+ * @mask_shared_by_dir:            Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be shared by channel type and
+ *                         direction.
+ * @mask_shared_by_all:            Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be shared by all channels.
+ */
+struct iio_event_spec {
+       enum iio_event_type type;
+       enum iio_event_direction dir;
+       unsigned long mask_separate;
+       unsigned long mask_shared_by_type;
+       unsigned long mask_shared_by_dir;
+       unsigned long mask_shared_by_all;
+};
+
 /**
  * struct iio_chan_spec - specification of a single channel
  * @type:              What type of measurement is the channel making.
@@ -146,13 +177,18 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
  *                     shift:          Shift right by this before masking out
  *                                     realbits.
  *                     endianness:     little or big endian
- * @info_mask:         What information is to be exported about this channel.
- *                     This includes calibbias, scale etc.
  * @info_mask_separate: What information is to be exported that is specific to
  *                     this channel.
  * @info_mask_shared_by_type: What information is to be exported that is shared
-*                      by all channels of the same type.
+ *                     by all channels of the same type.
+ * @info_mask_shared_by_dir: What information is to be exported that is shared
+ *                     by all channels of the same direction.
+ * @info_mask_shared_by_all: What information is to be exported that is shared
+ *                     by all channels.
  * @event_mask:                What events can this channel produce.
+ * @event_spec:                Array of events which should be registered for this
+ *                     channel.
+ * @num_event_specs:   Size of the event_spec array.
  * @ext_info:          Array of extended info attributes for this channel.
  *                     The array is NULL terminated, the last element should
  *                     have its name field set to NULL.
@@ -186,10 +222,13 @@ struct iio_chan_spec {
                u8      shift;
                enum iio_endian endianness;
        } scan_type;
-       long                    info_mask;
        long                    info_mask_separate;
        long                    info_mask_shared_by_type;
+       long                    info_mask_shared_by_dir;
+       long                    info_mask_shared_by_all;
        long                    event_mask;
+       const struct iio_event_spec *event_spec;
+       unsigned int            num_event_specs;
        const struct iio_chan_spec_ext_info *ext_info;
        const char              *extend_name;
        const char              *datasheet_name;
@@ -212,7 +251,9 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
        enum iio_chan_info_enum type)
 {
        return (chan->info_mask_separate & BIT(type)) |
-              (chan->info_mask_shared_by_type & BIT(type));
+               (chan->info_mask_shared_by_type & BIT(type)) |
+               (chan->info_mask_shared_by_dir & BIT(type)) |
+               (chan->info_mask_shared_by_all & BIT(type));
 }
 
 #define IIO_ST(si, rb, sb, sh)                                         \
@@ -270,6 +311,12 @@ struct iio_dev;
  *                     is event dependant. event_code specifies which event.
  * @write_event_value: write the value associated with the event.
  *                     Meaning is event dependent.
+ * @read_event_config_new: find out if the event is enabled. New style interface.
+ * @write_event_config_new: set if the event is enabled. New style interface.
+ * @read_event_value_new: read a configuration value associated with the event.
+ *                         New style interface.
+ * @write_event_value_new: write a configuration value for the event. New style
+ *                        interface.
  * @validate_trigger:  function to validate the trigger when the
  *                     current trigger gets changed.
  * @update_scan_mode:  function to configure device and scan buffer when
@@ -310,6 +357,30 @@ struct iio_info {
        int (*write_event_value)(struct iio_dev *indio_dev,
                                 u64 event_code,
                                 int val);
+
+       int (*read_event_config_new)(struct iio_dev *indio_dev,
+                                const struct iio_chan_spec *chan,
+                                enum iio_event_type type,
+                                enum iio_event_direction dir);
+
+       int (*write_event_config_new)(struct iio_dev *indio_dev,
+                                 const struct iio_chan_spec *chan,
+                                 enum iio_event_type type,
+                                 enum iio_event_direction dir,
+                                 int state);
+
+       int (*read_event_value_new)(struct iio_dev *indio_dev,
+                               const struct iio_chan_spec *chan,
+                               enum iio_event_type type,
+                               enum iio_event_direction dir,
+                               enum iio_event_info info, int *val, int *val2);
+
+       int (*write_event_value_new)(struct iio_dev *indio_dev,
+                                const struct iio_chan_spec *chan,
+                                enum iio_event_type type,
+                                enum iio_event_direction dir,
+                                enum iio_event_info info, int val, int val2);
+
        int (*validate_trigger)(struct iio_dev *indio_dev,
                                struct iio_trigger *trig);
        int (*update_scan_mode)(struct iio_dev *indio_dev,
@@ -457,7 +528,7 @@ static inline void iio_device_put(struct iio_dev *indio_dev)
 {
        if (indio_dev)
                put_device(&indio_dev->dev);
-};
+}
 
 /**
  * dev_to_iio_dev() - Get IIO device struct from a device struct
@@ -593,7 +664,7 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
 {
        return indio_dev->currentmode
                & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE);
-};
+}
 
 /**
  * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry
@@ -603,12 +674,12 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
 static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
 {
        return indio_dev->debugfs_dentry;
-};
+}
 #else
 static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
 {
        return NULL;
-};
+}
 #endif
 
 int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer,
index 2958c960003a7ed3bcb22baf8ca02266f3736c7d..8a1d18640ab94dd7d29ddec3473f3c5c0e9ef112 100644 (file)
@@ -100,6 +100,21 @@ struct iio_const_attr {
 #define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string)                        \
        IIO_CONST_ATTR(sampling_frequency_available, _string)
 
+/**
+ * IIO_DEV_ATTR_INT_TIME_AVAIL - list available integration times
+ * @_show: output method for the attribute
+ **/
+#define IIO_DEV_ATTR_INT_TIME_AVAIL(_show)             \
+       IIO_DEVICE_ATTR(integration_time_available, S_IRUGO, _show, NULL, 0)
+/**
+ * IIO_CONST_ATTR_INT_TIME_AVAIL - list available integration times
+ * @_string: frequency string for the attribute
+ *
+ * Constant version
+ **/
+#define IIO_CONST_ATTR_INT_TIME_AVAIL(_string)         \
+       IIO_CONST_ATTR(integration_time_available, _string)
+
 #define IIO_DEV_ATTR_TEMP_RAW(_show)                   \
        IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0)
 
index 88bf0f0d27b4a973b6b211b06ececfd294c82c4c..4ac928ee31c5e4c59c03de6aff936190168bb1f2 100644 (file)
@@ -54,6 +54,26 @@ enum iio_modifier {
        IIO_MOD_LIGHT_BLUE,
 };
 
+enum iio_event_type {
+       IIO_EV_TYPE_THRESH,
+       IIO_EV_TYPE_MAG,
+       IIO_EV_TYPE_ROC,
+       IIO_EV_TYPE_THRESH_ADAPTIVE,
+       IIO_EV_TYPE_MAG_ADAPTIVE,
+};
+
+enum iio_event_info {
+       IIO_EV_INFO_ENABLE,
+       IIO_EV_INFO_VALUE,
+       IIO_EV_INFO_HYSTERESIS,
+};
+
+enum iio_event_direction {
+       IIO_EV_DIR_EITHER,
+       IIO_EV_DIR_RISING,
+       IIO_EV_DIR_FALLING,
+};
+
 #define IIO_VAL_INT 1
 #define IIO_VAL_INT_PLUS_MICRO 2
 #define IIO_VAL_INT_PLUS_NANO 3
index 5e865b55494096898112234b1f2898cfc372d757..c9e831dc80bccb10efaec812787f75b57fbf5b71 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/atomic.h>
 #include <asm/ptrace.h>
+#include <asm/irq.h>
 
 /*
  * These correspond to the IORESOURCE_IRQ_* defines in
@@ -374,6 +375,16 @@ struct softirq_action
 
 asmlinkage void do_softirq(void);
 asmlinkage void __do_softirq(void);
+
+#ifdef __ARCH_HAS_DO_SOFTIRQ
+void do_softirq_own_stack(void);
+#else
+static inline void do_softirq_own_stack(void)
+{
+       __do_softirq();
+}
+#endif
+
 extern void open_softirq(int nr, void (*action)(struct softirq_action *));
 extern void softirq_init(void);
 extern void __raise_softirq_irqoff(unsigned int nr);
index 19c19a5eee293396d0ddec9454e1ecb55adfed5b..f6c82de125413e8b6076ab91d68f64771641bfd1 100644 (file)
@@ -34,9 +34,9 @@ struct ipc_namespace {
        int             sem_ctls[4];
        int             used_sems;
 
-       int             msg_ctlmax;
-       int             msg_ctlmnb;
-       int             msg_ctlmni;
+       unsigned int    msg_ctlmax;
+       unsigned int    msg_ctlmnb;
+       unsigned int    msg_ctlmni;
        atomic_t        msg_bytes;
        atomic_t        msg_hdrs;
        int             auto_msgmni;
diff --git a/include/linux/irqchip/bcm2835.h b/include/linux/irqchip/bcm2835.h
deleted file mode 100644 (file)
index 48a859b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2010 Broadcom
- *
- * 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
- */
-
-#ifndef __LINUX_IRQCHIP_BCM2835_H_
-#define __LINUX_IRQCHIP_BCM2835_H_
-
-#include <asm/exception.h>
-
-extern void bcm2835_init_irq(void);
-
-extern asmlinkage void __exception_irq_entry bcm2835_handle_irq(
-       struct pt_regs *regs);
-
-#endif
diff --git a/include/linux/kobj_completion.h b/include/linux/kobj_completion.h
new file mode 100644 (file)
index 0000000..a428f64
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _KOBJ_COMPLETION_H_
+#define _KOBJ_COMPLETION_H_
+
+#include <linux/kobject.h>
+#include <linux/completion.h>
+
+struct kobj_completion {
+       struct kobject kc_kobj;
+       struct completion kc_unregister;
+};
+
+#define kobj_to_kobj_completion(kobj) \
+       container_of(kobj, struct kobj_completion, kc_kobj)
+
+void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype);
+void kobj_completion_release(struct kobject *kobj);
+void kobj_completion_del_and_wait(struct kobj_completion *kc);
+#endif /* _KOBJ_COMPLETION_H_ */
index de6dcbcc6ef74335745943956cae0ba70bb35154..e7ba650086ce47078bbf64353bc63a2da5007ef1 100644 (file)
@@ -107,6 +107,7 @@ extern int __must_check kobject_move(struct kobject *, struct kobject *);
 extern struct kobject *kobject_get(struct kobject *kobj);
 extern void kobject_put(struct kobject *kobj);
 
+extern const void *kobject_namespace(struct kobject *kobj);
 extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
 
 struct kobj_type {
index f279ed9a91631cca7f236d20ef5a29d152332932..13dfd36a329474df228102dd49bafbdf1b5c687d 100644 (file)
@@ -36,4 +36,10 @@ extern int lockref_put_or_lock(struct lockref *);
 extern void lockref_mark_dead(struct lockref *);
 extern int lockref_get_not_dead(struct lockref *);
 
+/* Must be called under spinlock for reliable results */
+static inline int __lockref_is_dead(const struct lockref *l)
+{
+       return ((int)l->count < 0);
+}
+
 #endif /* __LINUX_LOCKREF_H */
index ca0790fba2f5d60abbe975fa3547c363c525f443..060e11256fbcf8866afc23d900134d4040c7a59a 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/notifier.h>
 #include <linux/err.h>
 
+#include <dt-bindings/mfd/dbx500-prcmu.h> /* For clock identifiers */
+
 /* Offset for the firmware version within the TCPM */
 #define DB8500_PRCMU_FW_VERSION_OFFSET 0xA4
 #define DBX540_PRCMU_FW_VERSION_OFFSET 0xA8
@@ -94,74 +96,6 @@ enum prcmu_wakeup_index {
 #define PRCMU_CLKSRC_ARMCLKFIX         0x46
 #define PRCMU_CLKSRC_HDMICLK           0x47
 
-/*
- * Clock identifiers.
- */
-enum prcmu_clock {
-       PRCMU_SGACLK,
-       PRCMU_UARTCLK,
-       PRCMU_MSP02CLK,
-       PRCMU_MSP1CLK,
-       PRCMU_I2CCLK,
-       PRCMU_SDMMCCLK,
-       PRCMU_SPARE1CLK,
-       PRCMU_SLIMCLK,
-       PRCMU_PER1CLK,
-       PRCMU_PER2CLK,
-       PRCMU_PER3CLK,
-       PRCMU_PER5CLK,
-       PRCMU_PER6CLK,
-       PRCMU_PER7CLK,
-       PRCMU_LCDCLK,
-       PRCMU_BMLCLK,
-       PRCMU_HSITXCLK,
-       PRCMU_HSIRXCLK,
-       PRCMU_HDMICLK,
-       PRCMU_APEATCLK,
-       PRCMU_APETRACECLK,
-       PRCMU_MCDECLK,
-       PRCMU_IPI2CCLK,
-       PRCMU_DSIALTCLK,
-       PRCMU_DMACLK,
-       PRCMU_B2R2CLK,
-       PRCMU_TVCLK,
-       PRCMU_SSPCLK,
-       PRCMU_RNGCLK,
-       PRCMU_UICCCLK,
-       PRCMU_PWMCLK,
-       PRCMU_IRDACLK,
-       PRCMU_IRRCCLK,
-       PRCMU_SIACLK,
-       PRCMU_SVACLK,
-       PRCMU_ACLK,
-       PRCMU_HVACLK, /* Ux540 only */
-       PRCMU_G1CLK, /* Ux540 only */
-       PRCMU_SDMMCHCLK,
-       PRCMU_CAMCLK,
-       PRCMU_BML8580CLK,
-       PRCMU_NUM_REG_CLOCKS,
-       PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS,
-       PRCMU_CDCLK,
-       PRCMU_TIMCLK,
-       PRCMU_PLLSOC0,
-       PRCMU_PLLSOC1,
-       PRCMU_ARMSS,
-       PRCMU_PLLDDR,
-       PRCMU_PLLDSI,
-       PRCMU_DSI0CLK,
-       PRCMU_DSI1CLK,
-       PRCMU_DSI0ESCCLK,
-       PRCMU_DSI1ESCCLK,
-       PRCMU_DSI2ESCCLK,
-       /* LCD DSI PLL - Ux540 only */
-       PRCMU_PLLDSI_LCD,
-       PRCMU_DSI0CLK_LCD,
-       PRCMU_DSI1CLK_LCD,
-       PRCMU_DSI0ESCCLK_LCD,
-       PRCMU_DSI1ESCCLK_LCD,
-       PRCMU_DSI2ESCCLK_LCD,
-};
-
 /**
  * enum prcmu_wdog_id - PRCMU watchdog IDs
  * @PRCMU_WDOG_ALL: use all timers
index b6bdcd66c07d2e758ba677f9c9c1796ada542bc8..7086b2248c8f0c00867f17d3fa90757cceca64cd 100644 (file)
 #define IMX6Q_GPR13_SATA_TX_LVL_1_240_V                (0x1f << 2)
 #define IMX6Q_GPR13_SATA_MPLL_CLK_EN           BIT(1)
 #define IMX6Q_GPR13_SATA_TX_EDGE_RATE          BIT(0)
+
+/* For imx6sl iomux gpr register field define */
+#define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK    (0x3 << 17)
+#define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK    (0x1 << 14)
+
 #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
index 25f2c611ab013db8e3a4135a00c129b3d556e7d5..08cce7f96ab9365359c30a4726d910022f571be5 100644 (file)
 /* Step Enable */
 #define STEPENB_MASK           (0x1FFFF << 0)
 #define STEPENB(val)           ((val) << 0)
+#define ENB(val)                       (1 << (val))
+#define STPENB_STEPENB         STEPENB(0x1FFFF)
+#define STPENB_STEPENB_TC      STEPENB(0x1FFF)
 
 /* IRQ enable */
 #define IRQENB_HW_PEN          BIT(0)
 #define IRQENB_FIFO0THRES      BIT(2)
+#define IRQENB_FIFO0OVRRUN     BIT(3)
+#define IRQENB_FIFO0UNDRFLW    BIT(4)
 #define IRQENB_FIFO1THRES      BIT(5)
+#define IRQENB_FIFO1OVRRUN     BIT(6)
+#define IRQENB_FIFO1UNDRFLW    BIT(7)
 #define IRQENB_PENUP           BIT(9)
 
 /* Step Configuration */
 #define STEPCONFIG_MODE_MASK   (3 << 0)
 #define STEPCONFIG_MODE(val)   ((val) << 0)
+#define STEPCONFIG_MODE_SWCNT  STEPCONFIG_MODE(1)
 #define STEPCONFIG_MODE_HWSYNC STEPCONFIG_MODE(2)
 #define STEPCONFIG_AVG_MASK    (7 << 2)
 #define STEPCONFIG_AVG(val)    ((val) << 2)
 #define ADC_CLK                        3000000
 #define TOTAL_STEPS            16
 #define TOTAL_CHANNELS         8
+#define FIFO1_THRESHOLD                19
 
 /*
 * ADC runs at 3MHz, and it takes
index 25f5d2d11e7c4c5b6053c4ba5c7ac17a601f4f2b..adf4070586d64be47fe5d18ed8f554e0c66670e1 100644 (file)
@@ -2874,8 +2874,20 @@ extern int __init dev_proc_init(void);
 #define dev_proc_init() 0
 #endif
 
-extern int netdev_class_create_file(struct class_attribute *class_attr);
-extern void netdev_class_remove_file(struct class_attribute *class_attr);
+extern int netdev_class_create_file_ns(struct class_attribute *class_attr,
+                                      const void *ns);
+extern void netdev_class_remove_file_ns(struct class_attribute *class_attr,
+                                       const void *ns);
+
+static inline int netdev_class_create_file(struct class_attribute *class_attr)
+{
+       return netdev_class_create_file_ns(class_attr, NULL);
+}
+
+static inline void netdev_class_remove_file(struct class_attribute *class_attr)
+{
+       netdev_class_remove_file_ns(class_attr, NULL);
+}
 
 extern struct kobj_ns_type_operations net_ns_type_operations;
 
index f3c7c24bec1ca99c89270611d87f9c264c3eb786..fbfdb9d8d3a7f59b4788bdfd1cdb26c86f0a81ca 100644 (file)
@@ -24,7 +24,8 @@ struct netpoll {
        struct net_device *dev;
        char dev_name[IFNAMSIZ];
        const char *name;
-       void (*rx_hook)(struct netpoll *, int, char *, int);
+       void (*rx_skb_hook)(struct netpoll *np, int source, struct sk_buff *skb,
+                           int offset, int len);
 
        union inet_addr local_ip, remote_ip;
        bool ipv6;
@@ -41,7 +42,7 @@ struct netpoll_info {
        unsigned long rx_flags;
        spinlock_t rx_lock;
        struct semaphore dev_lock;
-       struct list_head rx_np; /* netpolls that registered an rx_hook */
+       struct list_head rx_np; /* netpolls that registered an rx_skb_hook */
 
        struct sk_buff_head neigh_tx; /* list of neigh requests to reply to */
        struct sk_buff_head txq;
index e36dee52f224f146805b58a48008012dc68602a8..c6f41b616965b7b872879d873e49473e0fe81a6e 100644 (file)
@@ -395,7 +395,9 @@ enum lock_type4 {
 #define FATTR4_WORD1_FS_LAYOUT_TYPES    (1UL << 30)
 #define FATTR4_WORD2_LAYOUT_BLKSIZE     (1UL << 1)
 #define FATTR4_WORD2_MDSTHRESHOLD       (1UL << 4)
-#define FATTR4_WORD2_SECURITY_LABEL     (1UL << 17)
+#define FATTR4_WORD2_SECURITY_LABEL     (1UL << 16)
+#define FATTR4_WORD2_CHANGE_SECURITY_LABEL \
+                                       (1UL << 17)
 
 /* MDS threshold bitmap bits */
 #define THRESHOLD_RD                    (1UL << 0)
@@ -460,6 +462,7 @@ enum {
        NFSPROC4_CLNT_FS_LOCATIONS,
        NFSPROC4_CLNT_RELEASE_LOCKOWNER,
        NFSPROC4_CLNT_SECINFO,
+       NFSPROC4_CLNT_FSID_PRESENT,
 
        /* nfs41 */
        NFSPROC4_CLNT_EXCHANGE_ID,
index 3ea4cde8701ce1e97d6a39a4a1264452468a5254..14a48207a304ec65dda6ac8af22e0e0825b8fa6b 100644 (file)
@@ -269,9 +269,13 @@ static inline int NFS_STALE(const struct inode *inode)
        return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
 }
 
-static inline int NFS_FSCACHE(const struct inode *inode)
+static inline struct fscache_cookie *nfs_i_fscache(struct inode *inode)
 {
-       return test_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+#ifdef CONFIG_NFS_FSCACHE
+       return NFS_I(inode)->fscache;
+#else
+       return NULL;
+#endif
 }
 
 static inline __u64 NFS_FILEID(const struct inode *inode)
index b8cedced50c9c70dd00c680d42a424bcdb90a8a9..1150ea41b626723b67720320a23f0810a2ec2be4 100644 (file)
@@ -41,6 +41,7 @@ struct nfs_client {
 #define NFS_CS_DISCRTRY                1               /* - disconnect on RPC retry */
 #define NFS_CS_MIGRATION       2               /* - transparent state migr */
 #define NFS_CS_INFINITE_SLOTS  3               /* - don't limit TCP slots */
+#define NFS_CS_NO_RETRANS_TIMEOUT      4       /* - Disable retransmit timeouts */
        struct sockaddr_storage cl_addr;        /* server identifier */
        size_t                  cl_addrlen;
        char *                  cl_hostname;    /* hostname of server */
@@ -78,6 +79,7 @@ struct nfs_client {
        char                    cl_ipaddr[48];
        u32                     cl_cb_ident;    /* v4.0 callback identifier */
        const struct nfs4_minor_version_ops *cl_mvops;
+       unsigned long           cl_mig_gen;
 
        /* NFSv4.0 transport blocking */
        struct nfs4_slot_table  *cl_slot_tbl;
@@ -147,7 +149,9 @@ struct nfs_server {
        __u64                   maxfilesize;    /* maximum file size */
        struct timespec         time_delta;     /* smallest time granularity */
        unsigned long           mount_time;     /* when this fs was mounted */
+       struct super_block      *super;         /* VFS super block */
        dev_t                   s_dev;          /* superblock dev numbers */
+       struct nfs_auth_info    auth_info;      /* parsed auth flavors */
 
 #ifdef CONFIG_NFS_FSCACHE
        struct nfs_fscache_key  *fscache_key;   /* unique key for superblock */
@@ -187,6 +191,12 @@ struct nfs_server {
        struct list_head        state_owners_lru;
        struct list_head        layouts;
        struct list_head        delegations;
+
+       unsigned long           mig_gen;
+       unsigned long           mig_status;
+#define NFS_MIG_IN_TRANSITION          (1)
+#define NFS_MIG_FAILED                 (2)
+
        void (*destroy)(struct nfs_server *);
 
        atomic_t active; /* Keep trace of any activity to this server */
index 49f52c8f4422ffd8ce6f0e17d33e960e92361076..3ccfcecf8999550b25c84d77edef546d4eb9cf54 100644 (file)
@@ -591,6 +591,13 @@ struct nfs_renameres {
        struct nfs_fattr                *new_fattr;
 };
 
+/* parsed sec= options */
+#define NFS_AUTH_INFO_MAX_FLAVORS 12 /* see fs/nfs/super.c */
+struct nfs_auth_info {
+       unsigned int            flavor_len;
+       rpc_authflavor_t        flavors[NFS_AUTH_INFO_MAX_FLAVORS];
+};
+
 /*
  * Argument struct for decode_entry function
  */
@@ -1053,14 +1060,18 @@ struct nfs4_fs_locations {
 struct nfs4_fs_locations_arg {
        struct nfs4_sequence_args       seq_args;
        const struct nfs_fh *dir_fh;
+       const struct nfs_fh *fh;
        const struct qstr *name;
        struct page *page;
        const u32 *bitmask;
+       clientid4 clientid;
+       unsigned char migration:1, renew:1;
 };
 
 struct nfs4_fs_locations_res {
        struct nfs4_sequence_res        seq_res;
        struct nfs4_fs_locations       *fs_locations;
+       unsigned char                   migration:1, renew:1;
 };
 
 struct nfs4_secinfo4 {
@@ -1084,6 +1095,19 @@ struct nfs4_secinfo_res {
        struct nfs4_secinfo_flavors     *flavors;
 };
 
+struct nfs4_fsid_present_arg {
+       struct nfs4_sequence_args       seq_args;
+       const struct nfs_fh             *fh;
+       clientid4                       clientid;
+       unsigned char                   renew:1;
+};
+
+struct nfs4_fsid_present_res {
+       struct nfs4_sequence_res        seq_res;
+       struct nfs_fh                   *fh;
+       unsigned char                   renew:1;
+};
+
 #endif /* CONFIG_NFS_V4 */
 
 struct nfstime4 {
index c8ba627c1d608733b8480bb929d9e81d97e57fa0..2e069d1288df5f04e6982243d7cac0f7455cd31d 100644 (file)
@@ -584,6 +584,10 @@ struct perf_sample_data {
        struct perf_regs_user           regs_user;
        u64                             stack_user_size;
        u64                             weight;
+       /*
+        * Transaction flags for abort events:
+        */
+       u64                             txn;
 };
 
 static inline void perf_sample_data_init(struct perf_sample_data *data,
@@ -599,6 +603,7 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
        data->stack_user_size = 0;
        data->weight = 0;
        data->data_src.val = 0;
+       data->txn = 0;
 }
 
 extern void perf_output_sample(struct perf_output_handle *handle,
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
new file mode 100644 (file)
index 0000000..6d72269
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * phy.h -- generic phy header file
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.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.
+ */
+
+#ifndef __DRIVERS_PHY_H
+#define __DRIVERS_PHY_H
+
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/device.h>
+#include <linux/pm_runtime.h>
+
+struct phy;
+
+/**
+ * struct phy_ops - set of function pointers for performing phy operations
+ * @init: operation to be performed for initializing phy
+ * @exit: operation to be performed while exiting
+ * @power_on: powering on the phy
+ * @power_off: powering off the phy
+ * @owner: the module owner containing the ops
+ */
+struct phy_ops {
+       int     (*init)(struct phy *phy);
+       int     (*exit)(struct phy *phy);
+       int     (*power_on)(struct phy *phy);
+       int     (*power_off)(struct phy *phy);
+       struct module *owner;
+};
+
+/**
+ * struct phy - represents the phy device
+ * @dev: phy device
+ * @id: id of the phy device
+ * @ops: function pointers for performing phy operations
+ * @init_data: list of PHY consumers (non-dt only)
+ * @mutex: mutex to protect phy_ops
+ * @init_count: used to protect when the PHY is used by multiple consumers
+ * @power_count: used to protect when the PHY is used by multiple consumers
+ */
+struct phy {
+       struct device           dev;
+       int                     id;
+       const struct phy_ops    *ops;
+       struct phy_init_data    *init_data;
+       struct mutex            mutex;
+       int                     init_count;
+       int                     power_count;
+};
+
+/**
+ * struct phy_provider - represents the phy provider
+ * @dev: phy provider device
+ * @owner: the module owner having of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy pointer
+ * @list: to maintain a linked list of PHY providers
+ */
+struct phy_provider {
+       struct device           *dev;
+       struct module           *owner;
+       struct list_head        list;
+       struct phy * (*of_xlate)(struct device *dev,
+               struct of_phandle_args *args);
+};
+
+/**
+ * struct phy_consumer - represents the phy consumer
+ * @dev_name: the device name of the controller that will use this PHY device
+ * @port: name given to the consumer port
+ */
+struct phy_consumer {
+       const char *dev_name;
+       const char *port;
+};
+
+/**
+ * struct phy_init_data - contains the list of PHY consumers
+ * @num_consumers: number of consumers for this PHY device
+ * @consumers: list of PHY consumers
+ */
+struct phy_init_data {
+       unsigned int num_consumers;
+       struct phy_consumer *consumers;
+};
+
+#define PHY_CONSUMER(_dev_name, _port)                         \
+{                                                              \
+       .dev_name       = _dev_name,                            \
+       .port           = _port,                                \
+}
+
+#define        to_phy(dev)     (container_of((dev), struct phy, dev))
+
+#define        of_phy_provider_register(dev, xlate)    \
+       __of_phy_provider_register((dev), THIS_MODULE, (xlate))
+
+#define        devm_of_phy_provider_register(dev, xlate)       \
+       __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
+
+static inline void phy_set_drvdata(struct phy *phy, void *data)
+{
+       dev_set_drvdata(&phy->dev, data);
+}
+
+static inline void *phy_get_drvdata(struct phy *phy)
+{
+       return dev_get_drvdata(&phy->dev);
+}
+
+#if IS_ENABLED(CONFIG_GENERIC_PHY)
+int phy_pm_runtime_get(struct phy *phy);
+int phy_pm_runtime_get_sync(struct phy *phy);
+int phy_pm_runtime_put(struct phy *phy);
+int phy_pm_runtime_put_sync(struct phy *phy);
+void phy_pm_runtime_allow(struct phy *phy);
+void phy_pm_runtime_forbid(struct phy *phy);
+int phy_init(struct phy *phy);
+int phy_exit(struct phy *phy);
+int phy_power_on(struct phy *phy);
+int phy_power_off(struct phy *phy);
+struct phy *phy_get(struct device *dev, const char *string);
+struct phy *devm_phy_get(struct device *dev, const char *string);
+void phy_put(struct phy *phy);
+void devm_phy_put(struct device *dev, struct phy *phy);
+struct phy *of_phy_simple_xlate(struct device *dev,
+       struct of_phandle_args *args);
+struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
+       struct phy_init_data *init_data);
+struct phy *devm_phy_create(struct device *dev,
+       const struct phy_ops *ops, struct phy_init_data *init_data);
+void phy_destroy(struct phy *phy);
+void devm_phy_destroy(struct device *dev, struct phy *phy);
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+       struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+       struct of_phandle_args *args));
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+       struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+       struct of_phandle_args *args));
+void of_phy_provider_unregister(struct phy_provider *phy_provider);
+void devm_of_phy_provider_unregister(struct device *dev,
+       struct phy_provider *phy_provider);
+#else
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline int phy_pm_runtime_get_sync(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline int phy_pm_runtime_put(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline int phy_pm_runtime_put_sync(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline void phy_pm_runtime_allow(struct phy *phy)
+{
+       return;
+}
+
+static inline void phy_pm_runtime_forbid(struct phy *phy)
+{
+       return;
+}
+
+static inline int phy_init(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline int phy_power_on(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline int phy_power_off(struct phy *phy)
+{
+       return -ENOSYS;
+}
+
+static inline struct phy *phy_get(struct device *dev, const char *string)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_phy_get(struct device *dev, const char *string)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_put(struct phy *phy)
+{
+}
+
+static inline void devm_phy_put(struct device *dev, struct phy *phy)
+{
+}
+
+static inline struct phy *of_phy_simple_xlate(struct device *dev,
+       struct of_phandle_args *args)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *phy_create(struct device *dev,
+       const struct phy_ops *ops, struct phy_init_data *init_data)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_phy_create(struct device *dev,
+       const struct phy_ops *ops, struct phy_init_data *init_data)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_destroy(struct phy *phy)
+{
+}
+
+static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
+{
+}
+
+static inline struct phy_provider *__of_phy_provider_register(
+       struct device *dev, struct module *owner, struct phy * (*of_xlate)(
+       struct device *dev, struct of_phandle_args *args))
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy_provider *__devm_of_phy_provider_register(struct device
+       *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+       struct of_phandle_args *args))
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+}
+
+static inline void devm_of_phy_provider_unregister(struct device *dev,
+       struct phy_provider *phy_provider)
+{
+}
+#endif
+
+#endif /* __DRIVERS_PHY_H */
diff --git a/include/linux/platform_data/clk-nomadik.h b/include/linux/platform_data/clk-nomadik.h
deleted file mode 100644 (file)
index 5713c87..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Minimal platform data header */
-void nomadik_clk_init(void);
index 9d98f3aaa16c7637b42a8de33530aab4df9137ac..97baf831e07114c04b5e3d4163738da98b0ba5be 100644 (file)
@@ -10,6 +10,9 @@
 #ifndef __CLK_UX500_H
 #define __CLK_UX500_H
 
+void u8500_of_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
+                      u32 clkrst5_base, u32 clkrst6_base);
+
 void u8500_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
                    u32 clkrst5_base, u32 clkrst6_base);
 void u9540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
diff --git a/include/linux/platform_data/dma-s3c24xx.h b/include/linux/platform_data/dma-s3c24xx.h
new file mode 100644 (file)
index 0000000..89ba1b0
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * S3C24XX DMA handling
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.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.
+ */
+
+/* Helper to encode the source selection constraints for early s3c socs. */
+#define S3C24XX_DMA_CHANREQ(src, chan) ((BIT(3) | src) << chan * 4)
+
+enum s3c24xx_dma_bus {
+       S3C24XX_DMA_APB,
+       S3C24XX_DMA_AHB,
+};
+
+/**
+ * @bus: on which bus does the peripheral reside - AHB or APB.
+ * @handshake: is a handshake with the peripheral necessary
+ * @chansel: channel selection information, depending on variant; reqsel for
+ *          s3c2443 and later and channel-selection map for earlier SoCs
+ *          see CHANSEL doc in s3c2443-dma.c
+ */
+struct s3c24xx_dma_channel {
+       enum s3c24xx_dma_bus bus;
+       bool handshake;
+       u16 chansel;
+};
+
+/**
+ * struct s3c24xx_dma_platdata - platform specific settings
+ * @num_phy_channels: number of physical channels
+ * @channels: array of virtual channel descriptions
+ * @num_channels: number of virtual channels
+ */
+struct s3c24xx_dma_platdata {
+       int num_phy_channels;
+       struct s3c24xx_dma_channel *channels;
+       int num_channels;
+};
+
+struct dma_chan;
+bool s3c24xx_dma_filter(struct dma_chan *chan, void *param);
diff --git a/include/linux/platform_data/gpio-davinci.h b/include/linux/platform_data/gpio-davinci.h
new file mode 100644 (file)
index 0000000..6efd202
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * DaVinci GPIO Platform Related Defines
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DAVINCI_GPIO_PLATFORM_H
+#define __DAVINCI_GPIO_PLATFORM_H
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm-generic/gpio.h>
+
+enum davinci_gpio_type {
+       GPIO_TYPE_TNETV107X = 0,
+};
+
+struct davinci_gpio_platform_data {
+       u32     ngpio;
+       u32     gpio_unbanked;
+       u32     intc_irq_num;
+};
+
+
+struct davinci_gpio_controller {
+       struct gpio_chip        chip;
+       int                     irq_base;
+       /* Serialize access to GPIO registers */
+       spinlock_t              lock;
+       void __iomem            *regs;
+       void __iomem            *set_data;
+       void __iomem            *clr_data;
+       void __iomem            *in_data;
+       int                     gpio_unbanked;
+       unsigned                gpio_irq;
+};
+
+/*
+ * basic gpio routines
+ */
+#define        GPIO(X)         (X)     /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
+
+/* Convert GPIO signal to GPIO pin number */
+#define GPIO_TO_PIN(bank, gpio)        (16 * (bank) + (gpio))
+
+static inline u32 __gpio_mask(unsigned gpio)
+{
+       return 1 << (gpio % 32);
+}
+#endif
index bf34e17cee7f6eb9c9068d811c37dae3b8c10fe0..c2fd9024717cb5aca213c1700126b69d6d350e24 100644 (file)
@@ -25,13 +25,4 @@ struct s5p_platform_mipi_csis {
        u8 hs_settle;
 };
 
-/**
- * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
- * @id:     MIPI-CSIS harware instance index (0...1)
- * @on:     true to enable D-PHY and deassert its reset
- *          false to disable D-PHY
- * @return: 0 on success, or negative error code on failure
- */
-int s5p_csis_phy_enable(int id, bool on);
-
 #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
diff --git a/include/linux/platform_data/pinctrl-single.h b/include/linux/platform_data/pinctrl-single.h
new file mode 100644 (file)
index 0000000..72eacda
--- /dev/null
@@ -0,0 +1,12 @@
+/**
+ * irq:                optional wake-up interrupt
+ * rearm:      optional soc specific rearm function
+ *
+ * Note that the irq and rearm setup should come from device
+ * tree except for omap where there are still some dependencies
+ * to the legacy PRM code.
+ */
+struct pcs_pdata {
+       int irq;
+       void (*rearm)(void);
+};
diff --git a/include/linux/platform_data/usb-ehci-s5p.h b/include/linux/platform_data/usb-ehci-s5p.h
deleted file mode 100644 (file)
index 5f28cae..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@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.
- */
-
-#ifndef __PLAT_SAMSUNG_EHCI_H
-#define __PLAT_SAMSUNG_EHCI_H __FILE__
-
-struct s5p_ehci_platdata {
-       int (*phy_init)(struct platform_device *pdev, int type);
-       int (*phy_exit)(struct platform_device *pdev, int type);
-};
-
-extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
-
-#endif /* __PLAT_SAMSUNG_EHCI_H */
diff --git a/include/linux/platform_data/usb-ohci-exynos.h b/include/linux/platform_data/usb-ohci-exynos.h
deleted file mode 100644 (file)
index c256c59..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- *             http://www.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.
- */
-
-#ifndef __MACH_EXYNOS_OHCI_H
-#define __MACH_EXYNOS_OHCI_H
-
-struct exynos4_ohci_platdata {
-       int (*phy_init)(struct platform_device *pdev, int type);
-       int (*phy_exit)(struct platform_device *pdev, int type);
-};
-
-extern void exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd);
-
-#endif /* __MACH_EXYNOS_OHCI_H */
diff --git a/include/linux/platform_data/usb-rcar-gen2-phy.h b/include/linux/platform_data/usb-rcar-gen2-phy.h
new file mode 100644 (file)
index 0000000..dd3ba46
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013 Cogent Embedded, 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 __USB_RCAR_GEN2_PHY_H
+#define __USB_RCAR_GEN2_PHY_H
+
+#include <linux/types.h>
+
+struct rcar_gen2_phy_platform_data {
+       /* USB channel 0 configuration */
+       bool chan0_pci:1;       /* true: PCI USB host 0, false: USBHS */
+       /* USB channel 2 configuration */
+       bool chan2_pci:1;       /* true: PCI USB host 2, false: USBSS */
+};
+
+#endif
index ce8e4ffd78c773a1923c18cc53403726e79f71bf..16f6654082ddf82874a8531e51641d3bd62c1917 100644 (file)
@@ -178,6 +178,7 @@ struct platform_driver {
        int (*resume)(struct platform_device *);
        struct device_driver driver;
        const struct platform_device_id *id_table;
+       bool prevent_deferred_probe;
 };
 
 #define to_platform_driver(drv)        (container_of((drv), struct platform_driver, \
index e6131a782481186cb25ac1bb50f91bddc581e17d..694925837a1645bb7297cc9254efee7173a32197 100644 (file)
@@ -233,6 +233,8 @@ extern asmlinkage void dump_stack(void) __cold;
        no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #endif
 
+#include <linux/dynamic_debug.h>
+
 /* If you are writing a driver, please use dev_dbg instead */
 #if defined(CONFIG_DYNAMIC_DEBUG)
 /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
@@ -343,7 +345,19 @@ extern asmlinkage void dump_stack(void) __cold;
 #endif
 
 /* If you are writing a driver, please use dev_dbg instead */
-#if defined(DEBUG)
+#if defined(CONFIG_DYNAMIC_DEBUG)
+/* descriptor check is first to prevent flooding with "callbacks suppressed" */
+#define pr_debug_ratelimited(fmt, ...)                                 \
+do {                                                                   \
+       static DEFINE_RATELIMIT_STATE(_rs,                              \
+                                     DEFAULT_RATELIMIT_INTERVAL,       \
+                                     DEFAULT_RATELIMIT_BURST);         \
+       DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);                 \
+       if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) &&        \
+           __ratelimit(&_rs))                                          \
+               __dynamic_pr_debug(&descriptor, fmt, ##__VA_ARGS__);    \
+} while (0)
+#elif defined(DEBUG)
 #define pr_debug_ratelimited(fmt, ...)                                 \
        printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #else
index 4106721c4e5e39d3d0a08d44f5d50909da6c9b86..45a0a9e81478c41187088d6ce3fb9762f070e335 100644 (file)
  * be used anywhere you would want to use a list_empty_rcu().
  */
 
+/*
+ * INIT_LIST_HEAD_RCU - Initialize a list_head visible to RCU readers
+ * @list: list to be initialized
+ *
+ * You should instead use INIT_LIST_HEAD() for normal initialization and
+ * cleanup tasks, when readers have no access to the list being initialized.
+ * However, if the list being initialized is visible to readers, you
+ * need to keep the compiler from being too mischievous.
+ */
+static inline void INIT_LIST_HEAD_RCU(struct list_head *list)
+{
+       ACCESS_ONCE(list->next) = list;
+       ACCESS_ONCE(list->prev) = list;
+}
+
 /*
  * return the ->next pointer of a list_head in an rcu safe
  * way, we must not access it directly
@@ -191,9 +206,13 @@ static inline void list_splice_init_rcu(struct list_head *list,
        if (list_empty(list))
                return;
 
-       /* "first" and "last" tracking list, so initialize it. */
+       /*
+        * "first" and "last" tracking list, so initialize it.  RCU readers
+        * have access to this list, so we must use INIT_LIST_HEAD_RCU()
+        * instead of INIT_LIST_HEAD().
+        */
 
-       INIT_LIST_HEAD(list);
+       INIT_LIST_HEAD_RCU(list);
 
        /*
         * At this point, the list body still points to the source list.
index f1f1bc39346b85c303c227e3137b78e0e87bdcc8..39cbb889e20da020c8936aae8124601b718e05a5 100644 (file)
@@ -261,6 +261,10 @@ static inline void rcu_user_hooks_switch(struct task_struct *prev,
                rcu_irq_exit(); \
        } while (0)
 
+#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP)
+extern bool __rcu_is_watching(void);
+#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) */
+
 /*
  * Infrastructure to implement the synchronize_() primitives in
  * TREE_RCU and rcu_barrier_() primitives in TINY_RCU.
@@ -297,10 +301,6 @@ static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
 }
 #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 
-#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SMP)
-extern int rcu_is_cpu_idle(void);
-#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SMP) */
-
 #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU)
 bool rcu_lockdep_current_cpu_online(void);
 #else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */
@@ -351,7 +351,7 @@ static inline int rcu_read_lock_held(void)
 {
        if (!debug_lockdep_rcu_enabled())
                return 1;
-       if (rcu_is_cpu_idle())
+       if (!rcu_is_watching())
                return 0;
        if (!rcu_lockdep_current_cpu_online())
                return 0;
@@ -402,7 +402,7 @@ static inline int rcu_read_lock_sched_held(void)
 
        if (!debug_lockdep_rcu_enabled())
                return 1;
-       if (rcu_is_cpu_idle())
+       if (!rcu_is_watching())
                return 0;
        if (!rcu_lockdep_current_cpu_online())
                return 0;
@@ -771,7 +771,7 @@ static inline void rcu_read_lock(void)
        __rcu_read_lock();
        __acquire(RCU);
        rcu_lock_acquire(&rcu_lock_map);
-       rcu_lockdep_assert(!rcu_is_cpu_idle(),
+       rcu_lockdep_assert(rcu_is_watching(),
                           "rcu_read_lock() used illegally while idle");
 }
 
@@ -792,7 +792,7 @@ static inline void rcu_read_lock(void)
  */
 static inline void rcu_read_unlock(void)
 {
-       rcu_lockdep_assert(!rcu_is_cpu_idle(),
+       rcu_lockdep_assert(rcu_is_watching(),
                           "rcu_read_unlock() used illegally while idle");
        rcu_lock_release(&rcu_lock_map);
        __release(RCU);
@@ -821,7 +821,7 @@ static inline void rcu_read_lock_bh(void)
        local_bh_disable();
        __acquire(RCU_BH);
        rcu_lock_acquire(&rcu_bh_lock_map);
-       rcu_lockdep_assert(!rcu_is_cpu_idle(),
+       rcu_lockdep_assert(rcu_is_watching(),
                           "rcu_read_lock_bh() used illegally while idle");
 }
 
@@ -832,7 +832,7 @@ static inline void rcu_read_lock_bh(void)
  */
 static inline void rcu_read_unlock_bh(void)
 {
-       rcu_lockdep_assert(!rcu_is_cpu_idle(),
+       rcu_lockdep_assert(rcu_is_watching(),
                           "rcu_read_unlock_bh() used illegally while idle");
        rcu_lock_release(&rcu_bh_lock_map);
        __release(RCU_BH);
@@ -857,7 +857,7 @@ static inline void rcu_read_lock_sched(void)
        preempt_disable();
        __acquire(RCU_SCHED);
        rcu_lock_acquire(&rcu_sched_lock_map);
-       rcu_lockdep_assert(!rcu_is_cpu_idle(),
+       rcu_lockdep_assert(rcu_is_watching(),
                           "rcu_read_lock_sched() used illegally while idle");
 }
 
@@ -875,7 +875,7 @@ static inline notrace void rcu_read_lock_sched_notrace(void)
  */
 static inline void rcu_read_unlock_sched(void)
 {
-       rcu_lockdep_assert(!rcu_is_cpu_idle(),
+       rcu_lockdep_assert(rcu_is_watching(),
                           "rcu_read_unlock_sched() used illegally while idle");
        rcu_lock_release(&rcu_sched_lock_map);
        __release(RCU_SCHED);
index e31005ee339ebde022bd7dabace245ee79474d9b..09ebcbe9fd780932e2dee223daaa8426395e77d8 100644 (file)
@@ -132,4 +132,21 @@ static inline void rcu_scheduler_starting(void)
 }
 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
+#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE)
+
+static inline bool rcu_is_watching(void)
+{
+       return __rcu_is_watching();
+}
+
+#else /* defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */
+
+static inline bool rcu_is_watching(void)
+{
+       return true;
+}
+
+
+#endif /* #else defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */
+
 #endif /* __LINUX_RCUTINY_H */
index 226169d1bd2bc07fa465d9c4b4b21cf8131de162..4b9c8154874269d66cc3fa1312bc6e53d2584669 100644 (file)
@@ -90,4 +90,6 @@ extern void exit_rcu(void);
 extern void rcu_scheduler_starting(void);
 extern int rcu_scheduler_active __read_mostly;
 
+extern bool rcu_is_watching(void);
+
 #endif /* __LINUX_RCUTREE_H */
index b98291ac7f141f0b0cf33b569d7dde0796b60f8c..f729be981da0862a5ec09ee6a35e75312ae8768e 100644 (file)
@@ -66,7 +66,6 @@ struct uart_ops {
        void            (*set_ldisc)(struct uart_port *, int new);
        void            (*pm)(struct uart_port *, unsigned int state,
                              unsigned int oldstate);
-       int             (*set_wake)(struct uart_port *, unsigned int state);
 
        /*
         * Return a string describing the type of the port
index 6740801aa71ab519c59bd21a7e50ee5793cc242a..8af2804bab16645e0b625052daa90fe1dfabb194 100644 (file)
@@ -49,6 +49,7 @@ struct rpc_clnt {
 
        unsigned int            cl_softrtry : 1,/* soft timeouts */
                                cl_discrtry : 1,/* disconnect before retry */
+                               cl_noretranstimeo: 1,/* No retransmit timeouts */
                                cl_autobind : 1,/* use getport() */
                                cl_chatty   : 1;/* be verbose */
 
@@ -126,6 +127,7 @@ struct rpc_create_args {
 #define RPC_CLNT_CREATE_QUIET          (1UL << 6)
 #define RPC_CLNT_CREATE_INFINITE_SLOTS (1UL << 7)
 #define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT        (1UL << 8)
+#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT     (1UL << 9)
 
 struct rpc_clnt *rpc_create(struct rpc_create_args *args);
 struct rpc_clnt        *rpc_bind_new_program(struct rpc_clnt *,
@@ -134,6 +136,10 @@ void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
 struct rpc_clnt *rpc_clone_client_set_auth(struct rpc_clnt *,
                                rpc_authflavor_t);
+int            rpc_switch_client_transport(struct rpc_clnt *,
+                               struct xprt_create *,
+                               const struct rpc_timeout *);
+
 void           rpc_shutdown_client(struct rpc_clnt *);
 void           rpc_release_client(struct rpc_clnt *);
 void           rpc_task_release_client(struct rpc_task *);
index 096ee58be11a83f2fc05107639a2273cc0c677e6..3a847de83fabd5757ddcee00910a6ab991f79a98 100644 (file)
@@ -122,6 +122,7 @@ struct rpc_task_setup {
 #define RPC_TASK_SENT          0x0800          /* message was sent */
 #define RPC_TASK_TIMEOUT       0x1000          /* fail with ETIMEDOUT on timeout */
 #define RPC_TASK_NOCONNECT     0x2000          /* return ENOTCONN if not connected */
+#define RPC_TASK_NO_RETRANS_TIMEOUT    0x4000          /* wait forever for a reply */
 
 #define RPC_IS_ASYNC(t)                ((t)->tk_flags & RPC_TASK_ASYNC)
 #define RPC_IS_SWAPPER(t)      ((t)->tk_flags & RPC_TASK_SWAPPER)
index cec7b9b5e1bfb6591ad10997485b05ddc7421120..8097b9df677326717517f256b66dbaa17e27df93 100644 (file)
@@ -288,7 +288,7 @@ int                 xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
 int                    xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
 void                   xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);
 void                   xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);
-int                    xprt_prepare_transmit(struct rpc_task *task);
+bool                   xprt_prepare_transmit(struct rpc_task *task);
 void                   xprt_transmit(struct rpc_task *task);
 void                   xprt_end_transmit(struct rpc_task *task);
 int                    xprt_adjust_timeout(struct rpc_rqst *req);
index 11baec7c9b26dd4bfeb19ee4447c11cdda737a3c..6695040a031713ee257130e7295be38cc6aff293 100644 (file)
@@ -173,7 +173,6 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
 struct sysfs_ops {
        ssize_t (*show)(struct kobject *, struct attribute *, char *);
        ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
-       const void *(*namespace)(struct kobject *, const struct attribute *);
 };
 
 struct sysfs_dirent;
@@ -183,19 +182,23 @@ struct sysfs_dirent;
 int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
                            void *data, struct module *owner);
 
-int __must_check sysfs_create_dir(struct kobject *kobj);
+int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
 void sysfs_remove_dir(struct kobject *kobj);
-int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
-int __must_check sysfs_move_dir(struct kobject *kobj,
-                               struct kobject *new_parent_kobj);
-
-int __must_check sysfs_create_file(struct kobject *kobj,
-                                  const struct attribute *attr);
+int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
+                                    const void *new_ns);
+int __must_check sysfs_move_dir_ns(struct kobject *kobj,
+                                  struct kobject *new_parent_kobj,
+                                  const void *new_ns);
+
+int __must_check sysfs_create_file_ns(struct kobject *kobj,
+                                     const struct attribute *attr,
+                                     const void *ns);
 int __must_check sysfs_create_files(struct kobject *kobj,
                                   const struct attribute **attr);
 int __must_check sysfs_chmod_file(struct kobject *kobj,
                                  const struct attribute *attr, umode_t mode);
-void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
+void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
+                         const void *ns);
 void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
 
 int __must_check sysfs_create_bin_file(struct kobject *kobj,
@@ -210,8 +213,9 @@ int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
                                          const char *name);
 void sysfs_remove_link(struct kobject *kobj, const char *name);
 
-int sysfs_rename_link(struct kobject *kobj, struct kobject *target,
-                       const char *old_name, const char *new_name);
+int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target,
+                        const char *old_name, const char *new_name,
+                        const void *new_ns);
 
 void sysfs_delete_link(struct kobject *dir, struct kobject *targ,
                        const char *name);
@@ -241,9 +245,9 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_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(struct sysfs_dirent *parent_sd,
-                                     const void *ns,
-                                     const unsigned char *name);
+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);
 
@@ -257,7 +261,7 @@ static inline int sysfs_schedule_callback(struct kobject *kobj,
        return -ENOSYS;
 }
 
-static inline int sysfs_create_dir(struct kobject *kobj)
+static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
 {
        return 0;
 }
@@ -266,19 +270,22 @@ static inline void sysfs_remove_dir(struct kobject *kobj)
 {
 }
 
-static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
+static inline int sysfs_rename_dir_ns(struct kobject *kobj,
+                                     const char *new_name, const void *new_ns)
 {
        return 0;
 }
 
-static inline int sysfs_move_dir(struct kobject *kobj,
-                                struct kobject *new_parent_kobj)
+static inline int sysfs_move_dir_ns(struct kobject *kobj,
+                                   struct kobject *new_parent_kobj,
+                                   const void *new_ns)
 {
        return 0;
 }
 
-static inline int sysfs_create_file(struct kobject *kobj,
-                                   const struct attribute *attr)
+static inline int sysfs_create_file_ns(struct kobject *kobj,
+                                      const struct attribute *attr,
+                                      const void *ns)
 {
        return 0;
 }
@@ -295,8 +302,9 @@ static inline int sysfs_chmod_file(struct kobject *kobj,
        return 0;
 }
 
-static inline void sysfs_remove_file(struct kobject *kobj,
-                                    const struct attribute *attr)
+static inline void sysfs_remove_file_ns(struct kobject *kobj,
+                                       const struct attribute *attr,
+                                       const void *ns)
 {
 }
 
@@ -333,8 +341,9 @@ static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
 {
 }
 
-static inline int sysfs_rename_link(struct kobject *k, struct kobject *t,
-                                   const char *old_name, const char *new_name)
+static inline int sysfs_rename_link_ns(struct kobject *k, struct kobject *t,
+                                      const char *old_name,
+                                      const char *new_name, const void *ns)
 {
        return 0;
 }
@@ -413,10 +422,9 @@ static inline void sysfs_notify(struct kobject *kobj, const char *dir,
 static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
 {
 }
-static inline
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
-                                     const void *ns,
-                                     const unsigned char *name)
+static inline struct sysfs_dirent *
+sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd, const unsigned char *name,
+                   const void *ns)
 {
        return NULL;
 }
@@ -435,4 +443,28 @@ static inline int __must_check sysfs_init(void)
 
 #endif /* CONFIG_SYSFS */
 
+static inline int __must_check sysfs_create_file(struct kobject *kobj,
+                                                const struct attribute *attr)
+{
+       return sysfs_create_file_ns(kobj, attr, NULL);
+}
+
+static inline void sysfs_remove_file(struct kobject *kobj,
+                                    const struct attribute *attr)
+{
+       return sysfs_remove_file_ns(kobj, attr, NULL);
+}
+
+static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target,
+                                   const char *old_name, const char *new_name)
+{
+       return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL);
+}
+
+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);
+}
+
 #endif /* _SYSFS_H_ */
index 7faf933cced7018657d2212d543530484ce17ec9..387fa7d05c982b758942f83395e328949324fc1a 100644 (file)
@@ -17,9 +17,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
-/* Enable/disable SYSRQ support by default (0==no, 1==yes). */
-#define SYSRQ_DEFAULT_ENABLE   1
-
 /* Possible values of bitmask for enabling sysrq functions */
 /* 0x0001 is reserved for enable everything */
 #define SYSRQ_ENABLE_LOG       0x0002
index 55c29a8d5015f60927d9da28d7992f8e536bfa73..c98cfa40695248d16ab3ee91891c33334239c252 100644 (file)
@@ -34,8 +34,15 @@ struct clk;
 #define TEGRA_POWERGATE_CPU3   11
 #define TEGRA_POWERGATE_CELP   12
 #define TEGRA_POWERGATE_3D1    13
+#define TEGRA_POWERGATE_CPU0   14
+#define TEGRA_POWERGATE_C0NC   15
+#define TEGRA_POWERGATE_C1NC   16
+#define TEGRA_POWERGATE_DIS    18
+#define TEGRA_POWERGATE_DISB   19
+#define TEGRA_POWERGATE_XUSBA  20
+#define TEGRA_POWERGATE_XUSBB  21
+#define TEGRA_POWERGATE_XUSBC  22
 
-#define TEGRA_POWERGATE_CPU0   TEGRA_POWERGATE_CPU
 #define TEGRA_POWERGATE_3D0    TEGRA_POWERGATE_3D
 
 int tegra_powergate_is_powered(int id);
index 633cac77f9f97b56155bf5a005aa2899591425ac..97d660ed70c1901407dac9ea49bd1036840e649c 100644 (file)
@@ -180,7 +180,6 @@ struct tty_port_operations {
           IFF the port was initialized. Do not use to free resources. Called
           under the port mutex to serialize against activate/shutdowns */
        void (*shutdown)(struct tty_port *port);
-       void (*drop)(struct tty_port *port);
        /* Called under the port mutex from tty_port_open, serialized using
           the port mutex */
         /* FIXME: long term getting the tty argument *out* of this would be
index 06f28beed7c2c405a0a7760ca231c188257926b2..319eae70fe8415f774e57c4861b98688fb81bb4c 100644 (file)
@@ -30,6 +30,7 @@
 struct vm_area_struct;
 struct mm_struct;
 struct inode;
+struct notifier_block;
 
 #ifdef CONFIG_ARCH_SUPPORTS_UPROBES
 # include <asm/uprobes.h>
@@ -108,6 +109,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 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);
 extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
@@ -117,14 +119,21 @@ extern void uprobe_start_dup_mmap(void);
 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);
+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);
 extern bool uprobe_deny_signal(void);
-extern bool __weak arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs);
+extern bool arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs);
 extern void uprobe_clear_state(struct mm_struct *mm);
+extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
+extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
+extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
+extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
+extern int  arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
+extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
+extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
@@ -174,7 +183,7 @@ static inline unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
 static inline void uprobe_free_utask(struct task_struct *t)
 {
 }
-static inline void uprobe_copy_process(struct task_struct *t)
+static inline void uprobe_copy_process(struct task_struct *t, unsigned long flags)
 {
 }
 static inline void uprobe_clear_state(struct mm_struct *mm)
index 001629cd1a97b831f2eb448013c114b3a76f0de7..7454865ad14834f50a05dc9baf7f6d78ea3de7b8 100644 (file)
@@ -475,7 +475,8 @@ struct usb3_lpm_parameters {
  * @lpm_capable: device supports LPM
  * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM
  * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM
- * @usb2_hw_lpm_enabled: USB2 hardware LPM enabled
+ * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled
+ * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled
  * @usb3_lpm_enabled: USB3 hardware LPM enabled
  * @string_langid: language ID for strings
  * @product: iProduct string, if present (static)
@@ -548,6 +549,7 @@ struct usb_device {
        unsigned usb2_hw_lpm_capable:1;
        unsigned usb2_hw_lpm_besl_capable:1;
        unsigned usb2_hw_lpm_enabled:1;
+       unsigned usb2_hw_lpm_allowed:1;
        unsigned usb3_lpm_enabled:1;
        int string_langid;
 
@@ -702,7 +704,7 @@ extern int usb_alloc_streams(struct usb_interface *interface,
                unsigned int num_streams, gfp_t mem_flags);
 
 /* Reverts a group of bulk endpoints back to not using stream IDs. */
-extern void usb_free_streams(struct usb_interface *interface,
+extern int usb_free_streams(struct usb_interface *interface,
                struct usb_host_endpoint **eps, unsigned int num_eps,
                gfp_t mem_flags);
 
@@ -1209,11 +1211,13 @@ struct usb_anchor {
        struct list_head urb_list;
        wait_queue_head_t wait;
        spinlock_t lock;
+       atomic_t suspend_wakeups;
        unsigned int poisoned:1;
 };
 
 static inline void init_usb_anchor(struct usb_anchor *anchor)
 {
+       memset(anchor, 0, sizeof(*anchor));
        INIT_LIST_HEAD(&anchor->urb_list);
        init_waitqueue_head(&anchor->wait);
        spin_lock_init(&anchor->lock);
@@ -1574,6 +1578,8 @@ extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor);
+extern void usb_anchor_suspend_wakeups(struct usb_anchor *anchor);
+extern void usb_anchor_resume_wakeups(struct usb_anchor *anchor);
 extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor);
 extern void usb_unanchor_urb(struct urb *urb);
 extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
index 75efc45eaa2ff361d4cb92fa4c325eb8d5d50461..b8aba196f7f12948cbf4d2a587371b081f150d1c 100644 (file)
@@ -73,6 +73,7 @@ struct giveback_urb_bh {
        spinlock_t lock;
        struct list_head  head;
        struct tasklet_struct bh;
+       struct usb_host_endpoint *completing_ep;
 };
 
 struct usb_hcd {
@@ -140,6 +141,7 @@ struct usb_hcd {
        unsigned                wireless:1;     /* Wireless USB HCD */
        unsigned                authorized_default:1;
        unsigned                has_tt:1;       /* Integrated TT in root hub */
+       unsigned                amd_resume_bug:1; /* AMD remote wakeup quirk */
 
        unsigned int            irq;            /* irq allocated */
        void __iomem            *regs;          /* device memory/io */
@@ -378,6 +380,12 @@ static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
        return hcd->driver->flags & HCD_BH;
 }
 
+static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
+               struct usb_host_endpoint *ep)
+{
+       return hcd->high_prio_bh.completing_ep == ep;
+}
+
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
 extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
                int status);
@@ -428,6 +436,8 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev,
 extern void usb_hcd_pci_remove(struct pci_dev *dev);
 extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
 
+extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
+
 #ifdef CONFIG_PM
 extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
 #endif
@@ -496,6 +506,7 @@ struct usb_tt {
        struct usb_device       *hub;   /* upstream highspeed hub */
        int                     multi;  /* true means one TT per port */
        unsigned                think_time;     /* think time in ns */
+       void                    *hcpriv;        /* HCD private data */
 
        /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
        spinlock_t              lock;
@@ -554,9 +565,8 @@ extern void usb_ep0_reinit(struct usb_device *);
                 * of (7/6 * 8 * bytecount) = 9.33 * bytecount */
                /* bytecount = data payload byte count */
 
-#define NS_TO_US(ns)   ((ns + 500L) / 1000L)
-                       /* convert & round nanoseconds to microseconds */
-
+#define NS_TO_US(ns)   DIV_ROUND_UP(ns, 1000L)
+                       /* convert nanoseconds to microseconds, rounding up */
 
 /*
  * Full/low speed bandwidth allocation constants/support.
diff --git a/include/linux/usb/intel_mid_otg.h b/include/linux/usb/intel_mid_otg.h
deleted file mode 100644 (file)
index 756cf55..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Intel MID (Langwell/Penwell) USB OTG Transceiver driver
- * Copyright (C) 2008 - 2010, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __INTEL_MID_OTG_H
-#define __INTEL_MID_OTG_H
-
-#include <linux/pm.h>
-#include <linux/usb/otg.h>
-#include <linux/notifier.h>
-
-struct intel_mid_otg_xceiv;
-
-/* This is a common data structure for Intel MID platform to
- * save values of the OTG state machine */
-struct otg_hsm {
-       /* Input */
-       int a_bus_resume;
-       int a_bus_suspend;
-       int a_conn;
-       int a_sess_vld;
-       int a_srp_det;
-       int a_vbus_vld;
-       int b_bus_resume;
-       int b_bus_suspend;
-       int b_conn;
-       int b_se0_srp;
-       int b_ssend_srp;
-       int b_sess_end;
-       int b_sess_vld;
-       int id;
-/* id values */
-#define ID_B           0x05
-#define ID_A           0x04
-#define ID_ACA_C       0x03
-#define ID_ACA_B       0x02
-#define ID_ACA_A       0x01
-       int power_up;
-       int adp_change;
-       int test_device;
-
-       /* Internal variables */
-       int a_set_b_hnp_en;
-       int b_srp_done;
-       int b_hnp_enable;
-       int hnp_poll_enable;
-
-       /* Timeout indicator for timers */
-       int a_wait_vrise_tmout;
-       int a_wait_bcon_tmout;
-       int a_aidl_bdis_tmout;
-       int a_bidl_adis_tmout;
-       int a_bidl_adis_tmr;
-       int a_wait_vfall_tmout;
-       int b_ase0_brst_tmout;
-       int b_bus_suspend_tmout;
-       int b_srp_init_tmout;
-       int b_srp_fail_tmout;
-       int b_srp_fail_tmr;
-       int b_adp_sense_tmout;
-
-       /* Informative variables */
-       int a_bus_drop;
-       int a_bus_req;
-       int a_clr_err;
-       int b_bus_req;
-       int a_suspend_req;
-       int b_bus_suspend_vld;
-
-       /* Output */
-       int drv_vbus;
-       int loc_conn;
-       int loc_sof;
-
-       /* Others */
-       int vbus_srp_up;
-};
-
-/* must provide ULPI access function to read/write registers implemented in
- * ULPI address space */
-struct iotg_ulpi_access_ops {
-       int     (*read)(struct intel_mid_otg_xceiv *iotg, u8 reg, u8 *val);
-       int     (*write)(struct intel_mid_otg_xceiv *iotg, u8 reg, u8 val);
-};
-
-#define OTG_A_DEVICE   0x0
-#define OTG_B_DEVICE   0x1
-
-/*
- * the Intel MID (Langwell/Penwell) otg transceiver driver needs to interact
- * with device and host drivers to implement the USB OTG related feature. More
- * function members are added based on usb_phy data structure for this
- * purpose.
- */
-struct intel_mid_otg_xceiv {
-       struct usb_phy          otg;
-       struct otg_hsm          hsm;
-
-       /* base address */
-       void __iomem            *base;
-
-       /* ops to access ulpi */
-       struct iotg_ulpi_access_ops     ulpi_ops;
-
-       /* atomic notifier for interrupt context */
-       struct atomic_notifier_head     iotg_notifier;
-
-       /* start/stop USB Host function */
-       int     (*start_host)(struct intel_mid_otg_xceiv *iotg);
-       int     (*stop_host)(struct intel_mid_otg_xceiv *iotg);
-
-       /* start/stop USB Peripheral function */
-       int     (*start_peripheral)(struct intel_mid_otg_xceiv *iotg);
-       int     (*stop_peripheral)(struct intel_mid_otg_xceiv *iotg);
-
-       /* start/stop ADP sense/probe function */
-       int     (*set_adp_probe)(struct intel_mid_otg_xceiv *iotg,
-                                       bool enabled, int dev);
-       int     (*set_adp_sense)(struct intel_mid_otg_xceiv *iotg,
-                                       bool enabled);
-
-#ifdef CONFIG_PM
-       /* suspend/resume USB host function */
-       int     (*suspend_host)(struct intel_mid_otg_xceiv *iotg,
-                                       pm_message_t message);
-       int     (*resume_host)(struct intel_mid_otg_xceiv *iotg);
-
-       int     (*suspend_peripheral)(struct intel_mid_otg_xceiv *iotg,
-                                       pm_message_t message);
-       int     (*resume_peripheral)(struct intel_mid_otg_xceiv *iotg);
-#endif
-
-};
-static inline
-struct intel_mid_otg_xceiv *otg_to_mid_xceiv(struct usb_phy *otg)
-{
-       return container_of(otg, struct intel_mid_otg_xceiv, otg);
-}
-
-#define MID_OTG_NOTIFY_CONNECT         0x0001
-#define MID_OTG_NOTIFY_DISCONN         0x0002
-#define MID_OTG_NOTIFY_HSUSPEND                0x0003
-#define MID_OTG_NOTIFY_HRESUME         0x0004
-#define MID_OTG_NOTIFY_CSUSPEND                0x0005
-#define MID_OTG_NOTIFY_CRESUME         0x0006
-#define MID_OTG_NOTIFY_HOSTADD         0x0007
-#define MID_OTG_NOTIFY_HOSTREMOVE      0x0008
-#define MID_OTG_NOTIFY_CLIENTADD       0x0009
-#define MID_OTG_NOTIFY_CLIENTREMOVE    0x000a
-
-static inline int
-intel_mid_otg_register_notifier(struct intel_mid_otg_xceiv *iotg,
-                               struct notifier_block *nb)
-{
-       return atomic_notifier_chain_register(&iotg->iotg_notifier, nb);
-}
-
-static inline void
-intel_mid_otg_unregister_notifier(struct intel_mid_otg_xceiv *iotg,
-                               struct notifier_block *nb)
-{
-       atomic_notifier_chain_unregister(&iotg->iotg_notifier, nb);
-}
-
-#endif /* __INTEL_MID_OTG_H */
index 053c26841cc39bde245acac370e152189f256814..eb505250940af073cd1059f82c4e48d773df3acb 100644 (file)
@@ -99,8 +99,6 @@ struct musb_hdrc_platform_data {
        /* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */
        u8              mode;
 
-       u8              has_mailbox:1;
-
        /* for clk_get() */
        const char      *clock;
 
index 27b5b8c931b0bd70d1e20d636b08beb6ebe3dc64..596b01918813aaeffbeb170001cb370ae9f5f776 100644 (file)
 #ifndef __OMAP_CONTROL_USB_H__
 #define __OMAP_CONTROL_USB_H__
 
+enum omap_control_usb_type {
+       OMAP_CTRL_TYPE_OTGHS = 1,       /* Mailbox OTGHS_CONTROL */
+       OMAP_CTRL_TYPE_USB2,    /* USB2_PHY, power down in CONTROL_DEV_CONF */
+       OMAP_CTRL_TYPE_PIPE3,   /* PIPE3 PHY, DPLL & seperate Rx/Tx power */
+       OMAP_CTRL_TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */
+};
+
 struct omap_control_usb {
        struct device *dev;
 
-       u32 __iomem *dev_conf;
        u32 __iomem *otghs_control;
-       u32 __iomem *phy_power;
+       u32 __iomem *power;
+       u32 __iomem *power_aux;
 
        struct clk *sys_clk;
 
-       u32 type;
-};
-
-struct omap_control_usb_platform_data {
-       u8 type;
+       enum omap_control_usb_type type;
 };
 
 enum omap_control_usb_mode {
@@ -42,10 +45,6 @@ enum omap_control_usb_mode {
        USB_MODE_DISCONNECT,
 };
 
-/* To differentiate ctrl module IP having either mailbox or USB3 PHY power */
-#define        OMAP_CTRL_DEV_TYPE1             0x1
-#define        OMAP_CTRL_DEV_TYPE2             0x2
-
 #define        OMAP_CTRL_DEV_PHY_PD            BIT(0)
 
 #define        OMAP_CTRL_DEV_AVALID            BIT(0)
@@ -63,26 +62,18 @@ enum omap_control_usb_mode {
 #define        OMAP_CTRL_USB3_PHY_TX_RX_POWERON        0x3
 #define        OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF       0x0
 
+#define OMAP_CTRL_USB2_PHY_PD          BIT(28)
+
 #if IS_ENABLED(CONFIG_OMAP_CONTROL_USB)
-extern struct device *omap_get_control_dev(void);
 extern void omap_control_usb_phy_power(struct device *dev, int on);
-extern void omap_control_usb3_phy_power(struct device *dev, bool on);
 extern void omap_control_usb_set_mode(struct device *dev,
        enum omap_control_usb_mode mode);
 #else
-static inline struct device *omap_get_control_dev(void)
-{
-       return ERR_PTR(-ENODEV);
-}
 
 static inline void omap_control_usb_phy_power(struct device *dev, int on)
 {
 }
 
-static inline void omap_control_usb3_phy_power(struct device *dev, int on)
-{
-}
-
 static inline void omap_control_usb_set_mode(struct device *dev,
        enum omap_control_usb_mode mode)
 {
index d528b804515081f9d5388dc565822241cfd6adc9..704a1ab8240ca124f29c5ce361c871090d28ea5b 100644 (file)
@@ -320,6 +320,8 @@ extern struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor);
 extern void usb_serial_put(struct usb_serial *serial);
 extern int usb_serial_generic_open(struct tty_struct *tty,
        struct usb_serial_port *port);
+extern int usb_serial_generic_write_start(struct usb_serial_port *port,
+                                                       gfp_t mem_flags);
 extern int usb_serial_generic_write(struct tty_struct *tty,
        struct usb_serial_port *port, const unsigned char *buf, int count);
 extern void usb_serial_generic_close(struct usb_serial_port *port);
index 11d85b9c1b081af6a9f4f30ac3c1458766ed4238..cc8d818a83be40f58ae5ce29a60b08ca9b0ea8f5 100644 (file)
@@ -9,7 +9,8 @@ struct usb_phy_gen_xceiv_platform_data {
 
        /* if set fails with -EPROBE_DEFER if can't get regulator */
        unsigned int needs_vcc:1;
-       unsigned int needs_reset:1;
+       unsigned int needs_reset:1;     /* deprecated */
+       int gpio_reset;
 };
 
 #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
index 4ff744e2b678a27f051649b86f1c8ee4eb8210d1..c1257130769b5465a04d7d162207613f378acfde 100644 (file)
@@ -142,7 +142,7 @@ enum wa_notif_type {
 struct wa_notif_hdr {
        u8 bLength;
        u8 bNotifyType;                 /* enum wa_notif_type */
-} __attribute__((packed));
+} __packed;
 
 /**
  * HWA DN Received notification [(WUSB] section 8.5.4.2)
@@ -158,7 +158,7 @@ struct hwa_notif_dn {
        u8 bSourceDeviceAddr;           /* from errata 2005/07 */
        u8 bmAttributes;
        struct wusb_dn_hdr dndata[];
-} __attribute__((packed));
+} __packed;
 
 /* [WUSB] section 8.3.3 */
 enum wa_xfer_type {
@@ -167,6 +167,8 @@ enum wa_xfer_type {
        WA_XFER_TYPE_ISO = 0x82,
        WA_XFER_RESULT = 0x83,
        WA_XFER_ABORT = 0x84,
+       WA_XFER_ISO_PACKET_INFO = 0xA0,
+       WA_XFER_ISO_PACKET_STATUS = 0xA1,
 };
 
 /* [WUSB] section 8.3.3 */
@@ -177,28 +179,47 @@ struct wa_xfer_hdr {
        __le32 dwTransferID;            /* Host-assigned ID */
        __le32 dwTransferLength;        /* Length of data to xfer */
        u8 bTransferSegment;
-} __attribute__((packed));
+} __packed;
 
 struct wa_xfer_ctl {
        struct wa_xfer_hdr hdr;
        u8 bmAttribute;
        __le16 wReserved;
        struct usb_ctrlrequest baSetupData;
-} __attribute__((packed));
+} __packed;
 
 struct wa_xfer_bi {
        struct wa_xfer_hdr hdr;
        u8 bReserved;
        __le16 wReserved;
-} __attribute__((packed));
+} __packed;
 
+/* [WUSB] section 8.5.5 */
 struct wa_xfer_hwaiso {
        struct wa_xfer_hdr hdr;
        u8 bReserved;
        __le16 wPresentationTime;
        __le32 dwNumOfPackets;
-       /* FIXME: u8 pktdata[]? */
-} __attribute__((packed));
+} __packed;
+
+struct wa_xfer_packet_info_hwaiso {
+       __le16 wLength;
+       u8 bPacketType;
+       u8 bReserved;
+       __le16 PacketLength[0];
+} __packed;
+
+struct wa_xfer_packet_status_len_hwaiso {
+       __le16 PacketLength;
+       __le16 PacketStatus;
+} __packed;
+
+struct wa_xfer_packet_status_hwaiso {
+       __le16 wLength;
+       u8 bPacketType;
+       u8 bReserved;
+       struct wa_xfer_packet_status_len_hwaiso PacketStatus[0];
+} __packed;
 
 /* [WUSB] section 8.3.3.5 */
 struct wa_xfer_abort {
@@ -206,7 +227,7 @@ struct wa_xfer_abort {
        u8 bRequestType;
        __le16 wRPipe;                  /* RPipe index */
        __le32 dwTransferID;            /* Host-assigned ID */
-} __attribute__((packed));
+} __packed;
 
 /**
  * WA Transfer Complete notification ([WUSB] section 8.3.3.3)
@@ -216,7 +237,7 @@ struct wa_notif_xfer {
        struct wa_notif_hdr hdr;
        u8 bEndpoint;
        u8 Reserved;
-} __attribute__((packed));
+} __packed;
 
 /** Transfer result basic codes [WUSB] table 8-15 */
 enum {
@@ -243,7 +264,7 @@ struct wa_xfer_result {
        u8     bTransferSegment;
        u8     bTransferStatus;
        __le32 dwNumOfPackets;
-} __attribute__((packed));
+} __packed;
 
 /**
  * Wire Adapter Class Descriptor ([WUSB] section 8.5.2.7).
@@ -258,16 +279,16 @@ struct wa_xfer_result {
 struct usb_wa_descriptor {
        u8      bLength;
        u8      bDescriptorType;
-       u16     bcdWAVersion;
+       __le16  bcdWAVersion;
        u8      bNumPorts;              /* don't use!! */
        u8      bmAttributes;           /* Reserved == 0 */
-       u16     wNumRPipes;
-       u16     wRPipeMaxBlock;
+       __le16  wNumRPipes;
+       __le16  wRPipeMaxBlock;
        u8      bRPipeBlockSize;
        u8      bPwrOn2PwrGood;
        u8      bNumMMCIEs;
        u8      DeviceRemovable;        /* FIXME: in DWA this is up to 16 bytes */
-} __attribute__((packed));
+} __packed;
 
 /**
  * HWA Device Information Buffer (WUSB1.0[T8.54])
@@ -277,6 +298,6 @@ struct hwa_dev_info {
        u8      bDeviceAddress;
        __le16  wPHYRates;
        u8      bmDeviceAttribute;
-} __attribute__((packed));
+} __packed;
 
 #endif /* #ifndef __LINUX_USB_WUSB_WA_H */
index 48ec25a7fcb60a09a2c323c70221a31853a82261..5e661a979694e87d2679e395aa0dce0da033942f 100644 (file)
@@ -165,6 +165,7 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
 static inline void rt6_clean_expires(struct rt6_info *rt)
 {
        rt->rt6i_flags &= ~RTF_EXPIRES;
+       rt->dst.expires = 0;
 }
 
 static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
index ee2376cfaab3a668d01374844c6757d07e7e1be8..aca382266411620f6bd7b052311cee6d6b04e8e7 100644 (file)
@@ -39,15 +39,26 @@ TRACE_EVENT(rcu_utilization,
 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
 
 /*
- * Tracepoint for grace-period events: starting and ending a grace
- * period ("start" and "end", respectively), a CPU noting the start
- * of a new grace period or the end of an old grace period ("cpustart"
- * and "cpuend", respectively), a CPU passing through a quiescent
- * state ("cpuqs"), a CPU coming online or going offline ("cpuonl"
- * and "cpuofl", respectively), a CPU being kicked for being too
- * long in dyntick-idle mode ("kick"), a CPU accelerating its new
- * callbacks to RCU_NEXT_READY_TAIL ("AccReadyCB"), and a CPU
- * accelerating its new callbacks to RCU_WAIT_TAIL ("AccWaitCB").
+ * Tracepoint for grace-period events.  Takes a string identifying the
+ * RCU flavor, the grace-period number, and a string identifying the
+ * grace-period-related event as follows:
+ *
+ *     "AccReadyCB": CPU acclerates new callbacks to RCU_NEXT_READY_TAIL.
+ *     "AccWaitCB": CPU accelerates new callbacks to RCU_WAIT_TAIL.
+ *     "newreq": Request a new grace period.
+ *     "start": Start a grace period.
+ *     "cpustart": CPU first notices a grace-period start.
+ *     "cpuqs": CPU passes through a quiescent state.
+ *     "cpuonl": CPU comes online.
+ *     "cpuofl": CPU goes offline.
+ *     "reqwait": GP kthread sleeps waiting for grace-period request.
+ *     "reqwaitsig": GP kthread awakened by signal from reqwait state.
+ *     "fqswait": GP kthread waiting until time to force quiescent states.
+ *     "fqsstart": GP kthread starts forcing quiescent states.
+ *     "fqsend": GP kthread done forcing quiescent states.
+ *     "fqswaitsig": GP kthread awakened by signal from fqswait state.
+ *     "end": End a grace period.
+ *     "cpuend": CPU first notices a grace-period end.
  */
 TRACE_EVENT(rcu_grace_period,
 
@@ -160,6 +171,46 @@ TRACE_EVENT(rcu_grace_period_init,
                  __entry->grplo, __entry->grphi, __entry->qsmask)
 );
 
+/*
+ * Tracepoint for RCU no-CBs CPU callback handoffs.  This event is intended
+ * to assist debugging of these handoffs.
+ *
+ * The first argument is the name of the RCU flavor, and the second is
+ * the number of the offloaded CPU are extracted.  The third and final
+ * argument is a string as follows:
+ *
+ *     "WakeEmpty": Wake rcuo kthread, first CB to empty list.
+ *     "WakeOvf": Wake rcuo kthread, CB list is huge.
+ *     "WakeNot": Don't wake rcuo kthread.
+ *     "WakeNotPoll": Don't wake rcuo kthread because it is polling.
+ *     "Poll": Start of new polling cycle for rcu_nocb_poll.
+ *     "Sleep": Sleep waiting for CBs for !rcu_nocb_poll.
+ *     "WokeEmpty": rcuo kthread woke to find empty list.
+ *     "WokeNonEmpty": rcuo kthread woke to find non-empty list.
+ *     "WaitQueue": Enqueue partially done, timed wait for it to complete.
+ *     "WokeQueue": Partial enqueue now complete.
+ */
+TRACE_EVENT(rcu_nocb_wake,
+
+       TP_PROTO(const char *rcuname, int cpu, const char *reason),
+
+       TP_ARGS(rcuname, cpu, reason),
+
+       TP_STRUCT__entry(
+               __field(const char *, rcuname)
+               __field(int, cpu)
+               __field(const char *, reason)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->cpu = cpu;
+               __entry->reason = reason;
+       ),
+
+       TP_printk("%s %d %s", __entry->rcuname, __entry->cpu, __entry->reason)
+);
+
 /*
  * Tracepoint for tasks blocking within preemptible-RCU read-side
  * critical sections.  Track the type of RCU (which one day might
@@ -540,17 +591,17 @@ TRACE_EVENT(rcu_invoke_kfree_callback,
 TRACE_EVENT(rcu_batch_end,
 
        TP_PROTO(const char *rcuname, int callbacks_invoked,
-                bool cb, bool nr, bool iit, bool risk),
+                char cb, char nr, char iit, char risk),
 
        TP_ARGS(rcuname, callbacks_invoked, cb, nr, iit, risk),
 
        TP_STRUCT__entry(
                __field(const char *, rcuname)
                __field(int, callbacks_invoked)
-               __field(bool, cb)
-               __field(bool, nr)
-               __field(bool, iit)
-               __field(bool, risk)
+               __field(char, cb)
+               __field(char, nr)
+               __field(char, iit)
+               __field(char, risk)
        ),
 
        TP_fast_assign(
@@ -656,6 +707,7 @@ TRACE_EVENT(rcu_barrier,
 #define trace_rcu_future_grace_period(rcuname, gpnum, completed, c, \
                                      level, grplo, grphi, event) \
                                      do { } while (0)
+#define trace_rcu_nocb_wake(rcuname, cpu, reason) do { } while (0)
 #define trace_rcu_preempt_task(rcuname, pid, gpnum) do { } while (0)
 #define trace_rcu_unlock_preempted_task(rcuname, gpnum, pid) do { } while (0)
 #define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, \
index 115add2515aaad2bc5caebd1bf330060fee75ebc..33d2b8fe166dafcd8dd39c5b7a092b8b3d5befa6 100644 (file)
@@ -241,6 +241,8 @@ header-y += media.h
 header-y += mei.h
 header-y += mempolicy.h
 header-y += meye.h
+header-y += mic_common.h
+header-y += mic_ioctl.h
 header-y += mii.h
 header-y += minix_fs.h
 header-y += mman.h
diff --git a/include/uapi/linux/mic_common.h b/include/uapi/linux/mic_common.h
new file mode 100644 (file)
index 0000000..17e7d95
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC driver.
+ *
+ */
+#ifndef __MIC_COMMON_H_
+#define __MIC_COMMON_H_
+
+#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)
+
+/**
+ * struct mic_device_desc: Virtio device information shared between the
+ * virtio driver and userspace backend
+ *
+ * @type: Device type: console/network/disk etc.  Type 0/-1 terminates.
+ * @num_vq: Number of virtqueues.
+ * @feature_len: Number of bytes of feature bits.  Multiply by 2: one for
+   host features and one for guest acknowledgements.
+ * @config_len: Number of bytes of the config array after virtqueues.
+ * @status: A status byte, written by the Guest.
+ * @config: Start of the following variable length config.
+ */
+struct mic_device_desc {
+       __s8 type;
+       __u8 num_vq;
+       __u8 feature_len;
+       __u8 config_len;
+       __u8 status;
+       __u64 config[0];
+} __aligned(8);
+
+/**
+ * struct mic_device_ctrl: Per virtio device information in the device page
+ * used internally by the host and card side drivers.
+ *
+ * @vdev: Used for storing MIC vdev information by the guest.
+ * @config_change: Set to 1 by host when a config change is requested.
+ * @vdev_reset: Set to 1 by guest to indicate virtio device has been reset.
+ * @guest_ack: Set to 1 by guest to ack a command.
+ * @host_ack: Set to 1 by host to ack a command.
+ * @used_address_updated: Set to 1 by guest when the used address should be
+ * updated.
+ * @c2h_vdev_db: The doorbell number to be used by guest. Set by host.
+ * @h2c_vdev_db: The doorbell number to be used by host. Set by guest.
+ */
+struct mic_device_ctrl {
+       __u64 vdev;
+       __u8 config_change;
+       __u8 vdev_reset;
+       __u8 guest_ack;
+       __u8 host_ack;
+       __u8 used_address_updated;
+       __s8 c2h_vdev_db;
+       __s8 h2c_vdev_db;
+} __aligned(8);
+
+/**
+ * struct mic_bootparam: Virtio device independent information in device page
+ *
+ * @magic: A magic value used by the card to ensure it can see the host
+ * @c2h_shutdown_db: Card to Host shutdown doorbell set by host
+ * @h2c_shutdown_db: Host to Card shutdown doorbell set by card
+ * @h2c_config_db: Host to Card Virtio config doorbell set by card
+ * @shutdown_status: Card shutdown status set by card
+ * @shutdown_card: Set to 1 by the host when a card shutdown is initiated
+ */
+struct mic_bootparam {
+       __u32 magic;
+       __s8 c2h_shutdown_db;
+       __s8 h2c_shutdown_db;
+       __s8 h2c_config_db;
+       __u8 shutdown_status;
+       __u8 shutdown_card;
+} __aligned(8);
+
+/**
+ * struct mic_device_page: High level representation of the device page
+ *
+ * @bootparam: The bootparam structure is used for sharing information and
+ * status updates between MIC host and card drivers.
+ * @desc: Array of MIC virtio device descriptors.
+ */
+struct mic_device_page {
+       struct mic_bootparam bootparam;
+       struct mic_device_desc desc[0];
+};
+/**
+ * struct mic_vqconfig: This is how we expect the device configuration field
+ * for a virtqueue to be laid out in config space.
+ *
+ * @address: Guest/MIC physical address of the virtio ring
+ * (avail and desc rings)
+ * @used_address: Guest/MIC physical address of the used ring
+ * @num: The number of entries in the virtio_ring
+ */
+struct mic_vqconfig {
+       __u64 address;
+       __u64 used_address;
+       __u16 num;
+} __aligned(8);
+
+/*
+ * The alignment to use between consumer and producer parts of vring.
+ * This is pagesize for historical reasons.
+ */
+#define MIC_VIRTIO_RING_ALIGN          4096
+
+#define MIC_MAX_VRINGS                 4
+#define MIC_VRING_ENTRIES              128
+
+/*
+ * Max vring entries (power of 2) to ensure desc and avail rings
+ * fit in a single page
+ */
+#define MIC_MAX_VRING_ENTRIES          128
+
+/**
+ * Max size of the desc block in bytes: includes:
+ *     - struct mic_device_desc
+ *     - struct mic_vqconfig (num_vq of these)
+ *     - host and guest features
+ *     - virtio device config space
+ */
+#define MIC_MAX_DESC_BLK_SIZE          256
+
+/**
+ * struct _mic_vring_info - Host vring info exposed to userspace backend
+ * for the avail index and magic for the card.
+ *
+ * @avail_idx: host avail idx
+ * @magic: A magic debug cookie.
+ */
+struct _mic_vring_info {
+       __u16 avail_idx;
+       int magic;
+};
+
+/**
+ * struct mic_vring - Vring information.
+ *
+ * @vr: The virtio ring.
+ * @info: Host vring information exposed to the userspace backend for the
+ * avail index and magic for the card.
+ * @va: The va for the buffer allocated for vr and info.
+ * @len: The length of the buffer required for allocating vr and info.
+ */
+struct mic_vring {
+       struct vring vr;
+       struct _mic_vring_info *info;
+       void *va;
+       int len;
+};
+
+#define mic_aligned_desc_size(d) 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;
+}
+
+static inline struct mic_vqconfig *
+mic_vq_config(const struct mic_device_desc *desc)
+{
+       return (struct mic_vqconfig *)(desc + 1);
+}
+
+static inline __u8 *mic_vq_features(const struct mic_device_desc *desc)
+{
+       return (__u8 *)(mic_vq_config(desc) + desc->num_vq);
+}
+
+static inline __u8 *mic_vq_configspace(const struct mic_device_desc *desc)
+{
+       return mic_vq_features(desc) + desc->feature_len * 2;
+}
+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);
+}
+#endif
+
+/* Device page size */
+#define MIC_DP_SIZE 4096
+
+#define MIC_MAGIC 0xc0ffee00
+
+/**
+ * enum mic_states - MIC states.
+ */
+enum mic_states {
+       MIC_OFFLINE = 0,
+       MIC_ONLINE,
+       MIC_SHUTTING_DOWN,
+       MIC_RESET_FAILED,
+       MIC_SUSPENDING,
+       MIC_SUSPENDED,
+       MIC_LAST
+};
+
+/**
+ * enum mic_status - MIC status reported by card after
+ * a host or card initiated shutdown or a card crash.
+ */
+enum mic_status {
+       MIC_NOP = 0,
+       MIC_CRASHED,
+       MIC_HALTED,
+       MIC_POWER_OFF,
+       MIC_RESTART,
+       MIC_STATUS_LAST
+};
+
+#endif
diff --git a/include/uapi/linux/mic_ioctl.h b/include/uapi/linux/mic_ioctl.h
new file mode 100644 (file)
index 0000000..7fabba5
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Host driver.
+ *
+ */
+#ifndef _MIC_IOCTL_H_
+#define _MIC_IOCTL_H_
+
+#include <linux/types.h>
+
+/*
+ * mic_copy - MIC virtio descriptor copy.
+ *
+ * @iov: An array of IOVEC structures containing user space buffers.
+ * @iovcnt: Number of IOVEC structures in iov.
+ * @vr_idx: The vring index.
+ * @update_used: A non zero value results in used index being updated.
+ * @out_len: The aggregate of the total length written to or read from
+ *     the virtio device.
+ */
+struct mic_copy_desc {
+#ifdef __KERNEL__
+       struct iovec __user *iov;
+#else
+       struct iovec *iov;
+#endif
+       int iovcnt;
+       __u8 vr_idx;
+       __u8 update_used;
+       __u32 out_len;
+};
+
+/*
+ * Add a new virtio device
+ * The (struct mic_device_desc *) pointer points to a device page entry
+ *     for the virtio device consisting of:
+ *     - struct mic_device_desc
+ *     - struct mic_vqconfig (num_vq of these)
+ *     - host and guest features
+ *     - virtio device config space
+ * The total size referenced by the pointer should equal the size returned
+ * by desc_size() in mic_common.h
+ */
+#define MIC_VIRTIO_ADD_DEVICE _IOWR('s', 1, struct mic_device_desc *)
+
+/*
+ * Copy the number of entries in the iovec and update the used index
+ * if requested by the user.
+ */
+#define MIC_VIRTIO_COPY_DESC   _IOWR('s', 2, struct mic_copy_desc *)
+
+/*
+ * Notify virtio device of a config change
+ * The (__u8 *) pointer points to config space values for the device
+ * as they should be written into the device page. The total size
+ * referenced by the pointer should equal the config_len field of struct
+ * mic_device_desc.
+ */
+#define MIC_VIRTIO_CONFIG_CHANGE _IOWR('s', 5, __u8 *)
+
+#endif
index 576bddd72e0402b6020208da922c2837b321bb49..64b0f22f5c4c6ae96612adf41ed2414751c2315a 100644 (file)
@@ -60,7 +60,7 @@ struct nfs_mount_data {
 #define NFS_MOUNT_BROKEN_SUID  0x0400  /* 4 */
 #define NFS_MOUNT_NOACL                0x0800  /* 4 */
 #define NFS_MOUNT_STRICTLOCK   0x1000  /* reserved for NFSv4 */
-#define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 */
+#define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 non-text parsed mount data only */
 #define NFS_MOUNT_NORDIRPLUS   0x4000  /* 5 */
 #define NFS_MOUNT_UNSHARED     0x8000  /* 5 */
 #define NFS_MOUNT_FLAGMASK     0xFFFF
index 009a655a5d354c51e20fb34cb12ca653e94f9b71..e1802d6153aec4d0c5fd81300dcde057d9bf8a59 100644 (file)
@@ -136,8 +136,9 @@ enum perf_event_sample_format {
        PERF_SAMPLE_WEIGHT                      = 1U << 14,
        PERF_SAMPLE_DATA_SRC                    = 1U << 15,
        PERF_SAMPLE_IDENTIFIER                  = 1U << 16,
+       PERF_SAMPLE_TRANSACTION                 = 1U << 17,
 
-       PERF_SAMPLE_MAX = 1U << 17,             /* non-ABI */
+       PERF_SAMPLE_MAX = 1U << 18,             /* non-ABI */
 };
 
 /*
@@ -180,6 +181,28 @@ enum perf_sample_regs_abi {
        PERF_SAMPLE_REGS_ABI_64         = 2,
 };
 
+/*
+ * Values for the memory transaction event qualifier, mostly for
+ * abort events. Multiple bits can be set.
+ */
+enum {
+       PERF_TXN_ELISION        = (1 << 0), /* From elision */
+       PERF_TXN_TRANSACTION    = (1 << 1), /* From transaction */
+       PERF_TXN_SYNC           = (1 << 2), /* Instruction is related */
+       PERF_TXN_ASYNC          = (1 << 3), /* Instruction not related */
+       PERF_TXN_RETRY          = (1 << 4), /* Retry possible */
+       PERF_TXN_CONFLICT       = (1 << 5), /* Conflict abort */
+       PERF_TXN_CAPACITY_WRITE = (1 << 6), /* Capacity write abort */
+       PERF_TXN_CAPACITY_READ  = (1 << 7), /* Capacity read abort */
+
+       PERF_TXN_MAX            = (1 << 8), /* non-ABI */
+
+       /* bits 32..63 are reserved for the abort code */
+
+       PERF_TXN_ABORT_MASK  = (0xffffffffULL << 32),
+       PERF_TXN_ABORT_SHIFT = 32,
+};
+
 /*
  * The format of the data returned by read() on a perf event fd,
  * as specified by attr.read_format:
@@ -456,13 +479,15 @@ struct perf_event_mmap_page {
        /*
         * Control data for the mmap() data buffer.
         *
-        * User-space reading the @data_head value should issue an rmb(), on
-        * SMP capable platforms, after reading this value -- see
-        * perf_event_wakeup().
+        * User-space reading the @data_head value should issue an smp_rmb(),
+        * after reading this value.
         *
         * When the mapping is PROT_WRITE the @data_tail value should be
-        * written by userspace to reflect the last read data. In this case
-        * the kernel will not over-write unread data.
+        * written by userspace to reflect the last read data, after issueing
+        * an smp_mb() to separate the data read from the ->data_tail store.
+        * In this case the kernel will not over-write unread data.
+        *
+        * See perf_output_put_handle() for the data ordering.
         */
        __u64   data_head;              /* head in the data section */
        __u64   data_tail;              /* user-space written tail */
diff --git a/include/video/exynos_dp.h b/include/video/exynos_dp.h
deleted file mode 100644 (file)
index bd8cabd..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Samsung SoC DP device support
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Author: Jingoo Han <jg1.han@samsung.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 _EXYNOS_DP_H
-#define _EXYNOS_DP_H
-
-#define DP_TIMEOUT_LOOP_COUNT 100
-#define MAX_CR_LOOP 5
-#define MAX_EQ_LOOP 5
-
-enum link_rate_type {
-       LINK_RATE_1_62GBPS = 0x06,
-       LINK_RATE_2_70GBPS = 0x0a
-};
-
-enum link_lane_count_type {
-       LANE_COUNT1 = 1,
-       LANE_COUNT2 = 2,
-       LANE_COUNT4 = 4
-};
-
-enum link_training_state {
-       START,
-       CLOCK_RECOVERY,
-       EQUALIZER_TRAINING,
-       FINISHED,
-       FAILED
-};
-
-enum voltage_swing_level {
-       VOLTAGE_LEVEL_0,
-       VOLTAGE_LEVEL_1,
-       VOLTAGE_LEVEL_2,
-       VOLTAGE_LEVEL_3,
-};
-
-enum pre_emphasis_level {
-       PRE_EMPHASIS_LEVEL_0,
-       PRE_EMPHASIS_LEVEL_1,
-       PRE_EMPHASIS_LEVEL_2,
-       PRE_EMPHASIS_LEVEL_3,
-};
-
-enum pattern_set {
-       PRBS7,
-       D10_2,
-       TRAINING_PTN1,
-       TRAINING_PTN2,
-       DP_NONE
-};
-
-enum color_space {
-       COLOR_RGB,
-       COLOR_YCBCR422,
-       COLOR_YCBCR444
-};
-
-enum color_depth {
-       COLOR_6,
-       COLOR_8,
-       COLOR_10,
-       COLOR_12
-};
-
-enum color_coefficient {
-       COLOR_YCBCR601,
-       COLOR_YCBCR709
-};
-
-enum dynamic_range {
-       VESA,
-       CEA
-};
-
-enum pll_status {
-       PLL_UNLOCKED,
-       PLL_LOCKED
-};
-
-enum clock_recovery_m_value_type {
-       CALCULATED_M,
-       REGISTER_M
-};
-
-enum video_timing_recognition_type {
-       VIDEO_TIMING_FROM_CAPTURE,
-       VIDEO_TIMING_FROM_REGISTER
-};
-
-enum analog_power_block {
-       AUX_BLOCK,
-       CH0_BLOCK,
-       CH1_BLOCK,
-       CH2_BLOCK,
-       CH3_BLOCK,
-       ANALOG_TOTAL,
-       POWER_ALL
-};
-
-struct video_info {
-       char *name;
-
-       bool h_sync_polarity;
-       bool v_sync_polarity;
-       bool interlaced;
-
-       enum color_space color_space;
-       enum dynamic_range dynamic_range;
-       enum color_coefficient ycbcr_coeff;
-       enum color_depth color_depth;
-
-       enum link_rate_type link_rate;
-       enum link_lane_count_type lane_count;
-};
-
-struct exynos_dp_platdata {
-       struct video_info *video_info;
-
-       void (*phy_init)(void);
-       void (*phy_exit)(void);
-};
-
-#endif /* _EXYNOS_DP_H */
index 89dc88a171af812f1ee01f6b5b64af4e61fc7ca1..6a578f8a1b3e2126c3940d6f4dc2b93db54837bc 100644 (file)
@@ -216,6 +216,7 @@ struct mipi_dsim_config {
  *     automatically.
  * @e_clk_src: select byte clock source.
  * @pd: pointer to MIPI-DSI driver platform data.
+ * @phy: pointer to the MIPI-DSI PHY
  */
 struct mipi_dsim_device {
        struct device                   *dev;
@@ -236,6 +237,7 @@ struct mipi_dsim_device {
        bool                            suspended;
 
        struct mipi_dsim_platform_data  *pd;
+       struct phy                      *phy;
 };
 
 /*
@@ -248,7 +250,6 @@ struct mipi_dsim_device {
  * @enabled: indicate whether mipi controller got enabled or not.
  * @lcd_panel_info: pointer for lcd panel specific structure.
  *     this structure specifies width, height, timing and polarity and so on.
- * @phy_enable: pointer to a callback controlling D-PHY enable/reset
  */
 struct mipi_dsim_platform_data {
        char                            lcd_panel_name[PANEL_NAME_SIZE];
@@ -256,8 +257,6 @@ struct mipi_dsim_platform_data {
        struct mipi_dsim_config         *dsim_config;
        unsigned int                    enabled;
        void                            *lcd_panel_info;
-
-       int (*phy_enable)(struct platform_device *pdev, bool on);
 };
 
 /*
index 3ecd8a1178f102d832cdf3b4af0a908997ea648b..d9887456007a83b212eb41dabf95f7d8c781c6b4 100644 (file)
@@ -284,7 +284,7 @@ config AUDIT
 
 config AUDITSYSCALL
        bool "Enable system-call auditing support"
-       depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
+       depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
        default y if SECURITY_SELINUX
        help
          Enable low-overhead system-call auditing infrastructure that
index 130dfece27ac7cc74c40a60c6b8eeceb97963deb..b0e99deb6d05330482c8ec98f1a511f07f9fa5f1 100644 (file)
@@ -62,7 +62,7 @@ static int proc_ipc_dointvec_minmax_orphans(ctl_table *table, int write,
        return err;
 }
 
-static int proc_ipc_callback_dointvec(ctl_table *table, int write,
+static int proc_ipc_callback_dointvec_minmax(ctl_table *table, int write,
        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct ctl_table ipc_table;
@@ -72,7 +72,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write,
        memcpy(&ipc_table, table, sizeof(ipc_table));
        ipc_table.data = get_ipc(table);
 
-       rc = proc_dointvec(&ipc_table, write, buffer, lenp, ppos);
+       rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
 
        if (write && !rc && lenp_bef == *lenp)
                /*
@@ -152,15 +152,13 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
 #define proc_ipc_dointvec         NULL
 #define proc_ipc_dointvec_minmax   NULL
 #define proc_ipc_dointvec_minmax_orphans   NULL
-#define proc_ipc_callback_dointvec NULL
+#define proc_ipc_callback_dointvec_minmax  NULL
 #define proc_ipcauto_dointvec_minmax NULL
 #endif
 
 static int zero;
 static int one = 1;
-#ifdef CONFIG_CHECKPOINT_RESTORE
 static int int_max = INT_MAX;
-#endif
 
 static struct ctl_table ipc_kern_table[] = {
        {
@@ -198,21 +196,27 @@ static struct ctl_table ipc_kern_table[] = {
                .data           = &init_ipc_ns.msg_ctlmax,
                .maxlen         = sizeof (init_ipc_ns.msg_ctlmax),
                .mode           = 0644,
-               .proc_handler   = proc_ipc_dointvec,
+               .proc_handler   = proc_ipc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &int_max,
        },
        {
                .procname       = "msgmni",
                .data           = &init_ipc_ns.msg_ctlmni,
                .maxlen         = sizeof (init_ipc_ns.msg_ctlmni),
                .mode           = 0644,
-               .proc_handler   = proc_ipc_callback_dointvec,
+               .proc_handler   = proc_ipc_callback_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &int_max,
        },
        {
                .procname       =  "msgmnb",
                .data           = &init_ipc_ns.msg_ctlmnb,
                .maxlen         = sizeof (init_ipc_ns.msg_ctlmnb),
                .mode           = 0644,
-               .proc_handler   = proc_ipc_dointvec,
+               .proc_handler   = proc_ipc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &int_max,
        },
        {
                .procname       = "sem",
index b3d51e229356db26978e2244053ba93ebf686c3c..a4d1aa8da9bc7180ad279a709e4d22cc5627543d 100644 (file)
@@ -6,9 +6,9 @@ obj-y     = fork.o exec_domain.o panic.o \
            cpu.o exit.o itimer.o time.o softirq.o resource.o \
            sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
            signal.o sys.o kmod.o workqueue.o pid.o task_work.o \
-           rcupdate.o extable.o params.o posix-timers.o \
+           extable.o params.o posix-timers.o \
            kthread.o sys_ni.o posix-cpu-timers.o mutex.o \
-           hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
+           hrtimer.o rwsem.o nsproxy.o semaphore.o \
            notifier.o ksysfs.o cred.o reboot.o \
            async.o range.o groups.o lglock.o smpboot.o
 
@@ -27,6 +27,7 @@ obj-y += power/
 obj-y += printk/
 obj-y += cpu/
 obj-y += irq/
+obj-y += rcu/
 
 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
 obj-$(CONFIG_FREEZER) += freezer.o
@@ -81,12 +82,6 @@ obj-$(CONFIG_KGDB) += debug/
 obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
 obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
-obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
-obj-$(CONFIG_TREE_RCU) += rcutree.o
-obj-$(CONFIG_TREE_PREEMPT_RCU) += rcutree.o
-obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o
-obj-$(CONFIG_TINY_RCU) += rcutiny.o
-obj-$(CONFIG_TINY_PREEMPT_RCU) += rcutiny.o
 obj-$(CONFIG_RELAY) += relay.o
 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
index 953c14348375a6d440a904ec7d7e0d3e70d1d767..8c875ef6e120920c5fad9c1c70caf20d418bb7aa 100644 (file)
@@ -175,8 +175,8 @@ int sysctl_perf_event_sample_rate __read_mostly     = DEFAULT_MAX_SAMPLE_RATE;
 static int max_samples_per_tick __read_mostly  = DIV_ROUND_UP(DEFAULT_MAX_SAMPLE_RATE, HZ);
 static int perf_sample_period_ns __read_mostly = DEFAULT_SAMPLE_PERIOD_NS;
 
-static atomic_t perf_sample_allowed_ns __read_mostly =
-       ATOMIC_INIT( DEFAULT_SAMPLE_PERIOD_NS * DEFAULT_CPU_TIME_MAX_PERCENT / 100);
+static int perf_sample_allowed_ns __read_mostly =
+       DEFAULT_SAMPLE_PERIOD_NS * DEFAULT_CPU_TIME_MAX_PERCENT / 100;
 
 void update_perf_cpu_limits(void)
 {
@@ -184,7 +184,7 @@ void update_perf_cpu_limits(void)
 
        tmp *= sysctl_perf_cpu_time_max_percent;
        do_div(tmp, 100);
-       atomic_set(&perf_sample_allowed_ns, tmp);
+       ACCESS_ONCE(perf_sample_allowed_ns) = tmp;
 }
 
 static int perf_rotate_context(struct perf_cpu_context *cpuctx);
@@ -193,7 +193,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write,
                void __user *buffer, size_t *lenp,
                loff_t *ppos)
 {
-       int ret = proc_dointvec(table, write, buffer, lenp, ppos);
+       int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 
        if (ret || !write)
                return ret;
@@ -228,14 +228,15 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
  * we detect that events are taking too long.
  */
 #define NR_ACCUMULATED_SAMPLES 128
-DEFINE_PER_CPU(u64, running_sample_length);
+static DEFINE_PER_CPU(u64, running_sample_length);
 
 void perf_sample_event_took(u64 sample_len_ns)
 {
        u64 avg_local_sample_len;
        u64 local_samples_len;
+       u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns);
 
-       if (atomic_read(&perf_sample_allowed_ns) == 0)
+       if (allowed_ns == 0)
                return;
 
        /* decay the counter by 1 average sample */
@@ -251,7 +252,7 @@ void perf_sample_event_took(u64 sample_len_ns)
         */
        avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES;
 
-       if (avg_local_sample_len <= atomic_read(&perf_sample_allowed_ns))
+       if (avg_local_sample_len <= allowed_ns)
                return;
 
        if (max_samples_per_tick <= 1)
@@ -262,10 +263,9 @@ void perf_sample_event_took(u64 sample_len_ns)
        perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
 
        printk_ratelimited(KERN_WARNING
-                       "perf samples too long (%lld > %d), lowering "
+                       "perf samples too long (%lld > %lld), lowering "
                        "kernel.perf_event_max_sample_rate to %d\n",
-                       avg_local_sample_len,
-                       atomic_read(&perf_sample_allowed_ns),
+                       avg_local_sample_len, allowed_ns,
                        sysctl_perf_event_sample_rate);
 
        update_perf_cpu_limits();
@@ -899,6 +899,7 @@ static void unclone_ctx(struct perf_event_context *ctx)
                put_ctx(ctx->parent_ctx);
                ctx->parent_ctx = NULL;
        }
+       ctx->generation++;
 }
 
 static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
@@ -1136,6 +1137,8 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
        ctx->nr_events++;
        if (event->attr.inherit_stat)
                ctx->nr_stat++;
+
+       ctx->generation++;
 }
 
 /*
@@ -1201,6 +1204,9 @@ static void perf_event__header_size(struct perf_event *event)
        if (sample_type & PERF_SAMPLE_DATA_SRC)
                size += sizeof(data->data_src.val);
 
+       if (sample_type & PERF_SAMPLE_TRANSACTION)
+               size += sizeof(data->txn);
+
        event->header_size = size;
 }
 
@@ -1310,6 +1316,8 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
         */
        if (event->state > PERF_EVENT_STATE_OFF)
                event->state = PERF_EVENT_STATE_OFF;
+
+       ctx->generation++;
 }
 
 static void perf_group_detach(struct perf_event *event)
@@ -2146,22 +2154,38 @@ static void ctx_sched_out(struct perf_event_context *ctx,
 }
 
 /*
- * Test whether two contexts are equivalent, i.e. whether they
- * have both been cloned from the same version of the same context
- * and they both have the same number of enabled events.
- * If the number of enabled events is the same, then the set
- * of enabled events should be the same, because these are both
- * inherited contexts, therefore we can't access individual events
- * in them directly with an fd; we can only enable/disable all
- * events via prctl, or enable/disable all events in a family
- * via ioctl, which will have the same effect on both contexts.
+ * Test whether two contexts are equivalent, i.e. whether they have both been
+ * cloned from the same version of the same context.
+ *
+ * Equivalence is measured using a generation number in the context that is
+ * incremented on each modification to it; see unclone_ctx(), list_add_event()
+ * and list_del_event().
  */
 static int context_equiv(struct perf_event_context *ctx1,
                         struct perf_event_context *ctx2)
 {
-       return ctx1->parent_ctx && ctx1->parent_ctx == ctx2->parent_ctx
-               && ctx1->parent_gen == ctx2->parent_gen
-               && !ctx1->pin_count && !ctx2->pin_count;
+       /* Pinning disables the swap optimization */
+       if (ctx1->pin_count || ctx2->pin_count)
+               return 0;
+
+       /* If ctx1 is the parent of ctx2 */
+       if (ctx1 == ctx2->parent_ctx && ctx1->generation == ctx2->parent_gen)
+               return 1;
+
+       /* If ctx2 is the parent of ctx1 */
+       if (ctx1->parent_ctx == ctx2 && ctx1->parent_gen == ctx2->generation)
+               return 1;
+
+       /*
+        * If ctx1 and ctx2 have the same parent; we flatten the parent
+        * hierarchy, see perf_event_init_context().
+        */
+       if (ctx1->parent_ctx && ctx1->parent_ctx == ctx2->parent_ctx &&
+                       ctx1->parent_gen == ctx2->parent_gen)
+               return 1;
+
+       /* Unmatched */
+       return 0;
 }
 
 static void __perf_event_sync_stat(struct perf_event *event,
@@ -2244,7 +2268,7 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
 {
        struct perf_event_context *ctx = task->perf_event_ctxp[ctxn];
        struct perf_event_context *next_ctx;
-       struct perf_event_context *parent;
+       struct perf_event_context *parent, *next_parent;
        struct perf_cpu_context *cpuctx;
        int do_switch = 1;
 
@@ -2256,10 +2280,18 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
                return;
 
        rcu_read_lock();
-       parent = rcu_dereference(ctx->parent_ctx);
        next_ctx = next->perf_event_ctxp[ctxn];
-       if (parent && next_ctx &&
-           rcu_dereference(next_ctx->parent_ctx) == parent) {
+       if (!next_ctx)
+               goto unlock;
+
+       parent = rcu_dereference(ctx->parent_ctx);
+       next_parent = rcu_dereference(next_ctx->parent_ctx);
+
+       /* If neither context have a parent context; they cannot be clones. */
+       if (!parent && !next_parent)
+               goto unlock;
+
+       if (next_parent == ctx || next_ctx == parent || next_parent == parent) {
                /*
                 * Looks like the two contexts are clones, so we might be
                 * able to optimize the context switch.  We lock both
@@ -2287,6 +2319,7 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
                raw_spin_unlock(&next_ctx->lock);
                raw_spin_unlock(&ctx->lock);
        }
+unlock:
        rcu_read_unlock();
 
        if (do_switch) {
@@ -4572,6 +4605,9 @@ void perf_output_sample(struct perf_output_handle *handle,
        if (sample_type & PERF_SAMPLE_DATA_SRC)
                perf_output_put(handle, data->data_src.val);
 
+       if (sample_type & PERF_SAMPLE_TRANSACTION)
+               perf_output_put(handle, data->txn);
+
        if (!event->attr.watermark) {
                int wakeup_events = event->attr.wakeup_events;
 
@@ -5100,27 +5136,26 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
        unsigned int size;
        char tmp[16];
        char *buf = NULL;
-       const char *name;
-
-       memset(tmp, 0, sizeof(tmp));
+       char *name;
 
        if (file) {
                struct inode *inode;
                dev_t dev;
+
+               buf = kmalloc(PATH_MAX, GFP_KERNEL);
+               if (!buf) {
+                       name = "//enomem";
+                       goto cpy_name;
+               }
                /*
-                * d_path works from the end of the rb backwards, so we
+                * d_path() works from the end of the rb backwards, so we
                 * need to add enough zero bytes after the string to handle
                 * the 64bit alignment we do later.
                 */
-               buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
-               if (!buf) {
-                       name = strncpy(tmp, "//enomem", sizeof(tmp));
-                       goto got_name;
-               }
-               name = d_path(&file->f_path, buf, PATH_MAX);
+               name = d_path(&file->f_path, buf, PATH_MAX - sizeof(u64));
                if (IS_ERR(name)) {
-                       name = strncpy(tmp, "//toolong", sizeof(tmp));
-                       goto got_name;
+                       name = "//toolong";
+                       goto cpy_name;
                }
                inode = file_inode(vma->vm_file);
                dev = inode->i_sb->s_dev;
@@ -5128,34 +5163,39 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
                gen = inode->i_generation;
                maj = MAJOR(dev);
                min = MINOR(dev);
-
+               goto got_name;
        } else {
-               if (arch_vma_name(mmap_event->vma)) {
-                       name = strncpy(tmp, arch_vma_name(mmap_event->vma),
-                                      sizeof(tmp) - 1);
-                       tmp[sizeof(tmp) - 1] = '\0';
-                       goto got_name;
-               }
+               name = (char *)arch_vma_name(vma);
+               if (name)
+                       goto cpy_name;
 
-               if (!vma->vm_mm) {
-                       name = strncpy(tmp, "[vdso]", sizeof(tmp));
-                       goto got_name;
-               } else if (vma->vm_start <= vma->vm_mm->start_brk &&
+               if (vma->vm_start <= vma->vm_mm->start_brk &&
                                vma->vm_end >= vma->vm_mm->brk) {
-                       name = strncpy(tmp, "[heap]", sizeof(tmp));
-                       goto got_name;
-               } else if (vma->vm_start <= vma->vm_mm->start_stack &&
+                       name = "[heap]";
+                       goto cpy_name;
+               }
+               if (vma->vm_start <= vma->vm_mm->start_stack &&
                                vma->vm_end >= vma->vm_mm->start_stack) {
-                       name = strncpy(tmp, "[stack]", sizeof(tmp));
-                       goto got_name;
+                       name = "[stack]";
+                       goto cpy_name;
                }
 
-               name = strncpy(tmp, "//anon", sizeof(tmp));
-               goto got_name;
+               name = "//anon";
+               goto cpy_name;
        }
 
+cpy_name:
+       strlcpy(tmp, name, sizeof(tmp));
+       name = tmp;
 got_name:
-       size = ALIGN(strlen(name)+1, sizeof(u64));
+       /*
+        * Since our buffer works in 8 byte units we need to align our string
+        * size to a multiple of 8. However, we must guarantee the tail end is
+        * zero'd out to avoid leaking random bits to userspace.
+        */
+       size = strlen(name)+1;
+       while (!IS_ALIGNED(size, sizeof(u64)))
+               name[size++] = '\0';
 
        mmap_event->file_name = name;
        mmap_event->file_size = size;
@@ -6292,6 +6332,7 @@ type_show(struct device *dev, struct device_attribute *attr, char *page)
 
        return snprintf(page, PAGE_SIZE-1, "%d\n", pmu->type);
 }
+static DEVICE_ATTR_RO(type);
 
 static ssize_t
 perf_event_mux_interval_ms_show(struct device *dev,
@@ -6336,17 +6377,19 @@ perf_event_mux_interval_ms_store(struct device *dev,
 
        return count;
 }
+static DEVICE_ATTR_RW(perf_event_mux_interval_ms);
 
-static struct device_attribute pmu_dev_attrs[] = {
-       __ATTR_RO(type),
-       __ATTR_RW(perf_event_mux_interval_ms),
-       __ATTR_NULL,
+static struct attribute *pmu_dev_attrs[] = {
+       &dev_attr_type.attr,
+       &dev_attr_perf_event_mux_interval_ms.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(pmu_dev);
 
 static int pmu_bus_running;
 static struct bus_type pmu_bus = {
        .name           = "event_source",
-       .dev_attrs      = pmu_dev_attrs,
+       .dev_groups     = pmu_dev_groups,
 };
 
 static void pmu_dev_release(struct device *dev)
@@ -7126,7 +7169,6 @@ SYSCALL_DEFINE5(perf_event_open,
        }
 
        perf_install_in_context(ctx, event, event->cpu);
-       ++ctx->generation;
        perf_unpin_context(ctx);
        mutex_unlock(&ctx->mutex);
 
@@ -7209,7 +7251,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
        WARN_ON_ONCE(ctx->parent_ctx);
        mutex_lock(&ctx->mutex);
        perf_install_in_context(ctx, event, cpu);
-       ++ctx->generation;
        perf_unpin_context(ctx);
        mutex_unlock(&ctx->mutex);
 
index ca6599723be5624cdeb4a3cad5ef5dd10a4e1c7b..569b218782ad6f52053a21495c893935dcde5b10 100644 (file)
@@ -82,16 +82,16 @@ static inline unsigned long perf_data_size(struct ring_buffer *rb)
 }
 
 #define DEFINE_OUTPUT_COPY(func_name, memcpy_func)                     \
-static inline unsigned int                                             \
+static inline unsigned long                                            \
 func_name(struct perf_output_handle *handle,                           \
-         const void *buf, unsigned int len)                            \
+         const void *buf, unsigned long len)                           \
 {                                                                      \
        unsigned long size, written;                                    \
                                                                        \
        do {                                                            \
-               size = min_t(unsigned long, handle->size, len);         \
-                                                                       \
+               size    = min(handle->size, len);                       \
                written = memcpy_func(handle->addr, buf, size);         \
+               written = size - written;                               \
                                                                        \
                len -= written;                                         \
                handle->addr += written;                                \
@@ -110,20 +110,37 @@ func_name(struct perf_output_handle *handle,                              \
        return len;                                                     \
 }
 
-static inline int memcpy_common(void *dst, const void *src, size_t n)
+static inline unsigned long
+memcpy_common(void *dst, const void *src, unsigned long n)
 {
        memcpy(dst, src, n);
-       return n;
+       return 0;
 }
 
 DEFINE_OUTPUT_COPY(__output_copy, memcpy_common)
 
-#define MEMCPY_SKIP(dst, src, n) (n)
+static inline unsigned long
+memcpy_skip(void *dst, const void *src, unsigned long n)
+{
+       return 0;
+}
 
-DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
+DEFINE_OUTPUT_COPY(__output_skip, memcpy_skip)
 
 #ifndef arch_perf_out_copy_user
-#define arch_perf_out_copy_user __copy_from_user_inatomic
+#define arch_perf_out_copy_user arch_perf_out_copy_user
+
+static inline unsigned long
+arch_perf_out_copy_user(void *dst, const void *src, unsigned long n)
+{
+       unsigned long ret;
+
+       pagefault_disable();
+       ret = __copy_from_user_inatomic(dst, src, n);
+       pagefault_enable();
+
+       return ret;
+}
 #endif
 
 DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user)
index cd55144270b5401030f4b5ce5576f97b6b976b63..e8b168af135ba3ec7d72c780746ce02f051be2e3 100644 (file)
 #include <linux/perf_event.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/circ_buf.h>
 
 #include "internal.h"
 
-static bool perf_output_space(struct ring_buffer *rb, unsigned long tail,
-                             unsigned long offset, unsigned long head)
-{
-       unsigned long sz = perf_data_size(rb);
-       unsigned long mask = sz - 1;
-
-       /*
-        * check if user-writable
-        * overwrite : over-write its own tail
-        * !overwrite: buffer possibly drops events.
-        */
-       if (rb->overwrite)
-               return true;
-
-       /*
-        * verify that payload is not bigger than buffer
-        * otherwise masking logic may fail to detect
-        * the "not enough space" condition
-        */
-       if ((head - offset) > sz)
-               return false;
-
-       offset = (offset - tail) & mask;
-       head   = (head   - tail) & mask;
-
-       if ((int)(head - offset) < 0)
-               return false;
-
-       return true;
-}
-
 static void perf_output_wakeup(struct perf_output_handle *handle)
 {
        atomic_set(&handle->rb->poll, POLL_IN);
@@ -87,15 +57,36 @@ again:
                goto out;
 
        /*
-        * Publish the known good head. Rely on the full barrier implied
-        * by atomic_dec_and_test() order the rb->head read and this
-        * write.
+        * Since the mmap() consumer (userspace) can run on a different CPU:
+        *
+        *   kernel                             user
+        *
+        *   READ ->data_tail                   READ ->data_head
+        *   smp_mb()   (A)                     smp_rmb()       (C)
+        *   WRITE $data                        READ $data
+        *   smp_wmb()  (B)                     smp_mb()        (D)
+        *   STORE ->data_head                  WRITE ->data_tail
+        *
+        * Where A pairs with D, and B pairs with C.
+        *
+        * I don't think A needs to be a full barrier because we won't in fact
+        * write data until we see the store from userspace. So we simply don't
+        * issue the data WRITE until we observe it. Be conservative for now.
+        *
+        * OTOH, D needs to be a full barrier since it separates the data READ
+        * from the tail WRITE.
+        *
+        * For B a WMB is sufficient since it separates two WRITEs, and for C
+        * an RMB is sufficient since it separates two READs.
+        *
+        * See perf_output_begin().
         */
+       smp_wmb();
        rb->user_page->data_head = head;
 
        /*
-        * Now check if we missed an update, rely on the (compiler)
-        * barrier in atomic_dec_and_test() to re-read rb->head.
+        * Now check if we missed an update -- rely on previous implied
+        * compiler barriers to force a re-read.
         */
        if (unlikely(head != local_read(&rb->head))) {
                local_inc(&rb->nest);
@@ -114,8 +105,7 @@ int perf_output_begin(struct perf_output_handle *handle,
 {
        struct ring_buffer *rb;
        unsigned long tail, offset, head;
-       int have_lost;
-       struct perf_sample_data sample_data;
+       int have_lost, page_shift;
        struct {
                struct perf_event_header header;
                u64                      id;
@@ -130,55 +120,63 @@ int perf_output_begin(struct perf_output_handle *handle,
                event = event->parent;
 
        rb = rcu_dereference(event->rb);
-       if (!rb)
+       if (unlikely(!rb))
                goto out;
 
-       handle->rb      = rb;
-       handle->event   = event;
-
-       if (!rb->nr_pages)
+       if (unlikely(!rb->nr_pages))
                goto out;
 
+       handle->rb    = rb;
+       handle->event = event;
+
        have_lost = local_read(&rb->lost);
-       if (have_lost) {
-               lost_event.header.size = sizeof(lost_event);
-               perf_event_header__init_id(&lost_event.header, &sample_data,
-                                          event);
-               size += lost_event.header.size;
+       if (unlikely(have_lost)) {
+               size += sizeof(lost_event);
+               if (event->attr.sample_id_all)
+                       size += event->id_header_size;
        }
 
        perf_output_get_handle(handle);
 
        do {
-               /*
-                * Userspace could choose to issue a mb() before updating the
-                * tail pointer. So that all reads will be completed before the
-                * write is issued.
-                */
                tail = ACCESS_ONCE(rb->user_page->data_tail);
-               smp_rmb();
                offset = head = local_read(&rb->head);
-               head += size;
-               if (unlikely(!perf_output_space(rb, tail, offset, head)))
+               if (!rb->overwrite &&
+                   unlikely(CIRC_SPACE(head, tail, perf_data_size(rb)) < size))
                        goto fail;
+               head += size;
        } while (local_cmpxchg(&rb->head, offset, head) != offset);
 
-       if (head - local_read(&rb->wakeup) > rb->watermark)
+       /*
+        * Separate the userpage->tail read from the data stores below.
+        * Matches the MB userspace SHOULD issue after reading the data
+        * and before storing the new tail position.
+        *
+        * See perf_output_put_handle().
+        */
+       smp_mb();
+
+       if (unlikely(head - local_read(&rb->wakeup) > rb->watermark))
                local_add(rb->watermark, &rb->wakeup);
 
-       handle->page = offset >> (PAGE_SHIFT + page_order(rb));
-       handle->page &= rb->nr_pages - 1;
-       handle->size = offset & ((PAGE_SIZE << page_order(rb)) - 1);
-       handle->addr = rb->data_pages[handle->page];
-       handle->addr += handle->size;
-       handle->size = (PAGE_SIZE << page_order(rb)) - handle->size;
+       page_shift = PAGE_SHIFT + page_order(rb);
 
-       if (have_lost) {
+       handle->page = (offset >> page_shift) & (rb->nr_pages - 1);
+       offset &= (1UL << page_shift) - 1;
+       handle->addr = rb->data_pages[handle->page] + offset;
+       handle->size = (1UL << page_shift) - offset;
+
+       if (unlikely(have_lost)) {
+               struct perf_sample_data sample_data;
+
+               lost_event.header.size = sizeof(lost_event);
                lost_event.header.type = PERF_RECORD_LOST;
                lost_event.header.misc = 0;
                lost_event.id          = event->id;
                lost_event.lost        = local_xchg(&rb->lost, 0);
 
+               perf_event_header__init_id(&lost_event.header,
+                                          &sample_data, event);
                perf_output_put(handle, lost_event);
                perf_event__output_id_sample(event, handle, &sample_data);
        }
index ad8e1bdca70e4c702ff5c6e86255dc74a8b98259..24b7d6ca871b632f2e35912e720bfc0162c939c5 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kdebug.h>      /* notifier mechanism */
 #include "../../mm/internal.h" /* munlock_vma_page */
 #include <linux/percpu-rwsem.h>
+#include <linux/task_work.h>
 
 #include <linux/uprobes.h>
 
@@ -244,12 +245,12 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t
  * the architecture. If an arch has variable length instruction and the
  * breakpoint instruction is not of the smallest length instruction
  * supported by that architecture then we need to modify is_trap_at_addr and
- * write_opcode accordingly. This would never be a problem for archs that
- * have fixed length instructions.
+ * uprobe_write_opcode accordingly. This would never be a problem for archs
+ * that have fixed length instructions.
  */
 
 /*
- * write_opcode - write the opcode at a given virtual address.
+ * uprobe_write_opcode - write the opcode at a given virtual address.
  * @mm: the probed process address space.
  * @vaddr: the virtual address to store the opcode.
  * @opcode: opcode to be written at @vaddr.
@@ -260,7 +261,7 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t
  * For mm @mm, write the opcode at @vaddr.
  * Return 0 (success) or a negative errno.
  */
-static int write_opcode(struct mm_struct *mm, unsigned long vaddr,
+int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr,
                        uprobe_opcode_t opcode)
 {
        struct page *old_page, *new_page;
@@ -314,7 +315,7 @@ put_old:
  */
 int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
 {
-       return write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
+       return uprobe_write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
 }
 
 /**
@@ -329,7 +330,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 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)
@@ -503,9 +504,8 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc)
        return ret;
 }
 
-static int
-__copy_insn(struct address_space *mapping, struct file *filp, char *insn,
-                       unsigned long nbytes, loff_t offset)
+static int __copy_insn(struct address_space *mapping, struct file *filp,
+                       void *insn, int nbytes, loff_t offset)
 {
        struct page *page;
 
@@ -527,28 +527,28 @@ __copy_insn(struct address_space *mapping, struct file *filp, char *insn,
 
 static int copy_insn(struct uprobe *uprobe, struct file *filp)
 {
-       struct address_space *mapping;
-       unsigned long nbytes;
-       int bytes;
-
-       nbytes = PAGE_SIZE - (uprobe->offset & ~PAGE_MASK);
-       mapping = uprobe->inode->i_mapping;
+       struct address_space *mapping = uprobe->inode->i_mapping;
+       loff_t offs = uprobe->offset;
+       void *insn = uprobe->arch.insn;
+       int size = MAX_UINSN_BYTES;
+       int len, err = -EIO;
 
-       /* Instruction at end of binary; copy only available bytes */
-       if (uprobe->offset + MAX_UINSN_BYTES > uprobe->inode->i_size)
-               bytes = uprobe->inode->i_size - uprobe->offset;
-       else
-               bytes = MAX_UINSN_BYTES;
+       /* Copy only available bytes, -EIO if nothing was read */
+       do {
+               if (offs >= i_size_read(uprobe->inode))
+                       break;
 
-       /* Instruction at the page-boundary; copy bytes in second page */
-       if (nbytes < bytes) {
-               int err = __copy_insn(mapping, filp, uprobe->arch.insn + nbytes,
-                               bytes - nbytes, uprobe->offset + nbytes);
+               len = min_t(int, size, PAGE_SIZE - (offs & ~PAGE_MASK));
+               err = __copy_insn(mapping, filp, insn, len, offs);
                if (err)
-                       return err;
-               bytes = nbytes;
-       }
-       return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset);
+                       break;
+
+               insn += len;
+               offs += len;
+               size -= len;
+       } while (size);
+
+       return err;
 }
 
 static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
@@ -576,7 +576,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
        if (ret)
                goto out;
 
-       /* write_opcode() assumes we don't cross page boundary */
+       /* uprobe_write_opcode() assumes we don't cross page boundary */
        BUG_ON((uprobe->offset & ~PAGE_MASK) +
                        UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
 
@@ -1096,21 +1096,22 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
 }
 
 /* Slot allocation for XOL */
-static int xol_add_vma(struct xol_area *area)
+static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 {
-       struct mm_struct *mm = current->mm;
        int ret = -EALREADY;
 
        down_write(&mm->mmap_sem);
        if (mm->uprobes_state.xol_area)
                goto fail;
 
-       ret = -ENOMEM;
-       /* Try to map as high as possible, this is only a hint. */
-       area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
-       if (area->vaddr & ~PAGE_MASK) {
-               ret = area->vaddr;
-               goto fail;
+       if (!area->vaddr) {
+               /* Try to map as high as possible, this is only a hint. */
+               area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
+                                               PAGE_SIZE, 0, 0);
+               if (area->vaddr & ~PAGE_MASK) {
+                       ret = area->vaddr;
+                       goto fail;
+               }
        }
 
        ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
@@ -1120,30 +1121,19 @@ static int xol_add_vma(struct xol_area *area)
 
        smp_wmb();      /* pairs with get_xol_area() */
        mm->uprobes_state.xol_area = area;
-       ret = 0;
  fail:
        up_write(&mm->mmap_sem);
 
        return ret;
 }
 
-/*
- * get_xol_area - Allocate process's xol_area if necessary.
- * This area will be used for storing instructions for execution out of line.
- *
- * Returns the allocated area or NULL.
- */
-static struct xol_area *get_xol_area(void)
+static struct xol_area *__create_xol_area(unsigned long vaddr)
 {
        struct mm_struct *mm = current->mm;
-       struct xol_area *area;
        uprobe_opcode_t insn = UPROBE_SWBP_INSN;
+       struct xol_area *area;
 
-       area = mm->uprobes_state.xol_area;
-       if (area)
-               goto ret;
-
-       area = kzalloc(sizeof(*area), GFP_KERNEL);
+       area = kmalloc(sizeof(*area), GFP_KERNEL);
        if (unlikely(!area))
                goto out;
 
@@ -1155,13 +1145,14 @@ static struct xol_area *get_xol_area(void)
        if (!area->page)
                goto free_bitmap;
 
-       /* allocate first slot of task's xol_area for the return probes */
+       area->vaddr = vaddr;
+       init_waitqueue_head(&area->wq);
+       /* Reserve the 1st slot for get_trampoline_vaddr() */
        set_bit(0, area->bitmap);
-       copy_to_page(area->page, 0, &insn, UPROBE_SWBP_INSN_SIZE);
        atomic_set(&area->slot_count, 1);
-       init_waitqueue_head(&area->wq);
+       copy_to_page(area->page, 0, &insn, UPROBE_SWBP_INSN_SIZE);
 
-       if (!xol_add_vma(area))
+       if (!xol_add_vma(mm, area))
                return area;
 
        __free_page(area->page);
@@ -1170,9 +1161,25 @@ static struct xol_area *get_xol_area(void)
  free_area:
        kfree(area);
  out:
+       return NULL;
+}
+
+/*
+ * get_xol_area - Allocate process's xol_area if necessary.
+ * This area will be used for storing instructions for execution out of line.
+ *
+ * Returns the allocated area or NULL.
+ */
+static struct xol_area *get_xol_area(void)
+{
+       struct mm_struct *mm = current->mm;
+       struct xol_area *area;
+
+       if (!mm->uprobes_state.xol_area)
+               __create_xol_area(0);
+
        area = mm->uprobes_state.xol_area;
- ret:
-       smp_read_barrier_depends();     /* pairs with wmb in xol_add_vma() */
+       smp_read_barrier_depends();     /* pairs with wmb in xol_add_vma() */
        return area;
 }
 
@@ -1256,7 +1263,8 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
                return 0;
 
        /* Initialize the slot */
-       copy_to_page(area->page, xol_vaddr, uprobe->arch.insn, MAX_UINSN_BYTES);
+       copy_to_page(area->page, xol_vaddr,
+                       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.
@@ -1344,14 +1352,6 @@ void uprobe_free_utask(struct task_struct *t)
        t->utask = NULL;
 }
 
-/*
- * Called in context of a new clone/fork from copy_process.
- */
-void uprobe_copy_process(struct task_struct *t)
-{
-       t->utask = NULL;
-}
-
 /*
  * Allocate a uprobe_task object for the task if if necessary.
  * Called when the thread hits a breakpoint.
@@ -1367,6 +1367,90 @@ static struct uprobe_task *get_utask(void)
        return current->utask;
 }
 
+static int dup_utask(struct task_struct *t, struct uprobe_task *o_utask)
+{
+       struct uprobe_task *n_utask;
+       struct return_instance **p, *o, *n;
+
+       n_utask = kzalloc(sizeof(struct uprobe_task), GFP_KERNEL);
+       if (!n_utask)
+               return -ENOMEM;
+       t->utask = n_utask;
+
+       p = &n_utask->return_instances;
+       for (o = o_utask->return_instances; o; o = o->next) {
+               n = kmalloc(sizeof(struct return_instance), GFP_KERNEL);
+               if (!n)
+                       return -ENOMEM;
+
+               *n = *o;
+               atomic_inc(&n->uprobe->ref);
+               n->next = NULL;
+
+               *p = n;
+               p = &n->next;
+               n_utask->depth++;
+       }
+
+       return 0;
+}
+
+static void uprobe_warn(struct task_struct *t, const char *msg)
+{
+       pr_warn("uprobe: %s:%d failed to %s\n",
+                       current->comm, current->pid, 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))
+               uprobe_warn(current, "dup xol area");
+}
+
+/*
+ * Called in context of a new clone/fork from copy_process.
+ */
+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;
+
+       if (!utask || !utask->return_instances)
+               return;
+
+       if (mm == t->mm && !(flags & CLONE_VFORK))
+               return;
+
+       if (dup_utask(t, utask))
+               return uprobe_warn(t, "dup ret instances");
+
+       /* The task can fork() after dup_xol_work() fails */
+       area = mm->uprobes_state.xol_area;
+       if (!area)
+               return uprobe_warn(t, "dup xol area");
+
+       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);
+}
+
 /*
  * Current area->vaddr notion assume the trampoline address is always
  * equal area->vaddr.
@@ -1857,9 +1941,4 @@ static int __init init_uprobes(void)
 
        return register_die_notifier(&uprobe_exception_nb);
 }
-module_init(init_uprobes);
-
-static void __exit exit_uprobes(void)
-{
-}
-module_exit(exit_uprobes);
+__initcall(init_uprobes);
index c93be06dee874fae8366888840346ae58c012416..f6d11fc67f722201f1048527e00564ccd381afc1 100644 (file)
@@ -1370,7 +1370,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        INIT_LIST_HEAD(&p->pi_state_list);
        p->pi_state_cache = NULL;
 #endif
-       uprobe_copy_process(p);
        /*
         * sigaltstack should be cleared when sharing the same VM
         */
@@ -1487,6 +1486,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        perf_event_fork(p);
 
        trace_task_newtask(p, clone_flags);
+       uprobe_copy_process(p, clone_flags);
 
        return p;
 
index 514bcfd855a8f9c05ef2934f364f6c2d7b600e4e..3e59f951d42f9663bfe39f7a8fc25bdc98b8b149 100644 (file)
@@ -956,7 +956,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                        goto out_mput;
                }
 
-               sched_setscheduler(t, SCHED_FIFO, &param);
+               sched_setscheduler_nocheck(t, SCHED_FIFO, &param);
 
                /*
                 * We keep the reference to the task struct even if
index e16c45b9ee77054f80becd37a51da00776f796c1..4e8e14c34e428d6a75580ec862c4975b0425dfc0 100644 (file)
@@ -4224,7 +4224,7 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
        printk("\n%srcu_scheduler_active = %d, debug_locks = %d\n",
               !rcu_lockdep_current_cpu_online()
                        ? "RCU used illegally from offline CPU!\n"
-                       : rcu_is_cpu_idle()
+                       : !rcu_is_watching()
                                ? "RCU used illegally from idle CPU!\n"
                                : "",
               rcu_scheduler_active, debug_locks);
@@ -4247,7 +4247,7 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
         * So complain bitterly if someone does call rcu_read_lock(),
         * rcu_read_lock_bh() and so on from extended quiescent states.
         */
-       if (rcu_is_cpu_idle())
+       if (!rcu_is_watching())
                printk("RCU used illegally from extended quiescent state!\n");
 
        lockdep_print_held_locks(curr);
diff --git a/kernel/rcu.h b/kernel/rcu.h
deleted file mode 100644 (file)
index 7713196..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Read-Copy Update definitions shared among RCU implementations.
- *
- * 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 IBM Corporation, 2011
- *
- * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
- */
-
-#ifndef __LINUX_RCU_H
-#define __LINUX_RCU_H
-
-#ifdef CONFIG_RCU_TRACE
-#define RCU_TRACE(stmt) stmt
-#else /* #ifdef CONFIG_RCU_TRACE */
-#define RCU_TRACE(stmt)
-#endif /* #else #ifdef CONFIG_RCU_TRACE */
-
-/*
- * Process-level increment to ->dynticks_nesting field.  This allows for
- * architectures that use half-interrupts and half-exceptions from
- * process context.
- *
- * DYNTICK_TASK_NEST_MASK defines a field of width DYNTICK_TASK_NEST_WIDTH
- * that counts the number of process-based reasons why RCU cannot
- * consider the corresponding CPU to be idle, and DYNTICK_TASK_NEST_VALUE
- * is the value used to increment or decrement this field.
- *
- * The rest of the bits could in principle be used to count interrupts,
- * but this would mean that a negative-one value in the interrupt
- * field could incorrectly zero out the DYNTICK_TASK_NEST_MASK field.
- * We therefore provide a two-bit guard field defined by DYNTICK_TASK_MASK
- * that is set to DYNTICK_TASK_FLAG upon initial exit from idle.
- * The DYNTICK_TASK_EXIT_IDLE value is thus the combined value used upon
- * initial exit from idle.
- */
-#define DYNTICK_TASK_NEST_WIDTH 7
-#define DYNTICK_TASK_NEST_VALUE ((LLONG_MAX >> DYNTICK_TASK_NEST_WIDTH) + 1)
-#define DYNTICK_TASK_NEST_MASK  (LLONG_MAX - DYNTICK_TASK_NEST_VALUE + 1)
-#define DYNTICK_TASK_FLAG         ((DYNTICK_TASK_NEST_VALUE / 8) * 2)
-#define DYNTICK_TASK_MASK         ((DYNTICK_TASK_NEST_VALUE / 8) * 3)
-#define DYNTICK_TASK_EXIT_IDLE    (DYNTICK_TASK_NEST_VALUE + \
-                                   DYNTICK_TASK_FLAG)
-
-/*
- * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
- * by call_rcu() and rcu callback execution, and are therefore not part of the
- * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
- */
-
-#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
-# define STATE_RCU_HEAD_READY  0
-# define STATE_RCU_HEAD_QUEUED 1
-
-extern struct debug_obj_descr rcuhead_debug_descr;
-
-static inline int debug_rcu_head_queue(struct rcu_head *head)
-{
-       int r1;
-
-       r1 = debug_object_activate(head, &rcuhead_debug_descr);
-       debug_object_active_state(head, &rcuhead_debug_descr,
-                                 STATE_RCU_HEAD_READY,
-                                 STATE_RCU_HEAD_QUEUED);
-       return r1;
-}
-
-static inline void debug_rcu_head_unqueue(struct rcu_head *head)
-{
-       debug_object_active_state(head, &rcuhead_debug_descr,
-                                 STATE_RCU_HEAD_QUEUED,
-                                 STATE_RCU_HEAD_READY);
-       debug_object_deactivate(head, &rcuhead_debug_descr);
-}
-#else  /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-static inline int debug_rcu_head_queue(struct rcu_head *head)
-{
-       return 0;
-}
-
-static inline void debug_rcu_head_unqueue(struct rcu_head *head)
-{
-}
-#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-
-extern void kfree(const void *);
-
-static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head)
-{
-       unsigned long offset = (unsigned long)head->func;
-
-       if (__is_kfree_rcu_offset(offset)) {
-               RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset));
-               kfree((void *)head - offset);
-               return 1;
-       } else {
-               RCU_TRACE(trace_rcu_invoke_callback(rn, head));
-               head->func(head);
-               return 0;
-       }
-}
-
-extern int rcu_expedited;
-
-#ifdef CONFIG_RCU_STALL_COMMON
-
-extern int rcu_cpu_stall_suppress;
-int rcu_jiffies_till_stall_check(void);
-
-#endif /* #ifdef CONFIG_RCU_STALL_COMMON */
-
-#endif /* __LINUX_RCU_H */
diff --git a/kernel/rcu/Makefile b/kernel/rcu/Makefile
new file mode 100644 (file)
index 0000000..01e9ec3
--- /dev/null
@@ -0,0 +1,6 @@
+obj-y += update.o srcu.o
+obj-$(CONFIG_RCU_TORTURE_TEST) += torture.o
+obj-$(CONFIG_TREE_RCU) += tree.o
+obj-$(CONFIG_TREE_PREEMPT_RCU) += tree.o
+obj-$(CONFIG_TREE_RCU_TRACE) += tree_trace.o
+obj-$(CONFIG_TINY_RCU) += tiny.o
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
new file mode 100644 (file)
index 0000000..7859a0a
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Read-Copy Update definitions shared among RCU implementations.
+ *
+ * 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 IBM Corporation, 2011
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#ifndef __LINUX_RCU_H
+#define __LINUX_RCU_H
+
+#ifdef CONFIG_RCU_TRACE
+#define RCU_TRACE(stmt) stmt
+#else /* #ifdef CONFIG_RCU_TRACE */
+#define RCU_TRACE(stmt)
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+/*
+ * Process-level increment to ->dynticks_nesting field.  This allows for
+ * architectures that use half-interrupts and half-exceptions from
+ * process context.
+ *
+ * DYNTICK_TASK_NEST_MASK defines a field of width DYNTICK_TASK_NEST_WIDTH
+ * that counts the number of process-based reasons why RCU cannot
+ * consider the corresponding CPU to be idle, and DYNTICK_TASK_NEST_VALUE
+ * is the value used to increment or decrement this field.
+ *
+ * The rest of the bits could in principle be used to count interrupts,
+ * but this would mean that a negative-one value in the interrupt
+ * field could incorrectly zero out the DYNTICK_TASK_NEST_MASK field.
+ * We therefore provide a two-bit guard field defined by DYNTICK_TASK_MASK
+ * that is set to DYNTICK_TASK_FLAG upon initial exit from idle.
+ * The DYNTICK_TASK_EXIT_IDLE value is thus the combined value used upon
+ * initial exit from idle.
+ */
+#define DYNTICK_TASK_NEST_WIDTH 7
+#define DYNTICK_TASK_NEST_VALUE ((LLONG_MAX >> DYNTICK_TASK_NEST_WIDTH) + 1)
+#define DYNTICK_TASK_NEST_MASK  (LLONG_MAX - DYNTICK_TASK_NEST_VALUE + 1)
+#define DYNTICK_TASK_FLAG         ((DYNTICK_TASK_NEST_VALUE / 8) * 2)
+#define DYNTICK_TASK_MASK         ((DYNTICK_TASK_NEST_VALUE / 8) * 3)
+#define DYNTICK_TASK_EXIT_IDLE    (DYNTICK_TASK_NEST_VALUE + \
+                                   DYNTICK_TASK_FLAG)
+
+/*
+ * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
+ * by call_rcu() and rcu callback execution, and are therefore not part of the
+ * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
+ */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+# define STATE_RCU_HEAD_READY  0
+# define STATE_RCU_HEAD_QUEUED 1
+
+extern struct debug_obj_descr rcuhead_debug_descr;
+
+static inline int debug_rcu_head_queue(struct rcu_head *head)
+{
+       int r1;
+
+       r1 = debug_object_activate(head, &rcuhead_debug_descr);
+       debug_object_active_state(head, &rcuhead_debug_descr,
+                                 STATE_RCU_HEAD_READY,
+                                 STATE_RCU_HEAD_QUEUED);
+       return r1;
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+       debug_object_active_state(head, &rcuhead_debug_descr,
+                                 STATE_RCU_HEAD_QUEUED,
+                                 STATE_RCU_HEAD_READY);
+       debug_object_deactivate(head, &rcuhead_debug_descr);
+}
+#else  /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+static inline int debug_rcu_head_queue(struct rcu_head *head)
+{
+       return 0;
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+}
+#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+
+extern void kfree(const void *);
+
+static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head)
+{
+       unsigned long offset = (unsigned long)head->func;
+
+       if (__is_kfree_rcu_offset(offset)) {
+               RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset));
+               kfree((void *)head - offset);
+               return 1;
+       } else {
+               RCU_TRACE(trace_rcu_invoke_callback(rn, head));
+               head->func(head);
+               return 0;
+       }
+}
+
+extern int rcu_expedited;
+
+#ifdef CONFIG_RCU_STALL_COMMON
+
+extern int rcu_cpu_stall_suppress;
+int rcu_jiffies_till_stall_check(void);
+
+#endif /* #ifdef CONFIG_RCU_STALL_COMMON */
+
+/*
+ * Strings used in tracepoints need to be exported via the
+ * tracing system such that tools like perf and trace-cmd can
+ * translate the string address pointers to actual text.
+ */
+#define TPS(x)  tracepoint_string(x)
+
+#endif /* __LINUX_RCU_H */
diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
new file mode 100644 (file)
index 0000000..01d5ccb
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * Sleepable Read-Copy Update mechanism for mutual exclusion.
+ *
+ * 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) IBM Corporation, 2006
+ * Copyright (C) Fujitsu, 2012
+ *
+ * Author: Paul McKenney <paulmck@us.ibm.com>
+ *        Lai Jiangshan <laijs@cn.fujitsu.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU/ *.txt
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/percpu.h>
+#include <linux/preempt.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <linux/srcu.h>
+
+#include <trace/events/rcu.h>
+
+#include "rcu.h"
+
+/*
+ * Initialize an rcu_batch structure to empty.
+ */
+static inline void rcu_batch_init(struct rcu_batch *b)
+{
+       b->head = NULL;
+       b->tail = &b->head;
+}
+
+/*
+ * Enqueue a callback onto the tail of the specified rcu_batch structure.
+ */
+static inline void rcu_batch_queue(struct rcu_batch *b, struct rcu_head *head)
+{
+       *b->tail = head;
+       b->tail = &head->next;
+}
+
+/*
+ * Is the specified rcu_batch structure empty?
+ */
+static inline bool rcu_batch_empty(struct rcu_batch *b)
+{
+       return b->tail == &b->head;
+}
+
+/*
+ * Remove the callback at the head of the specified rcu_batch structure
+ * and return a pointer to it, or return NULL if the structure is empty.
+ */
+static inline struct rcu_head *rcu_batch_dequeue(struct rcu_batch *b)
+{
+       struct rcu_head *head;
+
+       if (rcu_batch_empty(b))
+               return NULL;
+
+       head = b->head;
+       b->head = head->next;
+       if (b->tail == &head->next)
+               rcu_batch_init(b);
+
+       return head;
+}
+
+/*
+ * Move all callbacks from the rcu_batch structure specified by "from" to
+ * the structure specified by "to".
+ */
+static inline void rcu_batch_move(struct rcu_batch *to, struct rcu_batch *from)
+{
+       if (!rcu_batch_empty(from)) {
+               *to->tail = from->head;
+               to->tail = from->tail;
+               rcu_batch_init(from);
+       }
+}
+
+static int init_srcu_struct_fields(struct srcu_struct *sp)
+{
+       sp->completed = 0;
+       spin_lock_init(&sp->queue_lock);
+       sp->running = false;
+       rcu_batch_init(&sp->batch_queue);
+       rcu_batch_init(&sp->batch_check0);
+       rcu_batch_init(&sp->batch_check1);
+       rcu_batch_init(&sp->batch_done);
+       INIT_DELAYED_WORK(&sp->work, process_srcu);
+       sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
+       return sp->per_cpu_ref ? 0 : -ENOMEM;
+}
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+int __init_srcu_struct(struct srcu_struct *sp, const char *name,
+                      struct lock_class_key *key)
+{
+       /* Don't re-initialize a lock while it is held. */
+       debug_check_no_locks_freed((void *)sp, sizeof(*sp));
+       lockdep_init_map(&sp->dep_map, name, key, 0);
+       return init_srcu_struct_fields(sp);
+}
+EXPORT_SYMBOL_GPL(__init_srcu_struct);
+
+#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+/**
+ * init_srcu_struct - initialize a sleep-RCU structure
+ * @sp: structure to initialize.
+ *
+ * Must invoke this on a given srcu_struct before passing that srcu_struct
+ * to any other function.  Each srcu_struct represents a separate domain
+ * of SRCU protection.
+ */
+int init_srcu_struct(struct srcu_struct *sp)
+{
+       return init_srcu_struct_fields(sp);
+}
+EXPORT_SYMBOL_GPL(init_srcu_struct);
+
+#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+/*
+ * Returns approximate total of the readers' ->seq[] values for the
+ * rank of per-CPU counters specified by idx.
+ */
+static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx)
+{
+       int cpu;
+       unsigned long sum = 0;
+       unsigned long t;
+
+       for_each_possible_cpu(cpu) {
+               t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]);
+               sum += t;
+       }
+       return sum;
+}
+
+/*
+ * Returns approximate number of readers active on the specified rank
+ * of the per-CPU ->c[] counters.
+ */
+static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx)
+{
+       int cpu;
+       unsigned long sum = 0;
+       unsigned long t;
+
+       for_each_possible_cpu(cpu) {
+               t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]);
+               sum += t;
+       }
+       return sum;
+}
+
+/*
+ * Return true if the number of pre-existing readers is determined to
+ * be stably zero.  An example unstable zero can occur if the call
+ * to srcu_readers_active_idx() misses an __srcu_read_lock() increment,
+ * but due to task migration, sees the corresponding __srcu_read_unlock()
+ * decrement.  This can happen because srcu_readers_active_idx() takes
+ * time to sum the array, and might in fact be interrupted or preempted
+ * partway through the summation.
+ */
+static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx)
+{
+       unsigned long seq;
+
+       seq = srcu_readers_seq_idx(sp, idx);
+
+       /*
+        * The following smp_mb() A pairs with the smp_mb() B located in
+        * __srcu_read_lock().  This pairing ensures that if an
+        * __srcu_read_lock() increments its counter after the summation
+        * in srcu_readers_active_idx(), then the corresponding SRCU read-side
+        * critical section will see any changes made prior to the start
+        * of the current SRCU grace period.
+        *
+        * Also, if the above call to srcu_readers_seq_idx() saw the
+        * increment of ->seq[], then the call to srcu_readers_active_idx()
+        * must see the increment of ->c[].
+        */
+       smp_mb(); /* A */
+
+       /*
+        * Note that srcu_readers_active_idx() can incorrectly return
+        * zero even though there is a pre-existing reader throughout.
+        * To see this, suppose that task A is in a very long SRCU
+        * read-side critical section that started on CPU 0, and that
+        * no other reader exists, so that the sum of the counters
+        * is equal to one.  Then suppose that task B starts executing
+        * srcu_readers_active_idx(), summing up to CPU 1, and then that
+        * task C starts reading on CPU 0, so that its increment is not
+        * summed, but finishes reading on CPU 2, so that its decrement
+        * -is- summed.  Then when task B completes its sum, it will
+        * incorrectly get zero, despite the fact that task A has been
+        * in its SRCU read-side critical section the whole time.
+        *
+        * We therefore do a validation step should srcu_readers_active_idx()
+        * return zero.
+        */
+       if (srcu_readers_active_idx(sp, idx) != 0)
+               return false;
+
+       /*
+        * The remainder of this function is the validation step.
+        * The following smp_mb() D pairs with the smp_mb() C in
+        * __srcu_read_unlock().  If the __srcu_read_unlock() was seen
+        * by srcu_readers_active_idx() above, then any destructive
+        * operation performed after the grace period will happen after
+        * the corresponding SRCU read-side critical section.
+        *
+        * Note that there can be at most NR_CPUS worth of readers using
+        * the old index, which is not enough to overflow even a 32-bit
+        * integer.  (Yes, this does mean that systems having more than
+        * a billion or so CPUs need to be 64-bit systems.)  Therefore,
+        * the sum of the ->seq[] counters cannot possibly overflow.
+        * Therefore, the only way that the return values of the two
+        * calls to srcu_readers_seq_idx() can be equal is if there were
+        * no increments of the corresponding rank of ->seq[] counts
+        * in the interim.  But the missed-increment scenario laid out
+        * above includes an increment of the ->seq[] counter by
+        * the corresponding __srcu_read_lock().  Therefore, if this
+        * scenario occurs, the return values from the two calls to
+        * srcu_readers_seq_idx() will differ, and thus the validation
+        * step below suffices.
+        */
+       smp_mb(); /* D */
+
+       return srcu_readers_seq_idx(sp, idx) == seq;
+}
+
+/**
+ * srcu_readers_active - returns approximate number of readers.
+ * @sp: which srcu_struct to count active readers (holding srcu_read_lock).
+ *
+ * Note that this is not an atomic primitive, and can therefore suffer
+ * severe errors when invoked on an active srcu_struct.  That said, it
+ * can be useful as an error check at cleanup time.
+ */
+static int srcu_readers_active(struct srcu_struct *sp)
+{
+       int cpu;
+       unsigned long sum = 0;
+
+       for_each_possible_cpu(cpu) {
+               sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]);
+               sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]);
+       }
+       return sum;
+}
+
+/**
+ * cleanup_srcu_struct - deconstruct a sleep-RCU structure
+ * @sp: structure to clean up.
+ *
+ * Must invoke this after you are finished using a given srcu_struct that
+ * was initialized via init_srcu_struct(), else you leak memory.
+ */
+void cleanup_srcu_struct(struct srcu_struct *sp)
+{
+       if (WARN_ON(srcu_readers_active(sp)))
+               return; /* Leakage unless caller handles error. */
+       free_percpu(sp->per_cpu_ref);
+       sp->per_cpu_ref = NULL;
+}
+EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
+
+/*
+ * Counts the new reader in the appropriate per-CPU element of the
+ * srcu_struct.  Must be called from process context.
+ * Returns an index that must be passed to the matching srcu_read_unlock().
+ */
+int __srcu_read_lock(struct srcu_struct *sp)
+{
+       int idx;
+
+       idx = ACCESS_ONCE(sp->completed) & 0x1;
+       preempt_disable();
+       ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->c[idx]) += 1;
+       smp_mb(); /* B */  /* Avoid leaking the critical section. */
+       ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->seq[idx]) += 1;
+       preempt_enable();
+       return idx;
+}
+EXPORT_SYMBOL_GPL(__srcu_read_lock);
+
+/*
+ * Removes the count for the old reader from the appropriate per-CPU
+ * element of the srcu_struct.  Note that this may well be a different
+ * CPU than that which was incremented by the corresponding srcu_read_lock().
+ * Must be called from process context.
+ */
+void __srcu_read_unlock(struct srcu_struct *sp, int idx)
+{
+       smp_mb(); /* C */  /* Avoid leaking the critical section. */
+       this_cpu_dec(sp->per_cpu_ref->c[idx]);
+}
+EXPORT_SYMBOL_GPL(__srcu_read_unlock);
+
+/*
+ * We use an adaptive strategy for synchronize_srcu() and especially for
+ * synchronize_srcu_expedited().  We spin for a fixed time period
+ * (defined below) to allow SRCU readers to exit their read-side critical
+ * sections.  If there are still some readers after 10 microseconds,
+ * we repeatedly block for 1-millisecond time periods.  This approach
+ * has done well in testing, so there is no need for a config parameter.
+ */
+#define SRCU_RETRY_CHECK_DELAY         5
+#define SYNCHRONIZE_SRCU_TRYCOUNT      2
+#define SYNCHRONIZE_SRCU_EXP_TRYCOUNT  12
+
+/*
+ * @@@ Wait until all pre-existing readers complete.  Such readers
+ * will have used the index specified by "idx".
+ * the caller should ensures the ->completed is not changed while checking
+ * and idx = (->completed & 1) ^ 1
+ */
+static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount)
+{
+       for (;;) {
+               if (srcu_readers_active_idx_check(sp, idx))
+                       return true;
+               if (--trycount <= 0)
+                       return false;
+               udelay(SRCU_RETRY_CHECK_DELAY);
+       }
+}
+
+/*
+ * Increment the ->completed counter so that future SRCU readers will
+ * use the other rank of the ->c[] and ->seq[] arrays.  This allows
+ * us to wait for pre-existing readers in a starvation-free manner.
+ */
+static void srcu_flip(struct srcu_struct *sp)
+{
+       sp->completed++;
+}
+
+/*
+ * Enqueue an SRCU callback on the specified srcu_struct structure,
+ * initiating grace-period processing if it is not already running.
+ */
+void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
+               void (*func)(struct rcu_head *head))
+{
+       unsigned long flags;
+
+       head->next = NULL;
+       head->func = func;
+       spin_lock_irqsave(&sp->queue_lock, flags);
+       rcu_batch_queue(&sp->batch_queue, head);
+       if (!sp->running) {
+               sp->running = true;
+               schedule_delayed_work(&sp->work, 0);
+       }
+       spin_unlock_irqrestore(&sp->queue_lock, flags);
+}
+EXPORT_SYMBOL_GPL(call_srcu);
+
+struct rcu_synchronize {
+       struct rcu_head head;
+       struct completion completion;
+};
+
+/*
+ * Awaken the corresponding synchronize_srcu() instance now that a
+ * grace period has elapsed.
+ */
+static void wakeme_after_rcu(struct rcu_head *head)
+{
+       struct rcu_synchronize *rcu;
+
+       rcu = container_of(head, struct rcu_synchronize, head);
+       complete(&rcu->completion);
+}
+
+static void srcu_advance_batches(struct srcu_struct *sp, int trycount);
+static void srcu_reschedule(struct srcu_struct *sp);
+
+/*
+ * Helper function for synchronize_srcu() and synchronize_srcu_expedited().
+ */
+static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
+{
+       struct rcu_synchronize rcu;
+       struct rcu_head *head = &rcu.head;
+       bool done = false;
+
+       rcu_lockdep_assert(!lock_is_held(&sp->dep_map) &&
+                          !lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_srcu() in same-type SRCU (or RCU) read-side critical section");
+
+       might_sleep();
+       init_completion(&rcu.completion);
+
+       head->next = NULL;
+       head->func = wakeme_after_rcu;
+       spin_lock_irq(&sp->queue_lock);
+       if (!sp->running) {
+               /* steal the processing owner */
+               sp->running = true;
+               rcu_batch_queue(&sp->batch_check0, head);
+               spin_unlock_irq(&sp->queue_lock);
+
+               srcu_advance_batches(sp, trycount);
+               if (!rcu_batch_empty(&sp->batch_done)) {
+                       BUG_ON(sp->batch_done.head != head);
+                       rcu_batch_dequeue(&sp->batch_done);
+                       done = true;
+               }
+               /* give the processing owner to work_struct */
+               srcu_reschedule(sp);
+       } else {
+               rcu_batch_queue(&sp->batch_queue, head);
+               spin_unlock_irq(&sp->queue_lock);
+       }
+
+       if (!done)
+               wait_for_completion(&rcu.completion);
+}
+
+/**
+ * synchronize_srcu - wait for prior SRCU read-side critical-section completion
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Wait for the count to drain to zero of both indexes. To avoid the
+ * possible starvation of synchronize_srcu(), it waits for the count of
+ * the index=((->completed & 1) ^ 1) to drain to zero at first,
+ * and then flip the completed and wait for the count of the other index.
+ *
+ * Can block; must be called from process context.
+ *
+ * Note that it is illegal to call synchronize_srcu() from the corresponding
+ * SRCU read-side critical section; doing so will result in deadlock.
+ * However, it is perfectly legal to call synchronize_srcu() on one
+ * srcu_struct from some other srcu_struct's read-side critical section.
+ */
+void synchronize_srcu(struct srcu_struct *sp)
+{
+       __synchronize_srcu(sp, rcu_expedited
+                          ? SYNCHRONIZE_SRCU_EXP_TRYCOUNT
+                          : SYNCHRONIZE_SRCU_TRYCOUNT);
+}
+EXPORT_SYMBOL_GPL(synchronize_srcu);
+
+/**
+ * synchronize_srcu_expedited - Brute-force SRCU grace period
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Wait for an SRCU grace period to elapse, but be more aggressive about
+ * spinning rather than blocking when waiting.
+ *
+ * Note that it is also illegal to call synchronize_srcu_expedited()
+ * from the corresponding SRCU read-side critical section;
+ * doing so will result in deadlock.  However, it is perfectly legal
+ * to call synchronize_srcu_expedited() on one srcu_struct from some
+ * other srcu_struct's read-side critical section, as long as
+ * the resulting graph of srcu_structs is acyclic.
+ */
+void synchronize_srcu_expedited(struct srcu_struct *sp)
+{
+       __synchronize_srcu(sp, SYNCHRONIZE_SRCU_EXP_TRYCOUNT);
+}
+EXPORT_SYMBOL_GPL(synchronize_srcu_expedited);
+
+/**
+ * srcu_barrier - Wait until all in-flight call_srcu() callbacks complete.
+ */
+void srcu_barrier(struct srcu_struct *sp)
+{
+       synchronize_srcu(sp);
+}
+EXPORT_SYMBOL_GPL(srcu_barrier);
+
+/**
+ * srcu_batches_completed - return batches completed.
+ * @sp: srcu_struct on which to report batch completion.
+ *
+ * Report the number of batches, correlated with, but not necessarily
+ * precisely the same as, the number of grace periods that have elapsed.
+ */
+long srcu_batches_completed(struct srcu_struct *sp)
+{
+       return sp->completed;
+}
+EXPORT_SYMBOL_GPL(srcu_batches_completed);
+
+#define SRCU_CALLBACK_BATCH    10
+#define SRCU_INTERVAL          1
+
+/*
+ * Move any new SRCU callbacks to the first stage of the SRCU grace
+ * period pipeline.
+ */
+static void srcu_collect_new(struct srcu_struct *sp)
+{
+       if (!rcu_batch_empty(&sp->batch_queue)) {
+               spin_lock_irq(&sp->queue_lock);
+               rcu_batch_move(&sp->batch_check0, &sp->batch_queue);
+               spin_unlock_irq(&sp->queue_lock);
+       }
+}
+
+/*
+ * Core SRCU state machine.  Advance callbacks from ->batch_check0 to
+ * ->batch_check1 and then to ->batch_done as readers drain.
+ */
+static void srcu_advance_batches(struct srcu_struct *sp, int trycount)
+{
+       int idx = 1 ^ (sp->completed & 1);
+
+       /*
+        * Because readers might be delayed for an extended period after
+        * fetching ->completed for their index, at any point in time there
+        * might well be readers using both idx=0 and idx=1.  We therefore
+        * need to wait for readers to clear from both index values before
+        * invoking a callback.
+        */
+
+       if (rcu_batch_empty(&sp->batch_check0) &&
+           rcu_batch_empty(&sp->batch_check1))
+               return; /* no callbacks need to be advanced */
+
+       if (!try_check_zero(sp, idx, trycount))
+               return; /* failed to advance, will try after SRCU_INTERVAL */
+
+       /*
+        * The callbacks in ->batch_check1 have already done with their
+        * first zero check and flip back when they were enqueued on
+        * ->batch_check0 in a previous invocation of srcu_advance_batches().
+        * (Presumably try_check_zero() returned false during that
+        * invocation, leaving the callbacks stranded on ->batch_check1.)
+        * They are therefore ready to invoke, so move them to ->batch_done.
+        */
+       rcu_batch_move(&sp->batch_done, &sp->batch_check1);
+
+       if (rcu_batch_empty(&sp->batch_check0))
+               return; /* no callbacks need to be advanced */
+       srcu_flip(sp);
+
+       /*
+        * The callbacks in ->batch_check0 just finished their
+        * first check zero and flip, so move them to ->batch_check1
+        * for future checking on the other idx.
+        */
+       rcu_batch_move(&sp->batch_check1, &sp->batch_check0);
+
+       /*
+        * SRCU read-side critical sections are normally short, so check
+        * at least twice in quick succession after a flip.
+        */
+       trycount = trycount < 2 ? 2 : trycount;
+       if (!try_check_zero(sp, idx^1, trycount))
+               return; /* failed to advance, will try after SRCU_INTERVAL */
+
+       /*
+        * The callbacks in ->batch_check1 have now waited for all
+        * pre-existing readers using both idx values.  They are therefore
+        * ready to invoke, so move them to ->batch_done.
+        */
+       rcu_batch_move(&sp->batch_done, &sp->batch_check1);
+}
+
+/*
+ * Invoke a limited number of SRCU callbacks that have passed through
+ * their grace period.  If there are more to do, SRCU will reschedule
+ * the workqueue.
+ */
+static void srcu_invoke_callbacks(struct srcu_struct *sp)
+{
+       int i;
+       struct rcu_head *head;
+
+       for (i = 0; i < SRCU_CALLBACK_BATCH; i++) {
+               head = rcu_batch_dequeue(&sp->batch_done);
+               if (!head)
+                       break;
+               local_bh_disable();
+               head->func(head);
+               local_bh_enable();
+       }
+}
+
+/*
+ * Finished one round of SRCU grace period.  Start another if there are
+ * more SRCU callbacks queued, otherwise put SRCU into not-running state.
+ */
+static void srcu_reschedule(struct srcu_struct *sp)
+{
+       bool pending = true;
+
+       if (rcu_batch_empty(&sp->batch_done) &&
+           rcu_batch_empty(&sp->batch_check1) &&
+           rcu_batch_empty(&sp->batch_check0) &&
+           rcu_batch_empty(&sp->batch_queue)) {
+               spin_lock_irq(&sp->queue_lock);
+               if (rcu_batch_empty(&sp->batch_done) &&
+                   rcu_batch_empty(&sp->batch_check1) &&
+                   rcu_batch_empty(&sp->batch_check0) &&
+                   rcu_batch_empty(&sp->batch_queue)) {
+                       sp->running = false;
+                       pending = false;
+               }
+               spin_unlock_irq(&sp->queue_lock);
+       }
+
+       if (pending)
+               schedule_delayed_work(&sp->work, SRCU_INTERVAL);
+}
+
+/*
+ * This is the work-queue function that handles SRCU grace periods.
+ */
+void process_srcu(struct work_struct *work)
+{
+       struct srcu_struct *sp;
+
+       sp = container_of(work, struct srcu_struct, work.work);
+
+       srcu_collect_new(sp);
+       srcu_advance_batches(sp, 1);
+       srcu_invoke_callbacks(sp);
+       srcu_reschedule(sp);
+}
+EXPORT_SYMBOL_GPL(process_srcu);
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
new file mode 100644 (file)
index 0000000..0c9a934
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition.
+ *
+ * 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 IBM Corporation, 2008
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU
+ */
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/cpu.h>
+#include <linux/prefetch.h>
+#include <linux/ftrace_event.h>
+
+#ifdef CONFIG_RCU_TRACE
+#include <trace/events/rcu.h>
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+#include "rcu.h"
+
+/* Forward declarations for tiny_plugin.h. */
+struct rcu_ctrlblk;
+static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp);
+static void rcu_process_callbacks(struct softirq_action *unused);
+static void __call_rcu(struct rcu_head *head,
+                      void (*func)(struct rcu_head *rcu),
+                      struct rcu_ctrlblk *rcp);
+
+static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
+
+#include "tiny_plugin.h"
+
+/* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. */
+static void rcu_idle_enter_common(long long newval)
+{
+       if (newval) {
+               RCU_TRACE(trace_rcu_dyntick(TPS("--="),
+                                           rcu_dynticks_nesting, newval));
+               rcu_dynticks_nesting = newval;
+               return;
+       }
+       RCU_TRACE(trace_rcu_dyntick(TPS("Start"),
+                                   rcu_dynticks_nesting, newval));
+       if (!is_idle_task(current)) {
+               struct task_struct *idle __maybe_unused = idle_task(smp_processor_id());
+
+               RCU_TRACE(trace_rcu_dyntick(TPS("Entry error: not idle task"),
+                                           rcu_dynticks_nesting, newval));
+               ftrace_dump(DUMP_ALL);
+               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
+                         current->pid, current->comm,
+                         idle->pid, idle->comm); /* must be idle task! */
+       }
+       rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
+       barrier();
+       rcu_dynticks_nesting = newval;
+}
+
+/*
+ * Enter idle, which is an extended quiescent state if we have fully
+ * entered that mode (i.e., if the new value of dynticks_nesting is zero).
+ */
+void rcu_idle_enter(void)
+{
+       unsigned long flags;
+       long long newval;
+
+       local_irq_save(flags);
+       WARN_ON_ONCE((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0);
+       if ((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) ==
+           DYNTICK_TASK_NEST_VALUE)
+               newval = 0;
+       else
+               newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE;
+       rcu_idle_enter_common(newval);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(rcu_idle_enter);
+
+/*
+ * Exit an interrupt handler towards idle.
+ */
+void rcu_irq_exit(void)
+{
+       unsigned long flags;
+       long long newval;
+
+       local_irq_save(flags);
+       newval = rcu_dynticks_nesting - 1;
+       WARN_ON_ONCE(newval < 0);
+       rcu_idle_enter_common(newval);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(rcu_irq_exit);
+
+/* Common code for rcu_idle_exit() and rcu_irq_enter(), see kernel/rcutree.c. */
+static void rcu_idle_exit_common(long long oldval)
+{
+       if (oldval) {
+               RCU_TRACE(trace_rcu_dyntick(TPS("++="),
+                                           oldval, rcu_dynticks_nesting));
+               return;
+       }
+       RCU_TRACE(trace_rcu_dyntick(TPS("End"), oldval, rcu_dynticks_nesting));
+       if (!is_idle_task(current)) {
+               struct task_struct *idle __maybe_unused = idle_task(smp_processor_id());
+
+               RCU_TRACE(trace_rcu_dyntick(TPS("Exit error: not idle task"),
+                         oldval, rcu_dynticks_nesting));
+               ftrace_dump(DUMP_ALL);
+               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
+                         current->pid, current->comm,
+                         idle->pid, idle->comm); /* must be idle task! */
+       }
+}
+
+/*
+ * Exit idle, so that we are no longer in an extended quiescent state.
+ */
+void rcu_idle_exit(void)
+{
+       unsigned long flags;
+       long long oldval;
+
+       local_irq_save(flags);
+       oldval = rcu_dynticks_nesting;
+       WARN_ON_ONCE(rcu_dynticks_nesting < 0);
+       if (rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK)
+               rcu_dynticks_nesting += DYNTICK_TASK_NEST_VALUE;
+       else
+               rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
+       rcu_idle_exit_common(oldval);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(rcu_idle_exit);
+
+/*
+ * Enter an interrupt handler, moving away from idle.
+ */
+void rcu_irq_enter(void)
+{
+       unsigned long flags;
+       long long oldval;
+
+       local_irq_save(flags);
+       oldval = rcu_dynticks_nesting;
+       rcu_dynticks_nesting++;
+       WARN_ON_ONCE(rcu_dynticks_nesting == 0);
+       rcu_idle_exit_common(oldval);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(rcu_irq_enter);
+
+#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE)
+
+/*
+ * Test whether RCU thinks that the current CPU is idle.
+ */
+bool __rcu_is_watching(void)
+{
+       return rcu_dynticks_nesting;
+}
+EXPORT_SYMBOL(__rcu_is_watching);
+
+#endif /* defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */
+
+/*
+ * Test whether the current CPU was interrupted from idle.  Nested
+ * interrupts don't count, we must be running at the first interrupt
+ * level.
+ */
+static int rcu_is_cpu_rrupt_from_idle(void)
+{
+       return rcu_dynticks_nesting <= 1;
+}
+
+/*
+ * Helper function for rcu_sched_qs() and rcu_bh_qs().
+ * Also irqs are disabled to avoid confusion due to interrupt handlers
+ * invoking call_rcu().
+ */
+static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
+{
+       RCU_TRACE(reset_cpu_stall_ticks(rcp));
+       if (rcp->rcucblist != NULL &&
+           rcp->donetail != rcp->curtail) {
+               rcp->donetail = rcp->curtail;
+               return 1;
+       }
+
+       return 0;
+}
+
+/*
+ * Record an rcu quiescent state.  And an rcu_bh quiescent state while we
+ * are at it, given that any rcu quiescent state is also an rcu_bh
+ * quiescent state.  Use "+" instead of "||" to defeat short circuiting.
+ */
+void rcu_sched_qs(int cpu)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       if (rcu_qsctr_help(&rcu_sched_ctrlblk) +
+           rcu_qsctr_help(&rcu_bh_ctrlblk))
+               raise_softirq(RCU_SOFTIRQ);
+       local_irq_restore(flags);
+}
+
+/*
+ * Record an rcu_bh quiescent state.
+ */
+void rcu_bh_qs(int cpu)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       if (rcu_qsctr_help(&rcu_bh_ctrlblk))
+               raise_softirq(RCU_SOFTIRQ);
+       local_irq_restore(flags);
+}
+
+/*
+ * Check to see if the scheduling-clock interrupt came from an extended
+ * quiescent state, and, if so, tell RCU about it.  This function must
+ * be called from hardirq context.  It is normally called from the
+ * scheduling-clock interrupt.
+ */
+void rcu_check_callbacks(int cpu, int user)
+{
+       RCU_TRACE(check_cpu_stalls());
+       if (user || rcu_is_cpu_rrupt_from_idle())
+               rcu_sched_qs(cpu);
+       else if (!in_softirq())
+               rcu_bh_qs(cpu);
+}
+
+/*
+ * Invoke the RCU callbacks on the specified rcu_ctrlkblk structure
+ * whose grace period has elapsed.
+ */
+static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
+{
+       const char *rn = NULL;
+       struct rcu_head *next, *list;
+       unsigned long flags;
+       RCU_TRACE(int cb_count = 0);
+
+       /* If no RCU callbacks ready to invoke, just return. */
+       if (&rcp->rcucblist == rcp->donetail) {
+               RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, 0, -1));
+               RCU_TRACE(trace_rcu_batch_end(rcp->name, 0,
+                                             !!ACCESS_ONCE(rcp->rcucblist),
+                                             need_resched(),
+                                             is_idle_task(current),
+                                             false));
+               return;
+       }
+
+       /* Move the ready-to-invoke callbacks to a local list. */
+       local_irq_save(flags);
+       RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, rcp->qlen, -1));
+       list = rcp->rcucblist;
+       rcp->rcucblist = *rcp->donetail;
+       *rcp->donetail = NULL;
+       if (rcp->curtail == rcp->donetail)
+               rcp->curtail = &rcp->rcucblist;
+       rcp->donetail = &rcp->rcucblist;
+       local_irq_restore(flags);
+
+       /* Invoke the callbacks on the local list. */
+       RCU_TRACE(rn = rcp->name);
+       while (list) {
+               next = list->next;
+               prefetch(next);
+               debug_rcu_head_unqueue(list);
+               local_bh_disable();
+               __rcu_reclaim(rn, list);
+               local_bh_enable();
+               list = next;
+               RCU_TRACE(cb_count++);
+       }
+       RCU_TRACE(rcu_trace_sub_qlen(rcp, cb_count));
+       RCU_TRACE(trace_rcu_batch_end(rcp->name,
+                                     cb_count, 0, need_resched(),
+                                     is_idle_task(current),
+                                     false));
+}
+
+static void rcu_process_callbacks(struct softirq_action *unused)
+{
+       __rcu_process_callbacks(&rcu_sched_ctrlblk);
+       __rcu_process_callbacks(&rcu_bh_ctrlblk);
+}
+
+/*
+ * Wait for a grace period to elapse.  But it is illegal to invoke
+ * synchronize_sched() from within an RCU read-side critical section.
+ * Therefore, any legal call to synchronize_sched() is a quiescent
+ * state, and so on a UP system, synchronize_sched() need do nothing.
+ * Ditto for synchronize_rcu_bh().  (But Lai Jiangshan points out the
+ * benefits of doing might_sleep() to reduce latency.)
+ *
+ * Cool, huh?  (Due to Josh Triplett.)
+ *
+ * But we want to make this a static inline later.  The cond_resched()
+ * currently makes this problematic.
+ */
+void synchronize_sched(void)
+{
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_sched() in RCU read-side critical section");
+       cond_resched();
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
+/*
+ * Helper function for call_rcu() and call_rcu_bh().
+ */
+static void __call_rcu(struct rcu_head *head,
+                      void (*func)(struct rcu_head *rcu),
+                      struct rcu_ctrlblk *rcp)
+{
+       unsigned long flags;
+
+       debug_rcu_head_queue(head);
+       head->func = func;
+       head->next = NULL;
+
+       local_irq_save(flags);
+       *rcp->curtail = head;
+       rcp->curtail = &head->next;
+       RCU_TRACE(rcp->qlen++);
+       local_irq_restore(flags);
+}
+
+/*
+ * Post an RCU callback to be invoked after the end of an RCU-sched grace
+ * period.  But since we have but one CPU, that would be after any
+ * quiescent state.
+ */
+void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_sched_ctrlblk);
+}
+EXPORT_SYMBOL_GPL(call_rcu_sched);
+
+/*
+ * Post an RCU bottom-half callback to be invoked after any subsequent
+ * quiescent state.
+ */
+void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_bh_ctrlblk);
+}
+EXPORT_SYMBOL_GPL(call_rcu_bh);
+
+void rcu_init(void)
+{
+       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+}
diff --git a/kernel/rcu/tiny_plugin.h b/kernel/rcu/tiny_plugin.h
new file mode 100644 (file)
index 0000000..280d06c
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition
+ * Internal non-public definitions that provide either classic
+ * or preemptible semantics.
+ *
+ * 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) 2010 Linaro
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+/* Global control variables for rcupdate callback mechanism. */
+struct rcu_ctrlblk {
+       struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
+       struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
+       struct rcu_head **curtail;      /* ->next pointer of last CB. */
+       RCU_TRACE(long qlen);           /* Number of pending CBs. */
+       RCU_TRACE(unsigned long gp_start); /* Start time for stalls. */
+       RCU_TRACE(unsigned long ticks_this_gp); /* Statistic for stalls. */
+       RCU_TRACE(unsigned long jiffies_stall); /* Jiffies at next stall. */
+       RCU_TRACE(const char *name);    /* Name of RCU type. */
+};
+
+/* Definition for rcupdate control block. */
+static struct rcu_ctrlblk rcu_sched_ctrlblk = {
+       .donetail       = &rcu_sched_ctrlblk.rcucblist,
+       .curtail        = &rcu_sched_ctrlblk.rcucblist,
+       RCU_TRACE(.name = "rcu_sched")
+};
+
+static struct rcu_ctrlblk rcu_bh_ctrlblk = {
+       .donetail       = &rcu_bh_ctrlblk.rcucblist,
+       .curtail        = &rcu_bh_ctrlblk.rcucblist,
+       RCU_TRACE(.name = "rcu_bh")
+};
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#include <linux/kernel_stat.h>
+
+int rcu_scheduler_active __read_mostly;
+EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+
+/*
+ * During boot, we forgive RCU lockdep issues.  After this function is
+ * invoked, we start taking RCU lockdep issues seriously.
+ */
+void __init rcu_scheduler_starting(void)
+{
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+#ifdef CONFIG_RCU_TRACE
+
+static void rcu_trace_sub_qlen(struct rcu_ctrlblk *rcp, int n)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       rcp->qlen -= n;
+       local_irq_restore(flags);
+}
+
+/*
+ * Dump statistics for TINY_RCU, such as they are.
+ */
+static int show_tiny_stats(struct seq_file *m, void *unused)
+{
+       seq_printf(m, "rcu_sched: qlen: %ld\n", rcu_sched_ctrlblk.qlen);
+       seq_printf(m, "rcu_bh: qlen: %ld\n", rcu_bh_ctrlblk.qlen);
+       return 0;
+}
+
+static int show_tiny_stats_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_tiny_stats, NULL);
+}
+
+static const struct file_operations show_tiny_stats_fops = {
+       .owner = THIS_MODULE,
+       .open = show_tiny_stats_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static struct dentry *rcudir;
+
+static int __init rcutiny_trace_init(void)
+{
+       struct dentry *retval;
+
+       rcudir = debugfs_create_dir("rcu", NULL);
+       if (!rcudir)
+               goto free_out;
+       retval = debugfs_create_file("rcudata", 0444, rcudir,
+                                    NULL, &show_tiny_stats_fops);
+       if (!retval)
+               goto free_out;
+       return 0;
+free_out:
+       debugfs_remove_recursive(rcudir);
+       return 1;
+}
+
+static void __exit rcutiny_trace_cleanup(void)
+{
+       debugfs_remove_recursive(rcudir);
+}
+
+module_init(rcutiny_trace_init);
+module_exit(rcutiny_trace_cleanup);
+
+MODULE_AUTHOR("Paul E. McKenney");
+MODULE_DESCRIPTION("Read-Copy Update tracing for tiny implementation");
+MODULE_LICENSE("GPL");
+
+static void check_cpu_stall(struct rcu_ctrlblk *rcp)
+{
+       unsigned long j;
+       unsigned long js;
+
+       if (rcu_cpu_stall_suppress)
+               return;
+       rcp->ticks_this_gp++;
+       j = jiffies;
+       js = rcp->jiffies_stall;
+       if (*rcp->curtail && ULONG_CMP_GE(j, js)) {
+               pr_err("INFO: %s stall on CPU (%lu ticks this GP) idle=%llx (t=%lu jiffies q=%ld)\n",
+                      rcp->name, rcp->ticks_this_gp, rcu_dynticks_nesting,
+                      jiffies - rcp->gp_start, rcp->qlen);
+               dump_stack();
+       }
+       if (*rcp->curtail && ULONG_CMP_GE(j, js))
+               rcp->jiffies_stall = jiffies +
+                       3 * rcu_jiffies_till_stall_check() + 3;
+       else if (ULONG_CMP_GE(j, js))
+               rcp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check();
+}
+
+static void reset_cpu_stall_ticks(struct rcu_ctrlblk *rcp)
+{
+       rcp->ticks_this_gp = 0;
+       rcp->gp_start = jiffies;
+       rcp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check();
+}
+
+static void check_cpu_stalls(void)
+{
+       RCU_TRACE(check_cpu_stall(&rcu_bh_ctrlblk));
+       RCU_TRACE(check_cpu_stall(&rcu_sched_ctrlblk));
+}
+
+#endif /* #ifdef CONFIG_RCU_TRACE */
diff --git a/kernel/rcu/torture.c b/kernel/rcu/torture.c
new file mode 100644 (file)
index 0000000..3929cd4
--- /dev/null
@@ -0,0 +1,2145 @@
+/*
+ * Read-Copy Update module-based torture test facility
+ *
+ * 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) IBM Corporation, 2005, 2006
+ *
+ * Authors: Paul E. McKenney <paulmck@us.ibm.com>
+ *       Josh Triplett <josh@freedesktop.org>
+ *
+ * See also:  Documentation/RCU/torture.txt
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/rcupdate.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/atomic.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/freezer.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/stat.h>
+#include <linux/srcu.h>
+#include <linux/slab.h>
+#include <linux/trace_clock.h>
+#include <asm/byteorder.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@freedesktop.org>");
+
+MODULE_ALIAS("rcutorture");
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "rcutorture."
+
+static int fqs_duration;
+module_param(fqs_duration, int, 0444);
+MODULE_PARM_DESC(fqs_duration, "Duration of fqs bursts (us), 0 to disable");
+static int fqs_holdoff;
+module_param(fqs_holdoff, int, 0444);
+MODULE_PARM_DESC(fqs_holdoff, "Holdoff time within fqs bursts (us)");
+static int fqs_stutter = 3;
+module_param(fqs_stutter, int, 0444);
+MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)");
+static bool gp_exp;
+module_param(gp_exp, bool, 0444);
+MODULE_PARM_DESC(gp_exp, "Use expedited GP wait primitives");
+static bool gp_normal;
+module_param(gp_normal, bool, 0444);
+MODULE_PARM_DESC(gp_normal, "Use normal (non-expedited) GP wait primitives");
+static int irqreader = 1;
+module_param(irqreader, int, 0444);
+MODULE_PARM_DESC(irqreader, "Allow RCU readers from irq handlers");
+static int n_barrier_cbs;
+module_param(n_barrier_cbs, int, 0444);
+MODULE_PARM_DESC(n_barrier_cbs, "# of callbacks/kthreads for barrier testing");
+static int nfakewriters = 4;
+module_param(nfakewriters, int, 0444);
+MODULE_PARM_DESC(nfakewriters, "Number of RCU fake writer threads");
+static int nreaders = -1;
+module_param(nreaders, int, 0444);
+MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
+static int object_debug;
+module_param(object_debug, int, 0444);
+MODULE_PARM_DESC(object_debug, "Enable debug-object double call_rcu() testing");
+static int onoff_holdoff;
+module_param(onoff_holdoff, int, 0444);
+MODULE_PARM_DESC(onoff_holdoff, "Time after boot before CPU hotplugs (s)");
+static int onoff_interval;
+module_param(onoff_interval, int, 0444);
+MODULE_PARM_DESC(onoff_interval, "Time between CPU hotplugs (s), 0=disable");
+static int shuffle_interval = 3;
+module_param(shuffle_interval, int, 0444);
+MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles");
+static int shutdown_secs;
+module_param(shutdown_secs, int, 0444);
+MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), <= zero to disable.");
+static int stall_cpu;
+module_param(stall_cpu, int, 0444);
+MODULE_PARM_DESC(stall_cpu, "Stall duration (s), zero to disable.");
+static int stall_cpu_holdoff = 10;
+module_param(stall_cpu_holdoff, int, 0444);
+MODULE_PARM_DESC(stall_cpu_holdoff, "Time to wait before starting stall (s).");
+static int stat_interval = 60;
+module_param(stat_interval, int, 0644);
+MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
+static int stutter = 5;
+module_param(stutter, int, 0444);
+MODULE_PARM_DESC(stutter, "Number of seconds to run/halt test");
+static int test_boost = 1;
+module_param(test_boost, int, 0444);
+MODULE_PARM_DESC(test_boost, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
+static int test_boost_duration = 4;
+module_param(test_boost_duration, int, 0444);
+MODULE_PARM_DESC(test_boost_duration, "Duration of each boost test, seconds.");
+static int test_boost_interval = 7;
+module_param(test_boost_interval, int, 0444);
+MODULE_PARM_DESC(test_boost_interval, "Interval between boost tests, seconds.");
+static bool test_no_idle_hz = true;
+module_param(test_no_idle_hz, bool, 0444);
+MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs");
+static char *torture_type = "rcu";
+module_param(torture_type, charp, 0444);
+MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)");
+static bool verbose;
+module_param(verbose, bool, 0444);
+MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
+
+#define TORTURE_FLAG "-torture:"
+#define PRINTK_STRING(s) \
+       do { pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0)
+#define VERBOSE_PRINTK_STRING(s) \
+       do { if (verbose) pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0)
+#define VERBOSE_PRINTK_ERRSTRING(s) \
+       do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0)
+
+static char printk_buf[4096];
+
+static int nrealreaders;
+static struct task_struct *writer_task;
+static struct task_struct **fakewriter_tasks;
+static struct task_struct **reader_tasks;
+static struct task_struct *stats_task;
+static struct task_struct *shuffler_task;
+static struct task_struct *stutter_task;
+static struct task_struct *fqs_task;
+static struct task_struct *boost_tasks[NR_CPUS];
+static struct task_struct *shutdown_task;
+#ifdef CONFIG_HOTPLUG_CPU
+static struct task_struct *onoff_task;
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+static struct task_struct *stall_task;
+static struct task_struct **barrier_cbs_tasks;
+static struct task_struct *barrier_task;
+
+#define RCU_TORTURE_PIPE_LEN 10
+
+struct rcu_torture {
+       struct rcu_head rtort_rcu;
+       int rtort_pipe_count;
+       struct list_head rtort_free;
+       int rtort_mbtest;
+};
+
+static LIST_HEAD(rcu_torture_freelist);
+static struct rcu_torture __rcu *rcu_torture_current;
+static unsigned long rcu_torture_current_version;
+static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
+static DEFINE_SPINLOCK(rcu_torture_lock);
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
+       { 0 };
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
+       { 0 };
+static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
+static atomic_t n_rcu_torture_alloc;
+static atomic_t n_rcu_torture_alloc_fail;
+static atomic_t n_rcu_torture_free;
+static atomic_t n_rcu_torture_mberror;
+static atomic_t n_rcu_torture_error;
+static long n_rcu_torture_barrier_error;
+static long n_rcu_torture_boost_ktrerror;
+static long n_rcu_torture_boost_rterror;
+static long n_rcu_torture_boost_failure;
+static long n_rcu_torture_boosts;
+static long n_rcu_torture_timers;
+static long n_offline_attempts;
+static long n_offline_successes;
+static unsigned long sum_offline;
+static int min_offline = -1;
+static int max_offline;
+static long n_online_attempts;
+static long n_online_successes;
+static unsigned long sum_online;
+static int min_online = -1;
+static int max_online;
+static long n_barrier_attempts;
+static long n_barrier_successes;
+static struct list_head rcu_torture_removed;
+static cpumask_var_t shuffle_tmp_mask;
+
+static int stutter_pause_test;
+
+#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE)
+#define RCUTORTURE_RUNNABLE_INIT 1
+#else
+#define RCUTORTURE_RUNNABLE_INIT 0
+#endif
+int rcutorture_runnable = RCUTORTURE_RUNNABLE_INIT;
+module_param(rcutorture_runnable, int, 0444);
+MODULE_PARM_DESC(rcutorture_runnable, "Start rcutorture at boot");
+
+#if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU)
+#define rcu_can_boost() 1
+#else /* #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */
+#define rcu_can_boost() 0
+#endif /* #else #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */
+
+#ifdef CONFIG_RCU_TRACE
+static u64 notrace rcu_trace_clock_local(void)
+{
+       u64 ts = trace_clock_local();
+       unsigned long __maybe_unused ts_rem = do_div(ts, NSEC_PER_USEC);
+       return ts;
+}
+#else /* #ifdef CONFIG_RCU_TRACE */
+static u64 notrace rcu_trace_clock_local(void)
+{
+       return 0ULL;
+}
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+static unsigned long shutdown_time;    /* jiffies to system shutdown. */
+static unsigned long boost_starttime;  /* jiffies of next boost test start. */
+DEFINE_MUTEX(boost_mutex);             /* protect setting boost_starttime */
+                                       /*  and boost task create/destroy. */
+static atomic_t barrier_cbs_count;     /* Barrier callbacks registered. */
+static bool barrier_phase;             /* Test phase. */
+static atomic_t barrier_cbs_invoked;   /* Barrier callbacks invoked. */
+static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */
+static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
+
+/* Mediate rmmod and system shutdown.  Concurrent rmmod & shutdown illegal! */
+
+#define FULLSTOP_DONTSTOP 0    /* Normal operation. */
+#define FULLSTOP_SHUTDOWN 1    /* System shutdown with rcutorture running. */
+#define FULLSTOP_RMMOD    2    /* Normal rmmod of rcutorture. */
+static int fullstop = FULLSTOP_RMMOD;
+/*
+ * Protect fullstop transitions and spawning of kthreads.
+ */
+static DEFINE_MUTEX(fullstop_mutex);
+
+/* Forward reference. */
+static void rcu_torture_cleanup(void);
+
+/*
+ * Detect and respond to a system shutdown.
+ */
+static int
+rcutorture_shutdown_notify(struct notifier_block *unused1,
+                          unsigned long unused2, void *unused3)
+{
+       mutex_lock(&fullstop_mutex);
+       if (fullstop == FULLSTOP_DONTSTOP)
+               fullstop = FULLSTOP_SHUTDOWN;
+       else
+               pr_warn(/* but going down anyway, so... */
+                      "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
+       mutex_unlock(&fullstop_mutex);
+       return NOTIFY_DONE;
+}
+
+/*
+ * Absorb kthreads into a kernel function that won't return, so that
+ * they won't ever access module text or data again.
+ */
+static void rcutorture_shutdown_absorb(const char *title)
+{
+       if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
+               pr_notice(
+                      "rcutorture thread %s parking due to system shutdown\n",
+                      title);
+               schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
+       }
+}
+
+/*
+ * Allocate an element from the rcu_tortures pool.
+ */
+static struct rcu_torture *
+rcu_torture_alloc(void)
+{
+       struct list_head *p;
+
+       spin_lock_bh(&rcu_torture_lock);
+       if (list_empty(&rcu_torture_freelist)) {
+               atomic_inc(&n_rcu_torture_alloc_fail);
+               spin_unlock_bh(&rcu_torture_lock);
+               return NULL;
+       }
+       atomic_inc(&n_rcu_torture_alloc);
+       p = rcu_torture_freelist.next;
+       list_del_init(p);
+       spin_unlock_bh(&rcu_torture_lock);
+       return container_of(p, struct rcu_torture, rtort_free);
+}
+
+/*
+ * Free an element to the rcu_tortures pool.
+ */
+static void
+rcu_torture_free(struct rcu_torture *p)
+{
+       atomic_inc(&n_rcu_torture_free);
+       spin_lock_bh(&rcu_torture_lock);
+       list_add_tail(&p->rtort_free, &rcu_torture_freelist);
+       spin_unlock_bh(&rcu_torture_lock);
+}
+
+struct rcu_random_state {
+       unsigned long rrs_state;
+       long rrs_count;
+};
+
+#define RCU_RANDOM_MULT 39916801  /* prime */
+#define RCU_RANDOM_ADD 479001701 /* prime */
+#define RCU_RANDOM_REFRESH 10000
+
+#define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 }
+
+/*
+ * Crude but fast random-number generator.  Uses a linear congruential
+ * generator, with occasional help from cpu_clock().
+ */
+static unsigned long
+rcu_random(struct rcu_random_state *rrsp)
+{
+       if (--rrsp->rrs_count < 0) {
+               rrsp->rrs_state += (unsigned long)local_clock();
+               rrsp->rrs_count = RCU_RANDOM_REFRESH;
+       }
+       rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
+       return swahw32(rrsp->rrs_state);
+}
+
+static void
+rcu_stutter_wait(const char *title)
+{
+       while (stutter_pause_test || !rcutorture_runnable) {
+               if (rcutorture_runnable)
+                       schedule_timeout_interruptible(1);
+               else
+                       schedule_timeout_interruptible(round_jiffies_relative(HZ));
+               rcutorture_shutdown_absorb(title);
+       }
+}
+
+/*
+ * Operations vector for selecting different types of tests.
+ */
+
+struct rcu_torture_ops {
+       void (*init)(void);
+       int (*readlock)(void);
+       void (*read_delay)(struct rcu_random_state *rrsp);
+       void (*readunlock)(int idx);
+       int (*completed)(void);
+       void (*deferred_free)(struct rcu_torture *p);
+       void (*sync)(void);
+       void (*exp_sync)(void);
+       void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
+       void (*cb_barrier)(void);
+       void (*fqs)(void);
+       int (*stats)(char *page);
+       int irq_capable;
+       int can_boost;
+       const char *name;
+};
+
+static struct rcu_torture_ops *cur_ops;
+
+/*
+ * Definitions for rcu torture testing.
+ */
+
+static int rcu_torture_read_lock(void) __acquires(RCU)
+{
+       rcu_read_lock();
+       return 0;
+}
+
+static void rcu_read_delay(struct rcu_random_state *rrsp)
+{
+       const unsigned long shortdelay_us = 200;
+       const unsigned long longdelay_ms = 50;
+
+       /* We want a short delay sometimes to make a reader delay the grace
+        * period, and we want a long delay occasionally to trigger
+        * force_quiescent_state. */
+
+       if (!(rcu_random(rrsp) % (nrealreaders * 2000 * longdelay_ms)))
+               mdelay(longdelay_ms);
+       if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us)))
+               udelay(shortdelay_us);
+#ifdef CONFIG_PREEMPT
+       if (!preempt_count() && !(rcu_random(rrsp) % (nrealreaders * 20000)))
+               preempt_schedule();  /* No QS if preempt_disable() in effect */
+#endif
+}
+
+static void rcu_torture_read_unlock(int idx) __releases(RCU)
+{
+       rcu_read_unlock();
+}
+
+static int rcu_torture_completed(void)
+{
+       return rcu_batches_completed();
+}
+
+static void
+rcu_torture_cb(struct rcu_head *p)
+{
+       int i;
+       struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
+
+       if (fullstop != FULLSTOP_DONTSTOP) {
+               /* Test is ending, just drop callbacks on the floor. */
+               /* The next initialization will pick up the pieces. */
+               return;
+       }
+       i = rp->rtort_pipe_count;
+       if (i > RCU_TORTURE_PIPE_LEN)
+               i = RCU_TORTURE_PIPE_LEN;
+       atomic_inc(&rcu_torture_wcount[i]);
+       if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
+               rp->rtort_mbtest = 0;
+               rcu_torture_free(rp);
+       } else {
+               cur_ops->deferred_free(rp);
+       }
+}
+
+static int rcu_no_completed(void)
+{
+       return 0;
+}
+
+static void rcu_torture_deferred_free(struct rcu_torture *p)
+{
+       call_rcu(&p->rtort_rcu, rcu_torture_cb);
+}
+
+static void rcu_sync_torture_init(void)
+{
+       INIT_LIST_HEAD(&rcu_torture_removed);
+}
+
+static struct rcu_torture_ops rcu_ops = {
+       .init           = rcu_sync_torture_init,
+       .readlock       = rcu_torture_read_lock,
+       .read_delay     = rcu_read_delay,
+       .readunlock     = rcu_torture_read_unlock,
+       .completed      = rcu_torture_completed,
+       .deferred_free  = rcu_torture_deferred_free,
+       .sync           = synchronize_rcu,
+       .exp_sync       = synchronize_rcu_expedited,
+       .call           = call_rcu,
+       .cb_barrier     = rcu_barrier,
+       .fqs            = rcu_force_quiescent_state,
+       .stats          = NULL,
+       .irq_capable    = 1,
+       .can_boost      = rcu_can_boost(),
+       .name           = "rcu"
+};
+
+/*
+ * Definitions for rcu_bh torture testing.
+ */
+
+static int rcu_bh_torture_read_lock(void) __acquires(RCU_BH)
+{
+       rcu_read_lock_bh();
+       return 0;
+}
+
+static void rcu_bh_torture_read_unlock(int idx) __releases(RCU_BH)
+{
+       rcu_read_unlock_bh();
+}
+
+static int rcu_bh_torture_completed(void)
+{
+       return rcu_batches_completed_bh();
+}
+
+static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
+{
+       call_rcu_bh(&p->rtort_rcu, rcu_torture_cb);
+}
+
+static struct rcu_torture_ops rcu_bh_ops = {
+       .init           = rcu_sync_torture_init,
+       .readlock       = rcu_bh_torture_read_lock,
+       .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
+       .readunlock     = rcu_bh_torture_read_unlock,
+       .completed      = rcu_bh_torture_completed,
+       .deferred_free  = rcu_bh_torture_deferred_free,
+       .sync           = synchronize_rcu_bh,
+       .exp_sync       = synchronize_rcu_bh_expedited,
+       .call           = call_rcu_bh,
+       .cb_barrier     = rcu_barrier_bh,
+       .fqs            = rcu_bh_force_quiescent_state,
+       .stats          = NULL,
+       .irq_capable    = 1,
+       .name           = "rcu_bh"
+};
+
+/*
+ * Definitions for srcu torture testing.
+ */
+
+DEFINE_STATIC_SRCU(srcu_ctl);
+
+static int srcu_torture_read_lock(void) __acquires(&srcu_ctl)
+{
+       return srcu_read_lock(&srcu_ctl);
+}
+
+static void srcu_read_delay(struct rcu_random_state *rrsp)
+{
+       long delay;
+       const long uspertick = 1000000 / HZ;
+       const long longdelay = 10;
+
+       /* We want there to be long-running readers, but not all the time. */
+
+       delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick);
+       if (!delay)
+               schedule_timeout_interruptible(longdelay);
+       else
+               rcu_read_delay(rrsp);
+}
+
+static void srcu_torture_read_unlock(int idx) __releases(&srcu_ctl)
+{
+       srcu_read_unlock(&srcu_ctl, idx);
+}
+
+static int srcu_torture_completed(void)
+{
+       return srcu_batches_completed(&srcu_ctl);
+}
+
+static void srcu_torture_deferred_free(struct rcu_torture *rp)
+{
+       call_srcu(&srcu_ctl, &rp->rtort_rcu, rcu_torture_cb);
+}
+
+static void srcu_torture_synchronize(void)
+{
+       synchronize_srcu(&srcu_ctl);
+}
+
+static void srcu_torture_call(struct rcu_head *head,
+                             void (*func)(struct rcu_head *head))
+{
+       call_srcu(&srcu_ctl, head, func);
+}
+
+static void srcu_torture_barrier(void)
+{
+       srcu_barrier(&srcu_ctl);
+}
+
+static int srcu_torture_stats(char *page)
+{
+       int cnt = 0;
+       int cpu;
+       int idx = srcu_ctl.completed & 0x1;
+
+       cnt += sprintf(&page[cnt], "%s%s per-CPU(idx=%d):",
+                      torture_type, TORTURE_FLAG, idx);
+       for_each_possible_cpu(cpu) {
+               cnt += sprintf(&page[cnt], " %d(%lu,%lu)", cpu,
+                              per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx],
+                              per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]);
+       }
+       cnt += sprintf(&page[cnt], "\n");
+       return cnt;
+}
+
+static void srcu_torture_synchronize_expedited(void)
+{
+       synchronize_srcu_expedited(&srcu_ctl);
+}
+
+static struct rcu_torture_ops srcu_ops = {
+       .init           = rcu_sync_torture_init,
+       .readlock       = srcu_torture_read_lock,
+       .read_delay     = srcu_read_delay,
+       .readunlock     = srcu_torture_read_unlock,
+       .completed      = srcu_torture_completed,
+       .deferred_free  = srcu_torture_deferred_free,
+       .sync           = srcu_torture_synchronize,
+       .exp_sync       = srcu_torture_synchronize_expedited,
+       .call           = srcu_torture_call,
+       .cb_barrier     = srcu_torture_barrier,
+       .stats          = srcu_torture_stats,
+       .name           = "srcu"
+};
+
+/*
+ * Definitions for sched torture testing.
+ */
+
+static int sched_torture_read_lock(void)
+{
+       preempt_disable();
+       return 0;
+}
+
+static void sched_torture_read_unlock(int idx)
+{
+       preempt_enable();
+}
+
+static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
+{
+       call_rcu_sched(&p->rtort_rcu, rcu_torture_cb);
+}
+
+static struct rcu_torture_ops sched_ops = {
+       .init           = rcu_sync_torture_init,
+       .readlock       = sched_torture_read_lock,
+       .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
+       .readunlock     = sched_torture_read_unlock,
+       .completed      = rcu_no_completed,
+       .deferred_free  = rcu_sched_torture_deferred_free,
+       .sync           = synchronize_sched,
+       .exp_sync       = synchronize_sched_expedited,
+       .call           = call_rcu_sched,
+       .cb_barrier     = rcu_barrier_sched,
+       .fqs            = rcu_sched_force_quiescent_state,
+       .stats          = NULL,
+       .irq_capable    = 1,
+       .name           = "sched"
+};
+
+/*
+ * RCU torture priority-boost testing.  Runs one real-time thread per
+ * CPU for moderate bursts, repeatedly registering RCU callbacks and
+ * spinning waiting for them to be invoked.  If a given callback takes
+ * too long to be invoked, we assume that priority inversion has occurred.
+ */
+
+struct rcu_boost_inflight {
+       struct rcu_head rcu;
+       int inflight;
+};
+
+static void rcu_torture_boost_cb(struct rcu_head *head)
+{
+       struct rcu_boost_inflight *rbip =
+               container_of(head, struct rcu_boost_inflight, rcu);
+
+       smp_mb(); /* Ensure RCU-core accesses precede clearing ->inflight */
+       rbip->inflight = 0;
+}
+
+static int rcu_torture_boost(void *arg)
+{
+       unsigned long call_rcu_time;
+       unsigned long endtime;
+       unsigned long oldstarttime;
+       struct rcu_boost_inflight rbi = { .inflight = 0 };
+       struct sched_param sp;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_boost started");
+
+       /* Set real-time priority. */
+       sp.sched_priority = 1;
+       if (sched_setscheduler(current, SCHED_FIFO, &sp) < 0) {
+               VERBOSE_PRINTK_STRING("rcu_torture_boost RT prio failed!");
+               n_rcu_torture_boost_rterror++;
+       }
+
+       init_rcu_head_on_stack(&rbi.rcu);
+       /* Each pass through the following loop does one boost-test cycle. */
+       do {
+               /* Wait for the next test interval. */
+               oldstarttime = boost_starttime;
+               while (ULONG_CMP_LT(jiffies, oldstarttime)) {
+                       schedule_timeout_interruptible(oldstarttime - jiffies);
+                       rcu_stutter_wait("rcu_torture_boost");
+                       if (kthread_should_stop() ||
+                           fullstop != FULLSTOP_DONTSTOP)
+                               goto checkwait;
+               }
+
+               /* Do one boost-test interval. */
+               endtime = oldstarttime + test_boost_duration * HZ;
+               call_rcu_time = jiffies;
+               while (ULONG_CMP_LT(jiffies, endtime)) {
+                       /* If we don't have a callback in flight, post one. */
+                       if (!rbi.inflight) {
+                               smp_mb(); /* RCU core before ->inflight = 1. */
+                               rbi.inflight = 1;
+                               call_rcu(&rbi.rcu, rcu_torture_boost_cb);
+                               if (jiffies - call_rcu_time >
+                                        test_boost_duration * HZ - HZ / 2) {
+                                       VERBOSE_PRINTK_STRING("rcu_torture_boost boosting failed");
+                                       n_rcu_torture_boost_failure++;
+                               }
+                               call_rcu_time = jiffies;
+                       }
+                       cond_resched();
+                       rcu_stutter_wait("rcu_torture_boost");
+                       if (kthread_should_stop() ||
+                           fullstop != FULLSTOP_DONTSTOP)
+                               goto checkwait;
+               }
+
+               /*
+                * Set the start time of the next test interval.
+                * Yes, this is vulnerable to long delays, but such
+                * delays simply cause a false negative for the next
+                * interval.  Besides, we are running at RT priority,
+                * so delays should be relatively rare.
+                */
+               while (oldstarttime == boost_starttime &&
+                      !kthread_should_stop()) {
+                       if (mutex_trylock(&boost_mutex)) {
+                               boost_starttime = jiffies +
+                                                 test_boost_interval * HZ;
+                               n_rcu_torture_boosts++;
+                               mutex_unlock(&boost_mutex);
+                               break;
+                       }
+                       schedule_timeout_uninterruptible(1);
+               }
+
+               /* Go do the stutter. */
+checkwait:     rcu_stutter_wait("rcu_torture_boost");
+       } while (!kthread_should_stop() && fullstop  == FULLSTOP_DONTSTOP);
+
+       /* Clean up and exit. */
+       VERBOSE_PRINTK_STRING("rcu_torture_boost task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_boost");
+       while (!kthread_should_stop() || rbi.inflight)
+               schedule_timeout_uninterruptible(1);
+       smp_mb(); /* order accesses to ->inflight before stack-frame death. */
+       destroy_rcu_head_on_stack(&rbi.rcu);
+       return 0;
+}
+
+/*
+ * RCU torture force-quiescent-state kthread.  Repeatedly induces
+ * bursts of calls to force_quiescent_state(), increasing the probability
+ * of occurrence of some important types of race conditions.
+ */
+static int
+rcu_torture_fqs(void *arg)
+{
+       unsigned long fqs_resume_time;
+       int fqs_burst_remaining;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_fqs task started");
+       do {
+               fqs_resume_time = jiffies + fqs_stutter * HZ;
+               while (ULONG_CMP_LT(jiffies, fqs_resume_time) &&
+                      !kthread_should_stop()) {
+                       schedule_timeout_interruptible(1);
+               }
+               fqs_burst_remaining = fqs_duration;
+               while (fqs_burst_remaining > 0 &&
+                      !kthread_should_stop()) {
+                       cur_ops->fqs();
+                       udelay(fqs_holdoff);
+                       fqs_burst_remaining -= fqs_holdoff;
+               }
+               rcu_stutter_wait("rcu_torture_fqs");
+       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
+       VERBOSE_PRINTK_STRING("rcu_torture_fqs task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_fqs");
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
+/*
+ * RCU torture writer kthread.  Repeatedly substitutes a new structure
+ * for that pointed to by rcu_torture_current, freeing the old structure
+ * after a series of grace periods (the "pipeline").
+ */
+static int
+rcu_torture_writer(void *arg)
+{
+       bool exp;
+       int i;
+       struct rcu_torture *rp;
+       struct rcu_torture *rp1;
+       struct rcu_torture *old_rp;
+       static DEFINE_RCU_RANDOM(rand);
+
+       VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
+       set_user_nice(current, 19);
+
+       do {
+               schedule_timeout_uninterruptible(1);
+               rp = rcu_torture_alloc();
+               if (rp == NULL)
+                       continue;
+               rp->rtort_pipe_count = 0;
+               udelay(rcu_random(&rand) & 0x3ff);
+               old_rp = rcu_dereference_check(rcu_torture_current,
+                                              current == writer_task);
+               rp->rtort_mbtest = 1;
+               rcu_assign_pointer(rcu_torture_current, rp);
+               smp_wmb(); /* Mods to old_rp must follow rcu_assign_pointer() */
+               if (old_rp) {
+                       i = old_rp->rtort_pipe_count;
+                       if (i > RCU_TORTURE_PIPE_LEN)
+                               i = RCU_TORTURE_PIPE_LEN;
+                       atomic_inc(&rcu_torture_wcount[i]);
+                       old_rp->rtort_pipe_count++;
+                       if (gp_normal == gp_exp)
+                               exp = !!(rcu_random(&rand) & 0x80);
+                       else
+                               exp = gp_exp;
+                       if (!exp) {
+                               cur_ops->deferred_free(old_rp);
+                       } else {
+                               cur_ops->exp_sync();
+                               list_add(&old_rp->rtort_free,
+                                        &rcu_torture_removed);
+                               list_for_each_entry_safe(rp, rp1,
+                                                        &rcu_torture_removed,
+                                                        rtort_free) {
+                                       i = rp->rtort_pipe_count;
+                                       if (i > RCU_TORTURE_PIPE_LEN)
+                                               i = RCU_TORTURE_PIPE_LEN;
+                                       atomic_inc(&rcu_torture_wcount[i]);
+                                       if (++rp->rtort_pipe_count >=
+                                           RCU_TORTURE_PIPE_LEN) {
+                                               rp->rtort_mbtest = 0;
+                                               list_del(&rp->rtort_free);
+                                               rcu_torture_free(rp);
+                                       }
+                                }
+                       }
+               }
+               rcutorture_record_progress(++rcu_torture_current_version);
+               rcu_stutter_wait("rcu_torture_writer");
+       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
+       VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_writer");
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
+/*
+ * RCU torture fake writer kthread.  Repeatedly calls sync, with a random
+ * delay between calls.
+ */
+static int
+rcu_torture_fakewriter(void *arg)
+{
+       DEFINE_RCU_RANDOM(rand);
+
+       VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
+       set_user_nice(current, 19);
+
+       do {
+               schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
+               udelay(rcu_random(&rand) & 0x3ff);
+               if (cur_ops->cb_barrier != NULL &&
+                   rcu_random(&rand) % (nfakewriters * 8) == 0) {
+                       cur_ops->cb_barrier();
+               } else if (gp_normal == gp_exp) {
+                       if (rcu_random(&rand) & 0x80)
+                               cur_ops->sync();
+                       else
+                               cur_ops->exp_sync();
+               } else if (gp_normal) {
+                       cur_ops->sync();
+               } else {
+                       cur_ops->exp_sync();
+               }
+               rcu_stutter_wait("rcu_torture_fakewriter");
+       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
+
+       VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_fakewriter");
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
+void rcutorture_trace_dump(void)
+{
+       static atomic_t beenhere = ATOMIC_INIT(0);
+
+       if (atomic_read(&beenhere))
+               return;
+       if (atomic_xchg(&beenhere, 1) != 0)
+               return;
+       ftrace_dump(DUMP_ALL);
+}
+
+/*
+ * RCU torture reader from timer handler.  Dereferences rcu_torture_current,
+ * incrementing the corresponding element of the pipeline array.  The
+ * counter in the element should never be greater than 1, otherwise, the
+ * RCU implementation is broken.
+ */
+static void rcu_torture_timer(unsigned long unused)
+{
+       int idx;
+       int completed;
+       int completed_end;
+       static DEFINE_RCU_RANDOM(rand);
+       static DEFINE_SPINLOCK(rand_lock);
+       struct rcu_torture *p;
+       int pipe_count;
+       unsigned long long ts;
+
+       idx = cur_ops->readlock();
+       completed = cur_ops->completed();
+       ts = rcu_trace_clock_local();
+       p = rcu_dereference_check(rcu_torture_current,
+                                 rcu_read_lock_bh_held() ||
+                                 rcu_read_lock_sched_held() ||
+                                 srcu_read_lock_held(&srcu_ctl));
+       if (p == NULL) {
+               /* Leave because rcu_torture_writer is not yet underway */
+               cur_ops->readunlock(idx);
+               return;
+       }
+       if (p->rtort_mbtest == 0)
+               atomic_inc(&n_rcu_torture_mberror);
+       spin_lock(&rand_lock);
+       cur_ops->read_delay(&rand);
+       n_rcu_torture_timers++;
+       spin_unlock(&rand_lock);
+       preempt_disable();
+       pipe_count = p->rtort_pipe_count;
+       if (pipe_count > RCU_TORTURE_PIPE_LEN) {
+               /* Should not happen, but... */
+               pipe_count = RCU_TORTURE_PIPE_LEN;
+       }
+       completed_end = cur_ops->completed();
+       if (pipe_count > 1) {
+               do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, ts,
+                                         completed, completed_end);
+               rcutorture_trace_dump();
+       }
+       __this_cpu_inc(rcu_torture_count[pipe_count]);
+       completed = completed_end - completed;
+       if (completed > RCU_TORTURE_PIPE_LEN) {
+               /* Should not happen, but... */
+               completed = RCU_TORTURE_PIPE_LEN;
+       }
+       __this_cpu_inc(rcu_torture_batch[completed]);
+       preempt_enable();
+       cur_ops->readunlock(idx);
+}
+
+/*
+ * RCU torture reader kthread.  Repeatedly dereferences rcu_torture_current,
+ * incrementing the corresponding element of the pipeline array.  The
+ * counter in the element should never be greater than 1, otherwise, the
+ * RCU implementation is broken.
+ */
+static int
+rcu_torture_reader(void *arg)
+{
+       int completed;
+       int completed_end;
+       int idx;
+       DEFINE_RCU_RANDOM(rand);
+       struct rcu_torture *p;
+       int pipe_count;
+       struct timer_list t;
+       unsigned long long ts;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
+       set_user_nice(current, 19);
+       if (irqreader && cur_ops->irq_capable)
+               setup_timer_on_stack(&t, rcu_torture_timer, 0);
+
+       do {
+               if (irqreader && cur_ops->irq_capable) {
+                       if (!timer_pending(&t))
+                               mod_timer(&t, jiffies + 1);
+               }
+               idx = cur_ops->readlock();
+               completed = cur_ops->completed();
+               ts = rcu_trace_clock_local();
+               p = rcu_dereference_check(rcu_torture_current,
+                                         rcu_read_lock_bh_held() ||
+                                         rcu_read_lock_sched_held() ||
+                                         srcu_read_lock_held(&srcu_ctl));
+               if (p == NULL) {
+                       /* Wait for rcu_torture_writer to get underway */
+                       cur_ops->readunlock(idx);
+                       schedule_timeout_interruptible(HZ);
+                       continue;
+               }
+               if (p->rtort_mbtest == 0)
+                       atomic_inc(&n_rcu_torture_mberror);
+               cur_ops->read_delay(&rand);
+               preempt_disable();
+               pipe_count = p->rtort_pipe_count;
+               if (pipe_count > RCU_TORTURE_PIPE_LEN) {
+                       /* Should not happen, but... */
+                       pipe_count = RCU_TORTURE_PIPE_LEN;
+               }
+               completed_end = cur_ops->completed();
+               if (pipe_count > 1) {
+                       do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu,
+                                                 ts, completed, completed_end);
+                       rcutorture_trace_dump();
+               }
+               __this_cpu_inc(rcu_torture_count[pipe_count]);
+               completed = completed_end - completed;
+               if (completed > RCU_TORTURE_PIPE_LEN) {
+                       /* Should not happen, but... */
+                       completed = RCU_TORTURE_PIPE_LEN;
+               }
+               __this_cpu_inc(rcu_torture_batch[completed]);
+               preempt_enable();
+               cur_ops->readunlock(idx);
+               schedule();
+               rcu_stutter_wait("rcu_torture_reader");
+       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
+       VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_reader");
+       if (irqreader && cur_ops->irq_capable)
+               del_timer_sync(&t);
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
+/*
+ * Create an RCU-torture statistics message in the specified buffer.
+ */
+static int
+rcu_torture_printk(char *page)
+{
+       int cnt = 0;
+       int cpu;
+       int i;
+       long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+       long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+
+       for_each_possible_cpu(cpu) {
+               for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+                       pipesummary[i] += per_cpu(rcu_torture_count, cpu)[i];
+                       batchsummary[i] += per_cpu(rcu_torture_batch, cpu)[i];
+               }
+       }
+       for (i = RCU_TORTURE_PIPE_LEN - 1; i >= 0; i--) {
+               if (pipesummary[i] != 0)
+                       break;
+       }
+       cnt += sprintf(&page[cnt], "%s%s ", torture_type, TORTURE_FLAG);
+       cnt += sprintf(&page[cnt],
+                      "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d ",
+                      rcu_torture_current,
+                      rcu_torture_current_version,
+                      list_empty(&rcu_torture_freelist),
+                      atomic_read(&n_rcu_torture_alloc),
+                      atomic_read(&n_rcu_torture_alloc_fail),
+                      atomic_read(&n_rcu_torture_free));
+       cnt += sprintf(&page[cnt], "rtmbe: %d rtbke: %ld rtbre: %ld ",
+                      atomic_read(&n_rcu_torture_mberror),
+                      n_rcu_torture_boost_ktrerror,
+                      n_rcu_torture_boost_rterror);
+       cnt += sprintf(&page[cnt], "rtbf: %ld rtb: %ld nt: %ld ",
+                      n_rcu_torture_boost_failure,
+                      n_rcu_torture_boosts,
+                      n_rcu_torture_timers);
+       cnt += sprintf(&page[cnt],
+                      "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ",
+                      n_online_successes, n_online_attempts,
+                      n_offline_successes, n_offline_attempts,
+                      min_online, max_online,
+                      min_offline, max_offline,
+                      sum_online, sum_offline, HZ);
+       cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld",
+                      n_barrier_successes,
+                      n_barrier_attempts,
+                      n_rcu_torture_barrier_error);
+       cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG);
+       if (atomic_read(&n_rcu_torture_mberror) != 0 ||
+           n_rcu_torture_barrier_error != 0 ||
+           n_rcu_torture_boost_ktrerror != 0 ||
+           n_rcu_torture_boost_rterror != 0 ||
+           n_rcu_torture_boost_failure != 0 ||
+           i > 1) {
+               cnt += sprintf(&page[cnt], "!!! ");
+               atomic_inc(&n_rcu_torture_error);
+               WARN_ON_ONCE(1);
+       }
+       cnt += sprintf(&page[cnt], "Reader Pipe: ");
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+               cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
+       cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG);
+       cnt += sprintf(&page[cnt], "Reader Batch: ");
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+               cnt += sprintf(&page[cnt], " %ld", batchsummary[i]);
+       cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG);
+       cnt += sprintf(&page[cnt], "Free-Block Circulation: ");
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+               cnt += sprintf(&page[cnt], " %d",
+                              atomic_read(&rcu_torture_wcount[i]));
+       }
+       cnt += sprintf(&page[cnt], "\n");
+       if (cur_ops->stats)
+               cnt += cur_ops->stats(&page[cnt]);
+       return cnt;
+}
+
+/*
+ * Print torture statistics.  Caller must ensure that there is only
+ * one call to this function at a given time!!!  This is normally
+ * accomplished by relying on the module system to only have one copy
+ * of the module loaded, and then by giving the rcu_torture_stats
+ * kthread full control (or the init/cleanup functions when rcu_torture_stats
+ * thread is not running).
+ */
+static void
+rcu_torture_stats_print(void)
+{
+       int cnt;
+
+       cnt = rcu_torture_printk(printk_buf);
+       pr_alert("%s", printk_buf);
+}
+
+/*
+ * Periodically prints torture statistics, if periodic statistics printing
+ * was specified via the stat_interval module parameter.
+ *
+ * No need to worry about fullstop here, since this one doesn't reference
+ * volatile state or register callbacks.
+ */
+static int
+rcu_torture_stats(void *arg)
+{
+       VERBOSE_PRINTK_STRING("rcu_torture_stats task started");
+       do {
+               schedule_timeout_interruptible(stat_interval * HZ);
+               rcu_torture_stats_print();
+               rcutorture_shutdown_absorb("rcu_torture_stats");
+       } while (!kthread_should_stop());
+       VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
+       return 0;
+}
+
+static int rcu_idle_cpu;       /* Force all torture tasks off this CPU */
+
+/* Shuffle tasks such that we allow @rcu_idle_cpu to become idle. A special case
+ * is when @rcu_idle_cpu = -1, when we allow the tasks to run on all CPUs.
+ */
+static void rcu_torture_shuffle_tasks(void)
+{
+       int i;
+
+       cpumask_setall(shuffle_tmp_mask);
+       get_online_cpus();
+
+       /* No point in shuffling if there is only one online CPU (ex: UP) */
+       if (num_online_cpus() == 1) {
+               put_online_cpus();
+               return;
+       }
+
+       if (rcu_idle_cpu != -1)
+               cpumask_clear_cpu(rcu_idle_cpu, shuffle_tmp_mask);
+
+       set_cpus_allowed_ptr(current, shuffle_tmp_mask);
+
+       if (reader_tasks) {
+               for (i = 0; i < nrealreaders; i++)
+                       if (reader_tasks[i])
+                               set_cpus_allowed_ptr(reader_tasks[i],
+                                                    shuffle_tmp_mask);
+       }
+       if (fakewriter_tasks) {
+               for (i = 0; i < nfakewriters; i++)
+                       if (fakewriter_tasks[i])
+                               set_cpus_allowed_ptr(fakewriter_tasks[i],
+                                                    shuffle_tmp_mask);
+       }
+       if (writer_task)
+               set_cpus_allowed_ptr(writer_task, shuffle_tmp_mask);
+       if (stats_task)
+               set_cpus_allowed_ptr(stats_task, shuffle_tmp_mask);
+       if (stutter_task)
+               set_cpus_allowed_ptr(stutter_task, shuffle_tmp_mask);
+       if (fqs_task)
+               set_cpus_allowed_ptr(fqs_task, shuffle_tmp_mask);
+       if (shutdown_task)
+               set_cpus_allowed_ptr(shutdown_task, shuffle_tmp_mask);
+#ifdef CONFIG_HOTPLUG_CPU
+       if (onoff_task)
+               set_cpus_allowed_ptr(onoff_task, shuffle_tmp_mask);
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+       if (stall_task)
+               set_cpus_allowed_ptr(stall_task, shuffle_tmp_mask);
+       if (barrier_cbs_tasks)
+               for (i = 0; i < n_barrier_cbs; i++)
+                       if (barrier_cbs_tasks[i])
+                               set_cpus_allowed_ptr(barrier_cbs_tasks[i],
+                                                    shuffle_tmp_mask);
+       if (barrier_task)
+               set_cpus_allowed_ptr(barrier_task, shuffle_tmp_mask);
+
+       if (rcu_idle_cpu == -1)
+               rcu_idle_cpu = num_online_cpus() - 1;
+       else
+               rcu_idle_cpu--;
+
+       put_online_cpus();
+}
+
+/* Shuffle tasks across CPUs, with the intent of allowing each CPU in the
+ * system to become idle at a time and cut off its timer ticks. This is meant
+ * to test the support for such tickless idle CPU in RCU.
+ */
+static int
+rcu_torture_shuffle(void *arg)
+{
+       VERBOSE_PRINTK_STRING("rcu_torture_shuffle task started");
+       do {
+               schedule_timeout_interruptible(shuffle_interval * HZ);
+               rcu_torture_shuffle_tasks();
+               rcutorture_shutdown_absorb("rcu_torture_shuffle");
+       } while (!kthread_should_stop());
+       VERBOSE_PRINTK_STRING("rcu_torture_shuffle task stopping");
+       return 0;
+}
+
+/* Cause the rcutorture test to "stutter", starting and stopping all
+ * threads periodically.
+ */
+static int
+rcu_torture_stutter(void *arg)
+{
+       VERBOSE_PRINTK_STRING("rcu_torture_stutter task started");
+       do {
+               schedule_timeout_interruptible(stutter * HZ);
+               stutter_pause_test = 1;
+               if (!kthread_should_stop())
+                       schedule_timeout_interruptible(stutter * HZ);
+               stutter_pause_test = 0;
+               rcutorture_shutdown_absorb("rcu_torture_stutter");
+       } while (!kthread_should_stop());
+       VERBOSE_PRINTK_STRING("rcu_torture_stutter task stopping");
+       return 0;
+}
+
+static inline void
+rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
+{
+       pr_alert("%s" TORTURE_FLAG
+                "--- %s: nreaders=%d nfakewriters=%d "
+                "stat_interval=%d verbose=%d test_no_idle_hz=%d "
+                "shuffle_interval=%d stutter=%d irqreader=%d "
+                "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "
+                "test_boost=%d/%d test_boost_interval=%d "
+                "test_boost_duration=%d shutdown_secs=%d "
+                "stall_cpu=%d stall_cpu_holdoff=%d "
+                "n_barrier_cbs=%d "
+                "onoff_interval=%d onoff_holdoff=%d\n",
+                torture_type, tag, nrealreaders, nfakewriters,
+                stat_interval, verbose, test_no_idle_hz, shuffle_interval,
+                stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
+                test_boost, cur_ops->can_boost,
+                test_boost_interval, test_boost_duration, shutdown_secs,
+                stall_cpu, stall_cpu_holdoff,
+                n_barrier_cbs,
+                onoff_interval, onoff_holdoff);
+}
+
+static struct notifier_block rcutorture_shutdown_nb = {
+       .notifier_call = rcutorture_shutdown_notify,
+};
+
+static void rcutorture_booster_cleanup(int cpu)
+{
+       struct task_struct *t;
+
+       if (boost_tasks[cpu] == NULL)
+               return;
+       mutex_lock(&boost_mutex);
+       VERBOSE_PRINTK_STRING("Stopping rcu_torture_boost task");
+       t = boost_tasks[cpu];
+       boost_tasks[cpu] = NULL;
+       mutex_unlock(&boost_mutex);
+
+       /* This must be outside of the mutex, otherwise deadlock! */
+       kthread_stop(t);
+       boost_tasks[cpu] = NULL;
+}
+
+static int rcutorture_booster_init(int cpu)
+{
+       int retval;
+
+       if (boost_tasks[cpu] != NULL)
+               return 0;  /* Already created, nothing more to do. */
+
+       /* Don't allow time recalculation while creating a new task. */
+       mutex_lock(&boost_mutex);
+       VERBOSE_PRINTK_STRING("Creating rcu_torture_boost task");
+       boost_tasks[cpu] = kthread_create_on_node(rcu_torture_boost, NULL,
+                                                 cpu_to_node(cpu),
+                                                 "rcu_torture_boost");
+       if (IS_ERR(boost_tasks[cpu])) {
+               retval = PTR_ERR(boost_tasks[cpu]);
+               VERBOSE_PRINTK_STRING("rcu_torture_boost task create failed");
+               n_rcu_torture_boost_ktrerror++;
+               boost_tasks[cpu] = NULL;
+               mutex_unlock(&boost_mutex);
+               return retval;
+       }
+       kthread_bind(boost_tasks[cpu], cpu);
+       wake_up_process(boost_tasks[cpu]);
+       mutex_unlock(&boost_mutex);
+       return 0;
+}
+
+/*
+ * Cause the rcutorture test to shutdown the system after the test has
+ * run for the time specified by the shutdown_secs module parameter.
+ */
+static int
+rcu_torture_shutdown(void *arg)
+{
+       long delta;
+       unsigned long jiffies_snap;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_shutdown task started");
+       jiffies_snap = ACCESS_ONCE(jiffies);
+       while (ULONG_CMP_LT(jiffies_snap, shutdown_time) &&
+              !kthread_should_stop()) {
+               delta = shutdown_time - jiffies_snap;
+               if (verbose)
+                       pr_alert("%s" TORTURE_FLAG
+                                "rcu_torture_shutdown task: %lu jiffies remaining\n",
+                                torture_type, delta);
+               schedule_timeout_interruptible(delta);
+               jiffies_snap = ACCESS_ONCE(jiffies);
+       }
+       if (kthread_should_stop()) {
+               VERBOSE_PRINTK_STRING("rcu_torture_shutdown task stopping");
+               return 0;
+       }
+
+       /* OK, shut down the system. */
+
+       VERBOSE_PRINTK_STRING("rcu_torture_shutdown task shutting down system");
+       shutdown_task = NULL;   /* Avoid self-kill deadlock. */
+       rcu_torture_cleanup();  /* Get the success/failure message. */
+       kernel_power_off();     /* Shut down the system. */
+       return 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Execute random CPU-hotplug operations at the interval specified
+ * by the onoff_interval.
+ */
+static int
+rcu_torture_onoff(void *arg)
+{
+       int cpu;
+       unsigned long delta;
+       int maxcpu = -1;
+       DEFINE_RCU_RANDOM(rand);
+       int ret;
+       unsigned long starttime;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_onoff task started");
+       for_each_online_cpu(cpu)
+               maxcpu = cpu;
+       WARN_ON(maxcpu < 0);
+       if (onoff_holdoff > 0) {
+               VERBOSE_PRINTK_STRING("rcu_torture_onoff begin holdoff");
+               schedule_timeout_interruptible(onoff_holdoff * HZ);
+               VERBOSE_PRINTK_STRING("rcu_torture_onoff end holdoff");
+       }
+       while (!kthread_should_stop()) {
+               cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1);
+               if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
+                       if (verbose)
+                               pr_alert("%s" TORTURE_FLAG
+                                        "rcu_torture_onoff task: offlining %d\n",
+                                        torture_type, cpu);
+                       starttime = jiffies;
+                       n_offline_attempts++;
+                       ret = cpu_down(cpu);
+                       if (ret) {
+                               if (verbose)
+                                       pr_alert("%s" TORTURE_FLAG
+                                                "rcu_torture_onoff task: offline %d failed: errno %d\n",
+                                                torture_type, cpu, ret);
+                       } else {
+                               if (verbose)
+                                       pr_alert("%s" TORTURE_FLAG
+                                                "rcu_torture_onoff task: offlined %d\n",
+                                                torture_type, cpu);
+                               n_offline_successes++;
+                               delta = jiffies - starttime;
+                               sum_offline += delta;
+                               if (min_offline < 0) {
+                                       min_offline = delta;
+                                       max_offline = delta;
+                               }
+                               if (min_offline > delta)
+                                       min_offline = delta;
+                               if (max_offline < delta)
+                                       max_offline = delta;
+                       }
+               } else if (cpu_is_hotpluggable(cpu)) {
+                       if (verbose)
+                               pr_alert("%s" TORTURE_FLAG
+                                        "rcu_torture_onoff task: onlining %d\n",
+                                        torture_type, cpu);
+                       starttime = jiffies;
+                       n_online_attempts++;
+                       ret = cpu_up(cpu);
+                       if (ret) {
+                               if (verbose)
+                                       pr_alert("%s" TORTURE_FLAG
+                                                "rcu_torture_onoff task: online %d failed: errno %d\n",
+                                                torture_type, cpu, ret);
+                       } else {
+                               if (verbose)
+                                       pr_alert("%s" TORTURE_FLAG
+                                                "rcu_torture_onoff task: onlined %d\n",
+                                                torture_type, cpu);
+                               n_online_successes++;
+                               delta = jiffies - starttime;
+                               sum_online += delta;
+                               if (min_online < 0) {
+                                       min_online = delta;
+                                       max_online = delta;
+                               }
+                               if (min_online > delta)
+                                       min_online = delta;
+                               if (max_online < delta)
+                                       max_online = delta;
+                       }
+               }
+               schedule_timeout_interruptible(onoff_interval * HZ);
+       }
+       VERBOSE_PRINTK_STRING("rcu_torture_onoff task stopping");
+       return 0;
+}
+
+static int
+rcu_torture_onoff_init(void)
+{
+       int ret;
+
+       if (onoff_interval <= 0)
+               return 0;
+       onoff_task = kthread_run(rcu_torture_onoff, NULL, "rcu_torture_onoff");
+       if (IS_ERR(onoff_task)) {
+               ret = PTR_ERR(onoff_task);
+               onoff_task = NULL;
+               return ret;
+       }
+       return 0;
+}
+
+static void rcu_torture_onoff_cleanup(void)
+{
+       if (onoff_task == NULL)
+               return;
+       VERBOSE_PRINTK_STRING("Stopping rcu_torture_onoff task");
+       kthread_stop(onoff_task);
+       onoff_task = NULL;
+}
+
+#else /* #ifdef CONFIG_HOTPLUG_CPU */
+
+static int
+rcu_torture_onoff_init(void)
+{
+       return 0;
+}
+
+static void rcu_torture_onoff_cleanup(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
+ * CPU-stall kthread.  It waits as specified by stall_cpu_holdoff, then
+ * induces a CPU stall for the time specified by stall_cpu.
+ */
+static int rcu_torture_stall(void *args)
+{
+       unsigned long stop_at;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_stall task started");
+       if (stall_cpu_holdoff > 0) {
+               VERBOSE_PRINTK_STRING("rcu_torture_stall begin holdoff");
+               schedule_timeout_interruptible(stall_cpu_holdoff * HZ);
+               VERBOSE_PRINTK_STRING("rcu_torture_stall end holdoff");
+       }
+       if (!kthread_should_stop()) {
+               stop_at = get_seconds() + stall_cpu;
+               /* RCU CPU stall is expected behavior in following code. */
+               pr_alert("rcu_torture_stall start.\n");
+               rcu_read_lock();
+               preempt_disable();
+               while (ULONG_CMP_LT(get_seconds(), stop_at))
+                       continue;  /* Induce RCU CPU stall warning. */
+               preempt_enable();
+               rcu_read_unlock();
+               pr_alert("rcu_torture_stall end.\n");
+       }
+       rcutorture_shutdown_absorb("rcu_torture_stall");
+       while (!kthread_should_stop())
+               schedule_timeout_interruptible(10 * HZ);
+       return 0;
+}
+
+/* Spawn CPU-stall kthread, if stall_cpu specified. */
+static int __init rcu_torture_stall_init(void)
+{
+       int ret;
+
+       if (stall_cpu <= 0)
+               return 0;
+       stall_task = kthread_run(rcu_torture_stall, NULL, "rcu_torture_stall");
+       if (IS_ERR(stall_task)) {
+               ret = PTR_ERR(stall_task);
+               stall_task = NULL;
+               return ret;
+       }
+       return 0;
+}
+
+/* Clean up after the CPU-stall kthread, if one was spawned. */
+static void rcu_torture_stall_cleanup(void)
+{
+       if (stall_task == NULL)
+               return;
+       VERBOSE_PRINTK_STRING("Stopping rcu_torture_stall_task.");
+       kthread_stop(stall_task);
+       stall_task = NULL;
+}
+
+/* Callback function for RCU barrier testing. */
+void rcu_torture_barrier_cbf(struct rcu_head *rcu)
+{
+       atomic_inc(&barrier_cbs_invoked);
+}
+
+/* kthread function to register callbacks used to test RCU barriers. */
+static int rcu_torture_barrier_cbs(void *arg)
+{
+       long myid = (long)arg;
+       bool lastphase = 0;
+       struct rcu_head rcu;
+
+       init_rcu_head_on_stack(&rcu);
+       VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task started");
+       set_user_nice(current, 19);
+       do {
+               wait_event(barrier_cbs_wq[myid],
+                          barrier_phase != lastphase ||
+                          kthread_should_stop() ||
+                          fullstop != FULLSTOP_DONTSTOP);
+               lastphase = barrier_phase;
+               smp_mb(); /* ensure barrier_phase load before ->call(). */
+               if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP)
+                       break;
+               cur_ops->call(&rcu, rcu_torture_barrier_cbf);
+               if (atomic_dec_and_test(&barrier_cbs_count))
+                       wake_up(&barrier_wq);
+       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
+       VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_barrier_cbs");
+       while (!kthread_should_stop())
+               schedule_timeout_interruptible(1);
+       cur_ops->cb_barrier();
+       destroy_rcu_head_on_stack(&rcu);
+       return 0;
+}
+
+/* kthread function to drive and coordinate RCU barrier testing. */
+static int rcu_torture_barrier(void *arg)
+{
+       int i;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_barrier task starting");
+       do {
+               atomic_set(&barrier_cbs_invoked, 0);
+               atomic_set(&barrier_cbs_count, n_barrier_cbs);
+               smp_mb(); /* Ensure barrier_phase after prior assignments. */
+               barrier_phase = !barrier_phase;
+               for (i = 0; i < n_barrier_cbs; i++)
+                       wake_up(&barrier_cbs_wq[i]);
+               wait_event(barrier_wq,
+                          atomic_read(&barrier_cbs_count) == 0 ||
+                          kthread_should_stop() ||
+                          fullstop != FULLSTOP_DONTSTOP);
+               if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP)
+                       break;
+               n_barrier_attempts++;
+               cur_ops->cb_barrier();
+               if (atomic_read(&barrier_cbs_invoked) != n_barrier_cbs) {
+                       n_rcu_torture_barrier_error++;
+                       WARN_ON_ONCE(1);
+               }
+               n_barrier_successes++;
+               schedule_timeout_interruptible(HZ / 10);
+       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
+       VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping");
+       rcutorture_shutdown_absorb("rcu_torture_barrier");
+       while (!kthread_should_stop())
+               schedule_timeout_interruptible(1);
+       return 0;
+}
+
+/* Initialize RCU barrier testing. */
+static int rcu_torture_barrier_init(void)
+{
+       int i;
+       int ret;
+
+       if (n_barrier_cbs == 0)
+               return 0;
+       if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) {
+               pr_alert("%s" TORTURE_FLAG
+                        " Call or barrier ops missing for %s,\n",
+                        torture_type, cur_ops->name);
+               pr_alert("%s" TORTURE_FLAG
+                        " RCU barrier testing omitted from run.\n",
+                        torture_type);
+               return 0;
+       }
+       atomic_set(&barrier_cbs_count, 0);
+       atomic_set(&barrier_cbs_invoked, 0);
+       barrier_cbs_tasks =
+               kzalloc(n_barrier_cbs * sizeof(barrier_cbs_tasks[0]),
+                       GFP_KERNEL);
+       barrier_cbs_wq =
+               kzalloc(n_barrier_cbs * sizeof(barrier_cbs_wq[0]),
+                       GFP_KERNEL);
+       if (barrier_cbs_tasks == NULL || !barrier_cbs_wq)
+               return -ENOMEM;
+       for (i = 0; i < n_barrier_cbs; i++) {
+               init_waitqueue_head(&barrier_cbs_wq[i]);
+               barrier_cbs_tasks[i] = kthread_run(rcu_torture_barrier_cbs,
+                                                  (void *)(long)i,
+                                                  "rcu_torture_barrier_cbs");
+               if (IS_ERR(barrier_cbs_tasks[i])) {
+                       ret = PTR_ERR(barrier_cbs_tasks[i]);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier_cbs");
+                       barrier_cbs_tasks[i] = NULL;
+                       return ret;
+               }
+       }
+       barrier_task = kthread_run(rcu_torture_barrier, NULL,
+                                  "rcu_torture_barrier");
+       if (IS_ERR(barrier_task)) {
+               ret = PTR_ERR(barrier_task);
+               VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier");
+               barrier_task = NULL;
+       }
+       return 0;
+}
+
+/* Clean up after RCU barrier testing. */
+static void rcu_torture_barrier_cleanup(void)
+{
+       int i;
+
+       if (barrier_task != NULL) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier task");
+               kthread_stop(barrier_task);
+               barrier_task = NULL;
+       }
+       if (barrier_cbs_tasks != NULL) {
+               for (i = 0; i < n_barrier_cbs; i++) {
+                       if (barrier_cbs_tasks[i] != NULL) {
+                               VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier_cbs task");
+                               kthread_stop(barrier_cbs_tasks[i]);
+                               barrier_cbs_tasks[i] = NULL;
+                       }
+               }
+               kfree(barrier_cbs_tasks);
+               barrier_cbs_tasks = NULL;
+       }
+       if (barrier_cbs_wq != NULL) {
+               kfree(barrier_cbs_wq);
+               barrier_cbs_wq = NULL;
+       }
+}
+
+static int rcutorture_cpu_notify(struct notifier_block *self,
+                                unsigned long action, void *hcpu)
+{
+       long cpu = (long)hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+               (void)rcutorture_booster_init(cpu);
+               break;
+       case CPU_DOWN_PREPARE:
+               rcutorture_booster_cleanup(cpu);
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block rcutorture_cpu_nb = {
+       .notifier_call = rcutorture_cpu_notify,
+};
+
+static void
+rcu_torture_cleanup(void)
+{
+       int i;
+
+       mutex_lock(&fullstop_mutex);
+       rcutorture_record_test_transition();
+       if (fullstop == FULLSTOP_SHUTDOWN) {
+               pr_warn(/* but going down anyway, so... */
+                      "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
+               mutex_unlock(&fullstop_mutex);
+               schedule_timeout_uninterruptible(10);
+               if (cur_ops->cb_barrier != NULL)
+                       cur_ops->cb_barrier();
+               return;
+       }
+       fullstop = FULLSTOP_RMMOD;
+       mutex_unlock(&fullstop_mutex);
+       unregister_reboot_notifier(&rcutorture_shutdown_nb);
+       rcu_torture_barrier_cleanup();
+       rcu_torture_stall_cleanup();
+       if (stutter_task) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task");
+               kthread_stop(stutter_task);
+       }
+       stutter_task = NULL;
+       if (shuffler_task) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
+               kthread_stop(shuffler_task);
+               free_cpumask_var(shuffle_tmp_mask);
+       }
+       shuffler_task = NULL;
+
+       if (writer_task) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
+               kthread_stop(writer_task);
+       }
+       writer_task = NULL;
+
+       if (reader_tasks) {
+               for (i = 0; i < nrealreaders; i++) {
+                       if (reader_tasks[i]) {
+                               VERBOSE_PRINTK_STRING(
+                                       "Stopping rcu_torture_reader task");
+                               kthread_stop(reader_tasks[i]);
+                       }
+                       reader_tasks[i] = NULL;
+               }
+               kfree(reader_tasks);
+               reader_tasks = NULL;
+       }
+       rcu_torture_current = NULL;
+
+       if (fakewriter_tasks) {
+               for (i = 0; i < nfakewriters; i++) {
+                       if (fakewriter_tasks[i]) {
+                               VERBOSE_PRINTK_STRING(
+                                       "Stopping rcu_torture_fakewriter task");
+                               kthread_stop(fakewriter_tasks[i]);
+                       }
+                       fakewriter_tasks[i] = NULL;
+               }
+               kfree(fakewriter_tasks);
+               fakewriter_tasks = NULL;
+       }
+
+       if (stats_task) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
+               kthread_stop(stats_task);
+       }
+       stats_task = NULL;
+
+       if (fqs_task) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_fqs task");
+               kthread_stop(fqs_task);
+       }
+       fqs_task = NULL;
+       if ((test_boost == 1 && cur_ops->can_boost) ||
+           test_boost == 2) {
+               unregister_cpu_notifier(&rcutorture_cpu_nb);
+               for_each_possible_cpu(i)
+                       rcutorture_booster_cleanup(i);
+       }
+       if (shutdown_task != NULL) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_shutdown task");
+               kthread_stop(shutdown_task);
+       }
+       shutdown_task = NULL;
+       rcu_torture_onoff_cleanup();
+
+       /* Wait for all RCU callbacks to fire.  */
+
+       if (cur_ops->cb_barrier != NULL)
+               cur_ops->cb_barrier();
+
+       rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
+
+       if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error)
+               rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE");
+       else if (n_online_successes != n_online_attempts ||
+                n_offline_successes != n_offline_attempts)
+               rcu_torture_print_module_parms(cur_ops,
+                                              "End of test: RCU_HOTPLUG");
+       else
+               rcu_torture_print_module_parms(cur_ops, "End of test: SUCCESS");
+}
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+static void rcu_torture_leak_cb(struct rcu_head *rhp)
+{
+}
+
+static void rcu_torture_err_cb(struct rcu_head *rhp)
+{
+       /*
+        * This -might- happen due to race conditions, but is unlikely.
+        * The scenario that leads to this happening is that the
+        * first of the pair of duplicate callbacks is queued,
+        * someone else starts a grace period that includes that
+        * callback, then the second of the pair must wait for the
+        * next grace period.  Unlikely, but can happen.  If it
+        * does happen, the debug-objects subsystem won't have splatted.
+        */
+       pr_alert("rcutorture: duplicated callback was invoked.\n");
+}
+#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+
+/*
+ * Verify that double-free causes debug-objects to complain, but only
+ * if CONFIG_DEBUG_OBJECTS_RCU_HEAD=y.  Otherwise, say that the test
+ * cannot be carried out.
+ */
+static void rcu_test_debug_objects(void)
+{
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+       struct rcu_head rh1;
+       struct rcu_head rh2;
+
+       init_rcu_head_on_stack(&rh1);
+       init_rcu_head_on_stack(&rh2);
+       pr_alert("rcutorture: WARN: Duplicate call_rcu() test starting.\n");
+
+       /* Try to queue the rh2 pair of callbacks for the same grace period. */
+       preempt_disable(); /* Prevent preemption from interrupting test. */
+       rcu_read_lock(); /* Make it impossible to finish a grace period. */
+       call_rcu(&rh1, rcu_torture_leak_cb); /* Start grace period. */
+       local_irq_disable(); /* Make it harder to start a new grace period. */
+       call_rcu(&rh2, rcu_torture_leak_cb);
+       call_rcu(&rh2, rcu_torture_err_cb); /* Duplicate callback. */
+       local_irq_enable();
+       rcu_read_unlock();
+       preempt_enable();
+
+       /* Wait for them all to get done so we can safely return. */
+       rcu_barrier();
+       pr_alert("rcutorture: WARN: Duplicate call_rcu() test complete.\n");
+       destroy_rcu_head_on_stack(&rh1);
+       destroy_rcu_head_on_stack(&rh2);
+#else /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+       pr_alert("rcutorture: !CONFIG_DEBUG_OBJECTS_RCU_HEAD, not testing duplicate call_rcu()\n");
+#endif /* #else #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+}
+
+static int __init
+rcu_torture_init(void)
+{
+       int i;
+       int cpu;
+       int firsterr = 0;
+       int retval;
+       static struct rcu_torture_ops *torture_ops[] = {
+               &rcu_ops, &rcu_bh_ops, &srcu_ops, &sched_ops,
+       };
+
+       mutex_lock(&fullstop_mutex);
+
+       /* Process args and tell the world that the torturer is on the job. */
+       for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
+               cur_ops = torture_ops[i];
+               if (strcmp(torture_type, cur_ops->name) == 0)
+                       break;
+       }
+       if (i == ARRAY_SIZE(torture_ops)) {
+               pr_alert("rcu-torture: invalid torture type: \"%s\"\n",
+                        torture_type);
+               pr_alert("rcu-torture types:");
+               for (i = 0; i < ARRAY_SIZE(torture_ops); i++)
+                       pr_alert(" %s", torture_ops[i]->name);
+               pr_alert("\n");
+               mutex_unlock(&fullstop_mutex);
+               return -EINVAL;
+       }
+       if (cur_ops->fqs == NULL && fqs_duration != 0) {
+               pr_alert("rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n");
+               fqs_duration = 0;
+       }
+       if (cur_ops->init)
+               cur_ops->init(); /* no "goto unwind" prior to this point!!! */
+
+       if (nreaders >= 0)
+               nrealreaders = nreaders;
+       else
+               nrealreaders = 2 * num_online_cpus();
+       rcu_torture_print_module_parms(cur_ops, "Start of test");
+       fullstop = FULLSTOP_DONTSTOP;
+
+       /* Set up the freelist. */
+
+       INIT_LIST_HEAD(&rcu_torture_freelist);
+       for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++) {
+               rcu_tortures[i].rtort_mbtest = 0;
+               list_add_tail(&rcu_tortures[i].rtort_free,
+                             &rcu_torture_freelist);
+       }
+
+       /* Initialize the statistics so that each run gets its own numbers. */
+
+       rcu_torture_current = NULL;
+       rcu_torture_current_version = 0;
+       atomic_set(&n_rcu_torture_alloc, 0);
+       atomic_set(&n_rcu_torture_alloc_fail, 0);
+       atomic_set(&n_rcu_torture_free, 0);
+       atomic_set(&n_rcu_torture_mberror, 0);
+       atomic_set(&n_rcu_torture_error, 0);
+       n_rcu_torture_barrier_error = 0;
+       n_rcu_torture_boost_ktrerror = 0;
+       n_rcu_torture_boost_rterror = 0;
+       n_rcu_torture_boost_failure = 0;
+       n_rcu_torture_boosts = 0;
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+               atomic_set(&rcu_torture_wcount[i], 0);
+       for_each_possible_cpu(cpu) {
+               for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+                       per_cpu(rcu_torture_count, cpu)[i] = 0;
+                       per_cpu(rcu_torture_batch, cpu)[i] = 0;
+               }
+       }
+
+       /* Start up the kthreads. */
+
+       VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
+       writer_task = kthread_create(rcu_torture_writer, NULL,
+                                    "rcu_torture_writer");
+       if (IS_ERR(writer_task)) {
+               firsterr = PTR_ERR(writer_task);
+               VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
+               writer_task = NULL;
+               goto unwind;
+       }
+       wake_up_process(writer_task);
+       fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
+                                  GFP_KERNEL);
+       if (fakewriter_tasks == NULL) {
+               VERBOSE_PRINTK_ERRSTRING("out of memory");
+               firsterr = -ENOMEM;
+               goto unwind;
+       }
+       for (i = 0; i < nfakewriters; i++) {
+               VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task");
+               fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL,
+                                                 "rcu_torture_fakewriter");
+               if (IS_ERR(fakewriter_tasks[i])) {
+                       firsterr = PTR_ERR(fakewriter_tasks[i]);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter");
+                       fakewriter_tasks[i] = NULL;
+                       goto unwind;
+               }
+       }
+       reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]),
+                              GFP_KERNEL);
+       if (reader_tasks == NULL) {
+               VERBOSE_PRINTK_ERRSTRING("out of memory");
+               firsterr = -ENOMEM;
+               goto unwind;
+       }
+       for (i = 0; i < nrealreaders; i++) {
+               VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task");
+               reader_tasks[i] = kthread_run(rcu_torture_reader, NULL,
+                                             "rcu_torture_reader");
+               if (IS_ERR(reader_tasks[i])) {
+                       firsterr = PTR_ERR(reader_tasks[i]);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create reader");
+                       reader_tasks[i] = NULL;
+                       goto unwind;
+               }
+       }
+       if (stat_interval > 0) {
+               VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task");
+               stats_task = kthread_run(rcu_torture_stats, NULL,
+                                       "rcu_torture_stats");
+               if (IS_ERR(stats_task)) {
+                       firsterr = PTR_ERR(stats_task);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create stats");
+                       stats_task = NULL;
+                       goto unwind;
+               }
+       }
+       if (test_no_idle_hz) {
+               rcu_idle_cpu = num_online_cpus() - 1;
+
+               if (!alloc_cpumask_var(&shuffle_tmp_mask, GFP_KERNEL)) {
+                       firsterr = -ENOMEM;
+                       VERBOSE_PRINTK_ERRSTRING("Failed to alloc mask");
+                       goto unwind;
+               }
+
+               /* Create the shuffler thread */
+               shuffler_task = kthread_run(rcu_torture_shuffle, NULL,
+                                         "rcu_torture_shuffle");
+               if (IS_ERR(shuffler_task)) {
+                       free_cpumask_var(shuffle_tmp_mask);
+                       firsterr = PTR_ERR(shuffler_task);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create shuffler");
+                       shuffler_task = NULL;
+                       goto unwind;
+               }
+       }
+       if (stutter < 0)
+               stutter = 0;
+       if (stutter) {
+               /* Create the stutter thread */
+               stutter_task = kthread_run(rcu_torture_stutter, NULL,
+                                         "rcu_torture_stutter");
+               if (IS_ERR(stutter_task)) {
+                       firsterr = PTR_ERR(stutter_task);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create stutter");
+                       stutter_task = NULL;
+                       goto unwind;
+               }
+       }
+       if (fqs_duration < 0)
+               fqs_duration = 0;
+       if (fqs_duration) {
+               /* Create the stutter thread */
+               fqs_task = kthread_run(rcu_torture_fqs, NULL,
+                                      "rcu_torture_fqs");
+               if (IS_ERR(fqs_task)) {
+                       firsterr = PTR_ERR(fqs_task);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create fqs");
+                       fqs_task = NULL;
+                       goto unwind;
+               }
+       }
+       if (test_boost_interval < 1)
+               test_boost_interval = 1;
+       if (test_boost_duration < 2)
+               test_boost_duration = 2;
+       if ((test_boost == 1 && cur_ops->can_boost) ||
+           test_boost == 2) {
+
+               boost_starttime = jiffies + test_boost_interval * HZ;
+               register_cpu_notifier(&rcutorture_cpu_nb);
+               for_each_possible_cpu(i) {
+                       if (cpu_is_offline(i))
+                               continue;  /* Heuristic: CPU can go offline. */
+                       retval = rcutorture_booster_init(i);
+                       if (retval < 0) {
+                               firsterr = retval;
+                               goto unwind;
+                       }
+               }
+       }
+       if (shutdown_secs > 0) {
+               shutdown_time = jiffies + shutdown_secs * HZ;
+               shutdown_task = kthread_create(rcu_torture_shutdown, NULL,
+                                              "rcu_torture_shutdown");
+               if (IS_ERR(shutdown_task)) {
+                       firsterr = PTR_ERR(shutdown_task);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown");
+                       shutdown_task = NULL;
+                       goto unwind;
+               }
+               wake_up_process(shutdown_task);
+       }
+       i = rcu_torture_onoff_init();
+       if (i != 0) {
+               firsterr = i;
+               goto unwind;
+       }
+       register_reboot_notifier(&rcutorture_shutdown_nb);
+       i = rcu_torture_stall_init();
+       if (i != 0) {
+               firsterr = i;
+               goto unwind;
+       }
+       retval = rcu_torture_barrier_init();
+       if (retval != 0) {
+               firsterr = retval;
+               goto unwind;
+       }
+       if (object_debug)
+               rcu_test_debug_objects();
+       rcutorture_record_test_transition();
+       mutex_unlock(&fullstop_mutex);
+       return 0;
+
+unwind:
+       mutex_unlock(&fullstop_mutex);
+       rcu_torture_cleanup();
+       return firsterr;
+}
+
+module_init(rcu_torture_init);
+module_exit(rcu_torture_cleanup);
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
new file mode 100644 (file)
index 0000000..4c06ddf
--- /dev/null
@@ -0,0 +1,3416 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion
+ *
+ * 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 IBM Corporation, 2008
+ *
+ * Authors: Dipankar Sarma <dipankar@in.ibm.com>
+ *         Manfred Spraul <manfred@colorfullife.com>
+ *         Paul E. McKenney <paulmck@linux.vnet.ibm.com> Hierarchical version
+ *
+ * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
+ * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *     Documentation/RCU
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/rcupdate.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/nmi.h>
+#include <linux/atomic.h>
+#include <linux/bitops.h>
+#include <linux/export.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/mutex.h>
+#include <linux/time.h>
+#include <linux/kernel_stat.h>
+#include <linux/wait.h>
+#include <linux/kthread.h>
+#include <linux/prefetch.h>
+#include <linux/delay.h>
+#include <linux/stop_machine.h>
+#include <linux/random.h>
+#include <linux/ftrace_event.h>
+#include <linux/suspend.h>
+
+#include "tree.h"
+#include <trace/events/rcu.h>
+
+#include "rcu.h"
+
+MODULE_ALIAS("rcutree");
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "rcutree."
+
+/* Data structures. */
+
+static struct lock_class_key rcu_node_class[RCU_NUM_LVLS];
+static struct lock_class_key rcu_fqs_class[RCU_NUM_LVLS];
+
+/*
+ * In order to export the rcu_state name to the tracing tools, it
+ * needs to be added in the __tracepoint_string section.
+ * This requires defining a separate variable tp_<sname>_varname
+ * that points to the string being used, and this will allow
+ * the tracing userspace tools to be able to decipher the string
+ * address to the matching string.
+ */
+#define RCU_STATE_INITIALIZER(sname, sabbr, cr) \
+static char sname##_varname[] = #sname; \
+static const char *tp_##sname##_varname __used __tracepoint_string = sname##_varname; \
+struct rcu_state sname##_state = { \
+       .level = { &sname##_state.node[0] }, \
+       .call = cr, \
+       .fqs_state = RCU_GP_IDLE, \
+       .gpnum = 0UL - 300UL, \
+       .completed = 0UL - 300UL, \
+       .orphan_lock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.orphan_lock), \
+       .orphan_nxttail = &sname##_state.orphan_nxtlist, \
+       .orphan_donetail = &sname##_state.orphan_donelist, \
+       .barrier_mutex = __MUTEX_INITIALIZER(sname##_state.barrier_mutex), \
+       .onoff_mutex = __MUTEX_INITIALIZER(sname##_state.onoff_mutex), \
+       .name = sname##_varname, \
+       .abbr = sabbr, \
+}; \
+DEFINE_PER_CPU(struct rcu_data, sname##_data)
+
+RCU_STATE_INITIALIZER(rcu_sched, 's', call_rcu_sched);
+RCU_STATE_INITIALIZER(rcu_bh, 'b', call_rcu_bh);
+
+static struct rcu_state *rcu_state;
+LIST_HEAD(rcu_struct_flavors);
+
+/* Increase (but not decrease) the CONFIG_RCU_FANOUT_LEAF at boot time. */
+static int rcu_fanout_leaf = CONFIG_RCU_FANOUT_LEAF;
+module_param(rcu_fanout_leaf, int, 0444);
+int rcu_num_lvls __read_mostly = RCU_NUM_LVLS;
+static int num_rcu_lvl[] = {  /* Number of rcu_nodes at specified level. */
+       NUM_RCU_LVL_0,
+       NUM_RCU_LVL_1,
+       NUM_RCU_LVL_2,
+       NUM_RCU_LVL_3,
+       NUM_RCU_LVL_4,
+};
+int rcu_num_nodes __read_mostly = NUM_RCU_NODES; /* Total # rcu_nodes in use. */
+
+/*
+ * The rcu_scheduler_active variable transitions from zero to one just
+ * before the first task is spawned.  So when this variable is zero, RCU
+ * can assume that there is but one task, allowing RCU to (for example)
+ * optimize synchronize_sched() to a simple barrier().  When this variable
+ * is one, RCU must actually do all the hard work required to detect real
+ * grace periods.  This variable is also used to suppress boot-time false
+ * positives from lockdep-RCU error checking.
+ */
+int rcu_scheduler_active __read_mostly;
+EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+
+/*
+ * The rcu_scheduler_fully_active variable transitions from zero to one
+ * during the early_initcall() processing, which is after the scheduler
+ * is capable of creating new tasks.  So RCU processing (for example,
+ * creating tasks for RCU priority boosting) must be delayed until after
+ * rcu_scheduler_fully_active transitions from zero to one.  We also
+ * currently delay invocation of any RCU callbacks until after this point.
+ *
+ * It might later prove better for people registering RCU callbacks during
+ * early boot to take responsibility for these callbacks, but one step at
+ * a time.
+ */
+static int rcu_scheduler_fully_active __read_mostly;
+
+#ifdef CONFIG_RCU_BOOST
+
+/*
+ * Control variables for per-CPU and per-rcu_node kthreads.  These
+ * handle all flavors of RCU.
+ */
+static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task);
+DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
+DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
+DEFINE_PER_CPU(char, rcu_cpu_has_work);
+
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu);
+static void invoke_rcu_core(void);
+static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp);
+
+/*
+ * Track the rcutorture test sequence number and the update version
+ * number within a given test.  The rcutorture_testseq is incremented
+ * on every rcutorture module load and unload, so has an odd value
+ * when a test is running.  The rcutorture_vernum is set to zero
+ * when rcutorture starts and is incremented on each rcutorture update.
+ * These variables enable correlating rcutorture output with the
+ * RCU tracing information.
+ */
+unsigned long rcutorture_testseq;
+unsigned long rcutorture_vernum;
+
+/*
+ * Return true if an RCU grace period is in progress.  The ACCESS_ONCE()s
+ * permit this function to be invoked without holding the root rcu_node
+ * structure's ->lock, but of course results can be subject to change.
+ */
+static int rcu_gp_in_progress(struct rcu_state *rsp)
+{
+       return ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum);
+}
+
+/*
+ * Note a quiescent state.  Because we do not need to know
+ * how many quiescent states passed, just if there was at least
+ * one since the start of the grace period, this just sets a flag.
+ * The caller must have disabled preemption.
+ */
+void rcu_sched_qs(int cpu)
+{
+       struct rcu_data *rdp = &per_cpu(rcu_sched_data, cpu);
+
+       if (rdp->passed_quiesce == 0)
+               trace_rcu_grace_period(TPS("rcu_sched"), rdp->gpnum, TPS("cpuqs"));
+       rdp->passed_quiesce = 1;
+}
+
+void rcu_bh_qs(int cpu)
+{
+       struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
+
+       if (rdp->passed_quiesce == 0)
+               trace_rcu_grace_period(TPS("rcu_bh"), rdp->gpnum, TPS("cpuqs"));
+       rdp->passed_quiesce = 1;
+}
+
+/*
+ * Note a context switch.  This is a quiescent state for RCU-sched,
+ * and requires special handling for preemptible RCU.
+ * The caller must have disabled preemption.
+ */
+void rcu_note_context_switch(int cpu)
+{
+       trace_rcu_utilization(TPS("Start context switch"));
+       rcu_sched_qs(cpu);
+       rcu_preempt_note_context_switch(cpu);
+       trace_rcu_utilization(TPS("End context switch"));
+}
+EXPORT_SYMBOL_GPL(rcu_note_context_switch);
+
+static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
+       .dynticks_nesting = DYNTICK_TASK_EXIT_IDLE,
+       .dynticks = ATOMIC_INIT(1),
+#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
+       .dynticks_idle_nesting = DYNTICK_TASK_NEST_VALUE,
+       .dynticks_idle = ATOMIC_INIT(1),
+#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
+};
+
+static long blimit = 10;       /* Maximum callbacks per rcu_do_batch. */
+static long qhimark = 10000;   /* If this many pending, ignore blimit. */
+static long qlowmark = 100;    /* Once only this many pending, use blimit. */
+
+module_param(blimit, long, 0444);
+module_param(qhimark, long, 0444);
+module_param(qlowmark, long, 0444);
+
+static ulong jiffies_till_first_fqs = ULONG_MAX;
+static ulong jiffies_till_next_fqs = ULONG_MAX;
+
+module_param(jiffies_till_first_fqs, ulong, 0644);
+module_param(jiffies_till_next_fqs, ulong, 0644);
+
+static void rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
+                                 struct rcu_data *rdp);
+static void force_qs_rnp(struct rcu_state *rsp,
+                        int (*f)(struct rcu_data *rsp, bool *isidle,
+                                 unsigned long *maxj),
+                        bool *isidle, unsigned long *maxj);
+static void force_quiescent_state(struct rcu_state *rsp);
+static int rcu_pending(int cpu);
+
+/*
+ * Return the number of RCU-sched batches processed thus far for debug & stats.
+ */
+long rcu_batches_completed_sched(void)
+{
+       return rcu_sched_state.completed;
+}
+EXPORT_SYMBOL_GPL(rcu_batches_completed_sched);
+
+/*
+ * Return the number of RCU BH batches processed thus far for debug & stats.
+ */
+long rcu_batches_completed_bh(void)
+{
+       return rcu_bh_state.completed;
+}
+EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
+
+/*
+ * Force a quiescent state for RCU BH.
+ */
+void rcu_bh_force_quiescent_state(void)
+{
+       force_quiescent_state(&rcu_bh_state);
+}
+EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state);
+
+/*
+ * Record the number of times rcutorture tests have been initiated and
+ * terminated.  This information allows the debugfs tracing stats to be
+ * correlated to the rcutorture messages, even when the rcutorture module
+ * is being repeatedly loaded and unloaded.  In other words, we cannot
+ * store this state in rcutorture itself.
+ */
+void rcutorture_record_test_transition(void)
+{
+       rcutorture_testseq++;
+       rcutorture_vernum = 0;
+}
+EXPORT_SYMBOL_GPL(rcutorture_record_test_transition);
+
+/*
+ * Record the number of writer passes through the current rcutorture test.
+ * This is also used to correlate debugfs tracing stats with the rcutorture
+ * messages.
+ */
+void rcutorture_record_progress(unsigned long vernum)
+{
+       rcutorture_vernum++;
+}
+EXPORT_SYMBOL_GPL(rcutorture_record_progress);
+
+/*
+ * Force a quiescent state for RCU-sched.
+ */
+void rcu_sched_force_quiescent_state(void)
+{
+       force_quiescent_state(&rcu_sched_state);
+}
+EXPORT_SYMBOL_GPL(rcu_sched_force_quiescent_state);
+
+/*
+ * Does the CPU have callbacks ready to be invoked?
+ */
+static int
+cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
+{
+       return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] &&
+              rdp->nxttail[RCU_DONE_TAIL] != NULL;
+}
+
+/*
+ * Does the current CPU require a not-yet-started grace period?
+ * The caller must have disabled interrupts to prevent races with
+ * normal callback registry.
+ */
+static int
+cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       int i;
+
+       if (rcu_gp_in_progress(rsp))
+               return 0;  /* No, a grace period is already in progress. */
+       if (rcu_nocb_needs_gp(rsp))
+               return 1;  /* Yes, a no-CBs CPU needs one. */
+       if (!rdp->nxttail[RCU_NEXT_TAIL])
+               return 0;  /* No, this is a no-CBs (or offline) CPU. */
+       if (*rdp->nxttail[RCU_NEXT_READY_TAIL])
+               return 1;  /* Yes, this CPU has newly registered callbacks. */
+       for (i = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++)
+               if (rdp->nxttail[i - 1] != rdp->nxttail[i] &&
+                   ULONG_CMP_LT(ACCESS_ONCE(rsp->completed),
+                                rdp->nxtcompleted[i]))
+                       return 1;  /* Yes, CBs for future grace period. */
+       return 0; /* No grace period needed. */
+}
+
+/*
+ * Return the root node of the specified rcu_state structure.
+ */
+static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
+{
+       return &rsp->node[0];
+}
+
+/*
+ * rcu_eqs_enter_common - current CPU is moving towards extended quiescent state
+ *
+ * If the new value of the ->dynticks_nesting counter now is zero,
+ * we really have entered idle, and must do the appropriate accounting.
+ * The caller must have disabled interrupts.
+ */
+static void rcu_eqs_enter_common(struct rcu_dynticks *rdtp, long long oldval,
+                               bool user)
+{
+       trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting);
+       if (!user && !is_idle_task(current)) {
+               struct task_struct *idle __maybe_unused =
+                       idle_task(smp_processor_id());
+
+               trace_rcu_dyntick(TPS("Error on entry: not idle task"), oldval, 0);
+               ftrace_dump(DUMP_ORIG);
+               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
+                         current->pid, current->comm,
+                         idle->pid, idle->comm); /* must be idle task! */
+       }
+       rcu_prepare_for_idle(smp_processor_id());
+       /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
+       smp_mb__before_atomic_inc();  /* See above. */
+       atomic_inc(&rdtp->dynticks);
+       smp_mb__after_atomic_inc();  /* Force ordering with next sojourn. */
+       WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
+
+       /*
+        * It is illegal to enter an extended quiescent state while
+        * in an RCU read-side critical section.
+        */
+       rcu_lockdep_assert(!lock_is_held(&rcu_lock_map),
+                          "Illegal idle entry in RCU read-side critical section.");
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),
+                          "Illegal idle entry in RCU-bh read-side critical section.");
+       rcu_lockdep_assert(!lock_is_held(&rcu_sched_lock_map),
+                          "Illegal idle entry in RCU-sched read-side critical section.");
+}
+
+/*
+ * Enter an RCU extended quiescent state, which can be either the
+ * idle loop or adaptive-tickless usermode execution.
+ */
+static void rcu_eqs_enter(bool user)
+{
+       long long oldval;
+       struct rcu_dynticks *rdtp;
+
+       rdtp = this_cpu_ptr(&rcu_dynticks);
+       oldval = rdtp->dynticks_nesting;
+       WARN_ON_ONCE((oldval & DYNTICK_TASK_NEST_MASK) == 0);
+       if ((oldval & DYNTICK_TASK_NEST_MASK) == DYNTICK_TASK_NEST_VALUE)
+               rdtp->dynticks_nesting = 0;
+       else
+               rdtp->dynticks_nesting -= DYNTICK_TASK_NEST_VALUE;
+       rcu_eqs_enter_common(rdtp, oldval, user);
+}
+
+/**
+ * rcu_idle_enter - inform RCU that current CPU is entering idle
+ *
+ * Enter idle mode, in other words, -leave- the mode in which RCU
+ * read-side critical sections can occur.  (Though RCU read-side
+ * critical sections can occur in irq handlers in idle, a possibility
+ * handled by irq_enter() and irq_exit().)
+ *
+ * We crowbar the ->dynticks_nesting field to zero to allow for
+ * the possibility of usermode upcalls having messed up our count
+ * of interrupt nesting level during the prior busy period.
+ */
+void rcu_idle_enter(void)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       rcu_eqs_enter(false);
+       rcu_sysidle_enter(this_cpu_ptr(&rcu_dynticks), 0);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(rcu_idle_enter);
+
+#ifdef CONFIG_RCU_USER_QS
+/**
+ * rcu_user_enter - inform RCU that we are resuming userspace.
+ *
+ * Enter RCU idle mode right before resuming userspace.  No use of RCU
+ * is permitted between this call and rcu_user_exit(). This way the
+ * CPU doesn't need to maintain the tick for RCU maintenance purposes
+ * when the CPU runs in userspace.
+ */
+void rcu_user_enter(void)
+{
+       rcu_eqs_enter(1);
+}
+#endif /* CONFIG_RCU_USER_QS */
+
+/**
+ * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
+ *
+ * Exit from an interrupt handler, which might possibly result in entering
+ * idle mode, in other words, leaving the mode in which read-side critical
+ * sections can occur.
+ *
+ * This code assumes that the idle loop never does anything that might
+ * result in unbalanced calls to irq_enter() and irq_exit().  If your
+ * architecture violates this assumption, RCU will give you what you
+ * deserve, good and hard.  But very infrequently and irreproducibly.
+ *
+ * Use things like work queues to work around this limitation.
+ *
+ * You have been warned.
+ */
+void rcu_irq_exit(void)
+{
+       unsigned long flags;
+       long long oldval;
+       struct rcu_dynticks *rdtp;
+
+       local_irq_save(flags);
+       rdtp = this_cpu_ptr(&rcu_dynticks);
+       oldval = rdtp->dynticks_nesting;
+       rdtp->dynticks_nesting--;
+       WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
+       if (rdtp->dynticks_nesting)
+               trace_rcu_dyntick(TPS("--="), oldval, rdtp->dynticks_nesting);
+       else
+               rcu_eqs_enter_common(rdtp, oldval, true);
+       rcu_sysidle_enter(rdtp, 1);
+       local_irq_restore(flags);
+}
+
+/*
+ * rcu_eqs_exit_common - current CPU moving away from extended quiescent state
+ *
+ * If the new value of the ->dynticks_nesting counter was previously zero,
+ * we really have exited idle, and must do the appropriate accounting.
+ * The caller must have disabled interrupts.
+ */
+static void rcu_eqs_exit_common(struct rcu_dynticks *rdtp, long long oldval,
+                              int user)
+{
+       smp_mb__before_atomic_inc();  /* Force ordering w/previous sojourn. */
+       atomic_inc(&rdtp->dynticks);
+       /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
+       smp_mb__after_atomic_inc();  /* See above. */
+       WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
+       rcu_cleanup_after_idle(smp_processor_id());
+       trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting);
+       if (!user && !is_idle_task(current)) {
+               struct task_struct *idle __maybe_unused =
+                       idle_task(smp_processor_id());
+
+               trace_rcu_dyntick(TPS("Error on exit: not idle task"),
+                                 oldval, rdtp->dynticks_nesting);
+               ftrace_dump(DUMP_ORIG);
+               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
+                         current->pid, current->comm,
+                         idle->pid, idle->comm); /* must be idle task! */
+       }
+}
+
+/*
+ * Exit an RCU extended quiescent state, which can be either the
+ * idle loop or adaptive-tickless usermode execution.
+ */
+static void rcu_eqs_exit(bool user)
+{
+       struct rcu_dynticks *rdtp;
+       long long oldval;
+
+       rdtp = this_cpu_ptr(&rcu_dynticks);
+       oldval = rdtp->dynticks_nesting;
+       WARN_ON_ONCE(oldval < 0);
+       if (oldval & DYNTICK_TASK_NEST_MASK)
+               rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE;
+       else
+               rdtp->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
+       rcu_eqs_exit_common(rdtp, oldval, user);
+}
+
+/**
+ * rcu_idle_exit - inform RCU that current CPU is leaving idle
+ *
+ * Exit idle mode, in other words, -enter- the mode in which RCU
+ * read-side critical sections can occur.
+ *
+ * We crowbar the ->dynticks_nesting field to DYNTICK_TASK_NEST to
+ * allow for the possibility of usermode upcalls messing up our count
+ * of interrupt nesting level during the busy period that is just
+ * now starting.
+ */
+void rcu_idle_exit(void)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       rcu_eqs_exit(false);
+       rcu_sysidle_exit(this_cpu_ptr(&rcu_dynticks), 0);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(rcu_idle_exit);
+
+#ifdef CONFIG_RCU_USER_QS
+/**
+ * rcu_user_exit - inform RCU that we are exiting userspace.
+ *
+ * Exit RCU idle mode while entering the kernel because it can
+ * run a RCU read side critical section anytime.
+ */
+void rcu_user_exit(void)
+{
+       rcu_eqs_exit(1);
+}
+#endif /* CONFIG_RCU_USER_QS */
+
+/**
+ * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle
+ *
+ * Enter an interrupt handler, which might possibly result in exiting
+ * idle mode, in other words, entering the mode in which read-side critical
+ * sections can occur.
+ *
+ * Note that the Linux kernel is fully capable of entering an interrupt
+ * handler that it never exits, for example when doing upcalls to
+ * user mode!  This code assumes that the idle loop never does upcalls to
+ * user mode.  If your architecture does do upcalls from the idle loop (or
+ * does anything else that results in unbalanced calls to the irq_enter()
+ * and irq_exit() functions), RCU will give you what you deserve, good
+ * and hard.  But very infrequently and irreproducibly.
+ *
+ * Use things like work queues to work around this limitation.
+ *
+ * You have been warned.
+ */
+void rcu_irq_enter(void)
+{
+       unsigned long flags;
+       struct rcu_dynticks *rdtp;
+       long long oldval;
+
+       local_irq_save(flags);
+       rdtp = this_cpu_ptr(&rcu_dynticks);
+       oldval = rdtp->dynticks_nesting;
+       rdtp->dynticks_nesting++;
+       WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
+       if (oldval)
+               trace_rcu_dyntick(TPS("++="), oldval, rdtp->dynticks_nesting);
+       else
+               rcu_eqs_exit_common(rdtp, oldval, true);
+       rcu_sysidle_exit(rdtp, 1);
+       local_irq_restore(flags);
+}
+
+/**
+ * rcu_nmi_enter - inform RCU of entry to NMI context
+ *
+ * If the CPU was idle with dynamic ticks active, and there is no
+ * irq handler running, this updates rdtp->dynticks_nmi to let the
+ * RCU grace-period handling know that the CPU is active.
+ */
+void rcu_nmi_enter(void)
+{
+       struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
+
+       if (rdtp->dynticks_nmi_nesting == 0 &&
+           (atomic_read(&rdtp->dynticks) & 0x1))
+               return;
+       rdtp->dynticks_nmi_nesting++;
+       smp_mb__before_atomic_inc();  /* Force delay from prior write. */
+       atomic_inc(&rdtp->dynticks);
+       /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
+       smp_mb__after_atomic_inc();  /* See above. */
+       WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
+}
+
+/**
+ * rcu_nmi_exit - inform RCU of exit from NMI context
+ *
+ * If the CPU was idle with dynamic ticks active, and there is no
+ * irq handler running, this updates rdtp->dynticks_nmi to let the
+ * RCU grace-period handling know that the CPU is no longer active.
+ */
+void rcu_nmi_exit(void)
+{
+       struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
+
+       if (rdtp->dynticks_nmi_nesting == 0 ||
+           --rdtp->dynticks_nmi_nesting != 0)
+               return;
+       /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
+       smp_mb__before_atomic_inc();  /* See above. */
+       atomic_inc(&rdtp->dynticks);
+       smp_mb__after_atomic_inc();  /* Force delay to next write. */
+       WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
+}
+
+/**
+ * __rcu_is_watching - are RCU read-side critical sections safe?
+ *
+ * Return true if RCU is watching the running CPU, which means that
+ * this CPU can safely enter RCU read-side critical sections.  Unlike
+ * rcu_is_watching(), the caller of __rcu_is_watching() must have at
+ * least disabled preemption.
+ */
+bool __rcu_is_watching(void)
+{
+       return atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1;
+}
+
+/**
+ * rcu_is_watching - see if RCU thinks that the current CPU is idle
+ *
+ * If the current CPU is in its idle loop and is neither in an interrupt
+ * or NMI handler, return true.
+ */
+bool rcu_is_watching(void)
+{
+       int ret;
+
+       preempt_disable();
+       ret = __rcu_is_watching();
+       preempt_enable();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rcu_is_watching);
+
+#if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU)
+
+/*
+ * Is the current CPU online?  Disable preemption to avoid false positives
+ * that could otherwise happen due to the current CPU number being sampled,
+ * this task being preempted, its old CPU being taken offline, resuming
+ * on some other CPU, then determining that its old CPU is now offline.
+ * It is OK to use RCU on an offline processor during initial boot, hence
+ * the check for rcu_scheduler_fully_active.  Note also that it is OK
+ * for a CPU coming online to use RCU for one jiffy prior to marking itself
+ * online in the cpu_online_mask.  Similarly, it is OK for a CPU going
+ * offline to continue to use RCU for one jiffy after marking itself
+ * offline in the cpu_online_mask.  This leniency is necessary given the
+ * non-atomic nature of the online and offline processing, for example,
+ * the fact that a CPU enters the scheduler after completing the CPU_DYING
+ * notifiers.
+ *
+ * This is also why RCU internally marks CPUs online during the
+ * CPU_UP_PREPARE phase and offline during the CPU_DEAD phase.
+ *
+ * Disable checking if in an NMI handler because we cannot safely report
+ * errors from NMI handlers anyway.
+ */
+bool rcu_lockdep_current_cpu_online(void)
+{
+       struct rcu_data *rdp;
+       struct rcu_node *rnp;
+       bool ret;
+
+       if (in_nmi())
+               return 1;
+       preempt_disable();
+       rdp = this_cpu_ptr(&rcu_sched_data);
+       rnp = rdp->mynode;
+       ret = (rdp->grpmask & rnp->qsmaskinit) ||
+             !rcu_scheduler_fully_active;
+       preempt_enable();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online);
+
+#endif /* #if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU) */
+
+/**
+ * rcu_is_cpu_rrupt_from_idle - see if idle or immediately interrupted from idle
+ *
+ * If the current CPU is idle or running at a first-level (not nested)
+ * interrupt from idle, return true.  The caller must have at least
+ * disabled preemption.
+ */
+static int rcu_is_cpu_rrupt_from_idle(void)
+{
+       return __this_cpu_read(rcu_dynticks.dynticks_nesting) <= 1;
+}
+
+/*
+ * Snapshot the specified CPU's dynticks counter so that we can later
+ * credit them with an implicit quiescent state.  Return 1 if this CPU
+ * is in dynticks idle mode, which is an extended quiescent state.
+ */
+static int dyntick_save_progress_counter(struct rcu_data *rdp,
+                                        bool *isidle, unsigned long *maxj)
+{
+       rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks);
+       rcu_sysidle_check_cpu(rdp, isidle, maxj);
+       return (rdp->dynticks_snap & 0x1) == 0;
+}
+
+/*
+ * Return true if the specified CPU has passed through a quiescent
+ * state by virtue of being in or having passed through an dynticks
+ * idle state since the last call to dyntick_save_progress_counter()
+ * for this same CPU, or by virtue of having been offline.
+ */
+static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
+                                   bool *isidle, unsigned long *maxj)
+{
+       unsigned int curr;
+       unsigned int snap;
+
+       curr = (unsigned int)atomic_add_return(0, &rdp->dynticks->dynticks);
+       snap = (unsigned int)rdp->dynticks_snap;
+
+       /*
+        * If the CPU passed through or entered a dynticks idle phase with
+        * no active irq/NMI handlers, then we can safely pretend that the CPU
+        * already acknowledged the request to pass through a quiescent
+        * state.  Either way, that CPU cannot possibly be in an RCU
+        * read-side critical section that started before the beginning
+        * of the current RCU grace period.
+        */
+       if ((curr & 0x1) == 0 || UINT_CMP_GE(curr, snap + 2)) {
+               trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
+               rdp->dynticks_fqs++;
+               return 1;
+       }
+
+       /*
+        * Check for the CPU being offline, but only if the grace period
+        * is old enough.  We don't need to worry about the CPU changing
+        * state: If we see it offline even once, it has been through a
+        * quiescent state.
+        *
+        * The reason for insisting that the grace period be at least
+        * one jiffy old is that CPUs that are not quite online and that
+        * have just gone offline can still execute RCU read-side critical
+        * sections.
+        */
+       if (ULONG_CMP_GE(rdp->rsp->gp_start + 2, jiffies))
+               return 0;  /* Grace period is not old enough. */
+       barrier();
+       if (cpu_is_offline(rdp->cpu)) {
+               trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl"));
+               rdp->offline_fqs++;
+               return 1;
+       }
+
+       /*
+        * There is a possibility that a CPU in adaptive-ticks state
+        * might run in the kernel with the scheduling-clock tick disabled
+        * for an extended time period.  Invoke rcu_kick_nohz_cpu() to
+        * force the CPU to restart the scheduling-clock tick in this
+        * CPU is in this state.
+        */
+       rcu_kick_nohz_cpu(rdp->cpu);
+
+       return 0;
+}
+
+static void record_gp_stall_check_time(struct rcu_state *rsp)
+{
+       unsigned long j = ACCESS_ONCE(jiffies);
+
+       rsp->gp_start = j;
+       smp_wmb(); /* Record start time before stall time. */
+       rsp->jiffies_stall = j + rcu_jiffies_till_stall_check();
+}
+
+/*
+ * Dump stacks of all tasks running on stalled CPUs.  This is a fallback
+ * for architectures that do not implement trigger_all_cpu_backtrace().
+ * The NMI-triggered stack traces are more accurate because they are
+ * printed by the target CPU.
+ */
+static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
+{
+       int cpu;
+       unsigned long flags;
+       struct rcu_node *rnp;
+
+       rcu_for_each_leaf_node(rsp, rnp) {
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               if (rnp->qsmask != 0) {
+                       for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
+                               if (rnp->qsmask & (1UL << cpu))
+                                       dump_cpu_task(rnp->grplo + cpu);
+               }
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       }
+}
+
+static void print_other_cpu_stall(struct rcu_state *rsp)
+{
+       int cpu;
+       long delta;
+       unsigned long flags;
+       int ndetected = 0;
+       struct rcu_node *rnp = rcu_get_root(rsp);
+       long totqlen = 0;
+
+       /* Only let one CPU complain about others per time interval. */
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       delta = jiffies - rsp->jiffies_stall;
+       if (delta < RCU_STALL_RAT_DELAY || !rcu_gp_in_progress(rsp)) {
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               return;
+       }
+       rsp->jiffies_stall = jiffies + 3 * rcu_jiffies_till_stall_check() + 3;
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+
+       /*
+        * OK, time to rat on our buddy...
+        * See Documentation/RCU/stallwarn.txt for info on how to debug
+        * RCU CPU stall warnings.
+        */
+       pr_err("INFO: %s detected stalls on CPUs/tasks:",
+              rsp->name);
+       print_cpu_stall_info_begin();
+       rcu_for_each_leaf_node(rsp, rnp) {
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               ndetected += rcu_print_task_stall(rnp);
+               if (rnp->qsmask != 0) {
+                       for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
+                               if (rnp->qsmask & (1UL << cpu)) {
+                                       print_cpu_stall_info(rsp,
+                                                            rnp->grplo + cpu);
+                                       ndetected++;
+                               }
+               }
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       }
+
+       /*
+        * Now rat on any tasks that got kicked up to the root rcu_node
+        * due to CPU offlining.
+        */
+       rnp = rcu_get_root(rsp);
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       ndetected += rcu_print_task_stall(rnp);
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+
+       print_cpu_stall_info_end();
+       for_each_possible_cpu(cpu)
+               totqlen += per_cpu_ptr(rsp->rda, cpu)->qlen;
+       pr_cont("(detected by %d, t=%ld jiffies, g=%lu, c=%lu, q=%lu)\n",
+              smp_processor_id(), (long)(jiffies - rsp->gp_start),
+              rsp->gpnum, rsp->completed, totqlen);
+       if (ndetected == 0)
+               pr_err("INFO: Stall ended before state dump start\n");
+       else if (!trigger_all_cpu_backtrace())
+               rcu_dump_cpu_stacks(rsp);
+
+       /* Complain about tasks blocking the grace period. */
+
+       rcu_print_detail_task_stall(rsp);
+
+       force_quiescent_state(rsp);  /* Kick them all. */
+}
+
+/*
+ * This function really isn't for public consumption, but RCU is special in
+ * that context switches can allow the state machine to make progress.
+ */
+extern void resched_cpu(int cpu);
+
+static void print_cpu_stall(struct rcu_state *rsp)
+{
+       int cpu;
+       unsigned long flags;
+       struct rcu_node *rnp = rcu_get_root(rsp);
+       long totqlen = 0;
+
+       /*
+        * OK, time to rat on ourselves...
+        * See Documentation/RCU/stallwarn.txt for info on how to debug
+        * RCU CPU stall warnings.
+        */
+       pr_err("INFO: %s self-detected stall on CPU", rsp->name);
+       print_cpu_stall_info_begin();
+       print_cpu_stall_info(rsp, smp_processor_id());
+       print_cpu_stall_info_end();
+       for_each_possible_cpu(cpu)
+               totqlen += per_cpu_ptr(rsp->rda, cpu)->qlen;
+       pr_cont(" (t=%lu jiffies g=%lu c=%lu q=%lu)\n",
+               jiffies - rsp->gp_start, rsp->gpnum, rsp->completed, totqlen);
+       if (!trigger_all_cpu_backtrace())
+               dump_stack();
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
+               rsp->jiffies_stall = jiffies +
+                                    3 * rcu_jiffies_till_stall_check() + 3;
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+
+       /*
+        * Attempt to revive the RCU machinery by forcing a context switch.
+        *
+        * A context switch would normally allow the RCU state machine to make
+        * progress and it could be we're stuck in kernel space without context
+        * switches for an entirely unreasonable amount of time.
+        */
+       resched_cpu(smp_processor_id());
+}
+
+static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       unsigned long completed;
+       unsigned long gpnum;
+       unsigned long gps;
+       unsigned long j;
+       unsigned long js;
+       struct rcu_node *rnp;
+
+       if (rcu_cpu_stall_suppress || !rcu_gp_in_progress(rsp))
+               return;
+       j = ACCESS_ONCE(jiffies);
+
+       /*
+        * Lots of memory barriers to reject false positives.
+        *
+        * The idea is to pick up rsp->gpnum, then rsp->jiffies_stall,
+        * then rsp->gp_start, and finally rsp->completed.  These values
+        * are updated in the opposite order with memory barriers (or
+        * equivalent) during grace-period initialization and cleanup.
+        * Now, a false positive can occur if we get an new value of
+        * rsp->gp_start and a old value of rsp->jiffies_stall.  But given
+        * the memory barriers, the only way that this can happen is if one
+        * grace period ends and another starts between these two fetches.
+        * Detect this by comparing rsp->completed with the previous fetch
+        * from rsp->gpnum.
+        *
+        * Given this check, comparisons of jiffies, rsp->jiffies_stall,
+        * and rsp->gp_start suffice to forestall false positives.
+        */
+       gpnum = ACCESS_ONCE(rsp->gpnum);
+       smp_rmb(); /* Pick up ->gpnum first... */
+       js = ACCESS_ONCE(rsp->jiffies_stall);
+       smp_rmb(); /* ...then ->jiffies_stall before the rest... */
+       gps = ACCESS_ONCE(rsp->gp_start);
+       smp_rmb(); /* ...and finally ->gp_start before ->completed. */
+       completed = ACCESS_ONCE(rsp->completed);
+       if (ULONG_CMP_GE(completed, gpnum) ||
+           ULONG_CMP_LT(j, js) ||
+           ULONG_CMP_GE(gps, js))
+               return; /* No stall or GP completed since entering function. */
+       rnp = rdp->mynode;
+       if (rcu_gp_in_progress(rsp) &&
+           (ACCESS_ONCE(rnp->qsmask) & rdp->grpmask)) {
+
+               /* We haven't checked in, so go dump stack. */
+               print_cpu_stall(rsp);
+
+       } else if (rcu_gp_in_progress(rsp) &&
+                  ULONG_CMP_GE(j, js + RCU_STALL_RAT_DELAY)) {
+
+               /* They had a few time units to dump stack, so complain. */
+               print_other_cpu_stall(rsp);
+       }
+}
+
+/**
+ * rcu_cpu_stall_reset - prevent further stall warnings in current grace period
+ *
+ * Set the stall-warning timeout way off into the future, thus preventing
+ * any RCU CPU stall-warning messages from appearing in the current set of
+ * RCU grace periods.
+ *
+ * The caller must disable hard irqs.
+ */
+void rcu_cpu_stall_reset(void)
+{
+       struct rcu_state *rsp;
+
+       for_each_rcu_flavor(rsp)
+               rsp->jiffies_stall = jiffies + ULONG_MAX / 2;
+}
+
+/*
+ * Initialize the specified rcu_data structure's callback list to empty.
+ */
+static void init_callback_list(struct rcu_data *rdp)
+{
+       int i;
+
+       if (init_nocb_callback_list(rdp))
+               return;
+       rdp->nxtlist = NULL;
+       for (i = 0; i < RCU_NEXT_SIZE; i++)
+               rdp->nxttail[i] = &rdp->nxtlist;
+}
+
+/*
+ * Determine the value that ->completed will have at the end of the
+ * next subsequent grace period.  This is used to tag callbacks so that
+ * a CPU can invoke callbacks in a timely fashion even if that CPU has
+ * been dyntick-idle for an extended period with callbacks under the
+ * influence of RCU_FAST_NO_HZ.
+ *
+ * The caller must hold rnp->lock with interrupts disabled.
+ */
+static unsigned long rcu_cbs_completed(struct rcu_state *rsp,
+                                      struct rcu_node *rnp)
+{
+       /*
+        * If RCU is idle, we just wait for the next grace period.
+        * But we can only be sure that RCU is idle if we are looking
+        * at the root rcu_node structure -- otherwise, a new grace
+        * period might have started, but just not yet gotten around
+        * to initializing the current non-root rcu_node structure.
+        */
+       if (rcu_get_root(rsp) == rnp && rnp->gpnum == rnp->completed)
+               return rnp->completed + 1;
+
+       /*
+        * Otherwise, wait for a possible partial grace period and
+        * then the subsequent full grace period.
+        */
+       return rnp->completed + 2;
+}
+
+/*
+ * Trace-event helper function for rcu_start_future_gp() and
+ * rcu_nocb_wait_gp().
+ */
+static void trace_rcu_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
+                               unsigned long c, const char *s)
+{
+       trace_rcu_future_grace_period(rdp->rsp->name, rnp->gpnum,
+                                     rnp->completed, c, rnp->level,
+                                     rnp->grplo, rnp->grphi, s);
+}
+
+/*
+ * Start some future grace period, as needed to handle newly arrived
+ * callbacks.  The required future grace periods are recorded in each
+ * rcu_node structure's ->need_future_gp field.
+ *
+ * The caller must hold the specified rcu_node structure's ->lock.
+ */
+static unsigned long __maybe_unused
+rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp)
+{
+       unsigned long c;
+       int i;
+       struct rcu_node *rnp_root = rcu_get_root(rdp->rsp);
+
+       /*
+        * Pick up grace-period number for new callbacks.  If this
+        * grace period is already marked as needed, return to the caller.
+        */
+       c = rcu_cbs_completed(rdp->rsp, rnp);
+       trace_rcu_future_gp(rnp, rdp, c, TPS("Startleaf"));
+       if (rnp->need_future_gp[c & 0x1]) {
+               trace_rcu_future_gp(rnp, rdp, c, TPS("Prestartleaf"));
+               return c;
+       }
+
+       /*
+        * If either this rcu_node structure or the root rcu_node structure
+        * believe that a grace period is in progress, then we must wait
+        * for the one following, which is in "c".  Because our request
+        * will be noticed at the end of the current grace period, we don't
+        * need to explicitly start one.
+        */
+       if (rnp->gpnum != rnp->completed ||
+           ACCESS_ONCE(rnp->gpnum) != ACCESS_ONCE(rnp->completed)) {
+               rnp->need_future_gp[c & 0x1]++;
+               trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf"));
+               return c;
+       }
+
+       /*
+        * There might be no grace period in progress.  If we don't already
+        * hold it, acquire the root rcu_node structure's lock in order to
+        * start one (if needed).
+        */
+       if (rnp != rnp_root)
+               raw_spin_lock(&rnp_root->lock);
+
+       /*
+        * Get a new grace-period number.  If there really is no grace
+        * period in progress, it will be smaller than the one we obtained
+        * earlier.  Adjust callbacks as needed.  Note that even no-CBs
+        * CPUs have a ->nxtcompleted[] array, so no no-CBs checks needed.
+        */
+       c = rcu_cbs_completed(rdp->rsp, rnp_root);
+       for (i = RCU_DONE_TAIL; i < RCU_NEXT_TAIL; i++)
+               if (ULONG_CMP_LT(c, rdp->nxtcompleted[i]))
+                       rdp->nxtcompleted[i] = c;
+
+       /*
+        * If the needed for the required grace period is already
+        * recorded, trace and leave.
+        */
+       if (rnp_root->need_future_gp[c & 0x1]) {
+               trace_rcu_future_gp(rnp, rdp, c, TPS("Prestartedroot"));
+               goto unlock_out;
+       }
+
+       /* Record the need for the future grace period. */
+       rnp_root->need_future_gp[c & 0x1]++;
+
+       /* If a grace period is not already in progress, start one. */
+       if (rnp_root->gpnum != rnp_root->completed) {
+               trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleafroot"));
+       } else {
+               trace_rcu_future_gp(rnp, rdp, c, TPS("Startedroot"));
+               rcu_start_gp_advanced(rdp->rsp, rnp_root, rdp);
+       }
+unlock_out:
+       if (rnp != rnp_root)
+               raw_spin_unlock(&rnp_root->lock);
+       return c;
+}
+
+/*
+ * Clean up any old requests for the just-ended grace period.  Also return
+ * whether any additional grace periods have been requested.  Also invoke
+ * rcu_nocb_gp_cleanup() in order to wake up any no-callbacks kthreads
+ * waiting for this grace period to complete.
+ */
+static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+       int c = rnp->completed;
+       int needmore;
+       struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
+
+       rcu_nocb_gp_cleanup(rsp, rnp);
+       rnp->need_future_gp[c & 0x1] = 0;
+       needmore = rnp->need_future_gp[(c + 1) & 0x1];
+       trace_rcu_future_gp(rnp, rdp, c,
+                           needmore ? TPS("CleanupMore") : TPS("Cleanup"));
+       return needmore;
+}
+
+/*
+ * If there is room, assign a ->completed number to any callbacks on
+ * this CPU that have not already been assigned.  Also accelerate any
+ * callbacks that were previously assigned a ->completed number that has
+ * since proven to be too conservative, which can happen if callbacks get
+ * assigned a ->completed number while RCU is idle, but with reference to
+ * a non-root rcu_node structure.  This function is idempotent, so it does
+ * not hurt to call it repeatedly.
+ *
+ * The caller must hold rnp->lock with interrupts disabled.
+ */
+static void rcu_accelerate_cbs(struct rcu_state *rsp, struct rcu_node *rnp,
+                              struct rcu_data *rdp)
+{
+       unsigned long c;
+       int i;
+
+       /* If the CPU has no callbacks, nothing to do. */
+       if (!rdp->nxttail[RCU_NEXT_TAIL] || !*rdp->nxttail[RCU_DONE_TAIL])
+               return;
+
+       /*
+        * Starting from the sublist containing the callbacks most
+        * recently assigned a ->completed number and working down, find the
+        * first sublist that is not assignable to an upcoming grace period.
+        * Such a sublist has something in it (first two tests) and has
+        * a ->completed number assigned that will complete sooner than
+        * the ->completed number for newly arrived callbacks (last test).
+        *
+        * The key point is that any later sublist can be assigned the
+        * same ->completed number as the newly arrived callbacks, which
+        * means that the callbacks in any of these later sublist can be
+        * grouped into a single sublist, whether or not they have already
+        * been assigned a ->completed number.
+        */
+       c = rcu_cbs_completed(rsp, rnp);
+       for (i = RCU_NEXT_TAIL - 1; i > RCU_DONE_TAIL; i--)
+               if (rdp->nxttail[i] != rdp->nxttail[i - 1] &&
+                   !ULONG_CMP_GE(rdp->nxtcompleted[i], c))
+                       break;
+
+       /*
+        * If there are no sublist for unassigned callbacks, leave.
+        * At the same time, advance "i" one sublist, so that "i" will
+        * index into the sublist where all the remaining callbacks should
+        * be grouped into.
+        */
+       if (++i >= RCU_NEXT_TAIL)
+               return;
+
+       /*
+        * Assign all subsequent callbacks' ->completed number to the next
+        * full grace period and group them all in the sublist initially
+        * indexed by "i".
+        */
+       for (; i <= RCU_NEXT_TAIL; i++) {
+               rdp->nxttail[i] = rdp->nxttail[RCU_NEXT_TAIL];
+               rdp->nxtcompleted[i] = c;
+       }
+       /* Record any needed additional grace periods. */
+       rcu_start_future_gp(rnp, rdp);
+
+       /* Trace depending on how much we were able to accelerate. */
+       if (!*rdp->nxttail[RCU_WAIT_TAIL])
+               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("AccWaitCB"));
+       else
+               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("AccReadyCB"));
+}
+
+/*
+ * Move any callbacks whose grace period has completed to the
+ * RCU_DONE_TAIL sublist, then compact the remaining sublists and
+ * assign ->completed numbers to any callbacks in the RCU_NEXT_TAIL
+ * sublist.  This function is idempotent, so it does not hurt to
+ * invoke it repeatedly.  As long as it is not invoked -too- often...
+ *
+ * The caller must hold rnp->lock with interrupts disabled.
+ */
+static void rcu_advance_cbs(struct rcu_state *rsp, struct rcu_node *rnp,
+                           struct rcu_data *rdp)
+{
+       int i, j;
+
+       /* If the CPU has no callbacks, nothing to do. */
+       if (!rdp->nxttail[RCU_NEXT_TAIL] || !*rdp->nxttail[RCU_DONE_TAIL])
+               return;
+
+       /*
+        * Find all callbacks whose ->completed numbers indicate that they
+        * are ready to invoke, and put them into the RCU_DONE_TAIL sublist.
+        */
+       for (i = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++) {
+               if (ULONG_CMP_LT(rnp->completed, rdp->nxtcompleted[i]))
+                       break;
+               rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[i];
+       }
+       /* Clean up any sublist tail pointers that were misordered above. */
+       for (j = RCU_WAIT_TAIL; j < i; j++)
+               rdp->nxttail[j] = rdp->nxttail[RCU_DONE_TAIL];
+
+       /* Copy down callbacks to fill in empty sublists. */
+       for (j = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++, j++) {
+               if (rdp->nxttail[j] == rdp->nxttail[RCU_NEXT_TAIL])
+                       break;
+               rdp->nxttail[j] = rdp->nxttail[i];
+               rdp->nxtcompleted[j] = rdp->nxtcompleted[i];
+       }
+
+       /* Classify any remaining callbacks. */
+       rcu_accelerate_cbs(rsp, rnp, rdp);
+}
+
+/*
+ * Update CPU-local rcu_data state to record the beginnings and ends of
+ * grace periods.  The caller must hold the ->lock of the leaf rcu_node
+ * structure corresponding to the current CPU, and must have irqs disabled.
+ */
+static void __note_gp_changes(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+       /* Handle the ends of any preceding grace periods first. */
+       if (rdp->completed == rnp->completed) {
+
+               /* No grace period end, so just accelerate recent callbacks. */
+               rcu_accelerate_cbs(rsp, rnp, rdp);
+
+       } else {
+
+               /* Advance callbacks. */
+               rcu_advance_cbs(rsp, rnp, rdp);
+
+               /* Remember that we saw this grace-period completion. */
+               rdp->completed = rnp->completed;
+               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuend"));
+       }
+
+       if (rdp->gpnum != rnp->gpnum) {
+               /*
+                * If the current grace period is waiting for this CPU,
+                * set up to detect a quiescent state, otherwise don't
+                * go looking for one.
+                */
+               rdp->gpnum = rnp->gpnum;
+               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpustart"));
+               rdp->passed_quiesce = 0;
+               rdp->qs_pending = !!(rnp->qsmask & rdp->grpmask);
+               zero_cpu_stall_ticks(rdp);
+       }
+}
+
+static void note_gp_changes(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       unsigned long flags;
+       struct rcu_node *rnp;
+
+       local_irq_save(flags);
+       rnp = rdp->mynode;
+       if ((rdp->gpnum == ACCESS_ONCE(rnp->gpnum) &&
+            rdp->completed == ACCESS_ONCE(rnp->completed)) || /* w/out lock. */
+           !raw_spin_trylock(&rnp->lock)) { /* irqs already off, so later. */
+               local_irq_restore(flags);
+               return;
+       }
+       __note_gp_changes(rsp, rnp, rdp);
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Initialize a new grace period.  Return 0 if no grace period required.
+ */
+static int rcu_gp_init(struct rcu_state *rsp)
+{
+       struct rcu_data *rdp;
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       rcu_bind_gp_kthread();
+       raw_spin_lock_irq(&rnp->lock);
+       if (rsp->gp_flags == 0) {
+               /* Spurious wakeup, tell caller to go back to sleep.  */
+               raw_spin_unlock_irq(&rnp->lock);
+               return 0;
+       }
+       rsp->gp_flags = 0; /* Clear all flags: New grace period. */
+
+       if (WARN_ON_ONCE(rcu_gp_in_progress(rsp))) {
+               /*
+                * Grace period already in progress, don't start another.
+                * Not supposed to be able to happen.
+                */
+               raw_spin_unlock_irq(&rnp->lock);
+               return 0;
+       }
+
+       /* Advance to a new grace period and initialize state. */
+       record_gp_stall_check_time(rsp);
+       smp_wmb(); /* Record GP times before starting GP. */
+       rsp->gpnum++;
+       trace_rcu_grace_period(rsp->name, rsp->gpnum, TPS("start"));
+       raw_spin_unlock_irq(&rnp->lock);
+
+       /* Exclude any concurrent CPU-hotplug operations. */
+       mutex_lock(&rsp->onoff_mutex);
+
+       /*
+        * Set the quiescent-state-needed bits in all the rcu_node
+        * structures for all currently online CPUs in breadth-first order,
+        * starting from the root rcu_node structure, relying on the layout
+        * of the tree within the rsp->node[] array.  Note that other CPUs
+        * will access only the leaves of the hierarchy, thus seeing that no
+        * grace period is in progress, at least until the corresponding
+        * leaf node has been initialized.  In addition, we have excluded
+        * CPU-hotplug operations.
+        *
+        * The grace period cannot complete until the initialization
+        * process finishes, because this kthread handles both.
+        */
+       rcu_for_each_node_breadth_first(rsp, rnp) {
+               raw_spin_lock_irq(&rnp->lock);
+               rdp = this_cpu_ptr(rsp->rda);
+               rcu_preempt_check_blocked_tasks(rnp);
+               rnp->qsmask = rnp->qsmaskinit;
+               ACCESS_ONCE(rnp->gpnum) = rsp->gpnum;
+               WARN_ON_ONCE(rnp->completed != rsp->completed);
+               ACCESS_ONCE(rnp->completed) = rsp->completed;
+               if (rnp == rdp->mynode)
+                       __note_gp_changes(rsp, rnp, rdp);
+               rcu_preempt_boost_start_gp(rnp);
+               trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
+                                           rnp->level, rnp->grplo,
+                                           rnp->grphi, rnp->qsmask);
+               raw_spin_unlock_irq(&rnp->lock);
+#ifdef CONFIG_PROVE_RCU_DELAY
+               if ((prandom_u32() % (rcu_num_nodes + 1)) == 0 &&
+                   system_state == SYSTEM_RUNNING)
+                       udelay(200);
+#endif /* #ifdef CONFIG_PROVE_RCU_DELAY */
+               cond_resched();
+       }
+
+       mutex_unlock(&rsp->onoff_mutex);
+       return 1;
+}
+
+/*
+ * Do one round of quiescent-state forcing.
+ */
+static int rcu_gp_fqs(struct rcu_state *rsp, int fqs_state_in)
+{
+       int fqs_state = fqs_state_in;
+       bool isidle = false;
+       unsigned long maxj;
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       rsp->n_force_qs++;
+       if (fqs_state == RCU_SAVE_DYNTICK) {
+               /* Collect dyntick-idle snapshots. */
+               if (is_sysidle_rcu_state(rsp)) {
+                       isidle = 1;
+                       maxj = jiffies - ULONG_MAX / 4;
+               }
+               force_qs_rnp(rsp, dyntick_save_progress_counter,
+                            &isidle, &maxj);
+               rcu_sysidle_report_gp(rsp, isidle, maxj);
+               fqs_state = RCU_FORCE_QS;
+       } else {
+               /* Handle dyntick-idle and offline CPUs. */
+               isidle = 0;
+               force_qs_rnp(rsp, rcu_implicit_dynticks_qs, &isidle, &maxj);
+       }
+       /* Clear flag to prevent immediate re-entry. */
+       if (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) {
+               raw_spin_lock_irq(&rnp->lock);
+               rsp->gp_flags &= ~RCU_GP_FLAG_FQS;
+               raw_spin_unlock_irq(&rnp->lock);
+       }
+       return fqs_state;
+}
+
+/*
+ * Clean up after the old grace period.
+ */
+static void rcu_gp_cleanup(struct rcu_state *rsp)
+{
+       unsigned long gp_duration;
+       int nocb = 0;
+       struct rcu_data *rdp;
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       raw_spin_lock_irq(&rnp->lock);
+       gp_duration = jiffies - rsp->gp_start;
+       if (gp_duration > rsp->gp_max)
+               rsp->gp_max = gp_duration;
+
+       /*
+        * We know the grace period is complete, but to everyone else
+        * it appears to still be ongoing.  But it is also the case
+        * that to everyone else it looks like there is nothing that
+        * they can do to advance the grace period.  It is therefore
+        * safe for us to drop the lock in order to mark the grace
+        * period as completed in all of the rcu_node structures.
+        */
+       raw_spin_unlock_irq(&rnp->lock);
+
+       /*
+        * Propagate new ->completed value to rcu_node structures so
+        * that other CPUs don't have to wait until the start of the next
+        * grace period to process their callbacks.  This also avoids
+        * some nasty RCU grace-period initialization races by forcing
+        * the end of the current grace period to be completely recorded in
+        * all of the rcu_node structures before the beginning of the next
+        * grace period is recorded in any of the rcu_node structures.
+        */
+       rcu_for_each_node_breadth_first(rsp, rnp) {
+               raw_spin_lock_irq(&rnp->lock);
+               ACCESS_ONCE(rnp->completed) = rsp->gpnum;
+               rdp = this_cpu_ptr(rsp->rda);
+               if (rnp == rdp->mynode)
+                       __note_gp_changes(rsp, rnp, rdp);
+               nocb += rcu_future_gp_cleanup(rsp, rnp);
+               raw_spin_unlock_irq(&rnp->lock);
+               cond_resched();
+       }
+       rnp = rcu_get_root(rsp);
+       raw_spin_lock_irq(&rnp->lock);
+       rcu_nocb_gp_set(rnp, nocb);
+
+       rsp->completed = rsp->gpnum; /* Declare grace period done. */
+       trace_rcu_grace_period(rsp->name, rsp->completed, TPS("end"));
+       rsp->fqs_state = RCU_GP_IDLE;
+       rdp = this_cpu_ptr(rsp->rda);
+       rcu_advance_cbs(rsp, rnp, rdp);  /* Reduce false positives below. */
+       if (cpu_needs_another_gp(rsp, rdp)) {
+               rsp->gp_flags = RCU_GP_FLAG_INIT;
+               trace_rcu_grace_period(rsp->name,
+                                      ACCESS_ONCE(rsp->gpnum),
+                                      TPS("newreq"));
+       }
+       raw_spin_unlock_irq(&rnp->lock);
+}
+
+/*
+ * Body of kthread that handles grace periods.
+ */
+static int __noreturn rcu_gp_kthread(void *arg)
+{
+       int fqs_state;
+       int gf;
+       unsigned long j;
+       int ret;
+       struct rcu_state *rsp = arg;
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       for (;;) {
+
+               /* Handle grace-period start. */
+               for (;;) {
+                       trace_rcu_grace_period(rsp->name,
+                                              ACCESS_ONCE(rsp->gpnum),
+                                              TPS("reqwait"));
+                       wait_event_interruptible(rsp->gp_wq,
+                                                ACCESS_ONCE(rsp->gp_flags) &
+                                                RCU_GP_FLAG_INIT);
+                       if (rcu_gp_init(rsp))
+                               break;
+                       cond_resched();
+                       flush_signals(current);
+                       trace_rcu_grace_period(rsp->name,
+                                              ACCESS_ONCE(rsp->gpnum),
+                                              TPS("reqwaitsig"));
+               }
+
+               /* Handle quiescent-state forcing. */
+               fqs_state = RCU_SAVE_DYNTICK;
+               j = jiffies_till_first_fqs;
+               if (j > HZ) {
+                       j = HZ;
+                       jiffies_till_first_fqs = HZ;
+               }
+               ret = 0;
+               for (;;) {
+                       if (!ret)
+                               rsp->jiffies_force_qs = jiffies + j;
+                       trace_rcu_grace_period(rsp->name,
+                                              ACCESS_ONCE(rsp->gpnum),
+                                              TPS("fqswait"));
+                       ret = wait_event_interruptible_timeout(rsp->gp_wq,
+                                       ((gf = ACCESS_ONCE(rsp->gp_flags)) &
+                                        RCU_GP_FLAG_FQS) ||
+                                       (!ACCESS_ONCE(rnp->qsmask) &&
+                                        !rcu_preempt_blocked_readers_cgp(rnp)),
+                                       j);
+                       /* If grace period done, leave loop. */
+                       if (!ACCESS_ONCE(rnp->qsmask) &&
+                           !rcu_preempt_blocked_readers_cgp(rnp))
+                               break;
+                       /* If time for quiescent-state forcing, do it. */
+                       if (ULONG_CMP_GE(jiffies, rsp->jiffies_force_qs) ||
+                           (gf & RCU_GP_FLAG_FQS)) {
+                               trace_rcu_grace_period(rsp->name,
+                                                      ACCESS_ONCE(rsp->gpnum),
+                                                      TPS("fqsstart"));
+                               fqs_state = rcu_gp_fqs(rsp, fqs_state);
+                               trace_rcu_grace_period(rsp->name,
+                                                      ACCESS_ONCE(rsp->gpnum),
+                                                      TPS("fqsend"));
+                               cond_resched();
+                       } else {
+                               /* Deal with stray signal. */
+                               cond_resched();
+                               flush_signals(current);
+                               trace_rcu_grace_period(rsp->name,
+                                                      ACCESS_ONCE(rsp->gpnum),
+                                                      TPS("fqswaitsig"));
+                       }
+                       j = jiffies_till_next_fqs;
+                       if (j > HZ) {
+                               j = HZ;
+                               jiffies_till_next_fqs = HZ;
+                       } else if (j < 1) {
+                               j = 1;
+                               jiffies_till_next_fqs = 1;
+                       }
+               }
+
+               /* Handle grace-period end. */
+               rcu_gp_cleanup(rsp);
+       }
+}
+
+static void rsp_wakeup(struct irq_work *work)
+{
+       struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work);
+
+       /* Wake up rcu_gp_kthread() to start the grace period. */
+       wake_up(&rsp->gp_wq);
+}
+
+/*
+ * Start a new RCU grace period if warranted, re-initializing the hierarchy
+ * in preparation for detecting the next grace period.  The caller must hold
+ * the root node's ->lock and hard irqs must be disabled.
+ *
+ * Note that it is legal for a dying CPU (which is marked as offline) to
+ * invoke this function.  This can happen when the dying CPU reports its
+ * quiescent state.
+ */
+static void
+rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
+                     struct rcu_data *rdp)
+{
+       if (!rsp->gp_kthread || !cpu_needs_another_gp(rsp, rdp)) {
+               /*
+                * Either we have not yet spawned the grace-period
+                * task, this CPU does not need another grace period,
+                * or a grace period is already in progress.
+                * Either way, don't start a new grace period.
+                */
+               return;
+       }
+       rsp->gp_flags = RCU_GP_FLAG_INIT;
+       trace_rcu_grace_period(rsp->name, ACCESS_ONCE(rsp->gpnum),
+                              TPS("newreq"));
+
+       /*
+        * We can't do wakeups while holding the rnp->lock, as that
+        * could cause possible deadlocks with the rq->lock. Defer
+        * the wakeup to interrupt context.  And don't bother waking
+        * up the running kthread.
+        */
+       if (current != rsp->gp_kthread)
+               irq_work_queue(&rsp->wakeup_work);
+}
+
+/*
+ * Similar to rcu_start_gp_advanced(), but also advance the calling CPU's
+ * callbacks.  Note that rcu_start_gp_advanced() cannot do this because it
+ * is invoked indirectly from rcu_advance_cbs(), which would result in
+ * endless recursion -- or would do so if it wasn't for the self-deadlock
+ * that is encountered beforehand.
+ */
+static void
+rcu_start_gp(struct rcu_state *rsp)
+{
+       struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       /*
+        * If there is no grace period in progress right now, any
+        * callbacks we have up to this point will be satisfied by the
+        * next grace period.  Also, advancing the callbacks reduces the
+        * probability of false positives from cpu_needs_another_gp()
+        * resulting in pointless grace periods.  So, advance callbacks
+        * then start the grace period!
+        */
+       rcu_advance_cbs(rsp, rnp, rdp);
+       rcu_start_gp_advanced(rsp, rnp, rdp);
+}
+
+/*
+ * Report a full set of quiescent states to the specified rcu_state
+ * data structure.  This involves cleaning up after the prior grace
+ * period and letting rcu_start_gp() start up the next grace period
+ * if one is needed.  Note that the caller must hold rnp->lock, which
+ * is released before return.
+ */
+static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
+       __releases(rcu_get_root(rsp)->lock)
+{
+       WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
+       raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
+       wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
+}
+
+/*
+ * Similar to rcu_report_qs_rdp(), for which it is a helper function.
+ * Allows quiescent states for a group of CPUs to be reported at one go
+ * to the specified rcu_node structure, though all the CPUs in the group
+ * must be represented by the same rcu_node structure (which need not be
+ * a leaf rcu_node structure, though it often will be).  That structure's
+ * lock must be held upon entry, and it is released before return.
+ */
+static void
+rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
+                 struct rcu_node *rnp, unsigned long flags)
+       __releases(rnp->lock)
+{
+       struct rcu_node *rnp_c;
+
+       /* Walk up the rcu_node hierarchy. */
+       for (;;) {
+               if (!(rnp->qsmask & mask)) {
+
+                       /* Our bit has already been cleared, so done. */
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       return;
+               }
+               rnp->qsmask &= ~mask;
+               trace_rcu_quiescent_state_report(rsp->name, rnp->gpnum,
+                                                mask, rnp->qsmask, rnp->level,
+                                                rnp->grplo, rnp->grphi,
+                                                !!rnp->gp_tasks);
+               if (rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
+
+                       /* Other bits still set at this level, so done. */
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       return;
+               }
+               mask = rnp->grpmask;
+               if (rnp->parent == NULL) {
+
+                       /* No more levels.  Exit loop holding root lock. */
+
+                       break;
+               }
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               rnp_c = rnp;
+               rnp = rnp->parent;
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               WARN_ON_ONCE(rnp_c->qsmask);
+       }
+
+       /*
+        * Get here if we are the last CPU to pass through a quiescent
+        * state for this grace period.  Invoke rcu_report_qs_rsp()
+        * to clean up and start the next grace period if one is needed.
+        */
+       rcu_report_qs_rsp(rsp, flags); /* releases rnp->lock. */
+}
+
+/*
+ * Record a quiescent state for the specified CPU to that CPU's rcu_data
+ * structure.  This must be either called from the specified CPU, or
+ * called when the specified CPU is known to be offline (and when it is
+ * also known that no other CPU is concurrently trying to help the offline
+ * CPU).  The lastcomp argument is used to make sure we are still in the
+ * grace period of interest.  We don't want to end the current grace period
+ * based on quiescent states detected in an earlier grace period!
+ */
+static void
+rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       unsigned long flags;
+       unsigned long mask;
+       struct rcu_node *rnp;
+
+       rnp = rdp->mynode;
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       if (rdp->passed_quiesce == 0 || rdp->gpnum != rnp->gpnum ||
+           rnp->completed == rnp->gpnum) {
+
+               /*
+                * The grace period in which this quiescent state was
+                * recorded has ended, so don't report it upwards.
+                * We will instead need a new quiescent state that lies
+                * within the current grace period.
+                */
+               rdp->passed_quiesce = 0;        /* need qs for new gp. */
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               return;
+       }
+       mask = rdp->grpmask;
+       if ((rnp->qsmask & mask) == 0) {
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       } else {
+               rdp->qs_pending = 0;
+
+               /*
+                * This GP can't end until cpu checks in, so all of our
+                * callbacks can be processed during the next GP.
+                */
+               rcu_accelerate_cbs(rsp, rnp, rdp);
+
+               rcu_report_qs_rnp(mask, rsp, rnp, flags); /* rlses rnp->lock */
+       }
+}
+
+/*
+ * Check to see if there is a new grace period of which this CPU
+ * is not yet aware, and if so, set up local rcu_data state for it.
+ * Otherwise, see if this CPU has just passed through its first
+ * quiescent state for this grace period, and record that fact if so.
+ */
+static void
+rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       /* Check for grace-period ends and beginnings. */
+       note_gp_changes(rsp, rdp);
+
+       /*
+        * Does this CPU still need to do its part for current grace period?
+        * If no, return and let the other CPUs do their part as well.
+        */
+       if (!rdp->qs_pending)
+               return;
+
+       /*
+        * Was there a quiescent state since the beginning of the grace
+        * period? If no, then exit and wait for the next call.
+        */
+       if (!rdp->passed_quiesce)
+               return;
+
+       /*
+        * Tell RCU we are done (but rcu_report_qs_rdp() will be the
+        * judge of that).
+        */
+       rcu_report_qs_rdp(rdp->cpu, rsp, rdp);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Send the specified CPU's RCU callbacks to the orphanage.  The
+ * specified CPU must be offline, and the caller must hold the
+ * ->orphan_lock.
+ */
+static void
+rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp,
+                         struct rcu_node *rnp, struct rcu_data *rdp)
+{
+       /* No-CBs CPUs do not have orphanable callbacks. */
+       if (rcu_is_nocb_cpu(rdp->cpu))
+               return;
+
+       /*
+        * Orphan the callbacks.  First adjust the counts.  This is safe
+        * because _rcu_barrier() excludes CPU-hotplug operations, so it
+        * cannot be running now.  Thus no memory barrier is required.
+        */
+       if (rdp->nxtlist != NULL) {
+               rsp->qlen_lazy += rdp->qlen_lazy;
+               rsp->qlen += rdp->qlen;
+               rdp->n_cbs_orphaned += rdp->qlen;
+               rdp->qlen_lazy = 0;
+               ACCESS_ONCE(rdp->qlen) = 0;
+       }
+
+       /*
+        * Next, move those callbacks still needing a grace period to
+        * the orphanage, where some other CPU will pick them up.
+        * Some of the callbacks might have gone partway through a grace
+        * period, but that is too bad.  They get to start over because we
+        * cannot assume that grace periods are synchronized across CPUs.
+        * We don't bother updating the ->nxttail[] array yet, instead
+        * we just reset the whole thing later on.
+        */
+       if (*rdp->nxttail[RCU_DONE_TAIL] != NULL) {
+               *rsp->orphan_nxttail = *rdp->nxttail[RCU_DONE_TAIL];
+               rsp->orphan_nxttail = rdp->nxttail[RCU_NEXT_TAIL];
+               *rdp->nxttail[RCU_DONE_TAIL] = NULL;
+       }
+
+       /*
+        * Then move the ready-to-invoke callbacks to the orphanage,
+        * where some other CPU will pick them up.  These will not be
+        * required to pass though another grace period: They are done.
+        */
+       if (rdp->nxtlist != NULL) {
+               *rsp->orphan_donetail = rdp->nxtlist;
+               rsp->orphan_donetail = rdp->nxttail[RCU_DONE_TAIL];
+       }
+
+       /* Finally, initialize the rcu_data structure's list to empty.  */
+       init_callback_list(rdp);
+}
+
+/*
+ * Adopt the RCU callbacks from the specified rcu_state structure's
+ * orphanage.  The caller must hold the ->orphan_lock.
+ */
+static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
+{
+       int i;
+       struct rcu_data *rdp = __this_cpu_ptr(rsp->rda);
+
+       /* No-CBs CPUs are handled specially. */
+       if (rcu_nocb_adopt_orphan_cbs(rsp, rdp))
+               return;
+
+       /* Do the accounting first. */
+       rdp->qlen_lazy += rsp->qlen_lazy;
+       rdp->qlen += rsp->qlen;
+       rdp->n_cbs_adopted += rsp->qlen;
+       if (rsp->qlen_lazy != rsp->qlen)
+               rcu_idle_count_callbacks_posted();
+       rsp->qlen_lazy = 0;
+       rsp->qlen = 0;
+
+       /*
+        * We do not need a memory barrier here because the only way we
+        * can get here if there is an rcu_barrier() in flight is if
+        * we are the task doing the rcu_barrier().
+        */
+
+       /* First adopt the ready-to-invoke callbacks. */
+       if (rsp->orphan_donelist != NULL) {
+               *rsp->orphan_donetail = *rdp->nxttail[RCU_DONE_TAIL];
+               *rdp->nxttail[RCU_DONE_TAIL] = rsp->orphan_donelist;
+               for (i = RCU_NEXT_SIZE - 1; i >= RCU_DONE_TAIL; i--)
+                       if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL])
+                               rdp->nxttail[i] = rsp->orphan_donetail;
+               rsp->orphan_donelist = NULL;
+               rsp->orphan_donetail = &rsp->orphan_donelist;
+       }
+
+       /* And then adopt the callbacks that still need a grace period. */
+       if (rsp->orphan_nxtlist != NULL) {
+               *rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_nxtlist;
+               rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_nxttail;
+               rsp->orphan_nxtlist = NULL;
+               rsp->orphan_nxttail = &rsp->orphan_nxtlist;
+       }
+}
+
+/*
+ * Trace the fact that this CPU is going offline.
+ */
+static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
+{
+       RCU_TRACE(unsigned long mask);
+       RCU_TRACE(struct rcu_data *rdp = this_cpu_ptr(rsp->rda));
+       RCU_TRACE(struct rcu_node *rnp = rdp->mynode);
+
+       RCU_TRACE(mask = rdp->grpmask);
+       trace_rcu_grace_period(rsp->name,
+                              rnp->gpnum + 1 - !!(rnp->qsmask & mask),
+                              TPS("cpuofl"));
+}
+
+/*
+ * The CPU has been completely removed, and some other CPU is reporting
+ * this fact from process context.  Do the remainder of the cleanup,
+ * including orphaning the outgoing CPU's RCU callbacks, and also
+ * adopting them.  There can only be one CPU hotplug operation at a time,
+ * so no other CPU can be attempting to update rcu_cpu_kthread_task.
+ */
+static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
+{
+       unsigned long flags;
+       unsigned long mask;
+       int need_report = 0;
+       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+       struct rcu_node *rnp = rdp->mynode;  /* Outgoing CPU's rdp & rnp. */
+
+       /* Adjust any no-longer-needed kthreads. */
+       rcu_boost_kthread_setaffinity(rnp, -1);
+
+       /* Remove the dead CPU from the bitmasks in the rcu_node hierarchy. */
+
+       /* Exclude any attempts to start a new grace period. */
+       mutex_lock(&rsp->onoff_mutex);
+       raw_spin_lock_irqsave(&rsp->orphan_lock, flags);
+
+       /* Orphan the dead CPU's callbacks, and adopt them if appropriate. */
+       rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp);
+       rcu_adopt_orphan_cbs(rsp);
+
+       /* Remove the outgoing CPU from the masks in the rcu_node hierarchy. */
+       mask = rdp->grpmask;    /* rnp->grplo is constant. */
+       do {
+               raw_spin_lock(&rnp->lock);      /* irqs already disabled. */
+               rnp->qsmaskinit &= ~mask;
+               if (rnp->qsmaskinit != 0) {
+                       if (rnp != rdp->mynode)
+                               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+                       break;
+               }
+               if (rnp == rdp->mynode)
+                       need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
+               else
+                       raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+               mask = rnp->grpmask;
+               rnp = rnp->parent;
+       } while (rnp != NULL);
+
+       /*
+        * We still hold the leaf rcu_node structure lock here, and
+        * irqs are still disabled.  The reason for this subterfuge is
+        * because invoking rcu_report_unblock_qs_rnp() with ->orphan_lock
+        * held leads to deadlock.
+        */
+       raw_spin_unlock(&rsp->orphan_lock); /* irqs remain disabled. */
+       rnp = rdp->mynode;
+       if (need_report & RCU_OFL_TASKS_NORM_GP)
+               rcu_report_unblock_qs_rnp(rnp, flags);
+       else
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       if (need_report & RCU_OFL_TASKS_EXP_GP)
+               rcu_report_exp_rnp(rsp, rnp, true);
+       WARN_ONCE(rdp->qlen != 0 || rdp->nxtlist != NULL,
+                 "rcu_cleanup_dead_cpu: Callbacks on offline CPU %d: qlen=%lu, nxtlist=%p\n",
+                 cpu, rdp->qlen, rdp->nxtlist);
+       init_callback_list(rdp);
+       /* Disallow further callbacks on this CPU. */
+       rdp->nxttail[RCU_NEXT_TAIL] = NULL;
+       mutex_unlock(&rsp->onoff_mutex);
+}
+
+#else /* #ifdef CONFIG_HOTPLUG_CPU */
+
+static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
+{
+}
+
+static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
+{
+}
+
+#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
+ * Invoke any RCU callbacks that have made it to the end of their grace
+ * period.  Thottle as specified by rdp->blimit.
+ */
+static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       unsigned long flags;
+       struct rcu_head *next, *list, **tail;
+       long bl, count, count_lazy;
+       int i;
+
+       /* If no callbacks are ready, just return. */
+       if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
+               trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, 0);
+               trace_rcu_batch_end(rsp->name, 0, !!ACCESS_ONCE(rdp->nxtlist),
+                                   need_resched(), is_idle_task(current),
+                                   rcu_is_callbacks_kthread());
+               return;
+       }
+
+       /*
+        * Extract the list of ready callbacks, disabling to prevent
+        * races with call_rcu() from interrupt handlers.
+        */
+       local_irq_save(flags);
+       WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
+       bl = rdp->blimit;
+       trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, bl);
+       list = rdp->nxtlist;
+       rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
+       *rdp->nxttail[RCU_DONE_TAIL] = NULL;
+       tail = rdp->nxttail[RCU_DONE_TAIL];
+       for (i = RCU_NEXT_SIZE - 1; i >= 0; i--)
+               if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL])
+                       rdp->nxttail[i] = &rdp->nxtlist;
+       local_irq_restore(flags);
+
+       /* Invoke callbacks. */
+       count = count_lazy = 0;
+       while (list) {
+               next = list->next;
+               prefetch(next);
+               debug_rcu_head_unqueue(list);
+               if (__rcu_reclaim(rsp->name, list))
+                       count_lazy++;
+               list = next;
+               /* Stop only if limit reached and CPU has something to do. */
+               if (++count >= bl &&
+                   (need_resched() ||
+                    (!is_idle_task(current) && !rcu_is_callbacks_kthread())))
+                       break;
+       }
+
+       local_irq_save(flags);
+       trace_rcu_batch_end(rsp->name, count, !!list, need_resched(),
+                           is_idle_task(current),
+                           rcu_is_callbacks_kthread());
+
+       /* Update count, and requeue any remaining callbacks. */
+       if (list != NULL) {
+               *tail = rdp->nxtlist;
+               rdp->nxtlist = list;
+               for (i = 0; i < RCU_NEXT_SIZE; i++)
+                       if (&rdp->nxtlist == rdp->nxttail[i])
+                               rdp->nxttail[i] = tail;
+                       else
+                               break;
+       }
+       smp_mb(); /* List handling before counting for rcu_barrier(). */
+       rdp->qlen_lazy -= count_lazy;
+       ACCESS_ONCE(rdp->qlen) -= count;
+       rdp->n_cbs_invoked += count;
+
+       /* Reinstate batch limit if we have worked down the excess. */
+       if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark)
+               rdp->blimit = blimit;
+
+       /* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */
+       if (rdp->qlen == 0 && rdp->qlen_last_fqs_check != 0) {
+               rdp->qlen_last_fqs_check = 0;
+               rdp->n_force_qs_snap = rsp->n_force_qs;
+       } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark)
+               rdp->qlen_last_fqs_check = rdp->qlen;
+       WARN_ON_ONCE((rdp->nxtlist == NULL) != (rdp->qlen == 0));
+
+       local_irq_restore(flags);
+
+       /* Re-invoke RCU core processing if there are callbacks remaining. */
+       if (cpu_has_callbacks_ready_to_invoke(rdp))
+               invoke_rcu_core();
+}
+
+/*
+ * Check to see if this CPU is in a non-context-switch quiescent state
+ * (user mode or idle loop for rcu, non-softirq execution for rcu_bh).
+ * Also schedule RCU core processing.
+ *
+ * This function must be called from hardirq context.  It is normally
+ * invoked from the scheduling-clock interrupt.  If rcu_pending returns
+ * false, there is no point in invoking rcu_check_callbacks().
+ */
+void rcu_check_callbacks(int cpu, int user)
+{
+       trace_rcu_utilization(TPS("Start scheduler-tick"));
+       increment_cpu_stall_ticks();
+       if (user || rcu_is_cpu_rrupt_from_idle()) {
+
+               /*
+                * Get here if this CPU took its interrupt from user
+                * mode or from the idle loop, and if this is not a
+                * nested interrupt.  In this case, the CPU is in
+                * a quiescent state, so note it.
+                *
+                * No memory barrier is required here because both
+                * rcu_sched_qs() and rcu_bh_qs() reference only CPU-local
+                * variables that other CPUs neither access nor modify,
+                * at least not while the corresponding CPU is online.
+                */
+
+               rcu_sched_qs(cpu);
+               rcu_bh_qs(cpu);
+
+       } else if (!in_softirq()) {
+
+               /*
+                * Get here if this CPU did not take its interrupt from
+                * softirq, in other words, if it is not interrupting
+                * a rcu_bh read-side critical section.  This is an _bh
+                * critical section, so note it.
+                */
+
+               rcu_bh_qs(cpu);
+       }
+       rcu_preempt_check_callbacks(cpu);
+       if (rcu_pending(cpu))
+               invoke_rcu_core();
+       trace_rcu_utilization(TPS("End scheduler-tick"));
+}
+
+/*
+ * Scan the leaf rcu_node structures, processing dyntick state for any that
+ * have not yet encountered a quiescent state, using the function specified.
+ * Also initiate boosting for any threads blocked on the root rcu_node.
+ *
+ * The caller must have suppressed start of new grace periods.
+ */
+static void force_qs_rnp(struct rcu_state *rsp,
+                        int (*f)(struct rcu_data *rsp, bool *isidle,
+                                 unsigned long *maxj),
+                        bool *isidle, unsigned long *maxj)
+{
+       unsigned long bit;
+       int cpu;
+       unsigned long flags;
+       unsigned long mask;
+       struct rcu_node *rnp;
+
+       rcu_for_each_leaf_node(rsp, rnp) {
+               cond_resched();
+               mask = 0;
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               if (!rcu_gp_in_progress(rsp)) {
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       return;
+               }
+               if (rnp->qsmask == 0) {
+                       rcu_initiate_boost(rnp, flags); /* releases rnp->lock */
+                       continue;
+               }
+               cpu = rnp->grplo;
+               bit = 1;
+               for (; cpu <= rnp->grphi; cpu++, bit <<= 1) {
+                       if ((rnp->qsmask & bit) != 0) {
+                               if ((rnp->qsmaskinit & bit) != 0)
+                                       *isidle = 0;
+                               if (f(per_cpu_ptr(rsp->rda, cpu), isidle, maxj))
+                                       mask |= bit;
+                       }
+               }
+               if (mask != 0) {
+
+                       /* rcu_report_qs_rnp() releases rnp->lock. */
+                       rcu_report_qs_rnp(mask, rsp, rnp, flags);
+                       continue;
+               }
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       }
+       rnp = rcu_get_root(rsp);
+       if (rnp->qsmask == 0) {
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */
+       }
+}
+
+/*
+ * Force quiescent states on reluctant CPUs, and also detect which
+ * CPUs are in dyntick-idle mode.
+ */
+static void force_quiescent_state(struct rcu_state *rsp)
+{
+       unsigned long flags;
+       bool ret;
+       struct rcu_node *rnp;
+       struct rcu_node *rnp_old = NULL;
+
+       /* Funnel through hierarchy to reduce memory contention. */
+       rnp = per_cpu_ptr(rsp->rda, raw_smp_processor_id())->mynode;
+       for (; rnp != NULL; rnp = rnp->parent) {
+               ret = (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) ||
+                     !raw_spin_trylock(&rnp->fqslock);
+               if (rnp_old != NULL)
+                       raw_spin_unlock(&rnp_old->fqslock);
+               if (ret) {
+                       rsp->n_force_qs_lh++;
+                       return;
+               }
+               rnp_old = rnp;
+       }
+       /* rnp_old == rcu_get_root(rsp), rnp == NULL. */
+
+       /* Reached the root of the rcu_node tree, acquire lock. */
+       raw_spin_lock_irqsave(&rnp_old->lock, flags);
+       raw_spin_unlock(&rnp_old->fqslock);
+       if (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) {
+               rsp->n_force_qs_lh++;
+               raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
+               return;  /* Someone beat us to it. */
+       }
+       rsp->gp_flags |= RCU_GP_FLAG_FQS;
+       raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
+       wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
+}
+
+/*
+ * This does the RCU core processing work for the specified rcu_state
+ * and rcu_data structures.  This may be called only from the CPU to
+ * whom the rdp belongs.
+ */
+static void
+__rcu_process_callbacks(struct rcu_state *rsp)
+{
+       unsigned long flags;
+       struct rcu_data *rdp = __this_cpu_ptr(rsp->rda);
+
+       WARN_ON_ONCE(rdp->beenonline == 0);
+
+       /* Update RCU state based on any recent quiescent states. */
+       rcu_check_quiescent_state(rsp, rdp);
+
+       /* Does this CPU require a not-yet-started grace period? */
+       local_irq_save(flags);
+       if (cpu_needs_another_gp(rsp, rdp)) {
+               raw_spin_lock(&rcu_get_root(rsp)->lock); /* irqs disabled. */
+               rcu_start_gp(rsp);
+               raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
+       } else {
+               local_irq_restore(flags);
+       }
+
+       /* If there are callbacks ready, invoke them. */
+       if (cpu_has_callbacks_ready_to_invoke(rdp))
+               invoke_rcu_callbacks(rsp, rdp);
+}
+
+/*
+ * Do RCU core processing for the current CPU.
+ */
+static void rcu_process_callbacks(struct softirq_action *unused)
+{
+       struct rcu_state *rsp;
+
+       if (cpu_is_offline(smp_processor_id()))
+               return;
+       trace_rcu_utilization(TPS("Start RCU core"));
+       for_each_rcu_flavor(rsp)
+               __rcu_process_callbacks(rsp);
+       trace_rcu_utilization(TPS("End RCU core"));
+}
+
+/*
+ * Schedule RCU callback invocation.  If the specified type of RCU
+ * does not support RCU priority boosting, just do a direct call,
+ * otherwise wake up the per-CPU kernel kthread.  Note that because we
+ * are running on the current CPU with interrupts disabled, the
+ * rcu_cpu_kthread_task cannot disappear out from under us.
+ */
+static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       if (unlikely(!ACCESS_ONCE(rcu_scheduler_fully_active)))
+               return;
+       if (likely(!rsp->boost)) {
+               rcu_do_batch(rsp, rdp);
+               return;
+       }
+       invoke_rcu_callbacks_kthread();
+}
+
+static void invoke_rcu_core(void)
+{
+       if (cpu_online(smp_processor_id()))
+               raise_softirq(RCU_SOFTIRQ);
+}
+
+/*
+ * Handle any core-RCU processing required by a call_rcu() invocation.
+ */
+static void __call_rcu_core(struct rcu_state *rsp, struct rcu_data *rdp,
+                           struct rcu_head *head, unsigned long flags)
+{
+       /*
+        * If called from an extended quiescent state, invoke the RCU
+        * core in order to force a re-evaluation of RCU's idleness.
+        */
+       if (!rcu_is_watching() && cpu_online(smp_processor_id()))
+               invoke_rcu_core();
+
+       /* If interrupts were disabled or CPU offline, don't invoke RCU core. */
+       if (irqs_disabled_flags(flags) || cpu_is_offline(smp_processor_id()))
+               return;
+
+       /*
+        * Force the grace period if too many callbacks or too long waiting.
+        * Enforce hysteresis, and don't invoke force_quiescent_state()
+        * if some other CPU has recently done so.  Also, don't bother
+        * invoking force_quiescent_state() if the newly enqueued callback
+        * is the only one waiting for a grace period to complete.
+        */
+       if (unlikely(rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) {
+
+               /* Are we ignoring a completed grace period? */
+               note_gp_changes(rsp, rdp);
+
+               /* Start a new grace period if one not already started. */
+               if (!rcu_gp_in_progress(rsp)) {
+                       struct rcu_node *rnp_root = rcu_get_root(rsp);
+
+                       raw_spin_lock(&rnp_root->lock);
+                       rcu_start_gp(rsp);
+                       raw_spin_unlock(&rnp_root->lock);
+               } else {
+                       /* Give the grace period a kick. */
+                       rdp->blimit = LONG_MAX;
+                       if (rsp->n_force_qs == rdp->n_force_qs_snap &&
+                           *rdp->nxttail[RCU_DONE_TAIL] != head)
+                               force_quiescent_state(rsp);
+                       rdp->n_force_qs_snap = rsp->n_force_qs;
+                       rdp->qlen_last_fqs_check = rdp->qlen;
+               }
+       }
+}
+
+/*
+ * RCU callback function to leak a callback.
+ */
+static void rcu_leak_callback(struct rcu_head *rhp)
+{
+}
+
+/*
+ * Helper function for call_rcu() and friends.  The cpu argument will
+ * normally be -1, indicating "currently running CPU".  It may specify
+ * a CPU only if that CPU is a no-CBs CPU.  Currently, only _rcu_barrier()
+ * is expected to specify a CPU.
+ */
+static void
+__call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
+          struct rcu_state *rsp, int cpu, bool lazy)
+{
+       unsigned long flags;
+       struct rcu_data *rdp;
+
+       WARN_ON_ONCE((unsigned long)head & 0x3); /* Misaligned rcu_head! */
+       if (debug_rcu_head_queue(head)) {
+               /* Probable double call_rcu(), so leak the callback. */
+               ACCESS_ONCE(head->func) = rcu_leak_callback;
+               WARN_ONCE(1, "__call_rcu(): Leaked duplicate callback\n");
+               return;
+       }
+       head->func = func;
+       head->next = NULL;
+
+       /*
+        * Opportunistically note grace-period endings and beginnings.
+        * Note that we might see a beginning right after we see an
+        * end, but never vice versa, since this CPU has to pass through
+        * a quiescent state betweentimes.
+        */
+       local_irq_save(flags);
+       rdp = this_cpu_ptr(rsp->rda);
+
+       /* Add the callback to our list. */
+       if (unlikely(rdp->nxttail[RCU_NEXT_TAIL] == NULL) || cpu != -1) {
+               int offline;
+
+               if (cpu != -1)
+                       rdp = per_cpu_ptr(rsp->rda, cpu);
+               offline = !__call_rcu_nocb(rdp, head, lazy);
+               WARN_ON_ONCE(offline);
+               /* _call_rcu() is illegal on offline CPU; leak the callback. */
+               local_irq_restore(flags);
+               return;
+       }
+       ACCESS_ONCE(rdp->qlen)++;
+       if (lazy)
+               rdp->qlen_lazy++;
+       else
+               rcu_idle_count_callbacks_posted();
+       smp_mb();  /* Count before adding callback for rcu_barrier(). */
+       *rdp->nxttail[RCU_NEXT_TAIL] = head;
+       rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
+
+       if (__is_kfree_rcu_offset((unsigned long)func))
+               trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
+                                        rdp->qlen_lazy, rdp->qlen);
+       else
+               trace_rcu_callback(rsp->name, head, rdp->qlen_lazy, rdp->qlen);
+
+       /* Go handle any RCU core processing required. */
+       __call_rcu_core(rsp, rdp, head, flags);
+       local_irq_restore(flags);
+}
+
+/*
+ * Queue an RCU-sched callback for invocation after a grace period.
+ */
+void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_sched_state, -1, 0);
+}
+EXPORT_SYMBOL_GPL(call_rcu_sched);
+
+/*
+ * Queue an RCU callback for invocation after a quicker grace period.
+ */
+void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_bh_state, -1, 0);
+}
+EXPORT_SYMBOL_GPL(call_rcu_bh);
+
+/*
+ * Because a context switch is a grace period for RCU-sched and RCU-bh,
+ * any blocking grace-period wait automatically implies a grace period
+ * if there is only one CPU online at any point time during execution
+ * of either synchronize_sched() or synchronize_rcu_bh().  It is OK to
+ * occasionally incorrectly indicate that there are multiple CPUs online
+ * when there was in fact only one the whole time, as this just adds
+ * some overhead: RCU still operates correctly.
+ */
+static inline int rcu_blocking_is_gp(void)
+{
+       int ret;
+
+       might_sleep();  /* Check for RCU read-side critical section. */
+       preempt_disable();
+       ret = num_online_cpus() <= 1;
+       preempt_enable();
+       return ret;
+}
+
+/**
+ * synchronize_sched - wait until an rcu-sched grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu-sched
+ * grace period has elapsed, in other words after all currently executing
+ * rcu-sched read-side critical sections have completed.   These read-side
+ * critical sections are delimited by rcu_read_lock_sched() and
+ * rcu_read_unlock_sched(), and may be nested.  Note that preempt_disable(),
+ * local_irq_disable(), and so on may be used in place of
+ * rcu_read_lock_sched().
+ *
+ * This means that all preempt_disable code sequences, including NMI and
+ * non-threaded hardware-interrupt handlers, in progress on entry will
+ * have completed before this primitive returns.  However, this does not
+ * guarantee that softirq handlers will have completed, since in some
+ * kernels, these handlers can run in process context, and can block.
+ *
+ * Note that this guarantee implies further memory-ordering guarantees.
+ * On systems with more than one CPU, when synchronize_sched() returns,
+ * each CPU is guaranteed to have executed a full memory barrier since the
+ * end of its last RCU-sched read-side critical section whose beginning
+ * preceded the call to synchronize_sched().  In addition, each CPU having
+ * an RCU read-side critical section that extends beyond the return from
+ * synchronize_sched() is guaranteed to have executed a full memory barrier
+ * after the beginning of synchronize_sched() and before the beginning of
+ * that RCU read-side critical section.  Note that these guarantees include
+ * CPUs that are offline, idle, or executing in user mode, as well as CPUs
+ * that are executing in the kernel.
+ *
+ * Furthermore, if CPU A invoked synchronize_sched(), which returned
+ * to its caller on CPU B, then both CPU A and CPU B are guaranteed
+ * to have executed a full memory barrier during the execution of
+ * synchronize_sched() -- even if CPU A and CPU B are the same CPU (but
+ * again only if the system has more than one CPU).
+ *
+ * This primitive provides the guarantees made by the (now removed)
+ * synchronize_kernel() API.  In contrast, synchronize_rcu() only
+ * guarantees that rcu_read_lock() sections will have completed.
+ * In "classic RCU", these two guarantees happen to be one and
+ * the same, but can differ in realtime RCU implementations.
+ */
+void synchronize_sched(void)
+{
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_sched() in RCU-sched read-side critical section");
+       if (rcu_blocking_is_gp())
+               return;
+       if (rcu_expedited)
+               synchronize_sched_expedited();
+       else
+               wait_rcu_gp(call_rcu_sched);
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
+/**
+ * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu_bh grace
+ * period has elapsed, in other words after all currently executing rcu_bh
+ * read-side critical sections have completed.  RCU read-side critical
+ * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(),
+ * and may be nested.
+ *
+ * See the description of synchronize_sched() for more detailed information
+ * on memory ordering guarantees.
+ */
+void synchronize_rcu_bh(void)
+{
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_rcu_bh() in RCU-bh read-side critical section");
+       if (rcu_blocking_is_gp())
+               return;
+       if (rcu_expedited)
+               synchronize_rcu_bh_expedited();
+       else
+               wait_rcu_gp(call_rcu_bh);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
+
+static int synchronize_sched_expedited_cpu_stop(void *data)
+{
+       /*
+        * There must be a full memory barrier on each affected CPU
+        * between the time that try_stop_cpus() is called and the
+        * time that it returns.
+        *
+        * In the current initial implementation of cpu_stop, the
+        * above condition is already met when the control reaches
+        * this point and the following smp_mb() is not strictly
+        * necessary.  Do smp_mb() anyway for documentation and
+        * robustness against future implementation changes.
+        */
+       smp_mb(); /* See above comment block. */
+       return 0;
+}
+
+/**
+ * synchronize_sched_expedited - Brute-force RCU-sched grace period
+ *
+ * Wait for an RCU-sched grace period to elapse, but use a "big hammer"
+ * approach to force the grace period to end quickly.  This consumes
+ * significant time on all CPUs and is unfriendly to real-time workloads,
+ * so is thus not recommended for any sort of common-case code.  In fact,
+ * if you are using synchronize_sched_expedited() in a loop, please
+ * restructure your code to batch your updates, and then use a single
+ * synchronize_sched() instead.
+ *
+ * Note that it is illegal to call this function while holding any lock
+ * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
+ * to call this function from a CPU-hotplug notifier.  Failing to observe
+ * these restriction will result in deadlock.
+ *
+ * This implementation can be thought of as an application of ticket
+ * locking to RCU, with sync_sched_expedited_started and
+ * sync_sched_expedited_done taking on the roles of the halves
+ * of the ticket-lock word.  Each task atomically increments
+ * sync_sched_expedited_started upon entry, snapshotting the old value,
+ * then attempts to stop all the CPUs.  If this succeeds, then each
+ * CPU will have executed a context switch, resulting in an RCU-sched
+ * grace period.  We are then done, so we use atomic_cmpxchg() to
+ * update sync_sched_expedited_done to match our snapshot -- but
+ * only if someone else has not already advanced past our snapshot.
+ *
+ * On the other hand, if try_stop_cpus() fails, we check the value
+ * of sync_sched_expedited_done.  If it has advanced past our
+ * initial snapshot, then someone else must have forced a grace period
+ * some time after we took our snapshot.  In this case, our work is
+ * done for us, and we can simply return.  Otherwise, we try again,
+ * but keep our initial snapshot for purposes of checking for someone
+ * doing our work for us.
+ *
+ * If we fail too many times in a row, we fall back to synchronize_sched().
+ */
+void synchronize_sched_expedited(void)
+{
+       long firstsnap, s, snap;
+       int trycount = 0;
+       struct rcu_state *rsp = &rcu_sched_state;
+
+       /*
+        * If we are in danger of counter wrap, just do synchronize_sched().
+        * By allowing sync_sched_expedited_started to advance no more than
+        * ULONG_MAX/8 ahead of sync_sched_expedited_done, we are ensuring
+        * that more than 3.5 billion CPUs would be required to force a
+        * counter wrap on a 32-bit system.  Quite a few more CPUs would of
+        * course be required on a 64-bit system.
+        */
+       if (ULONG_CMP_GE((ulong)atomic_long_read(&rsp->expedited_start),
+                        (ulong)atomic_long_read(&rsp->expedited_done) +
+                        ULONG_MAX / 8)) {
+               synchronize_sched();
+               atomic_long_inc(&rsp->expedited_wrap);
+               return;
+       }
+
+       /*
+        * Take a ticket.  Note that atomic_inc_return() implies a
+        * full memory barrier.
+        */
+       snap = atomic_long_inc_return(&rsp->expedited_start);
+       firstsnap = snap;
+       get_online_cpus();
+       WARN_ON_ONCE(cpu_is_offline(raw_smp_processor_id()));
+
+       /*
+        * Each pass through the following loop attempts to force a
+        * context switch on each CPU.
+        */
+       while (try_stop_cpus(cpu_online_mask,
+                            synchronize_sched_expedited_cpu_stop,
+                            NULL) == -EAGAIN) {
+               put_online_cpus();
+               atomic_long_inc(&rsp->expedited_tryfail);
+
+               /* Check to see if someone else did our work for us. */
+               s = atomic_long_read(&rsp->expedited_done);
+               if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) {
+                       /* ensure test happens before caller kfree */
+                       smp_mb__before_atomic_inc(); /* ^^^ */
+                       atomic_long_inc(&rsp->expedited_workdone1);
+                       return;
+               }
+
+               /* No joy, try again later.  Or just synchronize_sched(). */
+               if (trycount++ < 10) {
+                       udelay(trycount * num_online_cpus());
+               } else {
+                       wait_rcu_gp(call_rcu_sched);
+                       atomic_long_inc(&rsp->expedited_normal);
+                       return;
+               }
+
+               /* Recheck to see if someone else did our work for us. */
+               s = atomic_long_read(&rsp->expedited_done);
+               if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) {
+                       /* ensure test happens before caller kfree */
+                       smp_mb__before_atomic_inc(); /* ^^^ */
+                       atomic_long_inc(&rsp->expedited_workdone2);
+                       return;
+               }
+
+               /*
+                * Refetching sync_sched_expedited_started allows later
+                * callers to piggyback on our grace period.  We retry
+                * after they started, so our grace period works for them,
+                * and they started after our first try, so their grace
+                * period works for us.
+                */
+               get_online_cpus();
+               snap = atomic_long_read(&rsp->expedited_start);
+               smp_mb(); /* ensure read is before try_stop_cpus(). */
+       }
+       atomic_long_inc(&rsp->expedited_stoppedcpus);
+
+       /*
+        * Everyone up to our most recent fetch is covered by our grace
+        * period.  Update the counter, but only if our work is still
+        * relevant -- which it won't be if someone who started later
+        * than we did already did their update.
+        */
+       do {
+               atomic_long_inc(&rsp->expedited_done_tries);
+               s = atomic_long_read(&rsp->expedited_done);
+               if (ULONG_CMP_GE((ulong)s, (ulong)snap)) {
+                       /* ensure test happens before caller kfree */
+                       smp_mb__before_atomic_inc(); /* ^^^ */
+                       atomic_long_inc(&rsp->expedited_done_lost);
+                       break;
+               }
+       } while (atomic_long_cmpxchg(&rsp->expedited_done, s, snap) != s);
+       atomic_long_inc(&rsp->expedited_done_exit);
+
+       put_online_cpus();
+}
+EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
+
+/*
+ * Check to see if there is any immediate RCU-related work to be done
+ * by the current CPU, for the specified type of RCU, returning 1 if so.
+ * The checks are in order of increasing expense: checks that can be
+ * carried out against CPU-local state are performed first.  However,
+ * we must check for CPU stalls first, else we might not get a chance.
+ */
+static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       struct rcu_node *rnp = rdp->mynode;
+
+       rdp->n_rcu_pending++;
+
+       /* Check for CPU stalls, if enabled. */
+       check_cpu_stall(rsp, rdp);
+
+       /* Is the RCU core waiting for a quiescent state from this CPU? */
+       if (rcu_scheduler_fully_active &&
+           rdp->qs_pending && !rdp->passed_quiesce) {
+               rdp->n_rp_qs_pending++;
+       } else if (rdp->qs_pending && rdp->passed_quiesce) {
+               rdp->n_rp_report_qs++;
+               return 1;
+       }
+
+       /* Does this CPU have callbacks ready to invoke? */
+       if (cpu_has_callbacks_ready_to_invoke(rdp)) {
+               rdp->n_rp_cb_ready++;
+               return 1;
+       }
+
+       /* Has RCU gone idle with this CPU needing another grace period? */
+       if (cpu_needs_another_gp(rsp, rdp)) {
+               rdp->n_rp_cpu_needs_gp++;
+               return 1;
+       }
+
+       /* Has another RCU grace period completed?  */
+       if (ACCESS_ONCE(rnp->completed) != rdp->completed) { /* outside lock */
+               rdp->n_rp_gp_completed++;
+               return 1;
+       }
+
+       /* Has a new RCU grace period started? */
+       if (ACCESS_ONCE(rnp->gpnum) != rdp->gpnum) { /* outside lock */
+               rdp->n_rp_gp_started++;
+               return 1;
+       }
+
+       /* nothing to do */
+       rdp->n_rp_need_nothing++;
+       return 0;
+}
+
+/*
+ * Check to see if there is any immediate RCU-related work to be done
+ * by the current CPU, returning 1 if so.  This function is part of the
+ * RCU implementation; it is -not- an exported member of the RCU API.
+ */
+static int rcu_pending(int cpu)
+{
+       struct rcu_state *rsp;
+
+       for_each_rcu_flavor(rsp)
+               if (__rcu_pending(rsp, per_cpu_ptr(rsp->rda, cpu)))
+                       return 1;
+       return 0;
+}
+
+/*
+ * Return true if the specified CPU has any callback.  If all_lazy is
+ * non-NULL, store an indication of whether all callbacks are lazy.
+ * (If there are no callbacks, all of them are deemed to be lazy.)
+ */
+static int rcu_cpu_has_callbacks(int cpu, bool *all_lazy)
+{
+       bool al = true;
+       bool hc = false;
+       struct rcu_data *rdp;
+       struct rcu_state *rsp;
+
+       for_each_rcu_flavor(rsp) {
+               rdp = per_cpu_ptr(rsp->rda, cpu);
+               if (!rdp->nxtlist)
+                       continue;
+               hc = true;
+               if (rdp->qlen != rdp->qlen_lazy || !all_lazy) {
+                       al = false;
+                       break;
+               }
+       }
+       if (all_lazy)
+               *all_lazy = al;
+       return hc;
+}
+
+/*
+ * Helper function for _rcu_barrier() tracing.  If tracing is disabled,
+ * the compiler is expected to optimize this away.
+ */
+static void _rcu_barrier_trace(struct rcu_state *rsp, const char *s,
+                              int cpu, unsigned long done)
+{
+       trace_rcu_barrier(rsp->name, s, cpu,
+                         atomic_read(&rsp->barrier_cpu_count), done);
+}
+
+/*
+ * RCU callback function for _rcu_barrier().  If we are last, wake
+ * up the task executing _rcu_barrier().
+ */
+static void rcu_barrier_callback(struct rcu_head *rhp)
+{
+       struct rcu_data *rdp = container_of(rhp, struct rcu_data, barrier_head);
+       struct rcu_state *rsp = rdp->rsp;
+
+       if (atomic_dec_and_test(&rsp->barrier_cpu_count)) {
+               _rcu_barrier_trace(rsp, "LastCB", -1, rsp->n_barrier_done);
+               complete(&rsp->barrier_completion);
+       } else {
+               _rcu_barrier_trace(rsp, "CB", -1, rsp->n_barrier_done);
+       }
+}
+
+/*
+ * Called with preemption disabled, and from cross-cpu IRQ context.
+ */
+static void rcu_barrier_func(void *type)
+{
+       struct rcu_state *rsp = type;
+       struct rcu_data *rdp = __this_cpu_ptr(rsp->rda);
+
+       _rcu_barrier_trace(rsp, "IRQ", -1, rsp->n_barrier_done);
+       atomic_inc(&rsp->barrier_cpu_count);
+       rsp->call(&rdp->barrier_head, rcu_barrier_callback);
+}
+
+/*
+ * Orchestrate the specified type of RCU barrier, waiting for all
+ * RCU callbacks of the specified type to complete.
+ */
+static void _rcu_barrier(struct rcu_state *rsp)
+{
+       int cpu;
+       struct rcu_data *rdp;
+       unsigned long snap = ACCESS_ONCE(rsp->n_barrier_done);
+       unsigned long snap_done;
+
+       _rcu_barrier_trace(rsp, "Begin", -1, snap);
+
+       /* Take mutex to serialize concurrent rcu_barrier() requests. */
+       mutex_lock(&rsp->barrier_mutex);
+
+       /*
+        * Ensure that all prior references, including to ->n_barrier_done,
+        * are ordered before the _rcu_barrier() machinery.
+        */
+       smp_mb();  /* See above block comment. */
+
+       /*
+        * Recheck ->n_barrier_done to see if others did our work for us.
+        * This means checking ->n_barrier_done for an even-to-odd-to-even
+        * transition.  The "if" expression below therefore rounds the old
+        * value up to the next even number and adds two before comparing.
+        */
+       snap_done = rsp->n_barrier_done;
+       _rcu_barrier_trace(rsp, "Check", -1, snap_done);
+
+       /*
+        * If the value in snap is odd, we needed to wait for the current
+        * rcu_barrier() to complete, then wait for the next one, in other
+        * words, we need the value of snap_done to be three larger than
+        * the value of snap.  On the other hand, if the value in snap is
+        * even, we only had to wait for the next rcu_barrier() to complete,
+        * in other words, we need the value of snap_done to be only two
+        * greater than the value of snap.  The "(snap + 3) & ~0x1" computes
+        * this for us (thank you, Linus!).
+        */
+       if (ULONG_CMP_GE(snap_done, (snap + 3) & ~0x1)) {
+               _rcu_barrier_trace(rsp, "EarlyExit", -1, snap_done);
+               smp_mb(); /* caller's subsequent code after above check. */
+               mutex_unlock(&rsp->barrier_mutex);
+               return;
+       }
+
+       /*
+        * Increment ->n_barrier_done to avoid duplicate work.  Use
+        * ACCESS_ONCE() to prevent the compiler from speculating
+        * the increment to precede the early-exit check.
+        */
+       ACCESS_ONCE(rsp->n_barrier_done)++;
+       WARN_ON_ONCE((rsp->n_barrier_done & 0x1) != 1);
+       _rcu_barrier_trace(rsp, "Inc1", -1, rsp->n_barrier_done);
+       smp_mb(); /* Order ->n_barrier_done increment with below mechanism. */
+
+       /*
+        * Initialize the count to one rather than to zero in order to
+        * avoid a too-soon return to zero in case of a short grace period
+        * (or preemption of this task).  Exclude CPU-hotplug operations
+        * to ensure that no offline CPU has callbacks queued.
+        */
+       init_completion(&rsp->barrier_completion);
+       atomic_set(&rsp->barrier_cpu_count, 1);
+       get_online_cpus();
+
+       /*
+        * Force each CPU with callbacks to register a new callback.
+        * When that callback is invoked, we will know that all of the
+        * corresponding CPU's preceding callbacks have been invoked.
+        */
+       for_each_possible_cpu(cpu) {
+               if (!cpu_online(cpu) && !rcu_is_nocb_cpu(cpu))
+                       continue;
+               rdp = per_cpu_ptr(rsp->rda, cpu);
+               if (rcu_is_nocb_cpu(cpu)) {
+                       _rcu_barrier_trace(rsp, "OnlineNoCB", cpu,
+                                          rsp->n_barrier_done);
+                       atomic_inc(&rsp->barrier_cpu_count);
+                       __call_rcu(&rdp->barrier_head, rcu_barrier_callback,
+                                  rsp, cpu, 0);
+               } else if (ACCESS_ONCE(rdp->qlen)) {
+                       _rcu_barrier_trace(rsp, "OnlineQ", cpu,
+                                          rsp->n_barrier_done);
+                       smp_call_function_single(cpu, rcu_barrier_func, rsp, 1);
+               } else {
+                       _rcu_barrier_trace(rsp, "OnlineNQ", cpu,
+                                          rsp->n_barrier_done);
+               }
+       }
+       put_online_cpus();
+
+       /*
+        * Now that we have an rcu_barrier_callback() callback on each
+        * CPU, and thus each counted, remove the initial count.
+        */
+       if (atomic_dec_and_test(&rsp->barrier_cpu_count))
+               complete(&rsp->barrier_completion);
+
+       /* Increment ->n_barrier_done to prevent duplicate work. */
+       smp_mb(); /* Keep increment after above mechanism. */
+       ACCESS_ONCE(rsp->n_barrier_done)++;
+       WARN_ON_ONCE((rsp->n_barrier_done & 0x1) != 0);
+       _rcu_barrier_trace(rsp, "Inc2", -1, rsp->n_barrier_done);
+       smp_mb(); /* Keep increment before caller's subsequent code. */
+
+       /* Wait for all rcu_barrier_callback() callbacks to be invoked. */
+       wait_for_completion(&rsp->barrier_completion);
+
+       /* Other rcu_barrier() invocations can now safely proceed. */
+       mutex_unlock(&rsp->barrier_mutex);
+}
+
+/**
+ * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
+ */
+void rcu_barrier_bh(void)
+{
+       _rcu_barrier(&rcu_bh_state);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_bh);
+
+/**
+ * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
+ */
+void rcu_barrier_sched(void)
+{
+       _rcu_barrier(&rcu_sched_state);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_sched);
+
+/*
+ * Do boot-time initialization of a CPU's per-CPU RCU data.
+ */
+static void __init
+rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
+{
+       unsigned long flags;
+       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       /* Set up local state, ensuring consistent view of global state. */
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       rdp->grpmask = 1UL << (cpu - rdp->mynode->grplo);
+       init_callback_list(rdp);
+       rdp->qlen_lazy = 0;
+       ACCESS_ONCE(rdp->qlen) = 0;
+       rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
+       WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE);
+       WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1);
+       rdp->cpu = cpu;
+       rdp->rsp = rsp;
+       rcu_boot_init_nocb_percpu_data(rdp);
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Initialize a CPU's per-CPU RCU data.  Note that only one online or
+ * offline event can be happening at a given time.  Note also that we
+ * can accept some slop in the rsp->completed access due to the fact
+ * that this CPU cannot possibly have any RCU callbacks in flight yet.
+ */
+static void
+rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
+{
+       unsigned long flags;
+       unsigned long mask;
+       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       /* Exclude new grace periods. */
+       mutex_lock(&rsp->onoff_mutex);
+
+       /* Set up local state, ensuring consistent view of global state. */
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       rdp->beenonline = 1;     /* We have now been online. */
+       rdp->preemptible = preemptible;
+       rdp->qlen_last_fqs_check = 0;
+       rdp->n_force_qs_snap = rsp->n_force_qs;
+       rdp->blimit = blimit;
+       init_callback_list(rdp);  /* Re-enable callbacks on this CPU. */
+       rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
+       rcu_sysidle_init_percpu_data(rdp->dynticks);
+       atomic_set(&rdp->dynticks->dynticks,
+                  (atomic_read(&rdp->dynticks->dynticks) & ~0x1) + 1);
+       raw_spin_unlock(&rnp->lock);            /* irqs remain disabled. */
+
+       /* Add CPU to rcu_node bitmasks. */
+       rnp = rdp->mynode;
+       mask = rdp->grpmask;
+       do {
+               /* Exclude any attempts to start a new GP on small systems. */
+               raw_spin_lock(&rnp->lock);      /* irqs already disabled. */
+               rnp->qsmaskinit |= mask;
+               mask = rnp->grpmask;
+               if (rnp == rdp->mynode) {
+                       /*
+                        * If there is a grace period in progress, we will
+                        * set up to wait for it next time we run the
+                        * RCU core code.
+                        */
+                       rdp->gpnum = rnp->completed;
+                       rdp->completed = rnp->completed;
+                       rdp->passed_quiesce = 0;
+                       rdp->qs_pending = 0;
+                       trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuonl"));
+               }
+               raw_spin_unlock(&rnp->lock); /* irqs already disabled. */
+               rnp = rnp->parent;
+       } while (rnp != NULL && !(rnp->qsmaskinit & mask));
+       local_irq_restore(flags);
+
+       mutex_unlock(&rsp->onoff_mutex);
+}
+
+static void rcu_prepare_cpu(int cpu)
+{
+       struct rcu_state *rsp;
+
+       for_each_rcu_flavor(rsp)
+               rcu_init_percpu_data(cpu, rsp,
+                                    strcmp(rsp->name, "rcu_preempt") == 0);
+}
+
+/*
+ * Handle CPU online/offline notification events.
+ */
+static int rcu_cpu_notify(struct notifier_block *self,
+                                   unsigned long action, void *hcpu)
+{
+       long cpu = (long)hcpu;
+       struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
+       struct rcu_node *rnp = rdp->mynode;
+       struct rcu_state *rsp;
+
+       trace_rcu_utilization(TPS("Start CPU hotplug"));
+       switch (action) {
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               rcu_prepare_cpu(cpu);
+               rcu_prepare_kthreads(cpu);
+               break;
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+               rcu_boost_kthread_setaffinity(rnp, -1);
+               break;
+       case CPU_DOWN_PREPARE:
+               rcu_boost_kthread_setaffinity(rnp, cpu);
+               break;
+       case CPU_DYING:
+       case CPU_DYING_FROZEN:
+               for_each_rcu_flavor(rsp)
+                       rcu_cleanup_dying_cpu(rsp);
+               break;
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
+               for_each_rcu_flavor(rsp)
+                       rcu_cleanup_dead_cpu(cpu, rsp);
+               break;
+       default:
+               break;
+       }
+       trace_rcu_utilization(TPS("End CPU hotplug"));
+       return NOTIFY_OK;
+}
+
+static int rcu_pm_notify(struct notifier_block *self,
+                        unsigned long action, void *hcpu)
+{
+       switch (action) {
+       case PM_HIBERNATION_PREPARE:
+       case PM_SUSPEND_PREPARE:
+               if (nr_cpu_ids <= 256) /* Expediting bad for large systems. */
+                       rcu_expedited = 1;
+               break;
+       case PM_POST_HIBERNATION:
+       case PM_POST_SUSPEND:
+               rcu_expedited = 0;
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+/*
+ * Spawn the kthread that handles this RCU flavor's grace periods.
+ */
+static int __init rcu_spawn_gp_kthread(void)
+{
+       unsigned long flags;
+       struct rcu_node *rnp;
+       struct rcu_state *rsp;
+       struct task_struct *t;
+
+       for_each_rcu_flavor(rsp) {
+               t = kthread_run(rcu_gp_kthread, rsp, "%s", rsp->name);
+               BUG_ON(IS_ERR(t));
+               rnp = rcu_get_root(rsp);
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               rsp->gp_kthread = t;
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               rcu_spawn_nocb_kthreads(rsp);
+       }
+       return 0;
+}
+early_initcall(rcu_spawn_gp_kthread);
+
+/*
+ * This function is invoked towards the end of the scheduler's initialization
+ * process.  Before this is called, the idle task might contain
+ * RCU read-side critical sections (during which time, this idle
+ * task is booting the system).  After this function is called, the
+ * idle tasks are prohibited from containing RCU read-side critical
+ * sections.  This function also enables RCU lockdep checking.
+ */
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(num_online_cpus() != 1);
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
+/*
+ * Compute the per-level fanout, either using the exact fanout specified
+ * or balancing the tree, depending on CONFIG_RCU_FANOUT_EXACT.
+ */
+#ifdef CONFIG_RCU_FANOUT_EXACT
+static void __init rcu_init_levelspread(struct rcu_state *rsp)
+{
+       int i;
+
+       for (i = rcu_num_lvls - 1; i > 0; i--)
+               rsp->levelspread[i] = CONFIG_RCU_FANOUT;
+       rsp->levelspread[0] = rcu_fanout_leaf;
+}
+#else /* #ifdef CONFIG_RCU_FANOUT_EXACT */
+static void __init rcu_init_levelspread(struct rcu_state *rsp)
+{
+       int ccur;
+       int cprv;
+       int i;
+
+       cprv = nr_cpu_ids;
+       for (i = rcu_num_lvls - 1; i >= 0; i--) {
+               ccur = rsp->levelcnt[i];
+               rsp->levelspread[i] = (cprv + ccur - 1) / ccur;
+               cprv = ccur;
+       }
+}
+#endif /* #else #ifdef CONFIG_RCU_FANOUT_EXACT */
+
+/*
+ * Helper function for rcu_init() that initializes one rcu_state structure.
+ */
+static void __init rcu_init_one(struct rcu_state *rsp,
+               struct rcu_data __percpu *rda)
+{
+       static char *buf[] = { "rcu_node_0",
+                              "rcu_node_1",
+                              "rcu_node_2",
+                              "rcu_node_3" };  /* Match MAX_RCU_LVLS */
+       static char *fqs[] = { "rcu_node_fqs_0",
+                              "rcu_node_fqs_1",
+                              "rcu_node_fqs_2",
+                              "rcu_node_fqs_3" };  /* Match MAX_RCU_LVLS */
+       int cpustride = 1;
+       int i;
+       int j;
+       struct rcu_node *rnp;
+
+       BUILD_BUG_ON(MAX_RCU_LVLS > ARRAY_SIZE(buf));  /* Fix buf[] init! */
+
+       /* Silence gcc 4.8 warning about array index out of range. */
+       if (rcu_num_lvls > RCU_NUM_LVLS)
+               panic("rcu_init_one: rcu_num_lvls overflow");
+
+       /* Initialize the level-tracking arrays. */
+
+       for (i = 0; i < rcu_num_lvls; i++)
+               rsp->levelcnt[i] = num_rcu_lvl[i];
+       for (i = 1; i < rcu_num_lvls; i++)
+               rsp->level[i] = rsp->level[i - 1] + rsp->levelcnt[i - 1];
+       rcu_init_levelspread(rsp);
+
+       /* Initialize the elements themselves, starting from the leaves. */
+
+       for (i = rcu_num_lvls - 1; i >= 0; i--) {
+               cpustride *= rsp->levelspread[i];
+               rnp = rsp->level[i];
+               for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) {
+                       raw_spin_lock_init(&rnp->lock);
+                       lockdep_set_class_and_name(&rnp->lock,
+                                                  &rcu_node_class[i], buf[i]);
+                       raw_spin_lock_init(&rnp->fqslock);
+                       lockdep_set_class_and_name(&rnp->fqslock,
+                                                  &rcu_fqs_class[i], fqs[i]);
+                       rnp->gpnum = rsp->gpnum;
+                       rnp->completed = rsp->completed;
+                       rnp->qsmask = 0;
+                       rnp->qsmaskinit = 0;
+                       rnp->grplo = j * cpustride;
+                       rnp->grphi = (j + 1) * cpustride - 1;
+                       if (rnp->grphi >= NR_CPUS)
+                               rnp->grphi = NR_CPUS - 1;
+                       if (i == 0) {
+                               rnp->grpnum = 0;
+                               rnp->grpmask = 0;
+                               rnp->parent = NULL;
+                       } else {
+                               rnp->grpnum = j % rsp->levelspread[i - 1];
+                               rnp->grpmask = 1UL << rnp->grpnum;
+                               rnp->parent = rsp->level[i - 1] +
+                                             j / rsp->levelspread[i - 1];
+                       }
+                       rnp->level = i;
+                       INIT_LIST_HEAD(&rnp->blkd_tasks);
+                       rcu_init_one_nocb(rnp);
+               }
+       }
+
+       rsp->rda = rda;
+       init_waitqueue_head(&rsp->gp_wq);
+       init_irq_work(&rsp->wakeup_work, rsp_wakeup);
+       rnp = rsp->level[rcu_num_lvls - 1];
+       for_each_possible_cpu(i) {
+               while (i > rnp->grphi)
+                       rnp++;
+               per_cpu_ptr(rsp->rda, i)->mynode = rnp;
+               rcu_boot_init_percpu_data(i, rsp);
+       }
+       list_add(&rsp->flavors, &rcu_struct_flavors);
+}
+
+/*
+ * Compute the rcu_node tree geometry from kernel parameters.  This cannot
+ * replace the definitions in tree.h because those are needed to size
+ * the ->node array in the rcu_state structure.
+ */
+static void __init rcu_init_geometry(void)
+{
+       ulong d;
+       int i;
+       int j;
+       int n = nr_cpu_ids;
+       int rcu_capacity[MAX_RCU_LVLS + 1];
+
+       /*
+        * Initialize any unspecified boot parameters.
+        * The default values of jiffies_till_first_fqs and
+        * jiffies_till_next_fqs are set to the RCU_JIFFIES_TILL_FORCE_QS
+        * value, which is a function of HZ, then adding one for each
+        * RCU_JIFFIES_FQS_DIV CPUs that might be on the system.
+        */
+       d = RCU_JIFFIES_TILL_FORCE_QS + nr_cpu_ids / RCU_JIFFIES_FQS_DIV;
+       if (jiffies_till_first_fqs == ULONG_MAX)
+               jiffies_till_first_fqs = d;
+       if (jiffies_till_next_fqs == ULONG_MAX)
+               jiffies_till_next_fqs = d;
+
+       /* If the compile-time values are accurate, just leave. */
+       if (rcu_fanout_leaf == CONFIG_RCU_FANOUT_LEAF &&
+           nr_cpu_ids == NR_CPUS)
+               return;
+
+       /*
+        * Compute number of nodes that can be handled an rcu_node tree
+        * with the given number of levels.  Setting rcu_capacity[0] makes
+        * some of the arithmetic easier.
+        */
+       rcu_capacity[0] = 1;
+       rcu_capacity[1] = rcu_fanout_leaf;
+       for (i = 2; i <= MAX_RCU_LVLS; i++)
+               rcu_capacity[i] = rcu_capacity[i - 1] * CONFIG_RCU_FANOUT;
+
+       /*
+        * The boot-time rcu_fanout_leaf parameter is only permitted
+        * to increase the leaf-level fanout, not decrease it.  Of course,
+        * the leaf-level fanout cannot exceed the number of bits in
+        * the rcu_node masks.  Finally, the tree must be able to accommodate
+        * the configured number of CPUs.  Complain and fall back to the
+        * compile-time values if these limits are exceeded.
+        */
+       if (rcu_fanout_leaf < CONFIG_RCU_FANOUT_LEAF ||
+           rcu_fanout_leaf > sizeof(unsigned long) * 8 ||
+           n > rcu_capacity[MAX_RCU_LVLS]) {
+               WARN_ON(1);
+               return;
+       }
+
+       /* Calculate the number of rcu_nodes at each level of the tree. */
+       for (i = 1; i <= MAX_RCU_LVLS; i++)
+               if (n <= rcu_capacity[i]) {
+                       for (j = 0; j <= i; j++)
+                               num_rcu_lvl[j] =
+                                       DIV_ROUND_UP(n, rcu_capacity[i - j]);
+                       rcu_num_lvls = i;
+                       for (j = i + 1; j <= MAX_RCU_LVLS; j++)
+                               num_rcu_lvl[j] = 0;
+                       break;
+               }
+
+       /* Calculate the total number of rcu_node structures. */
+       rcu_num_nodes = 0;
+       for (i = 0; i <= MAX_RCU_LVLS; i++)
+               rcu_num_nodes += num_rcu_lvl[i];
+       rcu_num_nodes -= n;
+}
+
+void __init rcu_init(void)
+{
+       int cpu;
+
+       rcu_bootup_announce();
+       rcu_init_geometry();
+       rcu_init_one(&rcu_bh_state, &rcu_bh_data);
+       rcu_init_one(&rcu_sched_state, &rcu_sched_data);
+       __rcu_init_preempt();
+       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+
+       /*
+        * We don't need protection against CPU-hotplug here because
+        * this is called early in boot, before either interrupts
+        * or the scheduler are operational.
+        */
+       cpu_notifier(rcu_cpu_notify, 0);
+       pm_notifier(rcu_pm_notify, 0);
+       for_each_online_cpu(cpu)
+               rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
+}
+
+#include "tree_plugin.h"
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
new file mode 100644 (file)
index 0000000..52be957
--- /dev/null
@@ -0,0 +1,585 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion (tree-based version)
+ * Internal non-public definitions.
+ *
+ * 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 IBM Corporation, 2008
+ *
+ * Author: Ingo Molnar <mingo@elte.hu>
+ *        Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/seqlock.h>
+#include <linux/irq_work.h>
+
+/*
+ * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
+ * CONFIG_RCU_FANOUT_LEAF.
+ * In theory, it should be possible to add more levels straightforwardly.
+ * In practice, this did work well going from three levels to four.
+ * Of course, your mileage may vary.
+ */
+#define MAX_RCU_LVLS 4
+#define RCU_FANOUT_1         (CONFIG_RCU_FANOUT_LEAF)
+#define RCU_FANOUT_2         (RCU_FANOUT_1 * CONFIG_RCU_FANOUT)
+#define RCU_FANOUT_3         (RCU_FANOUT_2 * CONFIG_RCU_FANOUT)
+#define RCU_FANOUT_4         (RCU_FANOUT_3 * CONFIG_RCU_FANOUT)
+
+#if NR_CPUS <= RCU_FANOUT_1
+#  define RCU_NUM_LVLS       1
+#  define NUM_RCU_LVL_0              1
+#  define NUM_RCU_LVL_1              (NR_CPUS)
+#  define NUM_RCU_LVL_2              0
+#  define NUM_RCU_LVL_3              0
+#  define NUM_RCU_LVL_4              0
+#elif NR_CPUS <= RCU_FANOUT_2
+#  define RCU_NUM_LVLS       2
+#  define NUM_RCU_LVL_0              1
+#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
+#  define NUM_RCU_LVL_2              (NR_CPUS)
+#  define NUM_RCU_LVL_3              0
+#  define NUM_RCU_LVL_4              0
+#elif NR_CPUS <= RCU_FANOUT_3
+#  define RCU_NUM_LVLS       3
+#  define NUM_RCU_LVL_0              1
+#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2)
+#  define NUM_RCU_LVL_2              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
+#  define NUM_RCU_LVL_3              (NR_CPUS)
+#  define NUM_RCU_LVL_4              0
+#elif NR_CPUS <= RCU_FANOUT_4
+#  define RCU_NUM_LVLS       4
+#  define NUM_RCU_LVL_0              1
+#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3)
+#  define NUM_RCU_LVL_2              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2)
+#  define NUM_RCU_LVL_3              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
+#  define NUM_RCU_LVL_4              (NR_CPUS)
+#else
+# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
+#endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */
+
+#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4)
+#define NUM_RCU_NODES (RCU_SUM - NR_CPUS)
+
+extern int rcu_num_lvls;
+extern int rcu_num_nodes;
+
+/*
+ * Dynticks per-CPU state.
+ */
+struct rcu_dynticks {
+       long long dynticks_nesting; /* Track irq/process nesting level. */
+                                   /* Process level is worth LLONG_MAX/2. */
+       int dynticks_nmi_nesting;   /* Track NMI nesting level. */
+       atomic_t dynticks;          /* Even value for idle, else odd. */
+#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
+       long long dynticks_idle_nesting;
+                                   /* irq/process nesting level from idle. */
+       atomic_t dynticks_idle;     /* Even value for idle, else odd. */
+                                   /*  "Idle" excludes userspace execution. */
+       unsigned long dynticks_idle_jiffies;
+                                   /* End of last non-NMI non-idle period. */
+#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
+#ifdef CONFIG_RCU_FAST_NO_HZ
+       bool all_lazy;              /* Are all CPU's CBs lazy? */
+       unsigned long nonlazy_posted;
+                                   /* # times non-lazy CBs posted to CPU. */
+       unsigned long nonlazy_posted_snap;
+                                   /* idle-period nonlazy_posted snapshot. */
+       unsigned long last_accelerate;
+                                   /* Last jiffy CBs were accelerated. */
+       unsigned long last_advance_all;
+                                   /* Last jiffy CBs were all advanced. */
+       int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */
+#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */
+};
+
+/* RCU's kthread states for tracing. */
+#define RCU_KTHREAD_STOPPED  0
+#define RCU_KTHREAD_RUNNING  1
+#define RCU_KTHREAD_WAITING  2
+#define RCU_KTHREAD_OFFCPU   3
+#define RCU_KTHREAD_YIELDING 4
+#define RCU_KTHREAD_MAX      4
+
+/*
+ * Definition for node within the RCU grace-period-detection hierarchy.
+ */
+struct rcu_node {
+       raw_spinlock_t lock;    /* Root rcu_node's lock protects some */
+                               /*  rcu_state fields as well as following. */
+       unsigned long gpnum;    /* Current grace period for this node. */
+                               /*  This will either be equal to or one */
+                               /*  behind the root rcu_node's gpnum. */
+       unsigned long completed; /* Last GP completed for this node. */
+                               /*  This will either be equal to or one */
+                               /*  behind the root rcu_node's gpnum. */
+       unsigned long qsmask;   /* CPUs or groups that need to switch in */
+                               /*  order for current grace period to proceed.*/
+                               /*  In leaf rcu_node, each bit corresponds to */
+                               /*  an rcu_data structure, otherwise, each */
+                               /*  bit corresponds to a child rcu_node */
+                               /*  structure. */
+       unsigned long expmask;  /* Groups that have ->blkd_tasks */
+                               /*  elements that need to drain to allow the */
+                               /*  current expedited grace period to */
+                               /*  complete (only for TREE_PREEMPT_RCU). */
+       unsigned long qsmaskinit;
+                               /* Per-GP initial value for qsmask & expmask. */
+       unsigned long grpmask;  /* Mask to apply to parent qsmask. */
+                               /*  Only one bit will be set in this mask. */
+       int     grplo;          /* lowest-numbered CPU or group here. */
+       int     grphi;          /* highest-numbered CPU or group here. */
+       u8      grpnum;         /* CPU/group number for next level up. */
+       u8      level;          /* root is at level 0. */
+       struct rcu_node *parent;
+       struct list_head blkd_tasks;
+                               /* Tasks blocked in RCU read-side critical */
+                               /*  section.  Tasks are placed at the head */
+                               /*  of this list and age towards the tail. */
+       struct list_head *gp_tasks;
+                               /* Pointer to the first task blocking the */
+                               /*  current grace period, or NULL if there */
+                               /*  is no such task. */
+       struct list_head *exp_tasks;
+                               /* Pointer to the first task blocking the */
+                               /*  current expedited grace period, or NULL */
+                               /*  if there is no such task.  If there */
+                               /*  is no current expedited grace period, */
+                               /*  then there can cannot be any such task. */
+#ifdef CONFIG_RCU_BOOST
+       struct list_head *boost_tasks;
+                               /* Pointer to first task that needs to be */
+                               /*  priority boosted, or NULL if no priority */
+                               /*  boosting is needed for this rcu_node */
+                               /*  structure.  If there are no tasks */
+                               /*  queued on this rcu_node structure that */
+                               /*  are blocking the current grace period, */
+                               /*  there can be no such task. */
+       unsigned long boost_time;
+                               /* When to start boosting (jiffies). */
+       struct task_struct *boost_kthread_task;
+                               /* kthread that takes care of priority */
+                               /*  boosting for this rcu_node structure. */
+       unsigned int boost_kthread_status;
+                               /* State of boost_kthread_task for tracing. */
+       unsigned long n_tasks_boosted;
+                               /* Total number of tasks boosted. */
+       unsigned long n_exp_boosts;
+                               /* Number of tasks boosted for expedited GP. */
+       unsigned long n_normal_boosts;
+                               /* Number of tasks boosted for normal GP. */
+       unsigned long n_balk_blkd_tasks;
+                               /* Refused to boost: no blocked tasks. */
+       unsigned long n_balk_exp_gp_tasks;
+                               /* Refused to boost: nothing blocking GP. */
+       unsigned long n_balk_boost_tasks;
+                               /* Refused to boost: already boosting. */
+       unsigned long n_balk_notblocked;
+                               /* Refused to boost: RCU RS CS still running. */
+       unsigned long n_balk_notyet;
+                               /* Refused to boost: not yet time. */
+       unsigned long n_balk_nos;
+                               /* Refused to boost: not sure why, though. */
+                               /*  This can happen due to race conditions. */
+#endif /* #ifdef CONFIG_RCU_BOOST */
+#ifdef CONFIG_RCU_NOCB_CPU
+       wait_queue_head_t nocb_gp_wq[2];
+                               /* Place for rcu_nocb_kthread() to wait GP. */
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
+       int need_future_gp[2];
+                               /* Counts of upcoming no-CB GP requests. */
+       raw_spinlock_t fqslock ____cacheline_internodealigned_in_smp;
+} ____cacheline_internodealigned_in_smp;
+
+/*
+ * Do a full breadth-first scan of the rcu_node structures for the
+ * specified rcu_state structure.
+ */
+#define rcu_for_each_node_breadth_first(rsp, rnp) \
+       for ((rnp) = &(rsp)->node[0]; \
+            (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++)
+
+/*
+ * Do a breadth-first scan of the non-leaf rcu_node structures for the
+ * specified rcu_state structure.  Note that if there is a singleton
+ * rcu_node tree with but one rcu_node structure, this loop is a no-op.
+ */
+#define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \
+       for ((rnp) = &(rsp)->node[0]; \
+            (rnp) < (rsp)->level[rcu_num_lvls - 1]; (rnp)++)
+
+/*
+ * Scan the leaves of the rcu_node hierarchy for the specified rcu_state
+ * structure.  Note that if there is a singleton rcu_node tree with but
+ * one rcu_node structure, this loop -will- visit the rcu_node structure.
+ * It is still a leaf node, even if it is also the root node.
+ */
+#define rcu_for_each_leaf_node(rsp, rnp) \
+       for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \
+            (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++)
+
+/* Index values for nxttail array in struct rcu_data. */
+#define RCU_DONE_TAIL          0       /* Also RCU_WAIT head. */
+#define RCU_WAIT_TAIL          1       /* Also RCU_NEXT_READY head. */
+#define RCU_NEXT_READY_TAIL    2       /* Also RCU_NEXT head. */
+#define RCU_NEXT_TAIL          3
+#define RCU_NEXT_SIZE          4
+
+/* Per-CPU data for read-copy update. */
+struct rcu_data {
+       /* 1) quiescent-state and grace-period handling : */
+       unsigned long   completed;      /* Track rsp->completed gp number */
+                                       /*  in order to detect GP end. */
+       unsigned long   gpnum;          /* Highest gp number that this CPU */
+                                       /*  is aware of having started. */
+       bool            passed_quiesce; /* User-mode/idle loop etc. */
+       bool            qs_pending;     /* Core waits for quiesc state. */
+       bool            beenonline;     /* CPU online at least once. */
+       bool            preemptible;    /* Preemptible RCU? */
+       struct rcu_node *mynode;        /* This CPU's leaf of hierarchy */
+       unsigned long grpmask;          /* Mask to apply to leaf qsmask. */
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+       unsigned long   ticks_this_gp;  /* The number of scheduling-clock */
+                                       /*  ticks this CPU has handled */
+                                       /*  during and after the last grace */
+                                       /* period it is aware of. */
+#endif /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+       /* 2) batch handling */
+       /*
+        * If nxtlist is not NULL, it is partitioned as follows.
+        * Any of the partitions might be empty, in which case the
+        * pointer to that partition will be equal to the pointer for
+        * the following partition.  When the list is empty, all of
+        * the nxttail elements point to the ->nxtlist pointer itself,
+        * which in that case is NULL.
+        *
+        * [nxtlist, *nxttail[RCU_DONE_TAIL]):
+        *      Entries that batch # <= ->completed
+        *      The grace period for these entries has completed, and
+        *      the other grace-period-completed entries may be moved
+        *      here temporarily in rcu_process_callbacks().
+        * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]):
+        *      Entries that batch # <= ->completed - 1: waiting for current GP
+        * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]):
+        *      Entries known to have arrived before current GP ended
+        * [*nxttail[RCU_NEXT_READY_TAIL], *nxttail[RCU_NEXT_TAIL]):
+        *      Entries that might have arrived after current GP ended
+        *      Note that the value of *nxttail[RCU_NEXT_TAIL] will
+        *      always be NULL, as this is the end of the list.
+        */
+       struct rcu_head *nxtlist;
+       struct rcu_head **nxttail[RCU_NEXT_SIZE];
+       unsigned long   nxtcompleted[RCU_NEXT_SIZE];
+                                       /* grace periods for sublists. */
+       long            qlen_lazy;      /* # of lazy queued callbacks */
+       long            qlen;           /* # of queued callbacks, incl lazy */
+       long            qlen_last_fqs_check;
+                                       /* qlen at last check for QS forcing */
+       unsigned long   n_cbs_invoked;  /* count of RCU cbs invoked. */
+       unsigned long   n_nocbs_invoked; /* count of no-CBs RCU cbs invoked. */
+       unsigned long   n_cbs_orphaned; /* RCU cbs orphaned by dying CPU */
+       unsigned long   n_cbs_adopted;  /* RCU cbs adopted from dying CPU */
+       unsigned long   n_force_qs_snap;
+                                       /* did other CPU force QS recently? */
+       long            blimit;         /* Upper limit on a processed batch */
+
+       /* 3) dynticks interface. */
+       struct rcu_dynticks *dynticks;  /* Shared per-CPU dynticks state. */
+       int dynticks_snap;              /* Per-GP tracking for dynticks. */
+
+       /* 4) reasons this CPU needed to be kicked by force_quiescent_state */
+       unsigned long dynticks_fqs;     /* Kicked due to dynticks idle. */
+       unsigned long offline_fqs;      /* Kicked due to being offline. */
+
+       /* 5) __rcu_pending() statistics. */
+       unsigned long n_rcu_pending;    /* rcu_pending() calls since boot. */
+       unsigned long n_rp_qs_pending;
+       unsigned long n_rp_report_qs;
+       unsigned long n_rp_cb_ready;
+       unsigned long n_rp_cpu_needs_gp;
+       unsigned long n_rp_gp_completed;
+       unsigned long n_rp_gp_started;
+       unsigned long n_rp_need_nothing;
+
+       /* 6) _rcu_barrier() and OOM callbacks. */
+       struct rcu_head barrier_head;
+#ifdef CONFIG_RCU_FAST_NO_HZ
+       struct rcu_head oom_head;
+#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */
+
+       /* 7) Callback offloading. */
+#ifdef CONFIG_RCU_NOCB_CPU
+       struct rcu_head *nocb_head;     /* CBs waiting for kthread. */
+       struct rcu_head **nocb_tail;
+       atomic_long_t nocb_q_count;     /* # CBs waiting for kthread */
+       atomic_long_t nocb_q_count_lazy; /*  (approximate). */
+       int nocb_p_count;               /* # CBs being invoked by kthread */
+       int nocb_p_count_lazy;          /*  (approximate). */
+       wait_queue_head_t nocb_wq;      /* For nocb kthreads to sleep on. */
+       struct task_struct *nocb_kthread;
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
+
+       /* 8) RCU CPU stall data. */
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+       unsigned int softirq_snap;      /* Snapshot of softirq activity. */
+#endif /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+       int cpu;
+       struct rcu_state *rsp;
+};
+
+/* Values for fqs_state field in struct rcu_state. */
+#define RCU_GP_IDLE            0       /* No grace period in progress. */
+#define RCU_GP_INIT            1       /* Grace period being initialized. */
+#define RCU_SAVE_DYNTICK       2       /* Need to scan dyntick state. */
+#define RCU_FORCE_QS           3       /* Need to force quiescent state. */
+#define RCU_SIGNAL_INIT                RCU_SAVE_DYNTICK
+
+#define RCU_JIFFIES_TILL_FORCE_QS (1 + (HZ > 250) + (HZ > 500))
+                                       /* For jiffies_till_first_fqs and */
+                                       /*  and jiffies_till_next_fqs. */
+
+#define RCU_JIFFIES_FQS_DIV    256     /* Very large systems need more */
+                                       /*  delay between bouts of */
+                                       /*  quiescent-state forcing. */
+
+#define RCU_STALL_RAT_DELAY    2       /* Allow other CPUs time to take */
+                                       /*  at least one scheduling clock */
+                                       /*  irq before ratting on them. */
+
+#define rcu_wait(cond)                                                 \
+do {                                                                   \
+       for (;;) {                                                      \
+               set_current_state(TASK_INTERRUPTIBLE);                  \
+               if (cond)                                               \
+                       break;                                          \
+               schedule();                                             \
+       }                                                               \
+       __set_current_state(TASK_RUNNING);                              \
+} while (0)
+
+/*
+ * RCU global state, including node hierarchy.  This hierarchy is
+ * represented in "heap" form in a dense array.  The root (first level)
+ * of the hierarchy is in ->node[0] (referenced by ->level[0]), the second
+ * level in ->node[1] through ->node[m] (->node[1] referenced by ->level[1]),
+ * and the third level in ->node[m+1] and following (->node[m+1] referenced
+ * by ->level[2]).  The number of levels is determined by the number of
+ * CPUs and by CONFIG_RCU_FANOUT.  Small systems will have a "hierarchy"
+ * consisting of a single rcu_node.
+ */
+struct rcu_state {
+       struct rcu_node node[NUM_RCU_NODES];    /* Hierarchy. */
+       struct rcu_node *level[RCU_NUM_LVLS];   /* Hierarchy levels. */
+       u32 levelcnt[MAX_RCU_LVLS + 1];         /* # nodes in each level. */
+       u8 levelspread[RCU_NUM_LVLS];           /* kids/node in each level. */
+       struct rcu_data __percpu *rda;          /* pointer of percu rcu_data. */
+       void (*call)(struct rcu_head *head,     /* call_rcu() flavor. */
+                    void (*func)(struct rcu_head *head));
+
+       /* The following fields are guarded by the root rcu_node's lock. */
+
+       u8      fqs_state ____cacheline_internodealigned_in_smp;
+                                               /* Force QS state. */
+       u8      boost;                          /* Subject to priority boost. */
+       unsigned long gpnum;                    /* Current gp number. */
+       unsigned long completed;                /* # of last completed gp. */
+       struct task_struct *gp_kthread;         /* Task for grace periods. */
+       wait_queue_head_t gp_wq;                /* Where GP task waits. */
+       int gp_flags;                           /* Commands for GP task. */
+
+       /* End of fields guarded by root rcu_node's lock. */
+
+       raw_spinlock_t orphan_lock ____cacheline_internodealigned_in_smp;
+                                               /* Protect following fields. */
+       struct rcu_head *orphan_nxtlist;        /* Orphaned callbacks that */
+                                               /*  need a grace period. */
+       struct rcu_head **orphan_nxttail;       /* Tail of above. */
+       struct rcu_head *orphan_donelist;       /* Orphaned callbacks that */
+                                               /*  are ready to invoke. */
+       struct rcu_head **orphan_donetail;      /* Tail of above. */
+       long qlen_lazy;                         /* Number of lazy callbacks. */
+       long qlen;                              /* Total number of callbacks. */
+       /* End of fields guarded by orphan_lock. */
+
+       struct mutex onoff_mutex;               /* Coordinate hotplug & GPs. */
+
+       struct mutex barrier_mutex;             /* Guards barrier fields. */
+       atomic_t barrier_cpu_count;             /* # CPUs waiting on. */
+       struct completion barrier_completion;   /* Wake at barrier end. */
+       unsigned long n_barrier_done;           /* ++ at start and end of */
+                                               /*  _rcu_barrier(). */
+       /* End of fields guarded by barrier_mutex. */
+
+       atomic_long_t expedited_start;          /* Starting ticket. */
+       atomic_long_t expedited_done;           /* Done ticket. */
+       atomic_long_t expedited_wrap;           /* # near-wrap incidents. */
+       atomic_long_t expedited_tryfail;        /* # acquisition failures. */
+       atomic_long_t expedited_workdone1;      /* # done by others #1. */
+       atomic_long_t expedited_workdone2;      /* # done by others #2. */
+       atomic_long_t expedited_normal;         /* # fallbacks to normal. */
+       atomic_long_t expedited_stoppedcpus;    /* # successful stop_cpus. */
+       atomic_long_t expedited_done_tries;     /* # tries to update _done. */
+       atomic_long_t expedited_done_lost;      /* # times beaten to _done. */
+       atomic_long_t expedited_done_exit;      /* # times exited _done loop. */
+
+       unsigned long jiffies_force_qs;         /* Time at which to invoke */
+                                               /*  force_quiescent_state(). */
+       unsigned long n_force_qs;               /* Number of calls to */
+                                               /*  force_quiescent_state(). */
+       unsigned long n_force_qs_lh;            /* ~Number of calls leaving */
+                                               /*  due to lock unavailable. */
+       unsigned long n_force_qs_ngp;           /* Number of calls leaving */
+                                               /*  due to no GP active. */
+       unsigned long gp_start;                 /* Time at which GP started, */
+                                               /*  but in jiffies. */
+       unsigned long jiffies_stall;            /* Time at which to check */
+                                               /*  for CPU stalls. */
+       unsigned long gp_max;                   /* Maximum GP duration in */
+                                               /*  jiffies. */
+       const char *name;                       /* Name of structure. */
+       char abbr;                              /* Abbreviated name. */
+       struct list_head flavors;               /* List of RCU flavors. */
+       struct irq_work wakeup_work;            /* Postponed wakeups */
+};
+
+/* Values for rcu_state structure's gp_flags field. */
+#define RCU_GP_FLAG_INIT 0x1   /* Need grace-period initialization. */
+#define RCU_GP_FLAG_FQS  0x2   /* Need grace-period quiescent-state forcing. */
+
+extern struct list_head rcu_struct_flavors;
+
+/* Sequence through rcu_state structures for each RCU flavor. */
+#define for_each_rcu_flavor(rsp) \
+       list_for_each_entry((rsp), &rcu_struct_flavors, flavors)
+
+/* Return values for rcu_preempt_offline_tasks(). */
+
+#define RCU_OFL_TASKS_NORM_GP  0x1             /* Tasks blocking normal */
+                                               /*  GP were moved to root. */
+#define RCU_OFL_TASKS_EXP_GP   0x2             /* Tasks blocking expedited */
+                                               /*  GP were moved to root. */
+
+/*
+ * RCU implementation internal declarations:
+ */
+extern struct rcu_state rcu_sched_state;
+DECLARE_PER_CPU(struct rcu_data, rcu_sched_data);
+
+extern struct rcu_state rcu_bh_state;
+DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
+
+#ifdef CONFIG_TREE_PREEMPT_RCU
+extern struct rcu_state rcu_preempt_state;
+DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
+#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+
+#ifdef CONFIG_RCU_BOOST
+DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
+DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu);
+DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
+DECLARE_PER_CPU(char, rcu_cpu_has_work);
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+#ifndef RCU_TREE_NONCORE
+
+/* Forward declarations for rcutree_plugin.h */
+static void rcu_bootup_announce(void);
+long rcu_batches_completed(void);
+static void rcu_preempt_note_context_switch(int cpu);
+static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp);
+#ifdef CONFIG_HOTPLUG_CPU
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp,
+                                     unsigned long flags);
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+static void rcu_print_detail_task_stall(struct rcu_state *rsp);
+static int rcu_print_task_stall(struct rcu_node *rnp);
+static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
+#ifdef CONFIG_HOTPLUG_CPU
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+                                    struct rcu_node *rnp,
+                                    struct rcu_data *rdp);
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+static void rcu_preempt_check_callbacks(int cpu);
+void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU)
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
+                              bool wake);
+#endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */
+static void __init __rcu_init_preempt(void);
+static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);
+static void rcu_preempt_boost_start_gp(struct rcu_node *rnp);
+static void invoke_rcu_callbacks_kthread(void);
+static bool rcu_is_callbacks_kthread(void);
+#ifdef CONFIG_RCU_BOOST
+static void rcu_preempt_do_callbacks(void);
+static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
+                                                struct rcu_node *rnp);
+#endif /* #ifdef CONFIG_RCU_BOOST */
+static void rcu_prepare_kthreads(int cpu);
+static void rcu_cleanup_after_idle(int cpu);
+static void rcu_prepare_for_idle(int cpu);
+static void rcu_idle_count_callbacks_posted(void);
+static void print_cpu_stall_info_begin(void);
+static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
+static void print_cpu_stall_info_end(void);
+static void zero_cpu_stall_ticks(struct rcu_data *rdp);
+static void increment_cpu_stall_ticks(void);
+static int rcu_nocb_needs_gp(struct rcu_state *rsp);
+static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
+static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp);
+static void rcu_init_one_nocb(struct rcu_node *rnp);
+static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
+                           bool lazy);
+static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
+                                     struct rcu_data *rdp);
+static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp);
+static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp);
+static void rcu_kick_nohz_cpu(int cpu);
+static bool init_nocb_callback_list(struct rcu_data *rdp);
+static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq);
+static void rcu_sysidle_exit(struct rcu_dynticks *rdtp, int irq);
+static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,
+                                 unsigned long *maxj);
+static bool is_sysidle_rcu_state(struct rcu_state *rsp);
+static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
+                                 unsigned long maxj);
+static void rcu_bind_gp_kthread(void);
+static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp);
+
+#endif /* #ifndef RCU_TREE_NONCORE */
+
+#ifdef CONFIG_RCU_TRACE
+#ifdef CONFIG_RCU_NOCB_CPU
+/* Sum up queue lengths for tracing. */
+static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll)
+{
+       *ql = atomic_long_read(&rdp->nocb_q_count) + rdp->nocb_p_count;
+       *qll = atomic_long_read(&rdp->nocb_q_count_lazy) + rdp->nocb_p_count_lazy;
+}
+#else /* #ifdef CONFIG_RCU_NOCB_CPU */
+static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll)
+{
+       *ql = 0;
+       *qll = 0;
+}
+#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */
+#endif /* #ifdef CONFIG_RCU_TRACE */
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
new file mode 100644 (file)
index 0000000..3822ac0
--- /dev/null
@@ -0,0 +1,2831 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion (tree-based version)
+ * Internal non-public definitions that provide either classic
+ * or preemptible semantics.
+ *
+ * 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 Red Hat, 2009
+ * Copyright IBM Corporation, 2009
+ *
+ * Author: Ingo Molnar <mingo@elte.hu>
+ *        Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/gfp.h>
+#include <linux/oom.h>
+#include <linux/smpboot.h>
+#include "../time/tick-internal.h"
+
+#define RCU_KTHREAD_PRIO 1
+
+#ifdef CONFIG_RCU_BOOST
+#define RCU_BOOST_PRIO CONFIG_RCU_BOOST_PRIO
+#else
+#define RCU_BOOST_PRIO RCU_KTHREAD_PRIO
+#endif
+
+#ifdef CONFIG_RCU_NOCB_CPU
+static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */
+static bool have_rcu_nocb_mask;            /* Was rcu_nocb_mask allocated? */
+static bool __read_mostly rcu_nocb_poll;    /* Offload kthread are to poll. */
+static char __initdata nocb_buf[NR_CPUS * 5];
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
+
+/*
+ * Check the RCU kernel configuration parameters and print informative
+ * messages about anything out of the ordinary.  If you like #ifdef, you
+ * will love this function.
+ */
+static void __init rcu_bootup_announce_oddness(void)
+{
+#ifdef CONFIG_RCU_TRACE
+       pr_info("\tRCU debugfs-based tracing is enabled.\n");
+#endif
+#if (defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 64) || (!defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 32)
+       pr_info("\tCONFIG_RCU_FANOUT set to non-default value of %d\n",
+              CONFIG_RCU_FANOUT);
+#endif
+#ifdef CONFIG_RCU_FANOUT_EXACT
+       pr_info("\tHierarchical RCU autobalancing is disabled.\n");
+#endif
+#ifdef CONFIG_RCU_FAST_NO_HZ
+       pr_info("\tRCU dyntick-idle grace-period acceleration is enabled.\n");
+#endif
+#ifdef CONFIG_PROVE_RCU
+       pr_info("\tRCU lockdep checking is enabled.\n");
+#endif
+#ifdef CONFIG_RCU_TORTURE_TEST_RUNNABLE
+       pr_info("\tRCU torture testing starts during boot.\n");
+#endif
+#if defined(CONFIG_TREE_PREEMPT_RCU) && !defined(CONFIG_RCU_CPU_STALL_VERBOSE)
+       pr_info("\tDump stacks of tasks blocking RCU-preempt GP.\n");
+#endif
+#if defined(CONFIG_RCU_CPU_STALL_INFO)
+       pr_info("\tAdditional per-CPU info printed with stalls.\n");
+#endif
+#if NUM_RCU_LVL_4 != 0
+       pr_info("\tFour-level hierarchy is enabled.\n");
+#endif
+       if (rcu_fanout_leaf != CONFIG_RCU_FANOUT_LEAF)
+               pr_info("\tBoot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf);
+       if (nr_cpu_ids != NR_CPUS)
+               pr_info("\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids);
+#ifdef CONFIG_RCU_NOCB_CPU
+#ifndef CONFIG_RCU_NOCB_CPU_NONE
+       if (!have_rcu_nocb_mask) {
+               zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL);
+               have_rcu_nocb_mask = true;
+       }
+#ifdef CONFIG_RCU_NOCB_CPU_ZERO
+       pr_info("\tOffload RCU callbacks from CPU 0\n");
+       cpumask_set_cpu(0, rcu_nocb_mask);
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ZERO */
+#ifdef CONFIG_RCU_NOCB_CPU_ALL
+       pr_info("\tOffload RCU callbacks from all CPUs\n");
+       cpumask_copy(rcu_nocb_mask, cpu_possible_mask);
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ALL */
+#endif /* #ifndef CONFIG_RCU_NOCB_CPU_NONE */
+       if (have_rcu_nocb_mask) {
+               if (!cpumask_subset(rcu_nocb_mask, cpu_possible_mask)) {
+                       pr_info("\tNote: kernel parameter 'rcu_nocbs=' contains nonexistent CPUs.\n");
+                       cpumask_and(rcu_nocb_mask, cpu_possible_mask,
+                                   rcu_nocb_mask);
+               }
+               cpulist_scnprintf(nocb_buf, sizeof(nocb_buf), rcu_nocb_mask);
+               pr_info("\tOffload RCU callbacks from CPUs: %s.\n", nocb_buf);
+               if (rcu_nocb_poll)
+                       pr_info("\tPoll for callbacks from no-CBs CPUs.\n");
+       }
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
+}
+
+#ifdef CONFIG_TREE_PREEMPT_RCU
+
+RCU_STATE_INITIALIZER(rcu_preempt, 'p', call_rcu);
+static struct rcu_state *rcu_state = &rcu_preempt_state;
+
+static int rcu_preempted_readers_exp(struct rcu_node *rnp);
+
+/*
+ * Tell them what RCU they are running.
+ */
+static void __init rcu_bootup_announce(void)
+{
+       pr_info("Preemptible hierarchical RCU implementation.\n");
+       rcu_bootup_announce_oddness();
+}
+
+/*
+ * Return the number of RCU-preempt batches processed thus far
+ * for debug and statistics.
+ */
+long rcu_batches_completed_preempt(void)
+{
+       return rcu_preempt_state.completed;
+}
+EXPORT_SYMBOL_GPL(rcu_batches_completed_preempt);
+
+/*
+ * Return the number of RCU batches processed thus far for debug & stats.
+ */
+long rcu_batches_completed(void)
+{
+       return rcu_batches_completed_preempt();
+}
+EXPORT_SYMBOL_GPL(rcu_batches_completed);
+
+/*
+ * Force a quiescent state for preemptible RCU.
+ */
+void rcu_force_quiescent_state(void)
+{
+       force_quiescent_state(&rcu_preempt_state);
+}
+EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
+
+/*
+ * Record a preemptible-RCU quiescent state for the specified CPU.  Note
+ * that this just means that the task currently running on the CPU is
+ * not in a quiescent state.  There might be any number of tasks blocked
+ * while in an RCU read-side critical section.
+ *
+ * Unlike the other rcu_*_qs() functions, callers to this function
+ * must disable irqs in order to protect the assignment to
+ * ->rcu_read_unlock_special.
+ */
+static void rcu_preempt_qs(int cpu)
+{
+       struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
+
+       if (rdp->passed_quiesce == 0)
+               trace_rcu_grace_period(TPS("rcu_preempt"), rdp->gpnum, TPS("cpuqs"));
+       rdp->passed_quiesce = 1;
+       current->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
+}
+
+/*
+ * We have entered the scheduler, and the current task might soon be
+ * context-switched away from.  If this task is in an RCU read-side
+ * critical section, we will no longer be able to rely on the CPU to
+ * record that fact, so we enqueue the task on the blkd_tasks list.
+ * The task will dequeue itself when it exits the outermost enclosing
+ * RCU read-side critical section.  Therefore, the current grace period
+ * cannot be permitted to complete until the blkd_tasks list entries
+ * predating the current grace period drain, in other words, until
+ * rnp->gp_tasks becomes NULL.
+ *
+ * Caller must disable preemption.
+ */
+static void rcu_preempt_note_context_switch(int cpu)
+{
+       struct task_struct *t = current;
+       unsigned long flags;
+       struct rcu_data *rdp;
+       struct rcu_node *rnp;
+
+       if (t->rcu_read_lock_nesting > 0 &&
+           (t->rcu_read_unlock_special & RCU_READ_UNLOCK_BLOCKED) == 0) {
+
+               /* Possibly blocking in an RCU read-side critical section. */
+               rdp = per_cpu_ptr(rcu_preempt_state.rda, cpu);
+               rnp = rdp->mynode;
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               t->rcu_read_unlock_special |= RCU_READ_UNLOCK_BLOCKED;
+               t->rcu_blocked_node = rnp;
+
+               /*
+                * If this CPU has already checked in, then this task
+                * will hold up the next grace period rather than the
+                * current grace period.  Queue the task accordingly.
+                * If the task is queued for the current grace period
+                * (i.e., this CPU has not yet passed through a quiescent
+                * state for the current grace period), then as long
+                * as that task remains queued, the current grace period
+                * cannot end.  Note that there is some uncertainty as
+                * to exactly when the current grace period started.
+                * We take a conservative approach, which can result
+                * in unnecessarily waiting on tasks that started very
+                * slightly after the current grace period began.  C'est
+                * la vie!!!
+                *
+                * But first, note that the current CPU must still be
+                * on line!
+                */
+               WARN_ON_ONCE((rdp->grpmask & rnp->qsmaskinit) == 0);
+               WARN_ON_ONCE(!list_empty(&t->rcu_node_entry));
+               if ((rnp->qsmask & rdp->grpmask) && rnp->gp_tasks != NULL) {
+                       list_add(&t->rcu_node_entry, rnp->gp_tasks->prev);
+                       rnp->gp_tasks = &t->rcu_node_entry;
+#ifdef CONFIG_RCU_BOOST
+                       if (rnp->boost_tasks != NULL)
+                               rnp->boost_tasks = rnp->gp_tasks;
+#endif /* #ifdef CONFIG_RCU_BOOST */
+               } else {
+                       list_add(&t->rcu_node_entry, &rnp->blkd_tasks);
+                       if (rnp->qsmask & rdp->grpmask)
+                               rnp->gp_tasks = &t->rcu_node_entry;
+               }
+               trace_rcu_preempt_task(rdp->rsp->name,
+                                      t->pid,
+                                      (rnp->qsmask & rdp->grpmask)
+                                      ? rnp->gpnum
+                                      : rnp->gpnum + 1);
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       } else if (t->rcu_read_lock_nesting < 0 &&
+                  t->rcu_read_unlock_special) {
+
+               /*
+                * Complete exit from RCU read-side critical section on
+                * behalf of preempted instance of __rcu_read_unlock().
+                */
+               rcu_read_unlock_special(t);
+       }
+
+       /*
+        * Either we were not in an RCU read-side critical section to
+        * begin with, or we have now recorded that critical section
+        * globally.  Either way, we can now note a quiescent state
+        * for this CPU.  Again, if we were in an RCU read-side critical
+        * section, and if that critical section was blocking the current
+        * grace period, then the fact that the task has been enqueued
+        * means that we continue to block the current grace period.
+        */
+       local_irq_save(flags);
+       rcu_preempt_qs(cpu);
+       local_irq_restore(flags);
+}
+
+/*
+ * Check for preempted RCU readers blocking the current grace period
+ * for the specified rcu_node structure.  If the caller needs a reliable
+ * answer, it must hold the rcu_node's ->lock.
+ */
+static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp)
+{
+       return rnp->gp_tasks != NULL;
+}
+
+/*
+ * Record a quiescent state for all tasks that were previously queued
+ * on the specified rcu_node structure and that were blocking the current
+ * RCU grace period.  The caller must hold the specified rnp->lock with
+ * irqs disabled, and this lock is released upon return, but irqs remain
+ * disabled.
+ */
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
+       __releases(rnp->lock)
+{
+       unsigned long mask;
+       struct rcu_node *rnp_p;
+
+       if (rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               return;  /* Still need more quiescent states! */
+       }
+
+       rnp_p = rnp->parent;
+       if (rnp_p == NULL) {
+               /*
+                * Either there is only one rcu_node in the tree,
+                * or tasks were kicked up to root rcu_node due to
+                * CPUs going offline.
+                */
+               rcu_report_qs_rsp(&rcu_preempt_state, flags);
+               return;
+       }
+
+       /* Report up the rest of the hierarchy. */
+       mask = rnp->grpmask;
+       raw_spin_unlock(&rnp->lock);    /* irqs remain disabled. */
+       raw_spin_lock(&rnp_p->lock);    /* irqs already disabled. */
+       rcu_report_qs_rnp(mask, &rcu_preempt_state, rnp_p, flags);
+}
+
+/*
+ * Advance a ->blkd_tasks-list pointer to the next entry, instead
+ * returning NULL if at the end of the list.
+ */
+static struct list_head *rcu_next_node_entry(struct task_struct *t,
+                                            struct rcu_node *rnp)
+{
+       struct list_head *np;
+
+       np = t->rcu_node_entry.next;
+       if (np == &rnp->blkd_tasks)
+               np = NULL;
+       return np;
+}
+
+/*
+ * Handle special cases during rcu_read_unlock(), such as needing to
+ * notify RCU core processing or task having blocked during the RCU
+ * read-side critical section.
+ */
+void rcu_read_unlock_special(struct task_struct *t)
+{
+       int empty;
+       int empty_exp;
+       int empty_exp_now;
+       unsigned long flags;
+       struct list_head *np;
+#ifdef CONFIG_RCU_BOOST
+       struct rt_mutex *rbmp = NULL;
+#endif /* #ifdef CONFIG_RCU_BOOST */
+       struct rcu_node *rnp;
+       int special;
+
+       /* NMI handlers cannot block and cannot safely manipulate state. */
+       if (in_nmi())
+               return;
+
+       local_irq_save(flags);
+
+       /*
+        * If RCU core is waiting for this CPU to exit critical section,
+        * let it know that we have done so.
+        */
+       special = t->rcu_read_unlock_special;
+       if (special & RCU_READ_UNLOCK_NEED_QS) {
+               rcu_preempt_qs(smp_processor_id());
+       }
+
+       /* Hardware IRQ handlers cannot block. */
+       if (in_irq() || in_serving_softirq()) {
+               local_irq_restore(flags);
+               return;
+       }
+
+       /* Clean up if blocked during RCU read-side critical section. */
+       if (special & RCU_READ_UNLOCK_BLOCKED) {
+               t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_BLOCKED;
+
+               /*
+                * Remove this task from the list it blocked on.  The
+                * task can migrate while we acquire the lock, but at
+                * most one time.  So at most two passes through loop.
+                */
+               for (;;) {
+                       rnp = t->rcu_blocked_node;
+                       raw_spin_lock(&rnp->lock);  /* irqs already disabled. */
+                       if (rnp == t->rcu_blocked_node)
+                               break;
+                       raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+               }
+               empty = !rcu_preempt_blocked_readers_cgp(rnp);
+               empty_exp = !rcu_preempted_readers_exp(rnp);
+               smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
+               np = rcu_next_node_entry(t, rnp);
+               list_del_init(&t->rcu_node_entry);
+               t->rcu_blocked_node = NULL;
+               trace_rcu_unlock_preempted_task(TPS("rcu_preempt"),
+                                               rnp->gpnum, t->pid);
+               if (&t->rcu_node_entry == rnp->gp_tasks)
+                       rnp->gp_tasks = np;
+               if (&t->rcu_node_entry == rnp->exp_tasks)
+                       rnp->exp_tasks = np;
+#ifdef CONFIG_RCU_BOOST
+               if (&t->rcu_node_entry == rnp->boost_tasks)
+                       rnp->boost_tasks = np;
+               /* Snapshot/clear ->rcu_boost_mutex with rcu_node lock held. */
+               if (t->rcu_boost_mutex) {
+                       rbmp = t->rcu_boost_mutex;
+                       t->rcu_boost_mutex = NULL;
+               }
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+               /*
+                * If this was the last task on the current list, and if
+                * we aren't waiting on any CPUs, report the quiescent state.
+                * Note that rcu_report_unblock_qs_rnp() releases rnp->lock,
+                * so we must take a snapshot of the expedited state.
+                */
+               empty_exp_now = !rcu_preempted_readers_exp(rnp);
+               if (!empty && !rcu_preempt_blocked_readers_cgp(rnp)) {
+                       trace_rcu_quiescent_state_report(TPS("preempt_rcu"),
+                                                        rnp->gpnum,
+                                                        0, rnp->qsmask,
+                                                        rnp->level,
+                                                        rnp->grplo,
+                                                        rnp->grphi,
+                                                        !!rnp->gp_tasks);
+                       rcu_report_unblock_qs_rnp(rnp, flags);
+               } else {
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               }
+
+#ifdef CONFIG_RCU_BOOST
+               /* Unboost if we were boosted. */
+               if (rbmp)
+                       rt_mutex_unlock(rbmp);
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+               /*
+                * If this was the last task on the expedited lists,
+                * then we need to report up the rcu_node hierarchy.
+                */
+               if (!empty_exp && empty_exp_now)
+                       rcu_report_exp_rnp(&rcu_preempt_state, rnp, true);
+       } else {
+               local_irq_restore(flags);
+       }
+}
+
+#ifdef CONFIG_RCU_CPU_STALL_VERBOSE
+
+/*
+ * Dump detailed information for all tasks blocking the current RCU
+ * grace period on the specified rcu_node structure.
+ */
+static void rcu_print_detail_task_stall_rnp(struct rcu_node *rnp)
+{
+       unsigned long flags;
+       struct task_struct *t;
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       if (!rcu_preempt_blocked_readers_cgp(rnp)) {
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               return;
+       }
+       t = list_entry(rnp->gp_tasks,
+                      struct task_struct, rcu_node_entry);
+       list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry)
+               sched_show_task(t);
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Dump detailed information for all tasks blocking the current RCU
+ * grace period.
+ */
+static void rcu_print_detail_task_stall(struct rcu_state *rsp)
+{
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       rcu_print_detail_task_stall_rnp(rnp);
+       rcu_for_each_leaf_node(rsp, rnp)
+               rcu_print_detail_task_stall_rnp(rnp);
+}
+
+#else /* #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */
+
+static void rcu_print_detail_task_stall(struct rcu_state *rsp)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */
+
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+
+static void rcu_print_task_stall_begin(struct rcu_node *rnp)
+{
+       pr_err("\tTasks blocked on level-%d rcu_node (CPUs %d-%d):",
+              rnp->level, rnp->grplo, rnp->grphi);
+}
+
+static void rcu_print_task_stall_end(void)
+{
+       pr_cont("\n");
+}
+
+#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+static void rcu_print_task_stall_begin(struct rcu_node *rnp)
+{
+}
+
+static void rcu_print_task_stall_end(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+/*
+ * Scan the current list of tasks blocked within RCU read-side critical
+ * sections, printing out the tid of each.
+ */
+static int rcu_print_task_stall(struct rcu_node *rnp)
+{
+       struct task_struct *t;
+       int ndetected = 0;
+
+       if (!rcu_preempt_blocked_readers_cgp(rnp))
+               return 0;
+       rcu_print_task_stall_begin(rnp);
+       t = list_entry(rnp->gp_tasks,
+                      struct task_struct, rcu_node_entry);
+       list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
+               pr_cont(" P%d", t->pid);
+               ndetected++;
+       }
+       rcu_print_task_stall_end();
+       return ndetected;
+}
+
+/*
+ * Check that the list of blocked tasks for the newly completed grace
+ * period is in fact empty.  It is a serious bug to complete a grace
+ * period that still has RCU readers blocked!  This function must be
+ * invoked -before- updating this rnp's ->gpnum, and the rnp's ->lock
+ * must be held by the caller.
+ *
+ * Also, if there are blocked tasks on the list, they automatically
+ * block the newly created grace period, so set up ->gp_tasks accordingly.
+ */
+static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
+{
+       WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp));
+       if (!list_empty(&rnp->blkd_tasks))
+               rnp->gp_tasks = rnp->blkd_tasks.next;
+       WARN_ON_ONCE(rnp->qsmask);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Handle tasklist migration for case in which all CPUs covered by the
+ * specified rcu_node have gone offline.  Move them up to the root
+ * rcu_node.  The reason for not just moving them to the immediate
+ * parent is to remove the need for rcu_read_unlock_special() to
+ * make more than two attempts to acquire the target rcu_node's lock.
+ * Returns true if there were tasks blocking the current RCU grace
+ * period.
+ *
+ * Returns 1 if there was previously a task blocking the current grace
+ * period on the specified rcu_node structure.
+ *
+ * The caller must hold rnp->lock with irqs disabled.
+ */
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+                                    struct rcu_node *rnp,
+                                    struct rcu_data *rdp)
+{
+       struct list_head *lp;
+       struct list_head *lp_root;
+       int retval = 0;
+       struct rcu_node *rnp_root = rcu_get_root(rsp);
+       struct task_struct *t;
+
+       if (rnp == rnp_root) {
+               WARN_ONCE(1, "Last CPU thought to be offlined?");
+               return 0;  /* Shouldn't happen: at least one CPU online. */
+       }
+
+       /* If we are on an internal node, complain bitterly. */
+       WARN_ON_ONCE(rnp != rdp->mynode);
+
+       /*
+        * Move tasks up to root rcu_node.  Don't try to get fancy for
+        * this corner-case operation -- just put this node's tasks
+        * at the head of the root node's list, and update the root node's
+        * ->gp_tasks and ->exp_tasks pointers to those of this node's,
+        * if non-NULL.  This might result in waiting for more tasks than
+        * absolutely necessary, but this is a good performance/complexity
+        * tradeoff.
+        */
+       if (rcu_preempt_blocked_readers_cgp(rnp) && rnp->qsmask == 0)
+               retval |= RCU_OFL_TASKS_NORM_GP;
+       if (rcu_preempted_readers_exp(rnp))
+               retval |= RCU_OFL_TASKS_EXP_GP;
+       lp = &rnp->blkd_tasks;
+       lp_root = &rnp_root->blkd_tasks;
+       while (!list_empty(lp)) {
+               t = list_entry(lp->next, typeof(*t), rcu_node_entry);
+               raw_spin_lock(&rnp_root->lock); /* irqs already disabled */
+               list_del(&t->rcu_node_entry);
+               t->rcu_blocked_node = rnp_root;
+               list_add(&t->rcu_node_entry, lp_root);
+               if (&t->rcu_node_entry == rnp->gp_tasks)
+                       rnp_root->gp_tasks = rnp->gp_tasks;
+               if (&t->rcu_node_entry == rnp->exp_tasks)
+                       rnp_root->exp_tasks = rnp->exp_tasks;
+#ifdef CONFIG_RCU_BOOST
+               if (&t->rcu_node_entry == rnp->boost_tasks)
+                       rnp_root->boost_tasks = rnp->boost_tasks;
+#endif /* #ifdef CONFIG_RCU_BOOST */
+               raw_spin_unlock(&rnp_root->lock); /* irqs still disabled */
+       }
+
+       rnp->gp_tasks = NULL;
+       rnp->exp_tasks = NULL;
+#ifdef CONFIG_RCU_BOOST
+       rnp->boost_tasks = NULL;
+       /*
+        * In case root is being boosted and leaf was not.  Make sure
+        * that we boost the tasks blocking the current grace period
+        * in this case.
+        */
+       raw_spin_lock(&rnp_root->lock); /* irqs already disabled */
+       if (rnp_root->boost_tasks != NULL &&
+           rnp_root->boost_tasks != rnp_root->gp_tasks &&
+           rnp_root->boost_tasks != rnp_root->exp_tasks)
+               rnp_root->boost_tasks = rnp_root->gp_tasks;
+       raw_spin_unlock(&rnp_root->lock); /* irqs still disabled */
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+       return retval;
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
+ * Check for a quiescent state from the current CPU.  When a task blocks,
+ * the task is recorded in the corresponding CPU's rcu_node structure,
+ * which is checked elsewhere.
+ *
+ * Caller must disable hard irqs.
+ */
+static void rcu_preempt_check_callbacks(int cpu)
+{
+       struct task_struct *t = current;
+
+       if (t->rcu_read_lock_nesting == 0) {
+               rcu_preempt_qs(cpu);
+               return;
+       }
+       if (t->rcu_read_lock_nesting > 0 &&
+           per_cpu(rcu_preempt_data, cpu).qs_pending)
+               t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS;
+}
+
+#ifdef CONFIG_RCU_BOOST
+
+static void rcu_preempt_do_callbacks(void)
+{
+       rcu_do_batch(&rcu_preempt_state, this_cpu_ptr(&rcu_preempt_data));
+}
+
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+/*
+ * Queue a preemptible-RCU callback for invocation after a grace period.
+ */
+void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_preempt_state, -1, 0);
+}
+EXPORT_SYMBOL_GPL(call_rcu);
+
+/*
+ * Queue an RCU callback for lazy invocation after a grace period.
+ * This will likely be later named something like "call_rcu_lazy()",
+ * but this change will require some way of tagging the lazy RCU
+ * callbacks in the list of pending callbacks.  Until then, this
+ * function may only be called from __kfree_rcu().
+ */
+void kfree_call_rcu(struct rcu_head *head,
+                   void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_preempt_state, -1, 1);
+}
+EXPORT_SYMBOL_GPL(kfree_call_rcu);
+
+/**
+ * synchronize_rcu - wait until a grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full grace
+ * period has elapsed, in other words after all currently executing RCU
+ * read-side critical sections have completed.  Note, however, that
+ * upon return from synchronize_rcu(), the caller might well be executing
+ * concurrently with new RCU read-side critical sections that began while
+ * synchronize_rcu() was waiting.  RCU read-side critical sections are
+ * delimited by rcu_read_lock() and rcu_read_unlock(), and may be nested.
+ *
+ * See the description of synchronize_sched() for more detailed information
+ * on memory ordering guarantees.
+ */
+void synchronize_rcu(void)
+{
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_rcu() in RCU read-side critical section");
+       if (!rcu_scheduler_active)
+               return;
+       if (rcu_expedited)
+               synchronize_rcu_expedited();
+       else
+               wait_rcu_gp(call_rcu);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu);
+
+static DECLARE_WAIT_QUEUE_HEAD(sync_rcu_preempt_exp_wq);
+static unsigned long sync_rcu_preempt_exp_count;
+static DEFINE_MUTEX(sync_rcu_preempt_exp_mutex);
+
+/*
+ * Return non-zero if there are any tasks in RCU read-side critical
+ * sections blocking the current preemptible-RCU expedited grace period.
+ * If there is no preemptible-RCU expedited grace period currently in
+ * progress, returns zero unconditionally.
+ */
+static int rcu_preempted_readers_exp(struct rcu_node *rnp)
+{
+       return rnp->exp_tasks != NULL;
+}
+
+/*
+ * return non-zero if there is no RCU expedited grace period in progress
+ * for the specified rcu_node structure, in other words, if all CPUs and
+ * tasks covered by the specified rcu_node structure have done their bit
+ * for the current expedited grace period.  Works only for preemptible
+ * RCU -- other RCU implementation use other means.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex.
+ */
+static int sync_rcu_preempt_exp_done(struct rcu_node *rnp)
+{
+       return !rcu_preempted_readers_exp(rnp) &&
+              ACCESS_ONCE(rnp->expmask) == 0;
+}
+
+/*
+ * Report the exit from RCU read-side critical section for the last task
+ * that queued itself during or before the current expedited preemptible-RCU
+ * grace period.  This event is reported either to the rcu_node structure on
+ * which the task was queued or to one of that rcu_node structure's ancestors,
+ * recursively up the tree.  (Calm down, calm down, we do the recursion
+ * iteratively!)
+ *
+ * Most callers will set the "wake" flag, but the task initiating the
+ * expedited grace period need not wake itself.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex.
+ */
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
+                              bool wake)
+{
+       unsigned long flags;
+       unsigned long mask;
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       for (;;) {
+               if (!sync_rcu_preempt_exp_done(rnp)) {
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       break;
+               }
+               if (rnp->parent == NULL) {
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       if (wake)
+                               wake_up(&sync_rcu_preempt_exp_wq);
+                       break;
+               }
+               mask = rnp->grpmask;
+               raw_spin_unlock(&rnp->lock); /* irqs remain disabled */
+               rnp = rnp->parent;
+               raw_spin_lock(&rnp->lock); /* irqs already disabled */
+               rnp->expmask &= ~mask;
+       }
+}
+
+/*
+ * Snapshot the tasks blocking the newly started preemptible-RCU expedited
+ * grace period for the specified rcu_node structure.  If there are no such
+ * tasks, report it up the rcu_node hierarchy.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex and must exclude
+ * CPU hotplug operations.
+ */
+static void
+sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+       unsigned long flags;
+       int must_wait = 0;
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       if (list_empty(&rnp->blkd_tasks)) {
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       } else {
+               rnp->exp_tasks = rnp->blkd_tasks.next;
+               rcu_initiate_boost(rnp, flags);  /* releases rnp->lock */
+               must_wait = 1;
+       }
+       if (!must_wait)
+               rcu_report_exp_rnp(rsp, rnp, false); /* Don't wake self. */
+}
+
+/**
+ * synchronize_rcu_expedited - Brute-force RCU grace period
+ *
+ * Wait for an RCU-preempt grace period, but expedite it.  The basic
+ * idea is to invoke synchronize_sched_expedited() to push all the tasks to
+ * the ->blkd_tasks lists and wait for this list to drain.  This consumes
+ * significant time on all CPUs and is unfriendly to real-time workloads,
+ * so is thus not recommended for any sort of common-case code.
+ * In fact, if you are using synchronize_rcu_expedited() in a loop,
+ * please restructure your code to batch your updates, and then Use a
+ * single synchronize_rcu() instead.
+ *
+ * Note that it is illegal to call this function while holding any lock
+ * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
+ * to call this function from a CPU-hotplug notifier.  Failing to observe
+ * these restriction will result in deadlock.
+ */
+void synchronize_rcu_expedited(void)
+{
+       unsigned long flags;
+       struct rcu_node *rnp;
+       struct rcu_state *rsp = &rcu_preempt_state;
+       unsigned long snap;
+       int trycount = 0;
+
+       smp_mb(); /* Caller's modifications seen first by other CPUs. */
+       snap = ACCESS_ONCE(sync_rcu_preempt_exp_count) + 1;
+       smp_mb(); /* Above access cannot bleed into critical section. */
+
+       /*
+        * Block CPU-hotplug operations.  This means that any CPU-hotplug
+        * operation that finds an rcu_node structure with tasks in the
+        * process of being boosted will know that all tasks blocking
+        * this expedited grace period will already be in the process of
+        * being boosted.  This simplifies the process of moving tasks
+        * from leaf to root rcu_node structures.
+        */
+       get_online_cpus();
+
+       /*
+        * Acquire lock, falling back to synchronize_rcu() if too many
+        * lock-acquisition failures.  Of course, if someone does the
+        * expedited grace period for us, just leave.
+        */
+       while (!mutex_trylock(&sync_rcu_preempt_exp_mutex)) {
+               if (ULONG_CMP_LT(snap,
+                   ACCESS_ONCE(sync_rcu_preempt_exp_count))) {
+                       put_online_cpus();
+                       goto mb_ret; /* Others did our work for us. */
+               }
+               if (trycount++ < 10) {
+                       udelay(trycount * num_online_cpus());
+               } else {
+                       put_online_cpus();
+                       wait_rcu_gp(call_rcu);
+                       return;
+               }
+       }
+       if (ULONG_CMP_LT(snap, ACCESS_ONCE(sync_rcu_preempt_exp_count))) {
+               put_online_cpus();
+               goto unlock_mb_ret; /* Others did our work for us. */
+       }
+
+       /* force all RCU readers onto ->blkd_tasks lists. */
+       synchronize_sched_expedited();
+
+       /* Initialize ->expmask for all non-leaf rcu_node structures. */
+       rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) {
+               raw_spin_lock_irqsave(&rnp->lock, flags);
+               rnp->expmask = rnp->qsmaskinit;
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       }
+
+       /* Snapshot current state of ->blkd_tasks lists. */
+       rcu_for_each_leaf_node(rsp, rnp)
+               sync_rcu_preempt_exp_init(rsp, rnp);
+       if (NUM_RCU_NODES > 1)
+               sync_rcu_preempt_exp_init(rsp, rcu_get_root(rsp));
+
+       put_online_cpus();
+
+       /* Wait for snapshotted ->blkd_tasks lists to drain. */
+       rnp = rcu_get_root(rsp);
+       wait_event(sync_rcu_preempt_exp_wq,
+                  sync_rcu_preempt_exp_done(rnp));
+
+       /* Clean up and exit. */
+       smp_mb(); /* ensure expedited GP seen before counter increment. */
+       ACCESS_ONCE(sync_rcu_preempt_exp_count)++;
+unlock_mb_ret:
+       mutex_unlock(&sync_rcu_preempt_exp_mutex);
+mb_ret:
+       smp_mb(); /* ensure subsequent action seen after grace period. */
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+
+/**
+ * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete.
+ *
+ * Note that this primitive does not necessarily wait for an RCU grace period
+ * to complete.  For example, if there are no RCU callbacks queued anywhere
+ * in the system, then rcu_barrier() is within its rights to return
+ * immediately, without waiting for anything, much less an RCU grace period.
+ */
+void rcu_barrier(void)
+{
+       _rcu_barrier(&rcu_preempt_state);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
+/*
+ * Initialize preemptible RCU's state structures.
+ */
+static void __init __rcu_init_preempt(void)
+{
+       rcu_init_one(&rcu_preempt_state, &rcu_preempt_data);
+}
+
+/*
+ * Check for a task exiting while in a preemptible-RCU read-side
+ * critical section, clean up if so.  No need to issue warnings,
+ * as debug_check_no_locks_held() already does this if lockdep
+ * is enabled.
+ */
+void exit_rcu(void)
+{
+       struct task_struct *t = current;
+
+       if (likely(list_empty(&current->rcu_node_entry)))
+               return;
+       t->rcu_read_lock_nesting = 1;
+       barrier();
+       t->rcu_read_unlock_special = RCU_READ_UNLOCK_BLOCKED;
+       __rcu_read_unlock();
+}
+
+#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+
+static struct rcu_state *rcu_state = &rcu_sched_state;
+
+/*
+ * Tell them what RCU they are running.
+ */
+static void __init rcu_bootup_announce(void)
+{
+       pr_info("Hierarchical RCU implementation.\n");
+       rcu_bootup_announce_oddness();
+}
+
+/*
+ * Return the number of RCU batches processed thus far for debug & stats.
+ */
+long rcu_batches_completed(void)
+{
+       return rcu_batches_completed_sched();
+}
+EXPORT_SYMBOL_GPL(rcu_batches_completed);
+
+/*
+ * Force a quiescent state for RCU, which, because there is no preemptible
+ * RCU, becomes the same as rcu-sched.
+ */
+void rcu_force_quiescent_state(void)
+{
+       rcu_sched_force_quiescent_state();
+}
+EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
+
+/*
+ * Because preemptible RCU does not exist, we never have to check for
+ * CPUs being in quiescent states.
+ */
+static void rcu_preempt_note_context_switch(int cpu)
+{
+}
+
+/*
+ * Because preemptible RCU does not exist, there are never any preempted
+ * RCU readers.
+ */
+static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp)
+{
+       return 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/* Because preemptible RCU does not exist, no quieting of tasks. */
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
+{
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
+ * Because preemptible RCU does not exist, we never have to check for
+ * tasks blocked within RCU read-side critical sections.
+ */
+static void rcu_print_detail_task_stall(struct rcu_state *rsp)
+{
+}
+
+/*
+ * Because preemptible RCU does not exist, we never have to check for
+ * tasks blocked within RCU read-side critical sections.
+ */
+static int rcu_print_task_stall(struct rcu_node *rnp)
+{
+       return 0;
+}
+
+/*
+ * Because there is no preemptible RCU, there can be no readers blocked,
+ * so there is no need to check for blocked tasks.  So check only for
+ * bogus qsmask values.
+ */
+static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
+{
+       WARN_ON_ONCE(rnp->qsmask);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Because preemptible RCU does not exist, it never needs to migrate
+ * tasks that were blocked within RCU read-side critical sections, and
+ * such non-existent tasks cannot possibly have been blocking the current
+ * grace period.
+ */
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+                                    struct rcu_node *rnp,
+                                    struct rcu_data *rdp)
+{
+       return 0;
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
+ * Because preemptible RCU does not exist, it never has any callbacks
+ * to check.
+ */
+static void rcu_preempt_check_callbacks(int cpu)
+{
+}
+
+/*
+ * Queue an RCU callback for lazy invocation after a grace period.
+ * This will likely be later named something like "call_rcu_lazy()",
+ * but this change will require some way of tagging the lazy RCU
+ * callbacks in the list of pending callbacks.  Until then, this
+ * function may only be called from __kfree_rcu().
+ *
+ * Because there is no preemptible RCU, we use RCU-sched instead.
+ */
+void kfree_call_rcu(struct rcu_head *head,
+                   void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_sched_state, -1, 1);
+}
+EXPORT_SYMBOL_GPL(kfree_call_rcu);
+
+/*
+ * Wait for an rcu-preempt grace period, but make it happen quickly.
+ * But because preemptible RCU does not exist, map to rcu-sched.
+ */
+void synchronize_rcu_expedited(void)
+{
+       synchronize_sched_expedited();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Because preemptible RCU does not exist, there is never any need to
+ * report on tasks preempted in RCU read-side critical sections during
+ * expedited RCU grace periods.
+ */
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
+                              bool wake)
+{
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
+/*
+ * Because preemptible RCU does not exist, rcu_barrier() is just
+ * another name for rcu_barrier_sched().
+ */
+void rcu_barrier(void)
+{
+       rcu_barrier_sched();
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
+/*
+ * Because preemptible RCU does not exist, it need not be initialized.
+ */
+static void __init __rcu_init_preempt(void)
+{
+}
+
+/*
+ * Because preemptible RCU does not exist, tasks cannot possibly exit
+ * while in preemptible RCU read-side critical sections.
+ */
+void exit_rcu(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
+
+#ifdef CONFIG_RCU_BOOST
+
+#include "../rtmutex_common.h"
+
+#ifdef CONFIG_RCU_TRACE
+
+static void rcu_initiate_boost_trace(struct rcu_node *rnp)
+{
+       if (list_empty(&rnp->blkd_tasks))
+               rnp->n_balk_blkd_tasks++;
+       else if (rnp->exp_tasks == NULL && rnp->gp_tasks == NULL)
+               rnp->n_balk_exp_gp_tasks++;
+       else if (rnp->gp_tasks != NULL && rnp->boost_tasks != NULL)
+               rnp->n_balk_boost_tasks++;
+       else if (rnp->gp_tasks != NULL && rnp->qsmask != 0)
+               rnp->n_balk_notblocked++;
+       else if (rnp->gp_tasks != NULL &&
+                ULONG_CMP_LT(jiffies, rnp->boost_time))
+               rnp->n_balk_notyet++;
+       else
+               rnp->n_balk_nos++;
+}
+
+#else /* #ifdef CONFIG_RCU_TRACE */
+
+static void rcu_initiate_boost_trace(struct rcu_node *rnp)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+static void rcu_wake_cond(struct task_struct *t, int status)
+{
+       /*
+        * If the thread is yielding, only wake it when this
+        * is invoked from idle
+        */
+       if (status != RCU_KTHREAD_YIELDING || is_idle_task(current))
+               wake_up_process(t);
+}
+
+/*
+ * Carry out RCU priority boosting on the task indicated by ->exp_tasks
+ * or ->boost_tasks, advancing the pointer to the next task in the
+ * ->blkd_tasks list.
+ *
+ * Note that irqs must be enabled: boosting the task can block.
+ * Returns 1 if there are more tasks needing to be boosted.
+ */
+static int rcu_boost(struct rcu_node *rnp)
+{
+       unsigned long flags;
+       struct rt_mutex mtx;
+       struct task_struct *t;
+       struct list_head *tb;
+
+       if (rnp->exp_tasks == NULL && rnp->boost_tasks == NULL)
+               return 0;  /* Nothing left to boost. */
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+
+       /*
+        * Recheck under the lock: all tasks in need of boosting
+        * might exit their RCU read-side critical sections on their own.
+        */
+       if (rnp->exp_tasks == NULL && rnp->boost_tasks == NULL) {
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               return 0;
+       }
+
+       /*
+        * Preferentially boost tasks blocking expedited grace periods.
+        * This cannot starve the normal grace periods because a second
+        * expedited grace period must boost all blocked tasks, including
+        * those blocking the pre-existing normal grace period.
+        */
+       if (rnp->exp_tasks != NULL) {
+               tb = rnp->exp_tasks;
+               rnp->n_exp_boosts++;
+       } else {
+               tb = rnp->boost_tasks;
+               rnp->n_normal_boosts++;
+       }
+       rnp->n_tasks_boosted++;
+
+       /*
+        * We boost task t by manufacturing an rt_mutex that appears to
+        * be held by task t.  We leave a pointer to that rt_mutex where
+        * task t can find it, and task t will release the mutex when it
+        * exits its outermost RCU read-side critical section.  Then
+        * simply acquiring this artificial rt_mutex will boost task
+        * t's priority.  (Thanks to tglx for suggesting this approach!)
+        *
+        * Note that task t must acquire rnp->lock to remove itself from
+        * the ->blkd_tasks list, which it will do from exit() if from
+        * nowhere else.  We therefore are guaranteed that task t will
+        * stay around at least until we drop rnp->lock.  Note that
+        * rnp->lock also resolves races between our priority boosting
+        * and task t's exiting its outermost RCU read-side critical
+        * section.
+        */
+       t = container_of(tb, struct task_struct, rcu_node_entry);
+       rt_mutex_init_proxy_locked(&mtx, t);
+       t->rcu_boost_mutex = &mtx;
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       rt_mutex_lock(&mtx);  /* Side effect: boosts task t's priority. */
+       rt_mutex_unlock(&mtx);  /* Keep lockdep happy. */
+
+       return ACCESS_ONCE(rnp->exp_tasks) != NULL ||
+              ACCESS_ONCE(rnp->boost_tasks) != NULL;
+}
+
+/*
+ * Priority-boosting kthread.  One per leaf rcu_node and one for the
+ * root rcu_node.
+ */
+static int rcu_boost_kthread(void *arg)
+{
+       struct rcu_node *rnp = (struct rcu_node *)arg;
+       int spincnt = 0;
+       int more2boost;
+
+       trace_rcu_utilization(TPS("Start boost kthread@init"));
+       for (;;) {
+               rnp->boost_kthread_status = RCU_KTHREAD_WAITING;
+               trace_rcu_utilization(TPS("End boost kthread@rcu_wait"));
+               rcu_wait(rnp->boost_tasks || rnp->exp_tasks);
+               trace_rcu_utilization(TPS("Start boost kthread@rcu_wait"));
+               rnp->boost_kthread_status = RCU_KTHREAD_RUNNING;
+               more2boost = rcu_boost(rnp);
+               if (more2boost)
+                       spincnt++;
+               else
+                       spincnt = 0;
+               if (spincnt > 10) {
+                       rnp->boost_kthread_status = RCU_KTHREAD_YIELDING;
+                       trace_rcu_utilization(TPS("End boost kthread@rcu_yield"));
+                       schedule_timeout_interruptible(2);
+                       trace_rcu_utilization(TPS("Start boost kthread@rcu_yield"));
+                       spincnt = 0;
+               }
+       }
+       /* NOTREACHED */
+       trace_rcu_utilization(TPS("End boost kthread@notreached"));
+       return 0;
+}
+
+/*
+ * Check to see if it is time to start boosting RCU readers that are
+ * blocking the current grace period, and, if so, tell the per-rcu_node
+ * kthread to start boosting them.  If there is an expedited grace
+ * period in progress, it is always time to boost.
+ *
+ * The caller must hold rnp->lock, which this function releases.
+ * The ->boost_kthread_task is immortal, so we don't need to worry
+ * about it going away.
+ */
+static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
+{
+       struct task_struct *t;
+
+       if (!rcu_preempt_blocked_readers_cgp(rnp) && rnp->exp_tasks == NULL) {
+               rnp->n_balk_exp_gp_tasks++;
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               return;
+       }
+       if (rnp->exp_tasks != NULL ||
+           (rnp->gp_tasks != NULL &&
+            rnp->boost_tasks == NULL &&
+            rnp->qsmask == 0 &&
+            ULONG_CMP_GE(jiffies, rnp->boost_time))) {
+               if (rnp->exp_tasks == NULL)
+                       rnp->boost_tasks = rnp->gp_tasks;
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               t = rnp->boost_kthread_task;
+               if (t)
+                       rcu_wake_cond(t, rnp->boost_kthread_status);
+       } else {
+               rcu_initiate_boost_trace(rnp);
+               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       }
+}
+
+/*
+ * Wake up the per-CPU kthread to invoke RCU callbacks.
+ */
+static void invoke_rcu_callbacks_kthread(void)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __this_cpu_write(rcu_cpu_has_work, 1);
+       if (__this_cpu_read(rcu_cpu_kthread_task) != NULL &&
+           current != __this_cpu_read(rcu_cpu_kthread_task)) {
+               rcu_wake_cond(__this_cpu_read(rcu_cpu_kthread_task),
+                             __this_cpu_read(rcu_cpu_kthread_status));
+       }
+       local_irq_restore(flags);
+}
+
+/*
+ * Is the current CPU running the RCU-callbacks kthread?
+ * Caller must have preemption disabled.
+ */
+static bool rcu_is_callbacks_kthread(void)
+{
+       return __this_cpu_read(rcu_cpu_kthread_task) == current;
+}
+
+#define RCU_BOOST_DELAY_JIFFIES DIV_ROUND_UP(CONFIG_RCU_BOOST_DELAY * HZ, 1000)
+
+/*
+ * Do priority-boost accounting for the start of a new grace period.
+ */
+static void rcu_preempt_boost_start_gp(struct rcu_node *rnp)
+{
+       rnp->boost_time = jiffies + RCU_BOOST_DELAY_JIFFIES;
+}
+
+/*
+ * Create an RCU-boost kthread for the specified node if one does not
+ * already exist.  We only create this kthread for preemptible RCU.
+ * Returns zero if all is well, a negated errno otherwise.
+ */
+static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
+                                                struct rcu_node *rnp)
+{
+       int rnp_index = rnp - &rsp->node[0];
+       unsigned long flags;
+       struct sched_param sp;
+       struct task_struct *t;
+
+       if (&rcu_preempt_state != rsp)
+               return 0;
+
+       if (!rcu_scheduler_fully_active || rnp->qsmaskinit == 0)
+               return 0;
+
+       rsp->boost = 1;
+       if (rnp->boost_kthread_task != NULL)
+               return 0;
+       t = kthread_create(rcu_boost_kthread, (void *)rnp,
+                          "rcub/%d", rnp_index);
+       if (IS_ERR(t))
+               return PTR_ERR(t);
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       rnp->boost_kthread_task = t;
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       sp.sched_priority = RCU_BOOST_PRIO;
+       sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
+       wake_up_process(t); /* get to TASK_INTERRUPTIBLE quickly. */
+       return 0;
+}
+
+static void rcu_kthread_do_work(void)
+{
+       rcu_do_batch(&rcu_sched_state, this_cpu_ptr(&rcu_sched_data));
+       rcu_do_batch(&rcu_bh_state, this_cpu_ptr(&rcu_bh_data));
+       rcu_preempt_do_callbacks();
+}
+
+static void rcu_cpu_kthread_setup(unsigned int cpu)
+{
+       struct sched_param sp;
+
+       sp.sched_priority = RCU_KTHREAD_PRIO;
+       sched_setscheduler_nocheck(current, SCHED_FIFO, &sp);
+}
+
+static void rcu_cpu_kthread_park(unsigned int cpu)
+{
+       per_cpu(rcu_cpu_kthread_status, cpu) = RCU_KTHREAD_OFFCPU;
+}
+
+static int rcu_cpu_kthread_should_run(unsigned int cpu)
+{
+       return __this_cpu_read(rcu_cpu_has_work);
+}
+
+/*
+ * Per-CPU kernel thread that invokes RCU callbacks.  This replaces the
+ * RCU softirq used in flavors and configurations of RCU that do not
+ * support RCU priority boosting.
+ */
+static void rcu_cpu_kthread(unsigned int cpu)
+{
+       unsigned int *statusp = this_cpu_ptr(&rcu_cpu_kthread_status);
+       char work, *workp = this_cpu_ptr(&rcu_cpu_has_work);
+       int spincnt;
+
+       for (spincnt = 0; spincnt < 10; spincnt++) {
+               trace_rcu_utilization(TPS("Start CPU kthread@rcu_wait"));
+               local_bh_disable();
+               *statusp = RCU_KTHREAD_RUNNING;
+               this_cpu_inc(rcu_cpu_kthread_loops);
+               local_irq_disable();
+               work = *workp;
+               *workp = 0;
+               local_irq_enable();
+               if (work)
+                       rcu_kthread_do_work();
+               local_bh_enable();
+               if (*workp == 0) {
+                       trace_rcu_utilization(TPS("End CPU kthread@rcu_wait"));
+                       *statusp = RCU_KTHREAD_WAITING;
+                       return;
+               }
+       }
+       *statusp = RCU_KTHREAD_YIELDING;
+       trace_rcu_utilization(TPS("Start CPU kthread@rcu_yield"));
+       schedule_timeout_interruptible(2);
+       trace_rcu_utilization(TPS("End CPU kthread@rcu_yield"));
+       *statusp = RCU_KTHREAD_WAITING;
+}
+
+/*
+ * Set the per-rcu_node kthread's affinity to cover all CPUs that are
+ * served by the rcu_node in question.  The CPU hotplug lock is still
+ * held, so the value of rnp->qsmaskinit will be stable.
+ *
+ * We don't include outgoingcpu in the affinity set, use -1 if there is
+ * no outgoing CPU.  If there are no CPUs left in the affinity set,
+ * this function allows the kthread to execute on any CPU.
+ */
+static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu)
+{
+       struct task_struct *t = rnp->boost_kthread_task;
+       unsigned long mask = rnp->qsmaskinit;
+       cpumask_var_t cm;
+       int cpu;
+
+       if (!t)
+               return;
+       if (!zalloc_cpumask_var(&cm, GFP_KERNEL))
+               return;
+       for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1)
+               if ((mask & 0x1) && cpu != outgoingcpu)
+                       cpumask_set_cpu(cpu, cm);
+       if (cpumask_weight(cm) == 0) {
+               cpumask_setall(cm);
+               for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++)
+                       cpumask_clear_cpu(cpu, cm);
+               WARN_ON_ONCE(cpumask_weight(cm) == 0);
+       }
+       set_cpus_allowed_ptr(t, cm);
+       free_cpumask_var(cm);
+}
+
+static struct smp_hotplug_thread rcu_cpu_thread_spec = {
+       .store                  = &rcu_cpu_kthread_task,
+       .thread_should_run      = rcu_cpu_kthread_should_run,
+       .thread_fn              = rcu_cpu_kthread,
+       .thread_comm            = "rcuc/%u",
+       .setup                  = rcu_cpu_kthread_setup,
+       .park                   = rcu_cpu_kthread_park,
+};
+
+/*
+ * Spawn all kthreads -- called as soon as the scheduler is running.
+ */
+static int __init rcu_spawn_kthreads(void)
+{
+       struct rcu_node *rnp;
+       int cpu;
+
+       rcu_scheduler_fully_active = 1;
+       for_each_possible_cpu(cpu)
+               per_cpu(rcu_cpu_has_work, cpu) = 0;
+       BUG_ON(smpboot_register_percpu_thread(&rcu_cpu_thread_spec));
+       rnp = rcu_get_root(rcu_state);
+       (void)rcu_spawn_one_boost_kthread(rcu_state, rnp);
+       if (NUM_RCU_NODES > 1) {
+               rcu_for_each_leaf_node(rcu_state, rnp)
+                       (void)rcu_spawn_one_boost_kthread(rcu_state, rnp);
+       }
+       return 0;
+}
+early_initcall(rcu_spawn_kthreads);
+
+static void rcu_prepare_kthreads(int cpu)
+{
+       struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
+       struct rcu_node *rnp = rdp->mynode;
+
+       /* Fire up the incoming CPU's kthread and leaf rcu_node kthread. */
+       if (rcu_scheduler_fully_active)
+               (void)rcu_spawn_one_boost_kthread(rcu_state, rnp);
+}
+
+#else /* #ifdef CONFIG_RCU_BOOST */
+
+static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
+{
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+static void invoke_rcu_callbacks_kthread(void)
+{
+       WARN_ON_ONCE(1);
+}
+
+static bool rcu_is_callbacks_kthread(void)
+{
+       return false;
+}
+
+static void rcu_preempt_boost_start_gp(struct rcu_node *rnp)
+{
+}
+
+static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu)
+{
+}
+
+static int __init rcu_scheduler_really_started(void)
+{
+       rcu_scheduler_fully_active = 1;
+       return 0;
+}
+early_initcall(rcu_scheduler_really_started);
+
+static void rcu_prepare_kthreads(int cpu)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_BOOST */
+
+#if !defined(CONFIG_RCU_FAST_NO_HZ)
+
+/*
+ * Check to see if any future RCU-related work will need to be done
+ * by the current CPU, even if none need be done immediately, returning
+ * 1 if so.  This function is part of the RCU implementation; it is -not-
+ * an exported member of the RCU API.
+ *
+ * Because we not have RCU_FAST_NO_HZ, just check whether this CPU needs
+ * any flavor of RCU.
+ */
+int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies)
+{
+       *delta_jiffies = ULONG_MAX;
+       return rcu_cpu_has_callbacks(cpu, NULL);
+}
+
+/*
+ * Because we do not have RCU_FAST_NO_HZ, don't bother cleaning up
+ * after it.
+ */
+static void rcu_cleanup_after_idle(int cpu)
+{
+}
+
+/*
+ * Do the idle-entry grace-period work, which, because CONFIG_RCU_FAST_NO_HZ=n,
+ * is nothing.
+ */
+static void rcu_prepare_for_idle(int cpu)
+{
+}
+
+/*
+ * Don't bother keeping a running count of the number of RCU callbacks
+ * posted because CONFIG_RCU_FAST_NO_HZ=n.
+ */
+static void rcu_idle_count_callbacks_posted(void)
+{
+}
+
+#else /* #if !defined(CONFIG_RCU_FAST_NO_HZ) */
+
+/*
+ * This code is invoked when a CPU goes idle, at which point we want
+ * to have the CPU do everything required for RCU so that it can enter
+ * the energy-efficient dyntick-idle mode.  This is handled by a
+ * state machine implemented by rcu_prepare_for_idle() below.
+ *
+ * The following three proprocessor symbols control this state machine:
+ *
+ * RCU_IDLE_GP_DELAY gives the number of jiffies that a CPU is permitted
+ *     to sleep in dyntick-idle mode with RCU callbacks pending.  This
+ *     is sized to be roughly one RCU grace period.  Those energy-efficiency
+ *     benchmarkers who might otherwise be tempted to set this to a large
+ *     number, be warned: Setting RCU_IDLE_GP_DELAY too high can hang your
+ *     system.  And if you are -that- concerned about energy efficiency,
+ *     just power the system down and be done with it!
+ * RCU_IDLE_LAZY_GP_DELAY gives the number of jiffies that a CPU is
+ *     permitted to sleep in dyntick-idle mode with only lazy RCU
+ *     callbacks pending.  Setting this too high can OOM your system.
+ *
+ * The values below work well in practice.  If future workloads require
+ * adjustment, they can be converted into kernel config parameters, though
+ * making the state machine smarter might be a better option.
+ */
+#define RCU_IDLE_GP_DELAY 4            /* Roughly one grace period. */
+#define RCU_IDLE_LAZY_GP_DELAY (6 * HZ)        /* Roughly six seconds. */
+
+static int rcu_idle_gp_delay = RCU_IDLE_GP_DELAY;
+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;
+
+/*
+ * Try to advance callbacks for all flavors of RCU on the current CPU, but
+ * only if it has been awhile since the last time we did so.  Afterwards,
+ * if there are any callbacks ready for immediate invocation, return true.
+ */
+static bool rcu_try_advance_all_cbs(void)
+{
+       bool cbs_ready = false;
+       struct rcu_data *rdp;
+       struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
+       struct rcu_node *rnp;
+       struct rcu_state *rsp;
+
+       /* Exit early if we advanced recently. */
+       if (jiffies == rdtp->last_advance_all)
+               return 0;
+       rdtp->last_advance_all = jiffies;
+
+       for_each_rcu_flavor(rsp) {
+               rdp = this_cpu_ptr(rsp->rda);
+               rnp = rdp->mynode;
+
+               /*
+                * Don't bother checking unless a grace period has
+                * completed since we last checked and there are
+                * callbacks not yet ready to invoke.
+                */
+               if (rdp->completed != rnp->completed &&
+                   rdp->nxttail[RCU_DONE_TAIL] != rdp->nxttail[RCU_NEXT_TAIL])
+                       note_gp_changes(rsp, rdp);
+
+               if (cpu_has_callbacks_ready_to_invoke(rdp))
+                       cbs_ready = true;
+       }
+       return cbs_ready;
+}
+
+/*
+ * Allow the CPU to enter dyntick-idle mode unless it has callbacks ready
+ * to invoke.  If the CPU has callbacks, try to advance them.  Tell the
+ * caller to set the timeout based on whether or not there are non-lazy
+ * callbacks.
+ *
+ * The caller must have disabled interrupts.
+ */
+int rcu_needs_cpu(int cpu, unsigned long *dj)
+{
+       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
+
+       /* Snapshot to detect later posting of non-lazy callback. */
+       rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted;
+
+       /* If no callbacks, RCU doesn't need the CPU. */
+       if (!rcu_cpu_has_callbacks(cpu, &rdtp->all_lazy)) {
+               *dj = ULONG_MAX;
+               return 0;
+       }
+
+       /* Attempt to advance callbacks. */
+       if (rcu_try_advance_all_cbs()) {
+               /* Some ready to invoke, so initiate later invocation. */
+               invoke_rcu_core();
+               return 1;
+       }
+       rdtp->last_accelerate = jiffies;
+
+       /* Request timer delay depending on laziness, and round. */
+       if (!rdtp->all_lazy) {
+               *dj = round_up(rcu_idle_gp_delay + jiffies,
+                              rcu_idle_gp_delay) - jiffies;
+       } else {
+               *dj = round_jiffies(rcu_idle_lazy_gp_delay + jiffies) - jiffies;
+       }
+       return 0;
+}
+
+/*
+ * Prepare a CPU for idle from an RCU perspective.  The first major task
+ * is to sense whether nohz mode has been enabled or disabled via sysfs.
+ * The second major task is to check to see if a non-lazy callback has
+ * arrived at a CPU that previously had only lazy callbacks.  The third
+ * major task is to accelerate (that is, assign grace-period numbers to)
+ * any recently arrived callbacks.
+ *
+ * The caller must have disabled interrupts.
+ */
+static void rcu_prepare_for_idle(int cpu)
+{
+       struct rcu_data *rdp;
+       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
+       struct rcu_node *rnp;
+       struct rcu_state *rsp;
+       int tne;
+
+       /* Handle nohz enablement switches conservatively. */
+       tne = ACCESS_ONCE(tick_nohz_enabled);
+       if (tne != rdtp->tick_nohz_enabled_snap) {
+               if (rcu_cpu_has_callbacks(cpu, NULL))
+                       invoke_rcu_core(); /* force nohz to see update. */
+               rdtp->tick_nohz_enabled_snap = tne;
+               return;
+       }
+       if (!tne)
+               return;
+
+       /* If this is a no-CBs CPU, no callbacks, just return. */
+       if (rcu_is_nocb_cpu(cpu))
+               return;
+
+       /*
+        * If a non-lazy callback arrived at a CPU having only lazy
+        * callbacks, invoke RCU core for the side-effect of recalculating
+        * idle duration on re-entry to idle.
+        */
+       if (rdtp->all_lazy &&
+           rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) {
+               rdtp->all_lazy = false;
+               rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted;
+               invoke_rcu_core();
+               return;
+       }
+
+       /*
+        * If we have not yet accelerated this jiffy, accelerate all
+        * callbacks on this CPU.
+        */
+       if (rdtp->last_accelerate == jiffies)
+               return;
+       rdtp->last_accelerate = jiffies;
+       for_each_rcu_flavor(rsp) {
+               rdp = per_cpu_ptr(rsp->rda, cpu);
+               if (!*rdp->nxttail[RCU_DONE_TAIL])
+                       continue;
+               rnp = rdp->mynode;
+               raw_spin_lock(&rnp->lock); /* irqs already disabled. */
+               rcu_accelerate_cbs(rsp, rnp, rdp);
+               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+       }
+}
+
+/*
+ * Clean up for exit from idle.  Attempt to advance callbacks based on
+ * any grace periods that elapsed while the CPU was idle, and if any
+ * callbacks are now ready to invoke, initiate invocation.
+ */
+static void rcu_cleanup_after_idle(int cpu)
+{
+
+       if (rcu_is_nocb_cpu(cpu))
+               return;
+       if (rcu_try_advance_all_cbs())
+               invoke_rcu_core();
+}
+
+/*
+ * Keep a running count of the number of non-lazy callbacks posted
+ * on this CPU.  This running counter (which is never decremented) allows
+ * rcu_prepare_for_idle() to detect when something out of the idle loop
+ * posts a callback, even if an equal number of callbacks are invoked.
+ * Of course, callbacks should only be posted from within a trace event
+ * designed to be called from idle or from within RCU_NONIDLE().
+ */
+static void rcu_idle_count_callbacks_posted(void)
+{
+       __this_cpu_add(rcu_dynticks.nonlazy_posted, 1);
+}
+
+/*
+ * Data for flushing lazy RCU callbacks at OOM time.
+ */
+static atomic_t oom_callback_count;
+static DECLARE_WAIT_QUEUE_HEAD(oom_callback_wq);
+
+/*
+ * RCU OOM callback -- decrement the outstanding count and deliver the
+ * wake-up if we are the last one.
+ */
+static void rcu_oom_callback(struct rcu_head *rhp)
+{
+       if (atomic_dec_and_test(&oom_callback_count))
+               wake_up(&oom_callback_wq);
+}
+
+/*
+ * Post an rcu_oom_notify callback on the current CPU if it has at
+ * least one lazy callback.  This will unnecessarily post callbacks
+ * to CPUs that already have a non-lazy callback at the end of their
+ * callback list, but this is an infrequent operation, so accept some
+ * extra overhead to keep things simple.
+ */
+static void rcu_oom_notify_cpu(void *unused)
+{
+       struct rcu_state *rsp;
+       struct rcu_data *rdp;
+
+       for_each_rcu_flavor(rsp) {
+               rdp = __this_cpu_ptr(rsp->rda);
+               if (rdp->qlen_lazy != 0) {
+                       atomic_inc(&oom_callback_count);
+                       rsp->call(&rdp->oom_head, rcu_oom_callback);
+               }
+       }
+}
+
+/*
+ * If low on memory, ensure that each CPU has a non-lazy callback.
+ * This will wake up CPUs that have only lazy callbacks, in turn
+ * ensuring that they free up the corresponding memory in a timely manner.
+ * Because an uncertain amount of memory will be freed in some uncertain
+ * timeframe, we do not claim to have freed anything.
+ */
+static int rcu_oom_notify(struct notifier_block *self,
+                         unsigned long notused, void *nfreed)
+{
+       int cpu;
+
+       /* Wait for callbacks from earlier instance to complete. */
+       wait_event(oom_callback_wq, atomic_read(&oom_callback_count) == 0);
+
+       /*
+        * Prevent premature wakeup: ensure that all increments happen
+        * before there is a chance of the counter reaching zero.
+        */
+       atomic_set(&oom_callback_count, 1);
+
+       get_online_cpus();
+       for_each_online_cpu(cpu) {
+               smp_call_function_single(cpu, rcu_oom_notify_cpu, NULL, 1);
+               cond_resched();
+       }
+       put_online_cpus();
+
+       /* Unconditionally decrement: no need to wake ourselves up. */
+       atomic_dec(&oom_callback_count);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block rcu_oom_nb = {
+       .notifier_call = rcu_oom_notify
+};
+
+static int __init rcu_register_oom_notifier(void)
+{
+       register_oom_notifier(&rcu_oom_nb);
+       return 0;
+}
+early_initcall(rcu_register_oom_notifier);
+
+#endif /* #else #if !defined(CONFIG_RCU_FAST_NO_HZ) */
+
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+
+#ifdef CONFIG_RCU_FAST_NO_HZ
+
+static void print_cpu_stall_fast_no_hz(char *cp, int cpu)
+{
+       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
+       unsigned long nlpd = rdtp->nonlazy_posted - rdtp->nonlazy_posted_snap;
+
+       sprintf(cp, "last_accelerate: %04lx/%04lx, nonlazy_posted: %ld, %c%c",
+               rdtp->last_accelerate & 0xffff, jiffies & 0xffff,
+               ulong2long(nlpd),
+               rdtp->all_lazy ? 'L' : '.',
+               rdtp->tick_nohz_enabled_snap ? '.' : 'D');
+}
+
+#else /* #ifdef CONFIG_RCU_FAST_NO_HZ */
+
+static void print_cpu_stall_fast_no_hz(char *cp, int cpu)
+{
+       *cp = '\0';
+}
+
+#endif /* #else #ifdef CONFIG_RCU_FAST_NO_HZ */
+
+/* Initiate the stall-info list. */
+static void print_cpu_stall_info_begin(void)
+{
+       pr_cont("\n");
+}
+
+/*
+ * Print out diagnostic information for the specified stalled CPU.
+ *
+ * If the specified CPU is aware of the current RCU grace period
+ * (flavor specified by rsp), then print the number of scheduling
+ * clock interrupts the CPU has taken during the time that it has
+ * been aware.  Otherwise, print the number of RCU grace periods
+ * that this CPU is ignorant of, for example, "1" if the CPU was
+ * aware of the previous grace period.
+ *
+ * Also print out idle and (if CONFIG_RCU_FAST_NO_HZ) idle-entry info.
+ */
+static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
+{
+       char fast_no_hz[72];
+       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+       struct rcu_dynticks *rdtp = rdp->dynticks;
+       char *ticks_title;
+       unsigned long ticks_value;
+
+       if (rsp->gpnum == rdp->gpnum) {
+               ticks_title = "ticks this GP";
+               ticks_value = rdp->ticks_this_gp;
+       } else {
+               ticks_title = "GPs behind";
+               ticks_value = rsp->gpnum - rdp->gpnum;
+       }
+       print_cpu_stall_fast_no_hz(fast_no_hz, cpu);
+       pr_err("\t%d: (%lu %s) idle=%03x/%llx/%d softirq=%u/%u %s\n",
+              cpu, ticks_value, ticks_title,
+              atomic_read(&rdtp->dynticks) & 0xfff,
+              rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
+              rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
+              fast_no_hz);
+}
+
+/* Terminate the stall-info list. */
+static void print_cpu_stall_info_end(void)
+{
+       pr_err("\t");
+}
+
+/* Zero ->ticks_this_gp for all flavors of RCU. */
+static void zero_cpu_stall_ticks(struct rcu_data *rdp)
+{
+       rdp->ticks_this_gp = 0;
+       rdp->softirq_snap = kstat_softirqs_cpu(RCU_SOFTIRQ, smp_processor_id());
+}
+
+/* Increment ->ticks_this_gp for all flavors of RCU. */
+static void increment_cpu_stall_ticks(void)
+{
+       struct rcu_state *rsp;
+
+       for_each_rcu_flavor(rsp)
+               __this_cpu_ptr(rsp->rda)->ticks_this_gp++;
+}
+
+#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+static void print_cpu_stall_info_begin(void)
+{
+       pr_cont(" {");
+}
+
+static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
+{
+       pr_cont(" %d", cpu);
+}
+
+static void print_cpu_stall_info_end(void)
+{
+       pr_cont("} ");
+}
+
+static void zero_cpu_stall_ticks(struct rcu_data *rdp)
+{
+}
+
+static void increment_cpu_stall_ticks(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+#ifdef CONFIG_RCU_NOCB_CPU
+
+/*
+ * Offload callback processing from the boot-time-specified set of CPUs
+ * specified by rcu_nocb_mask.  For each CPU in the set, there is a
+ * kthread created that pulls the callbacks from the corresponding CPU,
+ * waits for a grace period to elapse, and invokes the callbacks.
+ * The no-CBs CPUs do a wake_up() on their kthread when they insert
+ * a callback into any empty list, unless the rcu_nocb_poll boot parameter
+ * has been specified, in which case each kthread actively polls its
+ * CPU.  (Which isn't so great for energy efficiency, but which does
+ * reduce RCU's overhead on that CPU.)
+ *
+ * This is intended to be used in conjunction with Frederic Weisbecker's
+ * adaptive-idle work, which would seriously reduce OS jitter on CPUs
+ * running CPU-bound user-mode computations.
+ *
+ * Offloading of callback processing could also in theory be used as
+ * an energy-efficiency measure because CPUs with no RCU callbacks
+ * queued are more aggressive about entering dyntick-idle mode.
+ */
+
+
+/* Parse the boot-time rcu_nocb_mask CPU list from the kernel parameters. */
+static int __init rcu_nocb_setup(char *str)
+{
+       alloc_bootmem_cpumask_var(&rcu_nocb_mask);
+       have_rcu_nocb_mask = true;
+       cpulist_parse(str, rcu_nocb_mask);
+       return 1;
+}
+__setup("rcu_nocbs=", rcu_nocb_setup);
+
+static int __init parse_rcu_nocb_poll(char *arg)
+{
+       rcu_nocb_poll = 1;
+       return 0;
+}
+early_param("rcu_nocb_poll", parse_rcu_nocb_poll);
+
+/*
+ * Do any no-CBs CPUs need another grace period?
+ *
+ * Interrupts must be disabled.  If the caller does not hold the root
+ * rnp_node structure's ->lock, the results are advisory only.
+ */
+static int rcu_nocb_needs_gp(struct rcu_state *rsp)
+{
+       struct rcu_node *rnp = rcu_get_root(rsp);
+
+       return rnp->need_future_gp[(ACCESS_ONCE(rnp->completed) + 1) & 0x1];
+}
+
+/*
+ * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended
+ * grace period.
+ */
+static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+       wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
+}
+
+/*
+ * Set the root rcu_node structure's ->need_future_gp field
+ * based on the sum of those of all rcu_node structures.  This does
+ * double-count the root rcu_node structure's requests, but this
+ * is necessary to handle the possibility of a rcu_nocb_kthread()
+ * having awakened during the time that the rcu_node structures
+ * were being updated for the end of the previous grace period.
+ */
+static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq)
+{
+       rnp->need_future_gp[(rnp->completed + 1) & 0x1] += nrq;
+}
+
+static void rcu_init_one_nocb(struct rcu_node *rnp)
+{
+       init_waitqueue_head(&rnp->nocb_gp_wq[0]);
+       init_waitqueue_head(&rnp->nocb_gp_wq[1]);
+}
+
+/* Is the specified CPU a no-CPUs CPU? */
+bool rcu_is_nocb_cpu(int cpu)
+{
+       if (have_rcu_nocb_mask)
+               return cpumask_test_cpu(cpu, rcu_nocb_mask);
+       return false;
+}
+
+/*
+ * Enqueue the specified string of rcu_head structures onto the specified
+ * CPU's no-CBs lists.  The CPU is specified by rdp, the head of the
+ * string by rhp, and the tail of the string by rhtp.  The non-lazy/lazy
+ * counts are supplied by rhcount and rhcount_lazy.
+ *
+ * If warranted, also wake up the kthread servicing this CPUs queues.
+ */
+static void __call_rcu_nocb_enqueue(struct rcu_data *rdp,
+                                   struct rcu_head *rhp,
+                                   struct rcu_head **rhtp,
+                                   int rhcount, int rhcount_lazy)
+{
+       int len;
+       struct rcu_head **old_rhpp;
+       struct task_struct *t;
+
+       /* Enqueue the callback on the nocb list and update counts. */
+       old_rhpp = xchg(&rdp->nocb_tail, rhtp);
+       ACCESS_ONCE(*old_rhpp) = rhp;
+       atomic_long_add(rhcount, &rdp->nocb_q_count);
+       atomic_long_add(rhcount_lazy, &rdp->nocb_q_count_lazy);
+
+       /* If we are not being polled and there is a kthread, awaken it ... */
+       t = ACCESS_ONCE(rdp->nocb_kthread);
+       if (rcu_nocb_poll || !t) {
+               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                   TPS("WakeNotPoll"));
+               return;
+       }
+       len = atomic_long_read(&rdp->nocb_q_count);
+       if (old_rhpp == &rdp->nocb_head) {
+               wake_up(&rdp->nocb_wq); /* ... only if queue was empty ... */
+               rdp->qlen_last_fqs_check = 0;
+               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeEmpty"));
+       } else if (len > rdp->qlen_last_fqs_check + qhimark) {
+               wake_up_process(t); /* ... or if many callbacks queued. */
+               rdp->qlen_last_fqs_check = LONG_MAX / 2;
+               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeOvf"));
+       } else {
+               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeNot"));
+       }
+       return;
+}
+
+/*
+ * This is a helper for __call_rcu(), which invokes this when the normal
+ * callback queue is inoperable.  If this is not a no-CBs CPU, this
+ * function returns failure back to __call_rcu(), which can complain
+ * appropriately.
+ *
+ * Otherwise, this function queues the callback where the corresponding
+ * "rcuo" kthread can find it.
+ */
+static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
+                           bool lazy)
+{
+
+       if (!rcu_is_nocb_cpu(rdp->cpu))
+               return 0;
+       __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy);
+       if (__is_kfree_rcu_offset((unsigned long)rhp->func))
+               trace_rcu_kfree_callback(rdp->rsp->name, rhp,
+                                        (unsigned long)rhp->func,
+                                        -atomic_long_read(&rdp->nocb_q_count_lazy),
+                                        -atomic_long_read(&rdp->nocb_q_count));
+       else
+               trace_rcu_callback(rdp->rsp->name, rhp,
+                                  -atomic_long_read(&rdp->nocb_q_count_lazy),
+                                  -atomic_long_read(&rdp->nocb_q_count));
+       return 1;
+}
+
+/*
+ * Adopt orphaned callbacks on a no-CBs CPU, or return 0 if this is
+ * not a no-CBs CPU.
+ */
+static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
+                                                    struct rcu_data *rdp)
+{
+       long ql = rsp->qlen;
+       long qll = rsp->qlen_lazy;
+
+       /* If this is not a no-CBs CPU, tell the caller to do it the old way. */
+       if (!rcu_is_nocb_cpu(smp_processor_id()))
+               return 0;
+       rsp->qlen = 0;
+       rsp->qlen_lazy = 0;
+
+       /* First, enqueue the donelist, if any.  This preserves CB ordering. */
+       if (rsp->orphan_donelist != NULL) {
+               __call_rcu_nocb_enqueue(rdp, rsp->orphan_donelist,
+                                       rsp->orphan_donetail, ql, qll);
+               ql = qll = 0;
+               rsp->orphan_donelist = NULL;
+               rsp->orphan_donetail = &rsp->orphan_donelist;
+       }
+       if (rsp->orphan_nxtlist != NULL) {
+               __call_rcu_nocb_enqueue(rdp, rsp->orphan_nxtlist,
+                                       rsp->orphan_nxttail, ql, qll);
+               ql = qll = 0;
+               rsp->orphan_nxtlist = NULL;
+               rsp->orphan_nxttail = &rsp->orphan_nxtlist;
+       }
+       return 1;
+}
+
+/*
+ * If necessary, kick off a new grace period, and either way wait
+ * for a subsequent grace period to complete.
+ */
+static void rcu_nocb_wait_gp(struct rcu_data *rdp)
+{
+       unsigned long c;
+       bool d;
+       unsigned long flags;
+       struct rcu_node *rnp = rdp->mynode;
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       c = rcu_start_future_gp(rnp, rdp);
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+
+       /*
+        * Wait for the grace period.  Do so interruptibly to avoid messing
+        * up the load average.
+        */
+       trace_rcu_future_gp(rnp, rdp, c, TPS("StartWait"));
+       for (;;) {
+               wait_event_interruptible(
+                       rnp->nocb_gp_wq[c & 0x1],
+                       (d = ULONG_CMP_GE(ACCESS_ONCE(rnp->completed), c)));
+               if (likely(d))
+                       break;
+               flush_signals(current);
+               trace_rcu_future_gp(rnp, rdp, c, TPS("ResumeWait"));
+       }
+       trace_rcu_future_gp(rnp, rdp, c, TPS("EndWait"));
+       smp_mb(); /* Ensure that CB invocation happens after GP end. */
+}
+
+/*
+ * Per-rcu_data kthread, but only for no-CBs CPUs.  Each kthread invokes
+ * callbacks queued by the corresponding no-CBs CPU.
+ */
+static int rcu_nocb_kthread(void *arg)
+{
+       int c, cl;
+       bool firsttime = 1;
+       struct rcu_head *list;
+       struct rcu_head *next;
+       struct rcu_head **tail;
+       struct rcu_data *rdp = arg;
+
+       /* Each pass through this loop invokes one batch of callbacks */
+       for (;;) {
+               /* If not polling, wait for next batch of callbacks. */
+               if (!rcu_nocb_poll) {
+                       trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                           TPS("Sleep"));
+                       wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head);
+               } else if (firsttime) {
+                       firsttime = 0;
+                       trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                           TPS("Poll"));
+               }
+               list = ACCESS_ONCE(rdp->nocb_head);
+               if (!list) {
+                       if (!rcu_nocb_poll)
+                               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                                   TPS("WokeEmpty"));
+                       schedule_timeout_interruptible(1);
+                       flush_signals(current);
+                       continue;
+               }
+               firsttime = 1;
+               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                   TPS("WokeNonEmpty"));
+
+               /*
+                * Extract queued callbacks, update counts, and wait
+                * for a grace period to elapse.
+                */
+               ACCESS_ONCE(rdp->nocb_head) = NULL;
+               tail = xchg(&rdp->nocb_tail, &rdp->nocb_head);
+               c = atomic_long_xchg(&rdp->nocb_q_count, 0);
+               cl = atomic_long_xchg(&rdp->nocb_q_count_lazy, 0);
+               ACCESS_ONCE(rdp->nocb_p_count) += c;
+               ACCESS_ONCE(rdp->nocb_p_count_lazy) += cl;
+               rcu_nocb_wait_gp(rdp);
+
+               /* Each pass through the following loop invokes a callback. */
+               trace_rcu_batch_start(rdp->rsp->name, cl, c, -1);
+               c = cl = 0;
+               while (list) {
+                       next = list->next;
+                       /* Wait for enqueuing to complete, if needed. */
+                       while (next == NULL && &list->next != tail) {
+                               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                                   TPS("WaitQueue"));
+                               schedule_timeout_interruptible(1);
+                               trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
+                                                   TPS("WokeQueue"));
+                               next = list->next;
+                       }
+                       debug_rcu_head_unqueue(list);
+                       local_bh_disable();
+                       if (__rcu_reclaim(rdp->rsp->name, list))
+                               cl++;
+                       c++;
+                       local_bh_enable();
+                       list = next;
+               }
+               trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1);
+               ACCESS_ONCE(rdp->nocb_p_count) -= c;
+               ACCESS_ONCE(rdp->nocb_p_count_lazy) -= cl;
+               rdp->n_nocbs_invoked += c;
+       }
+       return 0;
+}
+
+/* Initialize per-rcu_data variables for no-CBs CPUs. */
+static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
+{
+       rdp->nocb_tail = &rdp->nocb_head;
+       init_waitqueue_head(&rdp->nocb_wq);
+}
+
+/* Create a kthread for each RCU flavor for each no-CBs CPU. */
+static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp)
+{
+       int cpu;
+       struct rcu_data *rdp;
+       struct task_struct *t;
+
+       if (rcu_nocb_mask == NULL)
+               return;
+       for_each_cpu(cpu, rcu_nocb_mask) {
+               rdp = per_cpu_ptr(rsp->rda, cpu);
+               t = kthread_run(rcu_nocb_kthread, rdp,
+                               "rcuo%c/%d", rsp->abbr, cpu);
+               BUG_ON(IS_ERR(t));
+               ACCESS_ONCE(rdp->nocb_kthread) = t;
+       }
+}
+
+/* Prevent __call_rcu() from enqueuing callbacks on no-CBs CPUs */
+static bool init_nocb_callback_list(struct rcu_data *rdp)
+{
+       if (rcu_nocb_mask == NULL ||
+           !cpumask_test_cpu(rdp->cpu, rcu_nocb_mask))
+               return false;
+       rdp->nxttail[RCU_NEXT_TAIL] = NULL;
+       return true;
+}
+
+#else /* #ifdef CONFIG_RCU_NOCB_CPU */
+
+static int rcu_nocb_needs_gp(struct rcu_state *rsp)
+{
+       return 0;
+}
+
+static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+}
+
+static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq)
+{
+}
+
+static void rcu_init_one_nocb(struct rcu_node *rnp)
+{
+}
+
+static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
+                           bool lazy)
+{
+       return 0;
+}
+
+static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
+                                                    struct rcu_data *rdp)
+{
+       return 0;
+}
+
+static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
+{
+}
+
+static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp)
+{
+}
+
+static bool init_nocb_callback_list(struct rcu_data *rdp)
+{
+       return false;
+}
+
+#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */
+
+/*
+ * An adaptive-ticks CPU can potentially execute in kernel mode for an
+ * arbitrarily long period of time with the scheduling-clock tick turned
+ * off.  RCU will be paying attention to this CPU because it is in the
+ * kernel, but the CPU cannot be guaranteed to be executing the RCU state
+ * machine because the scheduling-clock tick has been disabled.  Therefore,
+ * if an adaptive-ticks CPU is failing to respond to the current grace
+ * period and has not be idle from an RCU perspective, kick it.
+ */
+static void rcu_kick_nohz_cpu(int cpu)
+{
+#ifdef CONFIG_NO_HZ_FULL
+       if (tick_nohz_full_cpu(cpu))
+               smp_send_reschedule(cpu);
+#endif /* #ifdef CONFIG_NO_HZ_FULL */
+}
+
+
+#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
+
+/*
+ * Define RCU flavor that holds sysidle state.  This needs to be the
+ * most active flavor of RCU.
+ */
+#ifdef CONFIG_PREEMPT_RCU
+static struct rcu_state *rcu_sysidle_state = &rcu_preempt_state;
+#else /* #ifdef CONFIG_PREEMPT_RCU */
+static struct rcu_state *rcu_sysidle_state = &rcu_sched_state;
+#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
+
+static int full_sysidle_state;         /* Current system-idle state. */
+#define RCU_SYSIDLE_NOT                0       /* Some CPU is not idle. */
+#define RCU_SYSIDLE_SHORT      1       /* All CPUs idle for brief period. */
+#define RCU_SYSIDLE_LONG       2       /* All CPUs idle for long enough. */
+#define RCU_SYSIDLE_FULL       3       /* All CPUs idle, ready for sysidle. */
+#define RCU_SYSIDLE_FULL_NOTED 4       /* Actually entered sysidle state. */
+
+/*
+ * Invoked to note exit from irq or task transition to idle.  Note that
+ * usermode execution does -not- count as idle here!  After all, we want
+ * to detect full-system idle states, not RCU quiescent states and grace
+ * periods.  The caller must have disabled interrupts.
+ */
+static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq)
+{
+       unsigned long j;
+
+       /* Adjust nesting, check for fully idle. */
+       if (irq) {
+               rdtp->dynticks_idle_nesting--;
+               WARN_ON_ONCE(rdtp->dynticks_idle_nesting < 0);
+               if (rdtp->dynticks_idle_nesting != 0)
+                       return;  /* Still not fully idle. */
+       } else {
+               if ((rdtp->dynticks_idle_nesting & DYNTICK_TASK_NEST_MASK) ==
+                   DYNTICK_TASK_NEST_VALUE) {
+                       rdtp->dynticks_idle_nesting = 0;
+               } else {
+                       rdtp->dynticks_idle_nesting -= DYNTICK_TASK_NEST_VALUE;
+                       WARN_ON_ONCE(rdtp->dynticks_idle_nesting < 0);
+                       return;  /* Still not fully idle. */
+               }
+       }
+
+       /* Record start of fully idle period. */
+       j = jiffies;
+       ACCESS_ONCE(rdtp->dynticks_idle_jiffies) = j;
+       smp_mb__before_atomic_inc();
+       atomic_inc(&rdtp->dynticks_idle);
+       smp_mb__after_atomic_inc();
+       WARN_ON_ONCE(atomic_read(&rdtp->dynticks_idle) & 0x1);
+}
+
+/*
+ * Unconditionally force exit from full system-idle state.  This is
+ * invoked when a normal CPU exits idle, but must be called separately
+ * for the timekeeping CPU (tick_do_timer_cpu).  The reason for this
+ * is that the timekeeping CPU is permitted to take scheduling-clock
+ * interrupts while the system is in system-idle state, and of course
+ * rcu_sysidle_exit() has no way of distinguishing a scheduling-clock
+ * interrupt from any other type of interrupt.
+ */
+void rcu_sysidle_force_exit(void)
+{
+       int oldstate = ACCESS_ONCE(full_sysidle_state);
+       int newoldstate;
+
+       /*
+        * Each pass through the following loop attempts to exit full
+        * system-idle state.  If contention proves to be a problem,
+        * a trylock-based contention tree could be used here.
+        */
+       while (oldstate > RCU_SYSIDLE_SHORT) {
+               newoldstate = cmpxchg(&full_sysidle_state,
+                                     oldstate, RCU_SYSIDLE_NOT);
+               if (oldstate == newoldstate &&
+                   oldstate == RCU_SYSIDLE_FULL_NOTED) {
+                       rcu_kick_nohz_cpu(tick_do_timer_cpu);
+                       return; /* We cleared it, done! */
+               }
+               oldstate = newoldstate;
+       }
+       smp_mb(); /* Order initial oldstate fetch vs. later non-idle work. */
+}
+
+/*
+ * Invoked to note entry to irq or task transition from idle.  Note that
+ * usermode execution does -not- count as idle here!  The caller must
+ * have disabled interrupts.
+ */
+static void rcu_sysidle_exit(struct rcu_dynticks *rdtp, int irq)
+{
+       /* Adjust nesting, check for already non-idle. */
+       if (irq) {
+               rdtp->dynticks_idle_nesting++;
+               WARN_ON_ONCE(rdtp->dynticks_idle_nesting <= 0);
+               if (rdtp->dynticks_idle_nesting != 1)
+                       return; /* Already non-idle. */
+       } else {
+               /*
+                * Allow for irq misnesting.  Yes, it really is possible
+                * to enter an irq handler then never leave it, and maybe
+                * also vice versa.  Handle both possibilities.
+                */
+               if (rdtp->dynticks_idle_nesting & DYNTICK_TASK_NEST_MASK) {
+                       rdtp->dynticks_idle_nesting += DYNTICK_TASK_NEST_VALUE;
+                       WARN_ON_ONCE(rdtp->dynticks_idle_nesting <= 0);
+                       return; /* Already non-idle. */
+               } else {
+                       rdtp->dynticks_idle_nesting = DYNTICK_TASK_EXIT_IDLE;
+               }
+       }
+
+       /* Record end of idle period. */
+       smp_mb__before_atomic_inc();
+       atomic_inc(&rdtp->dynticks_idle);
+       smp_mb__after_atomic_inc();
+       WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks_idle) & 0x1));
+
+       /*
+        * If we are the timekeeping CPU, we are permitted to be non-idle
+        * during a system-idle state.  This must be the case, because
+        * the timekeeping CPU has to take scheduling-clock interrupts
+        * during the time that the system is transitioning to full
+        * system-idle state.  This means that the timekeeping CPU must
+        * invoke rcu_sysidle_force_exit() directly if it does anything
+        * more than take a scheduling-clock interrupt.
+        */
+       if (smp_processor_id() == tick_do_timer_cpu)
+               return;
+
+       /* Update system-idle state: We are clearly no longer fully idle! */
+       rcu_sysidle_force_exit();
+}
+
+/*
+ * Check to see if the current CPU is idle.  Note that usermode execution
+ * does not count as idle.  The caller must have disabled interrupts.
+ */
+static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,
+                                 unsigned long *maxj)
+{
+       int cur;
+       unsigned long j;
+       struct rcu_dynticks *rdtp = rdp->dynticks;
+
+       /*
+        * If some other CPU has already reported non-idle, if this is
+        * not the flavor of RCU that tracks sysidle state, or if this
+        * is an offline or the timekeeping CPU, nothing to do.
+        */
+       if (!*isidle || rdp->rsp != rcu_sysidle_state ||
+           cpu_is_offline(rdp->cpu) || rdp->cpu == tick_do_timer_cpu)
+               return;
+       if (rcu_gp_in_progress(rdp->rsp))
+               WARN_ON_ONCE(smp_processor_id() != tick_do_timer_cpu);
+
+       /* Pick up current idle and NMI-nesting counter and check. */
+       cur = atomic_read(&rdtp->dynticks_idle);
+       if (cur & 0x1) {
+               *isidle = false; /* We are not idle! */
+               return;
+       }
+       smp_mb(); /* Read counters before timestamps. */
+
+       /* Pick up timestamps. */
+       j = ACCESS_ONCE(rdtp->dynticks_idle_jiffies);
+       /* If this CPU entered idle more recently, update maxj timestamp. */
+       if (ULONG_CMP_LT(*maxj, j))
+               *maxj = j;
+}
+
+/*
+ * Is this the flavor of RCU that is handling full-system idle?
+ */
+static bool is_sysidle_rcu_state(struct rcu_state *rsp)
+{
+       return rsp == rcu_sysidle_state;
+}
+
+/*
+ * Bind the grace-period kthread for the sysidle flavor of RCU to the
+ * timekeeping CPU.
+ */
+static void rcu_bind_gp_kthread(void)
+{
+       int cpu = ACCESS_ONCE(tick_do_timer_cpu);
+
+       if (cpu < 0 || cpu >= nr_cpu_ids)
+               return;
+       if (raw_smp_processor_id() != cpu)
+               set_cpus_allowed_ptr(current, cpumask_of(cpu));
+}
+
+/*
+ * Return a delay in jiffies based on the number of CPUs, rcu_node
+ * leaf fanout, and jiffies tick rate.  The idea is to allow larger
+ * systems more time to transition to full-idle state in order to
+ * avoid the cache thrashing that otherwise occur on the state variable.
+ * Really small systems (less than a couple of tens of CPUs) should
+ * instead use a single global atomically incremented counter, and later
+ * versions of this will automatically reconfigure themselves accordingly.
+ */
+static unsigned long rcu_sysidle_delay(void)
+{
+       if (nr_cpu_ids <= CONFIG_NO_HZ_FULL_SYSIDLE_SMALL)
+               return 0;
+       return DIV_ROUND_UP(nr_cpu_ids * HZ, rcu_fanout_leaf * 1000);
+}
+
+/*
+ * Advance the full-system-idle state.  This is invoked when all of
+ * the non-timekeeping CPUs are idle.
+ */
+static void rcu_sysidle(unsigned long j)
+{
+       /* Check the current state. */
+       switch (ACCESS_ONCE(full_sysidle_state)) {
+       case RCU_SYSIDLE_NOT:
+
+               /* First time all are idle, so note a short idle period. */
+               ACCESS_ONCE(full_sysidle_state) = RCU_SYSIDLE_SHORT;
+               break;
+
+       case RCU_SYSIDLE_SHORT:
+
+               /*
+                * Idle for a bit, time to advance to next state?
+                * cmpxchg failure means race with non-idle, let them win.
+                */
+               if (ULONG_CMP_GE(jiffies, j + rcu_sysidle_delay()))
+                       (void)cmpxchg(&full_sysidle_state,
+                                     RCU_SYSIDLE_SHORT, RCU_SYSIDLE_LONG);
+               break;
+
+       case RCU_SYSIDLE_LONG:
+
+               /*
+                * Do an additional check pass before advancing to full.
+                * cmpxchg failure means race with non-idle, let them win.
+                */
+               if (ULONG_CMP_GE(jiffies, j + rcu_sysidle_delay()))
+                       (void)cmpxchg(&full_sysidle_state,
+                                     RCU_SYSIDLE_LONG, RCU_SYSIDLE_FULL);
+               break;
+
+       default:
+               break;
+       }
+}
+
+/*
+ * Found a non-idle non-timekeeping CPU, so kick the system-idle state
+ * back to the beginning.
+ */
+static void rcu_sysidle_cancel(void)
+{
+       smp_mb();
+       ACCESS_ONCE(full_sysidle_state) = RCU_SYSIDLE_NOT;
+}
+
+/*
+ * Update the sysidle state based on the results of a force-quiescent-state
+ * scan of the CPUs' dyntick-idle state.
+ */
+static void rcu_sysidle_report(struct rcu_state *rsp, int isidle,
+                              unsigned long maxj, bool gpkt)
+{
+       if (rsp != rcu_sysidle_state)
+               return;  /* Wrong flavor, ignore. */
+       if (gpkt && nr_cpu_ids <= CONFIG_NO_HZ_FULL_SYSIDLE_SMALL)
+               return;  /* Running state machine from timekeeping CPU. */
+       if (isidle)
+               rcu_sysidle(maxj);    /* More idle! */
+       else
+               rcu_sysidle_cancel(); /* Idle is over. */
+}
+
+/*
+ * Wrapper for rcu_sysidle_report() when called from the grace-period
+ * kthread's context.
+ */
+static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
+                                 unsigned long maxj)
+{
+       rcu_sysidle_report(rsp, isidle, maxj, true);
+}
+
+/* Callback and function for forcing an RCU grace period. */
+struct rcu_sysidle_head {
+       struct rcu_head rh;
+       int inuse;
+};
+
+static void rcu_sysidle_cb(struct rcu_head *rhp)
+{
+       struct rcu_sysidle_head *rshp;
+
+       /*
+        * The following memory barrier is needed to replace the
+        * memory barriers that would normally be in the memory
+        * allocator.
+        */
+       smp_mb();  /* grace period precedes setting inuse. */
+
+       rshp = container_of(rhp, struct rcu_sysidle_head, rh);
+       ACCESS_ONCE(rshp->inuse) = 0;
+}
+
+/*
+ * Check to see if the system is fully idle, other than the timekeeping CPU.
+ * The caller must have disabled interrupts.
+ */
+bool rcu_sys_is_idle(void)
+{
+       static struct rcu_sysidle_head rsh;
+       int rss = ACCESS_ONCE(full_sysidle_state);
+
+       if (WARN_ON_ONCE(smp_processor_id() != tick_do_timer_cpu))
+               return false;
+
+       /* Handle small-system case by doing a full scan of CPUs. */
+       if (nr_cpu_ids <= CONFIG_NO_HZ_FULL_SYSIDLE_SMALL) {
+               int oldrss = rss - 1;
+
+               /*
+                * One pass to advance to each state up to _FULL.
+                * Give up if any pass fails to advance the state.
+                */
+               while (rss < RCU_SYSIDLE_FULL && oldrss < rss) {
+                       int cpu;
+                       bool isidle = true;
+                       unsigned long maxj = jiffies - ULONG_MAX / 4;
+                       struct rcu_data *rdp;
+
+                       /* Scan all the CPUs looking for nonidle CPUs. */
+                       for_each_possible_cpu(cpu) {
+                               rdp = per_cpu_ptr(rcu_sysidle_state->rda, cpu);
+                               rcu_sysidle_check_cpu(rdp, &isidle, &maxj);
+                               if (!isidle)
+                                       break;
+                       }
+                       rcu_sysidle_report(rcu_sysidle_state,
+                                          isidle, maxj, false);
+                       oldrss = rss;
+                       rss = ACCESS_ONCE(full_sysidle_state);
+               }
+       }
+
+       /* If this is the first observation of an idle period, record it. */
+       if (rss == RCU_SYSIDLE_FULL) {
+               rss = cmpxchg(&full_sysidle_state,
+                             RCU_SYSIDLE_FULL, RCU_SYSIDLE_FULL_NOTED);
+               return rss == RCU_SYSIDLE_FULL;
+       }
+
+       smp_mb(); /* ensure rss load happens before later caller actions. */
+
+       /* If already fully idle, tell the caller (in case of races). */
+       if (rss == RCU_SYSIDLE_FULL_NOTED)
+               return true;
+
+       /*
+        * If we aren't there yet, and a grace period is not in flight,
+        * initiate a grace period.  Either way, tell the caller that
+        * we are not there yet.  We use an xchg() rather than an assignment
+        * to make up for the memory barriers that would otherwise be
+        * provided by the memory allocator.
+        */
+       if (nr_cpu_ids > CONFIG_NO_HZ_FULL_SYSIDLE_SMALL &&
+           !rcu_gp_in_progress(rcu_sysidle_state) &&
+           !rsh.inuse && xchg(&rsh.inuse, 1) == 0)
+               call_rcu(&rsh.rh, rcu_sysidle_cb);
+       return false;
+}
+
+/*
+ * Initialize dynticks sysidle state for CPUs coming online.
+ */
+static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp)
+{
+       rdtp->dynticks_idle_nesting = DYNTICK_TASK_NEST_VALUE;
+}
+
+#else /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
+
+static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq)
+{
+}
+
+static void rcu_sysidle_exit(struct rcu_dynticks *rdtp, int irq)
+{
+}
+
+static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,
+                                 unsigned long *maxj)
+{
+}
+
+static bool is_sysidle_rcu_state(struct rcu_state *rsp)
+{
+       return false;
+}
+
+static void rcu_bind_gp_kthread(void)
+{
+}
+
+static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
+                                 unsigned long maxj)
+{
+}
+
+static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp)
+{
+}
+
+#endif /* #else #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
diff --git a/kernel/rcu/tree_trace.c b/kernel/rcu/tree_trace.c
new file mode 100644 (file)
index 0000000..3596797
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * Read-Copy Update tracing for classic implementation
+ *
+ * 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 IBM Corporation, 2008
+ *
+ * Papers:  http://www.rdrop.com/users/paulmck/RCU
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/rcupdate.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/atomic.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/mutex.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#define RCU_TREE_NONCORE
+#include "tree.h"
+
+static int r_open(struct inode *inode, struct file *file,
+                                       const struct seq_operations *op)
+{
+       int ret = seq_open(file, op);
+       if (!ret) {
+               struct seq_file *m = (struct seq_file *)file->private_data;
+               m->private = inode->i_private;
+       }
+       return ret;
+}
+
+static void *r_start(struct seq_file *m, loff_t *pos)
+{
+       struct rcu_state *rsp = (struct rcu_state *)m->private;
+       *pos = cpumask_next(*pos - 1, cpu_possible_mask);
+       if ((*pos) < nr_cpu_ids)
+               return per_cpu_ptr(rsp->rda, *pos);
+       return NULL;
+}
+
+static void *r_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       (*pos)++;
+       return r_start(m, pos);
+}
+
+static void r_stop(struct seq_file *m, void *v)
+{
+}
+
+static int show_rcubarrier(struct seq_file *m, void *v)
+{
+       struct rcu_state *rsp = (struct rcu_state *)m->private;
+       seq_printf(m, "bcc: %d nbd: %lu\n",
+                  atomic_read(&rsp->barrier_cpu_count),
+                  rsp->n_barrier_done);
+       return 0;
+}
+
+static int rcubarrier_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_rcubarrier, inode->i_private);
+}
+
+static const struct file_operations rcubarrier_fops = {
+       .owner = THIS_MODULE,
+       .open = rcubarrier_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = single_release,
+};
+
+#ifdef CONFIG_RCU_BOOST
+
+static char convert_kthread_status(unsigned int kthread_status)
+{
+       if (kthread_status > RCU_KTHREAD_MAX)
+               return '?';
+       return "SRWOY"[kthread_status];
+}
+
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
+{
+       long ql, qll;
+
+       if (!rdp->beenonline)
+               return;
+       seq_printf(m, "%3d%cc=%ld g=%ld pq=%d qp=%d",
+                  rdp->cpu,
+                  cpu_is_offline(rdp->cpu) ? '!' : ' ',
+                  ulong2long(rdp->completed), ulong2long(rdp->gpnum),
+                  rdp->passed_quiesce, rdp->qs_pending);
+       seq_printf(m, " dt=%d/%llx/%d df=%lu",
+                  atomic_read(&rdp->dynticks->dynticks),
+                  rdp->dynticks->dynticks_nesting,
+                  rdp->dynticks->dynticks_nmi_nesting,
+                  rdp->dynticks_fqs);
+       seq_printf(m, " of=%lu", rdp->offline_fqs);
+       rcu_nocb_q_lengths(rdp, &ql, &qll);
+       qll += rdp->qlen_lazy;
+       ql += rdp->qlen;
+       seq_printf(m, " ql=%ld/%ld qs=%c%c%c%c",
+                  qll, ql,
+                  ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
+                       rdp->nxttail[RCU_NEXT_TAIL]],
+                  ".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
+                       rdp->nxttail[RCU_NEXT_READY_TAIL]],
+                  ".W"[rdp->nxttail[RCU_DONE_TAIL] !=
+                       rdp->nxttail[RCU_WAIT_TAIL]],
+                  ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]]);
+#ifdef CONFIG_RCU_BOOST
+       seq_printf(m, " kt=%d/%c ktl=%x",
+                  per_cpu(rcu_cpu_has_work, rdp->cpu),
+                  convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
+                                         rdp->cpu)),
+                  per_cpu(rcu_cpu_kthread_loops, rdp->cpu) & 0xffff);
+#endif /* #ifdef CONFIG_RCU_BOOST */
+       seq_printf(m, " b=%ld", rdp->blimit);
+       seq_printf(m, " ci=%lu nci=%lu co=%lu ca=%lu\n",
+                  rdp->n_cbs_invoked, rdp->n_nocbs_invoked,
+                  rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
+}
+
+static int show_rcudata(struct seq_file *m, void *v)
+{
+       print_one_rcu_data(m, (struct rcu_data *)v);
+       return 0;
+}
+
+static const struct seq_operations rcudate_op = {
+       .start = r_start,
+       .next  = r_next,
+       .stop  = r_stop,
+       .show  = show_rcudata,
+};
+
+static int rcudata_open(struct inode *inode, struct file *file)
+{
+       return r_open(inode, file, &rcudate_op);
+}
+
+static const struct file_operations rcudata_fops = {
+       .owner = THIS_MODULE,
+       .open = rcudata_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = seq_release,
+};
+
+static int show_rcuexp(struct seq_file *m, void *v)
+{
+       struct rcu_state *rsp = (struct rcu_state *)m->private;
+
+       seq_printf(m, "s=%lu d=%lu w=%lu tf=%lu wd1=%lu wd2=%lu n=%lu sc=%lu dt=%lu dl=%lu dx=%lu\n",
+                  atomic_long_read(&rsp->expedited_start),
+                  atomic_long_read(&rsp->expedited_done),
+                  atomic_long_read(&rsp->expedited_wrap),
+                  atomic_long_read(&rsp->expedited_tryfail),
+                  atomic_long_read(&rsp->expedited_workdone1),
+                  atomic_long_read(&rsp->expedited_workdone2),
+                  atomic_long_read(&rsp->expedited_normal),
+                  atomic_long_read(&rsp->expedited_stoppedcpus),
+                  atomic_long_read(&rsp->expedited_done_tries),
+                  atomic_long_read(&rsp->expedited_done_lost),
+                  atomic_long_read(&rsp->expedited_done_exit));
+       return 0;
+}
+
+static int rcuexp_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_rcuexp, inode->i_private);
+}
+
+static const struct file_operations rcuexp_fops = {
+       .owner = THIS_MODULE,
+       .open = rcuexp_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = single_release,
+};
+
+#ifdef CONFIG_RCU_BOOST
+
+static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp)
+{
+       seq_printf(m, "%d:%d tasks=%c%c%c%c kt=%c ntb=%lu neb=%lu nnb=%lu ",
+                  rnp->grplo, rnp->grphi,
+                  "T."[list_empty(&rnp->blkd_tasks)],
+                  "N."[!rnp->gp_tasks],
+                  "E."[!rnp->exp_tasks],
+                  "B."[!rnp->boost_tasks],
+                  convert_kthread_status(rnp->boost_kthread_status),
+                  rnp->n_tasks_boosted, rnp->n_exp_boosts,
+                  rnp->n_normal_boosts);
+       seq_printf(m, "j=%04x bt=%04x\n",
+                  (int)(jiffies & 0xffff),
+                  (int)(rnp->boost_time & 0xffff));
+       seq_printf(m, "    balk: nt=%lu egt=%lu bt=%lu nb=%lu ny=%lu nos=%lu\n",
+                  rnp->n_balk_blkd_tasks,
+                  rnp->n_balk_exp_gp_tasks,
+                  rnp->n_balk_boost_tasks,
+                  rnp->n_balk_notblocked,
+                  rnp->n_balk_notyet,
+                  rnp->n_balk_nos);
+}
+
+static int show_rcu_node_boost(struct seq_file *m, void *unused)
+{
+       struct rcu_node *rnp;
+
+       rcu_for_each_leaf_node(&rcu_preempt_state, rnp)
+               print_one_rcu_node_boost(m, rnp);
+       return 0;
+}
+
+static int rcu_node_boost_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_rcu_node_boost, NULL);
+}
+
+static const struct file_operations rcu_node_boost_fops = {
+       .owner = THIS_MODULE,
+       .open = rcu_node_boost_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = single_release,
+};
+
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
+static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
+{
+       unsigned long gpnum;
+       int level = 0;
+       struct rcu_node *rnp;
+
+       gpnum = rsp->gpnum;
+       seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x ",
+                  ulong2long(rsp->completed), ulong2long(gpnum),
+                  rsp->fqs_state,
+                  (long)(rsp->jiffies_force_qs - jiffies),
+                  (int)(jiffies & 0xffff));
+       seq_printf(m, "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n",
+                  rsp->n_force_qs, rsp->n_force_qs_ngp,
+                  rsp->n_force_qs - rsp->n_force_qs_ngp,
+                  rsp->n_force_qs_lh, rsp->qlen_lazy, rsp->qlen);
+       for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < rcu_num_nodes; rnp++) {
+               if (rnp->level != level) {
+                       seq_puts(m, "\n");
+                       level = rnp->level;
+               }
+               seq_printf(m, "%lx/%lx %c%c>%c %d:%d ^%d    ",
+                          rnp->qsmask, rnp->qsmaskinit,
+                          ".G"[rnp->gp_tasks != NULL],
+                          ".E"[rnp->exp_tasks != NULL],
+                          ".T"[!list_empty(&rnp->blkd_tasks)],
+                          rnp->grplo, rnp->grphi, rnp->grpnum);
+       }
+       seq_puts(m, "\n");
+}
+
+static int show_rcuhier(struct seq_file *m, void *v)
+{
+       struct rcu_state *rsp = (struct rcu_state *)m->private;
+       print_one_rcu_state(m, rsp);
+       return 0;
+}
+
+static int rcuhier_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_rcuhier, inode->i_private);
+}
+
+static const struct file_operations rcuhier_fops = {
+       .owner = THIS_MODULE,
+       .open = rcuhier_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = single_release,
+};
+
+static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
+{
+       unsigned long flags;
+       unsigned long completed;
+       unsigned long gpnum;
+       unsigned long gpage;
+       unsigned long gpmax;
+       struct rcu_node *rnp = &rsp->node[0];
+
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       completed = ACCESS_ONCE(rsp->completed);
+       gpnum = ACCESS_ONCE(rsp->gpnum);
+       if (completed == gpnum)
+               gpage = 0;
+       else
+               gpage = jiffies - rsp->gp_start;
+       gpmax = rsp->gp_max;
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       seq_printf(m, "completed=%ld  gpnum=%ld  age=%ld  max=%ld\n",
+                  ulong2long(completed), ulong2long(gpnum), gpage, gpmax);
+}
+
+static int show_rcugp(struct seq_file *m, void *v)
+{
+       struct rcu_state *rsp = (struct rcu_state *)m->private;
+       show_one_rcugp(m, rsp);
+       return 0;
+}
+
+static int rcugp_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_rcugp, inode->i_private);
+}
+
+static const struct file_operations rcugp_fops = {
+       .owner = THIS_MODULE,
+       .open = rcugp_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = single_release,
+};
+
+static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
+{
+       if (!rdp->beenonline)
+               return;
+       seq_printf(m, "%3d%cnp=%ld ",
+                  rdp->cpu,
+                  cpu_is_offline(rdp->cpu) ? '!' : ' ',
+                  rdp->n_rcu_pending);
+       seq_printf(m, "qsp=%ld rpq=%ld cbr=%ld cng=%ld ",
+                  rdp->n_rp_qs_pending,
+                  rdp->n_rp_report_qs,
+                  rdp->n_rp_cb_ready,
+                  rdp->n_rp_cpu_needs_gp);
+       seq_printf(m, "gpc=%ld gps=%ld nn=%ld\n",
+                  rdp->n_rp_gp_completed,
+                  rdp->n_rp_gp_started,
+                  rdp->n_rp_need_nothing);
+}
+
+static int show_rcu_pending(struct seq_file *m, void *v)
+{
+       print_one_rcu_pending(m, (struct rcu_data *)v);
+       return 0;
+}
+
+static const struct seq_operations rcu_pending_op = {
+       .start = r_start,
+       .next  = r_next,
+       .stop  = r_stop,
+       .show  = show_rcu_pending,
+};
+
+static int rcu_pending_open(struct inode *inode, struct file *file)
+{
+       return r_open(inode, file, &rcu_pending_op);
+}
+
+static const struct file_operations rcu_pending_fops = {
+       .owner = THIS_MODULE,
+       .open = rcu_pending_open,
+       .read = seq_read,
+       .llseek = no_llseek,
+       .release = seq_release,
+};
+
+static int show_rcutorture(struct seq_file *m, void *unused)
+{
+       seq_printf(m, "rcutorture test sequence: %lu %s\n",
+                  rcutorture_testseq >> 1,
+                  (rcutorture_testseq & 0x1) ? "(test in progress)" : "");
+       seq_printf(m, "rcutorture update version number: %lu\n",
+                  rcutorture_vernum);
+       return 0;
+}
+
+static int rcutorture_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_rcutorture, NULL);
+}
+
+static const struct file_operations rcutorture_fops = {
+       .owner = THIS_MODULE,
+       .open = rcutorture_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static struct dentry *rcudir;
+
+static int __init rcutree_trace_init(void)
+{
+       struct rcu_state *rsp;
+       struct dentry *retval;
+       struct dentry *rspdir;
+
+       rcudir = debugfs_create_dir("rcu", NULL);
+       if (!rcudir)
+               goto free_out;
+
+       for_each_rcu_flavor(rsp) {
+               rspdir = debugfs_create_dir(rsp->name, rcudir);
+               if (!rspdir)
+                       goto free_out;
+
+               retval = debugfs_create_file("rcudata", 0444,
+                               rspdir, rsp, &rcudata_fops);
+               if (!retval)
+                       goto free_out;
+
+               retval = debugfs_create_file("rcuexp", 0444,
+                               rspdir, rsp, &rcuexp_fops);
+               if (!retval)
+                       goto free_out;
+
+               retval = debugfs_create_file("rcu_pending", 0444,
+                               rspdir, rsp, &rcu_pending_fops);
+               if (!retval)
+                       goto free_out;
+
+               retval = debugfs_create_file("rcubarrier", 0444,
+                               rspdir, rsp, &rcubarrier_fops);
+               if (!retval)
+                       goto free_out;
+
+#ifdef CONFIG_RCU_BOOST
+               if (rsp == &rcu_preempt_state) {
+                       retval = debugfs_create_file("rcuboost", 0444,
+                               rspdir, NULL, &rcu_node_boost_fops);
+                       if (!retval)
+                               goto free_out;
+               }
+#endif
+
+               retval = debugfs_create_file("rcugp", 0444,
+                               rspdir, rsp, &rcugp_fops);
+               if (!retval)
+                       goto free_out;
+
+               retval = debugfs_create_file("rcuhier", 0444,
+                               rspdir, rsp, &rcuhier_fops);
+               if (!retval)
+                       goto free_out;
+       }
+
+       retval = debugfs_create_file("rcutorture", 0444, rcudir,
+                                               NULL, &rcutorture_fops);
+       if (!retval)
+               goto free_out;
+       return 0;
+free_out:
+       debugfs_remove_recursive(rcudir);
+       return 1;
+}
+
+static void __exit rcutree_trace_cleanup(void)
+{
+       debugfs_remove_recursive(rcudir);
+}
+
+
+module_init(rcutree_trace_init);
+module_exit(rcutree_trace_cleanup);
+
+MODULE_AUTHOR("Paul E. McKenney");
+MODULE_DESCRIPTION("Read-Copy Update tracing for hierarchical implementation");
+MODULE_LICENSE("GPL");
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
new file mode 100644 (file)
index 0000000..6cb3dff
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion
+ *
+ * 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 IBM Corporation, 2001
+ *
+ * Authors: Dipankar Sarma <dipankar@in.ibm.com>
+ *         Manfred Spraul <manfred@colorfullife.com>
+ *
+ * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
+ * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
+ * Papers:
+ * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf
+ * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001)
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             http://lse.sourceforge.net/locking/rcupdate.html
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/atomic.h>
+#include <linux/bitops.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/mutex.h>
+#include <linux/export.h>
+#include <linux/hardirq.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/rcu.h>
+
+#include "rcu.h"
+
+MODULE_ALIAS("rcupdate");
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "rcupdate."
+
+module_param(rcu_expedited, int, 0);
+
+#ifdef CONFIG_PREEMPT_RCU
+
+/*
+ * Preemptible RCU implementation for rcu_read_lock().
+ * Just increment ->rcu_read_lock_nesting, shared state will be updated
+ * if we block.
+ */
+void __rcu_read_lock(void)
+{
+       current->rcu_read_lock_nesting++;
+       barrier();  /* critical section after entry code. */
+}
+EXPORT_SYMBOL_GPL(__rcu_read_lock);
+
+/*
+ * Preemptible RCU implementation for rcu_read_unlock().
+ * Decrement ->rcu_read_lock_nesting.  If the result is zero (outermost
+ * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then
+ * invoke rcu_read_unlock_special() to clean up after a context switch
+ * in an RCU read-side critical section and other special cases.
+ */
+void __rcu_read_unlock(void)
+{
+       struct task_struct *t = current;
+
+       if (t->rcu_read_lock_nesting != 1) {
+               --t->rcu_read_lock_nesting;
+       } else {
+               barrier();  /* critical section before exit code. */
+               t->rcu_read_lock_nesting = INT_MIN;
+#ifdef CONFIG_PROVE_RCU_DELAY
+               udelay(10); /* Make preemption more probable. */
+#endif /* #ifdef CONFIG_PROVE_RCU_DELAY */
+               barrier();  /* assign before ->rcu_read_unlock_special load */
+               if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special)))
+                       rcu_read_unlock_special(t);
+               barrier();  /* ->rcu_read_unlock_special load before assign */
+               t->rcu_read_lock_nesting = 0;
+       }
+#ifdef CONFIG_PROVE_LOCKING
+       {
+               int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting);
+
+               WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2);
+       }
+#endif /* #ifdef CONFIG_PROVE_LOCKING */
+}
+EXPORT_SYMBOL_GPL(__rcu_read_unlock);
+
+#endif /* #ifdef CONFIG_PREEMPT_RCU */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static struct lock_class_key rcu_lock_key;
+struct lockdep_map rcu_lock_map =
+       STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
+EXPORT_SYMBOL_GPL(rcu_lock_map);
+
+static struct lock_class_key rcu_bh_lock_key;
+struct lockdep_map rcu_bh_lock_map =
+       STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_bh", &rcu_bh_lock_key);
+EXPORT_SYMBOL_GPL(rcu_bh_lock_map);
+
+static struct lock_class_key rcu_sched_lock_key;
+struct lockdep_map rcu_sched_lock_map =
+       STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_sched", &rcu_sched_lock_key);
+EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
+
+int notrace debug_lockdep_rcu_enabled(void)
+{
+       return rcu_scheduler_active && debug_locks &&
+              current->lockdep_recursion == 0;
+}
+EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
+
+/**
+ * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section?
+ *
+ * Check for bottom half being disabled, which covers both the
+ * CONFIG_PROVE_RCU and not cases.  Note that if someone uses
+ * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled)
+ * will show the situation.  This is useful for debug checks in functions
+ * that require that they be called within an RCU read-side critical
+ * section.
+ *
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot.
+ *
+ * Note that rcu_read_lock() is disallowed if the CPU is either idle or
+ * offline from an RCU perspective, so check for those as well.
+ */
+int rcu_read_lock_bh_held(void)
+{
+       if (!debug_lockdep_rcu_enabled())
+               return 1;
+       if (!rcu_is_watching())
+               return 0;
+       if (!rcu_lockdep_current_cpu_online())
+               return 0;
+       return in_softirq() || irqs_disabled();
+}
+EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
+
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+struct rcu_synchronize {
+       struct rcu_head head;
+       struct completion completion;
+};
+
+/*
+ * Awaken the corresponding synchronize_rcu() instance now that a
+ * grace period has elapsed.
+ */
+static void wakeme_after_rcu(struct rcu_head  *head)
+{
+       struct rcu_synchronize *rcu;
+
+       rcu = container_of(head, struct rcu_synchronize, head);
+       complete(&rcu->completion);
+}
+
+void wait_rcu_gp(call_rcu_func_t crf)
+{
+       struct rcu_synchronize rcu;
+
+       init_rcu_head_on_stack(&rcu.head);
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       crf(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
+}
+EXPORT_SYMBOL_GPL(wait_rcu_gp);
+
+#ifdef CONFIG_PROVE_RCU
+/*
+ * wrapper function to avoid #include problems.
+ */
+int rcu_my_thread_group_empty(void)
+{
+       return thread_group_empty(current);
+}
+EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
+#endif /* #ifdef CONFIG_PROVE_RCU */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+static inline void debug_init_rcu_head(struct rcu_head *head)
+{
+       debug_object_init(head, &rcuhead_debug_descr);
+}
+
+static inline void debug_rcu_head_free(struct rcu_head *head)
+{
+       debug_object_free(head, &rcuhead_debug_descr);
+}
+
+/*
+ * fixup_activate is called when:
+ * - an active object is activated
+ * - an unknown object is activated (might be a statically initialized object)
+ * Activation is performed internally by call_rcu().
+ */
+static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state)
+{
+       struct rcu_head *head = addr;
+
+       switch (state) {
+
+       case ODEBUG_STATE_NOTAVAILABLE:
+               /*
+                * This is not really a fixup. We just make sure that it is
+                * tracked in the object tracker.
+                */
+               debug_object_init(head, &rcuhead_debug_descr);
+               debug_object_activate(head, &rcuhead_debug_descr);
+               return 0;
+       default:
+               return 1;
+       }
+}
+
+/**
+ * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects
+ * @head: pointer to rcu_head structure to be initialized
+ *
+ * This function informs debugobjects of a new rcu_head structure that
+ * has been allocated as an auto variable on the stack.  This function
+ * is not required for rcu_head structures that are statically defined or
+ * that are dynamically allocated on the heap.  This function has no
+ * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
+ */
+void init_rcu_head_on_stack(struct rcu_head *head)
+{
+       debug_object_init_on_stack(head, &rcuhead_debug_descr);
+}
+EXPORT_SYMBOL_GPL(init_rcu_head_on_stack);
+
+/**
+ * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects
+ * @head: pointer to rcu_head structure to be initialized
+ *
+ * This function informs debugobjects that an on-stack rcu_head structure
+ * is about to go out of scope.  As with init_rcu_head_on_stack(), this
+ * function is not required for rcu_head structures that are statically
+ * defined or that are dynamically allocated on the heap.  Also as with
+ * init_rcu_head_on_stack(), this function has no effect for
+ * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
+ */
+void destroy_rcu_head_on_stack(struct rcu_head *head)
+{
+       debug_object_free(head, &rcuhead_debug_descr);
+}
+EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack);
+
+struct debug_obj_descr rcuhead_debug_descr = {
+       .name = "rcu_head",
+       .fixup_activate = rcuhead_fixup_activate,
+};
+EXPORT_SYMBOL_GPL(rcuhead_debug_descr);
+#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+
+#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) || defined(CONFIG_RCU_TRACE)
+void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp,
+                              unsigned long secs,
+                              unsigned long c_old, unsigned long c)
+{
+       trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c);
+}
+EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read);
+#else
+#define do_trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \
+       do { } while (0)
+#endif
+
+#ifdef CONFIG_RCU_STALL_COMMON
+
+#ifdef CONFIG_PROVE_RCU
+#define RCU_STALL_DELAY_DELTA         (5 * HZ)
+#else
+#define RCU_STALL_DELAY_DELTA         0
+#endif
+
+int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
+static int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
+
+module_param(rcu_cpu_stall_suppress, int, 0644);
+module_param(rcu_cpu_stall_timeout, int, 0644);
+
+int rcu_jiffies_till_stall_check(void)
+{
+       int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
+
+       /*
+        * Limit check must be consistent with the Kconfig limits
+        * for CONFIG_RCU_CPU_STALL_TIMEOUT.
+        */
+       if (till_stall_check < 3) {
+               ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
+               till_stall_check = 3;
+       } else if (till_stall_check > 300) {
+               ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
+               till_stall_check = 300;
+       }
+       return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
+}
+
+static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr)
+{
+       rcu_cpu_stall_suppress = 1;
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block rcu_panic_block = {
+       .notifier_call = rcu_panic,
+};
+
+static int __init check_cpu_stall_init(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block);
+       return 0;
+}
+early_initcall(check_cpu_stall_init);
+
+#endif /* #ifdef CONFIG_RCU_STALL_COMMON */
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
deleted file mode 100644 (file)
index b02a339..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Read-Copy Update mechanism for mutual exclusion
- *
- * 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 IBM Corporation, 2001
- *
- * Authors: Dipankar Sarma <dipankar@in.ibm.com>
- *         Manfred Spraul <manfred@colorfullife.com>
- *
- * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
- * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
- * Papers:
- * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf
- * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001)
- *
- * For detailed explanation of Read-Copy Update mechanism see -
- *             http://lse.sourceforge.net/locking/rcupdate.html
- *
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/atomic.h>
-#include <linux/bitops.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/cpu.h>
-#include <linux/mutex.h>
-#include <linux/export.h>
-#include <linux/hardirq.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-#define CREATE_TRACE_POINTS
-#include <trace/events/rcu.h>
-
-#include "rcu.h"
-
-module_param(rcu_expedited, int, 0);
-
-#ifdef CONFIG_PREEMPT_RCU
-
-/*
- * Preemptible RCU implementation for rcu_read_lock().
- * Just increment ->rcu_read_lock_nesting, shared state will be updated
- * if we block.
- */
-void __rcu_read_lock(void)
-{
-       current->rcu_read_lock_nesting++;
-       barrier();  /* critical section after entry code. */
-}
-EXPORT_SYMBOL_GPL(__rcu_read_lock);
-
-/*
- * Preemptible RCU implementation for rcu_read_unlock().
- * Decrement ->rcu_read_lock_nesting.  If the result is zero (outermost
- * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then
- * invoke rcu_read_unlock_special() to clean up after a context switch
- * in an RCU read-side critical section and other special cases.
- */
-void __rcu_read_unlock(void)
-{
-       struct task_struct *t = current;
-
-       if (t->rcu_read_lock_nesting != 1) {
-               --t->rcu_read_lock_nesting;
-       } else {
-               barrier();  /* critical section before exit code. */
-               t->rcu_read_lock_nesting = INT_MIN;
-#ifdef CONFIG_PROVE_RCU_DELAY
-               udelay(10); /* Make preemption more probable. */
-#endif /* #ifdef CONFIG_PROVE_RCU_DELAY */
-               barrier();  /* assign before ->rcu_read_unlock_special load */
-               if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special)))
-                       rcu_read_unlock_special(t);
-               barrier();  /* ->rcu_read_unlock_special load before assign */
-               t->rcu_read_lock_nesting = 0;
-       }
-#ifdef CONFIG_PROVE_LOCKING
-       {
-               int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting);
-
-               WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2);
-       }
-#endif /* #ifdef CONFIG_PROVE_LOCKING */
-}
-EXPORT_SYMBOL_GPL(__rcu_read_unlock);
-
-#endif /* #ifdef CONFIG_PREEMPT_RCU */
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-static struct lock_class_key rcu_lock_key;
-struct lockdep_map rcu_lock_map =
-       STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
-EXPORT_SYMBOL_GPL(rcu_lock_map);
-
-static struct lock_class_key rcu_bh_lock_key;
-struct lockdep_map rcu_bh_lock_map =
-       STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_bh", &rcu_bh_lock_key);
-EXPORT_SYMBOL_GPL(rcu_bh_lock_map);
-
-static struct lock_class_key rcu_sched_lock_key;
-struct lockdep_map rcu_sched_lock_map =
-       STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_sched", &rcu_sched_lock_key);
-EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
-
-int notrace debug_lockdep_rcu_enabled(void)
-{
-       return rcu_scheduler_active && debug_locks &&
-              current->lockdep_recursion == 0;
-}
-EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
-
-/**
- * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section?
- *
- * Check for bottom half being disabled, which covers both the
- * CONFIG_PROVE_RCU and not cases.  Note that if someone uses
- * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled)
- * will show the situation.  This is useful for debug checks in functions
- * that require that they be called within an RCU read-side critical
- * section.
- *
- * Check debug_lockdep_rcu_enabled() to prevent false positives during boot.
- *
- * Note that rcu_read_lock() is disallowed if the CPU is either idle or
- * offline from an RCU perspective, so check for those as well.
- */
-int rcu_read_lock_bh_held(void)
-{
-       if (!debug_lockdep_rcu_enabled())
-               return 1;
-       if (rcu_is_cpu_idle())
-               return 0;
-       if (!rcu_lockdep_current_cpu_online())
-               return 0;
-       return in_softirq() || irqs_disabled();
-}
-EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
-
-#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
-
-struct rcu_synchronize {
-       struct rcu_head head;
-       struct completion completion;
-};
-
-/*
- * Awaken the corresponding synchronize_rcu() instance now that a
- * grace period has elapsed.
- */
-static void wakeme_after_rcu(struct rcu_head  *head)
-{
-       struct rcu_synchronize *rcu;
-
-       rcu = container_of(head, struct rcu_synchronize, head);
-       complete(&rcu->completion);
-}
-
-void wait_rcu_gp(call_rcu_func_t crf)
-{
-       struct rcu_synchronize rcu;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       crf(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
-}
-EXPORT_SYMBOL_GPL(wait_rcu_gp);
-
-#ifdef CONFIG_PROVE_RCU
-/*
- * wrapper function to avoid #include problems.
- */
-int rcu_my_thread_group_empty(void)
-{
-       return thread_group_empty(current);
-}
-EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
-#endif /* #ifdef CONFIG_PROVE_RCU */
-
-#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
-static inline void debug_init_rcu_head(struct rcu_head *head)
-{
-       debug_object_init(head, &rcuhead_debug_descr);
-}
-
-static inline void debug_rcu_head_free(struct rcu_head *head)
-{
-       debug_object_free(head, &rcuhead_debug_descr);
-}
-
-/*
- * fixup_activate is called when:
- * - an active object is activated
- * - an unknown object is activated (might be a statically initialized object)
- * Activation is performed internally by call_rcu().
- */
-static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state)
-{
-       struct rcu_head *head = addr;
-
-       switch (state) {
-
-       case ODEBUG_STATE_NOTAVAILABLE:
-               /*
-                * This is not really a fixup. We just make sure that it is
-                * tracked in the object tracker.
-                */
-               debug_object_init(head, &rcuhead_debug_descr);
-               debug_object_activate(head, &rcuhead_debug_descr);
-               return 0;
-       default:
-               return 1;
-       }
-}
-
-/**
- * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects
- * @head: pointer to rcu_head structure to be initialized
- *
- * This function informs debugobjects of a new rcu_head structure that
- * has been allocated as an auto variable on the stack.  This function
- * is not required for rcu_head structures that are statically defined or
- * that are dynamically allocated on the heap.  This function has no
- * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
- */
-void init_rcu_head_on_stack(struct rcu_head *head)
-{
-       debug_object_init_on_stack(head, &rcuhead_debug_descr);
-}
-EXPORT_SYMBOL_GPL(init_rcu_head_on_stack);
-
-/**
- * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects
- * @head: pointer to rcu_head structure to be initialized
- *
- * This function informs debugobjects that an on-stack rcu_head structure
- * is about to go out of scope.  As with init_rcu_head_on_stack(), this
- * function is not required for rcu_head structures that are statically
- * defined or that are dynamically allocated on the heap.  Also as with
- * init_rcu_head_on_stack(), this function has no effect for
- * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
- */
-void destroy_rcu_head_on_stack(struct rcu_head *head)
-{
-       debug_object_free(head, &rcuhead_debug_descr);
-}
-EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack);
-
-struct debug_obj_descr rcuhead_debug_descr = {
-       .name = "rcu_head",
-       .fixup_activate = rcuhead_fixup_activate,
-};
-EXPORT_SYMBOL_GPL(rcuhead_debug_descr);
-#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-
-#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) || defined(CONFIG_RCU_TRACE)
-void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp,
-                              unsigned long secs,
-                              unsigned long c_old, unsigned long c)
-{
-       trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c);
-}
-EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read);
-#else
-#define do_trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \
-       do { } while (0)
-#endif
-
-#ifdef CONFIG_RCU_STALL_COMMON
-
-#ifdef CONFIG_PROVE_RCU
-#define RCU_STALL_DELAY_DELTA         (5 * HZ)
-#else
-#define RCU_STALL_DELAY_DELTA         0
-#endif
-
-int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
-int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
-
-module_param(rcu_cpu_stall_suppress, int, 0644);
-module_param(rcu_cpu_stall_timeout, int, 0644);
-
-int rcu_jiffies_till_stall_check(void)
-{
-       int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
-
-       /*
-        * Limit check must be consistent with the Kconfig limits
-        * for CONFIG_RCU_CPU_STALL_TIMEOUT.
-        */
-       if (till_stall_check < 3) {
-               ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
-               till_stall_check = 3;
-       } else if (till_stall_check > 300) {
-               ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
-               till_stall_check = 300;
-       }
-       return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
-}
-
-static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr)
-{
-       rcu_cpu_stall_suppress = 1;
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block rcu_panic_block = {
-       .notifier_call = rcu_panic,
-};
-
-static int __init check_cpu_stall_init(void)
-{
-       atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block);
-       return 0;
-}
-early_initcall(check_cpu_stall_init);
-
-#endif /* #ifdef CONFIG_RCU_STALL_COMMON */
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
deleted file mode 100644 (file)
index 9ed6075..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition.
- *
- * 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 IBM Corporation, 2008
- *
- * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
- *
- * For detailed explanation of Read-Copy Update mechanism see -
- *             Documentation/RCU
- */
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/rcupdate.h>
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/cpu.h>
-#include <linux/prefetch.h>
-
-#ifdef CONFIG_RCU_TRACE
-#include <trace/events/rcu.h>
-#endif /* #else #ifdef CONFIG_RCU_TRACE */
-
-#include "rcu.h"
-
-/* Forward declarations for rcutiny_plugin.h. */
-struct rcu_ctrlblk;
-static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp);
-static void rcu_process_callbacks(struct softirq_action *unused);
-static void __call_rcu(struct rcu_head *head,
-                      void (*func)(struct rcu_head *rcu),
-                      struct rcu_ctrlblk *rcp);
-
-static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
-
-#include "rcutiny_plugin.h"
-
-/* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. */
-static void rcu_idle_enter_common(long long newval)
-{
-       if (newval) {
-               RCU_TRACE(trace_rcu_dyntick("--=",
-                                           rcu_dynticks_nesting, newval));
-               rcu_dynticks_nesting = newval;
-               return;
-       }
-       RCU_TRACE(trace_rcu_dyntick("Start", rcu_dynticks_nesting, newval));
-       if (!is_idle_task(current)) {
-               struct task_struct *idle = idle_task(smp_processor_id());
-
-               RCU_TRACE(trace_rcu_dyntick("Error on entry: not idle task",
-                                           rcu_dynticks_nesting, newval));
-               ftrace_dump(DUMP_ALL);
-               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
-                         current->pid, current->comm,
-                         idle->pid, idle->comm); /* must be idle task! */
-       }
-       rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
-       barrier();
-       rcu_dynticks_nesting = newval;
-}
-
-/*
- * Enter idle, which is an extended quiescent state if we have fully
- * entered that mode (i.e., if the new value of dynticks_nesting is zero).
- */
-void rcu_idle_enter(void)
-{
-       unsigned long flags;
-       long long newval;
-
-       local_irq_save(flags);
-       WARN_ON_ONCE((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0);
-       if ((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) ==
-           DYNTICK_TASK_NEST_VALUE)
-               newval = 0;
-       else
-               newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE;
-       rcu_idle_enter_common(newval);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(rcu_idle_enter);
-
-/*
- * Exit an interrupt handler towards idle.
- */
-void rcu_irq_exit(void)
-{
-       unsigned long flags;
-       long long newval;
-
-       local_irq_save(flags);
-       newval = rcu_dynticks_nesting - 1;
-       WARN_ON_ONCE(newval < 0);
-       rcu_idle_enter_common(newval);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(rcu_irq_exit);
-
-/* Common code for rcu_idle_exit() and rcu_irq_enter(), see kernel/rcutree.c. */
-static void rcu_idle_exit_common(long long oldval)
-{
-       if (oldval) {
-               RCU_TRACE(trace_rcu_dyntick("++=",
-                                           oldval, rcu_dynticks_nesting));
-               return;
-       }
-       RCU_TRACE(trace_rcu_dyntick("End", oldval, rcu_dynticks_nesting));
-       if (!is_idle_task(current)) {
-               struct task_struct *idle = idle_task(smp_processor_id());
-
-               RCU_TRACE(trace_rcu_dyntick("Error on exit: not idle task",
-                         oldval, rcu_dynticks_nesting));
-               ftrace_dump(DUMP_ALL);
-               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
-                         current->pid, current->comm,
-                         idle->pid, idle->comm); /* must be idle task! */
-       }
-}
-
-/*
- * Exit idle, so that we are no longer in an extended quiescent state.
- */
-void rcu_idle_exit(void)
-{
-       unsigned long flags;
-       long long oldval;
-
-       local_irq_save(flags);
-       oldval = rcu_dynticks_nesting;
-       WARN_ON_ONCE(rcu_dynticks_nesting < 0);
-       if (rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK)
-               rcu_dynticks_nesting += DYNTICK_TASK_NEST_VALUE;
-       else
-               rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
-       rcu_idle_exit_common(oldval);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(rcu_idle_exit);
-
-/*
- * Enter an interrupt handler, moving away from idle.
- */
-void rcu_irq_enter(void)
-{
-       unsigned long flags;
-       long long oldval;
-
-       local_irq_save(flags);
-       oldval = rcu_dynticks_nesting;
-       rcu_dynticks_nesting++;
-       WARN_ON_ONCE(rcu_dynticks_nesting == 0);
-       rcu_idle_exit_common(oldval);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(rcu_irq_enter);
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-
-/*
- * Test whether RCU thinks that the current CPU is idle.
- */
-int rcu_is_cpu_idle(void)
-{
-       return !rcu_dynticks_nesting;
-}
-EXPORT_SYMBOL(rcu_is_cpu_idle);
-
-#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
-
-/*
- * Test whether the current CPU was interrupted from idle.  Nested
- * interrupts don't count, we must be running at the first interrupt
- * level.
- */
-static int rcu_is_cpu_rrupt_from_idle(void)
-{
-       return rcu_dynticks_nesting <= 1;
-}
-
-/*
- * Helper function for rcu_sched_qs() and rcu_bh_qs().
- * Also irqs are disabled to avoid confusion due to interrupt handlers
- * invoking call_rcu().
- */
-static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
-{
-       RCU_TRACE(reset_cpu_stall_ticks(rcp));
-       if (rcp->rcucblist != NULL &&
-           rcp->donetail != rcp->curtail) {
-               rcp->donetail = rcp->curtail;
-               return 1;
-       }
-
-       return 0;
-}
-
-/*
- * Record an rcu quiescent state.  And an rcu_bh quiescent state while we
- * are at it, given that any rcu quiescent state is also an rcu_bh
- * quiescent state.  Use "+" instead of "||" to defeat short circuiting.
- */
-void rcu_sched_qs(int cpu)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       if (rcu_qsctr_help(&rcu_sched_ctrlblk) +
-           rcu_qsctr_help(&rcu_bh_ctrlblk))
-               raise_softirq(RCU_SOFTIRQ);
-       local_irq_restore(flags);
-}
-
-/*
- * Record an rcu_bh quiescent state.
- */
-void rcu_bh_qs(int cpu)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       if (rcu_qsctr_help(&rcu_bh_ctrlblk))
-               raise_softirq(RCU_SOFTIRQ);
-       local_irq_restore(flags);
-}
-
-/*
- * Check to see if the scheduling-clock interrupt came from an extended
- * quiescent state, and, if so, tell RCU about it.  This function must
- * be called from hardirq context.  It is normally called from the
- * scheduling-clock interrupt.
- */
-void rcu_check_callbacks(int cpu, int user)
-{
-       RCU_TRACE(check_cpu_stalls());
-       if (user || rcu_is_cpu_rrupt_from_idle())
-               rcu_sched_qs(cpu);
-       else if (!in_softirq())
-               rcu_bh_qs(cpu);
-}
-
-/*
- * Invoke the RCU callbacks on the specified rcu_ctrlkblk structure
- * whose grace period has elapsed.
- */
-static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
-{
-       const char *rn = NULL;
-       struct rcu_head *next, *list;
-       unsigned long flags;
-       RCU_TRACE(int cb_count = 0);
-
-       /* If no RCU callbacks ready to invoke, just return. */
-       if (&rcp->rcucblist == rcp->donetail) {
-               RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, 0, -1));
-               RCU_TRACE(trace_rcu_batch_end(rcp->name, 0,
-                                             ACCESS_ONCE(rcp->rcucblist),
-                                             need_resched(),
-                                             is_idle_task(current),
-                                             false));
-               return;
-       }
-
-       /* Move the ready-to-invoke callbacks to a local list. */
-       local_irq_save(flags);
-       RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, rcp->qlen, -1));
-       list = rcp->rcucblist;
-       rcp->rcucblist = *rcp->donetail;
-       *rcp->donetail = NULL;
-       if (rcp->curtail == rcp->donetail)
-               rcp->curtail = &rcp->rcucblist;
-       rcp->donetail = &rcp->rcucblist;
-       local_irq_restore(flags);
-
-       /* Invoke the callbacks on the local list. */
-       RCU_TRACE(rn = rcp->name);
-       while (list) {
-               next = list->next;
-               prefetch(next);
-               debug_rcu_head_unqueue(list);
-               local_bh_disable();
-               __rcu_reclaim(rn, list);
-               local_bh_enable();
-               list = next;
-               RCU_TRACE(cb_count++);
-       }
-       RCU_TRACE(rcu_trace_sub_qlen(rcp, cb_count));
-       RCU_TRACE(trace_rcu_batch_end(rcp->name, cb_count, 0, need_resched(),
-                                     is_idle_task(current),
-                                     false));
-}
-
-static void rcu_process_callbacks(struct softirq_action *unused)
-{
-       __rcu_process_callbacks(&rcu_sched_ctrlblk);
-       __rcu_process_callbacks(&rcu_bh_ctrlblk);
-}
-
-/*
- * Wait for a grace period to elapse.  But it is illegal to invoke
- * synchronize_sched() from within an RCU read-side critical section.
- * Therefore, any legal call to synchronize_sched() is a quiescent
- * state, and so on a UP system, synchronize_sched() need do nothing.
- * Ditto for synchronize_rcu_bh().  (But Lai Jiangshan points out the
- * benefits of doing might_sleep() to reduce latency.)
- *
- * Cool, huh?  (Due to Josh Triplett.)
- *
- * But we want to make this a static inline later.  The cond_resched()
- * currently makes this problematic.
- */
-void synchronize_sched(void)
-{
-       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
-                          !lock_is_held(&rcu_lock_map) &&
-                          !lock_is_held(&rcu_sched_lock_map),
-                          "Illegal synchronize_sched() in RCU read-side critical section");
-       cond_resched();
-}
-EXPORT_SYMBOL_GPL(synchronize_sched);
-
-/*
- * Helper function for call_rcu() and call_rcu_bh().
- */
-static void __call_rcu(struct rcu_head *head,
-                      void (*func)(struct rcu_head *rcu),
-                      struct rcu_ctrlblk *rcp)
-{
-       unsigned long flags;
-
-       debug_rcu_head_queue(head);
-       head->func = func;
-       head->next = NULL;
-
-       local_irq_save(flags);
-       *rcp->curtail = head;
-       rcp->curtail = &head->next;
-       RCU_TRACE(rcp->qlen++);
-       local_irq_restore(flags);
-}
-
-/*
- * Post an RCU callback to be invoked after the end of an RCU-sched grace
- * period.  But since we have but one CPU, that would be after any
- * quiescent state.
- */
-void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_sched_ctrlblk);
-}
-EXPORT_SYMBOL_GPL(call_rcu_sched);
-
-/*
- * Post an RCU bottom-half callback to be invoked after any subsequent
- * quiescent state.
- */
-void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_bh_ctrlblk);
-}
-EXPORT_SYMBOL_GPL(call_rcu_bh);
-
-void rcu_init(void)
-{
-       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
-}
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
deleted file mode 100644 (file)
index 280d06c..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition
- * Internal non-public definitions that provide either classic
- * or preemptible semantics.
- *
- * 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) 2010 Linaro
- *
- * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
- */
-
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-/* Global control variables for rcupdate callback mechanism. */
-struct rcu_ctrlblk {
-       struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
-       struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
-       struct rcu_head **curtail;      /* ->next pointer of last CB. */
-       RCU_TRACE(long qlen);           /* Number of pending CBs. */
-       RCU_TRACE(unsigned long gp_start); /* Start time for stalls. */
-       RCU_TRACE(unsigned long ticks_this_gp); /* Statistic for stalls. */
-       RCU_TRACE(unsigned long jiffies_stall); /* Jiffies at next stall. */
-       RCU_TRACE(const char *name);    /* Name of RCU type. */
-};
-
-/* Definition for rcupdate control block. */
-static struct rcu_ctrlblk rcu_sched_ctrlblk = {
-       .donetail       = &rcu_sched_ctrlblk.rcucblist,
-       .curtail        = &rcu_sched_ctrlblk.rcucblist,
-       RCU_TRACE(.name = "rcu_sched")
-};
-
-static struct rcu_ctrlblk rcu_bh_ctrlblk = {
-       .donetail       = &rcu_bh_ctrlblk.rcucblist,
-       .curtail        = &rcu_bh_ctrlblk.rcucblist,
-       RCU_TRACE(.name = "rcu_bh")
-};
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-#include <linux/kernel_stat.h>
-
-int rcu_scheduler_active __read_mostly;
-EXPORT_SYMBOL_GPL(rcu_scheduler_active);
-
-/*
- * During boot, we forgive RCU lockdep issues.  After this function is
- * invoked, we start taking RCU lockdep issues seriously.
- */
-void __init rcu_scheduler_starting(void)
-{
-       WARN_ON(nr_context_switches() > 0);
-       rcu_scheduler_active = 1;
-}
-
-#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
-
-#ifdef CONFIG_RCU_TRACE
-
-static void rcu_trace_sub_qlen(struct rcu_ctrlblk *rcp, int n)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       rcp->qlen -= n;
-       local_irq_restore(flags);
-}
-
-/*
- * Dump statistics for TINY_RCU, such as they are.
- */
-static int show_tiny_stats(struct seq_file *m, void *unused)
-{
-       seq_printf(m, "rcu_sched: qlen: %ld\n", rcu_sched_ctrlblk.qlen);
-       seq_printf(m, "rcu_bh: qlen: %ld\n", rcu_bh_ctrlblk.qlen);
-       return 0;
-}
-
-static int show_tiny_stats_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_tiny_stats, NULL);
-}
-
-static const struct file_operations show_tiny_stats_fops = {
-       .owner = THIS_MODULE,
-       .open = show_tiny_stats_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-static struct dentry *rcudir;
-
-static int __init rcutiny_trace_init(void)
-{
-       struct dentry *retval;
-
-       rcudir = debugfs_create_dir("rcu", NULL);
-       if (!rcudir)
-               goto free_out;
-       retval = debugfs_create_file("rcudata", 0444, rcudir,
-                                    NULL, &show_tiny_stats_fops);
-       if (!retval)
-               goto free_out;
-       return 0;
-free_out:
-       debugfs_remove_recursive(rcudir);
-       return 1;
-}
-
-static void __exit rcutiny_trace_cleanup(void)
-{
-       debugfs_remove_recursive(rcudir);
-}
-
-module_init(rcutiny_trace_init);
-module_exit(rcutiny_trace_cleanup);
-
-MODULE_AUTHOR("Paul E. McKenney");
-MODULE_DESCRIPTION("Read-Copy Update tracing for tiny implementation");
-MODULE_LICENSE("GPL");
-
-static void check_cpu_stall(struct rcu_ctrlblk *rcp)
-{
-       unsigned long j;
-       unsigned long js;
-
-       if (rcu_cpu_stall_suppress)
-               return;
-       rcp->ticks_this_gp++;
-       j = jiffies;
-       js = rcp->jiffies_stall;
-       if (*rcp->curtail && ULONG_CMP_GE(j, js)) {
-               pr_err("INFO: %s stall on CPU (%lu ticks this GP) idle=%llx (t=%lu jiffies q=%ld)\n",
-                      rcp->name, rcp->ticks_this_gp, rcu_dynticks_nesting,
-                      jiffies - rcp->gp_start, rcp->qlen);
-               dump_stack();
-       }
-       if (*rcp->curtail && ULONG_CMP_GE(j, js))
-               rcp->jiffies_stall = jiffies +
-                       3 * rcu_jiffies_till_stall_check() + 3;
-       else if (ULONG_CMP_GE(j, js))
-               rcp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check();
-}
-
-static void reset_cpu_stall_ticks(struct rcu_ctrlblk *rcp)
-{
-       rcp->ticks_this_gp = 0;
-       rcp->gp_start = jiffies;
-       rcp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check();
-}
-
-static void check_cpu_stalls(void)
-{
-       RCU_TRACE(check_cpu_stall(&rcu_bh_ctrlblk));
-       RCU_TRACE(check_cpu_stall(&rcu_sched_ctrlblk));
-}
-
-#endif /* #ifdef CONFIG_RCU_TRACE */
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
deleted file mode 100644 (file)
index be63101..0000000
+++ /dev/null
@@ -1,2139 +0,0 @@
-/*
- * Read-Copy Update module-based torture test facility
- *
- * 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) IBM Corporation, 2005, 2006
- *
- * Authors: Paul E. McKenney <paulmck@us.ibm.com>
- *       Josh Triplett <josh@freedesktop.org>
- *
- * See also:  Documentation/RCU/torture.txt
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kthread.h>
-#include <linux/err.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <linux/rcupdate.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/atomic.h>
-#include <linux/bitops.h>
-#include <linux/completion.h>
-#include <linux/moduleparam.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/freezer.h>
-#include <linux/cpu.h>
-#include <linux/delay.h>
-#include <linux/stat.h>
-#include <linux/srcu.h>
-#include <linux/slab.h>
-#include <linux/trace_clock.h>
-#include <asm/byteorder.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@freedesktop.org>");
-
-static int fqs_duration;
-module_param(fqs_duration, int, 0444);
-MODULE_PARM_DESC(fqs_duration, "Duration of fqs bursts (us), 0 to disable");
-static int fqs_holdoff;
-module_param(fqs_holdoff, int, 0444);
-MODULE_PARM_DESC(fqs_holdoff, "Holdoff time within fqs bursts (us)");
-static int fqs_stutter = 3;
-module_param(fqs_stutter, int, 0444);
-MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)");
-static bool gp_exp;
-module_param(gp_exp, bool, 0444);
-MODULE_PARM_DESC(gp_exp, "Use expedited GP wait primitives");
-static bool gp_normal;
-module_param(gp_normal, bool, 0444);
-MODULE_PARM_DESC(gp_normal, "Use normal (non-expedited) GP wait primitives");
-static int irqreader = 1;
-module_param(irqreader, int, 0444);
-MODULE_PARM_DESC(irqreader, "Allow RCU readers from irq handlers");
-static int n_barrier_cbs;
-module_param(n_barrier_cbs, int, 0444);
-MODULE_PARM_DESC(n_barrier_cbs, "# of callbacks/kthreads for barrier testing");
-static int nfakewriters = 4;
-module_param(nfakewriters, int, 0444);
-MODULE_PARM_DESC(nfakewriters, "Number of RCU fake writer threads");
-static int nreaders = -1;
-module_param(nreaders, int, 0444);
-MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
-static int object_debug;
-module_param(object_debug, int, 0444);
-MODULE_PARM_DESC(object_debug, "Enable debug-object double call_rcu() testing");
-static int onoff_holdoff;
-module_param(onoff_holdoff, int, 0444);
-MODULE_PARM_DESC(onoff_holdoff, "Time after boot before CPU hotplugs (s)");
-static int onoff_interval;
-module_param(onoff_interval, int, 0444);
-MODULE_PARM_DESC(onoff_interval, "Time between CPU hotplugs (s), 0=disable");
-static int shuffle_interval = 3;
-module_param(shuffle_interval, int, 0444);
-MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles");
-static int shutdown_secs;
-module_param(shutdown_secs, int, 0444);
-MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), <= zero to disable.");
-static int stall_cpu;
-module_param(stall_cpu, int, 0444);
-MODULE_PARM_DESC(stall_cpu, "Stall duration (s), zero to disable.");
-static int stall_cpu_holdoff = 10;
-module_param(stall_cpu_holdoff, int, 0444);
-MODULE_PARM_DESC(stall_cpu_holdoff, "Time to wait before starting stall (s).");
-static int stat_interval = 60;
-module_param(stat_interval, int, 0644);
-MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
-static int stutter = 5;
-module_param(stutter, int, 0444);
-MODULE_PARM_DESC(stutter, "Number of seconds to run/halt test");
-static int test_boost = 1;
-module_param(test_boost, int, 0444);
-MODULE_PARM_DESC(test_boost, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
-static int test_boost_duration = 4;
-module_param(test_boost_duration, int, 0444);
-MODULE_PARM_DESC(test_boost_duration, "Duration of each boost test, seconds.");
-static int test_boost_interval = 7;
-module_param(test_boost_interval, int, 0444);
-MODULE_PARM_DESC(test_boost_interval, "Interval between boost tests, seconds.");
-static bool test_no_idle_hz = true;
-module_param(test_no_idle_hz, bool, 0444);
-MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs");
-static char *torture_type = "rcu";
-module_param(torture_type, charp, 0444);
-MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)");
-static bool verbose;
-module_param(verbose, bool, 0444);
-MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
-
-#define TORTURE_FLAG "-torture:"
-#define PRINTK_STRING(s) \
-       do { pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0)
-#define VERBOSE_PRINTK_STRING(s) \
-       do { if (verbose) pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0)
-#define VERBOSE_PRINTK_ERRSTRING(s) \
-       do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0)
-
-static char printk_buf[4096];
-
-static int nrealreaders;
-static struct task_struct *writer_task;
-static struct task_struct **fakewriter_tasks;
-static struct task_struct **reader_tasks;
-static struct task_struct *stats_task;
-static struct task_struct *shuffler_task;
-static struct task_struct *stutter_task;
-static struct task_struct *fqs_task;
-static struct task_struct *boost_tasks[NR_CPUS];
-static struct task_struct *shutdown_task;
-#ifdef CONFIG_HOTPLUG_CPU
-static struct task_struct *onoff_task;
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-static struct task_struct *stall_task;
-static struct task_struct **barrier_cbs_tasks;
-static struct task_struct *barrier_task;
-
-#define RCU_TORTURE_PIPE_LEN 10
-
-struct rcu_torture {
-       struct rcu_head rtort_rcu;
-       int rtort_pipe_count;
-       struct list_head rtort_free;
-       int rtort_mbtest;
-};
-
-static LIST_HEAD(rcu_torture_freelist);
-static struct rcu_torture __rcu *rcu_torture_current;
-static unsigned long rcu_torture_current_version;
-static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
-static DEFINE_SPINLOCK(rcu_torture_lock);
-static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
-       { 0 };
-static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
-       { 0 };
-static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
-static atomic_t n_rcu_torture_alloc;
-static atomic_t n_rcu_torture_alloc_fail;
-static atomic_t n_rcu_torture_free;
-static atomic_t n_rcu_torture_mberror;
-static atomic_t n_rcu_torture_error;
-static long n_rcu_torture_barrier_error;
-static long n_rcu_torture_boost_ktrerror;
-static long n_rcu_torture_boost_rterror;
-static long n_rcu_torture_boost_failure;
-static long n_rcu_torture_boosts;
-static long n_rcu_torture_timers;
-static long n_offline_attempts;
-static long n_offline_successes;
-static unsigned long sum_offline;
-static int min_offline = -1;
-static int max_offline;
-static long n_online_attempts;
-static long n_online_successes;
-static unsigned long sum_online;
-static int min_online = -1;
-static int max_online;
-static long n_barrier_attempts;
-static long n_barrier_successes;
-static struct list_head rcu_torture_removed;
-static cpumask_var_t shuffle_tmp_mask;
-
-static int stutter_pause_test;
-
-#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE)
-#define RCUTORTURE_RUNNABLE_INIT 1
-#else
-#define RCUTORTURE_RUNNABLE_INIT 0
-#endif
-int rcutorture_runnable = RCUTORTURE_RUNNABLE_INIT;
-module_param(rcutorture_runnable, int, 0444);
-MODULE_PARM_DESC(rcutorture_runnable, "Start rcutorture at boot");
-
-#if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU)
-#define rcu_can_boost() 1
-#else /* #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */
-#define rcu_can_boost() 0
-#endif /* #else #if defined(CONFIG_RCU_BOOST) && !defined(CONFIG_HOTPLUG_CPU) */
-
-#ifdef CONFIG_RCU_TRACE
-static u64 notrace rcu_trace_clock_local(void)
-{
-       u64 ts = trace_clock_local();
-       unsigned long __maybe_unused ts_rem = do_div(ts, NSEC_PER_USEC);
-       return ts;
-}
-#else /* #ifdef CONFIG_RCU_TRACE */
-static u64 notrace rcu_trace_clock_local(void)
-{
-       return 0ULL;
-}
-#endif /* #else #ifdef CONFIG_RCU_TRACE */
-
-static unsigned long shutdown_time;    /* jiffies to system shutdown. */
-static unsigned long boost_starttime;  /* jiffies of next boost test start. */
-DEFINE_MUTEX(boost_mutex);             /* protect setting boost_starttime */
-                                       /*  and boost task create/destroy. */
-static atomic_t barrier_cbs_count;     /* Barrier callbacks registered. */
-static bool barrier_phase;             /* Test phase. */
-static atomic_t barrier_cbs_invoked;   /* Barrier callbacks invoked. */
-static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */
-static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
-
-/* Mediate rmmod and system shutdown.  Concurrent rmmod & shutdown illegal! */
-
-#define FULLSTOP_DONTSTOP 0    /* Normal operation. */
-#define FULLSTOP_SHUTDOWN 1    /* System shutdown with rcutorture running. */
-#define FULLSTOP_RMMOD    2    /* Normal rmmod of rcutorture. */
-static int fullstop = FULLSTOP_RMMOD;
-/*
- * Protect fullstop transitions and spawning of kthreads.
- */
-static DEFINE_MUTEX(fullstop_mutex);
-
-/* Forward reference. */
-static void rcu_torture_cleanup(void);
-
-/*
- * Detect and respond to a system shutdown.
- */
-static int
-rcutorture_shutdown_notify(struct notifier_block *unused1,
-                          unsigned long unused2, void *unused3)
-{
-       mutex_lock(&fullstop_mutex);
-       if (fullstop == FULLSTOP_DONTSTOP)
-               fullstop = FULLSTOP_SHUTDOWN;
-       else
-               pr_warn(/* but going down anyway, so... */
-                      "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
-       mutex_unlock(&fullstop_mutex);
-       return NOTIFY_DONE;
-}
-
-/*
- * Absorb kthreads into a kernel function that won't return, so that
- * they won't ever access module text or data again.
- */
-static void rcutorture_shutdown_absorb(const char *title)
-{
-       if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
-               pr_notice(
-                      "rcutorture thread %s parking due to system shutdown\n",
-                      title);
-               schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
-       }
-}
-
-/*
- * Allocate an element from the rcu_tortures pool.
- */
-static struct rcu_torture *
-rcu_torture_alloc(void)
-{
-       struct list_head *p;
-
-       spin_lock_bh(&rcu_torture_lock);
-       if (list_empty(&rcu_torture_freelist)) {
-               atomic_inc(&n_rcu_torture_alloc_fail);
-               spin_unlock_bh(&rcu_torture_lock);
-               return NULL;
-       }
-       atomic_inc(&n_rcu_torture_alloc);
-       p = rcu_torture_freelist.next;
-       list_del_init(p);
-       spin_unlock_bh(&rcu_torture_lock);
-       return container_of(p, struct rcu_torture, rtort_free);
-}
-
-/*
- * Free an element to the rcu_tortures pool.
- */
-static void
-rcu_torture_free(struct rcu_torture *p)
-{
-       atomic_inc(&n_rcu_torture_free);
-       spin_lock_bh(&rcu_torture_lock);
-       list_add_tail(&p->rtort_free, &rcu_torture_freelist);
-       spin_unlock_bh(&rcu_torture_lock);
-}
-
-struct rcu_random_state {
-       unsigned long rrs_state;
-       long rrs_count;
-};
-
-#define RCU_RANDOM_MULT 39916801  /* prime */
-#define RCU_RANDOM_ADD 479001701 /* prime */
-#define RCU_RANDOM_REFRESH 10000
-
-#define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 }
-
-/*
- * Crude but fast random-number generator.  Uses a linear congruential
- * generator, with occasional help from cpu_clock().
- */
-static unsigned long
-rcu_random(struct rcu_random_state *rrsp)
-{
-       if (--rrsp->rrs_count < 0) {
-               rrsp->rrs_state += (unsigned long)local_clock();
-               rrsp->rrs_count = RCU_RANDOM_REFRESH;
-       }
-       rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
-       return swahw32(rrsp->rrs_state);
-}
-
-static void
-rcu_stutter_wait(const char *title)
-{
-       while (stutter_pause_test || !rcutorture_runnable) {
-               if (rcutorture_runnable)
-                       schedule_timeout_interruptible(1);
-               else
-                       schedule_timeout_interruptible(round_jiffies_relative(HZ));
-               rcutorture_shutdown_absorb(title);
-       }
-}
-
-/*
- * Operations vector for selecting different types of tests.
- */
-
-struct rcu_torture_ops {
-       void (*init)(void);
-       int (*readlock)(void);
-       void (*read_delay)(struct rcu_random_state *rrsp);
-       void (*readunlock)(int idx);
-       int (*completed)(void);
-       void (*deferred_free)(struct rcu_torture *p);
-       void (*sync)(void);
-       void (*exp_sync)(void);
-       void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
-       void (*cb_barrier)(void);
-       void (*fqs)(void);
-       int (*stats)(char *page);
-       int irq_capable;
-       int can_boost;
-       const char *name;
-};
-
-static struct rcu_torture_ops *cur_ops;
-
-/*
- * Definitions for rcu torture testing.
- */
-
-static int rcu_torture_read_lock(void) __acquires(RCU)
-{
-       rcu_read_lock();
-       return 0;
-}
-
-static void rcu_read_delay(struct rcu_random_state *rrsp)
-{
-       const unsigned long shortdelay_us = 200;
-       const unsigned long longdelay_ms = 50;
-
-       /* We want a short delay sometimes to make a reader delay the grace
-        * period, and we want a long delay occasionally to trigger
-        * force_quiescent_state. */
-
-       if (!(rcu_random(rrsp) % (nrealreaders * 2000 * longdelay_ms)))
-               mdelay(longdelay_ms);
-       if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us)))
-               udelay(shortdelay_us);
-#ifdef CONFIG_PREEMPT
-       if (!preempt_count() && !(rcu_random(rrsp) % (nrealreaders * 20000)))
-               preempt_schedule();  /* No QS if preempt_disable() in effect */
-#endif
-}
-
-static void rcu_torture_read_unlock(int idx) __releases(RCU)
-{
-       rcu_read_unlock();
-}
-
-static int rcu_torture_completed(void)
-{
-       return rcu_batches_completed();
-}
-
-static void
-rcu_torture_cb(struct rcu_head *p)
-{
-       int i;
-       struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
-
-       if (fullstop != FULLSTOP_DONTSTOP) {
-               /* Test is ending, just drop callbacks on the floor. */
-               /* The next initialization will pick up the pieces. */
-               return;
-       }
-       i = rp->rtort_pipe_count;
-       if (i > RCU_TORTURE_PIPE_LEN)
-               i = RCU_TORTURE_PIPE_LEN;
-       atomic_inc(&rcu_torture_wcount[i]);
-       if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
-               rp->rtort_mbtest = 0;
-               rcu_torture_free(rp);
-       } else {
-               cur_ops->deferred_free(rp);
-       }
-}
-
-static int rcu_no_completed(void)
-{
-       return 0;
-}
-
-static void rcu_torture_deferred_free(struct rcu_torture *p)
-{
-       call_rcu(&p->rtort_rcu, rcu_torture_cb);
-}
-
-static void rcu_sync_torture_init(void)
-{
-       INIT_LIST_HEAD(&rcu_torture_removed);
-}
-
-static struct rcu_torture_ops rcu_ops = {
-       .init           = rcu_sync_torture_init,
-       .readlock       = rcu_torture_read_lock,
-       .read_delay     = rcu_read_delay,
-       .readunlock     = rcu_torture_read_unlock,
-       .completed      = rcu_torture_completed,
-       .deferred_free  = rcu_torture_deferred_free,
-       .sync           = synchronize_rcu,
-       .exp_sync       = synchronize_rcu_expedited,
-       .call           = call_rcu,
-       .cb_barrier     = rcu_barrier,
-       .fqs            = rcu_force_quiescent_state,
-       .stats          = NULL,
-       .irq_capable    = 1,
-       .can_boost      = rcu_can_boost(),
-       .name           = "rcu"
-};
-
-/*
- * Definitions for rcu_bh torture testing.
- */
-
-static int rcu_bh_torture_read_lock(void) __acquires(RCU_BH)
-{
-       rcu_read_lock_bh();
-       return 0;
-}
-
-static void rcu_bh_torture_read_unlock(int idx) __releases(RCU_BH)
-{
-       rcu_read_unlock_bh();
-}
-
-static int rcu_bh_torture_completed(void)
-{
-       return rcu_batches_completed_bh();
-}
-
-static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
-{
-       call_rcu_bh(&p->rtort_rcu, rcu_torture_cb);
-}
-
-static struct rcu_torture_ops rcu_bh_ops = {
-       .init           = rcu_sync_torture_init,
-       .readlock       = rcu_bh_torture_read_lock,
-       .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
-       .readunlock     = rcu_bh_torture_read_unlock,
-       .completed      = rcu_bh_torture_completed,
-       .deferred_free  = rcu_bh_torture_deferred_free,
-       .sync           = synchronize_rcu_bh,
-       .exp_sync       = synchronize_rcu_bh_expedited,
-       .call           = call_rcu_bh,
-       .cb_barrier     = rcu_barrier_bh,
-       .fqs            = rcu_bh_force_quiescent_state,
-       .stats          = NULL,
-       .irq_capable    = 1,
-       .name           = "rcu_bh"
-};
-
-/*
- * Definitions for srcu torture testing.
- */
-
-DEFINE_STATIC_SRCU(srcu_ctl);
-
-static int srcu_torture_read_lock(void) __acquires(&srcu_ctl)
-{
-       return srcu_read_lock(&srcu_ctl);
-}
-
-static void srcu_read_delay(struct rcu_random_state *rrsp)
-{
-       long delay;
-       const long uspertick = 1000000 / HZ;
-       const long longdelay = 10;
-
-       /* We want there to be long-running readers, but not all the time. */
-
-       delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick);
-       if (!delay)
-               schedule_timeout_interruptible(longdelay);
-       else
-               rcu_read_delay(rrsp);
-}
-
-static void srcu_torture_read_unlock(int idx) __releases(&srcu_ctl)
-{
-       srcu_read_unlock(&srcu_ctl, idx);
-}
-
-static int srcu_torture_completed(void)
-{
-       return srcu_batches_completed(&srcu_ctl);
-}
-
-static void srcu_torture_deferred_free(struct rcu_torture *rp)
-{
-       call_srcu(&srcu_ctl, &rp->rtort_rcu, rcu_torture_cb);
-}
-
-static void srcu_torture_synchronize(void)
-{
-       synchronize_srcu(&srcu_ctl);
-}
-
-static void srcu_torture_call(struct rcu_head *head,
-                             void (*func)(struct rcu_head *head))
-{
-       call_srcu(&srcu_ctl, head, func);
-}
-
-static void srcu_torture_barrier(void)
-{
-       srcu_barrier(&srcu_ctl);
-}
-
-static int srcu_torture_stats(char *page)
-{
-       int cnt = 0;
-       int cpu;
-       int idx = srcu_ctl.completed & 0x1;
-
-       cnt += sprintf(&page[cnt], "%s%s per-CPU(idx=%d):",
-                      torture_type, TORTURE_FLAG, idx);
-       for_each_possible_cpu(cpu) {
-               cnt += sprintf(&page[cnt], " %d(%lu,%lu)", cpu,
-                              per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx],
-                              per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]);
-       }
-       cnt += sprintf(&page[cnt], "\n");
-       return cnt;
-}
-
-static void srcu_torture_synchronize_expedited(void)
-{
-       synchronize_srcu_expedited(&srcu_ctl);
-}
-
-static struct rcu_torture_ops srcu_ops = {
-       .init           = rcu_sync_torture_init,
-       .readlock       = srcu_torture_read_lock,
-       .read_delay     = srcu_read_delay,
-       .readunlock     = srcu_torture_read_unlock,
-       .completed      = srcu_torture_completed,
-       .deferred_free  = srcu_torture_deferred_free,
-       .sync           = srcu_torture_synchronize,
-       .exp_sync       = srcu_torture_synchronize_expedited,
-       .call           = srcu_torture_call,
-       .cb_barrier     = srcu_torture_barrier,
-       .stats          = srcu_torture_stats,
-       .name           = "srcu"
-};
-
-/*
- * Definitions for sched torture testing.
- */
-
-static int sched_torture_read_lock(void)
-{
-       preempt_disable();
-       return 0;
-}
-
-static void sched_torture_read_unlock(int idx)
-{
-       preempt_enable();
-}
-
-static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
-{
-       call_rcu_sched(&p->rtort_rcu, rcu_torture_cb);
-}
-
-static struct rcu_torture_ops sched_ops = {
-       .init           = rcu_sync_torture_init,
-       .readlock       = sched_torture_read_lock,
-       .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
-       .readunlock     = sched_torture_read_unlock,
-       .completed      = rcu_no_completed,
-       .deferred_free  = rcu_sched_torture_deferred_free,
-       .sync           = synchronize_sched,
-       .exp_sync       = synchronize_sched_expedited,
-       .call           = call_rcu_sched,
-       .cb_barrier     = rcu_barrier_sched,
-       .fqs            = rcu_sched_force_quiescent_state,
-       .stats          = NULL,
-       .irq_capable    = 1,
-       .name           = "sched"
-};
-
-/*
- * RCU torture priority-boost testing.  Runs one real-time thread per
- * CPU for moderate bursts, repeatedly registering RCU callbacks and
- * spinning waiting for them to be invoked.  If a given callback takes
- * too long to be invoked, we assume that priority inversion has occurred.
- */
-
-struct rcu_boost_inflight {
-       struct rcu_head rcu;
-       int inflight;
-};
-
-static void rcu_torture_boost_cb(struct rcu_head *head)
-{
-       struct rcu_boost_inflight *rbip =
-               container_of(head, struct rcu_boost_inflight, rcu);
-
-       smp_mb(); /* Ensure RCU-core accesses precede clearing ->inflight */
-       rbip->inflight = 0;
-}
-
-static int rcu_torture_boost(void *arg)
-{
-       unsigned long call_rcu_time;
-       unsigned long endtime;
-       unsigned long oldstarttime;
-       struct rcu_boost_inflight rbi = { .inflight = 0 };
-       struct sched_param sp;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_boost started");
-
-       /* Set real-time priority. */
-       sp.sched_priority = 1;
-       if (sched_setscheduler(current, SCHED_FIFO, &sp) < 0) {
-               VERBOSE_PRINTK_STRING("rcu_torture_boost RT prio failed!");
-               n_rcu_torture_boost_rterror++;
-       }
-
-       init_rcu_head_on_stack(&rbi.rcu);
-       /* Each pass through the following loop does one boost-test cycle. */
-       do {
-               /* Wait for the next test interval. */
-               oldstarttime = boost_starttime;
-               while (ULONG_CMP_LT(jiffies, oldstarttime)) {
-                       schedule_timeout_interruptible(oldstarttime - jiffies);
-                       rcu_stutter_wait("rcu_torture_boost");
-                       if (kthread_should_stop() ||
-                           fullstop != FULLSTOP_DONTSTOP)
-                               goto checkwait;
-               }
-
-               /* Do one boost-test interval. */
-               endtime = oldstarttime + test_boost_duration * HZ;
-               call_rcu_time = jiffies;
-               while (ULONG_CMP_LT(jiffies, endtime)) {
-                       /* If we don't have a callback in flight, post one. */
-                       if (!rbi.inflight) {
-                               smp_mb(); /* RCU core before ->inflight = 1. */
-                               rbi.inflight = 1;
-                               call_rcu(&rbi.rcu, rcu_torture_boost_cb);
-                               if (jiffies - call_rcu_time >
-                                        test_boost_duration * HZ - HZ / 2) {
-                                       VERBOSE_PRINTK_STRING("rcu_torture_boost boosting failed");
-                                       n_rcu_torture_boost_failure++;
-                               }
-                               call_rcu_time = jiffies;
-                       }
-                       cond_resched();
-                       rcu_stutter_wait("rcu_torture_boost");
-                       if (kthread_should_stop() ||
-                           fullstop != FULLSTOP_DONTSTOP)
-                               goto checkwait;
-               }
-
-               /*
-                * Set the start time of the next test interval.
-                * Yes, this is vulnerable to long delays, but such
-                * delays simply cause a false negative for the next
-                * interval.  Besides, we are running at RT priority,
-                * so delays should be relatively rare.
-                */
-               while (oldstarttime == boost_starttime &&
-                      !kthread_should_stop()) {
-                       if (mutex_trylock(&boost_mutex)) {
-                               boost_starttime = jiffies +
-                                                 test_boost_interval * HZ;
-                               n_rcu_torture_boosts++;
-                               mutex_unlock(&boost_mutex);
-                               break;
-                       }
-                       schedule_timeout_uninterruptible(1);
-               }
-
-               /* Go do the stutter. */
-checkwait:     rcu_stutter_wait("rcu_torture_boost");
-       } while (!kthread_should_stop() && fullstop  == FULLSTOP_DONTSTOP);
-
-       /* Clean up and exit. */
-       VERBOSE_PRINTK_STRING("rcu_torture_boost task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_boost");
-       while (!kthread_should_stop() || rbi.inflight)
-               schedule_timeout_uninterruptible(1);
-       smp_mb(); /* order accesses to ->inflight before stack-frame death. */
-       destroy_rcu_head_on_stack(&rbi.rcu);
-       return 0;
-}
-
-/*
- * RCU torture force-quiescent-state kthread.  Repeatedly induces
- * bursts of calls to force_quiescent_state(), increasing the probability
- * of occurrence of some important types of race conditions.
- */
-static int
-rcu_torture_fqs(void *arg)
-{
-       unsigned long fqs_resume_time;
-       int fqs_burst_remaining;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_fqs task started");
-       do {
-               fqs_resume_time = jiffies + fqs_stutter * HZ;
-               while (ULONG_CMP_LT(jiffies, fqs_resume_time) &&
-                      !kthread_should_stop()) {
-                       schedule_timeout_interruptible(1);
-               }
-               fqs_burst_remaining = fqs_duration;
-               while (fqs_burst_remaining > 0 &&
-                      !kthread_should_stop()) {
-                       cur_ops->fqs();
-                       udelay(fqs_holdoff);
-                       fqs_burst_remaining -= fqs_holdoff;
-               }
-               rcu_stutter_wait("rcu_torture_fqs");
-       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
-       VERBOSE_PRINTK_STRING("rcu_torture_fqs task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_fqs");
-       while (!kthread_should_stop())
-               schedule_timeout_uninterruptible(1);
-       return 0;
-}
-
-/*
- * RCU torture writer kthread.  Repeatedly substitutes a new structure
- * for that pointed to by rcu_torture_current, freeing the old structure
- * after a series of grace periods (the "pipeline").
- */
-static int
-rcu_torture_writer(void *arg)
-{
-       bool exp;
-       int i;
-       struct rcu_torture *rp;
-       struct rcu_torture *rp1;
-       struct rcu_torture *old_rp;
-       static DEFINE_RCU_RANDOM(rand);
-
-       VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
-       set_user_nice(current, 19);
-
-       do {
-               schedule_timeout_uninterruptible(1);
-               rp = rcu_torture_alloc();
-               if (rp == NULL)
-                       continue;
-               rp->rtort_pipe_count = 0;
-               udelay(rcu_random(&rand) & 0x3ff);
-               old_rp = rcu_dereference_check(rcu_torture_current,
-                                              current == writer_task);
-               rp->rtort_mbtest = 1;
-               rcu_assign_pointer(rcu_torture_current, rp);
-               smp_wmb(); /* Mods to old_rp must follow rcu_assign_pointer() */
-               if (old_rp) {
-                       i = old_rp->rtort_pipe_count;
-                       if (i > RCU_TORTURE_PIPE_LEN)
-                               i = RCU_TORTURE_PIPE_LEN;
-                       atomic_inc(&rcu_torture_wcount[i]);
-                       old_rp->rtort_pipe_count++;
-                       if (gp_normal == gp_exp)
-                               exp = !!(rcu_random(&rand) & 0x80);
-                       else
-                               exp = gp_exp;
-                       if (!exp) {
-                               cur_ops->deferred_free(old_rp);
-                       } else {
-                               cur_ops->exp_sync();
-                               list_add(&old_rp->rtort_free,
-                                        &rcu_torture_removed);
-                               list_for_each_entry_safe(rp, rp1,
-                                                        &rcu_torture_removed,
-                                                        rtort_free) {
-                                       i = rp->rtort_pipe_count;
-                                       if (i > RCU_TORTURE_PIPE_LEN)
-                                               i = RCU_TORTURE_PIPE_LEN;
-                                       atomic_inc(&rcu_torture_wcount[i]);
-                                       if (++rp->rtort_pipe_count >=
-                                           RCU_TORTURE_PIPE_LEN) {
-                                               rp->rtort_mbtest = 0;
-                                               list_del(&rp->rtort_free);
-                                               rcu_torture_free(rp);
-                                       }
-                                }
-                       }
-               }
-               rcutorture_record_progress(++rcu_torture_current_version);
-               rcu_stutter_wait("rcu_torture_writer");
-       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
-       VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_writer");
-       while (!kthread_should_stop())
-               schedule_timeout_uninterruptible(1);
-       return 0;
-}
-
-/*
- * RCU torture fake writer kthread.  Repeatedly calls sync, with a random
- * delay between calls.
- */
-static int
-rcu_torture_fakewriter(void *arg)
-{
-       DEFINE_RCU_RANDOM(rand);
-
-       VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
-       set_user_nice(current, 19);
-
-       do {
-               schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
-               udelay(rcu_random(&rand) & 0x3ff);
-               if (cur_ops->cb_barrier != NULL &&
-                   rcu_random(&rand) % (nfakewriters * 8) == 0) {
-                       cur_ops->cb_barrier();
-               } else if (gp_normal == gp_exp) {
-                       if (rcu_random(&rand) & 0x80)
-                               cur_ops->sync();
-                       else
-                               cur_ops->exp_sync();
-               } else if (gp_normal) {
-                       cur_ops->sync();
-               } else {
-                       cur_ops->exp_sync();
-               }
-               rcu_stutter_wait("rcu_torture_fakewriter");
-       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
-
-       VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_fakewriter");
-       while (!kthread_should_stop())
-               schedule_timeout_uninterruptible(1);
-       return 0;
-}
-
-void rcutorture_trace_dump(void)
-{
-       static atomic_t beenhere = ATOMIC_INIT(0);
-
-       if (atomic_read(&beenhere))
-               return;
-       if (atomic_xchg(&beenhere, 1) != 0)
-               return;
-       ftrace_dump(DUMP_ALL);
-}
-
-/*
- * RCU torture reader from timer handler.  Dereferences rcu_torture_current,
- * incrementing the corresponding element of the pipeline array.  The
- * counter in the element should never be greater than 1, otherwise, the
- * RCU implementation is broken.
- */
-static void rcu_torture_timer(unsigned long unused)
-{
-       int idx;
-       int completed;
-       int completed_end;
-       static DEFINE_RCU_RANDOM(rand);
-       static DEFINE_SPINLOCK(rand_lock);
-       struct rcu_torture *p;
-       int pipe_count;
-       unsigned long long ts;
-
-       idx = cur_ops->readlock();
-       completed = cur_ops->completed();
-       ts = rcu_trace_clock_local();
-       p = rcu_dereference_check(rcu_torture_current,
-                                 rcu_read_lock_bh_held() ||
-                                 rcu_read_lock_sched_held() ||
-                                 srcu_read_lock_held(&srcu_ctl));
-       if (p == NULL) {
-               /* Leave because rcu_torture_writer is not yet underway */
-               cur_ops->readunlock(idx);
-               return;
-       }
-       if (p->rtort_mbtest == 0)
-               atomic_inc(&n_rcu_torture_mberror);
-       spin_lock(&rand_lock);
-       cur_ops->read_delay(&rand);
-       n_rcu_torture_timers++;
-       spin_unlock(&rand_lock);
-       preempt_disable();
-       pipe_count = p->rtort_pipe_count;
-       if (pipe_count > RCU_TORTURE_PIPE_LEN) {
-               /* Should not happen, but... */
-               pipe_count = RCU_TORTURE_PIPE_LEN;
-       }
-       completed_end = cur_ops->completed();
-       if (pipe_count > 1) {
-               do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, ts,
-                                         completed, completed_end);
-               rcutorture_trace_dump();
-       }
-       __this_cpu_inc(rcu_torture_count[pipe_count]);
-       completed = completed_end - completed;
-       if (completed > RCU_TORTURE_PIPE_LEN) {
-               /* Should not happen, but... */
-               completed = RCU_TORTURE_PIPE_LEN;
-       }
-       __this_cpu_inc(rcu_torture_batch[completed]);
-       preempt_enable();
-       cur_ops->readunlock(idx);
-}
-
-/*
- * RCU torture reader kthread.  Repeatedly dereferences rcu_torture_current,
- * incrementing the corresponding element of the pipeline array.  The
- * counter in the element should never be greater than 1, otherwise, the
- * RCU implementation is broken.
- */
-static int
-rcu_torture_reader(void *arg)
-{
-       int completed;
-       int completed_end;
-       int idx;
-       DEFINE_RCU_RANDOM(rand);
-       struct rcu_torture *p;
-       int pipe_count;
-       struct timer_list t;
-       unsigned long long ts;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
-       set_user_nice(current, 19);
-       if (irqreader && cur_ops->irq_capable)
-               setup_timer_on_stack(&t, rcu_torture_timer, 0);
-
-       do {
-               if (irqreader && cur_ops->irq_capable) {
-                       if (!timer_pending(&t))
-                               mod_timer(&t, jiffies + 1);
-               }
-               idx = cur_ops->readlock();
-               completed = cur_ops->completed();
-               ts = rcu_trace_clock_local();
-               p = rcu_dereference_check(rcu_torture_current,
-                                         rcu_read_lock_bh_held() ||
-                                         rcu_read_lock_sched_held() ||
-                                         srcu_read_lock_held(&srcu_ctl));
-               if (p == NULL) {
-                       /* Wait for rcu_torture_writer to get underway */
-                       cur_ops->readunlock(idx);
-                       schedule_timeout_interruptible(HZ);
-                       continue;
-               }
-               if (p->rtort_mbtest == 0)
-                       atomic_inc(&n_rcu_torture_mberror);
-               cur_ops->read_delay(&rand);
-               preempt_disable();
-               pipe_count = p->rtort_pipe_count;
-               if (pipe_count > RCU_TORTURE_PIPE_LEN) {
-                       /* Should not happen, but... */
-                       pipe_count = RCU_TORTURE_PIPE_LEN;
-               }
-               completed_end = cur_ops->completed();
-               if (pipe_count > 1) {
-                       do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu,
-                                                 ts, completed, completed_end);
-                       rcutorture_trace_dump();
-               }
-               __this_cpu_inc(rcu_torture_count[pipe_count]);
-               completed = completed_end - completed;
-               if (completed > RCU_TORTURE_PIPE_LEN) {
-                       /* Should not happen, but... */
-                       completed = RCU_TORTURE_PIPE_LEN;
-               }
-               __this_cpu_inc(rcu_torture_batch[completed]);
-               preempt_enable();
-               cur_ops->readunlock(idx);
-               schedule();
-               rcu_stutter_wait("rcu_torture_reader");
-       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
-       VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_reader");
-       if (irqreader && cur_ops->irq_capable)
-               del_timer_sync(&t);
-       while (!kthread_should_stop())
-               schedule_timeout_uninterruptible(1);
-       return 0;
-}
-
-/*
- * Create an RCU-torture statistics message in the specified buffer.
- */
-static int
-rcu_torture_printk(char *page)
-{
-       int cnt = 0;
-       int cpu;
-       int i;
-       long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
-       long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
-
-       for_each_possible_cpu(cpu) {
-               for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
-                       pipesummary[i] += per_cpu(rcu_torture_count, cpu)[i];
-                       batchsummary[i] += per_cpu(rcu_torture_batch, cpu)[i];
-               }
-       }
-       for (i = RCU_TORTURE_PIPE_LEN - 1; i >= 0; i--) {
-               if (pipesummary[i] != 0)
-                       break;
-       }
-       cnt += sprintf(&page[cnt], "%s%s ", torture_type, TORTURE_FLAG);
-       cnt += sprintf(&page[cnt],
-                      "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d ",
-                      rcu_torture_current,
-                      rcu_torture_current_version,
-                      list_empty(&rcu_torture_freelist),
-                      atomic_read(&n_rcu_torture_alloc),
-                      atomic_read(&n_rcu_torture_alloc_fail),
-                      atomic_read(&n_rcu_torture_free));
-       cnt += sprintf(&page[cnt], "rtmbe: %d rtbke: %ld rtbre: %ld ",
-                      atomic_read(&n_rcu_torture_mberror),
-                      n_rcu_torture_boost_ktrerror,
-                      n_rcu_torture_boost_rterror);
-       cnt += sprintf(&page[cnt], "rtbf: %ld rtb: %ld nt: %ld ",
-                      n_rcu_torture_boost_failure,
-                      n_rcu_torture_boosts,
-                      n_rcu_torture_timers);
-       cnt += sprintf(&page[cnt],
-                      "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ",
-                      n_online_successes, n_online_attempts,
-                      n_offline_successes, n_offline_attempts,
-                      min_online, max_online,
-                      min_offline, max_offline,
-                      sum_online, sum_offline, HZ);
-       cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld",
-                      n_barrier_successes,
-                      n_barrier_attempts,
-                      n_rcu_torture_barrier_error);
-       cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG);
-       if (atomic_read(&n_rcu_torture_mberror) != 0 ||
-           n_rcu_torture_barrier_error != 0 ||
-           n_rcu_torture_boost_ktrerror != 0 ||
-           n_rcu_torture_boost_rterror != 0 ||
-           n_rcu_torture_boost_failure != 0 ||
-           i > 1) {
-               cnt += sprintf(&page[cnt], "!!! ");
-               atomic_inc(&n_rcu_torture_error);
-               WARN_ON_ONCE(1);
-       }
-       cnt += sprintf(&page[cnt], "Reader Pipe: ");
-       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
-               cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
-       cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG);
-       cnt += sprintf(&page[cnt], "Reader Batch: ");
-       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
-               cnt += sprintf(&page[cnt], " %ld", batchsummary[i]);
-       cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG);
-       cnt += sprintf(&page[cnt], "Free-Block Circulation: ");
-       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
-               cnt += sprintf(&page[cnt], " %d",
-                              atomic_read(&rcu_torture_wcount[i]));
-       }
-       cnt += sprintf(&page[cnt], "\n");
-       if (cur_ops->stats)
-               cnt += cur_ops->stats(&page[cnt]);
-       return cnt;
-}
-
-/*
- * Print torture statistics.  Caller must ensure that there is only
- * one call to this function at a given time!!!  This is normally
- * accomplished by relying on the module system to only have one copy
- * of the module loaded, and then by giving the rcu_torture_stats
- * kthread full control (or the init/cleanup functions when rcu_torture_stats
- * thread is not running).
- */
-static void
-rcu_torture_stats_print(void)
-{
-       int cnt;
-
-       cnt = rcu_torture_printk(printk_buf);
-       pr_alert("%s", printk_buf);
-}
-
-/*
- * Periodically prints torture statistics, if periodic statistics printing
- * was specified via the stat_interval module parameter.
- *
- * No need to worry about fullstop here, since this one doesn't reference
- * volatile state or register callbacks.
- */
-static int
-rcu_torture_stats(void *arg)
-{
-       VERBOSE_PRINTK_STRING("rcu_torture_stats task started");
-       do {
-               schedule_timeout_interruptible(stat_interval * HZ);
-               rcu_torture_stats_print();
-               rcutorture_shutdown_absorb("rcu_torture_stats");
-       } while (!kthread_should_stop());
-       VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
-       return 0;
-}
-
-static int rcu_idle_cpu;       /* Force all torture tasks off this CPU */
-
-/* Shuffle tasks such that we allow @rcu_idle_cpu to become idle. A special case
- * is when @rcu_idle_cpu = -1, when we allow the tasks to run on all CPUs.
- */
-static void rcu_torture_shuffle_tasks(void)
-{
-       int i;
-
-       cpumask_setall(shuffle_tmp_mask);
-       get_online_cpus();
-
-       /* No point in shuffling if there is only one online CPU (ex: UP) */
-       if (num_online_cpus() == 1) {
-               put_online_cpus();
-               return;
-       }
-
-       if (rcu_idle_cpu != -1)
-               cpumask_clear_cpu(rcu_idle_cpu, shuffle_tmp_mask);
-
-       set_cpus_allowed_ptr(current, shuffle_tmp_mask);
-
-       if (reader_tasks) {
-               for (i = 0; i < nrealreaders; i++)
-                       if (reader_tasks[i])
-                               set_cpus_allowed_ptr(reader_tasks[i],
-                                                    shuffle_tmp_mask);
-       }
-       if (fakewriter_tasks) {
-               for (i = 0; i < nfakewriters; i++)
-                       if (fakewriter_tasks[i])
-                               set_cpus_allowed_ptr(fakewriter_tasks[i],
-                                                    shuffle_tmp_mask);
-       }
-       if (writer_task)
-               set_cpus_allowed_ptr(writer_task, shuffle_tmp_mask);
-       if (stats_task)
-               set_cpus_allowed_ptr(stats_task, shuffle_tmp_mask);
-       if (stutter_task)
-               set_cpus_allowed_ptr(stutter_task, shuffle_tmp_mask);
-       if (fqs_task)
-               set_cpus_allowed_ptr(fqs_task, shuffle_tmp_mask);
-       if (shutdown_task)
-               set_cpus_allowed_ptr(shutdown_task, shuffle_tmp_mask);
-#ifdef CONFIG_HOTPLUG_CPU
-       if (onoff_task)
-               set_cpus_allowed_ptr(onoff_task, shuffle_tmp_mask);
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-       if (stall_task)
-               set_cpus_allowed_ptr(stall_task, shuffle_tmp_mask);
-       if (barrier_cbs_tasks)
-               for (i = 0; i < n_barrier_cbs; i++)
-                       if (barrier_cbs_tasks[i])
-                               set_cpus_allowed_ptr(barrier_cbs_tasks[i],
-                                                    shuffle_tmp_mask);
-       if (barrier_task)
-               set_cpus_allowed_ptr(barrier_task, shuffle_tmp_mask);
-
-       if (rcu_idle_cpu == -1)
-               rcu_idle_cpu = num_online_cpus() - 1;
-       else
-               rcu_idle_cpu--;
-
-       put_online_cpus();
-}
-
-/* Shuffle tasks across CPUs, with the intent of allowing each CPU in the
- * system to become idle at a time and cut off its timer ticks. This is meant
- * to test the support for such tickless idle CPU in RCU.
- */
-static int
-rcu_torture_shuffle(void *arg)
-{
-       VERBOSE_PRINTK_STRING("rcu_torture_shuffle task started");
-       do {
-               schedule_timeout_interruptible(shuffle_interval * HZ);
-               rcu_torture_shuffle_tasks();
-               rcutorture_shutdown_absorb("rcu_torture_shuffle");
-       } while (!kthread_should_stop());
-       VERBOSE_PRINTK_STRING("rcu_torture_shuffle task stopping");
-       return 0;
-}
-
-/* Cause the rcutorture test to "stutter", starting and stopping all
- * threads periodically.
- */
-static int
-rcu_torture_stutter(void *arg)
-{
-       VERBOSE_PRINTK_STRING("rcu_torture_stutter task started");
-       do {
-               schedule_timeout_interruptible(stutter * HZ);
-               stutter_pause_test = 1;
-               if (!kthread_should_stop())
-                       schedule_timeout_interruptible(stutter * HZ);
-               stutter_pause_test = 0;
-               rcutorture_shutdown_absorb("rcu_torture_stutter");
-       } while (!kthread_should_stop());
-       VERBOSE_PRINTK_STRING("rcu_torture_stutter task stopping");
-       return 0;
-}
-
-static inline void
-rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
-{
-       pr_alert("%s" TORTURE_FLAG
-                "--- %s: nreaders=%d nfakewriters=%d "
-                "stat_interval=%d verbose=%d test_no_idle_hz=%d "
-                "shuffle_interval=%d stutter=%d irqreader=%d "
-                "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "
-                "test_boost=%d/%d test_boost_interval=%d "
-                "test_boost_duration=%d shutdown_secs=%d "
-                "stall_cpu=%d stall_cpu_holdoff=%d "
-                "n_barrier_cbs=%d "
-                "onoff_interval=%d onoff_holdoff=%d\n",
-                torture_type, tag, nrealreaders, nfakewriters,
-                stat_interval, verbose, test_no_idle_hz, shuffle_interval,
-                stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
-                test_boost, cur_ops->can_boost,
-                test_boost_interval, test_boost_duration, shutdown_secs,
-                stall_cpu, stall_cpu_holdoff,
-                n_barrier_cbs,
-                onoff_interval, onoff_holdoff);
-}
-
-static struct notifier_block rcutorture_shutdown_nb = {
-       .notifier_call = rcutorture_shutdown_notify,
-};
-
-static void rcutorture_booster_cleanup(int cpu)
-{
-       struct task_struct *t;
-
-       if (boost_tasks[cpu] == NULL)
-               return;
-       mutex_lock(&boost_mutex);
-       VERBOSE_PRINTK_STRING("Stopping rcu_torture_boost task");
-       t = boost_tasks[cpu];
-       boost_tasks[cpu] = NULL;
-       mutex_unlock(&boost_mutex);
-
-       /* This must be outside of the mutex, otherwise deadlock! */
-       kthread_stop(t);
-       boost_tasks[cpu] = NULL;
-}
-
-static int rcutorture_booster_init(int cpu)
-{
-       int retval;
-
-       if (boost_tasks[cpu] != NULL)
-               return 0;  /* Already created, nothing more to do. */
-
-       /* Don't allow time recalculation while creating a new task. */
-       mutex_lock(&boost_mutex);
-       VERBOSE_PRINTK_STRING("Creating rcu_torture_boost task");
-       boost_tasks[cpu] = kthread_create_on_node(rcu_torture_boost, NULL,
-                                                 cpu_to_node(cpu),
-                                                 "rcu_torture_boost");
-       if (IS_ERR(boost_tasks[cpu])) {
-               retval = PTR_ERR(boost_tasks[cpu]);
-               VERBOSE_PRINTK_STRING("rcu_torture_boost task create failed");
-               n_rcu_torture_boost_ktrerror++;
-               boost_tasks[cpu] = NULL;
-               mutex_unlock(&boost_mutex);
-               return retval;
-       }
-       kthread_bind(boost_tasks[cpu], cpu);
-       wake_up_process(boost_tasks[cpu]);
-       mutex_unlock(&boost_mutex);
-       return 0;
-}
-
-/*
- * Cause the rcutorture test to shutdown the system after the test has
- * run for the time specified by the shutdown_secs module parameter.
- */
-static int
-rcu_torture_shutdown(void *arg)
-{
-       long delta;
-       unsigned long jiffies_snap;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_shutdown task started");
-       jiffies_snap = ACCESS_ONCE(jiffies);
-       while (ULONG_CMP_LT(jiffies_snap, shutdown_time) &&
-              !kthread_should_stop()) {
-               delta = shutdown_time - jiffies_snap;
-               if (verbose)
-                       pr_alert("%s" TORTURE_FLAG
-                                "rcu_torture_shutdown task: %lu jiffies remaining\n",
-                                torture_type, delta);
-               schedule_timeout_interruptible(delta);
-               jiffies_snap = ACCESS_ONCE(jiffies);
-       }
-       if (kthread_should_stop()) {
-               VERBOSE_PRINTK_STRING("rcu_torture_shutdown task stopping");
-               return 0;
-       }
-
-       /* OK, shut down the system. */
-
-       VERBOSE_PRINTK_STRING("rcu_torture_shutdown task shutting down system");
-       shutdown_task = NULL;   /* Avoid self-kill deadlock. */
-       rcu_torture_cleanup();  /* Get the success/failure message. */
-       kernel_power_off();     /* Shut down the system. */
-       return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/*
- * Execute random CPU-hotplug operations at the interval specified
- * by the onoff_interval.
- */
-static int
-rcu_torture_onoff(void *arg)
-{
-       int cpu;
-       unsigned long delta;
-       int maxcpu = -1;
-       DEFINE_RCU_RANDOM(rand);
-       int ret;
-       unsigned long starttime;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_onoff task started");
-       for_each_online_cpu(cpu)
-               maxcpu = cpu;
-       WARN_ON(maxcpu < 0);
-       if (onoff_holdoff > 0) {
-               VERBOSE_PRINTK_STRING("rcu_torture_onoff begin holdoff");
-               schedule_timeout_interruptible(onoff_holdoff * HZ);
-               VERBOSE_PRINTK_STRING("rcu_torture_onoff end holdoff");
-       }
-       while (!kthread_should_stop()) {
-               cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1);
-               if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
-                       if (verbose)
-                               pr_alert("%s" TORTURE_FLAG
-                                        "rcu_torture_onoff task: offlining %d\n",
-                                        torture_type, cpu);
-                       starttime = jiffies;
-                       n_offline_attempts++;
-                       ret = cpu_down(cpu);
-                       if (ret) {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "rcu_torture_onoff task: offline %d failed: errno %d\n",
-                                                torture_type, cpu, ret);
-                       } else {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "rcu_torture_onoff task: offlined %d\n",
-                                                torture_type, cpu);
-                               n_offline_successes++;
-                               delta = jiffies - starttime;
-                               sum_offline += delta;
-                               if (min_offline < 0) {
-                                       min_offline = delta;
-                                       max_offline = delta;
-                               }
-                               if (min_offline > delta)
-                                       min_offline = delta;
-                               if (max_offline < delta)
-                                       max_offline = delta;
-                       }
-               } else if (cpu_is_hotpluggable(cpu)) {
-                       if (verbose)
-                               pr_alert("%s" TORTURE_FLAG
-                                        "rcu_torture_onoff task: onlining %d\n",
-                                        torture_type, cpu);
-                       starttime = jiffies;
-                       n_online_attempts++;
-                       ret = cpu_up(cpu);
-                       if (ret) {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "rcu_torture_onoff task: online %d failed: errno %d\n",
-                                                torture_type, cpu, ret);
-                       } else {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "rcu_torture_onoff task: onlined %d\n",
-                                                torture_type, cpu);
-                               n_online_successes++;
-                               delta = jiffies - starttime;
-                               sum_online += delta;
-                               if (min_online < 0) {
-                                       min_online = delta;
-                                       max_online = delta;
-                               }
-                               if (min_online > delta)
-                                       min_online = delta;
-                               if (max_online < delta)
-                                       max_online = delta;
-                       }
-               }
-               schedule_timeout_interruptible(onoff_interval * HZ);
-       }
-       VERBOSE_PRINTK_STRING("rcu_torture_onoff task stopping");
-       return 0;
-}
-
-static int
-rcu_torture_onoff_init(void)
-{
-       int ret;
-
-       if (onoff_interval <= 0)
-               return 0;
-       onoff_task = kthread_run(rcu_torture_onoff, NULL, "rcu_torture_onoff");
-       if (IS_ERR(onoff_task)) {
-               ret = PTR_ERR(onoff_task);
-               onoff_task = NULL;
-               return ret;
-       }
-       return 0;
-}
-
-static void rcu_torture_onoff_cleanup(void)
-{
-       if (onoff_task == NULL)
-               return;
-       VERBOSE_PRINTK_STRING("Stopping rcu_torture_onoff task");
-       kthread_stop(onoff_task);
-       onoff_task = NULL;
-}
-
-#else /* #ifdef CONFIG_HOTPLUG_CPU */
-
-static int
-rcu_torture_onoff_init(void)
-{
-       return 0;
-}
-
-static void rcu_torture_onoff_cleanup(void)
-{
-}
-
-#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
-
-/*
- * CPU-stall kthread.  It waits as specified by stall_cpu_holdoff, then
- * induces a CPU stall for the time specified by stall_cpu.
- */
-static int rcu_torture_stall(void *args)
-{
-       unsigned long stop_at;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_stall task started");
-       if (stall_cpu_holdoff > 0) {
-               VERBOSE_PRINTK_STRING("rcu_torture_stall begin holdoff");
-               schedule_timeout_interruptible(stall_cpu_holdoff * HZ);
-               VERBOSE_PRINTK_STRING("rcu_torture_stall end holdoff");
-       }
-       if (!kthread_should_stop()) {
-               stop_at = get_seconds() + stall_cpu;
-               /* RCU CPU stall is expected behavior in following code. */
-               pr_alert("rcu_torture_stall start.\n");
-               rcu_read_lock();
-               preempt_disable();
-               while (ULONG_CMP_LT(get_seconds(), stop_at))
-                       continue;  /* Induce RCU CPU stall warning. */
-               preempt_enable();
-               rcu_read_unlock();
-               pr_alert("rcu_torture_stall end.\n");
-       }
-       rcutorture_shutdown_absorb("rcu_torture_stall");
-       while (!kthread_should_stop())
-               schedule_timeout_interruptible(10 * HZ);
-       return 0;
-}
-
-/* Spawn CPU-stall kthread, if stall_cpu specified. */
-static int __init rcu_torture_stall_init(void)
-{
-       int ret;
-
-       if (stall_cpu <= 0)
-               return 0;
-       stall_task = kthread_run(rcu_torture_stall, NULL, "rcu_torture_stall");
-       if (IS_ERR(stall_task)) {
-               ret = PTR_ERR(stall_task);
-               stall_task = NULL;
-               return ret;
-       }
-       return 0;
-}
-
-/* Clean up after the CPU-stall kthread, if one was spawned. */
-static void rcu_torture_stall_cleanup(void)
-{
-       if (stall_task == NULL)
-               return;
-       VERBOSE_PRINTK_STRING("Stopping rcu_torture_stall_task.");
-       kthread_stop(stall_task);
-       stall_task = NULL;
-}
-
-/* Callback function for RCU barrier testing. */
-void rcu_torture_barrier_cbf(struct rcu_head *rcu)
-{
-       atomic_inc(&barrier_cbs_invoked);
-}
-
-/* kthread function to register callbacks used to test RCU barriers. */
-static int rcu_torture_barrier_cbs(void *arg)
-{
-       long myid = (long)arg;
-       bool lastphase = 0;
-       struct rcu_head rcu;
-
-       init_rcu_head_on_stack(&rcu);
-       VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task started");
-       set_user_nice(current, 19);
-       do {
-               wait_event(barrier_cbs_wq[myid],
-                          barrier_phase != lastphase ||
-                          kthread_should_stop() ||
-                          fullstop != FULLSTOP_DONTSTOP);
-               lastphase = barrier_phase;
-               smp_mb(); /* ensure barrier_phase load before ->call(). */
-               if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP)
-                       break;
-               cur_ops->call(&rcu, rcu_torture_barrier_cbf);
-               if (atomic_dec_and_test(&barrier_cbs_count))
-                       wake_up(&barrier_wq);
-       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
-       VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_barrier_cbs");
-       while (!kthread_should_stop())
-               schedule_timeout_interruptible(1);
-       cur_ops->cb_barrier();
-       destroy_rcu_head_on_stack(&rcu);
-       return 0;
-}
-
-/* kthread function to drive and coordinate RCU barrier testing. */
-static int rcu_torture_barrier(void *arg)
-{
-       int i;
-
-       VERBOSE_PRINTK_STRING("rcu_torture_barrier task starting");
-       do {
-               atomic_set(&barrier_cbs_invoked, 0);
-               atomic_set(&barrier_cbs_count, n_barrier_cbs);
-               smp_mb(); /* Ensure barrier_phase after prior assignments. */
-               barrier_phase = !barrier_phase;
-               for (i = 0; i < n_barrier_cbs; i++)
-                       wake_up(&barrier_cbs_wq[i]);
-               wait_event(barrier_wq,
-                          atomic_read(&barrier_cbs_count) == 0 ||
-                          kthread_should_stop() ||
-                          fullstop != FULLSTOP_DONTSTOP);
-               if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP)
-                       break;
-               n_barrier_attempts++;
-               cur_ops->cb_barrier();
-               if (atomic_read(&barrier_cbs_invoked) != n_barrier_cbs) {
-                       n_rcu_torture_barrier_error++;
-                       WARN_ON_ONCE(1);
-               }
-               n_barrier_successes++;
-               schedule_timeout_interruptible(HZ / 10);
-       } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
-       VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_barrier");
-       while (!kthread_should_stop())
-               schedule_timeout_interruptible(1);
-       return 0;
-}
-
-/* Initialize RCU barrier testing. */
-static int rcu_torture_barrier_init(void)
-{
-       int i;
-       int ret;
-
-       if (n_barrier_cbs == 0)
-               return 0;
-       if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) {
-               pr_alert("%s" TORTURE_FLAG
-                        " Call or barrier ops missing for %s,\n",
-                        torture_type, cur_ops->name);
-               pr_alert("%s" TORTURE_FLAG
-                        " RCU barrier testing omitted from run.\n",
-                        torture_type);
-               return 0;
-       }
-       atomic_set(&barrier_cbs_count, 0);
-       atomic_set(&barrier_cbs_invoked, 0);
-       barrier_cbs_tasks =
-               kzalloc(n_barrier_cbs * sizeof(barrier_cbs_tasks[0]),
-                       GFP_KERNEL);
-       barrier_cbs_wq =
-               kzalloc(n_barrier_cbs * sizeof(barrier_cbs_wq[0]),
-                       GFP_KERNEL);
-       if (barrier_cbs_tasks == NULL || !barrier_cbs_wq)
-               return -ENOMEM;
-       for (i = 0; i < n_barrier_cbs; i++) {
-               init_waitqueue_head(&barrier_cbs_wq[i]);
-               barrier_cbs_tasks[i] = kthread_run(rcu_torture_barrier_cbs,
-                                                  (void *)(long)i,
-                                                  "rcu_torture_barrier_cbs");
-               if (IS_ERR(barrier_cbs_tasks[i])) {
-                       ret = PTR_ERR(barrier_cbs_tasks[i]);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier_cbs");
-                       barrier_cbs_tasks[i] = NULL;
-                       return ret;
-               }
-       }
-       barrier_task = kthread_run(rcu_torture_barrier, NULL,
-                                  "rcu_torture_barrier");
-       if (IS_ERR(barrier_task)) {
-               ret = PTR_ERR(barrier_task);
-               VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier");
-               barrier_task = NULL;
-       }
-       return 0;
-}
-
-/* Clean up after RCU barrier testing. */
-static void rcu_torture_barrier_cleanup(void)
-{
-       int i;
-
-       if (barrier_task != NULL) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier task");
-               kthread_stop(barrier_task);
-               barrier_task = NULL;
-       }
-       if (barrier_cbs_tasks != NULL) {
-               for (i = 0; i < n_barrier_cbs; i++) {
-                       if (barrier_cbs_tasks[i] != NULL) {
-                               VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier_cbs task");
-                               kthread_stop(barrier_cbs_tasks[i]);
-                               barrier_cbs_tasks[i] = NULL;
-                       }
-               }
-               kfree(barrier_cbs_tasks);
-               barrier_cbs_tasks = NULL;
-       }
-       if (barrier_cbs_wq != NULL) {
-               kfree(barrier_cbs_wq);
-               barrier_cbs_wq = NULL;
-       }
-}
-
-static int rcutorture_cpu_notify(struct notifier_block *self,
-                                unsigned long action, void *hcpu)
-{
-       long cpu = (long)hcpu;
-
-       switch (action) {
-       case CPU_ONLINE:
-       case CPU_DOWN_FAILED:
-               (void)rcutorture_booster_init(cpu);
-               break;
-       case CPU_DOWN_PREPARE:
-               rcutorture_booster_cleanup(cpu);
-               break;
-       default:
-               break;
-       }
-       return NOTIFY_OK;
-}
-
-static struct notifier_block rcutorture_cpu_nb = {
-       .notifier_call = rcutorture_cpu_notify,
-};
-
-static void
-rcu_torture_cleanup(void)
-{
-       int i;
-
-       mutex_lock(&fullstop_mutex);
-       rcutorture_record_test_transition();
-       if (fullstop == FULLSTOP_SHUTDOWN) {
-               pr_warn(/* but going down anyway, so... */
-                      "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
-               mutex_unlock(&fullstop_mutex);
-               schedule_timeout_uninterruptible(10);
-               if (cur_ops->cb_barrier != NULL)
-                       cur_ops->cb_barrier();
-               return;
-       }
-       fullstop = FULLSTOP_RMMOD;
-       mutex_unlock(&fullstop_mutex);
-       unregister_reboot_notifier(&rcutorture_shutdown_nb);
-       rcu_torture_barrier_cleanup();
-       rcu_torture_stall_cleanup();
-       if (stutter_task) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task");
-               kthread_stop(stutter_task);
-       }
-       stutter_task = NULL;
-       if (shuffler_task) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
-               kthread_stop(shuffler_task);
-               free_cpumask_var(shuffle_tmp_mask);
-       }
-       shuffler_task = NULL;
-
-       if (writer_task) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
-               kthread_stop(writer_task);
-       }
-       writer_task = NULL;
-
-       if (reader_tasks) {
-               for (i = 0; i < nrealreaders; i++) {
-                       if (reader_tasks[i]) {
-                               VERBOSE_PRINTK_STRING(
-                                       "Stopping rcu_torture_reader task");
-                               kthread_stop(reader_tasks[i]);
-                       }
-                       reader_tasks[i] = NULL;
-               }
-               kfree(reader_tasks);
-               reader_tasks = NULL;
-       }
-       rcu_torture_current = NULL;
-
-       if (fakewriter_tasks) {
-               for (i = 0; i < nfakewriters; i++) {
-                       if (fakewriter_tasks[i]) {
-                               VERBOSE_PRINTK_STRING(
-                                       "Stopping rcu_torture_fakewriter task");
-                               kthread_stop(fakewriter_tasks[i]);
-                       }
-                       fakewriter_tasks[i] = NULL;
-               }
-               kfree(fakewriter_tasks);
-               fakewriter_tasks = NULL;
-       }
-
-       if (stats_task) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
-               kthread_stop(stats_task);
-       }
-       stats_task = NULL;
-
-       if (fqs_task) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_fqs task");
-               kthread_stop(fqs_task);
-       }
-       fqs_task = NULL;
-       if ((test_boost == 1 && cur_ops->can_boost) ||
-           test_boost == 2) {
-               unregister_cpu_notifier(&rcutorture_cpu_nb);
-               for_each_possible_cpu(i)
-                       rcutorture_booster_cleanup(i);
-       }
-       if (shutdown_task != NULL) {
-               VERBOSE_PRINTK_STRING("Stopping rcu_torture_shutdown task");
-               kthread_stop(shutdown_task);
-       }
-       shutdown_task = NULL;
-       rcu_torture_onoff_cleanup();
-
-       /* Wait for all RCU callbacks to fire.  */
-
-       if (cur_ops->cb_barrier != NULL)
-               cur_ops->cb_barrier();
-
-       rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
-
-       if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error)
-               rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE");
-       else if (n_online_successes != n_online_attempts ||
-                n_offline_successes != n_offline_attempts)
-               rcu_torture_print_module_parms(cur_ops,
-                                              "End of test: RCU_HOTPLUG");
-       else
-               rcu_torture_print_module_parms(cur_ops, "End of test: SUCCESS");
-}
-
-#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
-static void rcu_torture_leak_cb(struct rcu_head *rhp)
-{
-}
-
-static void rcu_torture_err_cb(struct rcu_head *rhp)
-{
-       /*
-        * This -might- happen due to race conditions, but is unlikely.
-        * The scenario that leads to this happening is that the
-        * first of the pair of duplicate callbacks is queued,
-        * someone else starts a grace period that includes that
-        * callback, then the second of the pair must wait for the
-        * next grace period.  Unlikely, but can happen.  If it
-        * does happen, the debug-objects subsystem won't have splatted.
-        */
-       pr_alert("rcutorture: duplicated callback was invoked.\n");
-}
-#endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-
-/*
- * Verify that double-free causes debug-objects to complain, but only
- * if CONFIG_DEBUG_OBJECTS_RCU_HEAD=y.  Otherwise, say that the test
- * cannot be carried out.
- */
-static void rcu_test_debug_objects(void)
-{
-#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
-       struct rcu_head rh1;
-       struct rcu_head rh2;
-
-       init_rcu_head_on_stack(&rh1);
-       init_rcu_head_on_stack(&rh2);
-       pr_alert("rcutorture: WARN: Duplicate call_rcu() test starting.\n");
-
-       /* Try to queue the rh2 pair of callbacks for the same grace period. */
-       preempt_disable(); /* Prevent preemption from interrupting test. */
-       rcu_read_lock(); /* Make it impossible to finish a grace period. */
-       call_rcu(&rh1, rcu_torture_leak_cb); /* Start grace period. */
-       local_irq_disable(); /* Make it harder to start a new grace period. */
-       call_rcu(&rh2, rcu_torture_leak_cb);
-       call_rcu(&rh2, rcu_torture_err_cb); /* Duplicate callback. */
-       local_irq_enable();
-       rcu_read_unlock();
-       preempt_enable();
-
-       /* Wait for them all to get done so we can safely return. */
-       rcu_barrier();
-       pr_alert("rcutorture: WARN: Duplicate call_rcu() test complete.\n");
-       destroy_rcu_head_on_stack(&rh1);
-       destroy_rcu_head_on_stack(&rh2);
-#else /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-       pr_alert("rcutorture: !CONFIG_DEBUG_OBJECTS_RCU_HEAD, not testing duplicate call_rcu()\n");
-#endif /* #else #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-}
-
-static int __init
-rcu_torture_init(void)
-{
-       int i;
-       int cpu;
-       int firsterr = 0;
-       int retval;
-       static struct rcu_torture_ops *torture_ops[] = {
-               &rcu_ops, &rcu_bh_ops, &srcu_ops, &sched_ops,
-       };
-
-       mutex_lock(&fullstop_mutex);
-
-       /* Process args and tell the world that the torturer is on the job. */
-       for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
-               cur_ops = torture_ops[i];
-               if (strcmp(torture_type, cur_ops->name) == 0)
-                       break;
-       }
-       if (i == ARRAY_SIZE(torture_ops)) {
-               pr_alert("rcu-torture: invalid torture type: \"%s\"\n",
-                        torture_type);
-               pr_alert("rcu-torture types:");
-               for (i = 0; i < ARRAY_SIZE(torture_ops); i++)
-                       pr_alert(" %s", torture_ops[i]->name);
-               pr_alert("\n");
-               mutex_unlock(&fullstop_mutex);
-               return -EINVAL;
-       }
-       if (cur_ops->fqs == NULL && fqs_duration != 0) {
-               pr_alert("rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n");
-               fqs_duration = 0;
-       }
-       if (cur_ops->init)
-               cur_ops->init(); /* no "goto unwind" prior to this point!!! */
-
-       if (nreaders >= 0)
-               nrealreaders = nreaders;
-       else
-               nrealreaders = 2 * num_online_cpus();
-       rcu_torture_print_module_parms(cur_ops, "Start of test");
-       fullstop = FULLSTOP_DONTSTOP;
-
-       /* Set up the freelist. */
-
-       INIT_LIST_HEAD(&rcu_torture_freelist);
-       for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++) {
-               rcu_tortures[i].rtort_mbtest = 0;
-               list_add_tail(&rcu_tortures[i].rtort_free,
-                             &rcu_torture_freelist);
-       }
-
-       /* Initialize the statistics so that each run gets its own numbers. */
-
-       rcu_torture_current = NULL;
-       rcu_torture_current_version = 0;
-       atomic_set(&n_rcu_torture_alloc, 0);
-       atomic_set(&n_rcu_torture_alloc_fail, 0);
-       atomic_set(&n_rcu_torture_free, 0);
-       atomic_set(&n_rcu_torture_mberror, 0);
-       atomic_set(&n_rcu_torture_error, 0);
-       n_rcu_torture_barrier_error = 0;
-       n_rcu_torture_boost_ktrerror = 0;
-       n_rcu_torture_boost_rterror = 0;
-       n_rcu_torture_boost_failure = 0;
-       n_rcu_torture_boosts = 0;
-       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
-               atomic_set(&rcu_torture_wcount[i], 0);
-       for_each_possible_cpu(cpu) {
-               for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
-                       per_cpu(rcu_torture_count, cpu)[i] = 0;
-                       per_cpu(rcu_torture_batch, cpu)[i] = 0;
-               }
-       }
-
-       /* Start up the kthreads. */
-
-       VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
-       writer_task = kthread_create(rcu_torture_writer, NULL,
-                                    "rcu_torture_writer");
-       if (IS_ERR(writer_task)) {
-               firsterr = PTR_ERR(writer_task);
-               VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
-               writer_task = NULL;
-               goto unwind;
-       }
-       wake_up_process(writer_task);
-       fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
-                                  GFP_KERNEL);
-       if (fakewriter_tasks == NULL) {
-               VERBOSE_PRINTK_ERRSTRING("out of memory");
-               firsterr = -ENOMEM;
-               goto unwind;
-       }
-       for (i = 0; i < nfakewriters; i++) {
-               VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task");
-               fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL,
-                                                 "rcu_torture_fakewriter");
-               if (IS_ERR(fakewriter_tasks[i])) {
-                       firsterr = PTR_ERR(fakewriter_tasks[i]);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter");
-                       fakewriter_tasks[i] = NULL;
-                       goto unwind;
-               }
-       }
-       reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]),
-                              GFP_KERNEL);
-       if (reader_tasks == NULL) {
-               VERBOSE_PRINTK_ERRSTRING("out of memory");
-               firsterr = -ENOMEM;
-               goto unwind;
-       }
-       for (i = 0; i < nrealreaders; i++) {
-               VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task");
-               reader_tasks[i] = kthread_run(rcu_torture_reader, NULL,
-                                             "rcu_torture_reader");
-               if (IS_ERR(reader_tasks[i])) {
-                       firsterr = PTR_ERR(reader_tasks[i]);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create reader");
-                       reader_tasks[i] = NULL;
-                       goto unwind;
-               }
-       }
-       if (stat_interval > 0) {
-               VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task");
-               stats_task = kthread_run(rcu_torture_stats, NULL,
-                                       "rcu_torture_stats");
-               if (IS_ERR(stats_task)) {
-                       firsterr = PTR_ERR(stats_task);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create stats");
-                       stats_task = NULL;
-                       goto unwind;
-               }
-       }
-       if (test_no_idle_hz) {
-               rcu_idle_cpu = num_online_cpus() - 1;
-
-               if (!alloc_cpumask_var(&shuffle_tmp_mask, GFP_KERNEL)) {
-                       firsterr = -ENOMEM;
-                       VERBOSE_PRINTK_ERRSTRING("Failed to alloc mask");
-                       goto unwind;
-               }
-
-               /* Create the shuffler thread */
-               shuffler_task = kthread_run(rcu_torture_shuffle, NULL,
-                                         "rcu_torture_shuffle");
-               if (IS_ERR(shuffler_task)) {
-                       free_cpumask_var(shuffle_tmp_mask);
-                       firsterr = PTR_ERR(shuffler_task);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create shuffler");
-                       shuffler_task = NULL;
-                       goto unwind;
-               }
-       }
-       if (stutter < 0)
-               stutter = 0;
-       if (stutter) {
-               /* Create the stutter thread */
-               stutter_task = kthread_run(rcu_torture_stutter, NULL,
-                                         "rcu_torture_stutter");
-               if (IS_ERR(stutter_task)) {
-                       firsterr = PTR_ERR(stutter_task);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create stutter");
-                       stutter_task = NULL;
-                       goto unwind;
-               }
-       }
-       if (fqs_duration < 0)
-               fqs_duration = 0;
-       if (fqs_duration) {
-               /* Create the stutter thread */
-               fqs_task = kthread_run(rcu_torture_fqs, NULL,
-                                      "rcu_torture_fqs");
-               if (IS_ERR(fqs_task)) {
-                       firsterr = PTR_ERR(fqs_task);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create fqs");
-                       fqs_task = NULL;
-                       goto unwind;
-               }
-       }
-       if (test_boost_interval < 1)
-               test_boost_interval = 1;
-       if (test_boost_duration < 2)
-               test_boost_duration = 2;
-       if ((test_boost == 1 && cur_ops->can_boost) ||
-           test_boost == 2) {
-
-               boost_starttime = jiffies + test_boost_interval * HZ;
-               register_cpu_notifier(&rcutorture_cpu_nb);
-               for_each_possible_cpu(i) {
-                       if (cpu_is_offline(i))
-                               continue;  /* Heuristic: CPU can go offline. */
-                       retval = rcutorture_booster_init(i);
-                       if (retval < 0) {
-                               firsterr = retval;
-                               goto unwind;
-                       }
-               }
-       }
-       if (shutdown_secs > 0) {
-               shutdown_time = jiffies + shutdown_secs * HZ;
-               shutdown_task = kthread_create(rcu_torture_shutdown, NULL,
-                                              "rcu_torture_shutdown");
-               if (IS_ERR(shutdown_task)) {
-                       firsterr = PTR_ERR(shutdown_task);
-                       VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown");
-                       shutdown_task = NULL;
-                       goto unwind;
-               }
-               wake_up_process(shutdown_task);
-       }
-       i = rcu_torture_onoff_init();
-       if (i != 0) {
-               firsterr = i;
-               goto unwind;
-       }
-       register_reboot_notifier(&rcutorture_shutdown_nb);
-       i = rcu_torture_stall_init();
-       if (i != 0) {
-               firsterr = i;
-               goto unwind;
-       }
-       retval = rcu_torture_barrier_init();
-       if (retval != 0) {
-               firsterr = retval;
-               goto unwind;
-       }
-       if (object_debug)
-               rcu_test_debug_objects();
-       rcutorture_record_test_transition();
-       mutex_unlock(&fullstop_mutex);
-       return 0;
-
-unwind:
-       mutex_unlock(&fullstop_mutex);
-       rcu_torture_cleanup();
-       return firsterr;
-}
-
-module_init(rcu_torture_init);
-module_exit(rcu_torture_cleanup);
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
deleted file mode 100644 (file)
index 1dc9f36..0000000
+++ /dev/null
@@ -1,3327 +0,0 @@
-/*
- * Read-Copy Update mechanism for mutual exclusion
- *
- * 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 IBM Corporation, 2008
- *
- * Authors: Dipankar Sarma <dipankar@in.ibm.com>
- *         Manfred Spraul <manfred@colorfullife.com>
- *         Paul E. McKenney <paulmck@linux.vnet.ibm.com> Hierarchical version
- *
- * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
- * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
- *
- * For detailed explanation of Read-Copy Update mechanism see -
- *     Documentation/RCU
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <linux/rcupdate.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/nmi.h>
-#include <linux/atomic.h>
-#include <linux/bitops.h>
-#include <linux/export.h>
-#include <linux/completion.h>
-#include <linux/moduleparam.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/cpu.h>
-#include <linux/mutex.h>
-#include <linux/time.h>
-#include <linux/kernel_stat.h>
-#include <linux/wait.h>
-#include <linux/kthread.h>
-#include <linux/prefetch.h>
-#include <linux/delay.h>
-#include <linux/stop_machine.h>
-#include <linux/random.h>
-#include <linux/ftrace_event.h>
-#include <linux/suspend.h>
-
-#include "rcutree.h"
-#include <trace/events/rcu.h>
-
-#include "rcu.h"
-
-/*
- * Strings used in tracepoints need to be exported via the
- * tracing system such that tools like perf and trace-cmd can
- * translate the string address pointers to actual text.
- */
-#define TPS(x) tracepoint_string(x)
-
-/* Data structures. */
-
-static struct lock_class_key rcu_node_class[RCU_NUM_LVLS];
-static struct lock_class_key rcu_fqs_class[RCU_NUM_LVLS];
-
-/*
- * In order to export the rcu_state name to the tracing tools, it
- * needs to be added in the __tracepoint_string section.
- * This requires defining a separate variable tp_<sname>_varname
- * that points to the string being used, and this will allow
- * the tracing userspace tools to be able to decipher the string
- * address to the matching string.
- */
-#define RCU_STATE_INITIALIZER(sname, sabbr, cr) \
-static char sname##_varname[] = #sname; \
-static const char *tp_##sname##_varname __used __tracepoint_string = sname##_varname; \
-struct rcu_state sname##_state = { \
-       .level = { &sname##_state.node[0] }, \
-       .call = cr, \
-       .fqs_state = RCU_GP_IDLE, \
-       .gpnum = 0UL - 300UL, \
-       .completed = 0UL - 300UL, \
-       .orphan_lock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.orphan_lock), \
-       .orphan_nxttail = &sname##_state.orphan_nxtlist, \
-       .orphan_donetail = &sname##_state.orphan_donelist, \
-       .barrier_mutex = __MUTEX_INITIALIZER(sname##_state.barrier_mutex), \
-       .onoff_mutex = __MUTEX_INITIALIZER(sname##_state.onoff_mutex), \
-       .name = sname##_varname, \
-       .abbr = sabbr, \
-}; \
-DEFINE_PER_CPU(struct rcu_data, sname##_data)
-
-RCU_STATE_INITIALIZER(rcu_sched, 's', call_rcu_sched);
-RCU_STATE_INITIALIZER(rcu_bh, 'b', call_rcu_bh);
-
-static struct rcu_state *rcu_state;
-LIST_HEAD(rcu_struct_flavors);
-
-/* Increase (but not decrease) the CONFIG_RCU_FANOUT_LEAF at boot time. */
-static int rcu_fanout_leaf = CONFIG_RCU_FANOUT_LEAF;
-module_param(rcu_fanout_leaf, int, 0444);
-int rcu_num_lvls __read_mostly = RCU_NUM_LVLS;
-static int num_rcu_lvl[] = {  /* Number of rcu_nodes at specified level. */
-       NUM_RCU_LVL_0,
-       NUM_RCU_LVL_1,
-       NUM_RCU_LVL_2,
-       NUM_RCU_LVL_3,
-       NUM_RCU_LVL_4,
-};
-int rcu_num_nodes __read_mostly = NUM_RCU_NODES; /* Total # rcu_nodes in use. */
-
-/*
- * The rcu_scheduler_active variable transitions from zero to one just
- * before the first task is spawned.  So when this variable is zero, RCU
- * can assume that there is but one task, allowing RCU to (for example)
- * optimize synchronize_sched() to a simple barrier().  When this variable
- * is one, RCU must actually do all the hard work required to detect real
- * grace periods.  This variable is also used to suppress boot-time false
- * positives from lockdep-RCU error checking.
- */
-int rcu_scheduler_active __read_mostly;
-EXPORT_SYMBOL_GPL(rcu_scheduler_active);
-
-/*
- * The rcu_scheduler_fully_active variable transitions from zero to one
- * during the early_initcall() processing, which is after the scheduler
- * is capable of creating new tasks.  So RCU processing (for example,
- * creating tasks for RCU priority boosting) must be delayed until after
- * rcu_scheduler_fully_active transitions from zero to one.  We also
- * currently delay invocation of any RCU callbacks until after this point.
- *
- * It might later prove better for people registering RCU callbacks during
- * early boot to take responsibility for these callbacks, but one step at
- * a time.
- */
-static int rcu_scheduler_fully_active __read_mostly;
-
-#ifdef CONFIG_RCU_BOOST
-
-/*
- * Control variables for per-CPU and per-rcu_node kthreads.  These
- * handle all flavors of RCU.
- */
-static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task);
-DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
-DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
-DEFINE_PER_CPU(char, rcu_cpu_has_work);
-
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu);
-static void invoke_rcu_core(void);
-static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp);
-
-/*
- * Track the rcutorture test sequence number and the update version
- * number within a given test.  The rcutorture_testseq is incremented
- * on every rcutorture module load and unload, so has an odd value
- * when a test is running.  The rcutorture_vernum is set to zero
- * when rcutorture starts and is incremented on each rcutorture update.
- * These variables enable correlating rcutorture output with the
- * RCU tracing information.
- */
-unsigned long rcutorture_testseq;
-unsigned long rcutorture_vernum;
-
-/*
- * Return true if an RCU grace period is in progress.  The ACCESS_ONCE()s
- * permit this function to be invoked without holding the root rcu_node
- * structure's ->lock, but of course results can be subject to change.
- */
-static int rcu_gp_in_progress(struct rcu_state *rsp)
-{
-       return ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum);
-}
-
-/*
- * Note a quiescent state.  Because we do not need to know
- * how many quiescent states passed, just if there was at least
- * one since the start of the grace period, this just sets a flag.
- * The caller must have disabled preemption.
- */
-void rcu_sched_qs(int cpu)
-{
-       struct rcu_data *rdp = &per_cpu(rcu_sched_data, cpu);
-
-       if (rdp->passed_quiesce == 0)
-               trace_rcu_grace_period(TPS("rcu_sched"), rdp->gpnum, TPS("cpuqs"));
-       rdp->passed_quiesce = 1;
-}
-
-void rcu_bh_qs(int cpu)
-{
-       struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
-
-       if (rdp->passed_quiesce == 0)
-               trace_rcu_grace_period(TPS("rcu_bh"), rdp->gpnum, TPS("cpuqs"));
-       rdp->passed_quiesce = 1;
-}
-
-/*
- * Note a context switch.  This is a quiescent state for RCU-sched,
- * and requires special handling for preemptible RCU.
- * The caller must have disabled preemption.
- */
-void rcu_note_context_switch(int cpu)
-{
-       trace_rcu_utilization(TPS("Start context switch"));
-       rcu_sched_qs(cpu);
-       rcu_preempt_note_context_switch(cpu);
-       trace_rcu_utilization(TPS("End context switch"));
-}
-EXPORT_SYMBOL_GPL(rcu_note_context_switch);
-
-DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
-       .dynticks_nesting = DYNTICK_TASK_EXIT_IDLE,
-       .dynticks = ATOMIC_INIT(1),
-#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
-       .dynticks_idle_nesting = DYNTICK_TASK_NEST_VALUE,
-       .dynticks_idle = ATOMIC_INIT(1),
-#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
-};
-
-static long blimit = 10;       /* Maximum callbacks per rcu_do_batch. */
-static long qhimark = 10000;   /* If this many pending, ignore blimit. */
-static long qlowmark = 100;    /* Once only this many pending, use blimit. */
-
-module_param(blimit, long, 0444);
-module_param(qhimark, long, 0444);
-module_param(qlowmark, long, 0444);
-
-static ulong jiffies_till_first_fqs = ULONG_MAX;
-static ulong jiffies_till_next_fqs = ULONG_MAX;
-
-module_param(jiffies_till_first_fqs, ulong, 0644);
-module_param(jiffies_till_next_fqs, ulong, 0644);
-
-static void rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
-                                 struct rcu_data *rdp);
-static void force_qs_rnp(struct rcu_state *rsp,
-                        int (*f)(struct rcu_data *rsp, bool *isidle,
-                                 unsigned long *maxj),
-                        bool *isidle, unsigned long *maxj);
-static void force_quiescent_state(struct rcu_state *rsp);
-static int rcu_pending(int cpu);
-
-/*
- * Return the number of RCU-sched batches processed thus far for debug & stats.
- */
-long rcu_batches_completed_sched(void)
-{
-       return rcu_sched_state.completed;
-}
-EXPORT_SYMBOL_GPL(rcu_batches_completed_sched);
-
-/*
- * Return the number of RCU BH batches processed thus far for debug & stats.
- */
-long rcu_batches_completed_bh(void)
-{
-       return rcu_bh_state.completed;
-}
-EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
-
-/*
- * Force a quiescent state for RCU BH.
- */
-void rcu_bh_force_quiescent_state(void)
-{
-       force_quiescent_state(&rcu_bh_state);
-}
-EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state);
-
-/*
- * Record the number of times rcutorture tests have been initiated and
- * terminated.  This information allows the debugfs tracing stats to be
- * correlated to the rcutorture messages, even when the rcutorture module
- * is being repeatedly loaded and unloaded.  In other words, we cannot
- * store this state in rcutorture itself.
- */
-void rcutorture_record_test_transition(void)
-{
-       rcutorture_testseq++;
-       rcutorture_vernum = 0;
-}
-EXPORT_SYMBOL_GPL(rcutorture_record_test_transition);
-
-/*
- * Record the number of writer passes through the current rcutorture test.
- * This is also used to correlate debugfs tracing stats with the rcutorture
- * messages.
- */
-void rcutorture_record_progress(unsigned long vernum)
-{
-       rcutorture_vernum++;
-}
-EXPORT_SYMBOL_GPL(rcutorture_record_progress);
-
-/*
- * Force a quiescent state for RCU-sched.
- */
-void rcu_sched_force_quiescent_state(void)
-{
-       force_quiescent_state(&rcu_sched_state);
-}
-EXPORT_SYMBOL_GPL(rcu_sched_force_quiescent_state);
-
-/*
- * Does the CPU have callbacks ready to be invoked?
- */
-static int
-cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
-{
-       return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] &&
-              rdp->nxttail[RCU_DONE_TAIL] != NULL;
-}
-
-/*
- * Does the current CPU require a not-yet-started grace period?
- * The caller must have disabled interrupts to prevent races with
- * normal callback registry.
- */
-static int
-cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       int i;
-
-       if (rcu_gp_in_progress(rsp))
-               return 0;  /* No, a grace period is already in progress. */
-       if (rcu_nocb_needs_gp(rsp))
-               return 1;  /* Yes, a no-CBs CPU needs one. */
-       if (!rdp->nxttail[RCU_NEXT_TAIL])
-               return 0;  /* No, this is a no-CBs (or offline) CPU. */
-       if (*rdp->nxttail[RCU_NEXT_READY_TAIL])
-               return 1;  /* Yes, this CPU has newly registered callbacks. */
-       for (i = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++)
-               if (rdp->nxttail[i - 1] != rdp->nxttail[i] &&
-                   ULONG_CMP_LT(ACCESS_ONCE(rsp->completed),
-                                rdp->nxtcompleted[i]))
-                       return 1;  /* Yes, CBs for future grace period. */
-       return 0; /* No grace period needed. */
-}
-
-/*
- * Return the root node of the specified rcu_state structure.
- */
-static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
-{
-       return &rsp->node[0];
-}
-
-/*
- * rcu_eqs_enter_common - current CPU is moving towards extended quiescent state
- *
- * If the new value of the ->dynticks_nesting counter now is zero,
- * we really have entered idle, and must do the appropriate accounting.
- * The caller must have disabled interrupts.
- */
-static void rcu_eqs_enter_common(struct rcu_dynticks *rdtp, long long oldval,
-                               bool user)
-{
-       trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting);
-       if (!user && !is_idle_task(current)) {
-               struct task_struct *idle = idle_task(smp_processor_id());
-
-               trace_rcu_dyntick(TPS("Error on entry: not idle task"), oldval, 0);
-               ftrace_dump(DUMP_ORIG);
-               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
-                         current->pid, current->comm,
-                         idle->pid, idle->comm); /* must be idle task! */
-       }
-       rcu_prepare_for_idle(smp_processor_id());
-       /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
-       smp_mb__before_atomic_inc();  /* See above. */
-       atomic_inc(&rdtp->dynticks);
-       smp_mb__after_atomic_inc();  /* Force ordering with next sojourn. */
-       WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
-
-       /*
-        * It is illegal to enter an extended quiescent state while
-        * in an RCU read-side critical section.
-        */
-       rcu_lockdep_assert(!lock_is_held(&rcu_lock_map),
-                          "Illegal idle entry in RCU read-side critical section.");
-       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),
-                          "Illegal idle entry in RCU-bh read-side critical section.");
-       rcu_lockdep_assert(!lock_is_held(&rcu_sched_lock_map),
-                          "Illegal idle entry in RCU-sched read-side critical section.");
-}
-
-/*
- * Enter an RCU extended quiescent state, which can be either the
- * idle loop or adaptive-tickless usermode execution.
- */
-static void rcu_eqs_enter(bool user)
-{
-       long long oldval;
-       struct rcu_dynticks *rdtp;
-
-       rdtp = &__get_cpu_var(rcu_dynticks);
-       oldval = rdtp->dynticks_nesting;
-       WARN_ON_ONCE((oldval & DYNTICK_TASK_NEST_MASK) == 0);
-       if ((oldval & DYNTICK_TASK_NEST_MASK) == DYNTICK_TASK_NEST_VALUE)
-               rdtp->dynticks_nesting = 0;
-       else
-               rdtp->dynticks_nesting -= DYNTICK_TASK_NEST_VALUE;
-       rcu_eqs_enter_common(rdtp, oldval, user);
-}
-
-/**
- * rcu_idle_enter - inform RCU that current CPU is entering idle
- *
- * Enter idle mode, in other words, -leave- the mode in which RCU
- * read-side critical sections can occur.  (Though RCU read-side
- * critical sections can occur in irq handlers in idle, a possibility
- * handled by irq_enter() and irq_exit().)
- *
- * We crowbar the ->dynticks_nesting field to zero to allow for
- * the possibility of usermode upcalls having messed up our count
- * of interrupt nesting level during the prior busy period.
- */
-void rcu_idle_enter(void)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       rcu_eqs_enter(false);
-       rcu_sysidle_enter(&__get_cpu_var(rcu_dynticks), 0);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(rcu_idle_enter);
-
-#ifdef CONFIG_RCU_USER_QS
-/**
- * rcu_user_enter - inform RCU that we are resuming userspace.
- *
- * Enter RCU idle mode right before resuming userspace.  No use of RCU
- * is permitted between this call and rcu_user_exit(). This way the
- * CPU doesn't need to maintain the tick for RCU maintenance purposes
- * when the CPU runs in userspace.
- */
-void rcu_user_enter(void)
-{
-       rcu_eqs_enter(1);
-}
-#endif /* CONFIG_RCU_USER_QS */
-
-/**
- * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
- *
- * Exit from an interrupt handler, which might possibly result in entering
- * idle mode, in other words, leaving the mode in which read-side critical
- * sections can occur.
- *
- * This code assumes that the idle loop never does anything that might
- * result in unbalanced calls to irq_enter() and irq_exit().  If your
- * architecture violates this assumption, RCU will give you what you
- * deserve, good and hard.  But very infrequently and irreproducibly.
- *
- * Use things like work queues to work around this limitation.
- *
- * You have been warned.
- */
-void rcu_irq_exit(void)
-{
-       unsigned long flags;
-       long long oldval;
-       struct rcu_dynticks *rdtp;
-
-       local_irq_save(flags);
-       rdtp = &__get_cpu_var(rcu_dynticks);
-       oldval = rdtp->dynticks_nesting;
-       rdtp->dynticks_nesting--;
-       WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
-       if (rdtp->dynticks_nesting)
-               trace_rcu_dyntick(TPS("--="), oldval, rdtp->dynticks_nesting);
-       else
-               rcu_eqs_enter_common(rdtp, oldval, true);
-       rcu_sysidle_enter(rdtp, 1);
-       local_irq_restore(flags);
-}
-
-/*
- * rcu_eqs_exit_common - current CPU moving away from extended quiescent state
- *
- * If the new value of the ->dynticks_nesting counter was previously zero,
- * we really have exited idle, and must do the appropriate accounting.
- * The caller must have disabled interrupts.
- */
-static void rcu_eqs_exit_common(struct rcu_dynticks *rdtp, long long oldval,
-                              int user)
-{
-       smp_mb__before_atomic_inc();  /* Force ordering w/previous sojourn. */
-       atomic_inc(&rdtp->dynticks);
-       /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
-       smp_mb__after_atomic_inc();  /* See above. */
-       WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
-       rcu_cleanup_after_idle(smp_processor_id());
-       trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting);
-       if (!user && !is_idle_task(current)) {
-               struct task_struct *idle = idle_task(smp_processor_id());
-
-               trace_rcu_dyntick(TPS("Error on exit: not idle task"),
-                                 oldval, rdtp->dynticks_nesting);
-               ftrace_dump(DUMP_ORIG);
-               WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
-                         current->pid, current->comm,
-                         idle->pid, idle->comm); /* must be idle task! */
-       }
-}
-
-/*
- * Exit an RCU extended quiescent state, which can be either the
- * idle loop or adaptive-tickless usermode execution.
- */
-static void rcu_eqs_exit(bool user)
-{
-       struct rcu_dynticks *rdtp;
-       long long oldval;
-
-       rdtp = &__get_cpu_var(rcu_dynticks);
-       oldval = rdtp->dynticks_nesting;
-       WARN_ON_ONCE(oldval < 0);
-       if (oldval & DYNTICK_TASK_NEST_MASK)
-               rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE;
-       else
-               rdtp->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
-       rcu_eqs_exit_common(rdtp, oldval, user);
-}
-
-/**
- * rcu_idle_exit - inform RCU that current CPU is leaving idle
- *
- * Exit idle mode, in other words, -enter- the mode in which RCU
- * read-side critical sections can occur.
- *
- * We crowbar the ->dynticks_nesting field to DYNTICK_TASK_NEST to
- * allow for the possibility of usermode upcalls messing up our count
- * of interrupt nesting level during the busy period that is just
- * now starting.
- */
-void rcu_idle_exit(void)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       rcu_eqs_exit(false);
-       rcu_sysidle_exit(&__get_cpu_var(rcu_dynticks), 0);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(rcu_idle_exit);
-
-#ifdef CONFIG_RCU_USER_QS
-/**
- * rcu_user_exit - inform RCU that we are exiting userspace.
- *
- * Exit RCU idle mode while entering the kernel because it can
- * run a RCU read side critical section anytime.
- */
-void rcu_user_exit(void)
-{
-       rcu_eqs_exit(1);
-}
-#endif /* CONFIG_RCU_USER_QS */
-
-/**
- * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle
- *
- * Enter an interrupt handler, which might possibly result in exiting
- * idle mode, in other words, entering the mode in which read-side critical
- * sections can occur.
- *
- * Note that the Linux kernel is fully capable of entering an interrupt
- * handler that it never exits, for example when doing upcalls to
- * user mode!  This code assumes that the idle loop never does upcalls to
- * user mode.  If your architecture does do upcalls from the idle loop (or
- * does anything else that results in unbalanced calls to the irq_enter()
- * and irq_exit() functions), RCU will give you what you deserve, good
- * and hard.  But very infrequently and irreproducibly.
- *
- * Use things like work queues to work around this limitation.
- *
- * You have been warned.
- */
-void rcu_irq_enter(void)
-{
-       unsigned long flags;
-       struct rcu_dynticks *rdtp;
-       long long oldval;
-
-       local_irq_save(flags);
-       rdtp = &__get_cpu_var(rcu_dynticks);
-       oldval = rdtp->dynticks_nesting;
-       rdtp->dynticks_nesting++;
-       WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
-       if (oldval)
-               trace_rcu_dyntick(TPS("++="), oldval, rdtp->dynticks_nesting);
-       else
-               rcu_eqs_exit_common(rdtp, oldval, true);
-       rcu_sysidle_exit(rdtp, 1);
-       local_irq_restore(flags);
-}
-
-/**
- * rcu_nmi_enter - inform RCU of entry to NMI context
- *
- * If the CPU was idle with dynamic ticks active, and there is no
- * irq handler running, this updates rdtp->dynticks_nmi to let the
- * RCU grace-period handling know that the CPU is active.
- */
-void rcu_nmi_enter(void)
-{
-       struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks);
-
-       if (rdtp->dynticks_nmi_nesting == 0 &&
-           (atomic_read(&rdtp->dynticks) & 0x1))
-               return;
-       rdtp->dynticks_nmi_nesting++;
-       smp_mb__before_atomic_inc();  /* Force delay from prior write. */
-       atomic_inc(&rdtp->dynticks);
-       /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
-       smp_mb__after_atomic_inc();  /* See above. */
-       WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
-}
-
-/**
- * rcu_nmi_exit - inform RCU of exit from NMI context
- *
- * If the CPU was idle with dynamic ticks active, and there is no
- * irq handler running, this updates rdtp->dynticks_nmi to let the
- * RCU grace-period handling know that the CPU is no longer active.
- */
-void rcu_nmi_exit(void)
-{
-       struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks);
-
-       if (rdtp->dynticks_nmi_nesting == 0 ||
-           --rdtp->dynticks_nmi_nesting != 0)
-               return;
-       /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
-       smp_mb__before_atomic_inc();  /* See above. */
-       atomic_inc(&rdtp->dynticks);
-       smp_mb__after_atomic_inc();  /* Force delay to next write. */
-       WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
-}
-
-/**
- * rcu_is_cpu_idle - see if RCU thinks that the current CPU is idle
- *
- * If the current CPU is in its idle loop and is neither in an interrupt
- * or NMI handler, return true.
- */
-int rcu_is_cpu_idle(void)
-{
-       int ret;
-
-       preempt_disable();
-       ret = (atomic_read(&__get_cpu_var(rcu_dynticks).dynticks) & 0x1) == 0;
-       preempt_enable();
-       return ret;
-}
-EXPORT_SYMBOL(rcu_is_cpu_idle);
-
-#if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU)
-
-/*
- * Is the current CPU online?  Disable preemption to avoid false positives
- * that could otherwise happen due to the current CPU number being sampled,
- * this task being preempted, its old CPU being taken offline, resuming
- * on some other CPU, then determining that its old CPU is now offline.
- * It is OK to use RCU on an offline processor during initial boot, hence
- * the check for rcu_scheduler_fully_active.  Note also that it is OK
- * for a CPU coming online to use RCU for one jiffy prior to marking itself
- * online in the cpu_online_mask.  Similarly, it is OK for a CPU going
- * offline to continue to use RCU for one jiffy after marking itself
- * offline in the cpu_online_mask.  This leniency is necessary given the
- * non-atomic nature of the online and offline processing, for example,
- * the fact that a CPU enters the scheduler after completing the CPU_DYING
- * notifiers.
- *
- * This is also why RCU internally marks CPUs online during the
- * CPU_UP_PREPARE phase and offline during the CPU_DEAD phase.
- *
- * Disable checking if in an NMI handler because we cannot safely report
- * errors from NMI handlers anyway.
- */
-bool rcu_lockdep_current_cpu_online(void)
-{
-       struct rcu_data *rdp;
-       struct rcu_node *rnp;
-       bool ret;
-
-       if (in_nmi())
-               return 1;
-       preempt_disable();
-       rdp = &__get_cpu_var(rcu_sched_data);
-       rnp = rdp->mynode;
-       ret = (rdp->grpmask & rnp->qsmaskinit) ||
-             !rcu_scheduler_fully_active;
-       preempt_enable();
-       return ret;
-}
-EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online);
-
-#endif /* #if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU) */
-
-/**
- * rcu_is_cpu_rrupt_from_idle - see if idle or immediately interrupted from idle
- *
- * If the current CPU is idle or running at a first-level (not nested)
- * interrupt from idle, return true.  The caller must have at least
- * disabled preemption.
- */
-static int rcu_is_cpu_rrupt_from_idle(void)
-{
-       return __get_cpu_var(rcu_dynticks).dynticks_nesting <= 1;
-}
-
-/*
- * Snapshot the specified CPU's dynticks counter so that we can later
- * credit them with an implicit quiescent state.  Return 1 if this CPU
- * is in dynticks idle mode, which is an extended quiescent state.
- */
-static int dyntick_save_progress_counter(struct rcu_data *rdp,
-                                        bool *isidle, unsigned long *maxj)
-{
-       rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks);
-       rcu_sysidle_check_cpu(rdp, isidle, maxj);
-       return (rdp->dynticks_snap & 0x1) == 0;
-}
-
-/*
- * Return true if the specified CPU has passed through a quiescent
- * state by virtue of being in or having passed through an dynticks
- * idle state since the last call to dyntick_save_progress_counter()
- * for this same CPU, or by virtue of having been offline.
- */
-static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
-                                   bool *isidle, unsigned long *maxj)
-{
-       unsigned int curr;
-       unsigned int snap;
-
-       curr = (unsigned int)atomic_add_return(0, &rdp->dynticks->dynticks);
-       snap = (unsigned int)rdp->dynticks_snap;
-
-       /*
-        * If the CPU passed through or entered a dynticks idle phase with
-        * no active irq/NMI handlers, then we can safely pretend that the CPU
-        * already acknowledged the request to pass through a quiescent
-        * state.  Either way, that CPU cannot possibly be in an RCU
-        * read-side critical section that started before the beginning
-        * of the current RCU grace period.
-        */
-       if ((curr & 0x1) == 0 || UINT_CMP_GE(curr, snap + 2)) {
-               trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
-               rdp->dynticks_fqs++;
-               return 1;
-       }
-
-       /*
-        * Check for the CPU being offline, but only if the grace period
-        * is old enough.  We don't need to worry about the CPU changing
-        * state: If we see it offline even once, it has been through a
-        * quiescent state.
-        *
-        * The reason for insisting that the grace period be at least
-        * one jiffy old is that CPUs that are not quite online and that
-        * have just gone offline can still execute RCU read-side critical
-        * sections.
-        */
-       if (ULONG_CMP_GE(rdp->rsp->gp_start + 2, jiffies))
-               return 0;  /* Grace period is not old enough. */
-       barrier();
-       if (cpu_is_offline(rdp->cpu)) {
-               trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl"));
-               rdp->offline_fqs++;
-               return 1;
-       }
-
-       /*
-        * There is a possibility that a CPU in adaptive-ticks state
-        * might run in the kernel with the scheduling-clock tick disabled
-        * for an extended time period.  Invoke rcu_kick_nohz_cpu() to
-        * force the CPU to restart the scheduling-clock tick in this
-        * CPU is in this state.
-        */
-       rcu_kick_nohz_cpu(rdp->cpu);
-
-       return 0;
-}
-
-static void record_gp_stall_check_time(struct rcu_state *rsp)
-{
-       rsp->gp_start = jiffies;
-       rsp->jiffies_stall = jiffies + rcu_jiffies_till_stall_check();
-}
-
-/*
- * Dump stacks of all tasks running on stalled CPUs.  This is a fallback
- * for architectures that do not implement trigger_all_cpu_backtrace().
- * The NMI-triggered stack traces are more accurate because they are
- * printed by the target CPU.
- */
-static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
-{
-       int cpu;
-       unsigned long flags;
-       struct rcu_node *rnp;
-
-       rcu_for_each_leaf_node(rsp, rnp) {
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               if (rnp->qsmask != 0) {
-                       for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
-                               if (rnp->qsmask & (1UL << cpu))
-                                       dump_cpu_task(rnp->grplo + cpu);
-               }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       }
-}
-
-static void print_other_cpu_stall(struct rcu_state *rsp)
-{
-       int cpu;
-       long delta;
-       unsigned long flags;
-       int ndetected = 0;
-       struct rcu_node *rnp = rcu_get_root(rsp);
-       long totqlen = 0;
-
-       /* Only let one CPU complain about others per time interval. */
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       delta = jiffies - rsp->jiffies_stall;
-       if (delta < RCU_STALL_RAT_DELAY || !rcu_gp_in_progress(rsp)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return;
-       }
-       rsp->jiffies_stall = jiffies + 3 * rcu_jiffies_till_stall_check() + 3;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-
-       /*
-        * OK, time to rat on our buddy...
-        * See Documentation/RCU/stallwarn.txt for info on how to debug
-        * RCU CPU stall warnings.
-        */
-       pr_err("INFO: %s detected stalls on CPUs/tasks:",
-              rsp->name);
-       print_cpu_stall_info_begin();
-       rcu_for_each_leaf_node(rsp, rnp) {
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               ndetected += rcu_print_task_stall(rnp);
-               if (rnp->qsmask != 0) {
-                       for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
-                               if (rnp->qsmask & (1UL << cpu)) {
-                                       print_cpu_stall_info(rsp,
-                                                            rnp->grplo + cpu);
-                                       ndetected++;
-                               }
-               }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       }
-
-       /*
-        * Now rat on any tasks that got kicked up to the root rcu_node
-        * due to CPU offlining.
-        */
-       rnp = rcu_get_root(rsp);
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       ndetected += rcu_print_task_stall(rnp);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-
-       print_cpu_stall_info_end();
-       for_each_possible_cpu(cpu)
-               totqlen += per_cpu_ptr(rsp->rda, cpu)->qlen;
-       pr_cont("(detected by %d, t=%ld jiffies, g=%lu, c=%lu, q=%lu)\n",
-              smp_processor_id(), (long)(jiffies - rsp->gp_start),
-              rsp->gpnum, rsp->completed, totqlen);
-       if (ndetected == 0)
-               pr_err("INFO: Stall ended before state dump start\n");
-       else if (!trigger_all_cpu_backtrace())
-               rcu_dump_cpu_stacks(rsp);
-
-       /* Complain about tasks blocking the grace period. */
-
-       rcu_print_detail_task_stall(rsp);
-
-       force_quiescent_state(rsp);  /* Kick them all. */
-}
-
-/*
- * This function really isn't for public consumption, but RCU is special in
- * that context switches can allow the state machine to make progress.
- */
-extern void resched_cpu(int cpu);
-
-static void print_cpu_stall(struct rcu_state *rsp)
-{
-       int cpu;
-       unsigned long flags;
-       struct rcu_node *rnp = rcu_get_root(rsp);
-       long totqlen = 0;
-
-       /*
-        * OK, time to rat on ourselves...
-        * See Documentation/RCU/stallwarn.txt for info on how to debug
-        * RCU CPU stall warnings.
-        */
-       pr_err("INFO: %s self-detected stall on CPU", rsp->name);
-       print_cpu_stall_info_begin();
-       print_cpu_stall_info(rsp, smp_processor_id());
-       print_cpu_stall_info_end();
-       for_each_possible_cpu(cpu)
-               totqlen += per_cpu_ptr(rsp->rda, cpu)->qlen;
-       pr_cont(" (t=%lu jiffies g=%lu c=%lu q=%lu)\n",
-               jiffies - rsp->gp_start, rsp->gpnum, rsp->completed, totqlen);
-       if (!trigger_all_cpu_backtrace())
-               dump_stack();
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
-               rsp->jiffies_stall = jiffies +
-                                    3 * rcu_jiffies_till_stall_check() + 3;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-
-       /*
-        * Attempt to revive the RCU machinery by forcing a context switch.
-        *
-        * A context switch would normally allow the RCU state machine to make
-        * progress and it could be we're stuck in kernel space without context
-        * switches for an entirely unreasonable amount of time.
-        */
-       resched_cpu(smp_processor_id());
-}
-
-static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       unsigned long j;
-       unsigned long js;
-       struct rcu_node *rnp;
-
-       if (rcu_cpu_stall_suppress)
-               return;
-       j = ACCESS_ONCE(jiffies);
-       js = ACCESS_ONCE(rsp->jiffies_stall);
-       rnp = rdp->mynode;
-       if (rcu_gp_in_progress(rsp) &&
-           (ACCESS_ONCE(rnp->qsmask) & rdp->grpmask) && ULONG_CMP_GE(j, js)) {
-
-               /* We haven't checked in, so go dump stack. */
-               print_cpu_stall(rsp);
-
-       } else if (rcu_gp_in_progress(rsp) &&
-                  ULONG_CMP_GE(j, js + RCU_STALL_RAT_DELAY)) {
-
-               /* They had a few time units to dump stack, so complain. */
-               print_other_cpu_stall(rsp);
-       }
-}
-
-/**
- * rcu_cpu_stall_reset - prevent further stall warnings in current grace period
- *
- * Set the stall-warning timeout way off into the future, thus preventing
- * any RCU CPU stall-warning messages from appearing in the current set of
- * RCU grace periods.
- *
- * The caller must disable hard irqs.
- */
-void rcu_cpu_stall_reset(void)
-{
-       struct rcu_state *rsp;
-
-       for_each_rcu_flavor(rsp)
-               rsp->jiffies_stall = jiffies + ULONG_MAX / 2;
-}
-
-/*
- * Initialize the specified rcu_data structure's callback list to empty.
- */
-static void init_callback_list(struct rcu_data *rdp)
-{
-       int i;
-
-       if (init_nocb_callback_list(rdp))
-               return;
-       rdp->nxtlist = NULL;
-       for (i = 0; i < RCU_NEXT_SIZE; i++)
-               rdp->nxttail[i] = &rdp->nxtlist;
-}
-
-/*
- * Determine the value that ->completed will have at the end of the
- * next subsequent grace period.  This is used to tag callbacks so that
- * a CPU can invoke callbacks in a timely fashion even if that CPU has
- * been dyntick-idle for an extended period with callbacks under the
- * influence of RCU_FAST_NO_HZ.
- *
- * The caller must hold rnp->lock with interrupts disabled.
- */
-static unsigned long rcu_cbs_completed(struct rcu_state *rsp,
-                                      struct rcu_node *rnp)
-{
-       /*
-        * If RCU is idle, we just wait for the next grace period.
-        * But we can only be sure that RCU is idle if we are looking
-        * at the root rcu_node structure -- otherwise, a new grace
-        * period might have started, but just not yet gotten around
-        * to initializing the current non-root rcu_node structure.
-        */
-       if (rcu_get_root(rsp) == rnp && rnp->gpnum == rnp->completed)
-               return rnp->completed + 1;
-
-       /*
-        * Otherwise, wait for a possible partial grace period and
-        * then the subsequent full grace period.
-        */
-       return rnp->completed + 2;
-}
-
-/*
- * Trace-event helper function for rcu_start_future_gp() and
- * rcu_nocb_wait_gp().
- */
-static void trace_rcu_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
-                               unsigned long c, const char *s)
-{
-       trace_rcu_future_grace_period(rdp->rsp->name, rnp->gpnum,
-                                     rnp->completed, c, rnp->level,
-                                     rnp->grplo, rnp->grphi, s);
-}
-
-/*
- * Start some future grace period, as needed to handle newly arrived
- * callbacks.  The required future grace periods are recorded in each
- * rcu_node structure's ->need_future_gp field.
- *
- * The caller must hold the specified rcu_node structure's ->lock.
- */
-static unsigned long __maybe_unused
-rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp)
-{
-       unsigned long c;
-       int i;
-       struct rcu_node *rnp_root = rcu_get_root(rdp->rsp);
-
-       /*
-        * Pick up grace-period number for new callbacks.  If this
-        * grace period is already marked as needed, return to the caller.
-        */
-       c = rcu_cbs_completed(rdp->rsp, rnp);
-       trace_rcu_future_gp(rnp, rdp, c, TPS("Startleaf"));
-       if (rnp->need_future_gp[c & 0x1]) {
-               trace_rcu_future_gp(rnp, rdp, c, TPS("Prestartleaf"));
-               return c;
-       }
-
-       /*
-        * If either this rcu_node structure or the root rcu_node structure
-        * believe that a grace period is in progress, then we must wait
-        * for the one following, which is in "c".  Because our request
-        * will be noticed at the end of the current grace period, we don't
-        * need to explicitly start one.
-        */
-       if (rnp->gpnum != rnp->completed ||
-           ACCESS_ONCE(rnp->gpnum) != ACCESS_ONCE(rnp->completed)) {
-               rnp->need_future_gp[c & 0x1]++;
-               trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf"));
-               return c;
-       }
-
-       /*
-        * There might be no grace period in progress.  If we don't already
-        * hold it, acquire the root rcu_node structure's lock in order to
-        * start one (if needed).
-        */
-       if (rnp != rnp_root)
-               raw_spin_lock(&rnp_root->lock);
-
-       /*
-        * Get a new grace-period number.  If there really is no grace
-        * period in progress, it will be smaller than the one we obtained
-        * earlier.  Adjust callbacks as needed.  Note that even no-CBs
-        * CPUs have a ->nxtcompleted[] array, so no no-CBs checks needed.
-        */
-       c = rcu_cbs_completed(rdp->rsp, rnp_root);
-       for (i = RCU_DONE_TAIL; i < RCU_NEXT_TAIL; i++)
-               if (ULONG_CMP_LT(c, rdp->nxtcompleted[i]))
-                       rdp->nxtcompleted[i] = c;
-
-       /*
-        * If the needed for the required grace period is already
-        * recorded, trace and leave.
-        */
-       if (rnp_root->need_future_gp[c & 0x1]) {
-               trace_rcu_future_gp(rnp, rdp, c, TPS("Prestartedroot"));
-               goto unlock_out;
-       }
-
-       /* Record the need for the future grace period. */
-       rnp_root->need_future_gp[c & 0x1]++;
-
-       /* If a grace period is not already in progress, start one. */
-       if (rnp_root->gpnum != rnp_root->completed) {
-               trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleafroot"));
-       } else {
-               trace_rcu_future_gp(rnp, rdp, c, TPS("Startedroot"));
-               rcu_start_gp_advanced(rdp->rsp, rnp_root, rdp);
-       }
-unlock_out:
-       if (rnp != rnp_root)
-               raw_spin_unlock(&rnp_root->lock);
-       return c;
-}
-
-/*
- * Clean up any old requests for the just-ended grace period.  Also return
- * whether any additional grace periods have been requested.  Also invoke
- * rcu_nocb_gp_cleanup() in order to wake up any no-callbacks kthreads
- * waiting for this grace period to complete.
- */
-static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
-{
-       int c = rnp->completed;
-       int needmore;
-       struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
-
-       rcu_nocb_gp_cleanup(rsp, rnp);
-       rnp->need_future_gp[c & 0x1] = 0;
-       needmore = rnp->need_future_gp[(c + 1) & 0x1];
-       trace_rcu_future_gp(rnp, rdp, c,
-                           needmore ? TPS("CleanupMore") : TPS("Cleanup"));
-       return needmore;
-}
-
-/*
- * If there is room, assign a ->completed number to any callbacks on
- * this CPU that have not already been assigned.  Also accelerate any
- * callbacks that were previously assigned a ->completed number that has
- * since proven to be too conservative, which can happen if callbacks get
- * assigned a ->completed number while RCU is idle, but with reference to
- * a non-root rcu_node structure.  This function is idempotent, so it does
- * not hurt to call it repeatedly.
- *
- * The caller must hold rnp->lock with interrupts disabled.
- */
-static void rcu_accelerate_cbs(struct rcu_state *rsp, struct rcu_node *rnp,
-                              struct rcu_data *rdp)
-{
-       unsigned long c;
-       int i;
-
-       /* If the CPU has no callbacks, nothing to do. */
-       if (!rdp->nxttail[RCU_NEXT_TAIL] || !*rdp->nxttail[RCU_DONE_TAIL])
-               return;
-
-       /*
-        * Starting from the sublist containing the callbacks most
-        * recently assigned a ->completed number and working down, find the
-        * first sublist that is not assignable to an upcoming grace period.
-        * Such a sublist has something in it (first two tests) and has
-        * a ->completed number assigned that will complete sooner than
-        * the ->completed number for newly arrived callbacks (last test).
-        *
-        * The key point is that any later sublist can be assigned the
-        * same ->completed number as the newly arrived callbacks, which
-        * means that the callbacks in any of these later sublist can be
-        * grouped into a single sublist, whether or not they have already
-        * been assigned a ->completed number.
-        */
-       c = rcu_cbs_completed(rsp, rnp);
-       for (i = RCU_NEXT_TAIL - 1; i > RCU_DONE_TAIL; i--)
-               if (rdp->nxttail[i] != rdp->nxttail[i - 1] &&
-                   !ULONG_CMP_GE(rdp->nxtcompleted[i], c))
-                       break;
-
-       /*
-        * If there are no sublist for unassigned callbacks, leave.
-        * At the same time, advance "i" one sublist, so that "i" will
-        * index into the sublist where all the remaining callbacks should
-        * be grouped into.
-        */
-       if (++i >= RCU_NEXT_TAIL)
-               return;
-
-       /*
-        * Assign all subsequent callbacks' ->completed number to the next
-        * full grace period and group them all in the sublist initially
-        * indexed by "i".
-        */
-       for (; i <= RCU_NEXT_TAIL; i++) {
-               rdp->nxttail[i] = rdp->nxttail[RCU_NEXT_TAIL];
-               rdp->nxtcompleted[i] = c;
-       }
-       /* Record any needed additional grace periods. */
-       rcu_start_future_gp(rnp, rdp);
-
-       /* Trace depending on how much we were able to accelerate. */
-       if (!*rdp->nxttail[RCU_WAIT_TAIL])
-               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("AccWaitCB"));
-       else
-               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("AccReadyCB"));
-}
-
-/*
- * Move any callbacks whose grace period has completed to the
- * RCU_DONE_TAIL sublist, then compact the remaining sublists and
- * assign ->completed numbers to any callbacks in the RCU_NEXT_TAIL
- * sublist.  This function is idempotent, so it does not hurt to
- * invoke it repeatedly.  As long as it is not invoked -too- often...
- *
- * The caller must hold rnp->lock with interrupts disabled.
- */
-static void rcu_advance_cbs(struct rcu_state *rsp, struct rcu_node *rnp,
-                           struct rcu_data *rdp)
-{
-       int i, j;
-
-       /* If the CPU has no callbacks, nothing to do. */
-       if (!rdp->nxttail[RCU_NEXT_TAIL] || !*rdp->nxttail[RCU_DONE_TAIL])
-               return;
-
-       /*
-        * Find all callbacks whose ->completed numbers indicate that they
-        * are ready to invoke, and put them into the RCU_DONE_TAIL sublist.
-        */
-       for (i = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++) {
-               if (ULONG_CMP_LT(rnp->completed, rdp->nxtcompleted[i]))
-                       break;
-               rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[i];
-       }
-       /* Clean up any sublist tail pointers that were misordered above. */
-       for (j = RCU_WAIT_TAIL; j < i; j++)
-               rdp->nxttail[j] = rdp->nxttail[RCU_DONE_TAIL];
-
-       /* Copy down callbacks to fill in empty sublists. */
-       for (j = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++, j++) {
-               if (rdp->nxttail[j] == rdp->nxttail[RCU_NEXT_TAIL])
-                       break;
-               rdp->nxttail[j] = rdp->nxttail[i];
-               rdp->nxtcompleted[j] = rdp->nxtcompleted[i];
-       }
-
-       /* Classify any remaining callbacks. */
-       rcu_accelerate_cbs(rsp, rnp, rdp);
-}
-
-/*
- * Update CPU-local rcu_data state to record the beginnings and ends of
- * grace periods.  The caller must hold the ->lock of the leaf rcu_node
- * structure corresponding to the current CPU, and must have irqs disabled.
- */
-static void __note_gp_changes(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
-{
-       /* Handle the ends of any preceding grace periods first. */
-       if (rdp->completed == rnp->completed) {
-
-               /* No grace period end, so just accelerate recent callbacks. */
-               rcu_accelerate_cbs(rsp, rnp, rdp);
-
-       } else {
-
-               /* Advance callbacks. */
-               rcu_advance_cbs(rsp, rnp, rdp);
-
-               /* Remember that we saw this grace-period completion. */
-               rdp->completed = rnp->completed;
-               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuend"));
-       }
-
-       if (rdp->gpnum != rnp->gpnum) {
-               /*
-                * If the current grace period is waiting for this CPU,
-                * set up to detect a quiescent state, otherwise don't
-                * go looking for one.
-                */
-               rdp->gpnum = rnp->gpnum;
-               trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpustart"));
-               rdp->passed_quiesce = 0;
-               rdp->qs_pending = !!(rnp->qsmask & rdp->grpmask);
-               zero_cpu_stall_ticks(rdp);
-       }
-}
-
-static void note_gp_changes(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       unsigned long flags;
-       struct rcu_node *rnp;
-
-       local_irq_save(flags);
-       rnp = rdp->mynode;
-       if ((rdp->gpnum == ACCESS_ONCE(rnp->gpnum) &&
-            rdp->completed == ACCESS_ONCE(rnp->completed)) || /* w/out lock. */
-           !raw_spin_trylock(&rnp->lock)) { /* irqs already off, so later. */
-               local_irq_restore(flags);
-               return;
-       }
-       __note_gp_changes(rsp, rnp, rdp);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-}
-
-/*
- * Initialize a new grace period.
- */
-static int rcu_gp_init(struct rcu_state *rsp)
-{
-       struct rcu_data *rdp;
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       rcu_bind_gp_kthread();
-       raw_spin_lock_irq(&rnp->lock);
-       rsp->gp_flags = 0; /* Clear all flags: New grace period. */
-
-       if (rcu_gp_in_progress(rsp)) {
-               /* Grace period already in progress, don't start another.  */
-               raw_spin_unlock_irq(&rnp->lock);
-               return 0;
-       }
-
-       /* Advance to a new grace period and initialize state. */
-       rsp->gpnum++;
-       trace_rcu_grace_period(rsp->name, rsp->gpnum, TPS("start"));
-       record_gp_stall_check_time(rsp);
-       raw_spin_unlock_irq(&rnp->lock);
-
-       /* Exclude any concurrent CPU-hotplug operations. */
-       mutex_lock(&rsp->onoff_mutex);
-
-       /*
-        * Set the quiescent-state-needed bits in all the rcu_node
-        * structures for all currently online CPUs in breadth-first order,
-        * starting from the root rcu_node structure, relying on the layout
-        * of the tree within the rsp->node[] array.  Note that other CPUs
-        * will access only the leaves of the hierarchy, thus seeing that no
-        * grace period is in progress, at least until the corresponding
-        * leaf node has been initialized.  In addition, we have excluded
-        * CPU-hotplug operations.
-        *
-        * The grace period cannot complete until the initialization
-        * process finishes, because this kthread handles both.
-        */
-       rcu_for_each_node_breadth_first(rsp, rnp) {
-               raw_spin_lock_irq(&rnp->lock);
-               rdp = this_cpu_ptr(rsp->rda);
-               rcu_preempt_check_blocked_tasks(rnp);
-               rnp->qsmask = rnp->qsmaskinit;
-               ACCESS_ONCE(rnp->gpnum) = rsp->gpnum;
-               WARN_ON_ONCE(rnp->completed != rsp->completed);
-               ACCESS_ONCE(rnp->completed) = rsp->completed;
-               if (rnp == rdp->mynode)
-                       __note_gp_changes(rsp, rnp, rdp);
-               rcu_preempt_boost_start_gp(rnp);
-               trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
-                                           rnp->level, rnp->grplo,
-                                           rnp->grphi, rnp->qsmask);
-               raw_spin_unlock_irq(&rnp->lock);
-#ifdef CONFIG_PROVE_RCU_DELAY
-               if ((prandom_u32() % (rcu_num_nodes + 1)) == 0 &&
-                   system_state == SYSTEM_RUNNING)
-                       udelay(200);
-#endif /* #ifdef CONFIG_PROVE_RCU_DELAY */
-               cond_resched();
-       }
-
-       mutex_unlock(&rsp->onoff_mutex);
-       return 1;
-}
-
-/*
- * Do one round of quiescent-state forcing.
- */
-int rcu_gp_fqs(struct rcu_state *rsp, int fqs_state_in)
-{
-       int fqs_state = fqs_state_in;
-       bool isidle = false;
-       unsigned long maxj;
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       rsp->n_force_qs++;
-       if (fqs_state == RCU_SAVE_DYNTICK) {
-               /* Collect dyntick-idle snapshots. */
-               if (is_sysidle_rcu_state(rsp)) {
-                       isidle = 1;
-                       maxj = jiffies - ULONG_MAX / 4;
-               }
-               force_qs_rnp(rsp, dyntick_save_progress_counter,
-                            &isidle, &maxj);
-               rcu_sysidle_report_gp(rsp, isidle, maxj);
-               fqs_state = RCU_FORCE_QS;
-       } else {
-               /* Handle dyntick-idle and offline CPUs. */
-               isidle = 0;
-               force_qs_rnp(rsp, rcu_implicit_dynticks_qs, &isidle, &maxj);
-       }
-       /* Clear flag to prevent immediate re-entry. */
-       if (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) {
-               raw_spin_lock_irq(&rnp->lock);
-               rsp->gp_flags &= ~RCU_GP_FLAG_FQS;
-               raw_spin_unlock_irq(&rnp->lock);
-       }
-       return fqs_state;
-}
-
-/*
- * Clean up after the old grace period.
- */
-static void rcu_gp_cleanup(struct rcu_state *rsp)
-{
-       unsigned long gp_duration;
-       int nocb = 0;
-       struct rcu_data *rdp;
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       raw_spin_lock_irq(&rnp->lock);
-       gp_duration = jiffies - rsp->gp_start;
-       if (gp_duration > rsp->gp_max)
-               rsp->gp_max = gp_duration;
-
-       /*
-        * We know the grace period is complete, but to everyone else
-        * it appears to still be ongoing.  But it is also the case
-        * that to everyone else it looks like there is nothing that
-        * they can do to advance the grace period.  It is therefore
-        * safe for us to drop the lock in order to mark the grace
-        * period as completed in all of the rcu_node structures.
-        */
-       raw_spin_unlock_irq(&rnp->lock);
-
-       /*
-        * Propagate new ->completed value to rcu_node structures so
-        * that other CPUs don't have to wait until the start of the next
-        * grace period to process their callbacks.  This also avoids
-        * some nasty RCU grace-period initialization races by forcing
-        * the end of the current grace period to be completely recorded in
-        * all of the rcu_node structures before the beginning of the next
-        * grace period is recorded in any of the rcu_node structures.
-        */
-       rcu_for_each_node_breadth_first(rsp, rnp) {
-               raw_spin_lock_irq(&rnp->lock);
-               ACCESS_ONCE(rnp->completed) = rsp->gpnum;
-               rdp = this_cpu_ptr(rsp->rda);
-               if (rnp == rdp->mynode)
-                       __note_gp_changes(rsp, rnp, rdp);
-               nocb += rcu_future_gp_cleanup(rsp, rnp);
-               raw_spin_unlock_irq(&rnp->lock);
-               cond_resched();
-       }
-       rnp = rcu_get_root(rsp);
-       raw_spin_lock_irq(&rnp->lock);
-       rcu_nocb_gp_set(rnp, nocb);
-
-       rsp->completed = rsp->gpnum; /* Declare grace period done. */
-       trace_rcu_grace_period(rsp->name, rsp->completed, TPS("end"));
-       rsp->fqs_state = RCU_GP_IDLE;
-       rdp = this_cpu_ptr(rsp->rda);
-       rcu_advance_cbs(rsp, rnp, rdp);  /* Reduce false positives below. */
-       if (cpu_needs_another_gp(rsp, rdp))
-               rsp->gp_flags = 1;
-       raw_spin_unlock_irq(&rnp->lock);
-}
-
-/*
- * Body of kthread that handles grace periods.
- */
-static int __noreturn rcu_gp_kthread(void *arg)
-{
-       int fqs_state;
-       unsigned long j;
-       int ret;
-       struct rcu_state *rsp = arg;
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       for (;;) {
-
-               /* Handle grace-period start. */
-               for (;;) {
-                       wait_event_interruptible(rsp->gp_wq,
-                                                rsp->gp_flags &
-                                                RCU_GP_FLAG_INIT);
-                       if ((rsp->gp_flags & RCU_GP_FLAG_INIT) &&
-                           rcu_gp_init(rsp))
-                               break;
-                       cond_resched();
-                       flush_signals(current);
-               }
-
-               /* Handle quiescent-state forcing. */
-               fqs_state = RCU_SAVE_DYNTICK;
-               j = jiffies_till_first_fqs;
-               if (j > HZ) {
-                       j = HZ;
-                       jiffies_till_first_fqs = HZ;
-               }
-               for (;;) {
-                       rsp->jiffies_force_qs = jiffies + j;
-                       ret = wait_event_interruptible_timeout(rsp->gp_wq,
-                                       (rsp->gp_flags & RCU_GP_FLAG_FQS) ||
-                                       (!ACCESS_ONCE(rnp->qsmask) &&
-                                        !rcu_preempt_blocked_readers_cgp(rnp)),
-                                       j);
-                       /* If grace period done, leave loop. */
-                       if (!ACCESS_ONCE(rnp->qsmask) &&
-                           !rcu_preempt_blocked_readers_cgp(rnp))
-                               break;
-                       /* If time for quiescent-state forcing, do it. */
-                       if (ret == 0 || (rsp->gp_flags & RCU_GP_FLAG_FQS)) {
-                               fqs_state = rcu_gp_fqs(rsp, fqs_state);
-                               cond_resched();
-                       } else {
-                               /* Deal with stray signal. */
-                               cond_resched();
-                               flush_signals(current);
-                       }
-                       j = jiffies_till_next_fqs;
-                       if (j > HZ) {
-                               j = HZ;
-                               jiffies_till_next_fqs = HZ;
-                       } else if (j < 1) {
-                               j = 1;
-                               jiffies_till_next_fqs = 1;
-                       }
-               }
-
-               /* Handle grace-period end. */
-               rcu_gp_cleanup(rsp);
-       }
-}
-
-static void rsp_wakeup(struct irq_work *work)
-{
-       struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work);
-
-       /* Wake up rcu_gp_kthread() to start the grace period. */
-       wake_up(&rsp->gp_wq);
-}
-
-/*
- * Start a new RCU grace period if warranted, re-initializing the hierarchy
- * in preparation for detecting the next grace period.  The caller must hold
- * the root node's ->lock and hard irqs must be disabled.
- *
- * Note that it is legal for a dying CPU (which is marked as offline) to
- * invoke this function.  This can happen when the dying CPU reports its
- * quiescent state.
- */
-static void
-rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
-                     struct rcu_data *rdp)
-{
-       if (!rsp->gp_kthread || !cpu_needs_another_gp(rsp, rdp)) {
-               /*
-                * Either we have not yet spawned the grace-period
-                * task, this CPU does not need another grace period,
-                * or a grace period is already in progress.
-                * Either way, don't start a new grace period.
-                */
-               return;
-       }
-       rsp->gp_flags = RCU_GP_FLAG_INIT;
-
-       /*
-        * We can't do wakeups while holding the rnp->lock, as that
-        * could cause possible deadlocks with the rq->lock. Defer
-        * the wakeup to interrupt context.  And don't bother waking
-        * up the running kthread.
-        */
-       if (current != rsp->gp_kthread)
-               irq_work_queue(&rsp->wakeup_work);
-}
-
-/*
- * Similar to rcu_start_gp_advanced(), but also advance the calling CPU's
- * callbacks.  Note that rcu_start_gp_advanced() cannot do this because it
- * is invoked indirectly from rcu_advance_cbs(), which would result in
- * endless recursion -- or would do so if it wasn't for the self-deadlock
- * that is encountered beforehand.
- */
-static void
-rcu_start_gp(struct rcu_state *rsp)
-{
-       struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       /*
-        * If there is no grace period in progress right now, any
-        * callbacks we have up to this point will be satisfied by the
-        * next grace period.  Also, advancing the callbacks reduces the
-        * probability of false positives from cpu_needs_another_gp()
-        * resulting in pointless grace periods.  So, advance callbacks
-        * then start the grace period!
-        */
-       rcu_advance_cbs(rsp, rnp, rdp);
-       rcu_start_gp_advanced(rsp, rnp, rdp);
-}
-
-/*
- * Report a full set of quiescent states to the specified rcu_state
- * data structure.  This involves cleaning up after the prior grace
- * period and letting rcu_start_gp() start up the next grace period
- * if one is needed.  Note that the caller must hold rnp->lock, which
- * is released before return.
- */
-static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
-       __releases(rcu_get_root(rsp)->lock)
-{
-       WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
-       raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
-       wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
-}
-
-/*
- * Similar to rcu_report_qs_rdp(), for which it is a helper function.
- * Allows quiescent states for a group of CPUs to be reported at one go
- * to the specified rcu_node structure, though all the CPUs in the group
- * must be represented by the same rcu_node structure (which need not be
- * a leaf rcu_node structure, though it often will be).  That structure's
- * lock must be held upon entry, and it is released before return.
- */
-static void
-rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
-                 struct rcu_node *rnp, unsigned long flags)
-       __releases(rnp->lock)
-{
-       struct rcu_node *rnp_c;
-
-       /* Walk up the rcu_node hierarchy. */
-       for (;;) {
-               if (!(rnp->qsmask & mask)) {
-
-                       /* Our bit has already been cleared, so done. */
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-                       return;
-               }
-               rnp->qsmask &= ~mask;
-               trace_rcu_quiescent_state_report(rsp->name, rnp->gpnum,
-                                                mask, rnp->qsmask, rnp->level,
-                                                rnp->grplo, rnp->grphi,
-                                                !!rnp->gp_tasks);
-               if (rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
-
-                       /* Other bits still set at this level, so done. */
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-                       return;
-               }
-               mask = rnp->grpmask;
-               if (rnp->parent == NULL) {
-
-                       /* No more levels.  Exit loop holding root lock. */
-
-                       break;
-               }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               rnp_c = rnp;
-               rnp = rnp->parent;
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               WARN_ON_ONCE(rnp_c->qsmask);
-       }
-
-       /*
-        * Get here if we are the last CPU to pass through a quiescent
-        * state for this grace period.  Invoke rcu_report_qs_rsp()
-        * to clean up and start the next grace period if one is needed.
-        */
-       rcu_report_qs_rsp(rsp, flags); /* releases rnp->lock. */
-}
-
-/*
- * Record a quiescent state for the specified CPU to that CPU's rcu_data
- * structure.  This must be either called from the specified CPU, or
- * called when the specified CPU is known to be offline (and when it is
- * also known that no other CPU is concurrently trying to help the offline
- * CPU).  The lastcomp argument is used to make sure we are still in the
- * grace period of interest.  We don't want to end the current grace period
- * based on quiescent states detected in an earlier grace period!
- */
-static void
-rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       unsigned long flags;
-       unsigned long mask;
-       struct rcu_node *rnp;
-
-       rnp = rdp->mynode;
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       if (rdp->passed_quiesce == 0 || rdp->gpnum != rnp->gpnum ||
-           rnp->completed == rnp->gpnum) {
-
-               /*
-                * The grace period in which this quiescent state was
-                * recorded has ended, so don't report it upwards.
-                * We will instead need a new quiescent state that lies
-                * within the current grace period.
-                */
-               rdp->passed_quiesce = 0;        /* need qs for new gp. */
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return;
-       }
-       mask = rdp->grpmask;
-       if ((rnp->qsmask & mask) == 0) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       } else {
-               rdp->qs_pending = 0;
-
-               /*
-                * This GP can't end until cpu checks in, so all of our
-                * callbacks can be processed during the next GP.
-                */
-               rcu_accelerate_cbs(rsp, rnp, rdp);
-
-               rcu_report_qs_rnp(mask, rsp, rnp, flags); /* rlses rnp->lock */
-       }
-}
-
-/*
- * Check to see if there is a new grace period of which this CPU
- * is not yet aware, and if so, set up local rcu_data state for it.
- * Otherwise, see if this CPU has just passed through its first
- * quiescent state for this grace period, and record that fact if so.
- */
-static void
-rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       /* Check for grace-period ends and beginnings. */
-       note_gp_changes(rsp, rdp);
-
-       /*
-        * Does this CPU still need to do its part for current grace period?
-        * If no, return and let the other CPUs do their part as well.
-        */
-       if (!rdp->qs_pending)
-               return;
-
-       /*
-        * Was there a quiescent state since the beginning of the grace
-        * period? If no, then exit and wait for the next call.
-        */
-       if (!rdp->passed_quiesce)
-               return;
-
-       /*
-        * Tell RCU we are done (but rcu_report_qs_rdp() will be the
-        * judge of that).
-        */
-       rcu_report_qs_rdp(rdp->cpu, rsp, rdp);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/*
- * Send the specified CPU's RCU callbacks to the orphanage.  The
- * specified CPU must be offline, and the caller must hold the
- * ->orphan_lock.
- */
-static void
-rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp,
-                         struct rcu_node *rnp, struct rcu_data *rdp)
-{
-       /* No-CBs CPUs do not have orphanable callbacks. */
-       if (rcu_is_nocb_cpu(rdp->cpu))
-               return;
-
-       /*
-        * Orphan the callbacks.  First adjust the counts.  This is safe
-        * because _rcu_barrier() excludes CPU-hotplug operations, so it
-        * cannot be running now.  Thus no memory barrier is required.
-        */
-       if (rdp->nxtlist != NULL) {
-               rsp->qlen_lazy += rdp->qlen_lazy;
-               rsp->qlen += rdp->qlen;
-               rdp->n_cbs_orphaned += rdp->qlen;
-               rdp->qlen_lazy = 0;
-               ACCESS_ONCE(rdp->qlen) = 0;
-       }
-
-       /*
-        * Next, move those callbacks still needing a grace period to
-        * the orphanage, where some other CPU will pick them up.
-        * Some of the callbacks might have gone partway through a grace
-        * period, but that is too bad.  They get to start over because we
-        * cannot assume that grace periods are synchronized across CPUs.
-        * We don't bother updating the ->nxttail[] array yet, instead
-        * we just reset the whole thing later on.
-        */
-       if (*rdp->nxttail[RCU_DONE_TAIL] != NULL) {
-               *rsp->orphan_nxttail = *rdp->nxttail[RCU_DONE_TAIL];
-               rsp->orphan_nxttail = rdp->nxttail[RCU_NEXT_TAIL];
-               *rdp->nxttail[RCU_DONE_TAIL] = NULL;
-       }
-
-       /*
-        * Then move the ready-to-invoke callbacks to the orphanage,
-        * where some other CPU will pick them up.  These will not be
-        * required to pass though another grace period: They are done.
-        */
-       if (rdp->nxtlist != NULL) {
-               *rsp->orphan_donetail = rdp->nxtlist;
-               rsp->orphan_donetail = rdp->nxttail[RCU_DONE_TAIL];
-       }
-
-       /* Finally, initialize the rcu_data structure's list to empty.  */
-       init_callback_list(rdp);
-}
-
-/*
- * Adopt the RCU callbacks from the specified rcu_state structure's
- * orphanage.  The caller must hold the ->orphan_lock.
- */
-static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
-{
-       int i;
-       struct rcu_data *rdp = __this_cpu_ptr(rsp->rda);
-
-       /* No-CBs CPUs are handled specially. */
-       if (rcu_nocb_adopt_orphan_cbs(rsp, rdp))
-               return;
-
-       /* Do the accounting first. */
-       rdp->qlen_lazy += rsp->qlen_lazy;
-       rdp->qlen += rsp->qlen;
-       rdp->n_cbs_adopted += rsp->qlen;
-       if (rsp->qlen_lazy != rsp->qlen)
-               rcu_idle_count_callbacks_posted();
-       rsp->qlen_lazy = 0;
-       rsp->qlen = 0;
-
-       /*
-        * We do not need a memory barrier here because the only way we
-        * can get here if there is an rcu_barrier() in flight is if
-        * we are the task doing the rcu_barrier().
-        */
-
-       /* First adopt the ready-to-invoke callbacks. */
-       if (rsp->orphan_donelist != NULL) {
-               *rsp->orphan_donetail = *rdp->nxttail[RCU_DONE_TAIL];
-               *rdp->nxttail[RCU_DONE_TAIL] = rsp->orphan_donelist;
-               for (i = RCU_NEXT_SIZE - 1; i >= RCU_DONE_TAIL; i--)
-                       if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL])
-                               rdp->nxttail[i] = rsp->orphan_donetail;
-               rsp->orphan_donelist = NULL;
-               rsp->orphan_donetail = &rsp->orphan_donelist;
-       }
-
-       /* And then adopt the callbacks that still need a grace period. */
-       if (rsp->orphan_nxtlist != NULL) {
-               *rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_nxtlist;
-               rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_nxttail;
-               rsp->orphan_nxtlist = NULL;
-               rsp->orphan_nxttail = &rsp->orphan_nxtlist;
-       }
-}
-
-/*
- * Trace the fact that this CPU is going offline.
- */
-static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
-{
-       RCU_TRACE(unsigned long mask);
-       RCU_TRACE(struct rcu_data *rdp = this_cpu_ptr(rsp->rda));
-       RCU_TRACE(struct rcu_node *rnp = rdp->mynode);
-
-       RCU_TRACE(mask = rdp->grpmask);
-       trace_rcu_grace_period(rsp->name,
-                              rnp->gpnum + 1 - !!(rnp->qsmask & mask),
-                              TPS("cpuofl"));
-}
-
-/*
- * The CPU has been completely removed, and some other CPU is reporting
- * this fact from process context.  Do the remainder of the cleanup,
- * including orphaning the outgoing CPU's RCU callbacks, and also
- * adopting them.  There can only be one CPU hotplug operation at a time,
- * so no other CPU can be attempting to update rcu_cpu_kthread_task.
- */
-static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
-{
-       unsigned long flags;
-       unsigned long mask;
-       int need_report = 0;
-       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-       struct rcu_node *rnp = rdp->mynode;  /* Outgoing CPU's rdp & rnp. */
-
-       /* Adjust any no-longer-needed kthreads. */
-       rcu_boost_kthread_setaffinity(rnp, -1);
-
-       /* Remove the dead CPU from the bitmasks in the rcu_node hierarchy. */
-
-       /* Exclude any attempts to start a new grace period. */
-       mutex_lock(&rsp->onoff_mutex);
-       raw_spin_lock_irqsave(&rsp->orphan_lock, flags);
-
-       /* Orphan the dead CPU's callbacks, and adopt them if appropriate. */
-       rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp);
-       rcu_adopt_orphan_cbs(rsp);
-
-       /* Remove the outgoing CPU from the masks in the rcu_node hierarchy. */
-       mask = rdp->grpmask;    /* rnp->grplo is constant. */
-       do {
-               raw_spin_lock(&rnp->lock);      /* irqs already disabled. */
-               rnp->qsmaskinit &= ~mask;
-               if (rnp->qsmaskinit != 0) {
-                       if (rnp != rdp->mynode)
-                               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
-                       break;
-               }
-               if (rnp == rdp->mynode)
-                       need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
-               else
-                       raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
-               mask = rnp->grpmask;
-               rnp = rnp->parent;
-       } while (rnp != NULL);
-
-       /*
-        * We still hold the leaf rcu_node structure lock here, and
-        * irqs are still disabled.  The reason for this subterfuge is
-        * because invoking rcu_report_unblock_qs_rnp() with ->orphan_lock
-        * held leads to deadlock.
-        */
-       raw_spin_unlock(&rsp->orphan_lock); /* irqs remain disabled. */
-       rnp = rdp->mynode;
-       if (need_report & RCU_OFL_TASKS_NORM_GP)
-               rcu_report_unblock_qs_rnp(rnp, flags);
-       else
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       if (need_report & RCU_OFL_TASKS_EXP_GP)
-               rcu_report_exp_rnp(rsp, rnp, true);
-       WARN_ONCE(rdp->qlen != 0 || rdp->nxtlist != NULL,
-                 "rcu_cleanup_dead_cpu: Callbacks on offline CPU %d: qlen=%lu, nxtlist=%p\n",
-                 cpu, rdp->qlen, rdp->nxtlist);
-       init_callback_list(rdp);
-       /* Disallow further callbacks on this CPU. */
-       rdp->nxttail[RCU_NEXT_TAIL] = NULL;
-       mutex_unlock(&rsp->onoff_mutex);
-}
-
-#else /* #ifdef CONFIG_HOTPLUG_CPU */
-
-static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
-{
-}
-
-static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
-{
-}
-
-#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
-
-/*
- * Invoke any RCU callbacks that have made it to the end of their grace
- * period.  Thottle as specified by rdp->blimit.
- */
-static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       unsigned long flags;
-       struct rcu_head *next, *list, **tail;
-       long bl, count, count_lazy;
-       int i;
-
-       /* If no callbacks are ready, just return. */
-       if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
-               trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, 0);
-               trace_rcu_batch_end(rsp->name, 0, !!ACCESS_ONCE(rdp->nxtlist),
-                                   need_resched(), is_idle_task(current),
-                                   rcu_is_callbacks_kthread());
-               return;
-       }
-
-       /*
-        * Extract the list of ready callbacks, disabling to prevent
-        * races with call_rcu() from interrupt handlers.
-        */
-       local_irq_save(flags);
-       WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
-       bl = rdp->blimit;
-       trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, bl);
-       list = rdp->nxtlist;
-       rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
-       *rdp->nxttail[RCU_DONE_TAIL] = NULL;
-       tail = rdp->nxttail[RCU_DONE_TAIL];
-       for (i = RCU_NEXT_SIZE - 1; i >= 0; i--)
-               if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL])
-                       rdp->nxttail[i] = &rdp->nxtlist;
-       local_irq_restore(flags);
-
-       /* Invoke callbacks. */
-       count = count_lazy = 0;
-       while (list) {
-               next = list->next;
-               prefetch(next);
-               debug_rcu_head_unqueue(list);
-               if (__rcu_reclaim(rsp->name, list))
-                       count_lazy++;
-               list = next;
-               /* Stop only if limit reached and CPU has something to do. */
-               if (++count >= bl &&
-                   (need_resched() ||
-                    (!is_idle_task(current) && !rcu_is_callbacks_kthread())))
-                       break;
-       }
-
-       local_irq_save(flags);
-       trace_rcu_batch_end(rsp->name, count, !!list, need_resched(),
-                           is_idle_task(current),
-                           rcu_is_callbacks_kthread());
-
-       /* Update count, and requeue any remaining callbacks. */
-       if (list != NULL) {
-               *tail = rdp->nxtlist;
-               rdp->nxtlist = list;
-               for (i = 0; i < RCU_NEXT_SIZE; i++)
-                       if (&rdp->nxtlist == rdp->nxttail[i])
-                               rdp->nxttail[i] = tail;
-                       else
-                               break;
-       }
-       smp_mb(); /* List handling before counting for rcu_barrier(). */
-       rdp->qlen_lazy -= count_lazy;
-       ACCESS_ONCE(rdp->qlen) -= count;
-       rdp->n_cbs_invoked += count;
-
-       /* Reinstate batch limit if we have worked down the excess. */
-       if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark)
-               rdp->blimit = blimit;
-
-       /* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */
-       if (rdp->qlen == 0 && rdp->qlen_last_fqs_check != 0) {
-               rdp->qlen_last_fqs_check = 0;
-               rdp->n_force_qs_snap = rsp->n_force_qs;
-       } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark)
-               rdp->qlen_last_fqs_check = rdp->qlen;
-       WARN_ON_ONCE((rdp->nxtlist == NULL) != (rdp->qlen == 0));
-
-       local_irq_restore(flags);
-
-       /* Re-invoke RCU core processing if there are callbacks remaining. */
-       if (cpu_has_callbacks_ready_to_invoke(rdp))
-               invoke_rcu_core();
-}
-
-/*
- * Check to see if this CPU is in a non-context-switch quiescent state
- * (user mode or idle loop for rcu, non-softirq execution for rcu_bh).
- * Also schedule RCU core processing.
- *
- * This function must be called from hardirq context.  It is normally
- * invoked from the scheduling-clock interrupt.  If rcu_pending returns
- * false, there is no point in invoking rcu_check_callbacks().
- */
-void rcu_check_callbacks(int cpu, int user)
-{
-       trace_rcu_utilization(TPS("Start scheduler-tick"));
-       increment_cpu_stall_ticks();
-       if (user || rcu_is_cpu_rrupt_from_idle()) {
-
-               /*
-                * Get here if this CPU took its interrupt from user
-                * mode or from the idle loop, and if this is not a
-                * nested interrupt.  In this case, the CPU is in
-                * a quiescent state, so note it.
-                *
-                * No memory barrier is required here because both
-                * rcu_sched_qs() and rcu_bh_qs() reference only CPU-local
-                * variables that other CPUs neither access nor modify,
-                * at least not while the corresponding CPU is online.
-                */
-
-               rcu_sched_qs(cpu);
-               rcu_bh_qs(cpu);
-
-       } else if (!in_softirq()) {
-
-               /*
-                * Get here if this CPU did not take its interrupt from
-                * softirq, in other words, if it is not interrupting
-                * a rcu_bh read-side critical section.  This is an _bh
-                * critical section, so note it.
-                */
-
-               rcu_bh_qs(cpu);
-       }
-       rcu_preempt_check_callbacks(cpu);
-       if (rcu_pending(cpu))
-               invoke_rcu_core();
-       trace_rcu_utilization(TPS("End scheduler-tick"));
-}
-
-/*
- * Scan the leaf rcu_node structures, processing dyntick state for any that
- * have not yet encountered a quiescent state, using the function specified.
- * Also initiate boosting for any threads blocked on the root rcu_node.
- *
- * The caller must have suppressed start of new grace periods.
- */
-static void force_qs_rnp(struct rcu_state *rsp,
-                        int (*f)(struct rcu_data *rsp, bool *isidle,
-                                 unsigned long *maxj),
-                        bool *isidle, unsigned long *maxj)
-{
-       unsigned long bit;
-       int cpu;
-       unsigned long flags;
-       unsigned long mask;
-       struct rcu_node *rnp;
-
-       rcu_for_each_leaf_node(rsp, rnp) {
-               cond_resched();
-               mask = 0;
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               if (!rcu_gp_in_progress(rsp)) {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-                       return;
-               }
-               if (rnp->qsmask == 0) {
-                       rcu_initiate_boost(rnp, flags); /* releases rnp->lock */
-                       continue;
-               }
-               cpu = rnp->grplo;
-               bit = 1;
-               for (; cpu <= rnp->grphi; cpu++, bit <<= 1) {
-                       if ((rnp->qsmask & bit) != 0) {
-                               if ((rnp->qsmaskinit & bit) != 0)
-                                       *isidle = 0;
-                               if (f(per_cpu_ptr(rsp->rda, cpu), isidle, maxj))
-                                       mask |= bit;
-                       }
-               }
-               if (mask != 0) {
-
-                       /* rcu_report_qs_rnp() releases rnp->lock. */
-                       rcu_report_qs_rnp(mask, rsp, rnp, flags);
-                       continue;
-               }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       }
-       rnp = rcu_get_root(rsp);
-       if (rnp->qsmask == 0) {
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */
-       }
-}
-
-/*
- * Force quiescent states on reluctant CPUs, and also detect which
- * CPUs are in dyntick-idle mode.
- */
-static void force_quiescent_state(struct rcu_state *rsp)
-{
-       unsigned long flags;
-       bool ret;
-       struct rcu_node *rnp;
-       struct rcu_node *rnp_old = NULL;
-
-       /* Funnel through hierarchy to reduce memory contention. */
-       rnp = per_cpu_ptr(rsp->rda, raw_smp_processor_id())->mynode;
-       for (; rnp != NULL; rnp = rnp->parent) {
-               ret = (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) ||
-                     !raw_spin_trylock(&rnp->fqslock);
-               if (rnp_old != NULL)
-                       raw_spin_unlock(&rnp_old->fqslock);
-               if (ret) {
-                       rsp->n_force_qs_lh++;
-                       return;
-               }
-               rnp_old = rnp;
-       }
-       /* rnp_old == rcu_get_root(rsp), rnp == NULL. */
-
-       /* Reached the root of the rcu_node tree, acquire lock. */
-       raw_spin_lock_irqsave(&rnp_old->lock, flags);
-       raw_spin_unlock(&rnp_old->fqslock);
-       if (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) {
-               rsp->n_force_qs_lh++;
-               raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
-               return;  /* Someone beat us to it. */
-       }
-       rsp->gp_flags |= RCU_GP_FLAG_FQS;
-       raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
-       wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
-}
-
-/*
- * This does the RCU core processing work for the specified rcu_state
- * and rcu_data structures.  This may be called only from the CPU to
- * whom the rdp belongs.
- */
-static void
-__rcu_process_callbacks(struct rcu_state *rsp)
-{
-       unsigned long flags;
-       struct rcu_data *rdp = __this_cpu_ptr(rsp->rda);
-
-       WARN_ON_ONCE(rdp->beenonline == 0);
-
-       /* Update RCU state based on any recent quiescent states. */
-       rcu_check_quiescent_state(rsp, rdp);
-
-       /* Does this CPU require a not-yet-started grace period? */
-       local_irq_save(flags);
-       if (cpu_needs_another_gp(rsp, rdp)) {
-               raw_spin_lock(&rcu_get_root(rsp)->lock); /* irqs disabled. */
-               rcu_start_gp(rsp);
-               raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
-       } else {
-               local_irq_restore(flags);
-       }
-
-       /* If there are callbacks ready, invoke them. */
-       if (cpu_has_callbacks_ready_to_invoke(rdp))
-               invoke_rcu_callbacks(rsp, rdp);
-}
-
-/*
- * Do RCU core processing for the current CPU.
- */
-static void rcu_process_callbacks(struct softirq_action *unused)
-{
-       struct rcu_state *rsp;
-
-       if (cpu_is_offline(smp_processor_id()))
-               return;
-       trace_rcu_utilization(TPS("Start RCU core"));
-       for_each_rcu_flavor(rsp)
-               __rcu_process_callbacks(rsp);
-       trace_rcu_utilization(TPS("End RCU core"));
-}
-
-/*
- * Schedule RCU callback invocation.  If the specified type of RCU
- * does not support RCU priority boosting, just do a direct call,
- * otherwise wake up the per-CPU kernel kthread.  Note that because we
- * are running on the current CPU with interrupts disabled, the
- * rcu_cpu_kthread_task cannot disappear out from under us.
- */
-static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       if (unlikely(!ACCESS_ONCE(rcu_scheduler_fully_active)))
-               return;
-       if (likely(!rsp->boost)) {
-               rcu_do_batch(rsp, rdp);
-               return;
-       }
-       invoke_rcu_callbacks_kthread();
-}
-
-static void invoke_rcu_core(void)
-{
-       if (cpu_online(smp_processor_id()))
-               raise_softirq(RCU_SOFTIRQ);
-}
-
-/*
- * Handle any core-RCU processing required by a call_rcu() invocation.
- */
-static void __call_rcu_core(struct rcu_state *rsp, struct rcu_data *rdp,
-                           struct rcu_head *head, unsigned long flags)
-{
-       /*
-        * If called from an extended quiescent state, invoke the RCU
-        * core in order to force a re-evaluation of RCU's idleness.
-        */
-       if (rcu_is_cpu_idle() && cpu_online(smp_processor_id()))
-               invoke_rcu_core();
-
-       /* If interrupts were disabled or CPU offline, don't invoke RCU core. */
-       if (irqs_disabled_flags(flags) || cpu_is_offline(smp_processor_id()))
-               return;
-
-       /*
-        * Force the grace period if too many callbacks or too long waiting.
-        * Enforce hysteresis, and don't invoke force_quiescent_state()
-        * if some other CPU has recently done so.  Also, don't bother
-        * invoking force_quiescent_state() if the newly enqueued callback
-        * is the only one waiting for a grace period to complete.
-        */
-       if (unlikely(rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) {
-
-               /* Are we ignoring a completed grace period? */
-               note_gp_changes(rsp, rdp);
-
-               /* Start a new grace period if one not already started. */
-               if (!rcu_gp_in_progress(rsp)) {
-                       struct rcu_node *rnp_root = rcu_get_root(rsp);
-
-                       raw_spin_lock(&rnp_root->lock);
-                       rcu_start_gp(rsp);
-                       raw_spin_unlock(&rnp_root->lock);
-               } else {
-                       /* Give the grace period a kick. */
-                       rdp->blimit = LONG_MAX;
-                       if (rsp->n_force_qs == rdp->n_force_qs_snap &&
-                           *rdp->nxttail[RCU_DONE_TAIL] != head)
-                               force_quiescent_state(rsp);
-                       rdp->n_force_qs_snap = rsp->n_force_qs;
-                       rdp->qlen_last_fqs_check = rdp->qlen;
-               }
-       }
-}
-
-/*
- * RCU callback function to leak a callback.
- */
-static void rcu_leak_callback(struct rcu_head *rhp)
-{
-}
-
-/*
- * Helper function for call_rcu() and friends.  The cpu argument will
- * normally be -1, indicating "currently running CPU".  It may specify
- * a CPU only if that CPU is a no-CBs CPU.  Currently, only _rcu_barrier()
- * is expected to specify a CPU.
- */
-static void
-__call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
-          struct rcu_state *rsp, int cpu, bool lazy)
-{
-       unsigned long flags;
-       struct rcu_data *rdp;
-
-       WARN_ON_ONCE((unsigned long)head & 0x3); /* Misaligned rcu_head! */
-       if (debug_rcu_head_queue(head)) {
-               /* Probable double call_rcu(), so leak the callback. */
-               ACCESS_ONCE(head->func) = rcu_leak_callback;
-               WARN_ONCE(1, "__call_rcu(): Leaked duplicate callback\n");
-               return;
-       }
-       head->func = func;
-       head->next = NULL;
-
-       /*
-        * Opportunistically note grace-period endings and beginnings.
-        * Note that we might see a beginning right after we see an
-        * end, but never vice versa, since this CPU has to pass through
-        * a quiescent state betweentimes.
-        */
-       local_irq_save(flags);
-       rdp = this_cpu_ptr(rsp->rda);
-
-       /* Add the callback to our list. */
-       if (unlikely(rdp->nxttail[RCU_NEXT_TAIL] == NULL) || cpu != -1) {
-               int offline;
-
-               if (cpu != -1)
-                       rdp = per_cpu_ptr(rsp->rda, cpu);
-               offline = !__call_rcu_nocb(rdp, head, lazy);
-               WARN_ON_ONCE(offline);
-               /* _call_rcu() is illegal on offline CPU; leak the callback. */
-               local_irq_restore(flags);
-               return;
-       }
-       ACCESS_ONCE(rdp->qlen)++;
-       if (lazy)
-               rdp->qlen_lazy++;
-       else
-               rcu_idle_count_callbacks_posted();
-       smp_mb();  /* Count before adding callback for rcu_barrier(). */
-       *rdp->nxttail[RCU_NEXT_TAIL] = head;
-       rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
-
-       if (__is_kfree_rcu_offset((unsigned long)func))
-               trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
-                                        rdp->qlen_lazy, rdp->qlen);
-       else
-               trace_rcu_callback(rsp->name, head, rdp->qlen_lazy, rdp->qlen);
-
-       /* Go handle any RCU core processing required. */
-       __call_rcu_core(rsp, rdp, head, flags);
-       local_irq_restore(flags);
-}
-
-/*
- * Queue an RCU-sched callback for invocation after a grace period.
- */
-void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_sched_state, -1, 0);
-}
-EXPORT_SYMBOL_GPL(call_rcu_sched);
-
-/*
- * Queue an RCU callback for invocation after a quicker grace period.
- */
-void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_bh_state, -1, 0);
-}
-EXPORT_SYMBOL_GPL(call_rcu_bh);
-
-/*
- * Because a context switch is a grace period for RCU-sched and RCU-bh,
- * any blocking grace-period wait automatically implies a grace period
- * if there is only one CPU online at any point time during execution
- * of either synchronize_sched() or synchronize_rcu_bh().  It is OK to
- * occasionally incorrectly indicate that there are multiple CPUs online
- * when there was in fact only one the whole time, as this just adds
- * some overhead: RCU still operates correctly.
- */
-static inline int rcu_blocking_is_gp(void)
-{
-       int ret;
-
-       might_sleep();  /* Check for RCU read-side critical section. */
-       preempt_disable();
-       ret = num_online_cpus() <= 1;
-       preempt_enable();
-       return ret;
-}
-
-/**
- * synchronize_sched - wait until an rcu-sched grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu-sched
- * grace period has elapsed, in other words after all currently executing
- * rcu-sched read-side critical sections have completed.   These read-side
- * critical sections are delimited by rcu_read_lock_sched() and
- * rcu_read_unlock_sched(), and may be nested.  Note that preempt_disable(),
- * local_irq_disable(), and so on may be used in place of
- * rcu_read_lock_sched().
- *
- * This means that all preempt_disable code sequences, including NMI and
- * non-threaded hardware-interrupt handlers, in progress on entry will
- * have completed before this primitive returns.  However, this does not
- * guarantee that softirq handlers will have completed, since in some
- * kernels, these handlers can run in process context, and can block.
- *
- * Note that this guarantee implies further memory-ordering guarantees.
- * On systems with more than one CPU, when synchronize_sched() returns,
- * each CPU is guaranteed to have executed a full memory barrier since the
- * end of its last RCU-sched read-side critical section whose beginning
- * preceded the call to synchronize_sched().  In addition, each CPU having
- * an RCU read-side critical section that extends beyond the return from
- * synchronize_sched() is guaranteed to have executed a full memory barrier
- * after the beginning of synchronize_sched() and before the beginning of
- * that RCU read-side critical section.  Note that these guarantees include
- * CPUs that are offline, idle, or executing in user mode, as well as CPUs
- * that are executing in the kernel.
- *
- * Furthermore, if CPU A invoked synchronize_sched(), which returned
- * to its caller on CPU B, then both CPU A and CPU B are guaranteed
- * to have executed a full memory barrier during the execution of
- * synchronize_sched() -- even if CPU A and CPU B are the same CPU (but
- * again only if the system has more than one CPU).
- *
- * This primitive provides the guarantees made by the (now removed)
- * synchronize_kernel() API.  In contrast, synchronize_rcu() only
- * guarantees that rcu_read_lock() sections will have completed.
- * In "classic RCU", these two guarantees happen to be one and
- * the same, but can differ in realtime RCU implementations.
- */
-void synchronize_sched(void)
-{
-       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
-                          !lock_is_held(&rcu_lock_map) &&
-                          !lock_is_held(&rcu_sched_lock_map),
-                          "Illegal synchronize_sched() in RCU-sched read-side critical section");
-       if (rcu_blocking_is_gp())
-               return;
-       if (rcu_expedited)
-               synchronize_sched_expedited();
-       else
-               wait_rcu_gp(call_rcu_sched);
-}
-EXPORT_SYMBOL_GPL(synchronize_sched);
-
-/**
- * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu_bh grace
- * period has elapsed, in other words after all currently executing rcu_bh
- * read-side critical sections have completed.  RCU read-side critical
- * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(),
- * and may be nested.
- *
- * See the description of synchronize_sched() for more detailed information
- * on memory ordering guarantees.
- */
-void synchronize_rcu_bh(void)
-{
-       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
-                          !lock_is_held(&rcu_lock_map) &&
-                          !lock_is_held(&rcu_sched_lock_map),
-                          "Illegal synchronize_rcu_bh() in RCU-bh read-side critical section");
-       if (rcu_blocking_is_gp())
-               return;
-       if (rcu_expedited)
-               synchronize_rcu_bh_expedited();
-       else
-               wait_rcu_gp(call_rcu_bh);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
-
-static int synchronize_sched_expedited_cpu_stop(void *data)
-{
-       /*
-        * There must be a full memory barrier on each affected CPU
-        * between the time that try_stop_cpus() is called and the
-        * time that it returns.
-        *
-        * In the current initial implementation of cpu_stop, the
-        * above condition is already met when the control reaches
-        * this point and the following smp_mb() is not strictly
-        * necessary.  Do smp_mb() anyway for documentation and
-        * robustness against future implementation changes.
-        */
-       smp_mb(); /* See above comment block. */
-       return 0;
-}
-
-/**
- * synchronize_sched_expedited - Brute-force RCU-sched grace period
- *
- * Wait for an RCU-sched grace period to elapse, but use a "big hammer"
- * approach to force the grace period to end quickly.  This consumes
- * significant time on all CPUs and is unfriendly to real-time workloads,
- * so is thus not recommended for any sort of common-case code.  In fact,
- * if you are using synchronize_sched_expedited() in a loop, please
- * restructure your code to batch your updates, and then use a single
- * synchronize_sched() instead.
- *
- * Note that it is illegal to call this function while holding any lock
- * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
- * to call this function from a CPU-hotplug notifier.  Failing to observe
- * these restriction will result in deadlock.
- *
- * This implementation can be thought of as an application of ticket
- * locking to RCU, with sync_sched_expedited_started and
- * sync_sched_expedited_done taking on the roles of the halves
- * of the ticket-lock word.  Each task atomically increments
- * sync_sched_expedited_started upon entry, snapshotting the old value,
- * then attempts to stop all the CPUs.  If this succeeds, then each
- * CPU will have executed a context switch, resulting in an RCU-sched
- * grace period.  We are then done, so we use atomic_cmpxchg() to
- * update sync_sched_expedited_done to match our snapshot -- but
- * only if someone else has not already advanced past our snapshot.
- *
- * On the other hand, if try_stop_cpus() fails, we check the value
- * of sync_sched_expedited_done.  If it has advanced past our
- * initial snapshot, then someone else must have forced a grace period
- * some time after we took our snapshot.  In this case, our work is
- * done for us, and we can simply return.  Otherwise, we try again,
- * but keep our initial snapshot for purposes of checking for someone
- * doing our work for us.
- *
- * If we fail too many times in a row, we fall back to synchronize_sched().
- */
-void synchronize_sched_expedited(void)
-{
-       long firstsnap, s, snap;
-       int trycount = 0;
-       struct rcu_state *rsp = &rcu_sched_state;
-
-       /*
-        * If we are in danger of counter wrap, just do synchronize_sched().
-        * By allowing sync_sched_expedited_started to advance no more than
-        * ULONG_MAX/8 ahead of sync_sched_expedited_done, we are ensuring
-        * that more than 3.5 billion CPUs would be required to force a
-        * counter wrap on a 32-bit system.  Quite a few more CPUs would of
-        * course be required on a 64-bit system.
-        */
-       if (ULONG_CMP_GE((ulong)atomic_long_read(&rsp->expedited_start),
-                        (ulong)atomic_long_read(&rsp->expedited_done) +
-                        ULONG_MAX / 8)) {
-               synchronize_sched();
-               atomic_long_inc(&rsp->expedited_wrap);
-               return;
-       }
-
-       /*
-        * Take a ticket.  Note that atomic_inc_return() implies a
-        * full memory barrier.
-        */
-       snap = atomic_long_inc_return(&rsp->expedited_start);
-       firstsnap = snap;
-       get_online_cpus();
-       WARN_ON_ONCE(cpu_is_offline(raw_smp_processor_id()));
-
-       /*
-        * Each pass through the following loop attempts to force a
-        * context switch on each CPU.
-        */
-       while (try_stop_cpus(cpu_online_mask,
-                            synchronize_sched_expedited_cpu_stop,
-                            NULL) == -EAGAIN) {
-               put_online_cpus();
-               atomic_long_inc(&rsp->expedited_tryfail);
-
-               /* Check to see if someone else did our work for us. */
-               s = atomic_long_read(&rsp->expedited_done);
-               if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) {
-                       /* ensure test happens before caller kfree */
-                       smp_mb__before_atomic_inc(); /* ^^^ */
-                       atomic_long_inc(&rsp->expedited_workdone1);
-                       return;
-               }
-
-               /* No joy, try again later.  Or just synchronize_sched(). */
-               if (trycount++ < 10) {
-                       udelay(trycount * num_online_cpus());
-               } else {
-                       wait_rcu_gp(call_rcu_sched);
-                       atomic_long_inc(&rsp->expedited_normal);
-                       return;
-               }
-
-               /* Recheck to see if someone else did our work for us. */
-               s = atomic_long_read(&rsp->expedited_done);
-               if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) {
-                       /* ensure test happens before caller kfree */
-                       smp_mb__before_atomic_inc(); /* ^^^ */
-                       atomic_long_inc(&rsp->expedited_workdone2);
-                       return;
-               }
-
-               /*
-                * Refetching sync_sched_expedited_started allows later
-                * callers to piggyback on our grace period.  We retry
-                * after they started, so our grace period works for them,
-                * and they started after our first try, so their grace
-                * period works for us.
-                */
-               get_online_cpus();
-               snap = atomic_long_read(&rsp->expedited_start);
-               smp_mb(); /* ensure read is before try_stop_cpus(). */
-       }
-       atomic_long_inc(&rsp->expedited_stoppedcpus);
-
-       /*
-        * Everyone up to our most recent fetch is covered by our grace
-        * period.  Update the counter, but only if our work is still
-        * relevant -- which it won't be if someone who started later
-        * than we did already did their update.
-        */
-       do {
-               atomic_long_inc(&rsp->expedited_done_tries);
-               s = atomic_long_read(&rsp->expedited_done);
-               if (ULONG_CMP_GE((ulong)s, (ulong)snap)) {
-                       /* ensure test happens before caller kfree */
-                       smp_mb__before_atomic_inc(); /* ^^^ */
-                       atomic_long_inc(&rsp->expedited_done_lost);
-                       break;
-               }
-       } while (atomic_long_cmpxchg(&rsp->expedited_done, s, snap) != s);
-       atomic_long_inc(&rsp->expedited_done_exit);
-
-       put_online_cpus();
-}
-EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
-
-/*
- * Check to see if there is any immediate RCU-related work to be done
- * by the current CPU, for the specified type of RCU, returning 1 if so.
- * The checks are in order of increasing expense: checks that can be
- * carried out against CPU-local state are performed first.  However,
- * we must check for CPU stalls first, else we might not get a chance.
- */
-static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       struct rcu_node *rnp = rdp->mynode;
-
-       rdp->n_rcu_pending++;
-
-       /* Check for CPU stalls, if enabled. */
-       check_cpu_stall(rsp, rdp);
-
-       /* Is the RCU core waiting for a quiescent state from this CPU? */
-       if (rcu_scheduler_fully_active &&
-           rdp->qs_pending && !rdp->passed_quiesce) {
-               rdp->n_rp_qs_pending++;
-       } else if (rdp->qs_pending && rdp->passed_quiesce) {
-               rdp->n_rp_report_qs++;
-               return 1;
-       }
-
-       /* Does this CPU have callbacks ready to invoke? */
-       if (cpu_has_callbacks_ready_to_invoke(rdp)) {
-               rdp->n_rp_cb_ready++;
-               return 1;
-       }
-
-       /* Has RCU gone idle with this CPU needing another grace period? */
-       if (cpu_needs_another_gp(rsp, rdp)) {
-               rdp->n_rp_cpu_needs_gp++;
-               return 1;
-       }
-
-       /* Has another RCU grace period completed?  */
-       if (ACCESS_ONCE(rnp->completed) != rdp->completed) { /* outside lock */
-               rdp->n_rp_gp_completed++;
-               return 1;
-       }
-
-       /* Has a new RCU grace period started? */
-       if (ACCESS_ONCE(rnp->gpnum) != rdp->gpnum) { /* outside lock */
-               rdp->n_rp_gp_started++;
-               return 1;
-       }
-
-       /* nothing to do */
-       rdp->n_rp_need_nothing++;
-       return 0;
-}
-
-/*
- * Check to see if there is any immediate RCU-related work to be done
- * by the current CPU, returning 1 if so.  This function is part of the
- * RCU implementation; it is -not- an exported member of the RCU API.
- */
-static int rcu_pending(int cpu)
-{
-       struct rcu_state *rsp;
-
-       for_each_rcu_flavor(rsp)
-               if (__rcu_pending(rsp, per_cpu_ptr(rsp->rda, cpu)))
-                       return 1;
-       return 0;
-}
-
-/*
- * Return true if the specified CPU has any callback.  If all_lazy is
- * non-NULL, store an indication of whether all callbacks are lazy.
- * (If there are no callbacks, all of them are deemed to be lazy.)
- */
-static int rcu_cpu_has_callbacks(int cpu, bool *all_lazy)
-{
-       bool al = true;
-       bool hc = false;
-       struct rcu_data *rdp;
-       struct rcu_state *rsp;
-
-       for_each_rcu_flavor(rsp) {
-               rdp = per_cpu_ptr(rsp->rda, cpu);
-               if (rdp->qlen != rdp->qlen_lazy)
-                       al = false;
-               if (rdp->nxtlist)
-                       hc = true;
-       }
-       if (all_lazy)
-               *all_lazy = al;
-       return hc;
-}
-
-/*
- * Helper function for _rcu_barrier() tracing.  If tracing is disabled,
- * the compiler is expected to optimize this away.
- */
-static void _rcu_barrier_trace(struct rcu_state *rsp, const char *s,
-                              int cpu, unsigned long done)
-{
-       trace_rcu_barrier(rsp->name, s, cpu,
-                         atomic_read(&rsp->barrier_cpu_count), done);
-}
-
-/*
- * RCU callback function for _rcu_barrier().  If we are last, wake
- * up the task executing _rcu_barrier().
- */
-static void rcu_barrier_callback(struct rcu_head *rhp)
-{
-       struct rcu_data *rdp = container_of(rhp, struct rcu_data, barrier_head);
-       struct rcu_state *rsp = rdp->rsp;
-
-       if (atomic_dec_and_test(&rsp->barrier_cpu_count)) {
-               _rcu_barrier_trace(rsp, "LastCB", -1, rsp->n_barrier_done);
-               complete(&rsp->barrier_completion);
-       } else {
-               _rcu_barrier_trace(rsp, "CB", -1, rsp->n_barrier_done);
-       }
-}
-
-/*
- * Called with preemption disabled, and from cross-cpu IRQ context.
- */
-static void rcu_barrier_func(void *type)
-{
-       struct rcu_state *rsp = type;
-       struct rcu_data *rdp = __this_cpu_ptr(rsp->rda);
-
-       _rcu_barrier_trace(rsp, "IRQ", -1, rsp->n_barrier_done);
-       atomic_inc(&rsp->barrier_cpu_count);
-       rsp->call(&rdp->barrier_head, rcu_barrier_callback);
-}
-
-/*
- * Orchestrate the specified type of RCU barrier, waiting for all
- * RCU callbacks of the specified type to complete.
- */
-static void _rcu_barrier(struct rcu_state *rsp)
-{
-       int cpu;
-       struct rcu_data *rdp;
-       unsigned long snap = ACCESS_ONCE(rsp->n_barrier_done);
-       unsigned long snap_done;
-
-       _rcu_barrier_trace(rsp, "Begin", -1, snap);
-
-       /* Take mutex to serialize concurrent rcu_barrier() requests. */
-       mutex_lock(&rsp->barrier_mutex);
-
-       /*
-        * Ensure that all prior references, including to ->n_barrier_done,
-        * are ordered before the _rcu_barrier() machinery.
-        */
-       smp_mb();  /* See above block comment. */
-
-       /*
-        * Recheck ->n_barrier_done to see if others did our work for us.
-        * This means checking ->n_barrier_done for an even-to-odd-to-even
-        * transition.  The "if" expression below therefore rounds the old
-        * value up to the next even number and adds two before comparing.
-        */
-       snap_done = rsp->n_barrier_done;
-       _rcu_barrier_trace(rsp, "Check", -1, snap_done);
-
-       /*
-        * If the value in snap is odd, we needed to wait for the current
-        * rcu_barrier() to complete, then wait for the next one, in other
-        * words, we need the value of snap_done to be three larger than
-        * the value of snap.  On the other hand, if the value in snap is
-        * even, we only had to wait for the next rcu_barrier() to complete,
-        * in other words, we need the value of snap_done to be only two
-        * greater than the value of snap.  The "(snap + 3) & ~0x1" computes
-        * this for us (thank you, Linus!).
-        */
-       if (ULONG_CMP_GE(snap_done, (snap + 3) & ~0x1)) {
-               _rcu_barrier_trace(rsp, "EarlyExit", -1, snap_done);
-               smp_mb(); /* caller's subsequent code after above check. */
-               mutex_unlock(&rsp->barrier_mutex);
-               return;
-       }
-
-       /*
-        * Increment ->n_barrier_done to avoid duplicate work.  Use
-        * ACCESS_ONCE() to prevent the compiler from speculating
-        * the increment to precede the early-exit check.
-        */
-       ACCESS_ONCE(rsp->n_barrier_done)++;
-       WARN_ON_ONCE((rsp->n_barrier_done & 0x1) != 1);
-       _rcu_barrier_trace(rsp, "Inc1", -1, rsp->n_barrier_done);
-       smp_mb(); /* Order ->n_barrier_done increment with below mechanism. */
-
-       /*
-        * Initialize the count to one rather than to zero in order to
-        * avoid a too-soon return to zero in case of a short grace period
-        * (or preemption of this task).  Exclude CPU-hotplug operations
-        * to ensure that no offline CPU has callbacks queued.
-        */
-       init_completion(&rsp->barrier_completion);
-       atomic_set(&rsp->barrier_cpu_count, 1);
-       get_online_cpus();
-
-       /*
-        * Force each CPU with callbacks to register a new callback.
-        * When that callback is invoked, we will know that all of the
-        * corresponding CPU's preceding callbacks have been invoked.
-        */
-       for_each_possible_cpu(cpu) {
-               if (!cpu_online(cpu) && !rcu_is_nocb_cpu(cpu))
-                       continue;
-               rdp = per_cpu_ptr(rsp->rda, cpu);
-               if (rcu_is_nocb_cpu(cpu)) {
-                       _rcu_barrier_trace(rsp, "OnlineNoCB", cpu,
-                                          rsp->n_barrier_done);
-                       atomic_inc(&rsp->barrier_cpu_count);
-                       __call_rcu(&rdp->barrier_head, rcu_barrier_callback,
-                                  rsp, cpu, 0);
-               } else if (ACCESS_ONCE(rdp->qlen)) {
-                       _rcu_barrier_trace(rsp, "OnlineQ", cpu,
-                                          rsp->n_barrier_done);
-                       smp_call_function_single(cpu, rcu_barrier_func, rsp, 1);
-               } else {
-                       _rcu_barrier_trace(rsp, "OnlineNQ", cpu,
-                                          rsp->n_barrier_done);
-               }
-       }
-       put_online_cpus();
-
-       /*
-        * Now that we have an rcu_barrier_callback() callback on each
-        * CPU, and thus each counted, remove the initial count.
-        */
-       if (atomic_dec_and_test(&rsp->barrier_cpu_count))
-               complete(&rsp->barrier_completion);
-
-       /* Increment ->n_barrier_done to prevent duplicate work. */
-       smp_mb(); /* Keep increment after above mechanism. */
-       ACCESS_ONCE(rsp->n_barrier_done)++;
-       WARN_ON_ONCE((rsp->n_barrier_done & 0x1) != 0);
-       _rcu_barrier_trace(rsp, "Inc2", -1, rsp->n_barrier_done);
-       smp_mb(); /* Keep increment before caller's subsequent code. */
-
-       /* Wait for all rcu_barrier_callback() callbacks to be invoked. */
-       wait_for_completion(&rsp->barrier_completion);
-
-       /* Other rcu_barrier() invocations can now safely proceed. */
-       mutex_unlock(&rsp->barrier_mutex);
-}
-
-/**
- * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
- */
-void rcu_barrier_bh(void)
-{
-       _rcu_barrier(&rcu_bh_state);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_bh);
-
-/**
- * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
- */
-void rcu_barrier_sched(void)
-{
-       _rcu_barrier(&rcu_sched_state);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_sched);
-
-/*
- * Do boot-time initialization of a CPU's per-CPU RCU data.
- */
-static void __init
-rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
-{
-       unsigned long flags;
-       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       /* Set up local state, ensuring consistent view of global state. */
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       rdp->grpmask = 1UL << (cpu - rdp->mynode->grplo);
-       init_callback_list(rdp);
-       rdp->qlen_lazy = 0;
-       ACCESS_ONCE(rdp->qlen) = 0;
-       rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
-       WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE);
-       WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1);
-       rdp->cpu = cpu;
-       rdp->rsp = rsp;
-       rcu_boot_init_nocb_percpu_data(rdp);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-}
-
-/*
- * Initialize a CPU's per-CPU RCU data.  Note that only one online or
- * offline event can be happening at a given time.  Note also that we
- * can accept some slop in the rsp->completed access due to the fact
- * that this CPU cannot possibly have any RCU callbacks in flight yet.
- */
-static void
-rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
-{
-       unsigned long flags;
-       unsigned long mask;
-       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       /* Exclude new grace periods. */
-       mutex_lock(&rsp->onoff_mutex);
-
-       /* Set up local state, ensuring consistent view of global state. */
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       rdp->beenonline = 1;     /* We have now been online. */
-       rdp->preemptible = preemptible;
-       rdp->qlen_last_fqs_check = 0;
-       rdp->n_force_qs_snap = rsp->n_force_qs;
-       rdp->blimit = blimit;
-       init_callback_list(rdp);  /* Re-enable callbacks on this CPU. */
-       rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
-       rcu_sysidle_init_percpu_data(rdp->dynticks);
-       atomic_set(&rdp->dynticks->dynticks,
-                  (atomic_read(&rdp->dynticks->dynticks) & ~0x1) + 1);
-       raw_spin_unlock(&rnp->lock);            /* irqs remain disabled. */
-
-       /* Add CPU to rcu_node bitmasks. */
-       rnp = rdp->mynode;
-       mask = rdp->grpmask;
-       do {
-               /* Exclude any attempts to start a new GP on small systems. */
-               raw_spin_lock(&rnp->lock);      /* irqs already disabled. */
-               rnp->qsmaskinit |= mask;
-               mask = rnp->grpmask;
-               if (rnp == rdp->mynode) {
-                       /*
-                        * If there is a grace period in progress, we will
-                        * set up to wait for it next time we run the
-                        * RCU core code.
-                        */
-                       rdp->gpnum = rnp->completed;
-                       rdp->completed = rnp->completed;
-                       rdp->passed_quiesce = 0;
-                       rdp->qs_pending = 0;
-                       trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuonl"));
-               }
-               raw_spin_unlock(&rnp->lock); /* irqs already disabled. */
-               rnp = rnp->parent;
-       } while (rnp != NULL && !(rnp->qsmaskinit & mask));
-       local_irq_restore(flags);
-
-       mutex_unlock(&rsp->onoff_mutex);
-}
-
-static void rcu_prepare_cpu(int cpu)
-{
-       struct rcu_state *rsp;
-
-       for_each_rcu_flavor(rsp)
-               rcu_init_percpu_data(cpu, rsp,
-                                    strcmp(rsp->name, "rcu_preempt") == 0);
-}
-
-/*
- * Handle CPU online/offline notification events.
- */
-static int rcu_cpu_notify(struct notifier_block *self,
-                                   unsigned long action, void *hcpu)
-{
-       long cpu = (long)hcpu;
-       struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
-       struct rcu_node *rnp = rdp->mynode;
-       struct rcu_state *rsp;
-
-       trace_rcu_utilization(TPS("Start CPU hotplug"));
-       switch (action) {
-       case CPU_UP_PREPARE:
-       case CPU_UP_PREPARE_FROZEN:
-               rcu_prepare_cpu(cpu);
-               rcu_prepare_kthreads(cpu);
-               break;
-       case CPU_ONLINE:
-       case CPU_DOWN_FAILED:
-               rcu_boost_kthread_setaffinity(rnp, -1);
-               break;
-       case CPU_DOWN_PREPARE:
-               rcu_boost_kthread_setaffinity(rnp, cpu);
-               break;
-       case CPU_DYING:
-       case CPU_DYING_FROZEN:
-               for_each_rcu_flavor(rsp)
-                       rcu_cleanup_dying_cpu(rsp);
-               break;
-       case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
-       case CPU_UP_CANCELED:
-       case CPU_UP_CANCELED_FROZEN:
-               for_each_rcu_flavor(rsp)
-                       rcu_cleanup_dead_cpu(cpu, rsp);
-               break;
-       default:
-               break;
-       }
-       trace_rcu_utilization(TPS("End CPU hotplug"));
-       return NOTIFY_OK;
-}
-
-static int rcu_pm_notify(struct notifier_block *self,
-                        unsigned long action, void *hcpu)
-{
-       switch (action) {
-       case PM_HIBERNATION_PREPARE:
-       case PM_SUSPEND_PREPARE:
-               if (nr_cpu_ids <= 256) /* Expediting bad for large systems. */
-                       rcu_expedited = 1;
-               break;
-       case PM_POST_HIBERNATION:
-       case PM_POST_SUSPEND:
-               rcu_expedited = 0;
-               break;
-       default:
-               break;
-       }
-       return NOTIFY_OK;
-}
-
-/*
- * Spawn the kthread that handles this RCU flavor's grace periods.
- */
-static int __init rcu_spawn_gp_kthread(void)
-{
-       unsigned long flags;
-       struct rcu_node *rnp;
-       struct rcu_state *rsp;
-       struct task_struct *t;
-
-       for_each_rcu_flavor(rsp) {
-               t = kthread_run(rcu_gp_kthread, rsp, "%s", rsp->name);
-               BUG_ON(IS_ERR(t));
-               rnp = rcu_get_root(rsp);
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               rsp->gp_kthread = t;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               rcu_spawn_nocb_kthreads(rsp);
-       }
-       return 0;
-}
-early_initcall(rcu_spawn_gp_kthread);
-
-/*
- * This function is invoked towards the end of the scheduler's initialization
- * process.  Before this is called, the idle task might contain
- * RCU read-side critical sections (during which time, this idle
- * task is booting the system).  After this function is called, the
- * idle tasks are prohibited from containing RCU read-side critical
- * sections.  This function also enables RCU lockdep checking.
- */
-void rcu_scheduler_starting(void)
-{
-       WARN_ON(num_online_cpus() != 1);
-       WARN_ON(nr_context_switches() > 0);
-       rcu_scheduler_active = 1;
-}
-
-/*
- * Compute the per-level fanout, either using the exact fanout specified
- * or balancing the tree, depending on CONFIG_RCU_FANOUT_EXACT.
- */
-#ifdef CONFIG_RCU_FANOUT_EXACT
-static void __init rcu_init_levelspread(struct rcu_state *rsp)
-{
-       int i;
-
-       for (i = rcu_num_lvls - 1; i > 0; i--)
-               rsp->levelspread[i] = CONFIG_RCU_FANOUT;
-       rsp->levelspread[0] = rcu_fanout_leaf;
-}
-#else /* #ifdef CONFIG_RCU_FANOUT_EXACT */
-static void __init rcu_init_levelspread(struct rcu_state *rsp)
-{
-       int ccur;
-       int cprv;
-       int i;
-
-       cprv = nr_cpu_ids;
-       for (i = rcu_num_lvls - 1; i >= 0; i--) {
-               ccur = rsp->levelcnt[i];
-               rsp->levelspread[i] = (cprv + ccur - 1) / ccur;
-               cprv = ccur;
-       }
-}
-#endif /* #else #ifdef CONFIG_RCU_FANOUT_EXACT */
-
-/*
- * Helper function for rcu_init() that initializes one rcu_state structure.
- */
-static void __init rcu_init_one(struct rcu_state *rsp,
-               struct rcu_data __percpu *rda)
-{
-       static char *buf[] = { "rcu_node_0",
-                              "rcu_node_1",
-                              "rcu_node_2",
-                              "rcu_node_3" };  /* Match MAX_RCU_LVLS */
-       static char *fqs[] = { "rcu_node_fqs_0",
-                              "rcu_node_fqs_1",
-                              "rcu_node_fqs_2",
-                              "rcu_node_fqs_3" };  /* Match MAX_RCU_LVLS */
-       int cpustride = 1;
-       int i;
-       int j;
-       struct rcu_node *rnp;
-
-       BUILD_BUG_ON(MAX_RCU_LVLS > ARRAY_SIZE(buf));  /* Fix buf[] init! */
-
-       /* Silence gcc 4.8 warning about array index out of range. */
-       if (rcu_num_lvls > RCU_NUM_LVLS)
-               panic("rcu_init_one: rcu_num_lvls overflow");
-
-       /* Initialize the level-tracking arrays. */
-
-       for (i = 0; i < rcu_num_lvls; i++)
-               rsp->levelcnt[i] = num_rcu_lvl[i];
-       for (i = 1; i < rcu_num_lvls; i++)
-               rsp->level[i] = rsp->level[i - 1] + rsp->levelcnt[i - 1];
-       rcu_init_levelspread(rsp);
-
-       /* Initialize the elements themselves, starting from the leaves. */
-
-       for (i = rcu_num_lvls - 1; i >= 0; i--) {
-               cpustride *= rsp->levelspread[i];
-               rnp = rsp->level[i];
-               for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) {
-                       raw_spin_lock_init(&rnp->lock);
-                       lockdep_set_class_and_name(&rnp->lock,
-                                                  &rcu_node_class[i], buf[i]);
-                       raw_spin_lock_init(&rnp->fqslock);
-                       lockdep_set_class_and_name(&rnp->fqslock,
-                                                  &rcu_fqs_class[i], fqs[i]);
-                       rnp->gpnum = rsp->gpnum;
-                       rnp->completed = rsp->completed;
-                       rnp->qsmask = 0;
-                       rnp->qsmaskinit = 0;
-                       rnp->grplo = j * cpustride;
-                       rnp->grphi = (j + 1) * cpustride - 1;
-                       if (rnp->grphi >= NR_CPUS)
-                               rnp->grphi = NR_CPUS - 1;
-                       if (i == 0) {
-                               rnp->grpnum = 0;
-                               rnp->grpmask = 0;
-                               rnp->parent = NULL;
-                       } else {
-                               rnp->grpnum = j % rsp->levelspread[i - 1];
-                               rnp->grpmask = 1UL << rnp->grpnum;
-                               rnp->parent = rsp->level[i - 1] +
-                                             j / rsp->levelspread[i - 1];
-                       }
-                       rnp->level = i;
-                       INIT_LIST_HEAD(&rnp->blkd_tasks);
-                       rcu_init_one_nocb(rnp);
-               }
-       }
-
-       rsp->rda = rda;
-       init_waitqueue_head(&rsp->gp_wq);
-       init_irq_work(&rsp->wakeup_work, rsp_wakeup);
-       rnp = rsp->level[rcu_num_lvls - 1];
-       for_each_possible_cpu(i) {
-               while (i > rnp->grphi)
-                       rnp++;
-               per_cpu_ptr(rsp->rda, i)->mynode = rnp;
-               rcu_boot_init_percpu_data(i, rsp);
-       }
-       list_add(&rsp->flavors, &rcu_struct_flavors);
-}
-
-/*
- * Compute the rcu_node tree geometry from kernel parameters.  This cannot
- * replace the definitions in rcutree.h because those are needed to size
- * the ->node array in the rcu_state structure.
- */
-static void __init rcu_init_geometry(void)
-{
-       ulong d;
-       int i;
-       int j;
-       int n = nr_cpu_ids;
-       int rcu_capacity[MAX_RCU_LVLS + 1];
-
-       /*
-        * Initialize any unspecified boot parameters.
-        * The default values of jiffies_till_first_fqs and
-        * jiffies_till_next_fqs are set to the RCU_JIFFIES_TILL_FORCE_QS
-        * value, which is a function of HZ, then adding one for each
-        * RCU_JIFFIES_FQS_DIV CPUs that might be on the system.
-        */
-       d = RCU_JIFFIES_TILL_FORCE_QS + nr_cpu_ids / RCU_JIFFIES_FQS_DIV;
-       if (jiffies_till_first_fqs == ULONG_MAX)
-               jiffies_till_first_fqs = d;
-       if (jiffies_till_next_fqs == ULONG_MAX)
-               jiffies_till_next_fqs = d;
-
-       /* If the compile-time values are accurate, just leave. */
-       if (rcu_fanout_leaf == CONFIG_RCU_FANOUT_LEAF &&
-           nr_cpu_ids == NR_CPUS)
-               return;
-
-       /*
-        * Compute number of nodes that can be handled an rcu_node tree
-        * with the given number of levels.  Setting rcu_capacity[0] makes
-        * some of the arithmetic easier.
-        */
-       rcu_capacity[0] = 1;
-       rcu_capacity[1] = rcu_fanout_leaf;
-       for (i = 2; i <= MAX_RCU_LVLS; i++)
-               rcu_capacity[i] = rcu_capacity[i - 1] * CONFIG_RCU_FANOUT;
-
-       /*
-        * The boot-time rcu_fanout_leaf parameter is only permitted
-        * to increase the leaf-level fanout, not decrease it.  Of course,
-        * the leaf-level fanout cannot exceed the number of bits in
-        * the rcu_node masks.  Finally, the tree must be able to accommodate
-        * the configured number of CPUs.  Complain and fall back to the
-        * compile-time values if these limits are exceeded.
-        */
-       if (rcu_fanout_leaf < CONFIG_RCU_FANOUT_LEAF ||
-           rcu_fanout_leaf > sizeof(unsigned long) * 8 ||
-           n > rcu_capacity[MAX_RCU_LVLS]) {
-               WARN_ON(1);
-               return;
-       }
-
-       /* Calculate the number of rcu_nodes at each level of the tree. */
-       for (i = 1; i <= MAX_RCU_LVLS; i++)
-               if (n <= rcu_capacity[i]) {
-                       for (j = 0; j <= i; j++)
-                               num_rcu_lvl[j] =
-                                       DIV_ROUND_UP(n, rcu_capacity[i - j]);
-                       rcu_num_lvls = i;
-                       for (j = i + 1; j <= MAX_RCU_LVLS; j++)
-                               num_rcu_lvl[j] = 0;
-                       break;
-               }
-
-       /* Calculate the total number of rcu_node structures. */
-       rcu_num_nodes = 0;
-       for (i = 0; i <= MAX_RCU_LVLS; i++)
-               rcu_num_nodes += num_rcu_lvl[i];
-       rcu_num_nodes -= n;
-}
-
-void __init rcu_init(void)
-{
-       int cpu;
-
-       rcu_bootup_announce();
-       rcu_init_geometry();
-       rcu_init_one(&rcu_sched_state, &rcu_sched_data);
-       rcu_init_one(&rcu_bh_state, &rcu_bh_data);
-       __rcu_init_preempt();
-       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
-
-       /*
-        * We don't need protection against CPU-hotplug here because
-        * this is called early in boot, before either interrupts
-        * or the scheduler are operational.
-        */
-       cpu_notifier(rcu_cpu_notify, 0);
-       pm_notifier(rcu_pm_notify, 0);
-       for_each_online_cpu(cpu)
-               rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
-}
-
-#include "rcutree_plugin.h"
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
deleted file mode 100644 (file)
index 5f97eab..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Read-Copy Update mechanism for mutual exclusion (tree-based version)
- * Internal non-public definitions.
- *
- * 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 IBM Corporation, 2008
- *
- * Author: Ingo Molnar <mingo@elte.hu>
- *        Paul E. McKenney <paulmck@linux.vnet.ibm.com>
- */
-
-#include <linux/cache.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/seqlock.h>
-#include <linux/irq_work.h>
-
-/*
- * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
- * CONFIG_RCU_FANOUT_LEAF.
- * In theory, it should be possible to add more levels straightforwardly.
- * In practice, this did work well going from three levels to four.
- * Of course, your mileage may vary.
- */
-#define MAX_RCU_LVLS 4
-#define RCU_FANOUT_1         (CONFIG_RCU_FANOUT_LEAF)
-#define RCU_FANOUT_2         (RCU_FANOUT_1 * CONFIG_RCU_FANOUT)
-#define RCU_FANOUT_3         (RCU_FANOUT_2 * CONFIG_RCU_FANOUT)
-#define RCU_FANOUT_4         (RCU_FANOUT_3 * CONFIG_RCU_FANOUT)
-
-#if NR_CPUS <= RCU_FANOUT_1
-#  define RCU_NUM_LVLS       1
-#  define NUM_RCU_LVL_0              1
-#  define NUM_RCU_LVL_1              (NR_CPUS)
-#  define NUM_RCU_LVL_2              0
-#  define NUM_RCU_LVL_3              0
-#  define NUM_RCU_LVL_4              0
-#elif NR_CPUS <= RCU_FANOUT_2
-#  define RCU_NUM_LVLS       2
-#  define NUM_RCU_LVL_0              1
-#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
-#  define NUM_RCU_LVL_2              (NR_CPUS)
-#  define NUM_RCU_LVL_3              0
-#  define NUM_RCU_LVL_4              0
-#elif NR_CPUS <= RCU_FANOUT_3
-#  define RCU_NUM_LVLS       3
-#  define NUM_RCU_LVL_0              1
-#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2)
-#  define NUM_RCU_LVL_2              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
-#  define NUM_RCU_LVL_3              (NR_CPUS)
-#  define NUM_RCU_LVL_4              0
-#elif NR_CPUS <= RCU_FANOUT_4
-#  define RCU_NUM_LVLS       4
-#  define NUM_RCU_LVL_0              1
-#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3)
-#  define NUM_RCU_LVL_2              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2)
-#  define NUM_RCU_LVL_3              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
-#  define NUM_RCU_LVL_4              (NR_CPUS)
-#else
-# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
-#endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */
-
-#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4)
-#define NUM_RCU_NODES (RCU_SUM - NR_CPUS)
-
-extern int rcu_num_lvls;
-extern int rcu_num_nodes;
-
-/*
- * Dynticks per-CPU state.
- */
-struct rcu_dynticks {
-       long long dynticks_nesting; /* Track irq/process nesting level. */
-                                   /* Process level is worth LLONG_MAX/2. */
-       int dynticks_nmi_nesting;   /* Track NMI nesting level. */
-       atomic_t dynticks;          /* Even value for idle, else odd. */
-#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
-       long long dynticks_idle_nesting;
-                                   /* irq/process nesting level from idle. */
-       atomic_t dynticks_idle;     /* Even value for idle, else odd. */
-                                   /*  "Idle" excludes userspace execution. */
-       unsigned long dynticks_idle_jiffies;
-                                   /* End of last non-NMI non-idle period. */
-#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
-#ifdef CONFIG_RCU_FAST_NO_HZ
-       bool all_lazy;              /* Are all CPU's CBs lazy? */
-       unsigned long nonlazy_posted;
-                                   /* # times non-lazy CBs posted to CPU. */
-       unsigned long nonlazy_posted_snap;
-                                   /* idle-period nonlazy_posted snapshot. */
-       unsigned long last_accelerate;
-                                   /* Last jiffy CBs were accelerated. */
-       int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */
-#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */
-};
-
-/* RCU's kthread states for tracing. */
-#define RCU_KTHREAD_STOPPED  0
-#define RCU_KTHREAD_RUNNING  1
-#define RCU_KTHREAD_WAITING  2
-#define RCU_KTHREAD_OFFCPU   3
-#define RCU_KTHREAD_YIELDING 4
-#define RCU_KTHREAD_MAX      4
-
-/*
- * Definition for node within the RCU grace-period-detection hierarchy.
- */
-struct rcu_node {
-       raw_spinlock_t lock;    /* Root rcu_node's lock protects some */
-                               /*  rcu_state fields as well as following. */
-       unsigned long gpnum;    /* Current grace period for this node. */
-                               /*  This will either be equal to or one */
-                               /*  behind the root rcu_node's gpnum. */
-       unsigned long completed; /* Last GP completed for this node. */
-                               /*  This will either be equal to or one */
-                               /*  behind the root rcu_node's gpnum. */
-       unsigned long qsmask;   /* CPUs or groups that need to switch in */
-                               /*  order for current grace period to proceed.*/
-                               /*  In leaf rcu_node, each bit corresponds to */
-                               /*  an rcu_data structure, otherwise, each */
-                               /*  bit corresponds to a child rcu_node */
-                               /*  structure. */
-       unsigned long expmask;  /* Groups that have ->blkd_tasks */
-                               /*  elements that need to drain to allow the */
-                               /*  current expedited grace period to */
-                               /*  complete (only for TREE_PREEMPT_RCU). */
-       unsigned long qsmaskinit;
-                               /* Per-GP initial value for qsmask & expmask. */
-       unsigned long grpmask;  /* Mask to apply to parent qsmask. */
-                               /*  Only one bit will be set in this mask. */
-       int     grplo;          /* lowest-numbered CPU or group here. */
-       int     grphi;          /* highest-numbered CPU or group here. */
-       u8      grpnum;         /* CPU/group number for next level up. */
-       u8      level;          /* root is at level 0. */
-       struct rcu_node *parent;
-       struct list_head blkd_tasks;
-                               /* Tasks blocked in RCU read-side critical */
-                               /*  section.  Tasks are placed at the head */
-                               /*  of this list and age towards the tail. */
-       struct list_head *gp_tasks;
-                               /* Pointer to the first task blocking the */
-                               /*  current grace period, or NULL if there */
-                               /*  is no such task. */
-       struct list_head *exp_tasks;
-                               /* Pointer to the first task blocking the */
-                               /*  current expedited grace period, or NULL */
-                               /*  if there is no such task.  If there */
-                               /*  is no current expedited grace period, */
-                               /*  then there can cannot be any such task. */
-#ifdef CONFIG_RCU_BOOST
-       struct list_head *boost_tasks;
-                               /* Pointer to first task that needs to be */
-                               /*  priority boosted, or NULL if no priority */
-                               /*  boosting is needed for this rcu_node */
-                               /*  structure.  If there are no tasks */
-                               /*  queued on this rcu_node structure that */
-                               /*  are blocking the current grace period, */
-                               /*  there can be no such task. */
-       unsigned long boost_time;
-                               /* When to start boosting (jiffies). */
-       struct task_struct *boost_kthread_task;
-                               /* kthread that takes care of priority */
-                               /*  boosting for this rcu_node structure. */
-       unsigned int boost_kthread_status;
-                               /* State of boost_kthread_task for tracing. */
-       unsigned long n_tasks_boosted;
-                               /* Total number of tasks boosted. */
-       unsigned long n_exp_boosts;
-                               /* Number of tasks boosted for expedited GP. */
-       unsigned long n_normal_boosts;
-                               /* Number of tasks boosted for normal GP. */
-       unsigned long n_balk_blkd_tasks;
-                               /* Refused to boost: no blocked tasks. */
-       unsigned long n_balk_exp_gp_tasks;
-                               /* Refused to boost: nothing blocking GP. */
-       unsigned long n_balk_boost_tasks;
-                               /* Refused to boost: already boosting. */
-       unsigned long n_balk_notblocked;
-                               /* Refused to boost: RCU RS CS still running. */
-       unsigned long n_balk_notyet;
-                               /* Refused to boost: not yet time. */
-       unsigned long n_balk_nos;
-                               /* Refused to boost: not sure why, though. */
-                               /*  This can happen due to race conditions. */
-#endif /* #ifdef CONFIG_RCU_BOOST */
-#ifdef CONFIG_RCU_NOCB_CPU
-       wait_queue_head_t nocb_gp_wq[2];
-                               /* Place for rcu_nocb_kthread() to wait GP. */
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
-       int need_future_gp[2];
-                               /* Counts of upcoming no-CB GP requests. */
-       raw_spinlock_t fqslock ____cacheline_internodealigned_in_smp;
-} ____cacheline_internodealigned_in_smp;
-
-/*
- * Do a full breadth-first scan of the rcu_node structures for the
- * specified rcu_state structure.
- */
-#define rcu_for_each_node_breadth_first(rsp, rnp) \
-       for ((rnp) = &(rsp)->node[0]; \
-            (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++)
-
-/*
- * Do a breadth-first scan of the non-leaf rcu_node structures for the
- * specified rcu_state structure.  Note that if there is a singleton
- * rcu_node tree with but one rcu_node structure, this loop is a no-op.
- */
-#define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \
-       for ((rnp) = &(rsp)->node[0]; \
-            (rnp) < (rsp)->level[rcu_num_lvls - 1]; (rnp)++)
-
-/*
- * Scan the leaves of the rcu_node hierarchy for the specified rcu_state
- * structure.  Note that if there is a singleton rcu_node tree with but
- * one rcu_node structure, this loop -will- visit the rcu_node structure.
- * It is still a leaf node, even if it is also the root node.
- */
-#define rcu_for_each_leaf_node(rsp, rnp) \
-       for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \
-            (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++)
-
-/* Index values for nxttail array in struct rcu_data. */
-#define RCU_DONE_TAIL          0       /* Also RCU_WAIT head. */
-#define RCU_WAIT_TAIL          1       /* Also RCU_NEXT_READY head. */
-#define RCU_NEXT_READY_TAIL    2       /* Also RCU_NEXT head. */
-#define RCU_NEXT_TAIL          3
-#define RCU_NEXT_SIZE          4
-
-/* Per-CPU data for read-copy update. */
-struct rcu_data {
-       /* 1) quiescent-state and grace-period handling : */
-       unsigned long   completed;      /* Track rsp->completed gp number */
-                                       /*  in order to detect GP end. */
-       unsigned long   gpnum;          /* Highest gp number that this CPU */
-                                       /*  is aware of having started. */
-       bool            passed_quiesce; /* User-mode/idle loop etc. */
-       bool            qs_pending;     /* Core waits for quiesc state. */
-       bool            beenonline;     /* CPU online at least once. */
-       bool            preemptible;    /* Preemptible RCU? */
-       struct rcu_node *mynode;        /* This CPU's leaf of hierarchy */
-       unsigned long grpmask;          /* Mask to apply to leaf qsmask. */
-#ifdef CONFIG_RCU_CPU_STALL_INFO
-       unsigned long   ticks_this_gp;  /* The number of scheduling-clock */
-                                       /*  ticks this CPU has handled */
-                                       /*  during and after the last grace */
-                                       /* period it is aware of. */
-#endif /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
-
-       /* 2) batch handling */
-       /*
-        * If nxtlist is not NULL, it is partitioned as follows.
-        * Any of the partitions might be empty, in which case the
-        * pointer to that partition will be equal to the pointer for
-        * the following partition.  When the list is empty, all of
-        * the nxttail elements point to the ->nxtlist pointer itself,
-        * which in that case is NULL.
-        *
-        * [nxtlist, *nxttail[RCU_DONE_TAIL]):
-        *      Entries that batch # <= ->completed
-        *      The grace period for these entries has completed, and
-        *      the other grace-period-completed entries may be moved
-        *      here temporarily in rcu_process_callbacks().
-        * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]):
-        *      Entries that batch # <= ->completed - 1: waiting for current GP
-        * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]):
-        *      Entries known to have arrived before current GP ended
-        * [*nxttail[RCU_NEXT_READY_TAIL], *nxttail[RCU_NEXT_TAIL]):
-        *      Entries that might have arrived after current GP ended
-        *      Note that the value of *nxttail[RCU_NEXT_TAIL] will
-        *      always be NULL, as this is the end of the list.
-        */
-       struct rcu_head *nxtlist;
-       struct rcu_head **nxttail[RCU_NEXT_SIZE];
-       unsigned long   nxtcompleted[RCU_NEXT_SIZE];
-                                       /* grace periods for sublists. */
-       long            qlen_lazy;      /* # of lazy queued callbacks */
-       long            qlen;           /* # of queued callbacks, incl lazy */
-       long            qlen_last_fqs_check;
-                                       /* qlen at last check for QS forcing */
-       unsigned long   n_cbs_invoked;  /* count of RCU cbs invoked. */
-       unsigned long   n_nocbs_invoked; /* count of no-CBs RCU cbs invoked. */
-       unsigned long   n_cbs_orphaned; /* RCU cbs orphaned by dying CPU */
-       unsigned long   n_cbs_adopted;  /* RCU cbs adopted from dying CPU */
-       unsigned long   n_force_qs_snap;
-                                       /* did other CPU force QS recently? */
-       long            blimit;         /* Upper limit on a processed batch */
-
-       /* 3) dynticks interface. */
-       struct rcu_dynticks *dynticks;  /* Shared per-CPU dynticks state. */
-       int dynticks_snap;              /* Per-GP tracking for dynticks. */
-
-       /* 4) reasons this CPU needed to be kicked by force_quiescent_state */
-       unsigned long dynticks_fqs;     /* Kicked due to dynticks idle. */
-       unsigned long offline_fqs;      /* Kicked due to being offline. */
-
-       /* 5) __rcu_pending() statistics. */
-       unsigned long n_rcu_pending;    /* rcu_pending() calls since boot. */
-       unsigned long n_rp_qs_pending;
-       unsigned long n_rp_report_qs;
-       unsigned long n_rp_cb_ready;
-       unsigned long n_rp_cpu_needs_gp;
-       unsigned long n_rp_gp_completed;
-       unsigned long n_rp_gp_started;
-       unsigned long n_rp_need_nothing;
-
-       /* 6) _rcu_barrier() and OOM callbacks. */
-       struct rcu_head barrier_head;
-#ifdef CONFIG_RCU_FAST_NO_HZ
-       struct rcu_head oom_head;
-#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */
-
-       /* 7) Callback offloading. */
-#ifdef CONFIG_RCU_NOCB_CPU
-       struct rcu_head *nocb_head;     /* CBs waiting for kthread. */
-       struct rcu_head **nocb_tail;
-       atomic_long_t nocb_q_count;     /* # CBs waiting for kthread */
-       atomic_long_t nocb_q_count_lazy; /*  (approximate). */
-       int nocb_p_count;               /* # CBs being invoked by kthread */
-       int nocb_p_count_lazy;          /*  (approximate). */
-       wait_queue_head_t nocb_wq;      /* For nocb kthreads to sleep on. */
-       struct task_struct *nocb_kthread;
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
-
-       /* 8) RCU CPU stall data. */
-#ifdef CONFIG_RCU_CPU_STALL_INFO
-       unsigned int softirq_snap;      /* Snapshot of softirq activity. */
-#endif /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
-
-       int cpu;
-       struct rcu_state *rsp;
-};
-
-/* Values for fqs_state field in struct rcu_state. */
-#define RCU_GP_IDLE            0       /* No grace period in progress. */
-#define RCU_GP_INIT            1       /* Grace period being initialized. */
-#define RCU_SAVE_DYNTICK       2       /* Need to scan dyntick state. */
-#define RCU_FORCE_QS           3       /* Need to force quiescent state. */
-#define RCU_SIGNAL_INIT                RCU_SAVE_DYNTICK
-
-#define RCU_JIFFIES_TILL_FORCE_QS (1 + (HZ > 250) + (HZ > 500))
-                                       /* For jiffies_till_first_fqs and */
-                                       /*  and jiffies_till_next_fqs. */
-
-#define RCU_JIFFIES_FQS_DIV    256     /* Very large systems need more */
-                                       /*  delay between bouts of */
-                                       /*  quiescent-state forcing. */
-
-#define RCU_STALL_RAT_DELAY    2       /* Allow other CPUs time to take */
-                                       /*  at least one scheduling clock */
-                                       /*  irq before ratting on them. */
-
-#define rcu_wait(cond)                                                 \
-do {                                                                   \
-       for (;;) {                                                      \
-               set_current_state(TASK_INTERRUPTIBLE);                  \
-               if (cond)                                               \
-                       break;                                          \
-               schedule();                                             \
-       }                                                               \
-       __set_current_state(TASK_RUNNING);                              \
-} while (0)
-
-/*
- * RCU global state, including node hierarchy.  This hierarchy is
- * represented in "heap" form in a dense array.  The root (first level)
- * of the hierarchy is in ->node[0] (referenced by ->level[0]), the second
- * level in ->node[1] through ->node[m] (->node[1] referenced by ->level[1]),
- * and the third level in ->node[m+1] and following (->node[m+1] referenced
- * by ->level[2]).  The number of levels is determined by the number of
- * CPUs and by CONFIG_RCU_FANOUT.  Small systems will have a "hierarchy"
- * consisting of a single rcu_node.
- */
-struct rcu_state {
-       struct rcu_node node[NUM_RCU_NODES];    /* Hierarchy. */
-       struct rcu_node *level[RCU_NUM_LVLS];   /* Hierarchy levels. */
-       u32 levelcnt[MAX_RCU_LVLS + 1];         /* # nodes in each level. */
-       u8 levelspread[RCU_NUM_LVLS];           /* kids/node in each level. */
-       struct rcu_data __percpu *rda;          /* pointer of percu rcu_data. */
-       void (*call)(struct rcu_head *head,     /* call_rcu() flavor. */
-                    void (*func)(struct rcu_head *head));
-
-       /* The following fields are guarded by the root rcu_node's lock. */
-
-       u8      fqs_state ____cacheline_internodealigned_in_smp;
-                                               /* Force QS state. */
-       u8      boost;                          /* Subject to priority boost. */
-       unsigned long gpnum;                    /* Current gp number. */
-       unsigned long completed;                /* # of last completed gp. */
-       struct task_struct *gp_kthread;         /* Task for grace periods. */
-       wait_queue_head_t gp_wq;                /* Where GP task waits. */
-       int gp_flags;                           /* Commands for GP task. */
-
-       /* End of fields guarded by root rcu_node's lock. */
-
-       raw_spinlock_t orphan_lock ____cacheline_internodealigned_in_smp;
-                                               /* Protect following fields. */
-       struct rcu_head *orphan_nxtlist;        /* Orphaned callbacks that */
-                                               /*  need a grace period. */
-       struct rcu_head **orphan_nxttail;       /* Tail of above. */
-       struct rcu_head *orphan_donelist;       /* Orphaned callbacks that */
-                                               /*  are ready to invoke. */
-       struct rcu_head **orphan_donetail;      /* Tail of above. */
-       long qlen_lazy;                         /* Number of lazy callbacks. */
-       long qlen;                              /* Total number of callbacks. */
-       /* End of fields guarded by orphan_lock. */
-
-       struct mutex onoff_mutex;               /* Coordinate hotplug & GPs. */
-
-       struct mutex barrier_mutex;             /* Guards barrier fields. */
-       atomic_t barrier_cpu_count;             /* # CPUs waiting on. */
-       struct completion barrier_completion;   /* Wake at barrier end. */
-       unsigned long n_barrier_done;           /* ++ at start and end of */
-                                               /*  _rcu_barrier(). */
-       /* End of fields guarded by barrier_mutex. */
-
-       atomic_long_t expedited_start;          /* Starting ticket. */
-       atomic_long_t expedited_done;           /* Done ticket. */
-       atomic_long_t expedited_wrap;           /* # near-wrap incidents. */
-       atomic_long_t expedited_tryfail;        /* # acquisition failures. */
-       atomic_long_t expedited_workdone1;      /* # done by others #1. */
-       atomic_long_t expedited_workdone2;      /* # done by others #2. */
-       atomic_long_t expedited_normal;         /* # fallbacks to normal. */
-       atomic_long_t expedited_stoppedcpus;    /* # successful stop_cpus. */
-       atomic_long_t expedited_done_tries;     /* # tries to update _done. */
-       atomic_long_t expedited_done_lost;      /* # times beaten to _done. */
-       atomic_long_t expedited_done_exit;      /* # times exited _done loop. */
-
-       unsigned long jiffies_force_qs;         /* Time at which to invoke */
-                                               /*  force_quiescent_state(). */
-       unsigned long n_force_qs;               /* Number of calls to */
-                                               /*  force_quiescent_state(). */
-       unsigned long n_force_qs_lh;            /* ~Number of calls leaving */
-                                               /*  due to lock unavailable. */
-       unsigned long n_force_qs_ngp;           /* Number of calls leaving */
-                                               /*  due to no GP active. */
-       unsigned long gp_start;                 /* Time at which GP started, */
-                                               /*  but in jiffies. */
-       unsigned long jiffies_stall;            /* Time at which to check */
-                                               /*  for CPU stalls. */
-       unsigned long gp_max;                   /* Maximum GP duration in */
-                                               /*  jiffies. */
-       const char *name;                       /* Name of structure. */
-       char abbr;                              /* Abbreviated name. */
-       struct list_head flavors;               /* List of RCU flavors. */
-       struct irq_work wakeup_work;            /* Postponed wakeups */
-};
-
-/* Values for rcu_state structure's gp_flags field. */
-#define RCU_GP_FLAG_INIT 0x1   /* Need grace-period initialization. */
-#define RCU_GP_FLAG_FQS  0x2   /* Need grace-period quiescent-state forcing. */
-
-extern struct list_head rcu_struct_flavors;
-
-/* Sequence through rcu_state structures for each RCU flavor. */
-#define for_each_rcu_flavor(rsp) \
-       list_for_each_entry((rsp), &rcu_struct_flavors, flavors)
-
-/* Return values for rcu_preempt_offline_tasks(). */
-
-#define RCU_OFL_TASKS_NORM_GP  0x1             /* Tasks blocking normal */
-                                               /*  GP were moved to root. */
-#define RCU_OFL_TASKS_EXP_GP   0x2             /* Tasks blocking expedited */
-                                               /*  GP were moved to root. */
-
-/*
- * RCU implementation internal declarations:
- */
-extern struct rcu_state rcu_sched_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_sched_data);
-
-extern struct rcu_state rcu_bh_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
-
-#ifdef CONFIG_TREE_PREEMPT_RCU
-extern struct rcu_state rcu_preempt_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
-#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-
-#ifdef CONFIG_RCU_BOOST
-DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
-DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu);
-DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
-DECLARE_PER_CPU(char, rcu_cpu_has_work);
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-#ifndef RCU_TREE_NONCORE
-
-/* Forward declarations for rcutree_plugin.h */
-static void rcu_bootup_announce(void);
-long rcu_batches_completed(void);
-static void rcu_preempt_note_context_switch(int cpu);
-static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp);
-#ifdef CONFIG_HOTPLUG_CPU
-static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp,
-                                     unsigned long flags);
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-static void rcu_print_detail_task_stall(struct rcu_state *rsp);
-static int rcu_print_task_stall(struct rcu_node *rnp);
-static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
-#ifdef CONFIG_HOTPLUG_CPU
-static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
-                                    struct rcu_node *rnp,
-                                    struct rcu_data *rdp);
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-static void rcu_preempt_check_callbacks(int cpu);
-void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
-#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU)
-static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
-                              bool wake);
-#endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */
-static void __init __rcu_init_preempt(void);
-static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);
-static void rcu_preempt_boost_start_gp(struct rcu_node *rnp);
-static void invoke_rcu_callbacks_kthread(void);
-static bool rcu_is_callbacks_kthread(void);
-#ifdef CONFIG_RCU_BOOST
-static void rcu_preempt_do_callbacks(void);
-static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
-                                                struct rcu_node *rnp);
-#endif /* #ifdef CONFIG_RCU_BOOST */
-static void rcu_prepare_kthreads(int cpu);
-static void rcu_cleanup_after_idle(int cpu);
-static void rcu_prepare_for_idle(int cpu);
-static void rcu_idle_count_callbacks_posted(void);
-static void print_cpu_stall_info_begin(void);
-static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
-static void print_cpu_stall_info_end(void);
-static void zero_cpu_stall_ticks(struct rcu_data *rdp);
-static void increment_cpu_stall_ticks(void);
-static int rcu_nocb_needs_gp(struct rcu_state *rsp);
-static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
-static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp);
-static void rcu_init_one_nocb(struct rcu_node *rnp);
-static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
-                           bool lazy);
-static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
-                                     struct rcu_data *rdp);
-static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp);
-static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp);
-static void rcu_kick_nohz_cpu(int cpu);
-static bool init_nocb_callback_list(struct rcu_data *rdp);
-static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq);
-static void rcu_sysidle_exit(struct rcu_dynticks *rdtp, int irq);
-static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,
-                                 unsigned long *maxj);
-static bool is_sysidle_rcu_state(struct rcu_state *rsp);
-static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
-                                 unsigned long maxj);
-static void rcu_bind_gp_kthread(void);
-static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp);
-
-#endif /* #ifndef RCU_TREE_NONCORE */
-
-#ifdef CONFIG_RCU_TRACE
-#ifdef CONFIG_RCU_NOCB_CPU
-/* Sum up queue lengths for tracing. */
-static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll)
-{
-       *ql = atomic_long_read(&rdp->nocb_q_count) + rdp->nocb_p_count;
-       *qll = atomic_long_read(&rdp->nocb_q_count_lazy) + rdp->nocb_p_count_lazy;
-}
-#else /* #ifdef CONFIG_RCU_NOCB_CPU */
-static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll)
-{
-       *ql = 0;
-       *qll = 0;
-}
-#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */
-#endif /* #ifdef CONFIG_RCU_TRACE */
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
deleted file mode 100644 (file)
index 130c97b..0000000
+++ /dev/null
@@ -1,2797 +0,0 @@
-/*
- * Read-Copy Update mechanism for mutual exclusion (tree-based version)
- * Internal non-public definitions that provide either classic
- * or preemptible semantics.
- *
- * 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 Red Hat, 2009
- * Copyright IBM Corporation, 2009
- *
- * Author: Ingo Molnar <mingo@elte.hu>
- *        Paul E. McKenney <paulmck@linux.vnet.ibm.com>
- */
-
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/oom.h>
-#include <linux/smpboot.h>
-#include "time/tick-internal.h"
-
-#define RCU_KTHREAD_PRIO 1
-
-#ifdef CONFIG_RCU_BOOST
-#define RCU_BOOST_PRIO CONFIG_RCU_BOOST_PRIO
-#else
-#define RCU_BOOST_PRIO RCU_KTHREAD_PRIO
-#endif
-
-#ifdef CONFIG_RCU_NOCB_CPU
-static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */
-static bool have_rcu_nocb_mask;            /* Was rcu_nocb_mask allocated? */
-static bool __read_mostly rcu_nocb_poll;    /* Offload kthread are to poll. */
-static char __initdata nocb_buf[NR_CPUS * 5];
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
-
-/*
- * Check the RCU kernel configuration parameters and print informative
- * messages about anything out of the ordinary.  If you like #ifdef, you
- * will love this function.
- */
-static void __init rcu_bootup_announce_oddness(void)
-{
-#ifdef CONFIG_RCU_TRACE
-       pr_info("\tRCU debugfs-based tracing is enabled.\n");
-#endif
-#if (defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 64) || (!defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 32)
-       pr_info("\tCONFIG_RCU_FANOUT set to non-default value of %d\n",
-              CONFIG_RCU_FANOUT);
-#endif
-#ifdef CONFIG_RCU_FANOUT_EXACT
-       pr_info("\tHierarchical RCU autobalancing is disabled.\n");
-#endif
-#ifdef CONFIG_RCU_FAST_NO_HZ
-       pr_info("\tRCU dyntick-idle grace-period acceleration is enabled.\n");
-#endif
-#ifdef CONFIG_PROVE_RCU
-       pr_info("\tRCU lockdep checking is enabled.\n");
-#endif
-#ifdef CONFIG_RCU_TORTURE_TEST_RUNNABLE
-       pr_info("\tRCU torture testing starts during boot.\n");
-#endif
-#if defined(CONFIG_TREE_PREEMPT_RCU) && !defined(CONFIG_RCU_CPU_STALL_VERBOSE)
-       pr_info("\tDump stacks of tasks blocking RCU-preempt GP.\n");
-#endif
-#if defined(CONFIG_RCU_CPU_STALL_INFO)
-       pr_info("\tAdditional per-CPU info printed with stalls.\n");
-#endif
-#if NUM_RCU_LVL_4 != 0
-       pr_info("\tFour-level hierarchy is enabled.\n");
-#endif
-       if (rcu_fanout_leaf != CONFIG_RCU_FANOUT_LEAF)
-               pr_info("\tBoot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf);
-       if (nr_cpu_ids != NR_CPUS)
-               pr_info("\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids);
-#ifdef CONFIG_RCU_NOCB_CPU
-#ifndef CONFIG_RCU_NOCB_CPU_NONE
-       if (!have_rcu_nocb_mask) {
-               zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL);
-               have_rcu_nocb_mask = true;
-       }
-#ifdef CONFIG_RCU_NOCB_CPU_ZERO
-       pr_info("\tOffload RCU callbacks from CPU 0\n");
-       cpumask_set_cpu(0, rcu_nocb_mask);
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ZERO */
-#ifdef CONFIG_RCU_NOCB_CPU_ALL
-       pr_info("\tOffload RCU callbacks from all CPUs\n");
-       cpumask_setall(rcu_nocb_mask);
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU_ALL */
-#endif /* #ifndef CONFIG_RCU_NOCB_CPU_NONE */
-       if (have_rcu_nocb_mask) {
-               cpulist_scnprintf(nocb_buf, sizeof(nocb_buf), rcu_nocb_mask);
-               pr_info("\tOffload RCU callbacks from CPUs: %s.\n", nocb_buf);
-               if (rcu_nocb_poll)
-                       pr_info("\tPoll for callbacks from no-CBs CPUs.\n");
-       }
-#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
-}
-
-#ifdef CONFIG_TREE_PREEMPT_RCU
-
-RCU_STATE_INITIALIZER(rcu_preempt, 'p', call_rcu);
-static struct rcu_state *rcu_state = &rcu_preempt_state;
-
-static int rcu_preempted_readers_exp(struct rcu_node *rnp);
-
-/*
- * Tell them what RCU they are running.
- */
-static void __init rcu_bootup_announce(void)
-{
-       pr_info("Preemptible hierarchical RCU implementation.\n");
-       rcu_bootup_announce_oddness();
-}
-
-/*
- * Return the number of RCU-preempt batches processed thus far
- * for debug and statistics.
- */
-long rcu_batches_completed_preempt(void)
-{
-       return rcu_preempt_state.completed;
-}
-EXPORT_SYMBOL_GPL(rcu_batches_completed_preempt);
-
-/*
- * Return the number of RCU batches processed thus far for debug & stats.
- */
-long rcu_batches_completed(void)
-{
-       return rcu_batches_completed_preempt();
-}
-EXPORT_SYMBOL_GPL(rcu_batches_completed);
-
-/*
- * Force a quiescent state for preemptible RCU.
- */
-void rcu_force_quiescent_state(void)
-{
-       force_quiescent_state(&rcu_preempt_state);
-}
-EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
-
-/*
- * Record a preemptible-RCU quiescent state for the specified CPU.  Note
- * that this just means that the task currently running on the CPU is
- * not in a quiescent state.  There might be any number of tasks blocked
- * while in an RCU read-side critical section.
- *
- * Unlike the other rcu_*_qs() functions, callers to this function
- * must disable irqs in order to protect the assignment to
- * ->rcu_read_unlock_special.
- */
-static void rcu_preempt_qs(int cpu)
-{
-       struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
-
-       if (rdp->passed_quiesce == 0)
-               trace_rcu_grace_period(TPS("rcu_preempt"), rdp->gpnum, TPS("cpuqs"));
-       rdp->passed_quiesce = 1;
-       current->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
-}
-
-/*
- * We have entered the scheduler, and the current task might soon be
- * context-switched away from.  If this task is in an RCU read-side
- * critical section, we will no longer be able to rely on the CPU to
- * record that fact, so we enqueue the task on the blkd_tasks list.
- * The task will dequeue itself when it exits the outermost enclosing
- * RCU read-side critical section.  Therefore, the current grace period
- * cannot be permitted to complete until the blkd_tasks list entries
- * predating the current grace period drain, in other words, until
- * rnp->gp_tasks becomes NULL.
- *
- * Caller must disable preemption.
- */
-static void rcu_preempt_note_context_switch(int cpu)
-{
-       struct task_struct *t = current;
-       unsigned long flags;
-       struct rcu_data *rdp;
-       struct rcu_node *rnp;
-
-       if (t->rcu_read_lock_nesting > 0 &&
-           (t->rcu_read_unlock_special & RCU_READ_UNLOCK_BLOCKED) == 0) {
-
-               /* Possibly blocking in an RCU read-side critical section. */
-               rdp = per_cpu_ptr(rcu_preempt_state.rda, cpu);
-               rnp = rdp->mynode;
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               t->rcu_read_unlock_special |= RCU_READ_UNLOCK_BLOCKED;
-               t->rcu_blocked_node = rnp;
-
-               /*
-                * If this CPU has already checked in, then this task
-                * will hold up the next grace period rather than the
-                * current grace period.  Queue the task accordingly.
-                * If the task is queued for the current grace period
-                * (i.e., this CPU has not yet passed through a quiescent
-                * state for the current grace period), then as long
-                * as that task remains queued, the current grace period
-                * cannot end.  Note that there is some uncertainty as
-                * to exactly when the current grace period started.
-                * We take a conservative approach, which can result
-                * in unnecessarily waiting on tasks that started very
-                * slightly after the current grace period began.  C'est
-                * la vie!!!
-                *
-                * But first, note that the current CPU must still be
-                * on line!
-                */
-               WARN_ON_ONCE((rdp->grpmask & rnp->qsmaskinit) == 0);
-               WARN_ON_ONCE(!list_empty(&t->rcu_node_entry));
-               if ((rnp->qsmask & rdp->grpmask) && rnp->gp_tasks != NULL) {
-                       list_add(&t->rcu_node_entry, rnp->gp_tasks->prev);
-                       rnp->gp_tasks = &t->rcu_node_entry;
-#ifdef CONFIG_RCU_BOOST
-                       if (rnp->boost_tasks != NULL)
-                               rnp->boost_tasks = rnp->gp_tasks;
-#endif /* #ifdef CONFIG_RCU_BOOST */
-               } else {
-                       list_add(&t->rcu_node_entry, &rnp->blkd_tasks);
-                       if (rnp->qsmask & rdp->grpmask)
-                               rnp->gp_tasks = &t->rcu_node_entry;
-               }
-               trace_rcu_preempt_task(rdp->rsp->name,
-                                      t->pid,
-                                      (rnp->qsmask & rdp->grpmask)
-                                      ? rnp->gpnum
-                                      : rnp->gpnum + 1);
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       } else if (t->rcu_read_lock_nesting < 0 &&
-                  t->rcu_read_unlock_special) {
-
-               /*
-                * Complete exit from RCU read-side critical section on
-                * behalf of preempted instance of __rcu_read_unlock().
-                */
-               rcu_read_unlock_special(t);
-       }
-
-       /*
-        * Either we were not in an RCU read-side critical section to
-        * begin with, or we have now recorded that critical section
-        * globally.  Either way, we can now note a quiescent state
-        * for this CPU.  Again, if we were in an RCU read-side critical
-        * section, and if that critical section was blocking the current
-        * grace period, then the fact that the task has been enqueued
-        * means that we continue to block the current grace period.
-        */
-       local_irq_save(flags);
-       rcu_preempt_qs(cpu);
-       local_irq_restore(flags);
-}
-
-/*
- * Check for preempted RCU readers blocking the current grace period
- * for the specified rcu_node structure.  If the caller needs a reliable
- * answer, it must hold the rcu_node's ->lock.
- */
-static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp)
-{
-       return rnp->gp_tasks != NULL;
-}
-
-/*
- * Record a quiescent state for all tasks that were previously queued
- * on the specified rcu_node structure and that were blocking the current
- * RCU grace period.  The caller must hold the specified rnp->lock with
- * irqs disabled, and this lock is released upon return, but irqs remain
- * disabled.
- */
-static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
-       __releases(rnp->lock)
-{
-       unsigned long mask;
-       struct rcu_node *rnp_p;
-
-       if (rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return;  /* Still need more quiescent states! */
-       }
-
-       rnp_p = rnp->parent;
-       if (rnp_p == NULL) {
-               /*
-                * Either there is only one rcu_node in the tree,
-                * or tasks were kicked up to root rcu_node due to
-                * CPUs going offline.
-                */
-               rcu_report_qs_rsp(&rcu_preempt_state, flags);
-               return;
-       }
-
-       /* Report up the rest of the hierarchy. */
-       mask = rnp->grpmask;
-       raw_spin_unlock(&rnp->lock);    /* irqs remain disabled. */
-       raw_spin_lock(&rnp_p->lock);    /* irqs already disabled. */
-       rcu_report_qs_rnp(mask, &rcu_preempt_state, rnp_p, flags);
-}
-
-/*
- * Advance a ->blkd_tasks-list pointer to the next entry, instead
- * returning NULL if at the end of the list.
- */
-static struct list_head *rcu_next_node_entry(struct task_struct *t,
-                                            struct rcu_node *rnp)
-{
-       struct list_head *np;
-
-       np = t->rcu_node_entry.next;
-       if (np == &rnp->blkd_tasks)
-               np = NULL;
-       return np;
-}
-
-/*
- * Handle special cases during rcu_read_unlock(), such as needing to
- * notify RCU core processing or task having blocked during the RCU
- * read-side critical section.
- */
-void rcu_read_unlock_special(struct task_struct *t)
-{
-       int empty;
-       int empty_exp;
-       int empty_exp_now;
-       unsigned long flags;
-       struct list_head *np;
-#ifdef CONFIG_RCU_BOOST
-       struct rt_mutex *rbmp = NULL;
-#endif /* #ifdef CONFIG_RCU_BOOST */
-       struct rcu_node *rnp;
-       int special;
-
-       /* NMI handlers cannot block and cannot safely manipulate state. */
-       if (in_nmi())
-               return;
-
-       local_irq_save(flags);
-
-       /*
-        * If RCU core is waiting for this CPU to exit critical section,
-        * let it know that we have done so.
-        */
-       special = t->rcu_read_unlock_special;
-       if (special & RCU_READ_UNLOCK_NEED_QS) {
-               rcu_preempt_qs(smp_processor_id());
-       }
-
-       /* Hardware IRQ handlers cannot block. */
-       if (in_irq() || in_serving_softirq()) {
-               local_irq_restore(flags);
-               return;
-       }
-
-       /* Clean up if blocked during RCU read-side critical section. */
-       if (special & RCU_READ_UNLOCK_BLOCKED) {
-               t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_BLOCKED;
-
-               /*
-                * Remove this task from the list it blocked on.  The
-                * task can migrate while we acquire the lock, but at
-                * most one time.  So at most two passes through loop.
-                */
-               for (;;) {
-                       rnp = t->rcu_blocked_node;
-                       raw_spin_lock(&rnp->lock);  /* irqs already disabled. */
-                       if (rnp == t->rcu_blocked_node)
-                               break;
-                       raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
-               }
-               empty = !rcu_preempt_blocked_readers_cgp(rnp);
-               empty_exp = !rcu_preempted_readers_exp(rnp);
-               smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
-               np = rcu_next_node_entry(t, rnp);
-               list_del_init(&t->rcu_node_entry);
-               t->rcu_blocked_node = NULL;
-               trace_rcu_unlock_preempted_task(TPS("rcu_preempt"),
-                                               rnp->gpnum, t->pid);
-               if (&t->rcu_node_entry == rnp->gp_tasks)
-                       rnp->gp_tasks = np;
-               if (&t->rcu_node_entry == rnp->exp_tasks)
-                       rnp->exp_tasks = np;
-#ifdef CONFIG_RCU_BOOST
-               if (&t->rcu_node_entry == rnp->boost_tasks)
-                       rnp->boost_tasks = np;
-               /* Snapshot/clear ->rcu_boost_mutex with rcu_node lock held. */
-               if (t->rcu_boost_mutex) {
-                       rbmp = t->rcu_boost_mutex;
-                       t->rcu_boost_mutex = NULL;
-               }
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-               /*
-                * If this was the last task on the current list, and if
-                * we aren't waiting on any CPUs, report the quiescent state.
-                * Note that rcu_report_unblock_qs_rnp() releases rnp->lock,
-                * so we must take a snapshot of the expedited state.
-                */
-               empty_exp_now = !rcu_preempted_readers_exp(rnp);
-               if (!empty && !rcu_preempt_blocked_readers_cgp(rnp)) {
-                       trace_rcu_quiescent_state_report(TPS("preempt_rcu"),
-                                                        rnp->gpnum,
-                                                        0, rnp->qsmask,
-                                                        rnp->level,
-                                                        rnp->grplo,
-                                                        rnp->grphi,
-                                                        !!rnp->gp_tasks);
-                       rcu_report_unblock_qs_rnp(rnp, flags);
-               } else {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               }
-
-#ifdef CONFIG_RCU_BOOST
-               /* Unboost if we were boosted. */
-               if (rbmp)
-                       rt_mutex_unlock(rbmp);
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-               /*
-                * If this was the last task on the expedited lists,
-                * then we need to report up the rcu_node hierarchy.
-                */
-               if (!empty_exp && empty_exp_now)
-                       rcu_report_exp_rnp(&rcu_preempt_state, rnp, true);
-       } else {
-               local_irq_restore(flags);
-       }
-}
-
-#ifdef CONFIG_RCU_CPU_STALL_VERBOSE
-
-/*
- * Dump detailed information for all tasks blocking the current RCU
- * grace period on the specified rcu_node structure.
- */
-static void rcu_print_detail_task_stall_rnp(struct rcu_node *rnp)
-{
-       unsigned long flags;
-       struct task_struct *t;
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       if (!rcu_preempt_blocked_readers_cgp(rnp)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return;
-       }
-       t = list_entry(rnp->gp_tasks,
-                      struct task_struct, rcu_node_entry);
-       list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry)
-               sched_show_task(t);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-}
-
-/*
- * Dump detailed information for all tasks blocking the current RCU
- * grace period.
- */
-static void rcu_print_detail_task_stall(struct rcu_state *rsp)
-{
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       rcu_print_detail_task_stall_rnp(rnp);
-       rcu_for_each_leaf_node(rsp, rnp)
-               rcu_print_detail_task_stall_rnp(rnp);
-}
-
-#else /* #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */
-
-static void rcu_print_detail_task_stall(struct rcu_state *rsp)
-{
-}
-
-#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */
-
-#ifdef CONFIG_RCU_CPU_STALL_INFO
-
-static void rcu_print_task_stall_begin(struct rcu_node *rnp)
-{
-       pr_err("\tTasks blocked on level-%d rcu_node (CPUs %d-%d):",
-              rnp->level, rnp->grplo, rnp->grphi);
-}
-
-static void rcu_print_task_stall_end(void)
-{
-       pr_cont("\n");
-}
-
-#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
-
-static void rcu_print_task_stall_begin(struct rcu_node *rnp)
-{
-}
-
-static void rcu_print_task_stall_end(void)
-{
-}
-
-#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */
-
-/*
- * Scan the current list of tasks blocked within RCU read-side critical
- * sections, printing out the tid of each.
- */
-static int rcu_print_task_stall(struct rcu_node *rnp)
-{
-       struct task_struct *t;
-       int ndetected = 0;
-
-       if (!rcu_preempt_blocked_readers_cgp(rnp))
-               return 0;
-       rcu_print_task_stall_begin(rnp);
-       t = list_entry(rnp->gp_tasks,
-                      struct task_struct, rcu_node_entry);
-       list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
-               pr_cont(" P%d", t->pid);
-               ndetected++;
-       }
-       rcu_print_task_stall_end();
-       return ndetected;
-}
-
-/*
- * Check that the list of blocked tasks for the newly completed grace
- * period is in fact empty.  It is a serious bug to complete a grace
- * period that still has RCU readers blocked!  This function must be
- * invoked -before- updating this rnp's ->gpnum, and the rnp's ->lock
- * must be held by the caller.
- *
- * Also, if there are blocked tasks on the list, they automatically
- * block the newly created grace period, so set up ->gp_tasks accordingly.
- */
-static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
-{
-       WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp));
-       if (!list_empty(&rnp->blkd_tasks))
-               rnp->gp_tasks = rnp->blkd_tasks.next;
-       WARN_ON_ONCE(rnp->qsmask);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/*
- * Handle tasklist migration for case in which all CPUs covered by the
- * specified rcu_node have gone offline.  Move them up to the root
- * rcu_node.  The reason for not just moving them to the immediate
- * parent is to remove the need for rcu_read_unlock_special() to
- * make more than two attempts to acquire the target rcu_node's lock.
- * Returns true if there were tasks blocking the current RCU grace
- * period.
- *
- * Returns 1 if there was previously a task blocking the current grace
- * period on the specified rcu_node structure.
- *
- * The caller must hold rnp->lock with irqs disabled.
- */
-static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
-                                    struct rcu_node *rnp,
-                                    struct rcu_data *rdp)
-{
-       struct list_head *lp;
-       struct list_head *lp_root;
-       int retval = 0;
-       struct rcu_node *rnp_root = rcu_get_root(rsp);
-       struct task_struct *t;
-
-       if (rnp == rnp_root) {
-               WARN_ONCE(1, "Last CPU thought to be offlined?");
-               return 0;  /* Shouldn't happen: at least one CPU online. */
-       }
-
-       /* If we are on an internal node, complain bitterly. */
-       WARN_ON_ONCE(rnp != rdp->mynode);
-
-       /*
-        * Move tasks up to root rcu_node.  Don't try to get fancy for
-        * this corner-case operation -- just put this node's tasks
-        * at the head of the root node's list, and update the root node's
-        * ->gp_tasks and ->exp_tasks pointers to those of this node's,
-        * if non-NULL.  This might result in waiting for more tasks than
-        * absolutely necessary, but this is a good performance/complexity
-        * tradeoff.
-        */
-       if (rcu_preempt_blocked_readers_cgp(rnp) && rnp->qsmask == 0)
-               retval |= RCU_OFL_TASKS_NORM_GP;
-       if (rcu_preempted_readers_exp(rnp))
-               retval |= RCU_OFL_TASKS_EXP_GP;
-       lp = &rnp->blkd_tasks;
-       lp_root = &rnp_root->blkd_tasks;
-       while (!list_empty(lp)) {
-               t = list_entry(lp->next, typeof(*t), rcu_node_entry);
-               raw_spin_lock(&rnp_root->lock); /* irqs already disabled */
-               list_del(&t->rcu_node_entry);
-               t->rcu_blocked_node = rnp_root;
-               list_add(&t->rcu_node_entry, lp_root);
-               if (&t->rcu_node_entry == rnp->gp_tasks)
-                       rnp_root->gp_tasks = rnp->gp_tasks;
-               if (&t->rcu_node_entry == rnp->exp_tasks)
-                       rnp_root->exp_tasks = rnp->exp_tasks;
-#ifdef CONFIG_RCU_BOOST
-               if (&t->rcu_node_entry == rnp->boost_tasks)
-                       rnp_root->boost_tasks = rnp->boost_tasks;
-#endif /* #ifdef CONFIG_RCU_BOOST */
-               raw_spin_unlock(&rnp_root->lock); /* irqs still disabled */
-       }
-
-       rnp->gp_tasks = NULL;
-       rnp->exp_tasks = NULL;
-#ifdef CONFIG_RCU_BOOST
-       rnp->boost_tasks = NULL;
-       /*
-        * In case root is being boosted and leaf was not.  Make sure
-        * that we boost the tasks blocking the current grace period
-        * in this case.
-        */
-       raw_spin_lock(&rnp_root->lock); /* irqs already disabled */
-       if (rnp_root->boost_tasks != NULL &&
-           rnp_root->boost_tasks != rnp_root->gp_tasks &&
-           rnp_root->boost_tasks != rnp_root->exp_tasks)
-               rnp_root->boost_tasks = rnp_root->gp_tasks;
-       raw_spin_unlock(&rnp_root->lock); /* irqs still disabled */
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-       return retval;
-}
-
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-
-/*
- * Check for a quiescent state from the current CPU.  When a task blocks,
- * the task is recorded in the corresponding CPU's rcu_node structure,
- * which is checked elsewhere.
- *
- * Caller must disable hard irqs.
- */
-static void rcu_preempt_check_callbacks(int cpu)
-{
-       struct task_struct *t = current;
-
-       if (t->rcu_read_lock_nesting == 0) {
-               rcu_preempt_qs(cpu);
-               return;
-       }
-       if (t->rcu_read_lock_nesting > 0 &&
-           per_cpu(rcu_preempt_data, cpu).qs_pending)
-               t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS;
-}
-
-#ifdef CONFIG_RCU_BOOST
-
-static void rcu_preempt_do_callbacks(void)
-{
-       rcu_do_batch(&rcu_preempt_state, &__get_cpu_var(rcu_preempt_data));
-}
-
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-/*
- * Queue a preemptible-RCU callback for invocation after a grace period.
- */
-void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_preempt_state, -1, 0);
-}
-EXPORT_SYMBOL_GPL(call_rcu);
-
-/*
- * Queue an RCU callback for lazy invocation after a grace period.
- * This will likely be later named something like "call_rcu_lazy()",
- * but this change will require some way of tagging the lazy RCU
- * callbacks in the list of pending callbacks.  Until then, this
- * function may only be called from __kfree_rcu().
- */
-void kfree_call_rcu(struct rcu_head *head,
-                   void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_preempt_state, -1, 1);
-}
-EXPORT_SYMBOL_GPL(kfree_call_rcu);
-
-/**
- * synchronize_rcu - wait until a grace period has elapsed.
- *
- * Control will return to the caller some time after a full grace
- * period has elapsed, in other words after all currently executing RCU
- * read-side critical sections have completed.  Note, however, that
- * upon return from synchronize_rcu(), the caller might well be executing
- * concurrently with new RCU read-side critical sections that began while
- * synchronize_rcu() was waiting.  RCU read-side critical sections are
- * delimited by rcu_read_lock() and rcu_read_unlock(), and may be nested.
- *
- * See the description of synchronize_sched() for more detailed information
- * on memory ordering guarantees.
- */
-void synchronize_rcu(void)
-{
-       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
-                          !lock_is_held(&rcu_lock_map) &&
-                          !lock_is_held(&rcu_sched_lock_map),
-                          "Illegal synchronize_rcu() in RCU read-side critical section");
-       if (!rcu_scheduler_active)
-               return;
-       if (rcu_expedited)
-               synchronize_rcu_expedited();
-       else
-               wait_rcu_gp(call_rcu);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu);
-
-static DECLARE_WAIT_QUEUE_HEAD(sync_rcu_preempt_exp_wq);
-static unsigned long sync_rcu_preempt_exp_count;
-static DEFINE_MUTEX(sync_rcu_preempt_exp_mutex);
-
-/*
- * Return non-zero if there are any tasks in RCU read-side critical
- * sections blocking the current preemptible-RCU expedited grace period.
- * If there is no preemptible-RCU expedited grace period currently in
- * progress, returns zero unconditionally.
- */
-static int rcu_preempted_readers_exp(struct rcu_node *rnp)
-{
-       return rnp->exp_tasks != NULL;
-}
-
-/*
- * return non-zero if there is no RCU expedited grace period in progress
- * for the specified rcu_node structure, in other words, if all CPUs and
- * tasks covered by the specified rcu_node structure have done their bit
- * for the current expedited grace period.  Works only for preemptible
- * RCU -- other RCU implementation use other means.
- *
- * Caller must hold sync_rcu_preempt_exp_mutex.
- */
-static int sync_rcu_preempt_exp_done(struct rcu_node *rnp)
-{
-       return !rcu_preempted_readers_exp(rnp) &&
-              ACCESS_ONCE(rnp->expmask) == 0;
-}
-
-/*
- * Report the exit from RCU read-side critical section for the last task
- * that queued itself during or before the current expedited preemptible-RCU
- * grace period.  This event is reported either to the rcu_node structure on
- * which the task was queued or to one of that rcu_node structure's ancestors,
- * recursively up the tree.  (Calm down, calm down, we do the recursion
- * iteratively!)
- *
- * Most callers will set the "wake" flag, but the task initiating the
- * expedited grace period need not wake itself.
- *
- * Caller must hold sync_rcu_preempt_exp_mutex.
- */
-static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
-                              bool wake)
-{
-       unsigned long flags;
-       unsigned long mask;
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       for (;;) {
-               if (!sync_rcu_preempt_exp_done(rnp)) {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-                       break;
-               }
-               if (rnp->parent == NULL) {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-                       if (wake)
-                               wake_up(&sync_rcu_preempt_exp_wq);
-                       break;
-               }
-               mask = rnp->grpmask;
-               raw_spin_unlock(&rnp->lock); /* irqs remain disabled */
-               rnp = rnp->parent;
-               raw_spin_lock(&rnp->lock); /* irqs already disabled */
-               rnp->expmask &= ~mask;
-       }
-}
-
-/*
- * Snapshot the tasks blocking the newly started preemptible-RCU expedited
- * grace period for the specified rcu_node structure.  If there are no such
- * tasks, report it up the rcu_node hierarchy.
- *
- * Caller must hold sync_rcu_preempt_exp_mutex and must exclude
- * CPU hotplug operations.
- */
-static void
-sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp)
-{
-       unsigned long flags;
-       int must_wait = 0;
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       if (list_empty(&rnp->blkd_tasks)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       } else {
-               rnp->exp_tasks = rnp->blkd_tasks.next;
-               rcu_initiate_boost(rnp, flags);  /* releases rnp->lock */
-               must_wait = 1;
-       }
-       if (!must_wait)
-               rcu_report_exp_rnp(rsp, rnp, false); /* Don't wake self. */
-}
-
-/**
- * synchronize_rcu_expedited - Brute-force RCU grace period
- *
- * Wait for an RCU-preempt grace period, but expedite it.  The basic
- * idea is to invoke synchronize_sched_expedited() to push all the tasks to
- * the ->blkd_tasks lists and wait for this list to drain.  This consumes
- * significant time on all CPUs and is unfriendly to real-time workloads,
- * so is thus not recommended for any sort of common-case code.
- * In fact, if you are using synchronize_rcu_expedited() in a loop,
- * please restructure your code to batch your updates, and then Use a
- * single synchronize_rcu() instead.
- *
- * Note that it is illegal to call this function while holding any lock
- * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
- * to call this function from a CPU-hotplug notifier.  Failing to observe
- * these restriction will result in deadlock.
- */
-void synchronize_rcu_expedited(void)
-{
-       unsigned long flags;
-       struct rcu_node *rnp;
-       struct rcu_state *rsp = &rcu_preempt_state;
-       unsigned long snap;
-       int trycount = 0;
-
-       smp_mb(); /* Caller's modifications seen first by other CPUs. */
-       snap = ACCESS_ONCE(sync_rcu_preempt_exp_count) + 1;
-       smp_mb(); /* Above access cannot bleed into critical section. */
-
-       /*
-        * Block CPU-hotplug operations.  This means that any CPU-hotplug
-        * operation that finds an rcu_node structure with tasks in the
-        * process of being boosted will know that all tasks blocking
-        * this expedited grace period will already be in the process of
-        * being boosted.  This simplifies the process of moving tasks
-        * from leaf to root rcu_node structures.
-        */
-       get_online_cpus();
-
-       /*
-        * Acquire lock, falling back to synchronize_rcu() if too many
-        * lock-acquisition failures.  Of course, if someone does the
-        * expedited grace period for us, just leave.
-        */
-       while (!mutex_trylock(&sync_rcu_preempt_exp_mutex)) {
-               if (ULONG_CMP_LT(snap,
-                   ACCESS_ONCE(sync_rcu_preempt_exp_count))) {
-                       put_online_cpus();
-                       goto mb_ret; /* Others did our work for us. */
-               }
-               if (trycount++ < 10) {
-                       udelay(trycount * num_online_cpus());
-               } else {
-                       put_online_cpus();
-                       wait_rcu_gp(call_rcu);
-                       return;
-               }
-       }
-       if (ULONG_CMP_LT(snap, ACCESS_ONCE(sync_rcu_preempt_exp_count))) {
-               put_online_cpus();
-               goto unlock_mb_ret; /* Others did our work for us. */
-       }
-
-       /* force all RCU readers onto ->blkd_tasks lists. */
-       synchronize_sched_expedited();
-
-       /* Initialize ->expmask for all non-leaf rcu_node structures. */
-       rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) {
-               raw_spin_lock_irqsave(&rnp->lock, flags);
-               rnp->expmask = rnp->qsmaskinit;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       }
-
-       /* Snapshot current state of ->blkd_tasks lists. */
-       rcu_for_each_leaf_node(rsp, rnp)
-               sync_rcu_preempt_exp_init(rsp, rnp);
-       if (NUM_RCU_NODES > 1)
-               sync_rcu_preempt_exp_init(rsp, rcu_get_root(rsp));
-
-       put_online_cpus();
-
-       /* Wait for snapshotted ->blkd_tasks lists to drain. */
-       rnp = rcu_get_root(rsp);
-       wait_event(sync_rcu_preempt_exp_wq,
-                  sync_rcu_preempt_exp_done(rnp));
-
-       /* Clean up and exit. */
-       smp_mb(); /* ensure expedited GP seen before counter increment. */
-       ACCESS_ONCE(sync_rcu_preempt_exp_count)++;
-unlock_mb_ret:
-       mutex_unlock(&sync_rcu_preempt_exp_mutex);
-mb_ret:
-       smp_mb(); /* ensure subsequent action seen after grace period. */
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
-
-/**
- * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete.
- *
- * Note that this primitive does not necessarily wait for an RCU grace period
- * to complete.  For example, if there are no RCU callbacks queued anywhere
- * in the system, then rcu_barrier() is within its rights to return
- * immediately, without waiting for anything, much less an RCU grace period.
- */
-void rcu_barrier(void)
-{
-       _rcu_barrier(&rcu_preempt_state);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier);
-
-/*
- * Initialize preemptible RCU's state structures.
- */
-static void __init __rcu_init_preempt(void)
-{
-       rcu_init_one(&rcu_preempt_state, &rcu_preempt_data);
-}
-
-/*
- * Check for a task exiting while in a preemptible-RCU read-side
- * critical section, clean up if so.  No need to issue warnings,
- * as debug_check_no_locks_held() already does this if lockdep
- * is enabled.
- */
-void exit_rcu(void)
-{
-       struct task_struct *t = current;
-
-       if (likely(list_empty(&current->rcu_node_entry)))
-               return;
-       t->rcu_read_lock_nesting = 1;
-       barrier();
-       t->rcu_read_unlock_special = RCU_READ_UNLOCK_BLOCKED;
-       __rcu_read_unlock();
-}
-
-#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-
-static struct rcu_state *rcu_state = &rcu_sched_state;
-
-/*
- * Tell them what RCU they are running.
- */
-static void __init rcu_bootup_announce(void)
-{
-       pr_info("Hierarchical RCU implementation.\n");
-       rcu_bootup_announce_oddness();
-}
-
-/*
- * Return the number of RCU batches processed thus far for debug & stats.
- */
-long rcu_batches_completed(void)
-{
-       return rcu_batches_completed_sched();
-}
-EXPORT_SYMBOL_GPL(rcu_batches_completed);
-
-/*
- * Force a quiescent state for RCU, which, because there is no preemptible
- * RCU, becomes the same as rcu-sched.
- */
-void rcu_force_quiescent_state(void)
-{
-       rcu_sched_force_quiescent_state();
-}
-EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
-
-/*
- * Because preemptible RCU does not exist, we never have to check for
- * CPUs being in quiescent states.
- */
-static void rcu_preempt_note_context_switch(int cpu)
-{
-}
-
-/*
- * Because preemptible RCU does not exist, there are never any preempted
- * RCU readers.
- */
-static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp)
-{
-       return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/* Because preemptible RCU does not exist, no quieting of tasks. */
-static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
-{
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-}
-
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-
-/*
- * Because preemptible RCU does not exist, we never have to check for
- * tasks blocked within RCU read-side critical sections.
- */
-static void rcu_print_detail_task_stall(struct rcu_state *rsp)
-{
-}
-
-/*
- * Because preemptible RCU does not exist, we never have to check for
- * tasks blocked within RCU read-side critical sections.
- */
-static int rcu_print_task_stall(struct rcu_node *rnp)
-{
-       return 0;
-}
-
-/*
- * Because there is no preemptible RCU, there can be no readers blocked,
- * so there is no need to check for blocked tasks.  So check only for
- * bogus qsmask values.
- */
-static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
-{
-       WARN_ON_ONCE(rnp->qsmask);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/*
- * Because preemptible RCU does not exist, it never needs to migrate
- * tasks that were blocked within RCU read-side critical sections, and
- * such non-existent tasks cannot possibly have been blocking the current
- * grace period.
- */
-static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
-                                    struct rcu_node *rnp,
-                                    struct rcu_data *rdp)
-{
-       return 0;
-}
-
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-
-/*
- * Because preemptible RCU does not exist, it never has any callbacks
- * to check.
- */
-static void rcu_preempt_check_callbacks(int cpu)
-{
-}
-
-/*
- * Queue an RCU callback for lazy invocation after a grace period.
- * This will likely be later named something like "call_rcu_lazy()",
- * but this change will require some way of tagging the lazy RCU
- * callbacks in the list of pending callbacks.  Until then, this
- * function may only be called from __kfree_rcu().
- *
- * Because there is no preemptible RCU, we use RCU-sched instead.
- */
-void kfree_call_rcu(struct rcu_head *head,
-                   void (*func)(struct rcu_head *rcu))
-{
-       __call_rcu(head, func, &rcu_sched_state, -1, 1);
-}
-EXPORT_SYMBOL_GPL(kfree_call_rcu);
-
-/*
- * Wait for an rcu-preempt grace period, but make it happen quickly.
- * But because preemptible RCU does not exist, map to rcu-sched.
- */
-void synchronize_rcu_expedited(void)
-{
-       synchronize_sched_expedited();
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/*
- * Because preemptible RCU does not exist, there is never any need to
- * report on tasks preempted in RCU read-side critical sections during
- * expedited RCU grace periods.
- */
-static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
-                              bool wake)
-{
-}
-
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-
-/*
- * Because preemptible RCU does not exist, rcu_barrier() is just
- * another name for rcu_barrier_sched().
- */
-void rcu_barrier(void)
-{
-       rcu_barrier_sched();
-}
-EXPORT_SYMBOL_GPL(rcu_barrier);
-
-/*
- * Because preemptible RCU does not exist, it need not be initialized.
- */
-static void __init __rcu_init_preempt(void)
-{
-}
-
-/*
- * Because preemptible RCU does not exist, tasks cannot possibly exit
- * while in preemptible RCU read-side critical sections.
- */
-void exit_rcu(void)
-{
-}
-
-#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
-
-#ifdef CONFIG_RCU_BOOST
-
-#include "rtmutex_common.h"
-
-#ifdef CONFIG_RCU_TRACE
-
-static void rcu_initiate_boost_trace(struct rcu_node *rnp)
-{
-       if (list_empty(&rnp->blkd_tasks))
-               rnp->n_balk_blkd_tasks++;
-       else if (rnp->exp_tasks == NULL && rnp->gp_tasks == NULL)
-               rnp->n_balk_exp_gp_tasks++;
-       else if (rnp->gp_tasks != NULL && rnp->boost_tasks != NULL)
-               rnp->n_balk_boost_tasks++;
-       else if (rnp->gp_tasks != NULL && rnp->qsmask != 0)
-               rnp->n_balk_notblocked++;
-       else if (rnp->gp_tasks != NULL &&
-                ULONG_CMP_LT(jiffies, rnp->boost_time))
-               rnp->n_balk_notyet++;
-       else
-               rnp->n_balk_nos++;
-}
-
-#else /* #ifdef CONFIG_RCU_TRACE */
-
-static void rcu_initiate_boost_trace(struct rcu_node *rnp)
-{
-}
-
-#endif /* #else #ifdef CONFIG_RCU_TRACE */
-
-static void rcu_wake_cond(struct task_struct *t, int status)
-{
-       /*
-        * If the thread is yielding, only wake it when this
-        * is invoked from idle
-        */
-       if (status != RCU_KTHREAD_YIELDING || is_idle_task(current))
-               wake_up_process(t);
-}
-
-/*
- * Carry out RCU priority boosting on the task indicated by ->exp_tasks
- * or ->boost_tasks, advancing the pointer to the next task in the
- * ->blkd_tasks list.
- *
- * Note that irqs must be enabled: boosting the task can block.
- * Returns 1 if there are more tasks needing to be boosted.
- */
-static int rcu_boost(struct rcu_node *rnp)
-{
-       unsigned long flags;
-       struct rt_mutex mtx;
-       struct task_struct *t;
-       struct list_head *tb;
-
-       if (rnp->exp_tasks == NULL && rnp->boost_tasks == NULL)
-               return 0;  /* Nothing left to boost. */
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-
-       /*
-        * Recheck under the lock: all tasks in need of boosting
-        * might exit their RCU read-side critical sections on their own.
-        */
-       if (rnp->exp_tasks == NULL && rnp->boost_tasks == NULL) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return 0;
-       }
-
-       /*
-        * Preferentially boost tasks blocking expedited grace periods.
-        * This cannot starve the normal grace periods because a second
-        * expedited grace period must boost all blocked tasks, including
-        * those blocking the pre-existing normal grace period.
-        */
-       if (rnp->exp_tasks != NULL) {
-               tb = rnp->exp_tasks;
-               rnp->n_exp_boosts++;
-       } else {
-               tb = rnp->boost_tasks;
-               rnp->n_normal_boosts++;
-       }
-       rnp->n_tasks_boosted++;
-
-       /*
-        * We boost task t by manufacturing an rt_mutex that appears to
-        * be held by task t.  We leave a pointer to that rt_mutex where
-        * task t can find it, and task t will release the mutex when it
-        * exits its outermost RCU read-side critical section.  Then
-        * simply acquiring this artificial rt_mutex will boost task
-        * t's priority.  (Thanks to tglx for suggesting this approach!)
-        *
-        * Note that task t must acquire rnp->lock to remove itself from
-        * the ->blkd_tasks list, which it will do from exit() if from
-        * nowhere else.  We therefore are guaranteed that task t will
-        * stay around at least until we drop rnp->lock.  Note that
-        * rnp->lock also resolves races between our priority boosting
-        * and task t's exiting its outermost RCU read-side critical
-        * section.
-        */
-       t = container_of(tb, struct task_struct, rcu_node_entry);
-       rt_mutex_init_proxy_locked(&mtx, t);
-       t->rcu_boost_mutex = &mtx;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       rt_mutex_lock(&mtx);  /* Side effect: boosts task t's priority. */
-       rt_mutex_unlock(&mtx);  /* Keep lockdep happy. */
-
-       return ACCESS_ONCE(rnp->exp_tasks) != NULL ||
-              ACCESS_ONCE(rnp->boost_tasks) != NULL;
-}
-
-/*
- * Priority-boosting kthread.  One per leaf rcu_node and one for the
- * root rcu_node.
- */
-static int rcu_boost_kthread(void *arg)
-{
-       struct rcu_node *rnp = (struct rcu_node *)arg;
-       int spincnt = 0;
-       int more2boost;
-
-       trace_rcu_utilization(TPS("Start boost kthread@init"));
-       for (;;) {
-               rnp->boost_kthread_status = RCU_KTHREAD_WAITING;
-               trace_rcu_utilization(TPS("End boost kthread@rcu_wait"));
-               rcu_wait(rnp->boost_tasks || rnp->exp_tasks);
-               trace_rcu_utilization(TPS("Start boost kthread@rcu_wait"));
-               rnp->boost_kthread_status = RCU_KTHREAD_RUNNING;
-               more2boost = rcu_boost(rnp);
-               if (more2boost)
-                       spincnt++;
-               else
-                       spincnt = 0;
-               if (spincnt > 10) {
-                       rnp->boost_kthread_status = RCU_KTHREAD_YIELDING;
-                       trace_rcu_utilization(TPS("End boost kthread@rcu_yield"));
-                       schedule_timeout_interruptible(2);
-                       trace_rcu_utilization(TPS("Start boost kthread@rcu_yield"));
-                       spincnt = 0;
-               }
-       }
-       /* NOTREACHED */
-       trace_rcu_utilization(TPS("End boost kthread@notreached"));
-       return 0;
-}
-
-/*
- * Check to see if it is time to start boosting RCU readers that are
- * blocking the current grace period, and, if so, tell the per-rcu_node
- * kthread to start boosting them.  If there is an expedited grace
- * period in progress, it is always time to boost.
- *
- * The caller must hold rnp->lock, which this function releases.
- * The ->boost_kthread_task is immortal, so we don't need to worry
- * about it going away.
- */
-static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
-{
-       struct task_struct *t;
-
-       if (!rcu_preempt_blocked_readers_cgp(rnp) && rnp->exp_tasks == NULL) {
-               rnp->n_balk_exp_gp_tasks++;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return;
-       }
-       if (rnp->exp_tasks != NULL ||
-           (rnp->gp_tasks != NULL &&
-            rnp->boost_tasks == NULL &&
-            rnp->qsmask == 0 &&
-            ULONG_CMP_GE(jiffies, rnp->boost_time))) {
-               if (rnp->exp_tasks == NULL)
-                       rnp->boost_tasks = rnp->gp_tasks;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               t = rnp->boost_kthread_task;
-               if (t)
-                       rcu_wake_cond(t, rnp->boost_kthread_status);
-       } else {
-               rcu_initiate_boost_trace(rnp);
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       }
-}
-
-/*
- * Wake up the per-CPU kthread to invoke RCU callbacks.
- */
-static void invoke_rcu_callbacks_kthread(void)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       __this_cpu_write(rcu_cpu_has_work, 1);
-       if (__this_cpu_read(rcu_cpu_kthread_task) != NULL &&
-           current != __this_cpu_read(rcu_cpu_kthread_task)) {
-               rcu_wake_cond(__this_cpu_read(rcu_cpu_kthread_task),
-                             __this_cpu_read(rcu_cpu_kthread_status));
-       }
-       local_irq_restore(flags);
-}
-
-/*
- * Is the current CPU running the RCU-callbacks kthread?
- * Caller must have preemption disabled.
- */
-static bool rcu_is_callbacks_kthread(void)
-{
-       return __get_cpu_var(rcu_cpu_kthread_task) == current;
-}
-
-#define RCU_BOOST_DELAY_JIFFIES DIV_ROUND_UP(CONFIG_RCU_BOOST_DELAY * HZ, 1000)
-
-/*
- * Do priority-boost accounting for the start of a new grace period.
- */
-static void rcu_preempt_boost_start_gp(struct rcu_node *rnp)
-{
-       rnp->boost_time = jiffies + RCU_BOOST_DELAY_JIFFIES;
-}
-
-/*
- * Create an RCU-boost kthread for the specified node if one does not
- * already exist.  We only create this kthread for preemptible RCU.
- * Returns zero if all is well, a negated errno otherwise.
- */
-static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
-                                                struct rcu_node *rnp)
-{
-       int rnp_index = rnp - &rsp->node[0];
-       unsigned long flags;
-       struct sched_param sp;
-       struct task_struct *t;
-
-       if (&rcu_preempt_state != rsp)
-               return 0;
-
-       if (!rcu_scheduler_fully_active || rnp->qsmaskinit == 0)
-               return 0;
-
-       rsp->boost = 1;
-       if (rnp->boost_kthread_task != NULL)
-               return 0;
-       t = kthread_create(rcu_boost_kthread, (void *)rnp,
-                          "rcub/%d", rnp_index);
-       if (IS_ERR(t))
-               return PTR_ERR(t);
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       rnp->boost_kthread_task = t;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       sp.sched_priority = RCU_BOOST_PRIO;
-       sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
-       wake_up_process(t); /* get to TASK_INTERRUPTIBLE quickly. */
-       return 0;
-}
-
-static void rcu_kthread_do_work(void)
-{
-       rcu_do_batch(&rcu_sched_state, &__get_cpu_var(rcu_sched_data));
-       rcu_do_batch(&rcu_bh_state, &__get_cpu_var(rcu_bh_data));
-       rcu_preempt_do_callbacks();
-}
-
-static void rcu_cpu_kthread_setup(unsigned int cpu)
-{
-       struct sched_param sp;
-
-       sp.sched_priority = RCU_KTHREAD_PRIO;
-       sched_setscheduler_nocheck(current, SCHED_FIFO, &sp);
-}
-
-static void rcu_cpu_kthread_park(unsigned int cpu)
-{
-       per_cpu(rcu_cpu_kthread_status, cpu) = RCU_KTHREAD_OFFCPU;
-}
-
-static int rcu_cpu_kthread_should_run(unsigned int cpu)
-{
-       return __get_cpu_var(rcu_cpu_has_work);
-}
-
-/*
- * Per-CPU kernel thread that invokes RCU callbacks.  This replaces the
- * RCU softirq used in flavors and configurations of RCU that do not
- * support RCU priority boosting.
- */
-static void rcu_cpu_kthread(unsigned int cpu)
-{
-       unsigned int *statusp = &__get_cpu_var(rcu_cpu_kthread_status);
-       char work, *workp = &__get_cpu_var(rcu_cpu_has_work);
-       int spincnt;
-
-       for (spincnt = 0; spincnt < 10; spincnt++) {
-               trace_rcu_utilization(TPS("Start CPU kthread@rcu_wait"));
-               local_bh_disable();
-               *statusp = RCU_KTHREAD_RUNNING;
-               this_cpu_inc(rcu_cpu_kthread_loops);
-               local_irq_disable();
-               work = *workp;
-               *workp = 0;
-               local_irq_enable();
-               if (work)
-                       rcu_kthread_do_work();
-               local_bh_enable();
-               if (*workp == 0) {
-                       trace_rcu_utilization(TPS("End CPU kthread@rcu_wait"));
-                       *statusp = RCU_KTHREAD_WAITING;
-                       return;
-               }
-       }
-       *statusp = RCU_KTHREAD_YIELDING;
-       trace_rcu_utilization(TPS("Start CPU kthread@rcu_yield"));
-       schedule_timeout_interruptible(2);
-       trace_rcu_utilization(TPS("End CPU kthread@rcu_yield"));
-       *statusp = RCU_KTHREAD_WAITING;
-}
-
-/*
- * Set the per-rcu_node kthread's affinity to cover all CPUs that are
- * served by the rcu_node in question.  The CPU hotplug lock is still
- * held, so the value of rnp->qsmaskinit will be stable.
- *
- * We don't include outgoingcpu in the affinity set, use -1 if there is
- * no outgoing CPU.  If there are no CPUs left in the affinity set,
- * this function allows the kthread to execute on any CPU.
- */
-static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu)
-{
-       struct task_struct *t = rnp->boost_kthread_task;
-       unsigned long mask = rnp->qsmaskinit;
-       cpumask_var_t cm;
-       int cpu;
-
-       if (!t)
-               return;
-       if (!zalloc_cpumask_var(&cm, GFP_KERNEL))
-               return;
-       for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1)
-               if ((mask & 0x1) && cpu != outgoingcpu)
-                       cpumask_set_cpu(cpu, cm);
-       if (cpumask_weight(cm) == 0) {
-               cpumask_setall(cm);
-               for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++)
-                       cpumask_clear_cpu(cpu, cm);
-               WARN_ON_ONCE(cpumask_weight(cm) == 0);
-       }
-       set_cpus_allowed_ptr(t, cm);
-       free_cpumask_var(cm);
-}
-
-static struct smp_hotplug_thread rcu_cpu_thread_spec = {
-       .store                  = &rcu_cpu_kthread_task,
-       .thread_should_run      = rcu_cpu_kthread_should_run,
-       .thread_fn              = rcu_cpu_kthread,
-       .thread_comm            = "rcuc/%u",
-       .setup                  = rcu_cpu_kthread_setup,
-       .park                   = rcu_cpu_kthread_park,
-};
-
-/*
- * Spawn all kthreads -- called as soon as the scheduler is running.
- */
-static int __init rcu_spawn_kthreads(void)
-{
-       struct rcu_node *rnp;
-       int cpu;
-
-       rcu_scheduler_fully_active = 1;
-       for_each_possible_cpu(cpu)
-               per_cpu(rcu_cpu_has_work, cpu) = 0;
-       BUG_ON(smpboot_register_percpu_thread(&rcu_cpu_thread_spec));
-       rnp = rcu_get_root(rcu_state);
-       (void)rcu_spawn_one_boost_kthread(rcu_state, rnp);
-       if (NUM_RCU_NODES > 1) {
-               rcu_for_each_leaf_node(rcu_state, rnp)
-                       (void)rcu_spawn_one_boost_kthread(rcu_state, rnp);
-       }
-       return 0;
-}
-early_initcall(rcu_spawn_kthreads);
-
-static void rcu_prepare_kthreads(int cpu)
-{
-       struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
-       struct rcu_node *rnp = rdp->mynode;
-
-       /* Fire up the incoming CPU's kthread and leaf rcu_node kthread. */
-       if (rcu_scheduler_fully_active)
-               (void)rcu_spawn_one_boost_kthread(rcu_state, rnp);
-}
-
-#else /* #ifdef CONFIG_RCU_BOOST */
-
-static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
-{
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-}
-
-static void invoke_rcu_callbacks_kthread(void)
-{
-       WARN_ON_ONCE(1);
-}
-
-static bool rcu_is_callbacks_kthread(void)
-{
-       return false;
-}
-
-static void rcu_preempt_boost_start_gp(struct rcu_node *rnp)
-{
-}
-
-static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu)
-{
-}
-
-static int __init rcu_scheduler_really_started(void)
-{
-       rcu_scheduler_fully_active = 1;
-       return 0;
-}
-early_initcall(rcu_scheduler_really_started);
-
-static void rcu_prepare_kthreads(int cpu)
-{
-}
-
-#endif /* #else #ifdef CONFIG_RCU_BOOST */
-
-#if !defined(CONFIG_RCU_FAST_NO_HZ)
-
-/*
- * Check to see if any future RCU-related work will need to be done
- * by the current CPU, even if none need be done immediately, returning
- * 1 if so.  This function is part of the RCU implementation; it is -not-
- * an exported member of the RCU API.
- *
- * Because we not have RCU_FAST_NO_HZ, just check whether this CPU needs
- * any flavor of RCU.
- */
-int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies)
-{
-       *delta_jiffies = ULONG_MAX;
-       return rcu_cpu_has_callbacks(cpu, NULL);
-}
-
-/*
- * Because we do not have RCU_FAST_NO_HZ, don't bother cleaning up
- * after it.
- */
-static void rcu_cleanup_after_idle(int cpu)
-{
-}
-
-/*
- * Do the idle-entry grace-period work, which, because CONFIG_RCU_FAST_NO_HZ=n,
- * is nothing.
- */
-static void rcu_prepare_for_idle(int cpu)
-{
-}
-
-/*
- * Don't bother keeping a running count of the number of RCU callbacks
- * posted because CONFIG_RCU_FAST_NO_HZ=n.
- */
-static void rcu_idle_count_callbacks_posted(void)
-{
-}
-
-#else /* #if !defined(CONFIG_RCU_FAST_NO_HZ) */
-
-/*
- * This code is invoked when a CPU goes idle, at which point we want
- * to have the CPU do everything required for RCU so that it can enter
- * the energy-efficient dyntick-idle mode.  This is handled by a
- * state machine implemented by rcu_prepare_for_idle() below.
- *
- * The following three proprocessor symbols control this state machine:
- *
- * RCU_IDLE_GP_DELAY gives the number of jiffies that a CPU is permitted
- *     to sleep in dyntick-idle mode with RCU callbacks pending.  This
- *     is sized to be roughly one RCU grace period.  Those energy-efficiency
- *     benchmarkers who might otherwise be tempted to set this to a large
- *     number, be warned: Setting RCU_IDLE_GP_DELAY too high can hang your
- *     system.  And if you are -that- concerned about energy efficiency,
- *     just power the system down and be done with it!
- * RCU_IDLE_LAZY_GP_DELAY gives the number of jiffies that a CPU is
- *     permitted to sleep in dyntick-idle mode with only lazy RCU
- *     callbacks pending.  Setting this too high can OOM your system.
- *
- * The values below work well in practice.  If future workloads require
- * adjustment, they can be converted into kernel config parameters, though
- * making the state machine smarter might be a better option.
- */
-#define RCU_IDLE_GP_DELAY 4            /* Roughly one grace period. */
-#define RCU_IDLE_LAZY_GP_DELAY (6 * HZ)        /* Roughly six seconds. */
-
-static int rcu_idle_gp_delay = RCU_IDLE_GP_DELAY;
-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;
-
-/*
- * Try to advance callbacks for all flavors of RCU on the current CPU.
- * Afterwards, if there are any callbacks ready for immediate invocation,
- * return true.
- */
-static bool rcu_try_advance_all_cbs(void)
-{
-       bool cbs_ready = false;
-       struct rcu_data *rdp;
-       struct rcu_node *rnp;
-       struct rcu_state *rsp;
-
-       for_each_rcu_flavor(rsp) {
-               rdp = this_cpu_ptr(rsp->rda);
-               rnp = rdp->mynode;
-
-               /*
-                * Don't bother checking unless a grace period has
-                * completed since we last checked and there are
-                * callbacks not yet ready to invoke.
-                */
-               if (rdp->completed != rnp->completed &&
-                   rdp->nxttail[RCU_DONE_TAIL] != rdp->nxttail[RCU_NEXT_TAIL])
-                       note_gp_changes(rsp, rdp);
-
-               if (cpu_has_callbacks_ready_to_invoke(rdp))
-                       cbs_ready = true;
-       }
-       return cbs_ready;
-}
-
-/*
- * Allow the CPU to enter dyntick-idle mode unless it has callbacks ready
- * to invoke.  If the CPU has callbacks, try to advance them.  Tell the
- * caller to set the timeout based on whether or not there are non-lazy
- * callbacks.
- *
- * The caller must have disabled interrupts.
- */
-int rcu_needs_cpu(int cpu, unsigned long *dj)
-{
-       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
-
-       /* Snapshot to detect later posting of non-lazy callback. */
-       rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted;
-
-       /* If no callbacks, RCU doesn't need the CPU. */
-       if (!rcu_cpu_has_callbacks(cpu, &rdtp->all_lazy)) {
-               *dj = ULONG_MAX;
-               return 0;
-       }
-
-       /* Attempt to advance callbacks. */
-       if (rcu_try_advance_all_cbs()) {
-               /* Some ready to invoke, so initiate later invocation. */
-               invoke_rcu_core();
-               return 1;
-       }
-       rdtp->last_accelerate = jiffies;
-
-       /* Request timer delay depending on laziness, and round. */
-       if (!rdtp->all_lazy) {
-               *dj = round_up(rcu_idle_gp_delay + jiffies,
-                              rcu_idle_gp_delay) - jiffies;
-       } else {
-               *dj = round_jiffies(rcu_idle_lazy_gp_delay + jiffies) - jiffies;
-       }
-       return 0;
-}
-
-/*
- * Prepare a CPU for idle from an RCU perspective.  The first major task
- * is to sense whether nohz mode has been enabled or disabled via sysfs.
- * The second major task is to check to see if a non-lazy callback has
- * arrived at a CPU that previously had only lazy callbacks.  The third
- * major task is to accelerate (that is, assign grace-period numbers to)
- * any recently arrived callbacks.
- *
- * The caller must have disabled interrupts.
- */
-static void rcu_prepare_for_idle(int cpu)
-{
-       struct rcu_data *rdp;
-       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
-       struct rcu_node *rnp;
-       struct rcu_state *rsp;
-       int tne;
-
-       /* Handle nohz enablement switches conservatively. */
-       tne = ACCESS_ONCE(tick_nohz_enabled);
-       if (tne != rdtp->tick_nohz_enabled_snap) {
-               if (rcu_cpu_has_callbacks(cpu, NULL))
-                       invoke_rcu_core(); /* force nohz to see update. */
-               rdtp->tick_nohz_enabled_snap = tne;
-               return;
-       }
-       if (!tne)
-               return;
-
-       /* If this is a no-CBs CPU, no callbacks, just return. */
-       if (rcu_is_nocb_cpu(cpu))
-               return;
-
-       /*
-        * If a non-lazy callback arrived at a CPU having only lazy
-        * callbacks, invoke RCU core for the side-effect of recalculating
-        * idle duration on re-entry to idle.
-        */
-       if (rdtp->all_lazy &&
-           rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) {
-               invoke_rcu_core();
-               return;
-       }
-
-       /*
-        * If we have not yet accelerated this jiffy, accelerate all
-        * callbacks on this CPU.
-        */
-       if (rdtp->last_accelerate == jiffies)
-               return;
-       rdtp->last_accelerate = jiffies;
-       for_each_rcu_flavor(rsp) {
-               rdp = per_cpu_ptr(rsp->rda, cpu);
-               if (!*rdp->nxttail[RCU_DONE_TAIL])
-                       continue;
-               rnp = rdp->mynode;
-               raw_spin_lock(&rnp->lock); /* irqs already disabled. */
-               rcu_accelerate_cbs(rsp, rnp, rdp);
-               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
-       }
-}
-
-/*
- * Clean up for exit from idle.  Attempt to advance callbacks based on
- * any grace periods that elapsed while the CPU was idle, and if any
- * callbacks are now ready to invoke, initiate invocation.
- */
-static void rcu_cleanup_after_idle(int cpu)
-{
-       struct rcu_data *rdp;
-       struct rcu_state *rsp;
-
-       if (rcu_is_nocb_cpu(cpu))
-               return;
-       rcu_try_advance_all_cbs();
-       for_each_rcu_flavor(rsp) {
-               rdp = per_cpu_ptr(rsp->rda, cpu);
-               if (cpu_has_callbacks_ready_to_invoke(rdp))
-                       invoke_rcu_core();
-       }
-}
-
-/*
- * Keep a running count of the number of non-lazy callbacks posted
- * on this CPU.  This running counter (which is never decremented) allows
- * rcu_prepare_for_idle() to detect when something out of the idle loop
- * posts a callback, even if an equal number of callbacks are invoked.
- * Of course, callbacks should only be posted from within a trace event
- * designed to be called from idle or from within RCU_NONIDLE().
- */
-static void rcu_idle_count_callbacks_posted(void)
-{
-       __this_cpu_add(rcu_dynticks.nonlazy_posted, 1);
-}
-
-/*
- * Data for flushing lazy RCU callbacks at OOM time.
- */
-static atomic_t oom_callback_count;
-static DECLARE_WAIT_QUEUE_HEAD(oom_callback_wq);
-
-/*
- * RCU OOM callback -- decrement the outstanding count and deliver the
- * wake-up if we are the last one.
- */
-static void rcu_oom_callback(struct rcu_head *rhp)
-{
-       if (atomic_dec_and_test(&oom_callback_count))
-               wake_up(&oom_callback_wq);
-}
-
-/*
- * Post an rcu_oom_notify callback on the current CPU if it has at
- * least one lazy callback.  This will unnecessarily post callbacks
- * to CPUs that already have a non-lazy callback at the end of their
- * callback list, but this is an infrequent operation, so accept some
- * extra overhead to keep things simple.
- */
-static void rcu_oom_notify_cpu(void *unused)
-{
-       struct rcu_state *rsp;
-       struct rcu_data *rdp;
-
-       for_each_rcu_flavor(rsp) {
-               rdp = __this_cpu_ptr(rsp->rda);
-               if (rdp->qlen_lazy != 0) {
-                       atomic_inc(&oom_callback_count);
-                       rsp->call(&rdp->oom_head, rcu_oom_callback);
-               }
-       }
-}
-
-/*
- * If low on memory, ensure that each CPU has a non-lazy callback.
- * This will wake up CPUs that have only lazy callbacks, in turn
- * ensuring that they free up the corresponding memory in a timely manner.
- * Because an uncertain amount of memory will be freed in some uncertain
- * timeframe, we do not claim to have freed anything.
- */
-static int rcu_oom_notify(struct notifier_block *self,
-                         unsigned long notused, void *nfreed)
-{
-       int cpu;
-
-       /* Wait for callbacks from earlier instance to complete. */
-       wait_event(oom_callback_wq, atomic_read(&oom_callback_count) == 0);
-
-       /*
-        * Prevent premature wakeup: ensure that all increments happen
-        * before there is a chance of the counter reaching zero.
-        */
-       atomic_set(&oom_callback_count, 1);
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               smp_call_function_single(cpu, rcu_oom_notify_cpu, NULL, 1);
-               cond_resched();
-       }
-       put_online_cpus();
-
-       /* Unconditionally decrement: no need to wake ourselves up. */
-       atomic_dec(&oom_callback_count);
-
-       return NOTIFY_OK;
-}
-
-static struct notifier_block rcu_oom_nb = {
-       .notifier_call = rcu_oom_notify
-};
-
-static int __init rcu_register_oom_notifier(void)
-{
-       register_oom_notifier(&rcu_oom_nb);
-       return 0;
-}
-early_initcall(rcu_register_oom_notifier);
-
-#endif /* #else #if !defined(CONFIG_RCU_FAST_NO_HZ) */
-
-#ifdef CONFIG_RCU_CPU_STALL_INFO
-
-#ifdef CONFIG_RCU_FAST_NO_HZ
-
-static void print_cpu_stall_fast_no_hz(char *cp, int cpu)
-{
-       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
-       unsigned long nlpd = rdtp->nonlazy_posted - rdtp->nonlazy_posted_snap;
-
-       sprintf(cp, "last_accelerate: %04lx/%04lx, nonlazy_posted: %ld, %c%c",
-               rdtp->last_accelerate & 0xffff, jiffies & 0xffff,
-               ulong2long(nlpd),
-               rdtp->all_lazy ? 'L' : '.',
-               rdtp->tick_nohz_enabled_snap ? '.' : 'D');
-}
-
-#else /* #ifdef CONFIG_RCU_FAST_NO_HZ */
-
-static void print_cpu_stall_fast_no_hz(char *cp, int cpu)
-{
-       *cp = '\0';
-}
-
-#endif /* #else #ifdef CONFIG_RCU_FAST_NO_HZ */
-
-/* Initiate the stall-info list. */
-static void print_cpu_stall_info_begin(void)
-{
-       pr_cont("\n");
-}
-
-/*
- * Print out diagnostic information for the specified stalled CPU.
- *
- * If the specified CPU is aware of the current RCU grace period
- * (flavor specified by rsp), then print the number of scheduling
- * clock interrupts the CPU has taken during the time that it has
- * been aware.  Otherwise, print the number of RCU grace periods
- * that this CPU is ignorant of, for example, "1" if the CPU was
- * aware of the previous grace period.
- *
- * Also print out idle and (if CONFIG_RCU_FAST_NO_HZ) idle-entry info.
- */
-static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
-{
-       char fast_no_hz[72];
-       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-       struct rcu_dynticks *rdtp = rdp->dynticks;
-       char *ticks_title;
-       unsigned long ticks_value;
-
-       if (rsp->gpnum == rdp->gpnum) {
-               ticks_title = "ticks this GP";
-               ticks_value = rdp->ticks_this_gp;
-       } else {
-               ticks_title = "GPs behind";
-               ticks_value = rsp->gpnum - rdp->gpnum;
-       }
-       print_cpu_stall_fast_no_hz(fast_no_hz, cpu);
-       pr_err("\t%d: (%lu %s) idle=%03x/%llx/%d softirq=%u/%u %s\n",
-              cpu, ticks_value, ticks_title,
-              atomic_read(&rdtp->dynticks) & 0xfff,
-              rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
-              rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
-              fast_no_hz);
-}
-
-/* Terminate the stall-info list. */
-static void print_cpu_stall_info_end(void)
-{
-       pr_err("\t");
-}
-
-/* Zero ->ticks_this_gp for all flavors of RCU. */
-static void zero_cpu_stall_ticks(struct rcu_data *rdp)
-{
-       rdp->ticks_this_gp = 0;
-       rdp->softirq_snap = kstat_softirqs_cpu(RCU_SOFTIRQ, smp_processor_id());
-}
-
-/* Increment ->ticks_this_gp for all flavors of RCU. */
-static void increment_cpu_stall_ticks(void)
-{
-       struct rcu_state *rsp;
-
-       for_each_rcu_flavor(rsp)
-               __this_cpu_ptr(rsp->rda)->ticks_this_gp++;
-}
-
-#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
-
-static void print_cpu_stall_info_begin(void)
-{
-       pr_cont(" {");
-}
-
-static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
-{
-       pr_cont(" %d", cpu);
-}
-
-static void print_cpu_stall_info_end(void)
-{
-       pr_cont("} ");
-}
-
-static void zero_cpu_stall_ticks(struct rcu_data *rdp)
-{
-}
-
-static void increment_cpu_stall_ticks(void)
-{
-}
-
-#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */
-
-#ifdef CONFIG_RCU_NOCB_CPU
-
-/*
- * Offload callback processing from the boot-time-specified set of CPUs
- * specified by rcu_nocb_mask.  For each CPU in the set, there is a
- * kthread created that pulls the callbacks from the corresponding CPU,
- * waits for a grace period to elapse, and invokes the callbacks.
- * The no-CBs CPUs do a wake_up() on their kthread when they insert
- * a callback into any empty list, unless the rcu_nocb_poll boot parameter
- * has been specified, in which case each kthread actively polls its
- * CPU.  (Which isn't so great for energy efficiency, but which does
- * reduce RCU's overhead on that CPU.)
- *
- * This is intended to be used in conjunction with Frederic Weisbecker's
- * adaptive-idle work, which would seriously reduce OS jitter on CPUs
- * running CPU-bound user-mode computations.
- *
- * Offloading of callback processing could also in theory be used as
- * an energy-efficiency measure because CPUs with no RCU callbacks
- * queued are more aggressive about entering dyntick-idle mode.
- */
-
-
-/* Parse the boot-time rcu_nocb_mask CPU list from the kernel parameters. */
-static int __init rcu_nocb_setup(char *str)
-{
-       alloc_bootmem_cpumask_var(&rcu_nocb_mask);
-       have_rcu_nocb_mask = true;
-       cpulist_parse(str, rcu_nocb_mask);
-       return 1;
-}
-__setup("rcu_nocbs=", rcu_nocb_setup);
-
-static int __init parse_rcu_nocb_poll(char *arg)
-{
-       rcu_nocb_poll = 1;
-       return 0;
-}
-early_param("rcu_nocb_poll", parse_rcu_nocb_poll);
-
-/*
- * Do any no-CBs CPUs need another grace period?
- *
- * Interrupts must be disabled.  If the caller does not hold the root
- * rnp_node structure's ->lock, the results are advisory only.
- */
-static int rcu_nocb_needs_gp(struct rcu_state *rsp)
-{
-       struct rcu_node *rnp = rcu_get_root(rsp);
-
-       return rnp->need_future_gp[(ACCESS_ONCE(rnp->completed) + 1) & 0x1];
-}
-
-/*
- * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended
- * grace period.
- */
-static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
-{
-       wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
-}
-
-/*
- * Set the root rcu_node structure's ->need_future_gp field
- * based on the sum of those of all rcu_node structures.  This does
- * double-count the root rcu_node structure's requests, but this
- * is necessary to handle the possibility of a rcu_nocb_kthread()
- * having awakened during the time that the rcu_node structures
- * were being updated for the end of the previous grace period.
- */
-static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq)
-{
-       rnp->need_future_gp[(rnp->completed + 1) & 0x1] += nrq;
-}
-
-static void rcu_init_one_nocb(struct rcu_node *rnp)
-{
-       init_waitqueue_head(&rnp->nocb_gp_wq[0]);
-       init_waitqueue_head(&rnp->nocb_gp_wq[1]);
-}
-
-/* Is the specified CPU a no-CPUs CPU? */
-bool rcu_is_nocb_cpu(int cpu)
-{
-       if (have_rcu_nocb_mask)
-               return cpumask_test_cpu(cpu, rcu_nocb_mask);
-       return false;
-}
-
-/*
- * Enqueue the specified string of rcu_head structures onto the specified
- * CPU's no-CBs lists.  The CPU is specified by rdp, the head of the
- * string by rhp, and the tail of the string by rhtp.  The non-lazy/lazy
- * counts are supplied by rhcount and rhcount_lazy.
- *
- * If warranted, also wake up the kthread servicing this CPUs queues.
- */
-static void __call_rcu_nocb_enqueue(struct rcu_data *rdp,
-                                   struct rcu_head *rhp,
-                                   struct rcu_head **rhtp,
-                                   int rhcount, int rhcount_lazy)
-{
-       int len;
-       struct rcu_head **old_rhpp;
-       struct task_struct *t;
-
-       /* Enqueue the callback on the nocb list and update counts. */
-       old_rhpp = xchg(&rdp->nocb_tail, rhtp);
-       ACCESS_ONCE(*old_rhpp) = rhp;
-       atomic_long_add(rhcount, &rdp->nocb_q_count);
-       atomic_long_add(rhcount_lazy, &rdp->nocb_q_count_lazy);
-
-       /* If we are not being polled and there is a kthread, awaken it ... */
-       t = ACCESS_ONCE(rdp->nocb_kthread);
-       if (rcu_nocb_poll | !t)
-               return;
-       len = atomic_long_read(&rdp->nocb_q_count);
-       if (old_rhpp == &rdp->nocb_head) {
-               wake_up(&rdp->nocb_wq); /* ... only if queue was empty ... */
-               rdp->qlen_last_fqs_check = 0;
-       } else if (len > rdp->qlen_last_fqs_check + qhimark) {
-               wake_up_process(t); /* ... or if many callbacks queued. */
-               rdp->qlen_last_fqs_check = LONG_MAX / 2;
-       }
-       return;
-}
-
-/*
- * This is a helper for __call_rcu(), which invokes this when the normal
- * callback queue is inoperable.  If this is not a no-CBs CPU, this
- * function returns failure back to __call_rcu(), which can complain
- * appropriately.
- *
- * Otherwise, this function queues the callback where the corresponding
- * "rcuo" kthread can find it.
- */
-static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
-                           bool lazy)
-{
-
-       if (!rcu_is_nocb_cpu(rdp->cpu))
-               return 0;
-       __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy);
-       if (__is_kfree_rcu_offset((unsigned long)rhp->func))
-               trace_rcu_kfree_callback(rdp->rsp->name, rhp,
-                                        (unsigned long)rhp->func,
-                                        rdp->qlen_lazy, rdp->qlen);
-       else
-               trace_rcu_callback(rdp->rsp->name, rhp,
-                                  rdp->qlen_lazy, rdp->qlen);
-       return 1;
-}
-
-/*
- * Adopt orphaned callbacks on a no-CBs CPU, or return 0 if this is
- * not a no-CBs CPU.
- */
-static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
-                                                    struct rcu_data *rdp)
-{
-       long ql = rsp->qlen;
-       long qll = rsp->qlen_lazy;
-
-       /* If this is not a no-CBs CPU, tell the caller to do it the old way. */
-       if (!rcu_is_nocb_cpu(smp_processor_id()))
-               return 0;
-       rsp->qlen = 0;
-       rsp->qlen_lazy = 0;
-
-       /* First, enqueue the donelist, if any.  This preserves CB ordering. */
-       if (rsp->orphan_donelist != NULL) {
-               __call_rcu_nocb_enqueue(rdp, rsp->orphan_donelist,
-                                       rsp->orphan_donetail, ql, qll);
-               ql = qll = 0;
-               rsp->orphan_donelist = NULL;
-               rsp->orphan_donetail = &rsp->orphan_donelist;
-       }
-       if (rsp->orphan_nxtlist != NULL) {
-               __call_rcu_nocb_enqueue(rdp, rsp->orphan_nxtlist,
-                                       rsp->orphan_nxttail, ql, qll);
-               ql = qll = 0;
-               rsp->orphan_nxtlist = NULL;
-               rsp->orphan_nxttail = &rsp->orphan_nxtlist;
-       }
-       return 1;
-}
-
-/*
- * If necessary, kick off a new grace period, and either way wait
- * for a subsequent grace period to complete.
- */
-static void rcu_nocb_wait_gp(struct rcu_data *rdp)
-{
-       unsigned long c;
-       bool d;
-       unsigned long flags;
-       struct rcu_node *rnp = rdp->mynode;
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       c = rcu_start_future_gp(rnp, rdp);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-
-       /*
-        * Wait for the grace period.  Do so interruptibly to avoid messing
-        * up the load average.
-        */
-       trace_rcu_future_gp(rnp, rdp, c, TPS("StartWait"));
-       for (;;) {
-               wait_event_interruptible(
-                       rnp->nocb_gp_wq[c & 0x1],
-                       (d = ULONG_CMP_GE(ACCESS_ONCE(rnp->completed), c)));
-               if (likely(d))
-                       break;
-               flush_signals(current);
-               trace_rcu_future_gp(rnp, rdp, c, TPS("ResumeWait"));
-       }
-       trace_rcu_future_gp(rnp, rdp, c, TPS("EndWait"));
-       smp_mb(); /* Ensure that CB invocation happens after GP end. */
-}
-
-/*
- * Per-rcu_data kthread, but only for no-CBs CPUs.  Each kthread invokes
- * callbacks queued by the corresponding no-CBs CPU.
- */
-static int rcu_nocb_kthread(void *arg)
-{
-       int c, cl;
-       struct rcu_head *list;
-       struct rcu_head *next;
-       struct rcu_head **tail;
-       struct rcu_data *rdp = arg;
-
-       /* Each pass through this loop invokes one batch of callbacks */
-       for (;;) {
-               /* If not polling, wait for next batch of callbacks. */
-               if (!rcu_nocb_poll)
-                       wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head);
-               list = ACCESS_ONCE(rdp->nocb_head);
-               if (!list) {
-                       schedule_timeout_interruptible(1);
-                       flush_signals(current);
-                       continue;
-               }
-
-               /*
-                * Extract queued callbacks, update counts, and wait
-                * for a grace period to elapse.
-                */
-               ACCESS_ONCE(rdp->nocb_head) = NULL;
-               tail = xchg(&rdp->nocb_tail, &rdp->nocb_head);
-               c = atomic_long_xchg(&rdp->nocb_q_count, 0);
-               cl = atomic_long_xchg(&rdp->nocb_q_count_lazy, 0);
-               ACCESS_ONCE(rdp->nocb_p_count) += c;
-               ACCESS_ONCE(rdp->nocb_p_count_lazy) += cl;
-               rcu_nocb_wait_gp(rdp);
-
-               /* Each pass through the following loop invokes a callback. */
-               trace_rcu_batch_start(rdp->rsp->name, cl, c, -1);
-               c = cl = 0;
-               while (list) {
-                       next = list->next;
-                       /* Wait for enqueuing to complete, if needed. */
-                       while (next == NULL && &list->next != tail) {
-                               schedule_timeout_interruptible(1);
-                               next = list->next;
-                       }
-                       debug_rcu_head_unqueue(list);
-                       local_bh_disable();
-                       if (__rcu_reclaim(rdp->rsp->name, list))
-                               cl++;
-                       c++;
-                       local_bh_enable();
-                       list = next;
-               }
-               trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1);
-               ACCESS_ONCE(rdp->nocb_p_count) -= c;
-               ACCESS_ONCE(rdp->nocb_p_count_lazy) -= cl;
-               rdp->n_nocbs_invoked += c;
-       }
-       return 0;
-}
-
-/* Initialize per-rcu_data variables for no-CBs CPUs. */
-static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
-{
-       rdp->nocb_tail = &rdp->nocb_head;
-       init_waitqueue_head(&rdp->nocb_wq);
-}
-
-/* Create a kthread for each RCU flavor for each no-CBs CPU. */
-static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp)
-{
-       int cpu;
-       struct rcu_data *rdp;
-       struct task_struct *t;
-
-       if (rcu_nocb_mask == NULL)
-               return;
-       for_each_cpu(cpu, rcu_nocb_mask) {
-               rdp = per_cpu_ptr(rsp->rda, cpu);
-               t = kthread_run(rcu_nocb_kthread, rdp,
-                               "rcuo%c/%d", rsp->abbr, cpu);
-               BUG_ON(IS_ERR(t));
-               ACCESS_ONCE(rdp->nocb_kthread) = t;
-       }
-}
-
-/* Prevent __call_rcu() from enqueuing callbacks on no-CBs CPUs */
-static bool init_nocb_callback_list(struct rcu_data *rdp)
-{
-       if (rcu_nocb_mask == NULL ||
-           !cpumask_test_cpu(rdp->cpu, rcu_nocb_mask))
-               return false;
-       rdp->nxttail[RCU_NEXT_TAIL] = NULL;
-       return true;
-}
-
-#else /* #ifdef CONFIG_RCU_NOCB_CPU */
-
-static int rcu_nocb_needs_gp(struct rcu_state *rsp)
-{
-       return 0;
-}
-
-static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
-{
-}
-
-static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq)
-{
-}
-
-static void rcu_init_one_nocb(struct rcu_node *rnp)
-{
-}
-
-static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
-                           bool lazy)
-{
-       return 0;
-}
-
-static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
-                                                    struct rcu_data *rdp)
-{
-       return 0;
-}
-
-static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
-{
-}
-
-static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp)
-{
-}
-
-static bool init_nocb_callback_list(struct rcu_data *rdp)
-{
-       return false;
-}
-
-#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */
-
-/*
- * An adaptive-ticks CPU can potentially execute in kernel mode for an
- * arbitrarily long period of time with the scheduling-clock tick turned
- * off.  RCU will be paying attention to this CPU because it is in the
- * kernel, but the CPU cannot be guaranteed to be executing the RCU state
- * machine because the scheduling-clock tick has been disabled.  Therefore,
- * if an adaptive-ticks CPU is failing to respond to the current grace
- * period and has not be idle from an RCU perspective, kick it.
- */
-static void rcu_kick_nohz_cpu(int cpu)
-{
-#ifdef CONFIG_NO_HZ_FULL
-       if (tick_nohz_full_cpu(cpu))
-               smp_send_reschedule(cpu);
-#endif /* #ifdef CONFIG_NO_HZ_FULL */
-}
-
-
-#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
-
-/*
- * Define RCU flavor that holds sysidle state.  This needs to be the
- * most active flavor of RCU.
- */
-#ifdef CONFIG_PREEMPT_RCU
-static struct rcu_state *rcu_sysidle_state = &rcu_preempt_state;
-#else /* #ifdef CONFIG_PREEMPT_RCU */
-static struct rcu_state *rcu_sysidle_state = &rcu_sched_state;
-#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
-
-static int full_sysidle_state;         /* Current system-idle state. */
-#define RCU_SYSIDLE_NOT                0       /* Some CPU is not idle. */
-#define RCU_SYSIDLE_SHORT      1       /* All CPUs idle for brief period. */
-#define RCU_SYSIDLE_LONG       2       /* All CPUs idle for long enough. */
-#define RCU_SYSIDLE_FULL       3       /* All CPUs idle, ready for sysidle. */
-#define RCU_SYSIDLE_FULL_NOTED 4       /* Actually entered sysidle state. */
-
-/*
- * Invoked to note exit from irq or task transition to idle.  Note that
- * usermode execution does -not- count as idle here!  After all, we want
- * to detect full-system idle states, not RCU quiescent states and grace
- * periods.  The caller must have disabled interrupts.
- */
-static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq)
-{
-       unsigned long j;
-
-       /* Adjust nesting, check for fully idle. */
-       if (irq) {
-               rdtp->dynticks_idle_nesting--;
-               WARN_ON_ONCE(rdtp->dynticks_idle_nesting < 0);
-               if (rdtp->dynticks_idle_nesting != 0)
-                       return;  /* Still not fully idle. */
-       } else {
-               if ((rdtp->dynticks_idle_nesting & DYNTICK_TASK_NEST_MASK) ==
-                   DYNTICK_TASK_NEST_VALUE) {
-                       rdtp->dynticks_idle_nesting = 0;
-               } else {
-                       rdtp->dynticks_idle_nesting -= DYNTICK_TASK_NEST_VALUE;
-                       WARN_ON_ONCE(rdtp->dynticks_idle_nesting < 0);
-                       return;  /* Still not fully idle. */
-               }
-       }
-
-       /* Record start of fully idle period. */
-       j = jiffies;
-       ACCESS_ONCE(rdtp->dynticks_idle_jiffies) = j;
-       smp_mb__before_atomic_inc();
-       atomic_inc(&rdtp->dynticks_idle);
-       smp_mb__after_atomic_inc();
-       WARN_ON_ONCE(atomic_read(&rdtp->dynticks_idle) & 0x1);
-}
-
-/*
- * Unconditionally force exit from full system-idle state.  This is
- * invoked when a normal CPU exits idle, but must be called separately
- * for the timekeeping CPU (tick_do_timer_cpu).  The reason for this
- * is that the timekeeping CPU is permitted to take scheduling-clock
- * interrupts while the system is in system-idle state, and of course
- * rcu_sysidle_exit() has no way of distinguishing a scheduling-clock
- * interrupt from any other type of interrupt.
- */
-void rcu_sysidle_force_exit(void)
-{
-       int oldstate = ACCESS_ONCE(full_sysidle_state);
-       int newoldstate;
-
-       /*
-        * Each pass through the following loop attempts to exit full
-        * system-idle state.  If contention proves to be a problem,
-        * a trylock-based contention tree could be used here.
-        */
-       while (oldstate > RCU_SYSIDLE_SHORT) {
-               newoldstate = cmpxchg(&full_sysidle_state,
-                                     oldstate, RCU_SYSIDLE_NOT);
-               if (oldstate == newoldstate &&
-                   oldstate == RCU_SYSIDLE_FULL_NOTED) {
-                       rcu_kick_nohz_cpu(tick_do_timer_cpu);
-                       return; /* We cleared it, done! */
-               }
-               oldstate = newoldstate;
-       }
-       smp_mb(); /* Order initial oldstate fetch vs. later non-idle work. */
-}
-
-/*
- * Invoked to note entry to irq or task transition from idle.  Note that
- * usermode execution does -not- count as idle here!  The caller must
- * have disabled interrupts.
- */
-static void rcu_sysidle_exit(struct rcu_dynticks *rdtp, int irq)
-{
-       /* Adjust nesting, check for already non-idle. */
-       if (irq) {
-               rdtp->dynticks_idle_nesting++;
-               WARN_ON_ONCE(rdtp->dynticks_idle_nesting <= 0);
-               if (rdtp->dynticks_idle_nesting != 1)
-                       return; /* Already non-idle. */
-       } else {
-               /*
-                * Allow for irq misnesting.  Yes, it really is possible
-                * to enter an irq handler then never leave it, and maybe
-                * also vice versa.  Handle both possibilities.
-                */
-               if (rdtp->dynticks_idle_nesting & DYNTICK_TASK_NEST_MASK) {
-                       rdtp->dynticks_idle_nesting += DYNTICK_TASK_NEST_VALUE;
-                       WARN_ON_ONCE(rdtp->dynticks_idle_nesting <= 0);
-                       return; /* Already non-idle. */
-               } else {
-                       rdtp->dynticks_idle_nesting = DYNTICK_TASK_EXIT_IDLE;
-               }
-       }
-
-       /* Record end of idle period. */
-       smp_mb__before_atomic_inc();
-       atomic_inc(&rdtp->dynticks_idle);
-       smp_mb__after_atomic_inc();
-       WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks_idle) & 0x1));
-
-       /*
-        * If we are the timekeeping CPU, we are permitted to be non-idle
-        * during a system-idle state.  This must be the case, because
-        * the timekeeping CPU has to take scheduling-clock interrupts
-        * during the time that the system is transitioning to full
-        * system-idle state.  This means that the timekeeping CPU must
-        * invoke rcu_sysidle_force_exit() directly if it does anything
-        * more than take a scheduling-clock interrupt.
-        */
-       if (smp_processor_id() == tick_do_timer_cpu)
-               return;
-
-       /* Update system-idle state: We are clearly no longer fully idle! */
-       rcu_sysidle_force_exit();
-}
-
-/*
- * Check to see if the current CPU is idle.  Note that usermode execution
- * does not count as idle.  The caller must have disabled interrupts.
- */
-static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,
-                                 unsigned long *maxj)
-{
-       int cur;
-       unsigned long j;
-       struct rcu_dynticks *rdtp = rdp->dynticks;
-
-       /*
-        * If some other CPU has already reported non-idle, if this is
-        * not the flavor of RCU that tracks sysidle state, or if this
-        * is an offline or the timekeeping CPU, nothing to do.
-        */
-       if (!*isidle || rdp->rsp != rcu_sysidle_state ||
-           cpu_is_offline(rdp->cpu) || rdp->cpu == tick_do_timer_cpu)
-               return;
-       if (rcu_gp_in_progress(rdp->rsp))
-               WARN_ON_ONCE(smp_processor_id() != tick_do_timer_cpu);
-
-       /* Pick up current idle and NMI-nesting counter and check. */
-       cur = atomic_read(&rdtp->dynticks_idle);
-       if (cur & 0x1) {
-               *isidle = false; /* We are not idle! */
-               return;
-       }
-       smp_mb(); /* Read counters before timestamps. */
-
-       /* Pick up timestamps. */
-       j = ACCESS_ONCE(rdtp->dynticks_idle_jiffies);
-       /* If this CPU entered idle more recently, update maxj timestamp. */
-       if (ULONG_CMP_LT(*maxj, j))
-               *maxj = j;
-}
-
-/*
- * Is this the flavor of RCU that is handling full-system idle?
- */
-static bool is_sysidle_rcu_state(struct rcu_state *rsp)
-{
-       return rsp == rcu_sysidle_state;
-}
-
-/*
- * Bind the grace-period kthread for the sysidle flavor of RCU to the
- * timekeeping CPU.
- */
-static void rcu_bind_gp_kthread(void)
-{
-       int cpu = ACCESS_ONCE(tick_do_timer_cpu);
-
-       if (cpu < 0 || cpu >= nr_cpu_ids)
-               return;
-       if (raw_smp_processor_id() != cpu)
-               set_cpus_allowed_ptr(current, cpumask_of(cpu));
-}
-
-/*
- * Return a delay in jiffies based on the number of CPUs, rcu_node
- * leaf fanout, and jiffies tick rate.  The idea is to allow larger
- * systems more time to transition to full-idle state in order to
- * avoid the cache thrashing that otherwise occur on the state variable.
- * Really small systems (less than a couple of tens of CPUs) should
- * instead use a single global atomically incremented counter, and later
- * versions of this will automatically reconfigure themselves accordingly.
- */
-static unsigned long rcu_sysidle_delay(void)
-{
-       if (nr_cpu_ids <= CONFIG_NO_HZ_FULL_SYSIDLE_SMALL)
-               return 0;
-       return DIV_ROUND_UP(nr_cpu_ids * HZ, rcu_fanout_leaf * 1000);
-}
-
-/*
- * Advance the full-system-idle state.  This is invoked when all of
- * the non-timekeeping CPUs are idle.
- */
-static void rcu_sysidle(unsigned long j)
-{
-       /* Check the current state. */
-       switch (ACCESS_ONCE(full_sysidle_state)) {
-       case RCU_SYSIDLE_NOT:
-
-               /* First time all are idle, so note a short idle period. */
-               ACCESS_ONCE(full_sysidle_state) = RCU_SYSIDLE_SHORT;
-               break;
-
-       case RCU_SYSIDLE_SHORT:
-
-               /*
-                * Idle for a bit, time to advance to next state?
-                * cmpxchg failure means race with non-idle, let them win.
-                */
-               if (ULONG_CMP_GE(jiffies, j + rcu_sysidle_delay()))
-                       (void)cmpxchg(&full_sysidle_state,
-                                     RCU_SYSIDLE_SHORT, RCU_SYSIDLE_LONG);
-               break;
-
-       case RCU_SYSIDLE_LONG:
-
-               /*
-                * Do an additional check pass before advancing to full.
-                * cmpxchg failure means race with non-idle, let them win.
-                */
-               if (ULONG_CMP_GE(jiffies, j + rcu_sysidle_delay()))
-                       (void)cmpxchg(&full_sysidle_state,
-                                     RCU_SYSIDLE_LONG, RCU_SYSIDLE_FULL);
-               break;
-
-       default:
-               break;
-       }
-}
-
-/*
- * Found a non-idle non-timekeeping CPU, so kick the system-idle state
- * back to the beginning.
- */
-static void rcu_sysidle_cancel(void)
-{
-       smp_mb();
-       ACCESS_ONCE(full_sysidle_state) = RCU_SYSIDLE_NOT;
-}
-
-/*
- * Update the sysidle state based on the results of a force-quiescent-state
- * scan of the CPUs' dyntick-idle state.
- */
-static void rcu_sysidle_report(struct rcu_state *rsp, int isidle,
-                              unsigned long maxj, bool gpkt)
-{
-       if (rsp != rcu_sysidle_state)
-               return;  /* Wrong flavor, ignore. */
-       if (gpkt && nr_cpu_ids <= CONFIG_NO_HZ_FULL_SYSIDLE_SMALL)
-               return;  /* Running state machine from timekeeping CPU. */
-       if (isidle)
-               rcu_sysidle(maxj);    /* More idle! */
-       else
-               rcu_sysidle_cancel(); /* Idle is over. */
-}
-
-/*
- * Wrapper for rcu_sysidle_report() when called from the grace-period
- * kthread's context.
- */
-static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
-                                 unsigned long maxj)
-{
-       rcu_sysidle_report(rsp, isidle, maxj, true);
-}
-
-/* Callback and function for forcing an RCU grace period. */
-struct rcu_sysidle_head {
-       struct rcu_head rh;
-       int inuse;
-};
-
-static void rcu_sysidle_cb(struct rcu_head *rhp)
-{
-       struct rcu_sysidle_head *rshp;
-
-       /*
-        * The following memory barrier is needed to replace the
-        * memory barriers that would normally be in the memory
-        * allocator.
-        */
-       smp_mb();  /* grace period precedes setting inuse. */
-
-       rshp = container_of(rhp, struct rcu_sysidle_head, rh);
-       ACCESS_ONCE(rshp->inuse) = 0;
-}
-
-/*
- * Check to see if the system is fully idle, other than the timekeeping CPU.
- * The caller must have disabled interrupts.
- */
-bool rcu_sys_is_idle(void)
-{
-       static struct rcu_sysidle_head rsh;
-       int rss = ACCESS_ONCE(full_sysidle_state);
-
-       if (WARN_ON_ONCE(smp_processor_id() != tick_do_timer_cpu))
-               return false;
-
-       /* Handle small-system case by doing a full scan of CPUs. */
-       if (nr_cpu_ids <= CONFIG_NO_HZ_FULL_SYSIDLE_SMALL) {
-               int oldrss = rss - 1;
-
-               /*
-                * One pass to advance to each state up to _FULL.
-                * Give up if any pass fails to advance the state.
-                */
-               while (rss < RCU_SYSIDLE_FULL && oldrss < rss) {
-                       int cpu;
-                       bool isidle = true;
-                       unsigned long maxj = jiffies - ULONG_MAX / 4;
-                       struct rcu_data *rdp;
-
-                       /* Scan all the CPUs looking for nonidle CPUs. */
-                       for_each_possible_cpu(cpu) {
-                               rdp = per_cpu_ptr(rcu_sysidle_state->rda, cpu);
-                               rcu_sysidle_check_cpu(rdp, &isidle, &maxj);
-                               if (!isidle)
-                                       break;
-                       }
-                       rcu_sysidle_report(rcu_sysidle_state,
-                                          isidle, maxj, false);
-                       oldrss = rss;
-                       rss = ACCESS_ONCE(full_sysidle_state);
-               }
-       }
-
-       /* If this is the first observation of an idle period, record it. */
-       if (rss == RCU_SYSIDLE_FULL) {
-               rss = cmpxchg(&full_sysidle_state,
-                             RCU_SYSIDLE_FULL, RCU_SYSIDLE_FULL_NOTED);
-               return rss == RCU_SYSIDLE_FULL;
-       }
-
-       smp_mb(); /* ensure rss load happens before later caller actions. */
-
-       /* If already fully idle, tell the caller (in case of races). */
-       if (rss == RCU_SYSIDLE_FULL_NOTED)
-               return true;
-
-       /*
-        * If we aren't there yet, and a grace period is not in flight,
-        * initiate a grace period.  Either way, tell the caller that
-        * we are not there yet.  We use an xchg() rather than an assignment
-        * to make up for the memory barriers that would otherwise be
-        * provided by the memory allocator.
-        */
-       if (nr_cpu_ids > CONFIG_NO_HZ_FULL_SYSIDLE_SMALL &&
-           !rcu_gp_in_progress(rcu_sysidle_state) &&
-           !rsh.inuse && xchg(&rsh.inuse, 1) == 0)
-               call_rcu(&rsh.rh, rcu_sysidle_cb);
-       return false;
-}
-
-/*
- * Initialize dynticks sysidle state for CPUs coming online.
- */
-static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp)
-{
-       rdtp->dynticks_idle_nesting = DYNTICK_TASK_NEST_VALUE;
-}
-
-#else /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
-
-static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq)
-{
-}
-
-static void rcu_sysidle_exit(struct rcu_dynticks *rdtp, int irq)
-{
-}
-
-static void rcu_sysidle_check_cpu(struct rcu_data *rdp, bool *isidle,
-                                 unsigned long *maxj)
-{
-}
-
-static bool is_sysidle_rcu_state(struct rcu_state *rsp)
-{
-       return false;
-}
-
-static void rcu_bind_gp_kthread(void)
-{
-}
-
-static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
-                                 unsigned long maxj)
-{
-}
-
-static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp)
-{
-}
-
-#endif /* #else #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
deleted file mode 100644 (file)
index cf6c174..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Read-Copy Update tracing for classic implementation
- *
- * 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 IBM Corporation, 2008
- *
- * Papers:  http://www.rdrop.com/users/paulmck/RCU
- *
- * For detailed explanation of Read-Copy Update mechanism see -
- *             Documentation/RCU
- *
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <linux/rcupdate.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/atomic.h>
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/completion.h>
-#include <linux/moduleparam.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/cpu.h>
-#include <linux/mutex.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#define RCU_TREE_NONCORE
-#include "rcutree.h"
-
-static int r_open(struct inode *inode, struct file *file,
-                                       const struct seq_operations *op)
-{
-       int ret = seq_open(file, op);
-       if (!ret) {
-               struct seq_file *m = (struct seq_file *)file->private_data;
-               m->private = inode->i_private;
-       }
-       return ret;
-}
-
-static void *r_start(struct seq_file *m, loff_t *pos)
-{
-       struct rcu_state *rsp = (struct rcu_state *)m->private;
-       *pos = cpumask_next(*pos - 1, cpu_possible_mask);
-       if ((*pos) < nr_cpu_ids)
-               return per_cpu_ptr(rsp->rda, *pos);
-       return NULL;
-}
-
-static void *r_next(struct seq_file *m, void *v, loff_t *pos)
-{
-       (*pos)++;
-       return r_start(m, pos);
-}
-
-static void r_stop(struct seq_file *m, void *v)
-{
-}
-
-static int show_rcubarrier(struct seq_file *m, void *v)
-{
-       struct rcu_state *rsp = (struct rcu_state *)m->private;
-       seq_printf(m, "bcc: %d nbd: %lu\n",
-                  atomic_read(&rsp->barrier_cpu_count),
-                  rsp->n_barrier_done);
-       return 0;
-}
-
-static int rcubarrier_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_rcubarrier, inode->i_private);
-}
-
-static const struct file_operations rcubarrier_fops = {
-       .owner = THIS_MODULE,
-       .open = rcubarrier_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = single_release,
-};
-
-#ifdef CONFIG_RCU_BOOST
-
-static char convert_kthread_status(unsigned int kthread_status)
-{
-       if (kthread_status > RCU_KTHREAD_MAX)
-               return '?';
-       return "SRWOY"[kthread_status];
-}
-
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
-{
-       long ql, qll;
-
-       if (!rdp->beenonline)
-               return;
-       seq_printf(m, "%3d%cc=%ld g=%ld pq=%d qp=%d",
-                  rdp->cpu,
-                  cpu_is_offline(rdp->cpu) ? '!' : ' ',
-                  ulong2long(rdp->completed), ulong2long(rdp->gpnum),
-                  rdp->passed_quiesce, rdp->qs_pending);
-       seq_printf(m, " dt=%d/%llx/%d df=%lu",
-                  atomic_read(&rdp->dynticks->dynticks),
-                  rdp->dynticks->dynticks_nesting,
-                  rdp->dynticks->dynticks_nmi_nesting,
-                  rdp->dynticks_fqs);
-       seq_printf(m, " of=%lu", rdp->offline_fqs);
-       rcu_nocb_q_lengths(rdp, &ql, &qll);
-       qll += rdp->qlen_lazy;
-       ql += rdp->qlen;
-       seq_printf(m, " ql=%ld/%ld qs=%c%c%c%c",
-                  qll, ql,
-                  ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
-                       rdp->nxttail[RCU_NEXT_TAIL]],
-                  ".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
-                       rdp->nxttail[RCU_NEXT_READY_TAIL]],
-                  ".W"[rdp->nxttail[RCU_DONE_TAIL] !=
-                       rdp->nxttail[RCU_WAIT_TAIL]],
-                  ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]]);
-#ifdef CONFIG_RCU_BOOST
-       seq_printf(m, " kt=%d/%c ktl=%x",
-                  per_cpu(rcu_cpu_has_work, rdp->cpu),
-                  convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
-                                         rdp->cpu)),
-                  per_cpu(rcu_cpu_kthread_loops, rdp->cpu) & 0xffff);
-#endif /* #ifdef CONFIG_RCU_BOOST */
-       seq_printf(m, " b=%ld", rdp->blimit);
-       seq_printf(m, " ci=%lu nci=%lu co=%lu ca=%lu\n",
-                  rdp->n_cbs_invoked, rdp->n_nocbs_invoked,
-                  rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
-}
-
-static int show_rcudata(struct seq_file *m, void *v)
-{
-       print_one_rcu_data(m, (struct rcu_data *)v);
-       return 0;
-}
-
-static const struct seq_operations rcudate_op = {
-       .start = r_start,
-       .next  = r_next,
-       .stop  = r_stop,
-       .show  = show_rcudata,
-};
-
-static int rcudata_open(struct inode *inode, struct file *file)
-{
-       return r_open(inode, file, &rcudate_op);
-}
-
-static const struct file_operations rcudata_fops = {
-       .owner = THIS_MODULE,
-       .open = rcudata_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = seq_release,
-};
-
-static int show_rcuexp(struct seq_file *m, void *v)
-{
-       struct rcu_state *rsp = (struct rcu_state *)m->private;
-
-       seq_printf(m, "s=%lu d=%lu w=%lu tf=%lu wd1=%lu wd2=%lu n=%lu sc=%lu dt=%lu dl=%lu dx=%lu\n",
-                  atomic_long_read(&rsp->expedited_start),
-                  atomic_long_read(&rsp->expedited_done),
-                  atomic_long_read(&rsp->expedited_wrap),
-                  atomic_long_read(&rsp->expedited_tryfail),
-                  atomic_long_read(&rsp->expedited_workdone1),
-                  atomic_long_read(&rsp->expedited_workdone2),
-                  atomic_long_read(&rsp->expedited_normal),
-                  atomic_long_read(&rsp->expedited_stoppedcpus),
-                  atomic_long_read(&rsp->expedited_done_tries),
-                  atomic_long_read(&rsp->expedited_done_lost),
-                  atomic_long_read(&rsp->expedited_done_exit));
-       return 0;
-}
-
-static int rcuexp_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_rcuexp, inode->i_private);
-}
-
-static const struct file_operations rcuexp_fops = {
-       .owner = THIS_MODULE,
-       .open = rcuexp_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = single_release,
-};
-
-#ifdef CONFIG_RCU_BOOST
-
-static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp)
-{
-       seq_printf(m, "%d:%d tasks=%c%c%c%c kt=%c ntb=%lu neb=%lu nnb=%lu ",
-                  rnp->grplo, rnp->grphi,
-                  "T."[list_empty(&rnp->blkd_tasks)],
-                  "N."[!rnp->gp_tasks],
-                  "E."[!rnp->exp_tasks],
-                  "B."[!rnp->boost_tasks],
-                  convert_kthread_status(rnp->boost_kthread_status),
-                  rnp->n_tasks_boosted, rnp->n_exp_boosts,
-                  rnp->n_normal_boosts);
-       seq_printf(m, "j=%04x bt=%04x\n",
-                  (int)(jiffies & 0xffff),
-                  (int)(rnp->boost_time & 0xffff));
-       seq_printf(m, "    balk: nt=%lu egt=%lu bt=%lu nb=%lu ny=%lu nos=%lu\n",
-                  rnp->n_balk_blkd_tasks,
-                  rnp->n_balk_exp_gp_tasks,
-                  rnp->n_balk_boost_tasks,
-                  rnp->n_balk_notblocked,
-                  rnp->n_balk_notyet,
-                  rnp->n_balk_nos);
-}
-
-static int show_rcu_node_boost(struct seq_file *m, void *unused)
-{
-       struct rcu_node *rnp;
-
-       rcu_for_each_leaf_node(&rcu_preempt_state, rnp)
-               print_one_rcu_node_boost(m, rnp);
-       return 0;
-}
-
-static int rcu_node_boost_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_rcu_node_boost, NULL);
-}
-
-static const struct file_operations rcu_node_boost_fops = {
-       .owner = THIS_MODULE,
-       .open = rcu_node_boost_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = single_release,
-};
-
-#endif /* #ifdef CONFIG_RCU_BOOST */
-
-static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
-{
-       unsigned long gpnum;
-       int level = 0;
-       struct rcu_node *rnp;
-
-       gpnum = rsp->gpnum;
-       seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x ",
-                  ulong2long(rsp->completed), ulong2long(gpnum),
-                  rsp->fqs_state,
-                  (long)(rsp->jiffies_force_qs - jiffies),
-                  (int)(jiffies & 0xffff));
-       seq_printf(m, "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n",
-                  rsp->n_force_qs, rsp->n_force_qs_ngp,
-                  rsp->n_force_qs - rsp->n_force_qs_ngp,
-                  rsp->n_force_qs_lh, rsp->qlen_lazy, rsp->qlen);
-       for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < rcu_num_nodes; rnp++) {
-               if (rnp->level != level) {
-                       seq_puts(m, "\n");
-                       level = rnp->level;
-               }
-               seq_printf(m, "%lx/%lx %c%c>%c %d:%d ^%d    ",
-                          rnp->qsmask, rnp->qsmaskinit,
-                          ".G"[rnp->gp_tasks != NULL],
-                          ".E"[rnp->exp_tasks != NULL],
-                          ".T"[!list_empty(&rnp->blkd_tasks)],
-                          rnp->grplo, rnp->grphi, rnp->grpnum);
-       }
-       seq_puts(m, "\n");
-}
-
-static int show_rcuhier(struct seq_file *m, void *v)
-{
-       struct rcu_state *rsp = (struct rcu_state *)m->private;
-       print_one_rcu_state(m, rsp);
-       return 0;
-}
-
-static int rcuhier_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_rcuhier, inode->i_private);
-}
-
-static const struct file_operations rcuhier_fops = {
-       .owner = THIS_MODULE,
-       .open = rcuhier_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = single_release,
-};
-
-static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
-{
-       unsigned long flags;
-       unsigned long completed;
-       unsigned long gpnum;
-       unsigned long gpage;
-       unsigned long gpmax;
-       struct rcu_node *rnp = &rsp->node[0];
-
-       raw_spin_lock_irqsave(&rnp->lock, flags);
-       completed = ACCESS_ONCE(rsp->completed);
-       gpnum = ACCESS_ONCE(rsp->gpnum);
-       if (completed == gpnum)
-               gpage = 0;
-       else
-               gpage = jiffies - rsp->gp_start;
-       gpmax = rsp->gp_max;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       seq_printf(m, "completed=%ld  gpnum=%ld  age=%ld  max=%ld\n",
-                  ulong2long(completed), ulong2long(gpnum), gpage, gpmax);
-}
-
-static int show_rcugp(struct seq_file *m, void *v)
-{
-       struct rcu_state *rsp = (struct rcu_state *)m->private;
-       show_one_rcugp(m, rsp);
-       return 0;
-}
-
-static int rcugp_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_rcugp, inode->i_private);
-}
-
-static const struct file_operations rcugp_fops = {
-       .owner = THIS_MODULE,
-       .open = rcugp_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = single_release,
-};
-
-static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
-{
-       if (!rdp->beenonline)
-               return;
-       seq_printf(m, "%3d%cnp=%ld ",
-                  rdp->cpu,
-                  cpu_is_offline(rdp->cpu) ? '!' : ' ',
-                  rdp->n_rcu_pending);
-       seq_printf(m, "qsp=%ld rpq=%ld cbr=%ld cng=%ld ",
-                  rdp->n_rp_qs_pending,
-                  rdp->n_rp_report_qs,
-                  rdp->n_rp_cb_ready,
-                  rdp->n_rp_cpu_needs_gp);
-       seq_printf(m, "gpc=%ld gps=%ld nn=%ld\n",
-                  rdp->n_rp_gp_completed,
-                  rdp->n_rp_gp_started,
-                  rdp->n_rp_need_nothing);
-}
-
-static int show_rcu_pending(struct seq_file *m, void *v)
-{
-       print_one_rcu_pending(m, (struct rcu_data *)v);
-       return 0;
-}
-
-static const struct seq_operations rcu_pending_op = {
-       .start = r_start,
-       .next  = r_next,
-       .stop  = r_stop,
-       .show  = show_rcu_pending,
-};
-
-static int rcu_pending_open(struct inode *inode, struct file *file)
-{
-       return r_open(inode, file, &rcu_pending_op);
-}
-
-static const struct file_operations rcu_pending_fops = {
-       .owner = THIS_MODULE,
-       .open = rcu_pending_open,
-       .read = seq_read,
-       .llseek = no_llseek,
-       .release = seq_release,
-};
-
-static int show_rcutorture(struct seq_file *m, void *unused)
-{
-       seq_printf(m, "rcutorture test sequence: %lu %s\n",
-                  rcutorture_testseq >> 1,
-                  (rcutorture_testseq & 0x1) ? "(test in progress)" : "");
-       seq_printf(m, "rcutorture update version number: %lu\n",
-                  rcutorture_vernum);
-       return 0;
-}
-
-static int rcutorture_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, show_rcutorture, NULL);
-}
-
-static const struct file_operations rcutorture_fops = {
-       .owner = THIS_MODULE,
-       .open = rcutorture_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-static struct dentry *rcudir;
-
-static int __init rcutree_trace_init(void)
-{
-       struct rcu_state *rsp;
-       struct dentry *retval;
-       struct dentry *rspdir;
-
-       rcudir = debugfs_create_dir("rcu", NULL);
-       if (!rcudir)
-               goto free_out;
-
-       for_each_rcu_flavor(rsp) {
-               rspdir = debugfs_create_dir(rsp->name, rcudir);
-               if (!rspdir)
-                       goto free_out;
-
-               retval = debugfs_create_file("rcudata", 0444,
-                               rspdir, rsp, &rcudata_fops);
-               if (!retval)
-                       goto free_out;
-
-               retval = debugfs_create_file("rcuexp", 0444,
-                               rspdir, rsp, &rcuexp_fops);
-               if (!retval)
-                       goto free_out;
-
-               retval = debugfs_create_file("rcu_pending", 0444,
-                               rspdir, rsp, &rcu_pending_fops);
-               if (!retval)
-                       goto free_out;
-
-               retval = debugfs_create_file("rcubarrier", 0444,
-                               rspdir, rsp, &rcubarrier_fops);
-               if (!retval)
-                       goto free_out;
-
-#ifdef CONFIG_RCU_BOOST
-               if (rsp == &rcu_preempt_state) {
-                       retval = debugfs_create_file("rcuboost", 0444,
-                               rspdir, NULL, &rcu_node_boost_fops);
-                       if (!retval)
-                               goto free_out;
-               }
-#endif
-
-               retval = debugfs_create_file("rcugp", 0444,
-                               rspdir, rsp, &rcugp_fops);
-               if (!retval)
-                       goto free_out;
-
-               retval = debugfs_create_file("rcuhier", 0444,
-                               rspdir, rsp, &rcuhier_fops);
-               if (!retval)
-                       goto free_out;
-       }
-
-       retval = debugfs_create_file("rcutorture", 0444, rcudir,
-                                               NULL, &rcutorture_fops);
-       if (!retval)
-               goto free_out;
-       return 0;
-free_out:
-       debugfs_remove_recursive(rcudir);
-       return 1;
-}
-
-static void __exit rcutree_trace_cleanup(void)
-{
-       debugfs_remove_recursive(rcudir);
-}
-
-
-module_init(rcutree_trace_init);
-module_exit(rcutree_trace_cleanup);
-
-MODULE_AUTHOR("Paul E. McKenney");
-MODULE_DESCRIPTION("Read-Copy Update tracing for hierarchical implementation");
-MODULE_LICENSE("GPL");
index dcab1d3fb53d284cc42da1e36c6e5d001cd5baa9..b24988353458c8cad2fff6aed7853f8625f1cf36 100644 (file)
@@ -29,7 +29,6 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/irq.h>
 
-#include <asm/irq.h>
 /*
    - No shared variables, all the data are CPU local.
    - If a softirq needs serialization, let it serialize itself
@@ -134,7 +133,6 @@ EXPORT_SYMBOL(local_bh_disable);
 
 static void __local_bh_enable(unsigned int cnt)
 {
-       WARN_ON_ONCE(in_irq());
        WARN_ON_ONCE(!irqs_disabled());
 
        if (softirq_count() == cnt)
@@ -149,6 +147,7 @@ static void __local_bh_enable(unsigned int cnt)
  */
 void _local_bh_enable(void)
 {
+       WARN_ON_ONCE(in_irq());
        __local_bh_enable(SOFTIRQ_DISABLE_OFFSET);
 }
 
@@ -171,8 +170,13 @@ static inline void _local_bh_enable_ip(unsigned long ip)
         */
        preempt_count_sub(SOFTIRQ_DISABLE_OFFSET - 1);
 
-       if (unlikely(!in_interrupt() && local_softirq_pending()))
+       if (unlikely(!in_interrupt() && local_softirq_pending())) {
+               /*
+                * Run softirq if any pending. And do it in its own stack
+                * as we may be calling this deep in a task call stack already.
+                */
                do_softirq();
+       }
 
        preempt_count_dec();
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -280,10 +284,11 @@ restart:
 
        account_irq_exit_time(current);
        __local_bh_enable(SOFTIRQ_OFFSET);
+       WARN_ON_ONCE(in_interrupt());
        tsk_restore_flags(current, old_flags, PF_MEMALLOC);
 }
 
-#ifndef __ARCH_HAS_DO_SOFTIRQ
+
 
 asmlinkage void do_softirq(void)
 {
@@ -298,13 +303,11 @@ asmlinkage void do_softirq(void)
        pending = local_softirq_pending();
 
        if (pending)
-               __do_softirq();
+               do_softirq_own_stack();
 
        local_irq_restore(flags);
 }
 
-#endif
-
 /*
  * Enter an interrupt context.
  */
@@ -329,15 +332,21 @@ void irq_enter(void)
 static inline void invoke_softirq(void)
 {
        if (!force_irqthreads) {
+#ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK
                /*
                 * We can safely execute softirq on the current stack if
                 * it is the irq stack, because it should be near empty
-                * at this stage. But we have no way to know if the arch
-                * calls irq_exit() on the irq stack. So call softirq
-                * in its own stack to prevent from any overrun on top
-                * of a potentially deep task stack.
+                * at this stage.
                 */
-               do_softirq();
+               __do_softirq();
+#else
+               /*
+                * Otherwise, irq_exit() is called on the task stack that can
+                * be potentially deep already. So call softirq in its own stack
+                * to prevent from any overrun.
+                */
+               do_softirq_own_stack();
+#endif
        } else {
                wakeup_softirqd();
        }
@@ -771,6 +780,10 @@ static void run_ksoftirqd(unsigned int cpu)
 {
        local_irq_disable();
        if (local_softirq_pending()) {
+               /*
+                * We can safely run softirq on inline stack, as we are not deep
+                * in the task stack here.
+                */
                __do_softirq();
                rcu_note_context_switch(cpu);
                local_irq_enable();
diff --git a/kernel/srcu.c b/kernel/srcu.c
deleted file mode 100644 (file)
index 01d5ccb..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * Sleepable Read-Copy Update mechanism for mutual exclusion.
- *
- * 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) IBM Corporation, 2006
- * Copyright (C) Fujitsu, 2012
- *
- * Author: Paul McKenney <paulmck@us.ibm.com>
- *        Lai Jiangshan <laijs@cn.fujitsu.com>
- *
- * For detailed explanation of Read-Copy Update mechanism see -
- *             Documentation/RCU/ *.txt
- *
- */
-
-#include <linux/export.h>
-#include <linux/mutex.h>
-#include <linux/percpu.h>
-#include <linux/preempt.h>
-#include <linux/rcupdate.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/delay.h>
-#include <linux/srcu.h>
-
-#include <trace/events/rcu.h>
-
-#include "rcu.h"
-
-/*
- * Initialize an rcu_batch structure to empty.
- */
-static inline void rcu_batch_init(struct rcu_batch *b)
-{
-       b->head = NULL;
-       b->tail = &b->head;
-}
-
-/*
- * Enqueue a callback onto the tail of the specified rcu_batch structure.
- */
-static inline void rcu_batch_queue(struct rcu_batch *b, struct rcu_head *head)
-{
-       *b->tail = head;
-       b->tail = &head->next;
-}
-
-/*
- * Is the specified rcu_batch structure empty?
- */
-static inline bool rcu_batch_empty(struct rcu_batch *b)
-{
-       return b->tail == &b->head;
-}
-
-/*
- * Remove the callback at the head of the specified rcu_batch structure
- * and return a pointer to it, or return NULL if the structure is empty.
- */
-static inline struct rcu_head *rcu_batch_dequeue(struct rcu_batch *b)
-{
-       struct rcu_head *head;
-
-       if (rcu_batch_empty(b))
-               return NULL;
-
-       head = b->head;
-       b->head = head->next;
-       if (b->tail == &head->next)
-               rcu_batch_init(b);
-
-       return head;
-}
-
-/*
- * Move all callbacks from the rcu_batch structure specified by "from" to
- * the structure specified by "to".
- */
-static inline void rcu_batch_move(struct rcu_batch *to, struct rcu_batch *from)
-{
-       if (!rcu_batch_empty(from)) {
-               *to->tail = from->head;
-               to->tail = from->tail;
-               rcu_batch_init(from);
-       }
-}
-
-static int init_srcu_struct_fields(struct srcu_struct *sp)
-{
-       sp->completed = 0;
-       spin_lock_init(&sp->queue_lock);
-       sp->running = false;
-       rcu_batch_init(&sp->batch_queue);
-       rcu_batch_init(&sp->batch_check0);
-       rcu_batch_init(&sp->batch_check1);
-       rcu_batch_init(&sp->batch_done);
-       INIT_DELAYED_WORK(&sp->work, process_srcu);
-       sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
-       return sp->per_cpu_ref ? 0 : -ENOMEM;
-}
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-
-int __init_srcu_struct(struct srcu_struct *sp, const char *name,
-                      struct lock_class_key *key)
-{
-       /* Don't re-initialize a lock while it is held. */
-       debug_check_no_locks_freed((void *)sp, sizeof(*sp));
-       lockdep_init_map(&sp->dep_map, name, key, 0);
-       return init_srcu_struct_fields(sp);
-}
-EXPORT_SYMBOL_GPL(__init_srcu_struct);
-
-#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
-
-/**
- * init_srcu_struct - initialize a sleep-RCU structure
- * @sp: structure to initialize.
- *
- * Must invoke this on a given srcu_struct before passing that srcu_struct
- * to any other function.  Each srcu_struct represents a separate domain
- * of SRCU protection.
- */
-int init_srcu_struct(struct srcu_struct *sp)
-{
-       return init_srcu_struct_fields(sp);
-}
-EXPORT_SYMBOL_GPL(init_srcu_struct);
-
-#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
-
-/*
- * Returns approximate total of the readers' ->seq[] values for the
- * rank of per-CPU counters specified by idx.
- */
-static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx)
-{
-       int cpu;
-       unsigned long sum = 0;
-       unsigned long t;
-
-       for_each_possible_cpu(cpu) {
-               t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]);
-               sum += t;
-       }
-       return sum;
-}
-
-/*
- * Returns approximate number of readers active on the specified rank
- * of the per-CPU ->c[] counters.
- */
-static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx)
-{
-       int cpu;
-       unsigned long sum = 0;
-       unsigned long t;
-
-       for_each_possible_cpu(cpu) {
-               t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]);
-               sum += t;
-       }
-       return sum;
-}
-
-/*
- * Return true if the number of pre-existing readers is determined to
- * be stably zero.  An example unstable zero can occur if the call
- * to srcu_readers_active_idx() misses an __srcu_read_lock() increment,
- * but due to task migration, sees the corresponding __srcu_read_unlock()
- * decrement.  This can happen because srcu_readers_active_idx() takes
- * time to sum the array, and might in fact be interrupted or preempted
- * partway through the summation.
- */
-static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx)
-{
-       unsigned long seq;
-
-       seq = srcu_readers_seq_idx(sp, idx);
-
-       /*
-        * The following smp_mb() A pairs with the smp_mb() B located in
-        * __srcu_read_lock().  This pairing ensures that if an
-        * __srcu_read_lock() increments its counter after the summation
-        * in srcu_readers_active_idx(), then the corresponding SRCU read-side
-        * critical section will see any changes made prior to the start
-        * of the current SRCU grace period.
-        *
-        * Also, if the above call to srcu_readers_seq_idx() saw the
-        * increment of ->seq[], then the call to srcu_readers_active_idx()
-        * must see the increment of ->c[].
-        */
-       smp_mb(); /* A */
-
-       /*
-        * Note that srcu_readers_active_idx() can incorrectly return
-        * zero even though there is a pre-existing reader throughout.
-        * To see this, suppose that task A is in a very long SRCU
-        * read-side critical section that started on CPU 0, and that
-        * no other reader exists, so that the sum of the counters
-        * is equal to one.  Then suppose that task B starts executing
-        * srcu_readers_active_idx(), summing up to CPU 1, and then that
-        * task C starts reading on CPU 0, so that its increment is not
-        * summed, but finishes reading on CPU 2, so that its decrement
-        * -is- summed.  Then when task B completes its sum, it will
-        * incorrectly get zero, despite the fact that task A has been
-        * in its SRCU read-side critical section the whole time.
-        *
-        * We therefore do a validation step should srcu_readers_active_idx()
-        * return zero.
-        */
-       if (srcu_readers_active_idx(sp, idx) != 0)
-               return false;
-
-       /*
-        * The remainder of this function is the validation step.
-        * The following smp_mb() D pairs with the smp_mb() C in
-        * __srcu_read_unlock().  If the __srcu_read_unlock() was seen
-        * by srcu_readers_active_idx() above, then any destructive
-        * operation performed after the grace period will happen after
-        * the corresponding SRCU read-side critical section.
-        *
-        * Note that there can be at most NR_CPUS worth of readers using
-        * the old index, which is not enough to overflow even a 32-bit
-        * integer.  (Yes, this does mean that systems having more than
-        * a billion or so CPUs need to be 64-bit systems.)  Therefore,
-        * the sum of the ->seq[] counters cannot possibly overflow.
-        * Therefore, the only way that the return values of the two
-        * calls to srcu_readers_seq_idx() can be equal is if there were
-        * no increments of the corresponding rank of ->seq[] counts
-        * in the interim.  But the missed-increment scenario laid out
-        * above includes an increment of the ->seq[] counter by
-        * the corresponding __srcu_read_lock().  Therefore, if this
-        * scenario occurs, the return values from the two calls to
-        * srcu_readers_seq_idx() will differ, and thus the validation
-        * step below suffices.
-        */
-       smp_mb(); /* D */
-
-       return srcu_readers_seq_idx(sp, idx) == seq;
-}
-
-/**
- * srcu_readers_active - returns approximate number of readers.
- * @sp: which srcu_struct to count active readers (holding srcu_read_lock).
- *
- * Note that this is not an atomic primitive, and can therefore suffer
- * severe errors when invoked on an active srcu_struct.  That said, it
- * can be useful as an error check at cleanup time.
- */
-static int srcu_readers_active(struct srcu_struct *sp)
-{
-       int cpu;
-       unsigned long sum = 0;
-
-       for_each_possible_cpu(cpu) {
-               sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]);
-               sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]);
-       }
-       return sum;
-}
-
-/**
- * cleanup_srcu_struct - deconstruct a sleep-RCU structure
- * @sp: structure to clean up.
- *
- * Must invoke this after you are finished using a given srcu_struct that
- * was initialized via init_srcu_struct(), else you leak memory.
- */
-void cleanup_srcu_struct(struct srcu_struct *sp)
-{
-       if (WARN_ON(srcu_readers_active(sp)))
-               return; /* Leakage unless caller handles error. */
-       free_percpu(sp->per_cpu_ref);
-       sp->per_cpu_ref = NULL;
-}
-EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
-
-/*
- * Counts the new reader in the appropriate per-CPU element of the
- * srcu_struct.  Must be called from process context.
- * Returns an index that must be passed to the matching srcu_read_unlock().
- */
-int __srcu_read_lock(struct srcu_struct *sp)
-{
-       int idx;
-
-       idx = ACCESS_ONCE(sp->completed) & 0x1;
-       preempt_disable();
-       ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->c[idx]) += 1;
-       smp_mb(); /* B */  /* Avoid leaking the critical section. */
-       ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->seq[idx]) += 1;
-       preempt_enable();
-       return idx;
-}
-EXPORT_SYMBOL_GPL(__srcu_read_lock);
-
-/*
- * Removes the count for the old reader from the appropriate per-CPU
- * element of the srcu_struct.  Note that this may well be a different
- * CPU than that which was incremented by the corresponding srcu_read_lock().
- * Must be called from process context.
- */
-void __srcu_read_unlock(struct srcu_struct *sp, int idx)
-{
-       smp_mb(); /* C */  /* Avoid leaking the critical section. */
-       this_cpu_dec(sp->per_cpu_ref->c[idx]);
-}
-EXPORT_SYMBOL_GPL(__srcu_read_unlock);
-
-/*
- * We use an adaptive strategy for synchronize_srcu() and especially for
- * synchronize_srcu_expedited().  We spin for a fixed time period
- * (defined below) to allow SRCU readers to exit their read-side critical
- * sections.  If there are still some readers after 10 microseconds,
- * we repeatedly block for 1-millisecond time periods.  This approach
- * has done well in testing, so there is no need for a config parameter.
- */
-#define SRCU_RETRY_CHECK_DELAY         5
-#define SYNCHRONIZE_SRCU_TRYCOUNT      2
-#define SYNCHRONIZE_SRCU_EXP_TRYCOUNT  12
-
-/*
- * @@@ Wait until all pre-existing readers complete.  Such readers
- * will have used the index specified by "idx".
- * the caller should ensures the ->completed is not changed while checking
- * and idx = (->completed & 1) ^ 1
- */
-static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount)
-{
-       for (;;) {
-               if (srcu_readers_active_idx_check(sp, idx))
-                       return true;
-               if (--trycount <= 0)
-                       return false;
-               udelay(SRCU_RETRY_CHECK_DELAY);
-       }
-}
-
-/*
- * Increment the ->completed counter so that future SRCU readers will
- * use the other rank of the ->c[] and ->seq[] arrays.  This allows
- * us to wait for pre-existing readers in a starvation-free manner.
- */
-static void srcu_flip(struct srcu_struct *sp)
-{
-       sp->completed++;
-}
-
-/*
- * Enqueue an SRCU callback on the specified srcu_struct structure,
- * initiating grace-period processing if it is not already running.
- */
-void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
-               void (*func)(struct rcu_head *head))
-{
-       unsigned long flags;
-
-       head->next = NULL;
-       head->func = func;
-       spin_lock_irqsave(&sp->queue_lock, flags);
-       rcu_batch_queue(&sp->batch_queue, head);
-       if (!sp->running) {
-               sp->running = true;
-               schedule_delayed_work(&sp->work, 0);
-       }
-       spin_unlock_irqrestore(&sp->queue_lock, flags);
-}
-EXPORT_SYMBOL_GPL(call_srcu);
-
-struct rcu_synchronize {
-       struct rcu_head head;
-       struct completion completion;
-};
-
-/*
- * Awaken the corresponding synchronize_srcu() instance now that a
- * grace period has elapsed.
- */
-static void wakeme_after_rcu(struct rcu_head *head)
-{
-       struct rcu_synchronize *rcu;
-
-       rcu = container_of(head, struct rcu_synchronize, head);
-       complete(&rcu->completion);
-}
-
-static void srcu_advance_batches(struct srcu_struct *sp, int trycount);
-static void srcu_reschedule(struct srcu_struct *sp);
-
-/*
- * Helper function for synchronize_srcu() and synchronize_srcu_expedited().
- */
-static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
-{
-       struct rcu_synchronize rcu;
-       struct rcu_head *head = &rcu.head;
-       bool done = false;
-
-       rcu_lockdep_assert(!lock_is_held(&sp->dep_map) &&
-                          !lock_is_held(&rcu_bh_lock_map) &&
-                          !lock_is_held(&rcu_lock_map) &&
-                          !lock_is_held(&rcu_sched_lock_map),
-                          "Illegal synchronize_srcu() in same-type SRCU (or RCU) read-side critical section");
-
-       might_sleep();
-       init_completion(&rcu.completion);
-
-       head->next = NULL;
-       head->func = wakeme_after_rcu;
-       spin_lock_irq(&sp->queue_lock);
-       if (!sp->running) {
-               /* steal the processing owner */
-               sp->running = true;
-               rcu_batch_queue(&sp->batch_check0, head);
-               spin_unlock_irq(&sp->queue_lock);
-
-               srcu_advance_batches(sp, trycount);
-               if (!rcu_batch_empty(&sp->batch_done)) {
-                       BUG_ON(sp->batch_done.head != head);
-                       rcu_batch_dequeue(&sp->batch_done);
-                       done = true;
-               }
-               /* give the processing owner to work_struct */
-               srcu_reschedule(sp);
-       } else {
-               rcu_batch_queue(&sp->batch_queue, head);
-               spin_unlock_irq(&sp->queue_lock);
-       }
-
-       if (!done)
-               wait_for_completion(&rcu.completion);
-}
-
-/**
- * synchronize_srcu - wait for prior SRCU read-side critical-section completion
- * @sp: srcu_struct with which to synchronize.
- *
- * Wait for the count to drain to zero of both indexes. To avoid the
- * possible starvation of synchronize_srcu(), it waits for the count of
- * the index=((->completed & 1) ^ 1) to drain to zero at first,
- * and then flip the completed and wait for the count of the other index.
- *
- * Can block; must be called from process context.
- *
- * Note that it is illegal to call synchronize_srcu() from the corresponding
- * SRCU read-side critical section; doing so will result in deadlock.
- * However, it is perfectly legal to call synchronize_srcu() on one
- * srcu_struct from some other srcu_struct's read-side critical section.
- */
-void synchronize_srcu(struct srcu_struct *sp)
-{
-       __synchronize_srcu(sp, rcu_expedited
-                          ? SYNCHRONIZE_SRCU_EXP_TRYCOUNT
-                          : SYNCHRONIZE_SRCU_TRYCOUNT);
-}
-EXPORT_SYMBOL_GPL(synchronize_srcu);
-
-/**
- * synchronize_srcu_expedited - Brute-force SRCU grace period
- * @sp: srcu_struct with which to synchronize.
- *
- * Wait for an SRCU grace period to elapse, but be more aggressive about
- * spinning rather than blocking when waiting.
- *
- * Note that it is also illegal to call synchronize_srcu_expedited()
- * from the corresponding SRCU read-side critical section;
- * doing so will result in deadlock.  However, it is perfectly legal
- * to call synchronize_srcu_expedited() on one srcu_struct from some
- * other srcu_struct's read-side critical section, as long as
- * the resulting graph of srcu_structs is acyclic.
- */
-void synchronize_srcu_expedited(struct srcu_struct *sp)
-{
-       __synchronize_srcu(sp, SYNCHRONIZE_SRCU_EXP_TRYCOUNT);
-}
-EXPORT_SYMBOL_GPL(synchronize_srcu_expedited);
-
-/**
- * srcu_barrier - Wait until all in-flight call_srcu() callbacks complete.
- */
-void srcu_barrier(struct srcu_struct *sp)
-{
-       synchronize_srcu(sp);
-}
-EXPORT_SYMBOL_GPL(srcu_barrier);
-
-/**
- * srcu_batches_completed - return batches completed.
- * @sp: srcu_struct on which to report batch completion.
- *
- * Report the number of batches, correlated with, but not necessarily
- * precisely the same as, the number of grace periods that have elapsed.
- */
-long srcu_batches_completed(struct srcu_struct *sp)
-{
-       return sp->completed;
-}
-EXPORT_SYMBOL_GPL(srcu_batches_completed);
-
-#define SRCU_CALLBACK_BATCH    10
-#define SRCU_INTERVAL          1
-
-/*
- * Move any new SRCU callbacks to the first stage of the SRCU grace
- * period pipeline.
- */
-static void srcu_collect_new(struct srcu_struct *sp)
-{
-       if (!rcu_batch_empty(&sp->batch_queue)) {
-               spin_lock_irq(&sp->queue_lock);
-               rcu_batch_move(&sp->batch_check0, &sp->batch_queue);
-               spin_unlock_irq(&sp->queue_lock);
-       }
-}
-
-/*
- * Core SRCU state machine.  Advance callbacks from ->batch_check0 to
- * ->batch_check1 and then to ->batch_done as readers drain.
- */
-static void srcu_advance_batches(struct srcu_struct *sp, int trycount)
-{
-       int idx = 1 ^ (sp->completed & 1);
-
-       /*
-        * Because readers might be delayed for an extended period after
-        * fetching ->completed for their index, at any point in time there
-        * might well be readers using both idx=0 and idx=1.  We therefore
-        * need to wait for readers to clear from both index values before
-        * invoking a callback.
-        */
-
-       if (rcu_batch_empty(&sp->batch_check0) &&
-           rcu_batch_empty(&sp->batch_check1))
-               return; /* no callbacks need to be advanced */
-
-       if (!try_check_zero(sp, idx, trycount))
-               return; /* failed to advance, will try after SRCU_INTERVAL */
-
-       /*
-        * The callbacks in ->batch_check1 have already done with their
-        * first zero check and flip back when they were enqueued on
-        * ->batch_check0 in a previous invocation of srcu_advance_batches().
-        * (Presumably try_check_zero() returned false during that
-        * invocation, leaving the callbacks stranded on ->batch_check1.)
-        * They are therefore ready to invoke, so move them to ->batch_done.
-        */
-       rcu_batch_move(&sp->batch_done, &sp->batch_check1);
-
-       if (rcu_batch_empty(&sp->batch_check0))
-               return; /* no callbacks need to be advanced */
-       srcu_flip(sp);
-
-       /*
-        * The callbacks in ->batch_check0 just finished their
-        * first check zero and flip, so move them to ->batch_check1
-        * for future checking on the other idx.
-        */
-       rcu_batch_move(&sp->batch_check1, &sp->batch_check0);
-
-       /*
-        * SRCU read-side critical sections are normally short, so check
-        * at least twice in quick succession after a flip.
-        */
-       trycount = trycount < 2 ? 2 : trycount;
-       if (!try_check_zero(sp, idx^1, trycount))
-               return; /* failed to advance, will try after SRCU_INTERVAL */
-
-       /*
-        * The callbacks in ->batch_check1 have now waited for all
-        * pre-existing readers using both idx values.  They are therefore
-        * ready to invoke, so move them to ->batch_done.
-        */
-       rcu_batch_move(&sp->batch_done, &sp->batch_check1);
-}
-
-/*
- * Invoke a limited number of SRCU callbacks that have passed through
- * their grace period.  If there are more to do, SRCU will reschedule
- * the workqueue.
- */
-static void srcu_invoke_callbacks(struct srcu_struct *sp)
-{
-       int i;
-       struct rcu_head *head;
-
-       for (i = 0; i < SRCU_CALLBACK_BATCH; i++) {
-               head = rcu_batch_dequeue(&sp->batch_done);
-               if (!head)
-                       break;
-               local_bh_disable();
-               head->func(head);
-               local_bh_enable();
-       }
-}
-
-/*
- * Finished one round of SRCU grace period.  Start another if there are
- * more SRCU callbacks queued, otherwise put SRCU into not-running state.
- */
-static void srcu_reschedule(struct srcu_struct *sp)
-{
-       bool pending = true;
-
-       if (rcu_batch_empty(&sp->batch_done) &&
-           rcu_batch_empty(&sp->batch_check1) &&
-           rcu_batch_empty(&sp->batch_check0) &&
-           rcu_batch_empty(&sp->batch_queue)) {
-               spin_lock_irq(&sp->queue_lock);
-               if (rcu_batch_empty(&sp->batch_done) &&
-                   rcu_batch_empty(&sp->batch_check1) &&
-                   rcu_batch_empty(&sp->batch_check0) &&
-                   rcu_batch_empty(&sp->batch_queue)) {
-                       sp->running = false;
-                       pending = false;
-               }
-               spin_unlock_irq(&sp->queue_lock);
-       }
-
-       if (pending)
-               schedule_delayed_work(&sp->work, SRCU_INTERVAL);
-}
-
-/*
- * This is the work-queue function that handles SRCU grace periods.
- */
-void process_srcu(struct work_struct *work)
-{
-       struct srcu_struct *sp;
-
-       sp = container_of(work, struct srcu_struct, work.work);
-
-       srcu_collect_new(sp);
-       srcu_advance_batches(sp, 1);
-       srcu_invoke_callbacks(sp);
-       srcu_reschedule(sp);
-}
-EXPORT_SYMBOL_GPL(process_srcu);
index a159e1fd2013fecd2c8c16f50e520278a587c1b8..36547dddcdb83eab551d0ee60fa34218067d1028 100644 (file)
@@ -190,7 +190,7 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
 
 #ifdef CONFIG_MAGIC_SYSRQ
 /* Note: sysrq code uses it's own private copy */
-static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
+static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
 
 static int sysrq_sysctl_handler(ctl_table *table, int write,
                                void __user *buffer, size_t *lenp,
@@ -1056,6 +1056,7 @@ static struct ctl_table kern_table[] = {
                .maxlen         = sizeof(sysctl_perf_event_sample_rate),
                .mode           = 0644,
                .proc_handler   = perf_proc_update_handler,
+               .extra1         = &one,
        },
        {
                .procname       = "perf_cpu_time_max_percent",
index 80c36bcf66e8e8d089776ff14b780f3f85efa418..78e27e3b52ac2ee0b9e86f544b77a45e12865d95 100644 (file)
@@ -26,7 +26,7 @@ static int perf_trace_event_perm(struct ftrace_event_call *tp_event,
 {
        /* The ftrace function trace is allowed only for root. */
        if (ftrace_event_is_function(tp_event) &&
-           perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
+           perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN))
                return -EPERM;
 
        /* No tracing, just counting, so no obvious leak */
index 094f3152ec2bf318dfe82797baede3b516cbd527..ebef88f61b7d81b1497cc2619e8d84a525b3471d 100644 (file)
@@ -312,6 +312,15 @@ config MAGIC_SYSRQ
          keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
          unless you really know what this hack does.
 
+config MAGIC_SYSRQ_DEFAULT_ENABLE
+       hex "Enable magic SysRq key functions by default"
+       depends on MAGIC_SYSRQ
+       default 0x1
+       help
+         Specifies which SysRq key functions are enabled by default.
+         This may be set to 1 or 0 to enable or disable them all, or
+         to a bitmask as described in Documentation/sysrq.txt.
+
 config DEBUG_KERNEL
        bool "Kernel debugging"
        help
index 084f7b18d0c0a722e215dce8d14dcda0e6ba78d8..5b4b8886435ec77c7f51ff0221b3bc01558e5798 100644 (file)
  */
 
 #include <linux/kobject.h>
+#include <linux/kobj_completion.h>
 #include <linux/string.h>
 #include <linux/export.h>
 #include <linux/stat.h>
 #include <linux/slab.h>
 
+/**
+ * kobject_namespace - return @kobj's namespace tag
+ * @kobj: kobject in question
+ *
+ * Returns namespace tag of @kobj if its parent has namespace ops enabled
+ * and thus @kobj should have a namespace tag associated with it.  Returns
+ * %NULL otherwise.
+ */
+const void *kobject_namespace(struct kobject *kobj)
+{
+       const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
+
+       if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
+               return NULL;
+
+       return kobj->ktype->namespace(kobj);
+}
+
 /*
  * populate_dir - populate directory with attributes.
  * @kobj: object we're working on.
@@ -46,13 +65,21 @@ static int populate_dir(struct kobject *kobj)
 
 static int create_dir(struct kobject *kobj)
 {
-       int error = 0;
-       error = sysfs_create_dir(kobj);
+       int error;
+
+       error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
        if (!error) {
                error = populate_dir(kobj);
                if (error)
                        sysfs_remove_dir(kobj);
        }
+
+       /*
+        * @kobj->sd may be deleted by an ancestor going away.  Hold an
+        * extra reference so that it stays until @kobj is gone.
+        */
+       sysfs_get(kobj->sd);
+
        return error;
 }
 
@@ -428,7 +455,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
                goto out;
        }
 
-       error = sysfs_rename_dir(kobj, new_name);
+       error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
        if (error)
                goto out;
 
@@ -472,6 +499,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
                if (kobj->kset)
                        new_parent = kobject_get(&kobj->kset->kobj);
        }
+
        /* old object path */
        devpath = kobject_get_path(kobj, GFP_KERNEL);
        if (!devpath) {
@@ -486,7 +514,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
        sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
        envp[0] = devpath_string;
        envp[1] = NULL;
-       error = sysfs_move_dir(kobj, new_parent);
+       error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
        if (error)
                goto out;
        old_parent = kobj->parent;
@@ -508,10 +536,15 @@ out:
  */
 void kobject_del(struct kobject *kobj)
 {
+       struct sysfs_dirent *sd;
+
        if (!kobj)
                return;
 
+       sd = kobj->sd;
        sysfs_remove_dir(kobj);
+       sysfs_put(sd);
+
        kobj->state_in_sysfs = 0;
        kobj_kset_leave(kobj);
        kobject_put(kobj->parent);
@@ -726,6 +759,55 @@ const struct sysfs_ops kobj_sysfs_ops = {
        .store  = kobj_attr_store,
 };
 
+/**
+ * kobj_completion_init - initialize a kobj_completion object.
+ * @kc: kobj_completion
+ * @ktype: type of kobject to initialize
+ *
+ * kobj_completion structures can be embedded within structures with different
+ * lifetime rules.  During the release of the enclosing object, we can
+ * wait on the release of the kobject so that we don't free it while it's
+ * still busy.
+ */
+void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype)
+{
+       init_completion(&kc->kc_unregister);
+       kobject_init(&kc->kc_kobj, ktype);
+}
+EXPORT_SYMBOL_GPL(kobj_completion_init);
+
+/**
+ * kobj_completion_release - release a kobj_completion object
+ * @kobj: kobject embedded in kobj_completion
+ *
+ * Used with kobject_release to notify waiters that the kobject has been
+ * released.
+ */
+void kobj_completion_release(struct kobject *kobj)
+{
+       struct kobj_completion *kc = kobj_to_kobj_completion(kobj);
+       complete(&kc->kc_unregister);
+}
+EXPORT_SYMBOL_GPL(kobj_completion_release);
+
+/**
+ * kobj_completion_del_and_wait - release the kobject and wait for it
+ * @kc: kobj_completion object to release
+ *
+ * Delete the kobject from sysfs and drop the reference count.  Then wait
+ * until any other outstanding references are also dropped.  This routine
+ * is only necessary once other references may have been taken on the
+ * kobject.  Typically this happens when the kobject has been published
+ * to sysfs via kobject_add.
+ */
+void kobj_completion_del_and_wait(struct kobj_completion *kc)
+{
+       kobject_del(&kc->kc_kobj);
+       kobject_put(&kc->kc_kobj);
+       wait_for_completion(&kc->kc_unregister);
+}
+EXPORT_SYMBOL_GPL(kobj_completion_del_and_wait);
+
 /**
  * kset_register - initialize and add a kset.
  * @k: kset.
index 6f9d434c1521eab9ca0b2821d10936af55f2b703..af6e95d0bed6122bf9fd1e4af2bd76a4e2be62b3 100644 (file)
@@ -153,6 +153,7 @@ void lockref_mark_dead(struct lockref *lockref)
        assert_spin_locked(&lockref->lock);
        lockref->count = -128;
 }
+EXPORT_SYMBOL(lockref_mark_dead);
 
 /**
  * lockref_get_not_dead - Increments count unless the ref is dead
index a685c8a79578b274cb361d442b953507e58d7d63..d16fa295ae1dbd0d43f1303b7796086cd968344c 100644 (file)
@@ -577,7 +577,8 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
                miter->__offset += miter->consumed;
                miter->__remaining -= miter->consumed;
 
-               if (miter->__flags & SG_MITER_TO_SG)
+               if ((miter->__flags & SG_MITER_TO_SG) &&
+                   !PageSlab(miter->page))
                        flush_kernel_dcache_page(miter->page);
 
                if (miter->__flags & SG_MITER_ATOMIC) {
index 497ec33ff22d6de772e761c6d13394480b266dc6..13b9d0f221b8460ae3c361dd51d22ae969e78325 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/page_cgroup.h>
 #include <linux/cpu.h>
 #include <linux/oom.h>
+#include <linux/lockdep.h>
 #include "internal.h"
 #include <net/sock.h>
 #include <net/ip.h>
@@ -2046,6 +2047,12 @@ static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg,
        return total;
 }
 
+#ifdef CONFIG_LOCKDEP
+static struct lockdep_map memcg_oom_lock_dep_map = {
+       .name = "memcg_oom_lock",
+};
+#endif
+
 static DEFINE_SPINLOCK(memcg_oom_lock);
 
 /*
@@ -2083,7 +2090,8 @@ static bool mem_cgroup_oom_trylock(struct mem_cgroup *memcg)
                        }
                        iter->oom_lock = false;
                }
-       }
+       } else
+               mutex_acquire(&memcg_oom_lock_dep_map, 0, 1, _RET_IP_);
 
        spin_unlock(&memcg_oom_lock);
 
@@ -2095,6 +2103,7 @@ static void mem_cgroup_oom_unlock(struct mem_cgroup *memcg)
        struct mem_cgroup *iter;
 
        spin_lock(&memcg_oom_lock);
+       mutex_release(&memcg_oom_lock_dep_map, 1, _RET_IP_);
        for_each_mem_cgroup_tree(iter, memcg)
                iter->oom_lock = false;
        spin_unlock(&memcg_oom_lock);
@@ -2765,10 +2774,10 @@ done:
        *ptr = memcg;
        return 0;
 nomem:
-       *ptr = NULL;
-       if (gfp_mask & __GFP_NOFAIL)
-               return 0;
-       return -ENOMEM;
+       if (!(gfp_mask & __GFP_NOFAIL)) {
+               *ptr = NULL;
+               return -ENOMEM;
+       }
 bypass:
        *ptr = root_mem_cgroup;
        return -EINTR;
@@ -3773,7 +3782,6 @@ void mem_cgroup_move_account_page_stat(struct mem_cgroup *from,
 {
        /* Update stat data for mem_cgroup */
        preempt_disable();
-       WARN_ON_ONCE(from->stat->count[idx] < nr_pages);
        __this_cpu_sub(from->stat->count[idx], nr_pages);
        __this_cpu_add(to->stat->count[idx], nr_pages);
        preempt_enable();
@@ -4950,31 +4958,18 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
        } while (usage > 0);
 }
 
-/*
- * This mainly exists for tests during the setting of set of use_hierarchy.
- * Since this is the very setting we are changing, the current hierarchy value
- * is meaningless
- */
-static inline bool __memcg_has_children(struct mem_cgroup *memcg)
-{
-       struct cgroup_subsys_state *pos;
-
-       /* bounce at first found */
-       css_for_each_child(pos, &memcg->css)
-               return true;
-       return false;
-}
-
-/*
- * Must be called with memcg_create_mutex held, unless the cgroup is guaranteed
- * to be already dead (as in mem_cgroup_force_empty, for instance).  This is
- * from mem_cgroup_count_children(), in the sense that we don't really care how
- * many children we have; we only need to know if we have any.  It also counts
- * any memcg without hierarchy as infertile.
- */
 static inline bool memcg_has_children(struct mem_cgroup *memcg)
 {
-       return memcg->use_hierarchy && __memcg_has_children(memcg);
+       lockdep_assert_held(&memcg_create_mutex);
+       /*
+        * The lock does not prevent addition or deletion to the list
+        * of children, but it prevents a new child from being
+        * initialized based on this parent in css_online(), so it's
+        * enough to decide whether hierarchically inherited
+        * attributes can still be changed or not.
+        */
+       return memcg->use_hierarchy &&
+               !list_empty(&memcg->css.cgroup->children);
 }
 
 /*
@@ -5054,7 +5049,7 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
         */
        if ((!parent_memcg || !parent_memcg->use_hierarchy) &&
                                (val == 1 || val == 0)) {
-               if (!__memcg_has_children(memcg))
+               if (list_empty(&memcg->css.cgroup->children))
                        memcg->use_hierarchy = val;
                else
                        retval = -EBUSY;
index ca04163635da3bb4a090596edb3009afdc6ee033..e6b7fecb3af185e452e99806d5c7962b5fad8f26 100644 (file)
@@ -64,7 +64,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
                        br_flood_deliver(br, skb, false);
                        goto out;
                }
-               if (br_multicast_rcv(br, NULL, skb)) {
+               if (br_multicast_rcv(br, NULL, skb, vid)) {
                        kfree_skb(skb);
                        goto out;
                }
index a2fd37ec35f7d26a0755f351d4104e9b02f0bb3a..7e73c32e205d10517595395ed2bed91ab48868b9 100644 (file)
@@ -80,7 +80,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
                br_fdb_update(br, p, eth_hdr(skb)->h_source, vid);
 
        if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) &&
-           br_multicast_rcv(br, p, skb))
+           br_multicast_rcv(br, p, skb, vid))
                goto drop;
 
        if (p->state == BR_STATE_LEARNING)
index 8b0b610ca2c9a3cb8eb14ead723198783db35659..686284ff3d6a1cabd0f16251d19346e11a810256 100644 (file)
@@ -947,7 +947,8 @@ void br_multicast_disable_port(struct net_bridge_port *port)
 
 static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
                                         struct net_bridge_port *port,
-                                        struct sk_buff *skb)
+                                        struct sk_buff *skb,
+                                        u16 vid)
 {
        struct igmpv3_report *ih;
        struct igmpv3_grec *grec;
@@ -957,12 +958,10 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
        int type;
        int err = 0;
        __be32 group;
-       u16 vid = 0;
 
        if (!pskb_may_pull(skb, sizeof(*ih)))
                return -EINVAL;
 
-       br_vlan_get_tag(skb, &vid);
        ih = igmpv3_report_hdr(skb);
        num = ntohs(ih->ngrec);
        len = sizeof(*ih);
@@ -1005,7 +1004,8 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
 #if IS_ENABLED(CONFIG_IPV6)
 static int br_ip6_multicast_mld2_report(struct net_bridge *br,
                                        struct net_bridge_port *port,
-                                       struct sk_buff *skb)
+                                       struct sk_buff *skb,
+                                       u16 vid)
 {
        struct icmp6hdr *icmp6h;
        struct mld2_grec *grec;
@@ -1013,12 +1013,10 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
        int len;
        int num;
        int err = 0;
-       u16 vid = 0;
 
        if (!pskb_may_pull(skb, sizeof(*icmp6h)))
                return -EINVAL;
 
-       br_vlan_get_tag(skb, &vid);
        icmp6h = icmp6_hdr(skb);
        num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
        len = sizeof(*icmp6h);
@@ -1141,7 +1139,8 @@ static void br_multicast_query_received(struct net_bridge *br,
 
 static int br_ip4_multicast_query(struct net_bridge *br,
                                  struct net_bridge_port *port,
-                                 struct sk_buff *skb)
+                                 struct sk_buff *skb,
+                                 u16 vid)
 {
        const struct iphdr *iph = ip_hdr(skb);
        struct igmphdr *ih = igmp_hdr(skb);
@@ -1153,7 +1152,6 @@ static int br_ip4_multicast_query(struct net_bridge *br,
        unsigned long now = jiffies;
        __be32 group;
        int err = 0;
-       u16 vid = 0;
 
        spin_lock(&br->multicast_lock);
        if (!netif_running(br->dev) ||
@@ -1189,7 +1187,6 @@ static int br_ip4_multicast_query(struct net_bridge *br,
        if (!group)
                goto out;
 
-       br_vlan_get_tag(skb, &vid);
        mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group, vid);
        if (!mp)
                goto out;
@@ -1219,7 +1216,8 @@ out:
 #if IS_ENABLED(CONFIG_IPV6)
 static int br_ip6_multicast_query(struct net_bridge *br,
                                  struct net_bridge_port *port,
-                                 struct sk_buff *skb)
+                                 struct sk_buff *skb,
+                                 u16 vid)
 {
        const struct ipv6hdr *ip6h = ipv6_hdr(skb);
        struct mld_msg *mld;
@@ -1231,7 +1229,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
        unsigned long now = jiffies;
        const struct in6_addr *group = NULL;
        int err = 0;
-       u16 vid = 0;
 
        spin_lock(&br->multicast_lock);
        if (!netif_running(br->dev) ||
@@ -1265,7 +1262,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
        if (!group)
                goto out;
 
-       br_vlan_get_tag(skb, &vid);
        mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group, vid);
        if (!mp)
                goto out;
@@ -1439,7 +1435,8 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
 
 static int br_multicast_ipv4_rcv(struct net_bridge *br,
                                 struct net_bridge_port *port,
-                                struct sk_buff *skb)
+                                struct sk_buff *skb,
+                                u16 vid)
 {
        struct sk_buff *skb2 = skb;
        const struct iphdr *iph;
@@ -1447,7 +1444,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
        unsigned int len;
        unsigned int offset;
        int err;
-       u16 vid = 0;
 
        /* We treat OOM as packet loss for now. */
        if (!pskb_may_pull(skb, sizeof(*iph)))
@@ -1508,7 +1504,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
 
        err = 0;
 
-       br_vlan_get_tag(skb2, &vid);
        BR_INPUT_SKB_CB(skb)->igmp = 1;
        ih = igmp_hdr(skb2);
 
@@ -1519,10 +1514,10 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
                err = br_ip4_multicast_add_group(br, port, ih->group, vid);
                break;
        case IGMPV3_HOST_MEMBERSHIP_REPORT:
-               err = br_ip4_multicast_igmp3_report(br, port, skb2);
+               err = br_ip4_multicast_igmp3_report(br, port, skb2, vid);
                break;
        case IGMP_HOST_MEMBERSHIP_QUERY:
-               err = br_ip4_multicast_query(br, port, skb2);
+               err = br_ip4_multicast_query(br, port, skb2, vid);
                break;
        case IGMP_HOST_LEAVE_MESSAGE:
                br_ip4_multicast_leave_group(br, port, ih->group, vid);
@@ -1540,7 +1535,8 @@ err_out:
 #if IS_ENABLED(CONFIG_IPV6)
 static int br_multicast_ipv6_rcv(struct net_bridge *br,
                                 struct net_bridge_port *port,
-                                struct sk_buff *skb)
+                                struct sk_buff *skb,
+                                u16 vid)
 {
        struct sk_buff *skb2;
        const struct ipv6hdr *ip6h;
@@ -1550,7 +1546,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
        unsigned int len;
        int offset;
        int err;
-       u16 vid = 0;
 
        if (!pskb_may_pull(skb, sizeof(*ip6h)))
                return -EINVAL;
@@ -1640,7 +1635,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 
        err = 0;
 
-       br_vlan_get_tag(skb, &vid);
        BR_INPUT_SKB_CB(skb)->igmp = 1;
 
        switch (icmp6_type) {
@@ -1657,10 +1651,10 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
                break;
            }
        case ICMPV6_MLD2_REPORT:
-               err = br_ip6_multicast_mld2_report(br, port, skb2);
+               err = br_ip6_multicast_mld2_report(br, port, skb2, vid);
                break;
        case ICMPV6_MGM_QUERY:
-               err = br_ip6_multicast_query(br, port, skb2);
+               err = br_ip6_multicast_query(br, port, skb2, vid);
                break;
        case ICMPV6_MGM_REDUCTION:
            {
@@ -1681,7 +1675,7 @@ out:
 #endif
 
 int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
-                    struct sk_buff *skb)
+                    struct sk_buff *skb, u16 vid)
 {
        BR_INPUT_SKB_CB(skb)->igmp = 0;
        BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
@@ -1691,10 +1685,10 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
-               return br_multicast_ipv4_rcv(br, port, skb);
+               return br_multicast_ipv4_rcv(br, port, skb, vid);
 #if IS_ENABLED(CONFIG_IPV6)
        case htons(ETH_P_IPV6):
-               return br_multicast_ipv6_rcv(br, port, skb);
+               return br_multicast_ipv6_rcv(br, port, skb, vid);
 #endif
        }
 
index e14c33b42f75c3d1f4b6bb095b32efdb9218683e..2e8244efb262d54362bd36a12b9c3000c4388260 100644 (file)
@@ -451,7 +451,8 @@ extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __us
 extern unsigned int br_mdb_rehash_seq;
 extern int br_multicast_rcv(struct net_bridge *br,
                            struct net_bridge_port *port,
-                           struct sk_buff *skb);
+                           struct sk_buff *skb,
+                           u16 vid);
 extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
                                               struct sk_buff *skb, u16 vid);
 extern void br_multicast_add_port(struct net_bridge_port *port);
@@ -522,7 +523,8 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br,
 #else
 static inline int br_multicast_rcv(struct net_bridge *br,
                                   struct net_bridge_port *port,
-                                  struct sk_buff *skb)
+                                  struct sk_buff *skb,
+                                  u16 vid)
 {
        return 0;
 }
index 518093802d1d640f3642e997b1481279fad9b68b..7c470c371e14f82a9734d3da4d0bb0a177169251 100644 (file)
@@ -181,6 +181,7 @@ static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
        ub->qlen++;
 
        pm = nlmsg_data(nlh);
+       memset(pm, 0, sizeof(*pm));
 
        /* Fill in the ulog data */
        pm->version = EBT_ULOG_VERSION;
@@ -193,8 +194,6 @@ static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
        pm->hook = hooknr;
        if (uloginfo->prefix != NULL)
                strcpy(pm->prefix, uloginfo->prefix);
-       else
-               *(pm->prefix) = '\0';
 
        if (in) {
                strcpy(pm->physindev, in->name);
@@ -204,16 +203,14 @@ static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
                        strcpy(pm->indev, br_port_get_rcu(in)->br->dev->name);
                else
                        strcpy(pm->indev, in->name);
-       } else
-               pm->indev[0] = pm->physindev[0] = '\0';
+       }
 
        if (out) {
                /* If out exists, then out is a bridge port */
                strcpy(pm->physoutdev, out->name);
                /* rcu_read_lock()ed by nf_hook_slow */
                strcpy(pm->outdev, br_port_get_rcu(out)->br->dev->name);
-       } else
-               pm->outdev[0] = pm->physoutdev[0] = '\0';
+       }
 
        if (skb_copy_bits(skb, -ETH_HLEN, pm->data, copy_len) < 0)
                BUG();
index 8d7d0dd72db211e23b5bcffd16f7600841841598..143b6fdb9647dae2d9c9f65d1a72e56bce1a1cc5 100644 (file)
@@ -40,7 +40,7 @@ again:
                struct iphdr _iph;
 ip:
                iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
-               if (!iph)
+               if (!iph || iph->ihl < 5)
                        return false;
 
                if (ip_is_fragment(iph))
index d954b56b4e47976b3b003c41cb7b39758d5d044d..325dee863e466dc74cc7fa4fd26abb56a2fae85c 100644 (file)
@@ -1344,17 +1344,19 @@ int netdev_register_kobject(struct net_device *net)
        return error;
 }
 
-int netdev_class_create_file(struct class_attribute *class_attr)
+int netdev_class_create_file_ns(struct class_attribute *class_attr,
+                               const void *ns)
 {
-       return class_create_file(&net_class, class_attr);
+       return class_create_file_ns(&net_class, class_attr, ns);
 }
-EXPORT_SYMBOL(netdev_class_create_file);
+EXPORT_SYMBOL(netdev_class_create_file_ns);
 
-void netdev_class_remove_file(struct class_attribute *class_attr)
+void netdev_class_remove_file_ns(struct class_attribute *class_attr,
+                                const void *ns)
 {
-       class_remove_file(&net_class, class_attr);
+       class_remove_file_ns(&net_class, class_attr, ns);
 }
-EXPORT_SYMBOL(netdev_class_remove_file);
+EXPORT_SYMBOL(netdev_class_remove_file_ns);
 
 int netdev_kobject_init(void)
 {
index fc75c9e461b8d366d5c29417735432dc573f08ae..8f971990677cd48026f651b2dba01d01190bfff6 100644 (file)
@@ -636,8 +636,9 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 
                        netpoll_send_skb(np, send_skb);
 
-                       /* If there are several rx_hooks for the same address,
-                          we're fine by sending a single reply */
+                       /* If there are several rx_skb_hooks for the same
+                        * address we're fine by sending a single reply
+                        */
                        break;
                }
                spin_unlock_irqrestore(&npinfo->rx_lock, flags);
@@ -719,8 +720,9 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 
                        netpoll_send_skb(np, send_skb);
 
-                       /* If there are several rx_hooks for the same address,
-                          we're fine by sending a single reply */
+                       /* If there are several rx_skb_hooks for the same
+                        * address, we're fine by sending a single reply
+                        */
                        break;
                }
                spin_unlock_irqrestore(&npinfo->rx_lock, flags);
@@ -756,11 +758,12 @@ static bool pkt_is_ns(struct sk_buff *skb)
 
 int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
 {
-       int proto, len, ulen;
-       int hits = 0;
+       int proto, len, ulen, data_len;
+       int hits = 0, offset;
        const struct iphdr *iph;
        struct udphdr *uh;
        struct netpoll *np, *tmp;
+       uint16_t source;
 
        if (list_empty(&npinfo->rx_np))
                goto out;
@@ -820,7 +823,10 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
 
                len -= iph->ihl*4;
                uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);
+               offset = (unsigned char *)(uh + 1) - skb->data;
                ulen = ntohs(uh->len);
+               data_len = skb->len - offset;
+               source = ntohs(uh->source);
 
                if (ulen != len)
                        goto out;
@@ -834,9 +840,7 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
                        if (np->local_port && np->local_port != ntohs(uh->dest))
                                continue;
 
-                       np->rx_hook(np, ntohs(uh->source),
-                                      (char *)(uh+1),
-                                      ulen - sizeof(struct udphdr));
+                       np->rx_skb_hook(np, source, skb, offset, data_len);
                        hits++;
                }
        } else {
@@ -859,7 +863,10 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
                if (!pskb_may_pull(skb, sizeof(struct udphdr)))
                        goto out;
                uh = udp_hdr(skb);
+               offset = (unsigned char *)(uh + 1) - skb->data;
                ulen = ntohs(uh->len);
+               data_len = skb->len - offset;
+               source = ntohs(uh->source);
                if (ulen != skb->len)
                        goto out;
                if (udp6_csum_init(skb, uh, IPPROTO_UDP))
@@ -872,9 +879,7 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
                        if (np->local_port && np->local_port != ntohs(uh->dest))
                                continue;
 
-                       np->rx_hook(np, ntohs(uh->source),
-                                      (char *)(uh+1),
-                                      ulen - sizeof(struct udphdr));
+                       np->rx_skb_hook(np, source, skb, offset, data_len);
                        hits++;
                }
 #endif
@@ -1062,7 +1067,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
 
        npinfo->netpoll = np;
 
-       if (np->rx_hook) {
+       if (np->rx_skb_hook) {
                spin_lock_irqsave(&npinfo->rx_lock, flags);
                npinfo->rx_flags |= NETPOLL_RX_ENABLED;
                list_add_tail(&np->rx, &npinfo->rx_np);
index 85a4f21aac1ad117f740d40da7123a663fdfefa8..59da7cde072447c2331422659adb7dadad4f3fae 100644 (file)
@@ -271,6 +271,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
        local_bh_disable();
        addend = xt_write_recseq_begin();
        private = table->private;
+       /*
+        * Ensure we load private-> members after we've fetched the base
+        * pointer.
+        */
+       smp_read_barrier_depends();
        table_base = private->entries[smp_processor_id()];
 
        e = get_entry(table_base, private->hook_entry[hook]);
index d23118d95ff9291401396953d094391db0e2e44e..718dfbd30cbe09560c1d545525b446fb5695f6af 100644 (file)
@@ -327,6 +327,11 @@ ipt_do_table(struct sk_buff *skb,
        addend = xt_write_recseq_begin();
        private = table->private;
        cpu        = smp_processor_id();
+       /*
+        * Ensure we load private-> members after we've fetched the base
+        * pointer.
+        */
+       smp_read_barrier_depends();
        table_base = private->entries[cpu];
        jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
        stackptr   = per_cpu_ptr(private->stackptr, cpu);
index cbc22158af490589833a4918f3610050a60d5be4..9cb993cd224bf702ca48382a0656163837433c54 100644 (file)
@@ -220,6 +220,7 @@ static void ipt_ulog_packet(struct net *net,
        ub->qlen++;
 
        pm = nlmsg_data(nlh);
+       memset(pm, 0, sizeof(*pm));
 
        /* We might not have a timestamp, get one */
        if (skb->tstamp.tv64 == 0)
@@ -238,8 +239,6 @@ static void ipt_ulog_packet(struct net *net,
        }
        else if (loginfo->prefix[0] != '\0')
                strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
-       else
-               *(pm->prefix) = '\0';
 
        if (in && in->hard_header_len > 0 &&
            skb->mac_header != skb->network_header &&
@@ -251,13 +250,9 @@ static void ipt_ulog_packet(struct net *net,
 
        if (in)
                strncpy(pm->indev_name, in->name, sizeof(pm->indev_name));
-       else
-               pm->indev_name[0] = '\0';
 
        if (out)
                strncpy(pm->outdev_name, out->name, sizeof(pm->outdev_name));
-       else
-               pm->outdev_name[0] = '\0';
 
        /* copy_len <= skb->len, so can't fail. */
        if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
index a16b01b537baa1e0e2b63e606f96fb37571d7638..068c8fb0d1585ec8823c0310b0a369fb76a559c0 100644 (file)
@@ -2856,7 +2856,8 @@ static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
         * left edge of the send window.
         * See draft-ietf-tcplw-high-performance-00, section 3.3.
         */
-       if (seq_rtt < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
+       if (seq_rtt < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
+           flag & FLAG_ACKED)
                seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
 
        if (seq_rtt < 0)
@@ -2871,14 +2872,19 @@ static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
 }
 
 /* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */
-static void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req)
+static void tcp_synack_rtt_meas(struct sock *sk, const u32 synack_stamp)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        s32 seq_rtt = -1;
 
-       if (tp->lsndtime && !tp->total_retrans)
-               seq_rtt = tcp_time_stamp - tp->lsndtime;
-       tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt, -1);
+       if (synack_stamp && !tp->total_retrans)
+               seq_rtt = tcp_time_stamp - synack_stamp;
+
+       /* If the ACK acks both the SYNACK and the (Fast Open'd) data packets
+        * sent in SYN_RECV, SYNACK RTT is the smooth RTT computed in tcp_ack()
+        */
+       if (!tp->srtt)
+               tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt, -1);
 }
 
 static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
@@ -2981,6 +2987,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
        s32 seq_rtt = -1;
        s32 ca_seq_rtt = -1;
        ktime_t last_ackt = net_invalid_timestamp();
+       bool rtt_update;
 
        while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) {
                struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
@@ -3057,14 +3064,13 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
        if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
                flag |= FLAG_SACK_RENEGING;
 
-       if (tcp_ack_update_rtt(sk, flag, seq_rtt, sack_rtt) ||
-           (flag & FLAG_ACKED))
-               tcp_rearm_rto(sk);
+       rtt_update = tcp_ack_update_rtt(sk, flag, seq_rtt, sack_rtt);
 
        if (flag & FLAG_ACKED) {
                const struct tcp_congestion_ops *ca_ops
                        = inet_csk(sk)->icsk_ca_ops;
 
+               tcp_rearm_rto(sk);
                if (unlikely(icsk->icsk_mtup.probe_size &&
                             !after(tp->mtu_probe.probe_seq_end, tp->snd_una))) {
                        tcp_mtup_probe_success(sk);
@@ -3103,6 +3109,13 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
 
                        ca_ops->pkts_acked(sk, pkts_acked, rtt_us);
                }
+       } else if (skb && rtt_update && sack_rtt >= 0 &&
+                  sack_rtt > (s32)(now - TCP_SKB_CB(skb)->when)) {
+               /* Do not re-arm RTO if the sack RTT is measured from data sent
+                * after when the head was last (re)transmitted. Otherwise the
+                * timeout may continue to extend in loss recovery.
+                */
+               tcp_rearm_rto(sk);
        }
 
 #if FASTRETRANS_DEBUG > 0
@@ -5587,6 +5600,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
        struct request_sock *req;
        int queued = 0;
        bool acceptable;
+       u32 synack_stamp;
 
        tp->rx_opt.saw_tstamp = 0;
 
@@ -5669,9 +5683,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                 * so release it.
                 */
                if (req) {
+                       synack_stamp = tcp_rsk(req)->snt_synack;
                        tp->total_retrans = req->num_retrans;
                        reqsk_fastopen_remove(sk, req, false);
                } else {
+                       synack_stamp = tp->lsndtime;
                        /* Make sure socket is routed, for correct metrics. */
                        icsk->icsk_af_ops->rebuild_header(sk);
                        tcp_init_congestion_control(sk);
@@ -5694,7 +5710,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
                tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale;
                tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
-               tcp_synack_rtt_meas(sk, req);
+               tcp_synack_rtt_meas(sk, synack_stamp);
 
                if (tp->rx_opt.tstamp_ok)
                        tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
index 3a7525e6c08633dad9424bc1a9cb13bf26dfec1e..533c58a5cfb7a9cf9f4f2b1842533916b20b39da 100644 (file)
@@ -18,6 +18,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
                                netdev_features_t features)
 {
        struct sk_buff *segs = ERR_PTR(-EINVAL);
+       unsigned int sum_truesize = 0;
        struct tcphdr *th;
        unsigned int thlen;
        unsigned int seq;
@@ -102,13 +103,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
                if (copy_destructor) {
                        skb->destructor = gso_skb->destructor;
                        skb->sk = gso_skb->sk;
-                       /* {tcp|sock}_wfree() use exact truesize accounting :
-                        * sum(skb->truesize) MUST be exactly be gso_skb->truesize
-                        * So we account mss bytes of 'true size' for each segment.
-                        * The last segment will contain the remaining.
-                        */
-                       skb->truesize = mss;
-                       gso_skb->truesize -= mss;
+                       sum_truesize += skb->truesize;
                }
                skb = skb->next;
                th = tcp_hdr(skb);
@@ -125,7 +120,9 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
        if (copy_destructor) {
                swap(gso_skb->sk, skb->sk);
                swap(gso_skb->destructor, skb->destructor);
-               swap(gso_skb->truesize, skb->truesize);
+               sum_truesize += skb->truesize;
+               atomic_add(sum_truesize - gso_skb->truesize,
+                          &skb->sk->sk_wmem_alloc);
        }
 
        delta = htonl(oldlen + (skb_tail_pointer(skb) -
index ccde54248c8ca77d3efc173ce457aa5f0153337a..e1a63930a96789b7df67a8b9914cd3bb69fb1cd9 100644 (file)
@@ -104,10 +104,14 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
        const struct iphdr *iph = ip_hdr(skb);
        u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
        struct flowi4 *fl4 = &fl->u.ip4;
+       int oif = 0;
+
+       if (skb_dst(skb))
+               oif = skb_dst(skb)->dev->ifindex;
 
        memset(fl4, 0, sizeof(struct flowi4));
        fl4->flowi4_mark = skb->mark;
-       fl4->flowi4_oif = skb_dst(skb)->dev->ifindex;
+       fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
 
        if (!ip_is_fragment(iph)) {
                switch (iph->protocol) {
@@ -236,7 +240,7 @@ static struct dst_ops xfrm4_dst_ops = {
        .destroy =              xfrm4_dst_destroy,
        .ifdown =               xfrm4_dst_ifdown,
        .local_out =            __ip_local_out,
-       .gc_thresh =            1024,
+       .gc_thresh =            32768,
 };
 
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
index 44400c216dc6361e4607fe9af3e2999639766a11..710238f58aa93c0319cf90adb0c203c35f8bc7e4 100644 (file)
@@ -349,6 +349,11 @@ ip6t_do_table(struct sk_buff *skb,
        local_bh_disable();
        addend = xt_write_recseq_begin();
        private = table->private;
+       /*
+        * Ensure we load private-> members after we've fetched the base
+        * pointer.
+        */
+       smp_read_barrier_depends();
        cpu        = smp_processor_id();
        table_base = private->entries[cpu];
        jumpstack  = (struct ip6t_entry **)private->jumpstack[cpu];
index f54e3a1010989ac93619d4984df4ed9b32aed521..04e17b3309fbe91af3aaf8caad4a6c32af1eab41 100644 (file)
@@ -1087,10 +1087,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
        if (rt->rt6i_genid != rt_genid_ipv6(dev_net(rt->dst.dev)))
                return NULL;
 
-       if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
-               return dst;
+       if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
+               return NULL;
 
-       return NULL;
+       if (rt6_check_expired(rt))
+               return NULL;
+
+       return dst;
 }
 
 static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
index 08ed2772b7aa58225bd6be95518ea95c1191dcd9..5f8e128c512d664080251bf6958c89021a1110c1 100644 (file)
@@ -135,10 +135,14 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
        struct ipv6_opt_hdr *exthdr;
        const unsigned char *nh = skb_network_header(skb);
        u8 nexthdr = nh[IP6CB(skb)->nhoff];
+       int oif = 0;
+
+       if (skb_dst(skb))
+               oif = skb_dst(skb)->dev->ifindex;
 
        memset(fl6, 0, sizeof(struct flowi6));
        fl6->flowi6_mark = skb->mark;
-       fl6->flowi6_oif = skb_dst(skb)->dev->ifindex;
+       fl6->flowi6_oif = reverse ? skb->skb_iif : oif;
 
        fl6->daddr = reverse ? hdr->saddr : hdr->daddr;
        fl6->saddr = reverse ? hdr->daddr : hdr->saddr;
@@ -285,7 +289,7 @@ static struct dst_ops xfrm6_dst_ops = {
        .destroy =              xfrm6_dst_destroy,
        .ifdown =               xfrm6_dst_ifdown,
        .local_out =            __ip6_local_out,
-       .gc_thresh =            1024,
+       .gc_thresh =            32768,
 };
 
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
index 8b03028cca69b616df298e0ffbfdeb247441a341..227aa11e8409bb18be93c0c432a4d71cfb6e8f38 100644 (file)
@@ -845,8 +845,13 @@ xt_replace_table(struct xt_table *table,
                return NULL;
        }
 
-       table->private = newinfo;
        newinfo->initial_entries = private->initial_entries;
+       /*
+        * Ensure contents of newinfo are visible before assigning to
+        * private.
+        */
+       smp_wmb();
+       table->private = newinfo;
 
        /*
         * Even though table entries have now been swapped, other CPU's
index 1e2fae32f81b9118f50a7c0d403cee2a324af252..ed00fef58996a8d702b6020720daf679caa1af15 100644 (file)
@@ -147,6 +147,7 @@ nfqueue_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_NFQ_info_v3 *info = par->targinfo;
        u32 queue = info->queuenum;
+       int ret;
 
        if (info->queues_total > 1) {
                if (info->flags & NFQ_FLAG_CPU_FANOUT) {
@@ -157,7 +158,11 @@ nfqueue_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
                        queue = nfqueue_hash(skb, par);
        }
 
-       return NF_QUEUE_NR(queue);
+       ret = NF_QUEUE_NR(queue);
+       if (info->flags & NFQ_FLAG_BYPASS)
+               ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
+
+       return ret;
 }
 
 static struct xt_target nfqueue_tg_reg[] __read_mostly = {
index c3235675f35997169ad4961722344537005a8f6e..5c2dab27610962caed49d6017a6cda5b5ac855fc 100644 (file)
@@ -65,8 +65,7 @@ void ovs_dp_notify_wq(struct work_struct *work)
                                        continue;
 
                                netdev_vport = netdev_vport_priv(vport);
-                               if (netdev_vport->dev->reg_state == NETREG_UNREGISTERED ||
-                                   netdev_vport->dev->reg_state == NETREG_UNREGISTERING)
+                               if (!(netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH))
                                        dp_detach_port_notify(vport);
                        }
                }
@@ -88,6 +87,10 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
                return NOTIFY_DONE;
 
        if (event == NETDEV_UNREGISTER) {
+               /* upper_dev_unlink and decrement promisc immediately */
+               ovs_netdev_detach_dev(vport);
+
+               /* schedule vport destroy, dev_put and genl notification */
                ovs_net = net_generic(dev_net(dev), ovs_net_id);
                queue_work(system_wq, &ovs_net->dp_notify_work);
        }
index 09d93c13cfd69a295d533cad35ab857c9eeee2f0..d21f77d875ba7b690a0c46231e0b539172488562 100644 (file)
@@ -150,15 +150,25 @@ static void free_port_rcu(struct rcu_head *rcu)
        ovs_vport_free(vport_from_priv(netdev_vport));
 }
 
-static void netdev_destroy(struct vport *vport)
+void ovs_netdev_detach_dev(struct vport *vport)
 {
        struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
 
-       rtnl_lock();
+       ASSERT_RTNL();
        netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
        netdev_rx_handler_unregister(netdev_vport->dev);
-       netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
+       netdev_upper_dev_unlink(netdev_vport->dev,
+                               netdev_master_upper_dev_get(netdev_vport->dev));
        dev_set_promiscuity(netdev_vport->dev, -1);
+}
+
+static void netdev_destroy(struct vport *vport)
+{
+       struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
+
+       rtnl_lock();
+       if (netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH)
+               ovs_netdev_detach_dev(vport);
        rtnl_unlock();
 
        call_rcu(&netdev_vport->rcu, free_port_rcu);
index dd298b5c5cdb25e1a721e5b845353ce055c02e60..8df01c1127e546d06ba2f8c3fde44b51c58ad0de 100644 (file)
@@ -39,5 +39,6 @@ netdev_vport_priv(const struct vport *vport)
 }
 
 const char *ovs_netdev_get_name(const struct vport *);
+void ovs_netdev_detach_dev(struct vport *);
 
 #endif /* vport_netdev.h */
index a9dfdda9ed1d55d17643f36ba05d9ac04ce1557d..fdc041c5785360731154521fb3492dba825776ff 100644 (file)
@@ -255,6 +255,7 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
                                     f->socket_hash != sk->sk_hash)) {
                                f->credit = q->initial_quantum;
                                f->socket_hash = sk->sk_hash;
+                               f->time_next_packet = 0ULL;
                        }
                        return f;
                }
index e7b2d4fe2b6a120c66b3e869d796eb6dba69c2d2..96a55910262c4e958bef93d203ce802dede835df 100644 (file)
@@ -279,7 +279,9 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
                sctp_v6_to_addr(&dst_saddr, &fl6->saddr, htons(bp->port));
                rcu_read_lock();
                list_for_each_entry_rcu(laddr, &bp->address_list, list) {
-                       if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
+                       if (!laddr->valid || laddr->state == SCTP_ADDR_DEL ||
+                           (laddr->state != SCTP_ADDR_SRC &&
+                            !asoc->src_out_of_asoc_ok))
                                continue;
 
                        /* Do not compare against v4 addrs */
index 666c668427996903b9baf185a831c1c10c75d8cb..1a6eef39ab2fcd169dde99a6494758793f5c88fc 100644 (file)
@@ -860,7 +860,6 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
            (!asoc->temp) && (sk->sk_shutdown != SHUTDOWN_MASK))
                return;
 
-       BUG_ON(asoc->peer.primary_path == NULL);
        sctp_unhash_established(asoc);
        sctp_association_free(asoc);
 }
index 084656671d6ee4cebc6220ad0d92bae654497882..97912b40c254d8a270e18f71e9e5b714e0dbcba8 100644 (file)
@@ -420,41 +420,53 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
        memcpy(gss_msg->databuf, &uid, sizeof(uid));
        gss_msg->msg.data = gss_msg->databuf;
        gss_msg->msg.len = sizeof(uid);
-       BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
+
+       BUILD_BUG_ON(sizeof(uid) > sizeof(gss_msg->databuf));
 }
 
-static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
+static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
                                const char *service_name,
                                const char *target_name)
 {
        struct gss_api_mech *mech = gss_msg->auth->mech;
        char *p = gss_msg->databuf;
-       int len = 0;
-
-       gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
-                                  mech->gm_name,
-                                  from_kuid(&init_user_ns, gss_msg->uid));
-       p += gss_msg->msg.len;
+       size_t buflen = sizeof(gss_msg->databuf);
+       int len;
+
+       len = scnprintf(p, buflen, "mech=%s uid=%d ", mech->gm_name,
+                       from_kuid(&init_user_ns, gss_msg->uid));
+       buflen -= len;
+       p += len;
+       gss_msg->msg.len = len;
        if (target_name) {
-               len = sprintf(p, "target=%s ", target_name);
+               len = scnprintf(p, buflen, "target=%s ", target_name);
+               buflen -= len;
                p += len;
                gss_msg->msg.len += len;
        }
        if (service_name != NULL) {
-               len = sprintf(p, "service=%s ", service_name);
+               len = scnprintf(p, buflen, "service=%s ", service_name);
+               buflen -= len;
                p += len;
                gss_msg->msg.len += len;
        }
        if (mech->gm_upcall_enctypes) {
-               len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes);
+               len = scnprintf(p, buflen, "enctypes=%s ",
+                               mech->gm_upcall_enctypes);
+               buflen -= len;
                p += len;
                gss_msg->msg.len += len;
        }
-       len = sprintf(p, "\n");
+       len = scnprintf(p, buflen, "\n");
+       if (len == 0)
+               goto out_overflow;
        gss_msg->msg.len += len;
 
        gss_msg->msg.data = gss_msg->databuf;
-       BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN);
+       return 0;
+out_overflow:
+       WARN_ON_ONCE(1);
+       return -ENOMEM;
 }
 
 static struct gss_upcall_msg *
@@ -463,15 +475,15 @@ gss_alloc_msg(struct gss_auth *gss_auth,
 {
        struct gss_upcall_msg *gss_msg;
        int vers;
+       int err = -ENOMEM;
 
        gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
        if (gss_msg == NULL)
-               return ERR_PTR(-ENOMEM);
+               goto err;
        vers = get_pipe_version(gss_auth->net);
-       if (vers < 0) {
-               kfree(gss_msg);
-               return ERR_PTR(vers);
-       }
+       err = vers;
+       if (err < 0)
+               goto err_free_msg;
        gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe;
        INIT_LIST_HEAD(&gss_msg->list);
        rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
@@ -482,10 +494,17 @@ gss_alloc_msg(struct gss_auth *gss_auth,
        switch (vers) {
        case 0:
                gss_encode_v0_msg(gss_msg);
+               break;
        default:
-               gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
+               err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
+               if (err)
+                       goto err_free_msg;
        };
        return gss_msg;
+err_free_msg:
+       kfree(gss_msg);
+err:
+       return ERR_PTR(err);
 }
 
 static struct gss_upcall_msg *
index 77479606a9716e9526019ba5e5a0dfa4b7d010a2..dab09dac8fc7ba08ed6ec1312eb840ef5d7bc5c0 100644 (file)
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
+#include <linux/rcupdate.h>
 #include <linux/utsname.h>
 #include <linux/workqueue.h>
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/un.h>
-#include <linux/rcupdate.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/addr.h>
@@ -264,6 +264,26 @@ void rpc_clients_notifier_unregister(void)
        return rpc_pipefs_notifier_unregister(&rpc_clients_block);
 }
 
+static struct rpc_xprt *rpc_clnt_set_transport(struct rpc_clnt *clnt,
+               struct rpc_xprt *xprt,
+               const struct rpc_timeout *timeout)
+{
+       struct rpc_xprt *old;
+
+       spin_lock(&clnt->cl_lock);
+       old = rcu_dereference_protected(clnt->cl_xprt,
+                       lockdep_is_held(&clnt->cl_lock));
+
+       if (!xprt_bound(xprt))
+               clnt->cl_autobind = 1;
+
+       clnt->cl_timeout = timeout;
+       rcu_assign_pointer(clnt->cl_xprt, xprt);
+       spin_unlock(&clnt->cl_lock);
+
+       return old;
+}
+
 static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
 {
        clnt->cl_nodelen = strlen(nodename);
@@ -272,12 +292,13 @@ static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
        memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
 }
 
-static int rpc_client_register(const struct rpc_create_args *args,
-                              struct rpc_clnt *clnt)
+static int rpc_client_register(struct rpc_clnt *clnt,
+                              rpc_authflavor_t pseudoflavor,
+                              const char *client_name)
 {
        struct rpc_auth_create_args auth_args = {
-               .pseudoflavor = args->authflavor,
-               .target_name = args->client_name,
+               .pseudoflavor = pseudoflavor,
+               .target_name = client_name,
        };
        struct rpc_auth *auth;
        struct net *net = rpc_net_ns(clnt);
@@ -298,7 +319,7 @@ static int rpc_client_register(const struct rpc_create_args *args,
        auth = rpcauth_create(&auth_args, clnt);
        if (IS_ERR(auth)) {
                dprintk("RPC:       Couldn't create auth handle (flavor %u)\n",
-                               args->authflavor);
+                               pseudoflavor);
                err = PTR_ERR(auth);
                goto err_auth;
        }
@@ -337,7 +358,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
 {
        const struct rpc_program *program = args->program;
        const struct rpc_version *version;
-       struct rpc_clnt         *clnt = NULL;
+       struct rpc_clnt *clnt = NULL;
+       const struct rpc_timeout *timeout;
        int err;
 
        /* sanity check the name before trying to print it */
@@ -365,7 +387,6 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
        if (err)
                goto out_no_clid;
 
-       rcu_assign_pointer(clnt->cl_xprt, xprt);
        clnt->cl_procinfo = version->procs;
        clnt->cl_maxproc  = version->nrprocs;
        clnt->cl_prog     = args->prognumber ? : program->number;
@@ -380,16 +401,15 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
        INIT_LIST_HEAD(&clnt->cl_tasks);
        spin_lock_init(&clnt->cl_lock);
 
-       if (!xprt_bound(xprt))
-               clnt->cl_autobind = 1;
-
-       clnt->cl_timeout = xprt->timeout;
+       timeout = xprt->timeout;
        if (args->timeout != NULL) {
                memcpy(&clnt->cl_timeout_default, args->timeout,
                                sizeof(clnt->cl_timeout_default));
-               clnt->cl_timeout = &clnt->cl_timeout_default;
+               timeout = &clnt->cl_timeout_default;
        }
 
+       rpc_clnt_set_transport(clnt, xprt, timeout);
+
        clnt->cl_rtt = &clnt->cl_rtt_default;
        rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
 
@@ -398,7 +418,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
        /* save the nodename */
        rpc_clnt_set_nodename(clnt, utsname()->nodename);
 
-       err = rpc_client_register(args, clnt);
+       err = rpc_client_register(clnt, args->authflavor, args->client_name);
        if (err)
                goto out_no_path;
        if (parent)
@@ -600,6 +620,80 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
 }
 EXPORT_SYMBOL_GPL(rpc_clone_client_set_auth);
 
+/**
+ * rpc_switch_client_transport: switch the RPC transport on the fly
+ * @clnt: pointer to a struct rpc_clnt
+ * @args: pointer to the new transport arguments
+ * @timeout: pointer to the new timeout parameters
+ *
+ * This function allows the caller to switch the RPC transport for the
+ * rpc_clnt structure 'clnt' to allow it to connect to a mirrored NFS
+ * server, for instance.  It assumes that the caller has ensured that
+ * there are no active RPC tasks by using some form of locking.
+ *
+ * Returns zero if "clnt" is now using the new xprt.  Otherwise a
+ * negative errno is returned, and "clnt" continues to use the old
+ * xprt.
+ */
+int rpc_switch_client_transport(struct rpc_clnt *clnt,
+               struct xprt_create *args,
+               const struct rpc_timeout *timeout)
+{
+       const struct rpc_timeout *old_timeo;
+       rpc_authflavor_t pseudoflavor;
+       struct rpc_xprt *xprt, *old;
+       struct rpc_clnt *parent;
+       int err;
+
+       xprt = xprt_create_transport(args);
+       if (IS_ERR(xprt)) {
+               dprintk("RPC:       failed to create new xprt for clnt %p\n",
+                       clnt);
+               return PTR_ERR(xprt);
+       }
+
+       pseudoflavor = clnt->cl_auth->au_flavor;
+
+       old_timeo = clnt->cl_timeout;
+       old = rpc_clnt_set_transport(clnt, xprt, timeout);
+
+       rpc_unregister_client(clnt);
+       __rpc_clnt_remove_pipedir(clnt);
+
+       /*
+        * A new transport was created.  "clnt" therefore
+        * becomes the root of a new cl_parent tree.  clnt's
+        * children, if it has any, still point to the old xprt.
+        */
+       parent = clnt->cl_parent;
+       clnt->cl_parent = clnt;
+
+       /*
+        * The old rpc_auth cache cannot be re-used.  GSS
+        * contexts in particular are between a single
+        * client and server.
+        */
+       err = rpc_client_register(clnt, pseudoflavor, NULL);
+       if (err)
+               goto out_revert;
+
+       synchronize_rcu();
+       if (parent != clnt)
+               rpc_release_client(parent);
+       xprt_put(old);
+       dprintk("RPC:       replaced xprt for clnt %p\n", clnt);
+       return 0;
+
+out_revert:
+       rpc_clnt_set_transport(clnt, old, old_timeo);
+       clnt->cl_parent = parent;
+       rpc_client_register(clnt, pseudoflavor, NULL);
+       xprt_put(xprt);
+       dprintk("RPC:       failed to switch xprt for clnt %p\n", clnt);
+       return err;
+}
+EXPORT_SYMBOL_GPL(rpc_switch_client_transport);
+
 /*
  * Kill all tasks for the given client.
  * XXX: kill their descendants as well?
@@ -772,6 +866,8 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
                atomic_inc(&clnt->cl_count);
                if (clnt->cl_softrtry)
                        task->tk_flags |= RPC_TASK_SOFT;
+               if (clnt->cl_noretranstimeo)
+                       task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT;
                if (sk_memalloc_socks()) {
                        struct rpc_xprt *xprt;
 
@@ -1690,6 +1786,7 @@ call_connect_status(struct rpc_task *task)
        dprint_status(task);
 
        trace_rpc_connect_status(task, status);
+       task->tk_status = 0;
        switch (status) {
                /* if soft mounted, test if we've timed out */
        case -ETIMEDOUT:
@@ -1698,12 +1795,14 @@ call_connect_status(struct rpc_task *task)
        case -ECONNREFUSED:
        case -ECONNRESET:
        case -ENETUNREACH:
+               /* retry with existing socket, after a delay */
+               rpc_delay(task, 3*HZ);
                if (RPC_IS_SOFTCONN(task))
                        break;
-               /* retry with existing socket, after a delay */
-       case 0:
        case -EAGAIN:
-               task->tk_status = 0;
+               task->tk_action = call_bind;
+               return;
+       case 0:
                clnt->cl_stats->netreconn++;
                task->tk_action = call_transmit;
                return;
@@ -1717,13 +1816,14 @@ call_connect_status(struct rpc_task *task)
 static void
 call_transmit(struct rpc_task *task)
 {
+       int is_retrans = RPC_WAS_SENT(task);
+
        dprint_status(task);
 
        task->tk_action = call_status;
        if (task->tk_status < 0)
                return;
-       task->tk_status = xprt_prepare_transmit(task);
-       if (task->tk_status != 0)
+       if (!xprt_prepare_transmit(task))
                return;
        task->tk_action = call_transmit_status;
        /* Encode here so that rpcsec_gss can use correct sequence number. */
@@ -1742,6 +1842,8 @@ call_transmit(struct rpc_task *task)
        xprt_transmit(task);
        if (task->tk_status < 0)
                return;
+       if (is_retrans)
+               task->tk_client->cl_stats->rpcretrans++;
        /*
         * On success, ensure that we call xprt_end_transmit() before sleeping
         * in order to allow access to the socket to other RPC requests.
@@ -1811,8 +1913,7 @@ call_bc_transmit(struct rpc_task *task)
 {
        struct rpc_rqst *req = task->tk_rqstp;
 
-       task->tk_status = xprt_prepare_transmit(task);
-       if (task->tk_status == -EAGAIN) {
+       if (!xprt_prepare_transmit(task)) {
                /*
                 * Could not reserve the transport. Try again after the
                 * transport is released.
@@ -1900,7 +2001,8 @@ call_status(struct rpc_task *task)
                rpc_delay(task, 3*HZ);
        case -ETIMEDOUT:
                task->tk_action = call_timeout;
-               if (task->tk_client->cl_discrtry)
+               if (!(task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT)
+                   && task->tk_client->cl_discrtry)
                        xprt_conditional_disconnect(req->rq_xprt,
                                        req->rq_connect_cookie);
                break;
@@ -1982,7 +2084,6 @@ call_timeout(struct rpc_task *task)
        rpcauth_invalcred(task);
 
 retry:
-       clnt->cl_stats->rpcretrans++;
        task->tk_action = call_bind;
        task->tk_status = 0;
 }
@@ -2025,7 +2126,6 @@ call_decode(struct rpc_task *task)
        if (req->rq_rcv_buf.len < 12) {
                if (!RPC_IS_SOFT(task)) {
                        task->tk_action = call_bind;
-                       clnt->cl_stats->rpcretrans++;
                        goto out_retry;
                }
                dprintk("RPC:       %s: too small RPC reply size (%d bytes)\n",
index 095363eee764b3ff496a745f56e4fa646f5f02c0..04199bc8416f0c3bd3add838381db36f12130144 100644 (file)
@@ -205,10 +205,8 @@ int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
                goto out_sleep;
        }
        xprt->snd_task = task;
-       if (req != NULL) {
-               req->rq_bytes_sent = 0;
+       if (req != NULL)
                req->rq_ntrans++;
-       }
 
        return 1;
 
@@ -263,7 +261,6 @@ int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
        }
        if (__xprt_get_cong(xprt, task)) {
                xprt->snd_task = task;
-               req->rq_bytes_sent = 0;
                req->rq_ntrans++;
                return 1;
        }
@@ -300,10 +297,8 @@ static bool __xprt_lock_write_func(struct rpc_task *task, void *data)
 
        req = task->tk_rqstp;
        xprt->snd_task = task;
-       if (req) {
-               req->rq_bytes_sent = 0;
+       if (req)
                req->rq_ntrans++;
-       }
        return true;
 }
 
@@ -329,7 +324,6 @@ static bool __xprt_lock_write_cong_func(struct rpc_task *task, void *data)
        }
        if (__xprt_get_cong(xprt, task)) {
                xprt->snd_task = task;
-               req->rq_bytes_sent = 0;
                req->rq_ntrans++;
                return true;
        }
@@ -358,6 +352,11 @@ out_unlock:
 void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
 {
        if (xprt->snd_task == task) {
+               if (task != NULL) {
+                       struct rpc_rqst *req = task->tk_rqstp;
+                       if (req != NULL)
+                               req->rq_bytes_sent = 0;
+               }
                xprt_clear_locked(xprt);
                __xprt_lock_write_next(xprt);
        }
@@ -375,6 +374,11 @@ EXPORT_SYMBOL_GPL(xprt_release_xprt);
 void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
 {
        if (xprt->snd_task == task) {
+               if (task != NULL) {
+                       struct rpc_rqst *req = task->tk_rqstp;
+                       if (req != NULL)
+                               req->rq_bytes_sent = 0;
+               }
                xprt_clear_locked(xprt);
                __xprt_lock_write_next_cong(xprt);
        }
@@ -854,24 +858,36 @@ static inline int xprt_has_timer(struct rpc_xprt *xprt)
  * @task: RPC task about to send a request
  *
  */
-int xprt_prepare_transmit(struct rpc_task *task)
+bool xprt_prepare_transmit(struct rpc_task *task)
 {
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = req->rq_xprt;
-       int err = 0;
+       bool ret = false;
 
        dprintk("RPC: %5u xprt_prepare_transmit\n", task->tk_pid);
 
        spin_lock_bh(&xprt->transport_lock);
-       if (req->rq_reply_bytes_recvd && !req->rq_bytes_sent) {
-               err = req->rq_reply_bytes_recvd;
+       if (!req->rq_bytes_sent) {
+               if (req->rq_reply_bytes_recvd) {
+                       task->tk_status = req->rq_reply_bytes_recvd;
+                       goto out_unlock;
+               }
+               if ((task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT)
+                   && xprt_connected(xprt)
+                   && req->rq_connect_cookie == xprt->connect_cookie) {
+                       xprt->ops->set_retrans_timeout(task);
+                       rpc_sleep_on(&xprt->pending, task, xprt_timer);
+                       goto out_unlock;
+               }
+       }
+       if (!xprt->ops->reserve_xprt(xprt, task)) {
+               task->tk_status = -EAGAIN;
                goto out_unlock;
        }
-       if (!xprt->ops->reserve_xprt(xprt, task))
-               err = -EAGAIN;
+       ret = true;
 out_unlock:
        spin_unlock_bh(&xprt->transport_lock);
-       return err;
+       return ret;
 }
 
 void xprt_end_transmit(struct rpc_task *task)
@@ -912,7 +928,6 @@ void xprt_transmit(struct rpc_task *task)
        } else if (!req->rq_bytes_sent)
                return;
 
-       req->rq_connect_cookie = xprt->connect_cookie;
        req->rq_xtime = ktime_get();
        status = xprt->ops->send_request(task);
        if (status != 0) {
@@ -938,12 +953,14 @@ void xprt_transmit(struct rpc_task *task)
        /* Don't race with disconnect */
        if (!xprt_connected(xprt))
                task->tk_status = -ENOTCONN;
-       else if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) {
+       else {
                /*
                 * Sleep on the pending queue since
                 * we're expecting a reply.
                 */
-               rpc_sleep_on(&xprt->pending, task, xprt_timer);
+               if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task))
+                       rpc_sleep_on(&xprt->pending, task, xprt_timer);
+               req->rq_connect_cookie = xprt->connect_cookie;
        }
        spin_unlock_bh(&xprt->transport_lock);
 }
@@ -1087,11 +1104,9 @@ struct rpc_xprt *xprt_alloc(struct net *net, size_t size,
        for (i = 0; i < num_prealloc; i++) {
                req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL);
                if (!req)
-                       break;
+                       goto out_free;
                list_add(&req->rq_list, &xprt->free);
        }
-       if (i < num_prealloc)
-               goto out_free;
        if (max_alloc > num_prealloc)
                xprt->max_reqs = max_alloc;
        else
@@ -1186,6 +1201,12 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
        req->rq_xprt    = xprt;
        req->rq_buffer  = NULL;
        req->rq_xid     = xprt_alloc_xid(xprt);
+       req->rq_connect_cookie = xprt->connect_cookie - 1;
+       req->rq_bytes_sent = 0;
+       req->rq_snd_buf.len = 0;
+       req->rq_snd_buf.buflen = 0;
+       req->rq_rcv_buf.len = 0;
+       req->rq_rcv_buf.buflen = 0;
        req->rq_release_snd_buf = NULL;
        xprt_reset_majortimeo(req);
        dprintk("RPC: %5u reserved req %p xid %08x\n", task->tk_pid,
index ee03d35677d962a3385d8d01a31968b70fa77b56..17c88928b7db0abe001697867ead944bf6621712 100644 (file)
@@ -835,6 +835,8 @@ static void xs_close(struct rpc_xprt *xprt)
 
        dprintk("RPC:       xs_close xprt %p\n", xprt);
 
+       cancel_delayed_work_sync(&transport->connect_worker);
+
        xs_reset_transport(transport);
        xprt->reestablish_timeout = 0;
 
@@ -854,14 +856,6 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
                xs_tcp_shutdown(xprt);
 }
 
-static void xs_local_destroy(struct rpc_xprt *xprt)
-{
-       xs_close(xprt);
-       xs_free_peer_addresses(xprt);
-       xprt_free(xprt);
-       module_put(THIS_MODULE);
-}
-
 /**
  * xs_destroy - prepare to shutdown a transport
  * @xprt: doomed transport
@@ -869,13 +863,12 @@ static void xs_local_destroy(struct rpc_xprt *xprt)
  */
 static void xs_destroy(struct rpc_xprt *xprt)
 {
-       struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
-
        dprintk("RPC:       xs_destroy xprt %p\n", xprt);
 
-       cancel_delayed_work_sync(&transport->connect_worker);
-
-       xs_local_destroy(xprt);
+       xs_close(xprt);
+       xs_free_peer_addresses(xprt);
+       xprt_free(xprt);
+       module_put(THIS_MODULE);
 }
 
 static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -1511,6 +1504,7 @@ static void xs_tcp_state_change(struct sock *sk)
                        transport->tcp_copied = 0;
                        transport->tcp_flags =
                                TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID;
+                       xprt->connect_cookie++;
 
                        xprt_wake_pending_tasks(xprt, -EAGAIN);
                }
@@ -1816,6 +1810,10 @@ static inline void xs_reclassify_socket(int family, struct socket *sock)
 }
 #endif
 
+static void xs_dummy_setup_socket(struct work_struct *work)
+{
+}
+
 static struct socket *xs_create_sock(struct rpc_xprt *xprt,
                struct sock_xprt *transport, int family, int type, int protocol)
 {
@@ -2112,6 +2110,19 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
 
        if (!transport->inet) {
                struct sock *sk = sock->sk;
+               unsigned int keepidle = xprt->timeout->to_initval / HZ;
+               unsigned int keepcnt = xprt->timeout->to_retries + 1;
+               unsigned int opt_on = 1;
+
+               /* TCP Keepalive options */
+               kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+                               (char *)&opt_on, sizeof(opt_on));
+               kernel_setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,
+                               (char *)&keepidle, sizeof(keepidle));
+               kernel_setsockopt(sock, SOL_TCP, TCP_KEEPINTVL,
+                               (char *)&keepidle, sizeof(keepidle));
+               kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT,
+                               (char *)&keepcnt, sizeof(keepcnt));
 
                write_lock_bh(&sk->sk_callback_lock);
 
@@ -2151,7 +2162,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
        case 0:
        case -EINPROGRESS:
                /* SYN_SENT! */
-               xprt->connect_cookie++;
                if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
                        xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
        }
@@ -2498,7 +2508,7 @@ static struct rpc_xprt_ops xs_local_ops = {
        .send_request           = xs_local_send_request,
        .set_retrans_timeout    = xprt_set_retrans_timeout_def,
        .close                  = xs_close,
-       .destroy                = xs_local_destroy,
+       .destroy                = xs_destroy,
        .print_stats            = xs_local_print_stats,
 };
 
@@ -2655,6 +2665,9 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
        xprt->ops = &xs_local_ops;
        xprt->timeout = &xs_local_default_timeout;
 
+       INIT_DELAYED_WORK(&transport->connect_worker,
+                       xs_dummy_setup_socket);
+
        switch (sun->sun_family) {
        case AF_LOCAL:
                if (sun->sun_path[0] != '/') {
@@ -2859,8 +2872,8 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
        if (args->bc_xprt->xpt_bc_xprt) {
                /*
                 * This server connection already has a backchannel
-                * export; we can't create a new one, as we wouldn't be
-                * able to match replies based on xid any more.  So,
+                * transport; we can't create a new one, as we wouldn't
+                * be able to match replies based on xid any more.  So,
                 * reuse the already-existing one:
                 */
                 return args->bc_xprt->xpt_bc_xprt;
index c959312c45e3e050307ac5126a59f8478babc7ae..e2fa133f9fba225656fa62f4e9fb61e745a4d46a 100644 (file)
@@ -16,8 +16,8 @@ config X25
          if you want that) and the lower level data link layer protocol LAPB
          (say Y to "LAPB Data Link Driver" below if you want that).
 
-         You can read more about X.25 at <http://www.sangoma.com/x25.htm> and
-         <http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/cbook/cx25.htm>.
+         You can read more about X.25 at <http://www.sangoma.com/tutorials/x25/> and
+         <http://docwiki.cisco.com/wiki/X.25>.
          Information about X.25 for Linux is contained in the files
          <file:Documentation/networking/x25.txt> and
          <file:Documentation/networking/x25-iface.txt>.
index 2906d520eea7c2b7636fc94f3a60f5131701f57d..3be02b680268d1ccb7e3672a92777b12963b8562 100644 (file)
@@ -141,14 +141,14 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
        const int plen = skb->len;
        int dlen = IPCOMP_SCRATCH_SIZE;
        u8 *start = skb->data;
-       const int cpu = get_cpu();
-       u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
-       struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
+       struct crypto_comp *tfm;
+       u8 *scratch;
        int err;
 
        local_bh_disable();
+       scratch = *this_cpu_ptr(ipcomp_scratches);
+       tfm = *this_cpu_ptr(ipcd->tfms);
        err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-       local_bh_enable();
        if (err)
                goto out;
 
@@ -158,13 +158,13 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
        }
 
        memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
-       put_cpu();
+       local_bh_enable();
 
        pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr));
        return 0;
 
 out:
-       put_cpu();
+       local_bh_enable();
        return err;
 }
 
index 487ac6f37ca23ce2d1e832fa177d74d4544386bf..9a11f9f799f499f2d34d1dea3dec48feb36db00f 100644 (file)
@@ -55,6 +55,7 @@ static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
+static unsigned long long kernel_start_addr = 0;
 
 int token_profit[0x10000];
 
@@ -65,7 +66,10 @@ unsigned char best_table_len[256];
 
 static void usage(void)
 {
-       fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
+       fprintf(stderr, "Usage: kallsyms [--all-symbols] "
+                       "[--symbol-prefix=<prefix char>] "
+                       "[--page-offset=<CONFIG_PAGE_OFFSET>] "
+                       "< in.map > out.S\n");
        exit(1);
 }
 
@@ -194,6 +198,9 @@ static int symbol_valid(struct sym_entry *s)
        int i;
        int offset = 1;
 
+       if (s->addr < kernel_start_addr)
+               return 0;
+
        /* skip prefix char */
        if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char)
                offset++;
@@ -646,6 +653,9 @@ int main(int argc, char **argv)
                                if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
                                        p++;
                                symbol_prefix_char = *p;
+                       } else if (strncmp(argv[i], "--page-offset=", 14) == 0) {
+                               const char *p = &argv[i][14];
+                               kernel_start_addr = strtoull(p, NULL, 16);
                        } else
                                usage();
                }
index 014994936b1c2152c82f793ce646342159d78eb5..32b10f53d0b4cbad76b13ef86d547ad864ae19c2 100644 (file)
@@ -82,6 +82,8 @@ kallsyms()
                kallsymopt="${kallsymopt} --all-symbols"
        fi
 
+       kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
+
        local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \
                      ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
 
index a4f31c900fa6a44ab75d1a4f3916d2bb1075c448..c5d473393816f971ec43135bd7dd3a27cc660beb 100644 (file)
@@ -115,7 +115,9 @@ git --git-dir=$(srctree)/.git archive --prefix=$(perf-tar)/         \
        -o $(perf-tar).tar;                                         \
 mkdir -p $(perf-tar);                                               \
 git --git-dir=$(srctree)/.git rev-parse HEAD > $(perf-tar)/HEAD;    \
-tar rf $(perf-tar).tar $(perf-tar)/HEAD;                            \
+(cd $(srctree)/tools/perf;                                          \
+util/PERF-VERSION-GEN ../../$(perf-tar)/ 2>/dev/null);              \
+tar rf $(perf-tar).tar $(perf-tar)/HEAD $(perf-tar)/PERF-VERSION-FILE; \
 rm -r $(perf-tar);                                                  \
 $(if $(findstring tar-src,$@),,                                     \
 $(if $(findstring bz2,$@),bzip2,                                    \
index 17f45e8aa89cd49561cce6c40cbc174f416d9c49..e1e9e0c999fefa854a507e623b821371ebf00b78 100644 (file)
@@ -49,6 +49,8 @@ static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
        struct snd_pcm *pcm;
 
        list_for_each_entry(pcm, &snd_pcm_devices, list) {
+               if (pcm->internal)
+                       continue;
                if (pcm->card == card && pcm->device == device)
                        return pcm;
        }
@@ -60,6 +62,8 @@ static int snd_pcm_next(struct snd_card *card, int device)
        struct snd_pcm *pcm;
 
        list_for_each_entry(pcm, &snd_pcm_devices, list) {
+               if (pcm->internal)
+                       continue;
                if (pcm->card == card && pcm->device > device)
                        return pcm->device;
                else if (pcm->card->number > card->number)
index bf313bea70858f8a4abd18ef6c60beca6668fea1..8ad554312b69196de4d9cf056024c2e8f07907bd 100644 (file)
@@ -4623,6 +4623,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
        SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4),
+       SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_ASUS_MODE4),
        SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
index 8b50e5958de5a43030ac854d18c046cf903e5841..01daf655e20b1663fbb92179283dea25ac209ac9 100644 (file)
@@ -530,6 +530,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
                                hubs->hp_startup_mode);
                        break;
                }
+               break;
 
        case SND_SOC_DAPM_PRE_PMD:
                snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
index 2eea1840315d3448248109215f216d2f607c0b89..37459dfd168d3d16362330cdf0ba047d29d41e97 100644 (file)
@@ -2,7 +2,7 @@ config SND_SOC_SAMSUNG
        tristate "ASoC support for Samsung"
        depends on PLAT_SAMSUNG
        select S3C64XX_DMA if ARCH_S3C64XX
-       select S3C2410_DMA if ARCH_S3C24XX
+       select S3C24XX_DMA if ARCH_S3C24XX
        help
          Say Y or M if you want to add support for codecs attached to
          the Samsung SoCs' Audio interfaces. You will also need to
index e5e81b11100108dbb724de7eedb0193836351253..fefc56100349d5c6c8d8c4a5015eebed545779ac 100644 (file)
 #undef S3C_IIS_V2_SUPPORTED
 
 #if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \
-       || defined(CONFIG_CPU_S5PV210)
-#define S3C_IIS_V2_SUPPORTED
-#endif
-
-#ifdef CONFIG_PLAT_S3C64XX
+       || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210)
 #define S3C_IIS_V2_SUPPORTED
 #endif
 
index c17c14c394df88bb0442ccaf51b5735f05455ab5..b2949aed1ac2e9bfd374dff8b0a2483ecf19ddf4 100644 (file)
@@ -1949,7 +1949,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
                                w->active ? "active" : "inactive");
 
        list_for_each_entry(p, &w->sources, list_sink) {
-               if (p->connected && !p->connected(w, p->sink))
+               if (p->connected && !p->connected(w, p->source))
                        continue;
 
                if (p->connect)
@@ -3495,6 +3495,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
                if (!w) {
                        dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
                                dai->driver->playback.stream_name);
+                       return -ENOMEM;
                }
 
                w->priv = dai;
@@ -3513,6 +3514,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
                if (!w) {
                        dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
                                dai->driver->capture.stream_name);
+                       return -ENOMEM;
                }
 
                w->priv = dai;
index 8fd9ec66121c111b5bcfc29fd6e0e286f125ad67..b8d6d541d854b7d719056cec96640548980eb79e 100644 (file)
@@ -89,6 +89,7 @@ static char *processor_arch;
 static char *os_build;
 static char *os_version;
 static char *lic_version = "Unknown version";
+static char full_domain_name[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
 static struct utsname uts_buf;
 
 /*
@@ -1367,7 +1368,7 @@ setval_error:
 }
 
 
-static int
+static void
 kvp_get_domain_name(char *buffer, int length)
 {
        struct addrinfo hints, *info ;
@@ -1381,12 +1382,12 @@ kvp_get_domain_name(char *buffer, int length)
 
        error = getaddrinfo(buffer, NULL, &hints, &info);
        if (error != 0) {
-               strcpy(buffer, "getaddrinfo failed\n");
-               return error;
+               snprintf(buffer, length, "getaddrinfo failed: 0x%x %s",
+                       error, gai_strerror(error));
+               return;
        }
-       strcpy(buffer, info->ai_canonname);
+       snprintf(buffer, length, "%s", info->ai_canonname);
        freeaddrinfo(info);
-       return error;
 }
 
 static int
@@ -1433,7 +1434,6 @@ int main(void)
        int     pool;
        char    *if_name;
        struct hv_kvp_ipaddr_value *kvp_ip_val;
-       char *kvp_send_buffer;
        char *kvp_recv_buffer;
        size_t kvp_recv_buffer_len;
 
@@ -1442,17 +1442,21 @@ int main(void)
        openlog("KVP", 0, LOG_USER);
        syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
 
-       kvp_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg);
-       kvp_send_buffer = calloc(1, kvp_recv_buffer_len);
+       kvp_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg);
        kvp_recv_buffer = calloc(1, kvp_recv_buffer_len);
-       if (!(kvp_send_buffer && kvp_recv_buffer)) {
-               syslog(LOG_ERR, "Failed to allocate netlink buffers");
+       if (!kvp_recv_buffer) {
+               syslog(LOG_ERR, "Failed to allocate netlink buffer");
                exit(EXIT_FAILURE);
        }
        /*
         * Retrieve OS release information.
         */
        kvp_get_os_info();
+       /*
+        * Cache Fully Qualified Domain Name because getaddrinfo takes an
+        * unpredictable amount of time to finish.
+        */
+       kvp_get_domain_name(full_domain_name, sizeof(full_domain_name));
 
        if (kvp_file_init()) {
                syslog(LOG_ERR, "Failed to initialize the pools");
@@ -1488,7 +1492,7 @@ int main(void)
        /*
         * Register ourselves with the kernel.
         */
-       message = (struct cn_msg *)kvp_send_buffer;
+       message = (struct cn_msg *)kvp_recv_buffer;
        message->id.idx = CN_KVP_IDX;
        message->id.val = CN_KVP_VAL;
 
@@ -1671,8 +1675,7 @@ int main(void)
 
                switch (hv_msg->body.kvp_enum_data.index) {
                case FullyQualifiedDomainName:
-                       kvp_get_domain_name(key_value,
-                                       HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+                       strcpy(key_value, full_domain_name);
                        strcpy(key_name, "FullyQualifiedDomainName");
                        break;
                case IntegrationServicesVersion:
index 8611962c672c70dd282443a59cda62f10523ac0f..8bcb04096eb267a1f6d49e672720661e779ec5c3 100644 (file)
@@ -140,7 +140,6 @@ int main(void)
        struct cn_msg   *incoming_cn_msg;
        int     op;
        struct hv_vss_msg *vss_msg;
-       char *vss_send_buffer;
        char *vss_recv_buffer;
        size_t vss_recv_buffer_len;
 
@@ -150,10 +149,9 @@ int main(void)
        openlog("Hyper-V VSS", 0, LOG_USER);
        syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
 
-       vss_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg);
-       vss_send_buffer = calloc(1, vss_recv_buffer_len);
+       vss_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg);
        vss_recv_buffer = calloc(1, vss_recv_buffer_len);
-       if (!(vss_send_buffer && vss_recv_buffer)) {
+       if (!vss_recv_buffer) {
                syslog(LOG_ERR, "Failed to allocate netlink buffers");
                exit(EXIT_FAILURE);
        }
@@ -185,7 +183,7 @@ int main(void)
        /*
         * Register ourselves with the kernel.
         */
-       message = (struct cn_msg *)vss_send_buffer;
+       message = (struct cn_msg *)vss_recv_buffer;
        message->id.idx = CN_VSS_IDX;
        message->id.val = CN_VSS_VAL;
        message->ack = 0;
index ca6cb779876a02de1bdd89f5ab0686e887bd2da0..fc1502098595b8b960f262c4f789c15c247d0d61 100644 (file)
@@ -134,14 +134,14 @@ ifeq ($(VERBOSE),1)
   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_plugin_obj_compile =   echo '  CC PLUGIN OBJ      '$(OBJ);
-  print_plugin_build =         echo '  CC PLUGI           '$(OBJ);
-  print_static_lib_build =     echo '  BUILD STATIC LIB   '$(OBJ);
-  print_install =              echo '  INSTALL     '$1'        to      $(DESTDIR_SQ)$2';
+  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_plugin_obj_compile =   echo '  BUILD    PLUGIN OBJ '$(OBJ);
+  print_plugin_build =         echo '  BUILD    PLUGIN     '$(OBJ);
+  print_static_lib_build =     echo '  BUILD    STATIC LIB '$(OBJ);
+  print_install =              echo '  INSTALL  '$1'   to      $(DESTDIR_SQ)$2';
 endif
 
 do_fpic_compile =                                      \
@@ -268,7 +268,7 @@ TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
 TRACEEVENT-CFLAGS: force
        @FLAGS='$(TRACK_CFLAGS)'; \
            if test x"$$FLAGS" != x"`cat TRACEEVENT-CFLAGS 2>/dev/null`" ; then \
-               echo 1>&2 "    * new build flags or cross compiler"; \
+               echo 1>&2 "  FLAGS:   * new build flags or cross compiler"; \
                echo "$$FLAGS" >TRACEEVENT-CFLAGS; \
             fi
 
index d1c2a6a4cd32b125a981dca6779abfce1b50967d..8f450adaa9c27107d6ecc42bed6b5702833babe9 100644 (file)
@@ -305,6 +305,11 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
        return 0;
 }
 
+void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock)
+{
+       pevent->trace_clock = trace_clock;
+}
+
 struct func_map {
        unsigned long long              addr;
        char                            *func;
@@ -599,10 +604,11 @@ find_printk(struct pevent *pevent, unsigned long long addr)
  * This registers a string by the address it was stored in the kernel.
  * The @fmt passed in is duplicated.
  */
-int pevent_register_print_string(struct pevent *pevent, char *fmt,
+int pevent_register_print_string(struct pevent *pevent, const char *fmt,
                                 unsigned long long addr)
 {
        struct printk_list *item = malloc(sizeof(*item));
+       char *p;
 
        if (!item)
                return -1;
@@ -610,10 +616,21 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
        item->next = pevent->printklist;
        item->addr = addr;
 
+       /* Strip off quotes and '\n' from the end */
+       if (fmt[0] == '"')
+               fmt++;
        item->printk = strdup(fmt);
        if (!item->printk)
                goto out_free;
 
+       p = item->printk + strlen(item->printk) - 1;
+       if (*p == '"')
+               *p = 0;
+
+       p -= 2;
+       if (strcmp(p, "\\n") == 0)
+               *p = 0;
+
        pevent->printklist = item;
        pevent->printk_count++;
 
@@ -3488,6 +3505,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
        struct pevent *pevent = event->pevent;
        struct print_flag_sym *flag;
        struct format_field *field;
+       struct printk_map *printk;
        unsigned long long val, fval;
        unsigned long addr;
        char *str;
@@ -3523,7 +3541,12 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                if (!(field->flags & FIELD_IS_ARRAY) &&
                    field->size == pevent->long_size) {
                        addr = *(unsigned long *)(data + field->offset);
-                       trace_seq_printf(s, "%lx", addr);
+                       /* Check if it matches a print format */
+                       printk = find_printk(pevent, addr);
+                       if (printk)
+                               trace_seq_puts(s, printk->printk);
+                       else
+                               trace_seq_printf(s, "%lx", addr);
                        break;
                }
                str = malloc(len + 1);
@@ -3565,15 +3588,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                }
                break;
        case PRINT_HEX:
-               field = arg->hex.field->field.field;
-               if (!field) {
-                       str = arg->hex.field->field.name;
-                       field = pevent_find_any_field(event, str);
-                       if (!field)
-                               goto out_warning_field;
-                       arg->hex.field->field.field = field;
+               if (arg->hex.field->type == PRINT_DYNAMIC_ARRAY) {
+                       unsigned long offset;
+                       offset = pevent_read_number(pevent,
+                               data + arg->hex.field->dynarray.field->offset,
+                               arg->hex.field->dynarray.field->size);
+                       hex = data + (offset & 0xffff);
+               } else {
+                       field = arg->hex.field->field.field;
+                       if (!field) {
+                               str = arg->hex.field->field.name;
+                               field = pevent_find_any_field(event, str);
+                               if (!field)
+                                       goto out_warning_field;
+                               arg->hex.field->field.field = field;
+                       }
+                       hex = data + field->offset;
                }
-               hex = data + field->offset;
                len = eval_num_arg(data, size, event, arg->hex.size);
                for (i = 0; i < len; i++) {
                        if (i)
@@ -3771,8 +3802,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
        if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
                goto out_free;
 
-       /* skip the first "%pf : " */
-       for (ptr = fmt + 6, bptr = data + field->offset;
+       /* skip the first "%pf: " */
+       for (ptr = fmt + 5, bptr = data + field->offset;
             bptr < data + size && *ptr; ptr++) {
                int ls = 0;
 
@@ -3882,7 +3913,6 @@ get_bprint_format(void *data, int size __maybe_unused,
        struct format_field *field;
        struct printk_map *printk;
        char *format;
-       char *p;
 
        field = pevent->bprint_fmt_field;
 
@@ -3899,25 +3929,13 @@ get_bprint_format(void *data, int size __maybe_unused,
 
        printk = find_printk(pevent, addr);
        if (!printk) {
-               if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0)
+               if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0)
                        return NULL;
                return format;
        }
 
-       p = printk->printk;
-       /* Remove any quotes. */
-       if (*p == '"')
-               p++;
-       if (asprintf(&format, "%s : %s", "%pf", p) < 0)
+       if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0)
                return NULL;
-       /* remove ending quotes and new line since we will add one too */
-       p = format + strlen(format) - 1;
-       if (*p == '"')
-               *p = 0;
-
-       p -= 2;
-       if (strcmp(p, "\\n") == 0)
-               *p = 0;
 
        return format;
 }
@@ -3963,7 +3981,7 @@ static int is_printable_array(char *p, unsigned int len)
        unsigned int i;
 
        for (i = 0; i < len && p[i]; i++)
-               if (!isprint(p[i]))
+               if (!isprint(p[i]) && !isspace(p[i]))
                    return 0;
        return 1;
 }
@@ -4428,11 +4446,11 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event,
 {
        int print_pretty = 1;
 
-       if (event->pevent->print_raw)
+       if (event->pevent->print_raw || (event->flags & EVENT_FL_PRINTRAW))
                print_event_fields(s, record->data, record->size, event);
        else {
 
-               if (event->handler)
+               if (event->handler && !(event->flags & EVENT_FL_NOHANDLE))
                        print_pretty = event->handler(s, record, event,
                                                      event->context);
 
@@ -4443,8 +4461,21 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event,
        trace_seq_terminate(s);
 }
 
+static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
+{
+       if (!use_trace_clock)
+               return true;
+
+       if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global")
+           || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf"))
+               return true;
+
+       /* trace_clock is setting in tsc or counter mode */
+       return false;
+}
+
 void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
-                       struct pevent_record *record)
+                       struct pevent_record *record, bool use_trace_clock)
 {
        static const char *spaces = "                    "; /* 20 spaces */
        struct event_format *event;
@@ -4457,9 +4488,14 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
        int pid;
        int len;
        int p;
+       bool use_usec_format;
 
-       secs = record->ts / NSECS_PER_SEC;
-       nsecs = record->ts - secs * NSECS_PER_SEC;
+       use_usec_format = is_timestamp_in_us(pevent->trace_clock,
+                                                       use_trace_clock);
+       if (use_usec_format) {
+               secs = record->ts / NSECS_PER_SEC;
+               nsecs = record->ts - secs * NSECS_PER_SEC;
+       }
 
        if (record->size < 0) {
                do_warning("ug! negative record size %d", record->size);
@@ -4484,15 +4520,20 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
        } else
                trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
 
-       if (pevent->flags & PEVENT_NSEC_OUTPUT) {
-               usecs = nsecs;
-               p = 9;
-       } else {
-               usecs = (nsecs + 500) / NSECS_PER_USEC;
-               p = 6;
-       }
+       if (use_usec_format) {
+               if (pevent->flags & PEVENT_NSEC_OUTPUT) {
+                       usecs = nsecs;
+                       p = 9;
+               } else {
+                       usecs = (nsecs + 500) / NSECS_PER_USEC;
+                       p = 6;
+               }
 
-       trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name);
+               trace_seq_printf(s, " %5lu.%0*lu: %s: ",
+                                       secs, p, usecs, event->name);
+       } else
+               trace_seq_printf(s, " %12llu: %s: ",
+                                       record->ts, event->name);
 
        /* Space out the event names evenly. */
        len = strlen(event->name);
@@ -5326,6 +5367,48 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
        return -1;
 }
 
+/**
+ * pevent_print_func_field - print a field and a format for function pointers
+ * @s: The seq to print to
+ * @fmt: The printf format to print the field with.
+ * @event: the event that the field is for
+ * @name: The name of the field
+ * @record: The record with the field name.
+ * @err: print default error if failed.
+ *
+ * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
+ */
+int pevent_print_func_field(struct trace_seq *s, const char *fmt,
+                           struct event_format *event, const char *name,
+                           struct pevent_record *record, int err)
+{
+       struct format_field *field = pevent_find_field(event, name);
+       struct pevent *pevent = event->pevent;
+       unsigned long long val;
+       struct func_map *func;
+       char tmp[128];
+
+       if (!field)
+               goto failed;
+
+       if (pevent_read_number_field(field, record->data, &val))
+               goto failed;
+
+       func = find_func(pevent, val);
+
+       if (func)
+               snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
+       else
+               sprintf(tmp, "0x%08llx", val);
+
+       return trace_seq_printf(s, fmt, tmp);
+
+ failed:
+       if (err)
+               trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
+       return -1;
+}
+
 static void free_func_handle(struct pevent_function_handler *func)
 {
        struct pevent_func_params *params;
index c37b2026d04a991b5d70db230db6a56d67320b99..8d73d2594f65de39c4a0c9d35c976847e30ab0fe 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _PARSE_EVENTS_H
 #define _PARSE_EVENTS_H
 
+#include <stdbool.h>
 #include <stdarg.h>
 #include <regex.h>
 
@@ -307,6 +308,8 @@ enum {
        EVENT_FL_ISBPRINT       = 0x04,
        EVENT_FL_ISFUNCENT      = 0x10,
        EVENT_FL_ISFUNCRET      = 0x20,
+       EVENT_FL_NOHANDLE       = 0x40,
+       EVENT_FL_PRINTRAW       = 0x80,
 
        EVENT_FL_FAILED         = 0x80000000
 };
@@ -450,6 +453,8 @@ struct pevent {
 
        /* cache */
        struct event_format *last_event;
+
+       char *trace_clock;
 };
 
 static inline void pevent_set_flag(struct pevent *pevent, int flag)
@@ -527,14 +532,15 @@ enum trace_flag_type {
 };
 
 int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
+void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock);
 int pevent_register_function(struct pevent *pevent, char *name,
                             unsigned long long addr, char *mod);
-int pevent_register_print_string(struct pevent *pevent, char *fmt,
+int pevent_register_print_string(struct pevent *pevent, const char *fmt,
                                 unsigned long long addr);
 int pevent_pid_is_registered(struct pevent *pevent, int pid);
 
 void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
-                       struct pevent_record *record);
+                       struct pevent_record *record, bool use_trace_clock);
 
 int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
                             int long_size);
@@ -563,6 +569,10 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
                           struct event_format *event, const char *name,
                           struct pevent_record *record, int err);
 
+int pevent_print_func_field(struct trace_seq *s, const char *fmt,
+                          struct event_format *event, const char *name,
+                          struct pevent_record *record, int err);
+
 int pevent_register_event_handler(struct pevent *pevent, int id,
                                  const char *sys_name, const char *event_name,
                                  pevent_event_handler_func func, void *context);
index 8f8fbc227a468477147629548ea983ee238e6ea6..782d86e961b9fb79195407e7634bceae9d55f279 100644 (file)
@@ -13,6 +13,7 @@ perf*.html
 common-cmds.h
 perf.data
 perf.data.old
+output.svg
 perf-archive
 tags
 TAGS
index 5a37a7c84e69891fc753f205c50b81d22238499f..3ba1c0b09908b0e66a8a87f5307d7e9066a003ce 100644 (file)
@@ -145,16 +145,17 @@ endif
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifneq ($(V),1)
-       QUIET_ASCIIDOC  = @echo '   ' ASCIIDOC $@;
-       QUIET_XMLTO     = @echo '   ' XMLTO $@;
-       QUIET_DB2TEXI   = @echo '   ' DB2TEXI $@;
-       QUIET_MAKEINFO  = @echo '   ' MAKEINFO $@;
-       QUIET_DBLATEX   = @echo '   ' DBLATEX $@;
-       QUIET_XSLTPROC  = @echo '   ' XSLTPROC $@;
-       QUIET_GEN       = @echo '   ' GEN $@;
+       QUIET_ASCIIDOC  = @echo '  ASCIIDOC '$@;
+       QUIET_XMLTO     = @echo '  XMLTO    '$@;
+       QUIET_DB2TEXI   = @echo '  DB2TEXI  '$@;
+       QUIET_MAKEINFO  = @echo '  MAKEINFO '$@;
+       QUIET_DBLATEX   = @echo '  DBLATEX  '$@;
+       QUIET_XSLTPROC  = @echo '  XSLTPROC '$@;
+       QUIET_GEN       = @echo '  GEN      '$@;
        QUIET_STDERR    = 2> /dev/null
        QUIET_SUBDIR0   = +@subdir=
-       QUIET_SUBDIR1   = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
+       QUIET_SUBDIR1   = ;$(NO_SUBDIR) \
+                          echo '  SUBDIR   ' $$subdir; \
                          $(MAKE) $(PRINT_DIR) -C $$subdir
        export V
 endif
@@ -183,47 +184,43 @@ ifdef missing_tools
 endif
 
 do-install-man: man
-       $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
-#      $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir)
-#      $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
-       $(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir)
-#      $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir)
-#      $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
+       $(call QUIET_INSTALL, Documentation-man) \
+               $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir); \
+#              $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir); \
+#              $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir); \
+               $(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir); \
+#              $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir); \
+#              $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
 
 install-man: check-man-tools man
 
-try-install-man:
 ifdef missing_tools
-       $(warning Please install $(missing_tools) to have the man pages installed)
+  DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed)
 else
-       $(MAKE) do-install-man
+  DO_INSTALL_MAN = do-install-man
 endif
 
+try-install-man: $(DO_INSTALL_MAN)
+
 install-info: info
-       $(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
-       $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir)
+       $(call QUIET_INSTALL, Documentation-info) \
+               $(INSTALL) -d -m 755 $(DESTDIR)$(infodir); \
+               $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir); \
        if test -r $(DESTDIR)$(infodir)/dir; then \
-         $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perf.info ;\
-         $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perfman.info ;\
+               $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perf.info ;\
+               $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perfman.info ;\
        else \
          echo "No directory found in $(DESTDIR)$(infodir)" >&2 ; \
        fi
 
 install-pdf: pdf
-       $(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir)
-       $(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir)
+       $(call QUIET_INSTALL, Documentation-pdf) \
+               $(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir); \
+               $(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir)
 
 #install-html: html
 #      '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir)
 
-ifneq ($(MAKECMDGOALS),clean)
-ifneq ($(MAKECMDGOALS),tags)
-$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
-       $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) $(OUTPUT)PERF-VERSION-FILE
-
--include $(OUTPUT)PERF-VERSION-FILE
-endif
-endif
 
 #
 # Determine "include::" file references in asciidoc files.
@@ -253,15 +250,17 @@ $(OUTPUT)cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
        $(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \
        date >$@
 
+CLEAN_FILES =                                                                  \
+       $(MAN_XML) $(addsuffix +,$(MAN_XML))                                    \
+       $(MAN_HTML) $(addsuffix +,$(MAN_HTML))                                  \
+       $(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7)                         \
+       $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++                      \
+       $(OUTPUT)perf.info $(OUTPUT)perfman.info                                \
+       $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep         \
+       $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt          \
+       $(cmds_txt) $(OUTPUT)*.made
 clean:
-       $(RM) $(MAN_XML) $(addsuffix +,$(MAN_XML))
-       $(RM) $(MAN_HTML) $(addsuffix +,$(MAN_HTML))
-       $(RM) $(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7)
-       $(RM) $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++
-       $(RM) $(OUTPUT)perf.info $(OUTPUT)perfman.info
-       $(RM) $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep
-       $(RM) $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt
-       $(RM) $(cmds_txt) $(OUTPUT)*.made
+       $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES)
 
 $(MAN_HTML): $(OUTPUT)%.html : %.txt
        $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
@@ -342,5 +341,3 @@ $(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
 
 #quick-install-html:
 #      '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(HTML_REF) $(DESTDIR)$(htmldir)
-
-.PHONY: .FORCE-PERF-VERSION-FILE
index e9a8349a7172f7533fe970062c5936b4fd7df6fd..fd77d81ea748663284bc55db4db8fa5c20fc2a28 100644 (file)
@@ -21,6 +21,19 @@ OPTIONS
 -a::
 --add=::
         Add specified file to the cache.
+-k::
+--kcore::
+        Add specified kcore file to the cache. For the current host that is
+        /proc/kcore which requires root permissions to read. Be aware that
+        running 'perf buildid-cache' as root may update root's build-id cache
+        not the user's. Use the -v option to see where the file is created.
+        Note that the copied file contains only code sections not the whole core
+        image. Note also that files "kallsyms" and "modules" must also be in the
+        same directory and are also copied.  All 3 files are created with read
+        permissions for root only. kcore will not be added if there is already a
+        kcore in the cache (with the same build-id) that has the same modules at
+        the same addresses. Use the -v option to see if a copy of kcore is
+        actually made.
 -r::
 --remove=::
         Remove specified file from the cache.
index ac84db2d23342aaa269255e34c9ab3f5d70a3e4f..6a06cefe96427453ad3b21e1caf64889f5f9ea55 100644 (file)
@@ -109,7 +109,9 @@ STAT LIVE OPTIONS
 
 -m::
 --mmap-pages=::
-    Number of mmap data pages. Must be a power of two.
+    Number of mmap data pages (must be a power of two) or size
+    specification with appended unit character - B/K/M/G. The
+    size is rounded up to have nearest pages power of two value.
 
 -a::
 --all-cpus::
index c7f5f55634ac3fab974216404fdcb6348aec94d0..ab25be28c9dcaab31adb1822195afab571308910 100644 (file)
@@ -48,7 +48,7 @@ REPORT OPTIONS
 -k::
 --key=<value>::
         Sorting key. Possible values: acquired (default), contended,
-        wait_total, wait_max, wait_min.
+       avg_wait, wait_total, wait_max, wait_min.
 
 INFO OPTIONS
 ------------
index ca0d3d9f4bac831d377fd90f9a38be1021c486ec..052f7c4dc00c25a47dbe6355f0f762744ad5a79a 100644 (file)
@@ -87,7 +87,9 @@ OPTIONS
 
 -m::
 --mmap-pages=::
-       Number of mmap data pages. Must be a power of two.
+       Number of mmap data pages (must be a power of two) or size
+       specification with appended unit character - B/K/M/G. The
+       size is rounded up to have nearest pages power of two value.
 
 -g::
        Enables call-graph (stack chain/backtrace) recording.
@@ -178,6 +180,9 @@ following filters are defined:
         - u:  only when the branch target is at the user level
         - k: only when the branch target is in the kernel
         - hv: only when the target is at the hypervisor level
+       - in_tx: only when the target is in a hardware transaction
+       - no_tx: only when the target is not in a hardware transaction
+       - abort_tx: only when the target is a hardware transaction abort
 
 +
 The option requires at least one branch type among any, any_call, any_ret, ind_call.
@@ -188,12 +193,14 @@ is enabled for all the sampling events. The sampled branch type is the same for
 The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k
 Note that this feature may not be available on all processors.
 
--W::
 --weight::
 Enable weightened sampling. An additional weight is recorded per sample and can be
 displayed with the weight and local_weight sort keys.  This currently works for TSX
 abort events and some memory events in precise mode on modern Intel CPUs.
 
+--transaction::
+Record transaction flags for transaction related events.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-list[1]
index 2b8097ee39d83c194fd8393a0a1a3e2b67e40b65..10a2798712511a26616ea618a91130a6ed467345 100644 (file)
@@ -71,7 +71,11 @@ OPTIONS
        entries are displayed as "[other]".
        - cpu: cpu number the task ran at the time of sample
        - srcline: filename and line number executed at the time of sample.  The
-       DWARF debuggin info must be provided.
+       DWARF debugging info must be provided.
+       - weight: Event specific weight, e.g. memory latency or transaction
+       abort cost. This is the global weight.
+       - local_weight: Local weight version of the weight above.
+       - transaction: Transaction abort flags.
 
        By default, comm, dso and symbol keys are used.
        (i.e. --sort comm,dso,symbol)
@@ -85,6 +89,8 @@ OPTIONS
        - symbol_from: name of function branched from
        - symbol_to: name of function branched to
        - mispredict: "N" for predicted branch, "Y" for mispredicted branch
+       - in_tx: branch in TSX transaction
+       - abort: TSX transaction abort.
 
        And default sort keys are changed to comm, dso_from, symbol_from, dso_to
        and symbol_to, see '--branch-stack'.
@@ -135,6 +141,14 @@ OPTIONS
 
        Default: fractal,0.5,callee,function.
 
+--max-stack::
+       Set the stack depth limit when parsing the callchain, anything
+       beyond the specified depth will be ignored. This is a trade-off
+       between information loss and faster processing especially for
+       workloads that can have a very long callchain stack.
+
+       Default: 127
+
 -G::
 --inverted::
         alias for inverted caller based call graph.
index 73c9759005a354eb8e052e7425f981bd16fb8c2a..80c7da6732f294782d86c51df8e8ba9225bf1d04 100644 (file)
@@ -137,6 +137,11 @@ core number and the number of online logical processors on that physical process
 After starting the program, wait msecs before measuring. This is useful to
 filter out the startup phase of the program, which is often very different.
 
+-T::
+--transaction::
+
+Print statistics of transactional execution if supported.
+
 EXAMPLES
 --------
 
index 1632b0efc7577a730388154164be888c619ad934..3ff8bd4f0b4d94163d77231881b462e50bbd4e17 100644 (file)
@@ -8,7 +8,8 @@ perf-timechart - Tool to visualize total system behavior during a workload
 SYNOPSIS
 --------
 [verse]
-'perf timechart' {record}
+'perf timechart' record <command>
+'perf timechart' [<options>]
 
 DESCRIPTION
 -----------
@@ -41,6 +42,18 @@ OPTIONS
 --symfs=<directory>::
         Look for files with symbols relative to this directory.
 
+EXAMPLES
+--------
+
+$ perf timechart record git pull
+
+  [ perf record: Woken up 13 times to write data ]
+  [ perf record: Captured and wrote 4.253 MB perf.data (~185801 samples) ]
+
+$ perf timechart
+
+  Written 10.2 seconds of trace to output.svg.
+
 SEE ALSO
 --------
 linkperf:perf-record[1]
index 6a118e71d0032e15d3ce8d55b91c24a1be83e31f..7de01dd7968898c18e34f40914017ae549a3f618 100644 (file)
@@ -68,7 +68,9 @@ Default is to monitor all CPUS.
 
 -m <pages>::
 --mmap-pages=<pages>::
-       Number of mmapped data pages.
+       Number of mmap data pages (must be a power of two) or size
+       specification with appended unit character - B/K/M/G. The
+       size is rounded up to have nearest pages power of two value.
 
 -p <pid>::
 --pid=<pid>::
@@ -112,7 +114,8 @@ Default is to monitor all CPUS.
 
 -s::
 --sort::
-       Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight, local_weight.
+       Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight,
+       local_weight, abort, in_tx, transaction
 
 -n::
 --show-nr-samples::
@@ -147,6 +150,14 @@ Default is to monitor all CPUS.
        Setup and enable call-graph (stack chain/backtrace) recording,
        implies -G.
 
+--max-stack::
+       Set the stack depth limit when parsing the callchain, anything
+       beyond the specified depth will be ignored. This is a trade-off
+       between information loss and faster processing especially for
+       workloads that can have a very long callchain stack.
+
+       Default: 127
+
 --ignore-callees=<regex>::
         Ignore callees of the function(s) matching the given regex.
         This has the effect of collecting the callers of each such
index daccd2c0a48fe9c933cf50c870f68aa9bfe253a6..7b0497f95a75f0dafdf079742cec136dcff3ffdc 100644 (file)
@@ -9,6 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'perf trace'
+'perf trace record'
 
 DESCRIPTION
 -----------
@@ -16,9 +17,14 @@ This command will show the events associated with the target, initially
 syscalls, but other system events like pagefaults, task lifetime events,
 scheduling events, etc.
 
-Initially this is a live mode only tool, but eventually will work with
-perf.data files like the other tools, allowing a detached 'record' from
-analysis phases.
+This is a live mode tool in addition to working with perf.data files like
+the other perf tools. Files can be generated using the 'perf record' command
+but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*').
+Alernatively, the 'perf trace record' can be used as a shortcut to
+automatically include the raw_syscalls events when writing events to a file.
+
+The following options apply to perf trace; options to perf trace record are
+found in the perf record man page.
 
 OPTIONS
 -------
@@ -59,7 +65,9 @@ OPTIONS
 
 -m::
 --mmap-pages=::
-       Number of mmap data pages. Must be a power of two.
+       Number of mmap data pages (must be a power of two) or size
+       specification with appended unit character - B/K/M/G. The
+       size is rounded up to have nearest pages power of two value.
 
 -C::
 --cpu::
@@ -78,6 +86,21 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
 --input
        Process events from a given perf data file.
 
+-T
+--time
+       Print full timestamp rather time relative to first sample.
+
+--comm::
+        Show process COMM right beside its ID, on by default, disable with --no-comm.
+
+--summary::
+       Show a summary of syscalls by thread with min, max, and average times (in
+    msec) and relative stddev.
+
+--tool_stats::
+       Show tool stats such as number of times fd->pathname was discovered thru
+       hooking the open syscall return + vfs_getname or via reading /proc/pid/fd, etc.
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script[1]
index 64c043b7a43848f17a023dcf9479dbd77f96d7be..4835618a5608892054de87d497e45e644fdeb0da 100644 (file)
-include ../scripts/Makefile.include
-
-# The default target of this Makefile is...
-all:
-
-include config/utilities.mak
-
-# Define V to have a more verbose compile.
-#
-# Define O to save output files in a separate directory.
-#
-# Define ARCH as name of target architecture if you want cross-builds.
-#
-# Define CROSS_COMPILE as prefix name of compiler if you want cross-builds.
-#
-# Define NO_LIBPERL to disable perl script extension.
-#
-# Define NO_LIBPYTHON to disable python script extension.
-#
-# Define PYTHON to point to the python binary if the default
-# `python' is not correct; for example: PYTHON=python2
-#
-# Define PYTHON_CONFIG to point to the python-config binary if
-# the default `$(PYTHON)-config' is not correct.
 #
-# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
+# This is a simple wrapper Makefile that calls the main Makefile.perf
+# with a -j option to do parallel builds
 #
-# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
+# If you want to invoke the perf build in some non-standard way then
+# you can use the 'make -f Makefile.perf' method to invoke it.
 #
-# Define LDFLAGS=-static to build a static binary.
-#
-# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
-#
-# Define NO_DWARF if you do not want debug-info analysis feature at all.
-#
-# Define WERROR=0 to disable treating any warnings as errors.
-#
-# Define NO_NEWT if you do not want TUI support. (deprecated)
-#
-# Define NO_SLANG if you do not want TUI support.
-#
-# Define NO_GTK2 if you do not want GTK+ GUI support.
+
 #
-# Define NO_DEMANGLE if you do not want C++ symbol demangling.
+# Clear out the built-in rules GNU make defines by default (such as .o targets),
+# so that we pass through all targets to Makefile.perf:
 #
-# Define NO_LIBELF if you do not want libelf dependency (e.g. cross-builds)
+.SUFFIXES:
+
 #
-# Define NO_LIBUNWIND if you do not want libunwind dependency for dwarf
-# backtrace post unwind.
+# We don't want to pass along options like -j:
 #
-# Define NO_BACKTRACE if you do not want stack backtrace debug feature
+unexport MAKEFLAGS
+
 #
-# Define NO_LIBNUMA if you do not want numa perf benchmark
+# Do a parallel build with multiple jobs, based on the number of CPUs online
+# in this system: 'make -j8' on a 8-CPU system, etc.
 #
-# Define NO_LIBAUDIT if you do not want libaudit support
+# (To override it, run 'make JOBS=1' and similar.)
 #
-# Define NO_LIBBIONIC if you do not want bionic support
-
-ifeq ($(srctree),)
-srctree := $(patsubst %/,%,$(dir $(shell pwd)))
-srctree := $(patsubst %/,%,$(dir $(srctree)))
-#$(info Determined 'srctree' to be $(srctree))
-endif
-
-ifneq ($(objtree),)
-#$(info Determined 'objtree' to be $(objtree))
-endif
-
-ifneq ($(OUTPUT),)
-#$(info Determined 'OUTPUT' to be $(OUTPUT))
-endif
-
-$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
-       @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
-
-CC = $(CROSS_COMPILE)gcc
-AR = $(CROSS_COMPILE)ar
-
-RM      = rm -f
-MKDIR   = mkdir
-FIND    = find
-INSTALL = install
-FLEX    = flex
-BISON   = bison
-STRIP   = strip
-
-LK_DIR          = $(srctree)/tools/lib/lk/
-TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
-
-# include config/Makefile by default and rule out
-# non-config cases
-config := 1
-
-NON_CONFIG_TARGETS := clean TAGS tags cscope help
-
-ifdef MAKECMDGOALS
-ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
-  config := 0
-endif
+ifeq ($(JOBS),)
+  JOBS := $(shell grep -c ^processor /proc/cpuinfo 2>/dev/null)
+  ifeq ($(JOBS),)
+    JOBS := 1
+  endif
 endif
 
-ifeq ($(config),1)
-include config/Makefile
+#
+# Only pass canonical directory names as the output directory:
+#
+ifneq ($(O),)
+  FULL_O := $(shell readlink -f $(O) || echo $(O))
 endif
 
-export prefix bindir sharedir sysconfdir
-
-# sparse is architecture-neutral, which means that we need to tell it
-# explicitly what architecture to check for. Fix this up for yours..
-SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
-
-# Guard against environment variables
-BUILTIN_OBJS =
-LIB_H =
-LIB_OBJS =
-PYRF_OBJS =
-SCRIPT_SH =
-
-SCRIPT_SH += perf-archive.sh
-
-grep-libs = $(filter -l%,$(1))
-strip-libs = $(filter-out -l%,$(1))
-
-ifneq ($(OUTPUT),)
-  TE_PATH=$(OUTPUT)
-ifneq ($(subdir),)
-  LK_PATH=$(OUTPUT)/../lib/lk/
-else
-  LK_PATH=$(OUTPUT)
-endif
+#
+# Only accept the 'DEBUG' variable from the command line:
+#
+ifeq ("$(origin DEBUG)", "command line")
+  ifeq ($(DEBUG),)
+    override DEBUG = 0
+  else
+    SET_DEBUG = "DEBUG=$(DEBUG)"
+  endif
 else
-  TE_PATH=$(TRACE_EVENT_DIR)
-  LK_PATH=$(LK_DIR)
+  override DEBUG = 0
 endif
 
-LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
-export LIBTRACEEVENT
-
-LIBLK = $(LK_PATH)liblk.a
-export LIBLK
-
-# python extension build directories
-PYTHON_EXTBUILD     := $(OUTPUT)python_ext_build/
-PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
-PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/
-export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
+define print_msg
+  @printf '  BUILD:   Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n'
+endef
 
-python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
+define make
+  @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $(SET_DEBUG) $@
+endef
 
-PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
-PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
-
-$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
-       $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
-         --quiet build_ext; \
-       mkdir -p $(OUTPUT)python && \
-       cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
 #
-# No Perl scripts right now:
+# Needed if no target specified:
 #
-
-SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
+all:
+       $(print_msg)
+       $(make)
 
 #
-# Single 'perf' binary right now:
+# The clean target is not really parallel, don't print the jobs info:
 #
-PROGRAMS += $(OUTPUT)perf
-
-# what 'all' will build and 'install' will install, in perfexecdir
-ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
-
-# what 'all' will build but not install in perfexecdir
-OTHER_PROGRAMS = $(OUTPUT)perf
-
-# Set paths to tools early so that they can be used for version tests.
-ifndef SHELL_PATH
-  SHELL_PATH = /bin/sh
-endif
-ifndef PERL_PATH
-  PERL_PATH = /usr/bin/perl
-endif
-
-export PERL_PATH
-
-$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
-       $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
-
-$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
-       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
-
-$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
-       $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
-
-$(OUTPUT)util/pmu-bison.c: util/pmu.y
-       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
-
-$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
-$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
-
-LIB_FILE=$(OUTPUT)libperf.a
-
-LIB_H += ../../include/uapi/linux/perf_event.h
-LIB_H += ../../include/linux/rbtree.h
-LIB_H += ../../include/linux/list.h
-LIB_H += ../../include/uapi/linux/const.h
-LIB_H += ../../include/linux/hash.h
-LIB_H += ../../include/linux/stringify.h
-LIB_H += util/include/linux/bitmap.h
-LIB_H += util/include/linux/bitops.h
-LIB_H += util/include/linux/compiler.h
-LIB_H += util/include/linux/const.h
-LIB_H += util/include/linux/ctype.h
-LIB_H += util/include/linux/kernel.h
-LIB_H += util/include/linux/list.h
-LIB_H += util/include/linux/export.h
-LIB_H += util/include/linux/magic.h
-LIB_H += util/include/linux/poison.h
-LIB_H += util/include/linux/prefetch.h
-LIB_H += util/include/linux/rbtree.h
-LIB_H += util/include/linux/rbtree_augmented.h
-LIB_H += util/include/linux/string.h
-LIB_H += util/include/linux/types.h
-LIB_H += util/include/linux/linkage.h
-LIB_H += util/include/asm/asm-offsets.h
-LIB_H += util/include/asm/bug.h
-LIB_H += util/include/asm/byteorder.h
-LIB_H += util/include/asm/hweight.h
-LIB_H += util/include/asm/swab.h
-LIB_H += util/include/asm/system.h
-LIB_H += util/include/asm/uaccess.h
-LIB_H += util/include/dwarf-regs.h
-LIB_H += util/include/asm/dwarf2.h
-LIB_H += util/include/asm/cpufeature.h
-LIB_H += util/include/asm/unistd_32.h
-LIB_H += util/include/asm/unistd_64.h
-LIB_H += perf.h
-LIB_H += util/annotate.h
-LIB_H += util/cache.h
-LIB_H += util/callchain.h
-LIB_H += util/build-id.h
-LIB_H += util/debug.h
-LIB_H += util/sysfs.h
-LIB_H += util/pmu.h
-LIB_H += util/event.h
-LIB_H += util/evsel.h
-LIB_H += util/evlist.h
-LIB_H += util/exec_cmd.h
-LIB_H += util/types.h
-LIB_H += util/levenshtein.h
-LIB_H += util/machine.h
-LIB_H += util/map.h
-LIB_H += util/parse-options.h
-LIB_H += util/parse-events.h
-LIB_H += util/quote.h
-LIB_H += util/util.h
-LIB_H += util/xyarray.h
-LIB_H += util/header.h
-LIB_H += util/help.h
-LIB_H += util/session.h
-LIB_H += util/strbuf.h
-LIB_H += util/strlist.h
-LIB_H += util/strfilter.h
-LIB_H += util/svghelper.h
-LIB_H += util/tool.h
-LIB_H += util/run-command.h
-LIB_H += util/sigchain.h
-LIB_H += util/dso.h
-LIB_H += util/symbol.h
-LIB_H += util/color.h
-LIB_H += util/values.h
-LIB_H += util/sort.h
-LIB_H += util/hist.h
-LIB_H += util/thread.h
-LIB_H += util/thread_map.h
-LIB_H += util/trace-event.h
-LIB_H += util/probe-finder.h
-LIB_H += util/dwarf-aux.h
-LIB_H += util/probe-event.h
-LIB_H += util/pstack.h
-LIB_H += util/cpumap.h
-LIB_H += util/top.h
-LIB_H += $(ARCH_INCLUDE)
-LIB_H += util/cgroup.h
-LIB_H += $(LIB_INCLUDE)traceevent/event-parse.h
-LIB_H += util/target.h
-LIB_H += util/rblist.h
-LIB_H += util/intlist.h
-LIB_H += util/perf_regs.h
-LIB_H += util/unwind.h
-LIB_H += util/vdso.h
-LIB_H += ui/helpline.h
-LIB_H += ui/progress.h
-LIB_H += ui/util.h
-LIB_H += ui/ui.h
-
-LIB_OBJS += $(OUTPUT)util/abspath.o
-LIB_OBJS += $(OUTPUT)util/alias.o
-LIB_OBJS += $(OUTPUT)util/annotate.o
-LIB_OBJS += $(OUTPUT)util/build-id.o
-LIB_OBJS += $(OUTPUT)util/config.o
-LIB_OBJS += $(OUTPUT)util/ctype.o
-LIB_OBJS += $(OUTPUT)util/sysfs.o
-LIB_OBJS += $(OUTPUT)util/pmu.o
-LIB_OBJS += $(OUTPUT)util/environment.o
-LIB_OBJS += $(OUTPUT)util/event.o
-LIB_OBJS += $(OUTPUT)util/evlist.o
-LIB_OBJS += $(OUTPUT)util/evsel.o
-LIB_OBJS += $(OUTPUT)util/exec_cmd.o
-LIB_OBJS += $(OUTPUT)util/help.o
-LIB_OBJS += $(OUTPUT)util/levenshtein.o
-LIB_OBJS += $(OUTPUT)util/parse-options.o
-LIB_OBJS += $(OUTPUT)util/parse-events.o
-LIB_OBJS += $(OUTPUT)util/path.o
-LIB_OBJS += $(OUTPUT)util/rbtree.o
-LIB_OBJS += $(OUTPUT)util/bitmap.o
-LIB_OBJS += $(OUTPUT)util/hweight.o
-LIB_OBJS += $(OUTPUT)util/run-command.o
-LIB_OBJS += $(OUTPUT)util/quote.o
-LIB_OBJS += $(OUTPUT)util/strbuf.o
-LIB_OBJS += $(OUTPUT)util/string.o
-LIB_OBJS += $(OUTPUT)util/strlist.o
-LIB_OBJS += $(OUTPUT)util/strfilter.o
-LIB_OBJS += $(OUTPUT)util/top.o
-LIB_OBJS += $(OUTPUT)util/usage.o
-LIB_OBJS += $(OUTPUT)util/wrapper.o
-LIB_OBJS += $(OUTPUT)util/sigchain.o
-LIB_OBJS += $(OUTPUT)util/dso.o
-LIB_OBJS += $(OUTPUT)util/symbol.o
-LIB_OBJS += $(OUTPUT)util/symbol-elf.o
-LIB_OBJS += $(OUTPUT)util/color.o
-LIB_OBJS += $(OUTPUT)util/pager.o
-LIB_OBJS += $(OUTPUT)util/header.o
-LIB_OBJS += $(OUTPUT)util/callchain.o
-LIB_OBJS += $(OUTPUT)util/values.o
-LIB_OBJS += $(OUTPUT)util/debug.o
-LIB_OBJS += $(OUTPUT)util/machine.o
-LIB_OBJS += $(OUTPUT)util/map.o
-LIB_OBJS += $(OUTPUT)util/pstack.o
-LIB_OBJS += $(OUTPUT)util/session.o
-LIB_OBJS += $(OUTPUT)util/thread.o
-LIB_OBJS += $(OUTPUT)util/thread_map.o
-LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
-LIB_OBJS += $(OUTPUT)util/parse-events-flex.o
-LIB_OBJS += $(OUTPUT)util/parse-events-bison.o
-LIB_OBJS += $(OUTPUT)util/pmu-flex.o
-LIB_OBJS += $(OUTPUT)util/pmu-bison.o
-LIB_OBJS += $(OUTPUT)util/trace-event-read.o
-LIB_OBJS += $(OUTPUT)util/trace-event-info.o
-LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
-LIB_OBJS += $(OUTPUT)util/svghelper.o
-LIB_OBJS += $(OUTPUT)util/sort.o
-LIB_OBJS += $(OUTPUT)util/hist.o
-LIB_OBJS += $(OUTPUT)util/probe-event.o
-LIB_OBJS += $(OUTPUT)util/util.o
-LIB_OBJS += $(OUTPUT)util/xyarray.o
-LIB_OBJS += $(OUTPUT)util/cpumap.o
-LIB_OBJS += $(OUTPUT)util/cgroup.o
-LIB_OBJS += $(OUTPUT)util/target.o
-LIB_OBJS += $(OUTPUT)util/rblist.o
-LIB_OBJS += $(OUTPUT)util/intlist.o
-LIB_OBJS += $(OUTPUT)util/vdso.o
-LIB_OBJS += $(OUTPUT)util/stat.o
-LIB_OBJS += $(OUTPUT)util/record.o
-
-LIB_OBJS += $(OUTPUT)ui/setup.o
-LIB_OBJS += $(OUTPUT)ui/helpline.o
-LIB_OBJS += $(OUTPUT)ui/progress.o
-LIB_OBJS += $(OUTPUT)ui/util.o
-LIB_OBJS += $(OUTPUT)ui/hist.o
-LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
-
-LIB_OBJS += $(OUTPUT)arch/common.o
-
-LIB_OBJS += $(OUTPUT)tests/parse-events.o
-LIB_OBJS += $(OUTPUT)tests/dso-data.o
-LIB_OBJS += $(OUTPUT)tests/attr.o
-LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o
-LIB_OBJS += $(OUTPUT)tests/open-syscall.o
-LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
-LIB_OBJS += $(OUTPUT)tests/open-syscall-tp-fields.o
-LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
-LIB_OBJS += $(OUTPUT)tests/perf-record.o
-LIB_OBJS += $(OUTPUT)tests/rdpmc.o
-LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o
-LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o
-LIB_OBJS += $(OUTPUT)tests/pmu.o
-LIB_OBJS += $(OUTPUT)tests/hists_link.o
-LIB_OBJS += $(OUTPUT)tests/python-use.o
-LIB_OBJS += $(OUTPUT)tests/bp_signal.o
-LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
-LIB_OBJS += $(OUTPUT)tests/task-exit.o
-LIB_OBJS += $(OUTPUT)tests/sw-clock.o
-ifeq ($(ARCH),x86)
-LIB_OBJS += $(OUTPUT)tests/perf-time-to-tsc.o
-endif
-LIB_OBJS += $(OUTPUT)tests/code-reading.o
-LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
-LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
-
-BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
-BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
-# Benchmark modules
-BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
-BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
-ifeq ($(RAW_ARCH),x86_64)
-BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
-BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o
-endif
-BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
-BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o
-
-BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
-BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
-BUILTIN_OBJS += $(OUTPUT)builtin-help.o
-BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
-BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
-BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
-BUILTIN_OBJS += $(OUTPUT)builtin-list.o
-BUILTIN_OBJS += $(OUTPUT)builtin-record.o
-BUILTIN_OBJS += $(OUTPUT)builtin-report.o
-BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
-BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
-BUILTIN_OBJS += $(OUTPUT)builtin-top.o
-BUILTIN_OBJS += $(OUTPUT)builtin-script.o
-BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
-BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
-BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
-BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
-BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
-BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o
-BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
-
-PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
-
-# We choose to avoid "if .. else if .. else .. endif endif"
-# because maintaining the nesting to match is a pain.  If
-# we had "elif" things would have been much nicer...
-
--include arch/$(ARCH)/Makefile
-
-ifneq ($(OUTPUT),)
-  CFLAGS += -I$(OUTPUT)
-endif
-
-ifdef NO_LIBELF
-EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
-
-# Remove ELF/DWARF dependent codes
-LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS))
-LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
-LIB_OBJS := $(filter-out $(OUTPUT)util/probe-event.o,$(LIB_OBJS))
-LIB_OBJS := $(filter-out $(OUTPUT)util/probe-finder.o,$(LIB_OBJS))
-
-BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
-
-# Use minimal symbol handling
-LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
-
-else # NO_LIBELF
-ifndef NO_DWARF
-  LIB_OBJS += $(OUTPUT)util/probe-finder.o
-  LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
-endif # NO_DWARF
-endif # NO_LIBELF
-
-ifndef NO_LIBUNWIND
-  LIB_OBJS += $(OUTPUT)util/unwind.o
-endif
-LIB_OBJS += $(OUTPUT)tests/keep-tracking.o
-
-ifndef NO_LIBAUDIT
-  BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
-endif
-
-ifndef NO_SLANG
-  LIB_OBJS += $(OUTPUT)ui/browser.o
-  LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
-  LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
-  LIB_OBJS += $(OUTPUT)ui/browsers/map.o
-  LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
-  LIB_OBJS += $(OUTPUT)ui/tui/setup.o
-  LIB_OBJS += $(OUTPUT)ui/tui/util.o
-  LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
-  LIB_OBJS += $(OUTPUT)ui/tui/progress.o
-  LIB_H += ui/browser.h
-  LIB_H += ui/browsers/map.h
-  LIB_H += ui/keysyms.h
-  LIB_H += ui/libslang.h
-endif
-
-ifndef NO_GTK2
-  LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/util.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
-endif
-
-ifndef NO_LIBPERL
-  LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
-  LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
-endif
-
-ifndef NO_LIBPYTHON
-  LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
-  LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
-endif
-
-ifeq ($(NO_PERF_REGS),0)
-  ifeq ($(ARCH),x86)
-    LIB_H += arch/x86/include/perf_regs.h
-  endif
-endif
-
-ifndef NO_LIBNUMA
-  BUILTIN_OBJS += $(OUTPUT)bench/numa.o
-endif
-
-ifdef ASCIIDOC8
-  export ASCIIDOC8
-endif
-
-LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
-
-export INSTALL SHELL_PATH
-
-### Build rules
-
-SHELL = $(SHELL_PATH)
-
-all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
-
-please_set_SHELL_PATH_to_a_more_modern_shell:
-       @$$(:)
-
-shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
-
-strip: $(PROGRAMS) $(OUTPUT)perf
-       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf
-
-$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
-               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
-               $(CFLAGS) -c $(filter %.c,$^) -o $@
-
-$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
-       $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
-               $(BUILTIN_OBJS) $(LIBS) -o $@
-
-$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
-               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
-               '-DPERF_MAN_PATH="$(mandir_SQ)"' \
-               '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
-
-$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
-               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
-               '-DPERF_MAN_PATH="$(mandir_SQ)"' \
-               '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
-
-$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
-
-$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
-       $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
-
-$(SCRIPTS) : % : %.sh
-       $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
-
-# These can record PERF_VERSION
-$(OUTPUT)perf.o perf.spec \
-       $(SCRIPTS) \
-       : $(OUTPUT)PERF-VERSION-FILE
-
-.SUFFIXES:
-.SUFFIXES: .o .c .S .s
-
-# These two need to be here so that when O= is not used they take precedence
-# over the general rule for .o
-
-$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $<
-
-$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
-
-$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
-$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
-$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
-$(OUTPUT)%.o: %.S
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
-$(OUTPUT)%.s: %.S
-       $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
-
-$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
-               '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
-               '-DPREFIX="$(prefix_SQ)"' \
-               $<
-
-$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
-               '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
-               $<
-
-$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
-               -DPYTHONPATH='"$(OUTPUT)python"' \
-               -DPYTHON='"$(PYTHON_WORD)"' \
-               $<
-
-$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-
-$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
-
-$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+clean:
+       $(make)
 
-$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
-
-$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
-
-$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
-
-$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-
-$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
-
-$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $<
-
-$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default $<
-
-$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
-
-$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
-
-$(OUTPUT)perf-%: %.o $(PERFLIBS)
-       $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
-$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
-
-# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
-# we depend the various files onto their directories.
-DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
-$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
-# In the second step, we make a rule to actually create these directories
-$(sort $(dir $(DIRECTORY_DEPS))):
-       $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
-
-$(LIB_FILE): $(LIB_OBJS)
-       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
-
-# libtraceevent.a
-$(LIBTRACEEVENT):
-       $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a
-
-$(LIBTRACEEVENT)-clean:
-       $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
-
-# if subdir is set, we've been called from above so target has been built
-# already
-$(LIBLK):
-ifeq ($(subdir),)
-       $(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a
-endif
-
-$(LIBLK)-clean:
-ifeq ($(subdir),)
-       $(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
-endif
-
-help:
-       @echo 'Perf make targets:'
-       @echo '  doc            - make *all* documentation (see below)'
-       @echo '  man            - make manpage documentation (access with man <foo>)'
-       @echo '  html           - make html documentation'
-       @echo '  info           - make GNU info documentation (access with info <foo>)'
-       @echo '  pdf            - make pdf documentation'
-       @echo '  TAGS           - use etags to make tag information for source browsing'
-       @echo '  tags           - use ctags to make tag information for source browsing'
-       @echo '  cscope - use cscope to make interactive browsing database'
-       @echo ''
-       @echo 'Perf install targets:'
-       @echo '  NOTE: documentation build requires asciidoc, xmlto packages to be installed'
-       @echo '  HINT: use "make prefix=<path> <install target>" to install to a particular'
-       @echo '        path like make prefix=/usr/local install install-doc'
-       @echo '  install        - install compiled binaries'
-       @echo '  install-doc    - install *all* documentation'
-       @echo '  install-man    - install manpage documentation'
-       @echo '  install-html   - install html documentation'
-       @echo '  install-info   - install GNU info documentation'
-       @echo '  install-pdf    - install pdf documentation'
-       @echo ''
-       @echo '  quick-install-doc      - alias for quick-install-man'
-       @echo '  quick-install-man      - install the documentation quickly'
-       @echo '  quick-install-html     - install the html documentation quickly'
-       @echo ''
-       @echo 'Perf maintainer targets:'
-       @echo '  clean                  - clean all binary objects and build output'
-
-
-DOC_TARGETS := doc man html info pdf
-
-INSTALL_DOC_TARGETS := $(patsubst %,install-%,$(DOC_TARGETS)) try-install-man
-INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
-
-# 'make doc' should call 'make -C Documentation all'
-$(DOC_TARGETS):
-       $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
-
-TAGS:
-       $(RM) TAGS
-       $(FIND) . -name '*.[hcS]' -print | xargs etags -a
-
-tags:
-       $(RM) tags
-       $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
-
-cscope:
-       $(RM) cscope*
-       $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
-
-### Detect prefix changes
-TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
-             $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
-
-$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
-       @FLAGS='$(TRACK_CFLAGS)'; \
-           if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
-               echo 1>&2 "    * new build flags or prefix"; \
-               echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
-            fi
-
-### Testing rules
-
-# GNU make supports exporting all variables by "export" without parameters.
-# However, the environment gets quite big, and some programs have problems
-# with that.
-
-check: $(OUTPUT)common-cmds.h
-       if sparse; \
-       then \
-               for i in *.c */*.c; \
-               do \
-                       sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
-               done; \
-       else \
-               exit 1; \
-       fi
-
-### Installation rules
-
-install-bin: all
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
-       $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-       $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-ifndef NO_LIBPERL
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
-       $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
-       $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
-       $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
-endif
-ifndef NO_LIBPYTHON
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
-       $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
-       $(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
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'
-       $(INSTALL) bash_completion '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'
-       $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'
-       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
-       $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
-
-install: install-bin try-install-man
-
-install-python_ext:
-       $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
-
-# 'make install-doc' should call 'make -C Documentation install'
-$(INSTALL_DOC_TARGETS):
-       $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=)
-
-### Cleaning rules
-
-clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean
-       $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
-       $(RM) $(ALL_PROGRAMS) perf
-       $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
-       $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
-       $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
-       $(RM) $(OUTPUT)util/*-bison*
-       $(RM) $(OUTPUT)util/*-flex*
-       $(python-clean)
-
-.PHONY: all install clean strip $(LIBTRACEEVENT) $(LIBLK)
-.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
-.PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
+#
+# All other targets get passed through:
+#
+%:
+       $(print_msg)
+       $(make)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
new file mode 100644 (file)
index 0000000..7fc8f17
--- /dev/null
@@ -0,0 +1,892 @@
+include ../scripts/Makefile.include
+
+# The default target of this Makefile is...
+all:
+
+include config/utilities.mak
+
+# Define V to have a more verbose compile.
+#
+# Define O to save output files in a separate directory.
+#
+# Define ARCH as name of target architecture if you want cross-builds.
+#
+# Define CROSS_COMPILE as prefix name of compiler if you want cross-builds.
+#
+# Define NO_LIBPERL to disable perl script extension.
+#
+# Define NO_LIBPYTHON to disable python script extension.
+#
+# Define PYTHON to point to the python binary if the default
+# `python' is not correct; for example: PYTHON=python2
+#
+# Define PYTHON_CONFIG to point to the python-config binary if
+# the default `$(PYTHON)-config' is not correct.
+#
+# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
+#
+# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
+#
+# Define LDFLAGS=-static to build a static binary.
+#
+# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
+#
+# Define NO_DWARF if you do not want debug-info analysis feature at all.
+#
+# Define WERROR=0 to disable treating any warnings as errors.
+#
+# Define NO_NEWT if you do not want TUI support. (deprecated)
+#
+# Define NO_SLANG if you do not want TUI support.
+#
+# Define NO_GTK2 if you do not want GTK+ GUI support.
+#
+# Define NO_DEMANGLE if you do not want C++ symbol demangling.
+#
+# Define NO_LIBELF if you do not want libelf dependency (e.g. cross-builds)
+#
+# Define NO_LIBUNWIND if you do not want libunwind dependency for dwarf
+# backtrace post unwind.
+#
+# Define NO_BACKTRACE if you do not want stack backtrace debug feature
+#
+# Define NO_LIBNUMA if you do not want numa perf benchmark
+#
+# Define NO_LIBAUDIT if you do not want libaudit support
+#
+# Define NO_LIBBIONIC if you do not want bionic support
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+#$(info Determined 'srctree' to be $(srctree))
+endif
+
+ifneq ($(objtree),)
+#$(info Determined 'objtree' to be $(objtree))
+endif
+
+ifneq ($(OUTPUT),)
+#$(info Determined 'OUTPUT' to be $(OUTPUT))
+endif
+
+$(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD
+       @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
+       @touch $(OUTPUT)PERF-VERSION-FILE
+
+CC = $(CROSS_COMPILE)gcc
+AR = $(CROSS_COMPILE)ar
+
+RM      = rm -f
+LN      = ln -f
+MKDIR   = mkdir
+FIND    = find
+INSTALL = install
+FLEX    = flex
+BISON   = bison
+STRIP   = strip
+
+LK_DIR          = $(srctree)/tools/lib/lk/
+TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
+
+# include config/Makefile by default and rule out
+# non-config cases
+config := 1
+
+NON_CONFIG_TARGETS := clean TAGS tags cscope help
+
+ifdef MAKECMDGOALS
+ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
+  config := 0
+endif
+endif
+
+ifeq ($(config),1)
+include config/Makefile
+endif
+
+export prefix bindir sharedir sysconfdir
+
+# sparse is architecture-neutral, which means that we need to tell it
+# explicitly what architecture to check for. Fix this up for yours..
+SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
+
+# Guard against environment variables
+BUILTIN_OBJS =
+LIB_H =
+LIB_OBJS =
+GTK_OBJS =
+PYRF_OBJS =
+SCRIPT_SH =
+
+SCRIPT_SH += perf-archive.sh
+
+grep-libs = $(filter -l%,$(1))
+strip-libs = $(filter-out -l%,$(1))
+
+ifneq ($(OUTPUT),)
+  TE_PATH=$(OUTPUT)
+ifneq ($(subdir),)
+  LK_PATH=$(OUTPUT)/../lib/lk/
+else
+  LK_PATH=$(OUTPUT)
+endif
+else
+  TE_PATH=$(TRACE_EVENT_DIR)
+  LK_PATH=$(LK_DIR)
+endif
+
+LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
+export LIBTRACEEVENT
+
+LIBLK = $(LK_PATH)liblk.a
+export LIBLK
+
+# python extension build directories
+PYTHON_EXTBUILD     := $(OUTPUT)python_ext_build/
+PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
+PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/
+export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
+
+python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
+
+PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
+PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
+
+$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
+       $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
+         --quiet build_ext; \
+       mkdir -p $(OUTPUT)python && \
+       cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
+#
+# No Perl scripts right now:
+#
+
+SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
+
+#
+# Single 'perf' binary right now:
+#
+PROGRAMS += $(OUTPUT)perf
+
+# what 'all' will build and 'install' will install, in perfexecdir
+ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
+
+# what 'all' will build but not install in perfexecdir
+OTHER_PROGRAMS = $(OUTPUT)perf
+
+# Set paths to tools early so that they can be used for version tests.
+ifndef SHELL_PATH
+  SHELL_PATH = /bin/sh
+endif
+ifndef PERL_PATH
+  PERL_PATH = /usr/bin/perl
+endif
+
+export PERL_PATH
+
+$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
+       $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
+
+$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
+       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
+
+$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
+       $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
+
+$(OUTPUT)util/pmu-bison.c: util/pmu.y
+       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
+
+$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
+
+LIB_FILE=$(OUTPUT)libperf.a
+
+LIB_H += ../../include/uapi/linux/perf_event.h
+LIB_H += ../../include/linux/rbtree.h
+LIB_H += ../../include/linux/list.h
+LIB_H += ../../include/uapi/linux/const.h
+LIB_H += ../../include/linux/hash.h
+LIB_H += ../../include/linux/stringify.h
+LIB_H += util/include/linux/bitmap.h
+LIB_H += util/include/linux/bitops.h
+LIB_H += util/include/linux/compiler.h
+LIB_H += util/include/linux/const.h
+LIB_H += util/include/linux/ctype.h
+LIB_H += util/include/linux/kernel.h
+LIB_H += util/include/linux/list.h
+LIB_H += util/include/linux/export.h
+LIB_H += util/include/linux/magic.h
+LIB_H += util/include/linux/poison.h
+LIB_H += util/include/linux/prefetch.h
+LIB_H += util/include/linux/rbtree.h
+LIB_H += util/include/linux/rbtree_augmented.h
+LIB_H += util/include/linux/string.h
+LIB_H += util/include/linux/types.h
+LIB_H += util/include/linux/linkage.h
+LIB_H += util/include/asm/asm-offsets.h
+LIB_H += util/include/asm/bug.h
+LIB_H += util/include/asm/byteorder.h
+LIB_H += util/include/asm/hweight.h
+LIB_H += util/include/asm/swab.h
+LIB_H += util/include/asm/system.h
+LIB_H += util/include/asm/uaccess.h
+LIB_H += util/include/dwarf-regs.h
+LIB_H += util/include/asm/dwarf2.h
+LIB_H += util/include/asm/cpufeature.h
+LIB_H += util/include/asm/unistd_32.h
+LIB_H += util/include/asm/unistd_64.h
+LIB_H += perf.h
+LIB_H += util/annotate.h
+LIB_H += util/cache.h
+LIB_H += util/callchain.h
+LIB_H += util/build-id.h
+LIB_H += util/debug.h
+LIB_H += util/fs.h
+LIB_H += util/pmu.h
+LIB_H += util/event.h
+LIB_H += util/evsel.h
+LIB_H += util/evlist.h
+LIB_H += util/exec_cmd.h
+LIB_H += util/types.h
+LIB_H += util/levenshtein.h
+LIB_H += util/machine.h
+LIB_H += util/map.h
+LIB_H += util/parse-options.h
+LIB_H += util/parse-events.h
+LIB_H += util/quote.h
+LIB_H += util/util.h
+LIB_H += util/xyarray.h
+LIB_H += util/header.h
+LIB_H += util/help.h
+LIB_H += util/session.h
+LIB_H += util/strbuf.h
+LIB_H += util/strlist.h
+LIB_H += util/strfilter.h
+LIB_H += util/svghelper.h
+LIB_H += util/tool.h
+LIB_H += util/run-command.h
+LIB_H += util/sigchain.h
+LIB_H += util/dso.h
+LIB_H += util/symbol.h
+LIB_H += util/color.h
+LIB_H += util/values.h
+LIB_H += util/sort.h
+LIB_H += util/hist.h
+LIB_H += util/comm.h
+LIB_H += util/thread.h
+LIB_H += util/thread_map.h
+LIB_H += util/trace-event.h
+LIB_H += util/probe-finder.h
+LIB_H += util/dwarf-aux.h
+LIB_H += util/probe-event.h
+LIB_H += util/pstack.h
+LIB_H += util/cpumap.h
+LIB_H += util/top.h
+LIB_H += $(ARCH_INCLUDE)
+LIB_H += util/cgroup.h
+LIB_H += $(LIB_INCLUDE)traceevent/event-parse.h
+LIB_H += util/target.h
+LIB_H += util/rblist.h
+LIB_H += util/intlist.h
+LIB_H += util/perf_regs.h
+LIB_H += util/unwind.h
+LIB_H += util/vdso.h
+LIB_H += ui/helpline.h
+LIB_H += ui/progress.h
+LIB_H += ui/util.h
+LIB_H += ui/ui.h
+LIB_H += util/data.h
+
+LIB_OBJS += $(OUTPUT)util/abspath.o
+LIB_OBJS += $(OUTPUT)util/alias.o
+LIB_OBJS += $(OUTPUT)util/annotate.o
+LIB_OBJS += $(OUTPUT)util/build-id.o
+LIB_OBJS += $(OUTPUT)util/config.o
+LIB_OBJS += $(OUTPUT)util/ctype.o
+LIB_OBJS += $(OUTPUT)util/fs.o
+LIB_OBJS += $(OUTPUT)util/pmu.o
+LIB_OBJS += $(OUTPUT)util/environment.o
+LIB_OBJS += $(OUTPUT)util/event.o
+LIB_OBJS += $(OUTPUT)util/evlist.o
+LIB_OBJS += $(OUTPUT)util/evsel.o
+LIB_OBJS += $(OUTPUT)util/exec_cmd.o
+LIB_OBJS += $(OUTPUT)util/help.o
+LIB_OBJS += $(OUTPUT)util/levenshtein.o
+LIB_OBJS += $(OUTPUT)util/parse-options.o
+LIB_OBJS += $(OUTPUT)util/parse-events.o
+LIB_OBJS += $(OUTPUT)util/path.o
+LIB_OBJS += $(OUTPUT)util/rbtree.o
+LIB_OBJS += $(OUTPUT)util/bitmap.o
+LIB_OBJS += $(OUTPUT)util/hweight.o
+LIB_OBJS += $(OUTPUT)util/run-command.o
+LIB_OBJS += $(OUTPUT)util/quote.o
+LIB_OBJS += $(OUTPUT)util/strbuf.o
+LIB_OBJS += $(OUTPUT)util/string.o
+LIB_OBJS += $(OUTPUT)util/strlist.o
+LIB_OBJS += $(OUTPUT)util/strfilter.o
+LIB_OBJS += $(OUTPUT)util/top.o
+LIB_OBJS += $(OUTPUT)util/usage.o
+LIB_OBJS += $(OUTPUT)util/wrapper.o
+LIB_OBJS += $(OUTPUT)util/sigchain.o
+LIB_OBJS += $(OUTPUT)util/dso.o
+LIB_OBJS += $(OUTPUT)util/symbol.o
+LIB_OBJS += $(OUTPUT)util/symbol-elf.o
+LIB_OBJS += $(OUTPUT)util/color.o
+LIB_OBJS += $(OUTPUT)util/pager.o
+LIB_OBJS += $(OUTPUT)util/header.o
+LIB_OBJS += $(OUTPUT)util/callchain.o
+LIB_OBJS += $(OUTPUT)util/values.o
+LIB_OBJS += $(OUTPUT)util/debug.o
+LIB_OBJS += $(OUTPUT)util/machine.o
+LIB_OBJS += $(OUTPUT)util/map.o
+LIB_OBJS += $(OUTPUT)util/pstack.o
+LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/comm.o
+LIB_OBJS += $(OUTPUT)util/thread.o
+LIB_OBJS += $(OUTPUT)util/thread_map.o
+LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
+LIB_OBJS += $(OUTPUT)util/parse-events-flex.o
+LIB_OBJS += $(OUTPUT)util/parse-events-bison.o
+LIB_OBJS += $(OUTPUT)util/pmu-flex.o
+LIB_OBJS += $(OUTPUT)util/pmu-bison.o
+LIB_OBJS += $(OUTPUT)util/trace-event-read.o
+LIB_OBJS += $(OUTPUT)util/trace-event-info.o
+LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
+LIB_OBJS += $(OUTPUT)util/svghelper.o
+LIB_OBJS += $(OUTPUT)util/sort.o
+LIB_OBJS += $(OUTPUT)util/hist.o
+LIB_OBJS += $(OUTPUT)util/probe-event.o
+LIB_OBJS += $(OUTPUT)util/util.o
+LIB_OBJS += $(OUTPUT)util/xyarray.o
+LIB_OBJS += $(OUTPUT)util/cpumap.o
+LIB_OBJS += $(OUTPUT)util/cgroup.o
+LIB_OBJS += $(OUTPUT)util/target.o
+LIB_OBJS += $(OUTPUT)util/rblist.o
+LIB_OBJS += $(OUTPUT)util/intlist.o
+LIB_OBJS += $(OUTPUT)util/vdso.o
+LIB_OBJS += $(OUTPUT)util/stat.o
+LIB_OBJS += $(OUTPUT)util/record.o
+LIB_OBJS += $(OUTPUT)util/srcline.o
+LIB_OBJS += $(OUTPUT)util/data.o
+
+LIB_OBJS += $(OUTPUT)ui/setup.o
+LIB_OBJS += $(OUTPUT)ui/helpline.o
+LIB_OBJS += $(OUTPUT)ui/progress.o
+LIB_OBJS += $(OUTPUT)ui/util.o
+LIB_OBJS += $(OUTPUT)ui/hist.o
+LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
+
+LIB_OBJS += $(OUTPUT)arch/common.o
+
+LIB_OBJS += $(OUTPUT)tests/parse-events.o
+LIB_OBJS += $(OUTPUT)tests/dso-data.o
+LIB_OBJS += $(OUTPUT)tests/attr.o
+LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o
+LIB_OBJS += $(OUTPUT)tests/open-syscall.o
+LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
+LIB_OBJS += $(OUTPUT)tests/open-syscall-tp-fields.o
+LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
+LIB_OBJS += $(OUTPUT)tests/perf-record.o
+LIB_OBJS += $(OUTPUT)tests/rdpmc.o
+LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o
+LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o
+LIB_OBJS += $(OUTPUT)tests/pmu.o
+LIB_OBJS += $(OUTPUT)tests/hists_link.o
+LIB_OBJS += $(OUTPUT)tests/python-use.o
+LIB_OBJS += $(OUTPUT)tests/bp_signal.o
+LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
+LIB_OBJS += $(OUTPUT)tests/task-exit.o
+LIB_OBJS += $(OUTPUT)tests/sw-clock.o
+ifeq ($(ARCH),x86)
+LIB_OBJS += $(OUTPUT)tests/perf-time-to-tsc.o
+endif
+LIB_OBJS += $(OUTPUT)tests/code-reading.o
+LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
+LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
+BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
+# Benchmark modules
+BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
+ifeq ($(RAW_ARCH),x86_64)
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o
+endif
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
+BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
+BUILTIN_OBJS += $(OUTPUT)builtin-help.o
+BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
+BUILTIN_OBJS += $(OUTPUT)builtin-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-record.o
+BUILTIN_OBJS += $(OUTPUT)builtin-report.o
+BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
+BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
+BUILTIN_OBJS += $(OUTPUT)builtin-top.o
+BUILTIN_OBJS += $(OUTPUT)builtin-script.o
+BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
+BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
+BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
+BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o
+BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
+
+PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
+
+# We choose to avoid "if .. else if .. else .. endif endif"
+# because maintaining the nesting to match is a pain.  If
+# we had "elif" things would have been much nicer...
+
+-include arch/$(ARCH)/Makefile
+
+ifneq ($(OUTPUT),)
+  CFLAGS += -I$(OUTPUT)
+endif
+
+ifdef NO_LIBELF
+EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
+
+# Remove ELF/DWARF dependent codes
+LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS))
+LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
+LIB_OBJS := $(filter-out $(OUTPUT)util/probe-event.o,$(LIB_OBJS))
+LIB_OBJS := $(filter-out $(OUTPUT)util/probe-finder.o,$(LIB_OBJS))
+
+BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
+
+# Use minimal symbol handling
+LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
+
+else # NO_LIBELF
+ifndef NO_DWARF
+  LIB_OBJS += $(OUTPUT)util/probe-finder.o
+  LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
+endif # NO_DWARF
+endif # NO_LIBELF
+
+ifndef NO_LIBUNWIND
+  LIB_OBJS += $(OUTPUT)util/unwind.o
+endif
+LIB_OBJS += $(OUTPUT)tests/keep-tracking.o
+
+ifndef NO_LIBAUDIT
+  BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+endif
+
+ifndef NO_SLANG
+  LIB_OBJS += $(OUTPUT)ui/browser.o
+  LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
+  LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
+  LIB_OBJS += $(OUTPUT)ui/browsers/map.o
+  LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
+  LIB_OBJS += $(OUTPUT)ui/tui/setup.o
+  LIB_OBJS += $(OUTPUT)ui/tui/util.o
+  LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
+  LIB_OBJS += $(OUTPUT)ui/tui/progress.o
+  LIB_H += ui/tui/tui.h
+  LIB_H += ui/browser.h
+  LIB_H += ui/browsers/map.h
+  LIB_H += ui/keysyms.h
+  LIB_H += ui/libslang.h
+endif
+
+ifndef NO_GTK2
+  ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so
+
+  GTK_OBJS += $(OUTPUT)ui/gtk/browser.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/hists.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/setup.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/util.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/progress.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o
+
+install-gtk: $(OUTPUT)libperf-gtk.so
+       $(call QUIET_INSTALL, 'GTK UI') \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \
+               $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)'
+endif
+
+ifndef NO_LIBPERL
+  LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+  LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
+endif
+
+ifndef NO_LIBPYTHON
+  LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+  LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+endif
+
+ifeq ($(NO_PERF_REGS),0)
+  ifeq ($(ARCH),x86)
+    LIB_H += arch/x86/include/perf_regs.h
+  endif
+endif
+
+ifndef NO_LIBNUMA
+  BUILTIN_OBJS += $(OUTPUT)bench/numa.o
+endif
+
+ifdef ASCIIDOC8
+  export ASCIIDOC8
+endif
+
+LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+
+export INSTALL SHELL_PATH
+
+### Build rules
+
+SHELL = $(SHELL_PATH)
+
+all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
+
+please_set_SHELL_PATH_to_a_more_modern_shell:
+       @$$(:)
+
+shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
+
+strip: $(PROGRAMS) $(OUTPUT)perf
+       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf
+
+$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
+               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+               $(CFLAGS) -c $(filter %.c,$^) -o $@
+
+$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
+       $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
+               $(BUILTIN_OBJS) $(LIBS) -o $@
+
+$(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H)
+       $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
+
+$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
+       $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
+
+$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+               '-DPERF_MAN_PATH="$(mandir_SQ)"' \
+               '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
+
+$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+               '-DPERF_MAN_PATH="$(mandir_SQ)"' \
+               '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
+
+$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
+
+$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
+       $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
+
+$(SCRIPTS) : % : %.sh
+       $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
+
+# These can record PERF_VERSION
+$(OUTPUT)perf.o perf.spec \
+       $(SCRIPTS) \
+       : $(OUTPUT)PERF-VERSION-FILE
+
+.SUFFIXES:
+
+#
+# If a target does not match any of the later rules then prefix it by $(OUTPUT)
+# This makes targets like 'make O=/tmp/perf perf.o' work in a natural way.
+#
+ifneq ($(OUTPUT),)
+%.o: $(OUTPUT)%.o
+       @echo "    # Redirected target $@ => $(OUTPUT)$@"
+util/%.o: $(OUTPUT)util/%.o
+       @echo "    # Redirected target $@ => $(OUTPUT)$@"
+bench/%.o: $(OUTPUT)bench/%.o
+       @echo "    # Redirected target $@ => $(OUTPUT)$@"
+tests/%.o: $(OUTPUT)tests/%.o
+       @echo "    # Redirected target $@ => $(OUTPUT)$@"
+endif
+
+# These two need to be here so that when O= is not used they take precedence
+# over the general rule for .o
+
+$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $<
+
+$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
+
+$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
+$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
+$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
+$(OUTPUT)%.o: %.S
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
+$(OUTPUT)%.s: %.S
+       $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
+
+$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
+               '-DPREFIX="$(prefix_SQ)"' \
+               $<
+
+$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
+               $<
+
+$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               -DPYTHONPATH='"$(OUTPUT)python"' \
+               -DPYTHON='"$(PYTHON_WORD)"' \
+               $<
+
+$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+
+$(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $<
+
+$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+
+$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+
+$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+
+$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+
+$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+
+$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+
+$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
+
+$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $<
+
+$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default $<
+
+$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+
+$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+
+$(OUTPUT)perf-%: %.o $(PERFLIBS)
+       $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
+
+$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
+$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
+
+# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
+# we depend the various files onto their directories.
+DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(GTK_OBJS)
+DIRECTORY_DEPS += $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
+$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
+# In the second step, we make a rule to actually create these directories
+$(sort $(dir $(DIRECTORY_DEPS))):
+       $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
+
+$(LIB_FILE): $(LIB_OBJS)
+       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
+
+# libtraceevent.a
+TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch])
+
+$(LIBTRACEEVENT): $(TE_SOURCES)
+       $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) CFLAGS="-g -Wall $(EXTRA_CFLAGS)" libtraceevent.a
+
+$(LIBTRACEEVENT)-clean:
+       $(call QUIET_CLEAN, libtraceevent)
+       @$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null
+
+LIBLK_SOURCES = $(wildcard $(LK_PATH)*.[ch])
+
+# if subdir is set, we've been called from above so target has been built
+# already
+$(LIBLK): $(LIBLK_SOURCES)
+ifeq ($(subdir),)
+       $(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a
+endif
+
+$(LIBLK)-clean:
+ifeq ($(subdir),)
+       $(call QUIET_CLEAN, liblk)
+       @$(MAKE) -C $(LK_DIR) O=$(OUTPUT) clean >/dev/null
+endif
+
+help:
+       @echo 'Perf make targets:'
+       @echo '  doc            - make *all* documentation (see below)'
+       @echo '  man            - make manpage documentation (access with man <foo>)'
+       @echo '  html           - make html documentation'
+       @echo '  info           - make GNU info documentation (access with info <foo>)'
+       @echo '  pdf            - make pdf documentation'
+       @echo '  TAGS           - use etags to make tag information for source browsing'
+       @echo '  tags           - use ctags to make tag information for source browsing'
+       @echo '  cscope - use cscope to make interactive browsing database'
+       @echo ''
+       @echo 'Perf install targets:'
+       @echo '  NOTE: documentation build requires asciidoc, xmlto packages to be installed'
+       @echo '  HINT: use "make prefix=<path> <install target>" to install to a particular'
+       @echo '        path like make prefix=/usr/local install install-doc'
+       @echo '  install        - install compiled binaries'
+       @echo '  install-doc    - install *all* documentation'
+       @echo '  install-man    - install manpage documentation'
+       @echo '  install-html   - install html documentation'
+       @echo '  install-info   - install GNU info documentation'
+       @echo '  install-pdf    - install pdf documentation'
+       @echo ''
+       @echo '  quick-install-doc      - alias for quick-install-man'
+       @echo '  quick-install-man      - install the documentation quickly'
+       @echo '  quick-install-html     - install the html documentation quickly'
+       @echo ''
+       @echo 'Perf maintainer targets:'
+       @echo '  clean                  - clean all binary objects and build output'
+
+
+DOC_TARGETS := doc man html info pdf
+
+INSTALL_DOC_TARGETS := $(patsubst %,install-%,$(DOC_TARGETS)) try-install-man
+INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
+
+# 'make doc' should call 'make -C Documentation all'
+$(DOC_TARGETS):
+       $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
+
+TAGS:
+       $(RM) TAGS
+       $(FIND) . -name '*.[hcS]' -print | xargs etags -a
+
+tags:
+       $(RM) tags
+       $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
+
+cscope:
+       $(RM) cscope*
+       $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
+
+### Detect prefix changes
+TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
+             $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
+
+$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
+       @FLAGS='$(TRACK_CFLAGS)'; \
+           if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
+               echo 1>&2 "  FLAGS:   * new build flags or prefix"; \
+               echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
+            fi
+
+### Testing rules
+
+# GNU make supports exporting all variables by "export" without parameters.
+# However, the environment gets quite big, and some programs have problems
+# with that.
+
+check: $(OUTPUT)common-cmds.h
+       if sparse; \
+       then \
+               for i in *.c */*.c; \
+               do \
+                       sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
+               done; \
+       else \
+               exit 1; \
+       fi
+
+### Installation rules
+
+install-gtk:
+
+install-bin: all install-gtk
+       $(call QUIET_INSTALL, binaries) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'; \
+               $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \
+               $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace'
+       $(call QUIET_INSTALL, libexec) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+       $(call QUIET_INSTALL, perf-archive) \
+               $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+ifndef NO_LIBPERL
+       $(call QUIET_INSTALL, perl-scripts) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
+               $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
+               $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \
+               $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
+endif
+ifndef NO_LIBPYTHON
+       $(call QUIET_INSTALL, python-scripts) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'; \
+               $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
+               $(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) \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \
+               $(INSTALL) bash_completion '$(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'; \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
+               $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
+
+install: install-bin try-install-man
+
+install-python_ext:
+       $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
+
+# 'make install-doc' should call 'make -C Documentation install'
+$(INSTALL_DOC_TARGETS):
+       $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=)
+
+### Cleaning rules
+
+#
+# This is here, not in config/Makefile, because config/Makefile does
+# not get included for the clean target:
+#
+config-clean:
+       $(call QUIET_CLEAN, config)
+       @$(MAKE) -C config/feature-checks clean >/dev/null
+
+clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean
+       $(call QUIET_CLEAN, core-objs)  $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS)
+       $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf
+       $(call QUIET_CLEAN, core-gen)   $(RM)  *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
+       $(call QUIET_CLEAN, Documentation)
+       @$(MAKE) -C Documentation O=$(OUTPUT) clean >/dev/null
+       $(python-clean)
+
+#
+# Trick: if ../../.git does not exist - we are building out of tree for example,
+# then force version regeneration:
+#
+ifeq ($(wildcard ../../.git/HEAD),)
+    GIT-HEAD-PHONY = ../../.git/HEAD
+else
+    GIT-HEAD-PHONY =
+endif
+
+.PHONY: all install clean config-clean strip install-gtk
+.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
+.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS
+
index 7fcdcdbee917a8473acf25fe7ac72c6c5a9732b0..e84ca76aae779ef484df1633b7cff3e35b327ba8 100644 (file)
@@ -5,7 +5,7 @@
 #include "../../util/types.h"
 #include <asm/perf_regs.h>
 
-#ifndef ARCH_X86_64
+#ifndef HAVE_ARCH_X86_64_SUPPORT
 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
 #else
 #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
@@ -52,7 +52,7 @@ static inline const char *perf_reg_name(int id)
                return "FS";
        case PERF_REG_X86_GS:
                return "GS";
-#ifdef ARCH_X86_64
+#ifdef HAVE_ARCH_X86_64_SUPPORT
        case PERF_REG_X86_R8:
                return "R8";
        case PERF_REG_X86_R9:
@@ -69,7 +69,7 @@ static inline const char *perf_reg_name(int id)
                return "R14";
        case PERF_REG_X86_R15:
                return "R15";
-#endif /* ARCH_X86_64 */
+#endif /* HAVE_ARCH_X86_64_SUPPORT */
        default:
                return NULL;
        }
index 78d956eff96fcd8de79a5afd42041c6c72fb02ec..456a88cf5b374bf3319ea2310e88f2cd179c9b28 100644 (file)
@@ -4,7 +4,7 @@
 #include "perf_regs.h"
 #include "../../util/unwind.h"
 
-#ifdef ARCH_X86_64
+#ifdef HAVE_ARCH_X86_64_SUPPORT
 int unwind__arch_reg_id(int regnum)
 {
        int id;
@@ -108,4 +108,4 @@ int unwind__arch_reg_id(int regnum)
 
        return id;
 }
-#endif /* ARCH_X86_64 */
+#endif /* HAVE_ARCH_X86_64_SUPPORT */
index 56e6a12aab59b42d4cffbc67858824af818f5fff..62e157db2e2b01e9400f9348d671fd9ba7267104 100644 (file)
@@ -1,17 +1,87 @@
 # perf completion
 
-function_exists()
+# Taken from git.git's completion script.
+__my_reassemble_comp_words_by_ref()
 {
-       declare -F $1 > /dev/null
-       return $?
+       local exclude i j first
+       # Which word separators to exclude?
+       exclude="${1//[^$COMP_WORDBREAKS]}"
+       cword_=$COMP_CWORD
+       if [ -z "$exclude" ]; then
+               words_=("${COMP_WORDS[@]}")
+               return
+       fi
+       # List of word completion separators has shrunk;
+       # re-assemble words to complete.
+       for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
+               # Append each nonempty word consisting of just
+               # word separator characters to the current word.
+               first=t
+               while
+                       [ $i -gt 0 ] &&
+                       [ -n "${COMP_WORDS[$i]}" ] &&
+                       # word consists of excluded word separators
+                       [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
+               do
+                       # Attach to the previous token,
+                       # unless the previous token is the command name.
+                       if [ $j -ge 2 ] && [ -n "$first" ]; then
+                               ((j--))
+                       fi
+                       first=
+                       words_[$j]=${words_[j]}${COMP_WORDS[i]}
+                       if [ $i = $COMP_CWORD ]; then
+                               cword_=$j
+                       fi
+                       if (($i < ${#COMP_WORDS[@]} - 1)); then
+                               ((i++))
+                       else
+                               # Done.
+                               return
+                       fi
+               done
+               words_[$j]=${words_[j]}${COMP_WORDS[i]}
+               if [ $i = $COMP_CWORD ]; then
+                       cword_=$j
+               fi
+       done
 }
 
-function_exists __ltrim_colon_completions ||
+type _get_comp_words_by_ref &>/dev/null ||
+_get_comp_words_by_ref()
+{
+       local exclude cur_ words_ cword_
+       if [ "$1" = "-n" ]; then
+               exclude=$2
+               shift 2
+       fi
+       __my_reassemble_comp_words_by_ref "$exclude"
+       cur_=${words_[cword_]}
+       while [ $# -gt 0 ]; do
+               case "$1" in
+               cur)
+                       cur=$cur_
+                       ;;
+               prev)
+                       prev=${words_[$cword_-1]}
+                       ;;
+               words)
+                       words=("${words_[@]}")
+                       ;;
+               cword)
+                       cword=$cword_
+                       ;;
+               esac
+               shift
+       done
+}
+
+type __ltrim_colon_completions &>/dev/null ||
 __ltrim_colon_completions()
 {
        if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
                # Remove colon-word prefix from COMPREPLY items
-               local colon_word=${1%${1##*:}}
+               local colon_word=${1%"${1##*:}"}
                local i=${#COMPREPLY[*]}
                while [[ $((--i)) -ge 0 ]]; do
                        COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
@@ -19,23 +89,18 @@ __ltrim_colon_completions()
        fi
 }
 
-have perf &&
+type perf &>/dev/null &&
 _perf()
 {
-       local cur prev cmd
+       local cur words cword prev cmd
 
        COMPREPLY=()
-       if function_exists _get_comp_words_by_ref; then
-               _get_comp_words_by_ref -n : cur prev
-       else
-               cur=$(_get_cword :)
-               prev=${COMP_WORDS[COMP_CWORD-1]}
-       fi
+       _get_comp_words_by_ref -n =: cur words cword prev
 
-       cmd=${COMP_WORDS[0]}
+       cmd=${words[0]}
 
        # List perf subcommands or long options
-       if [ $COMP_CWORD -eq 1 ]; then
+       if [ $cword -eq 1 ]; then
                if [[ $cur == --* ]]; then
                        COMPREPLY=( $( compgen -W '--help --version \
                        --exec-path --html-path --paginate --no-pager \
@@ -45,18 +110,17 @@ _perf()
                        COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
                fi
        # List possible events for -e option
-       elif [[ $prev == "-e" && "${COMP_WORDS[1]}" == @(record|stat|top) ]]; then
+       elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
                evts=$($cmd list --raw-dump)
                COMPREPLY=( $( compgen -W '$evts' -- "$cur" ) )
                __ltrim_colon_completions $cur
        # List long option names
        elif [[ $cur == --* ]];  then
-               subcmd=${COMP_WORDS[1]}
+               subcmd=${words[1]}
                opts=$($cmd $subcmd --list-opts)
                COMPREPLY=( $( compgen -W '$opts' -- "$cur" ) )
-       # Fall down to list regular files
-       else
-               _filedir
        fi
 } &&
-complete -F _perf perf
+
+complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \
+       || complete -o default -o nospace -F _perf perf
index a72e36cb53943c1a9689b8ce6ee35abc467ccb1d..57b4ed871459034b57159bb4eb21dc27e88e87ba 100644 (file)
@@ -1,5 +1,5 @@
 
-#ifdef ARCH_X86_64
+#ifdef HAVE_ARCH_X86_64_SUPPORT
 
 #define MEMCPY_FN(fn, name, desc)              \
        extern void *fn(void *, const void *, size_t);
index 8cdca43016b250109d8bdd3ea7568eb13229a125..5ce71d3b72cf9bc16251ba5e7ac81ad0c61560b6 100644 (file)
@@ -58,7 +58,7 @@ struct routine routines[] = {
        { "default",
          "Default memcpy() provided by glibc",
          memcpy },
-#ifdef ARCH_X86_64
+#ifdef HAVE_ARCH_X86_64_SUPPORT
 
 #define MEMCPY_FN(fn, name, desc) { name, desc, fn },
 #include "mem-memcpy-x86-64-asm-def.h"
index a040fa77665b0ef90eb66ba3901074f274536750..633800cb0dcb0ad60309c1a12003f42d38e64b08 100644 (file)
@@ -1,5 +1,5 @@
 
-#ifdef ARCH_X86_64
+#ifdef HAVE_ARCH_X86_64_SUPPORT
 
 #define MEMSET_FN(fn, name, desc)              \
        extern void *fn(void *, int, size_t);
index 4a2f12081964163c3f93bede8934c723806d16f2..9af79d2b18e5a178c97adfe6ddcaecda236dcfc6 100644 (file)
@@ -58,7 +58,7 @@ static const struct routine routines[] = {
        { "default",
          "Default memset() provided by glibc",
          memset },
-#ifdef ARCH_X86_64
+#ifdef HAVE_ARCH_X86_64_SUPPORT
 
 #define MEMSET_FN(fn, name, desc) { name, desc, fn },
 #include "mem-memset-x86-64-asm-def.h"
index 30d1c3225b46222d52f3d73b0cdb1fa1995e8efa..d4c83c60b9b29fa7d6249de70e5f0673d2066287 100644 (file)
@@ -429,14 +429,14 @@ static int parse_cpu_list(const char *arg)
        return 0;
 }
 
-static void parse_setup_cpu_list(void)
+static int parse_setup_cpu_list(void)
 {
        struct thread_data *td;
        char *str0, *str;
        int t;
 
        if (!g->p.cpu_list_str)
-               return;
+               return 0;
 
        dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks);
 
@@ -500,8 +500,12 @@ static void parse_setup_cpu_list(void)
 
                dprintf("CPUs: %d_%d-%d#%dx%d\n", bind_cpu_0, bind_len, bind_cpu_1, step, mul);
 
-               BUG_ON(bind_cpu_0 < 0 || bind_cpu_0 >= g->p.nr_cpus);
-               BUG_ON(bind_cpu_1 < 0 || bind_cpu_1 >= g->p.nr_cpus);
+               if (bind_cpu_0 >= g->p.nr_cpus || bind_cpu_1 >= g->p.nr_cpus) {
+                       printf("\nTest not applicable, system has only %d CPUs.\n", g->p.nr_cpus);
+                       return -1;
+               }
+
+               BUG_ON(bind_cpu_0 < 0 || bind_cpu_1 < 0);
                BUG_ON(bind_cpu_0 > bind_cpu_1);
 
                for (bind_cpu = bind_cpu_0; bind_cpu <= bind_cpu_1; bind_cpu += step) {
@@ -541,6 +545,7 @@ out:
                printf("# NOTE: %d tasks bound, %d tasks unbound\n", t, g->p.nr_tasks - t);
 
        free(str0);
+       return 0;
 }
 
 static int parse_cpus_opt(const struct option *opt __maybe_unused,
@@ -561,14 +566,14 @@ static int parse_node_list(const char *arg)
        return 0;
 }
 
-static void parse_setup_node_list(void)
+static int parse_setup_node_list(void)
 {
        struct thread_data *td;
        char *str0, *str;
        int t;
 
        if (!g->p.node_list_str)
-               return;
+               return 0;
 
        dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks);
 
@@ -619,8 +624,12 @@ static void parse_setup_node_list(void)
 
                dprintf("NODEs: %d-%d #%d\n", bind_node_0, bind_node_1, step);
 
-               BUG_ON(bind_node_0 < 0 || bind_node_0 >= g->p.nr_nodes);
-               BUG_ON(bind_node_1 < 0 || bind_node_1 >= g->p.nr_nodes);
+               if (bind_node_0 >= g->p.nr_nodes || bind_node_1 >= g->p.nr_nodes) {
+                       printf("\nTest not applicable, system has only %d nodes.\n", g->p.nr_nodes);
+                       return -1;
+               }
+
+               BUG_ON(bind_node_0 < 0 || bind_node_1 < 0);
                BUG_ON(bind_node_0 > bind_node_1);
 
                for (bind_node = bind_node_0; bind_node <= bind_node_1; bind_node += step) {
@@ -651,6 +660,7 @@ out:
                printf("# NOTE: %d tasks mem-bound, %d tasks unbound\n", t, g->p.nr_tasks - t);
 
        free(str0);
+       return 0;
 }
 
 static int parse_nodes_opt(const struct option *opt __maybe_unused,
@@ -1110,7 +1120,7 @@ static void *worker_thread(void *__tdata)
                /* Check whether our max runtime timed out: */
                if (g->p.nr_secs) {
                        timersub(&stop, &start0, &diff);
-                       if (diff.tv_sec >= g->p.nr_secs) {
+                       if ((u32)diff.tv_sec >= g->p.nr_secs) {
                                g->stop_work = true;
                                break;
                        }
@@ -1157,7 +1167,7 @@ static void *worker_thread(void *__tdata)
                        runtime_ns_max += diff.tv_usec * 1000;
 
                        if (details >= 0) {
-                               printf(" #%2d / %2d: %14.2lf nsecs/op [val: %016lx]\n",
+                               printf(" #%2d / %2d: %14.2lf nsecs/op [val: %016"PRIx64"]\n",
                                        process_nr, thread_nr, runtime_ns_max / bytes_done, val);
                        }
                        fflush(stdout);
@@ -1356,8 +1366,8 @@ static int init(void)
        init_thread_data();
 
        tprintf("#\n");
-       parse_setup_cpu_list();
-       parse_setup_node_list();
+       if (parse_setup_cpu_list() || parse_setup_node_list())
+               return -1;
        tprintf("#\n");
 
        print_summary();
@@ -1600,7 +1610,6 @@ static int run_bench_numa(const char *name, const char **argv)
        return 0;
 
 err:
-       usage_with_options(numa_usage, options);
        return -1;
 }
 
@@ -1701,8 +1710,7 @@ static int bench_all(void)
        BUG_ON(ret < 0);
 
        for (i = 0; i < nr; i++) {
-               if (run_bench_numa(tests[i][0], tests[i] + 1))
-                       return -1;
+               run_bench_numa(tests[i][0], tests[i] + 1);
        }
 
        printf("\n");
index 69cfba8d4c6cfb5a0bd402735d3eaa5bfdd7a467..07a8d7646a1549c61699f7311285238ef5ef93cf 100644 (file)
@@ -7,9 +7,7 @@
  * Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com>
  *  http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
  * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
- *
  */
-
 #include "../perf.h"
 #include "../util/util.h"
 #include "../util/parse-options.h"
 #include <sys/time.h>
 #include <sys/types.h>
 
+#include <pthread.h>
+
+struct thread_data {
+       int                     nr;
+       int                     pipe_read;
+       int                     pipe_write;
+       pthread_t               pthread;
+};
+
 #define LOOPS_DEFAULT 1000000
-static int loops = LOOPS_DEFAULT;
+static int                     loops = LOOPS_DEFAULT;
+
+/* Use processes by default: */
+static bool                    threaded;
 
 static const struct option options[] = {
-       OPT_INTEGER('l', "loop", &loops,
-                   "Specify number of loops"),
+       OPT_INTEGER('l', "loop",        &loops,         "Specify number of loops"),
+       OPT_BOOLEAN('T', "threaded",    &threaded,      "Specify threads/process based task setup"),
        OPT_END()
 };
 
@@ -42,13 +52,37 @@ static const char * const bench_sched_pipe_usage[] = {
        NULL
 };
 
-int bench_sched_pipe(int argc, const char **argv,
-                    const char *prefix __maybe_unused)
+static void *worker_thread(void *__tdata)
 {
-       int pipe_1[2], pipe_2[2];
+       struct thread_data *td = __tdata;
        int m = 0, i;
+       int ret;
+
+       for (i = 0; i < loops; i++) {
+               if (!td->nr) {
+                       ret = read(td->pipe_read, &m, sizeof(int));
+                       BUG_ON(ret != sizeof(int));
+                       ret = write(td->pipe_write, &m, sizeof(int));
+                       BUG_ON(ret != sizeof(int));
+               } else {
+                       ret = write(td->pipe_write, &m, sizeof(int));
+                       BUG_ON(ret != sizeof(int));
+                       ret = read(td->pipe_read, &m, sizeof(int));
+                       BUG_ON(ret != sizeof(int));
+               }
+       }
+
+       return NULL;
+}
+
+int bench_sched_pipe(int argc, const char **argv, const char *prefix __maybe_unused)
+{
+       struct thread_data threads[2], *td;
+       int pipe_1[2], pipe_2[2];
        struct timeval start, stop, diff;
        unsigned long long result_usec = 0;
+       int nr_threads = 2;
+       int t;
 
        /*
         * why does "ret" exist?
@@ -58,43 +92,66 @@ int bench_sched_pipe(int argc, const char **argv,
        int __maybe_unused ret, wait_stat;
        pid_t pid, retpid __maybe_unused;
 
-       argc = parse_options(argc, argv, options,
-                            bench_sched_pipe_usage, 0);
+       argc = parse_options(argc, argv, options, bench_sched_pipe_usage, 0);
 
        BUG_ON(pipe(pipe_1));
        BUG_ON(pipe(pipe_2));
 
-       pid = fork();
-       assert(pid >= 0);
-
        gettimeofday(&start, NULL);
 
-       if (!pid) {
-               for (i = 0; i < loops; i++) {
-                       ret = read(pipe_1[0], &m, sizeof(int));
-                       ret = write(pipe_2[1], &m, sizeof(int));
-               }
-       } else {
-               for (i = 0; i < loops; i++) {
-                       ret = write(pipe_1[1], &m, sizeof(int));
-                       ret = read(pipe_2[0], &m, sizeof(int));
+       for (t = 0; t < nr_threads; t++) {
+               td = threads + t;
+
+               td->nr = t;
+
+               if (t == 0) {
+                       td->pipe_read = pipe_1[0];
+                       td->pipe_write = pipe_2[1];
+               } else {
+                       td->pipe_write = pipe_1[1];
+                       td->pipe_read = pipe_2[0];
                }
        }
 
-       gettimeofday(&stop, NULL);
-       timersub(&stop, &start, &diff);
 
-       if (pid) {
+       if (threaded) {
+
+               for (t = 0; t < nr_threads; t++) {
+                       td = threads + t;
+
+                       ret = pthread_create(&td->pthread, NULL, worker_thread, td);
+                       BUG_ON(ret);
+               }
+
+               for (t = 0; t < nr_threads; t++) {
+                       td = threads + t;
+
+                       ret = pthread_join(td->pthread, NULL);
+                       BUG_ON(ret);
+               }
+
+       } else {
+               pid = fork();
+               assert(pid >= 0);
+
+               if (!pid) {
+                       worker_thread(threads + 0);
+                       exit(0);
+               } else {
+                       worker_thread(threads + 1);
+               }
+
                retpid = waitpid(pid, &wait_stat, 0);
                assert((retpid == pid) && WIFEXITED(wait_stat));
-       } else {
-               exit(0);
        }
 
+       gettimeofday(&stop, NULL);
+       timersub(&stop, &start, &diff);
+
        switch (bench_format) {
        case BENCH_FORMAT_DEFAULT:
-               printf("# Executed %d pipe operations between two tasks\n\n",
-                       loops);
+               printf("# Executed %d pipe operations between two %s\n\n",
+                       loops, threaded ? "threads" : "processes");
 
                result_usec = diff.tv_sec * 1000000;
                result_usec += diff.tv_usec;
index 5ebd0c3b71b6aa45d80aa63b47661996577cf6a4..4087ab19823c2f843c50e18d7b8e5042a079032f 100644 (file)
 #include "util/hist.h"
 #include "util/session.h"
 #include "util/tool.h"
+#include "util/data.h"
 #include "arch/common.h"
 
+#include <dlfcn.h>
 #include <linux/bitmap.h>
 
 struct perf_annotate {
@@ -63,7 +65,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
                return 0;
        }
 
-       he = __hists__add_entry(&evsel->hists, al, NULL, 1, 1);
+       he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0);
        if (he == NULL)
                return -ENOMEM;
 
@@ -116,11 +118,11 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
                                    ann->print_line, ann->full_paths, 0, 0);
 }
 
-static void hists__find_annotations(struct hists *self,
+static void hists__find_annotations(struct hists *hists,
                                    struct perf_evsel *evsel,
                                    struct perf_annotate *ann)
 {
-       struct rb_node *nd = rb_first(&self->entries), *next;
+       struct rb_node *nd = rb_first(&hists->entries), *next;
        int key = K_RIGHT;
 
        while (nd) {
@@ -142,8 +144,18 @@ find_next:
 
                if (use_browser == 2) {
                        int ret;
+                       int (*annotate)(struct hist_entry *he,
+                                       struct perf_evsel *evsel,
+                                       struct hist_browser_timer *hbt);
+
+                       annotate = dlsym(perf_gtk_handle,
+                                        "hist_entry__gtk_annotate");
+                       if (annotate == NULL) {
+                               ui__error("GTK browser not found!\n");
+                               return;
+                       }
 
-                       ret = hist_entry__gtk_annotate(he, evsel, NULL);
+                       ret = annotate(he, evsel, NULL);
                        if (!ret || !ann->skip_missing)
                                return;
 
@@ -188,9 +200,13 @@ static int __cmd_annotate(struct perf_annotate *ann)
        struct perf_session *session;
        struct perf_evsel *pos;
        u64 total_nr_samples;
+       struct perf_data_file file = {
+               .path  = input_name,
+               .mode  = PERF_DATA_MODE_READ,
+               .force = ann->force,
+       };
 
-       session = perf_session__new(input_name, O_RDONLY,
-                                   ann->force, false, &ann->tool);
+       session = perf_session__new(&file, false, &ann->tool);
        if (session == NULL)
                return -ENOMEM;
 
@@ -231,7 +247,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
 
                if (nr_samples > 0) {
                        total_nr_samples += nr_samples;
-                       hists__collapse_resort(hists);
+                       hists__collapse_resort(hists, NULL);
                        hists__output_resort(hists);
 
                        if (symbol_conf.event_group &&
@@ -243,12 +259,21 @@ static int __cmd_annotate(struct perf_annotate *ann)
        }
 
        if (total_nr_samples == 0) {
-               ui__error("The %s file has no samples!\n", session->filename);
+               ui__error("The %s file has no samples!\n", file.path);
                goto out_delete;
        }
 
-       if (use_browser == 2)
-               perf_gtk__show_annotations();
+       if (use_browser == 2) {
+               void (*show_annotations)(void);
+
+               show_annotations = dlsym(perf_gtk_handle,
+                                        "perf_gtk__show_annotations");
+               if (show_annotations == NULL) {
+                       ui__error("GTK browser not found!\n");
+                       goto out_delete;
+               }
+               show_annotations();
+       }
 
 out_delete:
        /*
index 77298bf892b85c68d3c662cfe62e050518630a49..e47f90cc7b98cdde57079975bbd5637f3249ce44 100644 (file)
@@ -1,21 +1,18 @@
 /*
- *
  * builtin-bench.c
  *
- * General benchmarking subsystem provided by perf
+ * General benchmarking collections provided by perf
  *
  * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
- *
  */
 
 /*
+ * Available benchmark collection list:
  *
- * Available subsystem list:
- *  sched ... scheduler and IPC mechanism
+ *  sched ... scheduler and IPC performance
  *  mem   ... memory access performance
- *
+ *  numa  ... NUMA scheduling and MM performance
  */
-
 #include "perf.h"
 #include "util/util.h"
 #include "util/parse-options.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/prctl.h>
 
-struct bench_suite {
-       const char *name;
-       const char *summary;
-       int (*fn)(int, const char **, const char *);
+typedef int (*bench_fn_t)(int argc, const char **argv, const char *prefix);
+
+struct bench {
+       const char      *name;
+       const char      *summary;
+       bench_fn_t      fn;
 };
-                                               \
-/* sentinel: easy for help */
-#define suite_all { "all", "Test all benchmark suites", NULL }
-
-#ifdef LIBNUMA_SUPPORT
-static struct bench_suite numa_suites[] = {
-       { "mem",
-         "Benchmark for NUMA workloads",
-         bench_numa },
-       suite_all,
-       { NULL,
-         NULL,
-         NULL                  }
+
+#ifdef HAVE_LIBNUMA_SUPPORT
+static struct bench numa_benchmarks[] = {
+       { "mem",        "Benchmark for NUMA workloads",                 bench_numa              },
+       { "all",        "Test all NUMA benchmarks",                     NULL                    },
+       { NULL,         NULL,                                           NULL                    }
 };
 #endif
 
-static struct bench_suite sched_suites[] = {
-       { "messaging",
-         "Benchmark for scheduler and IPC mechanisms",
-         bench_sched_messaging },
-       { "pipe",
-         "Flood of communication over pipe() between two processes",
-         bench_sched_pipe      },
-       suite_all,
-       { NULL,
-         NULL,
-         NULL                  }
+static struct bench sched_benchmarks[] = {
+       { "messaging",  "Benchmark for scheduling and IPC",             bench_sched_messaging   },
+       { "pipe",       "Benchmark for pipe() between two processes",   bench_sched_pipe        },
+       { "all",        "Test all scheduler benchmarks",                NULL                    },
+       { NULL,         NULL,                                           NULL                    }
 };
 
-static struct bench_suite mem_suites[] = {
-       { "memcpy",
-         "Simple memory copy in various ways",
-         bench_mem_memcpy },
-       { "memset",
-         "Simple memory set in various ways",
-         bench_mem_memset },
-       suite_all,
-       { NULL,
-         NULL,
-         NULL             }
+static struct bench mem_benchmarks[] = {
+       { "memcpy",     "Benchmark for memcpy()",                       bench_mem_memcpy        },
+       { "memset",     "Benchmark for memset() tests",                 bench_mem_memset        },
+       { "all",        "Test all memory benchmarks",                   NULL                    },
+       { NULL,         NULL,                                           NULL                    }
 };
 
-struct bench_subsys {
-       const char *name;
-       const char *summary;
-       struct bench_suite *suites;
+struct collection {
+       const char      *name;
+       const char      *summary;
+       struct bench    *benchmarks;
 };
 
-static struct bench_subsys subsystems[] = {
-#ifdef LIBNUMA_SUPPORT
-       { "numa",
-         "NUMA scheduling and MM behavior",
-         numa_suites },
+static struct collection collections[] = {
+       { "sched",      "Scheduler and IPC benchmarks",         sched_benchmarks        },
+       { "mem",        "Memory access benchmarks",                     mem_benchmarks          },
+#ifdef HAVE_LIBNUMA_SUPPORT
+       { "numa",       "NUMA scheduling and MM benchmarks",            numa_benchmarks         },
 #endif
-       { "sched",
-         "scheduler and IPC mechanism",
-         sched_suites },
-       { "mem",
-         "memory access performance",
-         mem_suites },
-       { "all",                /* sentinel: easy for help */
-         "all benchmark subsystem",
-         NULL },
-       { NULL,
-         NULL,
-         NULL       }
+       { "all",        "All benchmarks",                               NULL                    },
+       { NULL,         NULL,                                           NULL                    }
 };
 
-static void dump_suites(int subsys_index)
+/* Iterate over all benchmark collections: */
+#define for_each_collection(coll) \
+       for (coll = collections; coll->name; coll++)
+
+/* Iterate over all benchmarks within a collection: */
+#define for_each_bench(coll, bench) \
+       for (bench = coll->benchmarks; bench->name; bench++)
+
+static void dump_benchmarks(struct collection *coll)
 {
-       int i;
+       struct bench *bench;
 
-       printf("# List of available suites for %s...\n\n",
-              subsystems[subsys_index].name);
+       printf("\n        # List of available benchmarks for collection '%s':\n\n", coll->name);
 
-       for (i = 0; subsystems[subsys_index].suites[i].name; i++)
-               printf("%14s: %s\n",
-                      subsystems[subsys_index].suites[i].name,
-                      subsystems[subsys_index].suites[i].summary);
+       for_each_bench(coll, bench)
+               printf("%14s: %s\n", bench->name, bench->summary);
 
        printf("\n");
-       return;
 }
 
 static const char *bench_format_str;
+
+/* Output/formatting style, exported to benchmark modules: */
 int bench_format = BENCH_FORMAT_DEFAULT;
 
 static const struct option bench_options[] = {
-       OPT_STRING('f', "format", &bench_format_str, "default",
-                   "Specify format style"),
+       OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"),
        OPT_END()
 };
 
 static const char * const bench_usage[] = {
-       "perf bench [<common options>] <subsystem> <suite> [<options>]",
+       "perf bench [<common options>] <collection> <benchmark> [<options>]",
        NULL
 };
 
 static void print_usage(void)
 {
+       struct collection *coll;
        int i;
 
        printf("Usage: \n");
@@ -138,11 +115,10 @@ static void print_usage(void)
                printf("\t%s\n", bench_usage[i]);
        printf("\n");
 
-       printf("# List of available subsystems...\n\n");
+       printf("        # List of all available benchmark collections:\n\n");
 
-       for (i = 0; subsystems[i].name; i++)
-               printf("%14s: %s\n",
-                      subsystems[i].name, subsystems[i].summary);
+       for_each_collection(coll)
+               printf("%14s: %s\n", coll->name, coll->summary);
        printf("\n");
 }
 
@@ -159,44 +135,74 @@ static int bench_str2int(const char *str)
        return BENCH_FORMAT_UNKNOWN;
 }
 
-static void all_suite(struct bench_subsys *subsys)       /* FROM HERE */
+/*
+ * Run a specific benchmark but first rename the running task's ->comm[]
+ * to something meaningful:
+ */
+static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t fn,
+                    int argc, const char **argv, const char *prefix)
 {
-       int i;
+       int size;
+       char *name;
+       int ret;
+
+       size = strlen(coll_name) + 1 + strlen(bench_name) + 1;
+
+       name = zalloc(size);
+       BUG_ON(!name);
+
+       scnprintf(name, size, "%s-%s", coll_name, bench_name);
+
+       prctl(PR_SET_NAME, name);
+       argv[0] = name;
+
+       ret = fn(argc, argv, prefix);
+
+       free(name);
+
+       return ret;
+}
+
+static void run_collection(struct collection *coll)
+{
+       struct bench *bench;
        const char *argv[2];
-       struct bench_suite *suites = subsys->suites;
 
        argv[1] = NULL;
        /*
         * TODO:
-        * preparing preset parameters for
+        *
+        * Preparing preset parameters for
         * embedded, ordinary PC, HPC, etc...
-        * will be helpful
+        * would be helpful.
         */
-       for (i = 0; suites[i].fn; i++) {
-               printf("# Running %s/%s benchmark...\n",
-                      subsys->name,
-                      suites[i].name);
+       for_each_bench(coll, bench) {
+               if (!bench->fn)
+                       break;
+               printf("# Running %s/%s benchmark...\n", coll->name, bench->name);
                fflush(stdout);
 
-               argv[1] = suites[i].name;
-               suites[i].fn(1, argv, NULL);
+               argv[1] = bench->name;
+               run_bench(coll->name, bench->name, bench->fn, 1, argv, NULL);
                printf("\n");
        }
 }
 
-static void all_subsystem(void)
+static void run_all_collections(void)
 {
-       int i;
-       for (i = 0; subsystems[i].suites; i++)
-               all_suite(&subsystems[i]);
+       struct collection *coll;
+
+       for_each_collection(coll)
+               run_collection(coll);
 }
 
 int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
 {
-       int i, j, status = 0;
+       struct collection *coll;
+       int ret = 0;
 
        if (argc < 2) {
-               /* No subsystem specified. */
+               /* No collection specified. */
                print_usage();
                goto end;
        }
@@ -206,7 +212,7 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
 
        bench_format = bench_str2int(bench_format_str);
        if (bench_format == BENCH_FORMAT_UNKNOWN) {
-               printf("Unknown format descriptor:%s\n", bench_format_str);
+               printf("Unknown format descriptor: '%s'\n", bench_format_str);
                goto end;
        }
 
@@ -216,52 +222,51 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
        }
 
        if (!strcmp(argv[0], "all")) {
-               all_subsystem();
+               run_all_collections();
                goto end;
        }
 
-       for (i = 0; subsystems[i].name; i++) {
-               if (strcmp(subsystems[i].name, argv[0]))
+       for_each_collection(coll) {
+               struct bench *bench;
+
+               if (strcmp(coll->name, argv[0]))
                        continue;
 
                if (argc < 2) {
-                       /* No suite specified. */
-                       dump_suites(i);
+                       /* No bench specified. */
+                       dump_benchmarks(coll);
                        goto end;
                }
 
                if (!strcmp(argv[1], "all")) {
-                       all_suite(&subsystems[i]);
+                       run_collection(coll);
                        goto end;
                }
 
-               for (j = 0; subsystems[i].suites[j].name; j++) {
-                       if (strcmp(subsystems[i].suites[j].name, argv[1]))
+               for_each_bench(coll, bench) {
+                       if (strcmp(bench->name, argv[1]))
                                continue;
 
                        if (bench_format == BENCH_FORMAT_DEFAULT)
-                               printf("# Running %s/%s benchmark...\n",
-                                      subsystems[i].name,
-                                      subsystems[i].suites[j].name);
+                               printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name);
                        fflush(stdout);
-                       status = subsystems[i].suites[j].fn(argc - 1,
-                                                           argv + 1, prefix);
+                       ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1, prefix);
                        goto end;
                }
 
                if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
-                       dump_suites(i);
+                       dump_benchmarks(coll);
                        goto end;
                }
 
-               printf("Unknown suite:%s for %s\n", argv[1], argv[0]);
-               status = 1;
+               printf("Unknown benchmark: '%s' for collection '%s'\n", argv[1], argv[0]);
+               ret = 1;
                goto end;
        }
 
-       printf("Unknown subsystem:%s\n", argv[0]);
-       status = 1;
+       printf("Unknown collection: '%s'\n", argv[0]);
+       ret = 1;
 
 end:
-       return status;
+       return ret;
 }
index c96c8fa3824353f1c5401cd2a6bacb9701a2762e..cfede86161d8ae9410c123745bb60def09785331 100644 (file)
@@ -6,6 +6,11 @@
  * Copyright (C) 2010, Red Hat Inc.
  * Copyright (C) 2010, Arnaldo Carvalho de Melo <acme@redhat.com>
  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <dirent.h>
+#include <unistd.h>
 #include "builtin.h"
 #include "perf.h"
 #include "util/cache.h"
 #include "util/session.h"
 #include "util/symbol.h"
 
+static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
+{
+       char root_dir[PATH_MAX];
+       char notes[PATH_MAX];
+       u8 build_id[BUILD_ID_SIZE];
+       char *p;
+
+       strlcpy(root_dir, proc_dir, sizeof(root_dir));
+
+       p = strrchr(root_dir, '/');
+       if (!p)
+               return -1;
+       *p = '\0';
+
+       scnprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir);
+
+       if (sysfs__read_build_id(notes, build_id, sizeof(build_id)))
+               return -1;
+
+       build_id__sprintf(build_id, sizeof(build_id), sbuildid);
+
+       return 0;
+}
+
+static int build_id_cache__kcore_dir(char *dir, size_t sz)
+{
+       struct timeval tv;
+       struct tm tm;
+       char dt[32];
+
+       if (gettimeofday(&tv, NULL) || !localtime_r(&tv.tv_sec, &tm))
+               return -1;
+
+       if (!strftime(dt, sizeof(dt), "%Y%m%d%H%M%S", &tm))
+               return -1;
+
+       scnprintf(dir, sz, "%s%02u", dt, (unsigned)tv.tv_usec / 10000);
+
+       return 0;
+}
+
+static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
+                                         size_t to_dir_sz)
+{
+       char from[PATH_MAX];
+       char to[PATH_MAX];
+       struct dirent *dent;
+       int ret = -1;
+       DIR *d;
+
+       d = opendir(to_dir);
+       if (!d)
+               return -1;
+
+       scnprintf(from, sizeof(from), "%s/modules", from_dir);
+
+       while (1) {
+               dent = readdir(d);
+               if (!dent)
+                       break;
+               if (dent->d_type != DT_DIR)
+                       continue;
+               scnprintf(to, sizeof(to), "%s/%s/modules", to_dir,
+                         dent->d_name);
+               if (!compare_proc_modules(from, to)) {
+                       scnprintf(to, sizeof(to), "%s/%s", to_dir,
+                                 dent->d_name);
+                       strlcpy(to_dir, to, to_dir_sz);
+                       ret = 0;
+                       break;
+               }
+       }
+
+       closedir(d);
+
+       return ret;
+}
+
+static int build_id_cache__add_kcore(const char *filename, const char *debugdir)
+{
+       char dir[32], sbuildid[BUILD_ID_SIZE * 2 + 1];
+       char from_dir[PATH_MAX], to_dir[PATH_MAX];
+       char *p;
+
+       strlcpy(from_dir, filename, sizeof(from_dir));
+
+       p = strrchr(from_dir, '/');
+       if (!p || strcmp(p + 1, "kcore"))
+               return -1;
+       *p = '\0';
+
+       if (build_id_cache__kcore_buildid(from_dir, sbuildid))
+               return -1;
+
+       scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s",
+                 debugdir, sbuildid);
+
+       if (!build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
+               pr_debug("same kcore found in %s\n", to_dir);
+               return 0;
+       }
+
+       if (build_id_cache__kcore_dir(dir, sizeof(dir)))
+               return -1;
+
+       scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s/%s",
+                 debugdir, sbuildid, dir);
+
+       if (mkdir_p(to_dir, 0755))
+               return -1;
+
+       if (kcore_copy(from_dir, to_dir)) {
+               /* Remove YYYYmmddHHMMSShh directory */
+               if (!rmdir(to_dir)) {
+                       p = strrchr(to_dir, '/');
+                       if (p)
+                               *p = '\0';
+                       /* Try to remove buildid directory */
+                       if (!rmdir(to_dir)) {
+                               p = strrchr(to_dir, '/');
+                               if (p)
+                                       *p = '\0';
+                               /* Try to remove [kernel.kcore] directory */
+                               rmdir(to_dir);
+                       }
+               }
+               return -1;
+       }
+
+       pr_debug("kcore added to build-id cache directory %s\n", to_dir);
+
+       return 0;
+}
+
 static int build_id_cache__add_file(const char *filename, const char *debugdir)
 {
        char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -82,8 +221,12 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
 
 static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp)
 {
-       struct perf_session *session = perf_session__new(filename, O_RDONLY,
-                                                        force, false, NULL);
+       struct perf_data_file file = {
+               .path  = filename,
+               .mode  = PERF_DATA_MODE_READ,
+               .force = force,
+       };
+       struct perf_session *session = perf_session__new(&file, false, NULL);
        if (session == NULL)
                return -1;
 
@@ -130,11 +273,14 @@ int cmd_buildid_cache(int argc, const char **argv,
        char const *add_name_list_str = NULL,
                   *remove_name_list_str = NULL,
                   *missing_filename = NULL,
-                  *update_name_list_str = NULL;
+                  *update_name_list_str = NULL,
+                  *kcore_filename;
 
        const struct option buildid_cache_options[] = {
        OPT_STRING('a', "add", &add_name_list_str,
                   "file list", "file(s) to add"),
+       OPT_STRING('k', "kcore", &kcore_filename,
+                  "file", "kcore file to add"),
        OPT_STRING('r', "remove", &remove_name_list_str, "file list",
                    "file(s) to remove"),
        OPT_STRING('M', "missing", &missing_filename, "file",
@@ -217,5 +363,9 @@ int cmd_buildid_cache(int argc, const char **argv,
                }
        }
 
+       if (kcore_filename &&
+           build_id_cache__add_kcore(kcore_filename, debugdir))
+               pr_warning("Couldn't add %s\n", kcore_filename);
+
        return ret;
 }
index e74366a13218dbc5da8ef576b298d8bcc21c4ed6..ed3873b3e23873ded61f12486d50bb118c9471b2 100644 (file)
@@ -15,6 +15,7 @@
 #include "util/parse-options.h"
 #include "util/session.h"
 #include "util/symbol.h"
+#include "util/data.h"
 
 static int sysfs__fprintf_build_id(FILE *fp)
 {
@@ -52,6 +53,11 @@ static bool dso__skip_buildid(struct dso *dso, int with_hits)
 static int perf_session__list_build_ids(bool force, bool with_hits)
 {
        struct perf_session *session;
+       struct perf_data_file file = {
+               .path  = input_name,
+               .mode  = PERF_DATA_MODE_READ,
+               .force = force,
+       };
 
        symbol__elf_init();
        /*
@@ -60,15 +66,14 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
        if (filename__fprintf_build_id(input_name, stdout))
                goto out;
 
-       session = perf_session__new(input_name, O_RDONLY, force, false,
-                                   &build_id__mark_dso_hit_ops);
+       session = perf_session__new(&file, false, &build_id__mark_dso_hit_ops);
        if (session == NULL)
                return -1;
        /*
         * in pipe-mode, the only way to get the buildids is to parse
         * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
         */
-       if (with_hits || session->fd_pipe)
+       if (with_hits || perf_data_file__is_pipe(&file))
                perf_session__process_events(session, &build_id__mark_dso_hit_ops);
 
        perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
index f28799e94f2a4bbbb1226da3cd78b908c7b1f610..3b67ea2444bd4abf8314ef5c40c7d4b3e731c455 100644 (file)
@@ -16,6 +16,7 @@
 #include "util/sort.h"
 #include "util/symbol.h"
 #include "util/util.h"
+#include "util/data.h"
 
 #include <stdlib.h>
 #include <math.h>
@@ -42,7 +43,7 @@ struct diff_hpp_fmt {
 
 struct data__file {
        struct perf_session     *session;
-       const char              *file;
+       struct perf_data_file   file;
        int                      idx;
        struct hists            *hists;
        struct diff_hpp_fmt      fmt[PERF_HPP_DIFF__MAX_INDEX];
@@ -302,11 +303,12 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
        return -1;
 }
 
-static int hists__add_entry(struct hists *self,
+static int hists__add_entry(struct hists *hists,
                            struct addr_location *al, u64 period,
-                           u64 weight)
+                           u64 weight, u64 transaction)
 {
-       if (__hists__add_entry(self, al, NULL, period, weight) != NULL)
+       if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight,
+                              transaction) != NULL)
                return 0;
        return -ENOMEM;
 }
@@ -328,7 +330,8 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
        if (al.filtered)
                return 0;
 
-       if (hists__add_entry(&evsel->hists, &al, sample->period, sample->weight)) {
+       if (hists__add_entry(&evsel->hists, &al, sample->period,
+                            sample->weight, sample->transaction)) {
                pr_warning("problem incrementing symbol period, skipping event\n");
                return -1;
        }
@@ -367,7 +370,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
        list_for_each_entry(evsel, &evlist->entries, node) {
                struct hists *hists = &evsel->hists;
 
-               hists__collapse_resort(hists);
+               hists__collapse_resort(hists, NULL);
        }
 }
 
@@ -599,7 +602,7 @@ static void data__fprintf(void)
 
        data__for_each_file(i, d)
                fprintf(stdout, "#  [%d] %s %s\n",
-                       d->idx, d->file,
+                       d->idx, d->file.path,
                        !d->idx ? "(Baseline)" : "");
 
        fprintf(stdout, "#\n");
@@ -661,17 +664,16 @@ static int __cmd_diff(void)
        int ret = -EINVAL, i;
 
        data__for_each_file(i, d) {
-               d->session = perf_session__new(d->file, O_RDONLY, force,
-                                              false, &tool);
+               d->session = perf_session__new(&d->file, false, &tool);
                if (!d->session) {
-                       pr_err("Failed to open %s\n", d->file);
+                       pr_err("Failed to open %s\n", d->file.path);
                        ret = -ENOMEM;
                        goto out_delete;
                }
 
                ret = perf_session__process_events(d->session, &tool);
                if (ret) {
-                       pr_err("Failed to process %s\n", d->file);
+                       pr_err("Failed to process %s\n", d->file.path);
                        goto out_delete;
                }
 
@@ -1014,7 +1016,12 @@ static int data_init(int argc, const char **argv)
                return -ENOMEM;
 
        data__for_each_file(i, d) {
-               d->file = use_default ? defaults[i] : argv[i];
+               struct perf_data_file *file = &d->file;
+
+               file->path  = use_default ? defaults[i] : argv[i];
+               file->mode  = PERF_DATA_MODE_READ,
+               file->force = force,
+
                d->idx  = i;
        }
 
index 05bd9dfe875cb95aeb6d2008b3319c2e8ca8f5eb..20b0f12763b091fd392366865ab113f9aa66a3c7 100644 (file)
 #include "util/parse-events.h"
 #include "util/parse-options.h"
 #include "util/session.h"
+#include "util/data.h"
 
 static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
 {
        struct perf_session *session;
        struct perf_evsel *pos;
+       struct perf_data_file file = {
+               .path = file_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
 
-       session = perf_session__new(file_name, O_RDONLY, 0, false, NULL);
+       session = perf_session__new(&file, 0, NULL);
        if (session == NULL)
                return -ENOMEM;
 
index afe377b2884f740b0c469a367ab3938d99f7df0e..6a2508589460bfc1fec37c10163cf44b95a2ddfc 100644 (file)
@@ -15,6 +15,7 @@
 #include "util/tool.h"
 #include "util/debug.h"
 #include "util/build-id.h"
+#include "util/data.h"
 
 #include "util/parse-options.h"
 
@@ -71,12 +72,17 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
                                   union perf_event *event,
                                   struct perf_evlist **pevlist)
 {
+       struct perf_inject *inject = container_of(tool, struct perf_inject,
+                                                 tool);
        int ret;
 
        ret = perf_event__process_attr(tool, event, pevlist);
        if (ret)
                return ret;
 
+       if (!inject->pipe_output)
+               return 0;
+
        return perf_event__repipe_synth(tool, event);
 }
 
@@ -100,8 +106,8 @@ static int perf_event__repipe_sample(struct perf_tool *tool,
                                     struct perf_evsel *evsel,
                                     struct machine *machine)
 {
-       if (evsel->handler.func) {
-               inject_handler f = evsel->handler.func;
+       if (evsel->handler) {
+               inject_handler f = evsel->handler;
                return f(tool, event, sample, evsel, machine);
        }
 
@@ -161,38 +167,38 @@ static int perf_event__repipe_tracing_data(struct perf_tool *tool,
        return err;
 }
 
-static int dso__read_build_id(struct dso *self)
+static int dso__read_build_id(struct dso *dso)
 {
-       if (self->has_build_id)
+       if (dso->has_build_id)
                return 0;
 
-       if (filename__read_build_id(self->long_name, self->build_id,
-                                   sizeof(self->build_id)) > 0) {
-               self->has_build_id = true;
+       if (filename__read_build_id(dso->long_name, dso->build_id,
+                                   sizeof(dso->build_id)) > 0) {
+               dso->has_build_id = true;
                return 0;
        }
 
        return -1;
 }
 
-static int dso__inject_build_id(struct dso *self, struct perf_tool *tool,
+static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
                                struct machine *machine)
 {
        u16 misc = PERF_RECORD_MISC_USER;
        int err;
 
-       if (dso__read_build_id(self) < 0) {
-               pr_debug("no build_id found for %s\n", self->long_name);
+       if (dso__read_build_id(dso) < 0) {
+               pr_debug("no build_id found for %s\n", dso->long_name);
                return -1;
        }
 
-       if (self->kernel)
+       if (dso->kernel)
                misc = PERF_RECORD_MISC_KERNEL;
 
-       err = perf_event__synthesize_build_id(tool, self, misc, perf_event__repipe,
+       err = perf_event__synthesize_build_id(tool, dso, misc, perf_event__repipe,
                                              machine);
        if (err) {
-               pr_err("Can't synthesize build_id event for %s\n", self->long_name);
+               pr_err("Can't synthesize build_id event for %s\n", dso->long_name);
                return -1;
        }
 
@@ -231,7 +237,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
                                 * account this as unresolved.
                                 */
                        } else {
-#ifdef LIBELF_SUPPORT
+#ifdef HAVE_LIBELF_SUPPORT
                                pr_warning("no symbols found in %s, maybe "
                                           "install a debug package?\n",
                                           al.map->dso->long_name);
@@ -345,6 +351,10 @@ static int __cmd_inject(struct perf_inject *inject)
 {
        struct perf_session *session;
        int ret = -EINVAL;
+       struct perf_data_file file = {
+               .path = inject->input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
 
        signal(SIGINT, sig_handler);
 
@@ -355,7 +365,7 @@ static int __cmd_inject(struct perf_inject *inject)
                inject->tool.tracing_data = perf_event__repipe_tracing_data;
        }
 
-       session = perf_session__new(inject->input_name, O_RDONLY, false, true, &inject->tool);
+       session = perf_session__new(&file, true, &inject->tool);
        if (session == NULL)
                return -ENOMEM;
 
@@ -373,11 +383,11 @@ static int __cmd_inject(struct perf_inject *inject)
                                if (perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
                                        return -EINVAL;
 
-                               evsel->handler.func = perf_inject__sched_switch;
+                               evsel->handler = perf_inject__sched_switch;
                        } else if (!strcmp(name, "sched:sched_process_exit"))
-                               evsel->handler.func = perf_inject__sched_process_exit;
+                               evsel->handler = perf_inject__sched_process_exit;
                        else if (!strncmp(name, "sched:sched_stat_", 17))
-                               evsel->handler.func = perf_inject__sched_stat;
+                               evsel->handler = perf_inject__sched_stat;
                }
        }
 
index 9b5f077fee5b1b65a4e51b48ef1af0727b8c134b..929462aa494351f5f237eaa03ce0042146853945 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "util/parse-options.h"
 #include "util/trace-event.h"
+#include "util/data.h"
 
 #include "util/debug.h"
 
@@ -314,10 +315,10 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
                return -1;
        }
 
-       dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
+       dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
 
-       if (evsel->handler.func != NULL) {
-               tracepoint_handler f = evsel->handler.func;
+       if (evsel->handler != NULL) {
+               tracepoint_handler f = evsel->handler;
                return f(evsel, sample);
        }
 
@@ -486,8 +487,12 @@ static int __cmd_kmem(void)
                { "kmem:kfree",                 perf_evsel__process_free_event, },
                { "kmem:kmem_cache_free",       perf_evsel__process_free_event, },
        };
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
 
-       session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem);
+       session = perf_session__new(&file, false, &perf_kmem);
        if (session == NULL)
                return -ENOMEM;
 
index fbc2888d64950040d3f56444d11bc0e828396b31..cd9f92078aba2e42aaadb8b48f7dad04e23f3485 100644 (file)
 #include "util/tool.h"
 #include "util/stat.h"
 #include "util/top.h"
+#include "util/data.h"
 
 #include <sys/prctl.h>
+#ifdef HAVE_TIMERFD_SUPPORT
 #include <sys/timerfd.h>
+#endif
 
 #include <termios.h>
 #include <semaphore.h>
@@ -336,6 +339,7 @@ static void init_kvm_event_record(struct perf_kvm_stat *kvm)
                INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
 }
 
+#ifdef HAVE_TIMERFD_SUPPORT
 static void clear_events_cache_stats(struct list_head *kvm_events_cache)
 {
        struct list_head *head;
@@ -357,6 +361,7 @@ static void clear_events_cache_stats(struct list_head *kvm_events_cache)
                }
        }
 }
+#endif
 
 static int kvm_events_hash_fn(u64 key)
 {
@@ -782,6 +787,7 @@ static void print_result(struct perf_kvm_stat *kvm)
                pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
 }
 
+#ifdef HAVE_TIMERFD_SUPPORT
 static int process_lost_event(struct perf_tool *tool,
                              union perf_event *event __maybe_unused,
                              struct perf_sample *sample __maybe_unused,
@@ -792,6 +798,7 @@ static int process_lost_event(struct perf_tool *tool,
        kvm->lost_events++;
        return 0;
 }
+#endif
 
 static bool skip_sample(struct perf_kvm_stat *kvm,
                        struct perf_sample *sample)
@@ -871,6 +878,7 @@ static bool verify_vcpu(int vcpu)
        return true;
 }
 
+#ifdef HAVE_TIMERFD_SUPPORT
 /* keeping the max events to a modest level to keep
  * the processing of samples per mmap smooth.
  */
@@ -1212,6 +1220,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
 out:
        return rc;
 }
+#endif
 
 static int read_events(struct perf_kvm_stat *kvm)
 {
@@ -1222,10 +1231,13 @@ static int read_events(struct perf_kvm_stat *kvm)
                .comm                   = perf_event__process_comm,
                .ordered_samples        = true,
        };
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
 
        kvm->tool = eops;
-       kvm->session = perf_session__new(kvm->file_name, O_RDONLY, 0, false,
-                                        &kvm->tool);
+       kvm->session = perf_session__new(&file, false, &kvm->tool);
        if (!kvm->session) {
                pr_err("Initializing perf session failed\n");
                return -EINVAL;
@@ -1375,6 +1387,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
        return kvm_events_report_vcpu(kvm);
 }
 
+#ifdef HAVE_TIMERFD_SUPPORT
 static struct perf_evlist *kvm_live_event_list(void)
 {
        struct perf_evlist *evlist;
@@ -1433,8 +1446,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
        const struct option live_options[] = {
                OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
                        "record events on existing process id"),
-               OPT_UINTEGER('m', "mmap-pages", &kvm->opts.mmap_pages,
-                       "number of mmap data pages"),
+               OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages",
+                       "number of mmap data pages",
+                       perf_evlist__parse_mmap_pages),
                OPT_INCR('v', "verbose", &verbose,
                        "be more verbose (show counter open errors, etc)"),
                OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
@@ -1456,6 +1470,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
                "perf kvm stat live [<options>]",
                NULL
        };
+       struct perf_data_file file = {
+               .mode = PERF_DATA_MODE_WRITE,
+       };
 
 
        /* event handling */
@@ -1520,7 +1537,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
        /*
         * perf session
         */
-       kvm->session = perf_session__new(NULL, O_WRONLY, false, false, &kvm->tool);
+       kvm->session = perf_session__new(&file, false, &kvm->tool);
        if (kvm->session == NULL) {
                err = -ENOMEM;
                goto out;
@@ -1558,6 +1575,7 @@ out:
 
        return err;
 }
+#endif
 
 static void print_kvm_stat_usage(void)
 {
@@ -1596,8 +1614,10 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
        if (!strncmp(argv[1], "rep", 3))
                return kvm_events_report(&kvm, argc - 1 , argv + 1);
 
+#ifdef HAVE_TIMERFD_SUPPORT
        if (!strncmp(argv[1], "live", 4))
                return kvm_events_live(&kvm, argc - 1 , argv + 1);
+#endif
 
 perf_stat:
        return cmd_stat(argc, argv, NULL);
index e79f423cc3022fff357e132d11d573a66f5ad7a6..011195e38f2173947550100e62927e908b429d30 100644 (file)
 #include "util/parse-events.h"
 #include "util/cache.h"
 #include "util/pmu.h"
+#include "util/parse-options.h"
 
 int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 {
+       int i;
+       const struct option list_options[] = {
+               OPT_END()
+       };
+       const char * const list_usage[] = {
+               "perf list [hw|sw|cache|tracepoint|pmu|event_glob]",
+               NULL
+       };
+
+       argc = parse_options(argc, argv, list_options, list_usage,
+                            PARSE_OPT_STOP_AT_NON_OPTION);
+
        setup_pager();
 
-       if (argc == 1)
+       if (argc == 0) {
                print_events(NULL, false);
-       else {
-               int i;
-
-               for (i = 1; i < argc; ++i) {
-                       if (i > 2)
-                               putchar('\n');
-                       if (strncmp(argv[i], "tracepoint", 10) == 0)
-                               print_tracepoint_events(NULL, NULL, false);
-                       else if (strcmp(argv[i], "hw") == 0 ||
-                                strcmp(argv[i], "hardware") == 0)
-                               print_events_type(PERF_TYPE_HARDWARE);
-                       else if (strcmp(argv[i], "sw") == 0 ||
-                                strcmp(argv[i], "software") == 0)
-                               print_events_type(PERF_TYPE_SOFTWARE);
-                       else if (strcmp(argv[i], "cache") == 0 ||
-                                strcmp(argv[i], "hwcache") == 0)
-                               print_hwcache_events(NULL, false);
-                       else if (strcmp(argv[i], "pmu") == 0)
-                               print_pmu_events(NULL, false);
-                       else if (strcmp(argv[i], "--raw-dump") == 0)
-                               print_events(NULL, true);
-                       else {
-                               char *sep = strchr(argv[i], ':'), *s;
-                               int sep_idx;
+               return 0;
+       }
 
-                               if (sep == NULL) {
-                                       print_events(argv[i], false);
-                                       continue;
-                               }
-                               sep_idx = sep - argv[i];
-                               s = strdup(argv[i]);
-                               if (s == NULL)
-                                       return -1;
+       for (i = 0; i < argc; ++i) {
+               if (i)
+                       putchar('\n');
+               if (strncmp(argv[i], "tracepoint", 10) == 0)
+                       print_tracepoint_events(NULL, NULL, false);
+               else if (strcmp(argv[i], "hw") == 0 ||
+                        strcmp(argv[i], "hardware") == 0)
+                       print_events_type(PERF_TYPE_HARDWARE);
+               else if (strcmp(argv[i], "sw") == 0 ||
+                        strcmp(argv[i], "software") == 0)
+                       print_events_type(PERF_TYPE_SOFTWARE);
+               else if (strcmp(argv[i], "cache") == 0 ||
+                        strcmp(argv[i], "hwcache") == 0)
+                       print_hwcache_events(NULL, false);
+               else if (strcmp(argv[i], "pmu") == 0)
+                       print_pmu_events(NULL, false);
+               else if (strcmp(argv[i], "--raw-dump") == 0)
+                       print_events(NULL, true);
+               else {
+                       char *sep = strchr(argv[i], ':'), *s;
+                       int sep_idx;
 
-                               s[sep_idx] = '\0';
-                               print_tracepoint_events(s, s + sep_idx + 1, false);
-                               free(s);
+                       if (sep == NULL) {
+                               print_events(argv[i], false);
+                               continue;
                        }
+                       sep_idx = sep - argv[i];
+                       s = strdup(argv[i]);
+                       if (s == NULL)
+                               return -1;
+
+                       s[sep_idx] = '\0';
+                       print_tracepoint_events(s, s + sep_idx + 1, false);
+                       free(s);
                }
        }
        return 0;
index ee33ba2f05dd8b2f1f9c90f1820e0eab93b86f8b..c852c7a85d3236e86781b15616858a76b56c6206 100644 (file)
@@ -15,6 +15,7 @@
 #include "util/debug.h"
 #include "util/session.h"
 #include "util/tool.h"
+#include "util/data.h"
 
 #include <sys/types.h>
 #include <sys/prctl.h>
@@ -56,7 +57,9 @@ struct lock_stat {
 
        unsigned int            nr_readlock;
        unsigned int            nr_trylock;
+
        /* these times are in nano sec. */
+       u64                     avg_wait_time;
        u64                     wait_time_total;
        u64                     wait_time_min;
        u64                     wait_time_max;
@@ -208,6 +211,7 @@ static struct thread_stat *thread_stat_findnew_first(u32 tid)
 
 SINGLE_KEY(nr_acquired)
 SINGLE_KEY(nr_contended)
+SINGLE_KEY(avg_wait_time)
 SINGLE_KEY(wait_time_total)
 SINGLE_KEY(wait_time_max)
 
@@ -244,6 +248,7 @@ static struct rb_root               result; /* place to store sorted data */
 struct lock_key keys[] = {
        DEF_KEY_LOCK(acquired, nr_acquired),
        DEF_KEY_LOCK(contended, nr_contended),
+       DEF_KEY_LOCK(avg_wait, avg_wait_time),
        DEF_KEY_LOCK(wait_total, wait_time_total),
        DEF_KEY_LOCK(wait_min, wait_time_min),
        DEF_KEY_LOCK(wait_max, wait_time_max),
@@ -321,10 +326,12 @@ static struct lock_stat *lock_stat_findnew(void *addr, const char *name)
 
        new->addr = addr;
        new->name = zalloc(sizeof(char) * strlen(name) + 1);
-       if (!new->name)
+       if (!new->name) {
+               free(new);
                goto alloc_failed;
-       strcpy(new->name, name);
+       }
 
+       strcpy(new->name, name);
        new->wait_time_min = ULLONG_MAX;
 
        list_add(&new->hash_entry, entry);
@@ -400,17 +407,17 @@ static int report_lock_acquire_event(struct perf_evsel *evsel,
 
        ls = lock_stat_findnew(addr, name);
        if (!ls)
-               return -1;
+               return -ENOMEM;
        if (ls->discard)
                return 0;
 
        ts = thread_stat_findnew(sample->tid);
        if (!ts)
-               return -1;
+               return -ENOMEM;
 
        seq = get_seq(ts, addr);
        if (!seq)
-               return -1;
+               return -ENOMEM;
 
        switch (seq->state) {
        case SEQ_STATE_UNINITIALIZED:
@@ -446,7 +453,6 @@ broken:
                list_del(&seq->list);
                free(seq);
                goto end;
-               break;
        default:
                BUG_ON("Unknown state of lock sequence found!\n");
                break;
@@ -473,17 +479,17 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
 
        ls = lock_stat_findnew(addr, name);
        if (!ls)
-               return -1;
+               return -ENOMEM;
        if (ls->discard)
                return 0;
 
        ts = thread_stat_findnew(sample->tid);
        if (!ts)
-               return -1;
+               return -ENOMEM;
 
        seq = get_seq(ts, addr);
        if (!seq)
-               return -1;
+               return -ENOMEM;
 
        switch (seq->state) {
        case SEQ_STATE_UNINITIALIZED:
@@ -508,8 +514,6 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
                list_del(&seq->list);
                free(seq);
                goto end;
-               break;
-
        default:
                BUG_ON("Unknown state of lock sequence found!\n");
                break;
@@ -517,6 +521,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
 
        seq->state = SEQ_STATE_ACQUIRED;
        ls->nr_acquired++;
+       ls->avg_wait_time = ls->nr_contended ? ls->wait_time_total/ls->nr_contended : 0;
        seq->prev_event_time = sample->time;
 end:
        return 0;
@@ -536,17 +541,17 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
 
        ls = lock_stat_findnew(addr, name);
        if (!ls)
-               return -1;
+               return -ENOMEM;
        if (ls->discard)
                return 0;
 
        ts = thread_stat_findnew(sample->tid);
        if (!ts)
-               return -1;
+               return -ENOMEM;
 
        seq = get_seq(ts, addr);
        if (!seq)
-               return -1;
+               return -ENOMEM;
 
        switch (seq->state) {
        case SEQ_STATE_UNINITIALIZED:
@@ -564,7 +569,6 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
                list_del(&seq->list);
                free(seq);
                goto end;
-               break;
        default:
                BUG_ON("Unknown state of lock sequence found!\n");
                break;
@@ -572,6 +576,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
 
        seq->state = SEQ_STATE_CONTENDED;
        ls->nr_contended++;
+       ls->avg_wait_time = ls->wait_time_total/ls->nr_contended;
        seq->prev_event_time = sample->time;
 end:
        return 0;
@@ -591,22 +596,21 @@ static int report_lock_release_event(struct perf_evsel *evsel,
 
        ls = lock_stat_findnew(addr, name);
        if (!ls)
-               return -1;
+               return -ENOMEM;
        if (ls->discard)
                return 0;
 
        ts = thread_stat_findnew(sample->tid);
        if (!ts)
-               return -1;
+               return -ENOMEM;
 
        seq = get_seq(ts, addr);
        if (!seq)
-               return -1;
+               return -ENOMEM;
 
        switch (seq->state) {
        case SEQ_STATE_UNINITIALIZED:
                goto end;
-               break;
        case SEQ_STATE_ACQUIRED:
                break;
        case SEQ_STATE_READ_ACQUIRED:
@@ -624,7 +628,6 @@ static int report_lock_release_event(struct perf_evsel *evsel,
                ls->discard = 1;
                bad_hist[BROKEN_RELEASE]++;
                goto free_seq;
-               break;
        default:
                BUG_ON("Unknown state of lock sequence found!\n");
                break;
@@ -690,7 +693,7 @@ static void print_bad_events(int bad, int total)
 
        pr_info("\n=== output for debug===\n\n");
        pr_info("bad: %d, total: %d\n", bad, total);
-       pr_info("bad rate: %f %%\n", (double)bad / (double)total * 100);
+       pr_info("bad rate: %.2f %%\n", (double)bad / (double)total * 100);
        pr_info("histogram of events caused bad sequence\n");
        for (i = 0; i < BROKEN_MAX; i++)
                pr_info(" %10s: %d\n", name[i], bad_hist[i]);
@@ -707,6 +710,7 @@ static void print_result(void)
        pr_info("%10s ", "acquired");
        pr_info("%10s ", "contended");
 
+       pr_info("%15s ", "avg wait (ns)");
        pr_info("%15s ", "total wait (ns)");
        pr_info("%15s ", "max wait (ns)");
        pr_info("%15s ", "min wait (ns)");
@@ -738,6 +742,7 @@ static void print_result(void)
                pr_info("%10u ", st->nr_acquired);
                pr_info("%10u ", st->nr_contended);
 
+               pr_info("%15" PRIu64 " ", st->avg_wait_time);
                pr_info("%15" PRIu64 " ", st->wait_time_total);
                pr_info("%15" PRIu64 " ", st->wait_time_max);
                pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ?
@@ -762,7 +767,7 @@ static void dump_threads(void)
        while (node) {
                st = container_of(node, struct thread_stat, rb);
                t = perf_session__findnew(session, st->tid);
-               pr_info("%10d: %s\n", st->tid, t->comm);
+               pr_info("%10d: %s\n", st->tid, thread__comm_str(t));
                node = rb_next(node);
        };
 }
@@ -814,14 +819,26 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
                return -1;
        }
 
-       if (evsel->handler.func != NULL) {
-               tracepoint_handler f = evsel->handler.func;
+       if (evsel->handler != NULL) {
+               tracepoint_handler f = evsel->handler;
                return f(evsel, sample);
        }
 
        return 0;
 }
 
+static void sort_result(void)
+{
+       unsigned int i;
+       struct lock_stat *st;
+
+       for (i = 0; i < LOCKHASH_SIZE; i++) {
+               list_for_each_entry(st, &lockhash_table[i], hash_entry) {
+                       insert_to_result(st, compare);
+               }
+       }
+}
+
 static const struct perf_evsel_str_handler lock_tracepoints[] = {
        { "lock:lock_acquire",   perf_evsel__process_lock_acquire,   }, /* CONFIG_LOCKDEP */
        { "lock:lock_acquired",  perf_evsel__process_lock_acquired,  }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
@@ -829,51 +846,51 @@ static const struct perf_evsel_str_handler lock_tracepoints[] = {
        { "lock:lock_release",   perf_evsel__process_lock_release,   }, /* CONFIG_LOCKDEP */
 };
 
-static int read_events(void)
+static int __cmd_report(bool display_info)
 {
+       int err = -EINVAL;
        struct perf_tool eops = {
                .sample          = process_sample_event,
                .comm            = perf_event__process_comm,
                .ordered_samples = true,
        };
-       session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
+
+       session = perf_session__new(&file, false, &eops);
        if (!session) {
                pr_err("Initializing perf session failed\n");
-               return -1;
+               return -ENOMEM;
        }
 
+       if (!perf_session__has_traces(session, "lock record"))
+               goto out_delete;
+
        if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
                pr_err("Initializing perf session tracepoint handlers failed\n");
-               return -1;
+               goto out_delete;
        }
 
-       return perf_session__process_events(session, &eops);
-}
-
-static void sort_result(void)
-{
-       unsigned int i;
-       struct lock_stat *st;
+       if (select_key())
+               goto out_delete;
 
-       for (i = 0; i < LOCKHASH_SIZE; i++) {
-               list_for_each_entry(st, &lockhash_table[i], hash_entry) {
-                       insert_to_result(st, compare);
-               }
-       }
-}
+       err = perf_session__process_events(session, &eops);
+       if (err)
+               goto out_delete;
 
-static int __cmd_report(void)
-{
        setup_pager();
+       if (display_info) /* used for info subcommand */
+               err = dump_info();
+       else {
+               sort_result();
+               print_result();
+       }
 
-       if ((select_key() != 0) ||
-           (read_events() != 0))
-               return -1;
-
-       sort_result();
-       print_result();
-
-       return 0;
+out_delete:
+       perf_session__delete(session);
+       return err;
 }
 
 static int __cmd_record(int argc, const char **argv)
@@ -881,7 +898,7 @@ static int __cmd_record(int argc, const char **argv)
        const char *record_args[] = {
                "record", "-R", "-m", "1024", "-c", "1",
        };
-       unsigned int rec_argc, i, j;
+       unsigned int rec_argc, i, j, ret;
        const char **rec_argv;
 
        for (i = 0; i < ARRAY_SIZE(lock_tracepoints); i++) {
@@ -898,7 +915,7 @@ static int __cmd_record(int argc, const char **argv)
        rec_argc += 2 * ARRAY_SIZE(lock_tracepoints);
 
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
-       if (rec_argv == NULL)
+       if (!rec_argv)
                return -ENOMEM;
 
        for (i = 0; i < ARRAY_SIZE(record_args); i++)
@@ -914,7 +931,9 @@ static int __cmd_record(int argc, const char **argv)
 
        BUG_ON(i != rec_argc);
 
-       return cmd_record(i, rec_argv, NULL);
+       ret = cmd_record(i, rec_argv, NULL);
+       free(rec_argv);
+       return ret;
 }
 
 int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
@@ -934,7 +953,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
        };
        const struct option report_options[] = {
        OPT_STRING('k', "key", &sort_key, "acquired",
-                   "key for sorting (acquired / contended / wait_total / wait_max / wait_min)"),
+                   "key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
        /* TODO: type */
        OPT_END()
        };
@@ -972,7 +991,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
                        if (argc)
                                usage_with_options(report_usage, report_options);
                }
-               __cmd_report();
+               rc = __cmd_report(false);
        } else if (!strcmp(argv[0], "script")) {
                /* Aliased to 'perf script' */
                return cmd_script(argc, argv, prefix);
@@ -985,11 +1004,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
                }
                /* recycling report_lock_ops */
                trace_handler = &report_lock_ops;
-               setup_pager();
-               if (read_events() != 0)
-                       rc = -1;
-               else
-                       rc = dump_info();
+               rc = __cmd_report(true);
        } else {
                usage_with_options(lock_usage, lock_options);
        }
index 253133a6251d3c3d657671b7a8a603ef4cb03643..31c00f186da127fa6fca4157d839426886008c07 100644 (file)
@@ -5,6 +5,7 @@
 #include "util/trace-event.h"
 #include "util/tool.h"
 #include "util/session.h"
+#include "util/data.h"
 
 #define MEM_OPERATION_LOAD     "load"
 #define MEM_OPERATION_STORE    "store"
@@ -119,10 +120,14 @@ static int process_sample_event(struct perf_tool *tool,
 
 static int report_raw_events(struct perf_mem *mem)
 {
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
        int err = -EINVAL;
        int ret;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY,
-                                                        0, false, &mem->tool);
+       struct perf_session *session = perf_session__new(&file, false,
+                                                        &mem->tool);
 
        if (session == NULL)
                return -ENOMEM;
index e8a66f9a67153c6819422839a55bd1ae5f7d4fce..89acc17cf2a02e4c7d8760a7b89e1300007cc5a3 100644 (file)
@@ -173,7 +173,7 @@ static int opt_set_target(const struct option *opt, const char *str,
        if  (str && !params.target) {
                if (!strcmp(opt->long_name, "exec"))
                        params.uprobes = true;
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
                else if (!strcmp(opt->long_name, "module"))
                        params.uprobes = false;
 #endif
@@ -187,7 +187,7 @@ static int opt_set_target(const struct option *opt, const char *str,
        return ret;
 }
 
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
 static int opt_show_lines(const struct option *opt __maybe_unused,
                          const char *str, int unset __maybe_unused)
 {
@@ -257,7 +257,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
                "perf probe [<options>] --del '[GROUP:]EVENT' ...",
                "perf probe --list",
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
                "perf probe [<options>] --line 'LINEDESC'",
                "perf probe [<options>] --vars 'PROBEPOINT'",
 #endif
@@ -271,7 +271,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
                opt_del_probe_event),
        OPT_CALLBACK('a', "add", NULL,
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
                "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
                " [[NAME=]ARG ...]",
 #else
@@ -283,7 +283,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                "\t\tFUNC:\tFunction name\n"
                "\t\tOFF:\tOffset from function entry (in byte)\n"
                "\t\t%return:\tPut the probe at function return\n"
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
                "\t\tSRC:\tSource code path\n"
                "\t\tRL:\tRelative line number from function entry.\n"
                "\t\tAL:\tAbsolute line number in file.\n"
@@ -296,7 +296,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                opt_add_probe_event),
        OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
                    " with existing name"),
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
        OPT_CALLBACK('L', "line", NULL,
                     "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
                     "Show source code lines.", opt_show_lines),
@@ -408,7 +408,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                return ret;
        }
 
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
        if (params.show_lines && !params.uprobes) {
                if (params.mod_events) {
                        pr_err("  Error: Don't use --line with"
index d0465148464022c82e5fcfb431513624edf34740..15280b5e5574669c78376a419a8512eb5e774258 100644 (file)
 #include "util/symbol.h"
 #include "util/cpumap.h"
 #include "util/thread_map.h"
+#include "util/data.h"
 
 #include <unistd.h>
 #include <sched.h>
 #include <sys/mman.h>
 
-#ifndef HAVE_ON_EXIT
+#ifndef HAVE_ON_EXIT_SUPPORT
 #ifndef ATEXIT_MAX
 #define ATEXIT_MAX 32
 #endif
@@ -65,31 +66,25 @@ struct perf_record {
        struct perf_tool        tool;
        struct perf_record_opts opts;
        u64                     bytes_written;
-       const char              *output_name;
+       struct perf_data_file   file;
        struct perf_evlist      *evlist;
        struct perf_session     *session;
        const char              *progname;
-       int                     output;
-       unsigned int            page_size;
        int                     realtime_prio;
        bool                    no_buildid;
        bool                    no_buildid_cache;
        long                    samples;
-       off_t                   post_processing_offset;
 };
 
-static void advance_output(struct perf_record *rec, size_t size)
-{
-       rec->bytes_written += size;
-}
-
 static int write_output(struct perf_record *rec, void *buf, size_t size)
 {
+       struct perf_data_file *file = &rec->file;
+
        while (size) {
-               int ret = write(rec->output, buf, size);
+               int ret = write(file->fd, buf, size);
 
                if (ret < 0) {
-                       pr_err("failed to write\n");
+                       pr_err("failed to write perf data, error: %m\n");
                        return -1;
                }
 
@@ -119,7 +114,7 @@ static int perf_record__mmap_read(struct perf_record *rec,
 {
        unsigned int head = perf_mmap__read_head(md);
        unsigned int old = md->prev;
-       unsigned char *data = md->base + rec->page_size;
+       unsigned char *data = md->base + page_size;
        unsigned long size;
        void *buf;
        int rc = 0;
@@ -234,10 +229,6 @@ try_again:
                               "or try again with a smaller value of -m/--mmap_pages.\n"
                               "(current value: %d)\n", opts->mmap_pages);
                        rc = -errno;
-               } else if (!is_power_of_2(opts->mmap_pages) &&
-                          (opts->mmap_pages != UINT_MAX)) {
-                       pr_err("--mmap_pages/-m value must be a power of two.");
-                       rc = -EINVAL;
                } else {
                        pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
                        rc = -errno;
@@ -253,31 +244,34 @@ out:
 
 static int process_buildids(struct perf_record *rec)
 {
-       u64 size = lseek(rec->output, 0, SEEK_CUR);
+       struct perf_data_file *file  = &rec->file;
+       struct perf_session *session = rec->session;
+       u64 start = session->header.data_offset;
 
+       u64 size = lseek(file->fd, 0, SEEK_CUR);
        if (size == 0)
                return 0;
 
-       rec->session->fd = rec->output;
-       return __perf_session__process_events(rec->session, rec->post_processing_offset,
-                                             size - rec->post_processing_offset,
+       return __perf_session__process_events(session, start,
+                                             size - start,
                                              size, &build_id__mark_dso_hit_ops);
 }
 
 static void perf_record__exit(int status, void *arg)
 {
        struct perf_record *rec = arg;
+       struct perf_data_file *file = &rec->file;
 
        if (status != 0)
                return;
 
-       if (!rec->opts.pipe_output) {
+       if (!file->is_pipe) {
                rec->session->header.data_size += rec->bytes_written;
 
                if (!rec->no_buildid)
                        process_buildids(rec);
                perf_session__write_header(rec->session, rec->evlist,
-                                          rec->output, true);
+                                          file->fd, true);
                perf_session__delete(rec->session);
                perf_evlist__delete(rec->evlist);
                symbol__exit();
@@ -343,64 +337,47 @@ out:
        return rc;
 }
 
+static void perf_record__init_features(struct perf_record *rec)
+{
+       struct perf_evlist *evsel_list = rec->evlist;
+       struct perf_session *session = rec->session;
+       int feat;
+
+       for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
+               perf_header__set_feat(&session->header, feat);
+
+       if (rec->no_buildid)
+               perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
+
+       if (!have_tracepoints(&evsel_list->entries))
+               perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
+
+       if (!rec->opts.branch_stack)
+               perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
+}
+
 static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 {
-       struct stat st;
-       int flags;
-       int err, output, feat;
+       int err;
        unsigned long waking = 0;
        const bool forks = argc > 0;
        struct machine *machine;
        struct perf_tool *tool = &rec->tool;
        struct perf_record_opts *opts = &rec->opts;
        struct perf_evlist *evsel_list = rec->evlist;
-       const char *output_name = rec->output_name;
+       struct perf_data_file *file = &rec->file;
        struct perf_session *session;
        bool disabled = false;
 
        rec->progname = argv[0];
 
-       rec->page_size = sysconf(_SC_PAGE_SIZE);
-
        on_exit(perf_record__sig_exit, rec);
        signal(SIGCHLD, sig_handler);
        signal(SIGINT, sig_handler);
        signal(SIGUSR1, sig_handler);
        signal(SIGTERM, sig_handler);
 
-       if (!output_name) {
-               if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
-                       opts->pipe_output = true;
-               else
-                       rec->output_name = output_name = "perf.data";
-       }
-       if (output_name) {
-               if (!strcmp(output_name, "-"))
-                       opts->pipe_output = true;
-               else if (!stat(output_name, &st) && st.st_size) {
-                       char oldname[PATH_MAX];
-                       snprintf(oldname, sizeof(oldname), "%s.old",
-                                output_name);
-                       unlink(oldname);
-                       rename(output_name, oldname);
-               }
-       }
-
-       flags = O_CREAT|O_RDWR|O_TRUNC;
-
-       if (opts->pipe_output)
-               output = STDOUT_FILENO;
-       else
-               output = open(output_name, flags, S_IRUSR | S_IWUSR);
-       if (output < 0) {
-               perror("failed to create output file");
-               return -1;
-       }
-
-       rec->output = output;
-
-       session = perf_session__new(output_name, O_WRONLY,
-                                   true, false, NULL);
+       session = perf_session__new(file, false, NULL);
        if (session == NULL) {
                pr_err("Not enough memory for reading perf file header\n");
                return -1;
@@ -408,21 +385,11 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 
        rec->session = session;
 
-       for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
-               perf_header__set_feat(&session->header, feat);
-
-       if (rec->no_buildid)
-               perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
-
-       if (!have_tracepoints(&evsel_list->entries))
-               perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
-
-       if (!rec->opts.branch_stack)
-               perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
+       perf_record__init_features(rec);
 
        if (forks) {
                err = perf_evlist__prepare_workload(evsel_list, &opts->target,
-                                                   argv, opts->pipe_output,
+                                                   argv, file->is_pipe,
                                                    true);
                if (err < 0) {
                        pr_err("Couldn't run the workload!\n");
@@ -443,13 +410,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
         */
        on_exit(perf_record__exit, rec);
 
-       if (opts->pipe_output) {
-               err = perf_header__write_pipe(output);
+       if (file->is_pipe) {
+               err = perf_header__write_pipe(file->fd);
                if (err < 0)
                        goto out_delete_session;
        } else {
                err = perf_session__write_header(session, evsel_list,
-                                                output, false);
+                                                file->fd, false);
                if (err < 0)
                        goto out_delete_session;
        }
@@ -462,11 +429,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
                goto out_delete_session;
        }
 
-       rec->post_processing_offset = lseek(output, 0, SEEK_CUR);
-
        machine = &session->machines.host;
 
-       if (opts->pipe_output) {
+       if (file->is_pipe) {
                err = perf_event__synthesize_attrs(tool, session,
                                                   process_synthesized_event);
                if (err < 0) {
@@ -483,13 +448,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
                         * return this more properly and also
                         * propagate errors that now are calling die()
                         */
-                       err = perf_event__synthesize_tracing_data(tool, output, evsel_list,
+                       err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
                                                                  process_synthesized_event);
                        if (err <= 0) {
                                pr_err("Couldn't record tracing data.\n");
                                goto out_delete_session;
                        }
-                       advance_output(rec, err);
+                       rec->bytes_written += err;
                }
        }
 
@@ -590,7 +555,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
        fprintf(stderr,
                "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
                (double)rec->bytes_written / 1024.0 / 1024.0,
-               output_name,
+               file->path,
                rec->bytes_written / 24);
 
        return 0;
@@ -618,6 +583,9 @@ static const struct branch_mode branch_modes[] = {
        BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
        BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
        BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
+       BRANCH_OPT("abort_tx", PERF_SAMPLE_BRANCH_ABORT_TX),
+       BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX),
+       BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
        BRANCH_END
 };
 
@@ -684,7 +652,7 @@ error:
        return ret;
 }
 
-#ifdef LIBUNWIND_SUPPORT
+#ifdef HAVE_LIBUNWIND_SUPPORT
 static int get_stack_size(char *str, unsigned long *_size)
 {
        char *endptr;
@@ -710,7 +678,7 @@ static int get_stack_size(char *str, unsigned long *_size)
               max_size, str);
        return -1;
 }
-#endif /* LIBUNWIND_SUPPORT */
+#endif /* HAVE_LIBUNWIND_SUPPORT */
 
 int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
 {
@@ -739,7 +707,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
                                       "needed for -g fp\n");
                        break;
 
-#ifdef LIBUNWIND_SUPPORT
+#ifdef HAVE_LIBUNWIND_SUPPORT
                /* Dwarf style */
                } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
                        const unsigned long default_stack_dump_size = 8192;
@@ -755,7 +723,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
                                ret = get_stack_size(tok, &size);
                                opts->stack_dump_size = size;
                        }
-#endif /* LIBUNWIND_SUPPORT */
+#endif /* HAVE_LIBUNWIND_SUPPORT */
                } else {
                        pr_err("callchain: Unknown --call-graph option "
                               "value: %s\n", arg);
@@ -841,7 +809,7 @@ static struct perf_record record = {
 
 #define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: "
 
-#ifdef LIBUNWIND_SUPPORT
+#ifdef HAVE_LIBUNWIND_SUPPORT
 const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf";
 #else
 const char record_callchain_help[] = CALLCHAIN_HELP "fp";
@@ -875,13 +843,14 @@ const struct option record_options[] = {
        OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
                    "list of cpus to monitor"),
        OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
-       OPT_STRING('o', "output", &record.output_name, "file",
+       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_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
-       OPT_UINTEGER('m', "mmap-pages", &record.opts.mmap_pages,
-                    "number of mmap data pages"),
+       OPT_CALLBACK('m', "mmap-pages", &record.opts.mmap_pages, "pages",
+                    "number of mmap data pages",
+                    perf_evlist__parse_mmap_pages),
        OPT_BOOLEAN(0, "group", &record.opts.group,
                    "put the counters into a counter group"),
        OPT_CALLBACK_NOOPT('g', NULL, &record.opts,
@@ -920,6 +889,8 @@ const struct option record_options[] = {
                     parse_branch_stack),
        OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
                    "sample by weight (on special events only)"),
+       OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
+                   "sample transaction flags (special events only)"),
        OPT_END()
 };
 
@@ -989,20 +960,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
        if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
                usage_with_options(record_usage, record_options);
 
-       if (rec->opts.user_interval != ULLONG_MAX)
-               rec->opts.default_interval = rec->opts.user_interval;
-       if (rec->opts.user_freq != UINT_MAX)
-               rec->opts.freq = rec->opts.user_freq;
-
-       /*
-        * User specified count overrides default frequency.
-        */
-       if (rec->opts.default_interval)
-               rec->opts.freq = 0;
-       else if (rec->opts.freq) {
-               rec->opts.default_interval = rec->opts.freq;
-       } else {
-               ui__error("frequency and count are zero, aborting\n");
+       if (perf_record_opts__config(&rec->opts)) {
                err = -EINVAL;
                goto out_free_fd;
        }
index 72eae7498c09419c8f1f77a7a005c6dcbbb5eb4b..8cf8e66ba594156fc85a1ddca5b0b0305544ae23 100644 (file)
 #include "util/thread.h"
 #include "util/sort.h"
 #include "util/hist.h"
+#include "util/data.h"
 #include "arch/common.h"
 
+#include <dlfcn.h>
 #include <linux/bitmap.h>
 
 struct perf_report {
@@ -47,6 +49,7 @@ struct perf_report {
        bool                    show_threads;
        bool                    inverted_callchain;
        bool                    mem_mode;
+       int                     max_stack;
        struct perf_read_values show_threads_values;
        const char              *pretty_printing_style;
        const char              *cpu_list;
@@ -88,7 +91,8 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
        if ((sort__has_parent || symbol_conf.use_callchain) &&
            sample->callchain) {
                err = machine__resolve_callchain(machine, evsel, al->thread,
-                                                sample, &parent, al);
+                                                sample, &parent, al,
+                                                rep->max_stack);
                if (err)
                        return err;
        }
@@ -111,7 +115,8 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
         * and this is indirectly achieved by passing period=weight here
         * and the he_stat__add_period() function.
         */
-       he = __hists__add_mem_entry(&evsel->hists, al, parent, mi, cost, cost);
+       he = __hists__add_entry(&evsel->hists, al, parent, NULL, mi,
+                               cost, cost, 0);
        if (!he)
                return -ENOMEM;
 
@@ -179,7 +184,8 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
        if ((sort__has_parent || symbol_conf.use_callchain)
            && sample->callchain) {
                err = machine__resolve_callchain(machine, evsel, al->thread,
-                                                sample, &parent, al);
+                                                sample, &parent, al,
+                                                rep->max_stack);
                if (err)
                        return err;
        }
@@ -195,12 +201,16 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
 
                err = -ENOMEM;
 
+               /* overwrite the 'al' to branch-to info */
+               al->map = bi[i].to.map;
+               al->sym = bi[i].to.sym;
+               al->addr = bi[i].to.addr;
                /*
                 * The report shows the percentage of total branches captured
                 * and not events sampled. Thus we use a pseudo period of 1.
                 */
-               he = __hists__add_branch_entry(&evsel->hists, al, parent,
-                               &bi[i], 1, 1);
+               he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL,
+                                       1, 1, 0);
                if (he) {
                        struct annotation *notes;
                        bx = he->branch_info;
@@ -242,24 +252,28 @@ out:
        return err;
 }
 
-static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
+static int perf_evsel__add_hist_entry(struct perf_tool *tool,
+                                     struct perf_evsel *evsel,
                                      struct addr_location *al,
                                      struct perf_sample *sample,
                                      struct machine *machine)
 {
+       struct perf_report *rep = container_of(tool, struct perf_report, tool);
        struct symbol *parent = NULL;
        int err = 0;
        struct hist_entry *he;
 
        if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
                err = machine__resolve_callchain(machine, evsel, al->thread,
-                                                sample, &parent, al);
+                                                sample, &parent, al,
+                                                rep->max_stack);
                if (err)
                        return err;
        }
 
-       he = __hists__add_entry(&evsel->hists, al, parent, sample->period,
-                                       sample->weight);
+       he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL,
+                               sample->period, sample->weight,
+                               sample->transaction);
        if (he == NULL)
                return -ENOMEM;
 
@@ -330,7 +344,8 @@ static int process_sample_event(struct perf_tool *tool,
                if (al.map != NULL)
                        al.map->dso->hit = 1;
 
-               ret = perf_evsel__add_hist_entry(evsel, &al, sample, machine);
+               ret = perf_evsel__add_hist_entry(tool, evsel, &al, sample,
+                                                machine);
                if (ret < 0)
                        pr_debug("problem incrementing symbol period, skipping event\n");
        }
@@ -364,10 +379,11 @@ static int process_read_event(struct perf_tool *tool,
 /* For pipe mode, sample_type is not currently set */
 static int perf_report__setup_sample_type(struct perf_report *rep)
 {
-       struct perf_session *self = rep->session;
-       u64 sample_type = perf_evlist__combined_sample_type(self->evlist);
+       struct perf_session *session = rep->session;
+       u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
+       bool is_pipe = perf_data_file__is_pipe(session->file);
 
-       if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
+       if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
                if (sort__has_parent) {
                        ui__error("Selected --sort parent, but no "
                                    "callchain data. Did you call "
@@ -390,7 +406,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
        }
 
        if (sort__mode == SORT_MODE__BRANCH) {
-               if (!self->fd_pipe &&
+               if (!is_pipe &&
                    !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
                        ui__error("Selected -b but no branch data. "
                                  "Did you call perf record without -b?\n");
@@ -407,14 +423,14 @@ static void sig_handler(int sig __maybe_unused)
 }
 
 static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
-                                             struct hists *self,
+                                             struct hists *hists,
                                              const char *evname, FILE *fp)
 {
        size_t ret;
        char unit;
-       unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE];
-       u64 nr_events = self->stats.total_period;
-       struct perf_evsel *evsel = hists_to_evsel(self);
+       unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
+       u64 nr_events = hists->stats.total_period;
+       struct perf_evsel *evsel = hists_to_evsel(hists);
        char buf[512];
        size_t size = sizeof(buf);
 
@@ -486,6 +502,8 @@ static int __cmd_report(struct perf_report *rep)
        struct map *kernel_map;
        struct kmap *kernel_kmap;
        const char *help = "For a higher level overview, try: perf report --sort comm,dso";
+       struct ui_progress prog;
+       struct perf_data_file *file = session->file;
 
        signal(SIGINT, sig_handler);
 
@@ -546,6 +564,12 @@ static int __cmd_report(struct perf_report *rep)
                return 0;
        }
 
+       nr_samples = 0;
+       list_for_each_entry(pos, &session->evlist->entries, node)
+               nr_samples += pos->hists.nr_entries;
+
+       ui_progress__init(&prog, nr_samples, "Merging related events...");
+
        nr_samples = 0;
        list_for_each_entry(pos, &session->evlist->entries, node) {
                struct hists *hists = &pos->hists;
@@ -553,7 +577,7 @@ static int __cmd_report(struct perf_report *rep)
                if (pos->idx == 0)
                        hists->symbol_filter_str = rep->symbol_filter_str;
 
-               hists__collapse_resort(hists);
+               hists__collapse_resort(hists, &prog);
                nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
 
                /* Non-group events are considered as leader */
@@ -565,12 +589,13 @@ static int __cmd_report(struct perf_report *rep)
                        hists__link(leader_hists, hists);
                }
        }
+       ui_progress__finish();
 
        if (session_done())
                return 0;
 
        if (nr_samples == 0) {
-               ui__error("The %s file has no samples!\n", session->filename);
+               ui__error("The %s file has no samples!\n", file->path);
                return 0;
        }
 
@@ -591,8 +616,19 @@ static int __cmd_report(struct perf_report *rep)
                                ret = 0;
 
                } else if (use_browser == 2) {
-                       perf_evlist__gtk_browse_hists(session->evlist, help,
-                                                     NULL, rep->min_percent);
+                       int (*hist_browser)(struct perf_evlist *,
+                                           const char *,
+                                           struct hist_browser_timer *,
+                                           float min_pcnt);
+
+                       hist_browser = dlsym(perf_gtk_handle,
+                                            "perf_evlist__gtk_browse_hists");
+                       if (hist_browser == NULL) {
+                               ui__error("GTK browser not found!\n");
+                               return ret;
+                       }
+                       hist_browser(session->evlist, help, NULL,
+                                    rep->min_percent);
                }
        } else
                perf_evlist__tty_browse_hists(session->evlist, rep, help);
@@ -757,6 +793,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                        .ordered_samples = true,
                        .ordering_requires_timestamps = true,
                },
+               .max_stack               = PERF_MAX_STACK_DEPTH,
                .pretty_printing_style   = "normal",
        };
        const struct option options[] = {
@@ -787,7 +824,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                   "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
                   " dso_to, dso_from, symbol_to, symbol_from, mispredict,"
                   " weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, "
-                  "snoop, locked"),
+                  "snoop, locked, abort, in_tx, transaction"),
        OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
                    "Show sample percentage for different cpu modes"),
        OPT_STRING('p', "parent", &parent_pattern, "regex",
@@ -797,6 +834,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order",
                     "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address). "
                     "Default: fractal,0.5,callee,function", &parse_callchain_opt, callchain_default_opt),
+       OPT_INTEGER(0, "max-stack", &report.max_stack,
+                   "Set the maximum stack depth when parsing the callchain, "
+                   "anything beyond the specified depth will be ignored. "
+                   "Default: " __stringify(PERF_MAX_STACK_DEPTH)),
        OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
                    "alias for inverted call graph"),
        OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
@@ -845,6 +886,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                     "Don't show entries under that percent", parse_percent_limit),
        OPT_END()
        };
+       struct perf_data_file file = {
+               .mode  = PERF_DATA_MODE_READ,
+       };
 
        perf_config(perf_report_config, &report);
 
@@ -867,16 +911,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                        input_name = "perf.data";
        }
 
-       if (strcmp(input_name, "-") != 0)
-               setup_browser(true);
-       else {
-               use_browser = 0;
-               perf_hpp__init();
-       }
+       file.path  = input_name;
+       file.force = report.force;
 
 repeat:
-       session = perf_session__new(input_name, O_RDONLY,
-                                   report.force, false, &report.tool);
+       session = perf_session__new(&file, false, &report.tool);
        if (session == NULL)
                return -ENOMEM;
 
@@ -914,8 +953,22 @@ repeat:
                        sort_order = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked";
        }
 
-       if (setup_sorting() < 0)
-               usage_with_options(report_usage, options);
+       if (setup_sorting() < 0) {
+               parse_options_usage(report_usage, options, "s", 1);
+               goto error;
+       }
+
+       if (parent_pattern != default_parent_pattern) {
+               if (sort_dimension__add("parent") < 0)
+                       goto error;
+       }
+
+       if (strcmp(input_name, "-") != 0)
+               setup_browser(true);
+       else {
+               use_browser = 0;
+               perf_hpp__init();
+       }
 
        /*
         * Only in the TUI browser we are doing integrated annotation,
@@ -946,11 +999,6 @@ repeat:
        if (symbol__init() < 0)
                goto error;
 
-       if (parent_pattern != default_parent_pattern) {
-               if (sort_dimension__add("parent") < 0)
-                       goto error;
-       }
-
        if (argc) {
                /*
                 * Special case: if there's an argument left then assume that
index d8c51b2f263f7475da99a28df87cad3d1f6bb4d2..0f3c65518a2c669a9b83ad255d1018368de6ec69 100644 (file)
@@ -737,12 +737,12 @@ static int replay_fork_event(struct perf_sched *sched,
 
        if (verbose) {
                printf("fork event\n");
-               printf("... parent: %s/%d\n", parent->comm, parent->tid);
-               printf("...  child: %s/%d\n", child->comm, child->tid);
+               printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid);
+               printf("...  child: %s/%d\n", thread__comm_str(child), child->tid);
        }
 
-       register_pid(sched, parent->tid, parent->comm);
-       register_pid(sched, child->tid, child->comm);
+       register_pid(sched, parent->tid, thread__comm_str(parent));
+       register_pid(sched, child->tid, thread__comm_str(child));
        return 0;
 }
 
@@ -1077,7 +1077,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
        if (!atoms) {
                if (thread_atoms_insert(sched, migrant))
                        return -1;
-               register_pid(sched, migrant->tid, migrant->comm);
+               register_pid(sched, migrant->tid, thread__comm_str(migrant));
                atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
                if (!atoms) {
                        pr_err("migration-event: Internal tree error");
@@ -1111,13 +1111,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
        /*
         * Ignore idle threads:
         */
-       if (!strcmp(work_list->thread->comm, "swapper"))
+       if (!strcmp(thread__comm_str(work_list->thread), "swapper"))
                return;
 
        sched->all_runtime += work_list->total_runtime;
        sched->all_count   += work_list->nb_atoms;
 
-       ret = printf("  %s:%d ", work_list->thread->comm, work_list->thread->tid);
+       ret = printf("  %s:%d ", thread__comm_str(work_list->thread), work_list->thread->tid);
 
        for (i = 0; i < 24 - ret; i++)
                printf(" ");
@@ -1334,7 +1334,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
        printf("  %12.6f secs ", (double)timestamp/1e9);
        if (new_shortname) {
                printf("%s => %s:%d\n",
-                       sched_in->shortname, sched_in->comm, sched_in->tid);
+                      sched_in->shortname, thread__comm_str(sched_in), sched_in->tid);
        } else {
                printf("\n");
        }
@@ -1427,8 +1427,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_
        evsel->hists.stats.total_period += sample->period;
        hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
 
-       if (evsel->handler.func != NULL) {
-               tracepoint_handler f = evsel->handler.func;
+       if (evsel->handler != NULL) {
+               tracepoint_handler f = evsel->handler;
                err = f(tool, evsel, sample, machine);
        }
 
@@ -1446,8 +1446,12 @@ static int perf_sched__read_events(struct perf_sched *sched,
                { "sched:sched_migrate_task", process_sched_migrate_task_event, },
        };
        struct perf_session *session;
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
 
-       session = perf_session__new(input_name, O_RDONLY, 0, false, &sched->tool);
+       session = perf_session__new(&file, false, &sched->tool);
        if (session == NULL) {
                pr_debug("No Memory for session\n");
                return -1;
@@ -1651,29 +1655,27 @@ static int __cmd_record(int argc, const char **argv)
        return cmd_record(i, rec_argv, NULL);
 }
 
-static const char default_sort_order[] = "avg, max, switch, runtime";
-static struct perf_sched sched = {
-       .tool = {
-               .sample          = perf_sched__process_tracepoint_sample,
-               .comm            = perf_event__process_comm,
-               .lost            = perf_event__process_lost,
-               .fork            = perf_sched__process_fork_event,
-               .ordered_samples = true,
-       },
-       .cmp_pid              = LIST_HEAD_INIT(sched.cmp_pid),
-       .sort_list            = LIST_HEAD_INIT(sched.sort_list),
-       .start_work_mutex     = PTHREAD_MUTEX_INITIALIZER,
-       .work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
-       .curr_pid             = { [0 ... MAX_CPUS - 1] = -1 },
-       .sort_order           = default_sort_order,
-       .replay_repeat        = 10,
-       .profile_cpu          = -1,
-       .next_shortname1      = 'A',
-       .next_shortname2      = '0',
-};
-
 int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
 {
+       const char default_sort_order[] = "avg, max, switch, runtime";
+       struct perf_sched sched = {
+               .tool = {
+                       .sample          = perf_sched__process_tracepoint_sample,
+                       .comm            = perf_event__process_comm,
+                       .lost            = perf_event__process_lost,
+                       .fork            = perf_sched__process_fork_event,
+                       .ordered_samples = true,
+               },
+               .cmp_pid              = LIST_HEAD_INIT(sched.cmp_pid),
+               .sort_list            = LIST_HEAD_INIT(sched.sort_list),
+               .start_work_mutex     = PTHREAD_MUTEX_INITIALIZER,
+               .work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
+               .sort_order           = default_sort_order,
+               .replay_repeat        = 10,
+               .profile_cpu          = -1,
+               .next_shortname1      = 'A',
+               .next_shortname2      = '0',
+       };
        const struct option latency_options[] = {
        OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]",
                   "sort by key(s): runtime, switch, avg, max"),
@@ -1729,6 +1731,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
                .switch_event       = replay_switch_event,
                .fork_event         = replay_fork_event,
        };
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++)
+               sched.curr_pid[i] = -1;
 
        argc = parse_options(argc, argv, sched_options, sched_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
index 9c333ff3dfeb3de716eac13d48d7364e998bb50d..baf17989a216137064e089d4e2f65fef07a4357f 100644 (file)
@@ -15,6 +15,7 @@
 #include "util/evlist.h"
 #include "util/evsel.h"
 #include "util/sort.h"
+#include "util/data.h"
 #include <linux/bitmap.h>
 
 static char const              *script_name;
@@ -228,6 +229,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
        return 0;
 }
 
+static void set_print_ip_opts(struct perf_event_attr *attr)
+{
+       unsigned int type = attr->type;
+
+       output[type].print_ip_opts = 0;
+       if (PRINT_FIELD(IP))
+               output[type].print_ip_opts |= PRINT_IP_OPT_IP;
+
+       if (PRINT_FIELD(SYM))
+               output[type].print_ip_opts |= PRINT_IP_OPT_SYM;
+
+       if (PRINT_FIELD(DSO))
+               output[type].print_ip_opts |= PRINT_IP_OPT_DSO;
+
+       if (PRINT_FIELD(SYMOFFSET))
+               output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
+}
+
 /*
  * verify all user requested events exist and the samples
  * have the expected data
@@ -236,7 +255,6 @@ static int perf_session__check_output_opt(struct perf_session *session)
 {
        int j;
        struct perf_evsel *evsel;
-       struct perf_event_attr *attr;
 
        for (j = 0; j < PERF_TYPE_MAX; ++j) {
                evsel = perf_session__find_first_evtype(session, j);
@@ -259,20 +277,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
                if (evsel == NULL)
                        continue;
 
-               attr = &evsel->attr;
-
-               output[j].print_ip_opts = 0;
-               if (PRINT_FIELD(IP))
-                       output[j].print_ip_opts |= PRINT_IP_OPT_IP;
-
-               if (PRINT_FIELD(SYM))
-                       output[j].print_ip_opts |= PRINT_IP_OPT_SYM;
-
-               if (PRINT_FIELD(DSO))
-                       output[j].print_ip_opts |= PRINT_IP_OPT_DSO;
-
-               if (PRINT_FIELD(SYMOFFSET))
-                       output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
+               set_print_ip_opts(&evsel->attr);
        }
 
        return 0;
@@ -290,11 +295,11 @@ static void print_sample_start(struct perf_sample *sample,
 
        if (PRINT_FIELD(COMM)) {
                if (latency_format)
-                       printf("%8.8s ", thread->comm);
+                       printf("%8.8s ", thread__comm_str(thread));
                else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
-                       printf("%s ", thread->comm);
+                       printf("%s ", thread__comm_str(thread));
                else
-                       printf("%16s ", thread->comm);
+                       printf("%16s ", thread__comm_str(thread));
        }
 
        if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
@@ -409,7 +414,9 @@ static void print_sample_bts(union perf_event *event,
        printf(" => ");
 
        /* print branch_to information */
-       if (PRINT_FIELD(ADDR))
+       if (PRINT_FIELD(ADDR) ||
+           ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
+            !output[attr->type].user_set))
                print_sample_addr(event, sample, machine, thread, attr);
 
        printf("\n");
@@ -539,32 +546,51 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
        return 0;
 }
 
-static struct perf_tool perf_script = {
-       .sample          = process_sample_event,
-       .mmap            = perf_event__process_mmap,
-       .mmap2           = perf_event__process_mmap2,
-       .comm            = perf_event__process_comm,
-       .exit            = perf_event__process_exit,
-       .fork            = perf_event__process_fork,
-       .attr            = perf_event__process_attr,
-       .tracing_data    = perf_event__process_tracing_data,
-       .build_id        = perf_event__process_build_id,
-       .ordered_samples = true,
-       .ordering_requires_timestamps = true,
+struct perf_script {
+       struct perf_tool        tool;
+       struct perf_session     *session;
 };
 
+static int process_attr(struct perf_tool *tool, union perf_event *event,
+                       struct perf_evlist **pevlist)
+{
+       struct perf_script *scr = container_of(tool, struct perf_script, tool);
+       struct perf_evlist *evlist;
+       struct perf_evsel *evsel, *pos;
+       int err;
+
+       err = perf_event__process_attr(tool, event, pevlist);
+       if (err)
+               return err;
+
+       evlist = *pevlist;
+       evsel = perf_evlist__last(*pevlist);
+
+       if (evsel->attr.type >= PERF_TYPE_MAX)
+               return 0;
+
+       list_for_each_entry(pos, &evlist->entries, node) {
+               if (pos->attr.type == evsel->attr.type && pos != evsel)
+                       return 0;
+       }
+
+       set_print_ip_opts(&evsel->attr);
+
+       return perf_evsel__check_attr(evsel, scr->session);
+}
+
 static void sig_handler(int sig __maybe_unused)
 {
        session_done = 1;
 }
 
-static int __cmd_script(struct perf_session *session)
+static int __cmd_script(struct perf_script *script)
 {
        int ret;
 
        signal(SIGINT, sig_handler);
 
-       ret = perf_session__process_events(session, &perf_script);
+       ret = perf_session__process_events(script->session, &script->tool);
 
        if (debug_mode)
                pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -1113,10 +1139,14 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
        char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
        DIR *scripts_dir, *lang_dir;
        struct perf_session *session;
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
        char *temp;
        int i = 0;
 
-       session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
+       session = perf_session__new(&file, false, NULL);
        if (!session)
                return -1;
 
@@ -1266,6 +1296,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
        char *script_path = NULL;
        const char **__argv;
        int i, j, err;
+       struct perf_script script = {
+               .tool = {
+                       .sample          = process_sample_event,
+                       .mmap            = perf_event__process_mmap,
+                       .mmap2           = perf_event__process_mmap2,
+                       .comm            = perf_event__process_comm,
+                       .exit            = perf_event__process_exit,
+                       .fork            = perf_event__process_fork,
+                       .attr            = process_attr,
+                       .tracing_data    = perf_event__process_tracing_data,
+                       .build_id        = perf_event__process_build_id,
+                       .ordered_samples = true,
+                       .ordering_requires_timestamps = true,
+               },
+       };
        const struct option options[] = {
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -1317,12 +1362,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                "perf script [<options>] <top-script> [script-args]",
                NULL
        };
+       struct perf_data_file file = {
+               .mode = PERF_DATA_MODE_READ,
+       };
 
        setup_scripting();
 
        argc = parse_options(argc, argv, options, script_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
 
+       file.path = input_name;
+
        if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
                rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
                if (!rec_script_path)
@@ -1486,11 +1536,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
        if (!script_name)
                setup_pager();
 
-       session = perf_session__new(input_name, O_RDONLY, 0, false,
-                                   &perf_script);
+       session = perf_session__new(&file, false, &script.tool);
        if (session == NULL)
                return -ENOMEM;
 
+       script.session = session;
+
        if (cpu_list) {
                if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
                        return -1;
@@ -1514,7 +1565,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                        return -1;
                }
 
-               input = open(session->filename, O_RDONLY);      /* input_name */
+               input = open(file.path, O_RDONLY);      /* input_name */
                if (input < 0) {
                        perror("failed to open file");
                        return -1;
@@ -1554,7 +1605,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
        if (err < 0)
                goto out;
 
-       err = __cmd_script(session);
+       err = __cmd_script(&script);
 
        perf_session__delete(session);
        cleanup_scripting();
index 5098f144b92defd53e94f9f24184e3ade0672928..0fc1c941a73c3bd03cdfe183aad5397e53ed6496 100644 (file)
@@ -46,6 +46,7 @@
 #include "util/util.h"
 #include "util/parse-options.h"
 #include "util/parse-events.h"
+#include "util/pmu.h"
 #include "util/event.h"
 #include "util/evlist.h"
 #include "util/evsel.h"
@@ -70,6 +71,41 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
 static void print_counter(struct perf_evsel *counter, char *prefix);
 static void print_aggr(char *prefix);
 
+/* Default events used for perf stat -T */
+static const char * const transaction_attrs[] = {
+       "task-clock",
+       "{"
+       "instructions,"
+       "cycles,"
+       "cpu/cycles-t/,"
+       "cpu/tx-start/,"
+       "cpu/el-start/,"
+       "cpu/cycles-ct/"
+       "}"
+};
+
+/* More limited version when the CPU does not have all events. */
+static const char * const transaction_limited_attrs[] = {
+       "task-clock",
+       "{"
+       "instructions,"
+       "cycles,"
+       "cpu/cycles-t/,"
+       "cpu/tx-start/"
+       "}"
+};
+
+/* must match transaction_attrs and the beginning limited_attrs */
+enum {
+       T_TASK_CLOCK,
+       T_INSTRUCTIONS,
+       T_CYCLES,
+       T_CYCLES_IN_TX,
+       T_TRANSACTION_START,
+       T_ELISION_START,
+       T_CYCLES_IN_TX_CP,
+};
+
 static struct perf_evlist      *evsel_list;
 
 static struct perf_target      target = {
@@ -90,6 +126,7 @@ static enum aggr_mode                aggr_mode                       = AGGR_GLOBAL;
 static volatile pid_t          child_pid                       = -1;
 static bool                    null_run                        =  false;
 static int                     detailed_run                    =  0;
+static bool                    transaction_run;
 static bool                    big_num                         =  true;
 static int                     big_num_opt                     =  -1;
 static const char              *csv_sep                        = NULL;
@@ -214,7 +251,10 @@ static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
 static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
+static struct stats runtime_cycles_in_tx_stats[MAX_NR_CPUS];
 static struct stats walltime_nsecs_stats;
+static struct stats runtime_transaction_stats[MAX_NR_CPUS];
+static struct stats runtime_elision_stats[MAX_NR_CPUS];
 
 static void perf_stat__reset_stats(struct perf_evlist *evlist)
 {
@@ -236,6 +276,11 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
        memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
        memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
        memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
+       memset(runtime_cycles_in_tx_stats, 0,
+                       sizeof(runtime_cycles_in_tx_stats));
+       memset(runtime_transaction_stats, 0,
+               sizeof(runtime_transaction_stats));
+       memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
        memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
 }
 
@@ -274,6 +319,29 @@ static inline int nsec_counter(struct perf_evsel *evsel)
        return 0;
 }
 
+static struct perf_evsel *nth_evsel(int n)
+{
+       static struct perf_evsel **array;
+       static int array_len;
+       struct perf_evsel *ev;
+       int j;
+
+       /* Assumes this only called when evsel_list does not change anymore. */
+       if (!array) {
+               list_for_each_entry(ev, &evsel_list->entries, node)
+                       array_len++;
+               array = malloc(array_len * sizeof(void *));
+               if (!array)
+                       exit(ENOMEM);
+               j = 0;
+               list_for_each_entry(ev, &evsel_list->entries, node)
+                       array[j++] = ev;
+       }
+       if (n < array_len)
+               return array[n];
+       return NULL;
+}
+
 /*
  * Update various tracking values we maintain to print
  * more semantic information such as miss/hit ratios,
@@ -285,6 +353,15 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
                update_stats(&runtime_nsecs_stats[0], count[0]);
        else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
                update_stats(&runtime_cycles_stats[0], count[0]);
+       else if (transaction_run &&
+                perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX)))
+               update_stats(&runtime_cycles_in_tx_stats[0], count[0]);
+       else if (transaction_run &&
+                perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START)))
+               update_stats(&runtime_transaction_stats[0], count[0]);
+       else if (transaction_run &&
+                perf_evsel__cmp(counter, nth_evsel(T_ELISION_START)))
+               update_stats(&runtime_elision_stats[0], count[0]);
        else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
                update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
        else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
@@ -629,10 +706,13 @@ 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";
+       char name[25];
 
        aggr_printout(evsel, cpu, nr);
 
-       fprintf(output, fmt, msecs, csv_sep, perf_evsel__name(evsel));
+       scnprintf(name, sizeof(name), "%s%s",
+                 perf_evsel__name(evsel), csv_output ? "" : " (msec)");
+       fprintf(output, fmt, msecs, csv_sep, name);
 
        if (evsel->cgrp)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
@@ -828,7 +908,7 @@ 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;
+       double total, ratio = 0.0, total2;
        const char *fmt;
 
        if (csv_output)
@@ -853,11 +933,10 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
 
        if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
                total = avg_stats(&runtime_cycles_stats[cpu]);
-               if (total)
+               if (total) {
                        ratio = avg / total;
-
-               fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
-
+                       fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
+               }
                total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
                total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
 
@@ -920,10 +999,47 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
        } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
                total = avg_stats(&runtime_nsecs_stats[cpu]);
 
+               if (total) {
+                       ratio = avg / total;
+                       fprintf(output, " # %8.3f GHz                    ", ratio);
+               }
+       } else if (transaction_run &&
+                  perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
+               total = avg_stats(&runtime_cycles_stats[cpu]);
+               if (total)
+                       fprintf(output,
+                               " #   %5.2f%% transactional cycles   ",
+                               100.0 * (avg / total));
+       } else if (transaction_run &&
+                  perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) {
+               total = avg_stats(&runtime_cycles_stats[cpu]);
+               total2 = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
+               if (total2 < avg)
+                       total2 = avg;
+               if (total)
+                       fprintf(output,
+                               " #   %5.2f%% aborted cycles         ",
+                               100.0 * ((total2-avg) / total));
+       } else if (transaction_run &&
+                  perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) &&
+                  avg > 0 &&
+                  runtime_cycles_in_tx_stats[cpu].n != 0) {
+               total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
+
                if (total)
-                       ratio = 1.0 * avg / total;
+                       ratio = total / avg;
 
-               fprintf(output, " # %8.3f GHz                    ", ratio);
+               fprintf(output, " # %8.0f cycles / transaction   ", ratio);
+       } else if (transaction_run &&
+                  perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) &&
+                  avg > 0 &&
+                  runtime_cycles_in_tx_stats[cpu].n != 0) {
+               total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
+
+               if (total)
+                       ratio = total / avg;
+
+               fprintf(output, " # %8.0f cycles / elision       ", ratio);
        } else if (runtime_nsecs_stats[cpu].n != 0) {
                char unit = 'M';
 
@@ -1116,7 +1232,11 @@ static void print_stat(int argc, const char **argv)
        if (!csv_output) {
                fprintf(output, "\n");
                fprintf(output, " Performance counter stats for ");
-               if (!perf_target__has_task(&target)) {
+               if (target.system_wide)
+                       fprintf(output, "\'system wide");
+               else if (target.cpu_list)
+                       fprintf(output, "\'CPU(s) %s", target.cpu_list);
+               else if (!perf_target__has_task(&target)) {
                        fprintf(output, "\'%s", argv[0]);
                        for (i = 1; i < argc; i++)
                                fprintf(output, " %s", argv[i]);
@@ -1237,6 +1357,16 @@ static int perf_stat_init_aggr_mode(void)
        return 0;
 }
 
+static int setup_events(const char * const *attrs, unsigned len)
+{
+       unsigned i;
+
+       for (i = 0; i < len; i++) {
+               if (parse_events(evsel_list, attrs[i]))
+                       return -1;
+       }
+       return 0;
+}
 
 /*
  * Add default attributes, if there were no attributes specified or
@@ -1355,6 +1485,22 @@ static int add_default_attributes(void)
        if (null_run)
                return 0;
 
+       if (transaction_run) {
+               int err;
+               if (pmu_have_event("cpu", "cycles-ct") &&
+                   pmu_have_event("cpu", "el-start"))
+                       err = setup_events(transaction_attrs,
+                                       ARRAY_SIZE(transaction_attrs));
+               else
+                       err = setup_events(transaction_limited_attrs,
+                                ARRAY_SIZE(transaction_limited_attrs));
+               if (err < 0) {
+                       fprintf(stderr, "Cannot set up transaction events\n");
+                       return -1;
+               }
+               return 0;
+       }
+
        if (!evsel_list->nr_entries) {
                if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
                        return -1;
@@ -1389,6 +1535,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        int output_fd = 0;
        const char *output_name = NULL;
        const struct option options[] = {
+       OPT_BOOLEAN('T', "transaction", &transaction_run,
+                   "hardware transaction statistics"),
        OPT_CALLBACK('e', "event", &evsel_list, "event",
                     "event selector. use 'perf list' to list available events",
                     parse_events_option),
@@ -1448,7 +1596,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
                "perf stat [<options>] [<command>]",
                NULL
        };
-       int status = -ENOMEM, run_idx;
+       int status = -EINVAL, run_idx;
        const char *mode;
 
        setlocale(LC_ALL, "");
@@ -1466,12 +1614,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
        if (output_name && output_fd) {
                fprintf(stderr, "cannot use both --output and --log-fd\n");
-               usage_with_options(stat_usage, options);
+               parse_options_usage(stat_usage, options, "o", 1);
+               parse_options_usage(NULL, options, "log-fd", 0);
+               goto out;
        }
 
        if (output_fd < 0) {
                fprintf(stderr, "argument to --log-fd must be a > 0\n");
-               usage_with_options(stat_usage, options);
+               parse_options_usage(stat_usage, options, "log-fd", 0);
+               goto out;
        }
 
        if (!output) {
@@ -1508,16 +1659,21 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
                /* User explicitly passed -B? */
                if (big_num_opt == 1) {
                        fprintf(stderr, "-B option not supported with -x\n");
-                       usage_with_options(stat_usage, options);
+                       parse_options_usage(stat_usage, options, "B", 1);
+                       parse_options_usage(NULL, options, "x", 1);
+                       goto out;
                } else /* Nope, so disable big number formatting */
                        big_num = false;
        } else if (big_num_opt == 0) /* User passed --no-big-num */
                big_num = false;
 
-       if (!argc && !perf_target__has_task(&target))
+       if (!argc && perf_target__none(&target))
                usage_with_options(stat_usage, options);
+
        if (run_count < 0) {
-               usage_with_options(stat_usage, options);
+               pr_err("Run count must be a positive number\n");
+               parse_options_usage(stat_usage, options, "r", 1);
+               goto out;
        } else if (run_count == 0) {
                forever = true;
                run_count = 1;
@@ -1529,8 +1685,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
                fprintf(stderr, "both cgroup and no-aggregation "
                        "modes only available in system-wide mode\n");
 
-               usage_with_options(stat_usage, options);
-               return -1;
+               parse_options_usage(stat_usage, options, "G", 1);
+               parse_options_usage(NULL, options, "A", 1);
+               parse_options_usage(NULL, options, "a", 1);
+               goto out;
        }
 
        if (add_default_attributes())
@@ -1539,25 +1697,28 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        perf_target__validate(&target);
 
        if (perf_evlist__create_maps(evsel_list, &target) < 0) {
-               if (perf_target__has_task(&target))
+               if (perf_target__has_task(&target)) {
                        pr_err("Problems finding threads of monitor\n");
-               if (perf_target__has_cpu(&target))
+                       parse_options_usage(stat_usage, options, "p", 1);
+                       parse_options_usage(NULL, options, "t", 1);
+               } else if (perf_target__has_cpu(&target)) {
                        perror("failed to parse CPUs map");
-
-               usage_with_options(stat_usage, options);
-               return -1;
+                       parse_options_usage(stat_usage, options, "C", 1);
+                       parse_options_usage(NULL, options, "a", 1);
+               }
+               goto out;
        }
        if (interval && interval < 100) {
                pr_err("print interval must be >= 100ms\n");
-               usage_with_options(stat_usage, options);
-               return -1;
+               parse_options_usage(stat_usage, options, "I", 1);
+               goto out_free_maps;
        }
 
        if (perf_evlist__alloc_stats(evsel_list, interval))
                goto out_free_maps;
 
        if (perf_stat_init_aggr_mode())
-               goto out;
+               goto out_free_maps;
 
        /*
         * We dont want to block the signals - that would cause
index c2e02319347abd86c74f6ab0b44c37106c0fb238..41c9bde2fb67f1418faceaaf86475a163694bdeb 100644 (file)
@@ -36,6 +36,7 @@
 #include "util/session.h"
 #include "util/svghelper.h"
 #include "util/tool.h"
+#include "util/data.h"
 
 #define SUPPORT_OLD_POWER_EVENTS 1
 #define PWR_EVENT_EXIT -1
@@ -482,8 +483,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
        if (sample->cpu > numcpus)
                numcpus = sample->cpu;
 
-       if (evsel->handler.func != NULL) {
-               tracepoint_handler f = evsel->handler.func;
+       if (evsel->handler != NULL) {
+               tracepoint_handler f = evsel->handler;
                return f(evsel, sample);
        }
 
@@ -990,8 +991,13 @@ static int __cmd_timechart(const char *output_name)
                { "power:power_frequency",      process_sample_power_frequency },
 #endif
        };
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY,
-                                                        0, false, &perf_timechart);
+       struct perf_data_file file = {
+               .path = input_name,
+               .mode = PERF_DATA_MODE_READ,
+       };
+
+       struct perf_session *session = perf_session__new(&file, false,
+                                                        &perf_timechart);
        int ret = -EINVAL;
 
        if (session == NULL)
index 5a11f13e56f9f186cc7aa0926f4ee63008327358..9acca8856ccb2ba60ee3ae72cb954b6c1932da65 100644 (file)
@@ -246,10 +246,10 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
        struct hist_entry *he;
 
        pthread_mutex_lock(&evsel->hists.lock);
-       he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
-                               sample->weight);
+       he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL,
+                               sample->period, sample->weight,
+                               sample->transaction);
        pthread_mutex_unlock(&evsel->hists.lock);
-
        if (he == NULL)
                return NULL;
 
@@ -287,7 +287,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
                return;
        }
 
-       hists__collapse_resort(&top->sym_evsel->hists);
+       hists__collapse_resort(&top->sym_evsel->hists, NULL);
        hists__output_resort(&top->sym_evsel->hists);
        hists__decay_entries(&top->sym_evsel->hists,
                             top->hide_user_symbols,
@@ -553,7 +553,7 @@ static void perf_top__sort_new_samples(void *arg)
        if (t->evlist->selected != NULL)
                t->sym_evsel = t->evlist->selected;
 
-       hists__collapse_resort(&t->sym_evsel->hists);
+       hists__collapse_resort(&t->sym_evsel->hists, NULL);
        hists__output_resort(&t->sym_evsel->hists);
        hists__decay_entries(&t->sym_evsel->hists,
                             t->hide_user_symbols,
@@ -771,7 +771,8 @@ static void perf_event__process_sample(struct perf_tool *tool,
                    sample->callchain) {
                        err = machine__resolve_callchain(machine, evsel,
                                                         al.thread, sample,
-                                                        &parent, &al);
+                                                        &parent, &al,
+                                                        top->max_stack);
                        if (err)
                                return;
                }
@@ -856,7 +857,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
                                                   &sample, machine);
                } else if (event->header.type < PERF_RECORD_MAX) {
                        hists__inc_nr_events(&evsel->hists, event->header.type);
-                       machine__process_event(machine, event);
+                       machine__process_event(machine, event, &sample);
                } else
                        ++session->stats.nr_unknown_events;
 next_event:
@@ -932,11 +933,8 @@ static int __cmd_top(struct perf_top *top)
        struct perf_record_opts *opts = &top->record_opts;
        pthread_t thread;
        int ret;
-       /*
-        * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
-        * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
-        */
-       top->session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
+
+       top->session = perf_session__new(NULL, false, NULL);
        if (top->session == NULL)
                return -ENOMEM;
 
@@ -1043,7 +1041,7 @@ parse_percent_limit(const struct option *opt, const char *arg,
 
 int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
 {
-       int status;
+       int status = -1;
        char errbuf[BUFSIZ];
        struct perf_top top = {
                .count_filter        = 5,
@@ -1053,10 +1051,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                        .user_freq      = UINT_MAX,
                        .user_interval  = ULLONG_MAX,
                        .freq           = 4000, /* 4 KHz */
-                       .target              = {
+                       .target         = {
                                .uses_mmap   = true,
                        },
                },
+               .max_stack           = PERF_MAX_STACK_DEPTH,
                .sym_pcnt_filter     = 5,
        };
        struct perf_record_opts *opts = &top.record_opts;
@@ -1076,10 +1075,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                    "list of cpus to monitor"),
        OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
                   "file", "vmlinux pathname"),
+       OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
+                   "don't load vmlinux even if found"),
        OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols,
                    "hide kernel symbols"),
-       OPT_UINTEGER('m', "mmap-pages", &opts->mmap_pages,
-                    "number of mmap data pages"),
+       OPT_CALLBACK('m', "mmap-pages", &opts->mmap_pages, "pages",
+                    "number of mmap data pages",
+                    perf_evlist__parse_mmap_pages),
        OPT_INTEGER('r', "realtime", &top.realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
        OPT_INTEGER('d', "delay", &top.delay_secs,
@@ -1105,7 +1107,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
-                  "sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight"),
+                  "sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight,"
+                  " 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,
@@ -1114,6 +1117,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_CALLBACK(0, "call-graph", &top.record_opts,
                     "mode[,dump_size]", record_callchain_help,
                     &parse_callchain_opt),
+       OPT_INTEGER(0, "max-stack", &top.max_stack,
+                   "Set the maximum stack depth when parsing the callchain. "
+                   "Default: " __stringify(PERF_MAX_STACK_DEPTH)),
        OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
                   "ignore callees of these functions in call graphs",
                   report_parse_ignore_callees_opt),
@@ -1154,8 +1160,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
        if (sort_order == default_sort_order)
                sort_order = "dso,symbol";
 
-       if (setup_sorting() < 0)
-               usage_with_options(top_usage, options);
+       if (setup_sorting() < 0) {
+               parse_options_usage(top_usage, options, "s", 1);
+               goto out_delete_evlist;
+       }
 
        /* display thread wants entries to be collapsed in a different tree */
        sort__need_collapse = 1;
@@ -1201,20 +1209,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
        if (top.delay_secs < 1)
                top.delay_secs = 1;
 
-       if (opts->user_interval != ULLONG_MAX)
-               opts->default_interval = opts->user_interval;
-       if (opts->user_freq != UINT_MAX)
-               opts->freq = opts->user_freq;
-
-       /*
-        * User specified count overrides default frequency.
-        */
-       if (opts->default_interval)
-               opts->freq = 0;
-       else if (opts->freq) {
-               opts->default_interval = opts->freq;
-       } else {
-               ui__error("frequency and count are zero, aborting\n");
+       if (perf_record_opts__config(opts)) {
                status = -EINVAL;
                goto out_delete_maps;
        }
index 99c8d9ad6729cabf6bebe5b65c753af1a28d9024..329b7832b5dac7d46ace24cc597e7539cbfddd8d 100644 (file)
 #include "util/strlist.h"
 #include "util/intlist.h"
 #include "util/thread_map.h"
+#include "util/stat.h"
 
 #include <libaudit.h>
 #include <stdlib.h>
+#include <sys/eventfd.h>
 #include <sys/mman.h>
 #include <linux/futex.h>
 
 # define MADV_UNMERGEABLE      13
 #endif
 
-static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
-                                        unsigned long arg,
-                                        u8 arg_idx __maybe_unused,
-                                        u8 *arg_mask __maybe_unused)
+struct tp_field {
+       int offset;
+       union {
+               u64 (*integer)(struct tp_field *field, struct perf_sample *sample);
+               void *(*pointer)(struct tp_field *field, struct perf_sample *sample);
+       };
+};
+
+#define TP_UINT_FIELD(bits) \
+static u64 tp_field__u##bits(struct tp_field *field, struct perf_sample *sample) \
+{ \
+       return *(u##bits *)(sample->raw_data + field->offset); \
+}
+
+TP_UINT_FIELD(8);
+TP_UINT_FIELD(16);
+TP_UINT_FIELD(32);
+TP_UINT_FIELD(64);
+
+#define TP_UINT_FIELD__SWAPPED(bits) \
+static u64 tp_field__swapped_u##bits(struct tp_field *field, struct perf_sample *sample) \
+{ \
+       u##bits value = *(u##bits *)(sample->raw_data + field->offset); \
+       return bswap_##bits(value);\
+}
+
+TP_UINT_FIELD__SWAPPED(16);
+TP_UINT_FIELD__SWAPPED(32);
+TP_UINT_FIELD__SWAPPED(64);
+
+static int tp_field__init_uint(struct tp_field *field,
+                              struct format_field *format_field,
+                              bool needs_swap)
 {
-       return scnprintf(bf, size, "%#lx", arg);
+       field->offset = format_field->offset;
+
+       switch (format_field->size) {
+       case 1:
+               field->integer = tp_field__u8;
+               break;
+       case 2:
+               field->integer = needs_swap ? tp_field__swapped_u16 : tp_field__u16;
+               break;
+       case 4:
+               field->integer = needs_swap ? tp_field__swapped_u32 : tp_field__u32;
+               break;
+       case 8:
+               field->integer = needs_swap ? tp_field__swapped_u64 : tp_field__u64;
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
 }
 
-#define SCA_HEX syscall_arg__scnprintf_hex
+static void *tp_field__ptr(struct tp_field *field, struct perf_sample *sample)
+{
+       return sample->raw_data + field->offset;
+}
 
-static size_t syscall_arg__scnprintf_whence(char *bf, size_t size,
-                                           unsigned long arg,
-                                           u8 arg_idx __maybe_unused,
-                                           u8 *arg_mask __maybe_unused)
+static int tp_field__init_ptr(struct tp_field *field, struct format_field *format_field)
 {
-       int whence = arg;
+       field->offset = format_field->offset;
+       field->pointer = tp_field__ptr;
+       return 0;
+}
 
-       switch (whence) {
-#define P_WHENCE(n) case SEEK_##n: return scnprintf(bf, size, #n)
-       P_WHENCE(SET);
-       P_WHENCE(CUR);
-       P_WHENCE(END);
-#ifdef SEEK_DATA
-       P_WHENCE(DATA);
-#endif
-#ifdef SEEK_HOLE
-       P_WHENCE(HOLE);
-#endif
-#undef P_WHENCE
-       default: break;
+struct syscall_tp {
+       struct tp_field id;
+       union {
+               struct tp_field args, ret;
+       };
+};
+
+static int perf_evsel__init_tp_uint_field(struct perf_evsel *evsel,
+                                         struct tp_field *field,
+                                         const char *name)
+{
+       struct format_field *format_field = perf_evsel__field(evsel, name);
+
+       if (format_field == NULL)
+               return -1;
+
+       return tp_field__init_uint(field, format_field, evsel->needs_swap);
+}
+
+#define perf_evsel__init_sc_tp_uint_field(evsel, name) \
+       ({ struct syscall_tp *sc = evsel->priv;\
+          perf_evsel__init_tp_uint_field(evsel, &sc->name, #name); })
+
+static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel,
+                                        struct tp_field *field,
+                                        const char *name)
+{
+       struct format_field *format_field = perf_evsel__field(evsel, name);
+
+       if (format_field == NULL)
+               return -1;
+
+       return tp_field__init_ptr(field, format_field);
+}
+
+#define perf_evsel__init_sc_tp_ptr_field(evsel, name) \
+       ({ struct syscall_tp *sc = evsel->priv;\
+          perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); })
+
+static void perf_evsel__delete_priv(struct perf_evsel *evsel)
+{
+       free(evsel->priv);
+       evsel->priv = NULL;
+       perf_evsel__delete(evsel);
+}
+
+static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction,
+                                                   void *handler, int idx)
+{
+       struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction, idx);
+
+       if (evsel) {
+               evsel->priv = malloc(sizeof(struct syscall_tp));
+
+               if (evsel->priv == NULL)
+                       goto out_delete;
+
+               if (perf_evsel__init_sc_tp_uint_field(evsel, id))
+                       goto out_delete;
+
+               evsel->handler = handler;
        }
 
-       return scnprintf(bf, size, "%#x", whence);
+       return evsel;
+
+out_delete:
+       perf_evsel__delete_priv(evsel);
+       return NULL;
 }
 
-#define SCA_WHENCE syscall_arg__scnprintf_whence
+#define perf_evsel__sc_tp_uint(evsel, name, sample) \
+       ({ struct syscall_tp *fields = evsel->priv; \
+          fields->name.integer(&fields->name, sample); })
+
+#define perf_evsel__sc_tp_ptr(evsel, name, sample) \
+       ({ struct syscall_tp *fields = evsel->priv; \
+          fields->name.pointer(&fields->name, sample); })
+
+static int perf_evlist__add_syscall_newtp(struct perf_evlist *evlist,
+                                         void *sys_enter_handler,
+                                         void *sys_exit_handler)
+{
+       int ret = -1;
+       int idx = evlist->nr_entries;
+       struct perf_evsel *sys_enter, *sys_exit;
+
+       sys_enter = perf_evsel__syscall_newtp("sys_enter", sys_enter_handler, idx++);
+       if (sys_enter == NULL)
+               goto out;
+
+       if (perf_evsel__init_sc_tp_ptr_field(sys_enter, args))
+               goto out_delete_sys_enter;
+
+       sys_exit = perf_evsel__syscall_newtp("sys_exit", sys_exit_handler, idx++);
+       if (sys_exit == NULL)
+               goto out_delete_sys_enter;
+
+       if (perf_evsel__init_sc_tp_uint_field(sys_exit, ret))
+               goto out_delete_sys_exit;
+
+       perf_evlist__add(evlist, sys_enter);
+       perf_evlist__add(evlist, sys_exit);
+
+       ret = 0;
+out:
+       return ret;
+
+out_delete_sys_exit:
+       perf_evsel__delete_priv(sys_exit);
+out_delete_sys_enter:
+       perf_evsel__delete_priv(sys_enter);
+       goto out;
+}
+
+
+struct syscall_arg {
+       unsigned long val;
+       struct thread *thread;
+       struct trace  *trace;
+       void          *parm;
+       u8            idx;
+       u8            mask;
+};
+
+struct strarray {
+       int         offset;
+       int         nr_entries;
+       const char **entries;
+};
+
+#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \
+       .nr_entries = ARRAY_SIZE(array), \
+       .entries = array, \
+}
+
+#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \
+       .offset     = off, \
+       .nr_entries = ARRAY_SIZE(array), \
+       .entries = array, \
+}
+
+static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size,
+                                               const char *intfmt,
+                                               struct syscall_arg *arg)
+{
+       struct strarray *sa = arg->parm;
+       int idx = arg->val - sa->offset;
+
+       if (idx < 0 || idx >= sa->nr_entries)
+               return scnprintf(bf, size, intfmt, arg->val);
+
+       return scnprintf(bf, size, "%s", sa->entries[idx]);
+}
+
+static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size,
+                                             struct syscall_arg *arg)
+{
+       return __syscall_arg__scnprintf_strarray(bf, size, "%d", arg);
+}
+
+#define SCA_STRARRAY syscall_arg__scnprintf_strarray
+
+static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size,
+                                                struct syscall_arg *arg)
+{
+       return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg);
+}
+
+#define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray
+
+static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
+                                       struct syscall_arg *arg);
+
+#define SCA_FD syscall_arg__scnprintf_fd
+
+static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size,
+                                          struct syscall_arg *arg)
+{
+       int fd = arg->val;
+
+       if (fd == AT_FDCWD)
+               return scnprintf(bf, size, "CWD");
+
+       return syscall_arg__scnprintf_fd(bf, size, arg);
+}
+
+#define SCA_FDAT syscall_arg__scnprintf_fd_at
+
+static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
+                                             struct syscall_arg *arg);
+
+#define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd
+
+static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
+                                        struct syscall_arg *arg)
+{
+       return scnprintf(bf, size, "%#lx", arg->val);
+}
+
+#define SCA_HEX syscall_arg__scnprintf_hex
 
 static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
-                                              unsigned long arg,
-                                              u8 arg_idx __maybe_unused,
-                                              u8 *arg_mask __maybe_unused)
+                                              struct syscall_arg *arg)
 {
-       int printed = 0, prot = arg;
+       int printed = 0, prot = arg->val;
 
        if (prot == PROT_NONE)
                return scnprintf(bf, size, "NONE");
@@ -104,10 +336,9 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
 #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
 
 static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
-                                               unsigned long arg, u8 arg_idx __maybe_unused,
-                                               u8 *arg_mask __maybe_unused)
+                                               struct syscall_arg *arg)
 {
-       int printed = 0, flags = arg;
+       int printed = 0, flags = arg->val;
 
 #define        P_MMAP_FLAG(n) \
        if (flags & MAP_##n) { \
@@ -148,10 +379,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
 #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
 
 static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
-                                                     unsigned long arg, u8 arg_idx __maybe_unused,
-                                                     u8 *arg_mask __maybe_unused)
+                                                     struct syscall_arg *arg)
 {
-       int behavior = arg;
+       int behavior = arg->val;
 
        switch (behavior) {
 #define        P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n)
@@ -190,8 +420,38 @@ static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
 
 #define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior
 
-static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned long arg,
-                                             u8 arg_idx __maybe_unused, u8 *arg_mask)
+static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
+                                          struct syscall_arg *arg)
+{
+       int printed = 0, op = arg->val;
+
+       if (op == 0)
+               return scnprintf(bf, size, "NONE");
+#define        P_CMD(cmd) \
+       if ((op & LOCK_##cmd) == LOCK_##cmd) { \
+               printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \
+               op &= ~LOCK_##cmd; \
+       }
+
+       P_CMD(SH);
+       P_CMD(EX);
+       P_CMD(NB);
+       P_CMD(UN);
+       P_CMD(MAND);
+       P_CMD(RW);
+       P_CMD(READ);
+       P_CMD(WRITE);
+#undef P_OP
+
+       if (op)
+               printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op);
+
+       return printed;
+}
+
+#define SCA_FLOCK syscall_arg__scnprintf_flock
+
+static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
 {
        enum syscall_futex_args {
                SCF_UADDR   = (1 << 0),
@@ -201,24 +461,24 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned lo
                SCF_UADDR2  = (1 << 4),
                SCF_VAL3    = (1 << 5),
        };
-       int op = arg;
+       int op = arg->val;
        int cmd = op & FUTEX_CMD_MASK;
        size_t printed = 0;
 
        switch (cmd) {
 #define        P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
-       P_FUTEX_OP(WAIT);           *arg_mask |= SCF_VAL3|SCF_UADDR2;             break;
-       P_FUTEX_OP(WAKE);           *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
-       P_FUTEX_OP(FD);             *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
-       P_FUTEX_OP(REQUEUE);        *arg_mask |= SCF_VAL3|SCF_TIMEOUT;            break;
-       P_FUTEX_OP(CMP_REQUEUE);    *arg_mask |= SCF_TIMEOUT;                     break;
-       P_FUTEX_OP(CMP_REQUEUE_PI); *arg_mask |= SCF_TIMEOUT;                     break;
+       P_FUTEX_OP(WAIT);           arg->mask |= SCF_VAL3|SCF_UADDR2;             break;
+       P_FUTEX_OP(WAKE);           arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
+       P_FUTEX_OP(FD);             arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
+       P_FUTEX_OP(REQUEUE);        arg->mask |= SCF_VAL3|SCF_TIMEOUT;            break;
+       P_FUTEX_OP(CMP_REQUEUE);    arg->mask |= SCF_TIMEOUT;                     break;
+       P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT;                     break;
        P_FUTEX_OP(WAKE_OP);                                                      break;
-       P_FUTEX_OP(LOCK_PI);        *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
-       P_FUTEX_OP(UNLOCK_PI);      *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
-       P_FUTEX_OP(TRYLOCK_PI);     *arg_mask |= SCF_VAL3|SCF_UADDR2;             break;
-       P_FUTEX_OP(WAIT_BITSET);    *arg_mask |= SCF_UADDR2;                      break;
-       P_FUTEX_OP(WAKE_BITSET);    *arg_mask |= SCF_UADDR2;                      break;
+       P_FUTEX_OP(LOCK_PI);        arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
+       P_FUTEX_OP(UNLOCK_PI);      arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
+       P_FUTEX_OP(TRYLOCK_PI);     arg->mask |= SCF_VAL3|SCF_UADDR2;             break;
+       P_FUTEX_OP(WAIT_BITSET);    arg->mask |= SCF_UADDR2;                      break;
+       P_FUTEX_OP(WAKE_BITSET);    arg->mask |= SCF_UADDR2;                      break;
        P_FUTEX_OP(WAIT_REQUEUE_PI);                                              break;
        default: printed = scnprintf(bf, size, "%#x", cmd);                       break;
        }
@@ -234,14 +494,194 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned lo
 
 #define SCA_FUTEX_OP  syscall_arg__scnprintf_futex_op
 
+static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", };
+static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1);
+
+static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", };
+static DEFINE_STRARRAY(itimers);
+
+static const char *whences[] = { "SET", "CUR", "END",
+#ifdef SEEK_DATA
+"DATA",
+#endif
+#ifdef SEEK_HOLE
+"HOLE",
+#endif
+};
+static DEFINE_STRARRAY(whences);
+
+static const char *fcntl_cmds[] = {
+       "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK",
+       "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64",
+       "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX",
+       "F_GETOWNER_UIDS",
+};
+static DEFINE_STRARRAY(fcntl_cmds);
+
+static const char *rlimit_resources[] = {
+       "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE",
+       "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO",
+       "RTTIME",
+};
+static DEFINE_STRARRAY(rlimit_resources);
+
+static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", };
+static DEFINE_STRARRAY(sighow);
+
+static const char *clockid[] = {
+       "REALTIME", "MONOTONIC", "PROCESS_CPUTIME_ID", "THREAD_CPUTIME_ID",
+       "MONOTONIC_RAW", "REALTIME_COARSE", "MONOTONIC_COARSE",
+};
+static DEFINE_STRARRAY(clockid);
+
+static const char *socket_families[] = {
+       "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM",
+       "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI",
+       "SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC",
+       "RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC",
+       "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF",
+       "ALG", "NFC", "VSOCK",
+};
+static DEFINE_STRARRAY(socket_families);
+
+#ifndef SOCK_TYPE_MASK
+#define SOCK_TYPE_MASK 0xf
+#endif
+
+static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size,
+                                                     struct syscall_arg *arg)
+{
+       size_t printed;
+       int type = arg->val,
+           flags = type & ~SOCK_TYPE_MASK;
+
+       type &= SOCK_TYPE_MASK;
+       /*
+        * Can't use a strarray, MIPS may override for ABI reasons.
+        */
+       switch (type) {
+#define        P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
+       P_SK_TYPE(STREAM);
+       P_SK_TYPE(DGRAM);
+       P_SK_TYPE(RAW);
+       P_SK_TYPE(RDM);
+       P_SK_TYPE(SEQPACKET);
+       P_SK_TYPE(DCCP);
+       P_SK_TYPE(PACKET);
+#undef P_SK_TYPE
+       default:
+               printed = scnprintf(bf, size, "%#x", type);
+       }
+
+#define        P_SK_FLAG(n) \
+       if (flags & SOCK_##n) { \
+               printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
+               flags &= ~SOCK_##n; \
+       }
+
+       P_SK_FLAG(CLOEXEC);
+       P_SK_FLAG(NONBLOCK);
+#undef P_SK_FLAG
+
+       if (flags)
+               printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
+
+       return printed;
+}
+
+#define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
+
+#ifndef MSG_PROBE
+#define MSG_PROBE           0x10
+#endif
+#ifndef MSG_WAITFORONE
+#define MSG_WAITFORONE 0x10000
+#endif
+#ifndef MSG_SENDPAGE_NOTLAST
+#define MSG_SENDPAGE_NOTLAST 0x20000
+#endif
+#ifndef MSG_FASTOPEN
+#define MSG_FASTOPEN        0x20000000
+#endif
+
+static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
+                                              struct syscall_arg *arg)
+{
+       int printed = 0, flags = arg->val;
+
+       if (flags == 0)
+               return scnprintf(bf, size, "NONE");
+#define        P_MSG_FLAG(n) \
+       if (flags & MSG_##n) { \
+               printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
+               flags &= ~MSG_##n; \
+       }
+
+       P_MSG_FLAG(OOB);
+       P_MSG_FLAG(PEEK);
+       P_MSG_FLAG(DONTROUTE);
+       P_MSG_FLAG(TRYHARD);
+       P_MSG_FLAG(CTRUNC);
+       P_MSG_FLAG(PROBE);
+       P_MSG_FLAG(TRUNC);
+       P_MSG_FLAG(DONTWAIT);
+       P_MSG_FLAG(EOR);
+       P_MSG_FLAG(WAITALL);
+       P_MSG_FLAG(FIN);
+       P_MSG_FLAG(SYN);
+       P_MSG_FLAG(CONFIRM);
+       P_MSG_FLAG(RST);
+       P_MSG_FLAG(ERRQUEUE);
+       P_MSG_FLAG(NOSIGNAL);
+       P_MSG_FLAG(MORE);
+       P_MSG_FLAG(WAITFORONE);
+       P_MSG_FLAG(SENDPAGE_NOTLAST);
+       P_MSG_FLAG(FASTOPEN);
+       P_MSG_FLAG(CMSG_CLOEXEC);
+#undef P_MSG_FLAG
+
+       if (flags)
+               printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
+
+       return printed;
+}
+
+#define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags
+
+static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size,
+                                                struct syscall_arg *arg)
+{
+       size_t printed = 0;
+       int mode = arg->val;
+
+       if (mode == F_OK) /* 0 */
+               return scnprintf(bf, size, "F");
+#define        P_MODE(n) \
+       if (mode & n##_OK) { \
+               printed += scnprintf(bf + printed, size - printed, "%s", #n); \
+               mode &= ~n##_OK; \
+       }
+
+       P_MODE(R);
+       P_MODE(W);
+       P_MODE(X);
+#undef P_MODE
+
+       if (mode)
+               printed += scnprintf(bf + printed, size - printed, "|%#x", mode);
+
+       return printed;
+}
+
+#define SCA_ACCMODE syscall_arg__scnprintf_access_mode
+
 static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
-                                              unsigned long arg,
-                                              u8 arg_idx, u8 *arg_mask)
+                                              struct syscall_arg *arg)
 {
-       int printed = 0, flags = arg;
+       int printed = 0, flags = arg->val;
 
        if (!(flags & O_CREAT))
-               *arg_mask |= 1 << (arg_idx + 1); /* Mask the mode parm */
+               arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */
 
        if (flags == 0)
                return scnprintf(bf, size, "RDONLY");
@@ -291,32 +731,225 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
 
 #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags
 
+static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size,
+                                                  struct syscall_arg *arg)
+{
+       int printed = 0, flags = arg->val;
+
+       if (flags == 0)
+               return scnprintf(bf, size, "NONE");
+#define        P_FLAG(n) \
+       if (flags & EFD_##n) { \
+               printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
+               flags &= ~EFD_##n; \
+       }
+
+       P_FLAG(SEMAPHORE);
+       P_FLAG(CLOEXEC);
+       P_FLAG(NONBLOCK);
+#undef P_FLAG
+
+       if (flags)
+               printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
+
+       return printed;
+}
+
+#define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags
+
+static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size,
+                                               struct syscall_arg *arg)
+{
+       int printed = 0, flags = arg->val;
+
+#define        P_FLAG(n) \
+       if (flags & O_##n) { \
+               printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
+               flags &= ~O_##n; \
+       }
+
+       P_FLAG(CLOEXEC);
+       P_FLAG(NONBLOCK);
+#undef P_FLAG
+
+       if (flags)
+               printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
+
+       return printed;
+}
+
+#define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags
+
+static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
+{
+       int sig = arg->val;
+
+       switch (sig) {
+#define        P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n)
+       P_SIGNUM(HUP);
+       P_SIGNUM(INT);
+       P_SIGNUM(QUIT);
+       P_SIGNUM(ILL);
+       P_SIGNUM(TRAP);
+       P_SIGNUM(ABRT);
+       P_SIGNUM(BUS);
+       P_SIGNUM(FPE);
+       P_SIGNUM(KILL);
+       P_SIGNUM(USR1);
+       P_SIGNUM(SEGV);
+       P_SIGNUM(USR2);
+       P_SIGNUM(PIPE);
+       P_SIGNUM(ALRM);
+       P_SIGNUM(TERM);
+       P_SIGNUM(STKFLT);
+       P_SIGNUM(CHLD);
+       P_SIGNUM(CONT);
+       P_SIGNUM(STOP);
+       P_SIGNUM(TSTP);
+       P_SIGNUM(TTIN);
+       P_SIGNUM(TTOU);
+       P_SIGNUM(URG);
+       P_SIGNUM(XCPU);
+       P_SIGNUM(XFSZ);
+       P_SIGNUM(VTALRM);
+       P_SIGNUM(PROF);
+       P_SIGNUM(WINCH);
+       P_SIGNUM(IO);
+       P_SIGNUM(PWR);
+       P_SIGNUM(SYS);
+       default: break;
+       }
+
+       return scnprintf(bf, size, "%#x", sig);
+}
+
+#define SCA_SIGNUM syscall_arg__scnprintf_signum
+
+#define TCGETS         0x5401
+
+static const char *tioctls[] = {
+       "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW",
+       "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL",
+       "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI",
+       "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC",
+       "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX",
+       "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO",
+       "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK",
+       "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2",
+       "TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK",
+       "TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG",
+       "TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL",
+       [0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG",
+       "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS",
+       "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI",
+       "TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE",
+};
+
+static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401);
+
+#define STRARRAY(arg, name, array) \
+         .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \
+         .arg_parm      = { [arg] = &strarray__##array, }
+
 static struct syscall_fmt {
        const char *name;
        const char *alias;
-       size_t     (*arg_scnprintf[6])(char *bf, size_t size, unsigned long arg, u8 arg_idx, u8 *arg_mask);
+       size_t     (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg);
+       void       *arg_parm[6];
        bool       errmsg;
        bool       timeout;
        bool       hexret;
 } syscall_fmts[] = {
-       { .name     = "access",     .errmsg = true, },
+       { .name     = "access",     .errmsg = true,
+         .arg_scnprintf = { [1] = SCA_ACCMODE, /* mode */ }, },
        { .name     = "arch_prctl", .errmsg = true, .alias = "prctl", },
        { .name     = "brk",        .hexret = true,
          .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, },
-       { .name     = "mmap",       .hexret = true, },
+       { .name     = "clock_gettime",  .errmsg = true, STRARRAY(0, clk_id, clockid), },
+       { .name     = "close",      .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, 
        { .name     = "connect",    .errmsg = true, },
-       { .name     = "fstat",      .errmsg = true, .alias = "newfstat", },
-       { .name     = "fstatat",    .errmsg = true, .alias = "newfstatat", },
+       { .name     = "dup",        .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "dup2",       .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "dup3",       .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "epoll_ctl",  .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), },
+       { .name     = "eventfd2",   .errmsg = true,
+         .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, },
+       { .name     = "faccessat",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
+       { .name     = "fadvise64",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fallocate",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fchdir",     .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fchmod",     .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fchmodat",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
+       { .name     = "fchown",     .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fchownat",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
+       { .name     = "fcntl",      .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */
+                            [1] = SCA_STRARRAY, /* cmd */ },
+         .arg_parm      = { [1] = &strarray__fcntl_cmds, /* cmd */ }, },
+       { .name     = "fdatasync",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "flock",      .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */
+                            [1] = SCA_FLOCK, /* cmd */ }, },
+       { .name     = "fsetxattr",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fstat",      .errmsg = true, .alias = "newfstat",
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fstatat",    .errmsg = true, .alias = "newfstatat",
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
+       { .name     = "fstatfs",    .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "fsync",    .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "ftruncate", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
        { .name     = "futex",      .errmsg = true,
          .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, },
+       { .name     = "futimesat", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
+       { .name     = "getdents",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "getdents64", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "getitimer",  .errmsg = true, STRARRAY(0, which, itimers), },
+       { .name     = "getrlimit",  .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
        { .name     = "ioctl",      .errmsg = true,
-         .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, },
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ 
+                            [1] = SCA_STRHEXARRAY, /* cmd */
+                            [2] = SCA_HEX, /* arg */ },
+         .arg_parm      = { [1] = &strarray__tioctls, /* cmd */ }, },
+       { .name     = "kill",       .errmsg = true,
+         .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
+       { .name     = "linkat",     .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
        { .name     = "lseek",      .errmsg = true,
-         .arg_scnprintf = { [2] = SCA_WHENCE, /* whence */ }, },
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */
+                            [2] = SCA_STRARRAY, /* whence */ },
+         .arg_parm      = { [2] = &strarray__whences, /* whence */ }, },
        { .name     = "lstat",      .errmsg = true, .alias = "newlstat", },
        { .name     = "madvise",    .errmsg = true,
          .arg_scnprintf = { [0] = SCA_HEX,      /* start */
                             [2] = SCA_MADV_BHV, /* behavior */ }, },
+       { .name     = "mkdirat",    .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
+       { .name     = "mknodat",    .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
+       { .name     = "mlock",      .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
+       { .name     = "mlockall",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
        { .name     = "mmap",       .hexret = true,
          .arg_scnprintf = { [0] = SCA_HEX,       /* addr */
                             [2] = SCA_MMAP_PROT, /* prot */
@@ -327,24 +960,91 @@ static struct syscall_fmt {
        { .name     = "mremap",     .hexret = true,
          .arg_scnprintf = { [0] = SCA_HEX, /* addr */
                             [4] = SCA_HEX, /* new_addr */ }, },
+       { .name     = "munlock",    .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
        { .name     = "munmap",     .errmsg = true,
          .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
+       { .name     = "name_to_handle_at", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
+       { .name     = "newfstatat", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
        { .name     = "open",       .errmsg = true,
          .arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, },
        { .name     = "open_by_handle_at", .errmsg = true,
-         .arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, },
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
+                            [2] = SCA_OPEN_FLAGS, /* flags */ }, },
        { .name     = "openat",     .errmsg = true,
-         .arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, },
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
+                            [2] = SCA_OPEN_FLAGS, /* flags */ }, },
+       { .name     = "pipe2",      .errmsg = true,
+         .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, },
        { .name     = "poll",       .errmsg = true, .timeout = true, },
        { .name     = "ppoll",      .errmsg = true, .timeout = true, },
-       { .name     = "pread",      .errmsg = true, .alias = "pread64", },
-       { .name     = "pwrite",     .errmsg = true, .alias = "pwrite64", },
-       { .name     = "read",       .errmsg = true, },
-       { .name     = "recvfrom",   .errmsg = true, },
+       { .name     = "pread",      .errmsg = true, .alias = "pread64",
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "preadv",     .errmsg = true, .alias = "pread",
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "prlimit64",  .errmsg = true, STRARRAY(1, resource, rlimit_resources), },
+       { .name     = "pwrite",     .errmsg = true, .alias = "pwrite64",
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "pwritev",    .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "read",       .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "readlinkat", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
+       { .name     = "readv",      .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "recvfrom",   .errmsg = true,
+         .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
+       { .name     = "recvmmsg",   .errmsg = true,
+         .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
+       { .name     = "recvmsg",    .errmsg = true,
+         .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, },
+       { .name     = "renameat",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
+       { .name     = "rt_sigaction", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, },
+       { .name     = "rt_sigprocmask",  .errmsg = true, STRARRAY(0, how, sighow), },
+       { .name     = "rt_sigqueueinfo", .errmsg = true,
+         .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
+       { .name     = "rt_tgsigqueueinfo", .errmsg = true,
+         .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
        { .name     = "select",     .errmsg = true, .timeout = true, },
-       { .name     = "socket",     .errmsg = true, },
+       { .name     = "sendmmsg",    .errmsg = true,
+         .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
+       { .name     = "sendmsg",    .errmsg = true,
+         .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, },
+       { .name     = "sendto",     .errmsg = true,
+         .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
+       { .name     = "setitimer",  .errmsg = true, STRARRAY(0, which, itimers), },
+       { .name     = "setrlimit",  .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
+       { .name     = "shutdown",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "socket",     .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
+                            [1] = SCA_SK_TYPE, /* type */ },
+         .arg_parm      = { [0] = &strarray__socket_families, /* family */ }, },
+       { .name     = "socketpair", .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
+                            [1] = SCA_SK_TYPE, /* type */ },
+         .arg_parm      = { [0] = &strarray__socket_families, /* family */ }, },
        { .name     = "stat",       .errmsg = true, .alias = "newstat", },
+       { .name     = "symlinkat",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
+       { .name     = "tgkill",     .errmsg = true,
+         .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
+       { .name     = "tkill",      .errmsg = true,
+         .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
        { .name     = "uname",      .errmsg = true, .alias = "newuname", },
+       { .name     = "unlinkat",   .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
+       { .name     = "utimensat",  .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, },
+       { .name     = "write",      .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
+       { .name     = "writev",     .errmsg = true,
+         .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
 };
 
 static int syscall_fmt__cmp(const void *name, const void *fmtp)
@@ -364,8 +1064,8 @@ struct syscall {
        const char          *name;
        bool                filtered;
        struct syscall_fmt  *fmt;
-       size_t              (**arg_scnprintf)(char *bf, size_t size,
-                                             unsigned long arg, u8 arg_idx, u8 *args_mask);
+       size_t              (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg);
+       void                **arg_parm;
 };
 
 static size_t fprintf_duration(unsigned long t, FILE *fp)
@@ -389,11 +1089,24 @@ struct thread_trace {
        unsigned long     nr_events;
        char              *entry_str;
        double            runtime_ms;
+       struct {
+               int       max;
+               char      **table;
+       } paths;
+
+       struct intlist *syscall_stats;
 };
 
 static struct thread_trace *thread_trace__new(void)
 {
-       return zalloc(sizeof(struct thread_trace));
+       struct thread_trace *ttrace =  zalloc(sizeof(struct thread_trace));
+
+       if (ttrace)
+               ttrace->paths.max = -1;
+
+       ttrace->syscall_stats = intlist__new(NULL);
+
+       return ttrace;
 }
 
 static struct thread_trace *thread__trace(struct thread *thread, FILE *fp)
@@ -421,26 +1134,140 @@ fail:
 
 struct trace {
        struct perf_tool        tool;
-       int                     audit_machine;
+       struct {
+               int             machine;
+               int             open_id;
+       }                       audit;
        struct {
                int             max;
                struct syscall  *table;
        } syscalls;
        struct perf_record_opts opts;
-       struct machine          host;
+       struct machine          *host;
        u64                     base_time;
+       bool                    full_time;
        FILE                    *output;
        unsigned long           nr_events;
        struct strlist          *ev_qualifier;
        bool                    not_ev_qualifier;
+       bool                    live;
+       const char              *last_vfs_getname;
        struct intlist          *tid_list;
        struct intlist          *pid_list;
        bool                    sched;
        bool                    multiple_threads;
+       bool                    summary;
+       bool                    show_comm;
+       bool                    show_tool_stats;
        double                  duration_filter;
        double                  runtime_ms;
+       struct {
+               u64             vfs_getname, proc_getname;
+       } stats;
 };
 
+static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
+{
+       struct thread_trace *ttrace = thread->priv;
+
+       if (fd > ttrace->paths.max) {
+               char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *));
+
+               if (npath == NULL)
+                       return -1;
+
+               if (ttrace->paths.max != -1) {
+                       memset(npath + ttrace->paths.max + 1, 0,
+                              (fd - ttrace->paths.max) * sizeof(char *));
+               } else {
+                       memset(npath, 0, (fd + 1) * sizeof(char *));
+               }
+
+               ttrace->paths.table = npath;
+               ttrace->paths.max   = fd;
+       }
+
+       ttrace->paths.table[fd] = strdup(pathname);
+
+       return ttrace->paths.table[fd] != NULL ? 0 : -1;
+}
+
+static int thread__read_fd_path(struct thread *thread, int fd)
+{
+       char linkname[PATH_MAX], pathname[PATH_MAX];
+       struct stat st;
+       int ret;
+
+       if (thread->pid_ == thread->tid) {
+               scnprintf(linkname, sizeof(linkname),
+                         "/proc/%d/fd/%d", thread->pid_, fd);
+       } else {
+               scnprintf(linkname, sizeof(linkname),
+                         "/proc/%d/task/%d/fd/%d", thread->pid_, thread->tid, fd);
+       }
+
+       if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)sizeof(pathname))
+               return -1;
+
+       ret = readlink(linkname, pathname, sizeof(pathname));
+
+       if (ret < 0 || ret > st.st_size)
+               return -1;
+
+       pathname[ret] = '\0';
+       return trace__set_fd_pathname(thread, fd, pathname);
+}
+
+static const char *thread__fd_path(struct thread *thread, int fd,
+                                  struct trace *trace)
+{
+       struct thread_trace *ttrace = thread->priv;
+
+       if (ttrace == NULL)
+               return NULL;
+
+       if (fd < 0)
+               return NULL;
+
+       if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL))
+               if (!trace->live)
+                       return NULL;
+               ++trace->stats.proc_getname;
+               if (thread__read_fd_path(thread, fd)) {
+                       return NULL;
+       }
+
+       return ttrace->paths.table[fd];
+}
+
+static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
+                                       struct syscall_arg *arg)
+{
+       int fd = arg->val;
+       size_t printed = scnprintf(bf, size, "%d", fd);
+       const char *path = thread__fd_path(arg->thread, fd, arg->trace);
+
+       if (path)
+               printed += scnprintf(bf + printed, size - printed, "<%s>", path);
+
+       return printed;
+}
+
+static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
+                                             struct syscall_arg *arg)
+{
+       int fd = arg->val;
+       size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
+       struct thread_trace *ttrace = arg->thread->priv;
+
+       if (ttrace && fd >= 0 && fd <= ttrace->paths.max) {
+               free(ttrace->paths.table[fd]);
+               ttrace->paths.table[fd] = NULL;
+       }
+
+       return printed;
+}
+
 static bool trace__filter_duration(struct trace *trace, double t)
 {
        return t < (trace->duration_filter * NSEC_PER_MSEC);
@@ -454,10 +1281,12 @@ static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
 }
 
 static bool done = false;
+static bool interrupted = false;
 
-static void sig_handler(int sig __maybe_unused)
+static void sig_handler(int sig)
 {
        done = true;
+       interrupted = sig == SIGINT;
 }
 
 static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
@@ -466,14 +1295,17 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre
        size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
        printed += fprintf_duration(duration, fp);
 
-       if (trace->multiple_threads)
+       if (trace->multiple_threads) {
+               if (trace->show_comm)
+                       printed += fprintf(fp, "%.14s/", thread__comm_str(thread));
                printed += fprintf(fp, "%d ", thread->tid);
+       }
 
        return printed;
 }
 
 static int trace__process_event(struct trace *trace, struct machine *machine,
-                               union perf_event *event)
+                               union perf_event *event, struct perf_sample *sample)
 {
        int ret = 0;
 
@@ -481,9 +1313,9 @@ static int trace__process_event(struct trace *trace, struct machine *machine,
        case PERF_RECORD_LOST:
                color_fprintf(trace->output, PERF_COLOR_RED,
                              "LOST %" PRIu64 " events!\n", event->lost.lost);
-               ret = machine__process_lost_event(machine, event);
+               ret = machine__process_lost_event(machine, event, sample);
        default:
-               ret = machine__process_event(machine, event);
+               ret = machine__process_event(machine, event, sample);
                break;
        }
 
@@ -492,11 +1324,11 @@ static int trace__process_event(struct trace *trace, struct machine *machine,
 
 static int trace__tool_process(struct perf_tool *tool,
                               union perf_event *event,
-                              struct perf_sample *sample __maybe_unused,
+                              struct perf_sample *sample,
                               struct machine *machine)
 {
        struct trace *trace = container_of(tool, struct trace, tool);
-       return trace__process_event(trace, machine, event);
+       return trace__process_event(trace, machine, event, sample);
 }
 
 static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
@@ -506,16 +1338,17 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
        if (err)
                return err;
 
-       machine__init(&trace->host, "", HOST_KERNEL_ID);
-       machine__create_kernel_maps(&trace->host);
+       trace->host = machine__new_host();
+       if (trace->host == NULL)
+               return -ENOMEM;
 
        if (perf_target__has_task(&trace->opts.target)) {
                err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
                                                        trace__tool_process,
-                                                       &trace->host);
+                                                       trace->host);
        } else {
                err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
-                                                    &trace->host);
+                                                    trace->host);
        }
 
        if (err)
@@ -533,6 +1366,9 @@ static int syscall__set_arg_fmts(struct syscall *sc)
        if (sc->arg_scnprintf == NULL)
                return -1;
 
+       if (sc->fmt)
+               sc->arg_parm = sc->fmt->arg_parm;
+
        for (field = sc->tp_format->format.fields->next; field; field = field->next) {
                if (sc->fmt && sc->fmt->arg_scnprintf[idx])
                        sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
@@ -548,7 +1384,7 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 {
        char tp_name[128];
        struct syscall *sc;
-       const char *name = audit_syscall_to_name(id, trace->audit_machine);
+       const char *name = audit_syscall_to_name(id, trace->audit.machine);
 
        if (name == NULL)
                return -1;
@@ -603,32 +1439,52 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 }
 
 static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
-                                     unsigned long *args)
+                                     unsigned long *args, struct trace *trace,
+                                     struct thread *thread)
 {
-       int i = 0;
        size_t printed = 0;
 
        if (sc->tp_format != NULL) {
                struct format_field *field;
-               u8 mask = 0, bit = 1;
+               u8 bit = 1;
+               struct syscall_arg arg = {
+                       .idx    = 0,
+                       .mask   = 0,
+                       .trace  = trace,
+                       .thread = thread,
+               };
 
                for (field = sc->tp_format->format.fields->next; field;
-                    field = field->next, ++i, bit <<= 1) {
-                       if (mask & bit)
+                    field = field->next, ++arg.idx, bit <<= 1) {
+                       if (arg.mask & bit)
+                               continue;
+                       /*
+                        * Suppress this argument if its value is zero and
+                        * and we don't have a string associated in an
+                        * strarray for it.
+                        */
+                       if (args[arg.idx] == 0 &&
+                           !(sc->arg_scnprintf &&
+                             sc->arg_scnprintf[arg.idx] == SCA_STRARRAY &&
+                             sc->arg_parm[arg.idx]))
                                continue;
 
                        printed += scnprintf(bf + printed, size - printed,
                                             "%s%s: ", printed ? ", " : "", field->name);
-
-                       if (sc->arg_scnprintf && sc->arg_scnprintf[i]) {
-                               printed += sc->arg_scnprintf[i](bf + printed, size - printed,
-                                                               args[i], i, &mask);
+                       if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) {
+                               arg.val = args[arg.idx];
+                               if (sc->arg_parm)
+                                       arg.parm = sc->arg_parm[arg.idx];
+                               printed += sc->arg_scnprintf[arg.idx](bf + printed,
+                                                                     size - printed, &arg);
                        } else {
                                printed += scnprintf(bf + printed, size - printed,
-                                                    "%ld", args[i]);
+                                                    "%ld", args[arg.idx]);
                        }
                }
        } else {
+               int i = 0;
+
                while (i < 6) {
                        printed += scnprintf(bf + printed, size - printed,
                                             "%sarg%d: %ld",
@@ -644,10 +1500,8 @@ typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel,
                                  struct perf_sample *sample);
 
 static struct syscall *trace__syscall_info(struct trace *trace,
-                                          struct perf_evsel *evsel,
-                                          struct perf_sample *sample)
+                                          struct perf_evsel *evsel, int id)
 {
-       int id = perf_evsel__intval(evsel, sample, "id");
 
        if (id < 0) {
 
@@ -688,6 +1542,32 @@ out_cant_read:
        return NULL;
 }
 
+static void thread__update_stats(struct thread_trace *ttrace,
+                                int id, struct perf_sample *sample)
+{
+       struct int_node *inode;
+       struct stats *stats;
+       u64 duration = 0;
+
+       inode = intlist__findnew(ttrace->syscall_stats, id);
+       if (inode == NULL)
+               return;
+
+       stats = inode->priv;
+       if (stats == NULL) {
+               stats = malloc(sizeof(struct stats));
+               if (stats == NULL)
+                       return;
+               init_stats(stats);
+               inode->priv = stats;
+       }
+
+       if (ttrace->entry_time && sample->time > ttrace->entry_time)
+               duration = sample->time - ttrace->entry_time;
+
+       update_stats(stats, duration);
+}
+
 static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
                            struct perf_sample *sample)
 {
@@ -695,7 +1575,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
        void *args;
        size_t printed = 0;
        struct thread *thread;
-       struct syscall *sc = trace__syscall_info(trace, evsel, sample);
+       int id = perf_evsel__sc_tp_uint(evsel, id, sample);
+       struct syscall *sc = trace__syscall_info(trace, evsel, id);
        struct thread_trace *ttrace;
 
        if (sc == NULL)
@@ -704,18 +1585,12 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
        if (sc->filtered)
                return 0;
 
-       thread = machine__findnew_thread(&trace->host, sample->pid,
-                                        sample->tid);
+       thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
        ttrace = thread__trace(thread, trace->output);
        if (ttrace == NULL)
                return -1;
 
-       args = perf_evsel__rawptr(evsel, sample, "args");
-       if (args == NULL) {
-               fprintf(trace->output, "Problems reading syscall arguments\n");
-               return -1;
-       }
-
+       args = perf_evsel__sc_tp_ptr(evsel, args, sample);
        ttrace = thread->priv;
 
        if (ttrace->entry_str == NULL) {
@@ -728,7 +1603,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
        msg = ttrace->entry_str;
        printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name);
 
-       printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed,  args);
+       printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed,
+                                          args, trace, thread);
 
        if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) {
                if (!trace->duration_filter) {
@@ -747,7 +1623,8 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
        int ret;
        u64 duration = 0;
        struct thread *thread;
-       struct syscall *sc = trace__syscall_info(trace, evsel, sample);
+       int id = perf_evsel__sc_tp_uint(evsel, id, sample);
+       struct syscall *sc = trace__syscall_info(trace, evsel, id);
        struct thread_trace *ttrace;
 
        if (sc == NULL)
@@ -756,13 +1633,21 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
        if (sc->filtered)
                return 0;
 
-       thread = machine__findnew_thread(&trace->host, sample->pid,
-                                        sample->tid);
+       thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
        ttrace = thread__trace(thread, trace->output);
        if (ttrace == NULL)
                return -1;
 
-       ret = perf_evsel__intval(evsel, sample, "ret");
+       if (trace->summary)
+               thread__update_stats(ttrace, id, sample);
+
+       ret = perf_evsel__sc_tp_uint(evsel, ret, sample);
+
+       if (id == trace->audit.open_id && ret >= 0 && trace->last_vfs_getname) {
+               trace__set_fd_pathname(thread, ret, trace->last_vfs_getname);
+               trace->last_vfs_getname = NULL;
+               ++trace->stats.vfs_getname;
+       }
 
        ttrace = thread->priv;
 
@@ -808,12 +1693,19 @@ out:
        return 0;
 }
 
+static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel,
+                             struct perf_sample *sample)
+{
+       trace->last_vfs_getname = perf_evsel__rawptr(evsel, sample, "pathname");
+       return 0;
+}
+
 static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel,
                                     struct perf_sample *sample)
 {
         u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
        double runtime_ms = (double)runtime / NSEC_PER_MSEC;
-       struct thread *thread = machine__findnew_thread(&trace->host,
+       struct thread *thread = machine__findnew_thread(trace->host,
                                                        sample->pid,
                                                        sample->tid);
        struct thread_trace *ttrace = thread__trace(thread, trace->output);
@@ -856,12 +1748,12 @@ static int trace__process_sample(struct perf_tool *tool,
        struct trace *trace = container_of(tool, struct trace, tool);
        int err = 0;
 
-       tracepoint_handler handler = evsel->handler.func;
+       tracepoint_handler handler = evsel->handler;
 
        if (skip_sample(trace, sample))
                return 0;
 
-       if (trace->base_time == 0)
+       if (!trace->full_time && trace->base_time == 0)
                trace->base_time = sample->time;
 
        if (handler)
@@ -901,6 +1793,51 @@ static int parse_target_str(struct trace *trace)
        return 0;
 }
 
+static int trace__record(int argc, const char **argv)
+{
+       unsigned int rec_argc, i, j;
+       const char **rec_argv;
+       const char * const record_args[] = {
+               "record",
+               "-R",
+               "-m", "1024",
+               "-c", "1",
+               "-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit",
+       };
+
+       rec_argc = ARRAY_SIZE(record_args) + argc;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+       if (rec_argv == NULL)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(record_args); i++)
+               rec_argv[i] = record_args[i];
+
+       for (j = 0; j < (unsigned int)argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       return cmd_record(i, rec_argv, NULL);
+}
+
+static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp);
+
+static void perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname",
+                                                    evlist->nr_entries);
+       if (evsel == NULL)
+               return;
+
+       if (perf_evsel__field(evsel, "pathname") == NULL) {
+               perf_evsel__delete(evsel);
+               return;
+       }
+
+       evsel->handler = trace__vfs_getname;
+       perf_evlist__add(evlist, evsel);
+}
+
 static int trace__run(struct trace *trace, int argc, const char **argv)
 {
        struct perf_evlist *evlist = perf_evlist__new();
@@ -909,23 +1846,22 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
        unsigned long before;
        const bool forks = argc > 0;
 
+       trace->live = true;
+
        if (evlist == NULL) {
                fprintf(trace->output, "Not enough memory to run!\n");
                goto out;
        }
 
-       if (perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_enter", trace__sys_enter) ||
-           perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) {
-               fprintf(trace->output, "Couldn't read the raw_syscalls tracepoints information!\n");
-               goto out_delete_evlist;
-       }
+       if (perf_evlist__add_syscall_newtp(evlist, trace__sys_enter, trace__sys_exit))
+               goto out_error_tp;
+
+       perf_evlist__add_vfs_getname(evlist);
 
        if (trace->sched &&
-           perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
-                                  trace__sched_stat_runtime)) {
-               fprintf(trace->output, "Couldn't read the sched_stat_runtime tracepoint information!\n");
-               goto out_delete_evlist;
-       }
+               perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
+                               trace__sched_stat_runtime))
+               goto out_error_tp;
 
        err = perf_evlist__create_maps(evlist, &trace->opts.target);
        if (err < 0) {
@@ -954,10 +1890,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
        }
 
        err = perf_evlist__open(evlist);
-       if (err < 0) {
-               fprintf(trace->output, "Couldn't create the events: %s\n", strerror(errno));
-               goto out_delete_maps;
-       }
+       if (err < 0)
+               goto out_error_open;
 
        err = perf_evlist__mmap(evlist, UINT_MAX, false);
        if (err < 0) {
@@ -990,11 +1924,11 @@ again:
                                goto next_event;
                        }
 
-                       if (trace->base_time == 0)
+                       if (!trace->full_time && trace->base_time == 0)
                                trace->base_time = sample.time;
 
                        if (type != PERF_RECORD_SAMPLE) {
-                               trace__process_event(trace, &trace->host, event);
+                               trace__process_event(trace, trace->host, event, &sample);
                                continue;
                        }
 
@@ -1011,29 +1945,41 @@ again:
                                goto next_event;
                        }
 
-                       handler = evsel->handler.func;
+                       handler = evsel->handler;
                        handler(trace, evsel, &sample);
 next_event:
                        perf_evlist__mmap_consume(evlist, i);
 
-                       if (done)
-                               goto out_unmap_evlist;
+                       if (interrupted)
+                               goto out_disable;
                }
        }
 
        if (trace->nr_events == before) {
-               if (done)
-                       goto out_unmap_evlist;
+               int timeout = done ? 100 : -1;
 
-               poll(evlist->pollfd, evlist->nr_fds, -1);
+               if (poll(evlist->pollfd, evlist->nr_fds, timeout) > 0)
+                       goto again;
+       } else {
+               goto again;
        }
 
-       if (done)
-               perf_evlist__disable(evlist);
+out_disable:
+       perf_evlist__disable(evlist);
 
-       goto again;
+       if (!err) {
+               if (trace->summary)
+                       trace__fprintf_thread_summary(trace, trace->output);
+
+               if (trace->show_tool_stats) {
+                       fprintf(trace->output, "Stats:\n "
+                                              " vfs_getname : %" PRIu64 "\n"
+                                              " proc_getname: %" PRIu64 "\n",
+                               trace->stats.vfs_getname,
+                               trace->stats.proc_getname);
+               }
+       }
 
-out_unmap_evlist:
        perf_evlist__munmap(evlist);
 out_close_evlist:
        perf_evlist__close(evlist);
@@ -1042,7 +1988,22 @@ out_delete_maps:
 out_delete_evlist:
        perf_evlist__delete(evlist);
 out:
+       trace->live = false;
        return err;
+{
+       char errbuf[BUFSIZ];
+
+out_error_tp:
+       perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf));
+       goto out_error;
+
+out_error_open:
+       perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
+
+out_error:
+       fprintf(trace->output, "%s\n", errbuf);
+       goto out_delete_evlist;
+}
 }
 
 static int trace__replay(struct trace *trace)
@@ -1050,8 +2011,12 @@ static int trace__replay(struct trace *trace)
        const struct perf_evsel_str_handler handlers[] = {
                { "raw_syscalls:sys_enter",  trace__sys_enter, },
                { "raw_syscalls:sys_exit",   trace__sys_exit, },
+               { "probe:vfs_getname",       trace__vfs_getname, },
+       };
+       struct perf_data_file file = {
+               .path  = input_name,
+               .mode  = PERF_DATA_MODE_READ,
        };
-
        struct perf_session *session;
        int err = -1;
 
@@ -1074,11 +2039,12 @@ static int trace__replay(struct trace *trace)
        if (symbol__init() < 0)
                return -1;
 
-       session = perf_session__new(input_name, O_RDONLY, 0, false,
-                                   &trace->tool);
+       session = perf_session__new(&file, false, &trace->tool);
        if (session == NULL)
                return -ENOMEM;
 
+       trace->host = &session->machines.host;
+
        err = perf_session__set_tracepoints_handlers(session, handlers);
        if (err)
                goto out;
@@ -1103,6 +2069,9 @@ static int trace__replay(struct trace *trace)
        if (err)
                pr_err("Failed to process events, error %d", err);
 
+       else if (trace->summary)
+               trace__fprintf_thread_summary(trace, trace->output);
+
 out:
        perf_session__delete(session);
 
@@ -1113,47 +2082,111 @@ static size_t trace__fprintf_threads_header(FILE *fp)
 {
        size_t printed;
 
-       printed  = fprintf(fp, "\n _____________________________________________________________________\n");
-       printed += fprintf(fp," __)    Summary of events    (__\n\n");
-       printed += fprintf(fp,"              [ task - pid ]     [ events ] [ ratio ]  [ runtime ]\n");
-       printed += fprintf(fp," _____________________________________________________________________\n\n");
+       printed  = fprintf(fp, "\n _____________________________________________________________________________\n");
+       printed += fprintf(fp, " __)    Summary of events    (__\n\n");
+       printed += fprintf(fp, "              [ task - pid ]     [ events ] [ ratio ]  [ runtime ]\n");
+       printed += fprintf(fp, "                                  syscall  count    min     max    avg  stddev\n");
+       printed += fprintf(fp, "                                                   msec    msec   msec     %%\n");
+       printed += fprintf(fp, " _____________________________________________________________________________\n\n");
 
        return printed;
 }
 
-static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
+static size_t thread__dump_stats(struct thread_trace *ttrace,
+                                struct trace *trace, FILE *fp)
 {
-       size_t printed = trace__fprintf_threads_header(fp);
-       struct rb_node *nd;
-
-       for (nd = rb_first(&trace->host.threads); nd; nd = rb_next(nd)) {
-               struct thread *thread = rb_entry(nd, struct thread, rb_node);
-               struct thread_trace *ttrace = thread->priv;
-               const char *color;
-               double ratio;
-
-               if (ttrace == NULL)
-                       continue;
+       struct stats *stats;
+       size_t printed = 0;
+       struct syscall *sc;
+       struct int_node *inode = intlist__first(ttrace->syscall_stats);
 
-               ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
+       if (inode == NULL)
+               return 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 += fprintf(fp, "\n");
+
+       /* each int_node is a syscall */
+       while (inode) {
+               stats = inode->priv;
+               if (stats) {
+                       double min = (double)(stats->min) / NSEC_PER_MSEC;
+                       double max = (double)(stats->max) / NSEC_PER_MSEC;
+                       double avg = avg_stats(stats);
+                       double pct;
+                       u64 n = (u64) stats->n;
+
+                       pct = avg ? 100.0 * stddev_stats(stats)/avg : 0.0;
+                       avg /= NSEC_PER_MSEC;
+
+                       sc = &trace->syscalls.table[inode->i];
+                       printed += fprintf(fp, "%24s  %14s : ", "", sc->name);
+                       printed += fprintf(fp, "%5" PRIu64 "  %8.3f  %8.3f",
+                                          n, min, max);
+                       printed += fprintf(fp, "  %8.3f  %6.2f\n", avg, pct);
+               }
 
-               printed += color_fprintf(fp, color, "%20s", thread->comm);
-               printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
-               printed += color_fprintf(fp, color, "%5.1f%%", ratio);
-               printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
+               inode = intlist__next(inode);
        }
 
+       printed += fprintf(fp, "\n\n");
+
        return printed;
 }
 
+/* struct used to pass data to per-thread function */
+struct summary_data {
+       FILE *fp;
+       struct trace *trace;
+       size_t printed;
+};
+
+static int trace__fprintf_one_thread(struct thread *thread, void *priv)
+{
+       struct summary_data *data = priv;
+       FILE *fp = data->fp;
+       size_t printed = data->printed;
+       struct trace *trace = data->trace;
+       struct thread_trace *ttrace = thread->priv;
+       const char *color;
+       double ratio;
+
+       if (ttrace == NULL)
+               return 0;
+
+       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, "%20s", thread__comm_str(thread));
+       printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
+       printed += color_fprintf(fp, color, "%5.1f%%", ratio);
+       printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
+       printed += thread__dump_stats(ttrace, trace, fp);
+
+       data->printed += printed;
+
+       return 0;
+}
+
+static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
+{
+       struct summary_data data = {
+               .fp = fp,
+               .trace = trace
+       };
+       data.printed = trace__fprintf_threads_header(fp);
+
+       machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
+
+       return data.printed;
+}
+
 static int trace__set_duration(const struct option *opt, const char *str,
                               int unset __maybe_unused)
 {
@@ -1185,10 +2218,15 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
        const char * const trace_usage[] = {
                "perf trace [<options>] [<command>]",
                "perf trace [<options>] -- <command> [<options>]",
+               "perf trace record [<options>] [<command>]",
+               "perf trace record [<options>] -- <command> [<options>]",
                NULL
        };
        struct trace trace = {
-               .audit_machine = audit_detect_machine(),
+               .audit = {
+                       .machine = audit_detect_machine(),
+                       .open_id = audit_name_to_syscall("open", trace.audit.machine),
+               },
                .syscalls = {
                        . max = -1,
                },
@@ -1203,10 +2241,14 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
                        .mmap_pages    = 1024,
                },
                .output = stdout,
+               .show_comm = true,
        };
        const char *output_name = NULL;
        const char *ev_qualifier_str = NULL;
        const struct option trace_options[] = {
+       OPT_BOOLEAN(0, "comm", &trace.show_comm,
+                   "show the thread COMM next to its id"),
+       OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"),
        OPT_STRING('e', "expr", &ev_qualifier_str, "expr",
                    "list of events to trace"),
        OPT_STRING('o', "output", &output_name, "file", "output file name"),
@@ -1221,8 +2263,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
                    "list of cpus to monitor"),
        OPT_BOOLEAN(0, "no-inherit", &trace.opts.no_inherit,
                    "child tasks do not inherit counters"),
-       OPT_UINTEGER('m', "mmap-pages", &trace.opts.mmap_pages,
-                    "number of mmap data pages"),
+       OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages",
+                    "number of mmap data pages",
+                    perf_evlist__parse_mmap_pages),
        OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user",
                   "user to profile"),
        OPT_CALLBACK(0, "duration", &trace, "float",
@@ -1230,11 +2273,18 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
                     trace__set_duration),
        OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
        OPT_INCR('v', "verbose", &verbose, "be more verbose"),
+       OPT_BOOLEAN('T', "time", &trace.full_time,
+                   "Show full timestamp, not time relative to first start"),
+       OPT_BOOLEAN(0, "summary", &trace.summary,
+                   "Show syscall summary with statistics"),
        OPT_END()
        };
        int err;
        char bf[BUFSIZ];
 
+       if ((argc > 1) && (strcmp(argv[1], "record") == 0))
+               return trace__record(argc-2, &argv[2]);
+
        argc = parse_options(argc, argv, trace_options, trace_usage, 0);
 
        if (output_name != NULL) {
@@ -1282,9 +2332,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
        else
                err = trace__run(&trace, argc, argv);
 
-       if (trace.sched && !err)
-               trace__fprintf_thread_summary(&trace, trace.output);
-
 out_close:
        if (output_name != NULL)
                fclose(trace.output);
index 5f6f9b3271bb0657b77206f6723fd8b3786041bd..58b2d37ae23a19db3719ebfa29c98a79905a4c49 100644 (file)
@@ -23,15 +23,17 @@ ifeq ($(ARCH),x86_64)
   endif
   ifeq (${IS_X86_64}, 1)
     RAW_ARCH := x86_64
-    CFLAGS += -DARCH_X86_64
+    CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
     ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
+    LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
+  else
+    LIBUNWIND_LIBS = -lunwind -lunwind-x86
   endif
   NO_PERF_REGS := 0
-  LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
 endif
 
 ifeq ($(NO_PERF_REGS),0)
-  CFLAGS += -DHAVE_PERF_REGS
+  CFLAGS += -DHAVE_PERF_REGS_SUPPORT
 endif
 
 ifeq ($(src-perf),)
@@ -51,7 +53,6 @@ LIB_INCLUDE := $(srctree)/tools/lib/
 # include ARCH specific config
 -include $(src-perf)/arch/$(ARCH)/Makefile
 
-include $(src-perf)/config/feature-tests.mak
 include $(src-perf)/config/utilities.mak
 
 ifeq ($(call get-executable,$(FLEX)),)
@@ -67,10 +68,11 @@ ifneq ($(WERROR),0)
   CFLAGS += -Werror
 endif
 
-ifeq ("$(origin DEBUG)", "command line")
-  PERF_DEBUG = $(DEBUG)
+ifndef DEBUG
+  DEBUG := 0
 endif
-ifndef PERF_DEBUG
+
+ifeq ($(DEBUG),0)
   CFLAGS += -O6
 endif
 
@@ -89,20 +91,125 @@ CFLAGS += -std=gnu99
 
 EXTLIBS = -lelf -lpthread -lrt -lm -ldl
 
-ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
-  CFLAGS += -fstack-protector-all
+ifneq ($(OUTPUT),)
+  OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
+  $(shell mkdir -p $(OUTPUT_FEATURES))
 endif
 
-ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
-  CFLAGS += -Wstack-protector
+feature_check = $(eval $(feature_check_code))
+define feature_check_code
+  feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBUNWIND_LIBS="$(LIBUNWIND_LIBS)" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
+endef
+
+feature_set = $(eval $(feature_set_code))
+define feature_set_code
+  feature-$(1) := 1
+endef
+
+#
+# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
+#
+
+#
+# Note that this is not a complete list of all feature tests, just
+# those that are typically built on a fully configured system.
+#
+# [ Feature tests not mentioned here have to be built explicitly in
+#   the rule that uses them - an example for that is the 'bionic'
+#   feature check. ]
+#
+CORE_FEATURE_TESTS =                   \
+       backtrace                       \
+       dwarf                           \
+       fortify-source                  \
+       glibc                           \
+       gtk2                            \
+       gtk2-infobar                    \
+       libaudit                        \
+       libbfd                          \
+       libelf                          \
+       libelf-getphdrnum               \
+       libelf-mmap                     \
+       libnuma                         \
+       libperl                         \
+       libpython                       \
+       libpython-version               \
+       libslang                        \
+       libunwind                       \
+       on-exit                         \
+       stackprotector                  \
+       stackprotector-all
+
+#
+# So here we detect whether test-all was rebuilt, to be able
+# to skip the print-out of the long features list if the file
+# existed before and after it was built:
+#
+ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),)
+  test-all-failed := 1
+else
+  test-all-failed := 0
+endif
+
+#
+# Special fast-path for the 'all features are available' case:
+#
+$(call feature_check,all,$(MSG))
+
+#
+# Just in case the build freshly failed, make sure we print the
+# feature matrix:
+#
+ifeq ($(feature-all), 0)
+  test-all-failed := 1
 endif
 
-ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
-  CFLAGS += -Wvolatile-register-var
+ifeq ($(test-all-failed),1)
+  $(info )
+  $(info Auto-detecting system features:)
 endif
 
-ifndef PERF_DEBUG
-  ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
+ifeq ($(feature-all), 1)
+  #
+  # test-all.c passed - just set all the core feature flags to 1:
+  #
+  $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat)))
+else
+  $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1)
+  $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat)))
+endif
+
+#
+# Print the result of the feature test:
+#
+feature_print = $(eval $(feature_print_code)) $(info $(MSG))
+
+define feature_print_code
+  ifeq ($(feature-$(1)), 1)
+    MSG = $(shell printf '...%30s: [ \033[32mon\033[m  ]' $(1))
+  else
+    MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
+  endif
+endef
+
+#
+# Only print out our features if we rebuilt the testcases or if a test failed:
+#
+ifeq ($(test-all-failed), 1)
+  $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_print,$(feat)))
+  $(info )
+endif
+
+ifeq ($(feature-stackprotector-all), 1)
+  CFLAGS += -fstack-protector-all
+endif
+
+ifeq ($(feature-stackprotector), 1)
+  CFLAGS += -Wstack-protector
+endif
+
+ifeq ($(DEBUG),0)
+  ifeq ($(feature-fortify-source), 1)
     CFLAGS += -D_FORTIFY_SOURCE=2
   endif
 endif
@@ -128,84 +235,74 @@ CFLAGS += -I$(LIB_INCLUDE)
 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 
 ifndef NO_BIONIC
-ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
-  BIONIC := 1
-  EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
-  EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+  $(call feature_check,bionic)
+  ifeq ($(feature-bionic), 1)
+    BIONIC := 1
+    EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+    EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+  endif
 endif
-endif # NO_BIONIC
 
 ifdef NO_LIBELF
   NO_DWARF := 1
   NO_DEMANGLE := 1
   NO_LIBUNWIND := 1
 else
-FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
-ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
-  FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
-  ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
-    LIBC_SUPPORT := 1
-  endif
-  ifeq ($(BIONIC),1)
-    LIBC_SUPPORT := 1
-  endif
-  ifeq ($(LIBC_SUPPORT),1)
-    msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
+  ifeq ($(feature-libelf), 0)
+    ifeq ($(feature-glibc), 1)
+      LIBC_SUPPORT := 1
+    endif
+    ifeq ($(BIONIC),1)
+      LIBC_SUPPORT := 1
+    endif
+    ifeq ($(LIBC_SUPPORT),1)
+      msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
 
-    NO_LIBELF := 1
-    NO_DWARF := 1
-    NO_DEMANGLE := 1
+      NO_LIBELF := 1
+      NO_DWARF := 1
+      NO_DEMANGLE := 1
+    else
+      msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+    endif
   else
-    msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
-  endif
-else
-  # for linking with debug library, run like:
-  # make DEBUG=1 LIBDW_DIR=/opt/libdw/
-  ifdef LIBDW_DIR
-    LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
-    LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
-  endif
+    # for linking with debug library, run like:
+    # make DEBUG=1 LIBDW_DIR=/opt/libdw/
+    ifdef LIBDW_DIR
+      LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
+      LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
+    endif
 
-  FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lz -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
-  ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
-    msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
-    NO_DWARF := 1
-  endif # Dwarf support
-endif # SOURCE_LIBELF
+    ifneq ($(feature-dwarf), 1)
+      msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+      NO_DWARF := 1
+    endif # Dwarf support
+  endif # libelf support
 endif # NO_LIBELF
 
 ifndef NO_LIBELF
-CFLAGS += -DLIBELF_SUPPORT
-FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
-ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
-  CFLAGS += -DLIBELF_MMAP
-endif
-ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y)
-  CFLAGS += -DHAVE_ELF_GETPHDRNUM
-endif
+  CFLAGS += -DHAVE_LIBELF_SUPPORT
 
-# include ARCH specific config
--include $(src-perf)/arch/$(ARCH)/Makefile
+  ifeq ($(feature-libelf-mmap), 1)
+    CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
+  endif
 
-ifndef NO_DWARF
-ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
-  msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
-  NO_DWARF := 1
-else
-  CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
-  LDFLAGS += $(LIBDW_LDFLAGS)
-  EXTLIBS += -lelf -ldw
-endif # PERF_HAVE_DWARF_REGS
-endif # NO_DWARF
+  ifeq ($(feature-libelf-getphdrnum), 1)
+    CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT
+  endif
 
-endif # NO_LIBELF
+  # include ARCH specific config
+  -include $(src-perf)/arch/$(ARCH)/Makefile
 
-ifndef NO_LIBELF
-CFLAGS += -DLIBELF_SUPPORT
-FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
-ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
-  CFLAGS += -DLIBELF_MMAP
-endif # try-cc
+  ifndef NO_DWARF
+    ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+      msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
+      NO_DWARF := 1
+    else
+      CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS)
+      LDFLAGS += $(LIBDW_LDFLAGS)
+      EXTLIBS += -lelf -ldw
+    endif # PERF_HAVE_DWARF_REGS
+  endif # NO_DWARF
 endif # NO_LIBELF
 
 # There's only x86 (both 32 and 64) support for CFI unwind so far
@@ -214,34 +311,35 @@ ifneq ($(ARCH),x86)
 endif
 
 ifndef NO_LIBUNWIND
-# for linking with debug library, run like:
-# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
-ifdef LIBUNWIND_DIR
-  LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
-  LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
-endif
+  #
+  # For linking with debug library, run like:
+  #
+  #   make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
+  #
+  ifdef LIBUNWIND_DIR
+    LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
+    LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+  endif
 
-FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
-ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
-  msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
-  NO_LIBUNWIND := 1
-endif # Libunwind support
-endif # NO_LIBUNWIND
+  ifneq ($(feature-libunwind), 1)
+    msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+    NO_LIBUNWIND := 1
+  endif
+endif
 
 ifndef NO_LIBUNWIND
-  CFLAGS += -DLIBUNWIND_SUPPORT
+  CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
   EXTLIBS += $(LIBUNWIND_LIBS)
   CFLAGS += $(LIBUNWIND_CFLAGS)
   LDFLAGS += $(LIBUNWIND_LDFLAGS)
-endif # NO_LIBUNWIND
+endif
 
 ifndef NO_LIBAUDIT
-  FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
-  ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
+  ifneq ($(feature-libaudit), 1)
     msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
     NO_LIBAUDIT := 1
   else
-    CFLAGS += -DLIBAUDIT_SUPPORT
+    CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
     EXTLIBS += -laudit
   endif
 endif
@@ -251,30 +349,30 @@ ifdef NO_NEWT
 endif
 
 ifndef NO_SLANG
-  FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
-  ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
+  ifneq ($(feature-libslang), 1)
     msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
     NO_SLANG := 1
   else
     # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
     CFLAGS += -I/usr/include/slang
-    CFLAGS += -DSLANG_SUPPORT
+    CFLAGS += -DHAVE_SLANG_SUPPORT
     EXTLIBS += -lslang
   endif
 endif
 
 ifndef NO_GTK2
   FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
-  ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
+  ifneq ($(feature-gtk2), 1)
     msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
     NO_GTK2 := 1
   else
-    ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
-      CFLAGS += -DHAVE_GTK_INFO_BAR
+    ifeq ($(feature-gtk2-infobar), 1)
+      GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT
     endif
-    CFLAGS += -DGTK2_SUPPORT
-    CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
-    EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+    CFLAGS += -DHAVE_GTK2_SUPPORT
+    GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
+    GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+    EXTLIBS += -ldl
   endif
 endif
 
@@ -290,7 +388,7 @@ else
   PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
   FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
 
-  ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
+  ifneq ($(feature-libperl), 1)
     CFLAGS += -DNO_LIBPERL
     NO_LIBPERL := 1
   else
@@ -299,6 +397,13 @@ else
   endif
 endif
 
+$(call feature_check,timerfd)
+ifeq ($(feature-timerfd), 1)
+  CFLAGS += -DHAVE_TIMERFD_SUPPORT
+else
+  msg := $(warning No timerfd support. Disables 'perf kvm stat live');
+endif
+
 disable-python = $(eval $(disable-python_code))
 define disable-python_code
   CFLAGS += -DNO_LIBPYTHON
@@ -335,11 +440,11 @@ else
       PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
       FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
 
-      ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
+      ifneq ($(feature-libpython), 1)
         $(call disable-python,Python.h (for Python 2.x))
       else
 
-        ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
+        ifneq ($(feature-libpython-version), 1)
           $(warning Python 3 is not yet supported; please set)
           $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
           $(warning If you also have Python 2 installed, then)
@@ -362,33 +467,30 @@ else
   endif
 endif
 
+ifeq ($(feature-libbfd), 1)
+  EXTLIBS += -lbfd
+endif
+
 ifdef NO_DEMANGLE
   CFLAGS += -DNO_DEMANGLE
 else
-  ifdef HAVE_CPLUS_DEMANGLE
+  ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
     EXTLIBS += -liberty
-    CFLAGS += -DHAVE_CPLUS_DEMANGLE
+    CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
   else
-    FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
-    has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
-    ifeq ($(has_bfd),y)
-      EXTLIBS += -lbfd
-    else
-      FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
-      has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
-      ifeq ($(has_bfd_iberty),y)
+    ifneq ($(feature-libbfd), 1)
+      $(call feature_check,liberty)
+      ifeq ($(feature-liberty), 1)
         EXTLIBS += -lbfd -liberty
       else
-        FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
-        has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
-        ifeq ($(has_bfd_iberty_z),y)
+        $(call feature_check,liberty-z)
+        ifeq ($(feature-liberty-z), 1)
           EXTLIBS += -lbfd -liberty -lz
         else
-          FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
-          has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
-          ifeq ($(has_cplus_demangle),y)
+          $(call feature_check,cplus-demangle)
+          ifeq ($(feature-cplus-demangle), 1)
             EXTLIBS += -liberty
-            CFLAGS += -DHAVE_CPLUS_DEMANGLE
+            CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
           else
             msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
             CFLAGS += -DNO_DEMANGLE
@@ -399,31 +501,28 @@ else
   endif
 endif
 
-ifndef NO_STRLCPY
-  ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
-    CFLAGS += -DHAVE_STRLCPY
-  endif
+ifneq ($(filter -lbfd,$(EXTLIBS)),)
+  CFLAGS += -DHAVE_LIBBFD_SUPPORT
 endif
 
 ifndef NO_ON_EXIT
-  ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
-    CFLAGS += -DHAVE_ON_EXIT
+  ifeq ($(feature-on-exit), 1)
+    CFLAGS += -DHAVE_ON_EXIT_SUPPORT
   endif
 endif
 
 ifndef NO_BACKTRACE
-  ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
-    CFLAGS += -DBACKTRACE_SUPPORT
+  ifeq ($(feature-backtrace), 1)
+    CFLAGS += -DHAVE_BACKTRACE_SUPPORT
   endif
 endif
 
 ifndef NO_LIBNUMA
-  FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
-  ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
+  ifeq ($(feature-libnuma), 0)
     msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
     NO_LIBNUMA := 1
   else
-    CFLAGS += -DLIBNUMA_SUPPORT
+    CFLAGS += -DHAVE_LIBNUMA_SUPPORT
     EXTLIBS += -lnuma
   endif
 endif
@@ -459,7 +558,12 @@ else
 sysconfdir = $(prefix)/etc
 ETC_PERFCONFIG = etc/perfconfig
 endif
+ifeq ($(IS_X86_64),1)
+lib = lib64
+else
 lib = lib
+endif
+libdir = $(prefix)/$(lib)
 
 # Shell quote (do not use $(call) to accommodate ancient setups);
 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
@@ -472,6 +576,7 @@ template_dir_SQ = $(subst ','\'',$(template_dir))
 htmldir_SQ = $(subst ','\'',$(htmldir))
 prefix_SQ = $(subst ','\'',$(prefix))
 sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
+libdir_SQ = $(subst ','\'',$(libdir))
 
 ifneq ($(filter /%,$(firstword $(perfexecdir))),)
 perfexec_instdir = $(perfexecdir)
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
new file mode 100644 (file)
index 0000000..c803f17
--- /dev/null
@@ -0,0 +1,148 @@
+
+FILES=                                 \
+       test-all                        \
+       test-backtrace                  \
+       test-bionic                     \
+       test-dwarf                      \
+       test-fortify-source             \
+       test-glibc                      \
+       test-gtk2                       \
+       test-gtk2-infobar               \
+       test-hello                      \
+       test-libaudit                   \
+       test-libbfd                     \
+       test-liberty                    \
+       test-liberty-z                  \
+       test-cplus-demangle             \
+       test-libelf                     \
+       test-libelf-getphdrnum          \
+       test-libelf-mmap                \
+       test-libnuma                    \
+       test-libperl                    \
+       test-libpython                  \
+       test-libpython-version          \
+       test-libslang                   \
+       test-libunwind                  \
+       test-on-exit                    \
+       test-stackprotector-all         \
+       test-stackprotector             \
+       test-timerfd
+
+CC := $(CC) -MD
+
+all: $(FILES)
+
+BUILD = $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUTPUT)$@ $@.c
+
+###############################
+
+test-all:
+       $(BUILD) -Werror -fstack-protector -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma $(LIBUNWIND_LIBS) -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
+
+test-hello:
+       $(BUILD)
+
+test-stackprotector-all:
+       $(BUILD) -Werror -fstack-protector-all
+
+test-stackprotector:
+       $(BUILD) -Werror -fstack-protector -Wstack-protector
+
+test-fortify-source:
+       $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2
+
+test-bionic:
+       $(BUILD)
+
+test-libelf:
+       $(BUILD) -lelf
+
+test-glibc:
+       $(BUILD)
+
+test-dwarf:
+       $(BUILD) -ldw
+
+test-libelf-mmap:
+       $(BUILD) -lelf
+
+test-libelf-getphdrnum:
+       $(BUILD) -lelf
+
+test-libnuma:
+       $(BUILD) -lnuma
+
+test-libunwind:
+       $(BUILD) $(LIBUNWIND_LIBS) -lelf
+
+test-libaudit:
+       $(BUILD) -laudit
+
+test-libslang:
+       $(BUILD) -I/usr/include/slang -lslang
+
+test-gtk2:
+       $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+
+test-gtk2-infobar:
+       $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+
+grep-libs  = $(filter -l%,$(1))
+strip-libs = $(filter-out -l%,$(1))
+
+PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
+PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
+PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
+PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
+FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
+
+test-libperl:
+       $(BUILD) $(FLAGS_PERL_EMBED)
+
+override PYTHON := python
+override PYTHON_CONFIG := python-config
+
+escape-for-shell-sq =  $(subst ','\'',$(1))
+shell-sq = '$(escape-for-shell-sq)'
+
+PYTHON_CONFIG_SQ = $(call shell-sq,$(PYTHON_CONFIG))
+
+PYTHON_EMBED_LDOPTS = $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
+PYTHON_EMBED_LDFLAGS = $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
+PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
+PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
+FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
+
+test-libpython:
+       $(BUILD) $(FLAGS_PYTHON_EMBED)
+
+test-libpython-version:
+       $(BUILD) $(FLAGS_PYTHON_EMBED)
+
+test-libbfd:
+       $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl
+
+test-liberty:
+       $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty
+
+test-liberty-z:
+       $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz
+
+test-cplus-demangle:
+       $(BUILD) -liberty
+
+test-on-exit:
+       $(BUILD)
+
+test-backtrace:
+       $(BUILD)
+
+test-timerfd:
+       $(BUILD)
+
+-include *.d
+
+###############################
+
+clean:
+       rm -f $(FILES) *.d
diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/perf/config/feature-checks/test-all.c
new file mode 100644 (file)
index 0000000..59e7a70
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * test-all.c: Try to build all the main testcases at once.
+ *
+ * A well-configured system will have all the prereqs installed, so we can speed
+ * up auto-detection on such systems.
+ */
+
+/*
+ * Quirk: Python and Perl headers cannot be in arbitrary places, so keep
+ * these 3 testcases at the top:
+ */
+#define main main_test_libpython
+# include "test-libpython.c"
+#undef main
+
+#define main main_test_libpython_version
+# include "test-libpython-version.c"
+#undef main
+
+#define main main_test_libperl
+# include "test-libperl.c"
+#undef main
+
+#define main main_test_hello
+# include "test-hello.c"
+#undef main
+
+#define main main_test_libelf
+# include "test-libelf.c"
+#undef main
+
+#define main main_test_libelf_mmap
+# include "test-libelf-mmap.c"
+#undef main
+
+#define main main_test_glibc
+# include "test-glibc.c"
+#undef main
+
+#define main main_test_dwarf
+# include "test-dwarf.c"
+#undef main
+
+#define main main_test_libelf_getphdrnum
+# include "test-libelf-getphdrnum.c"
+#undef main
+
+#define main main_test_libunwind
+# include "test-libunwind.c"
+#undef main
+
+#define main main_test_libaudit
+# include "test-libaudit.c"
+#undef main
+
+#define main main_test_libslang
+# include "test-libslang.c"
+#undef main
+
+#define main main_test_gtk2
+# include "test-gtk2.c"
+#undef main
+
+#define main main_test_gtk2_infobar
+# include "test-gtk2-infobar.c"
+#undef main
+
+#define main main_test_libbfd
+# include "test-libbfd.c"
+#undef main
+
+#define main main_test_on_exit
+# include "test-on-exit.c"
+#undef main
+
+#define main main_test_backtrace
+# include "test-backtrace.c"
+#undef main
+
+#define main main_test_libnuma
+# include "test-libnuma.c"
+#undef main
+
+#define main main_test_timerfd
+# include "test-timerfd.c"
+#undef main
+
+int main(int argc, char *argv[])
+{
+       main_test_libpython();
+       main_test_libpython_version();
+       main_test_libperl();
+       main_test_hello();
+       main_test_libelf();
+       main_test_libelf_mmap();
+       main_test_glibc();
+       main_test_dwarf();
+       main_test_libelf_getphdrnum();
+       main_test_libunwind();
+       main_test_libaudit();
+       main_test_libslang();
+       main_test_gtk2(argc, argv);
+       main_test_gtk2_infobar(argc, argv);
+       main_test_libbfd();
+       main_test_on_exit();
+       main_test_backtrace();
+       main_test_libnuma();
+       main_test_timerfd();
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-backtrace.c b/tools/perf/config/feature-checks/test-backtrace.c
new file mode 100644 (file)
index 0000000..7124aa1
--- /dev/null
@@ -0,0 +1,13 @@
+#include <execinfo.h>
+#include <stdio.h>
+
+int main(void)
+{
+       void *backtrace_fns[10];
+       size_t entries;
+
+       entries = backtrace(backtrace_fns, 10);
+       backtrace_symbols_fd(backtrace_fns, entries, 1);
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-bionic.c b/tools/perf/config/feature-checks/test-bionic.c
new file mode 100644 (file)
index 0000000..eac24e9
--- /dev/null
@@ -0,0 +1,6 @@
+#include <android/api-level.h>
+
+int main(void)
+{
+       return __ANDROID_API__;
+}
diff --git a/tools/perf/config/feature-checks/test-cplus-demangle.c b/tools/perf/config/feature-checks/test-cplus-demangle.c
new file mode 100644 (file)
index 0000000..610c686
--- /dev/null
@@ -0,0 +1,14 @@
+extern int printf(const char *format, ...);
+extern char *cplus_demangle(const char *, int);
+
+int main(void)
+{
+       char symbol[4096] = "FieldName__9ClassNameFd";
+       char *tmp;
+
+       tmp = cplus_demangle(symbol, 0);
+
+       printf("demangled symbol: {%s}\n", tmp);
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-dwarf.c b/tools/perf/config/feature-checks/test-dwarf.c
new file mode 100644 (file)
index 0000000..3fc1801
--- /dev/null
@@ -0,0 +1,10 @@
+#include <dwarf.h>
+#include <elfutils/libdw.h>
+#include <elfutils/version.h>
+
+int main(void)
+{
+       Dwarf *dbg = dwarf_begin(0, DWARF_C_READ);
+
+       return (long)dbg;
+}
diff --git a/tools/perf/config/feature-checks/test-fortify-source.c b/tools/perf/config/feature-checks/test-fortify-source.c
new file mode 100644 (file)
index 0000000..c9f398d
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void)
+{
+       return puts("hi");
+}
diff --git a/tools/perf/config/feature-checks/test-glibc.c b/tools/perf/config/feature-checks/test-glibc.c
new file mode 100644 (file)
index 0000000..b082034
--- /dev/null
@@ -0,0 +1,8 @@
+#include <gnu/libc-version.h>
+
+int main(void)
+{
+       const char *version = gnu_get_libc_version();
+
+       return (long)version;
+}
diff --git a/tools/perf/config/feature-checks/test-gtk2-infobar.c b/tools/perf/config/feature-checks/test-gtk2-infobar.c
new file mode 100644 (file)
index 0000000..397b464
--- /dev/null
@@ -0,0 +1,11 @@
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+#include <gtk/gtk.h>
+#pragma GCC diagnostic error "-Wstrict-prototypes"
+
+int main(int argc, char *argv[])
+{
+       gtk_init(&argc, &argv);
+       gtk_info_bar_new();
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-gtk2.c b/tools/perf/config/feature-checks/test-gtk2.c
new file mode 100644 (file)
index 0000000..6bd80e5
--- /dev/null
@@ -0,0 +1,10 @@
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+#include <gtk/gtk.h>
+#pragma GCC diagnostic error "-Wstrict-prototypes"
+
+int main(int argc, char *argv[])
+{
+       gtk_init(&argc, &argv);
+
+        return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-hello.c b/tools/perf/config/feature-checks/test-hello.c
new file mode 100644 (file)
index 0000000..c9f398d
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void)
+{
+       return puts("hi");
+}
diff --git a/tools/perf/config/feature-checks/test-libaudit.c b/tools/perf/config/feature-checks/test-libaudit.c
new file mode 100644 (file)
index 0000000..afc019f
--- /dev/null
@@ -0,0 +1,10 @@
+#include <libaudit.h>
+
+extern int printf(const char *format, ...);
+
+int main(void)
+{
+       printf("error message: %s\n", audit_errno_to_name(0));
+
+       return audit_open();
+}
diff --git a/tools/perf/config/feature-checks/test-libbfd.c b/tools/perf/config/feature-checks/test-libbfd.c
new file mode 100644 (file)
index 0000000..2405990
--- /dev/null
@@ -0,0 +1,15 @@
+#include <bfd.h>
+
+extern int printf(const char *format, ...);
+
+int main(void)
+{
+       char symbol[4096] = "FieldName__9ClassNameFd";
+       char *tmp;
+
+       tmp = bfd_demangle(0, symbol, 0);
+
+       printf("demangled symbol: {%s}\n", tmp);
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-libelf-getphdrnum.c b/tools/perf/config/feature-checks/test-libelf-getphdrnum.c
new file mode 100644 (file)
index 0000000..d710459
--- /dev/null
@@ -0,0 +1,8 @@
+#include <libelf.h>
+
+int main(void)
+{
+       size_t dst;
+
+       return elf_getphdrnum(0, &dst);
+}
diff --git a/tools/perf/config/feature-checks/test-libelf-mmap.c b/tools/perf/config/feature-checks/test-libelf-mmap.c
new file mode 100644 (file)
index 0000000..564427d
--- /dev/null
@@ -0,0 +1,8 @@
+#include <libelf.h>
+
+int main(void)
+{
+       Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0);
+
+       return (long)elf;
+}
diff --git a/tools/perf/config/feature-checks/test-libelf.c b/tools/perf/config/feature-checks/test-libelf.c
new file mode 100644 (file)
index 0000000..08db322
--- /dev/null
@@ -0,0 +1,8 @@
+#include <libelf.h>
+
+int main(void)
+{
+       Elf *elf = elf_begin(0, ELF_C_READ, 0);
+
+       return (long)elf;
+}
diff --git a/tools/perf/config/feature-checks/test-libnuma.c b/tools/perf/config/feature-checks/test-libnuma.c
new file mode 100644 (file)
index 0000000..4763d9c
--- /dev/null
@@ -0,0 +1,9 @@
+#include <numa.h>
+#include <numaif.h>
+
+int main(void)
+{
+       numa_available();
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-libperl.c b/tools/perf/config/feature-checks/test-libperl.c
new file mode 100644 (file)
index 0000000..8871f6a
--- /dev/null
@@ -0,0 +1,9 @@
+#include <EXTERN.h>
+#include <perl.h>
+
+int main(void)
+{
+       perl_alloc();
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-libpython-version.c b/tools/perf/config/feature-checks/test-libpython-version.c
new file mode 100644 (file)
index 0000000..facea12
--- /dev/null
@@ -0,0 +1,10 @@
+#include <Python.h>
+
+#if PY_VERSION_HEX >= 0x03000000
+       #error
+#endif
+
+int main(void)
+{
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-libpython.c b/tools/perf/config/feature-checks/test-libpython.c
new file mode 100644 (file)
index 0000000..b24b28a
--- /dev/null
@@ -0,0 +1,8 @@
+#include <Python.h>
+
+int main(void)
+{
+       Py_Initialize();
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-libslang.c b/tools/perf/config/feature-checks/test-libslang.c
new file mode 100644 (file)
index 0000000..22ff22e
--- /dev/null
@@ -0,0 +1,6 @@
+#include <slang.h>
+
+int main(void)
+{
+       return SLsmg_init_smg();
+}
diff --git a/tools/perf/config/feature-checks/test-libunwind.c b/tools/perf/config/feature-checks/test-libunwind.c
new file mode 100644 (file)
index 0000000..43b9369
--- /dev/null
@@ -0,0 +1,27 @@
+#include <libunwind.h>
+#include <stdlib.h>
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+                                      unw_word_t ip,
+                                      unw_dyn_info_t *di,
+                                      unw_proc_info_t *pi,
+                                      int need_unwind_info, void *arg);
+
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+static unw_accessors_t accessors;
+
+int main(void)
+{
+       unw_addr_space_t addr_space;
+
+       addr_space = unw_create_addr_space(&accessors, 0);
+       if (addr_space)
+               return 0;
+
+       unw_init_remote(NULL, addr_space, NULL);
+       dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-on-exit.c b/tools/perf/config/feature-checks/test-on-exit.c
new file mode 100644 (file)
index 0000000..8e88b16
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+static void exit_fn(int status, void *__data)
+{
+       printf("exit status: %d, data: %d\n", status, *(int *)__data);
+}
+
+static int data = 123;
+
+int main(void)
+{
+       on_exit(exit_fn, &data);
+
+       return 321;
+}
diff --git a/tools/perf/config/feature-checks/test-stackprotector-all.c b/tools/perf/config/feature-checks/test-stackprotector-all.c
new file mode 100644 (file)
index 0000000..c9f398d
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void)
+{
+       return puts("hi");
+}
diff --git a/tools/perf/config/feature-checks/test-stackprotector.c b/tools/perf/config/feature-checks/test-stackprotector.c
new file mode 100644 (file)
index 0000000..c9f398d
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void)
+{
+       return puts("hi");
+}
diff --git a/tools/perf/config/feature-checks/test-timerfd.c b/tools/perf/config/feature-checks/test-timerfd.c
new file mode 100644 (file)
index 0000000..8c5c083
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * test for timerfd functions used by perf-kvm-stat-live
+ */
+#include <sys/timerfd.h>
+
+int main(void)
+{
+       struct itimerspec new_value;
+
+       int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+       if (fd < 0)
+               return 1;
+
+       if (timerfd_settime(fd, 0, &new_value, NULL) != 0)
+               return 1;
+
+       return 0;
+}
diff --git a/tools/perf/config/feature-checks/test-volatile-register-var.c b/tools/perf/config/feature-checks/test-volatile-register-var.c
new file mode 100644 (file)
index 0000000..c9f398d
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void)
+{
+       return puts("hi");
+}
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
deleted file mode 100644 (file)
index f793057..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-define SOURCE_HELLO
-#include <stdio.h>
-int main(void)
-{
-       return puts(\"hi\");
-}
-endef
-
-ifndef NO_DWARF
-define SOURCE_DWARF
-#include <dwarf.h>
-#include <elfutils/libdw.h>
-#include <elfutils/version.h>
-#ifndef _ELFUTILS_PREREQ
-#error
-#endif
-
-int main(void)
-{
-       Dwarf *dbg = dwarf_begin(0, DWARF_C_READ);
-       return (long)dbg;
-}
-endef
-endif
-
-define SOURCE_LIBELF
-#include <libelf.h>
-
-int main(void)
-{
-       Elf *elf = elf_begin(0, ELF_C_READ, 0);
-       return (long)elf;
-}
-endef
-
-define SOURCE_GLIBC
-#include <gnu/libc-version.h>
-
-int main(void)
-{
-       const char *version = gnu_get_libc_version();
-       return (long)version;
-}
-endef
-
-define SOURCE_BIONIC
-#include <android/api-level.h>
-
-int main(void)
-{
-       return __ANDROID_API__;
-}
-endef
-
-define SOURCE_ELF_MMAP
-#include <libelf.h>
-int main(void)
-{
-       Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0);
-       return (long)elf;
-}
-endef
-
-define SOURCE_ELF_GETPHDRNUM
-#include <libelf.h>
-int main(void)
-{
-       size_t dst;
-       return elf_getphdrnum(0, &dst);
-}
-endef
-
-ifndef NO_SLANG
-define SOURCE_SLANG
-#include <slang.h>
-
-int main(void)
-{
-       return SLsmg_init_smg();
-}
-endef
-endif
-
-ifndef NO_GTK2
-define SOURCE_GTK2
-#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
-#include <gtk/gtk.h>
-#pragma GCC diagnostic error \"-Wstrict-prototypes\"
-
-int main(int argc, char *argv[])
-{
-        gtk_init(&argc, &argv);
-
-        return 0;
-}
-endef
-
-define SOURCE_GTK2_INFOBAR
-#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
-#include <gtk/gtk.h>
-#pragma GCC diagnostic error \"-Wstrict-prototypes\"
-
-int main(void)
-{
-       gtk_info_bar_new();
-
-       return 0;
-}
-endef
-endif
-
-ifndef NO_LIBPERL
-define SOURCE_PERL_EMBED
-#include <EXTERN.h>
-#include <perl.h>
-
-int main(void)
-{
-perl_alloc();
-return 0;
-}
-endef
-endif
-
-ifndef NO_LIBPYTHON
-define SOURCE_PYTHON_VERSION
-#include <Python.h>
-#if PY_VERSION_HEX >= 0x03000000
-       #error
-#endif
-int main(void)
-{
-       return 0;
-}
-endef
-define SOURCE_PYTHON_EMBED
-#include <Python.h>
-int main(void)
-{
-       Py_Initialize();
-       return 0;
-}
-endef
-endif
-
-define SOURCE_BFD
-#include <bfd.h>
-
-int main(void)
-{
-       bfd_demangle(0, 0, 0);
-       return 0;
-}
-endef
-
-define SOURCE_CPLUS_DEMANGLE
-extern char *cplus_demangle(const char *, int);
-
-int main(void)
-{
-       cplus_demangle(0, 0);
-       return 0;
-}
-endef
-
-define SOURCE_STRLCPY
-#include <stdlib.h>
-extern size_t strlcpy(char *dest, const char *src, size_t size);
-
-int main(void)
-{
-       strlcpy(NULL, NULL, 0);
-       return 0;
-}
-endef
-
-ifndef NO_LIBUNWIND
-define SOURCE_LIBUNWIND
-#include <libunwind.h>
-#include <stdlib.h>
-
-extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
-                                      unw_word_t ip,
-                                      unw_dyn_info_t *di,
-                                      unw_proc_info_t *pi,
-                                      int need_unwind_info, void *arg);
-
-
-#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
-
-int main(void)
-{
-       unw_addr_space_t addr_space;
-       addr_space = unw_create_addr_space(NULL, 0);
-       unw_init_remote(NULL, addr_space, NULL);
-       dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
-       return 0;
-}
-endef
-endif
-
-ifndef NO_BACKTRACE
-define SOURCE_BACKTRACE
-#include <execinfo.h>
-#include <stdio.h>
-
-int main(void)
-{
-       backtrace(NULL, 0);
-       backtrace_symbols(NULL, 0);
-       return 0;
-}
-endef
-endif
-
-ifndef NO_LIBAUDIT
-define SOURCE_LIBAUDIT
-#include <libaudit.h>
-
-int main(void)
-{
-       printf(\"error message: %s\", audit_errno_to_name(0));
-       return audit_open();
-}
-endef
-endif
-
-define SOURCE_ON_EXIT
-#include <stdio.h>
-
-int main(void)
-{
-       return on_exit(NULL, NULL);
-}
-endef
-
-define SOURCE_LIBNUMA
-#include <numa.h>
-#include <numaif.h>
-
-int main(void)
-{
-       numa_available();
-       return 0;
-}
-endef
index 94d2d4f9c35d0e39ed0b570b033aca5294611736..f168debc5be268a75456a3639ccbf120ded594a2 100644 (file)
@@ -179,16 +179,9 @@ _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_e
 _gea_warn = $(warning The path '$(1)' is not executable.)
 _gea_err  = $(if $(1),$(error Please set '$(1)' appropriately))
 
-# try-cc
-# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
-ifneq ($(V),1)
-TRY_CC_OUTPUT= > /dev/null 2>&1
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+  ifneq ($(V),1)
+    QUIET_CLEAN                = @printf '  CLEAN    %s\n' $1;
+    QUIET_INSTALL      = @printf '  INSTALL  %s\n' $1;
+  endif
 endif
-TRY_CC_MSG=echo "    CHK $(3)" 1>&2;
-
-try-cc = $(shell sh -c                                           \
-       'TMP="$(OUTPUT)$(TMPOUT).$$$$";                           \
-        $(TRY_CC_MSG)                                            \
-        echo "$(1)" |                                            \
-        $(CC) -x c - $(2) -o "$$TMP" $(TRY_CC_OUTPUT) && echo y; \
-        rm -f "$$TMP"')
index 85e1aed95204c21de59b2b80721735670839b814..8b38b4e80ec2c6f6de581022143c989ed6a0e955 100644 (file)
@@ -49,14 +49,14 @@ static struct cmd_struct commands[] = {
        { "version",    cmd_version,    0 },
        { "script",     cmd_script,     0 },
        { "sched",      cmd_sched,      0 },
-#ifdef LIBELF_SUPPORT
+#ifdef HAVE_LIBELF_SUPPORT
        { "probe",      cmd_probe,      0 },
 #endif
        { "kmem",       cmd_kmem,       0 },
        { "lock",       cmd_lock,       0 },
        { "kvm",        cmd_kvm,        0 },
        { "test",       cmd_test,       0 },
-#ifdef LIBAUDIT_SUPPORT
+#ifdef HAVE_LIBAUDIT_SUPPORT
        { "trace",      cmd_trace,      0 },
 #endif
        { "inject",     cmd_inject,     0 },
@@ -456,6 +456,7 @@ int main(int argc, const char **argv)
 {
        const char *cmd;
 
+       /* The page_size is placed in util object. */
        page_size = sysconf(_SC_PAGE_SIZE);
 
        cmd = perf_extract_argv0_path(argv[0]);
@@ -480,7 +481,14 @@ int main(int argc, const char **argv)
                fprintf(stderr, "cannot handle %s internally", cmd);
                goto out;
        }
-
+#ifdef HAVE_LIBAUDIT_SUPPORT
+       if (!prefixcmp(cmd, "trace")) {
+               set_buildid_dir();
+               setup_path();
+               argv[0] = "trace";
+               return cmd_trace(argc, argv, NULL);
+       }
+#endif
        /* Look for flags.. */
        argv++;
        argc--;
index cf20187eee0a7345373dfc053c580bc1e77c4bb8..6a587e84fdfe2a238904434a8bdbc1edec7c12b8 100644 (file)
@@ -4,6 +4,8 @@
 #include <asm/unistd.h>
 
 #if defined(__i386__)
+#define mb()           asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
+#define wmb()          asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
 #define rmb()          asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
 #define cpu_relax()    asm volatile("rep; nop" ::: "memory");
 #define CPUINFO_PROC   "model name"
@@ -13,6 +15,8 @@
 #endif
 
 #if defined(__x86_64__)
+#define mb()           asm volatile("mfence" ::: "memory")
+#define wmb()          asm volatile("sfence" ::: "memory")
 #define rmb()          asm volatile("lfence" ::: "memory")
 #define cpu_relax()    asm volatile("rep; nop" ::: "memory");
 #define CPUINFO_PROC   "model name"
 
 #ifdef __powerpc__
 #include "../../arch/powerpc/include/uapi/asm/unistd.h"
+#define mb()           asm volatile ("sync" ::: "memory")
+#define wmb()          asm volatile ("sync" ::: "memory")
 #define rmb()          asm volatile ("sync" ::: "memory")
-#define cpu_relax()    asm volatile ("" ::: "memory");
 #define CPUINFO_PROC   "cpu"
 #endif
 
 #ifdef __s390__
+#define mb()           asm volatile("bcr 15,0" ::: "memory")
+#define wmb()          asm volatile("bcr 15,0" ::: "memory")
 #define rmb()          asm volatile("bcr 15,0" ::: "memory")
-#define cpu_relax()    asm volatile("" ::: "memory");
 #endif
 
 #ifdef __sh__
 #if defined(__SH4A__) || defined(__SH5__)
+# define mb()          asm volatile("synco" ::: "memory")
+# define wmb()         asm volatile("synco" ::: "memory")
 # define rmb()         asm volatile("synco" ::: "memory")
 #else
+# define mb()          asm volatile("" ::: "memory")
+# define wmb()         asm volatile("" ::: "memory")
 # define rmb()         asm volatile("" ::: "memory")
 #endif
-#define cpu_relax()    asm volatile("" ::: "memory")
 #define CPUINFO_PROC   "cpu type"
 #endif
 
 #ifdef __hppa__
+#define mb()           asm volatile("" ::: "memory")
+#define wmb()          asm volatile("" ::: "memory")
 #define rmb()          asm volatile("" ::: "memory")
-#define cpu_relax()    asm volatile("" ::: "memory");
 #define CPUINFO_PROC   "cpu"
 #endif
 
 #ifdef __sparc__
+#ifdef __LP64__
+#define mb()           asm volatile("ba,pt %%xcc, 1f\n"        \
+                                    "membar #StoreLoad\n"      \
+                                    "1:\n":::"memory")
+#else
+#define mb()           asm volatile("":::"memory")
+#endif
+#define wmb()          asm volatile("":::"memory")
 #define rmb()          asm volatile("":::"memory")
-#define cpu_relax()    asm volatile("":::"memory")
 #define CPUINFO_PROC   "cpu"
 #endif
 
 #ifdef __alpha__
+#define mb()           asm volatile("mb" ::: "memory")
+#define wmb()          asm volatile("wmb" ::: "memory")
 #define rmb()          asm volatile("mb" ::: "memory")
-#define cpu_relax()    asm volatile("" ::: "memory")
 #define CPUINFO_PROC   "cpu model"
 #endif
 
 #ifdef __ia64__
+#define mb()           asm volatile ("mf" ::: "memory")
+#define wmb()          asm volatile ("mf" ::: "memory")
 #define rmb()          asm volatile ("mf" ::: "memory")
 #define cpu_relax()    asm volatile ("hint @pause" ::: "memory")
 #define CPUINFO_PROC   "model name"
  * Use the __kuser_memory_barrier helper in the CPU helper page. See
  * arch/arm/kernel/entry-armv.S in the kernel source for details.
  */
+#define mb()           ((void(*)(void))0xffff0fa0)()
+#define wmb()          ((void(*)(void))0xffff0fa0)()
 #define rmb()          ((void(*)(void))0xffff0fa0)()
-#define cpu_relax()    asm volatile("":::"memory")
 #define CPUINFO_PROC   "Processor"
 #endif
 
 #ifdef __aarch64__
-#define rmb()          asm volatile("dmb ld" ::: "memory")
+#define mb()           asm volatile("dmb ish" ::: "memory")
+#define wmb()          asm volatile("dmb ishld" ::: "memory")
+#define rmb()          asm volatile("dmb ishst" ::: "memory")
 #define cpu_relax()    asm volatile("yield" ::: "memory")
 #endif
 
 #ifdef __mips__
-#define rmb()          asm volatile(                                   \
+#define mb()           asm volatile(                                   \
                                ".set   mips2\n\t"                      \
                                "sync\n\t"                              \
                                ".set   mips0"                          \
                                : /* no output */                       \
                                : /* no input */                        \
                                : "memory")
-#define cpu_relax()    asm volatile("" ::: "memory")
+#define wmb()  mb()
+#define rmb()  mb()
 #define CPUINFO_PROC   "cpu model"
 #endif
 
 #ifdef __arc__
+#define mb()           asm volatile("" ::: "memory")
+#define wmb()          asm volatile("" ::: "memory")
 #define rmb()          asm volatile("" ::: "memory")
-#define cpu_relax()    rmb()
 #define CPUINFO_PROC   "Processor"
 #endif
 
 #ifdef __metag__
+#define mb()           asm volatile("" ::: "memory")
+#define wmb()          asm volatile("" ::: "memory")
 #define rmb()          asm volatile("" ::: "memory")
-#define cpu_relax()    asm volatile("" ::: "memory")
 #define CPUINFO_PROC   "CPU"
 #endif
 
+#define barrier() asm volatile ("" ::: "memory")
+
+#ifndef cpu_relax
+#define cpu_relax() barrier()
+#endif
+
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+
 #include <time.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -182,7 +217,9 @@ struct ip_callchain {
 struct branch_flags {
        u64 mispred:1;
        u64 predicted:1;
-       u64 reserved:62;
+       u64 in_tx:1;
+       u64 abort:1;
+       u64 reserved:60;
 };
 
 struct branch_entry {
@@ -218,7 +255,6 @@ struct perf_record_opts {
        bool         no_delay;
        bool         no_inherit;
        bool         no_samples;
-       bool         pipe_output;
        bool         raw_samples;
        bool         sample_address;
        bool         sample_weight;
@@ -231,6 +267,7 @@ struct perf_record_opts {
        u64          default_interval;
        u64          user_interval;
        u16          stack_dump_size;
+       bool         sample_transaction;
 };
 
 #endif
index 315067b8f5522ae9cafbef1df506aca814e93012..fcd1dd66790623f4c6e08d62490f75e03b2e32dd 100644 (file)
@@ -25,7 +25,7 @@
 
 PyMODINIT_FUNC initperf_trace_context(void);
 
-static PyObject *perf_trace_context_common_pc(PyObject *self, PyObject *args)
+static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args)
 {
        static struct scripting_context *scripting_context;
        PyObject *context;
@@ -40,7 +40,7 @@ static PyObject *perf_trace_context_common_pc(PyObject *self, PyObject *args)
        return Py_BuildValue("i", retval);
 }
 
-static PyObject *perf_trace_context_common_flags(PyObject *self,
+static PyObject *perf_trace_context_common_flags(PyObject *obj,
                                                 PyObject *args)
 {
        static struct scripting_context *scripting_context;
@@ -56,7 +56,7 @@ static PyObject *perf_trace_context_common_flags(PyObject *self,
        return Py_BuildValue("i", retval);
 }
 
-static PyObject *perf_trace_context_common_lock_depth(PyObject *self,
+static PyObject *perf_trace_context_common_lock_depth(PyObject *obj,
                                                      PyObject *args)
 {
        static struct scripting_context *scripting_context;
index d102957cd59ae927b40f065579f96cf8c140a30e..430024f618f1b307381c43bc5e363f2dc6bb08cc 100644 (file)
@@ -44,9 +44,9 @@ Following tests are defined (with perf commands):
   perf record -c 123 kill                       (test-record-count)
   perf record -d kill                           (test-record-data)
   perf record -F 100 kill                       (test-record-freq)
-  perf record -g -- kill                        (test-record-graph-default)
-  perf record -g dwarf -- kill                  (test-record-graph-dwarf)
-  perf record -g fp kill                        (test-record-graph-fp)
+  perf record -g kill                           (test-record-graph-default)
+  perf record --call-graph dwarf kill          (test-record-graph-dwarf)
+  perf record --call-graph fp kill              (test-record-graph-fp)
   perf record --group -e cycles,instructions kill (test-record-group)
   perf record -e '{cycles,instructions}' kill   (test-record-group1)
   perf record -D kill                           (test-record-no-delay)
index 833d1849d76741bc82db78fef86fce6c8c6513ef..853597a9a8f6484a8446b9c8b94738ccaea37c2c 100644 (file)
@@ -1,6 +1,6 @@
 [config]
 command = record
-args    = -g -- kill >/dev/null 2>&1
+args    = -g kill >/dev/null 2>&1
 
 [event:base-record]
 sample_type=295
index e93e082f52080340eac2a5b6946106f2bbfbffe6..d6f324ea578cf903e0eb99c0c9cbb040855a2fdb 100644 (file)
@@ -1,6 +1,6 @@
 [config]
 command = record
-args    = -g dwarf -- kill >/dev/null 2>&1
+args    = --call-graph dwarf -- kill >/dev/null 2>&1
 
 [event:base-record]
 sample_type=12583
index 7cef3743f03f894561d4e039451af4ffa32dcfc3..055e3bee79935d50fde8773f84b0fcadd466b1d2 100644 (file)
@@ -1,6 +1,6 @@
 [config]
 command = record
-args    = -g fp kill >/dev/null 2>&1
+args    = --call-graph fp kill >/dev/null 2>&1
 
 [event:base-record]
 sample_type=295
index e3fedfa2906e5912d6dac6da9ef73daa53820b6d..49ccc3b2995ee30c8c2ad55a4c4b8308d9ad9055 100644 (file)
@@ -276,7 +276,7 @@ static int process_event(struct machine *machine, struct perf_evlist *evlist,
                return process_sample_event(machine, evlist, event, state);
 
        if (event->header.type < PERF_RECORD_MAX)
-               return machine__process_event(machine, event);
+               return machine__process_event(machine, event, NULL);
 
        return 0;
 }
index dffe0551acaa717add54e96bfb864c8fbf6cf2d6..9cc81a3eb9b456e6d2693bce799fedb0caba9862 100644 (file)
@@ -35,6 +35,7 @@ static char *test_file(int size)
        if (size != write(fd, buf, size))
                templ = NULL;
 
+       free(buf);
        close(fd);
        return templ;
 }
index 4228ffc0d9681d7acda97ecacccf8bea9b76f1e4..173bf42cc03e73e8291e4a6a7cf99f5d8d6d3107 100644 (file)
@@ -93,7 +93,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
                if (thread == NULL)
                        goto out;
 
-               thread__set_comm(thread, fake_threads[i].comm);
+               thread__set_comm(thread, fake_threads[i].comm, 0);
        }
 
        for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
@@ -110,7 +110,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
                strcpy(fake_mmap_event.mmap.filename,
                       fake_mmap_info[i].filename);
 
-               machine__process_mmap_event(machine, &fake_mmap_event);
+               machine__process_mmap_event(machine, &fake_mmap_event, NULL);
        }
 
        for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
@@ -222,7 +222,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
                                                          &sample) < 0)
                                goto out;
 
-                       he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1);
+                       he = __hists__add_entry(&evsel->hists, &al, NULL,
+                                               NULL, NULL, 1, 1, 0);
                        if (he == NULL)
                                goto out;
 
@@ -244,7 +245,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
                                                          &sample) < 0)
                                goto out;
 
-                       he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1);
+                       he = __hists__add_entry(&evsel->hists, &al, NULL,
+                                               NULL, NULL, 1, 1, 0);
                        if (he == NULL)
                                goto out;
 
@@ -419,7 +421,7 @@ static void print_hists(struct hists *hists)
                he = rb_entry(node, struct hist_entry, rb_node_in);
 
                pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
-                       i, he->thread->comm, he->ms.map->dso->short_name,
+                       i, thread__comm_str(he->thread), he->ms.map->dso->short_name,
                        he->ms.sym->name, he->stat.period);
 
                i++;
@@ -465,7 +467,7 @@ int test__hists_link(void)
                goto out;
 
        list_for_each_entry(evsel, &evlist->entries, node) {
-               hists__collapse_resort(&evsel->hists);
+               hists__collapse_resort(&evsel->hists, NULL);
 
                if (verbose > 2)
                        print_hists(&evsel->hists);
index 48114d164e9fb991898d18c28d027ba744181dad..ef671cd41bb3ef554478db74cecc61c6df28afca 100644 (file)
@@ -2,7 +2,7 @@
 #include "parse-events.h"
 #include "evsel.h"
 #include "evlist.h"
-#include "sysfs.h"
+#include "fs.h"
 #include <lk/debugfs.h>
 #include "tests.h"
 #include <linux/hw_breakpoint.h>
@@ -1456,7 +1456,7 @@ static int test_pmu(void)
        int ret;
 
        snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/",
-                sysfs_find_mountpoint());
+                sysfs__mountpoint());
 
        ret = stat(path, &st);
        if (ret)
@@ -1473,7 +1473,7 @@ static int test_pmu_events(void)
        int ret;
 
        snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/",
-                sysfs_find_mountpoint());
+                sysfs__mountpoint());
 
        ret = stat(path, &st);
        if (ret) {
index 7923b06ffc9198adde790901c8709dd8e66fa0b7..93a62b06c3afac27f7398f1572430cf29868b9d5 100644 (file)
@@ -45,7 +45,7 @@ int test__PERF_RECORD(void)
        };
        cpu_set_t cpu_mask;
        size_t cpu_mask_size = sizeof(cpu_mask);
-       struct perf_evlist *evlist = perf_evlist__new();
+       struct perf_evlist *evlist = perf_evlist__new_default();
        struct perf_evsel *evsel;
        struct perf_sample sample;
        const char *cmd = "sleep";
@@ -65,16 +65,6 @@ int test__PERF_RECORD(void)
                goto out;
        }
 
-       /*
-        * We need at least one evsel in the evlist, use the default
-        * one: "cycles".
-        */
-       err = perf_evlist__add_default(evlist);
-       if (err < 0) {
-               pr_debug("Not enough memory to create evsel\n");
-               goto out_delete_evlist;
-       }
-
        /*
         * Create maps of threads and cpus to monitor. In this case
         * we start with all threads and cpus (-1, -1) but then in
index ff94886aad995ec49e267c344885e34079dfdebd..46649c25fa5ed4982c364119792490c4ff861979 100644 (file)
@@ -9,8 +9,6 @@
 
 #if defined(__x86_64__) || defined(__i386__)
 
-#define barrier() asm volatile("" ::: "memory")
-
 static u64 rdpmc(unsigned int counter)
 {
        unsigned int low, high;
index 77f598dbd97a30b1f6429bdb131195b8766c963d..1b677202638d087b94903f3f395d9fab8ae15bc7 100644 (file)
@@ -121,6 +121,9 @@ static bool samples_same(const struct perf_sample *s1,
        if (type & PERF_SAMPLE_DATA_SRC)
                COMP(data_src);
 
+       if (type & PERF_SAMPLE_TRANSACTION)
+               COMP(transaction);
+
        return true;
 }
 
@@ -165,6 +168,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format)
                .cpu            = 110,
                .raw_size       = sizeof(raw_data),
                .data_src       = 111,
+               .transaction    = 112,
                .raw_data       = (void *)raw_data,
                .callchain      = &callchain.callchain,
                .branch_stack   = &branch_stack.branch_stack,
@@ -273,10 +277,11 @@ int test__sample_parsing(void)
 
        /*
         * Fail the test if it has not been updated when new sample format bits
-        * were added.
+        * were added.  Please actually update the test rather than just change
+        * the condition below.
         */
-       if (PERF_SAMPLE_MAX > PERF_SAMPLE_IDENTIFIER << 1) {
-               pr_debug("sample format has changed - test needs updating\n");
+       if (PERF_SAMPLE_MAX > PERF_SAMPLE_TRANSACTION << 1) {
+               pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
                return -1;
        }
 
index a3e64876e940020d93aa674ea064d735bf688713..c33d95f9559a0d08294b622600450646b9d0129c 100644 (file)
@@ -37,20 +37,11 @@ int test__task_exit(void)
        signal(SIGCHLD, sig_handler);
        signal(SIGUSR1, sig_handler);
 
-       evlist = perf_evlist__new();
+       evlist = perf_evlist__new_default();
        if (evlist == NULL) {
-               pr_debug("perf_evlist__new\n");
+               pr_debug("perf_evlist__new_default\n");
                return -1;
        }
-       /*
-        * We need at least one evsel in the evlist, use the default
-        * one: "cycles".
-        */
-       err = perf_evlist__add_default(evlist);
-       if (err < 0) {
-               pr_debug("Not enough memory to create evsel\n");
-               goto out_free_evlist;
-       }
 
        /*
         * Create maps of threads and cpus to monitor. In this case
@@ -117,7 +108,6 @@ out_close_evlist:
        perf_evlist__close(evlist);
 out_delete_maps:
        perf_evlist__delete_maps(evlist);
-out_free_evlist:
        perf_evlist__delete(evlist);
        return err;
 }
index 404ff66a3e367a84e67c4b0896a28318b829e867..7d45d2f536013e49e230aee7856d9aeaf3964f6b 100644 (file)
@@ -21,32 +21,32 @@ struct ui_browser {
        void          *priv;
        const char    *title;
        char          *helpline;
-       unsigned int  (*refresh)(struct ui_browser *self);
-       void          (*write)(struct ui_browser *self, void *entry, int row);
-       void          (*seek)(struct ui_browser *self, off_t offset, int whence);
-       bool          (*filter)(struct ui_browser *self, void *entry);
+       unsigned int  (*refresh)(struct ui_browser *browser);
+       void          (*write)(struct ui_browser *browser, void *entry, int row);
+       void          (*seek)(struct ui_browser *browser, off_t offset, int whence);
+       bool          (*filter)(struct ui_browser *browser, void *entry);
        u32           nr_entries;
        bool          navkeypressed;
        bool          use_navkeypressed;
 };
 
 int  ui_browser__set_color(struct ui_browser *browser, int color);
-void ui_browser__set_percent_color(struct ui_browser *self,
+void ui_browser__set_percent_color(struct ui_browser *browser,
                                   double percent, bool current);
-bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row);
-void ui_browser__refresh_dimensions(struct ui_browser *self);
-void ui_browser__reset_index(struct ui_browser *self);
+bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row);
+void ui_browser__refresh_dimensions(struct ui_browser *browser);
+void ui_browser__reset_index(struct ui_browser *browser);
 
-void ui_browser__gotorc(struct ui_browser *self, int y, int x);
+void ui_browser__gotorc(struct ui_browser *browser, int y, int x);
 void ui_browser__write_graph(struct ui_browser *browser, int graph);
 void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
                              u64 start, u64 end);
 void __ui_browser__show_title(struct ui_browser *browser, const char *title);
 void ui_browser__show_title(struct ui_browser *browser, const char *title);
-int ui_browser__show(struct ui_browser *self, const char *title,
+int ui_browser__show(struct ui_browser *browser, const char *title,
                     const char *helpline, ...);
-void ui_browser__hide(struct ui_browser *self);
-int ui_browser__refresh(struct ui_browser *self);
+void ui_browser__hide(struct ui_browser *browser);
+int ui_browser__refresh(struct ui_browser *browser);
 int ui_browser__run(struct ui_browser *browser, int delay_secs);
 void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries);
 void ui_browser__handle_resize(struct ui_browser *browser);
@@ -63,11 +63,11 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
 void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence);
 unsigned int ui_browser__argv_refresh(struct ui_browser *browser);
 
-void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence);
-unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self);
+void ui_browser__rb_tree_seek(struct ui_browser *browser, off_t offset, int whence);
+unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser);
 
-void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence);
-unsigned int ui_browser__list_head_refresh(struct ui_browser *self);
+void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int whence);
+unsigned int ui_browser__list_head_refresh(struct ui_browser *browser);
 
 void ui_browser__init(void);
 void annotate_browser__init(void);
index 08545ae46992cd5b284e279bf5ac131cf9c84e62..f0697a3aede04cb19f91d459cab62a6c08c5326f 100644 (file)
@@ -442,35 +442,37 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
 {
        struct map_symbol *ms = browser->b.priv;
        struct disasm_line *dl = browser->selection;
-       struct symbol *sym = ms->sym;
        struct annotation *notes;
-       struct symbol *target;
-       u64 ip;
+       struct addr_map_symbol target = {
+               .map = ms->map,
+               .addr = map__objdump_2mem(ms->map, dl->ops.target.addr),
+       };
        char title[SYM_TITLE_MAX_SIZE];
 
        if (!ins__is_call(dl->ins))
                return false;
 
-       ip = ms->map->map_ip(ms->map, dl->ops.target.addr);
-       target = map__find_symbol(ms->map, ip, NULL);
-       if (target == NULL) {
+       if (map_groups__find_ams(&target, NULL) ||
+           map__rip_2objdump(target.map, target.map->map_ip(target.map,
+                                                            target.addr)) !=
+           dl->ops.target.addr) {
                ui_helpline__puts("The called function was not found.");
                return true;
        }
 
-       notes = symbol__annotation(target);
+       notes = symbol__annotation(target.sym);
        pthread_mutex_lock(&notes->lock);
 
-       if (notes->src == NULL && symbol__alloc_hist(target) < 0) {
+       if (notes->src == NULL && symbol__alloc_hist(target.sym) < 0) {
                pthread_mutex_unlock(&notes->lock);
                ui__warning("Not enough memory for annotating '%s' symbol!\n",
-                           target->name);
+                           target.sym->name);
                return true;
        }
 
        pthread_mutex_unlock(&notes->lock);
-       symbol__tui_annotate(target, ms->map, evsel, hbt);
-       sym_title(sym, ms->map, title, sizeof(title));
+       symbol__tui_annotate(target.sym, target.map, evsel, hbt);
+       sym_title(ms->sym, ms->map, title, sizeof(title));
        ui_browser__show_title(&browser->b, title);
        return true;
 }
index 7ef36c360471e3f2ccef82d4bd2a4e4fb684eb14..16848bb4c41842355be8c7a36d2df574a9c90214 100644 (file)
@@ -1255,7 +1255,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size,
        if (thread)
                printed += scnprintf(bf + printed, size - printed,
                                    ", Thread: %s(%d)",
-                                   (thread->comm_set ? thread->comm : ""),
+                                    (thread->comm_set ? thread__comm_str(thread) : ""),
                                    thread->tid);
        if (dso)
                printed += scnprintf(bf + printed, size - printed,
@@ -1578,7 +1578,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                if (thread != NULL &&
                    asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
                             (browser->hists->thread_filter ? "out of" : "into"),
-                            (thread->comm_set ? thread->comm : ""),
+                            (thread->comm_set ? thread__comm_str(thread) : ""),
                             thread->tid) > 0)
                        zoom_thread = nr_options++;
 
@@ -1598,7 +1598,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                        struct symbol *sym;
 
                        if (asprintf(&options[nr_options], "Run scripts for samples of thread [%s]",
-                               browser->he_selection->thread->comm) > 0)
+                                    thread__comm_str(browser->he_selection->thread)) > 0)
                                scripts_comm = nr_options++;
 
                        sym = browser->he_selection->ms.sym;
@@ -1701,7 +1701,7 @@ zoom_out_thread:
                                sort_thread.elide = false;
                        } else {
                                ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
-                                                  thread->comm_set ? thread->comm : "",
+                                                  thread->comm_set ? thread__comm_str(thread) : "",
                                                   thread->tid);
                                browser->hists->thread_filter = thread;
                                sort_thread.elide = true;
@@ -1717,7 +1717,7 @@ do_scripts:
                        memset(script_opt, 0, 64);
 
                        if (choice == scripts_comm)
-                               sprintf(script_opt, " -c %s ", browser->he_selection->thread->comm);
+                               sprintf(script_opt, " -c %s ", thread__comm_str(browser->he_selection->thread));
 
                        if (choice == scripts_symbol)
                                sprintf(script_opt, " -S %s ", browser->he_selection->ms.sym->name);
@@ -1889,7 +1889,7 @@ out:
        return key;
 }
 
-static bool filter_group_entries(struct ui_browser *self __maybe_unused,
+static bool filter_group_entries(struct ui_browser *browser __maybe_unused,
                                 void *entry)
 {
        struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
index 95c7cfb8f2c60577d75df489ea2ef1382375720d..b11639f3368272ae754853ae05a62accb1ee3d05 100644 (file)
@@ -18,30 +18,30 @@ struct map_browser {
        u8                addrlen;
 };
 
-static void map_browser__write(struct ui_browser *self, void *nd, int row)
+static void map_browser__write(struct ui_browser *browser, void *nd, int row)
 {
        struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
-       struct map_browser *mb = container_of(self, struct map_browser, b);
-       bool current_entry = ui_browser__is_current_entry(self, row);
+       struct map_browser *mb = container_of(browser, struct map_browser, b);
+       bool current_entry = ui_browser__is_current_entry(browser, row);
        int width;
 
-       ui_browser__set_percent_color(self, 0, current_entry);
+       ui_browser__set_percent_color(browser, 0, current_entry);
        slsmg_printf("%*" PRIx64 " %*" PRIx64 " %c ",
                     mb->addrlen, sym->start, mb->addrlen, sym->end,
                     sym->binding == STB_GLOBAL ? 'g' :
                     sym->binding == STB_LOCAL  ? 'l' : 'w');
-       width = self->width - ((mb->addrlen * 2) + 4);
+       width = browser->width - ((mb->addrlen * 2) + 4);
        if (width > 0)
                slsmg_write_nstring(sym->name, width);
 }
 
 /* FIXME uber-kludgy, see comment on cmd_report... */
-static u32 *symbol__browser_index(struct symbol *self)
+static u32 *symbol__browser_index(struct symbol *browser)
 {
-       return ((void *)self) - sizeof(struct rb_node) - sizeof(u32);
+       return ((void *)browser) - sizeof(struct rb_node) - sizeof(u32);
 }
 
-static int map_browser__search(struct map_browser *self)
+static int map_browser__search(struct map_browser *browser)
 {
        char target[512];
        struct symbol *sym;
@@ -53,37 +53,37 @@ static int map_browser__search(struct map_browser *self)
 
        if (target[0] == '0' && tolower(target[1]) == 'x') {
                u64 addr = strtoull(target, NULL, 16);
-               sym = map__find_symbol(self->map, addr, NULL);
+               sym = map__find_symbol(browser->map, addr, NULL);
        } else
-               sym = map__find_symbol_by_name(self->map, target, NULL);
+               sym = map__find_symbol_by_name(browser->map, target, NULL);
 
        if (sym != NULL) {
                u32 *idx = symbol__browser_index(sym);
 
-               self->b.top = &sym->rb_node;
-               self->b.index = self->b.top_idx = *idx;
+               browser->b.top = &sym->rb_node;
+               browser->b.index = browser->b.top_idx = *idx;
        } else
                ui_helpline__fpush("%s not found!", target);
 
        return 0;
 }
 
-static int map_browser__run(struct map_browser *self)
+static int map_browser__run(struct map_browser *browser)
 {
        int key;
 
-       if (ui_browser__show(&self->b, self->map->dso->long_name,
+       if (ui_browser__show(&browser->b, browser->map->dso->long_name,
                             "Press <- or ESC to exit, %s / to search",
                             verbose ? "" : "restart with -v to use") < 0)
                return -1;
 
        while (1) {
-               key = ui_browser__run(&self->b, 0);
+               key = ui_browser__run(&browser->b, 0);
 
                switch (key) {
                case '/':
                        if (verbose)
-                               map_browser__search(self);
+                               map_browser__search(browser);
                default:
                        break;
                 case K_LEFT:
@@ -94,20 +94,20 @@ static int map_browser__run(struct map_browser *self)
                }
        }
 out:
-       ui_browser__hide(&self->b);
+       ui_browser__hide(&browser->b);
        return key;
 }
 
-int map__browse(struct map *self)
+int map__browse(struct map *map)
 {
        struct map_browser mb = {
                .b = {
-                       .entries = &self->dso->symbols[self->type],
+                       .entries = &map->dso->symbols[map->type],
                        .refresh = ui_browser__rb_tree_refresh,
                        .seek    = ui_browser__rb_tree_seek,
                        .write   = map_browser__write,
                },
-               .map = self,
+               .map = map,
        };
        struct rb_node *nd;
        char tmp[BITS_PER_LONG / 4];
index df8581a43e17bd2c956304074900d5f9968d2e6a..2d58e4b3eb6ffb295308098350a0997c8c5bea57 100644 (file)
@@ -2,5 +2,5 @@
 #define _PERF_UI_MAP_BROWSER_H_ 1
 struct map;
 
-int map__browse(struct map *self);
+int map__browse(struct map *map);
 #endif /* _PERF_UI_MAP_BROWSER_H_ */
index 12f009e61e94a7c60a6b2dbb1a9a959b690b9ad1..d63c68ea02a87e1adfbfaa2ea41ec52b373a0a0c 100644 (file)
@@ -84,22 +84,22 @@ static void script_browser__write(struct ui_browser *browser,
        slsmg_write_nstring(sline->line, browser->width);
 }
 
-static int script_browser__run(struct perf_script_browser *self)
+static int script_browser__run(struct perf_script_browser *browser)
 {
        int key;
 
-       if (ui_browser__show(&self->b, self->script_name,
+       if (ui_browser__show(&browser->b, browser->script_name,
                             "Press <- or ESC to exit") < 0)
                return -1;
 
        while (1) {
-               key = ui_browser__run(&self->b, 0);
+               key = ui_browser__run(&browser->b, 0);
 
                /* We can add some special key handling here if needed */
                break;
        }
 
-       ui_browser__hide(&self->b);
+       ui_browser__hide(&browser->b);
        return key;
 }
 
index f538794615dbb7c399371d93bd1b96cef77ea234..9c7ff8d31b274e32d22147664cb622437db514f1 100644 (file)
@@ -154,9 +154,9 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
        return 0;
 }
 
-int symbol__gtk_annotate(struct symbol *sym, struct map *map,
-                        struct perf_evsel *evsel,
-                        struct hist_browser_timer *hbt)
+static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
+                               struct perf_evsel *evsel,
+                               struct hist_browser_timer *hbt)
 {
        GtkWidget *window;
        GtkWidget *notebook;
@@ -226,6 +226,13 @@ int symbol__gtk_annotate(struct symbol *sym, struct map *map,
        return 0;
 }
 
+int hist_entry__gtk_annotate(struct hist_entry *he,
+                            struct perf_evsel *evsel,
+                            struct hist_browser_timer *hbt)
+{
+       return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
+}
+
 void perf_gtk__show_annotations(void)
 {
        GtkWidget *window;
index c95012cdb4387f95a4125f7da3f58cf224f33dc8..c24d91221290e0049b409de582dfcf6ce7994ef5 100644 (file)
@@ -43,7 +43,7 @@ const char *perf_gtk__get_percent_color(double percent)
        return NULL;
 }
 
-#ifdef HAVE_GTK_INFO_BAR
+#ifdef HAVE_GTK_INFO_BAR_SUPPORT
 GtkWidget *perf_gtk__setup_info_bar(void)
 {
        GtkWidget *info_bar;
index 3d96785ef155044d006f4438bf35b17ee3717148..0a9173ff9a61d16e804f27f7e4734b16166f696c 100644 (file)
@@ -12,7 +12,7 @@ struct perf_gtk_context {
        GtkWidget *main_window;
        GtkWidget *notebook;
 
-#ifdef HAVE_GTK_INFO_BAR
+#ifdef HAVE_GTK_INFO_BAR_SUPPORT
        GtkWidget *info_bar;
        GtkWidget *message_label;
 #endif
@@ -20,6 +20,9 @@ struct perf_gtk_context {
        guint statbar_ctx_id;
 };
 
+int perf_gtk__init(void);
+void perf_gtk__exit(bool wait_for_ok);
+
 extern struct perf_gtk_context *pgctx;
 
 static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx)
@@ -31,7 +34,7 @@ struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window);
 int perf_gtk__deactivate_context(struct perf_gtk_context **ctx);
 
 void perf_gtk__init_helpline(void);
-void perf_gtk__init_progress(void);
+void gtk_ui_progress__init(void);
 void perf_gtk__init_hpp(void);
 
 void perf_gtk__signal(int sig);
@@ -39,7 +42,7 @@ void perf_gtk__resize_window(GtkWidget *window);
 const char *perf_gtk__get_percent_color(double percent);
 GtkWidget *perf_gtk__setup_statusbar(void);
 
-#ifdef HAVE_GTK_INFO_BAR
+#ifdef HAVE_GTK_INFO_BAR_SUPPORT
 GtkWidget *perf_gtk__setup_info_bar(void);
 #else
 static inline GtkWidget *perf_gtk__setup_info_bar(void)
@@ -48,4 +51,17 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void)
 }
 #endif
 
+struct perf_evsel;
+struct perf_evlist;
+struct hist_entry;
+struct hist_browser_timer;
+
+int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
+                                 struct hist_browser_timer *hbt,
+                                 float min_pcnt);
+int hist_entry__gtk_annotate(struct hist_entry *he,
+                            struct perf_evsel *evsel,
+                            struct hist_browser_timer *hbt);
+void perf_gtk__show_annotations(void);
+
 #endif /* _PERF_GTK_H_ */
index 482bcf3df9b7a293b16b4e2b4f0091d9ee87bb95..b656655fbc39e6c5f0cc23659957d8a963c9a107 100644 (file)
@@ -7,14 +7,14 @@
 static GtkWidget *dialog;
 static GtkWidget *progress;
 
-static void gtk_progress_update(u64 curr, u64 total, const char *title)
+static void gtk_ui_progress__update(struct ui_progress *p)
 {
-       double fraction = total ? 1.0 * curr / total : 0.0;
+       double fraction = p->total ? 1.0 * p->curr / p->total : 0.0;
        char buf[1024];
 
        if (dialog == NULL) {
                GtkWidget *vbox = gtk_vbox_new(TRUE, 5);
-               GtkWidget *label = gtk_label_new(title);
+               GtkWidget *label = gtk_label_new(p->title);
 
                dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
                progress = gtk_progress_bar_new();
@@ -32,7 +32,7 @@ static void gtk_progress_update(u64 curr, u64 total, const char *title)
        }
 
        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
-       snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, curr, total);
+       snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, p->curr, p->total);
        gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), buf);
 
        /* we didn't call gtk_main yet, so do it manually */
@@ -40,7 +40,7 @@ static void gtk_progress_update(u64 curr, u64 total, const char *title)
                gtk_main_iteration();
 }
 
-static void gtk_progress_finish(void)
+static void gtk_ui_progress__finish(void)
 {
        /* this will also destroy all of its children */
        gtk_widget_destroy(dialog);
@@ -48,12 +48,12 @@ static void gtk_progress_finish(void)
        dialog = NULL;
 }
 
-static struct ui_progress gtk_progress_fns = {
-       .update         = gtk_progress_update,
-       .finish         = gtk_progress_finish,
+static struct ui_progress_ops gtk_ui_progress__ops = {
+       .update         = gtk_ui_progress__update,
+       .finish         = gtk_ui_progress__finish,
 };
 
-void perf_gtk__init_progress(void)
+void gtk_ui_progress__init(void)
 {
-       progress_fns = &gtk_progress_fns;
+       ui_progress__ops = &gtk_ui_progress__ops;
 }
index 6c2dd2e423f3a6a160bcbd879b71c6134ef9d460..1d57676f82124d82e18d032e349e879e09a060e8 100644 (file)
@@ -8,7 +8,7 @@ int perf_gtk__init(void)
 {
        perf_error__register(&perf_gtk_eops);
        perf_gtk__init_helpline();
-       perf_gtk__init_progress();
+       gtk_ui_progress__init();
        perf_gtk__init_hpp();
 
        return gtk_init_check(NULL, NULL) ? 0 : -1;
index c06942a41c782e0ac029dba3719c638a4563b772..696c1fbe42482db03b4fb460b488860435a4edf5 100644 (file)
@@ -53,7 +53,7 @@ static int perf_gtk__error(const char *format, va_list args)
        return 0;
 }
 
-#ifdef HAVE_GTK_INFO_BAR
+#ifdef HAVE_GTK_INFO_BAR_SUPPORT
 static int perf_gtk__warning_info_bar(const char *format, va_list args)
 {
        char *msg;
@@ -105,7 +105,7 @@ static int perf_gtk__warning_statusbar(const char *format, va_list args)
 
 struct perf_error_ops perf_gtk_eops = {
        .error          = perf_gtk__error,
-#ifdef HAVE_GTK_INFO_BAR
+#ifdef HAVE_GTK_INFO_BAR_SUPPORT
        .warning        = perf_gtk__warning_info_bar,
 #else
        .warning        = perf_gtk__warning_statusbar,
index 0a193281eba85ec12bbed36d85803b51d7d24464..78f4c92e9b73c1c55e5699bce4b628f551348beb 100644 (file)
@@ -117,7 +117,7 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,              \
                              struct perf_hpp *hpp, struct hist_entry *he)      \
 {                                                                              \
        return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%",                 \
-                         (hpp_snprint_fn)percent_color_snprintf, true);        \
+                         percent_color_snprintf, true);                        \
 }
 
 #define __HPP_ENTRY_PERCENT_FN(_type, _field)                                  \
index 3ec695607a4d074f844f4922805d52556b2ec645..a0f24c7115c59f891fa894739ef4da157a9e33cf 100644 (file)
@@ -1,26 +1,38 @@
 #include "../cache.h"
 #include "progress.h"
 
-static void nop_progress_update(u64 curr __maybe_unused,
-                               u64 total __maybe_unused,
-                               const char *title __maybe_unused)
+static void null_progress__update(struct ui_progress *p __maybe_unused)
 {
 }
 
-static struct ui_progress default_progress_fns =
+static struct ui_progress_ops null_progress__ops =
 {
-       .update         = nop_progress_update,
+       .update = null_progress__update,
 };
 
-struct ui_progress *progress_fns = &default_progress_fns;
+struct ui_progress_ops *ui_progress__ops = &null_progress__ops;
 
-void ui_progress__update(u64 curr, u64 total, const char *title)
+void ui_progress__update(struct ui_progress *p, u64 adv)
 {
-       return progress_fns->update(curr, total, title);
+       p->curr += adv;
+
+       if (p->curr >= p->next) {
+               p->next += p->step;
+               ui_progress__ops->update(p);
+       }
+}
+
+void ui_progress__init(struct ui_progress *p, u64 total, const char *title)
+{
+       p->curr = 0;
+       p->next = p->step = total / 16;
+       p->total = total;
+       p->title = title;
+
 }
 
 void ui_progress__finish(void)
 {
-       if (progress_fns->finish)
-               progress_fns->finish();
+       if (ui_progress__ops->finish)
+               ui_progress__ops->finish();
 }
index 257cc224f9cff6d29acc81c0db9d315ed4b2b39a..29ec8efffefb7ec9e0ac1936304257cc8c5ff9ef 100644 (file)
@@ -3,16 +3,21 @@
 
 #include <../types.h>
 
+void ui_progress__finish(void);
 struct ui_progress {
-       void (*update)(u64, u64, const char *);
-       void (*finish)(void);
+       const char *title;
+       u64 curr, next, step, total;
 };
+void ui_progress__init(struct ui_progress *p, u64 total, const char *title);
+void ui_progress__update(struct ui_progress *p, u64 adv);
 
-extern struct ui_progress *progress_fns;
-
-void ui_progress__init(void);
+struct ui_progress_ops {
+       void (*update)(struct ui_progress *p);
+       void (*finish)(void);
+};
 
-void ui_progress__update(u64 curr, u64 total, const char *title);
-void ui_progress__finish(void);
+extern struct ui_progress_ops *ui_progress__ops;
 
 #endif
index 47d9a571f261da9c65e36aa82f8dbdb70a838acc..5df5140a9f29e466dd055b8873711e722875f646 100644 (file)
@@ -1,10 +1,64 @@
 #include <pthread.h>
+#include <dlfcn.h>
 
 #include "../util/cache.h"
 #include "../util/debug.h"
 #include "../util/hist.h"
 
 pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
+void *perf_gtk_handle;
+
+#ifdef HAVE_GTK2_SUPPORT
+static int setup_gtk_browser(void)
+{
+       int (*perf_ui_init)(void);
+
+       if (perf_gtk_handle)
+               return 0;
+
+       perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY);
+       if (perf_gtk_handle == NULL) {
+               char buf[PATH_MAX];
+               scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO);
+               perf_gtk_handle = dlopen(buf, RTLD_LAZY);
+       }
+       if (perf_gtk_handle == NULL)
+               return -1;
+
+       perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
+       if (perf_ui_init == NULL)
+               goto out_close;
+
+       if (perf_ui_init() == 0)
+               return 0;
+
+out_close:
+       dlclose(perf_gtk_handle);
+       return -1;
+}
+
+static void exit_gtk_browser(bool wait_for_ok)
+{
+       void (*perf_ui_exit)(bool);
+
+       if (perf_gtk_handle == NULL)
+               return;
+
+       perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
+       if (perf_ui_exit == NULL)
+               goto out_close;
+
+       perf_ui_exit(wait_for_ok);
+
+out_close:
+       dlclose(perf_gtk_handle);
+
+       perf_gtk_handle = NULL;
+}
+#else
+static inline int setup_gtk_browser(void) { return -1; }
+static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
+#endif
 
 void setup_browser(bool fallback_to_pager)
 {
@@ -17,8 +71,11 @@ void setup_browser(bool fallback_to_pager)
 
        switch (use_browser) {
        case 2:
-               if (perf_gtk__init() == 0)
+               if (setup_gtk_browser() == 0)
                        break;
+               printf("GTK browser requested but could not find %s\n",
+                      PERF_GTK_DSO);
+               sleep(1);
                /* fall through */
        case 1:
                use_browser = 1;
@@ -39,7 +96,7 @@ void exit_browser(bool wait_for_ok)
 {
        switch (use_browser) {
        case 2:
-               perf_gtk__exit(wait_for_ok);
+               exit_gtk_browser(wait_for_ok);
                break;
 
        case 1:
index 6c152686e83763a9b18983d06f52e2a14b739b91..c244cb524ef2cc9d4e3eafabe065c8eef60b60a6 100644 (file)
@@ -213,20 +213,19 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
        return ret;
 }
 
-static size_t __callchain__fprintf_flat(FILE *fp,
-                                       struct callchain_node *self,
+static size_t __callchain__fprintf_flat(FILE *fp, struct callchain_node *node,
                                        u64 total_samples)
 {
        struct callchain_list *chain;
        size_t ret = 0;
 
-       if (!self)
+       if (!node)
                return 0;
 
-       ret += __callchain__fprintf_flat(fp, self->parent, total_samples);
+       ret += __callchain__fprintf_flat(fp, node->parent, total_samples);
 
 
-       list_for_each_entry(chain, &self->val, list) {
+       list_for_each_entry(chain, &node->val, list) {
                if (chain->ip >= PERF_CONTEXT_MAX)
                        continue;
                if (chain->ms.sym)
@@ -239,15 +238,14 @@ static size_t __callchain__fprintf_flat(FILE *fp,
        return ret;
 }
 
-static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *self,
+static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *tree,
                                      u64 total_samples)
 {
        size_t ret = 0;
        u32 entries_printed = 0;
-       struct rb_node *rb_node;
        struct callchain_node *chain;
+       struct rb_node *rb_node = rb_first(tree);
 
-       rb_node = rb_first(self);
        while (rb_node) {
                double percent;
 
index 6c2184d53cbf9a16d378d084984613d19ec99752..3e2d936d7443e9b31f349594a4a9935a98d69299 100644 (file)
@@ -2,9 +2,10 @@
 #include "../progress.h"
 #include "../libslang.h"
 #include "../ui.h"
+#include "tui.h"
 #include "../browser.h"
 
-static void tui_progress__update(u64 curr, u64 total, const char *title)
+static void tui_progress__update(struct ui_progress *p)
 {
        int bar, y;
        /*
@@ -14,7 +15,7 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
        if (use_browser <= 0)
                return;
 
-       if (total == 0)
+       if (p->total == 0)
                return;
 
        ui__refresh_dimensions(true);
@@ -23,20 +24,20 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
        SLsmg_set_color(0);
        SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
        SLsmg_gotorc(y++, 1);
-       SLsmg_write_string((char *)title);
+       SLsmg_write_string((char *)p->title);
        SLsmg_set_color(HE_COLORSET_SELECTED);
-       bar = ((SLtt_Screen_Cols - 2) * curr) / total;
+       bar = ((SLtt_Screen_Cols - 2) * p->curr) / p->total;
        SLsmg_fill_region(y, 1, 1, bar, ' ');
        SLsmg_refresh();
        pthread_mutex_unlock(&ui__lock);
 }
 
-static struct ui_progress tui_progress_fns =
+static struct ui_progress_ops tui_progress__ops =
 {
        .update         = tui_progress__update,
 };
 
-void ui_progress__init(void)
+void tui_progress__init(void)
 {
-       progress_fns = &tui_progress_fns;
+       ui_progress__ops = &tui_progress__ops;
 }
index b9401482d110bad0f5d39946c04b881cd9b779d9..2f612562978cdc13c7e89b6dbddd24c9f928d626 100644 (file)
@@ -9,6 +9,7 @@
 #include "../util.h"
 #include "../libslang.h"
 #include "../keysyms.h"
+#include "tui.h"
 
 static volatile int ui__need_resize;
 
@@ -119,7 +120,7 @@ int ui__init(void)
 
        ui_helpline__init();
        ui_browser__init();
-       ui_progress__init();
+       tui_progress__init();
 
        signal(SIGSEGV, ui__signal);
        signal(SIGFPE, ui__signal);
diff --git a/tools/perf/ui/tui/tui.h b/tools/perf/ui/tui/tui.h
new file mode 100644 (file)
index 0000000..18961c7
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _PERF_TUI_H_
+#define _PERF_TUI_H_ 1
+
+void tui_progress__init(void);
+
+#endif /* _PERF_TUI_H_ */
index 70cb0d4eb8aa390c008a4d84c575662c2515280d..ab88383f8be85d5278dfaba5b6b6b07b11a6b2d2 100644 (file)
@@ -6,13 +6,14 @@
 #include <linux/compiler.h>
 
 extern pthread_mutex_t ui__lock;
+extern void *perf_gtk_handle;
 
 extern int use_browser;
 
 void setup_browser(bool fallback_to_pager);
 void exit_browser(bool wait_for_ok);
 
-#ifdef SLANG_SUPPORT
+#ifdef HAVE_SLANG_SUPPORT
 int ui__init(void);
 void ui__exit(bool wait_for_ok);
 #else
@@ -23,17 +24,6 @@ static inline int ui__init(void)
 static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
 #endif
 
-#ifdef GTK2_SUPPORT
-int perf_gtk__init(void);
-void perf_gtk__exit(bool wait_for_ok);
-#else
-static inline int perf_gtk__init(void)
-{
-       return -1;
-}
-static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {}
-#endif
-
 void ui__refresh_dimensions(bool force);
 
 #endif /* _PERF_UI_H_ */
index 15a77b7c0e36f155c968cbf59780aec089c53f3a..39f17507578dae0c650dc91335e888d9a907ef4a 100755 (executable)
@@ -19,6 +19,9 @@ if test -d ../../.git -o -f ../../.git
 then
        TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null )
        CID=$(git log -1 --abbrev=4 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID"
+elif test -f ../../PERF-VERSION-FILE
+then
+       TAG=$(cut -d' ' -f3 ../../PERF-VERSION-FILE | sed -e 's/\"//g')
 fi
 if test -z "$TAG"
 then
@@ -40,7 +43,7 @@ else
        VC=unset
 fi
 test "$VN" = "$VC" || {
-       echo >&2 "PERF_VERSION = $VN"
+       echo >&2 "  PERF_VERSION = $VN"
        echo "#define PERF_VERSION \"$VN\"" >$GVF
 }
 
index 7eae5488ecea47344cac10677104cb9e6cb2cc44..cf6242c92ee244ab45498993cab477af7950853f 100644 (file)
@@ -825,20 +825,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
                dl->ops.target.offset = dl->ops.target.addr -
                                        map__rip_2objdump(map, sym->start);
 
-       /*
-        * kcore has no symbols, so add the call target name if it is on the
-        * same map.
-        */
+       /* kcore has no symbols, so add the call target name */
        if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) {
-               struct symbol *s;
-               u64 ip = dl->ops.target.addr;
-
-               if (ip >= map->start && ip <= map->end) {
-                       ip = map->map_ip(map, ip);
-                       s = map__find_symbol(map, ip, NULL);
-                       if (s && s->start == ip)
-                               dl->ops.target.name = strdup(s->name);
-               }
+               struct addr_map_symbol target = {
+                       .map = map,
+                       .addr = dl->ops.target.addr,
+               };
+
+               if (!map_groups__find_ams(&target, NULL) &&
+                   target.sym->start == target.al_addr)
+                       dl->ops.target.name = strdup(target.sym->name);
        }
 
        disasm__add(&notes->src->source, dl);
@@ -879,6 +875,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
        FILE *file;
        int err = 0;
        char symfs_filename[PATH_MAX];
+       struct kcore_extract kce;
+       bool delete_extract = false;
 
        if (filename) {
                snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
@@ -940,6 +938,23 @@ fallback:
        pr_debug("annotating [%p] %30s : [%p] %30s\n",
                 dso, dso->long_name, sym, sym->name);
 
+       if (dso__is_kcore(dso)) {
+               kce.kcore_filename = symfs_filename;
+               kce.addr = map__rip_2objdump(map, sym->start);
+               kce.offs = sym->start;
+               kce.len = sym->end + 1 - sym->start;
+               if (!kcore_extract__create(&kce)) {
+                       delete_extract = true;
+                       strlcpy(symfs_filename, kce.extract_filename,
+                               sizeof(symfs_filename));
+                       if (free_filename) {
+                               free(filename);
+                               free_filename = false;
+                       }
+                       filename = symfs_filename;
+               }
+       }
+
        snprintf(command, sizeof(command),
                 "%s %s%s --start-address=0x%016" PRIx64
                 " --stop-address=0x%016" PRIx64
@@ -972,6 +987,8 @@ fallback:
 
        pclose(file);
 out_free_filename:
+       if (delete_extract)
+               kcore_extract__delete(&kce);
        if (free_filename)
                free(filename);
        return err;
@@ -1070,7 +1087,7 @@ static void symbol__free_source_line(struct symbol *sym, int len)
                          (sizeof(src_line->p) * (src_line->nr_pcnt - 1));
 
        for (i = 0; i < len; i++) {
-               free(src_line->path);
+               free_srcline(src_line->path);
                src_line = (void *)src_line + sizeof_src_line;
        }
 
@@ -1081,13 +1098,11 @@ static void symbol__free_source_line(struct symbol *sym, int len)
 /* Get the filename:line for the colored entries */
 static int symbol__get_source_line(struct symbol *sym, struct map *map,
                                   struct perf_evsel *evsel,
-                                  struct rb_root *root, int len,
-                                  const char *filename)
+                                  struct rb_root *root, int len)
 {
        u64 start;
        int i, k;
        int evidx = evsel->idx;
-       char cmd[PATH_MAX * 2];
        struct source_line *src_line;
        struct annotation *notes = symbol__annotation(sym);
        struct sym_hist *h = annotation__histogram(notes, evidx);
@@ -1115,10 +1130,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
        start = map__rip_2objdump(map, sym->start);
 
        for (i = 0; i < len; i++) {
-               char *path = NULL;
-               size_t line_len;
                u64 offset;
-               FILE *fp;
                double percent_max = 0.0;
 
                src_line->nr_pcnt = nr_pcnt;
@@ -1135,23 +1147,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
                        goto next;
 
                offset = start + i;
-               sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
-               fp = popen(cmd, "r");
-               if (!fp)
-                       goto next;
-
-               if (getline(&path, &line_len, fp) < 0 || !line_len)
-                       goto next_close;
-
-               src_line->path = malloc(sizeof(char) * line_len + 1);
-               if (!src_line->path)
-                       goto next_close;
-
-               strcpy(src_line->path, path);
+               src_line->path = get_srcline(map->dso, offset);
                insert_source_line(&tmp_root, src_line);
 
-       next_close:
-               pclose(fp);
        next:
                src_line = (void *)src_line + sizeof_src_line;
        }
@@ -1192,7 +1190,7 @@ static void print_summary(struct rb_root *root, const char *filename)
 
                path = src_line->path;
                color = get_percent_color(percent_max);
-               color_fprintf(stdout, color, " %s", path);
+               color_fprintf(stdout, color, " %s\n", path);
 
                node = rb_next(node);
        }
@@ -1356,7 +1354,6 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
                         bool full_paths, int min_pcnt, int max_lines)
 {
        struct dso *dso = map->dso;
-       const char *filename = dso->long_name;
        struct rb_root source_line = RB_ROOT;
        u64 len;
 
@@ -1366,9 +1363,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
        len = symbol__size(sym);
 
        if (print_lines) {
-               symbol__get_source_line(sym, map, evsel, &source_line,
-                                       len, filename);
-               print_summary(&source_line, filename);
+               symbol__get_source_line(sym, map, evsel, &source_line, len);
+               print_summary(&source_line, dso->long_name);
        }
 
        symbol__annotate_printf(sym, map, evsel, full_paths,
index af755156d2785b7963d834adcd5e1ee3cc07b4be..834b7b57b7884f7b833291caa6bcaad2a1eff1d1 100644 (file)
@@ -150,7 +150,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
                         struct perf_evsel *evsel, bool print_lines,
                         bool full_paths, int min_pcnt, int max_lines);
 
-#ifdef SLANG_SUPPORT
+#ifdef HAVE_SLANG_SUPPORT
 int symbol__tui_annotate(struct symbol *sym, struct map *map,
                         struct perf_evsel *evsel,
                         struct hist_browser_timer *hbt);
@@ -165,30 +165,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
 }
 #endif
 
-#ifdef GTK2_SUPPORT
-int symbol__gtk_annotate(struct symbol *sym, struct map *map,
-                        struct perf_evsel *evsel,
-                        struct hist_browser_timer *hbt);
-
-static inline int hist_entry__gtk_annotate(struct hist_entry *he,
-                                          struct perf_evsel *evsel,
-                                          struct hist_browser_timer *hbt)
-{
-       return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
-}
-
-void perf_gtk__show_annotations(void);
-#else
-static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
-                               struct perf_evsel *evsel __maybe_unused,
-                               struct hist_browser_timer *hbt __maybe_unused)
-{
-       return 0;
-}
-
-static inline void perf_gtk__show_annotations(void) {}
-#endif
-
 extern const char      *disassembler_style;
 
 #endif /* __PERF_ANNOTATE_H */
index 7ded71d19d75323ab02184c460afde37fe17d831..a92770c98cc7c00dac6fdd57258eb120960a5294 100644 (file)
@@ -89,14 +89,14 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
        return raw - build_id;
 }
 
-char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
+char *dso__build_id_filename(struct dso *dso, char *bf, size_t size)
 {
        char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 
-       if (!self->has_build_id)
+       if (!dso->has_build_id)
                return NULL;
 
-       build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex);
+       build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex);
        if (bf == NULL) {
                if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir,
                             build_id_hex, build_id_hex + 2) < 0)
index a811f5c62e18b3988be2e4d806886a5352f81a65..929f28a7c14dc05cb1c3fd174e17520dda95b7ec 100644 (file)
@@ -10,10 +10,9 @@ extern struct perf_tool build_id__mark_dso_hit_ops;
 struct dso;
 
 int build_id__sprintf(const u8 *build_id, int len, char *bf);
-char *dso__build_id_filename(struct dso *self, char *bf, size_t size);
+char *dso__build_id_filename(struct dso *dso, char *bf, size_t size);
 
 int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
                           struct perf_sample *sample, struct perf_evsel *evsel,
                           struct machine *machine);
-
 #endif
index 26e367239873fadbdcde27610d6ee2577c0e9f79..7b176dd02e1ae94e6f5479b78ae4c2e84bb7836c 100644 (file)
@@ -70,8 +70,7 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2
 extern char *perf_pathdup(const char *fmt, ...)
        __attribute__((format (printf, 1, 2)));
 
-#ifndef HAVE_STRLCPY
+/* Matches the libc/libbsd function attribute so we declare this unconditionally: */
 extern size_t strlcpy(char *dest, const char *src, size_t size);
-#endif
 
 #endif /* __PERF_CACHE_H */
index 482f68081cd8d50a7c84fd25845841c18fcfb870..e3970e3eaacf45bc7a10db4a86314c2fdd79fbb5 100644 (file)
 
 __thread struct callchain_cursor callchain_cursor;
 
-#define chain_for_each_child(child, parent)    \
-       list_for_each_entry(child, &parent->children, siblings)
-
-#define chain_for_each_child_safe(child, next, parent) \
-       list_for_each_entry_safe(child, next, &parent->children, siblings)
-
 static void
 rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
                    enum chain_mode mode)
@@ -71,10 +65,16 @@ static void
 __sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
                  u64 min_hit)
 {
+       struct rb_node *n;
        struct callchain_node *child;
 
-       chain_for_each_child(child, node)
+       n = rb_first(&node->rb_root_in);
+       while (n) {
+               child = rb_entry(n, struct callchain_node, rb_node_in);
+               n = rb_next(n);
+
                __sort_chain_flat(rb_root, child, min_hit);
+       }
 
        if (node->hit && node->hit >= min_hit)
                rb_insert_callchain(rb_root, node, CHAIN_FLAT);
@@ -94,11 +94,16 @@ sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root,
 static void __sort_chain_graph_abs(struct callchain_node *node,
                                   u64 min_hit)
 {
+       struct rb_node *n;
        struct callchain_node *child;
 
        node->rb_root = RB_ROOT;
+       n = rb_first(&node->rb_root_in);
+
+       while (n) {
+               child = rb_entry(n, struct callchain_node, rb_node_in);
+               n = rb_next(n);
 
-       chain_for_each_child(child, node) {
                __sort_chain_graph_abs(child, min_hit);
                if (callchain_cumul_hits(child) >= min_hit)
                        rb_insert_callchain(&node->rb_root, child,
@@ -117,13 +122,18 @@ sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_root *chain_root,
 static void __sort_chain_graph_rel(struct callchain_node *node,
                                   double min_percent)
 {
+       struct rb_node *n;
        struct callchain_node *child;
        u64 min_hit;
 
        node->rb_root = RB_ROOT;
        min_hit = ceil(node->children_hit * min_percent);
 
-       chain_for_each_child(child, node) {
+       n = rb_first(&node->rb_root_in);
+       while (n) {
+               child = rb_entry(n, struct callchain_node, rb_node_in);
+               n = rb_next(n);
+
                __sort_chain_graph_rel(child, min_percent);
                if (callchain_cumul_hits(child) >= min_hit)
                        rb_insert_callchain(&node->rb_root, child,
@@ -173,19 +183,26 @@ create_child(struct callchain_node *parent, bool inherit_children)
                return NULL;
        }
        new->parent = parent;
-       INIT_LIST_HEAD(&new->children);
        INIT_LIST_HEAD(&new->val);
 
        if (inherit_children) {
-               struct callchain_node *next;
+               struct rb_node *n;
+               struct callchain_node *child;
+
+               new->rb_root_in = parent->rb_root_in;
+               parent->rb_root_in = RB_ROOT;
 
-               list_splice(&parent->children, &new->children);
-               INIT_LIST_HEAD(&parent->children);
+               n = rb_first(&new->rb_root_in);
+               while (n) {
+                       child = rb_entry(n, struct callchain_node, rb_node_in);
+                       child->parent = new;
+                       n = rb_next(n);
+               }
 
-               chain_for_each_child(next, new)
-                       next->parent = new;
+               /* make it the first child */
+               rb_link_node(&new->rb_node_in, NULL, &parent->rb_root_in.rb_node);
+               rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
        }
-       list_add_tail(&new->siblings, &parent->children);
 
        return new;
 }
@@ -223,7 +240,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
        }
 }
 
-static void
+static struct callchain_node *
 add_child(struct callchain_node *parent,
          struct callchain_cursor *cursor,
          u64 period)
@@ -235,6 +252,19 @@ add_child(struct callchain_node *parent,
 
        new->children_hit = 0;
        new->hit = period;
+       return new;
+}
+
+static s64 match_chain(struct callchain_cursor_node *node,
+                     struct callchain_list *cnode)
+{
+       struct symbol *sym = node->sym;
+
+       if (cnode->ms.sym && sym &&
+           callchain_param.key == CCKEY_FUNCTION)
+               return cnode->ms.sym->start - sym->start;
+       else
+               return cnode->ip - node->ip;
 }
 
 /*
@@ -272,9 +302,33 @@ split_add_child(struct callchain_node *parent,
 
        /* create a new child for the new branch if any */
        if (idx_total < cursor->nr) {
+               struct callchain_node *first;
+               struct callchain_list *cnode;
+               struct callchain_cursor_node *node;
+               struct rb_node *p, **pp;
+
                parent->hit = 0;
-               add_child(parent, cursor, period);
                parent->children_hit += period;
+
+               node = callchain_cursor_current(cursor);
+               new = add_child(parent, cursor, period);
+
+               /*
+                * This is second child since we moved parent's children
+                * to new (first) child above.
+                */
+               p = parent->rb_root_in.rb_node;
+               first = rb_entry(p, struct callchain_node, rb_node_in);
+               cnode = list_first_entry(&first->val, struct callchain_list,
+                                        list);
+
+               if (match_chain(node, cnode) < 0)
+                       pp = &p->rb_left;
+               else
+                       pp = &p->rb_right;
+
+               rb_link_node(&new->rb_node_in, p, pp);
+               rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
        } else {
                parent->hit = period;
        }
@@ -291,16 +345,40 @@ append_chain_children(struct callchain_node *root,
                      u64 period)
 {
        struct callchain_node *rnode;
+       struct callchain_cursor_node *node;
+       struct rb_node **p = &root->rb_root_in.rb_node;
+       struct rb_node *parent = NULL;
+
+       node = callchain_cursor_current(cursor);
+       if (!node)
+               return;
 
        /* lookup in childrens */
-       chain_for_each_child(rnode, root) {
-               unsigned int ret = append_chain(rnode, cursor, period);
+       while (*p) {
+               s64 ret;
+               struct callchain_list *cnode;
 
-               if (!ret)
+               parent = *p;
+               rnode = rb_entry(parent, struct callchain_node, rb_node_in);
+               cnode = list_first_entry(&rnode->val, struct callchain_list,
+                                        list);
+
+               /* just check first entry */
+               ret = match_chain(node, cnode);
+               if (ret == 0) {
+                       append_chain(rnode, cursor, period);
                        goto inc_children_hit;
+               }
+
+               if (ret < 0)
+                       p = &parent->rb_left;
+               else
+                       p = &parent->rb_right;
        }
        /* nothing in children, add to the current node */
-       add_child(root, cursor, period);
+       rnode = add_child(root, cursor, period);
+       rb_link_node(&rnode->rb_node_in, parent, p);
+       rb_insert_color(&rnode->rb_node_in, &root->rb_root_in);
 
 inc_children_hit:
        root->children_hit += period;
@@ -325,28 +403,20 @@ append_chain(struct callchain_node *root,
         */
        list_for_each_entry(cnode, &root->val, list) {
                struct callchain_cursor_node *node;
-               struct symbol *sym;
 
                node = callchain_cursor_current(cursor);
                if (!node)
                        break;
 
-               sym = node->sym;
-
-               if (cnode->ms.sym && sym &&
-                   callchain_param.key == CCKEY_FUNCTION) {
-                       if (cnode->ms.sym->start != sym->start)
-                               break;
-               } else if (cnode->ip != node->ip)
+               if (match_chain(node, cnode) != 0)
                        break;
 
-               if (!found)
-                       found = true;
+               found = true;
 
                callchain_cursor_advance(cursor);
        }
 
-       /* matches not, relay on the parent */
+       /* matches not, relay no the parent */
        if (!found) {
                cursor->curr = curr_snap;
                cursor->pos = start;
@@ -395,8 +465,9 @@ merge_chain_branch(struct callchain_cursor *cursor,
                   struct callchain_node *dst, struct callchain_node *src)
 {
        struct callchain_cursor_node **old_last = cursor->last;
-       struct callchain_node *child, *next_child;
+       struct callchain_node *child;
        struct callchain_list *list, *next_list;
+       struct rb_node *n;
        int old_pos = cursor->nr;
        int err = 0;
 
@@ -412,12 +483,16 @@ merge_chain_branch(struct callchain_cursor *cursor,
                append_chain_children(dst, cursor, src->hit);
        }
 
-       chain_for_each_child_safe(child, next_child, src) {
+       n = rb_first(&src->rb_root_in);
+       while (n) {
+               child = container_of(n, struct callchain_node, rb_node_in);
+               n = rb_next(n);
+               rb_erase(&child->rb_node_in, &src->rb_root_in);
+
                err = merge_chain_branch(cursor, dst, child);
                if (err)
                        break;
 
-               list_del(&child->siblings);
                free(child);
        }
 
index 9e99060408ae759e39401f686300090b76e52edf..4f7f989876ec7ba9b5a505334c15160e7e36aa40 100644 (file)
@@ -21,11 +21,11 @@ enum chain_order {
 
 struct callchain_node {
        struct callchain_node   *parent;
-       struct list_head        siblings;
-       struct list_head        children;
        struct list_head        val;
-       struct rb_node          rb_node; /* to sort nodes in an rbtree */
-       struct rb_root          rb_root; /* sorted tree of children */
+       struct rb_node          rb_node_in; /* to insert nodes in an rbtree */
+       struct rb_node          rb_node;    /* to sort nodes in an output tree */
+       struct rb_root          rb_root_in; /* input tree of children */
+       struct rb_root          rb_root;    /* sorted output tree of children */
        unsigned int            val_nr;
        u64                     hit;
        u64                     children_hit;
@@ -86,13 +86,12 @@ extern __thread struct callchain_cursor callchain_cursor;
 
 static inline void callchain_init(struct callchain_root *root)
 {
-       INIT_LIST_HEAD(&root->node.siblings);
-       INIT_LIST_HEAD(&root->node.children);
        INIT_LIST_HEAD(&root->node.val);
 
        root->node.parent = NULL;
        root->node.hit = 0;
        root->node.children_hit = 0;
+       root->node.rb_root_in = RB_ROOT;
        root->max_depth = 0;
 }
 
index 11e46da17bbb3c73ac53c1aac9aaa1ab50471a31..66e44a5019d538fff04d338bbf304b3dccecb4e2 100644 (file)
@@ -318,8 +318,15 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
        return r;
 }
 
-int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...)
 {
-       const char *color = get_percent_color(percent);
+       va_list args;
+       double percent;
+       const char *color;
+
+       va_start(args, fmt);
+       percent = va_arg(args, double);
+       va_end(args);
+       color = get_percent_color(percent);
        return color_snprintf(bf, size, color, fmt, percent);
 }
index dea082b7960210a17ccd2ee12d71a61a6192a503..fced3840e99c53bda892a466068c78e57c5982eb 100644 (file)
@@ -39,7 +39,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
 int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
-int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...);
 int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
 const char *get_percent_color(double percent);
 
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
new file mode 100644 (file)
index 0000000..ee0df0e
--- /dev/null
@@ -0,0 +1,121 @@
+#include "comm.h"
+#include "util.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+struct comm_str {
+       char *str;
+       struct rb_node rb_node;
+       int ref;
+};
+
+/* Should perhaps be moved to struct machine */
+static struct rb_root comm_str_root;
+
+static void comm_str__get(struct comm_str *cs)
+{
+       cs->ref++;
+}
+
+static void comm_str__put(struct comm_str *cs)
+{
+       if (!--cs->ref) {
+               rb_erase(&cs->rb_node, &comm_str_root);
+               free(cs->str);
+               free(cs);
+       }
+}
+
+static struct comm_str *comm_str__alloc(const char *str)
+{
+       struct comm_str *cs;
+
+       cs = zalloc(sizeof(*cs));
+       if (!cs)
+               return NULL;
+
+       cs->str = strdup(str);
+       if (!cs->str) {
+               free(cs);
+               return NULL;
+       }
+
+       return cs;
+}
+
+static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
+{
+       struct rb_node **p = &root->rb_node;
+       struct rb_node *parent = NULL;
+       struct comm_str *iter, *new;
+       int cmp;
+
+       while (*p != NULL) {
+               parent = *p;
+               iter = rb_entry(parent, struct comm_str, rb_node);
+
+               cmp = strcmp(str, iter->str);
+               if (!cmp)
+                       return iter;
+
+               if (cmp < 0)
+                       p = &(*p)->rb_left;
+               else
+                       p = &(*p)->rb_right;
+       }
+
+       new = comm_str__alloc(str);
+       if (!new)
+               return NULL;
+
+       rb_link_node(&new->rb_node, parent, p);
+       rb_insert_color(&new->rb_node, root);
+
+       return new;
+}
+
+struct comm *comm__new(const char *str, u64 timestamp)
+{
+       struct comm *comm = zalloc(sizeof(*comm));
+
+       if (!comm)
+               return NULL;
+
+       comm->start = timestamp;
+
+       comm->comm_str = comm_str__findnew(str, &comm_str_root);
+       if (!comm->comm_str) {
+               free(comm);
+               return NULL;
+       }
+
+       comm_str__get(comm->comm_str);
+
+       return comm;
+}
+
+void comm__override(struct comm *comm, const char *str, u64 timestamp)
+{
+       struct comm_str *old = comm->comm_str;
+
+       comm->comm_str = comm_str__findnew(str, &comm_str_root);
+       if (!comm->comm_str) {
+               comm->comm_str = old;
+               return;
+       }
+
+       comm->start = timestamp;
+       comm_str__get(comm->comm_str);
+       comm_str__put(old);
+}
+
+void comm__free(struct comm *comm)
+{
+       comm_str__put(comm->comm_str);
+       free(comm);
+}
+
+const char *comm__str(const struct comm *comm)
+{
+       return comm->comm_str->str;
+}
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
new file mode 100644 (file)
index 0000000..7a86e56
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __PERF_COMM_H
+#define __PERF_COMM_H
+
+#include "../perf.h"
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+struct comm_str;
+
+struct comm {
+       struct comm_str *comm_str;
+       u64 start;
+       struct list_head list;
+};
+
+void comm__free(struct comm *comm);
+struct comm *comm__new(const char *str, u64 timestamp);
+const char *comm__str(const struct comm *comm);
+void comm__override(struct comm *comm, const char *str, u64 timestamp);
+
+#endif  /* __PERF_COMM_H */
index beb8cf9f9976df75e77f38dbc5860b37acb5a9a9..a9b48c42e81eb36e34cce24e091be66437270d44 100644 (file)
@@ -1,5 +1,5 @@
 #include "util.h"
-#include "sysfs.h"
+#include "fs.h"
 #include "../perf.h"
 #include "cpumap.h"
 #include <assert.h>
@@ -216,7 +216,7 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)
 
        cpu = map->map[idx];
 
-       mnt = sysfs_find_mountpoint();
+       mnt = sysfs__mountpoint();
        if (!mnt)
                return -1;
 
@@ -279,7 +279,7 @@ int cpu_map__get_core(struct cpu_map *map, int idx)
 
        cpu = map->map[idx];
 
-       mnt = sysfs_find_mountpoint();
+       mnt = sysfs__mountpoint();
        if (!mnt)
                return -1;
 
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
new file mode 100644 (file)
index 0000000..7d09faf
--- /dev/null
@@ -0,0 +1,120 @@
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "data.h"
+#include "util.h"
+
+static bool check_pipe(struct perf_data_file *file)
+{
+       struct stat st;
+       bool is_pipe = false;
+       int fd = perf_data_file__is_read(file) ?
+                STDIN_FILENO : STDOUT_FILENO;
+
+       if (!file->path) {
+               if (!fstat(fd, &st) && S_ISFIFO(st.st_mode))
+                       is_pipe = true;
+       } else {
+               if (!strcmp(file->path, "-"))
+                       is_pipe = true;
+       }
+
+       if (is_pipe)
+               file->fd = fd;
+
+       return file->is_pipe = is_pipe;
+}
+
+static int check_backup(struct perf_data_file *file)
+{
+       struct stat st;
+
+       if (!stat(file->path, &st) && st.st_size) {
+               /* TODO check errors properly */
+               char oldname[PATH_MAX];
+               snprintf(oldname, sizeof(oldname), "%s.old",
+                        file->path);
+               unlink(oldname);
+               rename(file->path, oldname);
+       }
+
+       return 0;
+}
+
+static int open_file_read(struct perf_data_file *file)
+{
+       struct stat st;
+       int fd;
+
+       fd = open(file->path, O_RDONLY);
+       if (fd < 0) {
+               int err = errno;
+
+               pr_err("failed to open %s: %s", file->path, strerror(err));
+               if (err == ENOENT && !strcmp(file->path, "perf.data"))
+                       pr_err("  (try 'perf record' first)");
+               pr_err("\n");
+               return -err;
+       }
+
+       if (fstat(fd, &st) < 0)
+               goto out_close;
+
+       if (!file->force && st.st_uid && (st.st_uid != geteuid())) {
+               pr_err("file %s not owned by current user or root\n",
+                      file->path);
+               goto out_close;
+       }
+
+       if (!st.st_size) {
+               pr_info("zero-sized file (%s), nothing to do!\n",
+                       file->path);
+               goto out_close;
+       }
+
+       file->size = st.st_size;
+       return fd;
+
+ out_close:
+       close(fd);
+       return -1;
+}
+
+static int open_file_write(struct perf_data_file *file)
+{
+       if (check_backup(file))
+               return -1;
+
+       return open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
+}
+
+static int open_file(struct perf_data_file *file)
+{
+       int fd;
+
+       fd = perf_data_file__is_read(file) ?
+            open_file_read(file) : open_file_write(file);
+
+       file->fd = fd;
+       return fd < 0 ? -1 : 0;
+}
+
+int perf_data_file__open(struct perf_data_file *file)
+{
+       if (check_pipe(file))
+               return 0;
+
+       if (!file->path)
+               file->path = "perf.data";
+
+       return open_file(file);
+}
+
+void perf_data_file__close(struct perf_data_file *file)
+{
+       close(file->fd);
+}
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h
new file mode 100644 (file)
index 0000000..8c2df80
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __PERF_DATA_H
+#define __PERF_DATA_H
+
+#include <stdbool.h>
+
+enum perf_data_mode {
+       PERF_DATA_MODE_WRITE,
+       PERF_DATA_MODE_READ,
+};
+
+struct perf_data_file {
+       const char *path;
+       int fd;
+       bool is_pipe;
+       bool force;
+       unsigned long size;
+       enum perf_data_mode mode;
+};
+
+static inline bool perf_data_file__is_read(struct perf_data_file *file)
+{
+       return file->mode == PERF_DATA_MODE_READ;
+}
+
+static inline bool perf_data_file__is_write(struct perf_data_file *file)
+{
+       return file->mode == PERF_DATA_MODE_WRITE;
+}
+
+static inline int perf_data_file__is_pipe(struct perf_data_file *file)
+{
+       return file->is_pipe;
+}
+
+static inline int perf_data_file__fd(struct perf_data_file *file)
+{
+       return file->fd;
+}
+
+static inline unsigned long perf_data_file__size(struct perf_data_file *file)
+{
+       return file->size;
+}
+
+int perf_data_file__open(struct perf_data_file *file);
+void perf_data_file__close(struct perf_data_file *file);
+
+#endif /* __PERF_DATA_H */
index e3c1ff8512c827330d4afde013e19b7c5eeb58f2..af4c687cc49b54279c95c10ed48fe12843700658 100644 (file)
@@ -7,19 +7,20 @@
 char dso__symtab_origin(const struct dso *dso)
 {
        static const char origin[] = {
-               [DSO_BINARY_TYPE__KALLSYMS]             = 'k',
-               [DSO_BINARY_TYPE__VMLINUX]              = 'v',
-               [DSO_BINARY_TYPE__JAVA_JIT]             = 'j',
-               [DSO_BINARY_TYPE__DEBUGLINK]            = 'l',
-               [DSO_BINARY_TYPE__BUILD_ID_CACHE]       = 'B',
-               [DSO_BINARY_TYPE__FEDORA_DEBUGINFO]     = 'f',
-               [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO]     = 'u',
-               [DSO_BINARY_TYPE__BUILDID_DEBUGINFO]    = 'b',
-               [DSO_BINARY_TYPE__SYSTEM_PATH_DSO]      = 'd',
-               [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]  = 'K',
-               [DSO_BINARY_TYPE__GUEST_KALLSYMS]       = 'g',
-               [DSO_BINARY_TYPE__GUEST_KMODULE]        = 'G',
-               [DSO_BINARY_TYPE__GUEST_VMLINUX]        = 'V',
+               [DSO_BINARY_TYPE__KALLSYMS]                     = 'k',
+               [DSO_BINARY_TYPE__VMLINUX]                      = 'v',
+               [DSO_BINARY_TYPE__JAVA_JIT]                     = 'j',
+               [DSO_BINARY_TYPE__DEBUGLINK]                    = 'l',
+               [DSO_BINARY_TYPE__BUILD_ID_CACHE]               = 'B',
+               [DSO_BINARY_TYPE__FEDORA_DEBUGINFO]             = 'f',
+               [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO]             = 'u',
+               [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO]       = 'o',
+               [DSO_BINARY_TYPE__BUILDID_DEBUGINFO]            = 'b',
+               [DSO_BINARY_TYPE__SYSTEM_PATH_DSO]              = 'd',
+               [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]          = 'K',
+               [DSO_BINARY_TYPE__GUEST_KALLSYMS]               = 'g',
+               [DSO_BINARY_TYPE__GUEST_KMODULE]                = 'G',
+               [DSO_BINARY_TYPE__GUEST_VMLINUX]                = 'V',
        };
 
        if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
@@ -64,6 +65,28 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
                         symbol_conf.symfs, dso->long_name);
                break;
 
+       case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
+       {
+               char *last_slash;
+               size_t len;
+               size_t dir_size;
+
+               last_slash = dso->long_name + dso->long_name_len;
+               while (last_slash != dso->long_name && *last_slash != '/')
+                       last_slash--;
+
+               len = scnprintf(file, size, "%s", symbol_conf.symfs);
+               dir_size = last_slash - dso->long_name + 2;
+               if (dir_size > (size - len)) {
+                       ret = -1;
+                       break;
+               }
+               len += scnprintf(file + len, dir_size, "%s",  dso->long_name);
+               len += scnprintf(file + len , size - len, ".debug%s",
+                                                               last_slash);
+               break;
+       }
+
        case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
                if (!dso->has_build_id) {
                        ret = -1;
@@ -427,6 +450,7 @@ struct dso *dso__new(const char *name)
                dso->rel = 0;
                dso->sorted_by_name = 0;
                dso->has_build_id = 0;
+               dso->has_srcline = 1;
                dso->kernel = DSO_TYPE_USER;
                dso->needs_swap = DSO_SWAP__UNSET;
                INIT_LIST_HEAD(&dso->node);
index b793053335d60fca3302fd34b27543cd6151b0fb..9ac666abbe7ef988f30630c053f9c4e709eb3edb 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdbool.h>
 #include "types.h"
 #include "map.h"
+#include "build-id.h"
 
 enum dso_binary_type {
        DSO_BINARY_TYPE__KALLSYMS = 0,
@@ -23,6 +24,7 @@ enum dso_binary_type {
        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
        DSO_BINARY_TYPE__KCORE,
        DSO_BINARY_TYPE__GUEST_KCORE,
+       DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
        DSO_BINARY_TYPE__NOT_FOUND,
 };
 
@@ -81,6 +83,7 @@ struct dso {
        enum dso_binary_type    data_type;
        u8               adjust_symbols:1;
        u8               has_build_id:1;
+       u8               has_srcline:1;
        u8               hit:1;
        u8               annotate_warned:1;
        u8               sname_alloc:1;
index 49096ea58a15dec22dc1e20b0de5d69bf2c2ac3a..ec9ae1114ed4ca57492948686cf2858d3f2591d8 100644 (file)
@@ -512,18 +512,18 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 
 int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
-                            struct perf_sample *sample __maybe_unused,
+                            struct perf_sample *sample,
                             struct machine *machine)
 {
-       return machine__process_comm_event(machine, event);
+       return machine__process_comm_event(machine, event, sample);
 }
 
 int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
-                            struct perf_sample *sample __maybe_unused,
+                            struct perf_sample *sample,
                             struct machine *machine)
 {
-       return machine__process_lost_event(machine, event);
+       return machine__process_lost_event(machine, event, sample);
 }
 
 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
@@ -546,18 +546,18 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
 
 int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
-                            struct perf_sample *sample __maybe_unused,
+                            struct perf_sample *sample,
                             struct machine *machine)
 {
-       return machine__process_mmap_event(machine, event);
+       return machine__process_mmap_event(machine, event, sample);
 }
 
 int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
-                            struct perf_sample *sample __maybe_unused,
+                            struct perf_sample *sample,
                             struct machine *machine)
 {
-       return machine__process_mmap2_event(machine, event);
+       return machine__process_mmap2_event(machine, event, sample);
 }
 
 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
@@ -569,18 +569,18 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
 
 int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
-                            struct perf_sample *sample __maybe_unused,
+                            struct perf_sample *sample,
                             struct machine *machine)
 {
-       return machine__process_fork_event(machine, event);
+       return machine__process_fork_event(machine, event, sample);
 }
 
 int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
-                            struct perf_sample *sample __maybe_unused,
+                            struct perf_sample *sample,
                             struct machine *machine)
 {
-       return machine__process_exit_event(machine, event);
+       return machine__process_exit_event(machine, event, sample);
 }
 
 size_t perf_event__fprintf(union perf_event *event, FILE *fp)
@@ -611,21 +611,21 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
 
 int perf_event__process(struct perf_tool *tool __maybe_unused,
                        union perf_event *event,
-                       struct perf_sample *sample __maybe_unused,
+                       struct perf_sample *sample,
                        struct machine *machine)
 {
-       return machine__process_event(machine, event);
+       return machine__process_event(machine, event, sample);
 }
 
-void thread__find_addr_map(struct thread *self,
+void thread__find_addr_map(struct thread *thread,
                           struct machine *machine, u8 cpumode,
                           enum map_type type, u64 addr,
                           struct addr_location *al)
 {
-       struct map_groups *mg = &self->mg;
+       struct map_groups *mg = &thread->mg;
        bool load_map = false;
 
-       al->thread = self;
+       al->thread = thread;
        al->addr = addr;
        al->cpumode = cpumode;
        al->filtered = false;
@@ -721,10 +721,10 @@ int perf_event__preprocess_sample(const union perf_event *event,
                return -1;
 
        if (symbol_conf.comm_list &&
-           !strlist__has_entry(symbol_conf.comm_list, thread->comm))
+           !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread)))
                goto out_filtered;
 
-       dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
+       dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
        /*
         * Have we already created the kernel maps for this machine?
         *
index c67ecc457d295d029a2307c1b0ad7e1531b944d1..f8d70f3003ab6995a6522846f5807fecb20f2fce 100644 (file)
@@ -61,6 +61,12 @@ struct read_event {
        u64 id;
 };
 
+struct throttle_event {
+       struct perf_event_header header;
+       u64 time;
+       u64 id;
+       u64 stream_id;
+};
 
 #define PERF_SAMPLE_MASK                               \
        (PERF_SAMPLE_IP | PERF_SAMPLE_TID |             \
@@ -69,6 +75,9 @@ struct read_event {
         PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD |         \
         PERF_SAMPLE_IDENTIFIER)
 
+/* perf sample has 16 bits size limit */
+#define PERF_SAMPLE_MAX_SIZE (1 << 16)
+
 struct sample_event {
        struct perf_event_header        header;
        u64 array[];
@@ -111,6 +120,7 @@ struct perf_sample {
        u64 stream_id;
        u64 period;
        u64 weight;
+       u64 transaction;
        u32 cpu;
        u32 raw_size;
        u64 data_src;
@@ -177,6 +187,7 @@ union perf_event {
        struct fork_event               fork;
        struct lost_event               lost;
        struct read_event               read;
+       struct throttle_event           throttle;
        struct sample_event             sample;
        struct attr_event               attr;
        struct event_type_event         event_type;
@@ -240,7 +251,8 @@ int perf_event__process(struct perf_tool *tool,
                        struct machine *machine);
 
 struct addr_location;
-int perf_event__preprocess_sample(const union perf_event *self,
+
+int perf_event__preprocess_sample(const union perf_event *event,
                                  struct machine *machine,
                                  struct addr_location *al,
                                  struct perf_sample *sample);
index e584cd30b0f2dca4866919e578e4c8e9e3f71ade..b939221efd8dea0b670d1d968e7fa9086c7034a0 100644 (file)
@@ -18,6 +18,7 @@
 #include <unistd.h>
 
 #include "parse-events.h"
+#include "parse-options.h"
 
 #include <sys/mman.h>
 
@@ -49,6 +50,18 @@ struct perf_evlist *perf_evlist__new(void)
        return evlist;
 }
 
+struct perf_evlist *perf_evlist__new_default(void)
+{
+       struct perf_evlist *evlist = perf_evlist__new();
+
+       if (evlist && perf_evlist__add_default(evlist)) {
+               perf_evlist__delete(evlist);
+               evlist = NULL;
+       }
+
+       return evlist;
+}
+
 /**
  * perf_evlist__set_id_pos - set the positions of event ids.
  * @evlist: selected event list
@@ -242,7 +255,7 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
        if (evsel == NULL)
                return -1;
 
-       evsel->handler.func = handler;
+       evsel->handler = handler;
        perf_evlist__add(evlist, evsel);
        return 0;
 }
@@ -527,7 +540,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
                if ((old & md->mask) + size != ((old + size) & md->mask)) {
                        unsigned int offset = old;
                        unsigned int len = min(sizeof(*event), size), cpy;
-                       void *dst = &md->event_copy;
+                       void *dst = md->event_copy;
 
                        do {
                                cpy = min(md->mask + 1 - (offset & md->mask), len);
@@ -537,7 +550,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
                                len -= cpy;
                        } while (len);
 
-                       event = &md->event_copy;
+                       event = (union perf_event *) md->event_copy;
                }
 
                old += size;
@@ -594,6 +607,8 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
        evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
                                      MAP_SHARED, fd, 0);
        if (evlist->mmap[idx].base == MAP_FAILED) {
+               pr_debug2("failed to mmap perf event ring buffer, error %d\n",
+                         errno);
                evlist->mmap[idx].base = NULL;
                return -1;
        }
@@ -602,9 +617,36 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
        return 0;
 }
 
-static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
+static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
+                                      int prot, int mask, int cpu, int thread,
+                                      int *output)
 {
        struct perf_evsel *evsel;
+
+       list_for_each_entry(evsel, &evlist->entries, node) {
+               int fd = FD(evsel, cpu, thread);
+
+               if (*output == -1) {
+                       *output = fd;
+                       if (__perf_evlist__mmap(evlist, idx, prot, mask,
+                                               *output) < 0)
+                               return -1;
+               } else {
+                       if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
+                               return -1;
+               }
+
+               if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
+                   perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
+                       return -1;
+       }
+
+       return 0;
+}
+
+static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
+                                    int mask)
+{
        int cpu, thread;
        int nr_cpus = cpu_map__nr(evlist->cpus);
        int nr_threads = thread_map__nr(evlist->threads);
@@ -614,23 +656,9 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m
                int output = -1;
 
                for (thread = 0; thread < nr_threads; thread++) {
-                       list_for_each_entry(evsel, &evlist->entries, node) {
-                               int fd = FD(evsel, cpu, thread);
-
-                               if (output == -1) {
-                                       output = fd;
-                                       if (__perf_evlist__mmap(evlist, cpu,
-                                                               prot, mask, output) < 0)
-                                               goto out_unmap;
-                               } else {
-                                       if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
-                                               goto out_unmap;
-                               }
-
-                               if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
-                                   perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
-                                       goto out_unmap;
-                       }
+                       if (perf_evlist__mmap_per_evsel(evlist, cpu, prot, mask,
+                                                       cpu, thread, &output))
+                               goto out_unmap;
                }
        }
 
@@ -642,9 +670,9 @@ out_unmap:
        return -1;
 }
 
-static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
+static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
+                                       int mask)
 {
-       struct perf_evsel *evsel;
        int thread;
        int nr_threads = thread_map__nr(evlist->threads);
 
@@ -652,23 +680,9 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in
        for (thread = 0; thread < nr_threads; thread++) {
                int output = -1;
 
-               list_for_each_entry(evsel, &evlist->entries, node) {
-                       int fd = FD(evsel, 0, thread);
-
-                       if (output == -1) {
-                               output = fd;
-                               if (__perf_evlist__mmap(evlist, thread,
-                                                       prot, mask, output) < 0)
-                                       goto out_unmap;
-                       } else {
-                               if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
-                                       goto out_unmap;
-                       }
-
-                       if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
-                           perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
-                               goto out_unmap;
-               }
+               if (perf_evlist__mmap_per_evsel(evlist, thread, prot, mask, 0,
+                                               thread, &output))
+                       goto out_unmap;
        }
 
        return 0;
@@ -679,20 +693,76 @@ out_unmap:
        return -1;
 }
 
-/** perf_evlist__mmap - Create per cpu maps to receive events
- *
- * @evlist - list of events
- * @pages - map length in pages
- * @overwrite - overwrite older events?
- *
- * If overwrite is false the user needs to signal event consuption using:
- *
- *     struct perf_mmap *m = &evlist->mmap[cpu];
- *     unsigned int head = perf_mmap__read_head(m);
+static size_t perf_evlist__mmap_size(unsigned long pages)
+{
+       /* 512 kiB: default amount of unprivileged mlocked memory */
+       if (pages == UINT_MAX)
+               pages = (512 * 1024) / page_size;
+       else if (!is_power_of_2(pages))
+               return 0;
+
+       return (pages + 1) * page_size;
+}
+
+int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
+                                 int unset __maybe_unused)
+{
+       unsigned int *mmap_pages = opt->value;
+       unsigned long pages, val;
+       size_t size;
+       static struct parse_tag tags[] = {
+               { .tag  = 'B', .mult = 1       },
+               { .tag  = 'K', .mult = 1 << 10 },
+               { .tag  = 'M', .mult = 1 << 20 },
+               { .tag  = 'G', .mult = 1 << 30 },
+               { .tag  = 0 },
+       };
+
+       val = parse_tag_value(str, tags);
+       if (val != (unsigned long) -1) {
+               /* we got file size value */
+               pages = PERF_ALIGN(val, page_size) / page_size;
+               if (pages < (1UL << 31) && !is_power_of_2(pages)) {
+                       pages = next_pow2(pages);
+                       pr_info("rounding mmap pages size to %lu (%lu pages)\n",
+                               pages * page_size, pages);
+               }
+       } else {
+               /* we got pages count value */
+               char *eptr;
+               pages = strtoul(str, &eptr, 10);
+               if (*eptr != '\0') {
+                       pr_err("failed to parse --mmap_pages/-m value\n");
+                       return -1;
+               }
+       }
+
+       if (pages > UINT_MAX || pages > SIZE_MAX / page_size) {
+               pr_err("--mmap_pages/-m value too big\n");
+               return -1;
+       }
+
+       size = perf_evlist__mmap_size(pages);
+       if (!size) {
+               pr_err("--mmap_pages/-m value must be a power of two.");
+               return -1;
+       }
+
+       *mmap_pages = pages;
+       return 0;
+}
+
+/**
+ * perf_evlist__mmap - Create mmaps to receive events.
+ * @evlist: list of events
+ * @pages: map length in pages
+ * @overwrite: overwrite older events?
  *
- *     perf_mmap__write_tail(m, head)
+ * If @overwrite is %false the user needs to signal event consumption using
+ * perf_mmap__write_tail().  Using perf_evlist__mmap_read() does this
+ * automatically.
  *
- * Using perf_evlist__read_on_cpu does this automatically.
+ * Return: %0 on success, negative error code otherwise.
  */
 int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
                      bool overwrite)
@@ -702,14 +772,6 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
        const struct thread_map *threads = evlist->threads;
        int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
 
-        /* 512 kiB: default amount of unprivileged mlocked memory */
-        if (pages == UINT_MAX)
-                pages = (512 * 1024) / page_size;
-       else if (!is_power_of_2(pages))
-               return -EINVAL;
-
-       mask = pages * page_size - 1;
-
        if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
                return -ENOMEM;
 
@@ -717,7 +779,9 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
                return -ENOMEM;
 
        evlist->overwrite = overwrite;
-       evlist->mmap_len = (pages + 1) * page_size;
+       evlist->mmap_len = perf_evlist__mmap_size(pages);
+       pr_debug("mmap size %zuB\n", evlist->mmap_len);
+       mask = evlist->mmap_len - page_size - 1;
 
        list_for_each_entry(evsel, &evlist->entries, node) {
                if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
@@ -1073,3 +1137,66 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
 
        return printed + fprintf(fp, "\n");;
 }
+
+int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
+                            int err, char *buf, size_t size)
+{
+       char sbuf[128];
+
+       switch (err) {
+       case ENOENT:
+               scnprintf(buf, size, "%s",
+                         "Error:\tUnable to find debugfs\n"
+                         "Hint:\tWas your kernel was compiled with debugfs support?\n"
+                         "Hint:\tIs the debugfs filesystem mounted?\n"
+                         "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
+               break;
+       case EACCES:
+               scnprintf(buf, size,
+                         "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n"
+                         "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
+                         debugfs_mountpoint, debugfs_mountpoint);
+               break;
+       default:
+               scnprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
+               break;
+       }
+
+       return 0;
+}
+
+int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
+                              int err, char *buf, size_t size)
+{
+       int printed, value;
+       char sbuf[128], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
+
+       switch (err) {
+       case EACCES:
+       case EPERM:
+               printed = scnprintf(buf, size,
+                                   "Error:\t%s.\n"
+                                   "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
+
+               if (filename__read_int("/proc/sys/kernel/perf_event_paranoid", &value))
+                       break;
+
+               printed += scnprintf(buf + printed, size - printed, "\nHint:\t");
+
+               if (value >= 2) {
+                       printed += scnprintf(buf + printed, size - printed,
+                                            "For your workloads it needs to be <= 1\nHint:\t");
+               }
+               printed += scnprintf(buf + printed, size - printed,
+                                    "For system wide tracing it needs to be set to -1");
+
+               printed += scnprintf(buf + printed, size - printed,
+                                   ".\nHint:\tThe current value is %d.", value);
+               break;
+       default:
+               scnprintf(buf, size, "%s", emsg);
+               break;
+       }
+
+       return 0;
+}
index 206d093393069012421a65b6dc893f570de32dd9..ecaa582f40e265b5022c35075da162464df538d2 100644 (file)
@@ -21,7 +21,7 @@ struct perf_mmap {
        void             *base;
        int              mask;
        unsigned int     prev;
-       union perf_event event_copy;
+       char             event_copy[PERF_SAMPLE_MAX_SIZE];
 };
 
 struct perf_evlist {
@@ -31,7 +31,7 @@ struct perf_evlist {
        int              nr_groups;
        int              nr_fds;
        int              nr_mmaps;
-       int              mmap_len;
+       size_t           mmap_len;
        int              id_pos;
        int              is_pos;
        u64              combined_sample_type;
@@ -53,6 +53,7 @@ struct perf_evsel_str_handler {
 };
 
 struct perf_evlist *perf_evlist__new(void);
+struct perf_evlist *perf_evlist__new_default(void);
 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
                       struct thread_map *threads);
 void perf_evlist__exit(struct perf_evlist *evlist);
@@ -87,7 +88,7 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
 
 struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
 
-union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
+union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
 
 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
 
@@ -98,6 +99,7 @@ void perf_evlist__set_id_pos(struct perf_evlist *evlist);
 bool perf_can_sample_identifier(void);
 void perf_evlist__config(struct perf_evlist *evlist,
                         struct perf_record_opts *opts);
+int perf_record_opts__config(struct perf_record_opts *opts);
 
 int perf_evlist__prepare_workload(struct perf_evlist *evlist,
                                  struct perf_target *target,
@@ -105,6 +107,10 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
                                  bool want_signal);
 int perf_evlist__start_workload(struct perf_evlist *evlist);
 
+int perf_evlist__parse_mmap_pages(const struct option *opt,
+                                 const char *str,
+                                 int unset);
+
 int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
                      bool overwrite);
 void perf_evlist__munmap(struct perf_evlist *evlist);
@@ -165,10 +171,13 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist)
 
 size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp);
 
+int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size);
+int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size);
+
 static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm)
 {
        struct perf_event_mmap_page *pc = mm->base;
-       int head = pc->data_head;
+       int head = ACCESS_ONCE(pc->data_head);
        rmb();
        return head;
 }
@@ -181,7 +190,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
        /*
         * ensure all reads are done before we write the tail out.
         */
-       /* mb(); */
+       mb();
        pc->data_tail = tail;
 }
 
index 9f1ef9bee2d0c96583dac31d4c12bcc220b519bf..5280820ed3897ea9ffddd1ce5f5c4e007071bf16 100644 (file)
@@ -663,7 +663,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
        }
 
        if (opts->sample_address)
-               attr->sample_type       |= PERF_SAMPLE_DATA_SRC;
+               perf_evsel__set_sample_bit(evsel, DATA_SRC);
 
        if (opts->no_delay) {
                attr->watermark = 0;
@@ -675,11 +675,14 @@ void perf_evsel__config(struct perf_evsel *evsel,
        }
 
        if (opts->sample_weight)
-               attr->sample_type       |= PERF_SAMPLE_WEIGHT;
+               perf_evsel__set_sample_bit(evsel, WEIGHT);
 
        attr->mmap  = track;
        attr->comm  = track;
 
+       if (opts->sample_transaction)
+               perf_evsel__set_sample_bit(evsel, TRANSACTION);
+
        /*
         * XXX see the function comment above
         *
@@ -982,6 +985,7 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
        ret += PRINT_ATTR2(exclude_host, exclude_guest);
        ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel,
                            "excl.callchain_user", exclude_callchain_user);
+       ret += PRINT_ATTR_U32(mmap2);
 
        ret += PRINT_ATTR_U32(wakeup_events);
        ret += PRINT_ATTR_U32(wakeup_watermark);
@@ -1047,6 +1051,8 @@ retry_open:
                                                                     group_fd, flags);
                        if (FD(evsel, cpu, thread) < 0) {
                                err = -errno;
+                               pr_debug2("perf_event_open failed, error %d\n",
+                                         err);
                                goto try_fallback;
                        }
                        set_rlimit = NO_CHANGE;
@@ -1213,6 +1219,7 @@ static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel,
 
                sample->pid = u.val32[0];
                sample->tid = u.val32[1];
+               array--;
        }
 
        return 0;
@@ -1452,6 +1459,9 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
                        array = (void *)array + sz;
                        OVERFLOW_CHECK_u64(array);
                        data->user_stack.size = *array++;
+                       if (WARN_ONCE(data->user_stack.size > sz,
+                                     "user stack dump failure\n"))
+                               return -EFAULT;
                }
        }
 
@@ -1469,6 +1479,13 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
                array++;
        }
 
+       data->transaction = 0;
+       if (type & PERF_SAMPLE_TRANSACTION) {
+               OVERFLOW_CHECK_u64(array);
+               data->transaction = *array;
+               array++;
+       }
+
        return 0;
 }
 
@@ -1561,6 +1578,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
        if (type & PERF_SAMPLE_DATA_SRC)
                result += sizeof(u64);
 
+       if (type & PERF_SAMPLE_TRANSACTION)
+               result += sizeof(u64);
+
        return result;
 }
 
@@ -1734,6 +1754,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
                array++;
        }
 
+       if (type & PERF_SAMPLE_TRANSACTION) {
+               *array = sample->transaction;
+               array++;
+       }
+
        return 0;
 }
 
index 4a7bdc713bab2fa4266069388ed79d530ba64b94..64ec8e1a7a2879a21c0592cbe1b50bd7b13f7ea0 100644 (file)
@@ -74,10 +74,7 @@ struct perf_evsel {
                off_t           id_offset;
        };
        struct cgroup_sel       *cgrp;
-       struct {
-               void            *func;
-               void            *data;
-       } handler;
+       void                    *handler;
        struct cpu_map          *cpus;
        unsigned int            sample_size;
        int                     id_pos;
@@ -197,6 +194,12 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1,
               (e1->attr.config == e2->attr.config);
 }
 
+#define perf_evsel__cmp(a, b)                  \
+       ((a) &&                                 \
+        (b) &&                                 \
+        (a)->attr.type == (b)->attr.type &&    \
+        (a)->attr.config == (b)->attr.config)
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
                              int cpu, int thread, bool scale);
 
diff --git a/tools/perf/util/fs.c b/tools/perf/util/fs.c
new file mode 100644 (file)
index 0000000..f5be1f2
--- /dev/null
@@ -0,0 +1,119 @@
+
+/* TODO merge/factor into tools/lib/lk/debugfs.c */
+
+#include "util.h"
+#include "util/fs.h"
+
+static const char * const sysfs__fs_known_mountpoints[] = {
+       "/sys",
+       0,
+};
+
+static const char * const procfs__known_mountpoints[] = {
+       "/proc",
+       0,
+};
+
+struct fs {
+       const char              *name;
+       const char * const      *mounts;
+       char                     path[PATH_MAX + 1];
+       bool                     found;
+       long                     magic;
+};
+
+enum {
+       FS__SYSFS  = 0,
+       FS__PROCFS = 1,
+};
+
+static struct fs fs__entries[] = {
+       [FS__SYSFS] = {
+               .name   = "sysfs",
+               .mounts = sysfs__fs_known_mountpoints,
+               .magic  = SYSFS_MAGIC,
+       },
+       [FS__PROCFS] = {
+               .name   = "proc",
+               .mounts = procfs__known_mountpoints,
+               .magic  = PROC_SUPER_MAGIC,
+       },
+};
+
+static bool fs__read_mounts(struct fs *fs)
+{
+       bool found = false;
+       char type[100];
+       FILE *fp;
+
+       fp = fopen("/proc/mounts", "r");
+       if (fp == NULL)
+               return NULL;
+
+       while (!found &&
+              fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
+                     fs->path, type) == 2) {
+
+               if (strcmp(type, fs->name) == 0)
+                       found = true;
+       }
+
+       fclose(fp);
+       return fs->found = found;
+}
+
+static int fs__valid_mount(const char *fs, long magic)
+{
+       struct statfs st_fs;
+
+       if (statfs(fs, &st_fs) < 0)
+               return -ENOENT;
+       else if (st_fs.f_type != magic)
+               return -ENOENT;
+
+       return 0;
+}
+
+static bool fs__check_mounts(struct fs *fs)
+{
+       const char * const *ptr;
+
+       ptr = fs->mounts;
+       while (*ptr) {
+               if (fs__valid_mount(*ptr, fs->magic) == 0) {
+                       fs->found = true;
+                       strcpy(fs->path, *ptr);
+                       return true;
+               }
+               ptr++;
+       }
+
+       return false;
+}
+
+static const char *fs__get_mountpoint(struct fs *fs)
+{
+       if (fs__check_mounts(fs))
+               return fs->path;
+
+       return fs__read_mounts(fs) ? fs->path : NULL;
+}
+
+static const char *fs__mountpoint(int idx)
+{
+       struct fs *fs = &fs__entries[idx];
+
+       if (fs->found)
+               return (const char *)fs->path;
+
+       return fs__get_mountpoint(fs);
+}
+
+#define FS__MOUNTPOINT(name, idx)      \
+const char *name##__mountpoint(void)   \
+{                                      \
+       return fs__mountpoint(idx);     \
+}
+
+FS__MOUNTPOINT(sysfs,  FS__SYSFS);
+FS__MOUNTPOINT(procfs, FS__PROCFS);
diff --git a/tools/perf/util/fs.h b/tools/perf/util/fs.h
new file mode 100644 (file)
index 0000000..5e09ce1
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __PERF_FS
+#define __PERF_FS
+
+const char *sysfs__mountpoint(void);
+const char *procfs__mountpoint(void);
+
+#endif /* __PERF_FS */
index 3ac38031d53400337815560562a52093aaeee9e2..36a885d2cd22d12ed004177f375bcaf4aac86a28 100755 (executable)
@@ -22,7 +22,7 @@ do
      }' "Documentation/perf-$cmd.txt"
 done
 
-echo "#ifdef LIBELF_SUPPORT"
+echo "#ifdef HAVE_LIBELF_SUPPORT"
 sed -n -e 's/^perf-\([^        ]*\)[   ].* full.*/\1/p' command-list.txt |
 sort |
 while read cmd
@@ -35,5 +35,5 @@ do
            p
      }' "Documentation/perf-$cmd.txt"
 done
-echo "#endif /* LIBELF_SUPPORT */"
+echo "#endif /* HAVE_LIBELF_SUPPORT */"
 echo "};"
index c3e5a3b817ab714497dc7f6f39520945dc886b1a..26d9520a0c1b6ebf550bfd001bcd278fa8736d9c 100644 (file)
@@ -22,6 +22,7 @@
 #include "vdso.h"
 #include "strbuf.h"
 #include "build-id.h"
+#include "data.h"
 
 static bool no_buildid_cache = false;
 
@@ -2189,7 +2190,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
 {
        struct header_print_data hd;
        struct perf_header *header = &session->header;
-       int fd = session->fd;
+       int fd = perf_data_file__fd(session->file);
        hd.fp = fp;
        hd.full = full;
 
@@ -2650,7 +2651,8 @@ static int perf_header__read_pipe(struct perf_session *session)
        struct perf_header *header = &session->header;
        struct perf_pipe_file_header f_header;
 
-       if (perf_file_header__read_pipe(&f_header, header, session->fd,
+       if (perf_file_header__read_pipe(&f_header, header,
+                                       perf_data_file__fd(session->file),
                                        session->repipe) < 0) {
                pr_debug("incompatible file format\n");
                return -EINVAL;
@@ -2751,18 +2753,19 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
 
 int perf_session__read_header(struct perf_session *session)
 {
+       struct perf_data_file *file = session->file;
        struct perf_header *header = &session->header;
        struct perf_file_header f_header;
        struct perf_file_attr   f_attr;
        u64                     f_id;
        int nr_attrs, nr_ids, i, j;
-       int fd = session->fd;
+       int fd = perf_data_file__fd(file);
 
        session->evlist = perf_evlist__new();
        if (session->evlist == NULL)
                return -ENOMEM;
 
-       if (session->fd_pipe)
+       if (perf_data_file__is_pipe(file))
                return perf_header__read_pipe(session);
 
        if (perf_file_header__read(&f_header, header, fd) < 0)
@@ -2777,7 +2780,7 @@ int perf_session__read_header(struct perf_session *session)
        if (f_header.data.size == 0) {
                pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
                           "Was the 'perf record' command properly terminated?\n",
-                          session->filename);
+                          file->path);
        }
 
        nr_attrs = f_header.attrs.size / f_header.attr_size;
@@ -2990,18 +2993,19 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused,
                                     struct perf_session *session)
 {
        ssize_t size_read, padding, size = event->tracing_data.size;
-       off_t offset = lseek(session->fd, 0, SEEK_CUR);
+       int fd = perf_data_file__fd(session->file);
+       off_t offset = lseek(fd, 0, SEEK_CUR);
        char buf[BUFSIZ];
 
        /* setup for reading amidst mmap */
-       lseek(session->fd, offset + sizeof(struct tracing_data_event),
+       lseek(fd, offset + sizeof(struct tracing_data_event),
              SEEK_SET);
 
-       size_read = trace_report(session->fd, &session->pevent,
+       size_read = trace_report(fd, &session->pevent,
                                 session->repipe);
        padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
 
-       if (readn(session->fd, buf, padding) < 0) {
+       if (readn(fd, buf, padding) < 0) {
                pr_err("%s: reading input file", __func__);
                return -1;
        }
index 9ff6cf3e9a99f69596b37372f60203c11bec88a3..822903eaa201f3ec81648206eaf3c2f3ae2710c0 100644 (file)
@@ -160,6 +160,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
        hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
        hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
        hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
+
+       if (h->transaction)
+               hists__new_col_len(hists, HISTC_TRANSACTION,
+                                  hist_entry__transaction_len());
 }
 
 void hists__output_recalc_col_len(struct hists *hists, int max_rows)
@@ -346,7 +350,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
        struct rb_node **p;
        struct rb_node *parent = NULL;
        struct hist_entry *he;
-       int cmp;
+       int64_t cmp;
 
        p = &hists->entries_in->rb_node;
 
@@ -395,6 +399,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
        if (!he)
                return NULL;
 
+       hists->nr_entries++;
        rb_link_node(&he->rb_node_in, parent, p);
        rb_insert_color(&he->rb_node_in, hists->entries_in);
 out:
@@ -402,74 +407,16 @@ out:
        return he;
 }
 
-struct hist_entry *__hists__add_mem_entry(struct hists *self,
-                                         struct addr_location *al,
-                                         struct symbol *sym_parent,
-                                         struct mem_info *mi,
-                                         u64 period,
-                                         u64 weight)
-{
-       struct hist_entry entry = {
-               .thread = al->thread,
-               .ms = {
-                       .map    = al->map,
-                       .sym    = al->sym,
-               },
-               .stat = {
-                       .period = period,
-                       .weight = weight,
-                       .nr_events = 1,
-               },
-               .cpu    = al->cpu,
-               .ip     = al->addr,
-               .level  = al->level,
-               .parent = sym_parent,
-               .filtered = symbol__parent_filter(sym_parent),
-               .hists = self,
-               .mem_info = mi,
-               .branch_info = NULL,
-       };
-       return add_hist_entry(self, &entry, al, period, weight);
-}
-
-struct hist_entry *__hists__add_branch_entry(struct hists *self,
-                                            struct addr_location *al,
-                                            struct symbol *sym_parent,
-                                            struct branch_info *bi,
-                                            u64 period,
-                                            u64 weight)
-{
-       struct hist_entry entry = {
-               .thread = al->thread,
-               .ms = {
-                       .map    = bi->to.map,
-                       .sym    = bi->to.sym,
-               },
-               .cpu    = al->cpu,
-               .ip     = bi->to.addr,
-               .level  = al->level,
-               .stat = {
-                       .period = period,
-                       .nr_events = 1,
-                       .weight = weight,
-               },
-               .parent = sym_parent,
-               .filtered = symbol__parent_filter(sym_parent),
-               .branch_info = bi,
-               .hists  = self,
-               .mem_info = NULL,
-       };
-
-       return add_hist_entry(self, &entry, al, period, weight);
-}
-
-struct hist_entry *__hists__add_entry(struct hists *self,
+struct hist_entry *__hists__add_entry(struct hists *hists,
                                      struct addr_location *al,
-                                     struct symbol *sym_parent, u64 period,
-                                     u64 weight)
+                                     struct symbol *sym_parent,
+                                     struct branch_info *bi,
+                                     struct mem_info *mi,
+                                     u64 period, u64 weight, u64 transaction)
 {
        struct hist_entry entry = {
                .thread = al->thread,
+               .comm = thread__comm(al->thread),
                .ms = {
                        .map    = al->map,
                        .sym    = al->sym,
@@ -478,18 +425,19 @@ struct hist_entry *__hists__add_entry(struct hists *self,
                .ip     = al->addr,
                .level  = al->level,
                .stat = {
-                       .period = period,
                        .nr_events = 1,
+                       .period = period,
                        .weight = weight,
                },
                .parent = sym_parent,
                .filtered = symbol__parent_filter(sym_parent),
-               .hists  = self,
-               .branch_info = NULL,
-               .mem_info = NULL,
+               .hists  = hists,
+               .branch_info = bi,
+               .mem_info = mi,
+               .transaction = transaction,
        };
 
-       return add_hist_entry(self, &entry, al, period, weight);
+       return add_hist_entry(hists, &entry, al, period, weight);
 }
 
 int64_t
@@ -530,6 +478,7 @@ void hist_entry__free(struct hist_entry *he)
 {
        free(he->branch_info);
        free(he->mem_info);
+       free_srcline(he->srcline);
        free(he);
 }
 
@@ -598,7 +547,7 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
        hists__filter_entry_by_symbol(hists, he);
 }
 
-void hists__collapse_resort(struct hists *hists)
+void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
 {
        struct rb_root *root;
        struct rb_node *next;
@@ -625,6 +574,8 @@ void hists__collapse_resort(struct hists *hists)
                         */
                        hists__apply_filters(hists, n);
                }
+               if (prog)
+                       ui_progress__update(prog, 1);
        }
 }
 
@@ -884,7 +835,7 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists,
        struct rb_node **p;
        struct rb_node *parent = NULL;
        struct hist_entry *he;
-       int cmp;
+       int64_t cmp;
 
        if (sort__need_collapse)
                root = &hists->entries_collapsed;
index ce8dc61ce2c358ddea5851079916292e6838a370..b621347a1585db4a469b8a08d10acb107406c20f 100644 (file)
@@ -6,6 +6,7 @@
 #include "callchain.h"
 #include "header.h"
 #include "color.h"
+#include "ui/progress.h"
 
 extern struct callchain_param callchain_param;
 
@@ -46,6 +47,8 @@ enum hist_column {
        HISTC_CPU,
        HISTC_SRCLINE,
        HISTC_MISPREDICT,
+       HISTC_IN_TX,
+       HISTC_ABORT,
        HISTC_SYMBOL_FROM,
        HISTC_SYMBOL_TO,
        HISTC_DSO_FROM,
@@ -58,6 +61,7 @@ enum hist_column {
        HISTC_MEM_TLB,
        HISTC_MEM_LVL,
        HISTC_MEM_SNOOP,
+       HISTC_TRANSACTION,
        HISTC_NR_COLS, /* Last entry */
 };
 
@@ -80,54 +84,43 @@ struct hists {
        u16                     col_len[HISTC_NR_COLS];
 };
 
-struct hist_entry *__hists__add_entry(struct hists *self,
+struct hist_entry *__hists__add_entry(struct hists *hists,
                                      struct addr_location *al,
-                                     struct symbol *parent, u64 period,
-                                     u64 weight);
+                                     struct symbol *parent,
+                                     struct branch_info *bi,
+                                     struct mem_info *mi, u64 period,
+                                     u64 weight, u64 transaction);
 int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
 int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
-int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size,
+int hist_entry__transaction_len(void);
+int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
                              struct hists *hists);
 void hist_entry__free(struct hist_entry *);
 
-struct hist_entry *__hists__add_branch_entry(struct hists *self,
-                                            struct addr_location *al,
-                                            struct symbol *sym_parent,
-                                            struct branch_info *bi,
-                                            u64 period,
-                                            u64 weight);
-
-struct hist_entry *__hists__add_mem_entry(struct hists *self,
-                                         struct addr_location *al,
-                                         struct symbol *sym_parent,
-                                         struct mem_info *mi,
-                                         u64 period,
-                                         u64 weight);
-
-void hists__output_resort(struct hists *self);
-void hists__collapse_resort(struct hists *self);
+void hists__output_resort(struct hists *hists);
+void hists__collapse_resort(struct hists *hists, struct ui_progress *prog);
 
 void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
 void hists__output_recalc_col_len(struct hists *hists, int max_rows);
 
 void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h);
-void hists__inc_nr_events(struct hists *self, u32 type);
+void hists__inc_nr_events(struct hists *hists, u32 type);
 void events_stats__inc(struct events_stats *stats, u32 type);
 size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
 
-size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
+size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
                      int max_cols, float min_pcnt, FILE *fp);
 
-int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
-int hist_entry__annotate(struct hist_entry *self, size_t privsize);
+int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
+int hist_entry__annotate(struct hist_entry *he, size_t privsize);
 
 void hists__filter_by_dso(struct hists *hists);
 void hists__filter_by_thread(struct hists *hists);
 void hists__filter_by_symbol(struct hists *hists);
 
-u16 hists__col_len(struct hists *self, enum hist_column col);
-void hists__set_col_len(struct hists *self, enum hist_column col, u16 len);
-bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len);
+u16 hists__col_len(struct hists *hists, enum hist_column col);
+void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len);
+bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len);
 void hists__reset_col_len(struct hists *hists);
 void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
 
@@ -196,7 +189,7 @@ struct hist_browser_timer {
        int refresh;
 };
 
-#ifdef SLANG_SUPPORT
+#ifdef HAVE_SLANG_SUPPORT
 #include "../ui/keysyms.h"
 int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
                             struct hist_browser_timer *hbt);
@@ -217,12 +210,9 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
        return 0;
 }
 
-static inline int hist_entry__tui_annotate(struct hist_entry *self
-                                          __maybe_unused,
-                                          struct perf_evsel *evsel
-                                          __maybe_unused,
-                                          struct hist_browser_timer *hbt
-                                          __maybe_unused)
+static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused,
+                                          struct perf_evsel *evsel __maybe_unused,
+                                          struct hist_browser_timer *hbt __maybe_unused)
 {
        return 0;
 }
@@ -237,20 +227,5 @@ static inline int script_browse(const char *script_opt __maybe_unused)
 #define K_SWITCH_INPUT_DATA -3000
 #endif
 
-#ifdef GTK2_SUPPORT
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
-                                 struct hist_browser_timer *hbt __maybe_unused,
-                                 float min_pcnt);
-#else
-static inline
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
-                                 const char *help __maybe_unused,
-                                 struct hist_browser_timer *hbt __maybe_unused,
-                                 float min_pcnt __maybe_unused)
-{
-       return 0;
-}
-#endif
-
-unsigned int hists__sort_list_width(struct hists *self);
+unsigned int hists__sort_list_width(struct hists *hists);
 #endif /* __PERF_HIST_H */
index cf6727e99c440657b3cd6f29ac05c4f6f38bd89b..8f149655f497302f39b5352cf099fbd71d4d02d7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _PERF_DWARF_REGS_H_
 #define _PERF_DWARF_REGS_H_
 
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
 const char *get_arch_regstr(unsigned int n);
 #endif
 
index 96b919dae11c27bbbae7e14f1c6eb7cb0cd91a89..b003ad7200b230702b133071ab3d402395ab57e6 100644 (file)
@@ -2,20 +2,29 @@
 #define _PERF_LINUX_COMPILER_H_
 
 #ifndef __always_inline
-#define __always_inline        inline
+# define __always_inline       inline __attribute__((always_inline))
 #endif
+
 #define __user
+
 #ifndef __attribute_const__
-#define __attribute_const__
+# define __attribute_const__
 #endif
 
 #ifndef __maybe_unused
-#define __maybe_unused         __attribute__((unused))
+# define __maybe_unused                __attribute__((unused))
+#endif
+
+#ifndef __packed
+# define __packed              __attribute__((__packed__))
 #endif
-#define __packed       __attribute__((__packed__))
 
 #ifndef __force
-#define __force
+# define __force
+#endif
+
+#ifndef __weak
+# define __weak                        __attribute__((weak))
 #endif
 
 #endif
index 58b64ed4da12e442c49e0b3069a1f4a11f83dc8e..07d63cf3e0f6f5d0860c7aa8a8531b49367fd468 100644 (file)
@@ -9,4 +9,8 @@
 #define SYSFS_MAGIC            0x62656572
 #endif
 
+#ifndef PROC_SUPER_MAGIC
+#define PROC_SUPER_MAGIC       0x9fa0
+#endif
+
 #endif
index 11a8d86f7fea3bf4ec5fb8cb05f27dc4c491d948..89715b64a31578e2f26fc98a4e9c778bb72710d5 100644 (file)
@@ -20,6 +20,7 @@ static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
 
        if (node != NULL) {
                node->i = i;
+               node->priv = NULL;
                rc = &node->rb_node;
        }
 
@@ -57,22 +58,36 @@ void intlist__remove(struct intlist *ilist, struct int_node *node)
        rblist__remove_node(&ilist->rblist, &node->rb_node);
 }
 
-struct int_node *intlist__find(struct intlist *ilist, int i)
+static struct int_node *__intlist__findnew(struct intlist *ilist,
+                                          int i, bool create)
 {
-       struct int_node *node;
+       struct int_node *node = NULL;
        struct rb_node *rb_node;
 
        if (ilist == NULL)
                return NULL;
 
-       node = NULL;
-       rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
+       if (create)
+               rb_node = rblist__findnew(&ilist->rblist, (void *)((long)i));
+       else
+               rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
+
        if (rb_node)
                node = container_of(rb_node, struct int_node, rb_node);
 
        return node;
 }
 
+struct int_node *intlist__find(struct intlist *ilist, int i)
+{
+       return __intlist__findnew(ilist, i, false);
+}
+
+struct int_node *intlist__findnew(struct intlist *ilist, int i)
+{
+       return __intlist__findnew(ilist, i, true);
+}
+
 static int intlist__parse_list(struct intlist *ilist, const char *s)
 {
        char *sep;
index 62351dad848f76c478cced833c315cc71ff1ed63..aa6877d36858288c9027d83ab2390b82a2370fc2 100644 (file)
@@ -9,6 +9,7 @@
 struct int_node {
        struct rb_node rb_node;
        int i;
+       void *priv;
 };
 
 struct intlist {
@@ -23,6 +24,7 @@ int intlist__add(struct intlist *ilist, int i);
 
 struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx);
 struct int_node *intlist__find(struct intlist *ilist, int i);
+struct int_node *intlist__findnew(struct intlist *ilist, int i);
 
 static inline bool intlist__has_entry(struct intlist *ilist, int i)
 {
index 6188d2876a7128aaa68e426c3334dfcae099dc41..ce034c183a7ede78535ee8f11d13a18b2fe6617f 100644 (file)
@@ -40,12 +40,29 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
                        return -ENOMEM;
 
                snprintf(comm, sizeof(comm), "[guest/%d]", pid);
-               thread__set_comm(thread, comm);
+               thread__set_comm(thread, comm, 0);
        }
 
        return 0;
 }
 
+struct machine *machine__new_host(void)
+{
+       struct machine *machine = malloc(sizeof(*machine));
+
+       if (machine != NULL) {
+               machine__init(machine, "", HOST_KERNEL_ID);
+
+               if (machine__create_kernel_maps(machine) < 0)
+                       goto out_delete;
+       }
+
+       return machine;
+out_delete:
+       free(machine);
+       return NULL;
+}
+
 static void dsos__delete(struct list_head *dsos)
 {
        struct dso *pos, *n;
@@ -314,7 +331,8 @@ struct thread *machine__find_thread(struct machine *machine, pid_t tid)
        return __machine__findnew_thread(machine, 0, tid, false);
 }
 
-int machine__process_comm_event(struct machine *machine, union perf_event *event)
+int machine__process_comm_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample)
 {
        struct thread *thread = machine__findnew_thread(machine,
                                                        event->comm.pid,
@@ -323,7 +341,7 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
        if (dump_trace)
                perf_event__fprintf_comm(event, stdout);
 
-       if (thread == NULL || thread__set_comm(thread, event->comm.comm)) {
+       if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
                dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
                return -1;
        }
@@ -332,7 +350,7 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
 }
 
 int machine__process_lost_event(struct machine *machine __maybe_unused,
-                               union perf_event *event)
+                               union perf_event *event, struct perf_sample *sample __maybe_unused)
 {
        dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
                    event->lost.id, event->lost.lost);
@@ -776,75 +794,44 @@ static int machine__set_modules_path(struct machine *machine)
        return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
 }
 
-static int machine__create_modules(struct machine *machine)
+static int machine__create_module(void *arg, const char *name, u64 start)
 {
-       char *line = NULL;
-       size_t n;
-       FILE *file;
+       struct machine *machine = arg;
        struct map *map;
+
+       map = machine__new_module(machine, start, name);
+       if (map == NULL)
+               return -1;
+
+       dso__kernel_module_get_build_id(map->dso, machine->root_dir);
+
+       return 0;
+}
+
+static int machine__create_modules(struct machine *machine)
+{
        const char *modules;
        char path[PATH_MAX];
 
-       if (machine__is_default_guest(machine))
+       if (machine__is_default_guest(machine)) {
                modules = symbol_conf.default_guest_modules;
-       else {
-               sprintf(path, "%s/proc/modules", machine->root_dir);
+       else {
+               snprintf(path, PATH_MAX, "%s/proc/modules", machine->root_dir);
                modules = path;
        }
 
        if (symbol__restricted_filename(modules, "/proc/modules"))
                return -1;
 
-       file = fopen(modules, "r");
-       if (file == NULL)
+       if (modules__parse(modules, machine, machine__create_module))
                return -1;
 
-       while (!feof(file)) {
-               char name[PATH_MAX];
-               u64 start;
-               char *sep;
-               int line_len;
-
-               line_len = getline(&line, &n, file);
-               if (line_len < 0)
-                       break;
-
-               if (!line)
-                       goto out_failure;
-
-               line[--line_len] = '\0'; /* \n */
-
-               sep = strrchr(line, 'x');
-               if (sep == NULL)
-                       continue;
-
-               hex2u64(sep + 1, &start);
-
-               sep = strchr(line, ' ');
-               if (sep == NULL)
-                       continue;
-
-               *sep = '\0';
-
-               snprintf(name, sizeof(name), "[%s]", line);
-               map = machine__new_module(machine, start, name);
-               if (map == NULL)
-                       goto out_delete_line;
-               dso__kernel_module_get_build_id(map->dso, machine->root_dir);
-       }
+       if (!machine__set_modules_path(machine))
+               return 0;
 
-       free(line);
-       fclose(file);
+       pr_debug("Problems setting modules path maps, continuing anyway...\n");
 
-       if (machine__set_modules_path(machine) < 0) {
-               pr_debug("Problems setting modules path maps, continuing anyway...\n");
-       }
        return 0;
-
-out_delete_line:
-       free(line);
-out_failure:
-       return -1;
 }
 
 int machine__create_kernel_maps(struct machine *machine)
@@ -998,7 +985,8 @@ out_problem:
 }
 
 int machine__process_mmap2_event(struct machine *machine,
-                                union perf_event *event)
+                                union perf_event *event,
+                                struct perf_sample *sample __maybe_unused)
 {
        u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
        struct thread *thread;
@@ -1045,7 +1033,8 @@ out_problem:
        return 0;
 }
 
-int machine__process_mmap_event(struct machine *machine, union perf_event *event)
+int machine__process_mmap_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample __maybe_unused)
 {
        u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
        struct thread *thread;
@@ -1102,7 +1091,8 @@ static void machine__remove_thread(struct machine *machine, struct thread *th)
        list_add_tail(&th->node, &machine->dead_threads);
 }
 
-int machine__process_fork_event(struct machine *machine, union perf_event *event)
+int machine__process_fork_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample)
 {
        struct thread *thread = machine__find_thread(machine, event->fork.tid);
        struct thread *parent = machine__findnew_thread(machine,
@@ -1119,7 +1109,7 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
                perf_event__fprintf_task(event, stdout);
 
        if (thread == NULL || parent == NULL ||
-           thread__fork(thread, parent) < 0) {
+           thread__fork(thread, parent, sample->time) < 0) {
                dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
                return -1;
        }
@@ -1127,8 +1117,8 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
        return 0;
 }
 
-int machine__process_exit_event(struct machine *machine __maybe_unused,
-                               union perf_event *event)
+int machine__process_exit_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample __maybe_unused)
 {
        struct thread *thread = machine__find_thread(machine, event->fork.tid);
 
@@ -1141,23 +1131,24 @@ int machine__process_exit_event(struct machine *machine __maybe_unused,
        return 0;
 }
 
-int machine__process_event(struct machine *machine, union perf_event *event)
+int machine__process_event(struct machine *machine, union perf_event *event,
+                          struct perf_sample *sample)
 {
        int ret;
 
        switch (event->header.type) {
        case PERF_RECORD_COMM:
-               ret = machine__process_comm_event(machine, event); break;
+               ret = machine__process_comm_event(machine, event, sample); break;
        case PERF_RECORD_MMAP:
-               ret = machine__process_mmap_event(machine, event); break;
+               ret = machine__process_mmap_event(machine, event, sample); break;
        case PERF_RECORD_MMAP2:
-               ret = machine__process_mmap2_event(machine, event); break;
+               ret = machine__process_mmap2_event(machine, event, sample); break;
        case PERF_RECORD_FORK:
-               ret = machine__process_fork_event(machine, event); break;
+               ret = machine__process_fork_event(machine, event, sample); break;
        case PERF_RECORD_EXIT:
-               ret = machine__process_exit_event(machine, event); break;
+               ret = machine__process_exit_event(machine, event, sample); break;
        case PERF_RECORD_LOST:
-               ret = machine__process_lost_event(machine, event); break;
+               ret = machine__process_lost_event(machine, event, sample); break;
        default:
                ret = -1;
                break;
@@ -1267,10 +1258,12 @@ static int machine__resolve_callchain_sample(struct machine *machine,
                                             struct thread *thread,
                                             struct ip_callchain *chain,
                                             struct symbol **parent,
-                                            struct addr_location *root_al)
+                                            struct addr_location *root_al,
+                                            int max_stack)
 {
        u8 cpumode = PERF_RECORD_MISC_USER;
-       unsigned int i;
+       int chain_nr = min(max_stack, (int)chain->nr);
+       int i;
        int err;
 
        callchain_cursor_reset(&callchain_cursor);
@@ -1280,7 +1273,7 @@ static int machine__resolve_callchain_sample(struct machine *machine,
                return 0;
        }
 
-       for (i = 0; i < chain->nr; i++) {
+       for (i = 0; i < chain_nr; i++) {
                u64 ip;
                struct addr_location al;
 
@@ -1352,12 +1345,14 @@ int machine__resolve_callchain(struct machine *machine,
                               struct thread *thread,
                               struct perf_sample *sample,
                               struct symbol **parent,
-                              struct addr_location *root_al)
+                              struct addr_location *root_al,
+                              int max_stack)
 {
        int ret;
 
        ret = machine__resolve_callchain_sample(machine, thread,
-                                               sample->callchain, parent, root_al);
+                                               sample->callchain, parent,
+                                               root_al, max_stack);
        if (ret)
                return ret;
 
@@ -1376,3 +1371,26 @@ int machine__resolve_callchain(struct machine *machine,
                                   sample);
 
 }
+
+int machine__for_each_thread(struct machine *machine,
+                            int (*fn)(struct thread *thread, void *p),
+                            void *priv)
+{
+       struct rb_node *nd;
+       struct thread *thread;
+       int rc = 0;
+
+       for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
+               thread = rb_entry(nd, struct thread, rb_node);
+               rc = fn(thread, priv);
+               if (rc != 0)
+                       return rc;
+       }
+
+       list_for_each_entry(thread, &machine->dead_threads, node) {
+               rc = fn(thread, priv);
+               if (rc != 0)
+                       return rc;
+       }
+       return rc;
+}
index 58a6be1fc739ba8e543ebd7d1bb6ea5185991703..2389ba81fafedf018be283e6aea14295d610613e 100644 (file)
@@ -40,13 +40,20 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)
 
 struct thread *machine__find_thread(struct machine *machine, pid_t tid);
 
-int machine__process_comm_event(struct machine *machine, union perf_event *event);
-int machine__process_exit_event(struct machine *machine, union perf_event *event);
-int machine__process_fork_event(struct machine *machine, union perf_event *event);
-int machine__process_lost_event(struct machine *machine, union perf_event *event);
-int machine__process_mmap_event(struct machine *machine, union perf_event *event);
-int machine__process_mmap2_event(struct machine *machine, union perf_event *event);
-int machine__process_event(struct machine *machine, union perf_event *event);
+int machine__process_comm_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample);
+int machine__process_exit_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample);
+int machine__process_fork_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample);
+int machine__process_lost_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample);
+int machine__process_mmap_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample);
+int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
+                                struct perf_sample *sample);
+int machine__process_event(struct machine *machine, union perf_event *event,
+                               struct perf_sample *sample);
 
 typedef void (*machine__process_t)(struct machine *machine, void *data);
 
@@ -74,6 +81,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
 void machines__set_symbol_filter(struct machines *machines,
                                 symbol_filter_t symbol_filter);
 
+struct machine *machine__new_host(void);
 int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
 void machine__exit(struct machine *machine);
 void machine__delete_dead_threads(struct machine *machine);
@@ -91,7 +99,8 @@ int machine__resolve_callchain(struct machine *machine,
                               struct thread *thread,
                               struct perf_sample *sample,
                               struct symbol **parent,
-                              struct addr_location *root_al);
+                              struct addr_location *root_al,
+                              int max_stack);
 
 /*
  * Default guest kernel is defined by parameter --guestkallsyms
@@ -165,4 +174,8 @@ void machines__destroy_kernel_maps(struct machines *machines);
 
 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
 
+int machine__for_each_thread(struct machine *machine,
+                            int (*fn)(struct thread *thread, void *p),
+                            void *priv);
+
 #endif /* __PERF_MACHINE_H */
index 4f6680d2043b1e68ef7b9dfbc63a37326fcc6f22..ef5bc913ca7a9fdda7946401e55f9b0295dddfb6 100644 (file)
@@ -172,7 +172,7 @@ int map__load(struct map *map, symbol_filter_t filter)
                pr_warning(", continuing without symbols\n");
                return -1;
        } else if (nr == 0) {
-#ifdef LIBELF_SUPPORT
+#ifdef HAVE_LIBELF_SUPPORT
                const size_t len = strlen(name);
                const size_t real_len = len - sizeof(DSO__DELETED);
 
@@ -252,10 +252,16 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
        return fprintf(fp, "%s", dsoname);
 }
 
-/*
+/**
+ * map__rip_2objdump - convert symbol start address to objdump address.
+ * @map: memory map
+ * @rip: symbol start address
+ *
  * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
  * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
  * relative to section start.
+ *
+ * Return: Address suitable for passing to "objdump --start-address="
  */
 u64 map__rip_2objdump(struct map *map, u64 rip)
 {
@@ -268,6 +274,29 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
        return map->unmap_ip(map, rip);
 }
 
+/**
+ * map__objdump_2mem - convert objdump address to a memory address.
+ * @map: memory map
+ * @ip: objdump address
+ *
+ * Closely related to map__rip_2objdump(), this function takes an address from
+ * objdump and converts it to a memory address.  Note this assumes that @map
+ * contains the address.  To be sure the result is valid, check it forwards
+ * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
+ *
+ * Return: Memory address.
+ */
+u64 map__objdump_2mem(struct map *map, u64 ip)
+{
+       if (!map->dso->adjust_symbols)
+               return map->unmap_ip(map, ip);
+
+       if (map->dso->rel)
+               return map->unmap_ip(map, ip + map->pgoff);
+
+       return ip;
+}
+
 void map_groups__init(struct map_groups *mg)
 {
        int i;
@@ -371,6 +400,23 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
        return NULL;
 }
 
+int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
+{
+       if (ams->addr < ams->map->start || ams->addr > ams->map->end) {
+               if (ams->map->groups == NULL)
+                       return -1;
+               ams->map = map_groups__find(ams->map->groups, ams->map->type,
+                                           ams->addr);
+               if (ams->map == NULL)
+                       return -1;
+       }
+
+       ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
+       ams->sym = map__find_symbol(ams->map, ams->al_addr, filter);
+
+       return ams->sym ? 0 : -1;
+}
+
 size_t __map_groups__fprintf_maps(struct map_groups *mg,
                                  enum map_type type, int verbose, FILE *fp)
 {
index 4886ca2805361df87a57c9f4406ed5c38fe418b5..e4e259c3ba167d77836e67d85c63e6d110f61550 100644 (file)
@@ -84,6 +84,9 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
 /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
 u64 map__rip_2objdump(struct map *map, u64 rip);
 
+/* objdump address -> memory address */
+u64 map__objdump_2mem(struct map *map, u64 ip);
+
 struct symbol;
 
 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
@@ -167,6 +170,10 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
                                               struct map **mapp,
                                               symbol_filter_t filter);
 
+struct addr_map_symbol;
+
+int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter);
+
 static inline
 struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
                                                 const char *name, struct map **mapp,
index 98125319b158b7e6e588ba4adf861494b69e18d6..c90e55cf7e82ebc134fb827ca68f45385138f161 100644 (file)
@@ -998,8 +998,10 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
        char evt_path[MAXPATHLEN];
        char dir_path[MAXPATHLEN];
 
-       if (debugfs_valid_mountpoint(tracing_events_path))
+       if (debugfs_valid_mountpoint(tracing_events_path)) {
+               printf("  [ Tracepoints not available: %s ]\n", strerror(errno));
                return;
+       }
 
        sys_dir = opendir(tracing_events_path);
        if (!sys_dir)
index 91346b7539607fb9e3b6dcb8f944af36f9e88572..343299575b303fb5443b99288fd487aab26e3915 100644 (file)
@@ -126,6 +126,37 @@ modifier_bp        [rwx]{1,3}
 
 }
 
+<config>{
+config                 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
+config1                        { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
+config2                        { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
+name                   { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
+period                 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
+branch_type            { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
+,                      { return ','; }
+"/"                    { BEGIN(INITIAL); return '/'; }
+{name_minus}           { return str(yyscanner, PE_NAME); }
+}
+
+<mem>{
+{modifier_bp}          { return str(yyscanner, PE_MODIFIER_BP); }
+:                      { return ':'; }
+{num_dec}              { return value(yyscanner, 10); }
+{num_hex}              { return value(yyscanner, 16); }
+       /*
+        * We need to separate 'mem:' scanner part, in order to get specific
+        * modifier bits parsed out. Otherwise we would need to handle PE_NAME
+        * and we'd need to parse it manually. During the escape from <mem>
+        * state we need to put the escaping char back, so we dont miss it.
+        */
+.                      { unput(*yytext); BEGIN(INITIAL); }
+       /*
+        * We destroy the scanner after reaching EOF,
+        * but anyway just to be sure get back to INIT state.
+        */
+<<EOF>>                        { BEGIN(INITIAL); }
+}
+
 cpu-cycles|cycles                              { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
 stalled-cycles-frontend|idle-cycles-frontend   { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
 stalled-cycles-backend|idle-cycles-backend     { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
@@ -162,18 +193,6 @@ speculative-read|speculative-load  |
 refs|Reference|ops|access              |
 misses|miss                            { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
 
-<config>{
-config                 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
-config1                        { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
-config2                        { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
-name                   { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
-period                 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
-branch_type            { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
-,                      { return ','; }
-"/"                    { BEGIN(INITIAL); return '/'; }
-{name_minus}           { return str(yyscanner, PE_NAME); }
-}
-
 mem:                   { BEGIN(mem); return PE_PREFIX_MEM; }
 r{num_raw_hex}         { return raw(yyscanner); }
 {num_dec}              { return value(yyscanner, 10); }
@@ -189,25 +208,7 @@ r{num_raw_hex}             { return raw(yyscanner); }
 "}"                    { return '}'; }
 =                      { return '='; }
 \n                     { }
-
-<mem>{
-{modifier_bp}          { return str(yyscanner, PE_MODIFIER_BP); }
-:                      { return ':'; }
-{num_dec}              { return value(yyscanner, 10); }
-{num_hex}              { return value(yyscanner, 16); }
-       /*
-        * We need to separate 'mem:' scanner part, in order to get specific
-        * modifier bits parsed out. Otherwise we would need to handle PE_NAME
-        * and we'd need to parse it manually. During the escape from <mem>
-        * state we need to put the escaping char back, so we dont miss it.
-        */
-.                      { unput(*yytext); BEGIN(INITIAL); }
-       /*
-        * We destroy the scanner after reaching EOF,
-        * but anyway just to be sure get back to INIT state.
-        */
-<<EOF>>                        { BEGIN(INITIAL); }
-}
+.                      { }
 
 %%
 
index 2bc9e70df7e2552ecc14857d1f26c2311bb2fde7..31f404a032a90499e5d366123f3185972edf3b49 100644 (file)
@@ -339,10 +339,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                if (arg[1] != '-') {
                        ctx->opt = arg + 1;
                        if (internal_help && *ctx->opt == 'h')
-                               return parse_options_usage(usagestr, options);
+                               return usage_with_options_internal(usagestr, options, 0);
                        switch (parse_short_opt(ctx, options)) {
                        case -1:
-                               return parse_options_usage(usagestr, options);
+                               return parse_options_usage(usagestr, options, arg + 1, 1);
                        case -2:
                                goto unknown;
                        default:
@@ -352,10 +352,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                                check_typos(arg + 1, options);
                        while (ctx->opt) {
                                if (internal_help && *ctx->opt == 'h')
-                                       return parse_options_usage(usagestr, options);
+                                       return usage_with_options_internal(usagestr, options, 0);
+                               arg = ctx->opt;
                                switch (parse_short_opt(ctx, options)) {
                                case -1:
-                                       return parse_options_usage(usagestr, options);
+                                       return parse_options_usage(usagestr, options, arg, 1);
                                case -2:
                                        /* fake a short option thing to hide the fact that we may have
                                         * started to parse aggregated stuff
@@ -383,12 +384,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                if (internal_help && !strcmp(arg + 2, "help-all"))
                        return usage_with_options_internal(usagestr, options, 1);
                if (internal_help && !strcmp(arg + 2, "help"))
-                       return parse_options_usage(usagestr, options);
+                       return usage_with_options_internal(usagestr, options, 0);
                if (!strcmp(arg + 2, "list-opts"))
                        return PARSE_OPT_LIST;
                switch (parse_long_opt(ctx, arg + 2, options)) {
                case -1:
-                       return parse_options_usage(usagestr, options);
+                       return parse_options_usage(usagestr, options, arg + 2, 0);
                case -2:
                        goto unknown;
                default:
@@ -445,6 +446,89 @@ int parse_options(int argc, const char **argv, const struct option *options,
 #define USAGE_OPTS_WIDTH 24
 #define USAGE_GAP         2
 
+static void print_option_help(const struct option *opts, int full)
+{
+       size_t pos;
+       int pad;
+
+       if (opts->type == OPTION_GROUP) {
+               fputc('\n', stderr);
+               if (*opts->help)
+                       fprintf(stderr, "%s\n", opts->help);
+               return;
+       }
+       if (!full && (opts->flags & PARSE_OPT_HIDDEN))
+               return;
+
+       pos = fprintf(stderr, "    ");
+       if (opts->short_name)
+               pos += fprintf(stderr, "-%c", opts->short_name);
+       else
+               pos += fprintf(stderr, "    ");
+
+       if (opts->long_name && opts->short_name)
+               pos += fprintf(stderr, ", ");
+       if (opts->long_name)
+               pos += fprintf(stderr, "--%s", opts->long_name);
+
+       switch (opts->type) {
+       case OPTION_ARGUMENT:
+               break;
+       case OPTION_LONG:
+       case OPTION_U64:
+       case OPTION_INTEGER:
+       case OPTION_UINTEGER:
+               if (opts->flags & PARSE_OPT_OPTARG)
+                       if (opts->long_name)
+                               pos += fprintf(stderr, "[=<n>]");
+                       else
+                               pos += fprintf(stderr, "[<n>]");
+               else
+                       pos += fprintf(stderr, " <n>");
+               break;
+       case OPTION_CALLBACK:
+               if (opts->flags & PARSE_OPT_NOARG)
+                       break;
+               /* FALLTHROUGH */
+       case OPTION_STRING:
+               if (opts->argh) {
+                       if (opts->flags & PARSE_OPT_OPTARG)
+                               if (opts->long_name)
+                                       pos += fprintf(stderr, "[=<%s>]", opts->argh);
+                               else
+                                       pos += fprintf(stderr, "[<%s>]", opts->argh);
+                       else
+                               pos += fprintf(stderr, " <%s>", opts->argh);
+               } else {
+                       if (opts->flags & PARSE_OPT_OPTARG)
+                               if (opts->long_name)
+                                       pos += fprintf(stderr, "[=...]");
+                               else
+                                       pos += fprintf(stderr, "[...]");
+                       else
+                               pos += fprintf(stderr, " ...");
+               }
+               break;
+       default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
+       case OPTION_END:
+       case OPTION_GROUP:
+       case OPTION_BIT:
+       case OPTION_BOOLEAN:
+       case OPTION_INCR:
+       case OPTION_SET_UINT:
+       case OPTION_SET_PTR:
+               break;
+       }
+
+       if (pos <= USAGE_OPTS_WIDTH)
+               pad = USAGE_OPTS_WIDTH - pos;
+       else {
+               fputc('\n', stderr);
+               pad = USAGE_OPTS_WIDTH;
+       }
+       fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
+}
+
 int usage_with_options_internal(const char * const *usagestr,
                                const struct option *opts, int full)
 {
@@ -464,87 +548,9 @@ int usage_with_options_internal(const char * const *usagestr,
        if (opts->type != OPTION_GROUP)
                fputc('\n', stderr);
 
-       for (; opts->type != OPTION_END; opts++) {
-               size_t pos;
-               int pad;
-
-               if (opts->type == OPTION_GROUP) {
-                       fputc('\n', stderr);
-                       if (*opts->help)
-                               fprintf(stderr, "%s\n", opts->help);
-                       continue;
-               }
-               if (!full && (opts->flags & PARSE_OPT_HIDDEN))
-                       continue;
-
-               pos = fprintf(stderr, "    ");
-               if (opts->short_name)
-                       pos += fprintf(stderr, "-%c", opts->short_name);
-               else
-                       pos += fprintf(stderr, "    ");
-
-               if (opts->long_name && opts->short_name)
-                       pos += fprintf(stderr, ", ");
-               if (opts->long_name)
-                       pos += fprintf(stderr, "--%s", opts->long_name);
-
-               switch (opts->type) {
-               case OPTION_ARGUMENT:
-                       break;
-               case OPTION_LONG:
-               case OPTION_U64:
-               case OPTION_INTEGER:
-               case OPTION_UINTEGER:
-                       if (opts->flags & PARSE_OPT_OPTARG)
-                               if (opts->long_name)
-                                       pos += fprintf(stderr, "[=<n>]");
-                               else
-                                       pos += fprintf(stderr, "[<n>]");
-                       else
-                               pos += fprintf(stderr, " <n>");
-                       break;
-               case OPTION_CALLBACK:
-                       if (opts->flags & PARSE_OPT_NOARG)
-                               break;
-                       /* FALLTHROUGH */
-               case OPTION_STRING:
-                       if (opts->argh) {
-                               if (opts->flags & PARSE_OPT_OPTARG)
-                                       if (opts->long_name)
-                                               pos += fprintf(stderr, "[=<%s>]", opts->argh);
-                                       else
-                                               pos += fprintf(stderr, "[<%s>]", opts->argh);
-                               else
-                                       pos += fprintf(stderr, " <%s>", opts->argh);
-                       } else {
-                               if (opts->flags & PARSE_OPT_OPTARG)
-                                       if (opts->long_name)
-                                               pos += fprintf(stderr, "[=...]");
-                                       else
-                                               pos += fprintf(stderr, "[...]");
-                               else
-                                       pos += fprintf(stderr, " ...");
-                       }
-                       break;
-               default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
-               case OPTION_END:
-               case OPTION_GROUP:
-               case OPTION_BIT:
-               case OPTION_BOOLEAN:
-               case OPTION_INCR:
-               case OPTION_SET_UINT:
-               case OPTION_SET_PTR:
-                       break;
-               }
+       for (  ; opts->type != OPTION_END; opts++)
+               print_option_help(opts, full);
 
-               if (pos <= USAGE_OPTS_WIDTH)
-                       pad = USAGE_OPTS_WIDTH - pos;
-               else {
-                       fputc('\n', stderr);
-                       pad = USAGE_OPTS_WIDTH;
-               }
-               fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
-       }
        fputc('\n', stderr);
 
        return PARSE_OPT_HELP;
@@ -559,9 +565,45 @@ void usage_with_options(const char * const *usagestr,
 }
 
 int parse_options_usage(const char * const *usagestr,
-                       const struct option *opts)
+                       const struct option *opts,
+                       const char *optstr, bool short_opt)
 {
-       return usage_with_options_internal(usagestr, opts, 0);
+       if (!usagestr)
+               goto opt;
+
+       fprintf(stderr, "\n usage: %s\n", *usagestr++);
+       while (*usagestr && **usagestr)
+               fprintf(stderr, "    or: %s\n", *usagestr++);
+       while (*usagestr) {
+               fprintf(stderr, "%s%s\n",
+                               **usagestr ? "    " : "",
+                               *usagestr);
+               usagestr++;
+       }
+       fputc('\n', stderr);
+
+opt:
+       for (  ; opts->type != OPTION_END; opts++) {
+               if (short_opt) {
+                       if (opts->short_name == *optstr)
+                               break;
+                       continue;
+               }
+
+               if (opts->long_name == NULL)
+                       continue;
+
+               if (!prefixcmp(optstr, opts->long_name))
+                       break;
+               if (!prefixcmp(optstr, "no-") &&
+                   !prefixcmp(optstr + 3, opts->long_name))
+                       break;
+       }
+
+       if (opts->type != OPTION_END)
+               print_option_help(opts, 0);
+
+       return PARSE_OPT_HELP;
 }
 
 
index 7bb5999940ca925f60482bbfa10aea1a6e685b10..b0241e28eaf7dd7b81469e22416e8f1e16e26c63 100644 (file)
@@ -158,7 +158,9 @@ struct parse_opt_ctx_t {
 };
 
 extern int parse_options_usage(const char * const *usagestr,
-                              const struct option *opts);
+                              const struct option *opts,
+                              const char *optstr,
+                              bool short_opt);
 
 extern void parse_options_start(struct parse_opt_ctx_t *ctx,
                                int argc, const char **argv, int flags);
index a8c49548ca48f5bc4f7ae14134ee57d7779b46e8..5d13cb45b3171a98a171b0f7228d1fff470bf8c0 100644 (file)
@@ -22,19 +22,23 @@ static const char *get_perf_dir(void)
        return ".";
 }
 
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dest, const char *src, size_t size)
+/*
+ * If libc has strlcpy() then that version will override this
+ * implementation:
+ */
+size_t __weak strlcpy(char *dest, const char *src, size_t size)
 {
        size_t ret = strlen(src);
 
        if (size) {
                size_t len = (ret >= size) ? size - 1 : ret;
+
                memcpy(dest, src, len);
                dest[len] = '\0';
        }
+
        return ret;
 }
-#endif
 
 static char *get_pathname(void)
 {
index 5a4f2b6f3738c1966b180484dcfb71f70d0e0afd..a3d42cd749196b83c4c8226bfd069a68cd3a6917 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __PERF_REGS_H
 #define __PERF_REGS_H
 
-#ifdef HAVE_PERF_REGS
+#ifdef HAVE_PERF_REGS_SUPPORT
 #include <perf_regs.h>
 #else
 #define PERF_REGS_MASK 0
@@ -10,5 +10,5 @@ static inline const char *perf_reg_name(int id __maybe_unused)
 {
        return NULL;
 }
-#endif /* HAVE_PERF_REGS */
+#endif /* HAVE_PERF_REGS_SUPPORT */
 #endif /* __PERF_REGS_H */
index bc9d8069d37637835758d02e13ec3bc751d0f5e3..c232d8dd410bf6483ba8fcd850380bbd562f03ee 100644 (file)
@@ -4,7 +4,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <dirent.h>
-#include "sysfs.h"
+#include "fs.h"
 #include "util.h"
 #include "pmu.h"
 #include "parse-events.h"
@@ -77,9 +77,8 @@ static int pmu_format(const char *name, struct list_head *format)
 {
        struct stat st;
        char path[PATH_MAX];
-       const char *sysfs;
+       const char *sysfs = sysfs__mountpoint();
 
-       sysfs = sysfs_find_mountpoint();
        if (!sysfs)
                return -1;
 
@@ -166,9 +165,8 @@ static int pmu_aliases(const char *name, struct list_head *head)
 {
        struct stat st;
        char path[PATH_MAX];
-       const char *sysfs;
+       const char *sysfs = sysfs__mountpoint();
 
-       sysfs = sysfs_find_mountpoint();
        if (!sysfs)
                return -1;
 
@@ -212,11 +210,10 @@ static int pmu_type(const char *name, __u32 *type)
 {
        struct stat st;
        char path[PATH_MAX];
-       const char *sysfs;
        FILE *file;
        int ret = 0;
+       const char *sysfs = sysfs__mountpoint();
 
-       sysfs = sysfs_find_mountpoint();
        if (!sysfs)
                return -1;
 
@@ -241,11 +238,10 @@ static int pmu_type(const char *name, __u32 *type)
 static void pmu_read_sysfs(void)
 {
        char path[PATH_MAX];
-       const char *sysfs;
        DIR *dir;
        struct dirent *dent;
+       const char *sysfs = sysfs__mountpoint();
 
-       sysfs = sysfs_find_mountpoint();
        if (!sysfs)
                return;
 
@@ -270,11 +266,10 @@ static struct cpu_map *pmu_cpumask(const char *name)
 {
        struct stat st;
        char path[PATH_MAX];
-       const char *sysfs;
        FILE *file;
        struct cpu_map *cpus;
+       const char *sysfs = sysfs__mountpoint();
 
-       sysfs = sysfs_find_mountpoint();
        if (!sysfs)
                return NULL;
 
@@ -637,3 +632,19 @@ void print_pmu_events(const char *event_glob, bool name_only)
                printf("\n");
        free(aliases);
 }
+
+bool pmu_have_event(const char *pname, const char *name)
+{
+       struct perf_pmu *pmu;
+       struct perf_pmu_alias *alias;
+
+       pmu = NULL;
+       while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+               if (strcmp(pname, pmu->name))
+                       continue;
+               list_for_each_entry(alias, &pmu->aliases, list)
+                       if (!strcmp(alias->name, name))
+                               return true;
+       }
+       return false;
+}
index 6b2cbe2d4cc3a6d59a3d692770793c19ea984930..1179b26f244a31280e5454787a51a8f01ff9ac2e 100644 (file)
@@ -42,6 +42,7 @@ int perf_pmu__format_parse(char *dir, struct list_head *head);
 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
 
 void print_pmu_events(const char *event_glob, bool name_only);
+bool pmu_have_event(const char *pname, const char *name);
 
 int perf_pmu__test(void);
 #endif /* __PMU_H */
index aa04bf9c9ad791a00faf7546cf75163a0dabd60a..9c6989ca2bea0242edcfed3f75803dd4e923068d 100644 (file)
@@ -47,7 +47,6 @@
 #include "session.h"
 
 #define MAX_CMDLEN 256
-#define MAX_PROBE_ARGS 128
 #define PERFPROBE_GROUP "probe"
 
 bool probe_event_dry_run;      /* Dry run flag */
@@ -201,7 +200,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
        return 0;
 }
 
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
 /* Open new debuginfo of given module */
 static struct debuginfo *open_debuginfo(const char *module)
 {
@@ -630,7 +629,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
        return ret;
 }
 
-#else  /* !DWARF_SUPPORT */
+#else  /* !HAVE_DWARF_SUPPORT */
 
 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
                                        struct perf_probe_point *pp)
index f0692737ebf1237373a140c0ec76a7a4a7a96f9d..ffb657ffd327b1779b328f4546f4d45c0784e243 100644 (file)
@@ -115,7 +115,7 @@ static const Dwfl_Callbacks offline_callbacks = {
 };
 
 /* Get a Dwarf from offline image */
-static int debuginfo__init_offline_dwarf(struct debuginfo *self,
+static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
                                         const char *path)
 {
        int fd;
@@ -124,25 +124,25 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self,
        if (fd < 0)
                return fd;
 
-       self->dwfl = dwfl_begin(&offline_callbacks);
-       if (!self->dwfl)
+       dbg->dwfl = dwfl_begin(&offline_callbacks);
+       if (!dbg->dwfl)
                goto error;
 
-       self->mod = dwfl_report_offline(self->dwfl, "", "", fd);
-       if (!self->mod)
+       dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
+       if (!dbg->mod)
                goto error;
 
-       self->dbg = dwfl_module_getdwarf(self->mod, &self->bias);
-       if (!self->dbg)
+       dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
+       if (!dbg->dbg)
                goto error;
 
        return 0;
 error:
-       if (self->dwfl)
-               dwfl_end(self->dwfl);
+       if (dbg->dwfl)
+               dwfl_end(dbg->dwfl);
        else
                close(fd);
-       memset(self, 0, sizeof(*self));
+       memset(dbg, 0, sizeof(*dbg));
 
        return -ENOENT;
 }
@@ -180,24 +180,24 @@ static const Dwfl_Callbacks kernel_callbacks = {
 };
 
 /* Get a Dwarf from live kernel image */
-static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
+static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
                                               Dwarf_Addr addr)
 {
-       self->dwfl = dwfl_begin(&kernel_callbacks);
-       if (!self->dwfl)
+       dbg->dwfl = dwfl_begin(&kernel_callbacks);
+       if (!dbg->dwfl)
                return -EINVAL;
 
        /* Load the kernel dwarves: Don't care the result here */
-       dwfl_linux_kernel_report_kernel(self->dwfl);
-       dwfl_linux_kernel_report_modules(self->dwfl);
+       dwfl_linux_kernel_report_kernel(dbg->dwfl);
+       dwfl_linux_kernel_report_modules(dbg->dwfl);
 
-       self->dbg = dwfl_addrdwarf(self->dwfl, addr, &self->bias);
+       dbg->dbg = dwfl_addrdwarf(dbg->dwfl, addr, &dbg->bias);
        /* Here, check whether we could get a real dwarf */
-       if (!self->dbg) {
+       if (!dbg->dbg) {
                pr_debug("Failed to find kernel dwarf at %lx\n",
                         (unsigned long)addr);
-               dwfl_end(self->dwfl);
-               memset(self, 0, sizeof(*self));
+               dwfl_end(dbg->dwfl);
+               memset(dbg, 0, sizeof(*dbg));
                return -ENOENT;
        }
 
@@ -205,7 +205,7 @@ static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
 }
 #else
 /* With older elfutils, this just support kernel module... */
-static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
+static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
                                               Dwarf_Addr addr __maybe_unused)
 {
        const char *path = kernel_get_module_path("kernel");
@@ -216,44 +216,45 @@ static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
        }
 
        pr_debug2("Use file %s for debuginfo\n", path);
-       return debuginfo__init_offline_dwarf(self, path);
+       return debuginfo__init_offline_dwarf(dbg, path);
 }
 #endif
 
 struct debuginfo *debuginfo__new(const char *path)
 {
-       struct debuginfo *self = zalloc(sizeof(struct debuginfo));
-       if (!self)
+       struct debuginfo *dbg = zalloc(sizeof(*dbg));
+       if (!dbg)
                return NULL;
 
-       if (debuginfo__init_offline_dwarf(self, path) < 0) {
-               free(self);
-               self = NULL;
+       if (debuginfo__init_offline_dwarf(dbg, path) < 0) {
+               free(dbg);
+               dbg = NULL;
        }
 
-       return self;
+       return dbg;
 }
 
 struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
 {
-       struct debuginfo *self = zalloc(sizeof(struct debuginfo));
-       if (!self)
+       struct debuginfo *dbg = zalloc(sizeof(*dbg));
+
+       if (!dbg)
                return NULL;
 
-       if (debuginfo__init_online_kernel_dwarf(self, (Dwarf_Addr)addr) < 0) {
-               free(self);
-               self = NULL;
+       if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) {
+               free(dbg);
+               dbg = NULL;
        }
 
-       return self;
+       return dbg;
 }
 
-void debuginfo__delete(struct debuginfo *self)
+void debuginfo__delete(struct debuginfo *dbg)
 {
-       if (self) {
-               if (self->dwfl)
-                       dwfl_end(self->dwfl);
-               free(self);
+       if (dbg) {
+               if (dbg->dwfl)
+                       dwfl_end(dbg->dwfl);
+               free(dbg);
        }
 }
 
@@ -273,12 +274,15 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
 /*
  * Convert a location into trace_arg.
  * If tvar == NULL, this just checks variable can be converted.
+ * If fentry == true and vr_die is a parameter, do huristic search
+ * for the location fuzzed by function entry mcount.
  */
 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
-                                    Dwarf_Op *fb_ops,
+                                    Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
                                     struct probe_trace_arg *tvar)
 {
        Dwarf_Attribute attr;
+       Dwarf_Addr tmp = 0;
        Dwarf_Op *op;
        size_t nops;
        unsigned int regn;
@@ -291,12 +295,29 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
                goto static_var;
 
        /* TODO: handle more than 1 exprs */
-       if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
-           dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 ||
-           nops == 0) {
-               /* TODO: Support const_value */
+       if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
+               return -EINVAL; /* Broken DIE ? */
+       if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
+               ret = dwarf_entrypc(sp_die, &tmp);
+               if (ret || addr != tmp ||
+                   dwarf_tag(vr_die) != DW_TAG_formal_parameter ||
+                   dwarf_highpc(sp_die, &tmp))
+                       return -ENOENT;
+               /*
+                * This is fuzzed by fentry mcount. We try to find the
+                * parameter location at the earliest address.
+                */
+               for (addr += 1; addr <= tmp; addr++) {
+                       if (dwarf_getlocation_addr(&attr, addr, &op,
+                                                  &nops, 1) > 0)
+                               goto found;
+               }
                return -ENOENT;
        }
+found:
+       if (nops == 0)
+               /* TODO: Support const_value */
+               return -ENOENT;
 
        if (op->atom == DW_OP_addr) {
 static_var:
@@ -563,7 +584,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
        }
 
        if (die_find_member(&type, field->name, die_mem) == NULL) {
-               pr_warning("%s(tyep:%s) has no member %s.\n", varname,
+               pr_warning("%s(type:%s) has no member %s.\n", varname,
                           dwarf_diename(&type), field->name);
                return -EINVAL;
        }
@@ -600,7 +621,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
                 dwarf_diename(vr_die));
 
        ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
-                                       pf->tvar);
+                                       &pf->sp_die, pf->tvar);
        if (ret == -ENOENT)
                pr_err("Failed to find the location of %s at this address.\n"
                       " Perhaps, it has been optimized out.\n", pf->pvar->var);
@@ -1063,7 +1084,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
 }
 
 /* Find probe points from debuginfo */
-static int debuginfo__find_probes(struct debuginfo *self,
+static int debuginfo__find_probes(struct debuginfo *dbg,
                                  struct probe_finder *pf)
 {
        struct perf_probe_point *pp = &pf->pev->point;
@@ -1074,7 +1095,7 @@ static int debuginfo__find_probes(struct debuginfo *self,
 
 #if _ELFUTILS_PREREQ(0, 142)
        /* Get the call frame information from this dwarf */
-       pf->cfi = dwarf_getcfi(self->dbg);
+       pf->cfi = dwarf_getcfi(dbg->dbg);
 #endif
 
        off = 0;
@@ -1093,7 +1114,7 @@ static int debuginfo__find_probes(struct debuginfo *self,
                        .data = pf,
                };
 
-               dwarf_getpubnames(self->dbg, pubname_search_cb,
+               dwarf_getpubnames(dbg->dbg, pubname_search_cb,
                                  &pubname_param, 0);
                if (pubname_param.found) {
                        ret = probe_point_search_cb(&pf->sp_die, &probe_param);
@@ -1103,9 +1124,9 @@ static int debuginfo__find_probes(struct debuginfo *self,
        }
 
        /* Loop on CUs (Compilation Unit) */
-       while (!dwarf_nextcu(self->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
+       while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
                /* Get the DIE(Debugging Information Entry) of this CU */
-               diep = dwarf_offdie(self->dbg, off + cuhl, &pf->cu_die);
+               diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
                if (!diep)
                        continue;
 
@@ -1136,12 +1157,80 @@ found:
        return ret;
 }
 
+struct local_vars_finder {
+       struct probe_finder *pf;
+       struct perf_probe_arg *args;
+       int max_args;
+       int nargs;
+       int ret;
+};
+
+/* Collect available variables in this scope */
+static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
+{
+       struct local_vars_finder *vf = data;
+       struct probe_finder *pf = vf->pf;
+       int tag;
+
+       tag = dwarf_tag(die_mem);
+       if (tag == DW_TAG_formal_parameter ||
+           tag == DW_TAG_variable) {
+               if (convert_variable_location(die_mem, vf->pf->addr,
+                                             vf->pf->fb_ops, &pf->sp_die,
+                                             NULL) == 0) {
+                       vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
+                       if (vf->args[vf->nargs].var == NULL) {
+                               vf->ret = -ENOMEM;
+                               return DIE_FIND_CB_END;
+                       }
+                       pr_debug(" %s", vf->args[vf->nargs].var);
+                       vf->nargs++;
+               }
+       }
+
+       if (dwarf_haspc(die_mem, vf->pf->addr))
+               return DIE_FIND_CB_CONTINUE;
+       else
+               return DIE_FIND_CB_SIBLING;
+}
+
+static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
+                            struct perf_probe_arg *args)
+{
+       Dwarf_Die die_mem;
+       int i;
+       int n = 0;
+       struct local_vars_finder vf = {.pf = pf, .args = args,
+                               .max_args = MAX_PROBE_ARGS, .ret = 0};
+
+       for (i = 0; i < pf->pev->nargs; i++) {
+               /* var never be NULL */
+               if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
+                       pr_debug("Expanding $vars into:");
+                       vf.nargs = n;
+                       /* Special local variables */
+                       die_find_child(sc_die, copy_variables_cb, (void *)&vf,
+                                      &die_mem);
+                       pr_debug(" (%d)\n", vf.nargs - n);
+                       if (vf.ret < 0)
+                               return vf.ret;
+                       n = vf.nargs;
+               } else {
+                       /* Copy normal argument */
+                       args[n] = pf->pev->args[i];
+                       n++;
+               }
+       }
+       return n;
+}
+
 /* Add a found probe point into trace event list */
 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
        struct trace_event_finder *tf =
                        container_of(pf, struct trace_event_finder, pf);
        struct probe_trace_event *tev;
+       struct perf_probe_arg *args;
        int ret, i;
 
        /* Check number of tevs */
@@ -1161,31 +1250,45 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
        pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
                 tev->point.offset);
 
-       /* Find each argument */
-       tev->nargs = pf->pev->nargs;
-       tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
-       if (tev->args == NULL)
+       /* Expand special probe argument if exist */
+       args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
+       if (args == NULL)
                return -ENOMEM;
-       for (i = 0; i < pf->pev->nargs; i++) {
-               pf->pvar = &pf->pev->args[i];
+
+       ret = expand_probe_args(sc_die, pf, args);
+       if (ret < 0)
+               goto end;
+
+       tev->nargs = ret;
+       tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
+       if (tev->args == NULL) {
+               ret = -ENOMEM;
+               goto end;
+       }
+
+       /* Find each argument */
+       for (i = 0; i < tev->nargs; i++) {
+               pf->pvar = &args[i];
                pf->tvar = &tev->args[i];
                /* Variable should be found from scope DIE */
                ret = find_variable(sc_die, pf);
                if (ret != 0)
-                       return ret;
+                       break;
        }
 
-       return 0;
+end:
+       free(args);
+       return ret;
 }
 
 /* Find probe_trace_events specified by perf_probe_event from debuginfo */
-int debuginfo__find_trace_events(struct debuginfo *self,
+int debuginfo__find_trace_events(struct debuginfo *dbg,
                                 struct perf_probe_event *pev,
                                 struct probe_trace_event **tevs, int max_tevs)
 {
        struct trace_event_finder tf = {
                        .pf = {.pev = pev, .callback = add_probe_trace_event},
-                       .mod = self->mod, .max_tevs = max_tevs};
+                       .mod = dbg->mod, .max_tevs = max_tevs};
        int ret;
 
        /* Allocate result tevs array */
@@ -1196,7 +1299,7 @@ int debuginfo__find_trace_events(struct debuginfo *self,
        tf.tevs = *tevs;
        tf.ntevs = 0;
 
-       ret = debuginfo__find_probes(self, &tf.pf);
+       ret = debuginfo__find_probes(dbg, &tf.pf);
        if (ret < 0) {
                free(*tevs);
                *tevs = NULL;
@@ -1222,7 +1325,8 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
        if (tag == DW_TAG_formal_parameter ||
            tag == DW_TAG_variable) {
                ret = convert_variable_location(die_mem, af->pf.addr,
-                                               af->pf.fb_ops, NULL);
+                                               af->pf.fb_ops, &af->pf.sp_die,
+                                               NULL);
                if (ret == 0) {
                        ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
                        pr_debug2("Add new var: %s\n", buf);
@@ -1286,14 +1390,14 @@ out:
 }
 
 /* Find available variables at given probe point */
-int debuginfo__find_available_vars_at(struct debuginfo *self,
+int debuginfo__find_available_vars_at(struct debuginfo *dbg,
                                      struct perf_probe_event *pev,
                                      struct variable_list **vls,
                                      int max_vls, bool externs)
 {
        struct available_var_finder af = {
                        .pf = {.pev = pev, .callback = add_available_vars},
-                       .mod = self->mod,
+                       .mod = dbg->mod,
                        .max_vls = max_vls, .externs = externs};
        int ret;
 
@@ -1305,7 +1409,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
        af.vls = *vls;
        af.nvls = 0;
 
-       ret = debuginfo__find_probes(self, &af.pf);
+       ret = debuginfo__find_probes(dbg, &af.pf);
        if (ret < 0) {
                /* Free vlist for error */
                while (af.nvls--) {
@@ -1323,7 +1427,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
 }
 
 /* Reverse search */
-int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
+int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                                struct perf_probe_point *ppt)
 {
        Dwarf_Die cudie, spdie, indie;
@@ -1332,10 +1436,10 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
        int baseline = 0, lineno = 0, ret = 0;
 
        /* Adjust address with bias */
-       addr += self->bias;
+       addr += dbg->bias;
 
        /* Find cu die */
-       if (!dwarf_addrdie(self->dbg, (Dwarf_Addr)addr - self->bias, &cudie)) {
+       if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr - dbg->bias, &cudie)) {
                pr_warning("Failed to find debug information for address %lx\n",
                           addr);
                ret = -EINVAL;
@@ -1536,7 +1640,7 @@ static int find_line_range_by_func(struct line_finder *lf)
        return param.retval;
 }
 
-int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
+int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
 {
        struct line_finder lf = {.lr = lr, .found = 0};
        int ret = 0;
@@ -1553,7 +1657,7 @@ int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
                struct dwarf_callback_param line_range_param = {
                        .data = (void *)&lf, .retval = 0};
 
-               dwarf_getpubnames(self->dbg, pubname_search_cb,
+               dwarf_getpubnames(dbg->dbg, pubname_search_cb,
                                  &pubname_param, 0);
                if (pubname_param.found) {
                        line_range_search_cb(&lf.sp_die, &line_range_param);
@@ -1564,12 +1668,12 @@ int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
 
        /* Loop on CUs (Compilation Unit) */
        while (!lf.found && ret >= 0) {
-               if (dwarf_nextcu(self->dbg, off, &noff, &cuhl,
+               if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
                                 NULL, NULL, NULL) != 0)
                        break;
 
                /* Get the DIE(Debugging Information Entry) of this CU */
-               diep = dwarf_offdie(self->dbg, off + cuhl, &lf.cu_die);
+               diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
                if (!diep)
                        continue;
 
index 3b7d63018960d7ff6a6808ce81eff2d34b40bd09..ffc33cdd25cc343816fd9e05586832bf48b82205 100644 (file)
@@ -7,6 +7,7 @@
 
 #define MAX_PROBE_BUFFER       1024
 #define MAX_PROBES              128
+#define MAX_PROBE_ARGS          128
 
 static inline int is_c_varname(const char *name)
 {
@@ -14,7 +15,7 @@ static inline int is_c_varname(const char *name)
        return isalpha(name[0]) || name[0] == '_';
 }
 
-#ifdef DWARF_SUPPORT
+#ifdef HAVE_DWARF_SUPPORT
 
 #include "dwarf-aux.h"
 
@@ -30,25 +31,25 @@ struct debuginfo {
 
 extern struct debuginfo *debuginfo__new(const char *path);
 extern struct debuginfo *debuginfo__new_online_kernel(unsigned long addr);
-extern void debuginfo__delete(struct debuginfo *self);
+extern void debuginfo__delete(struct debuginfo *dbg);
 
 /* Find probe_trace_events specified by perf_probe_event from debuginfo */
-extern int debuginfo__find_trace_events(struct debuginfo *self,
+extern int debuginfo__find_trace_events(struct debuginfo *dbg,
                                        struct perf_probe_event *pev,
                                        struct probe_trace_event **tevs,
                                        int max_tevs);
 
 /* Find a perf_probe_point from debuginfo */
-extern int debuginfo__find_probe_point(struct debuginfo *self,
+extern int debuginfo__find_probe_point(struct debuginfo *dbg,
                                       unsigned long addr,
                                       struct perf_probe_point *ppt);
 
 /* Find a line range */
-extern int debuginfo__find_line_range(struct debuginfo *self,
+extern int debuginfo__find_line_range(struct debuginfo *dbg,
                                      struct line_range *lr);
 
 /* Find available variables */
-extern int debuginfo__find_available_vars_at(struct debuginfo *self,
+extern int debuginfo__find_available_vars_at(struct debuginfo *dbg,
                                             struct perf_probe_event *pev,
                                             struct variable_list **vls,
                                             int max_points, bool externs);
@@ -105,6 +106,6 @@ struct line_finder {
        int                     found;
 };
 
-#endif /* DWARF_SUPPORT */
+#endif /* HAVE_DWARF_SUPPORT */
 
 #endif /*_PROBE_FINDER_H */
index 4cedea59f518ce7c1fcb61b0368598453bdf3a63..c3cb6584d52763f24c3074886de50c9ff741c71c 100644 (file)
@@ -5,10 +5,10 @@
 
 struct pstack;
 struct pstack *pstack__new(unsigned short max_nr_entries);
-void pstack__delete(struct pstack *self);
-bool pstack__empty(const struct pstack *self);
-void pstack__remove(struct pstack *self, void *key);
-void pstack__push(struct pstack *self, void *key);
-void *pstack__pop(struct pstack *self);
+void pstack__delete(struct pstack *pstack);
+bool pstack__empty(const struct pstack *pstack);
+void pstack__remove(struct pstack *pstack, void *key);
+void pstack__push(struct pstack *pstack, void *key);
+void *pstack__pop(struct pstack *pstack);
 
 #endif /* _PERF_PSTACK_ */
index f75ae1b9900c435af147f24e6c29dd414ca9692c..239036fb2b2c0b08b9352dcbce368904917d2521 100644 (file)
@@ -17,5 +17,5 @@ util/xyarray.c
 util/cgroup.c
 util/rblist.c
 util/strlist.c
-util/sysfs.c
+util/fs.c
 ../../lib/rbtree.c
index 2ac4bc92bb1ff2b130e47a59e43c3127ba0568b7..4bf8ace7f5116a3b7536ba9c13592bb4f8e7a7e1 100644 (file)
@@ -33,13 +33,6 @@ int eprintf(int level, const char *fmt, ...)
 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
 #endif
 
-struct throttle_event {
-       struct perf_event_header header;
-       u64                      time;
-       u64                      id;
-       u64                      stream_id;
-};
-
 PyMODINIT_FUNC initperf(void);
 
 #define member_def(type, member, ptype, help) \
@@ -1038,6 +1031,7 @@ PyMODINIT_FUNC initperf(void)
            pyrf_cpu_map__setup_types() < 0)
                return;
 
+       /* The page_size is placed in util object. */
        page_size = sysconf(_SC_PAGE_SIZE);
 
        Py_INCREF(&pyrf_evlist__type);
index a16cdd2625ad2b4a0ff8ff39d6b91b331f3a3a1e..0dfe27d99458c845991e490283c067d0d0706221 100644 (file)
@@ -48,10 +48,12 @@ void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
        rblist->node_delete(rblist, rb_node);
 }
 
-struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
+static struct rb_node *__rblist__findnew(struct rblist *rblist,
+                                        const void *entry,
+                                        bool create)
 {
        struct rb_node **p = &rblist->entries.rb_node;
-       struct rb_node *parent = NULL;
+       struct rb_node *parent = NULL, *new_node = NULL;
 
        while (*p != NULL) {
                int rc;
@@ -67,7 +69,26 @@ struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
                        return parent;
        }
 
-       return NULL;
+       if (create) {
+               new_node = rblist->node_new(rblist, entry);
+               if (new_node) {
+                       rb_link_node(new_node, parent, p);
+                       rb_insert_color(new_node, &rblist->entries);
+                       ++rblist->nr_entries;
+               }
+       }
+
+       return new_node;
+}
+
+struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
+{
+       return __rblist__findnew(rblist, entry, false);
+}
+
+struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry)
+{
+       return __rblist__findnew(rblist, entry, true);
 }
 
 void rblist__init(struct rblist *rblist)
index 6d0cae5ae83d5e848b56a9518575ad3c7a114444..ff9913b994c26126203e303f694021f9d24e739a 100644 (file)
@@ -32,6 +32,7 @@ void rblist__delete(struct rblist *rblist);
 int rblist__add_node(struct rblist *rblist, const void *new_entry);
 void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node);
 struct rb_node *rblist__find(struct rblist *rblist, const void *entry);
+struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry);
 struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx);
 
 static inline bool rblist__empty(const struct rblist *rblist)
index 18d73aa2f0f89679537b5cb77bdf914a597cd1ad..c8845b107f6085cfacb907fce862c2e76dc6db5b 100644 (file)
@@ -2,6 +2,8 @@
 #include "evsel.h"
 #include "cpumap.h"
 #include "parse-events.h"
+#include "fs.h"
+#include "util.h"
 
 typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);
 
@@ -106,3 +108,72 @@ void perf_evlist__config(struct perf_evlist *evlist,
 
        perf_evlist__set_id_pos(evlist);
 }
+
+static int get_max_rate(unsigned int *rate)
+{
+       char path[PATH_MAX];
+       const char *procfs = procfs__mountpoint();
+
+       if (!procfs)
+               return -1;
+
+       snprintf(path, PATH_MAX,
+                "%s/sys/kernel/perf_event_max_sample_rate", procfs);
+
+       return filename__read_int(path, (int *) rate);
+}
+
+static int perf_record_opts__config_freq(struct perf_record_opts *opts)
+{
+       bool user_freq = opts->user_freq != UINT_MAX;
+       unsigned int max_rate;
+
+       if (opts->user_interval != ULLONG_MAX)
+               opts->default_interval = opts->user_interval;
+       if (user_freq)
+               opts->freq = opts->user_freq;
+
+       /*
+        * User specified count overrides default frequency.
+        */
+       if (opts->default_interval)
+               opts->freq = 0;
+       else if (opts->freq) {
+               opts->default_interval = opts->freq;
+       } else {
+               pr_err("frequency and count are zero, aborting\n");
+               return -1;
+       }
+
+       if (get_max_rate(&max_rate))
+               return 0;
+
+       /*
+        * User specified frequency is over current maximum.
+        */
+       if (user_freq && (max_rate < opts->freq)) {
+               pr_err("Maximum frequency rate (%u) reached.\n"
+                  "Please use -F freq option with lower value or consider\n"
+                  "tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
+                  max_rate);
+               return -1;
+       }
+
+       /*
+        * Default frequency is over current maximum.
+        */
+       if (max_rate < opts->freq) {
+               pr_warning("Lowering default frequency rate to %u.\n"
+                          "Please consider tweaking "
+                          "/proc/sys/kernel/perf_event_max_sample_rate.\n",
+                          max_rate);
+               opts->freq = max_rate;
+       }
+
+       return 0;
+}
+
+int perf_record_opts__config(struct perf_record_opts *opts)
+{
+       return perf_record_opts__config_freq(opts);
+}
index c0c9795c4f0235b51848e01db33a7950069b182a..d5e5969f6fea4fce43974a748f3069e869ab9fca 100644 (file)
@@ -273,7 +273,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
        int cpu = sample->cpu;
        void *data = sample->raw_data;
        unsigned long long nsecs = sample->time;
-       char *comm = thread->comm;
+       const char *comm = thread__comm_str(thread);
 
        dSP;
 
index 95d91a0b23afe01a45463a02dcc8eadbb5ba5169..53c20e7fd90037ce46dc1c53d20e99264d66c47a 100644 (file)
@@ -250,7 +250,7 @@ static void python_process_tracepoint(union perf_event *perf_event
        int cpu = sample->cpu;
        void *data = sample->raw_data;
        unsigned long long nsecs = sample->time;
-       char *comm = thread->comm;
+       const char *comm = thread__comm_str(thread);
 
        t = PyTuple_New(MAX_FIELDS);
        if (!t)
@@ -389,7 +389,7 @@ static void python_process_general_event(union perf_event *perf_event
        pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
                        (const char *)sample->raw_data, sample->raw_size));
        pydict_set_item_string_decref(dict, "comm",
-                       PyString_FromString(thread->comm));
+                       PyString_FromString(thread__comm_str(thread)));
        if (al->map) {
                pydict_set_item_string_decref(dict, "dso",
                        PyString_FromString(al->map->dso->name));
index 568b750c01f60b3d81cda29966ed40534a7bc8e1..f36d24a024453f6e2777d1bc4cfbb10fb9a3cf4a 100644 (file)
 #include "perf_regs.h"
 #include "vdso.h"
 
-static int perf_session__open(struct perf_session *self, bool force)
+static int perf_session__open(struct perf_session *session)
 {
-       struct stat input_stat;
+       struct perf_data_file *file = session->file;
 
-       if (!strcmp(self->filename, "-")) {
-               self->fd_pipe = true;
-               self->fd = STDIN_FILENO;
-
-               if (perf_session__read_header(self) < 0)
-                       pr_err("incompatible file format (rerun with -v to learn more)");
-
-               return 0;
-       }
-
-       self->fd = open(self->filename, O_RDONLY);
-       if (self->fd < 0) {
-               int err = errno;
-
-               pr_err("failed to open %s: %s", self->filename, strerror(err));
-               if (err == ENOENT && !strcmp(self->filename, "perf.data"))
-                       pr_err("  (try 'perf record' first)");
-               pr_err("\n");
-               return -errno;
-       }
-
-       if (fstat(self->fd, &input_stat) < 0)
-               goto out_close;
-
-       if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
-               pr_err("file %s not owned by current user or root\n",
-                      self->filename);
-               goto out_close;
-       }
-
-       if (!input_stat.st_size) {
-               pr_info("zero-sized file (%s), nothing to do!\n",
-                       self->filename);
-               goto out_close;
-       }
-
-       if (perf_session__read_header(self) < 0) {
+       if (perf_session__read_header(session) < 0) {
                pr_err("incompatible file format (rerun with -v to learn more)");
-               goto out_close;
+               return -1;
        }
 
-       if (!perf_evlist__valid_sample_type(self->evlist)) {
+       if (perf_data_file__is_pipe(file))
+               return 0;
+
+       if (!perf_evlist__valid_sample_type(session->evlist)) {
                pr_err("non matching sample_type");
-               goto out_close;
+               return -1;
        }
 
-       if (!perf_evlist__valid_sample_id_all(self->evlist)) {
+       if (!perf_evlist__valid_sample_id_all(session->evlist)) {
                pr_err("non matching sample_id_all");
-               goto out_close;
+               return -1;
        }
 
-       if (!perf_evlist__valid_read_format(self->evlist)) {
+       if (!perf_evlist__valid_read_format(session->evlist)) {
                pr_err("non matching read_format");
-               goto out_close;
+               return -1;
        }
 
-       self->size = input_stat.st_size;
        return 0;
-
-out_close:
-       close(self->fd);
-       self->fd = -1;
-       return -1;
 }
 
 void perf_session__set_id_hdr_size(struct perf_session *session)
@@ -92,71 +53,70 @@ void perf_session__set_id_hdr_size(struct perf_session *session)
        machines__set_id_hdr_size(&session->machines, id_hdr_size);
 }
 
-int perf_session__create_kernel_maps(struct perf_session *self)
+int perf_session__create_kernel_maps(struct perf_session *session)
 {
-       int ret = machine__create_kernel_maps(&self->machines.host);
+       int ret = machine__create_kernel_maps(&session->machines.host);
 
        if (ret >= 0)
-               ret = machines__create_guest_kernel_maps(&self->machines);
+               ret = machines__create_guest_kernel_maps(&session->machines);
        return ret;
 }
 
-static void perf_session__destroy_kernel_maps(struct perf_session *self)
+static void perf_session__destroy_kernel_maps(struct perf_session *session)
 {
-       machines__destroy_kernel_maps(&self->machines);
+       machines__destroy_kernel_maps(&session->machines);
 }
 
-struct perf_session *perf_session__new(const char *filename, int mode,
-                                      bool force, bool repipe,
-                                      struct perf_tool *tool)
+struct perf_session *perf_session__new(struct perf_data_file *file,
+                                      bool repipe, struct perf_tool *tool)
 {
-       struct perf_session *self;
-       struct stat st;
-       size_t len;
-
-       if (!filename || !strlen(filename)) {
-               if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
-                       filename = "-";
-               else
-                       filename = "perf.data";
-       }
+       struct perf_session *session = zalloc(sizeof(*session));
 
-       len = strlen(filename);
-       self = zalloc(sizeof(*self) + len);
-
-       if (self == NULL)
+       if (!session)
                goto out;
 
-       memcpy(self->filename, filename, len);
-       self->repipe = repipe;
-       INIT_LIST_HEAD(&self->ordered_samples.samples);
-       INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
-       INIT_LIST_HEAD(&self->ordered_samples.to_free);
-       machines__init(&self->machines);
+       session->repipe = repipe;
+       INIT_LIST_HEAD(&session->ordered_samples.samples);
+       INIT_LIST_HEAD(&session->ordered_samples.sample_cache);
+       INIT_LIST_HEAD(&session->ordered_samples.to_free);
+       machines__init(&session->machines);
 
-       if (mode == O_RDONLY) {
-               if (perf_session__open(self, force) < 0)
+       if (file) {
+               if (perf_data_file__open(file))
                        goto out_delete;
-               perf_session__set_id_hdr_size(self);
-       } else if (mode == O_WRONLY) {
+
+               session->file = file;
+
+               if (perf_data_file__is_read(file)) {
+                       if (perf_session__open(session) < 0)
+                               goto out_close;
+
+                       perf_session__set_id_hdr_size(session);
+               }
+       }
+
+       if (!file || perf_data_file__is_write(file)) {
                /*
                 * In O_RDONLY mode this will be performed when reading the
                 * kernel MMAP event, in perf_event__process_mmap().
                 */
-               if (perf_session__create_kernel_maps(self) < 0)
+               if (perf_session__create_kernel_maps(session) < 0)
                        goto out_delete;
        }
 
        if (tool && tool->ordering_requires_timestamps &&
-           tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) {
+           tool->ordered_samples && !perf_evlist__sample_id_all(session->evlist)) {
                dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
                tool->ordered_samples = false;
        }
 
-out:
-       return self;
-out_delete:
-       perf_session__delete(self);
+       return session;
+
+ out_close:
+       perf_data_file__close(file);
+ out_delete:
+       perf_session__delete(session);
+ out:
        return NULL;
 }
 
@@ -186,15 +146,16 @@ static void perf_session_env__delete(struct perf_session_env *env)
        free(env->pmu_mappings);
 }
 
-void perf_session__delete(struct perf_session *self)
+void perf_session__delete(struct perf_session *session)
 {
-       perf_session__destroy_kernel_maps(self);
-       perf_session__delete_dead_threads(self);
-       perf_session__delete_threads(self);
-       perf_session_env__delete(&self->header.env);
-       machines__exit(&self->machines);
-       close(self->fd);
-       free(self);
+       perf_session__destroy_kernel_maps(session);
+       perf_session__delete_dead_threads(session);
+       perf_session__delete_threads(session);
+       perf_session_env__delete(&session->header.env);
+       machines__exit(&session->machines);
+       if (session->file)
+               perf_data_file__close(session->file);
+       free(session);
        vdso__exit();
 }
 
@@ -397,6 +358,17 @@ static void perf_event__read_swap(union perf_event *event, bool sample_id_all)
                swap_sample_id_all(event, &event->read + 1);
 }
 
+static void perf_event__throttle_swap(union perf_event *event,
+                                     bool sample_id_all)
+{
+       event->throttle.time      = bswap_64(event->throttle.time);
+       event->throttle.id        = bswap_64(event->throttle.id);
+       event->throttle.stream_id = bswap_64(event->throttle.stream_id);
+
+       if (sample_id_all)
+               swap_sample_id_all(event, &event->throttle + 1);
+}
+
 static u8 revbyte(u8 b)
 {
        int rev = (b >> 4) | ((b & 0xf) << 4);
@@ -442,6 +414,9 @@ void perf_event__attr_swap(struct perf_event_attr *attr)
        attr->bp_type           = bswap_32(attr->bp_type);
        attr->bp_addr           = bswap_64(attr->bp_addr);
        attr->bp_len            = bswap_64(attr->bp_len);
+       attr->branch_sample_type = bswap_64(attr->branch_sample_type);
+       attr->sample_regs_user   = bswap_64(attr->sample_regs_user);
+       attr->sample_stack_user  = bswap_32(attr->sample_stack_user);
 
        swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64));
 }
@@ -482,6 +457,8 @@ static perf_event__swap_op perf_event__swap_ops[] = {
        [PERF_RECORD_EXIT]                = perf_event__task_swap,
        [PERF_RECORD_LOST]                = perf_event__all64_swap,
        [PERF_RECORD_READ]                = perf_event__read_swap,
+       [PERF_RECORD_THROTTLE]            = perf_event__throttle_swap,
+       [PERF_RECORD_UNTHROTTLE]          = perf_event__throttle_swap,
        [PERF_RECORD_SAMPLE]              = perf_event__all64_swap,
        [PERF_RECORD_HEADER_ATTR]         = perf_event__hdr_attr_swap,
        [PERF_RECORD_HEADER_EVENT_TYPE]   = perf_event__event_type_swap,
@@ -525,13 +502,16 @@ static int flush_sample_queue(struct perf_session *s,
        struct perf_sample sample;
        u64 limit = os->next_flush;
        u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
-       unsigned idx = 0, progress_next = os->nr_samples / 16;
        bool show_progress = limit == ULLONG_MAX;
+       struct ui_progress prog;
        int ret;
 
        if (!tool->ordered_samples || !limit)
                return 0;
 
+       if (show_progress)
+               ui_progress__init(&prog, os->nr_samples, "Processing time ordered events...");
+
        list_for_each_entry_safe(iter, tmp, head, list) {
                if (session_done())
                        return 0;
@@ -552,11 +532,9 @@ static int flush_sample_queue(struct perf_session *s,
                os->last_flush = iter->timestamp;
                list_del(&iter->list);
                list_add(&iter->list, &os->sample_cache);
-               if (show_progress && (++idx >= progress_next)) {
-                       progress_next += os->nr_samples / 16;
-                       ui_progress__update(idx, os->nr_samples,
-                                           "Processing time ordered events...");
-               }
+
+               if (show_progress)
+                       ui_progress__update(&prog, 1);
        }
 
        if (list_empty(head)) {
@@ -860,6 +838,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
        if (sample_type & PERF_SAMPLE_DATA_SRC)
                printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
 
+       if (sample_type & PERF_SAMPLE_TRANSACTION)
+               printf("... transaction: %" PRIx64 "\n", sample->transaction);
+
        if (sample_type & PERF_SAMPLE_READ)
                sample_read__printf(sample, evsel->attr.read_format);
 }
@@ -1031,6 +1012,7 @@ static int perf_session_deliver_event(struct perf_session *session,
 static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
                                            struct perf_tool *tool, u64 file_offset)
 {
+       int fd = perf_data_file__fd(session->file);
        int err;
 
        dump_event(session, event, file_offset, NULL);
@@ -1044,7 +1026,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
                return err;
        case PERF_RECORD_HEADER_TRACING_DATA:
                /* setup for reading amidst mmap */
-               lseek(session->fd, file_offset, SEEK_SET);
+               lseek(fd, file_offset, SEEK_SET);
                return tool->tracing_data(tool, event, session);
        case PERF_RECORD_HEADER_BUILD_ID:
                return tool->build_id(tool, event, session);
@@ -1101,11 +1083,11 @@ static int perf_session__process_event(struct perf_session *session,
                                          file_offset);
 }
 
-void perf_event_header__bswap(struct perf_event_header *self)
+void perf_event_header__bswap(struct perf_event_header *hdr)
 {
-       self->type = bswap_32(self->type);
-       self->misc = bswap_16(self->misc);
-       self->size = bswap_16(self->size);
+       hdr->type = bswap_32(hdr->type);
+       hdr->misc = bswap_16(hdr->misc);
+       hdr->size = bswap_16(hdr->size);
 }
 
 struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
@@ -1113,11 +1095,11 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
        return machine__findnew_thread(&session->machines.host, 0, pid);
 }
 
-static struct thread *perf_session__register_idle_thread(struct perf_session *self)
+static struct thread *perf_session__register_idle_thread(struct perf_session *session)
 {
-       struct thread *thread = perf_session__findnew(self, 0);
+       struct thread *thread = perf_session__findnew(session, 0);
 
-       if (thread == NULL || thread__set_comm(thread, "swapper")) {
+       if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
                pr_err("problem inserting idle task.\n");
                thread = NULL;
        }
@@ -1167,9 +1149,10 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
 
 volatile int session_done;
 
-static int __perf_session__process_pipe_events(struct perf_session *self,
+static int __perf_session__process_pipe_events(struct perf_session *session,
                                               struct perf_tool *tool)
 {
+       int fd = perf_data_file__fd(session->file);
        union perf_event *event;
        uint32_t size, cur_size = 0;
        void *buf = NULL;
@@ -1188,7 +1171,7 @@ static int __perf_session__process_pipe_events(struct perf_session *self,
                return -errno;
 more:
        event = buf;
-       err = readn(self->fd, event, sizeof(struct perf_event_header));
+       err = readn(fd, event, sizeof(struct perf_event_header));
        if (err <= 0) {
                if (err == 0)
                        goto done;
@@ -1197,7 +1180,7 @@ more:
                goto out_err;
        }
 
-       if (self->header.needs_swap)
+       if (session->header.needs_swap)
                perf_event_header__bswap(&event->header);
 
        size = event->header.size;
@@ -1220,7 +1203,7 @@ more:
        p += sizeof(struct perf_event_header);
 
        if (size - sizeof(struct perf_event_header)) {
-               err = readn(self->fd, p, size - sizeof(struct perf_event_header));
+               err = readn(fd, p, size - sizeof(struct perf_event_header));
                if (err <= 0) {
                        if (err == 0) {
                                pr_err("unexpected end of event stream\n");
@@ -1232,7 +1215,7 @@ more:
                }
        }
 
-       if ((skip = perf_session__process_event(self, event, tool, head)) < 0) {
+       if ((skip = perf_session__process_event(session, event, tool, head)) < 0) {
                pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
                       head, event->header.size, event->header.type);
                err = -EINVAL;
@@ -1247,11 +1230,13 @@ more:
        if (!session_done())
                goto more;
 done:
-       err = 0;
+       /* do the final flush for ordered samples */
+       session->ordered_samples.next_flush = ULLONG_MAX;
+       err = flush_sample_queue(session, tool);
 out_err:
        free(buf);
-       perf_session__warn_about_errors(self, tool);
-       perf_session_free_sample_buffers(self);
+       perf_session__warn_about_errors(session, tool);
+       perf_session_free_sample_buffers(session);
        return err;
 }
 
@@ -1299,12 +1284,14 @@ int __perf_session__process_events(struct perf_session *session,
                                   u64 data_offset, u64 data_size,
                                   u64 file_size, struct perf_tool *tool)
 {
-       u64 head, page_offset, file_offset, file_pos, progress_next;
+       int fd = perf_data_file__fd(session->file);
+       u64 head, page_offset, file_offset, file_pos;
        int err, mmap_prot, mmap_flags, map_idx = 0;
        size_t  mmap_size;
        char *buf, *mmaps[NUM_MMAPS];
        union perf_event *event;
        uint32_t size;
+       struct ui_progress prog;
 
        perf_tool__fill_defaults(tool);
 
@@ -1315,7 +1302,7 @@ int __perf_session__process_events(struct perf_session *session,
        if (data_size && (data_offset + data_size < file_size))
                file_size = data_offset + data_size;
 
-       progress_next = file_size / 16;
+       ui_progress__init(&prog, file_size, "Processing events...");
 
        mmap_size = MMAP_SIZE;
        if (mmap_size > file_size)
@@ -1331,7 +1318,7 @@ int __perf_session__process_events(struct perf_session *session,
                mmap_flags = MAP_PRIVATE;
        }
 remap:
-       buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, session->fd,
+       buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, fd,
                   file_offset);
        if (buf == MAP_FAILED) {
                pr_err("failed to mmap file\n");
@@ -1370,19 +1357,15 @@ more:
        head += size;
        file_pos += size;
 
-       if (file_pos >= progress_next) {
-               progress_next += file_size / 16;
-               ui_progress__update(file_pos, file_size,
-                                   "Processing events...");
-       }
+       ui_progress__update(&prog, size);
 
-       err = 0;
        if (session_done())
-               goto out_err;
+               goto out;
 
        if (file_pos < file_size)
                goto more;
 
+out:
        /* do the final flush for ordered samples */
        session->ordered_samples.next_flush = ULLONG_MAX;
        err = flush_sample_queue(session, tool);
@@ -1393,21 +1376,22 @@ out_err:
        return err;
 }
 
-int perf_session__process_events(struct perf_session *self,
+int perf_session__process_events(struct perf_session *session,
                                 struct perf_tool *tool)
 {
+       u64 size = perf_data_file__size(session->file);
        int err;
 
-       if (perf_session__register_idle_thread(self) == NULL)
+       if (perf_session__register_idle_thread(session) == NULL)
                return -ENOMEM;
 
-       if (!self->fd_pipe)
-               err = __perf_session__process_events(self,
-                                                    self->header.data_offset,
-                                                    self->header.data_size,
-                                                    self->size, tool);
+       if (!perf_data_file__is_pipe(session->file))
+               err = __perf_session__process_events(session,
+                                                    session->header.data_offset,
+                                                    session->header.data_size,
+                                                    size, tool);
        else
-               err = __perf_session__process_pipe_events(self, tool);
+               err = __perf_session__process_pipe_events(session, tool);
 
        return err;
 }
@@ -1456,15 +1440,15 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
        return 0;
 }
 
-size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
+size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp)
 {
-       return machines__fprintf_dsos(&self->machines, fp);
+       return machines__fprintf_dsos(&session->machines, fp);
 }
 
-size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
+size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp,
                                          bool (skip)(struct dso *dso, int parm), int parm)
 {
-       return machines__fprintf_dsos_buildid(&self->machines, fp, skip, parm);
+       return machines__fprintf_dsos_buildid(&session->machines, fp, skip, parm);
 }
 
 size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
@@ -1525,7 +1509,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
        if (symbol_conf.use_callchain && sample->callchain) {
 
                if (machine__resolve_callchain(machine, evsel, al.thread,
-                                              sample, NULL, NULL) != 0) {
+                                              sample, NULL, NULL,
+                                              PERF_MAX_STACK_DEPTH) != 0) {
                        if (verbose)
                                error("Failed to resolve callchain. Skipping\n");
                        return;
@@ -1629,13 +1614,14 @@ int perf_session__cpu_bitmap(struct perf_session *session,
 void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
                                bool full)
 {
+       int fd = perf_data_file__fd(session->file);
        struct stat st;
        int ret;
 
        if (session == NULL || fp == NULL)
                return;
 
-       ret = fstat(session->fd, &st);
+       ret = fstat(fd, &st);
        if (ret == -1)
                return;
 
@@ -1664,9 +1650,9 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
                        continue;
 
                err = -EEXIST;
-               if (evsel->handler.func != NULL)
+               if (evsel->handler != NULL)
                        goto out;
-               evsel->handler.func = assocs[i].handler;
+               evsel->handler = assocs[i].handler;
        }
 
        err = 0;
index 04bf7373a7e5fb04222b1a9cdb5c295045c0626f..50f640958f0f8aec87c7f5b3ef7346ad27363542 100644 (file)
@@ -7,6 +7,7 @@
 #include "machine.h"
 #include "symbol.h"
 #include "thread.h"
+#include "data.h"
 #include <linux/rbtree.h>
 #include <linux/perf_event.h>
 
@@ -29,16 +30,13 @@ struct ordered_samples {
 
 struct perf_session {
        struct perf_header      header;
-       unsigned long           size;
        struct machines         machines;
        struct perf_evlist      *evlist;
        struct pevent           *pevent;
        struct events_stats     stats;
-       int                     fd;
-       bool                    fd_pipe;
        bool                    repipe;
        struct ordered_samples  ordered_samples;
-       char                    filename[1];
+       struct perf_data_file   *file;
 };
 
 #define PRINT_IP_OPT_IP                (1<<0)
@@ -49,17 +47,16 @@ struct perf_session {
 
 struct perf_tool;
 
-struct perf_session *perf_session__new(const char *filename, int mode,
-                                      bool force, bool repipe,
-                                      struct perf_tool *tool);
+struct perf_session *perf_session__new(struct perf_data_file *file,
+                                      bool repipe, struct perf_tool *tool);
 void perf_session__delete(struct perf_session *session);
 
-void perf_event_header__bswap(struct perf_event_header *self);
+void perf_event_header__bswap(struct perf_event_header *hdr);
 
-int __perf_session__process_events(struct perf_session *self,
+int __perf_session__process_events(struct perf_session *session,
                                   u64 data_offset, u64 data_size, u64 size,
                                   struct perf_tool *tool);
-int perf_session__process_events(struct perf_session *self,
+int perf_session__process_events(struct perf_session *session,
                                 struct perf_tool *tool);
 
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
@@ -67,37 +64,38 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 
 void perf_tool__fill_defaults(struct perf_tool *tool);
 
-int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel *evsel,
+int perf_session__resolve_callchain(struct perf_session *session,
+                                   struct perf_evsel *evsel,
                                    struct thread *thread,
                                    struct ip_callchain *chain,
                                    struct symbol **parent);
 
-bool perf_session__has_traces(struct perf_session *self, const char *msg);
+bool perf_session__has_traces(struct perf_session *session, const char *msg);
 
 void mem_bswap_64(void *src, int byte_size);
 void mem_bswap_32(void *src, int byte_size);
 void perf_event__attr_swap(struct perf_event_attr *attr);
 
-int perf_session__create_kernel_maps(struct perf_session *self);
+int perf_session__create_kernel_maps(struct perf_session *session);
 
 void perf_session__set_id_hdr_size(struct perf_session *session);
 
 static inline
-struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
+struct machine *perf_session__find_machine(struct perf_session *session, pid_t pid)
 {
-       return machines__find(&self->machines, pid);
+       return machines__find(&session->machines, pid);
 }
 
 static inline
-struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
+struct machine *perf_session__findnew_machine(struct perf_session *session, pid_t pid)
 {
-       return machines__findnew(&self->machines, pid);
+       return machines__findnew(&session->machines, pid);
 }
 
-struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
-size_t perf_session__fprintf(struct perf_session *self, FILE *fp);
+struct thread *perf_session__findnew(struct perf_session *session, pid_t pid);
+size_t perf_session__fprintf(struct perf_session *session, FILE *fp);
 
-size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
+size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp);
 
 size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp,
                                          bool (fn)(struct dso *dso, int parm), int parm);
index 5f118a089519a46bb6b370536660476bc6880eda..3c1b75c8b9a65e15834ee31c07dabb3f19b5fe4c 100644 (file)
@@ -1,5 +1,6 @@
 #include "sort.h"
 #include "hist.h"
+#include "comm.h"
 #include "symbol.h"
 
 regex_t                parent_regex;
@@ -42,7 +43,7 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
        return n;
 }
 
-static int64_t cmp_null(void *l, void *r)
+static int64_t cmp_null(const void *l, const void *r)
 {
        if (!l && !r)
                return 0;
@@ -60,11 +61,12 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
        return right->thread->tid - left->thread->tid;
 }
 
-static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
                                       size_t size, unsigned int width)
 {
+       const char *comm = thread__comm_str(he->thread);
        return repsep_snprintf(bf, size, "%*s:%5d", width - 6,
-                             self->thread->comm ?: "", self->thread->tid);
+                              comm ?: "", he->thread->tid);
 }
 
 struct sort_entry sort_thread = {
@@ -79,25 +81,21 @@ struct sort_entry sort_thread = {
 static int64_t
 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-       return right->thread->tid - left->thread->tid;
+       /* Compare the addr that should be unique among comm */
+       return comm__str(right->comm) - comm__str(left->comm);
 }
 
 static int64_t
 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
 {
-       char *comm_l = left->thread->comm;
-       char *comm_r = right->thread->comm;
-
-       if (!comm_l || !comm_r)
-               return cmp_null(comm_l, comm_r);
-
-       return strcmp(comm_l, comm_r);
+       /* Compare the addr that should be unique among comm */
+       return comm__str(right->comm) - comm__str(left->comm);
 }
 
-static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf,
                                     size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
+       return repsep_snprintf(bf, size, "%*s", width, comm__str(he->comm));
 }
 
 struct sort_entry sort_comm = {
@@ -148,10 +146,10 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
        return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
 }
 
-static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
-       return _hist_entry__dso_snprintf(self->ms.map, bf, size, width);
+       return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
 }
 
 struct sort_entry sort_dso = {
@@ -182,9 +180,19 @@ static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
 static int64_t
 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
 {
+       int64_t ret;
+
        if (!left->ms.sym && !right->ms.sym)
                return right->level - left->level;
 
+       /*
+        * comparing symbol address alone is not enough since it's a
+        * relative address within a dso.
+        */
+       ret = sort__dso_cmp(left, right);
+       if (ret != 0)
+               return ret;
+
        return _sort__sym_cmp(left->ms.sym, right->ms.sym);
 }
 
@@ -224,11 +232,11 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
        return ret;
 }
 
-static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
-       return _hist_entry__sym_snprintf(self->ms.map, self->ms.sym, self->ip,
-                                        self->level, bf, size, width);
+       return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
+                                        he->level, bf, size, width);
 }
 
 struct sort_entry sort_sym = {
@@ -243,50 +251,32 @@ struct sort_entry sort_sym = {
 static int64_t
 sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-       return (int64_t)(right->ip - left->ip);
+       if (!left->srcline) {
+               if (!left->ms.map)
+                       left->srcline = SRCLINE_UNKNOWN;
+               else {
+                       struct map *map = left->ms.map;
+                       left->srcline = get_srcline(map->dso,
+                                           map__rip_2objdump(map, left->ip));
+               }
+       }
+       if (!right->srcline) {
+               if (!right->ms.map)
+                       right->srcline = SRCLINE_UNKNOWN;
+               else {
+                       struct map *map = right->ms.map;
+                       right->srcline = get_srcline(map->dso,
+                                           map__rip_2objdump(map, right->ip));
+               }
+       }
+       return strcmp(left->srcline, right->srcline);
 }
 
-static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
                                        size_t size,
                                        unsigned int width __maybe_unused)
 {
-       FILE *fp = NULL;
-       char cmd[PATH_MAX + 2], *path = self->srcline, *nl;
-       size_t line_len;
-
-       if (path != NULL)
-               goto out_path;
-
-       if (!self->ms.map)
-               goto out_ip;
-
-       if (!strncmp(self->ms.map->dso->long_name, "/tmp/perf-", 10))
-               goto out_ip;
-
-       snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64,
-                self->ms.map->dso->long_name, self->ip);
-       fp = popen(cmd, "r");
-       if (!fp)
-               goto out_ip;
-
-       if (getline(&path, &line_len, fp) < 0 || !line_len)
-               goto out_ip;
-       self->srcline = strdup(path);
-       if (self->srcline == NULL)
-               goto out_ip;
-
-       nl = strchr(self->srcline, '\n');
-       if (nl != NULL)
-               *nl = '\0';
-       path = self->srcline;
-out_path:
-       if (fp)
-               pclose(fp);
-       return repsep_snprintf(bf, size, "%s", path);
-out_ip:
-       if (fp)
-               pclose(fp);
-       return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip);
+       return repsep_snprintf(bf, size, "%s", he->srcline);
 }
 
 struct sort_entry sort_srcline = {
@@ -310,11 +300,11 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
        return strcmp(sym_l->name, sym_r->name);
 }
 
-static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
                                       size_t size, unsigned int width)
 {
        return repsep_snprintf(bf, size, "%-*s", width,
-                             self->parent ? self->parent->name : "[other]");
+                             he->parent ? he->parent->name : "[other]");
 }
 
 struct sort_entry sort_parent = {
@@ -332,10 +322,10 @@ sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
        return right->cpu - left->cpu;
 }
 
-static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
-                                      size_t size, unsigned int width)
+static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf,
+                                   size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%*d", width, self->cpu);
+       return repsep_snprintf(bf, size, "%*d", width, he->cpu);
 }
 
 struct sort_entry sort_cpu = {
@@ -354,10 +344,10 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
                              right->branch_info->from.map);
 }
 
-static int hist_entry__dso_from_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
-       return _hist_entry__dso_snprintf(self->branch_info->from.map,
+       return _hist_entry__dso_snprintf(he->branch_info->from.map,
                                         bf, size, width);
 }
 
@@ -368,10 +358,10 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
                              right->branch_info->to.map);
 }
 
-static int hist_entry__dso_to_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
                                       size_t size, unsigned int width)
 {
-       return _hist_entry__dso_snprintf(self->branch_info->to.map,
+       return _hist_entry__dso_snprintf(he->branch_info->to.map,
                                         bf, size, width);
 }
 
@@ -399,21 +389,21 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
        return _sort__sym_cmp(to_l->sym, to_r->sym);
 }
 
-static int hist_entry__sym_from_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
                                         size_t size, unsigned int width)
 {
-       struct addr_map_symbol *from = &self->branch_info->from;
+       struct addr_map_symbol *from = &he->branch_info->from;
        return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
-                                        self->level, bf, size, width);
+                                        he->level, bf, size, width);
 
 }
 
-static int hist_entry__sym_to_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
                                       size_t size, unsigned int width)
 {
-       struct addr_map_symbol *to = &self->branch_info->to;
+       struct addr_map_symbol *to = &he->branch_info->to;
        return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
-                                        self->level, bf, size, width);
+                                        he->level, bf, size, width);
 
 }
 
@@ -456,13 +446,13 @@ sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
        return mp || p;
 }
 
-static int hist_entry__mispredict_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width){
        static const char *out = "N/A";
 
-       if (self->branch_info->flags.predicted)
+       if (he->branch_info->flags.predicted)
                out = "N";
-       else if (self->branch_info->flags.mispred)
+       else if (he->branch_info->flags.mispred)
                out = "Y";
 
        return repsep_snprintf(bf, size, "%-*s", width, out);
@@ -482,19 +472,19 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
        return (int64_t)(r - l);
 }
 
-static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
        uint64_t addr = 0;
        struct map *map = NULL;
        struct symbol *sym = NULL;
 
-       if (self->mem_info) {
-               addr = self->mem_info->daddr.addr;
-               map = self->mem_info->daddr.map;
-               sym = self->mem_info->daddr.sym;
+       if (he->mem_info) {
+               addr = he->mem_info->daddr.addr;
+               map = he->mem_info->daddr.map;
+               sym = he->mem_info->daddr.sym;
        }
-       return _hist_entry__sym_snprintf(map, sym, addr, self->level, bf, size,
+       return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
                                         width);
 }
 
@@ -512,13 +502,13 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
        return _sort__dso_cmp(map_l, map_r);
 }
 
-static int hist_entry__dso_daddr_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
        struct map *map = NULL;
 
-       if (self->mem_info)
-               map = self->mem_info->daddr.map;
+       if (he->mem_info)
+               map = he->mem_info->daddr.map;
 
        return _hist_entry__dso_snprintf(map, bf, size, width);
 }
@@ -542,14 +532,14 @@ sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
        return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
 }
 
-static int hist_entry__locked_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
        const char *out;
        u64 mask = PERF_MEM_LOCK_NA;
 
-       if (self->mem_info)
-               mask = self->mem_info->data_src.mem_lock;
+       if (he->mem_info)
+               mask = he->mem_info->data_src.mem_lock;
 
        if (mask & PERF_MEM_LOCK_NA)
                out = "N/A";
@@ -591,7 +581,7 @@ static const char * const tlb_access[] = {
 };
 #define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
 
-static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
        char out[64];
@@ -602,8 +592,8 @@ static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
 
        out[0] = '\0';
 
-       if (self->mem_info)
-               m = self->mem_info->data_src.mem_dtlb;
+       if (he->mem_info)
+               m = he->mem_info->data_src.mem_dtlb;
 
        hit = m & PERF_MEM_TLB_HIT;
        miss = m & PERF_MEM_TLB_MISS;
@@ -668,7 +658,7 @@ static const char * const mem_lvl[] = {
 };
 #define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
 
-static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
        char out[64];
@@ -677,8 +667,8 @@ static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
        u64 m =  PERF_MEM_LVL_NA;
        u64 hit, miss;
 
-       if (self->mem_info)
-               m  = self->mem_info->data_src.mem_lvl;
+       if (he->mem_info)
+               m  = he->mem_info->data_src.mem_lvl;
 
        out[0] = '\0';
 
@@ -736,7 +726,7 @@ static const char * const snoop_access[] = {
 };
 #define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
 
-static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
        char out[64];
@@ -746,8 +736,8 @@ static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
 
        out[0] = '\0';
 
-       if (self->mem_info)
-               m = self->mem_info->data_src.mem_snoop;
+       if (he->mem_info)
+               m = he->mem_info->data_src.mem_snoop;
 
        for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) {
                if (!(m & 0x1))
@@ -784,10 +774,10 @@ sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
        return he_weight(left) - he_weight(right);
 }
 
-static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
+       return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
 }
 
 struct sort_entry sort_local_weight = {
@@ -803,10 +793,10 @@ sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
        return left->stat.weight - right->stat.weight;
 }
 
-static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
                                              size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight);
+       return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
 }
 
 struct sort_entry sort_global_weight = {
@@ -858,6 +848,127 @@ struct sort_entry sort_mem_snoop = {
        .se_width_idx   = HISTC_MEM_SNOOP,
 };
 
+static int64_t
+sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       return left->branch_info->flags.abort !=
+               right->branch_info->flags.abort;
+}
+
+static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
+                                   size_t size, unsigned int width)
+{
+       static const char *out = ".";
+
+       if (he->branch_info->flags.abort)
+               out = "A";
+       return repsep_snprintf(bf, size, "%-*s", width, out);
+}
+
+struct sort_entry sort_abort = {
+       .se_header      = "Transaction abort",
+       .se_cmp         = sort__abort_cmp,
+       .se_snprintf    = hist_entry__abort_snprintf,
+       .se_width_idx   = HISTC_ABORT,
+};
+
+static int64_t
+sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       return left->branch_info->flags.in_tx !=
+               right->branch_info->flags.in_tx;
+}
+
+static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
+                                   size_t size, unsigned int width)
+{
+       static const char *out = ".";
+
+       if (he->branch_info->flags.in_tx)
+               out = "T";
+
+       return repsep_snprintf(bf, size, "%-*s", width, out);
+}
+
+struct sort_entry sort_in_tx = {
+       .se_header      = "Branch in transaction",
+       .se_cmp         = sort__in_tx_cmp,
+       .se_snprintf    = hist_entry__in_tx_snprintf,
+       .se_width_idx   = HISTC_IN_TX,
+};
+
+static int64_t
+sort__transaction_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       return left->transaction - right->transaction;
+}
+
+static inline char *add_str(char *p, const char *str)
+{
+       strcpy(p, str);
+       return p + strlen(str);
+}
+
+static struct txbit {
+       unsigned flag;
+       const char *name;
+       int skip_for_len;
+} txbits[] = {
+       { PERF_TXN_ELISION,        "EL ",        0 },
+       { PERF_TXN_TRANSACTION,    "TX ",        1 },
+       { PERF_TXN_SYNC,           "SYNC ",      1 },
+       { PERF_TXN_ASYNC,          "ASYNC ",     0 },
+       { PERF_TXN_RETRY,          "RETRY ",     0 },
+       { PERF_TXN_CONFLICT,       "CON ",       0 },
+       { PERF_TXN_CAPACITY_WRITE, "CAP-WRITE ", 1 },
+       { PERF_TXN_CAPACITY_READ,  "CAP-READ ",  0 },
+       { 0, NULL, 0 }
+};
+
+int hist_entry__transaction_len(void)
+{
+       int i;
+       int len = 0;
+
+       for (i = 0; txbits[i].name; i++) {
+               if (!txbits[i].skip_for_len)
+                       len += strlen(txbits[i].name);
+       }
+       len += 4; /* :XX<space> */
+       return len;
+}
+
+static int hist_entry__transaction_snprintf(struct hist_entry *he, char *bf,
+                                           size_t size, unsigned int width)
+{
+       u64 t = he->transaction;
+       char buf[128];
+       char *p = buf;
+       int i;
+
+       buf[0] = 0;
+       for (i = 0; txbits[i].name; i++)
+               if (txbits[i].flag & t)
+                       p = add_str(p, txbits[i].name);
+       if (t && !(t & (PERF_TXN_SYNC|PERF_TXN_ASYNC)))
+               p = add_str(p, "NEITHER ");
+       if (t & PERF_TXN_ABORT_MASK) {
+               sprintf(p, ":%" PRIx64,
+                       (t & PERF_TXN_ABORT_MASK) >>
+                       PERF_TXN_ABORT_SHIFT);
+               p += strlen(p);
+       }
+
+       return repsep_snprintf(bf, size, "%-*s", width, buf);
+}
+
+struct sort_entry sort_transaction = {
+       .se_header      = "Transaction                ",
+       .se_cmp         = sort__transaction_cmp,
+       .se_snprintf    = hist_entry__transaction_snprintf,
+       .se_width_idx   = HISTC_TRANSACTION,
+};
+
 struct sort_dimension {
        const char              *name;
        struct sort_entry       *entry;
@@ -876,6 +987,7 @@ static struct sort_dimension common_sort_dimensions[] = {
        DIM(SORT_SRCLINE, "srcline", sort_srcline),
        DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
        DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
+       DIM(SORT_TRANSACTION, "transaction", sort_transaction),
 };
 
 #undef DIM
@@ -888,6 +1000,8 @@ static struct sort_dimension bstack_sort_dimensions[] = {
        DIM(SORT_SYM_FROM, "symbol_from", sort_sym_from),
        DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
        DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
+       DIM(SORT_IN_TX, "in_tx", sort_in_tx),
+       DIM(SORT_ABORT, "abort", sort_abort),
 };
 
 #undef DIM
@@ -1009,7 +1123,7 @@ int setup_sorting(void)
        return ret;
 }
 
-static void sort_entry__setup_elide(struct sort_entry *self,
+static void sort_entry__setup_elide(struct sort_entry *se,
                                    struct strlist *list,
                                    const char *list_name, FILE *fp)
 {
@@ -1017,7 +1131,7 @@ static void sort_entry__setup_elide(struct sort_entry *self,
                if (fp != NULL)
                        fprintf(fp, "# %s: %s\n", list_name,
                                strlist__entry(list, 0)->s);
-               self->elide = true;
+               se->elide = true;
        }
 }
 
index 4e80dbd271e77e245d41f2f36afdffdf8ae7ab4e..43e5ff42a609a6cb61675bd3cd3bacbd3d9b1c29 100644 (file)
@@ -22,7 +22,6 @@
 #include "parse-events.h"
 
 #include "thread.h"
-#include "sort.h"
 
 extern regex_t parent_regex;
 extern const char *sort_order;
@@ -84,7 +83,9 @@ struct hist_entry {
        struct he_stat          stat;
        struct map_symbol       ms;
        struct thread           *thread;
+       struct comm             *comm;
        u64                     ip;
+       u64                     transaction;
        s32                     cpu;
 
        struct hist_entry_diff  diff;
@@ -145,6 +146,7 @@ enum sort_type {
        SORT_SRCLINE,
        SORT_LOCAL_WEIGHT,
        SORT_GLOBAL_WEIGHT,
+       SORT_TRANSACTION,
 
        /* branch stack specific sort keys */
        __SORT_BRANCH_STACK,
@@ -153,6 +155,8 @@ enum sort_type {
        SORT_SYM_FROM,
        SORT_SYM_TO,
        SORT_MISPREDICT,
+       SORT_ABORT,
+       SORT_IN_TX,
 
        /* memory mode specific sort keys */
        __SORT_MEMORY_MODE,
@@ -175,7 +179,7 @@ struct sort_entry {
 
        int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
        int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
-       int     (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+       int     (*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
                               unsigned int width);
        u8      se_width_idx;
        bool    elide;
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
new file mode 100644 (file)
index 0000000..d11aefb
--- /dev/null
@@ -0,0 +1,265 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/kernel.h>
+
+#include "util/dso.h"
+#include "util/util.h"
+#include "util/debug.h"
+
+#ifdef HAVE_LIBBFD_SUPPORT
+
+/*
+ * Implement addr2line using libbfd.
+ */
+#define PACKAGE "perf"
+#include <bfd.h>
+
+struct a2l_data {
+       const char      *input;
+       unsigned long   addr;
+
+       bool            found;
+       const char      *filename;
+       const char      *funcname;
+       unsigned        line;
+
+       bfd             *abfd;
+       asymbol         **syms;
+};
+
+static int bfd_error(const char *string)
+{
+       const char *errmsg;
+
+       errmsg = bfd_errmsg(bfd_get_error());
+       fflush(stdout);
+
+       if (string)
+               pr_debug("%s: %s\n", string, errmsg);
+       else
+               pr_debug("%s\n", errmsg);
+
+       return -1;
+}
+
+static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
+{
+       long storage;
+       long symcount;
+       asymbol **syms;
+       bfd_boolean dynamic = FALSE;
+
+       if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
+               return bfd_error(bfd_get_filename(abfd));
+
+       storage = bfd_get_symtab_upper_bound(abfd);
+       if (storage == 0L) {
+               storage = bfd_get_dynamic_symtab_upper_bound(abfd);
+               dynamic = TRUE;
+       }
+       if (storage < 0L)
+               return bfd_error(bfd_get_filename(abfd));
+
+       syms = malloc(storage);
+       if (dynamic)
+               symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
+       else
+               symcount = bfd_canonicalize_symtab(abfd, syms);
+
+       if (symcount < 0) {
+               free(syms);
+               return bfd_error(bfd_get_filename(abfd));
+       }
+
+       a2l->syms = syms;
+       return 0;
+}
+
+static void find_address_in_section(bfd *abfd, asection *section, void *data)
+{
+       bfd_vma pc, vma;
+       bfd_size_type size;
+       struct a2l_data *a2l = data;
+
+       if (a2l->found)
+               return;
+
+       if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
+               return;
+
+       pc = a2l->addr;
+       vma = bfd_get_section_vma(abfd, section);
+       size = bfd_get_section_size(section);
+
+       if (pc < vma || pc >= vma + size)
+               return;
+
+       a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma,
+                                          &a2l->filename, &a2l->funcname,
+                                          &a2l->line);
+}
+
+static struct a2l_data *addr2line_init(const char *path)
+{
+       bfd *abfd;
+       struct a2l_data *a2l = NULL;
+
+       abfd = bfd_openr(path, NULL);
+       if (abfd == NULL)
+               return NULL;
+
+       if (!bfd_check_format(abfd, bfd_object))
+               goto out;
+
+       a2l = zalloc(sizeof(*a2l));
+       if (a2l == NULL)
+               goto out;
+
+       a2l->abfd = abfd;
+       a2l->input = strdup(path);
+       if (a2l->input == NULL)
+               goto out;
+
+       if (slurp_symtab(abfd, a2l))
+               goto out;
+
+       return a2l;
+
+out:
+       if (a2l) {
+               free((void *)a2l->input);
+               free(a2l);
+       }
+       bfd_close(abfd);
+       return NULL;
+}
+
+static void addr2line_cleanup(struct a2l_data *a2l)
+{
+       if (a2l->abfd)
+               bfd_close(a2l->abfd);
+       free((void *)a2l->input);
+       free(a2l->syms);
+       free(a2l);
+}
+
+static int addr2line(const char *dso_name, unsigned long addr,
+                    char **file, unsigned int *line)
+{
+       int ret = 0;
+       struct a2l_data *a2l;
+
+       a2l = addr2line_init(dso_name);
+       if (a2l == NULL) {
+               pr_warning("addr2line_init failed for %s\n", dso_name);
+               return 0;
+       }
+
+       a2l->addr = addr;
+       bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
+
+       if (a2l->found && a2l->filename) {
+               *file = strdup(a2l->filename);
+               *line = a2l->line;
+
+               if (*file)
+                       ret = 1;
+       }
+
+       addr2line_cleanup(a2l);
+       return ret;
+}
+
+#else /* HAVE_LIBBFD_SUPPORT */
+
+static int addr2line(const char *dso_name, unsigned long addr,
+                    char **file, unsigned int *line_nr)
+{
+       FILE *fp;
+       char cmd[PATH_MAX];
+       char *filename = NULL;
+       size_t len;
+       char *sep;
+       int ret = 0;
+
+       scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64,
+                 dso_name, addr);
+
+       fp = popen(cmd, "r");
+       if (fp == NULL) {
+               pr_warning("popen failed for %s\n", dso_name);
+               return 0;
+       }
+
+       if (getline(&filename, &len, fp) < 0 || !len) {
+               pr_warning("addr2line has no output for %s\n", dso_name);
+               goto out;
+       }
+
+       sep = strchr(filename, '\n');
+       if (sep)
+               *sep = '\0';
+
+       if (!strcmp(filename, "??:0")) {
+               pr_debug("no debugging info in %s\n", dso_name);
+               free(filename);
+               goto out;
+       }
+
+       sep = strchr(filename, ':');
+       if (sep) {
+               *sep++ = '\0';
+               *file = filename;
+               *line_nr = strtoul(sep, NULL, 0);
+               ret = 1;
+       }
+out:
+       pclose(fp);
+       return ret;
+}
+#endif /* HAVE_LIBBFD_SUPPORT */
+
+char *get_srcline(struct dso *dso, unsigned long addr)
+{
+       char *file = NULL;
+       unsigned line = 0;
+       char *srcline;
+       char *dso_name = dso->long_name;
+       size_t size;
+
+       if (!dso->has_srcline)
+               return SRCLINE_UNKNOWN;
+
+       if (dso_name[0] == '[')
+               goto out;
+
+       if (!strncmp(dso_name, "/tmp/perf-", 10))
+               goto out;
+
+       if (!addr2line(dso_name, addr, &file, &line))
+               goto out;
+
+       /* just calculate actual length */
+       size = snprintf(NULL, 0, "%s:%u", file, line) + 1;
+
+       srcline = malloc(size);
+       if (srcline)
+               snprintf(srcline, size, "%s:%u", file, line);
+       else
+               srcline = SRCLINE_UNKNOWN;
+
+       free(file);
+       return srcline;
+
+out:
+       dso->has_srcline = 0;
+       return SRCLINE_UNKNOWN;
+}
+
+void free_srcline(char *srcline)
+{
+       if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
+               free(srcline);
+}
index 834c8ebfe38e961169e07eb8d89bf17ffe42782c..3edd0538161f3556f49ca1e10b1f3a1edd2e6468 100644 (file)
@@ -10,22 +10,22 @@ static const char *OP_not   = "!";  /* Logical NOT */
 #define is_operator(c) ((c) == '|' || (c) == '&' || (c) == '!')
 #define is_separator(c)        (is_operator(c) || (c) == '(' || (c) == ')')
 
-static void strfilter_node__delete(struct strfilter_node *self)
+static void strfilter_node__delete(struct strfilter_node *node)
 {
-       if (self) {
-               if (self->p && !is_operator(*self->p))
-                       free((char *)self->p);
-               strfilter_node__delete(self->l);
-               strfilter_node__delete(self->r);
-               free(self);
+       if (node) {
+               if (node->p && !is_operator(*node->p))
+                       free((char *)node->p);
+               strfilter_node__delete(node->l);
+               strfilter_node__delete(node->r);
+               free(node);
        }
 }
 
-void strfilter__delete(struct strfilter *self)
+void strfilter__delete(struct strfilter *filter)
 {
-       if (self) {
-               strfilter_node__delete(self->root);
-               free(self);
+       if (filter) {
+               strfilter_node__delete(filter->root);
+               free(filter);
        }
 }
 
@@ -62,15 +62,15 @@ static struct strfilter_node *strfilter_node__alloc(const char *op,
                                                    struct strfilter_node *l,
                                                    struct strfilter_node *r)
 {
-       struct strfilter_node *ret = zalloc(sizeof(struct strfilter_node));
+       struct strfilter_node *node = zalloc(sizeof(*node));
 
-       if (ret) {
-               ret->p = op;
-               ret->l = l;
-               ret->r = r;
+       if (node) {
+               node->p = op;
+               node->l = l;
+               node->r = r;
        }
 
-       return ret;
+       return node;
 }
 
 static struct strfilter_node *strfilter_node__new(const char *s,
@@ -154,46 +154,46 @@ error:
  */
 struct strfilter *strfilter__new(const char *rules, const char **err)
 {
-       struct strfilter *ret = zalloc(sizeof(struct strfilter));
+       struct strfilter *filter = zalloc(sizeof(*filter));
        const char *ep = NULL;
 
-       if (ret)
-               ret->root = strfilter_node__new(rules, &ep);
+       if (filter)
+               filter->root = strfilter_node__new(rules, &ep);
 
-       if (!ret || !ret->root || *ep != '\0') {
+       if (!filter || !filter->root || *ep != '\0') {
                if (err)
                        *err = ep;
-               strfilter__delete(ret);
-               ret = NULL;
+               strfilter__delete(filter);
+               filter = NULL;
        }
 
-       return ret;
+       return filter;
 }
 
-static bool strfilter_node__compare(struct strfilter_node *self,
+static bool strfilter_node__compare(struct strfilter_node *node,
                                    const char *str)
 {
-       if (!self || !self->p)
+       if (!node || !node->p)
                return false;
 
-       switch (*self->p) {
+       switch (*node->p) {
        case '|':       /* OR */
-               return strfilter_node__compare(self->l, str) ||
-                       strfilter_node__compare(self->r, str);
+               return strfilter_node__compare(node->l, str) ||
+                       strfilter_node__compare(node->r, str);
        case '&':       /* AND */
-               return strfilter_node__compare(self->l, str) &&
-                       strfilter_node__compare(self->r, str);
+               return strfilter_node__compare(node->l, str) &&
+                       strfilter_node__compare(node->r, str);
        case '!':       /* NOT */
-               return !strfilter_node__compare(self->r, str);
+               return !strfilter_node__compare(node->r, str);
        default:
-               return strglobmatch(str, self->p);
+               return strglobmatch(str, node->p);
        }
 }
 
 /* Return true if STR matches the filter rules */
-bool strfilter__compare(struct strfilter *self, const char *str)
+bool strfilter__compare(struct strfilter *filter, const char *str)
 {
-       if (!self)
+       if (!filter)
                return false;
-       return strfilter_node__compare(self->root, str);
+       return strfilter_node__compare(filter->root, str);
 }
index 00f58a7506dea45ddcef2f9319324d8813ef2668..fe611f3c9e3965007a7ea5ed9f3fbbc768b5f271 100644 (file)
@@ -30,19 +30,19 @@ struct strfilter *strfilter__new(const char *rules, const char **err);
 
 /**
  * strfilter__compare - compare given string and a string filter
- * @self: String filter
+ * @filter: String filter
  * @str: target string
  *
- * Compare @str and @self. Return true if the str match the rule
+ * Compare @str and @filter. Return true if the str match the rule
  */
-bool strfilter__compare(struct strfilter *self, const char *str);
+bool strfilter__compare(struct strfilter *filter, const char *str);
 
 /**
  * strfilter__delete - delete a string filter
- * @self: String filter to delete
+ * @filter: String filter to delete
  *
- * Delete @self.
+ * Delete @filter.
  */
-void strfilter__delete(struct strfilter *self);
+void strfilter__delete(struct strfilter *filter);
 
 #endif
index a9c829be52169eac5b9f00d9382fd9281152b9e6..eed0b96302af189fa4b7c75f73ef538b8493336e 100644 (file)
@@ -8,7 +8,7 @@
 #include "symbol.h"
 #include "debug.h"
 
-#ifndef HAVE_ELF_GETPHDRNUM
+#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
 static int elf_getphdrnum(Elf *elf, size_t *dst)
 {
        GElf_Ehdr gehdr;
@@ -487,27 +487,27 @@ int filename__read_debuglink(const char *filename, char *debuglink,
 
        ek = elf_kind(elf);
        if (ek != ELF_K_ELF)
-               goto out_close;
+               goto out_elf_end;
 
        if (gelf_getehdr(elf, &ehdr) == NULL) {
                pr_err("%s: cannot get elf header.\n", __func__);
-               goto out_close;
+               goto out_elf_end;
        }
 
        sec = elf_section_by_name(elf, &ehdr, &shdr,
                                  ".gnu_debuglink", NULL);
        if (sec == NULL)
-               goto out_close;
+               goto out_elf_end;
 
        data = elf_getdata(sec, NULL);
        if (data == NULL)
-               goto out_close;
+               goto out_elf_end;
 
        /* the start of this section is a zero-terminated string */
        strncpy(debuglink, data->d_buf, size);
 
+out_elf_end:
        elf_end(elf);
-
 out_close:
        close(fd);
 out:
@@ -1018,6 +1018,601 @@ int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
        return err;
 }
 
+static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len)
+{
+       ssize_t r;
+       size_t n;
+       int err = -1;
+       char *buf = malloc(page_size);
+
+       if (buf == NULL)
+               return -1;
+
+       if (lseek(to, to_offs, SEEK_SET) != to_offs)
+               goto out;
+
+       if (lseek(from, from_offs, SEEK_SET) != from_offs)
+               goto out;
+
+       while (len) {
+               n = page_size;
+               if (len < n)
+                       n = len;
+               /* Use read because mmap won't work on proc files */
+               r = read(from, buf, n);
+               if (r < 0)
+                       goto out;
+               if (!r)
+                       break;
+               n = r;
+               r = write(to, buf, n);
+               if (r < 0)
+                       goto out;
+               if ((size_t)r != n)
+                       goto out;
+               len -= n;
+       }
+
+       err = 0;
+out:
+       free(buf);
+       return err;
+}
+
+struct kcore {
+       int fd;
+       int elfclass;
+       Elf *elf;
+       GElf_Ehdr ehdr;
+};
+
+static int kcore__open(struct kcore *kcore, const char *filename)
+{
+       GElf_Ehdr *ehdr;
+
+       kcore->fd = open(filename, O_RDONLY);
+       if (kcore->fd == -1)
+               return -1;
+
+       kcore->elf = elf_begin(kcore->fd, ELF_C_READ, NULL);
+       if (!kcore->elf)
+               goto out_close;
+
+       kcore->elfclass = gelf_getclass(kcore->elf);
+       if (kcore->elfclass == ELFCLASSNONE)
+               goto out_end;
+
+       ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
+       if (!ehdr)
+               goto out_end;
+
+       return 0;
+
+out_end:
+       elf_end(kcore->elf);
+out_close:
+       close(kcore->fd);
+       return -1;
+}
+
+static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
+                      bool temp)
+{
+       GElf_Ehdr *ehdr;
+
+       kcore->elfclass = elfclass;
+
+       if (temp)
+               kcore->fd = mkstemp(filename);
+       else
+               kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400);
+       if (kcore->fd == -1)
+               return -1;
+
+       kcore->elf = elf_begin(kcore->fd, ELF_C_WRITE, NULL);
+       if (!kcore->elf)
+               goto out_close;
+
+       if (!gelf_newehdr(kcore->elf, elfclass))
+               goto out_end;
+
+       ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
+       if (!ehdr)
+               goto out_end;
+
+       return 0;
+
+out_end:
+       elf_end(kcore->elf);
+out_close:
+       close(kcore->fd);
+       unlink(filename);
+       return -1;
+}
+
+static void kcore__close(struct kcore *kcore)
+{
+       elf_end(kcore->elf);
+       close(kcore->fd);
+}
+
+static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count)
+{
+       GElf_Ehdr *ehdr = &to->ehdr;
+       GElf_Ehdr *kehdr = &from->ehdr;
+
+       memcpy(ehdr->e_ident, kehdr->e_ident, EI_NIDENT);
+       ehdr->e_type      = kehdr->e_type;
+       ehdr->e_machine   = kehdr->e_machine;
+       ehdr->e_version   = kehdr->e_version;
+       ehdr->e_entry     = 0;
+       ehdr->e_shoff     = 0;
+       ehdr->e_flags     = kehdr->e_flags;
+       ehdr->e_phnum     = count;
+       ehdr->e_shentsize = 0;
+       ehdr->e_shnum     = 0;
+       ehdr->e_shstrndx  = 0;
+
+       if (from->elfclass == ELFCLASS32) {
+               ehdr->e_phoff     = sizeof(Elf32_Ehdr);
+               ehdr->e_ehsize    = sizeof(Elf32_Ehdr);
+               ehdr->e_phentsize = sizeof(Elf32_Phdr);
+       } else {
+               ehdr->e_phoff     = sizeof(Elf64_Ehdr);
+               ehdr->e_ehsize    = sizeof(Elf64_Ehdr);
+               ehdr->e_phentsize = sizeof(Elf64_Phdr);
+       }
+
+       if (!gelf_update_ehdr(to->elf, ehdr))
+               return -1;
+
+       if (!gelf_newphdr(to->elf, count))
+               return -1;
+
+       return 0;
+}
+
+static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset,
+                          u64 addr, u64 len)
+{
+       GElf_Phdr gphdr;
+       GElf_Phdr *phdr;
+
+       phdr = gelf_getphdr(kcore->elf, idx, &gphdr);
+       if (!phdr)
+               return -1;
+
+       phdr->p_type    = PT_LOAD;
+       phdr->p_flags   = PF_R | PF_W | PF_X;
+       phdr->p_offset  = offset;
+       phdr->p_vaddr   = addr;
+       phdr->p_paddr   = 0;
+       phdr->p_filesz  = len;
+       phdr->p_memsz   = len;
+       phdr->p_align   = page_size;
+
+       if (!gelf_update_phdr(kcore->elf, idx, phdr))
+               return -1;
+
+       return 0;
+}
+
+static off_t kcore__write(struct kcore *kcore)
+{
+       return elf_update(kcore->elf, ELF_C_WRITE);
+}
+
+struct phdr_data {
+       off_t offset;
+       u64 addr;
+       u64 len;
+};
+
+struct kcore_copy_info {
+       u64 stext;
+       u64 etext;
+       u64 first_symbol;
+       u64 last_symbol;
+       u64 first_module;
+       u64 last_module_symbol;
+       struct phdr_data kernel_map;
+       struct phdr_data modules_map;
+};
+
+static int kcore_copy__process_kallsyms(void *arg, const char *name, char type,
+                                       u64 start)
+{
+       struct kcore_copy_info *kci = arg;
+
+       if (!symbol_type__is_a(type, MAP__FUNCTION))
+               return 0;
+
+       if (strchr(name, '[')) {
+               if (start > kci->last_module_symbol)
+                       kci->last_module_symbol = start;
+               return 0;
+       }
+
+       if (!kci->first_symbol || start < kci->first_symbol)
+               kci->first_symbol = start;
+
+       if (!kci->last_symbol || start > kci->last_symbol)
+               kci->last_symbol = start;
+
+       if (!strcmp(name, "_stext")) {
+               kci->stext = start;
+               return 0;
+       }
+
+       if (!strcmp(name, "_etext")) {
+               kci->etext = start;
+               return 0;
+       }
+
+       return 0;
+}
+
+static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci,
+                                     const char *dir)
+{
+       char kallsyms_filename[PATH_MAX];
+
+       scnprintf(kallsyms_filename, PATH_MAX, "%s/kallsyms", dir);
+
+       if (symbol__restricted_filename(kallsyms_filename, "/proc/kallsyms"))
+               return -1;
+
+       if (kallsyms__parse(kallsyms_filename, kci,
+                           kcore_copy__process_kallsyms) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int kcore_copy__process_modules(void *arg,
+                                      const char *name __maybe_unused,
+                                      u64 start)
+{
+       struct kcore_copy_info *kci = arg;
+
+       if (!kci->first_module || start < kci->first_module)
+               kci->first_module = start;
+
+       return 0;
+}
+
+static int kcore_copy__parse_modules(struct kcore_copy_info *kci,
+                                    const char *dir)
+{
+       char modules_filename[PATH_MAX];
+
+       scnprintf(modules_filename, PATH_MAX, "%s/modules", dir);
+
+       if (symbol__restricted_filename(modules_filename, "/proc/modules"))
+               return -1;
+
+       if (modules__parse(modules_filename, kci,
+                          kcore_copy__process_modules) < 0)
+               return -1;
+
+       return 0;
+}
+
+static void kcore_copy__map(struct phdr_data *p, u64 start, u64 end, u64 pgoff,
+                           u64 s, u64 e)
+{
+       if (p->addr || s < start || s >= end)
+               return;
+
+       p->addr = s;
+       p->offset = (s - start) + pgoff;
+       p->len = e < end ? e - s : end - s;
+}
+
+static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data)
+{
+       struct kcore_copy_info *kci = data;
+       u64 end = start + len;
+
+       kcore_copy__map(&kci->kernel_map, start, end, pgoff, kci->stext,
+                       kci->etext);
+
+       kcore_copy__map(&kci->modules_map, start, end, pgoff, kci->first_module,
+                       kci->last_module_symbol);
+
+       return 0;
+}
+
+static int kcore_copy__read_maps(struct kcore_copy_info *kci, Elf *elf)
+{
+       if (elf_read_maps(elf, true, kcore_copy__read_map, kci) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int kcore_copy__calc_maps(struct kcore_copy_info *kci, const char *dir,
+                                Elf *elf)
+{
+       if (kcore_copy__parse_kallsyms(kci, dir))
+               return -1;
+
+       if (kcore_copy__parse_modules(kci, dir))
+               return -1;
+
+       if (kci->stext)
+               kci->stext = round_down(kci->stext, page_size);
+       else
+               kci->stext = round_down(kci->first_symbol, page_size);
+
+       if (kci->etext) {
+               kci->etext = round_up(kci->etext, page_size);
+       } else if (kci->last_symbol) {
+               kci->etext = round_up(kci->last_symbol, page_size);
+               kci->etext += page_size;
+       }
+
+       kci->first_module = round_down(kci->first_module, page_size);
+
+       if (kci->last_module_symbol) {
+               kci->last_module_symbol = round_up(kci->last_module_symbol,
+                                                  page_size);
+               kci->last_module_symbol += page_size;
+       }
+
+       if (!kci->stext || !kci->etext)
+               return -1;
+
+       if (kci->first_module && !kci->last_module_symbol)
+               return -1;
+
+       return kcore_copy__read_maps(kci, elf);
+}
+
+static int kcore_copy__copy_file(const char *from_dir, const char *to_dir,
+                                const char *name)
+{
+       char from_filename[PATH_MAX];
+       char to_filename[PATH_MAX];
+
+       scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
+       scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
+
+       return copyfile_mode(from_filename, to_filename, 0400);
+}
+
+static int kcore_copy__unlink(const char *dir, const char *name)
+{
+       char filename[PATH_MAX];
+
+       scnprintf(filename, PATH_MAX, "%s/%s", dir, name);
+
+       return unlink(filename);
+}
+
+static int kcore_copy__compare_fds(int from, int to)
+{
+       char *buf_from;
+       char *buf_to;
+       ssize_t ret;
+       size_t len;
+       int err = -1;
+
+       buf_from = malloc(page_size);
+       buf_to = malloc(page_size);
+       if (!buf_from || !buf_to)
+               goto out;
+
+       while (1) {
+               /* Use read because mmap won't work on proc files */
+               ret = read(from, buf_from, page_size);
+               if (ret < 0)
+                       goto out;
+
+               if (!ret)
+                       break;
+
+               len = ret;
+
+               if (readn(to, buf_to, len) != (int)len)
+                       goto out;
+
+               if (memcmp(buf_from, buf_to, len))
+                       goto out;
+       }
+
+       err = 0;
+out:
+       free(buf_to);
+       free(buf_from);
+       return err;
+}
+
+static int kcore_copy__compare_files(const char *from_filename,
+                                    const char *to_filename)
+{
+       int from, to, err = -1;
+
+       from = open(from_filename, O_RDONLY);
+       if (from < 0)
+               return -1;
+
+       to = open(to_filename, O_RDONLY);
+       if (to < 0)
+               goto out_close_from;
+
+       err = kcore_copy__compare_fds(from, to);
+
+       close(to);
+out_close_from:
+       close(from);
+       return err;
+}
+
+static int kcore_copy__compare_file(const char *from_dir, const char *to_dir,
+                                   const char *name)
+{
+       char from_filename[PATH_MAX];
+       char to_filename[PATH_MAX];
+
+       scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
+       scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
+
+       return kcore_copy__compare_files(from_filename, to_filename);
+}
+
+/**
+ * kcore_copy - copy kallsyms, modules and kcore from one directory to another.
+ * @from_dir: from directory
+ * @to_dir: to directory
+ *
+ * This function copies kallsyms, modules and kcore files from one directory to
+ * another.  kallsyms and modules are copied entirely.  Only code segments are
+ * copied from kcore.  It is assumed that two segments suffice: one for the
+ * kernel proper and one for all the modules.  The code segments are determined
+ * from kallsyms and modules files.  The kernel map starts at _stext or the
+ * lowest function symbol, and ends at _etext or the highest function symbol.
+ * The module map starts at the lowest module address and ends at the highest
+ * module symbol.  Start addresses are rounded down to the nearest page.  End
+ * addresses are rounded up to the nearest page.  An extra page is added to the
+ * highest kernel symbol and highest module symbol to, hopefully, encompass that
+ * symbol too.  Because it contains only code sections, the resulting kcore is
+ * unusual.  One significant peculiarity is that the mapping (start -> pgoff)
+ * is not the same for the kernel map and the modules map.  That happens because
+ * the data is copied adjacently whereas the original kcore has gaps.  Finally,
+ * kallsyms and modules files are compared with their copies to check that
+ * modules have not been loaded or unloaded while the copies were taking place.
+ *
+ * Return: %0 on success, %-1 on failure.
+ */
+int kcore_copy(const char *from_dir, const char *to_dir)
+{
+       struct kcore kcore;
+       struct kcore extract;
+       size_t count = 2;
+       int idx = 0, err = -1;
+       off_t offset = page_size, sz, modules_offset = 0;
+       struct kcore_copy_info kci = { .stext = 0, };
+       char kcore_filename[PATH_MAX];
+       char extract_filename[PATH_MAX];
+
+       if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms"))
+               return -1;
+
+       if (kcore_copy__copy_file(from_dir, to_dir, "modules"))
+               goto out_unlink_kallsyms;
+
+       scnprintf(kcore_filename, PATH_MAX, "%s/kcore", from_dir);
+       scnprintf(extract_filename, PATH_MAX, "%s/kcore", to_dir);
+
+       if (kcore__open(&kcore, kcore_filename))
+               goto out_unlink_modules;
+
+       if (kcore_copy__calc_maps(&kci, from_dir, kcore.elf))
+               goto out_kcore_close;
+
+       if (kcore__init(&extract, extract_filename, kcore.elfclass, false))
+               goto out_kcore_close;
+
+       if (!kci.modules_map.addr)
+               count -= 1;
+
+       if (kcore__copy_hdr(&kcore, &extract, count))
+               goto out_extract_close;
+
+       if (kcore__add_phdr(&extract, idx++, offset, kci.kernel_map.addr,
+                           kci.kernel_map.len))
+               goto out_extract_close;
+
+       if (kci.modules_map.addr) {
+               modules_offset = offset + kci.kernel_map.len;
+               if (kcore__add_phdr(&extract, idx, modules_offset,
+                                   kci.modules_map.addr, kci.modules_map.len))
+                       goto out_extract_close;
+       }
+
+       sz = kcore__write(&extract);
+       if (sz < 0 || sz > offset)
+               goto out_extract_close;
+
+       if (copy_bytes(kcore.fd, kci.kernel_map.offset, extract.fd, offset,
+                      kci.kernel_map.len))
+               goto out_extract_close;
+
+       if (modules_offset && copy_bytes(kcore.fd, kci.modules_map.offset,
+                                        extract.fd, modules_offset,
+                                        kci.modules_map.len))
+               goto out_extract_close;
+
+       if (kcore_copy__compare_file(from_dir, to_dir, "modules"))
+               goto out_extract_close;
+
+       if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms"))
+               goto out_extract_close;
+
+       err = 0;
+
+out_extract_close:
+       kcore__close(&extract);
+       if (err)
+               unlink(extract_filename);
+out_kcore_close:
+       kcore__close(&kcore);
+out_unlink_modules:
+       if (err)
+               kcore_copy__unlink(to_dir, "modules");
+out_unlink_kallsyms:
+       if (err)
+               kcore_copy__unlink(to_dir, "kallsyms");
+
+       return err;
+}
+
+int kcore_extract__create(struct kcore_extract *kce)
+{
+       struct kcore kcore;
+       struct kcore extract;
+       size_t count = 1;
+       int idx = 0, err = -1;
+       off_t offset = page_size, sz;
+
+       if (kcore__open(&kcore, kce->kcore_filename))
+               return -1;
+
+       strcpy(kce->extract_filename, PERF_KCORE_EXTRACT);
+       if (kcore__init(&extract, kce->extract_filename, kcore.elfclass, true))
+               goto out_kcore_close;
+
+       if (kcore__copy_hdr(&kcore, &extract, count))
+               goto out_extract_close;
+
+       if (kcore__add_phdr(&extract, idx, offset, kce->addr, kce->len))
+               goto out_extract_close;
+
+       sz = kcore__write(&extract);
+       if (sz < 0 || sz > offset)
+               goto out_extract_close;
+
+       if (copy_bytes(kcore.fd, kce->offs, extract.fd, offset, kce->len))
+               goto out_extract_close;
+
+       err = 0;
+
+out_extract_close:
+       kcore__close(&extract);
+       if (err)
+               unlink(kce->extract_filename);
+out_kcore_close:
+       kcore__close(&kcore);
+
+       return err;
+}
+
+void kcore_extract__delete(struct kcore_extract *kce)
+{
+       unlink(kce->extract_filename);
+}
+
 void symbol__elf_init(void)
 {
        elf_version(EV_CURRENT);
index 3a802c300fc564adce713aebbd848a1b936e78c1..2d2dd0532b5a971e588086c0605ae0d6ed4080df 100644 (file)
@@ -308,6 +308,21 @@ int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused,
        return -1;
 }
 
+int kcore_extract__create(struct kcore_extract *kce __maybe_unused)
+{
+       return -1;
+}
+
+void kcore_extract__delete(struct kcore_extract *kce __maybe_unused)
+{
+}
+
+int kcore_copy(const char *from_dir __maybe_unused,
+              const char *to_dir __maybe_unused)
+{
+       return -1;
+}
+
 void symbol__elf_init(void)
 {
 }
index 7eb0362f4ffd2468c81f6ae1a93686d00dfefe50..c0c36965fff0f0060b2f2a077edc17c569648bf2 100644 (file)
@@ -51,6 +51,7 @@ static enum dso_binary_type binary_type_symtab[] = {
        DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
        DSO_BINARY_TYPE__GUEST_KMODULE,
        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+       DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
        DSO_BINARY_TYPE__NOT_FOUND,
 };
 
@@ -159,10 +160,12 @@ again:
 
                if (choose_best_symbol(curr, next) == SYMBOL_A) {
                        rb_erase(&next->rb_node, symbols);
+                       symbol__delete(next);
                        goto again;
                } else {
                        nd = rb_next(&curr->rb_node);
                        rb_erase(&curr->rb_node, symbols);
+                       symbol__delete(curr);
                }
        }
 }
@@ -499,6 +502,64 @@ out_failure:
        return -1;
 }
 
+int modules__parse(const char *filename, void *arg,
+                  int (*process_module)(void *arg, const char *name,
+                                        u64 start))
+{
+       char *line = NULL;
+       size_t n;
+       FILE *file;
+       int err = 0;
+
+       file = fopen(filename, "r");
+       if (file == NULL)
+               return -1;
+
+       while (1) {
+               char name[PATH_MAX];
+               u64 start;
+               char *sep;
+               ssize_t line_len;
+
+               line_len = getline(&line, &n, file);
+               if (line_len < 0) {
+                       if (feof(file))
+                               break;
+                       err = -1;
+                       goto out;
+               }
+
+               if (!line) {
+                       err = -1;
+                       goto out;
+               }
+
+               line[--line_len] = '\0'; /* \n */
+
+               sep = strrchr(line, 'x');
+               if (sep == NULL)
+                       continue;
+
+               hex2u64(sep + 1, &start);
+
+               sep = strchr(line, ' ');
+               if (sep == NULL)
+                       continue;
+
+               *sep = '\0';
+
+               scnprintf(name, sizeof(name), "[%s]", line);
+
+               err = process_module(arg, name, start);
+               if (err)
+                       break;
+       }
+out:
+       free(line);
+       fclose(file);
+       return err;
+}
+
 struct process_kallsyms_args {
        struct map *map;
        struct dso *dso;
@@ -739,51 +800,242 @@ bool symbol__restricted_filename(const char *filename,
        return restricted;
 }
 
-struct kcore_mapfn_data {
-       struct dso *dso;
-       enum map_type type;
-       struct list_head maps;
+struct module_info {
+       struct rb_node rb_node;
+       char *name;
+       u64 start;
 };
 
-static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
+static void add_module(struct module_info *mi, struct rb_root *modules)
 {
-       struct kcore_mapfn_data *md = data;
-       struct map *map;
+       struct rb_node **p = &modules->rb_node;
+       struct rb_node *parent = NULL;
+       struct module_info *m;
 
-       map = map__new2(start, md->dso, md->type);
-       if (map == NULL)
+       while (*p != NULL) {
+               parent = *p;
+               m = rb_entry(parent, struct module_info, rb_node);
+               if (strcmp(mi->name, m->name) < 0)
+                       p = &(*p)->rb_left;
+               else
+                       p = &(*p)->rb_right;
+       }
+       rb_link_node(&mi->rb_node, parent, p);
+       rb_insert_color(&mi->rb_node, modules);
+}
+
+static void delete_modules(struct rb_root *modules)
+{
+       struct module_info *mi;
+       struct rb_node *next = rb_first(modules);
+
+       while (next) {
+               mi = rb_entry(next, struct module_info, rb_node);
+               next = rb_next(&mi->rb_node);
+               rb_erase(&mi->rb_node, modules);
+               free(mi->name);
+               free(mi);
+       }
+}
+
+static struct module_info *find_module(const char *name,
+                                      struct rb_root *modules)
+{
+       struct rb_node *n = modules->rb_node;
+
+       while (n) {
+               struct module_info *m;
+               int cmp;
+
+               m = rb_entry(n, struct module_info, rb_node);
+               cmp = strcmp(name, m->name);
+               if (cmp < 0)
+                       n = n->rb_left;
+               else if (cmp > 0)
+                       n = n->rb_right;
+               else
+                       return m;
+       }
+
+       return NULL;
+}
+
+static int __read_proc_modules(void *arg, const char *name, u64 start)
+{
+       struct rb_root *modules = arg;
+       struct module_info *mi;
+
+       mi = zalloc(sizeof(struct module_info));
+       if (!mi)
                return -ENOMEM;
 
-       map->end = map->start + len;
-       map->pgoff = pgoff;
+       mi->name = strdup(name);
+       mi->start = start;
 
-       list_add(&map->node, &md->maps);
+       if (!mi->name) {
+               free(mi);
+               return -ENOMEM;
+       }
+
+       add_module(mi, modules);
+
+       return 0;
+}
+
+static int read_proc_modules(const char *filename, struct rb_root *modules)
+{
+       if (symbol__restricted_filename(filename, "/proc/modules"))
+               return -1;
+
+       if (modules__parse(filename, modules, __read_proc_modules)) {
+               delete_modules(modules);
+               return -1;
+       }
 
        return 0;
 }
 
+int compare_proc_modules(const char *from, const char *to)
+{
+       struct rb_root from_modules = RB_ROOT;
+       struct rb_root to_modules = RB_ROOT;
+       struct rb_node *from_node, *to_node;
+       struct module_info *from_m, *to_m;
+       int ret = -1;
+
+       if (read_proc_modules(from, &from_modules))
+               return -1;
+
+       if (read_proc_modules(to, &to_modules))
+               goto out_delete_from;
+
+       from_node = rb_first(&from_modules);
+       to_node = rb_first(&to_modules);
+       while (from_node) {
+               if (!to_node)
+                       break;
+
+               from_m = rb_entry(from_node, struct module_info, rb_node);
+               to_m = rb_entry(to_node, struct module_info, rb_node);
+
+               if (from_m->start != to_m->start ||
+                   strcmp(from_m->name, to_m->name))
+                       break;
+
+               from_node = rb_next(from_node);
+               to_node = rb_next(to_node);
+       }
+
+       if (!from_node && !to_node)
+               ret = 0;
+
+       delete_modules(&to_modules);
+out_delete_from:
+       delete_modules(&from_modules);
+
+       return ret;
+}
+
+static int do_validate_kcore_modules(const char *filename, struct map *map,
+                                 struct map_groups *kmaps)
+{
+       struct rb_root modules = RB_ROOT;
+       struct map *old_map;
+       int err;
+
+       err = read_proc_modules(filename, &modules);
+       if (err)
+               return err;
+
+       old_map = map_groups__first(kmaps, map->type);
+       while (old_map) {
+               struct map *next = map_groups__next(old_map);
+               struct module_info *mi;
+
+               if (old_map == map || old_map->start == map->start) {
+                       /* The kernel map */
+                       old_map = next;
+                       continue;
+               }
+
+               /* Module must be in memory at the same address */
+               mi = find_module(old_map->dso->short_name, &modules);
+               if (!mi || mi->start != old_map->start) {
+                       err = -EINVAL;
+                       goto out;
+               }
+
+               old_map = next;
+       }
+out:
+       delete_modules(&modules);
+       return err;
+}
+
 /*
- * If kallsyms is referenced by name then we look for kcore in the same
+ * If kallsyms is referenced by name then we look for filename in the same
  * directory.
  */
-static bool kcore_filename_from_kallsyms_filename(char *kcore_filename,
-                                                 const char *kallsyms_filename)
+static bool filename_from_kallsyms_filename(char *filename,
+                                           const char *base_name,
+                                           const char *kallsyms_filename)
 {
        char *name;
 
-       strcpy(kcore_filename, kallsyms_filename);
-       name = strrchr(kcore_filename, '/');
+       strcpy(filename, kallsyms_filename);
+       name = strrchr(filename, '/');
        if (!name)
                return false;
 
-       if (!strcmp(name, "/kallsyms")) {
-               strcpy(name, "/kcore");
+       name += 1;
+
+       if (!strcmp(name, "kallsyms")) {
+               strcpy(name, base_name);
                return true;
        }
 
        return false;
 }
 
+static int validate_kcore_modules(const char *kallsyms_filename,
+                                 struct map *map)
+{
+       struct map_groups *kmaps = map__kmap(map)->kmaps;
+       char modules_filename[PATH_MAX];
+
+       if (!filename_from_kallsyms_filename(modules_filename, "modules",
+                                            kallsyms_filename))
+               return -EINVAL;
+
+       if (do_validate_kcore_modules(modules_filename, map, kmaps))
+               return -EINVAL;
+
+       return 0;
+}
+
+struct kcore_mapfn_data {
+       struct dso *dso;
+       enum map_type type;
+       struct list_head maps;
+};
+
+static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
+{
+       struct kcore_mapfn_data *md = data;
+       struct map *map;
+
+       map = map__new2(start, md->dso, md->type);
+       if (map == NULL)
+               return -ENOMEM;
+
+       map->end = map->start + len;
+       map->pgoff = pgoff;
+
+       list_add(&map->node, &md->maps);
+
+       return 0;
+}
+
 static int dso__load_kcore(struct dso *dso, struct map *map,
                           const char *kallsyms_filename)
 {
@@ -800,8 +1052,12 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
        if (map != machine->vmlinux_maps[map->type])
                return -EINVAL;
 
-       if (!kcore_filename_from_kallsyms_filename(kcore_filename,
-                                                  kallsyms_filename))
+       if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
+                                            kallsyms_filename))
+               return -EINVAL;
+
+       /* All modules must be present at their original addresses */
+       if (validate_kcore_modules(kallsyms_filename, map))
                return -EINVAL;
 
        md.dso = dso;
@@ -1188,6 +1444,105 @@ out:
        return err;
 }
 
+static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
+{
+       char kallsyms_filename[PATH_MAX];
+       struct dirent *dent;
+       int ret = -1;
+       DIR *d;
+
+       d = opendir(dir);
+       if (!d)
+               return -1;
+
+       while (1) {
+               dent = readdir(d);
+               if (!dent)
+                       break;
+               if (dent->d_type != DT_DIR)
+                       continue;
+               scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
+                         "%s/%s/kallsyms", dir, dent->d_name);
+               if (!validate_kcore_modules(kallsyms_filename, map)) {
+                       strlcpy(dir, kallsyms_filename, dir_sz);
+                       ret = 0;
+                       break;
+               }
+       }
+
+       closedir(d);
+
+       return ret;
+}
+
+static char *dso__find_kallsyms(struct dso *dso, struct map *map)
+{
+       u8 host_build_id[BUILD_ID_SIZE];
+       char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+       bool is_host = false;
+       char path[PATH_MAX];
+
+       if (!dso->has_build_id) {
+               /*
+                * Last resort, if we don't have a build-id and couldn't find
+                * any vmlinux file, try the running kernel kallsyms table.
+                */
+               goto proc_kallsyms;
+       }
+
+       if (sysfs__read_build_id("/sys/kernel/notes", host_build_id,
+                                sizeof(host_build_id)) == 0)
+               is_host = dso__build_id_equal(dso, host_build_id);
+
+       build_id__sprintf(dso->build_id, sizeof(dso->build_id), 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;
+               closedir(d);
+
+               /*
+                * Do not check the build-id cache, until we know we cannot use
+                * /proc/kcore.
+                */
+               fd = open("/proc/kcore", O_RDONLY);
+               if (fd != -1) {
+                       close(fd);
+                       /* If module maps match go with /proc/kallsyms */
+                       if (!validate_kcore_modules("/proc/kallsyms", map))
+                               goto proc_kallsyms;
+               }
+
+               /* Find kallsyms in build-id cache with kcore */
+               if (!find_matching_kcore(map, path, sizeof(path)))
+                       return strdup(path);
+
+               goto proc_kallsyms;
+       }
+
+       scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s",
+                 buildid_dir, sbuild_id);
+
+       if (access(path, F_OK)) {
+               pr_err("No kallsyms or vmlinux with build-id %s was found\n",
+                      sbuild_id);
+               return NULL;
+       }
+
+       return strdup(path);
+
+proc_kallsyms:
+       return strdup("/proc/kallsyms");
+}
+
 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
                                symbol_filter_t filter)
 {
@@ -1214,7 +1569,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
                goto do_kallsyms;
        }
 
-       if (symbol_conf.vmlinux_name != NULL) {
+       if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
                err = dso__load_vmlinux(dso, map,
                                        symbol_conf.vmlinux_name, filter);
                if (err > 0) {
@@ -1226,7 +1581,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
                return err;
        }
 
-       if (vmlinux_path != NULL) {
+       if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
                err = dso__load_vmlinux_path(dso, map, filter);
                if (err > 0)
                        return err;
@@ -1236,51 +1591,11 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
        if (symbol_conf.symfs[0] != 0)
                return -1;
 
-       /*
-        * Say the kernel DSO was created when processing the build-id header table,
-        * we have a build-id, so check if it is the same as the running kernel,
-        * using it if it is.
-        */
-       if (dso->has_build_id) {
-               u8 kallsyms_build_id[BUILD_ID_SIZE];
-               char sbuild_id[BUILD_ID_SIZE * 2 + 1];
-
-               if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
-                                        sizeof(kallsyms_build_id)) == 0) {
-                       if (dso__build_id_equal(dso, kallsyms_build_id)) {
-                               kallsyms_filename = "/proc/kallsyms";
-                               goto do_kallsyms;
-                       }
-               }
-               /*
-                * Now look if we have it on the build-id cache in
-                * $HOME/.debug/[kernel.kallsyms].
-                */
-               build_id__sprintf(dso->build_id, sizeof(dso->build_id),
-                                 sbuild_id);
-
-               if (asprintf(&kallsyms_allocated_filename,
-                            "%s/.debug/[kernel.kallsyms]/%s",
-                            getenv("HOME"), sbuild_id) == -1) {
-                       pr_err("Not enough memory for kallsyms file lookup\n");
-                       return -1;
-               }
-
-               kallsyms_filename = kallsyms_allocated_filename;
+       kallsyms_allocated_filename = dso__find_kallsyms(dso, map);
+       if (!kallsyms_allocated_filename)
+               return -1;
 
-               if (access(kallsyms_filename, F_OK)) {
-                       pr_err("No kallsyms or vmlinux with build-id %s "
-                              "was found\n", sbuild_id);
-                       free(kallsyms_allocated_filename);
-                       return -1;
-               }
-       } else {
-               /*
-                * Last resort, if we don't have a build-id and couldn't find
-                * any vmlinux file, try the running kernel kallsyms table.
-                */
-               kallsyms_filename = "/proc/kallsyms";
-       }
+       kallsyms_filename = kallsyms_allocated_filename;
 
 do_kallsyms:
        err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
index fd5b70ea29812334572fc7a6f5fad2c3ec7058e7..07de8fea2f48dbc346124539e7393307b839051a 100644 (file)
@@ -13,7 +13,7 @@
 #include <libgen.h>
 #include "build-id.h"
 
-#ifdef LIBELF_SUPPORT
+#ifdef HAVE_LIBELF_SUPPORT
 #include <libelf.h>
 #include <gelf.h>
 #endif
@@ -21,7 +21,7 @@
 
 #include "dso.h"
 
-#ifdef HAVE_CPLUS_DEMANGLE
+#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
 extern char *cplus_demangle(const char *, int);
 
 static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i)
@@ -46,7 +46,7 @@ static inline char *bfd_demangle(void __maybe_unused *v,
  * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
  * for newer versions we can use mmap to reduce memory usage:
  */
-#ifdef LIBELF_MMAP
+#ifdef HAVE_LIBELF_MMAP_SUPPORT
 # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
 #else
 # define PERF_ELF_C_READ_MMAP ELF_C_READ
@@ -85,6 +85,7 @@ struct symbol_conf {
        unsigned short  priv_size;
        unsigned short  nr_events;
        bool            try_vmlinux_path,
+                       ignore_vmlinux,
                        show_kernel_path,
                        use_modules,
                        sort_by_name,
@@ -178,7 +179,7 @@ struct symsrc {
        int fd;
        enum dso_binary_type type;
 
-#ifdef LIBELF_SUPPORT
+#ifdef HAVE_LIBELF_SUPPORT
        Elf *elf;
        GElf_Ehdr ehdr;
 
@@ -222,6 +223,9 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
 int kallsyms__parse(const char *filename, void *arg,
                    int (*process_symbol)(void *arg, const char *name,
                                          char type, u64 start));
+int modules__parse(const char *filename, void *arg,
+                  int (*process_module)(void *arg, const char *name,
+                                        u64 start));
 int filename__read_debuglink(const char *filename, char *debuglink,
                             size_t size);
 
@@ -252,4 +256,21 @@ typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
 int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
                    bool *is_64_bit);
 
+#define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX"
+
+struct kcore_extract {
+       char *kcore_filename;
+       u64 addr;
+       u64 offs;
+       u64 len;
+       char extract_filename[sizeof(PERF_KCORE_EXTRACT)];
+       int fd;
+};
+
+int kcore_extract__create(struct kcore_extract *kce);
+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);
+
 #endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/sysfs.c b/tools/perf/util/sysfs.c
deleted file mode 100644 (file)
index f71e9ea..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-
-#include "util.h"
-#include "sysfs.h"
-
-static const char * const sysfs_known_mountpoints[] = {
-       "/sys",
-       0,
-};
-
-static int sysfs_found;
-char sysfs_mountpoint[PATH_MAX + 1];
-
-static int sysfs_valid_mountpoint(const char *sysfs)
-{
-       struct statfs st_fs;
-
-       if (statfs(sysfs, &st_fs) < 0)
-               return -ENOENT;
-       else if (st_fs.f_type != (long) SYSFS_MAGIC)
-               return -ENOENT;
-
-       return 0;
-}
-
-const char *sysfs_find_mountpoint(void)
-{
-       const char * const *ptr;
-       char type[100];
-       FILE *fp;
-
-       if (sysfs_found)
-               return (const char *) sysfs_mountpoint;
-
-       ptr = sysfs_known_mountpoints;
-       while (*ptr) {
-               if (sysfs_valid_mountpoint(*ptr) == 0) {
-                       sysfs_found = 1;
-                       strcpy(sysfs_mountpoint, *ptr);
-                       return sysfs_mountpoint;
-               }
-               ptr++;
-       }
-
-       /* give up and parse /proc/mounts */
-       fp = fopen("/proc/mounts", "r");
-       if (fp == NULL)
-               return NULL;
-
-       while (!sysfs_found &&
-              fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
-                     sysfs_mountpoint, type) == 2) {
-
-               if (strcmp(type, "sysfs") == 0)
-                       sysfs_found = 1;
-       }
-
-       fclose(fp);
-
-       return sysfs_found ? sysfs_mountpoint : NULL;
-}
diff --git a/tools/perf/util/sysfs.h b/tools/perf/util/sysfs.h
deleted file mode 100644 (file)
index a813b72..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __SYSFS_H__
-#define __SYSFS_H__
-
-const char *sysfs_find_mountpoint(void);
-
-#endif /* __DEBUGFS_H__ */
index e3d4a550a703211d8fabeb9807c28a86466fe6d8..cd8e2f59271969f410daf28afdf93523699f475c 100644 (file)
 #include "thread.h"
 #include "util.h"
 #include "debug.h"
+#include "comm.h"
 
 struct thread *thread__new(pid_t pid, pid_t tid)
 {
-       struct thread *self = zalloc(sizeof(*self));
-
-       if (self != NULL) {
-               map_groups__init(&self->mg);
-               self->pid_ = pid;
-               self->tid = tid;
-               self->ppid = -1;
-               self->comm = malloc(32);
-               if (self->comm)
-                       snprintf(self->comm, 32, ":%d", self->tid);
+       char *comm_str;
+       struct comm *comm;
+       struct thread *thread = zalloc(sizeof(*thread));
+
+       if (thread != NULL) {
+               map_groups__init(&thread->mg);
+               thread->pid_ = pid;
+               thread->tid = tid;
+               thread->ppid = -1;
+               INIT_LIST_HEAD(&thread->comm_list);
+
+               comm_str = malloc(32);
+               if (!comm_str)
+                       goto err_thread;
+
+               snprintf(comm_str, 32, ":%d", tid);
+               comm = comm__new(comm_str, 0);
+               free(comm_str);
+               if (!comm)
+                       goto err_thread;
+
+               list_add(&comm->list, &thread->comm_list);
+       }
+
+       return thread;
+
+err_thread:
+       free(thread);
+       return NULL;
+}
+
+void thread__delete(struct thread *thread)
+{
+       struct comm *comm, *tmp;
+
+       map_groups__exit(&thread->mg);
+       list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
+               list_del(&comm->list);
+               comm__free(comm);
        }
 
-       return self;
+       free(thread);
 }
 
-void thread__delete(struct thread *self)
+struct comm *thread__comm(const struct thread *thread)
 {
-       map_groups__exit(&self->mg);
-       free(self->comm);
-       free(self);
+       if (list_empty(&thread->comm_list))
+               return NULL;
+
+       return list_first_entry(&thread->comm_list, struct comm, list);
 }
 
-int thread__set_comm(struct thread *self, const char *comm)
+/* CHECKME: time should always be 0 if event aren't ordered */
+int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
 {
-       int err;
-
-       if (self->comm)
-               free(self->comm);
-       self->comm = strdup(comm);
-       err = self->comm == NULL ? -ENOMEM : 0;
-       if (!err) {
-               self->comm_set = true;
+       struct comm *new, *curr = thread__comm(thread);
+
+       /* Override latest entry if it had no specific time coverage */
+       if (!curr->start) {
+               comm__override(curr, str, timestamp);
+               return 0;
        }
-       return err;
+
+       new = comm__new(str, timestamp);
+       if (!new)
+               return -ENOMEM;
+
+       list_add(&new->list, &thread->comm_list);
+       thread->comm_set = true;
+
+       return 0;
+}
+
+const char *thread__comm_str(const struct thread *thread)
+{
+       const struct comm *comm = thread__comm(thread);
+
+       if (!comm)
+               return NULL;
+
+       return comm__str(comm);
 }
 
-int thread__comm_len(struct thread *self)
+/* CHECKME: it should probably better return the max comm len from its comm list */
+int thread__comm_len(struct thread *thread)
 {
-       if (!self->comm_len) {
-               if (!self->comm)
+       if (!thread->comm_len) {
+               const char *comm = thread__comm_str(thread);
+               if (!comm)
                        return 0;
-               self->comm_len = strlen(self->comm);
+               thread->comm_len = strlen(comm);
        }
 
-       return self->comm_len;
+       return thread->comm_len;
 }
 
 size_t thread__fprintf(struct thread *thread, FILE *fp)
 {
-       return fprintf(fp, "Thread %d %s\n", thread->tid, thread->comm) +
+       return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
               map_groups__fprintf(&thread->mg, verbose, fp);
 }
 
-void thread__insert_map(struct thread *self, struct map *map)
+void thread__insert_map(struct thread *thread, struct map *map)
 {
-       map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
-       map_groups__insert(&self->mg, map);
+       map_groups__fixup_overlappings(&thread->mg, map, verbose, stderr);
+       map_groups__insert(&thread->mg, map);
 }
 
-int thread__fork(struct thread *self, struct thread *parent)
+int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
 {
-       int i;
+       int i, err;
 
        if (parent->comm_set) {
-               if (self->comm)
-                       free(self->comm);
-               self->comm = strdup(parent->comm);
-               if (!self->comm)
+               const char *comm = thread__comm_str(parent);
+               if (!comm)
                        return -ENOMEM;
-               self->comm_set = true;
+               err = thread__set_comm(thread, comm, timestamp);
+               if (!err)
+                       return err;
+               thread->comm_set = true;
        }
 
        for (i = 0; i < MAP__NR_TYPES; ++i)
-               if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
+               if (map_groups__clone(&thread->mg, &parent->mg, i) < 0)
                        return -ENOMEM;
 
-       self->ppid = parent->tid;
+       thread->ppid = parent->tid;
 
        return 0;
 }
index 4ebbb40d46d43e13cc78010601611eb30e5c7498..897c1b2a750a278c8cecf000c892d5f6bba8f0af 100644 (file)
@@ -2,6 +2,7 @@
 #define __PERF_THREAD_H
 
 #include <linux/rbtree.h>
+#include <linux/list.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include "symbol.h"
@@ -18,31 +19,34 @@ struct thread {
        char                    shortname[3];
        bool                    comm_set;
        bool                    dead; /* if set thread has exited */
-       char                    *comm;
+       struct list_head        comm_list;
        int                     comm_len;
 
        void                    *priv;
 };
 
 struct machine;
+struct comm;
 
 struct thread *thread__new(pid_t pid, pid_t tid);
-void thread__delete(struct thread *self);
+void thread__delete(struct thread *thread);
 static inline void thread__exited(struct thread *thread)
 {
        thread->dead = true;
 }
 
-int thread__set_comm(struct thread *self, const char *comm);
-int thread__comm_len(struct thread *self);
-void thread__insert_map(struct thread *self, struct map *map);
-int thread__fork(struct thread *self, struct thread *parent);
+int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
+int thread__comm_len(struct thread *thread);
+struct comm *thread__comm(const struct thread *thread);
+const char *thread__comm_str(const struct thread *thread);
+void thread__insert_map(struct thread *thread, struct map *map);
+int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
 size_t thread__fprintf(struct thread *thread, FILE *fp);
 
-static inline struct map *thread__find_map(struct thread *self,
+static inline struct map *thread__find_map(struct thread *thread,
                                           enum map_type type, u64 addr)
 {
-       return self ? map_groups__find(&self->mg, type, addr) : NULL;
+       return thread ? map_groups__find(&thread->mg, type, addr) : NULL;
 }
 
 void thread__find_addr_map(struct thread *thread, struct machine *machine,
index b554ffc462b653e73b7e8de84cfa53e2609be989..88cfeaff600b334390842e725b9a7f792b0fd9af 100644 (file)
@@ -24,6 +24,7 @@ struct perf_top {
        u64                exact_samples;
        u64                guest_us_samples, guest_kernel_samples;
        int                print_entries, count_filter, delay_secs;
+       int                max_stack;
        bool               hide_kernel_symbols, hide_user_symbols, zero;
        bool               use_tui, use_stdio;
        bool               kptr_restrict_warned;
index e9e1c03f927d27bce1e041a9cc61ca47dae2b987..6681f71f2f95e329ddc5eba636d05ce67d3591ee 100644 (file)
@@ -120,42 +120,6 @@ raw_field_value(struct event_format *event, const char *name, void *data)
        return val;
 }
 
-void *raw_field_ptr(struct event_format *event, const char *name, void *data)
-{
-       struct format_field *field;
-
-       field = pevent_find_any_field(event, name);
-       if (!field)
-               return NULL;
-
-       if (field->flags & FIELD_IS_DYNAMIC) {
-               int offset;
-
-               offset = *(int *)(data + field->offset);
-               offset &= 0xffff;
-
-               return data + offset;
-       }
-
-       return data + field->offset;
-}
-
-int trace_parse_common_type(struct pevent *pevent, void *data)
-{
-       struct pevent_record record;
-
-       record.data = data;
-       return pevent_data_type(pevent, &record);
-}
-
-int trace_parse_common_pid(struct pevent *pevent, void *data)
-{
-       struct pevent_record record;
-
-       record.data = data;
-       return pevent_data_pid(pevent, &record);
-}
-
 unsigned long long read_size(struct event_format *event, void *ptr, int size)
 {
        return pevent_read_number(event->pevent, ptr, size);
index fafe1a40444a2b0785e4d41b048ee0926786fcf9..04df63114109604403f2f57a84ed03ec0b765707 100644 (file)
@@ -11,8 +11,6 @@ union perf_event;
 struct perf_tool;
 struct thread;
 
-extern struct pevent *perf_pevent;
-
 int bigendian(void);
 
 struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
@@ -23,26 +21,19 @@ int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size);
 int parse_event_file(struct pevent *pevent,
                     char *buf, unsigned long size, char *sys);
 
-struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu);
-
 unsigned long long
 raw_field_value(struct event_format *event, const char *name, void *data);
-void *raw_field_ptr(struct event_format *event, const char *name, void *data);
 
 void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
 void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
 
 ssize_t trace_report(int fd, struct pevent **pevent, bool repipe);
 
-int trace_parse_common_type(struct pevent *pevent, void *data);
-int trace_parse_common_pid(struct pevent *pevent, void *data);
-
 struct event_format *trace_find_next_event(struct pevent *pevent,
                                           struct event_format *event);
 unsigned long long read_size(struct event_format *event, void *ptr, int size);
 unsigned long long eval_flag(const char *flag);
 
-struct pevent_record *trace_read_data(struct pevent *pevent, int cpu);
 int read_tracing_data(int fd, struct list_head *pattrs);
 
 struct tracing_data {
index cb6bc503a792413dd701fec8dafbf60d9e921ed6..ec0c71a2ca2e22f2c78ef90726d0e9afe623b43c 100644 (file)
@@ -13,7 +13,7 @@ struct unwind_entry {
 
 typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
 
-#ifdef LIBUNWIND_SUPPORT
+#ifdef HAVE_LIBUNWIND_SUPPORT
 int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
                        struct machine *machine,
                        struct thread *thread,
@@ -31,5 +31,5 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
 {
        return 0;
 }
-#endif /* LIBUNWIND_SUPPORT */
+#endif /* HAVE_LIBUNWIND_SUPPORT */
 #endif /* __UNWIND_H */
index 6d17b18e915d56b47e02d16c4c27cae2a85764db..28a0a89c1f739749a59c8b80aa3d3b37d8f4000f 100644 (file)
@@ -1,7 +1,7 @@
 #include "../perf.h"
 #include "util.h"
 #include <sys/mman.h>
-#ifdef BACKTRACE_SUPPORT
+#ifdef HAVE_BACKTRACE_SUPPORT
 #include <execinfo.h>
 #endif
 #include <stdio.h>
@@ -55,17 +55,20 @@ int mkdir_p(char *path, mode_t mode)
        return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
 }
 
-static int slow_copyfile(const char *from, const char *to)
+static int slow_copyfile(const char *from, const char *to, mode_t mode)
 {
-       int err = 0;
+       int err = -1;
        char *line = NULL;
        size_t n;
        FILE *from_fp = fopen(from, "r"), *to_fp;
+       mode_t old_umask;
 
        if (from_fp == NULL)
                goto out;
 
+       old_umask = umask(mode ^ 0777);
        to_fp = fopen(to, "w");
+       umask(old_umask);
        if (to_fp == NULL)
                goto out_fclose_from;
 
@@ -82,7 +85,7 @@ out:
        return err;
 }
 
-int copyfile(const char *from, const char *to)
+int copyfile_mode(const char *from, const char *to, mode_t mode)
 {
        int fromfd, tofd;
        struct stat st;
@@ -93,13 +96,13 @@ int copyfile(const char *from, const char *to)
                goto out;
 
        if (st.st_size == 0) /* /proc? do it slowly... */
-               return slow_copyfile(from, to);
+               return slow_copyfile(from, to, mode);
 
        fromfd = open(from, O_RDONLY);
        if (fromfd < 0)
                goto out;
 
-       tofd = creat(to, 0755);
+       tofd = creat(to, mode);
        if (tofd < 0)
                goto out_close_from;
 
@@ -121,6 +124,11 @@ out:
        return err;
 }
 
+int copyfile(const char *from, const char *to)
+{
+       return copyfile_mode(from, to, 0755);
+}
+
 unsigned long convert_unit(unsigned long value, char *unit)
 {
        *unit = ' ';
@@ -204,7 +212,7 @@ int hex2u64(const char *ptr, u64 *long_val)
 }
 
 /* Obtain a backtrace and print it to stdout. */
-#ifdef BACKTRACE_SUPPORT
+#ifdef HAVE_BACKTRACE_SUPPORT
 void dump_stack(void)
 {
        void *array[16];
@@ -361,3 +369,47 @@ int parse_nsec_time(const char *str, u64 *ptime)
        *ptime = time_sec * NSEC_PER_SEC + time_nsec;
        return 0;
 }
+
+unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
+{
+       struct parse_tag *i = tags;
+
+       while (i->tag) {
+               char *s;
+
+               s = strchr(str, i->tag);
+               if (s) {
+                       unsigned long int value;
+                       char *endptr;
+
+                       value = strtoul(str, &endptr, 10);
+                       if (s != endptr)
+                               break;
+
+                       if (value > ULONG_MAX / i->mult)
+                               break;
+                       value *= i->mult;
+                       return value;
+               }
+               i++;
+       }
+
+       return (unsigned long) -1;
+}
+
+int filename__read_int(const char *filename, int *value)
+{
+       char line[64];
+       int fd = open(filename, O_RDONLY), err = -1;
+
+       if (fd < 0)
+               return -1;
+
+       if (read(fd, line, sizeof(line)) > 0) {
+               *value = atoi(line);
+               err = 0;
+       }
+
+       close(fd);
+       return err;
+}
index a53535949043f32654a181c3728a421c52baf276..c8f362daba8755f5b054d70c90f52211f6d8ccc8 100644 (file)
@@ -128,6 +128,8 @@ void put_tracing_file(char *file);
 #endif
 #endif
 
+#define PERF_GTK_DSO  "libperf-gtk.so"
+
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
@@ -241,6 +243,7 @@ static inline int sane_case(int x, int high)
 
 int mkdir_p(char *path, mode_t mode);
 int copyfile(const char *from, const char *to);
+int copyfile_mode(const char *from, const char *to, mode_t mode);
 
 s64 perf_atoll(const char *str);
 char **argv_split(const char *str, int *argcp);
@@ -270,6 +273,13 @@ bool is_power_of_2(unsigned long n)
        return (n != 0 && ((n & (n - 1)) == 0));
 }
 
+static inline unsigned next_pow2(unsigned x)
+{
+       if (!x)
+               return 1;
+       return 1ULL << (32 - __builtin_clz(x - 1));
+}
+
 size_t hex_width(u64 v);
 int hex2u64(const char *ptr, u64 *val);
 
@@ -281,4 +291,20 @@ void dump_stack(void);
 extern unsigned int page_size;
 
 void get_term_dimensions(struct winsize *ws);
+
+struct parse_tag {
+       char tag;
+       int mult;
+};
+
+unsigned long parse_tag_value(const char *str, struct parse_tag *tags);
+
+#define SRCLINE_UNKNOWN  ((char *) "??:0")
+
+struct dso;
+
+char *get_srcline(struct dso *dso, unsigned long addr);
+void free_srcline(char *srcline);
+
+int filename__read_int(const char *filename, int *value);
 #endif /* GIT_COMPAT_UTIL_H */
index 0d0506d55c71348a3ddce72fcec03824ed987bf3..ee76544deecb4138c7fdd2fee2ef4b410d39e5cc 100644 (file)
@@ -59,21 +59,22 @@ QUIET_SUBDIR0  = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
 QUIET_SUBDIR1  =
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifneq ($(V),1)
-       QUIET_CC       = @echo '   ' CC $@;
-       QUIET_AR       = @echo '   ' AR $@;
-       QUIET_LINK     = @echo '   ' LINK $@;
-       QUIET_MKDIR    = @echo '   ' MKDIR $@;
-       QUIET_GEN      = @echo '   ' GEN $@;
+  ifneq ($(V),1)
+       QUIET_CC       = @echo '  CC       '$@;
+       QUIET_AR       = @echo '  AR       '$@;
+       QUIET_LINK     = @echo '  LINK     '$@;
+       QUIET_MKDIR    = @echo '  MKDIR    '$@;
+       QUIET_GEN      = @echo '  GEN      '$@;
        QUIET_SUBDIR0  = +@subdir=
-       QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
+       QUIET_SUBDIR1  = ;$(NO_SUBDIR) \
+                         echo '  SUBDIR   '$$subdir; \
                         $(MAKE) $(PRINT_DIR) -C $$subdir
-       QUIET_FLEX     = @echo '   ' FLEX $@;
-       QUIET_BISON    = @echo '   ' BISON $@;
+       QUIET_FLEX     = @echo '  FLEX     '$@;
+       QUIET_BISON    = @echo '  BISON    '$@;
 
        descend = \
-               +@echo '   ' DESCEND $(1); \
+               +@echo         '  DESCEND  '$(1); \
                mkdir -p $(OUTPUT)$(1) && \
                $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
-endif
+  endif
 endif
This page took 3.829507 seconds and 5 git commands to generate.